From f99106743c32d616080f69ba85647039470d58a9 Mon Sep 17 00:00:00 2001
From: build-token <build-token>
Date: Tue, 2 Aug 2022 10:10:11 +0000
Subject: [PATCH] publish: Merge remote-tracking branch 'origin/main' into
 feat/insee-code

generated from commit 58baa01c358a466a6f88b241971df5b3faae30b2
---
 index.js     | 112321 ++++++++++++++++++++++++------------------------
 package.json |      6 +-
 2 files changed, 56302 insertions(+), 56025 deletions(-)

diff --git a/index.js b/index.js
index 6ed7fba..9043f7c 100644
--- a/index.js
+++ b/index.js
@@ -527,7 +527,7 @@ async function findUserPdl(
 
 const requestFactory = __webpack_require__(2);
 
-const hydrateAndFilter = __webpack_require__(341);
+const hydrateAndFilter = __webpack_require__(353);
 
 const categorization = __webpack_require__(1226);
 
@@ -536,7 +536,7 @@ const log = __webpack_require__(1243);
 module.exports = {
   BaseKonnector: __webpack_require__(1244),
   CookieKonnector: __webpack_require__(1324),
-  cozyClient: __webpack_require__(473),
+  cozyClient: __webpack_require__(485),
   errors: __webpack_require__(1250),
   log,
   saveFiles: __webpack_require__(1246),
@@ -559,7 +559,7 @@ module.exports = {
   scrape: __webpack_require__(1328),
   mkdirp: __webpack_require__(1249),
   normalizeFilename: __webpack_require__(1329),
-  utils: __webpack_require__(472),
+  utils: __webpack_require__(484),
   solveCaptcha: __webpack_require__(1330),
   createCategorizer: categorization.createCategorizer,
   categorize: categorization.categorize,
@@ -658,7 +658,7 @@ module.exports = __webpack_require__(3)["default"];
  */
 let request = __webpack_require__(4);
 
-const requestdebug = __webpack_require__(253); // Quickly found more UserAgent here
+const requestdebug = __webpack_require__(254); // Quickly found more UserAgent here
 // https://www.whatismybrowser.com/guides/the-latest-user-agent/
 
 
@@ -756,7 +756,7 @@ function mergeDefaultOptions(options = {}) {
 }
 
 function transformWithCheerio(body, response, resolveWithFullResponse) {
-  const result = (__webpack_require__(255).load)(body);
+  const result = (__webpack_require__(256).load)(body);
 
   if (resolveWithFullResponse) {
     return { ...response,
@@ -809,7 +809,7 @@ try {
 
 } catch (err) {
     /* istanbul ignore next */
-    var EOL = (__webpack_require__(252).EOL);
+    var EOL = (__webpack_require__(253).EOL);
     /* istanbul ignore next */
     console.error(EOL + '###' + EOL + '### The "request" library is not installed automatically anymore.' + EOL + '### But is a dependency of "request-promise".' + EOL + '### Please install it with:' + EOL + '### npm install request --save' + EOL + '###' + EOL);
     /* istanbul ignore next */
@@ -10363,7 +10363,7 @@ var hawk = __webpack_require__(245)
 var Multipart = (__webpack_require__(246).Multipart)
 var Redirect = (__webpack_require__(247).Redirect)
 var Tunnel = (__webpack_require__(248).Tunnel)
-var now = __webpack_require__(251)
+var now = __webpack_require__(252)
 var Buffer = (__webpack_require__(77).Buffer)
 
 var safeStringify = helpers.safeStringify
@@ -40070,7 +40070,7 @@ var net = __webpack_require__(62)
   , events = __webpack_require__(250)
   , assert = __webpack_require__(91)
   , util = __webpack_require__(64)
-  , Buffer = (__webpack_require__(77).Buffer)
+  , Buffer = (__webpack_require__(251).Buffer)
   ;
 
 exports.httpOverHttp = httpOverHttp
@@ -40316,6 +40316,77 @@ module.exports = require("events");
 
 /***/ }),
 /* 251 */
+/***/ ((module, exports, __webpack_require__) => {
+
+/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
+/* eslint-disable node/no-deprecated-api */
+var buffer = __webpack_require__(78)
+var Buffer = buffer.Buffer
+
+// alternative to using Object.keys for old browsers
+function copyProps (src, dst) {
+  for (var key in src) {
+    dst[key] = src[key]
+  }
+}
+if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
+  module.exports = buffer
+} else {
+  // Copy properties from require('buffer')
+  copyProps(buffer, exports)
+  exports.Buffer = SafeBuffer
+}
+
+function SafeBuffer (arg, encodingOrOffset, length) {
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+SafeBuffer.prototype = Object.create(Buffer.prototype)
+
+// Copy static methods from Buffer
+copyProps(Buffer, SafeBuffer)
+
+SafeBuffer.from = function (arg, encodingOrOffset, length) {
+  if (typeof arg === 'number') {
+    throw new TypeError('Argument must not be a number')
+  }
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+SafeBuffer.alloc = function (size, fill, encoding) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  var buf = Buffer(size)
+  if (fill !== undefined) {
+    if (typeof encoding === 'string') {
+      buf.fill(fill, encoding)
+    } else {
+      buf.fill(fill)
+    }
+  } else {
+    buf.fill(0)
+  }
+  return buf
+}
+
+SafeBuffer.allocUnsafe = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return Buffer(size)
+}
+
+SafeBuffer.allocUnsafeSlow = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return buffer.SlowBuffer(size)
+}
+
+
+/***/ }),
+/* 252 */
 /***/ (function(module) {
 
 // Generated by CoffeeScript 1.12.2
@@ -40357,17 +40428,17 @@ module.exports = require("events");
 
 
 /***/ }),
-/* 252 */
+/* 253 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = require("os");
 
 /***/ }),
-/* 253 */
+/* 254 */
 /***/ ((module, exports, __webpack_require__) => {
 
-var clone = __webpack_require__(254);
+var clone = __webpack_require__(255);
 
 var debugId = 0
 
@@ -40462,7 +40533,7 @@ exports.log = function(type, data, r) {
 
 
 /***/ }),
-/* 254 */
+/* 255 */
 /***/ ((module) => {
 
 "use strict";
@@ -40474,29 +40545,29 @@ module.exports = function (obj) {
 
 
 /***/ }),
-/* 255 */
+/* 256 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.root = exports.parseHTML = exports.merge = exports.contains = void 0;
-var tslib_1 = __webpack_require__(256);
+var tslib_1 = __webpack_require__(257);
 /**
  * Types used in signatures of Cheerio methods.
  *
  * @category Cheerio
  */
-tslib_1.__exportStar(__webpack_require__(257), exports);
 tslib_1.__exportStar(__webpack_require__(258), exports);
-var load_1 = __webpack_require__(258);
+tslib_1.__exportStar(__webpack_require__(259), exports);
+var load_1 = __webpack_require__(259);
 /**
  * The default cheerio instance.
  *
  * @deprecated Use the function returned by `load` instead.
  */
 exports["default"] = load_1.load([]);
-var staticMethods = tslib_1.__importStar(__webpack_require__(260));
+var staticMethods = tslib_1.__importStar(__webpack_require__(261));
 /**
  * In order to promote consistency with the jQuery library, users are encouraged
  * to instead use the static method of the same name.
@@ -40562,7 +40633,7 @@ exports.root = staticMethods.root;
 
 
 /***/ }),
-/* 256 */
+/* 257 */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
 "use strict";
@@ -40835,7 +40906,7 @@ function __classPrivateFieldSet(receiver, state, value, kind, f) {
 
 
 /***/ }),
-/* 257 */
+/* 258 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -40844,18 +40915,18 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
 
 
 /***/ }),
-/* 258 */
+/* 259 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.load = void 0;
-var tslib_1 = __webpack_require__(256);
-var options_1 = tslib_1.__importStar(__webpack_require__(259));
-var staticMethods = tslib_1.__importStar(__webpack_require__(260));
-var cheerio_1 = __webpack_require__(333);
-var parse_1 = tslib_1.__importDefault(__webpack_require__(334));
+var tslib_1 = __webpack_require__(257);
+var options_1 = tslib_1.__importStar(__webpack_require__(260));
+var staticMethods = tslib_1.__importStar(__webpack_require__(261));
+var cheerio_1 = __webpack_require__(345);
+var parse_1 = tslib_1.__importDefault(__webpack_require__(346));
 /**
  * Create a querying function, bound to a document created from the provided
  * markup. Note that similar to web browser contexts, this operation may
@@ -40904,14 +40975,14 @@ exports.load = load;
 
 
 /***/ }),
-/* 259 */
+/* 260 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.flatten = void 0;
-var tslib_1 = __webpack_require__(256);
+var tslib_1 = __webpack_require__(257);
 var defaultOpts = {
     xml: false,
     decodeEntities: true,
@@ -40933,19 +41004,19 @@ exports.flatten = flatten;
 
 
 /***/ }),
-/* 260 */
+/* 261 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.merge = exports.contains = exports.root = exports.parseHTML = exports.text = exports.xml = exports.html = void 0;
-var tslib_1 = __webpack_require__(256);
-var options_1 = tslib_1.__importStar(__webpack_require__(259));
-var cheerio_select_1 = __webpack_require__(261);
-var htmlparser2_1 = __webpack_require__(302);
-var parse5_adapter_1 = __webpack_require__(306);
-var htmlparser2_adapter_1 = __webpack_require__(332);
+var tslib_1 = __webpack_require__(257);
+var options_1 = tslib_1.__importStar(__webpack_require__(260));
+var cheerio_select_1 = __webpack_require__(262);
+var htmlparser2_1 = __webpack_require__(303);
+var parse5_adapter_1 = __webpack_require__(316);
+var htmlparser2_adapter_1 = __webpack_require__(344);
 /**
  * Helper function to render a DOM.
  *
@@ -41147,7 +41218,7 @@ function isArrayLike(item) {
 
 
 /***/ }),
-/* 261 */
+/* 262 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -41189,13 +41260,13 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.select = exports.filter = exports.some = exports.is = exports.aliases = exports.pseudos = exports.filters = void 0;
-var css_what_1 = __webpack_require__(262);
-var css_select_1 = __webpack_require__(265);
-var DomUtils = __importStar(__webpack_require__(266));
-var helpers_1 = __webpack_require__(300);
-var positionals_1 = __webpack_require__(301);
+var css_what_1 = __webpack_require__(263);
+var css_select_1 = __webpack_require__(266);
+var DomUtils = __importStar(__webpack_require__(267));
+var helpers_1 = __webpack_require__(301);
+var positionals_1 = __webpack_require__(302);
 // Re-export pseudo extension points
-var css_select_2 = __webpack_require__(265);
+var css_select_2 = __webpack_require__(266);
 Object.defineProperty(exports, "filters", ({ enumerable: true, get: function () { return css_select_2.filters; } }));
 Object.defineProperty(exports, "pseudos", ({ enumerable: true, get: function () { return css_select_2.pseudos; } }));
 Object.defineProperty(exports, "aliases", ({ enumerable: true, get: function () { return css_select_2.aliases; } }));
@@ -41450,7 +41521,7 @@ function filterElements(elements, sel, options) {
 
 
 /***/ }),
-/* 262 */
+/* 263 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -41470,15 +41541,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.stringify = exports.parse = void 0;
-__exportStar(__webpack_require__(263), exports);
-var parse_1 = __webpack_require__(263);
+__exportStar(__webpack_require__(264), exports);
+var parse_1 = __webpack_require__(264);
 Object.defineProperty(exports, "parse", ({ enumerable: true, get: function () { return __importDefault(parse_1).default; } }));
-var stringify_1 = __webpack_require__(264);
+var stringify_1 = __webpack_require__(265);
 Object.defineProperty(exports, "stringify", ({ enumerable: true, get: function () { return __importDefault(stringify_1).default; } }));
 
 
 /***/ }),
-/* 263 */
+/* 264 */
 /***/ (function(__unused_webpack_module, exports) {
 
 "use strict";
@@ -41913,7 +41984,7 @@ function addToken(subselects, tokens) {
 
 
 /***/ }),
-/* 264 */
+/* 265 */
 /***/ (function(__unused_webpack_module, exports) {
 
 "use strict";
@@ -42021,7 +42092,7 @@ function escapeName(str) {
 
 
 /***/ }),
-/* 265 */
+/* 266 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -42047,10 +42118,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.aliases = exports.pseudos = exports.filters = exports.is = exports.selectOne = exports.selectAll = exports.prepareContext = exports._compileToken = exports._compileUnsafe = exports.compile = void 0;
-var DomUtils = __importStar(__webpack_require__(266));
-var boolbase_1 = __webpack_require__(286);
-var compile_1 = __webpack_require__(287);
-var subselects_1 = __webpack_require__(299);
+var DomUtils = __importStar(__webpack_require__(267));
+var boolbase_1 = __webpack_require__(287);
+var compile_1 = __webpack_require__(288);
+var subselects_1 = __webpack_require__(300);
 var defaultEquals = function (a, b) { return a === b; };
 var defaultOptions = {
     adapter: DomUtils,
@@ -42165,14 +42236,14 @@ exports.is = is;
  */
 exports["default"] = exports.selectAll;
 // Export filters, pseudos and aliases to allow users to supply their own.
-var pseudo_selectors_1 = __webpack_require__(292);
+var pseudo_selectors_1 = __webpack_require__(293);
 Object.defineProperty(exports, "filters", ({ enumerable: true, get: function () { return pseudo_selectors_1.filters; } }));
 Object.defineProperty(exports, "pseudos", ({ enumerable: true, get: function () { return pseudo_selectors_1.pseudos; } }));
 Object.defineProperty(exports, "aliases", ({ enumerable: true, get: function () { return pseudo_selectors_1.aliases; } }));
 
 
 /***/ }),
-/* 266 */
+/* 267 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -42189,13 +42260,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.hasChildren = exports.isDocument = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = void 0;
-__exportStar(__webpack_require__(267), exports);
-__exportStar(__webpack_require__(281), exports);
+__exportStar(__webpack_require__(268), exports);
 __exportStar(__webpack_require__(282), exports);
 __exportStar(__webpack_require__(283), exports);
 __exportStar(__webpack_require__(284), exports);
 __exportStar(__webpack_require__(285), exports);
-var domhandler_1 = __webpack_require__(268);
+__exportStar(__webpack_require__(286), exports);
+var domhandler_1 = __webpack_require__(269);
 Object.defineProperty(exports, "isTag", ({ enumerable: true, get: function () { return domhandler_1.isTag; } }));
 Object.defineProperty(exports, "isCDATA", ({ enumerable: true, get: function () { return domhandler_1.isCDATA; } }));
 Object.defineProperty(exports, "isText", ({ enumerable: true, get: function () { return domhandler_1.isText; } }));
@@ -42205,7 +42276,7 @@ Object.defineProperty(exports, "hasChildren", ({ enumerable: true, get: function
 
 
 /***/ }),
-/* 267 */
+/* 268 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -42215,9 +42286,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.innerText = exports.textContent = exports.getText = exports.getInnerHTML = exports.getOuterHTML = void 0;
-var domhandler_1 = __webpack_require__(268);
-var dom_serializer_1 = __importDefault(__webpack_require__(271));
-var domelementtype_1 = __webpack_require__(269);
+var domhandler_1 = __webpack_require__(269);
+var dom_serializer_1 = __importDefault(__webpack_require__(272));
+var domelementtype_1 = __webpack_require__(270);
 /**
  * @param node Node to get the outer HTML of.
  * @param options Options for serialization.
@@ -42301,7 +42372,7 @@ exports.innerText = innerText;
 
 
 /***/ }),
-/* 268 */
+/* 269 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -42318,9 +42389,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.DomHandler = void 0;
-var domelementtype_1 = __webpack_require__(269);
-var node_1 = __webpack_require__(270);
-__exportStar(__webpack_require__(270), exports);
+var domelementtype_1 = __webpack_require__(270);
+var node_1 = __webpack_require__(271);
+__exportStar(__webpack_require__(271), exports);
 var reWhitespace = /\s+/g;
 // Default options
 var defaultOpts = {
@@ -42477,7 +42548,7 @@ exports["default"] = DomHandler;
 
 
 /***/ }),
-/* 269 */
+/* 270 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -42539,7 +42610,7 @@ exports.Doctype = ElementType.Doctype;
 
 
 /***/ }),
-/* 270 */
+/* 271 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -42572,7 +42643,7 @@ var __assign = (this && this.__assign) || function () {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0;
-var domelementtype_1 = __webpack_require__(269);
+var domelementtype_1 = __webpack_require__(270);
 var nodeTypes = new Map([
     [domelementtype_1.ElementType.Tag, 1],
     [domelementtype_1.ElementType.Script, 1],
@@ -42936,7 +43007,7 @@ function cloneChildren(childs) {
 
 
 /***/ }),
-/* 271 */
+/* 272 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -42975,15 +43046,15 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
 /*
  * Module dependencies
  */
-var ElementType = __importStar(__webpack_require__(269));
-var entities_1 = __webpack_require__(272);
+var ElementType = __importStar(__webpack_require__(270));
+var entities_1 = __webpack_require__(273);
 /**
  * Mixed-case SVG and MathML tags & attributes
  * recognized by the HTML parser.
  *
  * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign
  */
-var foreignNames_1 = __webpack_require__(280);
+var foreignNames_1 = __webpack_require__(281);
 var unencodedElements = new Set([
     "style",
     "script",
@@ -43154,15 +43225,15 @@ function renderComment(elem) {
 
 
 /***/ }),
-/* 272 */
+/* 273 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = void 0;
-var decode_1 = __webpack_require__(273);
-var encode_1 = __webpack_require__(279);
+var decode_1 = __webpack_require__(274);
+var encode_1 = __webpack_require__(280);
 /**
  * Decodes a string with entities.
  *
@@ -43196,7 +43267,7 @@ function encode(data, level) {
     return (!level || level <= 0 ? encode_1.encodeXML : encode_1.encodeHTML)(data);
 }
 exports.encode = encode;
-var encode_2 = __webpack_require__(279);
+var encode_2 = __webpack_require__(280);
 Object.defineProperty(exports, "encodeXML", ({ enumerable: true, get: function () { return encode_2.encodeXML; } }));
 Object.defineProperty(exports, "encodeHTML", ({ enumerable: true, get: function () { return encode_2.encodeHTML; } }));
 Object.defineProperty(exports, "encodeNonAsciiHTML", ({ enumerable: true, get: function () { return encode_2.encodeNonAsciiHTML; } }));
@@ -43205,7 +43276,7 @@ Object.defineProperty(exports, "escapeUTF8", ({ enumerable: true, get: function
 // Legacy aliases (deprecated)
 Object.defineProperty(exports, "encodeHTML4", ({ enumerable: true, get: function () { return encode_2.encodeHTML; } }));
 Object.defineProperty(exports, "encodeHTML5", ({ enumerable: true, get: function () { return encode_2.encodeHTML; } }));
-var decode_2 = __webpack_require__(273);
+var decode_2 = __webpack_require__(274);
 Object.defineProperty(exports, "decodeXML", ({ enumerable: true, get: function () { return decode_2.decodeXML; } }));
 Object.defineProperty(exports, "decodeHTML", ({ enumerable: true, get: function () { return decode_2.decodeHTML; } }));
 Object.defineProperty(exports, "decodeHTMLStrict", ({ enumerable: true, get: function () { return decode_2.decodeHTMLStrict; } }));
@@ -43218,7 +43289,7 @@ Object.defineProperty(exports, "decodeXMLStrict", ({ enumerable: true, get: func
 
 
 /***/ }),
-/* 273 */
+/* 274 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -43228,10 +43299,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.decodeHTML = exports.decodeHTMLStrict = exports.decodeXML = void 0;
-var entities_json_1 = __importDefault(__webpack_require__(274));
-var legacy_json_1 = __importDefault(__webpack_require__(275));
-var xml_json_1 = __importDefault(__webpack_require__(276));
-var decode_codepoint_1 = __importDefault(__webpack_require__(277));
+var entities_json_1 = __importDefault(__webpack_require__(275));
+var legacy_json_1 = __importDefault(__webpack_require__(276));
+var xml_json_1 = __importDefault(__webpack_require__(277));
+var decode_codepoint_1 = __importDefault(__webpack_require__(278));
 var strictEntityRe = /&(?:[a-zA-Z0-9]+|#[xX][\da-fA-F]+|#\d+);/g;
 exports.decodeXML = getStrictDecoder(xml_json_1.default);
 exports.decodeHTMLStrict = getStrictDecoder(entities_json_1.default);
@@ -43278,28 +43349,28 @@ function getReplacer(map) {
 
 
 /***/ }),
-/* 274 */
+/* 275 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"Aacute":"Á","aacute":"á","Abreve":"Ă","abreve":"ă","ac":"∾","acd":"∿","acE":"∾̳","Acirc":"Â","acirc":"â","acute":"´","Acy":"А","acy":"а","AElig":"Æ","aelig":"æ","af":"⁡","Afr":"𝔄","afr":"𝔞","Agrave":"À","agrave":"à","alefsym":"ℵ","aleph":"ℵ","Alpha":"Α","alpha":"α","Amacr":"Ā","amacr":"ā","amalg":"⨿","amp":"&","AMP":"&","andand":"⩕","And":"⩓","and":"∧","andd":"⩜","andslope":"⩘","andv":"⩚","ang":"∠","ange":"⦤","angle":"∠","angmsdaa":"⦨","angmsdab":"⦩","angmsdac":"⦪","angmsdad":"⦫","angmsdae":"⦬","angmsdaf":"⦭","angmsdag":"⦮","angmsdah":"⦯","angmsd":"∡","angrt":"∟","angrtvb":"⊾","angrtvbd":"⦝","angsph":"∢","angst":"Å","angzarr":"⍼","Aogon":"Ą","aogon":"ą","Aopf":"𝔸","aopf":"𝕒","apacir":"⩯","ap":"≈","apE":"⩰","ape":"≊","apid":"≋","apos":"\'","ApplyFunction":"⁡","approx":"≈","approxeq":"≊","Aring":"Å","aring":"å","Ascr":"𝒜","ascr":"𝒶","Assign":"≔","ast":"*","asymp":"≈","asympeq":"≍","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","awconint":"∳","awint":"⨑","backcong":"≌","backepsilon":"϶","backprime":"‵","backsim":"∽","backsimeq":"⋍","Backslash":"∖","Barv":"⫧","barvee":"⊽","barwed":"⌅","Barwed":"⌆","barwedge":"⌅","bbrk":"⎵","bbrktbrk":"⎶","bcong":"≌","Bcy":"Б","bcy":"б","bdquo":"„","becaus":"∵","because":"∵","Because":"∵","bemptyv":"⦰","bepsi":"϶","bernou":"ℬ","Bernoullis":"ℬ","Beta":"Β","beta":"β","beth":"ℶ","between":"≬","Bfr":"𝔅","bfr":"𝔟","bigcap":"⋂","bigcirc":"◯","bigcup":"⋃","bigodot":"⨀","bigoplus":"⨁","bigotimes":"⨂","bigsqcup":"⨆","bigstar":"★","bigtriangledown":"▽","bigtriangleup":"△","biguplus":"⨄","bigvee":"⋁","bigwedge":"⋀","bkarow":"⤍","blacklozenge":"⧫","blacksquare":"▪","blacktriangle":"▴","blacktriangledown":"▾","blacktriangleleft":"◂","blacktriangleright":"▸","blank":"␣","blk12":"▒","blk14":"░","blk34":"▓","block":"█","bne":"=⃥","bnequiv":"≡⃥","bNot":"⫭","bnot":"⌐","Bopf":"𝔹","bopf":"𝕓","bot":"⊥","bottom":"⊥","bowtie":"⋈","boxbox":"⧉","boxdl":"┐","boxdL":"╕","boxDl":"╖","boxDL":"╗","boxdr":"┌","boxdR":"╒","boxDr":"╓","boxDR":"╔","boxh":"─","boxH":"═","boxhd":"┬","boxHd":"╤","boxhD":"╥","boxHD":"╦","boxhu":"┴","boxHu":"╧","boxhU":"╨","boxHU":"╩","boxminus":"⊟","boxplus":"⊞","boxtimes":"⊠","boxul":"┘","boxuL":"╛","boxUl":"╜","boxUL":"╝","boxur":"└","boxuR":"╘","boxUr":"╙","boxUR":"╚","boxv":"│","boxV":"║","boxvh":"┼","boxvH":"╪","boxVh":"╫","boxVH":"╬","boxvl":"┤","boxvL":"╡","boxVl":"╢","boxVL":"╣","boxvr":"├","boxvR":"╞","boxVr":"╟","boxVR":"╠","bprime":"‵","breve":"˘","Breve":"˘","brvbar":"¦","bscr":"𝒷","Bscr":"ℬ","bsemi":"⁏","bsim":"∽","bsime":"⋍","bsolb":"⧅","bsol":"\\\\","bsolhsub":"⟈","bull":"•","bullet":"•","bump":"≎","bumpE":"⪮","bumpe":"≏","Bumpeq":"≎","bumpeq":"≏","Cacute":"Ć","cacute":"ć","capand":"⩄","capbrcup":"⩉","capcap":"⩋","cap":"∩","Cap":"⋒","capcup":"⩇","capdot":"⩀","CapitalDifferentialD":"ⅅ","caps":"∩︀","caret":"⁁","caron":"ˇ","Cayleys":"ℭ","ccaps":"⩍","Ccaron":"Č","ccaron":"č","Ccedil":"Ç","ccedil":"ç","Ccirc":"Ĉ","ccirc":"ĉ","Cconint":"∰","ccups":"⩌","ccupssm":"⩐","Cdot":"Ċ","cdot":"ċ","cedil":"¸","Cedilla":"¸","cemptyv":"⦲","cent":"¢","centerdot":"·","CenterDot":"·","cfr":"𝔠","Cfr":"ℭ","CHcy":"Ч","chcy":"ч","check":"✓","checkmark":"✓","Chi":"Χ","chi":"χ","circ":"ˆ","circeq":"≗","circlearrowleft":"↺","circlearrowright":"↻","circledast":"⊛","circledcirc":"⊚","circleddash":"⊝","CircleDot":"⊙","circledR":"®","circledS":"Ⓢ","CircleMinus":"⊖","CirclePlus":"⊕","CircleTimes":"⊗","cir":"○","cirE":"⧃","cire":"≗","cirfnint":"⨐","cirmid":"⫯","cirscir":"⧂","ClockwiseContourIntegral":"∲","CloseCurlyDoubleQuote":"”","CloseCurlyQuote":"’","clubs":"♣","clubsuit":"♣","colon":":","Colon":"∷","Colone":"⩴","colone":"≔","coloneq":"≔","comma":",","commat":"@","comp":"∁","compfn":"∘","complement":"∁","complexes":"ℂ","cong":"≅","congdot":"⩭","Congruent":"≡","conint":"∮","Conint":"∯","ContourIntegral":"∮","copf":"𝕔","Copf":"ℂ","coprod":"∐","Coproduct":"∐","copy":"©","COPY":"©","copysr":"℗","CounterClockwiseContourIntegral":"∳","crarr":"↵","cross":"✗","Cross":"⨯","Cscr":"𝒞","cscr":"𝒸","csub":"⫏","csube":"⫑","csup":"⫐","csupe":"⫒","ctdot":"⋯","cudarrl":"⤸","cudarrr":"⤵","cuepr":"⋞","cuesc":"⋟","cularr":"↶","cularrp":"⤽","cupbrcap":"⩈","cupcap":"⩆","CupCap":"≍","cup":"∪","Cup":"⋓","cupcup":"⩊","cupdot":"⊍","cupor":"⩅","cups":"∪︀","curarr":"↷","curarrm":"⤼","curlyeqprec":"⋞","curlyeqsucc":"⋟","curlyvee":"⋎","curlywedge":"⋏","curren":"¤","curvearrowleft":"↶","curvearrowright":"↷","cuvee":"⋎","cuwed":"⋏","cwconint":"∲","cwint":"∱","cylcty":"⌭","dagger":"†","Dagger":"‡","daleth":"ℸ","darr":"↓","Darr":"↡","dArr":"⇓","dash":"‐","Dashv":"⫤","dashv":"⊣","dbkarow":"⤏","dblac":"˝","Dcaron":"Ď","dcaron":"ď","Dcy":"Д","dcy":"д","ddagger":"‡","ddarr":"⇊","DD":"ⅅ","dd":"ⅆ","DDotrahd":"⤑","ddotseq":"⩷","deg":"°","Del":"∇","Delta":"Δ","delta":"δ","demptyv":"⦱","dfisht":"⥿","Dfr":"𝔇","dfr":"𝔡","dHar":"⥥","dharl":"⇃","dharr":"⇂","DiacriticalAcute":"´","DiacriticalDot":"˙","DiacriticalDoubleAcute":"˝","DiacriticalGrave":"`","DiacriticalTilde":"˜","diam":"⋄","diamond":"⋄","Diamond":"⋄","diamondsuit":"♦","diams":"♦","die":"¨","DifferentialD":"ⅆ","digamma":"ϝ","disin":"⋲","div":"÷","divide":"÷","divideontimes":"⋇","divonx":"⋇","DJcy":"Ђ","djcy":"ђ","dlcorn":"⌞","dlcrop":"⌍","dollar":"$","Dopf":"𝔻","dopf":"𝕕","Dot":"¨","dot":"˙","DotDot":"⃜","doteq":"≐","doteqdot":"≑","DotEqual":"≐","dotminus":"∸","dotplus":"∔","dotsquare":"⊡","doublebarwedge":"⌆","DoubleContourIntegral":"∯","DoubleDot":"¨","DoubleDownArrow":"⇓","DoubleLeftArrow":"⇐","DoubleLeftRightArrow":"⇔","DoubleLeftTee":"⫤","DoubleLongLeftArrow":"⟸","DoubleLongLeftRightArrow":"⟺","DoubleLongRightArrow":"⟹","DoubleRightArrow":"⇒","DoubleRightTee":"⊨","DoubleUpArrow":"⇑","DoubleUpDownArrow":"⇕","DoubleVerticalBar":"∥","DownArrowBar":"⤓","downarrow":"↓","DownArrow":"↓","Downarrow":"⇓","DownArrowUpArrow":"⇵","DownBreve":"̑","downdownarrows":"⇊","downharpoonleft":"⇃","downharpoonright":"⇂","DownLeftRightVector":"⥐","DownLeftTeeVector":"⥞","DownLeftVectorBar":"⥖","DownLeftVector":"↽","DownRightTeeVector":"⥟","DownRightVectorBar":"⥗","DownRightVector":"⇁","DownTeeArrow":"↧","DownTee":"⊤","drbkarow":"⤐","drcorn":"⌟","drcrop":"⌌","Dscr":"𝒟","dscr":"𝒹","DScy":"Ѕ","dscy":"ѕ","dsol":"⧶","Dstrok":"Đ","dstrok":"đ","dtdot":"⋱","dtri":"▿","dtrif":"▾","duarr":"⇵","duhar":"⥯","dwangle":"⦦","DZcy":"Џ","dzcy":"џ","dzigrarr":"⟿","Eacute":"É","eacute":"é","easter":"⩮","Ecaron":"Ě","ecaron":"ě","Ecirc":"Ê","ecirc":"ê","ecir":"≖","ecolon":"≕","Ecy":"Э","ecy":"э","eDDot":"⩷","Edot":"Ė","edot":"ė","eDot":"≑","ee":"ⅇ","efDot":"≒","Efr":"𝔈","efr":"𝔢","eg":"⪚","Egrave":"È","egrave":"è","egs":"⪖","egsdot":"⪘","el":"⪙","Element":"∈","elinters":"⏧","ell":"ℓ","els":"⪕","elsdot":"⪗","Emacr":"Ē","emacr":"ē","empty":"∅","emptyset":"∅","EmptySmallSquare":"◻","emptyv":"∅","EmptyVerySmallSquare":"▫","emsp13":" ","emsp14":" ","emsp":" ","ENG":"Ŋ","eng":"ŋ","ensp":" ","Eogon":"Ę","eogon":"ę","Eopf":"𝔼","eopf":"𝕖","epar":"⋕","eparsl":"⧣","eplus":"⩱","epsi":"ε","Epsilon":"Ε","epsilon":"ε","epsiv":"ϵ","eqcirc":"≖","eqcolon":"≕","eqsim":"≂","eqslantgtr":"⪖","eqslantless":"⪕","Equal":"⩵","equals":"=","EqualTilde":"≂","equest":"≟","Equilibrium":"⇌","equiv":"≡","equivDD":"⩸","eqvparsl":"⧥","erarr":"⥱","erDot":"≓","escr":"ℯ","Escr":"ℰ","esdot":"≐","Esim":"⩳","esim":"≂","Eta":"Η","eta":"η","ETH":"Ð","eth":"ð","Euml":"Ë","euml":"ë","euro":"€","excl":"!","exist":"∃","Exists":"∃","expectation":"ℰ","exponentiale":"ⅇ","ExponentialE":"ⅇ","fallingdotseq":"≒","Fcy":"Ф","fcy":"ф","female":"♀","ffilig":"ffi","fflig":"ff","ffllig":"ffl","Ffr":"𝔉","ffr":"𝔣","filig":"fi","FilledSmallSquare":"◼","FilledVerySmallSquare":"▪","fjlig":"fj","flat":"♭","fllig":"fl","fltns":"▱","fnof":"ƒ","Fopf":"𝔽","fopf":"𝕗","forall":"∀","ForAll":"∀","fork":"⋔","forkv":"⫙","Fouriertrf":"ℱ","fpartint":"⨍","frac12":"½","frac13":"⅓","frac14":"¼","frac15":"⅕","frac16":"⅙","frac18":"⅛","frac23":"⅔","frac25":"⅖","frac34":"¾","frac35":"⅗","frac38":"⅜","frac45":"⅘","frac56":"⅚","frac58":"⅝","frac78":"⅞","frasl":"⁄","frown":"⌢","fscr":"𝒻","Fscr":"ℱ","gacute":"ǵ","Gamma":"Γ","gamma":"γ","Gammad":"Ϝ","gammad":"ϝ","gap":"⪆","Gbreve":"Ğ","gbreve":"ğ","Gcedil":"Ģ","Gcirc":"Ĝ","gcirc":"ĝ","Gcy":"Г","gcy":"г","Gdot":"Ġ","gdot":"ġ","ge":"≥","gE":"≧","gEl":"⪌","gel":"⋛","geq":"≥","geqq":"≧","geqslant":"⩾","gescc":"⪩","ges":"⩾","gesdot":"⪀","gesdoto":"⪂","gesdotol":"⪄","gesl":"⋛︀","gesles":"⪔","Gfr":"𝔊","gfr":"𝔤","gg":"≫","Gg":"⋙","ggg":"⋙","gimel":"ℷ","GJcy":"Ѓ","gjcy":"ѓ","gla":"⪥","gl":"≷","glE":"⪒","glj":"⪤","gnap":"⪊","gnapprox":"⪊","gne":"⪈","gnE":"≩","gneq":"⪈","gneqq":"≩","gnsim":"⋧","Gopf":"𝔾","gopf":"𝕘","grave":"`","GreaterEqual":"≥","GreaterEqualLess":"⋛","GreaterFullEqual":"≧","GreaterGreater":"⪢","GreaterLess":"≷","GreaterSlantEqual":"⩾","GreaterTilde":"≳","Gscr":"𝒢","gscr":"ℊ","gsim":"≳","gsime":"⪎","gsiml":"⪐","gtcc":"⪧","gtcir":"⩺","gt":">","GT":">","Gt":"≫","gtdot":"⋗","gtlPar":"⦕","gtquest":"⩼","gtrapprox":"⪆","gtrarr":"⥸","gtrdot":"⋗","gtreqless":"⋛","gtreqqless":"⪌","gtrless":"≷","gtrsim":"≳","gvertneqq":"≩︀","gvnE":"≩︀","Hacek":"ˇ","hairsp":" ","half":"½","hamilt":"ℋ","HARDcy":"Ъ","hardcy":"ъ","harrcir":"⥈","harr":"↔","hArr":"⇔","harrw":"↭","Hat":"^","hbar":"ℏ","Hcirc":"Ĥ","hcirc":"ĥ","hearts":"♥","heartsuit":"♥","hellip":"…","hercon":"⊹","hfr":"𝔥","Hfr":"ℌ","HilbertSpace":"ℋ","hksearow":"⤥","hkswarow":"⤦","hoarr":"⇿","homtht":"∻","hookleftarrow":"↩","hookrightarrow":"↪","hopf":"𝕙","Hopf":"ℍ","horbar":"―","HorizontalLine":"─","hscr":"𝒽","Hscr":"ℋ","hslash":"ℏ","Hstrok":"Ħ","hstrok":"ħ","HumpDownHump":"≎","HumpEqual":"≏","hybull":"⁃","hyphen":"‐","Iacute":"Í","iacute":"í","ic":"⁣","Icirc":"Î","icirc":"î","Icy":"И","icy":"и","Idot":"İ","IEcy":"Е","iecy":"е","iexcl":"¡","iff":"⇔","ifr":"𝔦","Ifr":"ℑ","Igrave":"Ì","igrave":"ì","ii":"ⅈ","iiiint":"⨌","iiint":"∭","iinfin":"⧜","iiota":"℩","IJlig":"IJ","ijlig":"ij","Imacr":"Ī","imacr":"ī","image":"ℑ","ImaginaryI":"ⅈ","imagline":"ℐ","imagpart":"ℑ","imath":"ı","Im":"ℑ","imof":"⊷","imped":"Ƶ","Implies":"⇒","incare":"℅","in":"∈","infin":"∞","infintie":"⧝","inodot":"ı","intcal":"⊺","int":"∫","Int":"∬","integers":"ℤ","Integral":"∫","intercal":"⊺","Intersection":"⋂","intlarhk":"⨗","intprod":"⨼","InvisibleComma":"⁣","InvisibleTimes":"⁢","IOcy":"Ё","iocy":"ё","Iogon":"Į","iogon":"į","Iopf":"𝕀","iopf":"𝕚","Iota":"Ι","iota":"ι","iprod":"⨼","iquest":"¿","iscr":"𝒾","Iscr":"ℐ","isin":"∈","isindot":"⋵","isinE":"⋹","isins":"⋴","isinsv":"⋳","isinv":"∈","it":"⁢","Itilde":"Ĩ","itilde":"ĩ","Iukcy":"І","iukcy":"і","Iuml":"Ï","iuml":"ï","Jcirc":"Ĵ","jcirc":"ĵ","Jcy":"Й","jcy":"й","Jfr":"𝔍","jfr":"𝔧","jmath":"ȷ","Jopf":"𝕁","jopf":"𝕛","Jscr":"𝒥","jscr":"𝒿","Jsercy":"Ј","jsercy":"ј","Jukcy":"Є","jukcy":"є","Kappa":"Κ","kappa":"κ","kappav":"ϰ","Kcedil":"Ķ","kcedil":"ķ","Kcy":"К","kcy":"к","Kfr":"𝔎","kfr":"𝔨","kgreen":"ĸ","KHcy":"Х","khcy":"х","KJcy":"Ќ","kjcy":"ќ","Kopf":"𝕂","kopf":"𝕜","Kscr":"𝒦","kscr":"𝓀","lAarr":"⇚","Lacute":"Ĺ","lacute":"ĺ","laemptyv":"⦴","lagran":"ℒ","Lambda":"Λ","lambda":"λ","lang":"⟨","Lang":"⟪","langd":"⦑","langle":"⟨","lap":"⪅","Laplacetrf":"ℒ","laquo":"«","larrb":"⇤","larrbfs":"⤟","larr":"←","Larr":"↞","lArr":"⇐","larrfs":"⤝","larrhk":"↩","larrlp":"↫","larrpl":"⤹","larrsim":"⥳","larrtl":"↢","latail":"⤙","lAtail":"⤛","lat":"⪫","late":"⪭","lates":"⪭︀","lbarr":"⤌","lBarr":"⤎","lbbrk":"❲","lbrace":"{","lbrack":"[","lbrke":"⦋","lbrksld":"⦏","lbrkslu":"⦍","Lcaron":"Ľ","lcaron":"ľ","Lcedil":"Ļ","lcedil":"ļ","lceil":"⌈","lcub":"{","Lcy":"Л","lcy":"л","ldca":"⤶","ldquo":"“","ldquor":"„","ldrdhar":"⥧","ldrushar":"⥋","ldsh":"↲","le":"≤","lE":"≦","LeftAngleBracket":"⟨","LeftArrowBar":"⇤","leftarrow":"←","LeftArrow":"←","Leftarrow":"⇐","LeftArrowRightArrow":"⇆","leftarrowtail":"↢","LeftCeiling":"⌈","LeftDoubleBracket":"⟦","LeftDownTeeVector":"⥡","LeftDownVectorBar":"⥙","LeftDownVector":"⇃","LeftFloor":"⌊","leftharpoondown":"↽","leftharpoonup":"↼","leftleftarrows":"⇇","leftrightarrow":"↔","LeftRightArrow":"↔","Leftrightarrow":"⇔","leftrightarrows":"⇆","leftrightharpoons":"⇋","leftrightsquigarrow":"↭","LeftRightVector":"⥎","LeftTeeArrow":"↤","LeftTee":"⊣","LeftTeeVector":"⥚","leftthreetimes":"⋋","LeftTriangleBar":"⧏","LeftTriangle":"⊲","LeftTriangleEqual":"⊴","LeftUpDownVector":"⥑","LeftUpTeeVector":"⥠","LeftUpVectorBar":"⥘","LeftUpVector":"↿","LeftVectorBar":"⥒","LeftVector":"↼","lEg":"⪋","leg":"⋚","leq":"≤","leqq":"≦","leqslant":"⩽","lescc":"⪨","les":"⩽","lesdot":"⩿","lesdoto":"⪁","lesdotor":"⪃","lesg":"⋚︀","lesges":"⪓","lessapprox":"⪅","lessdot":"⋖","lesseqgtr":"⋚","lesseqqgtr":"⪋","LessEqualGreater":"⋚","LessFullEqual":"≦","LessGreater":"≶","lessgtr":"≶","LessLess":"⪡","lesssim":"≲","LessSlantEqual":"⩽","LessTilde":"≲","lfisht":"⥼","lfloor":"⌊","Lfr":"𝔏","lfr":"𝔩","lg":"≶","lgE":"⪑","lHar":"⥢","lhard":"↽","lharu":"↼","lharul":"⥪","lhblk":"▄","LJcy":"Љ","ljcy":"љ","llarr":"⇇","ll":"≪","Ll":"⋘","llcorner":"⌞","Lleftarrow":"⇚","llhard":"⥫","lltri":"◺","Lmidot":"Ŀ","lmidot":"ŀ","lmoustache":"⎰","lmoust":"⎰","lnap":"⪉","lnapprox":"⪉","lne":"⪇","lnE":"≨","lneq":"⪇","lneqq":"≨","lnsim":"⋦","loang":"⟬","loarr":"⇽","lobrk":"⟦","longleftarrow":"⟵","LongLeftArrow":"⟵","Longleftarrow":"⟸","longleftrightarrow":"⟷","LongLeftRightArrow":"⟷","Longleftrightarrow":"⟺","longmapsto":"⟼","longrightarrow":"⟶","LongRightArrow":"⟶","Longrightarrow":"⟹","looparrowleft":"↫","looparrowright":"↬","lopar":"⦅","Lopf":"𝕃","lopf":"𝕝","loplus":"⨭","lotimes":"⨴","lowast":"∗","lowbar":"_","LowerLeftArrow":"↙","LowerRightArrow":"↘","loz":"◊","lozenge":"◊","lozf":"⧫","lpar":"(","lparlt":"⦓","lrarr":"⇆","lrcorner":"⌟","lrhar":"⇋","lrhard":"⥭","lrm":"‎","lrtri":"⊿","lsaquo":"‹","lscr":"𝓁","Lscr":"ℒ","lsh":"↰","Lsh":"↰","lsim":"≲","lsime":"⪍","lsimg":"⪏","lsqb":"[","lsquo":"‘","lsquor":"‚","Lstrok":"Ł","lstrok":"ł","ltcc":"⪦","ltcir":"⩹","lt":"<","LT":"<","Lt":"≪","ltdot":"⋖","lthree":"⋋","ltimes":"⋉","ltlarr":"⥶","ltquest":"⩻","ltri":"◃","ltrie":"⊴","ltrif":"◂","ltrPar":"⦖","lurdshar":"⥊","luruhar":"⥦","lvertneqq":"≨︀","lvnE":"≨︀","macr":"¯","male":"♂","malt":"✠","maltese":"✠","Map":"⤅","map":"↦","mapsto":"↦","mapstodown":"↧","mapstoleft":"↤","mapstoup":"↥","marker":"▮","mcomma":"⨩","Mcy":"М","mcy":"м","mdash":"—","mDDot":"∺","measuredangle":"∡","MediumSpace":" ","Mellintrf":"ℳ","Mfr":"𝔐","mfr":"𝔪","mho":"℧","micro":"µ","midast":"*","midcir":"⫰","mid":"∣","middot":"·","minusb":"⊟","minus":"−","minusd":"∸","minusdu":"⨪","MinusPlus":"∓","mlcp":"⫛","mldr":"…","mnplus":"∓","models":"⊧","Mopf":"𝕄","mopf":"𝕞","mp":"∓","mscr":"𝓂","Mscr":"ℳ","mstpos":"∾","Mu":"Μ","mu":"μ","multimap":"⊸","mumap":"⊸","nabla":"∇","Nacute":"Ń","nacute":"ń","nang":"∠⃒","nap":"≉","napE":"⩰̸","napid":"≋̸","napos":"ʼn","napprox":"≉","natural":"♮","naturals":"ℕ","natur":"♮","nbsp":" ","nbump":"≎̸","nbumpe":"≏̸","ncap":"⩃","Ncaron":"Ň","ncaron":"ň","Ncedil":"Ņ","ncedil":"ņ","ncong":"≇","ncongdot":"⩭̸","ncup":"⩂","Ncy":"Н","ncy":"н","ndash":"–","nearhk":"⤤","nearr":"↗","neArr":"⇗","nearrow":"↗","ne":"≠","nedot":"≐̸","NegativeMediumSpace":"​","NegativeThickSpace":"​","NegativeThinSpace":"​","NegativeVeryThinSpace":"​","nequiv":"≢","nesear":"⤨","nesim":"≂̸","NestedGreaterGreater":"≫","NestedLessLess":"≪","NewLine":"\\n","nexist":"∄","nexists":"∄","Nfr":"𝔑","nfr":"𝔫","ngE":"≧̸","nge":"≱","ngeq":"≱","ngeqq":"≧̸","ngeqslant":"⩾̸","nges":"⩾̸","nGg":"⋙̸","ngsim":"≵","nGt":"≫⃒","ngt":"≯","ngtr":"≯","nGtv":"≫̸","nharr":"↮","nhArr":"⇎","nhpar":"⫲","ni":"∋","nis":"⋼","nisd":"⋺","niv":"∋","NJcy":"Њ","njcy":"њ","nlarr":"↚","nlArr":"⇍","nldr":"‥","nlE":"≦̸","nle":"≰","nleftarrow":"↚","nLeftarrow":"⇍","nleftrightarrow":"↮","nLeftrightarrow":"⇎","nleq":"≰","nleqq":"≦̸","nleqslant":"⩽̸","nles":"⩽̸","nless":"≮","nLl":"⋘̸","nlsim":"≴","nLt":"≪⃒","nlt":"≮","nltri":"⋪","nltrie":"⋬","nLtv":"≪̸","nmid":"∤","NoBreak":"⁠","NonBreakingSpace":" ","nopf":"𝕟","Nopf":"ℕ","Not":"⫬","not":"¬","NotCongruent":"≢","NotCupCap":"≭","NotDoubleVerticalBar":"∦","NotElement":"∉","NotEqual":"≠","NotEqualTilde":"≂̸","NotExists":"∄","NotGreater":"≯","NotGreaterEqual":"≱","NotGreaterFullEqual":"≧̸","NotGreaterGreater":"≫̸","NotGreaterLess":"≹","NotGreaterSlantEqual":"⩾̸","NotGreaterTilde":"≵","NotHumpDownHump":"≎̸","NotHumpEqual":"≏̸","notin":"∉","notindot":"⋵̸","notinE":"⋹̸","notinva":"∉","notinvb":"⋷","notinvc":"⋶","NotLeftTriangleBar":"⧏̸","NotLeftTriangle":"⋪","NotLeftTriangleEqual":"⋬","NotLess":"≮","NotLessEqual":"≰","NotLessGreater":"≸","NotLessLess":"≪̸","NotLessSlantEqual":"⩽̸","NotLessTilde":"≴","NotNestedGreaterGreater":"⪢̸","NotNestedLessLess":"⪡̸","notni":"∌","notniva":"∌","notnivb":"⋾","notnivc":"⋽","NotPrecedes":"⊀","NotPrecedesEqual":"⪯̸","NotPrecedesSlantEqual":"⋠","NotReverseElement":"∌","NotRightTriangleBar":"⧐̸","NotRightTriangle":"⋫","NotRightTriangleEqual":"⋭","NotSquareSubset":"⊏̸","NotSquareSubsetEqual":"⋢","NotSquareSuperset":"⊐̸","NotSquareSupersetEqual":"⋣","NotSubset":"⊂⃒","NotSubsetEqual":"⊈","NotSucceeds":"⊁","NotSucceedsEqual":"⪰̸","NotSucceedsSlantEqual":"⋡","NotSucceedsTilde":"≿̸","NotSuperset":"⊃⃒","NotSupersetEqual":"⊉","NotTilde":"≁","NotTildeEqual":"≄","NotTildeFullEqual":"≇","NotTildeTilde":"≉","NotVerticalBar":"∤","nparallel":"∦","npar":"∦","nparsl":"⫽⃥","npart":"∂̸","npolint":"⨔","npr":"⊀","nprcue":"⋠","nprec":"⊀","npreceq":"⪯̸","npre":"⪯̸","nrarrc":"⤳̸","nrarr":"↛","nrArr":"⇏","nrarrw":"↝̸","nrightarrow":"↛","nRightarrow":"⇏","nrtri":"⋫","nrtrie":"⋭","nsc":"⊁","nsccue":"⋡","nsce":"⪰̸","Nscr":"𝒩","nscr":"𝓃","nshortmid":"∤","nshortparallel":"∦","nsim":"≁","nsime":"≄","nsimeq":"≄","nsmid":"∤","nspar":"∦","nsqsube":"⋢","nsqsupe":"⋣","nsub":"⊄","nsubE":"⫅̸","nsube":"⊈","nsubset":"⊂⃒","nsubseteq":"⊈","nsubseteqq":"⫅̸","nsucc":"⊁","nsucceq":"⪰̸","nsup":"⊅","nsupE":"⫆̸","nsupe":"⊉","nsupset":"⊃⃒","nsupseteq":"⊉","nsupseteqq":"⫆̸","ntgl":"≹","Ntilde":"Ñ","ntilde":"ñ","ntlg":"≸","ntriangleleft":"⋪","ntrianglelefteq":"⋬","ntriangleright":"⋫","ntrianglerighteq":"⋭","Nu":"Ν","nu":"ν","num":"#","numero":"№","numsp":" ","nvap":"≍⃒","nvdash":"⊬","nvDash":"⊭","nVdash":"⊮","nVDash":"⊯","nvge":"≥⃒","nvgt":">⃒","nvHarr":"⤄","nvinfin":"⧞","nvlArr":"⤂","nvle":"≤⃒","nvlt":"<⃒","nvltrie":"⊴⃒","nvrArr":"⤃","nvrtrie":"⊵⃒","nvsim":"∼⃒","nwarhk":"⤣","nwarr":"↖","nwArr":"⇖","nwarrow":"↖","nwnear":"⤧","Oacute":"Ó","oacute":"ó","oast":"⊛","Ocirc":"Ô","ocirc":"ô","ocir":"⊚","Ocy":"О","ocy":"о","odash":"⊝","Odblac":"Ő","odblac":"ő","odiv":"⨸","odot":"⊙","odsold":"⦼","OElig":"Œ","oelig":"œ","ofcir":"⦿","Ofr":"𝔒","ofr":"𝔬","ogon":"˛","Ograve":"Ò","ograve":"ò","ogt":"⧁","ohbar":"⦵","ohm":"Ω","oint":"∮","olarr":"↺","olcir":"⦾","olcross":"⦻","oline":"‾","olt":"⧀","Omacr":"Ō","omacr":"ō","Omega":"Ω","omega":"ω","Omicron":"Ο","omicron":"ο","omid":"⦶","ominus":"⊖","Oopf":"𝕆","oopf":"𝕠","opar":"⦷","OpenCurlyDoubleQuote":"“","OpenCurlyQuote":"‘","operp":"⦹","oplus":"⊕","orarr":"↻","Or":"⩔","or":"∨","ord":"⩝","order":"ℴ","orderof":"ℴ","ordf":"ª","ordm":"º","origof":"⊶","oror":"⩖","orslope":"⩗","orv":"⩛","oS":"Ⓢ","Oscr":"𝒪","oscr":"ℴ","Oslash":"Ø","oslash":"ø","osol":"⊘","Otilde":"Õ","otilde":"õ","otimesas":"⨶","Otimes":"⨷","otimes":"⊗","Ouml":"Ö","ouml":"ö","ovbar":"⌽","OverBar":"‾","OverBrace":"⏞","OverBracket":"⎴","OverParenthesis":"⏜","para":"¶","parallel":"∥","par":"∥","parsim":"⫳","parsl":"⫽","part":"∂","PartialD":"∂","Pcy":"П","pcy":"п","percnt":"%","period":".","permil":"‰","perp":"⊥","pertenk":"‱","Pfr":"𝔓","pfr":"𝔭","Phi":"Φ","phi":"φ","phiv":"ϕ","phmmat":"ℳ","phone":"☎","Pi":"Π","pi":"π","pitchfork":"⋔","piv":"ϖ","planck":"ℏ","planckh":"ℎ","plankv":"ℏ","plusacir":"⨣","plusb":"⊞","pluscir":"⨢","plus":"+","plusdo":"∔","plusdu":"⨥","pluse":"⩲","PlusMinus":"±","plusmn":"±","plussim":"⨦","plustwo":"⨧","pm":"±","Poincareplane":"ℌ","pointint":"⨕","popf":"𝕡","Popf":"ℙ","pound":"£","prap":"⪷","Pr":"⪻","pr":"≺","prcue":"≼","precapprox":"⪷","prec":"≺","preccurlyeq":"≼","Precedes":"≺","PrecedesEqual":"⪯","PrecedesSlantEqual":"≼","PrecedesTilde":"≾","preceq":"⪯","precnapprox":"⪹","precneqq":"⪵","precnsim":"⋨","pre":"⪯","prE":"⪳","precsim":"≾","prime":"′","Prime":"″","primes":"ℙ","prnap":"⪹","prnE":"⪵","prnsim":"⋨","prod":"∏","Product":"∏","profalar":"⌮","profline":"⌒","profsurf":"⌓","prop":"∝","Proportional":"∝","Proportion":"∷","propto":"∝","prsim":"≾","prurel":"⊰","Pscr":"𝒫","pscr":"𝓅","Psi":"Ψ","psi":"ψ","puncsp":" ","Qfr":"𝔔","qfr":"𝔮","qint":"⨌","qopf":"𝕢","Qopf":"ℚ","qprime":"⁗","Qscr":"𝒬","qscr":"𝓆","quaternions":"ℍ","quatint":"⨖","quest":"?","questeq":"≟","quot":"\\"","QUOT":"\\"","rAarr":"⇛","race":"∽̱","Racute":"Ŕ","racute":"ŕ","radic":"√","raemptyv":"⦳","rang":"⟩","Rang":"⟫","rangd":"⦒","range":"⦥","rangle":"⟩","raquo":"»","rarrap":"⥵","rarrb":"⇥","rarrbfs":"⤠","rarrc":"⤳","rarr":"→","Rarr":"↠","rArr":"⇒","rarrfs":"⤞","rarrhk":"↪","rarrlp":"↬","rarrpl":"⥅","rarrsim":"⥴","Rarrtl":"⤖","rarrtl":"↣","rarrw":"↝","ratail":"⤚","rAtail":"⤜","ratio":"∶","rationals":"ℚ","rbarr":"⤍","rBarr":"⤏","RBarr":"⤐","rbbrk":"❳","rbrace":"}","rbrack":"]","rbrke":"⦌","rbrksld":"⦎","rbrkslu":"⦐","Rcaron":"Ř","rcaron":"ř","Rcedil":"Ŗ","rcedil":"ŗ","rceil":"⌉","rcub":"}","Rcy":"Р","rcy":"р","rdca":"⤷","rdldhar":"⥩","rdquo":"”","rdquor":"”","rdsh":"↳","real":"ℜ","realine":"ℛ","realpart":"ℜ","reals":"ℝ","Re":"ℜ","rect":"▭","reg":"®","REG":"®","ReverseElement":"∋","ReverseEquilibrium":"⇋","ReverseUpEquilibrium":"⥯","rfisht":"⥽","rfloor":"⌋","rfr":"𝔯","Rfr":"ℜ","rHar":"⥤","rhard":"⇁","rharu":"⇀","rharul":"⥬","Rho":"Ρ","rho":"ρ","rhov":"ϱ","RightAngleBracket":"⟩","RightArrowBar":"⇥","rightarrow":"→","RightArrow":"→","Rightarrow":"⇒","RightArrowLeftArrow":"⇄","rightarrowtail":"↣","RightCeiling":"⌉","RightDoubleBracket":"⟧","RightDownTeeVector":"⥝","RightDownVectorBar":"⥕","RightDownVector":"⇂","RightFloor":"⌋","rightharpoondown":"⇁","rightharpoonup":"⇀","rightleftarrows":"⇄","rightleftharpoons":"⇌","rightrightarrows":"⇉","rightsquigarrow":"↝","RightTeeArrow":"↦","RightTee":"⊢","RightTeeVector":"⥛","rightthreetimes":"⋌","RightTriangleBar":"⧐","RightTriangle":"⊳","RightTriangleEqual":"⊵","RightUpDownVector":"⥏","RightUpTeeVector":"⥜","RightUpVectorBar":"⥔","RightUpVector":"↾","RightVectorBar":"⥓","RightVector":"⇀","ring":"˚","risingdotseq":"≓","rlarr":"⇄","rlhar":"⇌","rlm":"‏","rmoustache":"⎱","rmoust":"⎱","rnmid":"⫮","roang":"⟭","roarr":"⇾","robrk":"⟧","ropar":"⦆","ropf":"𝕣","Ropf":"ℝ","roplus":"⨮","rotimes":"⨵","RoundImplies":"⥰","rpar":")","rpargt":"⦔","rppolint":"⨒","rrarr":"⇉","Rrightarrow":"⇛","rsaquo":"›","rscr":"𝓇","Rscr":"ℛ","rsh":"↱","Rsh":"↱","rsqb":"]","rsquo":"’","rsquor":"’","rthree":"⋌","rtimes":"⋊","rtri":"▹","rtrie":"⊵","rtrif":"▸","rtriltri":"⧎","RuleDelayed":"⧴","ruluhar":"⥨","rx":"℞","Sacute":"Ś","sacute":"ś","sbquo":"‚","scap":"⪸","Scaron":"Š","scaron":"š","Sc":"⪼","sc":"≻","sccue":"≽","sce":"⪰","scE":"⪴","Scedil":"Ş","scedil":"ş","Scirc":"Ŝ","scirc":"ŝ","scnap":"⪺","scnE":"⪶","scnsim":"⋩","scpolint":"⨓","scsim":"≿","Scy":"С","scy":"с","sdotb":"⊡","sdot":"⋅","sdote":"⩦","searhk":"⤥","searr":"↘","seArr":"⇘","searrow":"↘","sect":"§","semi":";","seswar":"⤩","setminus":"∖","setmn":"∖","sext":"✶","Sfr":"𝔖","sfr":"𝔰","sfrown":"⌢","sharp":"♯","SHCHcy":"Щ","shchcy":"щ","SHcy":"Ш","shcy":"ш","ShortDownArrow":"↓","ShortLeftArrow":"←","shortmid":"∣","shortparallel":"∥","ShortRightArrow":"→","ShortUpArrow":"↑","shy":"­","Sigma":"Σ","sigma":"σ","sigmaf":"ς","sigmav":"ς","sim":"∼","simdot":"⩪","sime":"≃","simeq":"≃","simg":"⪞","simgE":"⪠","siml":"⪝","simlE":"⪟","simne":"≆","simplus":"⨤","simrarr":"⥲","slarr":"←","SmallCircle":"∘","smallsetminus":"∖","smashp":"⨳","smeparsl":"⧤","smid":"∣","smile":"⌣","smt":"⪪","smte":"⪬","smtes":"⪬︀","SOFTcy":"Ь","softcy":"ь","solbar":"⌿","solb":"⧄","sol":"/","Sopf":"𝕊","sopf":"𝕤","spades":"♠","spadesuit":"♠","spar":"∥","sqcap":"⊓","sqcaps":"⊓︀","sqcup":"⊔","sqcups":"⊔︀","Sqrt":"√","sqsub":"⊏","sqsube":"⊑","sqsubset":"⊏","sqsubseteq":"⊑","sqsup":"⊐","sqsupe":"⊒","sqsupset":"⊐","sqsupseteq":"⊒","square":"□","Square":"□","SquareIntersection":"⊓","SquareSubset":"⊏","SquareSubsetEqual":"⊑","SquareSuperset":"⊐","SquareSupersetEqual":"⊒","SquareUnion":"⊔","squarf":"▪","squ":"□","squf":"▪","srarr":"→","Sscr":"𝒮","sscr":"𝓈","ssetmn":"∖","ssmile":"⌣","sstarf":"⋆","Star":"⋆","star":"☆","starf":"★","straightepsilon":"ϵ","straightphi":"ϕ","strns":"¯","sub":"⊂","Sub":"⋐","subdot":"⪽","subE":"⫅","sube":"⊆","subedot":"⫃","submult":"⫁","subnE":"⫋","subne":"⊊","subplus":"⪿","subrarr":"⥹","subset":"⊂","Subset":"⋐","subseteq":"⊆","subseteqq":"⫅","SubsetEqual":"⊆","subsetneq":"⊊","subsetneqq":"⫋","subsim":"⫇","subsub":"⫕","subsup":"⫓","succapprox":"⪸","succ":"≻","succcurlyeq":"≽","Succeeds":"≻","SucceedsEqual":"⪰","SucceedsSlantEqual":"≽","SucceedsTilde":"≿","succeq":"⪰","succnapprox":"⪺","succneqq":"⪶","succnsim":"⋩","succsim":"≿","SuchThat":"∋","sum":"∑","Sum":"∑","sung":"♪","sup1":"¹","sup2":"²","sup3":"³","sup":"⊃","Sup":"⋑","supdot":"⪾","supdsub":"⫘","supE":"⫆","supe":"⊇","supedot":"⫄","Superset":"⊃","SupersetEqual":"⊇","suphsol":"⟉","suphsub":"⫗","suplarr":"⥻","supmult":"⫂","supnE":"⫌","supne":"⊋","supplus":"⫀","supset":"⊃","Supset":"⋑","supseteq":"⊇","supseteqq":"⫆","supsetneq":"⊋","supsetneqq":"⫌","supsim":"⫈","supsub":"⫔","supsup":"⫖","swarhk":"⤦","swarr":"↙","swArr":"⇙","swarrow":"↙","swnwar":"⤪","szlig":"ß","Tab":"\\t","target":"⌖","Tau":"Τ","tau":"τ","tbrk":"⎴","Tcaron":"Ť","tcaron":"ť","Tcedil":"Ţ","tcedil":"ţ","Tcy":"Т","tcy":"т","tdot":"⃛","telrec":"⌕","Tfr":"𝔗","tfr":"𝔱","there4":"∴","therefore":"∴","Therefore":"∴","Theta":"Θ","theta":"θ","thetasym":"ϑ","thetav":"ϑ","thickapprox":"≈","thicksim":"∼","ThickSpace":"  ","ThinSpace":" ","thinsp":" ","thkap":"≈","thksim":"∼","THORN":"Þ","thorn":"þ","tilde":"˜","Tilde":"∼","TildeEqual":"≃","TildeFullEqual":"≅","TildeTilde":"≈","timesbar":"⨱","timesb":"⊠","times":"×","timesd":"⨰","tint":"∭","toea":"⤨","topbot":"⌶","topcir":"⫱","top":"⊤","Topf":"𝕋","topf":"𝕥","topfork":"⫚","tosa":"⤩","tprime":"‴","trade":"™","TRADE":"™","triangle":"▵","triangledown":"▿","triangleleft":"◃","trianglelefteq":"⊴","triangleq":"≜","triangleright":"▹","trianglerighteq":"⊵","tridot":"◬","trie":"≜","triminus":"⨺","TripleDot":"⃛","triplus":"⨹","trisb":"⧍","tritime":"⨻","trpezium":"⏢","Tscr":"𝒯","tscr":"𝓉","TScy":"Ц","tscy":"ц","TSHcy":"Ћ","tshcy":"ћ","Tstrok":"Ŧ","tstrok":"ŧ","twixt":"≬","twoheadleftarrow":"↞","twoheadrightarrow":"↠","Uacute":"Ú","uacute":"ú","uarr":"↑","Uarr":"↟","uArr":"⇑","Uarrocir":"⥉","Ubrcy":"Ў","ubrcy":"ў","Ubreve":"Ŭ","ubreve":"ŭ","Ucirc":"Û","ucirc":"û","Ucy":"У","ucy":"у","udarr":"⇅","Udblac":"Ű","udblac":"ű","udhar":"⥮","ufisht":"⥾","Ufr":"𝔘","ufr":"𝔲","Ugrave":"Ù","ugrave":"ù","uHar":"⥣","uharl":"↿","uharr":"↾","uhblk":"▀","ulcorn":"⌜","ulcorner":"⌜","ulcrop":"⌏","ultri":"◸","Umacr":"Ū","umacr":"ū","uml":"¨","UnderBar":"_","UnderBrace":"⏟","UnderBracket":"⎵","UnderParenthesis":"⏝","Union":"⋃","UnionPlus":"⊎","Uogon":"Ų","uogon":"ų","Uopf":"𝕌","uopf":"𝕦","UpArrowBar":"⤒","uparrow":"↑","UpArrow":"↑","Uparrow":"⇑","UpArrowDownArrow":"⇅","updownarrow":"↕","UpDownArrow":"↕","Updownarrow":"⇕","UpEquilibrium":"⥮","upharpoonleft":"↿","upharpoonright":"↾","uplus":"⊎","UpperLeftArrow":"↖","UpperRightArrow":"↗","upsi":"υ","Upsi":"ϒ","upsih":"ϒ","Upsilon":"Υ","upsilon":"υ","UpTeeArrow":"↥","UpTee":"⊥","upuparrows":"⇈","urcorn":"⌝","urcorner":"⌝","urcrop":"⌎","Uring":"Ů","uring":"ů","urtri":"◹","Uscr":"𝒰","uscr":"𝓊","utdot":"⋰","Utilde":"Ũ","utilde":"ũ","utri":"▵","utrif":"▴","uuarr":"⇈","Uuml":"Ü","uuml":"ü","uwangle":"⦧","vangrt":"⦜","varepsilon":"ϵ","varkappa":"ϰ","varnothing":"∅","varphi":"ϕ","varpi":"ϖ","varpropto":"∝","varr":"↕","vArr":"⇕","varrho":"ϱ","varsigma":"ς","varsubsetneq":"⊊︀","varsubsetneqq":"⫋︀","varsupsetneq":"⊋︀","varsupsetneqq":"⫌︀","vartheta":"ϑ","vartriangleleft":"⊲","vartriangleright":"⊳","vBar":"⫨","Vbar":"⫫","vBarv":"⫩","Vcy":"В","vcy":"в","vdash":"⊢","vDash":"⊨","Vdash":"⊩","VDash":"⊫","Vdashl":"⫦","veebar":"⊻","vee":"∨","Vee":"⋁","veeeq":"≚","vellip":"⋮","verbar":"|","Verbar":"‖","vert":"|","Vert":"‖","VerticalBar":"∣","VerticalLine":"|","VerticalSeparator":"❘","VerticalTilde":"≀","VeryThinSpace":" ","Vfr":"𝔙","vfr":"𝔳","vltri":"⊲","vnsub":"⊂⃒","vnsup":"⊃⃒","Vopf":"𝕍","vopf":"𝕧","vprop":"∝","vrtri":"⊳","Vscr":"𝒱","vscr":"𝓋","vsubnE":"⫋︀","vsubne":"⊊︀","vsupnE":"⫌︀","vsupne":"⊋︀","Vvdash":"⊪","vzigzag":"⦚","Wcirc":"Ŵ","wcirc":"ŵ","wedbar":"⩟","wedge":"∧","Wedge":"⋀","wedgeq":"≙","weierp":"℘","Wfr":"𝔚","wfr":"𝔴","Wopf":"𝕎","wopf":"𝕨","wp":"℘","wr":"≀","wreath":"≀","Wscr":"𝒲","wscr":"𝓌","xcap":"⋂","xcirc":"◯","xcup":"⋃","xdtri":"▽","Xfr":"𝔛","xfr":"𝔵","xharr":"⟷","xhArr":"⟺","Xi":"Ξ","xi":"ξ","xlarr":"⟵","xlArr":"⟸","xmap":"⟼","xnis":"⋻","xodot":"⨀","Xopf":"𝕏","xopf":"𝕩","xoplus":"⨁","xotime":"⨂","xrarr":"⟶","xrArr":"⟹","Xscr":"𝒳","xscr":"𝓍","xsqcup":"⨆","xuplus":"⨄","xutri":"△","xvee":"⋁","xwedge":"⋀","Yacute":"Ý","yacute":"ý","YAcy":"Я","yacy":"я","Ycirc":"Ŷ","ycirc":"ŷ","Ycy":"Ы","ycy":"ы","yen":"¥","Yfr":"𝔜","yfr":"𝔶","YIcy":"Ї","yicy":"ї","Yopf":"𝕐","yopf":"𝕪","Yscr":"𝒴","yscr":"𝓎","YUcy":"Ю","yucy":"ю","yuml":"ÿ","Yuml":"Ÿ","Zacute":"Ź","zacute":"ź","Zcaron":"Ž","zcaron":"ž","Zcy":"З","zcy":"з","Zdot":"Ż","zdot":"ż","zeetrf":"ℨ","ZeroWidthSpace":"​","Zeta":"Ζ","zeta":"ζ","zfr":"𝔷","Zfr":"ℨ","ZHcy":"Ж","zhcy":"ж","zigrarr":"⇝","zopf":"𝕫","Zopf":"ℤ","Zscr":"𝒵","zscr":"𝓏","zwj":"‍","zwnj":"‌"}');
 
 /***/ }),
-/* 275 */
+/* 276 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"Aacute":"Á","aacute":"á","Acirc":"Â","acirc":"â","acute":"´","AElig":"Æ","aelig":"æ","Agrave":"À","agrave":"à","amp":"&","AMP":"&","Aring":"Å","aring":"å","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","brvbar":"¦","Ccedil":"Ç","ccedil":"ç","cedil":"¸","cent":"¢","copy":"©","COPY":"©","curren":"¤","deg":"°","divide":"÷","Eacute":"É","eacute":"é","Ecirc":"Ê","ecirc":"ê","Egrave":"È","egrave":"è","ETH":"Ð","eth":"ð","Euml":"Ë","euml":"ë","frac12":"½","frac14":"¼","frac34":"¾","gt":">","GT":">","Iacute":"Í","iacute":"í","Icirc":"Î","icirc":"î","iexcl":"¡","Igrave":"Ì","igrave":"ì","iquest":"¿","Iuml":"Ï","iuml":"ï","laquo":"«","lt":"<","LT":"<","macr":"¯","micro":"µ","middot":"·","nbsp":" ","not":"¬","Ntilde":"Ñ","ntilde":"ñ","Oacute":"Ó","oacute":"ó","Ocirc":"Ô","ocirc":"ô","Ograve":"Ò","ograve":"ò","ordf":"ª","ordm":"º","Oslash":"Ø","oslash":"ø","Otilde":"Õ","otilde":"õ","Ouml":"Ö","ouml":"ö","para":"¶","plusmn":"±","pound":"£","quot":"\\"","QUOT":"\\"","raquo":"»","reg":"®","REG":"®","sect":"§","shy":"­","sup1":"¹","sup2":"²","sup3":"³","szlig":"ß","THORN":"Þ","thorn":"þ","times":"×","Uacute":"Ú","uacute":"ú","Ucirc":"Û","ucirc":"û","Ugrave":"Ù","ugrave":"ù","uml":"¨","Uuml":"Ü","uuml":"ü","Yacute":"Ý","yacute":"ý","yen":"¥","yuml":"ÿ"}');
 
 /***/ }),
-/* 276 */
+/* 277 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"amp":"&","apos":"\'","gt":">","lt":"<","quot":"\\""}');
 
 /***/ }),
-/* 277 */
+/* 278 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -43308,7 +43379,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-var decode_json_1 = __importDefault(__webpack_require__(278));
+var decode_json_1 = __importDefault(__webpack_require__(279));
 // Adapted from https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
 var fromCodePoint = 
 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -43336,14 +43407,14 @@ exports["default"] = decodeCodePoint;
 
 
 /***/ }),
-/* 278 */
+/* 279 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"0":65533,"128":8364,"130":8218,"131":402,"132":8222,"133":8230,"134":8224,"135":8225,"136":710,"137":8240,"138":352,"139":8249,"140":338,"142":381,"145":8216,"146":8217,"147":8220,"148":8221,"149":8226,"150":8211,"151":8212,"152":732,"153":8482,"154":353,"155":8250,"156":339,"158":382,"159":376}');
 
 /***/ }),
-/* 279 */
+/* 280 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -43353,7 +43424,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = void 0;
-var xml_json_1 = __importDefault(__webpack_require__(276));
+var xml_json_1 = __importDefault(__webpack_require__(277));
 var inverseXML = getInverseObj(xml_json_1.default);
 var xmlReplacer = getInverseReplacer(inverseXML);
 /**
@@ -43364,7 +43435,7 @@ var xmlReplacer = getInverseReplacer(inverseXML);
  * numeric hexadecimal reference (eg. `&#xfc;`) will be used.
  */
 exports.encodeXML = getASCIIEncoder(inverseXML);
-var entities_json_1 = __importDefault(__webpack_require__(274));
+var entities_json_1 = __importDefault(__webpack_require__(275));
 var inverseHTML = getInverseObj(entities_json_1.default);
 var htmlReplacer = getInverseReplacer(inverseHTML);
 /**
@@ -43486,7 +43557,7 @@ function getASCIIEncoder(obj) {
 
 
 /***/ }),
-/* 280 */
+/* 281 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -43596,14 +43667,14 @@ exports.attributeNames = new Map([
 
 
 /***/ }),
-/* 281 */
+/* 282 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.prevElementSibling = exports.nextElementSibling = exports.getName = exports.hasAttrib = exports.getAttributeValue = exports.getSiblings = exports.getParent = exports.getChildren = void 0;
-var domhandler_1 = __webpack_require__(268);
+var domhandler_1 = __webpack_require__(269);
 var emptyArray = [];
 /**
  * Get a node's children.
@@ -43720,7 +43791,7 @@ exports.prevElementSibling = prevElementSibling;
 
 
 /***/ }),
-/* 282 */
+/* 283 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -43856,14 +43927,14 @@ exports.prepend = prepend;
 
 
 /***/ }),
-/* 283 */
+/* 284 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.findAll = exports.existsOne = exports.findOne = exports.findOneChild = exports.find = exports.filter = void 0;
-var domhandler_1 = __webpack_require__(268);
+var domhandler_1 = __webpack_require__(269);
 /**
  * Search a node and its children for nodes passing a test function.
  *
@@ -43989,15 +44060,15 @@ exports.findAll = findAll;
 
 
 /***/ }),
-/* 284 */
+/* 285 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.getElementsByTagType = exports.getElementsByTagName = exports.getElementById = exports.getElements = exports.testElement = void 0;
-var domhandler_1 = __webpack_require__(268);
-var querying_1 = __webpack_require__(283);
+var domhandler_1 = __webpack_require__(269);
+var querying_1 = __webpack_require__(284);
 var Checks = {
     tag_name: function (name) {
         if (typeof name === "function") {
@@ -44120,14 +44191,14 @@ exports.getElementsByTagType = getElementsByTagType;
 
 
 /***/ }),
-/* 285 */
+/* 286 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.uniqueSort = exports.compareDocumentPosition = exports.removeSubsets = void 0;
-var domhandler_1 = __webpack_require__(268);
+var domhandler_1 = __webpack_require__(269);
 /**
  * Given an array of nodes, remove any member that is contained by another.
  *
@@ -44252,7 +44323,7 @@ exports.uniqueSort = uniqueSort;
 
 
 /***/ }),
-/* 286 */
+/* 287 */
 /***/ ((module) => {
 
 module.exports = {
@@ -44265,7 +44336,7 @@ module.exports = {
 };
 
 /***/ }),
-/* 287 */
+/* 288 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -44275,12 +44346,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.compileToken = exports.compileUnsafe = exports.compile = void 0;
-var css_what_1 = __webpack_require__(262);
-var boolbase_1 = __webpack_require__(286);
-var sort_1 = __importDefault(__webpack_require__(288));
-var procedure_1 = __webpack_require__(289);
-var general_1 = __webpack_require__(290);
-var subselects_1 = __webpack_require__(299);
+var css_what_1 = __webpack_require__(263);
+var boolbase_1 = __webpack_require__(287);
+var sort_1 = __importDefault(__webpack_require__(289));
+var procedure_1 = __webpack_require__(290);
+var general_1 = __webpack_require__(291);
+var subselects_1 = __webpack_require__(300);
 /**
  * Compiles a selector to an executable function.
  *
@@ -44387,13 +44458,13 @@ function reduceRules(a, b) {
 
 
 /***/ }),
-/* 288 */
+/* 289 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-var procedure_1 = __webpack_require__(289);
+var procedure_1 = __webpack_require__(290);
 var attributes = {
     exists: 10,
     equals: 8,
@@ -44478,7 +44549,7 @@ function getProcedure(token) {
 
 
 /***/ }),
-/* 289 */
+/* 290 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -44505,15 +44576,15 @@ exports.isTraversal = isTraversal;
 
 
 /***/ }),
-/* 290 */
+/* 291 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.compileGeneralSelector = void 0;
-var attributes_1 = __webpack_require__(291);
-var pseudo_selectors_1 = __webpack_require__(292);
+var attributes_1 = __webpack_require__(292);
+var pseudo_selectors_1 = __webpack_require__(293);
 /*
  * All available rules
  */
@@ -44616,14 +44687,14 @@ exports.compileGeneralSelector = compileGeneralSelector;
 
 
 /***/ }),
-/* 291 */
+/* 292 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.attributeRules = void 0;
-var boolbase_1 = __webpack_require__(286);
+var boolbase_1 = __webpack_require__(287);
 /**
  * All reserved characters in a regex, used for escaping.
  *
@@ -44794,7 +44865,7 @@ exports.attributeRules = {
 
 
 /***/ }),
-/* 292 */
+/* 293 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
@@ -44815,15 +44886,15 @@ exports.compilePseudoSelector = exports.aliases = exports.pseudos = exports.filt
  * of `next()` and your code.
  * Pseudos should be used to implement simple checks.
  */
-var boolbase_1 = __webpack_require__(286);
-var css_what_1 = __webpack_require__(262);
-var filters_1 = __webpack_require__(293);
+var boolbase_1 = __webpack_require__(287);
+var css_what_1 = __webpack_require__(263);
+var filters_1 = __webpack_require__(294);
 Object.defineProperty(exports, "filters", ({ enumerable: true, get: function () { return filters_1.filters; } }));
-var pseudos_1 = __webpack_require__(297);
+var pseudos_1 = __webpack_require__(298);
 Object.defineProperty(exports, "pseudos", ({ enumerable: true, get: function () { return pseudos_1.pseudos; } }));
-var aliases_1 = __webpack_require__(298);
+var aliases_1 = __webpack_require__(299);
 Object.defineProperty(exports, "aliases", ({ enumerable: true, get: function () { return aliases_1.aliases; } }));
-var subselects_1 = __webpack_require__(299);
+var subselects_1 = __webpack_require__(300);
 function compilePseudoSelector(next, selector, options, context, compileToken) {
     var name = selector.name, data = selector.data;
     if (Array.isArray(data)) {
@@ -44855,7 +44926,7 @@ exports.compilePseudoSelector = compilePseudoSelector;
 
 
 /***/ }),
-/* 293 */
+/* 294 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -44865,8 +44936,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.filters = void 0;
-var nth_check_1 = __importDefault(__webpack_require__(294));
-var boolbase_1 = __webpack_require__(286);
+var nth_check_1 = __importDefault(__webpack_require__(295));
+var boolbase_1 = __webpack_require__(287);
 function getChildFunc(next, adapter) {
     return function (elem) {
         var parent = adapter.getParent(elem);
@@ -45018,16 +45089,16 @@ function dynamicStatePseudo(name) {
 
 
 /***/ }),
-/* 294 */
+/* 295 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.compile = exports.parse = void 0;
-var parse_1 = __webpack_require__(295);
+var parse_1 = __webpack_require__(296);
 Object.defineProperty(exports, "parse", ({ enumerable: true, get: function () { return parse_1.parse; } }));
-var compile_1 = __webpack_require__(296);
+var compile_1 = __webpack_require__(297);
 Object.defineProperty(exports, "compile", ({ enumerable: true, get: function () { return compile_1.compile; } }));
 /**
  * Parses and compiles a formula to a highly optimized function.
@@ -45059,7 +45130,7 @@ exports["default"] = nthCheck;
 
 
 /***/ }),
-/* 295 */
+/* 296 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -45105,14 +45176,14 @@ exports.parse = parse;
 
 
 /***/ }),
-/* 296 */
+/* 297 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.compile = void 0;
-var boolbase_1 = __webpack_require__(286);
+var boolbase_1 = __webpack_require__(287);
 /**
  * Returns a function that checks if an elements index matches the given rule
  * highly optimized to return the fastest solution.
@@ -45167,7 +45238,7 @@ exports.compile = compile;
 
 
 /***/ }),
-/* 297 */
+/* 298 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -45263,7 +45334,7 @@ exports.verifyPseudoArgs = verifyPseudoArgs;
 
 
 /***/ }),
-/* 298 */
+/* 299 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -45303,7 +45374,7 @@ exports.aliases = {
 
 
 /***/ }),
-/* 299 */
+/* 300 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -45315,8 +45386,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.subselects = exports.getNextSiblings = exports.ensureIsTag = exports.PLACEHOLDER_ELEMENT = void 0;
-var boolbase_1 = __webpack_require__(286);
-var procedure_1 = __webpack_require__(289);
+var boolbase_1 = __webpack_require__(287);
+var procedure_1 = __webpack_require__(290);
 /** Used as a placeholder for :has. Will be replaced with the actual element. */
 exports.PLACEHOLDER_ELEMENT = {};
 function ensureIsTag(next, adapter) {
@@ -45415,14 +45486,14 @@ exports.subselects = {
 
 
 /***/ }),
-/* 300 */
+/* 301 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.groupSelectors = exports.getDocumentRoot = void 0;
-var positionals_1 = __webpack_require__(301);
+var positionals_1 = __webpack_require__(302);
 function getDocumentRoot(node) {
     while (node.parent)
         node = node.parent;
@@ -45447,7 +45518,7 @@ exports.groupSelectors = groupSelectors;
 
 
 /***/ }),
-/* 301 */
+/* 302 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -45496,7 +45567,7 @@ exports.getLimit = getLimit;
 
 
 /***/ }),
-/* 302 */
+/* 303 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -45528,9 +45599,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.RssHandler = exports.DefaultHandler = exports.DomUtils = exports.ElementType = exports.Tokenizer = exports.createDomStream = exports.parseDOM = exports.parseDocument = exports.DomHandler = exports.Parser = void 0;
-var Parser_1 = __webpack_require__(303);
+var Parser_1 = __webpack_require__(304);
 Object.defineProperty(exports, "Parser", ({ enumerable: true, get: function () { return Parser_1.Parser; } }));
-var domhandler_1 = __webpack_require__(268);
+var domhandler_1 = __webpack_require__(306);
 Object.defineProperty(exports, "DomHandler", ({ enumerable: true, get: function () { return domhandler_1.DomHandler; } }));
 Object.defineProperty(exports, "DefaultHandler", ({ enumerable: true, get: function () { return domhandler_1.DomHandler; } }));
 // Helper methods
@@ -45572,22 +45643,22 @@ function createDomStream(cb, options, elementCb) {
     return new Parser_1.Parser(handler, options);
 }
 exports.createDomStream = createDomStream;
-var Tokenizer_1 = __webpack_require__(304);
+var Tokenizer_1 = __webpack_require__(305);
 Object.defineProperty(exports, "Tokenizer", ({ enumerable: true, get: function () { return __importDefault(Tokenizer_1).default; } }));
-var ElementType = __importStar(__webpack_require__(269));
+var ElementType = __importStar(__webpack_require__(270));
 exports.ElementType = ElementType;
 /*
  * All of the following exports exist for backwards-compatibility.
  * They should probably be removed eventually.
  */
-__exportStar(__webpack_require__(305), exports);
-exports.DomUtils = __importStar(__webpack_require__(266));
-var FeedHandler_1 = __webpack_require__(305);
+__exportStar(__webpack_require__(308), exports);
+exports.DomUtils = __importStar(__webpack_require__(309));
+var FeedHandler_1 = __webpack_require__(308);
 Object.defineProperty(exports, "RssHandler", ({ enumerable: true, get: function () { return FeedHandler_1.FeedHandler; } }));
 
 
 /***/ }),
-/* 303 */
+/* 304 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -45597,7 +45668,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.Parser = void 0;
-var Tokenizer_1 = __importDefault(__webpack_require__(304));
+var Tokenizer_1 = __importDefault(__webpack_require__(305));
 var formTags = new Set([
     "input",
     "option",
@@ -45975,7 +46046,7 @@ exports.Parser = Parser;
 
 
 /***/ }),
-/* 304 */
+/* 305 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -45984,10 +46055,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-var decode_codepoint_1 = __importDefault(__webpack_require__(277));
-var entities_json_1 = __importDefault(__webpack_require__(274));
-var legacy_json_1 = __importDefault(__webpack_require__(275));
-var xml_json_1 = __importDefault(__webpack_require__(276));
+var decode_codepoint_1 = __importDefault(__webpack_require__(278));
+var entities_json_1 = __importDefault(__webpack_require__(275));
+var legacy_json_1 = __importDefault(__webpack_require__(276));
+var xml_json_1 = __importDefault(__webpack_require__(277));
 function whitespace(c) {
     return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
 }
@@ -46891,7 +46962,580 @@ exports["default"] = Tokenizer;
 
 
 /***/ }),
-/* 305 */
+/* 306 */
+/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.DomHandler = void 0;
+var domelementtype_1 = __webpack_require__(270);
+var node_1 = __webpack_require__(307);
+__exportStar(__webpack_require__(307), exports);
+var reWhitespace = /\s+/g;
+// Default options
+var defaultOpts = {
+    normalizeWhitespace: false,
+    withStartIndices: false,
+    withEndIndices: false,
+};
+var DomHandler = /** @class */ (function () {
+    /**
+     * @param callback Called once parsing has completed.
+     * @param options Settings for the handler.
+     * @param elementCB Callback whenever a tag is closed.
+     */
+    function DomHandler(callback, options, elementCB) {
+        /** The elements of the DOM */
+        this.dom = [];
+        /** The root element for the DOM */
+        this.root = new node_1.Document(this.dom);
+        /** Indicated whether parsing has been completed. */
+        this.done = false;
+        /** Stack of open tags. */
+        this.tagStack = [this.root];
+        /** A data node that is still being written to. */
+        this.lastNode = null;
+        /** Reference to the parser instance. Used for location information. */
+        this.parser = null;
+        // Make it possible to skip arguments, for backwards-compatibility
+        if (typeof options === "function") {
+            elementCB = options;
+            options = defaultOpts;
+        }
+        if (typeof callback === "object") {
+            options = callback;
+            callback = undefined;
+        }
+        this.callback = callback !== null && callback !== void 0 ? callback : null;
+        this.options = options !== null && options !== void 0 ? options : defaultOpts;
+        this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;
+    }
+    DomHandler.prototype.onparserinit = function (parser) {
+        this.parser = parser;
+    };
+    // Resets the handler back to starting state
+    DomHandler.prototype.onreset = function () {
+        var _a;
+        this.dom = [];
+        this.root = new node_1.Document(this.dom);
+        this.done = false;
+        this.tagStack = [this.root];
+        this.lastNode = null;
+        this.parser = (_a = this.parser) !== null && _a !== void 0 ? _a : null;
+    };
+    // Signals the handler that parsing is done
+    DomHandler.prototype.onend = function () {
+        if (this.done)
+            return;
+        this.done = true;
+        this.parser = null;
+        this.handleCallback(null);
+    };
+    DomHandler.prototype.onerror = function (error) {
+        this.handleCallback(error);
+    };
+    DomHandler.prototype.onclosetag = function () {
+        this.lastNode = null;
+        var elem = this.tagStack.pop();
+        if (this.options.withEndIndices) {
+            elem.endIndex = this.parser.endIndex;
+        }
+        if (this.elementCB)
+            this.elementCB(elem);
+    };
+    DomHandler.prototype.onopentag = function (name, attribs) {
+        var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined;
+        var element = new node_1.Element(name, attribs, undefined, type);
+        this.addNode(element);
+        this.tagStack.push(element);
+    };
+    DomHandler.prototype.ontext = function (data) {
+        var normalizeWhitespace = this.options.normalizeWhitespace;
+        var lastNode = this.lastNode;
+        if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) {
+            if (normalizeWhitespace) {
+                lastNode.data = (lastNode.data + data).replace(reWhitespace, " ");
+            }
+            else {
+                lastNode.data += data;
+            }
+        }
+        else {
+            if (normalizeWhitespace) {
+                data = data.replace(reWhitespace, " ");
+            }
+            var node = new node_1.Text(data);
+            this.addNode(node);
+            this.lastNode = node;
+        }
+    };
+    DomHandler.prototype.oncomment = function (data) {
+        if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) {
+            this.lastNode.data += data;
+            return;
+        }
+        var node = new node_1.Comment(data);
+        this.addNode(node);
+        this.lastNode = node;
+    };
+    DomHandler.prototype.oncommentend = function () {
+        this.lastNode = null;
+    };
+    DomHandler.prototype.oncdatastart = function () {
+        var text = new node_1.Text("");
+        var node = new node_1.NodeWithChildren(domelementtype_1.ElementType.CDATA, [text]);
+        this.addNode(node);
+        text.parent = node;
+        this.lastNode = text;
+    };
+    DomHandler.prototype.oncdataend = function () {
+        this.lastNode = null;
+    };
+    DomHandler.prototype.onprocessinginstruction = function (name, data) {
+        var node = new node_1.ProcessingInstruction(name, data);
+        this.addNode(node);
+    };
+    DomHandler.prototype.handleCallback = function (error) {
+        if (typeof this.callback === "function") {
+            this.callback(error, this.dom);
+        }
+        else if (error) {
+            throw error;
+        }
+    };
+    DomHandler.prototype.addNode = function (node) {
+        var parent = this.tagStack[this.tagStack.length - 1];
+        var previousSibling = parent.children[parent.children.length - 1];
+        if (this.options.withStartIndices) {
+            node.startIndex = this.parser.startIndex;
+        }
+        if (this.options.withEndIndices) {
+            node.endIndex = this.parser.endIndex;
+        }
+        parent.children.push(node);
+        if (previousSibling) {
+            node.prev = previousSibling;
+            previousSibling.next = node;
+        }
+        node.parent = parent;
+        this.lastNode = null;
+    };
+    return DomHandler;
+}());
+exports.DomHandler = DomHandler;
+exports["default"] = DomHandler;
+
+
+/***/ }),
+/* 307 */
+/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
+
+"use strict";
+
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        if (typeof b !== "function" && b !== null)
+            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0;
+var domelementtype_1 = __webpack_require__(270);
+var nodeTypes = new Map([
+    [domelementtype_1.ElementType.Tag, 1],
+    [domelementtype_1.ElementType.Script, 1],
+    [domelementtype_1.ElementType.Style, 1],
+    [domelementtype_1.ElementType.Directive, 1],
+    [domelementtype_1.ElementType.Text, 3],
+    [domelementtype_1.ElementType.CDATA, 4],
+    [domelementtype_1.ElementType.Comment, 8],
+    [domelementtype_1.ElementType.Root, 9],
+]);
+/**
+ * This object will be used as the prototype for Nodes when creating a
+ * DOM-Level-1-compliant structure.
+ */
+var Node = /** @class */ (function () {
+    /**
+     *
+     * @param type The type of the node.
+     */
+    function Node(type) {
+        this.type = type;
+        /** Parent of the node */
+        this.parent = null;
+        /** Previous sibling */
+        this.prev = null;
+        /** Next sibling */
+        this.next = null;
+        /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */
+        this.startIndex = null;
+        /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */
+        this.endIndex = null;
+    }
+    Object.defineProperty(Node.prototype, "nodeType", {
+        // Read-only aliases
+        get: function () {
+            var _a;
+            return (_a = nodeTypes.get(this.type)) !== null && _a !== void 0 ? _a : 1;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Node.prototype, "parentNode", {
+        // Read-write aliases for properties
+        get: function () {
+            return this.parent;
+        },
+        set: function (parent) {
+            this.parent = parent;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Node.prototype, "previousSibling", {
+        get: function () {
+            return this.prev;
+        },
+        set: function (prev) {
+            this.prev = prev;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Node.prototype, "nextSibling", {
+        get: function () {
+            return this.next;
+        },
+        set: function (next) {
+            this.next = next;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    /**
+     * Clone this node, and optionally its children.
+     *
+     * @param recursive Clone child nodes as well.
+     * @returns A clone of the node.
+     */
+    Node.prototype.cloneNode = function (recursive) {
+        if (recursive === void 0) { recursive = false; }
+        return cloneNode(this, recursive);
+    };
+    return Node;
+}());
+exports.Node = Node;
+var DataNode = /** @class */ (function (_super) {
+    __extends(DataNode, _super);
+    /**
+     * @param type The type of the node
+     * @param data The content of the data node
+     */
+    function DataNode(type, data) {
+        var _this = _super.call(this, type) || this;
+        _this.data = data;
+        return _this;
+    }
+    Object.defineProperty(DataNode.prototype, "nodeValue", {
+        get: function () {
+            return this.data;
+        },
+        set: function (data) {
+            this.data = data;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    return DataNode;
+}(Node));
+exports.DataNode = DataNode;
+var Text = /** @class */ (function (_super) {
+    __extends(Text, _super);
+    function Text(data) {
+        return _super.call(this, domelementtype_1.ElementType.Text, data) || this;
+    }
+    return Text;
+}(DataNode));
+exports.Text = Text;
+var Comment = /** @class */ (function (_super) {
+    __extends(Comment, _super);
+    function Comment(data) {
+        return _super.call(this, domelementtype_1.ElementType.Comment, data) || this;
+    }
+    return Comment;
+}(DataNode));
+exports.Comment = Comment;
+var ProcessingInstruction = /** @class */ (function (_super) {
+    __extends(ProcessingInstruction, _super);
+    function ProcessingInstruction(name, data) {
+        var _this = _super.call(this, domelementtype_1.ElementType.Directive, data) || this;
+        _this.name = name;
+        return _this;
+    }
+    return ProcessingInstruction;
+}(DataNode));
+exports.ProcessingInstruction = ProcessingInstruction;
+/**
+ * A `Node` that can have children.
+ */
+var NodeWithChildren = /** @class */ (function (_super) {
+    __extends(NodeWithChildren, _super);
+    /**
+     * @param type Type of the node.
+     * @param children Children of the node. Only certain node types can have children.
+     */
+    function NodeWithChildren(type, children) {
+        var _this = _super.call(this, type) || this;
+        _this.children = children;
+        return _this;
+    }
+    Object.defineProperty(NodeWithChildren.prototype, "firstChild", {
+        // Aliases
+        get: function () {
+            var _a;
+            return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(NodeWithChildren.prototype, "lastChild", {
+        get: function () {
+            return this.children.length > 0
+                ? this.children[this.children.length - 1]
+                : null;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(NodeWithChildren.prototype, "childNodes", {
+        get: function () {
+            return this.children;
+        },
+        set: function (children) {
+            this.children = children;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    return NodeWithChildren;
+}(Node));
+exports.NodeWithChildren = NodeWithChildren;
+var Document = /** @class */ (function (_super) {
+    __extends(Document, _super);
+    function Document(children) {
+        return _super.call(this, domelementtype_1.ElementType.Root, children) || this;
+    }
+    return Document;
+}(NodeWithChildren));
+exports.Document = Document;
+var Element = /** @class */ (function (_super) {
+    __extends(Element, _super);
+    /**
+     * @param name Name of the tag, eg. `div`, `span`.
+     * @param attribs Object mapping attribute names to attribute values.
+     * @param children Children of the node.
+     */
+    function Element(name, attribs, children, type) {
+        if (children === void 0) { children = []; }
+        if (type === void 0) { type = name === "script"
+            ? domelementtype_1.ElementType.Script
+            : name === "style"
+                ? domelementtype_1.ElementType.Style
+                : domelementtype_1.ElementType.Tag; }
+        var _this = _super.call(this, type, children) || this;
+        _this.name = name;
+        _this.attribs = attribs;
+        return _this;
+    }
+    Object.defineProperty(Element.prototype, "tagName", {
+        // DOM Level 1 aliases
+        get: function () {
+            return this.name;
+        },
+        set: function (name) {
+            this.name = name;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Element.prototype, "attributes", {
+        get: function () {
+            var _this = this;
+            return Object.keys(this.attribs).map(function (name) {
+                var _a, _b;
+                return ({
+                    name: name,
+                    value: _this.attribs[name],
+                    namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name],
+                    prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name],
+                });
+            });
+        },
+        enumerable: false,
+        configurable: true
+    });
+    return Element;
+}(NodeWithChildren));
+exports.Element = Element;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node is a `Element`, `false` otherwise.
+ */
+function isTag(node) {
+    return domelementtype_1.isTag(node);
+}
+exports.isTag = isTag;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `CDATA`, `false` otherwise.
+ */
+function isCDATA(node) {
+    return node.type === domelementtype_1.ElementType.CDATA;
+}
+exports.isCDATA = isCDATA;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `Text`, `false` otherwise.
+ */
+function isText(node) {
+    return node.type === domelementtype_1.ElementType.Text;
+}
+exports.isText = isText;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `Comment`, `false` otherwise.
+ */
+function isComment(node) {
+    return node.type === domelementtype_1.ElementType.Comment;
+}
+exports.isComment = isComment;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
+ */
+function isDirective(node) {
+    return node.type === domelementtype_1.ElementType.Directive;
+}
+exports.isDirective = isDirective;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
+ */
+function isDocument(node) {
+    return node.type === domelementtype_1.ElementType.Root;
+}
+exports.isDocument = isDocument;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise.
+ */
+function hasChildren(node) {
+    return Object.prototype.hasOwnProperty.call(node, "children");
+}
+exports.hasChildren = hasChildren;
+/**
+ * Clone a node, and optionally its children.
+ *
+ * @param recursive Clone child nodes as well.
+ * @returns A clone of the node.
+ */
+function cloneNode(node, recursive) {
+    if (recursive === void 0) { recursive = false; }
+    var result;
+    if (isText(node)) {
+        result = new Text(node.data);
+    }
+    else if (isComment(node)) {
+        result = new Comment(node.data);
+    }
+    else if (isTag(node)) {
+        var children = recursive ? cloneChildren(node.children) : [];
+        var clone_1 = new Element(node.name, __assign({}, node.attribs), children);
+        children.forEach(function (child) { return (child.parent = clone_1); });
+        if (node["x-attribsNamespace"]) {
+            clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]);
+        }
+        if (node["x-attribsPrefix"]) {
+            clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]);
+        }
+        result = clone_1;
+    }
+    else if (isCDATA(node)) {
+        var children = recursive ? cloneChildren(node.children) : [];
+        var clone_2 = new NodeWithChildren(domelementtype_1.ElementType.CDATA, children);
+        children.forEach(function (child) { return (child.parent = clone_2); });
+        result = clone_2;
+    }
+    else if (isDocument(node)) {
+        var children = recursive ? cloneChildren(node.children) : [];
+        var clone_3 = new Document(children);
+        children.forEach(function (child) { return (child.parent = clone_3); });
+        if (node["x-mode"]) {
+            clone_3["x-mode"] = node["x-mode"];
+        }
+        result = clone_3;
+    }
+    else if (isDirective(node)) {
+        var instruction = new ProcessingInstruction(node.name, node.data);
+        if (node["x-name"] != null) {
+            instruction["x-name"] = node["x-name"];
+            instruction["x-publicId"] = node["x-publicId"];
+            instruction["x-systemId"] = node["x-systemId"];
+        }
+        result = instruction;
+    }
+    else {
+        throw new Error("Not implemented yet: " + node.type);
+    }
+    result.startIndex = node.startIndex;
+    result.endIndex = node.endIndex;
+    return result;
+}
+exports.cloneNode = cloneNode;
+function cloneChildren(childs) {
+    var children = childs.map(function (child) { return cloneNode(child, true); });
+    for (var i = 1; i < children.length; i++) {
+        children[i].prev = children[i - 1];
+        children[i - 1].next = children[i];
+    }
+    return children;
+}
+
+
+/***/ }),
+/* 308 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -46935,9 +47579,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.parseFeed = exports.FeedHandler = void 0;
-var domhandler_1 = __importDefault(__webpack_require__(268));
-var DomUtils = __importStar(__webpack_require__(266));
-var Parser_1 = __webpack_require__(303);
+var domhandler_1 = __importDefault(__webpack_require__(306));
+var DomUtils = __importStar(__webpack_require__(309));
+var Parser_1 = __webpack_require__(304);
 var FeedItemMediaMedium;
 (function (FeedItemMediaMedium) {
     FeedItemMediaMedium[FeedItemMediaMedium["image"] = 0] = "image";
@@ -47133,17 +47777,802 @@ exports.parseFeed = parseFeed;
 
 
 /***/ }),
-/* 306 */
+/* 309 */
+/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
+
+"use strict";
+
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.hasChildren = exports.isDocument = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = void 0;
+__exportStar(__webpack_require__(310), exports);
+__exportStar(__webpack_require__(311), exports);
+__exportStar(__webpack_require__(312), exports);
+__exportStar(__webpack_require__(313), exports);
+__exportStar(__webpack_require__(314), exports);
+__exportStar(__webpack_require__(315), exports);
+var domhandler_1 = __webpack_require__(306);
+Object.defineProperty(exports, "isTag", ({ enumerable: true, get: function () { return domhandler_1.isTag; } }));
+Object.defineProperty(exports, "isCDATA", ({ enumerable: true, get: function () { return domhandler_1.isCDATA; } }));
+Object.defineProperty(exports, "isText", ({ enumerable: true, get: function () { return domhandler_1.isText; } }));
+Object.defineProperty(exports, "isComment", ({ enumerable: true, get: function () { return domhandler_1.isComment; } }));
+Object.defineProperty(exports, "isDocument", ({ enumerable: true, get: function () { return domhandler_1.isDocument; } }));
+Object.defineProperty(exports, "hasChildren", ({ enumerable: true, get: function () { return domhandler_1.hasChildren; } }));
+
+
+/***/ }),
+/* 310 */
+/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
+
+"use strict";
+
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.innerText = exports.textContent = exports.getText = exports.getInnerHTML = exports.getOuterHTML = void 0;
+var domhandler_1 = __webpack_require__(306);
+var dom_serializer_1 = __importDefault(__webpack_require__(272));
+var domelementtype_1 = __webpack_require__(270);
+/**
+ * @param node Node to get the outer HTML of.
+ * @param options Options for serialization.
+ * @deprecated Use the `dom-serializer` module directly.
+ * @returns `node`'s outer HTML.
+ */
+function getOuterHTML(node, options) {
+    return dom_serializer_1.default(node, options);
+}
+exports.getOuterHTML = getOuterHTML;
+/**
+ * @param node Node to get the inner HTML of.
+ * @param options Options for serialization.
+ * @deprecated Use the `dom-serializer` module directly.
+ * @returns `node`'s inner HTML.
+ */
+function getInnerHTML(node, options) {
+    return domhandler_1.hasChildren(node)
+        ? node.children.map(function (node) { return getOuterHTML(node, options); }).join("")
+        : "";
+}
+exports.getInnerHTML = getInnerHTML;
+/**
+ * Get a node's inner text. Same as `textContent`, but inserts newlines for `<br>` tags.
+ *
+ * @deprecated Use `textContent` instead.
+ * @param node Node to get the inner text of.
+ * @returns `node`'s inner text.
+ */
+function getText(node) {
+    if (Array.isArray(node))
+        return node.map(getText).join("");
+    if (domhandler_1.isTag(node))
+        return node.name === "br" ? "\n" : getText(node.children);
+    if (domhandler_1.isCDATA(node))
+        return getText(node.children);
+    if (domhandler_1.isText(node))
+        return node.data;
+    return "";
+}
+exports.getText = getText;
+/**
+ * Get a node's text content.
+ *
+ * @param node Node to get the text content of.
+ * @returns `node`'s text content.
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent}
+ */
+function textContent(node) {
+    if (Array.isArray(node))
+        return node.map(textContent).join("");
+    if (domhandler_1.isTag(node))
+        return textContent(node.children);
+    if (domhandler_1.isCDATA(node))
+        return textContent(node.children);
+    if (domhandler_1.isText(node))
+        return node.data;
+    return "";
+}
+exports.textContent = textContent;
+/**
+ * Get a node's inner text.
+ *
+ * @param node Node to get the inner text of.
+ * @returns `node`'s inner text.
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText}
+ */
+function innerText(node) {
+    if (Array.isArray(node))
+        return node.map(innerText).join("");
+    if (domhandler_1.hasChildren(node) && node.type === domelementtype_1.ElementType.Tag) {
+        return innerText(node.children);
+    }
+    if (domhandler_1.isCDATA(node))
+        return innerText(node.children);
+    if (domhandler_1.isText(node))
+        return node.data;
+    return "";
+}
+exports.innerText = innerText;
+
+
+/***/ }),
+/* 311 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.prevElementSibling = exports.nextElementSibling = exports.getName = exports.hasAttrib = exports.getAttributeValue = exports.getSiblings = exports.getParent = exports.getChildren = void 0;
+var domhandler_1 = __webpack_require__(306);
+var emptyArray = [];
+/**
+ * Get a node's children.
+ *
+ * @param elem Node to get the children of.
+ * @returns `elem`'s children, or an empty array.
+ */
+function getChildren(elem) {
+    var _a;
+    return (_a = elem.children) !== null && _a !== void 0 ? _a : emptyArray;
+}
+exports.getChildren = getChildren;
+/**
+ * Get a node's parent.
+ *
+ * @param elem Node to get the parent of.
+ * @returns `elem`'s parent node.
+ */
+function getParent(elem) {
+    return elem.parent || null;
+}
+exports.getParent = getParent;
+/**
+ * Gets an elements siblings, including the element itself.
+ *
+ * Attempts to get the children through the element's parent first.
+ * If we don't have a parent (the element is a root node),
+ * we walk the element's `prev` & `next` to get all remaining nodes.
+ *
+ * @param elem Element to get the siblings of.
+ * @returns `elem`'s siblings.
+ */
+function getSiblings(elem) {
+    var _a, _b;
+    var parent = getParent(elem);
+    if (parent != null)
+        return getChildren(parent);
+    var siblings = [elem];
+    var prev = elem.prev, next = elem.next;
+    while (prev != null) {
+        siblings.unshift(prev);
+        (_a = prev, prev = _a.prev);
+    }
+    while (next != null) {
+        siblings.push(next);
+        (_b = next, next = _b.next);
+    }
+    return siblings;
+}
+exports.getSiblings = getSiblings;
+/**
+ * Gets an attribute from an element.
+ *
+ * @param elem Element to check.
+ * @param name Attribute name to retrieve.
+ * @returns The element's attribute value, or `undefined`.
+ */
+function getAttributeValue(elem, name) {
+    var _a;
+    return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name];
+}
+exports.getAttributeValue = getAttributeValue;
+/**
+ * Checks whether an element has an attribute.
+ *
+ * @param elem Element to check.
+ * @param name Attribute name to look for.
+ * @returns Returns whether `elem` has the attribute `name`.
+ */
+function hasAttrib(elem, name) {
+    return (elem.attribs != null &&
+        Object.prototype.hasOwnProperty.call(elem.attribs, name) &&
+        elem.attribs[name] != null);
+}
+exports.hasAttrib = hasAttrib;
+/**
+ * Get the tag name of an element.
+ *
+ * @param elem The element to get the name for.
+ * @returns The tag name of `elem`.
+ */
+function getName(elem) {
+    return elem.name;
+}
+exports.getName = getName;
+/**
+ * Returns the next element sibling of a node.
+ *
+ * @param elem The element to get the next sibling of.
+ * @returns `elem`'s next sibling that is a tag.
+ */
+function nextElementSibling(elem) {
+    var _a;
+    var next = elem.next;
+    while (next !== null && !domhandler_1.isTag(next))
+        (_a = next, next = _a.next);
+    return next;
+}
+exports.nextElementSibling = nextElementSibling;
+/**
+ * Returns the previous element sibling of a node.
+ *
+ * @param elem The element to get the previous sibling of.
+ * @returns `elem`'s previous sibling that is a tag.
+ */
+function prevElementSibling(elem) {
+    var _a;
+    var prev = elem.prev;
+    while (prev !== null && !domhandler_1.isTag(prev))
+        (_a = prev, prev = _a.prev);
+    return prev;
+}
+exports.prevElementSibling = prevElementSibling;
+
+
+/***/ }),
+/* 312 */
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.prepend = exports.prependChild = exports.append = exports.appendChild = exports.replaceElement = exports.removeElement = void 0;
+/**
+ * Remove an element from the dom
+ *
+ * @param elem The element to be removed
+ */
+function removeElement(elem) {
+    if (elem.prev)
+        elem.prev.next = elem.next;
+    if (elem.next)
+        elem.next.prev = elem.prev;
+    if (elem.parent) {
+        var childs = elem.parent.children;
+        childs.splice(childs.lastIndexOf(elem), 1);
+    }
+}
+exports.removeElement = removeElement;
+/**
+ * Replace an element in the dom
+ *
+ * @param elem The element to be replaced
+ * @param replacement The element to be added
+ */
+function replaceElement(elem, replacement) {
+    var prev = (replacement.prev = elem.prev);
+    if (prev) {
+        prev.next = replacement;
+    }
+    var next = (replacement.next = elem.next);
+    if (next) {
+        next.prev = replacement;
+    }
+    var parent = (replacement.parent = elem.parent);
+    if (parent) {
+        var childs = parent.children;
+        childs[childs.lastIndexOf(elem)] = replacement;
+    }
+}
+exports.replaceElement = replaceElement;
+/**
+ * Append a child to an element.
+ *
+ * @param elem The element to append to.
+ * @param child The element to be added as a child.
+ */
+function appendChild(elem, child) {
+    removeElement(child);
+    child.next = null;
+    child.parent = elem;
+    if (elem.children.push(child) > 1) {
+        var sibling = elem.children[elem.children.length - 2];
+        sibling.next = child;
+        child.prev = sibling;
+    }
+    else {
+        child.prev = null;
+    }
+}
+exports.appendChild = appendChild;
+/**
+ * Append an element after another.
+ *
+ * @param elem The element to append after.
+ * @param next The element be added.
+ */
+function append(elem, next) {
+    removeElement(next);
+    var parent = elem.parent;
+    var currNext = elem.next;
+    next.next = currNext;
+    next.prev = elem;
+    elem.next = next;
+    next.parent = parent;
+    if (currNext) {
+        currNext.prev = next;
+        if (parent) {
+            var childs = parent.children;
+            childs.splice(childs.lastIndexOf(currNext), 0, next);
+        }
+    }
+    else if (parent) {
+        parent.children.push(next);
+    }
+}
+exports.append = append;
+/**
+ * Prepend a child to an element.
+ *
+ * @param elem The element to prepend before.
+ * @param child The element to be added as a child.
+ */
+function prependChild(elem, child) {
+    removeElement(child);
+    child.parent = elem;
+    child.prev = null;
+    if (elem.children.unshift(child) !== 1) {
+        var sibling = elem.children[1];
+        sibling.prev = child;
+        child.next = sibling;
+    }
+    else {
+        child.next = null;
+    }
+}
+exports.prependChild = prependChild;
+/**
+ * Prepend an element before another.
+ *
+ * @param elem The element to prepend before.
+ * @param prev The element be added.
+ */
+function prepend(elem, prev) {
+    removeElement(prev);
+    var parent = elem.parent;
+    if (parent) {
+        var childs = parent.children;
+        childs.splice(childs.indexOf(elem), 0, prev);
+    }
+    if (elem.prev) {
+        elem.prev.next = prev;
+    }
+    prev.parent = parent;
+    prev.prev = elem.prev;
+    prev.next = elem;
+    elem.prev = prev;
+}
+exports.prepend = prepend;
+
+
+/***/ }),
+/* 313 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.findAll = exports.existsOne = exports.findOne = exports.findOneChild = exports.find = exports.filter = void 0;
+var domhandler_1 = __webpack_require__(306);
+/**
+ * Search a node and its children for nodes passing a test function.
+ *
+ * @param test Function to test nodes on.
+ * @param node Node to search. Will be included in the result set if it matches.
+ * @param recurse Also consider child nodes.
+ * @param limit Maximum number of nodes to return.
+ * @returns All nodes passing `test`.
+ */
+function filter(test, node, recurse, limit) {
+    if (recurse === void 0) { recurse = true; }
+    if (limit === void 0) { limit = Infinity; }
+    if (!Array.isArray(node))
+        node = [node];
+    return find(test, node, recurse, limit);
+}
+exports.filter = filter;
+/**
+ * Search an array of node and its children for nodes passing a test function.
+ *
+ * @param test Function to test nodes on.
+ * @param nodes Array of nodes to search.
+ * @param recurse Also consider child nodes.
+ * @param limit Maximum number of nodes to return.
+ * @returns All nodes passing `test`.
+ */
+function find(test, nodes, recurse, limit) {
+    var result = [];
+    for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+        var elem = nodes_1[_i];
+        if (test(elem)) {
+            result.push(elem);
+            if (--limit <= 0)
+                break;
+        }
+        if (recurse && domhandler_1.hasChildren(elem) && elem.children.length > 0) {
+            var children = find(test, elem.children, recurse, limit);
+            result.push.apply(result, children);
+            limit -= children.length;
+            if (limit <= 0)
+                break;
+        }
+    }
+    return result;
+}
+exports.find = find;
+/**
+ * Finds the first element inside of an array that matches a test function.
+ *
+ * @param test Function to test nodes on.
+ * @param nodes Array of nodes to search.
+ * @returns The first node in the array that passes `test`.
+ */
+function findOneChild(test, nodes) {
+    return nodes.find(test);
+}
+exports.findOneChild = findOneChild;
+/**
+ * Finds one element in a tree that passes a test.
+ *
+ * @param test Function to test nodes on.
+ * @param nodes Array of nodes to search.
+ * @param recurse Also consider child nodes.
+ * @returns The first child node that passes `test`.
+ */
+function findOne(test, nodes, recurse) {
+    if (recurse === void 0) { recurse = true; }
+    var elem = null;
+    for (var i = 0; i < nodes.length && !elem; i++) {
+        var checked = nodes[i];
+        if (!domhandler_1.isTag(checked)) {
+            continue;
+        }
+        else if (test(checked)) {
+            elem = checked;
+        }
+        else if (recurse && checked.children.length > 0) {
+            elem = findOne(test, checked.children);
+        }
+    }
+    return elem;
+}
+exports.findOne = findOne;
+/**
+ * @param test Function to test nodes on.
+ * @param nodes Array of nodes to search.
+ * @returns Whether a tree of nodes contains at least one node passing a test.
+ */
+function existsOne(test, nodes) {
+    return nodes.some(function (checked) {
+        return domhandler_1.isTag(checked) &&
+            (test(checked) ||
+                (checked.children.length > 0 &&
+                    existsOne(test, checked.children)));
+    });
+}
+exports.existsOne = existsOne;
+/**
+ * Search and array of nodes and its children for nodes passing a test function.
+ *
+ * Same as `find`, only with less options, leading to reduced complexity.
+ *
+ * @param test Function to test nodes on.
+ * @param nodes Array of nodes to search.
+ * @returns All nodes passing `test`.
+ */
+function findAll(test, nodes) {
+    var _a;
+    var result = [];
+    var stack = nodes.filter(domhandler_1.isTag);
+    var elem;
+    while ((elem = stack.shift())) {
+        var children = (_a = elem.children) === null || _a === void 0 ? void 0 : _a.filter(domhandler_1.isTag);
+        if (children && children.length > 0) {
+            stack.unshift.apply(stack, children);
+        }
+        if (test(elem))
+            result.push(elem);
+    }
+    return result;
+}
+exports.findAll = findAll;
+
+
+/***/ }),
+/* 314 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.getElementsByTagType = exports.getElementsByTagName = exports.getElementById = exports.getElements = exports.testElement = void 0;
+var domhandler_1 = __webpack_require__(306);
+var querying_1 = __webpack_require__(313);
+var Checks = {
+    tag_name: function (name) {
+        if (typeof name === "function") {
+            return function (elem) { return domhandler_1.isTag(elem) && name(elem.name); };
+        }
+        else if (name === "*") {
+            return domhandler_1.isTag;
+        }
+        return function (elem) { return domhandler_1.isTag(elem) && elem.name === name; };
+    },
+    tag_type: function (type) {
+        if (typeof type === "function") {
+            return function (elem) { return type(elem.type); };
+        }
+        return function (elem) { return elem.type === type; };
+    },
+    tag_contains: function (data) {
+        if (typeof data === "function") {
+            return function (elem) { return domhandler_1.isText(elem) && data(elem.data); };
+        }
+        return function (elem) { return domhandler_1.isText(elem) && elem.data === data; };
+    },
+};
+/**
+ * @param attrib Attribute to check.
+ * @param value Attribute value to look for.
+ * @returns A function to check whether the a node has an attribute with a particular value.
+ */
+function getAttribCheck(attrib, value) {
+    if (typeof value === "function") {
+        return function (elem) { return domhandler_1.isTag(elem) && value(elem.attribs[attrib]); };
+    }
+    return function (elem) { return domhandler_1.isTag(elem) && elem.attribs[attrib] === value; };
+}
+/**
+ * @param a First function to combine.
+ * @param b Second function to combine.
+ * @returns A function taking a node and returning `true` if either
+ * of the input functions returns `true` for the node.
+ */
+function combineFuncs(a, b) {
+    return function (elem) { return a(elem) || b(elem); };
+}
+/**
+ * @param options An object describing nodes to look for.
+ * @returns A function executing all checks in `options` and returning `true`
+ * if any of them match a node.
+ */
+function compileTest(options) {
+    var funcs = Object.keys(options).map(function (key) {
+        var value = options[key];
+        return key in Checks
+            ? Checks[key](value)
+            : getAttribCheck(key, value);
+    });
+    return funcs.length === 0 ? null : funcs.reduce(combineFuncs);
+}
+/**
+ * @param options An object describing nodes to look for.
+ * @param node The element to test.
+ * @returns Whether the element matches the description in `options`.
+ */
+function testElement(options, node) {
+    var test = compileTest(options);
+    return test ? test(node) : true;
+}
+exports.testElement = testElement;
+/**
+ * @param options An object describing nodes to look for.
+ * @param nodes Nodes to search through.
+ * @param recurse Also consider child nodes.
+ * @param limit Maximum number of nodes to return.
+ * @returns All nodes that match `options`.
+ */
+function getElements(options, nodes, recurse, limit) {
+    if (limit === void 0) { limit = Infinity; }
+    var test = compileTest(options);
+    return test ? querying_1.filter(test, nodes, recurse, limit) : [];
+}
+exports.getElements = getElements;
+/**
+ * @param id The unique ID attribute value to look for.
+ * @param nodes Nodes to search through.
+ * @param recurse Also consider child nodes.
+ * @returns The node with the supplied ID.
+ */
+function getElementById(id, nodes, recurse) {
+    if (recurse === void 0) { recurse = true; }
+    if (!Array.isArray(nodes))
+        nodes = [nodes];
+    return querying_1.findOne(getAttribCheck("id", id), nodes, recurse);
+}
+exports.getElementById = getElementById;
+/**
+ * @param tagName Tag name to search for.
+ * @param nodes Nodes to search through.
+ * @param recurse Also consider child nodes.
+ * @param limit Maximum number of nodes to return.
+ * @returns All nodes with the supplied `tagName`.
+ */
+function getElementsByTagName(tagName, nodes, recurse, limit) {
+    if (recurse === void 0) { recurse = true; }
+    if (limit === void 0) { limit = Infinity; }
+    return querying_1.filter(Checks.tag_name(tagName), nodes, recurse, limit);
+}
+exports.getElementsByTagName = getElementsByTagName;
+/**
+ * @param type Element type to look for.
+ * @param nodes Nodes to search through.
+ * @param recurse Also consider child nodes.
+ * @param limit Maximum number of nodes to return.
+ * @returns All nodes with the supplied `type`.
+ */
+function getElementsByTagType(type, nodes, recurse, limit) {
+    if (recurse === void 0) { recurse = true; }
+    if (limit === void 0) { limit = Infinity; }
+    return querying_1.filter(Checks.tag_type(type), nodes, recurse, limit);
+}
+exports.getElementsByTagType = getElementsByTagType;
+
+
+/***/ }),
+/* 315 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.uniqueSort = exports.compareDocumentPosition = exports.removeSubsets = void 0;
+var domhandler_1 = __webpack_require__(306);
+/**
+ * Given an array of nodes, remove any member that is contained by another.
+ *
+ * @param nodes Nodes to filter.
+ * @returns Remaining nodes that aren't subtrees of each other.
+ */
+function removeSubsets(nodes) {
+    var idx = nodes.length;
+    /*
+     * Check if each node (or one of its ancestors) is already contained in the
+     * array.
+     */
+    while (--idx >= 0) {
+        var node = nodes[idx];
+        /*
+         * Remove the node if it is not unique.
+         * We are going through the array from the end, so we only
+         * have to check nodes that preceed the node under consideration in the array.
+         */
+        if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) {
+            nodes.splice(idx, 1);
+            continue;
+        }
+        for (var ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
+            if (nodes.includes(ancestor)) {
+                nodes.splice(idx, 1);
+                break;
+            }
+        }
+    }
+    return nodes;
+}
+exports.removeSubsets = removeSubsets;
+/**
+ * Compare the position of one node against another node in any other document.
+ * The return value is a bitmask with the following values:
+ *
+ * Document order:
+ * > There is an ordering, document order, defined on all the nodes in the
+ * > document corresponding to the order in which the first character of the
+ * > XML representation of each node occurs in the XML representation of the
+ * > document after expansion of general entities. Thus, the document element
+ * > node will be the first node. Element nodes occur before their children.
+ * > Thus, document order orders element nodes in order of the occurrence of
+ * > their start-tag in the XML (after expansion of entities). The attribute
+ * > nodes of an element occur after the element and before its children. The
+ * > relative order of attribute nodes is implementation-dependent./
+ *
+ * Source:
+ * http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
+ *
+ * @param nodeA The first node to use in the comparison
+ * @param nodeB The second node to use in the comparison
+ * @returns A bitmask describing the input nodes' relative position.
+ *
+ * See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
+ * a description of these values.
+ */
+function compareDocumentPosition(nodeA, nodeB) {
+    var aParents = [];
+    var bParents = [];
+    if (nodeA === nodeB) {
+        return 0;
+    }
+    var current = domhandler_1.hasChildren(nodeA) ? nodeA : nodeA.parent;
+    while (current) {
+        aParents.unshift(current);
+        current = current.parent;
+    }
+    current = domhandler_1.hasChildren(nodeB) ? nodeB : nodeB.parent;
+    while (current) {
+        bParents.unshift(current);
+        current = current.parent;
+    }
+    var maxIdx = Math.min(aParents.length, bParents.length);
+    var idx = 0;
+    while (idx < maxIdx && aParents[idx] === bParents[idx]) {
+        idx++;
+    }
+    if (idx === 0) {
+        return 1 /* DISCONNECTED */;
+    }
+    var sharedParent = aParents[idx - 1];
+    var siblings = sharedParent.children;
+    var aSibling = aParents[idx];
+    var bSibling = bParents[idx];
+    if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
+        if (sharedParent === nodeB) {
+            return 4 /* FOLLOWING */ | 16 /* CONTAINED_BY */;
+        }
+        return 4 /* FOLLOWING */;
+    }
+    if (sharedParent === nodeA) {
+        return 2 /* PRECEDING */ | 8 /* CONTAINS */;
+    }
+    return 2 /* PRECEDING */;
+}
+exports.compareDocumentPosition = compareDocumentPosition;
+/**
+ * Sort an array of nodes based on their relative position in the document and
+ * remove any duplicate nodes. If the array contains nodes that do not belong
+ * to the same document, sort order is unspecified.
+ *
+ * @param nodes Array of DOM nodes.
+ * @returns Collection of unique nodes, sorted in document order.
+ */
+function uniqueSort(nodes) {
+    nodes = nodes.filter(function (node, i, arr) { return !arr.includes(node, i + 1); });
+    nodes.sort(function (a, b) {
+        var relative = compareDocumentPosition(a, b);
+        if (relative & 2 /* PRECEDING */) {
+            return -1;
+        }
+        else if (relative & 4 /* FOLLOWING */) {
+            return 1;
+        }
+        return 0;
+    });
+    return nodes;
+}
+exports.uniqueSort = uniqueSort;
+
+
+/***/ }),
+/* 316 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.render = exports.parse = void 0;
-var tslib_1 = __webpack_require__(256);
-var domhandler_1 = __webpack_require__(268);
-var parse5_1 = __webpack_require__(307);
-var parse5_htmlparser2_tree_adapter_1 = tslib_1.__importDefault(__webpack_require__(331));
+var tslib_1 = __webpack_require__(257);
+var domhandler_1 = __webpack_require__(317);
+var parse5_1 = __webpack_require__(319);
+var parse5_htmlparser2_tree_adapter_1 = tslib_1.__importDefault(__webpack_require__(343));
 function parse(content, options, isDocument) {
     var opts = {
         scriptingEnabled: typeof options.scriptingEnabled === 'boolean'
@@ -47181,93 +48610,666 @@ exports.render = render;
 
 
 /***/ }),
-/* 307 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 317 */
+/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
 
-
-const Parser = __webpack_require__(308);
-const Serializer = __webpack_require__(330);
-
-// Shorthands
-exports.parse = function parse(html, options) {
-    const parser = new Parser(options);
-
-    return parser.parse(html);
-};
-
-exports.parseFragment = function parseFragment(fragmentContext, html, options) {
-    if (typeof fragmentContext === 'string') {
-        options = html;
-        html = fragmentContext;
-        fragmentContext = null;
-    }
-
-    const parser = new Parser(options);
-
-    return parser.parseFragment(html, fragmentContext);
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
 };
-
-exports.serialize = function(node, options) {
-    const serializer = new Serializer(node, options);
-
-    return serializer.serialize();
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.DomHandler = void 0;
+var domelementtype_1 = __webpack_require__(270);
+var node_1 = __webpack_require__(318);
+__exportStar(__webpack_require__(318), exports);
+var reWhitespace = /\s+/g;
+// Default options
+var defaultOpts = {
+    normalizeWhitespace: false,
+    withStartIndices: false,
+    withEndIndices: false,
 };
+var DomHandler = /** @class */ (function () {
+    /**
+     * @param callback Called once parsing has completed.
+     * @param options Settings for the handler.
+     * @param elementCB Callback whenever a tag is closed.
+     */
+    function DomHandler(callback, options, elementCB) {
+        /** The elements of the DOM */
+        this.dom = [];
+        /** The root element for the DOM */
+        this.root = new node_1.Document(this.dom);
+        /** Indicated whether parsing has been completed. */
+        this.done = false;
+        /** Stack of open tags. */
+        this.tagStack = [this.root];
+        /** A data node that is still being written to. */
+        this.lastNode = null;
+        /** Reference to the parser instance. Used for location information. */
+        this.parser = null;
+        // Make it possible to skip arguments, for backwards-compatibility
+        if (typeof options === "function") {
+            elementCB = options;
+            options = defaultOpts;
+        }
+        if (typeof callback === "object") {
+            options = callback;
+            callback = undefined;
+        }
+        this.callback = callback !== null && callback !== void 0 ? callback : null;
+        this.options = options !== null && options !== void 0 ? options : defaultOpts;
+        this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;
+    }
+    DomHandler.prototype.onparserinit = function (parser) {
+        this.parser = parser;
+    };
+    // Resets the handler back to starting state
+    DomHandler.prototype.onreset = function () {
+        var _a;
+        this.dom = [];
+        this.root = new node_1.Document(this.dom);
+        this.done = false;
+        this.tagStack = [this.root];
+        this.lastNode = null;
+        this.parser = (_a = this.parser) !== null && _a !== void 0 ? _a : null;
+    };
+    // Signals the handler that parsing is done
+    DomHandler.prototype.onend = function () {
+        if (this.done)
+            return;
+        this.done = true;
+        this.parser = null;
+        this.handleCallback(null);
+    };
+    DomHandler.prototype.onerror = function (error) {
+        this.handleCallback(error);
+    };
+    DomHandler.prototype.onclosetag = function () {
+        this.lastNode = null;
+        var elem = this.tagStack.pop();
+        if (this.options.withEndIndices) {
+            elem.endIndex = this.parser.endIndex;
+        }
+        if (this.elementCB)
+            this.elementCB(elem);
+    };
+    DomHandler.prototype.onopentag = function (name, attribs) {
+        var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined;
+        var element = new node_1.Element(name, attribs, undefined, type);
+        this.addNode(element);
+        this.tagStack.push(element);
+    };
+    DomHandler.prototype.ontext = function (data) {
+        var normalizeWhitespace = this.options.normalizeWhitespace;
+        var lastNode = this.lastNode;
+        if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) {
+            if (normalizeWhitespace) {
+                lastNode.data = (lastNode.data + data).replace(reWhitespace, " ");
+            }
+            else {
+                lastNode.data += data;
+            }
+        }
+        else {
+            if (normalizeWhitespace) {
+                data = data.replace(reWhitespace, " ");
+            }
+            var node = new node_1.Text(data);
+            this.addNode(node);
+            this.lastNode = node;
+        }
+    };
+    DomHandler.prototype.oncomment = function (data) {
+        if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) {
+            this.lastNode.data += data;
+            return;
+        }
+        var node = new node_1.Comment(data);
+        this.addNode(node);
+        this.lastNode = node;
+    };
+    DomHandler.prototype.oncommentend = function () {
+        this.lastNode = null;
+    };
+    DomHandler.prototype.oncdatastart = function () {
+        var text = new node_1.Text("");
+        var node = new node_1.NodeWithChildren(domelementtype_1.ElementType.CDATA, [text]);
+        this.addNode(node);
+        text.parent = node;
+        this.lastNode = text;
+    };
+    DomHandler.prototype.oncdataend = function () {
+        this.lastNode = null;
+    };
+    DomHandler.prototype.onprocessinginstruction = function (name, data) {
+        var node = new node_1.ProcessingInstruction(name, data);
+        this.addNode(node);
+    };
+    DomHandler.prototype.handleCallback = function (error) {
+        if (typeof this.callback === "function") {
+            this.callback(error, this.dom);
+        }
+        else if (error) {
+            throw error;
+        }
+    };
+    DomHandler.prototype.addNode = function (node) {
+        var parent = this.tagStack[this.tagStack.length - 1];
+        var previousSibling = parent.children[parent.children.length - 1];
+        if (this.options.withStartIndices) {
+            node.startIndex = this.parser.startIndex;
+        }
+        if (this.options.withEndIndices) {
+            node.endIndex = this.parser.endIndex;
+        }
+        parent.children.push(node);
+        if (previousSibling) {
+            node.prev = previousSibling;
+            previousSibling.next = node;
+        }
+        node.parent = parent;
+        this.lastNode = null;
+    };
+    return DomHandler;
+}());
+exports.DomHandler = DomHandler;
+exports["default"] = DomHandler;
 
 
 /***/ }),
-/* 308 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 318 */
+/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
 
-
-const Tokenizer = __webpack_require__(309);
-const OpenElementStack = __webpack_require__(314);
-const FormattingElementList = __webpack_require__(316);
-const LocationInfoParserMixin = __webpack_require__(317);
-const ErrorReportingParserMixin = __webpack_require__(322);
-const Mixin = __webpack_require__(318);
-const defaultTreeAdapter = __webpack_require__(326);
-const mergeOptions = __webpack_require__(327);
-const doctype = __webpack_require__(328);
-const foreignContent = __webpack_require__(329);
-const ERR = __webpack_require__(312);
-const unicode = __webpack_require__(311);
-const HTML = __webpack_require__(315);
-
-//Aliases
-const $ = HTML.TAG_NAMES;
-const NS = HTML.NAMESPACES;
-const ATTRS = HTML.ATTRS;
-
-const DEFAULT_OPTIONS = {
-    scriptingEnabled: true,
-    sourceCodeLocationInfo: false,
-    onParseError: null,
-    treeAdapter: defaultTreeAdapter
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        if (typeof b !== "function" && b !== null)
+            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
 };
-
-//Misc constants
-const HIDDEN_INPUT_TYPE = 'hidden';
-
-//Adoption agency loops iteration count
-const AA_OUTER_LOOP_ITER = 8;
-const AA_INNER_LOOP_ITER = 3;
-
-//Insertion modes
-const INITIAL_MODE = 'INITIAL_MODE';
-const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE';
-const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE';
-const IN_HEAD_MODE = 'IN_HEAD_MODE';
-const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE';
-const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE';
-const IN_BODY_MODE = 'IN_BODY_MODE';
-const TEXT_MODE = 'TEXT_MODE';
-const IN_TABLE_MODE = 'IN_TABLE_MODE';
-const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE';
-const IN_CAPTION_MODE = 'IN_CAPTION_MODE';
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0;
+var domelementtype_1 = __webpack_require__(270);
+var nodeTypes = new Map([
+    [domelementtype_1.ElementType.Tag, 1],
+    [domelementtype_1.ElementType.Script, 1],
+    [domelementtype_1.ElementType.Style, 1],
+    [domelementtype_1.ElementType.Directive, 1],
+    [domelementtype_1.ElementType.Text, 3],
+    [domelementtype_1.ElementType.CDATA, 4],
+    [domelementtype_1.ElementType.Comment, 8],
+    [domelementtype_1.ElementType.Root, 9],
+]);
+/**
+ * This object will be used as the prototype for Nodes when creating a
+ * DOM-Level-1-compliant structure.
+ */
+var Node = /** @class */ (function () {
+    /**
+     *
+     * @param type The type of the node.
+     */
+    function Node(type) {
+        this.type = type;
+        /** Parent of the node */
+        this.parent = null;
+        /** Previous sibling */
+        this.prev = null;
+        /** Next sibling */
+        this.next = null;
+        /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */
+        this.startIndex = null;
+        /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */
+        this.endIndex = null;
+    }
+    Object.defineProperty(Node.prototype, "nodeType", {
+        // Read-only aliases
+        get: function () {
+            var _a;
+            return (_a = nodeTypes.get(this.type)) !== null && _a !== void 0 ? _a : 1;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Node.prototype, "parentNode", {
+        // Read-write aliases for properties
+        get: function () {
+            return this.parent;
+        },
+        set: function (parent) {
+            this.parent = parent;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Node.prototype, "previousSibling", {
+        get: function () {
+            return this.prev;
+        },
+        set: function (prev) {
+            this.prev = prev;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Node.prototype, "nextSibling", {
+        get: function () {
+            return this.next;
+        },
+        set: function (next) {
+            this.next = next;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    /**
+     * Clone this node, and optionally its children.
+     *
+     * @param recursive Clone child nodes as well.
+     * @returns A clone of the node.
+     */
+    Node.prototype.cloneNode = function (recursive) {
+        if (recursive === void 0) { recursive = false; }
+        return cloneNode(this, recursive);
+    };
+    return Node;
+}());
+exports.Node = Node;
+var DataNode = /** @class */ (function (_super) {
+    __extends(DataNode, _super);
+    /**
+     * @param type The type of the node
+     * @param data The content of the data node
+     */
+    function DataNode(type, data) {
+        var _this = _super.call(this, type) || this;
+        _this.data = data;
+        return _this;
+    }
+    Object.defineProperty(DataNode.prototype, "nodeValue", {
+        get: function () {
+            return this.data;
+        },
+        set: function (data) {
+            this.data = data;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    return DataNode;
+}(Node));
+exports.DataNode = DataNode;
+var Text = /** @class */ (function (_super) {
+    __extends(Text, _super);
+    function Text(data) {
+        return _super.call(this, domelementtype_1.ElementType.Text, data) || this;
+    }
+    return Text;
+}(DataNode));
+exports.Text = Text;
+var Comment = /** @class */ (function (_super) {
+    __extends(Comment, _super);
+    function Comment(data) {
+        return _super.call(this, domelementtype_1.ElementType.Comment, data) || this;
+    }
+    return Comment;
+}(DataNode));
+exports.Comment = Comment;
+var ProcessingInstruction = /** @class */ (function (_super) {
+    __extends(ProcessingInstruction, _super);
+    function ProcessingInstruction(name, data) {
+        var _this = _super.call(this, domelementtype_1.ElementType.Directive, data) || this;
+        _this.name = name;
+        return _this;
+    }
+    return ProcessingInstruction;
+}(DataNode));
+exports.ProcessingInstruction = ProcessingInstruction;
+/**
+ * A `Node` that can have children.
+ */
+var NodeWithChildren = /** @class */ (function (_super) {
+    __extends(NodeWithChildren, _super);
+    /**
+     * @param type Type of the node.
+     * @param children Children of the node. Only certain node types can have children.
+     */
+    function NodeWithChildren(type, children) {
+        var _this = _super.call(this, type) || this;
+        _this.children = children;
+        return _this;
+    }
+    Object.defineProperty(NodeWithChildren.prototype, "firstChild", {
+        // Aliases
+        get: function () {
+            var _a;
+            return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(NodeWithChildren.prototype, "lastChild", {
+        get: function () {
+            return this.children.length > 0
+                ? this.children[this.children.length - 1]
+                : null;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(NodeWithChildren.prototype, "childNodes", {
+        get: function () {
+            return this.children;
+        },
+        set: function (children) {
+            this.children = children;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    return NodeWithChildren;
+}(Node));
+exports.NodeWithChildren = NodeWithChildren;
+var Document = /** @class */ (function (_super) {
+    __extends(Document, _super);
+    function Document(children) {
+        return _super.call(this, domelementtype_1.ElementType.Root, children) || this;
+    }
+    return Document;
+}(NodeWithChildren));
+exports.Document = Document;
+var Element = /** @class */ (function (_super) {
+    __extends(Element, _super);
+    /**
+     * @param name Name of the tag, eg. `div`, `span`.
+     * @param attribs Object mapping attribute names to attribute values.
+     * @param children Children of the node.
+     */
+    function Element(name, attribs, children, type) {
+        if (children === void 0) { children = []; }
+        if (type === void 0) { type = name === "script"
+            ? domelementtype_1.ElementType.Script
+            : name === "style"
+                ? domelementtype_1.ElementType.Style
+                : domelementtype_1.ElementType.Tag; }
+        var _this = _super.call(this, type, children) || this;
+        _this.name = name;
+        _this.attribs = attribs;
+        return _this;
+    }
+    Object.defineProperty(Element.prototype, "tagName", {
+        // DOM Level 1 aliases
+        get: function () {
+            return this.name;
+        },
+        set: function (name) {
+            this.name = name;
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(Element.prototype, "attributes", {
+        get: function () {
+            var _this = this;
+            return Object.keys(this.attribs).map(function (name) {
+                var _a, _b;
+                return ({
+                    name: name,
+                    value: _this.attribs[name],
+                    namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name],
+                    prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name],
+                });
+            });
+        },
+        enumerable: false,
+        configurable: true
+    });
+    return Element;
+}(NodeWithChildren));
+exports.Element = Element;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node is a `Element`, `false` otherwise.
+ */
+function isTag(node) {
+    return domelementtype_1.isTag(node);
+}
+exports.isTag = isTag;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `CDATA`, `false` otherwise.
+ */
+function isCDATA(node) {
+    return node.type === domelementtype_1.ElementType.CDATA;
+}
+exports.isCDATA = isCDATA;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `Text`, `false` otherwise.
+ */
+function isText(node) {
+    return node.type === domelementtype_1.ElementType.Text;
+}
+exports.isText = isText;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `Comment`, `false` otherwise.
+ */
+function isComment(node) {
+    return node.type === domelementtype_1.ElementType.Comment;
+}
+exports.isComment = isComment;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
+ */
+function isDirective(node) {
+    return node.type === domelementtype_1.ElementType.Directive;
+}
+exports.isDirective = isDirective;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
+ */
+function isDocument(node) {
+    return node.type === domelementtype_1.ElementType.Root;
+}
+exports.isDocument = isDocument;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise.
+ */
+function hasChildren(node) {
+    return Object.prototype.hasOwnProperty.call(node, "children");
+}
+exports.hasChildren = hasChildren;
+/**
+ * Clone a node, and optionally its children.
+ *
+ * @param recursive Clone child nodes as well.
+ * @returns A clone of the node.
+ */
+function cloneNode(node, recursive) {
+    if (recursive === void 0) { recursive = false; }
+    var result;
+    if (isText(node)) {
+        result = new Text(node.data);
+    }
+    else if (isComment(node)) {
+        result = new Comment(node.data);
+    }
+    else if (isTag(node)) {
+        var children = recursive ? cloneChildren(node.children) : [];
+        var clone_1 = new Element(node.name, __assign({}, node.attribs), children);
+        children.forEach(function (child) { return (child.parent = clone_1); });
+        if (node["x-attribsNamespace"]) {
+            clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]);
+        }
+        if (node["x-attribsPrefix"]) {
+            clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]);
+        }
+        result = clone_1;
+    }
+    else if (isCDATA(node)) {
+        var children = recursive ? cloneChildren(node.children) : [];
+        var clone_2 = new NodeWithChildren(domelementtype_1.ElementType.CDATA, children);
+        children.forEach(function (child) { return (child.parent = clone_2); });
+        result = clone_2;
+    }
+    else if (isDocument(node)) {
+        var children = recursive ? cloneChildren(node.children) : [];
+        var clone_3 = new Document(children);
+        children.forEach(function (child) { return (child.parent = clone_3); });
+        if (node["x-mode"]) {
+            clone_3["x-mode"] = node["x-mode"];
+        }
+        result = clone_3;
+    }
+    else if (isDirective(node)) {
+        var instruction = new ProcessingInstruction(node.name, node.data);
+        if (node["x-name"] != null) {
+            instruction["x-name"] = node["x-name"];
+            instruction["x-publicId"] = node["x-publicId"];
+            instruction["x-systemId"] = node["x-systemId"];
+        }
+        result = instruction;
+    }
+    else {
+        throw new Error("Not implemented yet: " + node.type);
+    }
+    result.startIndex = node.startIndex;
+    result.endIndex = node.endIndex;
+    return result;
+}
+exports.cloneNode = cloneNode;
+function cloneChildren(childs) {
+    var children = childs.map(function (child) { return cloneNode(child, true); });
+    for (var i = 1; i < children.length; i++) {
+        children[i].prev = children[i - 1];
+        children[i - 1].next = children[i];
+    }
+    return children;
+}
+
+
+/***/ }),
+/* 319 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+
+const Parser = __webpack_require__(320);
+const Serializer = __webpack_require__(342);
+
+// Shorthands
+exports.parse = function parse(html, options) {
+    const parser = new Parser(options);
+
+    return parser.parse(html);
+};
+
+exports.parseFragment = function parseFragment(fragmentContext, html, options) {
+    if (typeof fragmentContext === 'string') {
+        options = html;
+        html = fragmentContext;
+        fragmentContext = null;
+    }
+
+    const parser = new Parser(options);
+
+    return parser.parseFragment(html, fragmentContext);
+};
+
+exports.serialize = function(node, options) {
+    const serializer = new Serializer(node, options);
+
+    return serializer.serialize();
+};
+
+
+/***/ }),
+/* 320 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+"use strict";
+
+
+const Tokenizer = __webpack_require__(321);
+const OpenElementStack = __webpack_require__(326);
+const FormattingElementList = __webpack_require__(328);
+const LocationInfoParserMixin = __webpack_require__(329);
+const ErrorReportingParserMixin = __webpack_require__(334);
+const Mixin = __webpack_require__(330);
+const defaultTreeAdapter = __webpack_require__(338);
+const mergeOptions = __webpack_require__(339);
+const doctype = __webpack_require__(340);
+const foreignContent = __webpack_require__(341);
+const ERR = __webpack_require__(324);
+const unicode = __webpack_require__(323);
+const HTML = __webpack_require__(327);
+
+//Aliases
+const $ = HTML.TAG_NAMES;
+const NS = HTML.NAMESPACES;
+const ATTRS = HTML.ATTRS;
+
+const DEFAULT_OPTIONS = {
+    scriptingEnabled: true,
+    sourceCodeLocationInfo: false,
+    onParseError: null,
+    treeAdapter: defaultTreeAdapter
+};
+
+//Misc constants
+const HIDDEN_INPUT_TYPE = 'hidden';
+
+//Adoption agency loops iteration count
+const AA_OUTER_LOOP_ITER = 8;
+const AA_INNER_LOOP_ITER = 3;
+
+//Insertion modes
+const INITIAL_MODE = 'INITIAL_MODE';
+const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE';
+const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE';
+const IN_HEAD_MODE = 'IN_HEAD_MODE';
+const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE';
+const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE';
+const IN_BODY_MODE = 'IN_BODY_MODE';
+const TEXT_MODE = 'TEXT_MODE';
+const IN_TABLE_MODE = 'IN_TABLE_MODE';
+const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE';
+const IN_CAPTION_MODE = 'IN_CAPTION_MODE';
 const IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE';
 const IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE';
 const IN_ROW_MODE = 'IN_ROW_MODE';
@@ -50180,16 +52182,16 @@ function endTagInForeignContent(p, token) {
 
 
 /***/ }),
-/* 309 */
+/* 321 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Preprocessor = __webpack_require__(310);
-const unicode = __webpack_require__(311);
-const neTree = __webpack_require__(313);
-const ERR = __webpack_require__(312);
+const Preprocessor = __webpack_require__(322);
+const unicode = __webpack_require__(323);
+const neTree = __webpack_require__(325);
+const ERR = __webpack_require__(324);
 
 //Aliases
 const $ = unicode.CODE_POINTS;
@@ -52383,14 +54385,14 @@ module.exports = Tokenizer;
 
 
 /***/ }),
-/* 310 */
+/* 322 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const unicode = __webpack_require__(311);
-const ERR = __webpack_require__(312);
+const unicode = __webpack_require__(323);
+const ERR = __webpack_require__(324);
 
 //Aliases
 const $ = unicode.CODE_POINTS;
@@ -52549,7 +54551,7 @@ module.exports = Preprocessor;
 
 
 /***/ }),
-/* 311 */
+/* 323 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -52665,7 +54667,7 @@ exports.isUndefinedCodePoint = function(cp) {
 
 
 /***/ }),
-/* 312 */
+/* 324 */
 /***/ ((module) => {
 
 "use strict";
@@ -52737,7 +54739,7 @@ module.exports = {
 
 
 /***/ }),
-/* 313 */
+/* 325 */
 /***/ ((module) => {
 
 "use strict";
@@ -52748,13 +54750,13 @@ module.exports = {
 module.exports = new Uint16Array([4,52,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,106,303,412,810,1432,1701,1796,1987,2114,2360,2420,2484,3170,3251,4140,4393,4575,4610,5106,5512,5728,6117,6274,6315,6345,6427,6516,7002,7910,8733,9323,9870,10170,10631,10893,11318,11386,11467,12773,13092,14474,14922,15448,15542,16419,17666,18166,18611,19004,19095,19298,19397,4,16,69,77,97,98,99,102,103,108,109,110,111,112,114,115,116,117,140,150,158,169,176,194,199,210,216,222,226,242,256,266,283,294,108,105,103,5,198,1,59,148,1,198,80,5,38,1,59,156,1,38,99,117,116,101,5,193,1,59,167,1,193,114,101,118,101,59,1,258,4,2,105,121,182,191,114,99,5,194,1,59,189,1,194,59,1,1040,114,59,3,55349,56580,114,97,118,101,5,192,1,59,208,1,192,112,104,97,59,1,913,97,99,114,59,1,256,100,59,1,10835,4,2,103,112,232,237,111,110,59,1,260,102,59,3,55349,56632,112,108,121,70,117,110,99,116,105,111,110,59,1,8289,105,110,103,5,197,1,59,264,1,197,4,2,99,115,272,277,114,59,3,55349,56476,105,103,110,59,1,8788,105,108,100,101,5,195,1,59,292,1,195,109,108,5,196,1,59,301,1,196,4,8,97,99,101,102,111,114,115,117,321,350,354,383,388,394,400,405,4,2,99,114,327,336,107,115,108,97,115,104,59,1,8726,4,2,118,119,342,345,59,1,10983,101,100,59,1,8966,121,59,1,1041,4,3,99,114,116,362,369,379,97,117,115,101,59,1,8757,110,111,117,108,108,105,115,59,1,8492,97,59,1,914,114,59,3,55349,56581,112,102,59,3,55349,56633,101,118,101,59,1,728,99,114,59,1,8492,109,112,101,113,59,1,8782,4,14,72,79,97,99,100,101,102,104,105,108,111,114,115,117,442,447,456,504,542,547,569,573,577,616,678,784,790,796,99,121,59,1,1063,80,89,5,169,1,59,454,1,169,4,3,99,112,121,464,470,497,117,116,101,59,1,262,4,2,59,105,476,478,1,8914,116,97,108,68,105,102,102,101,114,101,110,116,105,97,108,68,59,1,8517,108,101,121,115,59,1,8493,4,4,97,101,105,111,514,520,530,535,114,111,110,59,1,268,100,105,108,5,199,1,59,528,1,199,114,99,59,1,264,110,105,110,116,59,1,8752,111,116,59,1,266,4,2,100,110,553,560,105,108,108,97,59,1,184,116,101,114,68,111,116,59,1,183,114,59,1,8493,105,59,1,935,114,99,108,101,4,4,68,77,80,84,591,596,603,609,111,116,59,1,8857,105,110,117,115,59,1,8854,108,117,115,59,1,8853,105,109,101,115,59,1,8855,111,4,2,99,115,623,646,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8754,101,67,117,114,108,121,4,2,68,81,658,671,111,117,98,108,101,81,117,111,116,101,59,1,8221,117,111,116,101,59,1,8217,4,4,108,110,112,117,688,701,736,753,111,110,4,2,59,101,696,698,1,8759,59,1,10868,4,3,103,105,116,709,717,722,114,117,101,110,116,59,1,8801,110,116,59,1,8751,111,117,114,73,110,116,101,103,114,97,108,59,1,8750,4,2,102,114,742,745,59,1,8450,111,100,117,99,116,59,1,8720,110,116,101,114,67,108,111,99,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8755,111,115,115,59,1,10799,99,114,59,3,55349,56478,112,4,2,59,67,803,805,1,8915,97,112,59,1,8781,4,11,68,74,83,90,97,99,101,102,105,111,115,834,850,855,860,865,888,903,916,921,1011,1415,4,2,59,111,840,842,1,8517,116,114,97,104,100,59,1,10513,99,121,59,1,1026,99,121,59,1,1029,99,121,59,1,1039,4,3,103,114,115,873,879,883,103,101,114,59,1,8225,114,59,1,8609,104,118,59,1,10980,4,2,97,121,894,900,114,111,110,59,1,270,59,1,1044,108,4,2,59,116,910,912,1,8711,97,59,1,916,114,59,3,55349,56583,4,2,97,102,927,998,4,2,99,109,933,992,114,105,116,105,99,97,108,4,4,65,68,71,84,950,957,978,985,99,117,116,101,59,1,180,111,4,2,116,117,964,967,59,1,729,98,108,101,65,99,117,116,101,59,1,733,114,97,118,101,59,1,96,105,108,100,101,59,1,732,111,110,100,59,1,8900,102,101,114,101,110,116,105,97,108,68,59,1,8518,4,4,112,116,117,119,1021,1026,1048,1249,102,59,3,55349,56635,4,3,59,68,69,1034,1036,1041,1,168,111,116,59,1,8412,113,117,97,108,59,1,8784,98,108,101,4,6,67,68,76,82,85,86,1065,1082,1101,1189,1211,1236,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8751,111,4,2,116,119,1089,1092,59,1,168,110,65,114,114,111,119,59,1,8659,4,2,101,111,1107,1141,102,116,4,3,65,82,84,1117,1124,1136,114,114,111,119,59,1,8656,105,103,104,116,65,114,114,111,119,59,1,8660,101,101,59,1,10980,110,103,4,2,76,82,1149,1177,101,102,116,4,2,65,82,1158,1165,114,114,111,119,59,1,10232,105,103,104,116,65,114,114,111,119,59,1,10234,105,103,104,116,65,114,114,111,119,59,1,10233,105,103,104,116,4,2,65,84,1199,1206,114,114,111,119,59,1,8658,101,101,59,1,8872,112,4,2,65,68,1218,1225,114,114,111,119,59,1,8657,111,119,110,65,114,114,111,119,59,1,8661,101,114,116,105,99,97,108,66,97,114,59,1,8741,110,4,6,65,66,76,82,84,97,1264,1292,1299,1352,1391,1408,114,114,111,119,4,3,59,66,85,1276,1278,1283,1,8595,97,114,59,1,10515,112,65,114,114,111,119,59,1,8693,114,101,118,101,59,1,785,101,102,116,4,3,82,84,86,1310,1323,1334,105,103,104,116,86,101,99,116,111,114,59,1,10576,101,101,86,101,99,116,111,114,59,1,10590,101,99,116,111,114,4,2,59,66,1345,1347,1,8637,97,114,59,1,10582,105,103,104,116,4,2,84,86,1362,1373,101,101,86,101,99,116,111,114,59,1,10591,101,99,116,111,114,4,2,59,66,1384,1386,1,8641,97,114,59,1,10583,101,101,4,2,59,65,1399,1401,1,8868,114,114,111,119,59,1,8615,114,114,111,119,59,1,8659,4,2,99,116,1421,1426,114,59,3,55349,56479,114,111,107,59,1,272,4,16,78,84,97,99,100,102,103,108,109,111,112,113,115,116,117,120,1466,1470,1478,1489,1515,1520,1525,1536,1544,1593,1609,1617,1650,1664,1668,1677,71,59,1,330,72,5,208,1,59,1476,1,208,99,117,116,101,5,201,1,59,1487,1,201,4,3,97,105,121,1497,1503,1512,114,111,110,59,1,282,114,99,5,202,1,59,1510,1,202,59,1,1069,111,116,59,1,278,114,59,3,55349,56584,114,97,118,101,5,200,1,59,1534,1,200,101,109,101,110,116,59,1,8712,4,2,97,112,1550,1555,99,114,59,1,274,116,121,4,2,83,86,1563,1576,109,97,108,108,83,113,117,97,114,101,59,1,9723,101,114,121,83,109,97,108,108,83,113,117,97,114,101,59,1,9643,4,2,103,112,1599,1604,111,110,59,1,280,102,59,3,55349,56636,115,105,108,111,110,59,1,917,117,4,2,97,105,1624,1640,108,4,2,59,84,1631,1633,1,10869,105,108,100,101,59,1,8770,108,105,98,114,105,117,109,59,1,8652,4,2,99,105,1656,1660,114,59,1,8496,109,59,1,10867,97,59,1,919,109,108,5,203,1,59,1675,1,203,4,2,105,112,1683,1689,115,116,115,59,1,8707,111,110,101,110,116,105,97,108,69,59,1,8519,4,5,99,102,105,111,115,1713,1717,1722,1762,1791,121,59,1,1060,114,59,3,55349,56585,108,108,101,100,4,2,83,86,1732,1745,109,97,108,108,83,113,117,97,114,101,59,1,9724,101,114,121,83,109,97,108,108,83,113,117,97,114,101,59,1,9642,4,3,112,114,117,1770,1775,1781,102,59,3,55349,56637,65,108,108,59,1,8704,114,105,101,114,116,114,102,59,1,8497,99,114,59,1,8497,4,12,74,84,97,98,99,100,102,103,111,114,115,116,1822,1827,1834,1848,1855,1877,1882,1887,1890,1896,1978,1984,99,121,59,1,1027,5,62,1,59,1832,1,62,109,109,97,4,2,59,100,1843,1845,1,915,59,1,988,114,101,118,101,59,1,286,4,3,101,105,121,1863,1869,1874,100,105,108,59,1,290,114,99,59,1,284,59,1,1043,111,116,59,1,288,114,59,3,55349,56586,59,1,8921,112,102,59,3,55349,56638,101,97,116,101,114,4,6,69,70,71,76,83,84,1915,1933,1944,1953,1959,1971,113,117,97,108,4,2,59,76,1925,1927,1,8805,101,115,115,59,1,8923,117,108,108,69,113,117,97,108,59,1,8807,114,101,97,116,101,114,59,1,10914,101,115,115,59,1,8823,108,97,110,116,69,113,117,97,108,59,1,10878,105,108,100,101,59,1,8819,99,114,59,3,55349,56482,59,1,8811,4,8,65,97,99,102,105,111,115,117,2005,2012,2026,2032,2036,2049,2073,2089,82,68,99,121,59,1,1066,4,2,99,116,2018,2023,101,107,59,1,711,59,1,94,105,114,99,59,1,292,114,59,1,8460,108,98,101,114,116,83,112,97,99,101,59,1,8459,4,2,112,114,2055,2059,102,59,1,8461,105,122,111,110,116,97,108,76,105,110,101,59,1,9472,4,2,99,116,2079,2083,114,59,1,8459,114,111,107,59,1,294,109,112,4,2,68,69,2097,2107,111,119,110,72,117,109,112,59,1,8782,113,117,97,108,59,1,8783,4,14,69,74,79,97,99,100,102,103,109,110,111,115,116,117,2144,2149,2155,2160,2171,2189,2194,2198,2209,2245,2307,2329,2334,2341,99,121,59,1,1045,108,105,103,59,1,306,99,121,59,1,1025,99,117,116,101,5,205,1,59,2169,1,205,4,2,105,121,2177,2186,114,99,5,206,1,59,2184,1,206,59,1,1048,111,116,59,1,304,114,59,1,8465,114,97,118,101,5,204,1,59,2207,1,204,4,3,59,97,112,2217,2219,2238,1,8465,4,2,99,103,2225,2229,114,59,1,298,105,110,97,114,121,73,59,1,8520,108,105,101,115,59,1,8658,4,2,116,118,2251,2281,4,2,59,101,2257,2259,1,8748,4,2,103,114,2265,2271,114,97,108,59,1,8747,115,101,99,116,105,111,110,59,1,8898,105,115,105,98,108,101,4,2,67,84,2293,2300,111,109,109,97,59,1,8291,105,109,101,115,59,1,8290,4,3,103,112,116,2315,2320,2325,111,110,59,1,302,102,59,3,55349,56640,97,59,1,921,99,114,59,1,8464,105,108,100,101,59,1,296,4,2,107,109,2347,2352,99,121,59,1,1030,108,5,207,1,59,2358,1,207,4,5,99,102,111,115,117,2372,2386,2391,2397,2414,4,2,105,121,2378,2383,114,99,59,1,308,59,1,1049,114,59,3,55349,56589,112,102,59,3,55349,56641,4,2,99,101,2403,2408,114,59,3,55349,56485,114,99,121,59,1,1032,107,99,121,59,1,1028,4,7,72,74,97,99,102,111,115,2436,2441,2446,2452,2467,2472,2478,99,121,59,1,1061,99,121,59,1,1036,112,112,97,59,1,922,4,2,101,121,2458,2464,100,105,108,59,1,310,59,1,1050,114,59,3,55349,56590,112,102,59,3,55349,56642,99,114,59,3,55349,56486,4,11,74,84,97,99,101,102,108,109,111,115,116,2508,2513,2520,2562,2585,2981,2986,3004,3011,3146,3167,99,121,59,1,1033,5,60,1,59,2518,1,60,4,5,99,109,110,112,114,2532,2538,2544,2548,2558,117,116,101,59,1,313,98,100,97,59,1,923,103,59,1,10218,108,97,99,101,116,114,102,59,1,8466,114,59,1,8606,4,3,97,101,121,2570,2576,2582,114,111,110,59,1,317,100,105,108,59,1,315,59,1,1051,4,2,102,115,2591,2907,116,4,10,65,67,68,70,82,84,85,86,97,114,2614,2663,2672,2728,2735,2760,2820,2870,2888,2895,4,2,110,114,2620,2633,103,108,101,66,114,97,99,107,101,116,59,1,10216,114,111,119,4,3,59,66,82,2644,2646,2651,1,8592,97,114,59,1,8676,105,103,104,116,65,114,114,111,119,59,1,8646,101,105,108,105,110,103,59,1,8968,111,4,2,117,119,2679,2692,98,108,101,66,114,97,99,107,101,116,59,1,10214,110,4,2,84,86,2699,2710,101,101,86,101,99,116,111,114,59,1,10593,101,99,116,111,114,4,2,59,66,2721,2723,1,8643,97,114,59,1,10585,108,111,111,114,59,1,8970,105,103,104,116,4,2,65,86,2745,2752,114,114,111,119,59,1,8596,101,99,116,111,114,59,1,10574,4,2,101,114,2766,2792,101,4,3,59,65,86,2775,2777,2784,1,8867,114,114,111,119,59,1,8612,101,99,116,111,114,59,1,10586,105,97,110,103,108,101,4,3,59,66,69,2806,2808,2813,1,8882,97,114,59,1,10703,113,117,97,108,59,1,8884,112,4,3,68,84,86,2829,2841,2852,111,119,110,86,101,99,116,111,114,59,1,10577,101,101,86,101,99,116,111,114,59,1,10592,101,99,116,111,114,4,2,59,66,2863,2865,1,8639,97,114,59,1,10584,101,99,116,111,114,4,2,59,66,2881,2883,1,8636,97,114,59,1,10578,114,114,111,119,59,1,8656,105,103,104,116,97,114,114,111,119,59,1,8660,115,4,6,69,70,71,76,83,84,2922,2936,2947,2956,2962,2974,113,117,97,108,71,114,101,97,116,101,114,59,1,8922,117,108,108,69,113,117,97,108,59,1,8806,114,101,97,116,101,114,59,1,8822,101,115,115,59,1,10913,108,97,110,116,69,113,117,97,108,59,1,10877,105,108,100,101,59,1,8818,114,59,3,55349,56591,4,2,59,101,2992,2994,1,8920,102,116,97,114,114,111,119,59,1,8666,105,100,111,116,59,1,319,4,3,110,112,119,3019,3110,3115,103,4,4,76,82,108,114,3030,3058,3070,3098,101,102,116,4,2,65,82,3039,3046,114,114,111,119,59,1,10229,105,103,104,116,65,114,114,111,119,59,1,10231,105,103,104,116,65,114,114,111,119,59,1,10230,101,102,116,4,2,97,114,3079,3086,114,114,111,119,59,1,10232,105,103,104,116,97,114,114,111,119,59,1,10234,105,103,104,116,97,114,114,111,119,59,1,10233,102,59,3,55349,56643,101,114,4,2,76,82,3123,3134,101,102,116,65,114,114,111,119,59,1,8601,105,103,104,116,65,114,114,111,119,59,1,8600,4,3,99,104,116,3154,3158,3161,114,59,1,8466,59,1,8624,114,111,107,59,1,321,59,1,8810,4,8,97,99,101,102,105,111,115,117,3188,3192,3196,3222,3227,3237,3243,3248,112,59,1,10501,121,59,1,1052,4,2,100,108,3202,3213,105,117,109,83,112,97,99,101,59,1,8287,108,105,110,116,114,102,59,1,8499,114,59,3,55349,56592,110,117,115,80,108,117,115,59,1,8723,112,102,59,3,55349,56644,99,114,59,1,8499,59,1,924,4,9,74,97,99,101,102,111,115,116,117,3271,3276,3283,3306,3422,3427,4120,4126,4137,99,121,59,1,1034,99,117,116,101,59,1,323,4,3,97,101,121,3291,3297,3303,114,111,110,59,1,327,100,105,108,59,1,325,59,1,1053,4,3,103,115,119,3314,3380,3415,97,116,105,118,101,4,3,77,84,86,3327,3340,3365,101,100,105,117,109,83,112,97,99,101,59,1,8203,104,105,4,2,99,110,3348,3357,107,83,112,97,99,101,59,1,8203,83,112,97,99,101,59,1,8203,101,114,121,84,104,105,110,83,112,97,99,101,59,1,8203,116,101,100,4,2,71,76,3389,3405,114,101,97,116,101,114,71,114,101,97,116,101,114,59,1,8811,101,115,115,76,101,115,115,59,1,8810,76,105,110,101,59,1,10,114,59,3,55349,56593,4,4,66,110,112,116,3437,3444,3460,3464,114,101,97,107,59,1,8288,66,114,101,97,107,105,110,103,83,112,97,99,101,59,1,160,102,59,1,8469,4,13,59,67,68,69,71,72,76,78,80,82,83,84,86,3492,3494,3517,3536,3578,3657,3685,3784,3823,3860,3915,4066,4107,1,10988,4,2,111,117,3500,3510,110,103,114,117,101,110,116,59,1,8802,112,67,97,112,59,1,8813,111,117,98,108,101,86,101,114,116,105,99,97,108,66,97,114,59,1,8742,4,3,108,113,120,3544,3552,3571,101,109,101,110,116,59,1,8713,117,97,108,4,2,59,84,3561,3563,1,8800,105,108,100,101,59,3,8770,824,105,115,116,115,59,1,8708,114,101,97,116,101,114,4,7,59,69,70,71,76,83,84,3600,3602,3609,3621,3631,3637,3650,1,8815,113,117,97,108,59,1,8817,117,108,108,69,113,117,97,108,59,3,8807,824,114,101,97,116,101,114,59,3,8811,824,101,115,115,59,1,8825,108,97,110,116,69,113,117,97,108,59,3,10878,824,105,108,100,101,59,1,8821,117,109,112,4,2,68,69,3666,3677,111,119,110,72,117,109,112,59,3,8782,824,113,117,97,108,59,3,8783,824,101,4,2,102,115,3692,3724,116,84,114,105,97,110,103,108,101,4,3,59,66,69,3709,3711,3717,1,8938,97,114,59,3,10703,824,113,117,97,108,59,1,8940,115,4,6,59,69,71,76,83,84,3739,3741,3748,3757,3764,3777,1,8814,113,117,97,108,59,1,8816,114,101,97,116,101,114,59,1,8824,101,115,115,59,3,8810,824,108,97,110,116,69,113,117,97,108,59,3,10877,824,105,108,100,101,59,1,8820,101,115,116,101,100,4,2,71,76,3795,3812,114,101,97,116,101,114,71,114,101,97,116,101,114,59,3,10914,824,101,115,115,76,101,115,115,59,3,10913,824,114,101,99,101,100,101,115,4,3,59,69,83,3838,3840,3848,1,8832,113,117,97,108,59,3,10927,824,108,97,110,116,69,113,117,97,108,59,1,8928,4,2,101,105,3866,3881,118,101,114,115,101,69,108,101,109,101,110,116,59,1,8716,103,104,116,84,114,105,97,110,103,108,101,4,3,59,66,69,3900,3902,3908,1,8939,97,114,59,3,10704,824,113,117,97,108,59,1,8941,4,2,113,117,3921,3973,117,97,114,101,83,117,4,2,98,112,3933,3952,115,101,116,4,2,59,69,3942,3945,3,8847,824,113,117,97,108,59,1,8930,101,114,115,101,116,4,2,59,69,3963,3966,3,8848,824,113,117,97,108,59,1,8931,4,3,98,99,112,3981,4000,4045,115,101,116,4,2,59,69,3990,3993,3,8834,8402,113,117,97,108,59,1,8840,99,101,101,100,115,4,4,59,69,83,84,4015,4017,4025,4037,1,8833,113,117,97,108,59,3,10928,824,108,97,110,116,69,113,117,97,108,59,1,8929,105,108,100,101,59,3,8831,824,101,114,115,101,116,4,2,59,69,4056,4059,3,8835,8402,113,117,97,108,59,1,8841,105,108,100,101,4,4,59,69,70,84,4080,4082,4089,4100,1,8769,113,117,97,108,59,1,8772,117,108,108,69,113,117,97,108,59,1,8775,105,108,100,101,59,1,8777,101,114,116,105,99,97,108,66,97,114,59,1,8740,99,114,59,3,55349,56489,105,108,100,101,5,209,1,59,4135,1,209,59,1,925,4,14,69,97,99,100,102,103,109,111,112,114,115,116,117,118,4170,4176,4187,4205,4212,4217,4228,4253,4259,4292,4295,4316,4337,4346,108,105,103,59,1,338,99,117,116,101,5,211,1,59,4185,1,211,4,2,105,121,4193,4202,114,99,5,212,1,59,4200,1,212,59,1,1054,98,108,97,99,59,1,336,114,59,3,55349,56594,114,97,118,101,5,210,1,59,4226,1,210,4,3,97,101,105,4236,4241,4246,99,114,59,1,332,103,97,59,1,937,99,114,111,110,59,1,927,112,102,59,3,55349,56646,101,110,67,117,114,108,121,4,2,68,81,4272,4285,111,117,98,108,101,81,117,111,116,101,59,1,8220,117,111,116,101,59,1,8216,59,1,10836,4,2,99,108,4301,4306,114,59,3,55349,56490,97,115,104,5,216,1,59,4314,1,216,105,4,2,108,109,4323,4332,100,101,5,213,1,59,4330,1,213,101,115,59,1,10807,109,108,5,214,1,59,4344,1,214,101,114,4,2,66,80,4354,4380,4,2,97,114,4360,4364,114,59,1,8254,97,99,4,2,101,107,4372,4375,59,1,9182,101,116,59,1,9140,97,114,101,110,116,104,101,115,105,115,59,1,9180,4,9,97,99,102,104,105,108,111,114,115,4413,4422,4426,4431,4435,4438,4448,4471,4561,114,116,105,97,108,68,59,1,8706,121,59,1,1055,114,59,3,55349,56595,105,59,1,934,59,1,928,117,115,77,105,110,117,115,59,1,177,4,2,105,112,4454,4467,110,99,97,114,101,112,108,97,110,101,59,1,8460,102,59,1,8473,4,4,59,101,105,111,4481,4483,4526,4531,1,10939,99,101,100,101,115,4,4,59,69,83,84,4498,4500,4507,4519,1,8826,113,117,97,108,59,1,10927,108,97,110,116,69,113,117,97,108,59,1,8828,105,108,100,101,59,1,8830,109,101,59,1,8243,4,2,100,112,4537,4543,117,99,116,59,1,8719,111,114,116,105,111,110,4,2,59,97,4555,4557,1,8759,108,59,1,8733,4,2,99,105,4567,4572,114,59,3,55349,56491,59,1,936,4,4,85,102,111,115,4585,4594,4599,4604,79,84,5,34,1,59,4592,1,34,114,59,3,55349,56596,112,102,59,1,8474,99,114,59,3,55349,56492,4,12,66,69,97,99,101,102,104,105,111,114,115,117,4636,4642,4650,4681,4704,4763,4767,4771,5047,5069,5081,5094,97,114,114,59,1,10512,71,5,174,1,59,4648,1,174,4,3,99,110,114,4658,4664,4668,117,116,101,59,1,340,103,59,1,10219,114,4,2,59,116,4675,4677,1,8608,108,59,1,10518,4,3,97,101,121,4689,4695,4701,114,111,110,59,1,344,100,105,108,59,1,342,59,1,1056,4,2,59,118,4710,4712,1,8476,101,114,115,101,4,2,69,85,4722,4748,4,2,108,113,4728,4736,101,109,101,110,116,59,1,8715,117,105,108,105,98,114,105,117,109,59,1,8651,112,69,113,117,105,108,105,98,114,105,117,109,59,1,10607,114,59,1,8476,111,59,1,929,103,104,116,4,8,65,67,68,70,84,85,86,97,4792,4840,4849,4905,4912,4972,5022,5040,4,2,110,114,4798,4811,103,108,101,66,114,97,99,107,101,116,59,1,10217,114,111,119,4,3,59,66,76,4822,4824,4829,1,8594,97,114,59,1,8677,101,102,116,65,114,114,111,119,59,1,8644,101,105,108,105,110,103,59,1,8969,111,4,2,117,119,4856,4869,98,108,101,66,114,97,99,107,101,116,59,1,10215,110,4,2,84,86,4876,4887,101,101,86,101,99,116,111,114,59,1,10589,101,99,116,111,114,4,2,59,66,4898,4900,1,8642,97,114,59,1,10581,108,111,111,114,59,1,8971,4,2,101,114,4918,4944,101,4,3,59,65,86,4927,4929,4936,1,8866,114,114,111,119,59,1,8614,101,99,116,111,114,59,1,10587,105,97,110,103,108,101,4,3,59,66,69,4958,4960,4965,1,8883,97,114,59,1,10704,113,117,97,108,59,1,8885,112,4,3,68,84,86,4981,4993,5004,111,119,110,86,101,99,116,111,114,59,1,10575,101,101,86,101,99,116,111,114,59,1,10588,101,99,116,111,114,4,2,59,66,5015,5017,1,8638,97,114,59,1,10580,101,99,116,111,114,4,2,59,66,5033,5035,1,8640,97,114,59,1,10579,114,114,111,119,59,1,8658,4,2,112,117,5053,5057,102,59,1,8477,110,100,73,109,112,108,105,101,115,59,1,10608,105,103,104,116,97,114,114,111,119,59,1,8667,4,2,99,104,5087,5091,114,59,1,8475,59,1,8625,108,101,68,101,108,97,121,101,100,59,1,10740,4,13,72,79,97,99,102,104,105,109,111,113,115,116,117,5134,5150,5157,5164,5198,5203,5259,5265,5277,5283,5374,5380,5385,4,2,67,99,5140,5146,72,99,121,59,1,1065,121,59,1,1064,70,84,99,121,59,1,1068,99,117,116,101,59,1,346,4,5,59,97,101,105,121,5176,5178,5184,5190,5195,1,10940,114,111,110,59,1,352,100,105,108,59,1,350,114,99,59,1,348,59,1,1057,114,59,3,55349,56598,111,114,116,4,4,68,76,82,85,5216,5227,5238,5250,111,119,110,65,114,114,111,119,59,1,8595,101,102,116,65,114,114,111,119,59,1,8592,105,103,104,116,65,114,114,111,119,59,1,8594,112,65,114,114,111,119,59,1,8593,103,109,97,59,1,931,97,108,108,67,105,114,99,108,101,59,1,8728,112,102,59,3,55349,56650,4,2,114,117,5289,5293,116,59,1,8730,97,114,101,4,4,59,73,83,85,5306,5308,5322,5367,1,9633,110,116,101,114,115,101,99,116,105,111,110,59,1,8851,117,4,2,98,112,5329,5347,115,101,116,4,2,59,69,5338,5340,1,8847,113,117,97,108,59,1,8849,101,114,115,101,116,4,2,59,69,5358,5360,1,8848,113,117,97,108,59,1,8850,110,105,111,110,59,1,8852,99,114,59,3,55349,56494,97,114,59,1,8902,4,4,98,99,109,112,5395,5420,5475,5478,4,2,59,115,5401,5403,1,8912,101,116,4,2,59,69,5411,5413,1,8912,113,117,97,108,59,1,8838,4,2,99,104,5426,5468,101,101,100,115,4,4,59,69,83,84,5440,5442,5449,5461,1,8827,113,117,97,108,59,1,10928,108,97,110,116,69,113,117,97,108,59,1,8829,105,108,100,101,59,1,8831,84,104,97,116,59,1,8715,59,1,8721,4,3,59,101,115,5486,5488,5507,1,8913,114,115,101,116,4,2,59,69,5498,5500,1,8835,113,117,97,108,59,1,8839,101,116,59,1,8913,4,11,72,82,83,97,99,102,104,105,111,114,115,5536,5546,5552,5567,5579,5602,5607,5655,5695,5701,5711,79,82,78,5,222,1,59,5544,1,222,65,68,69,59,1,8482,4,2,72,99,5558,5563,99,121,59,1,1035,121,59,1,1062,4,2,98,117,5573,5576,59,1,9,59,1,932,4,3,97,101,121,5587,5593,5599,114,111,110,59,1,356,100,105,108,59,1,354,59,1,1058,114,59,3,55349,56599,4,2,101,105,5613,5631,4,2,114,116,5619,5627,101,102,111,114,101,59,1,8756,97,59,1,920,4,2,99,110,5637,5647,107,83,112,97,99,101,59,3,8287,8202,83,112,97,99,101,59,1,8201,108,100,101,4,4,59,69,70,84,5668,5670,5677,5688,1,8764,113,117,97,108,59,1,8771,117,108,108,69,113,117,97,108,59,1,8773,105,108,100,101,59,1,8776,112,102,59,3,55349,56651,105,112,108,101,68,111,116,59,1,8411,4,2,99,116,5717,5722,114,59,3,55349,56495,114,111,107,59,1,358,4,14,97,98,99,100,102,103,109,110,111,112,114,115,116,117,5758,5789,5805,5823,5830,5835,5846,5852,5921,5937,6089,6095,6101,6108,4,2,99,114,5764,5774,117,116,101,5,218,1,59,5772,1,218,114,4,2,59,111,5781,5783,1,8607,99,105,114,59,1,10569,114,4,2,99,101,5796,5800,121,59,1,1038,118,101,59,1,364,4,2,105,121,5811,5820,114,99,5,219,1,59,5818,1,219,59,1,1059,98,108,97,99,59,1,368,114,59,3,55349,56600,114,97,118,101,5,217,1,59,5844,1,217,97,99,114,59,1,362,4,2,100,105,5858,5905,101,114,4,2,66,80,5866,5892,4,2,97,114,5872,5876,114,59,1,95,97,99,4,2,101,107,5884,5887,59,1,9183,101,116,59,1,9141,97,114,101,110,116,104,101,115,105,115,59,1,9181,111,110,4,2,59,80,5913,5915,1,8899,108,117,115,59,1,8846,4,2,103,112,5927,5932,111,110,59,1,370,102,59,3,55349,56652,4,8,65,68,69,84,97,100,112,115,5955,5985,5996,6009,6026,6033,6044,6075,114,114,111,119,4,3,59,66,68,5967,5969,5974,1,8593,97,114,59,1,10514,111,119,110,65,114,114,111,119,59,1,8645,111,119,110,65,114,114,111,119,59,1,8597,113,117,105,108,105,98,114,105,117,109,59,1,10606,101,101,4,2,59,65,6017,6019,1,8869,114,114,111,119,59,1,8613,114,114,111,119,59,1,8657,111,119,110,97,114,114,111,119,59,1,8661,101,114,4,2,76,82,6052,6063,101,102,116,65,114,114,111,119,59,1,8598,105,103,104,116,65,114,114,111,119,59,1,8599,105,4,2,59,108,6082,6084,1,978,111,110,59,1,933,105,110,103,59,1,366,99,114,59,3,55349,56496,105,108,100,101,59,1,360,109,108,5,220,1,59,6115,1,220,4,9,68,98,99,100,101,102,111,115,118,6137,6143,6148,6152,6166,6250,6255,6261,6267,97,115,104,59,1,8875,97,114,59,1,10987,121,59,1,1042,97,115,104,4,2,59,108,6161,6163,1,8873,59,1,10982,4,2,101,114,6172,6175,59,1,8897,4,3,98,116,121,6183,6188,6238,97,114,59,1,8214,4,2,59,105,6194,6196,1,8214,99,97,108,4,4,66,76,83,84,6209,6214,6220,6231,97,114,59,1,8739,105,110,101,59,1,124,101,112,97,114,97,116,111,114,59,1,10072,105,108,100,101,59,1,8768,84,104,105,110,83,112,97,99,101,59,1,8202,114,59,3,55349,56601,112,102,59,3,55349,56653,99,114,59,3,55349,56497,100,97,115,104,59,1,8874,4,5,99,101,102,111,115,6286,6292,6298,6303,6309,105,114,99,59,1,372,100,103,101,59,1,8896,114,59,3,55349,56602,112,102,59,3,55349,56654,99,114,59,3,55349,56498,4,4,102,105,111,115,6325,6330,6333,6339,114,59,3,55349,56603,59,1,926,112,102,59,3,55349,56655,99,114,59,3,55349,56499,4,9,65,73,85,97,99,102,111,115,117,6365,6370,6375,6380,6391,6405,6410,6416,6422,99,121,59,1,1071,99,121,59,1,1031,99,121,59,1,1070,99,117,116,101,5,221,1,59,6389,1,221,4,2,105,121,6397,6402,114,99,59,1,374,59,1,1067,114,59,3,55349,56604,112,102,59,3,55349,56656,99,114,59,3,55349,56500,109,108,59,1,376,4,8,72,97,99,100,101,102,111,115,6445,6450,6457,6472,6477,6501,6505,6510,99,121,59,1,1046,99,117,116,101,59,1,377,4,2,97,121,6463,6469,114,111,110,59,1,381,59,1,1047,111,116,59,1,379,4,2,114,116,6483,6497,111,87,105,100,116,104,83,112,97,99,101,59,1,8203,97,59,1,918,114,59,1,8488,112,102,59,1,8484,99,114,59,3,55349,56501,4,16,97,98,99,101,102,103,108,109,110,111,112,114,115,116,117,119,6550,6561,6568,6612,6622,6634,6645,6672,6699,6854,6870,6923,6933,6963,6974,6983,99,117,116,101,5,225,1,59,6559,1,225,114,101,118,101,59,1,259,4,6,59,69,100,105,117,121,6582,6584,6588,6591,6600,6609,1,8766,59,3,8766,819,59,1,8767,114,99,5,226,1,59,6598,1,226,116,101,5,180,1,59,6607,1,180,59,1,1072,108,105,103,5,230,1,59,6620,1,230,4,2,59,114,6628,6630,1,8289,59,3,55349,56606,114,97,118,101,5,224,1,59,6643,1,224,4,2,101,112,6651,6667,4,2,102,112,6657,6663,115,121,109,59,1,8501,104,59,1,8501,104,97,59,1,945,4,2,97,112,6678,6692,4,2,99,108,6684,6688,114,59,1,257,103,59,1,10815,5,38,1,59,6697,1,38,4,2,100,103,6705,6737,4,5,59,97,100,115,118,6717,6719,6724,6727,6734,1,8743,110,100,59,1,10837,59,1,10844,108,111,112,101,59,1,10840,59,1,10842,4,7,59,101,108,109,114,115,122,6753,6755,6758,6762,6814,6835,6848,1,8736,59,1,10660,101,59,1,8736,115,100,4,2,59,97,6770,6772,1,8737,4,8,97,98,99,100,101,102,103,104,6790,6793,6796,6799,6802,6805,6808,6811,59,1,10664,59,1,10665,59,1,10666,59,1,10667,59,1,10668,59,1,10669,59,1,10670,59,1,10671,116,4,2,59,118,6821,6823,1,8735,98,4,2,59,100,6830,6832,1,8894,59,1,10653,4,2,112,116,6841,6845,104,59,1,8738,59,1,197,97,114,114,59,1,9084,4,2,103,112,6860,6865,111,110,59,1,261,102,59,3,55349,56658,4,7,59,69,97,101,105,111,112,6886,6888,6891,6897,6900,6904,6908,1,8776,59,1,10864,99,105,114,59,1,10863,59,1,8778,100,59,1,8779,115,59,1,39,114,111,120,4,2,59,101,6917,6919,1,8776,113,59,1,8778,105,110,103,5,229,1,59,6931,1,229,4,3,99,116,121,6941,6946,6949,114,59,3,55349,56502,59,1,42,109,112,4,2,59,101,6957,6959,1,8776,113,59,1,8781,105,108,100,101,5,227,1,59,6972,1,227,109,108,5,228,1,59,6981,1,228,4,2,99,105,6989,6997,111,110,105,110,116,59,1,8755,110,116,59,1,10769,4,16,78,97,98,99,100,101,102,105,107,108,110,111,112,114,115,117,7036,7041,7119,7135,7149,7155,7219,7224,7347,7354,7463,7489,7786,7793,7814,7866,111,116,59,1,10989,4,2,99,114,7047,7094,107,4,4,99,101,112,115,7058,7064,7073,7080,111,110,103,59,1,8780,112,115,105,108,111,110,59,1,1014,114,105,109,101,59,1,8245,105,109,4,2,59,101,7088,7090,1,8765,113,59,1,8909,4,2,118,119,7100,7105,101,101,59,1,8893,101,100,4,2,59,103,7113,7115,1,8965,101,59,1,8965,114,107,4,2,59,116,7127,7129,1,9141,98,114,107,59,1,9142,4,2,111,121,7141,7146,110,103,59,1,8780,59,1,1073,113,117,111,59,1,8222,4,5,99,109,112,114,116,7167,7181,7188,7193,7199,97,117,115,4,2,59,101,7176,7178,1,8757,59,1,8757,112,116,121,118,59,1,10672,115,105,59,1,1014,110,111,117,59,1,8492,4,3,97,104,119,7207,7210,7213,59,1,946,59,1,8502,101,101,110,59,1,8812,114,59,3,55349,56607,103,4,7,99,111,115,116,117,118,119,7241,7262,7288,7305,7328,7335,7340,4,3,97,105,117,7249,7253,7258,112,59,1,8898,114,99,59,1,9711,112,59,1,8899,4,3,100,112,116,7270,7275,7281,111,116,59,1,10752,108,117,115,59,1,10753,105,109,101,115,59,1,10754,4,2,113,116,7294,7300,99,117,112,59,1,10758,97,114,59,1,9733,114,105,97,110,103,108,101,4,2,100,117,7318,7324,111,119,110,59,1,9661,112,59,1,9651,112,108,117,115,59,1,10756,101,101,59,1,8897,101,100,103,101,59,1,8896,97,114,111,119,59,1,10509,4,3,97,107,111,7362,7436,7458,4,2,99,110,7368,7432,107,4,3,108,115,116,7377,7386,7394,111,122,101,110,103,101,59,1,10731,113,117,97,114,101,59,1,9642,114,105,97,110,103,108,101,4,4,59,100,108,114,7411,7413,7419,7425,1,9652,111,119,110,59,1,9662,101,102,116,59,1,9666,105,103,104,116,59,1,9656,107,59,1,9251,4,2,49,51,7442,7454,4,2,50,52,7448,7451,59,1,9618,59,1,9617,52,59,1,9619,99,107,59,1,9608,4,2,101,111,7469,7485,4,2,59,113,7475,7478,3,61,8421,117,105,118,59,3,8801,8421,116,59,1,8976,4,4,112,116,119,120,7499,7504,7517,7523,102,59,3,55349,56659,4,2,59,116,7510,7512,1,8869,111,109,59,1,8869,116,105,101,59,1,8904,4,12,68,72,85,86,98,100,104,109,112,116,117,118,7549,7571,7597,7619,7655,7660,7682,7708,7715,7721,7728,7750,4,4,76,82,108,114,7559,7562,7565,7568,59,1,9559,59,1,9556,59,1,9558,59,1,9555,4,5,59,68,85,100,117,7583,7585,7588,7591,7594,1,9552,59,1,9574,59,1,9577,59,1,9572,59,1,9575,4,4,76,82,108,114,7607,7610,7613,7616,59,1,9565,59,1,9562,59,1,9564,59,1,9561,4,7,59,72,76,82,104,108,114,7635,7637,7640,7643,7646,7649,7652,1,9553,59,1,9580,59,1,9571,59,1,9568,59,1,9579,59,1,9570,59,1,9567,111,120,59,1,10697,4,4,76,82,108,114,7670,7673,7676,7679,59,1,9557,59,1,9554,59,1,9488,59,1,9484,4,5,59,68,85,100,117,7694,7696,7699,7702,7705,1,9472,59,1,9573,59,1,9576,59,1,9516,59,1,9524,105,110,117,115,59,1,8863,108,117,115,59,1,8862,105,109,101,115,59,1,8864,4,4,76,82,108,114,7738,7741,7744,7747,59,1,9563,59,1,9560,59,1,9496,59,1,9492,4,7,59,72,76,82,104,108,114,7766,7768,7771,7774,7777,7780,7783,1,9474,59,1,9578,59,1,9569,59,1,9566,59,1,9532,59,1,9508,59,1,9500,114,105,109,101,59,1,8245,4,2,101,118,7799,7804,118,101,59,1,728,98,97,114,5,166,1,59,7812,1,166,4,4,99,101,105,111,7824,7829,7834,7846,114,59,3,55349,56503,109,105,59,1,8271,109,4,2,59,101,7841,7843,1,8765,59,1,8909,108,4,3,59,98,104,7855,7857,7860,1,92,59,1,10693,115,117,98,59,1,10184,4,2,108,109,7872,7885,108,4,2,59,101,7879,7881,1,8226,116,59,1,8226,112,4,3,59,69,101,7894,7896,7899,1,8782,59,1,10926,4,2,59,113,7905,7907,1,8783,59,1,8783,4,15,97,99,100,101,102,104,105,108,111,114,115,116,117,119,121,7942,8021,8075,8080,8121,8126,8157,8279,8295,8430,8446,8485,8491,8707,8726,4,3,99,112,114,7950,7956,8007,117,116,101,59,1,263,4,6,59,97,98,99,100,115,7970,7972,7977,7984,7998,8003,1,8745,110,100,59,1,10820,114,99,117,112,59,1,10825,4,2,97,117,7990,7994,112,59,1,10827,112,59,1,10823,111,116,59,1,10816,59,3,8745,65024,4,2,101,111,8013,8017,116,59,1,8257,110,59,1,711,4,4,97,101,105,117,8031,8046,8056,8061,4,2,112,114,8037,8041,115,59,1,10829,111,110,59,1,269,100,105,108,5,231,1,59,8054,1,231,114,99,59,1,265,112,115,4,2,59,115,8069,8071,1,10828,109,59,1,10832,111,116,59,1,267,4,3,100,109,110,8088,8097,8104,105,108,5,184,1,59,8095,1,184,112,116,121,118,59,1,10674,116,5,162,2,59,101,8112,8114,1,162,114,100,111,116,59,1,183,114,59,3,55349,56608,4,3,99,101,105,8134,8138,8154,121,59,1,1095,99,107,4,2,59,109,8146,8148,1,10003,97,114,107,59,1,10003,59,1,967,114,4,7,59,69,99,101,102,109,115,8174,8176,8179,8258,8261,8268,8273,1,9675,59,1,10691,4,3,59,101,108,8187,8189,8193,1,710,113,59,1,8791,101,4,2,97,100,8200,8223,114,114,111,119,4,2,108,114,8210,8216,101,102,116,59,1,8634,105,103,104,116,59,1,8635,4,5,82,83,97,99,100,8235,8238,8241,8246,8252,59,1,174,59,1,9416,115,116,59,1,8859,105,114,99,59,1,8858,97,115,104,59,1,8861,59,1,8791,110,105,110,116,59,1,10768,105,100,59,1,10991,99,105,114,59,1,10690,117,98,115,4,2,59,117,8288,8290,1,9827,105,116,59,1,9827,4,4,108,109,110,112,8305,8326,8376,8400,111,110,4,2,59,101,8313,8315,1,58,4,2,59,113,8321,8323,1,8788,59,1,8788,4,2,109,112,8332,8344,97,4,2,59,116,8339,8341,1,44,59,1,64,4,3,59,102,108,8352,8354,8358,1,8705,110,59,1,8728,101,4,2,109,120,8365,8371,101,110,116,59,1,8705,101,115,59,1,8450,4,2,103,105,8382,8395,4,2,59,100,8388,8390,1,8773,111,116,59,1,10861,110,116,59,1,8750,4,3,102,114,121,8408,8412,8417,59,3,55349,56660,111,100,59,1,8720,5,169,2,59,115,8424,8426,1,169,114,59,1,8471,4,2,97,111,8436,8441,114,114,59,1,8629,115,115,59,1,10007,4,2,99,117,8452,8457,114,59,3,55349,56504,4,2,98,112,8463,8474,4,2,59,101,8469,8471,1,10959,59,1,10961,4,2,59,101,8480,8482,1,10960,59,1,10962,100,111,116,59,1,8943,4,7,100,101,108,112,114,118,119,8507,8522,8536,8550,8600,8697,8702,97,114,114,4,2,108,114,8516,8519,59,1,10552,59,1,10549,4,2,112,115,8528,8532,114,59,1,8926,99,59,1,8927,97,114,114,4,2,59,112,8545,8547,1,8630,59,1,10557,4,6,59,98,99,100,111,115,8564,8566,8573,8587,8592,8596,1,8746,114,99,97,112,59,1,10824,4,2,97,117,8579,8583,112,59,1,10822,112,59,1,10826,111,116,59,1,8845,114,59,1,10821,59,3,8746,65024,4,4,97,108,114,118,8610,8623,8663,8672,114,114,4,2,59,109,8618,8620,1,8631,59,1,10556,121,4,3,101,118,119,8632,8651,8656,113,4,2,112,115,8639,8645,114,101,99,59,1,8926,117,99,99,59,1,8927,101,101,59,1,8910,101,100,103,101,59,1,8911,101,110,5,164,1,59,8670,1,164,101,97,114,114,111,119,4,2,108,114,8684,8690,101,102,116,59,1,8630,105,103,104,116,59,1,8631,101,101,59,1,8910,101,100,59,1,8911,4,2,99,105,8713,8721,111,110,105,110,116,59,1,8754,110,116,59,1,8753,108,99,116,121,59,1,9005,4,19,65,72,97,98,99,100,101,102,104,105,106,108,111,114,115,116,117,119,122,8773,8778,8783,8821,8839,8854,8887,8914,8930,8944,9036,9041,9058,9197,9227,9258,9281,9297,9305,114,114,59,1,8659,97,114,59,1,10597,4,4,103,108,114,115,8793,8799,8805,8809,103,101,114,59,1,8224,101,116,104,59,1,8504,114,59,1,8595,104,4,2,59,118,8816,8818,1,8208,59,1,8867,4,2,107,108,8827,8834,97,114,111,119,59,1,10511,97,99,59,1,733,4,2,97,121,8845,8851,114,111,110,59,1,271,59,1,1076,4,3,59,97,111,8862,8864,8880,1,8518,4,2,103,114,8870,8876,103,101,114,59,1,8225,114,59,1,8650,116,115,101,113,59,1,10871,4,3,103,108,109,8895,8902,8907,5,176,1,59,8900,1,176,116,97,59,1,948,112,116,121,118,59,1,10673,4,2,105,114,8920,8926,115,104,116,59,1,10623,59,3,55349,56609,97,114,4,2,108,114,8938,8941,59,1,8643,59,1,8642,4,5,97,101,103,115,118,8956,8986,8989,8996,9001,109,4,3,59,111,115,8965,8967,8983,1,8900,110,100,4,2,59,115,8975,8977,1,8900,117,105,116,59,1,9830,59,1,9830,59,1,168,97,109,109,97,59,1,989,105,110,59,1,8946,4,3,59,105,111,9009,9011,9031,1,247,100,101,5,247,2,59,111,9020,9022,1,247,110,116,105,109,101,115,59,1,8903,110,120,59,1,8903,99,121,59,1,1106,99,4,2,111,114,9048,9053,114,110,59,1,8990,111,112,59,1,8973,4,5,108,112,116,117,119,9070,9076,9081,9130,9144,108,97,114,59,1,36,102,59,3,55349,56661,4,5,59,101,109,112,115,9093,9095,9109,9116,9122,1,729,113,4,2,59,100,9102,9104,1,8784,111,116,59,1,8785,105,110,117,115,59,1,8760,108,117,115,59,1,8724,113,117,97,114,101,59,1,8865,98,108,101,98,97,114,119,101,100,103,101,59,1,8966,110,4,3,97,100,104,9153,9160,9172,114,114,111,119,59,1,8595,111,119,110,97,114,114,111,119,115,59,1,8650,97,114,112,111,111,110,4,2,108,114,9184,9190,101,102,116,59,1,8643,105,103,104,116,59,1,8642,4,2,98,99,9203,9211,107,97,114,111,119,59,1,10512,4,2,111,114,9217,9222,114,110,59,1,8991,111,112,59,1,8972,4,3,99,111,116,9235,9248,9252,4,2,114,121,9241,9245,59,3,55349,56505,59,1,1109,108,59,1,10742,114,111,107,59,1,273,4,2,100,114,9264,9269,111,116,59,1,8945,105,4,2,59,102,9276,9278,1,9663,59,1,9662,4,2,97,104,9287,9292,114,114,59,1,8693,97,114,59,1,10607,97,110,103,108,101,59,1,10662,4,2,99,105,9311,9315,121,59,1,1119,103,114,97,114,114,59,1,10239,4,18,68,97,99,100,101,102,103,108,109,110,111,112,113,114,115,116,117,120,9361,9376,9398,9439,9444,9447,9462,9495,9531,9585,9598,9614,9659,9755,9771,9792,9808,9826,4,2,68,111,9367,9372,111,116,59,1,10871,116,59,1,8785,4,2,99,115,9382,9392,117,116,101,5,233,1,59,9390,1,233,116,101,114,59,1,10862,4,4,97,105,111,121,9408,9414,9430,9436,114,111,110,59,1,283,114,4,2,59,99,9421,9423,1,8790,5,234,1,59,9428,1,234,108,111,110,59,1,8789,59,1,1101,111,116,59,1,279,59,1,8519,4,2,68,114,9453,9458,111,116,59,1,8786,59,3,55349,56610,4,3,59,114,115,9470,9472,9482,1,10906,97,118,101,5,232,1,59,9480,1,232,4,2,59,100,9488,9490,1,10902,111,116,59,1,10904,4,4,59,105,108,115,9505,9507,9515,9518,1,10905,110,116,101,114,115,59,1,9191,59,1,8467,4,2,59,100,9524,9526,1,10901,111,116,59,1,10903,4,3,97,112,115,9539,9544,9564,99,114,59,1,275,116,121,4,3,59,115,118,9554,9556,9561,1,8709,101,116,59,1,8709,59,1,8709,112,4,2,49,59,9571,9583,4,2,51,52,9577,9580,59,1,8196,59,1,8197,1,8195,4,2,103,115,9591,9594,59,1,331,112,59,1,8194,4,2,103,112,9604,9609,111,110,59,1,281,102,59,3,55349,56662,4,3,97,108,115,9622,9635,9640,114,4,2,59,115,9629,9631,1,8917,108,59,1,10723,117,115,59,1,10865,105,4,3,59,108,118,9649,9651,9656,1,949,111,110,59,1,949,59,1,1013,4,4,99,115,117,118,9669,9686,9716,9747,4,2,105,111,9675,9680,114,99,59,1,8790,108,111,110,59,1,8789,4,2,105,108,9692,9696,109,59,1,8770,97,110,116,4,2,103,108,9705,9710,116,114,59,1,10902,101,115,115,59,1,10901,4,3,97,101,105,9724,9729,9734,108,115,59,1,61,115,116,59,1,8799,118,4,2,59,68,9741,9743,1,8801,68,59,1,10872,112,97,114,115,108,59,1,10725,4,2,68,97,9761,9766,111,116,59,1,8787,114,114,59,1,10609,4,3,99,100,105,9779,9783,9788,114,59,1,8495,111,116,59,1,8784,109,59,1,8770,4,2,97,104,9798,9801,59,1,951,5,240,1,59,9806,1,240,4,2,109,114,9814,9822,108,5,235,1,59,9820,1,235,111,59,1,8364,4,3,99,105,112,9834,9838,9843,108,59,1,33,115,116,59,1,8707,4,2,101,111,9849,9859,99,116,97,116,105,111,110,59,1,8496,110,101,110,116,105,97,108,101,59,1,8519,4,12,97,99,101,102,105,106,108,110,111,112,114,115,9896,9910,9914,9921,9954,9960,9967,9989,9994,10027,10036,10164,108,108,105,110,103,100,111,116,115,101,113,59,1,8786,121,59,1,1092,109,97,108,101,59,1,9792,4,3,105,108,114,9929,9935,9950,108,105,103,59,1,64259,4,2,105,108,9941,9945,103,59,1,64256,105,103,59,1,64260,59,3,55349,56611,108,105,103,59,1,64257,108,105,103,59,3,102,106,4,3,97,108,116,9975,9979,9984,116,59,1,9837,105,103,59,1,64258,110,115,59,1,9649,111,102,59,1,402,4,2,112,114,10000,10005,102,59,3,55349,56663,4,2,97,107,10011,10016,108,108,59,1,8704,4,2,59,118,10022,10024,1,8916,59,1,10969,97,114,116,105,110,116,59,1,10765,4,2,97,111,10042,10159,4,2,99,115,10048,10155,4,6,49,50,51,52,53,55,10062,10102,10114,10135,10139,10151,4,6,50,51,52,53,54,56,10076,10083,10086,10093,10096,10099,5,189,1,59,10081,1,189,59,1,8531,5,188,1,59,10091,1,188,59,1,8533,59,1,8537,59,1,8539,4,2,51,53,10108,10111,59,1,8532,59,1,8534,4,3,52,53,56,10122,10129,10132,5,190,1,59,10127,1,190,59,1,8535,59,1,8540,53,59,1,8536,4,2,54,56,10145,10148,59,1,8538,59,1,8541,56,59,1,8542,108,59,1,8260,119,110,59,1,8994,99,114,59,3,55349,56507,4,17,69,97,98,99,100,101,102,103,105,106,108,110,111,114,115,116,118,10206,10217,10247,10254,10268,10273,10358,10363,10374,10380,10385,10406,10458,10464,10470,10497,10610,4,2,59,108,10212,10214,1,8807,59,1,10892,4,3,99,109,112,10225,10231,10244,117,116,101,59,1,501,109,97,4,2,59,100,10239,10241,1,947,59,1,989,59,1,10886,114,101,118,101,59,1,287,4,2,105,121,10260,10265,114,99,59,1,285,59,1,1075,111,116,59,1,289,4,4,59,108,113,115,10283,10285,10288,10308,1,8805,59,1,8923,4,3,59,113,115,10296,10298,10301,1,8805,59,1,8807,108,97,110,116,59,1,10878,4,4,59,99,100,108,10318,10320,10324,10345,1,10878,99,59,1,10921,111,116,4,2,59,111,10332,10334,1,10880,4,2,59,108,10340,10342,1,10882,59,1,10884,4,2,59,101,10351,10354,3,8923,65024,115,59,1,10900,114,59,3,55349,56612,4,2,59,103,10369,10371,1,8811,59,1,8921,109,101,108,59,1,8503,99,121,59,1,1107,4,4,59,69,97,106,10395,10397,10400,10403,1,8823,59,1,10898,59,1,10917,59,1,10916,4,4,69,97,101,115,10416,10419,10434,10453,59,1,8809,112,4,2,59,112,10426,10428,1,10890,114,111,120,59,1,10890,4,2,59,113,10440,10442,1,10888,4,2,59,113,10448,10450,1,10888,59,1,8809,105,109,59,1,8935,112,102,59,3,55349,56664,97,118,101,59,1,96,4,2,99,105,10476,10480,114,59,1,8458,109,4,3,59,101,108,10489,10491,10494,1,8819,59,1,10894,59,1,10896,5,62,6,59,99,100,108,113,114,10512,10514,10527,10532,10538,10545,1,62,4,2,99,105,10520,10523,59,1,10919,114,59,1,10874,111,116,59,1,8919,80,97,114,59,1,10645,117,101,115,116,59,1,10876,4,5,97,100,101,108,115,10557,10574,10579,10599,10605,4,2,112,114,10563,10570,112,114,111,120,59,1,10886,114,59,1,10616,111,116,59,1,8919,113,4,2,108,113,10586,10592,101,115,115,59,1,8923,108,101,115,115,59,1,10892,101,115,115,59,1,8823,105,109,59,1,8819,4,2,101,110,10616,10626,114,116,110,101,113,113,59,3,8809,65024,69,59,3,8809,65024,4,10,65,97,98,99,101,102,107,111,115,121,10653,10658,10713,10718,10724,10760,10765,10786,10850,10875,114,114,59,1,8660,4,4,105,108,109,114,10668,10674,10678,10684,114,115,112,59,1,8202,102,59,1,189,105,108,116,59,1,8459,4,2,100,114,10690,10695,99,121,59,1,1098,4,3,59,99,119,10703,10705,10710,1,8596,105,114,59,1,10568,59,1,8621,97,114,59,1,8463,105,114,99,59,1,293,4,3,97,108,114,10732,10748,10754,114,116,115,4,2,59,117,10741,10743,1,9829,105,116,59,1,9829,108,105,112,59,1,8230,99,111,110,59,1,8889,114,59,3,55349,56613,115,4,2,101,119,10772,10779,97,114,111,119,59,1,10533,97,114,111,119,59,1,10534,4,5,97,109,111,112,114,10798,10803,10809,10839,10844,114,114,59,1,8703,116,104,116,59,1,8763,107,4,2,108,114,10816,10827,101,102,116,97,114,114,111,119,59,1,8617,105,103,104,116,97,114,114,111,119,59,1,8618,102,59,3,55349,56665,98,97,114,59,1,8213,4,3,99,108,116,10858,10863,10869,114,59,3,55349,56509,97,115,104,59,1,8463,114,111,107,59,1,295,4,2,98,112,10881,10887,117,108,108,59,1,8259,104,101,110,59,1,8208,4,15,97,99,101,102,103,105,106,109,110,111,112,113,115,116,117,10925,10936,10958,10977,10990,11001,11039,11045,11101,11192,11220,11226,11237,11285,11299,99,117,116,101,5,237,1,59,10934,1,237,4,3,59,105,121,10944,10946,10955,1,8291,114,99,5,238,1,59,10953,1,238,59,1,1080,4,2,99,120,10964,10968,121,59,1,1077,99,108,5,161,1,59,10975,1,161,4,2,102,114,10983,10986,59,1,8660,59,3,55349,56614,114,97,118,101,5,236,1,59,10999,1,236,4,4,59,105,110,111,11011,11013,11028,11034,1,8520,4,2,105,110,11019,11024,110,116,59,1,10764,116,59,1,8749,102,105,110,59,1,10716,116,97,59,1,8489,108,105,103,59,1,307,4,3,97,111,112,11053,11092,11096,4,3,99,103,116,11061,11065,11088,114,59,1,299,4,3,101,108,112,11073,11076,11082,59,1,8465,105,110,101,59,1,8464,97,114,116,59,1,8465,104,59,1,305,102,59,1,8887,101,100,59,1,437,4,5,59,99,102,111,116,11113,11115,11121,11136,11142,1,8712,97,114,101,59,1,8453,105,110,4,2,59,116,11129,11131,1,8734,105,101,59,1,10717,100,111,116,59,1,305,4,5,59,99,101,108,112,11154,11156,11161,11179,11186,1,8747,97,108,59,1,8890,4,2,103,114,11167,11173,101,114,115,59,1,8484,99,97,108,59,1,8890,97,114,104,107,59,1,10775,114,111,100,59,1,10812,4,4,99,103,112,116,11202,11206,11211,11216,121,59,1,1105,111,110,59,1,303,102,59,3,55349,56666,97,59,1,953,114,111,100,59,1,10812,117,101,115,116,5,191,1,59,11235,1,191,4,2,99,105,11243,11248,114,59,3,55349,56510,110,4,5,59,69,100,115,118,11261,11263,11266,11271,11282,1,8712,59,1,8953,111,116,59,1,8949,4,2,59,118,11277,11279,1,8948,59,1,8947,59,1,8712,4,2,59,105,11291,11293,1,8290,108,100,101,59,1,297,4,2,107,109,11305,11310,99,121,59,1,1110,108,5,239,1,59,11316,1,239,4,6,99,102,109,111,115,117,11332,11346,11351,11357,11363,11380,4,2,105,121,11338,11343,114,99,59,1,309,59,1,1081,114,59,3,55349,56615,97,116,104,59,1,567,112,102,59,3,55349,56667,4,2,99,101,11369,11374,114,59,3,55349,56511,114,99,121,59,1,1112,107,99,121,59,1,1108,4,8,97,99,102,103,104,106,111,115,11404,11418,11433,11438,11445,11450,11455,11461,112,112,97,4,2,59,118,11413,11415,1,954,59,1,1008,4,2,101,121,11424,11430,100,105,108,59,1,311,59,1,1082,114,59,3,55349,56616,114,101,101,110,59,1,312,99,121,59,1,1093,99,121,59,1,1116,112,102,59,3,55349,56668,99,114,59,3,55349,56512,4,23,65,66,69,72,97,98,99,100,101,102,103,104,106,108,109,110,111,112,114,115,116,117,118,11515,11538,11544,11555,11560,11721,11780,11818,11868,12136,12160,12171,12203,12208,12246,12275,12327,12509,12523,12569,12641,12732,12752,4,3,97,114,116,11523,11528,11532,114,114,59,1,8666,114,59,1,8656,97,105,108,59,1,10523,97,114,114,59,1,10510,4,2,59,103,11550,11552,1,8806,59,1,10891,97,114,59,1,10594,4,9,99,101,103,109,110,112,113,114,116,11580,11586,11594,11600,11606,11624,11627,11636,11694,117,116,101,59,1,314,109,112,116,121,118,59,1,10676,114,97,110,59,1,8466,98,100,97,59,1,955,103,4,3,59,100,108,11615,11617,11620,1,10216,59,1,10641,101,59,1,10216,59,1,10885,117,111,5,171,1,59,11634,1,171,114,4,8,59,98,102,104,108,112,115,116,11655,11657,11669,11673,11677,11681,11685,11690,1,8592,4,2,59,102,11663,11665,1,8676,115,59,1,10527,115,59,1,10525,107,59,1,8617,112,59,1,8619,108,59,1,10553,105,109,59,1,10611,108,59,1,8610,4,3,59,97,101,11702,11704,11709,1,10923,105,108,59,1,10521,4,2,59,115,11715,11717,1,10925,59,3,10925,65024,4,3,97,98,114,11729,11734,11739,114,114,59,1,10508,114,107,59,1,10098,4,2,97,107,11745,11758,99,4,2,101,107,11752,11755,59,1,123,59,1,91,4,2,101,115,11764,11767,59,1,10635,108,4,2,100,117,11774,11777,59,1,10639,59,1,10637,4,4,97,101,117,121,11790,11796,11811,11815,114,111,110,59,1,318,4,2,100,105,11802,11807,105,108,59,1,316,108,59,1,8968,98,59,1,123,59,1,1083,4,4,99,113,114,115,11828,11832,11845,11864,97,59,1,10550,117,111,4,2,59,114,11840,11842,1,8220,59,1,8222,4,2,100,117,11851,11857,104,97,114,59,1,10599,115,104,97,114,59,1,10571,104,59,1,8626,4,5,59,102,103,113,115,11880,11882,12008,12011,12031,1,8804,116,4,5,97,104,108,114,116,11895,11913,11935,11947,11996,114,114,111,119,4,2,59,116,11905,11907,1,8592,97,105,108,59,1,8610,97,114,112,111,111,110,4,2,100,117,11925,11931,111,119,110,59,1,8637,112,59,1,8636,101,102,116,97,114,114,111,119,115,59,1,8647,105,103,104,116,4,3,97,104,115,11959,11974,11984,114,114,111,119,4,2,59,115,11969,11971,1,8596,59,1,8646,97,114,112,111,111,110,115,59,1,8651,113,117,105,103,97,114,114,111,119,59,1,8621,104,114,101,101,116,105,109,101,115,59,1,8907,59,1,8922,4,3,59,113,115,12019,12021,12024,1,8804,59,1,8806,108,97,110,116,59,1,10877,4,5,59,99,100,103,115,12043,12045,12049,12070,12083,1,10877,99,59,1,10920,111,116,4,2,59,111,12057,12059,1,10879,4,2,59,114,12065,12067,1,10881,59,1,10883,4,2,59,101,12076,12079,3,8922,65024,115,59,1,10899,4,5,97,100,101,103,115,12095,12103,12108,12126,12131,112,112,114,111,120,59,1,10885,111,116,59,1,8918,113,4,2,103,113,12115,12120,116,114,59,1,8922,103,116,114,59,1,10891,116,114,59,1,8822,105,109,59,1,8818,4,3,105,108,114,12144,12150,12156,115,104,116,59,1,10620,111,111,114,59,1,8970,59,3,55349,56617,4,2,59,69,12166,12168,1,8822,59,1,10897,4,2,97,98,12177,12198,114,4,2,100,117,12184,12187,59,1,8637,4,2,59,108,12193,12195,1,8636,59,1,10602,108,107,59,1,9604,99,121,59,1,1113,4,5,59,97,99,104,116,12220,12222,12227,12235,12241,1,8810,114,114,59,1,8647,111,114,110,101,114,59,1,8990,97,114,100,59,1,10603,114,105,59,1,9722,4,2,105,111,12252,12258,100,111,116,59,1,320,117,115,116,4,2,59,97,12267,12269,1,9136,99,104,101,59,1,9136,4,4,69,97,101,115,12285,12288,12303,12322,59,1,8808,112,4,2,59,112,12295,12297,1,10889,114,111,120,59,1,10889,4,2,59,113,12309,12311,1,10887,4,2,59,113,12317,12319,1,10887,59,1,8808,105,109,59,1,8934,4,8,97,98,110,111,112,116,119,122,12345,12359,12364,12421,12446,12467,12474,12490,4,2,110,114,12351,12355,103,59,1,10220,114,59,1,8701,114,107,59,1,10214,103,4,3,108,109,114,12373,12401,12409,101,102,116,4,2,97,114,12382,12389,114,114,111,119,59,1,10229,105,103,104,116,97,114,114,111,119,59,1,10231,97,112,115,116,111,59,1,10236,105,103,104,116,97,114,114,111,119,59,1,10230,112,97,114,114,111,119,4,2,108,114,12433,12439,101,102,116,59,1,8619,105,103,104,116,59,1,8620,4,3,97,102,108,12454,12458,12462,114,59,1,10629,59,3,55349,56669,117,115,59,1,10797,105,109,101,115,59,1,10804,4,2,97,98,12480,12485,115,116,59,1,8727,97,114,59,1,95,4,3,59,101,102,12498,12500,12506,1,9674,110,103,101,59,1,9674,59,1,10731,97,114,4,2,59,108,12517,12519,1,40,116,59,1,10643,4,5,97,99,104,109,116,12535,12540,12548,12561,12564,114,114,59,1,8646,111,114,110,101,114,59,1,8991,97,114,4,2,59,100,12556,12558,1,8651,59,1,10605,59,1,8206,114,105,59,1,8895,4,6,97,99,104,105,113,116,12583,12589,12594,12597,12614,12635,113,117,111,59,1,8249,114,59,3,55349,56513,59,1,8624,109,4,3,59,101,103,12606,12608,12611,1,8818,59,1,10893,59,1,10895,4,2,98,117,12620,12623,59,1,91,111,4,2,59,114,12630,12632,1,8216,59,1,8218,114,111,107,59,1,322,5,60,8,59,99,100,104,105,108,113,114,12660,12662,12675,12680,12686,12692,12698,12705,1,60,4,2,99,105,12668,12671,59,1,10918,114,59,1,10873,111,116,59,1,8918,114,101,101,59,1,8907,109,101,115,59,1,8905,97,114,114,59,1,10614,117,101,115,116,59,1,10875,4,2,80,105,12711,12716,97,114,59,1,10646,4,3,59,101,102,12724,12726,12729,1,9667,59,1,8884,59,1,9666,114,4,2,100,117,12739,12746,115,104,97,114,59,1,10570,104,97,114,59,1,10598,4,2,101,110,12758,12768,114,116,110,101,113,113,59,3,8808,65024,69,59,3,8808,65024,4,14,68,97,99,100,101,102,104,105,108,110,111,112,115,117,12803,12809,12893,12908,12914,12928,12933,12937,13011,13025,13032,13049,13052,13069,68,111,116,59,1,8762,4,4,99,108,112,114,12819,12827,12849,12887,114,5,175,1,59,12825,1,175,4,2,101,116,12833,12836,59,1,9794,4,2,59,101,12842,12844,1,10016,115,101,59,1,10016,4,2,59,115,12855,12857,1,8614,116,111,4,4,59,100,108,117,12869,12871,12877,12883,1,8614,111,119,110,59,1,8615,101,102,116,59,1,8612,112,59,1,8613,107,101,114,59,1,9646,4,2,111,121,12899,12905,109,109,97,59,1,10793,59,1,1084,97,115,104,59,1,8212,97,115,117,114,101,100,97,110,103,108,101,59,1,8737,114,59,3,55349,56618,111,59,1,8487,4,3,99,100,110,12945,12954,12985,114,111,5,181,1,59,12952,1,181,4,4,59,97,99,100,12964,12966,12971,12976,1,8739,115,116,59,1,42,105,114,59,1,10992,111,116,5,183,1,59,12983,1,183,117,115,4,3,59,98,100,12995,12997,13000,1,8722,59,1,8863,4,2,59,117,13006,13008,1,8760,59,1,10794,4,2,99,100,13017,13021,112,59,1,10971,114,59,1,8230,112,108,117,115,59,1,8723,4,2,100,112,13038,13044,101,108,115,59,1,8871,102,59,3,55349,56670,59,1,8723,4,2,99,116,13058,13063,114,59,3,55349,56514,112,111,115,59,1,8766,4,3,59,108,109,13077,13079,13087,1,956,116,105,109,97,112,59,1,8888,97,112,59,1,8888,4,24,71,76,82,86,97,98,99,100,101,102,103,104,105,106,108,109,111,112,114,115,116,117,118,119,13142,13165,13217,13229,13247,13330,13359,13414,13420,13508,13513,13579,13602,13626,13631,13762,13767,13855,13936,13995,14214,14285,14312,14432,4,2,103,116,13148,13152,59,3,8921,824,4,2,59,118,13158,13161,3,8811,8402,59,3,8811,824,4,3,101,108,116,13173,13200,13204,102,116,4,2,97,114,13181,13188,114,114,111,119,59,1,8653,105,103,104,116,97,114,114,111,119,59,1,8654,59,3,8920,824,4,2,59,118,13210,13213,3,8810,8402,59,3,8810,824,105,103,104,116,97,114,114,111,119,59,1,8655,4,2,68,100,13235,13241,97,115,104,59,1,8879,97,115,104,59,1,8878,4,5,98,99,110,112,116,13259,13264,13270,13275,13308,108,97,59,1,8711,117,116,101,59,1,324,103,59,3,8736,8402,4,5,59,69,105,111,112,13287,13289,13293,13298,13302,1,8777,59,3,10864,824,100,59,3,8779,824,115,59,1,329,114,111,120,59,1,8777,117,114,4,2,59,97,13316,13318,1,9838,108,4,2,59,115,13325,13327,1,9838,59,1,8469,4,2,115,117,13336,13344,112,5,160,1,59,13342,1,160,109,112,4,2,59,101,13352,13355,3,8782,824,59,3,8783,824,4,5,97,101,111,117,121,13371,13385,13391,13407,13411,4,2,112,114,13377,13380,59,1,10819,111,110,59,1,328,100,105,108,59,1,326,110,103,4,2,59,100,13399,13401,1,8775,111,116,59,3,10861,824,112,59,1,10818,59,1,1085,97,115,104,59,1,8211,4,7,59,65,97,100,113,115,120,13436,13438,13443,13466,13472,13478,13494,1,8800,114,114,59,1,8663,114,4,2,104,114,13450,13454,107,59,1,10532,4,2,59,111,13460,13462,1,8599,119,59,1,8599,111,116,59,3,8784,824,117,105,118,59,1,8802,4,2,101,105,13484,13489,97,114,59,1,10536,109,59,3,8770,824,105,115,116,4,2,59,115,13503,13505,1,8708,59,1,8708,114,59,3,55349,56619,4,4,69,101,115,116,13523,13527,13563,13568,59,3,8807,824,4,3,59,113,115,13535,13537,13559,1,8817,4,3,59,113,115,13545,13547,13551,1,8817,59,3,8807,824,108,97,110,116,59,3,10878,824,59,3,10878,824,105,109,59,1,8821,4,2,59,114,13574,13576,1,8815,59,1,8815,4,3,65,97,112,13587,13592,13597,114,114,59,1,8654,114,114,59,1,8622,97,114,59,1,10994,4,3,59,115,118,13610,13612,13623,1,8715,4,2,59,100,13618,13620,1,8956,59,1,8954,59,1,8715,99,121,59,1,1114,4,7,65,69,97,100,101,115,116,13647,13652,13656,13661,13665,13737,13742,114,114,59,1,8653,59,3,8806,824,114,114,59,1,8602,114,59,1,8229,4,4,59,102,113,115,13675,13677,13703,13725,1,8816,116,4,2,97,114,13684,13691,114,114,111,119,59,1,8602,105,103,104,116,97,114,114,111,119,59,1,8622,4,3,59,113,115,13711,13713,13717,1,8816,59,3,8806,824,108,97,110,116,59,3,10877,824,4,2,59,115,13731,13734,3,10877,824,59,1,8814,105,109,59,1,8820,4,2,59,114,13748,13750,1,8814,105,4,2,59,101,13757,13759,1,8938,59,1,8940,105,100,59,1,8740,4,2,112,116,13773,13778,102,59,3,55349,56671,5,172,3,59,105,110,13787,13789,13829,1,172,110,4,4,59,69,100,118,13800,13802,13806,13812,1,8713,59,3,8953,824,111,116,59,3,8949,824,4,3,97,98,99,13820,13823,13826,59,1,8713,59,1,8951,59,1,8950,105,4,2,59,118,13836,13838,1,8716,4,3,97,98,99,13846,13849,13852,59,1,8716,59,1,8958,59,1,8957,4,3,97,111,114,13863,13892,13899,114,4,4,59,97,115,116,13874,13876,13883,13888,1,8742,108,108,101,108,59,1,8742,108,59,3,11005,8421,59,3,8706,824,108,105,110,116,59,1,10772,4,3,59,99,101,13907,13909,13914,1,8832,117,101,59,1,8928,4,2,59,99,13920,13923,3,10927,824,4,2,59,101,13929,13931,1,8832,113,59,3,10927,824,4,4,65,97,105,116,13946,13951,13971,13982,114,114,59,1,8655,114,114,4,3,59,99,119,13961,13963,13967,1,8603,59,3,10547,824,59,3,8605,824,103,104,116,97,114,114,111,119,59,1,8603,114,105,4,2,59,101,13990,13992,1,8939,59,1,8941,4,7,99,104,105,109,112,113,117,14011,14036,14060,14080,14085,14090,14106,4,4,59,99,101,114,14021,14023,14028,14032,1,8833,117,101,59,1,8929,59,3,10928,824,59,3,55349,56515,111,114,116,4,2,109,112,14045,14050,105,100,59,1,8740,97,114,97,108,108,101,108,59,1,8742,109,4,2,59,101,14067,14069,1,8769,4,2,59,113,14075,14077,1,8772,59,1,8772,105,100,59,1,8740,97,114,59,1,8742,115,117,4,2,98,112,14098,14102,101,59,1,8930,101,59,1,8931,4,3,98,99,112,14114,14157,14171,4,4,59,69,101,115,14124,14126,14130,14133,1,8836,59,3,10949,824,59,1,8840,101,116,4,2,59,101,14141,14144,3,8834,8402,113,4,2,59,113,14151,14153,1,8840,59,3,10949,824,99,4,2,59,101,14164,14166,1,8833,113,59,3,10928,824,4,4,59,69,101,115,14181,14183,14187,14190,1,8837,59,3,10950,824,59,1,8841,101,116,4,2,59,101,14198,14201,3,8835,8402,113,4,2,59,113,14208,14210,1,8841,59,3,10950,824,4,4,103,105,108,114,14224,14228,14238,14242,108,59,1,8825,108,100,101,5,241,1,59,14236,1,241,103,59,1,8824,105,97,110,103,108,101,4,2,108,114,14254,14269,101,102,116,4,2,59,101,14263,14265,1,8938,113,59,1,8940,105,103,104,116,4,2,59,101,14279,14281,1,8939,113,59,1,8941,4,2,59,109,14291,14293,1,957,4,3,59,101,115,14301,14303,14308,1,35,114,111,59,1,8470,112,59,1,8199,4,9,68,72,97,100,103,105,108,114,115,14332,14338,14344,14349,14355,14369,14376,14408,14426,97,115,104,59,1,8877,97,114,114,59,1,10500,112,59,3,8781,8402,97,115,104,59,1,8876,4,2,101,116,14361,14365,59,3,8805,8402,59,3,62,8402,110,102,105,110,59,1,10718,4,3,65,101,116,14384,14389,14393,114,114,59,1,10498,59,3,8804,8402,4,2,59,114,14399,14402,3,60,8402,105,101,59,3,8884,8402,4,2,65,116,14414,14419,114,114,59,1,10499,114,105,101,59,3,8885,8402,105,109,59,3,8764,8402,4,3,65,97,110,14440,14445,14468,114,114,59,1,8662,114,4,2,104,114,14452,14456,107,59,1,10531,4,2,59,111,14462,14464,1,8598,119,59,1,8598,101,97,114,59,1,10535,4,18,83,97,99,100,101,102,103,104,105,108,109,111,112,114,115,116,117,118,14512,14515,14535,14560,14597,14603,14618,14643,14657,14662,14701,14741,14747,14769,14851,14877,14907,14916,59,1,9416,4,2,99,115,14521,14531,117,116,101,5,243,1,59,14529,1,243,116,59,1,8859,4,2,105,121,14541,14557,114,4,2,59,99,14548,14550,1,8858,5,244,1,59,14555,1,244,59,1,1086,4,5,97,98,105,111,115,14572,14577,14583,14587,14591,115,104,59,1,8861,108,97,99,59,1,337,118,59,1,10808,116,59,1,8857,111,108,100,59,1,10684,108,105,103,59,1,339,4,2,99,114,14609,14614,105,114,59,1,10687,59,3,55349,56620,4,3,111,114,116,14626,14630,14640,110,59,1,731,97,118,101,5,242,1,59,14638,1,242,59,1,10689,4,2,98,109,14649,14654,97,114,59,1,10677,59,1,937,110,116,59,1,8750,4,4,97,99,105,116,14672,14677,14693,14698,114,114,59,1,8634,4,2,105,114,14683,14687,114,59,1,10686,111,115,115,59,1,10683,110,101,59,1,8254,59,1,10688,4,3,97,101,105,14709,14714,14719,99,114,59,1,333,103,97,59,1,969,4,3,99,100,110,14727,14733,14736,114,111,110,59,1,959,59,1,10678,117,115,59,1,8854,112,102,59,3,55349,56672,4,3,97,101,108,14755,14759,14764,114,59,1,10679,114,112,59,1,10681,117,115,59,1,8853,4,7,59,97,100,105,111,115,118,14785,14787,14792,14831,14837,14841,14848,1,8744,114,114,59,1,8635,4,4,59,101,102,109,14802,14804,14817,14824,1,10845,114,4,2,59,111,14811,14813,1,8500,102,59,1,8500,5,170,1,59,14822,1,170,5,186,1,59,14829,1,186,103,111,102,59,1,8886,114,59,1,10838,108,111,112,101,59,1,10839,59,1,10843,4,3,99,108,111,14859,14863,14873,114,59,1,8500,97,115,104,5,248,1,59,14871,1,248,108,59,1,8856,105,4,2,108,109,14884,14893,100,101,5,245,1,59,14891,1,245,101,115,4,2,59,97,14901,14903,1,8855,115,59,1,10806,109,108,5,246,1,59,14914,1,246,98,97,114,59,1,9021,4,12,97,99,101,102,104,105,108,109,111,114,115,117,14948,14992,14996,15033,15038,15068,15090,15189,15192,15222,15427,15441,114,4,4,59,97,115,116,14959,14961,14976,14989,1,8741,5,182,2,59,108,14968,14970,1,182,108,101,108,59,1,8741,4,2,105,108,14982,14986,109,59,1,10995,59,1,11005,59,1,8706,121,59,1,1087,114,4,5,99,105,109,112,116,15009,15014,15019,15024,15027,110,116,59,1,37,111,100,59,1,46,105,108,59,1,8240,59,1,8869,101,110,107,59,1,8241,114,59,3,55349,56621,4,3,105,109,111,15046,15057,15063,4,2,59,118,15052,15054,1,966,59,1,981,109,97,116,59,1,8499,110,101,59,1,9742,4,3,59,116,118,15076,15078,15087,1,960,99,104,102,111,114,107,59,1,8916,59,1,982,4,2,97,117,15096,15119,110,4,2,99,107,15103,15115,107,4,2,59,104,15110,15112,1,8463,59,1,8462,118,59,1,8463,115,4,9,59,97,98,99,100,101,109,115,116,15140,15142,15148,15151,15156,15168,15171,15179,15184,1,43,99,105,114,59,1,10787,59,1,8862,105,114,59,1,10786,4,2,111,117,15162,15165,59,1,8724,59,1,10789,59,1,10866,110,5,177,1,59,15177,1,177,105,109,59,1,10790,119,111,59,1,10791,59,1,177,4,3,105,112,117,15200,15208,15213,110,116,105,110,116,59,1,10773,102,59,3,55349,56673,110,100,5,163,1,59,15220,1,163,4,10,59,69,97,99,101,105,110,111,115,117,15244,15246,15249,15253,15258,15334,15347,15367,15416,15421,1,8826,59,1,10931,112,59,1,10935,117,101,59,1,8828,4,2,59,99,15264,15266,1,10927,4,6,59,97,99,101,110,115,15280,15282,15290,15299,15303,15329,1,8826,112,112,114,111,120,59,1,10935,117,114,108,121,101,113,59,1,8828,113,59,1,10927,4,3,97,101,115,15311,15319,15324,112,112,114,111,120,59,1,10937,113,113,59,1,10933,105,109,59,1,8936,105,109,59,1,8830,109,101,4,2,59,115,15342,15344,1,8242,59,1,8473,4,3,69,97,115,15355,15358,15362,59,1,10933,112,59,1,10937,105,109,59,1,8936,4,3,100,102,112,15375,15378,15404,59,1,8719,4,3,97,108,115,15386,15392,15398,108,97,114,59,1,9006,105,110,101,59,1,8978,117,114,102,59,1,8979,4,2,59,116,15410,15412,1,8733,111,59,1,8733,105,109,59,1,8830,114,101,108,59,1,8880,4,2,99,105,15433,15438,114,59,3,55349,56517,59,1,968,110,99,115,112,59,1,8200,4,6,102,105,111,112,115,117,15462,15467,15472,15478,15485,15491,114,59,3,55349,56622,110,116,59,1,10764,112,102,59,3,55349,56674,114,105,109,101,59,1,8279,99,114,59,3,55349,56518,4,3,97,101,111,15499,15520,15534,116,4,2,101,105,15506,15515,114,110,105,111,110,115,59,1,8461,110,116,59,1,10774,115,116,4,2,59,101,15528,15530,1,63,113,59,1,8799,116,5,34,1,59,15540,1,34,4,21,65,66,72,97,98,99,100,101,102,104,105,108,109,110,111,112,114,115,116,117,120,15586,15609,15615,15620,15796,15855,15893,15931,15977,16001,16039,16183,16204,16222,16228,16285,16312,16318,16363,16408,16416,4,3,97,114,116,15594,15599,15603,114,114,59,1,8667,114,59,1,8658,97,105,108,59,1,10524,97,114,114,59,1,10511,97,114,59,1,10596,4,7,99,100,101,110,113,114,116,15636,15651,15656,15664,15687,15696,15770,4,2,101,117,15642,15646,59,3,8765,817,116,101,59,1,341,105,99,59,1,8730,109,112,116,121,118,59,1,10675,103,4,4,59,100,101,108,15675,15677,15680,15683,1,10217,59,1,10642,59,1,10661,101,59,1,10217,117,111,5,187,1,59,15694,1,187,114,4,11,59,97,98,99,102,104,108,112,115,116,119,15721,15723,15727,15739,15742,15746,15750,15754,15758,15763,15767,1,8594,112,59,1,10613,4,2,59,102,15733,15735,1,8677,115,59,1,10528,59,1,10547,115,59,1,10526,107,59,1,8618,112,59,1,8620,108,59,1,10565,105,109,59,1,10612,108,59,1,8611,59,1,8605,4,2,97,105,15776,15781,105,108,59,1,10522,111,4,2,59,110,15788,15790,1,8758,97,108,115,59,1,8474,4,3,97,98,114,15804,15809,15814,114,114,59,1,10509,114,107,59,1,10099,4,2,97,107,15820,15833,99,4,2,101,107,15827,15830,59,1,125,59,1,93,4,2,101,115,15839,15842,59,1,10636,108,4,2,100,117,15849,15852,59,1,10638,59,1,10640,4,4,97,101,117,121,15865,15871,15886,15890,114,111,110,59,1,345,4,2,100,105,15877,15882,105,108,59,1,343,108,59,1,8969,98,59,1,125,59,1,1088,4,4,99,108,113,115,15903,15907,15914,15927,97,59,1,10551,100,104,97,114,59,1,10601,117,111,4,2,59,114,15922,15924,1,8221,59,1,8221,104,59,1,8627,4,3,97,99,103,15939,15966,15970,108,4,4,59,105,112,115,15950,15952,15957,15963,1,8476,110,101,59,1,8475,97,114,116,59,1,8476,59,1,8477,116,59,1,9645,5,174,1,59,15975,1,174,4,3,105,108,114,15985,15991,15997,115,104,116,59,1,10621,111,111,114,59,1,8971,59,3,55349,56623,4,2,97,111,16007,16028,114,4,2,100,117,16014,16017,59,1,8641,4,2,59,108,16023,16025,1,8640,59,1,10604,4,2,59,118,16034,16036,1,961,59,1,1009,4,3,103,110,115,16047,16167,16171,104,116,4,6,97,104,108,114,115,116,16063,16081,16103,16130,16143,16155,114,114,111,119,4,2,59,116,16073,16075,1,8594,97,105,108,59,1,8611,97,114,112,111,111,110,4,2,100,117,16093,16099,111,119,110,59,1,8641,112,59,1,8640,101,102,116,4,2,97,104,16112,16120,114,114,111,119,115,59,1,8644,97,114,112,111,111,110,115,59,1,8652,105,103,104,116,97,114,114,111,119,115,59,1,8649,113,117,105,103,97,114,114,111,119,59,1,8605,104,114,101,101,116,105,109,101,115,59,1,8908,103,59,1,730,105,110,103,100,111,116,115,101,113,59,1,8787,4,3,97,104,109,16191,16196,16201,114,114,59,1,8644,97,114,59,1,8652,59,1,8207,111,117,115,116,4,2,59,97,16214,16216,1,9137,99,104,101,59,1,9137,109,105,100,59,1,10990,4,4,97,98,112,116,16238,16252,16257,16278,4,2,110,114,16244,16248,103,59,1,10221,114,59,1,8702,114,107,59,1,10215,4,3,97,102,108,16265,16269,16273,114,59,1,10630,59,3,55349,56675,117,115,59,1,10798,105,109,101,115,59,1,10805,4,2,97,112,16291,16304,114,4,2,59,103,16298,16300,1,41,116,59,1,10644,111,108,105,110,116,59,1,10770,97,114,114,59,1,8649,4,4,97,99,104,113,16328,16334,16339,16342,113,117,111,59,1,8250,114,59,3,55349,56519,59,1,8625,4,2,98,117,16348,16351,59,1,93,111,4,2,59,114,16358,16360,1,8217,59,1,8217,4,3,104,105,114,16371,16377,16383,114,101,101,59,1,8908,109,101,115,59,1,8906,105,4,4,59,101,102,108,16394,16396,16399,16402,1,9657,59,1,8885,59,1,9656,116,114,105,59,1,10702,108,117,104,97,114,59,1,10600,59,1,8478,4,19,97,98,99,100,101,102,104,105,108,109,111,112,113,114,115,116,117,119,122,16459,16466,16472,16572,16590,16672,16687,16746,16844,16850,16924,16963,16988,17115,17121,17154,17206,17614,17656,99,117,116,101,59,1,347,113,117,111,59,1,8218,4,10,59,69,97,99,101,105,110,112,115,121,16494,16496,16499,16513,16518,16531,16536,16556,16564,16569,1,8827,59,1,10932,4,2,112,114,16505,16508,59,1,10936,111,110,59,1,353,117,101,59,1,8829,4,2,59,100,16524,16526,1,10928,105,108,59,1,351,114,99,59,1,349,4,3,69,97,115,16544,16547,16551,59,1,10934,112,59,1,10938,105,109,59,1,8937,111,108,105,110,116,59,1,10771,105,109,59,1,8831,59,1,1089,111,116,4,3,59,98,101,16582,16584,16587,1,8901,59,1,8865,59,1,10854,4,7,65,97,99,109,115,116,120,16606,16611,16634,16642,16646,16652,16668,114,114,59,1,8664,114,4,2,104,114,16618,16622,107,59,1,10533,4,2,59,111,16628,16630,1,8600,119,59,1,8600,116,5,167,1,59,16640,1,167,105,59,1,59,119,97,114,59,1,10537,109,4,2,105,110,16659,16665,110,117,115,59,1,8726,59,1,8726,116,59,1,10038,114,4,2,59,111,16679,16682,3,55349,56624,119,110,59,1,8994,4,4,97,99,111,121,16697,16702,16716,16739,114,112,59,1,9839,4,2,104,121,16708,16713,99,121,59,1,1097,59,1,1096,114,116,4,2,109,112,16724,16729,105,100,59,1,8739,97,114,97,108,108,101,108,59,1,8741,5,173,1,59,16744,1,173,4,2,103,109,16752,16770,109,97,4,3,59,102,118,16762,16764,16767,1,963,59,1,962,59,1,962,4,8,59,100,101,103,108,110,112,114,16788,16790,16795,16806,16817,16828,16832,16838,1,8764,111,116,59,1,10858,4,2,59,113,16801,16803,1,8771,59,1,8771,4,2,59,69,16812,16814,1,10910,59,1,10912,4,2,59,69,16823,16825,1,10909,59,1,10911,101,59,1,8774,108,117,115,59,1,10788,97,114,114,59,1,10610,97,114,114,59,1,8592,4,4,97,101,105,116,16860,16883,16891,16904,4,2,108,115,16866,16878,108,115,101,116,109,105,110,117,115,59,1,8726,104,112,59,1,10803,112,97,114,115,108,59,1,10724,4,2,100,108,16897,16900,59,1,8739,101,59,1,8995,4,2,59,101,16910,16912,1,10922,4,2,59,115,16918,16920,1,10924,59,3,10924,65024,4,3,102,108,112,16932,16938,16958,116,99,121,59,1,1100,4,2,59,98,16944,16946,1,47,4,2,59,97,16952,16954,1,10692,114,59,1,9023,102,59,3,55349,56676,97,4,2,100,114,16970,16985,101,115,4,2,59,117,16978,16980,1,9824,105,116,59,1,9824,59,1,8741,4,3,99,115,117,16996,17028,17089,4,2,97,117,17002,17015,112,4,2,59,115,17009,17011,1,8851,59,3,8851,65024,112,4,2,59,115,17022,17024,1,8852,59,3,8852,65024,117,4,2,98,112,17035,17062,4,3,59,101,115,17043,17045,17048,1,8847,59,1,8849,101,116,4,2,59,101,17056,17058,1,8847,113,59,1,8849,4,3,59,101,115,17070,17072,17075,1,8848,59,1,8850,101,116,4,2,59,101,17083,17085,1,8848,113,59,1,8850,4,3,59,97,102,17097,17099,17112,1,9633,114,4,2,101,102,17106,17109,59,1,9633,59,1,9642,59,1,9642,97,114,114,59,1,8594,4,4,99,101,109,116,17131,17136,17142,17148,114,59,3,55349,56520,116,109,110,59,1,8726,105,108,101,59,1,8995,97,114,102,59,1,8902,4,2,97,114,17160,17172,114,4,2,59,102,17167,17169,1,9734,59,1,9733,4,2,97,110,17178,17202,105,103,104,116,4,2,101,112,17188,17197,112,115,105,108,111,110,59,1,1013,104,105,59,1,981,115,59,1,175,4,5,98,99,109,110,112,17218,17351,17420,17423,17427,4,9,59,69,100,101,109,110,112,114,115,17238,17240,17243,17248,17261,17267,17279,17285,17291,1,8834,59,1,10949,111,116,59,1,10941,4,2,59,100,17254,17256,1,8838,111,116,59,1,10947,117,108,116,59,1,10945,4,2,69,101,17273,17276,59,1,10955,59,1,8842,108,117,115,59,1,10943,97,114,114,59,1,10617,4,3,101,105,117,17299,17335,17339,116,4,3,59,101,110,17308,17310,17322,1,8834,113,4,2,59,113,17317,17319,1,8838,59,1,10949,101,113,4,2,59,113,17330,17332,1,8842,59,1,10955,109,59,1,10951,4,2,98,112,17345,17348,59,1,10965,59,1,10963,99,4,6,59,97,99,101,110,115,17366,17368,17376,17385,17389,17415,1,8827,112,112,114,111,120,59,1,10936,117,114,108,121,101,113,59,1,8829,113,59,1,10928,4,3,97,101,115,17397,17405,17410,112,112,114,111,120,59,1,10938,113,113,59,1,10934,105,109,59,1,8937,105,109,59,1,8831,59,1,8721,103,59,1,9834,4,13,49,50,51,59,69,100,101,104,108,109,110,112,115,17455,17462,17469,17476,17478,17481,17496,17509,17524,17530,17536,17548,17554,5,185,1,59,17460,1,185,5,178,1,59,17467,1,178,5,179,1,59,17474,1,179,1,8835,59,1,10950,4,2,111,115,17487,17491,116,59,1,10942,117,98,59,1,10968,4,2,59,100,17502,17504,1,8839,111,116,59,1,10948,115,4,2,111,117,17516,17520,108,59,1,10185,98,59,1,10967,97,114,114,59,1,10619,117,108,116,59,1,10946,4,2,69,101,17542,17545,59,1,10956,59,1,8843,108,117,115,59,1,10944,4,3,101,105,117,17562,17598,17602,116,4,3,59,101,110,17571,17573,17585,1,8835,113,4,2,59,113,17580,17582,1,8839,59,1,10950,101,113,4,2,59,113,17593,17595,1,8843,59,1,10956,109,59,1,10952,4,2,98,112,17608,17611,59,1,10964,59,1,10966,4,3,65,97,110,17622,17627,17650,114,114,59,1,8665,114,4,2,104,114,17634,17638,107,59,1,10534,4,2,59,111,17644,17646,1,8601,119,59,1,8601,119,97,114,59,1,10538,108,105,103,5,223,1,59,17664,1,223,4,13,97,98,99,100,101,102,104,105,111,112,114,115,119,17694,17709,17714,17737,17742,17749,17754,17860,17905,17957,17964,18090,18122,4,2,114,117,17700,17706,103,101,116,59,1,8982,59,1,964,114,107,59,1,9140,4,3,97,101,121,17722,17728,17734,114,111,110,59,1,357,100,105,108,59,1,355,59,1,1090,111,116,59,1,8411,108,114,101,99,59,1,8981,114,59,3,55349,56625,4,4,101,105,107,111,17764,17805,17836,17851,4,2,114,116,17770,17786,101,4,2,52,102,17777,17780,59,1,8756,111,114,101,59,1,8756,97,4,3,59,115,118,17795,17797,17802,1,952,121,109,59,1,977,59,1,977,4,2,99,110,17811,17831,107,4,2,97,115,17818,17826,112,112,114,111,120,59,1,8776,105,109,59,1,8764,115,112,59,1,8201,4,2,97,115,17842,17846,112,59,1,8776,105,109,59,1,8764,114,110,5,254,1,59,17858,1,254,4,3,108,109,110,17868,17873,17901,100,101,59,1,732,101,115,5,215,3,59,98,100,17884,17886,17898,1,215,4,2,59,97,17892,17894,1,8864,114,59,1,10801,59,1,10800,116,59,1,8749,4,3,101,112,115,17913,17917,17953,97,59,1,10536,4,4,59,98,99,102,17927,17929,17934,17939,1,8868,111,116,59,1,9014,105,114,59,1,10993,4,2,59,111,17945,17948,3,55349,56677,114,107,59,1,10970,97,59,1,10537,114,105,109,101,59,1,8244,4,3,97,105,112,17972,17977,18082,100,101,59,1,8482,4,7,97,100,101,109,112,115,116,17993,18051,18056,18059,18066,18072,18076,110,103,108,101,4,5,59,100,108,113,114,18009,18011,18017,18032,18035,1,9653,111,119,110,59,1,9663,101,102,116,4,2,59,101,18026,18028,1,9667,113,59,1,8884,59,1,8796,105,103,104,116,4,2,59,101,18045,18047,1,9657,113,59,1,8885,111,116,59,1,9708,59,1,8796,105,110,117,115,59,1,10810,108,117,115,59,1,10809,98,59,1,10701,105,109,101,59,1,10811,101,122,105,117,109,59,1,9186,4,3,99,104,116,18098,18111,18116,4,2,114,121,18104,18108,59,3,55349,56521,59,1,1094,99,121,59,1,1115,114,111,107,59,1,359,4,2,105,111,18128,18133,120,116,59,1,8812,104,101,97,100,4,2,108,114,18143,18154,101,102,116,97,114,114,111,119,59,1,8606,105,103,104,116,97,114,114,111,119,59,1,8608,4,18,65,72,97,98,99,100,102,103,104,108,109,111,112,114,115,116,117,119,18204,18209,18214,18234,18250,18268,18292,18308,18319,18343,18379,18397,18413,18504,18547,18553,18584,18603,114,114,59,1,8657,97,114,59,1,10595,4,2,99,114,18220,18230,117,116,101,5,250,1,59,18228,1,250,114,59,1,8593,114,4,2,99,101,18241,18245,121,59,1,1118,118,101,59,1,365,4,2,105,121,18256,18265,114,99,5,251,1,59,18263,1,251,59,1,1091,4,3,97,98,104,18276,18281,18287,114,114,59,1,8645,108,97,99,59,1,369,97,114,59,1,10606,4,2,105,114,18298,18304,115,104,116,59,1,10622,59,3,55349,56626,114,97,118,101,5,249,1,59,18317,1,249,4,2,97,98,18325,18338,114,4,2,108,114,18332,18335,59,1,8639,59,1,8638,108,107,59,1,9600,4,2,99,116,18349,18374,4,2,111,114,18355,18369,114,110,4,2,59,101,18363,18365,1,8988,114,59,1,8988,111,112,59,1,8975,114,105,59,1,9720,4,2,97,108,18385,18390,99,114,59,1,363,5,168,1,59,18395,1,168,4,2,103,112,18403,18408,111,110,59,1,371,102,59,3,55349,56678,4,6,97,100,104,108,115,117,18427,18434,18445,18470,18475,18494,114,114,111,119,59,1,8593,111,119,110,97,114,114,111,119,59,1,8597,97,114,112,111,111,110,4,2,108,114,18457,18463,101,102,116,59,1,8639,105,103,104,116,59,1,8638,117,115,59,1,8846,105,4,3,59,104,108,18484,18486,18489,1,965,59,1,978,111,110,59,1,965,112,97,114,114,111,119,115,59,1,8648,4,3,99,105,116,18512,18537,18542,4,2,111,114,18518,18532,114,110,4,2,59,101,18526,18528,1,8989,114,59,1,8989,111,112,59,1,8974,110,103,59,1,367,114,105,59,1,9721,99,114,59,3,55349,56522,4,3,100,105,114,18561,18566,18572,111,116,59,1,8944,108,100,101,59,1,361,105,4,2,59,102,18579,18581,1,9653,59,1,9652,4,2,97,109,18590,18595,114,114,59,1,8648,108,5,252,1,59,18601,1,252,97,110,103,108,101,59,1,10663,4,15,65,66,68,97,99,100,101,102,108,110,111,112,114,115,122,18643,18648,18661,18667,18847,18851,18857,18904,18909,18915,18931,18937,18943,18949,18996,114,114,59,1,8661,97,114,4,2,59,118,18656,18658,1,10984,59,1,10985,97,115,104,59,1,8872,4,2,110,114,18673,18679,103,114,116,59,1,10652,4,7,101,107,110,112,114,115,116,18695,18704,18711,18720,18742,18754,18810,112,115,105,108,111,110,59,1,1013,97,112,112,97,59,1,1008,111,116,104,105,110,103,59,1,8709,4,3,104,105,114,18728,18732,18735,105,59,1,981,59,1,982,111,112,116,111,59,1,8733,4,2,59,104,18748,18750,1,8597,111,59,1,1009,4,2,105,117,18760,18766,103,109,97,59,1,962,4,2,98,112,18772,18791,115,101,116,110,101,113,4,2,59,113,18784,18787,3,8842,65024,59,3,10955,65024,115,101,116,110,101,113,4,2,59,113,18803,18806,3,8843,65024,59,3,10956,65024,4,2,104,114,18816,18822,101,116,97,59,1,977,105,97,110,103,108,101,4,2,108,114,18834,18840,101,102,116,59,1,8882,105,103,104,116,59,1,8883,121,59,1,1074,97,115,104,59,1,8866,4,3,101,108,114,18865,18884,18890,4,3,59,98,101,18873,18875,18880,1,8744,97,114,59,1,8891,113,59,1,8794,108,105,112,59,1,8942,4,2,98,116,18896,18901,97,114,59,1,124,59,1,124,114,59,3,55349,56627,116,114,105,59,1,8882,115,117,4,2,98,112,18923,18927,59,3,8834,8402,59,3,8835,8402,112,102,59,3,55349,56679,114,111,112,59,1,8733,116,114,105,59,1,8883,4,2,99,117,18955,18960,114,59,3,55349,56523,4,2,98,112,18966,18981,110,4,2,69,101,18973,18977,59,3,10955,65024,59,3,8842,65024,110,4,2,69,101,18988,18992,59,3,10956,65024,59,3,8843,65024,105,103,122,97,103,59,1,10650,4,7,99,101,102,111,112,114,115,19020,19026,19061,19066,19072,19075,19089,105,114,99,59,1,373,4,2,100,105,19032,19055,4,2,98,103,19038,19043,97,114,59,1,10847,101,4,2,59,113,19050,19052,1,8743,59,1,8793,101,114,112,59,1,8472,114,59,3,55349,56628,112,102,59,3,55349,56680,59,1,8472,4,2,59,101,19081,19083,1,8768,97,116,104,59,1,8768,99,114,59,3,55349,56524,4,14,99,100,102,104,105,108,109,110,111,114,115,117,118,119,19125,19146,19152,19157,19173,19176,19192,19197,19202,19236,19252,19269,19286,19291,4,3,97,105,117,19133,19137,19142,112,59,1,8898,114,99,59,1,9711,112,59,1,8899,116,114,105,59,1,9661,114,59,3,55349,56629,4,2,65,97,19163,19168,114,114,59,1,10234,114,114,59,1,10231,59,1,958,4,2,65,97,19182,19187,114,114,59,1,10232,114,114,59,1,10229,97,112,59,1,10236,105,115,59,1,8955,4,3,100,112,116,19210,19215,19230,111,116,59,1,10752,4,2,102,108,19221,19225,59,3,55349,56681,117,115,59,1,10753,105,109,101,59,1,10754,4,2,65,97,19242,19247,114,114,59,1,10233,114,114,59,1,10230,4,2,99,113,19258,19263,114,59,3,55349,56525,99,117,112,59,1,10758,4,2,112,116,19275,19281,108,117,115,59,1,10756,114,105,59,1,9651,101,101,59,1,8897,101,100,103,101,59,1,8896,4,8,97,99,101,102,105,111,115,117,19316,19335,19349,19357,19362,19367,19373,19379,99,4,2,117,121,19323,19332,116,101,5,253,1,59,19330,1,253,59,1,1103,4,2,105,121,19341,19346,114,99,59,1,375,59,1,1099,110,5,165,1,59,19355,1,165,114,59,3,55349,56630,99,121,59,1,1111,112,102,59,3,55349,56682,99,114,59,3,55349,56526,4,2,99,109,19385,19389,121,59,1,1102,108,5,255,1,59,19395,1,255,4,10,97,99,100,101,102,104,105,111,115,119,19419,19426,19441,19446,19462,19467,19472,19480,19486,19492,99,117,116,101,59,1,378,4,2,97,121,19432,19438,114,111,110,59,1,382,59,1,1079,111,116,59,1,380,4,2,101,116,19452,19458,116,114,102,59,1,8488,97,59,1,950,114,59,3,55349,56631,99,121,59,1,1078,103,114,97,114,114,59,1,8669,112,102,59,3,55349,56683,99,114,59,3,55349,56527,4,2,106,110,19498,19501,59,1,8205,106,59,1,8204]);
 
 /***/ }),
-/* 314 */
+/* 326 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const HTML = __webpack_require__(315);
+const HTML = __webpack_require__(327);
 
 //Aliases
 const $ = HTML.TAG_NAMES;
@@ -53237,7 +55239,7 @@ module.exports = OpenElementStack;
 
 
 /***/ }),
-/* 315 */
+/* 327 */
 /***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
@@ -53516,7 +55518,7 @@ exports.SPECIAL_ELEMENTS = {
 
 
 /***/ }),
-/* 316 */
+/* 328 */
 /***/ ((module) => {
 
 "use strict";
@@ -53704,17 +55706,17 @@ module.exports = FormattingElementList;
 
 
 /***/ }),
-/* 317 */
+/* 329 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Mixin = __webpack_require__(318);
-const Tokenizer = __webpack_require__(309);
-const LocationInfoTokenizerMixin = __webpack_require__(319);
-const LocationInfoOpenElementStackMixin = __webpack_require__(321);
-const HTML = __webpack_require__(315);
+const Mixin = __webpack_require__(330);
+const Tokenizer = __webpack_require__(321);
+const LocationInfoTokenizerMixin = __webpack_require__(331);
+const LocationInfoOpenElementStackMixin = __webpack_require__(333);
+const HTML = __webpack_require__(327);
 
 //Aliases
 const $ = HTML.TAG_NAMES;
@@ -53934,7 +55936,7 @@ module.exports = LocationInfoParserMixin;
 
 
 /***/ }),
-/* 318 */
+/* 330 */
 /***/ ((module) => {
 
 "use strict";
@@ -53980,15 +55982,15 @@ module.exports = Mixin;
 
 
 /***/ }),
-/* 319 */
+/* 331 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Mixin = __webpack_require__(318);
-const Tokenizer = __webpack_require__(309);
-const PositionTrackingPreprocessorMixin = __webpack_require__(320);
+const Mixin = __webpack_require__(330);
+const Tokenizer = __webpack_require__(321);
+const PositionTrackingPreprocessorMixin = __webpack_require__(332);
 
 class LocationInfoTokenizerMixin extends Mixin {
     constructor(tokenizer) {
@@ -54133,13 +56135,13 @@ module.exports = LocationInfoTokenizerMixin;
 
 
 /***/ }),
-/* 320 */
+/* 332 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Mixin = __webpack_require__(318);
+const Mixin = __webpack_require__(330);
 
 class PositionTrackingPreprocessorMixin extends Mixin {
     constructor(preprocessor) {
@@ -54204,13 +56206,13 @@ module.exports = PositionTrackingPreprocessorMixin;
 
 
 /***/ }),
-/* 321 */
+/* 333 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Mixin = __webpack_require__(318);
+const Mixin = __webpack_require__(330);
 
 class LocationInfoOpenElementStackMixin extends Mixin {
     constructor(stack, opts) {
@@ -54246,16 +56248,16 @@ module.exports = LocationInfoOpenElementStackMixin;
 
 
 /***/ }),
-/* 322 */
+/* 334 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const ErrorReportingMixinBase = __webpack_require__(323);
-const ErrorReportingTokenizerMixin = __webpack_require__(324);
-const LocationInfoTokenizerMixin = __webpack_require__(319);
-const Mixin = __webpack_require__(318);
+const ErrorReportingMixinBase = __webpack_require__(335);
+const ErrorReportingTokenizerMixin = __webpack_require__(336);
+const LocationInfoTokenizerMixin = __webpack_require__(331);
+const Mixin = __webpack_require__(330);
 
 class ErrorReportingParserMixin extends ErrorReportingMixinBase {
     constructor(parser, opts) {
@@ -54305,13 +56307,13 @@ module.exports = ErrorReportingParserMixin;
 
 
 /***/ }),
-/* 323 */
+/* 335 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Mixin = __webpack_require__(318);
+const Mixin = __webpack_require__(330);
 
 class ErrorReportingMixinBase extends Mixin {
     constructor(host, opts) {
@@ -54355,15 +56357,15 @@ module.exports = ErrorReportingMixinBase;
 
 
 /***/ }),
-/* 324 */
+/* 336 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const ErrorReportingMixinBase = __webpack_require__(323);
-const ErrorReportingPreprocessorMixin = __webpack_require__(325);
-const Mixin = __webpack_require__(318);
+const ErrorReportingMixinBase = __webpack_require__(335);
+const ErrorReportingPreprocessorMixin = __webpack_require__(337);
+const Mixin = __webpack_require__(330);
 
 class ErrorReportingTokenizerMixin extends ErrorReportingMixinBase {
     constructor(tokenizer, opts) {
@@ -54379,15 +56381,15 @@ module.exports = ErrorReportingTokenizerMixin;
 
 
 /***/ }),
-/* 325 */
+/* 337 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const ErrorReportingMixinBase = __webpack_require__(323);
-const PositionTrackingPreprocessorMixin = __webpack_require__(320);
-const Mixin = __webpack_require__(318);
+const ErrorReportingMixinBase = __webpack_require__(335);
+const PositionTrackingPreprocessorMixin = __webpack_require__(332);
+const Mixin = __webpack_require__(330);
 
 class ErrorReportingPreprocessorMixin extends ErrorReportingMixinBase {
     constructor(preprocessor, opts) {
@@ -54410,13 +56412,13 @@ module.exports = ErrorReportingPreprocessorMixin;
 
 
 /***/ }),
-/* 326 */
+/* 338 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-const { DOCUMENT_MODE } = __webpack_require__(315);
+const { DOCUMENT_MODE } = __webpack_require__(327);
 
 //Node construction
 exports.createDocument = function() {
@@ -54638,7 +56640,7 @@ exports.updateNodeSourceCodeLocation = function(node, endLocation) {
 
 
 /***/ }),
-/* 327 */
+/* 339 */
 /***/ ((module) => {
 
 "use strict";
@@ -54658,13 +56660,13 @@ module.exports = function mergeOptions(defaults, options) {
 
 
 /***/ }),
-/* 328 */
+/* 340 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-const { DOCUMENT_MODE } = __webpack_require__(315);
+const { DOCUMENT_MODE } = __webpack_require__(327);
 
 //Const
 const VALID_DOCTYPE_NAME = 'html';
@@ -54827,14 +56829,14 @@ exports.serializeContent = function(name, publicId, systemId) {
 
 
 /***/ }),
-/* 329 */
+/* 341 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-const Tokenizer = __webpack_require__(309);
-const HTML = __webpack_require__(315);
+const Tokenizer = __webpack_require__(321);
+const HTML = __webpack_require__(327);
 
 //Aliases
 const $ = HTML.TAG_NAMES;
@@ -55099,16 +57101,16 @@ exports.isIntegrationPoint = function(tn, ns, attrs, foreignNS) {
 
 
 /***/ }),
-/* 330 */
+/* 342 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-const defaultTreeAdapter = __webpack_require__(326);
-const mergeOptions = __webpack_require__(327);
-const doctype = __webpack_require__(328);
-const HTML = __webpack_require__(315);
+const defaultTreeAdapter = __webpack_require__(338);
+const mergeOptions = __webpack_require__(339);
+const doctype = __webpack_require__(340);
+const HTML = __webpack_require__(327);
 
 //Aliases
 const $ = HTML.TAG_NAMES;
@@ -55282,14 +57284,14 @@ module.exports = Serializer;
 
 
 /***/ }),
-/* 331 */
+/* 343 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-const doctype = __webpack_require__(328);
-const { DOCUMENT_MODE } = __webpack_require__(315);
+const doctype = __webpack_require__(340);
+const { DOCUMENT_MODE } = __webpack_require__(327);
 
 //Conversion tables for DOM Level1 structure emulation
 const nodeTypes = {
@@ -55637,7 +57639,7 @@ exports.updateNodeSourceCodeLocation = function(node, endLocation) {
 
 
 /***/ }),
-/* 332 */
+/* 344 */
 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
 
 "use strict";
@@ -55647,29 +57649,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.render = exports.parse = void 0;
-var htmlparser2_1 = __webpack_require__(302);
+var htmlparser2_1 = __webpack_require__(303);
 Object.defineProperty(exports, "parse", ({ enumerable: true, get: function () { return htmlparser2_1.parseDocument; } }));
-var dom_serializer_1 = __webpack_require__(271);
+var dom_serializer_1 = __webpack_require__(272);
 Object.defineProperty(exports, "render", ({ enumerable: true, get: function () { return __importDefault(dom_serializer_1).default; } }));
 
 
 /***/ }),
-/* 333 */
+/* 345 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.Cheerio = void 0;
-var tslib_1 = __webpack_require__(256);
-var parse_1 = tslib_1.__importDefault(__webpack_require__(334));
-var options_1 = tslib_1.__importDefault(__webpack_require__(259));
-var utils_1 = __webpack_require__(335);
-var Attributes = tslib_1.__importStar(__webpack_require__(336));
-var Traversing = tslib_1.__importStar(__webpack_require__(337));
-var Manipulation = tslib_1.__importStar(__webpack_require__(338));
-var Css = tslib_1.__importStar(__webpack_require__(339));
-var Forms = tslib_1.__importStar(__webpack_require__(340));
+var tslib_1 = __webpack_require__(257);
+var parse_1 = tslib_1.__importDefault(__webpack_require__(346));
+var options_1 = tslib_1.__importDefault(__webpack_require__(260));
+var utils_1 = __webpack_require__(347);
+var Attributes = tslib_1.__importStar(__webpack_require__(348));
+var Traversing = tslib_1.__importStar(__webpack_require__(349));
+var Manipulation = tslib_1.__importStar(__webpack_require__(350));
+var Css = tslib_1.__importStar(__webpack_require__(351));
+var Forms = tslib_1.__importStar(__webpack_require__(352));
 var Cheerio = /** @class */ (function () {
     /**
      * Instance of cheerio. Methods are specified in the modules. Usage of this
@@ -55776,17 +57778,17 @@ function isNode(obj) {
 
 
 /***/ }),
-/* 334 */
+/* 346 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.update = void 0;
-var htmlparser2_1 = __webpack_require__(302);
-var htmlparser2_adapter_1 = __webpack_require__(332);
-var parse5_adapter_1 = __webpack_require__(306);
-var domhandler_1 = __webpack_require__(268);
+var htmlparser2_1 = __webpack_require__(303);
+var htmlparser2_adapter_1 = __webpack_require__(344);
+var parse5_adapter_1 = __webpack_require__(316);
+var domhandler_1 = __webpack_require__(317);
 /*
  * Parser
  */
@@ -55850,15 +57852,15 @@ exports.update = update;
 
 
 /***/ }),
-/* 335 */
+/* 347 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.isHtml = exports.cloneDom = exports.domEach = exports.cssCase = exports.camelCase = exports.isCheerio = exports.isTag = void 0;
-var htmlparser2_1 = __webpack_require__(302);
-var domhandler_1 = __webpack_require__(268);
+var htmlparser2_1 = __webpack_require__(303);
+var domhandler_1 = __webpack_require__(317);
 /**
  * Check if the DOM element is a tag.
  *
@@ -55968,7 +57970,7 @@ exports.isHtml = isHtml;
 
 
 /***/ }),
-/* 336 */
+/* 348 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
@@ -55980,8 +57982,8 @@ exports.isHtml = isHtml;
  */
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.toggleClass = exports.removeClass = exports.addClass = exports.hasClass = exports.removeAttr = exports.val = exports.data = exports.prop = exports.attr = void 0;
-var static_1 = __webpack_require__(260);
-var utils_1 = __webpack_require__(335);
+var static_1 = __webpack_require__(261);
+var utils_1 = __webpack_require__(347);
 var hasOwn = Object.prototype.hasOwnProperty;
 var rspace = /\s+/;
 var dataAttrPrefix = 'data-';
@@ -56566,7 +58568,7 @@ exports.toggleClass = toggleClass;
 
 
 /***/ }),
-/* 337 */
+/* 349 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
@@ -56578,12 +58580,12 @@ exports.toggleClass = toggleClass;
  */
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.addBack = exports.add = exports.end = exports.slice = exports.index = exports.toArray = exports.get = exports.eq = exports.last = exports.first = exports.has = exports.not = exports.is = exports.filterArray = exports.filter = exports.map = exports.each = exports.contents = exports.children = exports.siblings = exports.prevUntil = exports.prevAll = exports.prev = exports.nextUntil = exports.nextAll = exports.next = exports.closest = exports.parentsUntil = exports.parents = exports.parent = exports.find = void 0;
-var tslib_1 = __webpack_require__(256);
-var domhandler_1 = __webpack_require__(268);
-var select = tslib_1.__importStar(__webpack_require__(261));
-var utils_1 = __webpack_require__(335);
-var static_1 = __webpack_require__(260);
-var htmlparser2_1 = __webpack_require__(302);
+var tslib_1 = __webpack_require__(257);
+var domhandler_1 = __webpack_require__(317);
+var select = tslib_1.__importStar(__webpack_require__(262));
+var utils_1 = __webpack_require__(347);
+var static_1 = __webpack_require__(261);
+var htmlparser2_1 = __webpack_require__(303);
 var uniqueSort = htmlparser2_1.DomUtils.uniqueSort;
 var reSiblingSelector = /^\s*[~+]/;
 /**
@@ -57245,11327 +59247,7796 @@ exports.first = first;
  *
  * ```js
  * $('#fruits').children().last().text();
- * //=> Pear
- * ```
- *
- * @returns The last element.
- * @see {@link https://api.jquery.com/last/}
- */
-function last() {
-    return this.length > 0 ? this._make(this[this.length - 1]) : this;
-}
-exports.last = last;
-/**
- * Reduce the set of matched elements to the one at the specified index. Use
- * `.eq(-i)` to count backwards from the last selected element.
- *
- * @category Traversing
- * @example
- *
- * ```js
- * $('li').eq(0).text();
- * //=> Apple
- *
- * $('li').eq(-1).text();
- * //=> Pear
- * ```
- *
- * @param i - Index of the element to select.
- * @returns The element at the `i`th position.
- * @see {@link https://api.jquery.com/eq/}
- */
-function eq(i) {
-    var _a;
-    i = +i;
-    // Use the first identity optimization if possible
-    if (i === 0 && this.length <= 1)
-        return this;
-    if (i < 0)
-        i = this.length + i;
-    return this._make((_a = this[i]) !== null && _a !== void 0 ? _a : []);
-}
-exports.eq = eq;
-function get(i) {
-    if (i == null) {
-        return this.toArray();
-    }
-    return this[i < 0 ? this.length + i : i];
-}
-exports.get = get;
-/**
- * Retrieve all the DOM elements contained in the jQuery set as an array.
- *
- * @example
- *
- * ```js
- * $('li').toArray();
- * //=> [ {...}, {...}, {...} ]
- * ```
- *
- * @returns The contained items.
- */
-function toArray() {
-    return Array.prototype.slice.call(this);
-}
-exports.toArray = toArray;
-/**
- * Search for a given element from among the matched elements.
- *
- * @category Traversing
- * @example
- *
- * ```js
- * $('.pear').index();
- * //=> 2 $('.orange').index('li');
- * //=> 1
- * $('.apple').index($('#fruit, li'));
- * //=> 1
- * ```
- *
- * @param selectorOrNeedle - Element to look for.
- * @returns The index of the element.
- * @see {@link https://api.jquery.com/index/}
- */
-function index(selectorOrNeedle) {
-    var $haystack;
-    var needle;
-    if (selectorOrNeedle == null) {
-        $haystack = this.parent().children();
-        needle = this[0];
-    }
-    else if (typeof selectorOrNeedle === 'string') {
-        $haystack = this._make(selectorOrNeedle);
-        needle = this[0];
-    }
-    else {
-        $haystack = this;
-        needle = utils_1.isCheerio(selectorOrNeedle)
-            ? selectorOrNeedle[0]
-            : selectorOrNeedle;
-    }
-    return Array.prototype.indexOf.call($haystack, needle);
-}
-exports.index = index;
-/**
- * Gets the elements matching the specified range (0-based position).
- *
- * @category Traversing
- * @example
- *
- * ```js
- * $('li').slice(1).eq(0).text();
- * //=> 'Orange'
- *
- * $('li').slice(1, 2).length;
- * //=> 1
- * ```
- *
- * @param start - An position at which the elements begin to be selected. If
- *   negative, it indicates an offset from the end of the set.
- * @param end - An position at which the elements stop being selected. If
- *   negative, it indicates an offset from the end of the set. If omitted, the
- *   range continues until the end of the set.
- * @returns The elements matching the specified range.
- * @see {@link https://api.jquery.com/slice/}
- */
-function slice(start, end) {
-    return this._make(Array.prototype.slice.call(this, start, end));
-}
-exports.slice = slice;
-/**
- * End the most recent filtering operation in the current chain and return the
- * set of matched elements to its previous state.
- *
- * @category Traversing
- * @example
- *
- * ```js
- * $('li').eq(0).end().length;
- * //=> 3
- * ```
- *
- * @returns The previous state of the set of matched elements.
- * @see {@link https://api.jquery.com/end/}
- */
-function end() {
-    var _a;
-    return (_a = this.prevObject) !== null && _a !== void 0 ? _a : this._make([]);
-}
-exports.end = end;
-/**
- * Add elements to the set of matched elements.
- *
- * @category Traversing
- * @example
- *
- * ```js
- * $('.apple').add('.orange').length;
- * //=> 2
- * ```
- *
- * @param other - Elements to add.
- * @param context - Optionally the context of the new selection.
- * @returns The combined set.
- * @see {@link https://api.jquery.com/add/}
- */
-function add(other, context) {
-    var selection = this._make(other, context);
-    var contents = uniqueSort(tslib_1.__spreadArray(tslib_1.__spreadArray([], this.get()), selection.get()));
-    return this._make(contents);
-}
-exports.add = add;
-/**
- * Add the previous set of elements on the stack to the current set, optionally
- * filtered by a selector.
- *
- * @category Traversing
- * @example
- *
- * ```js
- * $('li').eq(0).addBack('.orange').length;
- * //=> 2
- * ```
- *
- * @param selector - Selector for the elements to add.
- * @returns The combined set.
- * @see {@link https://api.jquery.com/addBack/}
- */
-function addBack(selector) {
-    return this.prevObject
-        ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject)
-        : this;
-}
-exports.addBack = addBack;
-
-
-/***/ }),
-/* 338 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.clone = exports.text = exports.toString = exports.html = exports.empty = exports.replaceWith = exports.remove = exports.insertBefore = exports.before = exports.insertAfter = exports.after = exports.wrapAll = exports.unwrap = exports.wrapInner = exports.wrap = exports.prepend = exports.append = exports.prependTo = exports.appendTo = exports._makeDomArray = void 0;
-var tslib_1 = __webpack_require__(256);
-var domhandler_1 = __webpack_require__(268);
-/**
- * Methods for modifying the DOM structure.
- *
- * @module cheerio/manipulation
- */
-var domhandler_2 = __webpack_require__(268);
-var parse_1 = tslib_1.__importStar(__webpack_require__(334));
-var static_1 = __webpack_require__(260);
-var utils_1 = __webpack_require__(335);
-var htmlparser2_1 = __webpack_require__(302);
-/**
- * Create an array of nodes, recursing into arrays and parsing strings if necessary.
- *
- * @private
- * @category Manipulation
- * @param elem - Elements to make an array of.
- * @param clone - Optionally clone nodes.
- * @returns The array of nodes.
- */
-function _makeDomArray(elem, clone) {
-    var _this = this;
-    if (elem == null) {
-        return [];
-    }
-    if (utils_1.isCheerio(elem)) {
-        return clone ? utils_1.cloneDom(elem.get()) : elem.get();
-    }
-    if (Array.isArray(elem)) {
-        return elem.reduce(function (newElems, el) { return newElems.concat(_this._makeDomArray(el, clone)); }, []);
-    }
-    if (typeof elem === 'string') {
-        return parse_1.default(elem, this.options, false).children;
-    }
-    return clone ? utils_1.cloneDom([elem]) : [elem];
-}
-exports._makeDomArray = _makeDomArray;
-function _insert(concatenator) {
-    return function () {
-        var _this = this;
-        var elems = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-            elems[_i] = arguments[_i];
-        }
-        var lastIdx = this.length - 1;
-        return utils_1.domEach(this, function (el, i) {
-            if (!domhandler_1.hasChildren(el))
-                return;
-            var domSrc = typeof elems[0] === 'function'
-                ? elems[0].call(el, i, static_1.html(el.children))
-                : elems;
-            var dom = _this._makeDomArray(domSrc, i < lastIdx);
-            concatenator(dom, el.children, el);
-        });
-    };
-}
-/**
- * Modify an array in-place, removing some number of elements and adding new
- * elements directly following them.
- *
- * @private
- * @category Manipulation
- * @param array - Target array to splice.
- * @param spliceIdx - Index at which to begin changing the array.
- * @param spliceCount - Number of elements to remove from the array.
- * @param newElems - Elements to insert into the array.
- * @param parent - The parent of the node.
- * @returns The spliced array.
- */
-function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) {
-    var _a, _b;
-    var spliceArgs = tslib_1.__spreadArray([
-        spliceIdx,
-        spliceCount
-    ], newElems);
-    var prev = array[spliceIdx - 1] || null;
-    var next = array[spliceIdx + spliceCount] || null;
-    /*
-     * Before splicing in new elements, ensure they do not already appear in the
-     * current array.
-     */
-    for (var idx = 0; idx < newElems.length; ++idx) {
-        var node = newElems[idx];
-        var oldParent = node.parent;
-        if (oldParent) {
-            var prevIdx = oldParent.children.indexOf(newElems[idx]);
-            if (prevIdx > -1) {
-                oldParent.children.splice(prevIdx, 1);
-                if (parent === oldParent && spliceIdx > prevIdx) {
-                    spliceArgs[0]--;
-                }
-            }
-        }
-        node.parent = parent;
-        if (node.prev) {
-            node.prev.next = (_a = node.next) !== null && _a !== void 0 ? _a : null;
-        }
-        if (node.next) {
-            node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null;
-        }
-        node.prev = newElems[idx - 1] || prev;
-        node.next = newElems[idx + 1] || next;
-    }
-    if (prev) {
-        prev.next = newElems[0];
-    }
-    if (next) {
-        next.prev = newElems[newElems.length - 1];
-    }
-    return array.splice.apply(array, spliceArgs);
-}
-/**
- * Insert every element in the set of matched elements to the end of the target.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('<li class="plum">Plum</li>').appendTo('#fruits');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //      <li class="plum">Plum</li>
- * //    </ul>
- * ```
- *
- * @param target - Element to append elements to.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/appendTo/}
- */
-function appendTo(target) {
-    var appendTarget = utils_1.isCheerio(target) ? target : this._make(target);
-    appendTarget.append(this);
-    return this;
-}
-exports.appendTo = appendTo;
-/**
- * Insert every element in the set of matched elements to the beginning of the target.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('<li class="plum">Plum</li>').prependTo('#fruits');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="plum">Plum</li>
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //    </ul>
- * ```
- *
- * @param target - Element to prepend elements to.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/prependTo/}
- */
-function prependTo(target) {
-    var prependTarget = utils_1.isCheerio(target) ? target : this._make(target);
-    prependTarget.prepend(this);
-    return this;
-}
-exports.prependTo = prependTo;
-/**
- * Inserts content as the *last* child of each of the selected elements.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('ul').append('<li class="plum">Plum</li>');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //      <li class="plum">Plum</li>
- * //    </ul>
- * ```
- *
- * @see {@link https://api.jquery.com/append/}
- */
-exports.append = _insert(function (dom, children, parent) {
-    uniqueSplice(children, children.length, 0, dom, parent);
-});
-/**
- * Inserts content as the *first* child of each of the selected elements.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('ul').prepend('<li class="plum">Plum</li>');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="plum">Plum</li>
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //    </ul>
- * ```
- *
- * @see {@link https://api.jquery.com/prepend/}
- */
-exports.prepend = _insert(function (dom, children, parent) {
-    uniqueSplice(children, 0, 0, dom, parent);
-});
-function _wrap(insert) {
-    return function (wrapper) {
-        var lastIdx = this.length - 1;
-        var lastParent = this.parents().last();
-        for (var i = 0; i < this.length; i++) {
-            var el = this[i];
-            var wrap_1 = typeof wrapper === 'function'
-                ? wrapper.call(el, i, el)
-                : typeof wrapper === 'string' && !utils_1.isHtml(wrapper)
-                    ? lastParent.find(wrapper).clone()
-                    : wrapper;
-            var wrapperDom = this._makeDomArray(wrap_1, i < lastIdx)[0];
-            if (!wrapperDom || !htmlparser2_1.DomUtils.hasChildren(wrapperDom))
-                continue;
-            var elInsertLocation = wrapperDom;
-            /*
-             * Find the deepest child. Only consider the first tag child of each node
-             * (ignore text); stop if no children are found.
-             */
-            var j = 0;
-            while (j < elInsertLocation.children.length) {
-                var child = elInsertLocation.children[j];
-                if (utils_1.isTag(child)) {
-                    elInsertLocation = child;
-                    j = 0;
-                }
-                else {
-                    j++;
-                }
-            }
-            insert(el, elInsertLocation, [wrapperDom]);
-        }
-        return this;
-    };
-}
-/**
- * The .wrap() function can take any string or object that could be passed to
- * the $() factory function to specify a DOM structure. This structure may be
- * nested several levels deep, but should contain only one inmost element. A
- * copy of this structure will be wrapped around each of the elements in the set
- * of matched elements. This method returns the original set of elements for
- * chaining purposes.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * const redFruit = $('<div class="red-fruit"></div>');
- * $('.apple').wrap(redFruit);
- *
- * //=> <ul id="fruits">
- * //     <div class="red-fruit">
- * //      <li class="apple">Apple</li>
- * //     </div>
- * //     <li class="orange">Orange</li>
- * //     <li class="plum">Plum</li>
- * //   </ul>
- *
- * const healthy = $('<div class="healthy"></div>');
- * $('li').wrap(healthy);
- *
- * //=> <ul id="fruits">
- * //     <div class="healthy">
- * //       <li class="apple">Apple</li>
- * //     </div>
- * //     <div class="healthy">
- * //       <li class="orange">Orange</li>
- * //     </div>
- * //     <div class="healthy">
- * //        <li class="plum">Plum</li>
- * //     </div>
- * //   </ul>
- * ```
- *
- * @param wrapper - The DOM structure to wrap around each element in the selection.
- * @see {@link https://api.jquery.com/wrap/}
- */
-exports.wrap = _wrap(function (el, elInsertLocation, wrapperDom) {
-    var parent = el.parent;
-    if (!parent)
-        return;
-    var siblings = parent.children;
-    var index = siblings.indexOf(el);
-    parse_1.update([el], elInsertLocation);
-    /*
-     * The previous operation removed the current element from the `siblings`
-     * array, so the `dom` array can be inserted without removing any
-     * additional elements.
-     */
-    uniqueSplice(siblings, index, 0, wrapperDom, parent);
-});
-/**
- * The .wrapInner() function can take any string or object that could be passed
- * to the $() factory function to specify a DOM structure. This structure may be
- * nested several levels deep, but should contain only one inmost element. The
- * structure will be wrapped around the content of each of the elements in the
- * set of matched elements.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * const redFruit = $('<div class="red-fruit"></div>');
- * $('.apple').wrapInner(redFruit);
- *
- * //=> <ul id="fruits">
- * //     <li class="apple">
- * //       <div class="red-fruit">Apple</div>
- * //     </li>
- * //     <li class="orange">Orange</li>
- * //     <li class="pear">Pear</li>
- * //   </ul>
- *
- * const healthy = $('<div class="healthy"></div>');
- * $('li').wrapInner(healthy);
- *
- * //=> <ul id="fruits">
- * //     <li class="apple">
- * //       <div class="healthy">Apple</div>
- * //     </li>
- * //     <li class="orange">
- * //       <div class="healthy">Orange</div>
- * //     </li>
- * //     <li class="pear">
- * //       <div class="healthy">Pear</div>
- * //     </li>
- * //   </ul>
- * ```
- *
- * @param wrapper - The DOM structure to wrap around the content of each element
- *   in the selection.
- * @returns The instance itself, for chaining.
- * @see {@link https://api.jquery.com/wrapInner/}
- */
-exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) {
-    if (!domhandler_1.hasChildren(el))
-        return;
-    parse_1.update(el.children, elInsertLocation);
-    parse_1.update(wrapperDom, el);
-});
-/**
- * The .unwrap() function, removes the parents of the set of matched elements
- * from the DOM, leaving the matched elements in their place.
- *
- * @category Manipulation
- * @example <caption>without selector</caption>
- *
- * ```js
- * const $ = cheerio.load(
- *   '<div id=test>\n  <div><p>Hello</p></div>\n  <div><p>World</p></div>\n</div>'
- * );
- * $('#test p').unwrap();
- *
- * //=> <div id=test>
- * //     <p>Hello</p>
- * //     <p>World</p>
- * //   </div>
- * ```
- *
- * @example <caption>with selector</caption>
- *
- * ```js
- * const $ = cheerio.load(
- *   '<div id=test>\n  <p>Hello</p>\n  <b><p>World</p></b>\n</div>'
- * );
- * $('#test p').unwrap('b');
- *
- * //=> <div id=test>
- * //     <p>Hello</p>
- * //     <p>World</p>
- * //   </div>
- * ```
- *
- * @param selector - A selector to check the parent element against. If an
- *   element's parent does not match the selector, the element won't be unwrapped.
- * @returns The instance itself, for chaining.
- * @see {@link https://api.jquery.com/unwrap/}
- */
-function unwrap(selector) {
-    var _this = this;
-    this.parent(selector)
-        .not('body')
-        .each(function (_, el) {
-        _this._make(el).replaceWith(el.children);
-    });
-    return this;
-}
-exports.unwrap = unwrap;
-/**
- * The .wrapAll() function can take any string or object that could be passed to
- * the $() function to specify a DOM structure. This structure may be nested
- * several levels deep, but should contain only one inmost element. The
- * structure will be wrapped around all of the elements in the set of matched
- * elements, as a single group.
- *
- * @category Manipulation
- * @example <caption>With markup passed to `wrapAll`</caption>
- *
- * ```js
- * const $ = cheerio.load(
- *   '<div class="container"><div class="inner">First</div><div class="inner">Second</div></div>'
- * );
- * $('.inner').wrapAll("<div class='new'></div>");
- *
- * //=> <div class="container">
- * //     <div class='new'>
- * //       <div class="inner">First</div>
- * //       <div class="inner">Second</div>
- * //     </div>
- * //   </div>
- * ```
- *
- * @example <caption>With an existing cheerio instance</caption>
- *
- * ```js
- * const $ = cheerio.load(
- *   '<span>Span 1</span><strong>Strong</strong><span>Span 2</span>'
- * );
- * const wrap = $('<div><p><em><b></b></em></p></div>');
- * $('span').wrapAll(wrap);
- *
- * //=> <div>
- * //     <p>
- * //       <em>
- * //         <b>
- * //           <span>Span 1</span>
- * //           <span>Span 2</span>
- * //         </b>
- * //       </em>
- * //     </p>
- * //   </div>
- * //   <strong>Strong</strong>
- * ```
- *
- * @param wrapper - The DOM structure to wrap around all matched elements in the
- *   selection.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/wrapAll/}
- */
-function wrapAll(wrapper) {
-    var el = this[0];
-    if (el) {
-        var wrap_2 = this._make(typeof wrapper === 'function' ? wrapper.call(el, 0, el) : wrapper).insertBefore(el);
-        // If html is given as wrapper, wrap may contain text elements
-        var elInsertLocation = void 0;
-        for (var i = 0; i < wrap_2.length; i++) {
-            if (wrap_2[i].type === 'tag')
-                elInsertLocation = wrap_2[i];
-        }
-        var j = 0;
-        /*
-         * Find the deepest child. Only consider the first tag child of each node
-         * (ignore text); stop if no children are found.
-         */
-        while (elInsertLocation && j < elInsertLocation.children.length) {
-            var child = elInsertLocation.children[j];
-            if (child.type === 'tag') {
-                elInsertLocation = child;
-                j = 0;
-            }
-            else {
-                j++;
-            }
-        }
-        if (elInsertLocation)
-            this._make(elInsertLocation).append(this);
-    }
-    return this;
-}
-exports.wrapAll = wrapAll;
-/* eslint-disable jsdoc/check-param-names*/
-/**
- * Insert content next to each element in the set of matched elements.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('.apple').after('<li class="plum">Plum</li>');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="apple">Apple</li>
- * //      <li class="plum">Plum</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //    </ul>
- * ```
- *
- * @param content - HTML string, DOM element, array of DOM elements or Cheerio
- *   to insert after each element in the set of matched elements.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/after/}
- */
-function after() {
-    var _this = this;
-    var elems = [];
-    for (var _i = 0; _i < arguments.length; _i++) {
-        elems[_i] = arguments[_i];
-    }
-    var lastIdx = this.length - 1;
-    return utils_1.domEach(this, function (el, i) {
-        var parent = el.parent;
-        if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) {
-            return;
-        }
-        var siblings = parent.children;
-        var index = siblings.indexOf(el);
-        // If not found, move on
-        /* istanbul ignore next */
-        if (index < 0)
-            return;
-        var domSrc = typeof elems[0] === 'function'
-            ? elems[0].call(el, i, static_1.html(el.children))
-            : elems;
-        var dom = _this._makeDomArray(domSrc, i < lastIdx);
-        // Add element after `this` element
-        uniqueSplice(siblings, index + 1, 0, dom, parent);
-    });
-}
-exports.after = after;
-/* eslint-enable jsdoc/check-param-names*/
-/**
- * Insert every element in the set of matched elements after the target.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('<li class="plum">Plum</li>').insertAfter('.apple');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="apple">Apple</li>
- * //      <li class="plum">Plum</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //    </ul>
- * ```
- *
- * @param target - Element to insert elements after.
- * @returns The set of newly inserted elements.
- * @see {@link https://api.jquery.com/insertAfter/}
- */
-function insertAfter(target) {
-    var _this = this;
-    if (typeof target === 'string') {
-        target = this._make(target);
-    }
-    this.remove();
-    var clones = [];
-    this._makeDomArray(target).forEach(function (el) {
-        var clonedSelf = _this.clone().toArray();
-        var parent = el.parent;
-        if (!parent) {
-            return;
-        }
-        var siblings = parent.children;
-        var index = siblings.indexOf(el);
-        // If not found, move on
-        /* istanbul ignore next */
-        if (index < 0)
-            return;
-        // Add cloned `this` element(s) after target element
-        uniqueSplice(siblings, index + 1, 0, clonedSelf, parent);
-        clones.push.apply(clones, clonedSelf);
-    });
-    return this._make(clones);
-}
-exports.insertAfter = insertAfter;
-/* eslint-disable jsdoc/check-param-names*/
-/**
- * Insert content previous to each element in the set of matched elements.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('.apple').before('<li class="plum">Plum</li>');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="plum">Plum</li>
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //    </ul>
- * ```
- *
- * @param content - HTML string, DOM element, array of DOM elements or Cheerio
- *   to insert before each element in the set of matched elements.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/before/}
- */
-function before() {
-    var _this = this;
-    var elems = [];
-    for (var _i = 0; _i < arguments.length; _i++) {
-        elems[_i] = arguments[_i];
-    }
-    var lastIdx = this.length - 1;
-    return utils_1.domEach(this, function (el, i) {
-        var parent = el.parent;
-        if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) {
-            return;
-        }
-        var siblings = parent.children;
-        var index = siblings.indexOf(el);
-        // If not found, move on
-        /* istanbul ignore next */
-        if (index < 0)
-            return;
-        var domSrc = typeof elems[0] === 'function'
-            ? elems[0].call(el, i, static_1.html(el.children))
-            : elems;
-        var dom = _this._makeDomArray(domSrc, i < lastIdx);
-        // Add element before `el` element
-        uniqueSplice(siblings, index, 0, dom, parent);
-    });
-}
-exports.before = before;
-/* eslint-enable jsdoc/check-param-names*/
-/**
- * Insert every element in the set of matched elements before the target.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('<li class="plum">Plum</li>').insertBefore('.apple');
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="plum">Plum</li>
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //      <li class="pear">Pear</li>
- * //    </ul>
- * ```
- *
- * @param target - Element to insert elements before.
- * @returns The set of newly inserted elements.
- * @see {@link https://api.jquery.com/insertBefore/}
- */
-function insertBefore(target) {
-    var _this = this;
-    var targetArr = this._make(target);
-    this.remove();
-    var clones = [];
-    utils_1.domEach(targetArr, function (el) {
-        var clonedSelf = _this.clone().toArray();
-        var parent = el.parent;
-        if (!parent) {
-            return;
-        }
-        var siblings = parent.children;
-        var index = siblings.indexOf(el);
-        // If not found, move on
-        /* istanbul ignore next */
-        if (index < 0)
-            return;
-        // Add cloned `this` element(s) after target element
-        uniqueSplice(siblings, index, 0, clonedSelf, parent);
-        clones.push.apply(clones, clonedSelf);
-    });
-    return this._make(clones);
-}
-exports.insertBefore = insertBefore;
-/**
- * Removes the set of matched elements from the DOM and all their children.
- * `selector` filters the set of matched elements to be removed.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('.pear').remove();
- * $.html();
- * //=>  <ul id="fruits">
- * //      <li class="apple">Apple</li>
- * //      <li class="orange">Orange</li>
- * //    </ul>
- * ```
- *
- * @param selector - Optional selector for elements to remove.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/remove/}
- */
-function remove(selector) {
-    // Filter if we have selector
-    var elems = selector ? this.filter(selector) : this;
-    utils_1.domEach(elems, function (el) {
-        htmlparser2_1.DomUtils.removeElement(el);
-        el.prev = el.next = el.parent = null;
-    });
-    return this;
-}
-exports.remove = remove;
-/**
- * Replaces matched elements with `content`.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * const plum = $('<li class="plum">Plum</li>');
- * $('.pear').replaceWith(plum);
- * $.html();
- * //=> <ul id="fruits">
- * //     <li class="apple">Apple</li>
- * //     <li class="orange">Orange</li>
- * //     <li class="plum">Plum</li>
- * //   </ul>
- * ```
- *
- * @param content - Replacement for matched elements.
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/replaceWith/}
- */
-function replaceWith(content) {
-    var _this = this;
-    return utils_1.domEach(this, function (el, i) {
-        var parent = el.parent;
-        if (!parent) {
-            return;
-        }
-        var siblings = parent.children;
-        var cont = typeof content === 'function' ? content.call(el, i, el) : content;
-        var dom = _this._makeDomArray(cont);
-        /*
-         * In the case that `dom` contains nodes that already exist in other
-         * structures, ensure those nodes are properly removed.
-         */
-        parse_1.update(dom, null);
-        var index = siblings.indexOf(el);
-        // Completely remove old element
-        uniqueSplice(siblings, index, 1, dom, parent);
-        if (!dom.includes(el)) {
-            el.parent = el.prev = el.next = null;
-        }
-    });
-}
-exports.replaceWith = replaceWith;
-/**
- * Empties an element, removing all its children.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * $('ul').empty();
- * $.html();
- * //=>  <ul id="fruits"></ul>
- * ```
- *
- * @returns The instance itself.
- * @see {@link https://api.jquery.com/empty/}
- */
-function empty() {
-    return utils_1.domEach(this, function (el) {
-        if (!htmlparser2_1.DomUtils.hasChildren(el))
-            return;
-        el.children.forEach(function (child) {
-            child.next = child.prev = child.parent = null;
-        });
-        el.children.length = 0;
-    });
-}
-exports.empty = empty;
-function html(str) {
-    if (str === undefined) {
-        var el = this[0];
-        if (!el || !htmlparser2_1.DomUtils.hasChildren(el))
-            return null;
-        return static_1.html(el.children, this.options);
-    }
-    // Keep main options unchanged
-    var opts = tslib_1.__assign(tslib_1.__assign({}, this.options), { context: null });
-    return utils_1.domEach(this, function (el) {
-        if (!htmlparser2_1.DomUtils.hasChildren(el))
-            return;
-        el.children.forEach(function (child) {
-            child.next = child.prev = child.parent = null;
-        });
-        opts.context = el;
-        var content = utils_1.isCheerio(str)
-            ? str.toArray()
-            : parse_1.default("" + str, opts, false).children;
-        parse_1.update(content, el);
-    });
-}
-exports.html = html;
-/**
- * Turns the collection to a string. Alias for `.html()`.
- *
- * @category Manipulation
- * @returns The rendered document.
- */
-function toString() {
-    return static_1.html(this, this.options);
-}
-exports.toString = toString;
-function text(str) {
-    var _this = this;
-    // If `str` is undefined, act as a "getter"
-    if (str === undefined) {
-        return static_1.text(this);
-    }
-    if (typeof str === 'function') {
-        // Function support
-        return utils_1.domEach(this, function (el, i) {
-            text.call(_this._make(el), str.call(el, i, static_1.text([el])));
-        });
-    }
-    // Append text node to each selected elements
-    return utils_1.domEach(this, function (el) {
-        if (!htmlparser2_1.DomUtils.hasChildren(el))
-            return;
-        el.children.forEach(function (child) {
-            child.next = child.prev = child.parent = null;
-        });
-        var textNode = new domhandler_2.Text(str);
-        parse_1.update(textNode, el);
-    });
-}
-exports.text = text;
-/**
- * Clone the cheerio object.
- *
- * @category Manipulation
- * @example
- *
- * ```js
- * const moreFruit = $('#fruits').clone();
- * ```
- *
- * @returns The cloned object.
- * @see {@link https://api.jquery.com/clone/}
- */
-function clone() {
-    return this._make(utils_1.cloneDom(this.get()));
-}
-exports.clone = clone;
-
-
-/***/ }),
-/* 339 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.css = void 0;
-var utils_1 = __webpack_require__(335);
-function css(prop, val) {
-    if ((prop != null && val != null) ||
-        // When `prop` is a "plain" object
-        (typeof prop === 'object' && !Array.isArray(prop))) {
-        return utils_1.domEach(this, function (el, i) {
-            if (utils_1.isTag(el)) {
-                // `prop` can't be an array here anymore.
-                setCss(el, prop, val, i);
-            }
-        });
-    }
-    return getCss(this[0], prop);
-}
-exports.css = css;
-/**
- * Set styles of all elements.
- *
- * @private
- * @param el - Element to set style of.
- * @param prop - Name of property.
- * @param value - Value to set property to.
- * @param idx - Optional index within the selection.
- */
-function setCss(el, prop, value, idx) {
-    if (typeof prop === 'string') {
-        var styles = getCss(el);
-        var val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value;
-        if (val === '') {
-            delete styles[prop];
-        }
-        else if (val != null) {
-            styles[prop] = val;
-        }
-        el.attribs.style = stringify(styles);
-    }
-    else if (typeof prop === 'object') {
-        Object.keys(prop).forEach(function (k, i) {
-            setCss(el, k, prop[k], i);
-        });
-    }
-}
-function getCss(el, prop) {
-    if (!el || !utils_1.isTag(el))
-        return;
-    var styles = parse(el.attribs.style);
-    if (typeof prop === 'string') {
-        return styles[prop];
-    }
-    if (Array.isArray(prop)) {
-        var newStyles_1 = {};
-        prop.forEach(function (item) {
-            if (styles[item] != null) {
-                newStyles_1[item] = styles[item];
-            }
-        });
-        return newStyles_1;
-    }
-    return styles;
-}
-/**
- * Stringify `obj` to styles.
- *
- * @private
- * @category CSS
- * @param obj - Object to stringify.
- * @returns The serialized styles.
- */
-function stringify(obj) {
-    return Object.keys(obj).reduce(function (str, prop) { return "" + str + (str ? ' ' : '') + prop + ": " + obj[prop] + ";"; }, '');
-}
-/**
- * Parse `styles`.
- *
- * @private
- * @category CSS
- * @param styles - Styles to be parsed.
- * @returns The parsed styles.
- */
-function parse(styles) {
-    styles = (styles || '').trim();
-    if (!styles)
-        return {};
-    return styles.split(';').reduce(function (obj, str) {
-        var n = str.indexOf(':');
-        // Skip if there is no :, or if it is the first/last character
-        if (n < 1 || n === str.length - 1)
-            return obj;
-        obj[str.slice(0, n).trim()] = str.slice(n + 1).trim();
-        return obj;
-    }, {});
-}
-
-
-/***/ }),
-/* 340 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.serializeArray = exports.serialize = void 0;
-var utils_1 = __webpack_require__(335);
-/*
- * https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
- * https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
- */
-var submittableSelector = 'input,select,textarea,keygen';
-var r20 = /%20/g;
-var rCRLF = /\r?\n/g;
-/**
- * Encode a set of form elements as a string for submission.
- *
- * @category Forms
- * @returns The serialized form.
- * @see {@link https://api.jquery.com/serialize/}
- */
-function serialize() {
-    // Convert form elements into name/value objects
-    var arr = this.serializeArray();
-    // Serialize each element into a key/value string
-    var retArr = arr.map(function (data) {
-        return encodeURIComponent(data.name) + "=" + encodeURIComponent(data.value);
-    });
-    // Return the resulting serialization
-    return retArr.join('&').replace(r20, '+');
-}
-exports.serialize = serialize;
-/**
- * Encode a set of form elements as an array of names and values.
- *
- * @category Forms
- * @example
- *
- * ```js
- * $('<form><input name="foo" value="bar" /></form>').serializeArray();
- * //=> [ { name: 'foo', value: 'bar' } ]
- * ```
- *
- * @returns The serialized form.
- * @see {@link https://api.jquery.com/serializeArray/}
- */
-function serializeArray() {
-    var _this = this;
-    // Resolve all form elements from either forms or collections of form elements
-    return this.map(function (_, elem) {
-        var $elem = _this._make(elem);
-        if (utils_1.isTag(elem) && elem.name === 'form') {
-            return $elem.find(submittableSelector).toArray();
-        }
-        return $elem.filter(submittableSelector).toArray();
-    })
-        .filter(
-    // Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
-    '[name!=""]:enabled' +
-        // And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)
-        ':not(:submit, :button, :image, :reset, :file)' +
-        // And are either checked/don't have a checkable state
-        ':matches([checked], :not(:checkbox, :radio))'
-    // Convert each of the elements to its value(s)
-    )
-        .map(function (_, elem) {
-        var _a;
-        var $elem = _this._make(elem);
-        var name = $elem.attr('name'); // We have filtered for elements with a name before.
-        // If there is no value set (e.g. `undefined`, `null`), then default value to empty
-        var value = (_a = $elem.val()) !== null && _a !== void 0 ? _a : '';
-        // If we have an array of values (e.g. `<select multiple>`), return an array of key/value pairs
-        if (Array.isArray(value)) {
-            return value.map(function (val) {
-                /*
-                 * We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms
-                 * These can occur inside of `<textarea>'s`
-                 */
-                return ({ name: name, value: val.replace(rCRLF, '\r\n') });
-            });
-        }
-        // Otherwise (e.g. `<input type="text">`, return only one key/value pair
-        return { name: name, value: value.replace(rCRLF, '\r\n') };
-    })
-        .toArray();
-}
-exports.serializeArray = serializeArray;
-
-
-/***/ }),
-/* 341 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-/**
- * Filters the passed array from data already present in the cozy so that there is
- * not duplicated data in the Cozy.
- *
- * @module hydrateAndFilter
- */
-const bluebird = __webpack_require__(5);
-
-const log = (__webpack_require__(342).namespace)('hydrateAndFilter');
-
-const get = __webpack_require__(358);
-
-const uniqBy = __webpack_require__(400);
-
-const {
-  queryAll
-} = __webpack_require__(472);
-/**
- * Since we can use methods or basic functions for
- * `shouldSave` and `shouldUpdate` we pass the
- * appropriate `this` and `arguments`.
- *
- * If `funcOrMethod` is a method, it will be called
- * with args[0] as `this` and the rest as `arguments`
- * Otherwise, `this` will be null and `args` will be passed
- * as `arguments`.
- */
-
-
-const suitableCall = (funcOrMethod, ...args) => {
-  const arity = funcOrMethod.length;
-
-  if (arity < args.length) {
-    // must be a method
-    return funcOrMethod.apply(args[0], args.slice(1));
-  } else {
-    // must be a function
-    return funcOrMethod.apply(null, args);
-  }
-};
-/**
- * Filters the passed array from data already present in the cozy so that there is
- * not duplicated data in the Cozy.
- *
- * You need at least the `GET` permission for the given doctype in your manifest, to be able to
- * use this function.
- *
- * Parameters:
- *
- * `documents`: an array of objects corresponding to the data you want to save in the cozy
- * `doctype` (string): the doctype where you want to save data (ex: 'io.cozy.bills')
- * `options` :
- *    - `keys` (array) : List of keys used to check that two items are the same. By default it is set to `['id']'.
- *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
- *    - `selector` (optionnal object) : Mango request to get records. Default is built from the keys `{selector: {_id: {"$gt": null}}}` to get all the records.
- *
- * ```javascript
- * const documents = [
- *   {
- *     name: 'toto',
- *     height: 1.8
- *   },
- *   {
- *     name: 'titi',
- *     height: 1.7
- *   }
- * ]
- *
- * return hydrateAndFilter(documents, 'io.cozy.height', {
- *   keys: ['name']
- * }).then(filteredDocuments => addData(filteredDocuments, 'io.cozy.height'))
- *
- * ```
- *
- * @alias module:hydrateAndFilter
- */
-
-
-const hydrateAndFilter = (documents = [], doctype, options = {}) => {
-  const cozy = __webpack_require__(473);
-
-  log('debug', `${documents.length} items before hydrateAndFilter`);
-  if (!doctype) return Promise.reject(new Error(`Doctype is mandatory to filter the connector data.`));
-  const keys = options.keys ? options.keys : ['_id'];
-  const store = {};
-
-  const createHash = item => {
-    return keys.map(key => {
-      let result = get(item, key);
-      if (key === 'date') result = new Date(result);
-      return result;
-    }).join('####');
-  };
-
-  const getIndex = () => {
-    const index = options.index ? Promise.resolve(options.index) : cozy.data.defineIndex(doctype, keys);
-    return index;
-  };
-
-  const getItems = async index => {
-    const selector = options.selector ? options.selector : null;
-    return await queryAll(doctype, selector, index);
-  };
-
-  const populateStore = store => dbitems => {
-    dbitems.forEach(dbitem => {
-      store[createHash(dbitem)] = dbitem;
-    });
-  }; // We add _id to `documents` that we find in the database.
-  // This is useful when linking with bank operations (a bill
-  // can already be in the database but not already matched
-  // to an operation) since the linking operation need the _id
-  // of the document
-
-
-  const hydrateExistingEntries = store => () => {
-    documents.forEach(document => {
-      const key = createHash(document);
-
-      if (store[key]) {
-        document._id = store[key]._id;
-        document._rev = store[key]._rev;
-        if (!document.cozyMetadata && store[key].cozyMetadata) document.cozyMetadata = store[key].cozyMetadata;
-      }
-    });
-    return documents;
-  };
-
-  const defaultShouldSave = () => true;
-
-  const defaultShouldUpdate = existing => false; // eslint-disable-line no-unused-vars
-
-
-  const filterEntries = store => async () => {
-    // Filter out items according to shouldSave / shouldUpdate.
-    // Both can be passed as option or can be part of the entry.
-    return uniqBy(await bluebird.filter(documents, entry => {
-      const shouldSave = entry.shouldSave || options.shouldSave || defaultShouldSave;
-      const shouldUpdate = entry.shouldUpdate || options.shouldUpdate || defaultShouldUpdate;
-      const existing = store[createHash(entry)];
-
-      if (existing) {
-        return suitableCall(shouldUpdate, entry, existing);
-      } else {
-        return suitableCall(shouldSave, entry);
-      }
-    }), entry => entry && entry._id || entry);
-  };
-
-  const formatOutput = entries => {
-    log('debug', `${entries.length} items after hydrateAndFilter`);
-    return entries;
-  };
-
-  return getIndex().then(getItems).then(populateStore(store)).then(hydrateExistingEntries(store)).then(filterEntries(store)).then(entries => entries.filter(Boolean)) // Filter out wrong entries
-  .then(formatOutput);
-};
-
-module.exports = hydrateAndFilter;
-
-/***/ }),
-/* 342 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-const { filterLevel, filterSecrets } = __webpack_require__(343)
-const Secret = __webpack_require__(344)
-const { LOG_LEVEL } = process.env
-let level = LOG_LEVEL || 'debug'
-const format = __webpack_require__(345)
-const filters = [filterLevel, filterSecrets]
-
-const filterOut = function () {
-  for (const filter of filters) {
-    if (filter.apply(null, arguments) === false) {
-      return true
-    }
-  }
-  return false
-}
-
-/**
- * Use it to log messages in your konnector. Typical types are
- *
- * - `debug`
- * - `warning`
- * - `info`
- * - `error`
- * - `ok`
- *
- *
- * @example
- *
- * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector.
- *
- * ```js
- * logger = log('my-namespace')
- * logger('debug', '365 bills')
- * // my-namespace : debug : 365 bills
- * logger('info', 'Page fetched')
- * // my-namespace : info : Page fetched
- * ```
- * @param  {string} type
- * @param  {string} message
- * @param  {string} label
- * @param  {string} namespace
- */
-function log(type, message, label, namespace) {
-  if (filterOut(level, type, message, label, namespace)) {
-    return
-  }
-  // eslint-disable-next-line no-console
-  console.log(format(type, message, label, namespace))
-}
-
-log.addFilter = function (filter) {
-  return filters.push(filter)
-}
-
-log.setLevel = function (lvl) {
-  level = lvl
-}
-
-// Short-hands
-const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical']
-methods.forEach(level => {
-  log[level] = function (message, label, namespace) {
-    return log(level, message, label, namespace)
-  }
-})
-
-module.exports = log
-
-log.setNoRetry = obj => {
-  if (obj) obj.no_retry = true
-  else obj = { no_retry: true }
-  return obj.no_retry
-}
-log.Secret = Secret
-log.namespace = function (namespace) {
-  return function (type, message, label, ns = namespace) {
-    log(type, message, label, ns)
-  }
-}
-
-
-/***/ }),
-/* 343 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-const levels = {
-  secret: 0,
-  debug: 10,
-  info: 20,
-  warn: 30,
-  error: 40,
-  ok: 50,
-  critical: 50
-}
-
-const Secret = __webpack_require__(344)
-
-const filterSecrets = function (level, type, message) {
-  if (type !== 'secret' && message instanceof Secret) {
-    throw new Error('You should log a secret with log.secret')
-  }
-}
-
-const filterLevel = function (level, type) {
-  return levels[type] >= levels[level]
-}
-
-module.exports = {
-  filterSecrets,
-  filterLevel
-}
-
-
-/***/ }),
-/* 344 */
-/***/ ((module) => {
-
-const Secret = function (data) {
-  Object.assign(this, data)
-  return this
-}
-
-Secret.prototype.toString = function () {
-  throw new Error('Cannot convert Secret to string')
-}
-
-module.exports = Secret
-
-
-/***/ }),
-/* 345 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-const prodFormat = __webpack_require__(346)
-const devFormat = __webpack_require__(347)
-
-switch (process.env.NODE_ENV) {
-  case 'production':
-    module.exports = prodFormat
-    break
-  case 'development':
-    module.exports = devFormat
-    break
-  case 'standalone':
-    module.exports = devFormat
-    break
-  case 'test':
-    module.exports = devFormat
-    break
-  default:
-    module.exports = prodFormat
-}
-
-
-/***/ }),
-/* 346 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-const stringify = __webpack_require__(75)
-
-const LOG_LENGTH_LIMIT = 64 * 1024 - 1
-
-function prodFormat(type, message, label, namespace) {
-  const log = { time: new Date(), type, label, namespace }
-
-  if (typeof message === 'object') {
-    if (message && message.no_retry) {
-      log.no_retry = message.no_retry
-    }
-    if (message && message.message) {
-      log.message = message.message
-    }
-  } else {
-    log.message = message
-  }
-
-  // properly display error messages
-  if (log.message && log.message.stack) {
-    log.message = log.message.stack
-  }
-
-  // cut the string to avoid a fail in the stack
-  let result = log
-  try {
-    result = stringify(log).substr(0, LOG_LENGTH_LIMIT)
-  } catch (err) {
-    // eslint-disable-next-line no-console
-    console.log(err.message, 'cozy-logger: Failed to convert message to JSON')
-  }
-  return result
-}
-
-module.exports = prodFormat
-
-
-/***/ }),
-/* 347 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-const util = __webpack_require__(64)
-const chalk = __webpack_require__(348)
-
-if (util && util.inspect && util.inspect.defaultOptions) {
-  util.inspect.defaultOptions.maxArrayLength = null
-  util.inspect.defaultOptions.depth = 2
-  util.inspect.defaultOptions.colors = true
-}
-
-const type2color = {
-  debug: 'cyan',
-  warn: 'yellow',
-  info: 'blue',
-  error: 'red',
-  ok: 'green',
-  secret: 'red',
-  critical: 'red'
-}
-
-function devFormat(type, message, label, namespace) {
-  let formatmessage = message
-
-  if (typeof formatmessage !== 'string') {
-    formatmessage = util.inspect(formatmessage)
-  }
-
-  let formatlabel = label ? ` : "${label}" ` : ''
-  let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : ''
-
-  let color = type2color[type]
-  let formattype = color ? chalk[color](type) : type
-
-  return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}`
-}
-
-module.exports = devFormat
-
-
-/***/ }),
-/* 348 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-"use strict";
-
-const escapeStringRegexp = __webpack_require__(349);
-const ansiStyles = __webpack_require__(350);
-const stdoutColor = (__webpack_require__(355).stdout);
-
-const template = __webpack_require__(357);
-
-const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
-
-// `supportsColor.level` → `ansiStyles.color[name]` mapping
-const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
-
-// `color-convert` models to exclude from the Chalk API due to conflicts and such
-const skipModels = new Set(['gray']);
-
-const styles = Object.create(null);
-
-function applyOptions(obj, options) {
-	options = options || {};
-
-	// Detect level if not set manually
-	const scLevel = stdoutColor ? stdoutColor.level : 0;
-	obj.level = options.level === undefined ? scLevel : options.level;
-	obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
-}
-
-function Chalk(options) {
-	// We check for this.template here since calling `chalk.constructor()`
-	// by itself will have a `this` of a previously constructed chalk object
-	if (!this || !(this instanceof Chalk) || this.template) {
-		const chalk = {};
-		applyOptions(chalk, options);
-
-		chalk.template = function () {
-			const args = [].slice.call(arguments);
-			return chalkTag.apply(null, [chalk.template].concat(args));
-		};
-
-		Object.setPrototypeOf(chalk, Chalk.prototype);
-		Object.setPrototypeOf(chalk.template, chalk);
-
-		chalk.template.constructor = Chalk;
-
-		return chalk.template;
-	}
-
-	applyOptions(this, options);
-}
-
-// Use bright blue on Windows as the normal blue color is illegible
-if (isSimpleWindowsTerm) {
-	ansiStyles.blue.open = '\u001B[94m';
-}
-
-for (const key of Object.keys(ansiStyles)) {
-	ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
-
-	styles[key] = {
-		get() {
-			const codes = ansiStyles[key];
-			return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
-		}
-	};
-}
-
-styles.visible = {
-	get() {
-		return build.call(this, this._styles || [], true, 'visible');
-	}
-};
-
-ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
-for (const model of Object.keys(ansiStyles.color.ansi)) {
-	if (skipModels.has(model)) {
-		continue;
-	}
-
-	styles[model] = {
-		get() {
-			const level = this.level;
-			return function () {
-				const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
-				const codes = {
-					open,
-					close: ansiStyles.color.close,
-					closeRe: ansiStyles.color.closeRe
-				};
-				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
-			};
-		}
-	};
-}
-
-ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
-for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
-	if (skipModels.has(model)) {
-		continue;
-	}
-
-	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
-	styles[bgModel] = {
-		get() {
-			const level = this.level;
-			return function () {
-				const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
-				const codes = {
-					open,
-					close: ansiStyles.bgColor.close,
-					closeRe: ansiStyles.bgColor.closeRe
-				};
-				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
-			};
-		}
-	};
-}
-
-const proto = Object.defineProperties(() => {}, styles);
-
-function build(_styles, _empty, key) {
-	const builder = function () {
-		return applyStyle.apply(builder, arguments);
-	};
-
-	builder._styles = _styles;
-	builder._empty = _empty;
-
-	const self = this;
-
-	Object.defineProperty(builder, 'level', {
-		enumerable: true,
-		get() {
-			return self.level;
-		},
-		set(level) {
-			self.level = level;
-		}
-	});
-
-	Object.defineProperty(builder, 'enabled', {
-		enumerable: true,
-		get() {
-			return self.enabled;
-		},
-		set(enabled) {
-			self.enabled = enabled;
-		}
-	});
-
-	// See below for fix regarding invisible grey/dim combination on Windows
-	builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
-
-	// `__proto__` is used because we must return a function, but there is
-	// no way to create a function with a different prototype
-	builder.__proto__ = proto; // eslint-disable-line no-proto
-
-	return builder;
-}
-
-function applyStyle() {
-	// Support varags, but simply cast to string in case there's only one arg
-	const args = arguments;
-	const argsLen = args.length;
-	let str = String(arguments[0]);
-
-	if (argsLen === 0) {
-		return '';
-	}
-
-	if (argsLen > 1) {
-		// Don't slice `arguments`, it prevents V8 optimizations
-		for (let a = 1; a < argsLen; a++) {
-			str += ' ' + args[a];
-		}
-	}
-
-	if (!this.enabled || this.level <= 0 || !str) {
-		return this._empty ? '' : str;
-	}
-
-	// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
-	// see https://github.com/chalk/chalk/issues/58
-	// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
-	const originalDim = ansiStyles.dim.open;
-	if (isSimpleWindowsTerm && this.hasGrey) {
-		ansiStyles.dim.open = '';
-	}
-
-	for (const code of this._styles.slice().reverse()) {
-		// Replace any instances already present with a re-opening code
-		// otherwise only the part of the string until said closing code
-		// will be colored, and the rest will simply be 'plain'.
-		str = code.open + str.replace(code.closeRe, code.open) + code.close;
-
-		// Close the styling before a linebreak and reopen
-		// after next line to fix a bleed issue on macOS
-		// https://github.com/chalk/chalk/pull/92
-		str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
-	}
-
-	// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
-	ansiStyles.dim.open = originalDim;
-
-	return str;
-}
-
-function chalkTag(chalk, strings) {
-	if (!Array.isArray(strings)) {
-		// If chalk() was called by itself or with a string,
-		// return the string itself as a string.
-		return [].slice.call(arguments, 1).join(' ');
-	}
-
-	const args = [].slice.call(arguments, 2);
-	const parts = [strings.raw[0]];
-
-	for (let i = 1; i < strings.length; i++) {
-		parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
-		parts.push(String(strings.raw[i]));
-	}
-
-	return template(chalk, parts.join(''));
-}
-
-Object.defineProperties(Chalk.prototype, styles);
-
-module.exports = Chalk(); // eslint-disable-line new-cap
-module.exports.supportsColor = stdoutColor;
-module.exports["default"] = module.exports; // For TypeScript
-
-
-/***/ }),
-/* 349 */
-/***/ ((module) => {
-
-"use strict";
-
-
-var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
-
-module.exports = function (str) {
-	if (typeof str !== 'string') {
-		throw new TypeError('Expected a string');
-	}
-
-	return str.replace(matchOperatorsRe, '\\$&');
-};
-
-
-/***/ }),
-/* 350 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-"use strict";
-/* module decorator */ module = __webpack_require__.nmd(module);
-
-const colorConvert = __webpack_require__(351);
-
-const wrapAnsi16 = (fn, offset) => function () {
-	const code = fn.apply(colorConvert, arguments);
-	return `\u001B[${code + offset}m`;
-};
-
-const wrapAnsi256 = (fn, offset) => function () {
-	const code = fn.apply(colorConvert, arguments);
-	return `\u001B[${38 + offset};5;${code}m`;
-};
-
-const wrapAnsi16m = (fn, offset) => function () {
-	const rgb = fn.apply(colorConvert, arguments);
-	return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
-};
-
-function assembleStyles() {
-	const codes = new Map();
-	const styles = {
-		modifier: {
-			reset: [0, 0],
-			// 21 isn't widely supported and 22 does the same thing
-			bold: [1, 22],
-			dim: [2, 22],
-			italic: [3, 23],
-			underline: [4, 24],
-			inverse: [7, 27],
-			hidden: [8, 28],
-			strikethrough: [9, 29]
-		},
-		color: {
-			black: [30, 39],
-			red: [31, 39],
-			green: [32, 39],
-			yellow: [33, 39],
-			blue: [34, 39],
-			magenta: [35, 39],
-			cyan: [36, 39],
-			white: [37, 39],
-			gray: [90, 39],
-
-			// Bright color
-			redBright: [91, 39],
-			greenBright: [92, 39],
-			yellowBright: [93, 39],
-			blueBright: [94, 39],
-			magentaBright: [95, 39],
-			cyanBright: [96, 39],
-			whiteBright: [97, 39]
-		},
-		bgColor: {
-			bgBlack: [40, 49],
-			bgRed: [41, 49],
-			bgGreen: [42, 49],
-			bgYellow: [43, 49],
-			bgBlue: [44, 49],
-			bgMagenta: [45, 49],
-			bgCyan: [46, 49],
-			bgWhite: [47, 49],
-
-			// Bright color
-			bgBlackBright: [100, 49],
-			bgRedBright: [101, 49],
-			bgGreenBright: [102, 49],
-			bgYellowBright: [103, 49],
-			bgBlueBright: [104, 49],
-			bgMagentaBright: [105, 49],
-			bgCyanBright: [106, 49],
-			bgWhiteBright: [107, 49]
-		}
-	};
-
-	// Fix humans
-	styles.color.grey = styles.color.gray;
-
-	for (const groupName of Object.keys(styles)) {
-		const group = styles[groupName];
-
-		for (const styleName of Object.keys(group)) {
-			const style = group[styleName];
-
-			styles[styleName] = {
-				open: `\u001B[${style[0]}m`,
-				close: `\u001B[${style[1]}m`
-			};
-
-			group[styleName] = styles[styleName];
-
-			codes.set(style[0], style[1]);
-		}
-
-		Object.defineProperty(styles, groupName, {
-			value: group,
-			enumerable: false
-		});
-
-		Object.defineProperty(styles, 'codes', {
-			value: codes,
-			enumerable: false
-		});
-	}
-
-	const ansi2ansi = n => n;
-	const rgb2rgb = (r, g, b) => [r, g, b];
-
-	styles.color.close = '\u001B[39m';
-	styles.bgColor.close = '\u001B[49m';
-
-	styles.color.ansi = {
-		ansi: wrapAnsi16(ansi2ansi, 0)
-	};
-	styles.color.ansi256 = {
-		ansi256: wrapAnsi256(ansi2ansi, 0)
-	};
-	styles.color.ansi16m = {
-		rgb: wrapAnsi16m(rgb2rgb, 0)
-	};
-
-	styles.bgColor.ansi = {
-		ansi: wrapAnsi16(ansi2ansi, 10)
-	};
-	styles.bgColor.ansi256 = {
-		ansi256: wrapAnsi256(ansi2ansi, 10)
-	};
-	styles.bgColor.ansi16m = {
-		rgb: wrapAnsi16m(rgb2rgb, 10)
-	};
-
-	for (let key of Object.keys(colorConvert)) {
-		if (typeof colorConvert[key] !== 'object') {
-			continue;
-		}
-
-		const suite = colorConvert[key];
-
-		if (key === 'ansi16') {
-			key = 'ansi';
-		}
-
-		if ('ansi16' in suite) {
-			styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0);
-			styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10);
-		}
-
-		if ('ansi256' in suite) {
-			styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0);
-			styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10);
-		}
-
-		if ('rgb' in suite) {
-			styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0);
-			styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10);
-		}
-	}
-
-	return styles;
-}
-
-// Make the export immutable
-Object.defineProperty(module, 'exports', {
-	enumerable: true,
-	get: assembleStyles
-});
-
-
-/***/ }),
-/* 351 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var conversions = __webpack_require__(352);
-var route = __webpack_require__(354);
-
-var convert = {};
-
-var models = Object.keys(conversions);
-
-function wrapRaw(fn) {
-	var wrappedFn = function (args) {
-		if (args === undefined || args === null) {
-			return args;
-		}
-
-		if (arguments.length > 1) {
-			args = Array.prototype.slice.call(arguments);
-		}
-
-		return fn(args);
-	};
-
-	// preserve .conversion property if there is one
-	if ('conversion' in fn) {
-		wrappedFn.conversion = fn.conversion;
-	}
-
-	return wrappedFn;
-}
-
-function wrapRounded(fn) {
-	var wrappedFn = function (args) {
-		if (args === undefined || args === null) {
-			return args;
-		}
-
-		if (arguments.length > 1) {
-			args = Array.prototype.slice.call(arguments);
-		}
-
-		var result = fn(args);
-
-		// we're assuming the result is an array here.
-		// see notice in conversions.js; don't use box types
-		// in conversion functions.
-		if (typeof result === 'object') {
-			for (var len = result.length, i = 0; i < len; i++) {
-				result[i] = Math.round(result[i]);
-			}
-		}
-
-		return result;
-	};
-
-	// preserve .conversion property if there is one
-	if ('conversion' in fn) {
-		wrappedFn.conversion = fn.conversion;
-	}
-
-	return wrappedFn;
-}
-
-models.forEach(function (fromModel) {
-	convert[fromModel] = {};
-
-	Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
-	Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
-
-	var routes = route(fromModel);
-	var routeModels = Object.keys(routes);
-
-	routeModels.forEach(function (toModel) {
-		var fn = routes[toModel];
-
-		convert[fromModel][toModel] = wrapRounded(fn);
-		convert[fromModel][toModel].raw = wrapRaw(fn);
-	});
-});
-
-module.exports = convert;
-
-
-/***/ }),
-/* 352 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-/* MIT license */
-var cssKeywords = __webpack_require__(353);
-
-// NOTE: conversions should only return primitive values (i.e. arrays, or
-//       values that give correct `typeof` results).
-//       do not use box values types (i.e. Number(), String(), etc.)
-
-var reverseKeywords = {};
-for (var key in cssKeywords) {
-	if (cssKeywords.hasOwnProperty(key)) {
-		reverseKeywords[cssKeywords[key]] = key;
-	}
-}
-
-var convert = module.exports = {
-	rgb: {channels: 3, labels: 'rgb'},
-	hsl: {channels: 3, labels: 'hsl'},
-	hsv: {channels: 3, labels: 'hsv'},
-	hwb: {channels: 3, labels: 'hwb'},
-	cmyk: {channels: 4, labels: 'cmyk'},
-	xyz: {channels: 3, labels: 'xyz'},
-	lab: {channels: 3, labels: 'lab'},
-	lch: {channels: 3, labels: 'lch'},
-	hex: {channels: 1, labels: ['hex']},
-	keyword: {channels: 1, labels: ['keyword']},
-	ansi16: {channels: 1, labels: ['ansi16']},
-	ansi256: {channels: 1, labels: ['ansi256']},
-	hcg: {channels: 3, labels: ['h', 'c', 'g']},
-	apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
-	gray: {channels: 1, labels: ['gray']}
-};
-
-// hide .channels and .labels properties
-for (var model in convert) {
-	if (convert.hasOwnProperty(model)) {
-		if (!('channels' in convert[model])) {
-			throw new Error('missing channels property: ' + model);
-		}
-
-		if (!('labels' in convert[model])) {
-			throw new Error('missing channel labels property: ' + model);
-		}
-
-		if (convert[model].labels.length !== convert[model].channels) {
-			throw new Error('channel and label counts mismatch: ' + model);
-		}
-
-		var channels = convert[model].channels;
-		var labels = convert[model].labels;
-		delete convert[model].channels;
-		delete convert[model].labels;
-		Object.defineProperty(convert[model], 'channels', {value: channels});
-		Object.defineProperty(convert[model], 'labels', {value: labels});
-	}
-}
-
-convert.rgb.hsl = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var min = Math.min(r, g, b);
-	var max = Math.max(r, g, b);
-	var delta = max - min;
-	var h;
-	var s;
-	var l;
-
-	if (max === min) {
-		h = 0;
-	} else if (r === max) {
-		h = (g - b) / delta;
-	} else if (g === max) {
-		h = 2 + (b - r) / delta;
-	} else if (b === max) {
-		h = 4 + (r - g) / delta;
-	}
-
-	h = Math.min(h * 60, 360);
-
-	if (h < 0) {
-		h += 360;
-	}
-
-	l = (min + max) / 2;
-
-	if (max === min) {
-		s = 0;
-	} else if (l <= 0.5) {
-		s = delta / (max + min);
-	} else {
-		s = delta / (2 - max - min);
-	}
-
-	return [h, s * 100, l * 100];
-};
-
-convert.rgb.hsv = function (rgb) {
-	var rdif;
-	var gdif;
-	var bdif;
-	var h;
-	var s;
-
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var v = Math.max(r, g, b);
-	var diff = v - Math.min(r, g, b);
-	var diffc = function (c) {
-		return (v - c) / 6 / diff + 1 / 2;
-	};
-
-	if (diff === 0) {
-		h = s = 0;
-	} else {
-		s = diff / v;
-		rdif = diffc(r);
-		gdif = diffc(g);
-		bdif = diffc(b);
-
-		if (r === v) {
-			h = bdif - gdif;
-		} else if (g === v) {
-			h = (1 / 3) + rdif - bdif;
-		} else if (b === v) {
-			h = (2 / 3) + gdif - rdif;
-		}
-		if (h < 0) {
-			h += 1;
-		} else if (h > 1) {
-			h -= 1;
-		}
-	}
-
-	return [
-		h * 360,
-		s * 100,
-		v * 100
-	];
-};
-
-convert.rgb.hwb = function (rgb) {
-	var r = rgb[0];
-	var g = rgb[1];
-	var b = rgb[2];
-	var h = convert.rgb.hsl(rgb)[0];
-	var w = 1 / 255 * Math.min(r, Math.min(g, b));
-
-	b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
-
-	return [h, w * 100, b * 100];
-};
-
-convert.rgb.cmyk = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var c;
-	var m;
-	var y;
-	var k;
-
-	k = Math.min(1 - r, 1 - g, 1 - b);
-	c = (1 - r - k) / (1 - k) || 0;
-	m = (1 - g - k) / (1 - k) || 0;
-	y = (1 - b - k) / (1 - k) || 0;
-
-	return [c * 100, m * 100, y * 100, k * 100];
-};
-
-/**
- * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
- * */
-function comparativeDistance(x, y) {
-	return (
-		Math.pow(x[0] - y[0], 2) +
-		Math.pow(x[1] - y[1], 2) +
-		Math.pow(x[2] - y[2], 2)
-	);
-}
-
-convert.rgb.keyword = function (rgb) {
-	var reversed = reverseKeywords[rgb];
-	if (reversed) {
-		return reversed;
-	}
-
-	var currentClosestDistance = Infinity;
-	var currentClosestKeyword;
-
-	for (var keyword in cssKeywords) {
-		if (cssKeywords.hasOwnProperty(keyword)) {
-			var value = cssKeywords[keyword];
-
-			// Compute comparative distance
-			var distance = comparativeDistance(rgb, value);
-
-			// Check if its less, if so set as closest
-			if (distance < currentClosestDistance) {
-				currentClosestDistance = distance;
-				currentClosestKeyword = keyword;
-			}
-		}
-	}
-
-	return currentClosestKeyword;
-};
-
-convert.keyword.rgb = function (keyword) {
-	return cssKeywords[keyword];
-};
-
-convert.rgb.xyz = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-
-	// assume sRGB
-	r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
-	g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
-	b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
-
-	var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
-	var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
-	var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
-
-	return [x * 100, y * 100, z * 100];
-};
-
-convert.rgb.lab = function (rgb) {
-	var xyz = convert.rgb.xyz(rgb);
-	var x = xyz[0];
-	var y = xyz[1];
-	var z = xyz[2];
-	var l;
-	var a;
-	var b;
-
-	x /= 95.047;
-	y /= 100;
-	z /= 108.883;
-
-	x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
-	y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
-	z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
-
-	l = (116 * y) - 16;
-	a = 500 * (x - y);
-	b = 200 * (y - z);
-
-	return [l, a, b];
-};
-
-convert.hsl.rgb = function (hsl) {
-	var h = hsl[0] / 360;
-	var s = hsl[1] / 100;
-	var l = hsl[2] / 100;
-	var t1;
-	var t2;
-	var t3;
-	var rgb;
-	var val;
-
-	if (s === 0) {
-		val = l * 255;
-		return [val, val, val];
-	}
-
-	if (l < 0.5) {
-		t2 = l * (1 + s);
-	} else {
-		t2 = l + s - l * s;
-	}
-
-	t1 = 2 * l - t2;
-
-	rgb = [0, 0, 0];
-	for (var i = 0; i < 3; i++) {
-		t3 = h + 1 / 3 * -(i - 1);
-		if (t3 < 0) {
-			t3++;
-		}
-		if (t3 > 1) {
-			t3--;
-		}
-
-		if (6 * t3 < 1) {
-			val = t1 + (t2 - t1) * 6 * t3;
-		} else if (2 * t3 < 1) {
-			val = t2;
-		} else if (3 * t3 < 2) {
-			val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
-		} else {
-			val = t1;
-		}
-
-		rgb[i] = val * 255;
-	}
-
-	return rgb;
-};
-
-convert.hsl.hsv = function (hsl) {
-	var h = hsl[0];
-	var s = hsl[1] / 100;
-	var l = hsl[2] / 100;
-	var smin = s;
-	var lmin = Math.max(l, 0.01);
-	var sv;
-	var v;
-
-	l *= 2;
-	s *= (l <= 1) ? l : 2 - l;
-	smin *= lmin <= 1 ? lmin : 2 - lmin;
-	v = (l + s) / 2;
-	sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
-
-	return [h, sv * 100, v * 100];
-};
-
-convert.hsv.rgb = function (hsv) {
-	var h = hsv[0] / 60;
-	var s = hsv[1] / 100;
-	var v = hsv[2] / 100;
-	var hi = Math.floor(h) % 6;
-
-	var f = h - Math.floor(h);
-	var p = 255 * v * (1 - s);
-	var q = 255 * v * (1 - (s * f));
-	var t = 255 * v * (1 - (s * (1 - f)));
-	v *= 255;
-
-	switch (hi) {
-		case 0:
-			return [v, t, p];
-		case 1:
-			return [q, v, p];
-		case 2:
-			return [p, v, t];
-		case 3:
-			return [p, q, v];
-		case 4:
-			return [t, p, v];
-		case 5:
-			return [v, p, q];
-	}
-};
-
-convert.hsv.hsl = function (hsv) {
-	var h = hsv[0];
-	var s = hsv[1] / 100;
-	var v = hsv[2] / 100;
-	var vmin = Math.max(v, 0.01);
-	var lmin;
-	var sl;
-	var l;
-
-	l = (2 - s) * v;
-	lmin = (2 - s) * vmin;
-	sl = s * vmin;
-	sl /= (lmin <= 1) ? lmin : 2 - lmin;
-	sl = sl || 0;
-	l /= 2;
-
-	return [h, sl * 100, l * 100];
-};
-
-// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
-convert.hwb.rgb = function (hwb) {
-	var h = hwb[0] / 360;
-	var wh = hwb[1] / 100;
-	var bl = hwb[2] / 100;
-	var ratio = wh + bl;
-	var i;
-	var v;
-	var f;
-	var n;
-
-	// wh + bl cant be > 1
-	if (ratio > 1) {
-		wh /= ratio;
-		bl /= ratio;
-	}
-
-	i = Math.floor(6 * h);
-	v = 1 - bl;
-	f = 6 * h - i;
-
-	if ((i & 0x01) !== 0) {
-		f = 1 - f;
-	}
-
-	n = wh + f * (v - wh); // linear interpolation
-
-	var r;
-	var g;
-	var b;
-	switch (i) {
-		default:
-		case 6:
-		case 0: r = v; g = n; b = wh; break;
-		case 1: r = n; g = v; b = wh; break;
-		case 2: r = wh; g = v; b = n; break;
-		case 3: r = wh; g = n; b = v; break;
-		case 4: r = n; g = wh; b = v; break;
-		case 5: r = v; g = wh; b = n; break;
-	}
-
-	return [r * 255, g * 255, b * 255];
-};
-
-convert.cmyk.rgb = function (cmyk) {
-	var c = cmyk[0] / 100;
-	var m = cmyk[1] / 100;
-	var y = cmyk[2] / 100;
-	var k = cmyk[3] / 100;
-	var r;
-	var g;
-	var b;
-
-	r = 1 - Math.min(1, c * (1 - k) + k);
-	g = 1 - Math.min(1, m * (1 - k) + k);
-	b = 1 - Math.min(1, y * (1 - k) + k);
-
-	return [r * 255, g * 255, b * 255];
-};
-
-convert.xyz.rgb = function (xyz) {
-	var x = xyz[0] / 100;
-	var y = xyz[1] / 100;
-	var z = xyz[2] / 100;
-	var r;
-	var g;
-	var b;
-
-	r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
-	g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
-	b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
-
-	// assume sRGB
-	r = r > 0.0031308
-		? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
-		: r * 12.92;
-
-	g = g > 0.0031308
-		? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
-		: g * 12.92;
-
-	b = b > 0.0031308
-		? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
-		: b * 12.92;
-
-	r = Math.min(Math.max(0, r), 1);
-	g = Math.min(Math.max(0, g), 1);
-	b = Math.min(Math.max(0, b), 1);
-
-	return [r * 255, g * 255, b * 255];
-};
-
-convert.xyz.lab = function (xyz) {
-	var x = xyz[0];
-	var y = xyz[1];
-	var z = xyz[2];
-	var l;
-	var a;
-	var b;
-
-	x /= 95.047;
-	y /= 100;
-	z /= 108.883;
-
-	x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
-	y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
-	z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
-
-	l = (116 * y) - 16;
-	a = 500 * (x - y);
-	b = 200 * (y - z);
-
-	return [l, a, b];
-};
-
-convert.lab.xyz = function (lab) {
-	var l = lab[0];
-	var a = lab[1];
-	var b = lab[2];
-	var x;
-	var y;
-	var z;
-
-	y = (l + 16) / 116;
-	x = a / 500 + y;
-	z = y - b / 200;
-
-	var y2 = Math.pow(y, 3);
-	var x2 = Math.pow(x, 3);
-	var z2 = Math.pow(z, 3);
-	y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
-	x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
-	z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
-
-	x *= 95.047;
-	y *= 100;
-	z *= 108.883;
-
-	return [x, y, z];
-};
-
-convert.lab.lch = function (lab) {
-	var l = lab[0];
-	var a = lab[1];
-	var b = lab[2];
-	var hr;
-	var h;
-	var c;
-
-	hr = Math.atan2(b, a);
-	h = hr * 360 / 2 / Math.PI;
-
-	if (h < 0) {
-		h += 360;
-	}
-
-	c = Math.sqrt(a * a + b * b);
-
-	return [l, c, h];
-};
-
-convert.lch.lab = function (lch) {
-	var l = lch[0];
-	var c = lch[1];
-	var h = lch[2];
-	var a;
-	var b;
-	var hr;
-
-	hr = h / 360 * 2 * Math.PI;
-	a = c * Math.cos(hr);
-	b = c * Math.sin(hr);
-
-	return [l, a, b];
-};
-
-convert.rgb.ansi16 = function (args) {
-	var r = args[0];
-	var g = args[1];
-	var b = args[2];
-	var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
-
-	value = Math.round(value / 50);
-
-	if (value === 0) {
-		return 30;
-	}
-
-	var ansi = 30
-		+ ((Math.round(b / 255) << 2)
-		| (Math.round(g / 255) << 1)
-		| Math.round(r / 255));
-
-	if (value === 2) {
-		ansi += 60;
-	}
-
-	return ansi;
-};
-
-convert.hsv.ansi16 = function (args) {
-	// optimization here; we already know the value and don't need to get
-	// it converted for us.
-	return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
-};
-
-convert.rgb.ansi256 = function (args) {
-	var r = args[0];
-	var g = args[1];
-	var b = args[2];
-
-	// we use the extended greyscale palette here, with the exception of
-	// black and white. normal palette only has 4 greyscale shades.
-	if (r === g && g === b) {
-		if (r < 8) {
-			return 16;
-		}
-
-		if (r > 248) {
-			return 231;
-		}
-
-		return Math.round(((r - 8) / 247) * 24) + 232;
-	}
-
-	var ansi = 16
-		+ (36 * Math.round(r / 255 * 5))
-		+ (6 * Math.round(g / 255 * 5))
-		+ Math.round(b / 255 * 5);
-
-	return ansi;
-};
-
-convert.ansi16.rgb = function (args) {
-	var color = args % 10;
-
-	// handle greyscale
-	if (color === 0 || color === 7) {
-		if (args > 50) {
-			color += 3.5;
-		}
-
-		color = color / 10.5 * 255;
-
-		return [color, color, color];
-	}
-
-	var mult = (~~(args > 50) + 1) * 0.5;
-	var r = ((color & 1) * mult) * 255;
-	var g = (((color >> 1) & 1) * mult) * 255;
-	var b = (((color >> 2) & 1) * mult) * 255;
-
-	return [r, g, b];
-};
-
-convert.ansi256.rgb = function (args) {
-	// handle greyscale
-	if (args >= 232) {
-		var c = (args - 232) * 10 + 8;
-		return [c, c, c];
-	}
-
-	args -= 16;
-
-	var rem;
-	var r = Math.floor(args / 36) / 5 * 255;
-	var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
-	var b = (rem % 6) / 5 * 255;
-
-	return [r, g, b];
-};
-
-convert.rgb.hex = function (args) {
-	var integer = ((Math.round(args[0]) & 0xFF) << 16)
-		+ ((Math.round(args[1]) & 0xFF) << 8)
-		+ (Math.round(args[2]) & 0xFF);
-
-	var string = integer.toString(16).toUpperCase();
-	return '000000'.substring(string.length) + string;
-};
-
-convert.hex.rgb = function (args) {
-	var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
-	if (!match) {
-		return [0, 0, 0];
-	}
-
-	var colorString = match[0];
-
-	if (match[0].length === 3) {
-		colorString = colorString.split('').map(function (char) {
-			return char + char;
-		}).join('');
-	}
-
-	var integer = parseInt(colorString, 16);
-	var r = (integer >> 16) & 0xFF;
-	var g = (integer >> 8) & 0xFF;
-	var b = integer & 0xFF;
-
-	return [r, g, b];
-};
-
-convert.rgb.hcg = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var max = Math.max(Math.max(r, g), b);
-	var min = Math.min(Math.min(r, g), b);
-	var chroma = (max - min);
-	var grayscale;
-	var hue;
-
-	if (chroma < 1) {
-		grayscale = min / (1 - chroma);
-	} else {
-		grayscale = 0;
-	}
-
-	if (chroma <= 0) {
-		hue = 0;
-	} else
-	if (max === r) {
-		hue = ((g - b) / chroma) % 6;
-	} else
-	if (max === g) {
-		hue = 2 + (b - r) / chroma;
-	} else {
-		hue = 4 + (r - g) / chroma + 4;
-	}
-
-	hue /= 6;
-	hue %= 1;
-
-	return [hue * 360, chroma * 100, grayscale * 100];
-};
-
-convert.hsl.hcg = function (hsl) {
-	var s = hsl[1] / 100;
-	var l = hsl[2] / 100;
-	var c = 1;
-	var f = 0;
-
-	if (l < 0.5) {
-		c = 2.0 * s * l;
-	} else {
-		c = 2.0 * s * (1.0 - l);
-	}
-
-	if (c < 1.0) {
-		f = (l - 0.5 * c) / (1.0 - c);
-	}
-
-	return [hsl[0], c * 100, f * 100];
-};
-
-convert.hsv.hcg = function (hsv) {
-	var s = hsv[1] / 100;
-	var v = hsv[2] / 100;
-
-	var c = s * v;
-	var f = 0;
-
-	if (c < 1.0) {
-		f = (v - c) / (1 - c);
-	}
-
-	return [hsv[0], c * 100, f * 100];
-};
-
-convert.hcg.rgb = function (hcg) {
-	var h = hcg[0] / 360;
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
-
-	if (c === 0.0) {
-		return [g * 255, g * 255, g * 255];
-	}
-
-	var pure = [0, 0, 0];
-	var hi = (h % 1) * 6;
-	var v = hi % 1;
-	var w = 1 - v;
-	var mg = 0;
-
-	switch (Math.floor(hi)) {
-		case 0:
-			pure[0] = 1; pure[1] = v; pure[2] = 0; break;
-		case 1:
-			pure[0] = w; pure[1] = 1; pure[2] = 0; break;
-		case 2:
-			pure[0] = 0; pure[1] = 1; pure[2] = v; break;
-		case 3:
-			pure[0] = 0; pure[1] = w; pure[2] = 1; break;
-		case 4:
-			pure[0] = v; pure[1] = 0; pure[2] = 1; break;
-		default:
-			pure[0] = 1; pure[1] = 0; pure[2] = w;
-	}
-
-	mg = (1.0 - c) * g;
-
-	return [
-		(c * pure[0] + mg) * 255,
-		(c * pure[1] + mg) * 255,
-		(c * pure[2] + mg) * 255
-	];
-};
-
-convert.hcg.hsv = function (hcg) {
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
-
-	var v = c + g * (1.0 - c);
-	var f = 0;
-
-	if (v > 0.0) {
-		f = c / v;
-	}
-
-	return [hcg[0], f * 100, v * 100];
-};
-
-convert.hcg.hsl = function (hcg) {
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
-
-	var l = g * (1.0 - c) + 0.5 * c;
-	var s = 0;
-
-	if (l > 0.0 && l < 0.5) {
-		s = c / (2 * l);
-	} else
-	if (l >= 0.5 && l < 1.0) {
-		s = c / (2 * (1 - l));
-	}
-
-	return [hcg[0], s * 100, l * 100];
-};
-
-convert.hcg.hwb = function (hcg) {
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
-	var v = c + g * (1.0 - c);
-	return [hcg[0], (v - c) * 100, (1 - v) * 100];
-};
-
-convert.hwb.hcg = function (hwb) {
-	var w = hwb[1] / 100;
-	var b = hwb[2] / 100;
-	var v = 1 - b;
-	var c = v - w;
-	var g = 0;
-
-	if (c < 1) {
-		g = (v - c) / (1 - c);
-	}
-
-	return [hwb[0], c * 100, g * 100];
-};
-
-convert.apple.rgb = function (apple) {
-	return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
-};
-
-convert.rgb.apple = function (rgb) {
-	return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
-};
-
-convert.gray.rgb = function (args) {
-	return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
-};
-
-convert.gray.hsl = convert.gray.hsv = function (args) {
-	return [0, 0, args[0]];
-};
-
-convert.gray.hwb = function (gray) {
-	return [0, 100, gray[0]];
-};
-
-convert.gray.cmyk = function (gray) {
-	return [0, 0, 0, gray[0]];
-};
-
-convert.gray.lab = function (gray) {
-	return [gray[0], 0, 0];
-};
-
-convert.gray.hex = function (gray) {
-	var val = Math.round(gray[0] / 100 * 255) & 0xFF;
-	var integer = (val << 16) + (val << 8) + val;
-
-	var string = integer.toString(16).toUpperCase();
-	return '000000'.substring(string.length) + string;
-};
-
-convert.rgb.gray = function (rgb) {
-	var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
-	return [val / 255 * 100];
-};
-
-
-/***/ }),
-/* 353 */
-/***/ ((module) => {
-
-"use strict";
-
-
-module.exports = {
-	"aliceblue": [240, 248, 255],
-	"antiquewhite": [250, 235, 215],
-	"aqua": [0, 255, 255],
-	"aquamarine": [127, 255, 212],
-	"azure": [240, 255, 255],
-	"beige": [245, 245, 220],
-	"bisque": [255, 228, 196],
-	"black": [0, 0, 0],
-	"blanchedalmond": [255, 235, 205],
-	"blue": [0, 0, 255],
-	"blueviolet": [138, 43, 226],
-	"brown": [165, 42, 42],
-	"burlywood": [222, 184, 135],
-	"cadetblue": [95, 158, 160],
-	"chartreuse": [127, 255, 0],
-	"chocolate": [210, 105, 30],
-	"coral": [255, 127, 80],
-	"cornflowerblue": [100, 149, 237],
-	"cornsilk": [255, 248, 220],
-	"crimson": [220, 20, 60],
-	"cyan": [0, 255, 255],
-	"darkblue": [0, 0, 139],
-	"darkcyan": [0, 139, 139],
-	"darkgoldenrod": [184, 134, 11],
-	"darkgray": [169, 169, 169],
-	"darkgreen": [0, 100, 0],
-	"darkgrey": [169, 169, 169],
-	"darkkhaki": [189, 183, 107],
-	"darkmagenta": [139, 0, 139],
-	"darkolivegreen": [85, 107, 47],
-	"darkorange": [255, 140, 0],
-	"darkorchid": [153, 50, 204],
-	"darkred": [139, 0, 0],
-	"darksalmon": [233, 150, 122],
-	"darkseagreen": [143, 188, 143],
-	"darkslateblue": [72, 61, 139],
-	"darkslategray": [47, 79, 79],
-	"darkslategrey": [47, 79, 79],
-	"darkturquoise": [0, 206, 209],
-	"darkviolet": [148, 0, 211],
-	"deeppink": [255, 20, 147],
-	"deepskyblue": [0, 191, 255],
-	"dimgray": [105, 105, 105],
-	"dimgrey": [105, 105, 105],
-	"dodgerblue": [30, 144, 255],
-	"firebrick": [178, 34, 34],
-	"floralwhite": [255, 250, 240],
-	"forestgreen": [34, 139, 34],
-	"fuchsia": [255, 0, 255],
-	"gainsboro": [220, 220, 220],
-	"ghostwhite": [248, 248, 255],
-	"gold": [255, 215, 0],
-	"goldenrod": [218, 165, 32],
-	"gray": [128, 128, 128],
-	"green": [0, 128, 0],
-	"greenyellow": [173, 255, 47],
-	"grey": [128, 128, 128],
-	"honeydew": [240, 255, 240],
-	"hotpink": [255, 105, 180],
-	"indianred": [205, 92, 92],
-	"indigo": [75, 0, 130],
-	"ivory": [255, 255, 240],
-	"khaki": [240, 230, 140],
-	"lavender": [230, 230, 250],
-	"lavenderblush": [255, 240, 245],
-	"lawngreen": [124, 252, 0],
-	"lemonchiffon": [255, 250, 205],
-	"lightblue": [173, 216, 230],
-	"lightcoral": [240, 128, 128],
-	"lightcyan": [224, 255, 255],
-	"lightgoldenrodyellow": [250, 250, 210],
-	"lightgray": [211, 211, 211],
-	"lightgreen": [144, 238, 144],
-	"lightgrey": [211, 211, 211],
-	"lightpink": [255, 182, 193],
-	"lightsalmon": [255, 160, 122],
-	"lightseagreen": [32, 178, 170],
-	"lightskyblue": [135, 206, 250],
-	"lightslategray": [119, 136, 153],
-	"lightslategrey": [119, 136, 153],
-	"lightsteelblue": [176, 196, 222],
-	"lightyellow": [255, 255, 224],
-	"lime": [0, 255, 0],
-	"limegreen": [50, 205, 50],
-	"linen": [250, 240, 230],
-	"magenta": [255, 0, 255],
-	"maroon": [128, 0, 0],
-	"mediumaquamarine": [102, 205, 170],
-	"mediumblue": [0, 0, 205],
-	"mediumorchid": [186, 85, 211],
-	"mediumpurple": [147, 112, 219],
-	"mediumseagreen": [60, 179, 113],
-	"mediumslateblue": [123, 104, 238],
-	"mediumspringgreen": [0, 250, 154],
-	"mediumturquoise": [72, 209, 204],
-	"mediumvioletred": [199, 21, 133],
-	"midnightblue": [25, 25, 112],
-	"mintcream": [245, 255, 250],
-	"mistyrose": [255, 228, 225],
-	"moccasin": [255, 228, 181],
-	"navajowhite": [255, 222, 173],
-	"navy": [0, 0, 128],
-	"oldlace": [253, 245, 230],
-	"olive": [128, 128, 0],
-	"olivedrab": [107, 142, 35],
-	"orange": [255, 165, 0],
-	"orangered": [255, 69, 0],
-	"orchid": [218, 112, 214],
-	"palegoldenrod": [238, 232, 170],
-	"palegreen": [152, 251, 152],
-	"paleturquoise": [175, 238, 238],
-	"palevioletred": [219, 112, 147],
-	"papayawhip": [255, 239, 213],
-	"peachpuff": [255, 218, 185],
-	"peru": [205, 133, 63],
-	"pink": [255, 192, 203],
-	"plum": [221, 160, 221],
-	"powderblue": [176, 224, 230],
-	"purple": [128, 0, 128],
-	"rebeccapurple": [102, 51, 153],
-	"red": [255, 0, 0],
-	"rosybrown": [188, 143, 143],
-	"royalblue": [65, 105, 225],
-	"saddlebrown": [139, 69, 19],
-	"salmon": [250, 128, 114],
-	"sandybrown": [244, 164, 96],
-	"seagreen": [46, 139, 87],
-	"seashell": [255, 245, 238],
-	"sienna": [160, 82, 45],
-	"silver": [192, 192, 192],
-	"skyblue": [135, 206, 235],
-	"slateblue": [106, 90, 205],
-	"slategray": [112, 128, 144],
-	"slategrey": [112, 128, 144],
-	"snow": [255, 250, 250],
-	"springgreen": [0, 255, 127],
-	"steelblue": [70, 130, 180],
-	"tan": [210, 180, 140],
-	"teal": [0, 128, 128],
-	"thistle": [216, 191, 216],
-	"tomato": [255, 99, 71],
-	"turquoise": [64, 224, 208],
-	"violet": [238, 130, 238],
-	"wheat": [245, 222, 179],
-	"white": [255, 255, 255],
-	"whitesmoke": [245, 245, 245],
-	"yellow": [255, 255, 0],
-	"yellowgreen": [154, 205, 50]
-};
-
-
-/***/ }),
-/* 354 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var conversions = __webpack_require__(352);
-
-/*
-	this function routes a model to all other models.
-
-	all functions that are routed have a property `.conversion` attached
-	to the returned synthetic function. This property is an array
-	of strings, each with the steps in between the 'from' and 'to'
-	color models (inclusive).
-
-	conversions that are not possible simply are not included.
-*/
-
-function buildGraph() {
-	var graph = {};
-	// https://jsperf.com/object-keys-vs-for-in-with-closure/3
-	var models = Object.keys(conversions);
-
-	for (var len = models.length, i = 0; i < len; i++) {
-		graph[models[i]] = {
-			// http://jsperf.com/1-vs-infinity
-			// micro-opt, but this is simple.
-			distance: -1,
-			parent: null
-		};
-	}
-
-	return graph;
-}
-
-// https://en.wikipedia.org/wiki/Breadth-first_search
-function deriveBFS(fromModel) {
-	var graph = buildGraph();
-	var queue = [fromModel]; // unshift -> queue -> pop
-
-	graph[fromModel].distance = 0;
-
-	while (queue.length) {
-		var current = queue.pop();
-		var adjacents = Object.keys(conversions[current]);
-
-		for (var len = adjacents.length, i = 0; i < len; i++) {
-			var adjacent = adjacents[i];
-			var node = graph[adjacent];
-
-			if (node.distance === -1) {
-				node.distance = graph[current].distance + 1;
-				node.parent = current;
-				queue.unshift(adjacent);
-			}
-		}
-	}
-
-	return graph;
-}
-
-function link(from, to) {
-	return function (args) {
-		return to(from(args));
-	};
-}
-
-function wrapConversion(toModel, graph) {
-	var path = [graph[toModel].parent, toModel];
-	var fn = conversions[graph[toModel].parent][toModel];
-
-	var cur = graph[toModel].parent;
-	while (graph[cur].parent) {
-		path.unshift(graph[cur].parent);
-		fn = link(conversions[graph[cur].parent][cur], fn);
-		cur = graph[cur].parent;
-	}
-
-	fn.conversion = path;
-	return fn;
-}
-
-module.exports = function (fromModel) {
-	var graph = deriveBFS(fromModel);
-	var conversion = {};
-
-	var models = Object.keys(graph);
-	for (var len = models.length, i = 0; i < len; i++) {
-		var toModel = models[i];
-		var node = graph[toModel];
-
-		if (node.parent === null) {
-			// no possible conversion, or this node is the source model.
-			continue;
-		}
-
-		conversion[toModel] = wrapConversion(toModel, graph);
-	}
-
-	return conversion;
-};
-
-
-
-/***/ }),
-/* 355 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-"use strict";
-
-const os = __webpack_require__(252);
-const hasFlag = __webpack_require__(356);
-
-const env = process.env;
-
-let forceColor;
-if (hasFlag('no-color') ||
-	hasFlag('no-colors') ||
-	hasFlag('color=false')) {
-	forceColor = false;
-} else if (hasFlag('color') ||
-	hasFlag('colors') ||
-	hasFlag('color=true') ||
-	hasFlag('color=always')) {
-	forceColor = true;
-}
-if ('FORCE_COLOR' in env) {
-	forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
-}
-
-function translateLevel(level) {
-	if (level === 0) {
-		return false;
-	}
-
-	return {
-		level,
-		hasBasic: true,
-		has256: level >= 2,
-		has16m: level >= 3
-	};
-}
-
-function supportsColor(stream) {
-	if (forceColor === false) {
-		return 0;
-	}
-
-	if (hasFlag('color=16m') ||
-		hasFlag('color=full') ||
-		hasFlag('color=truecolor')) {
-		return 3;
-	}
-
-	if (hasFlag('color=256')) {
-		return 2;
-	}
-
-	if (stream && !stream.isTTY && forceColor !== true) {
-		return 0;
-	}
-
-	const min = forceColor ? 1 : 0;
-
-	if (process.platform === 'win32') {
-		// Node.js 7.5.0 is the first version of Node.js to include a patch to
-		// libuv that enables 256 color output on Windows. Anything earlier and it
-		// won't work. However, here we target Node.js 8 at minimum as it is an LTS
-		// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
-		// release that supports 256 colors. Windows 10 build 14931 is the first release
-		// that supports 16m/TrueColor.
-		const osRelease = os.release().split('.');
-		if (
-			Number(process.versions.node.split('.')[0]) >= 8 &&
-			Number(osRelease[0]) >= 10 &&
-			Number(osRelease[2]) >= 10586
-		) {
-			return Number(osRelease[2]) >= 14931 ? 3 : 2;
-		}
-
-		return 1;
-	}
-
-	if ('CI' in env) {
-		if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
-			return 1;
-		}
-
-		return min;
-	}
-
-	if ('TEAMCITY_VERSION' in env) {
-		return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
-	}
-
-	if (env.COLORTERM === 'truecolor') {
-		return 3;
-	}
-
-	if ('TERM_PROGRAM' in env) {
-		const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
-
-		switch (env.TERM_PROGRAM) {
-			case 'iTerm.app':
-				return version >= 3 ? 3 : 2;
-			case 'Apple_Terminal':
-				return 2;
-			// No default
-		}
-	}
-
-	if (/-256(color)?$/i.test(env.TERM)) {
-		return 2;
-	}
-
-	if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
-		return 1;
-	}
-
-	if ('COLORTERM' in env) {
-		return 1;
-	}
-
-	if (env.TERM === 'dumb') {
-		return min;
-	}
-
-	return min;
-}
-
-function getSupportLevel(stream) {
-	const level = supportsColor(stream);
-	return translateLevel(level);
-}
-
-module.exports = {
-	supportsColor: getSupportLevel,
-	stdout: getSupportLevel(process.stdout),
-	stderr: getSupportLevel(process.stderr)
-};
-
-
-/***/ }),
-/* 356 */
-/***/ ((module) => {
-
-"use strict";
-
-module.exports = (flag, argv) => {
-	argv = argv || process.argv;
-	const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
-	const pos = argv.indexOf(prefix + flag);
-	const terminatorPos = argv.indexOf('--');
-	return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
-};
-
-
-/***/ }),
-/* 357 */
-/***/ ((module) => {
-
-"use strict";
-
-const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
-const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
-const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
-const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
-
-const ESCAPES = new Map([
-	['n', '\n'],
-	['r', '\r'],
-	['t', '\t'],
-	['b', '\b'],
-	['f', '\f'],
-	['v', '\v'],
-	['0', '\0'],
-	['\\', '\\'],
-	['e', '\u001B'],
-	['a', '\u0007']
-]);
-
-function unescape(c) {
-	if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
-		return String.fromCharCode(parseInt(c.slice(1), 16));
-	}
-
-	return ESCAPES.get(c) || c;
-}
-
-function parseArguments(name, args) {
-	const results = [];
-	const chunks = args.trim().split(/\s*,\s*/g);
-	let matches;
-
-	for (const chunk of chunks) {
-		if (!isNaN(chunk)) {
-			results.push(Number(chunk));
-		} else if ((matches = chunk.match(STRING_REGEX))) {
-			results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
-		} else {
-			throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
-		}
-	}
-
-	return results;
-}
-
-function parseStyle(style) {
-	STYLE_REGEX.lastIndex = 0;
-
-	const results = [];
-	let matches;
-
-	while ((matches = STYLE_REGEX.exec(style)) !== null) {
-		const name = matches[1];
-
-		if (matches[2]) {
-			const args = parseArguments(name, matches[2]);
-			results.push([name].concat(args));
-		} else {
-			results.push([name]);
-		}
-	}
-
-	return results;
+ * //=> Pear
+ * ```
+ *
+ * @returns The last element.
+ * @see {@link https://api.jquery.com/last/}
+ */
+function last() {
+    return this.length > 0 ? this._make(this[this.length - 1]) : this;
 }
-
-function buildStyle(chalk, styles) {
-	const enabled = {};
-
-	for (const layer of styles) {
-		for (const style of layer.styles) {
-			enabled[style[0]] = layer.inverse ? null : style.slice(1);
-		}
-	}
-
-	let current = chalk;
-	for (const styleName of Object.keys(enabled)) {
-		if (Array.isArray(enabled[styleName])) {
-			if (!(styleName in current)) {
-				throw new Error(`Unknown Chalk style: ${styleName}`);
-			}
-
-			if (enabled[styleName].length > 0) {
-				current = current[styleName].apply(current, enabled[styleName]);
-			} else {
-				current = current[styleName];
-			}
-		}
-	}
-
-	return current;
+exports.last = last;
+/**
+ * Reduce the set of matched elements to the one at the specified index. Use
+ * `.eq(-i)` to count backwards from the last selected element.
+ *
+ * @category Traversing
+ * @example
+ *
+ * ```js
+ * $('li').eq(0).text();
+ * //=> Apple
+ *
+ * $('li').eq(-1).text();
+ * //=> Pear
+ * ```
+ *
+ * @param i - Index of the element to select.
+ * @returns The element at the `i`th position.
+ * @see {@link https://api.jquery.com/eq/}
+ */
+function eq(i) {
+    var _a;
+    i = +i;
+    // Use the first identity optimization if possible
+    if (i === 0 && this.length <= 1)
+        return this;
+    if (i < 0)
+        i = this.length + i;
+    return this._make((_a = this[i]) !== null && _a !== void 0 ? _a : []);
 }
-
-module.exports = (chalk, tmp) => {
-	const styles = [];
-	const chunks = [];
-	let chunk = [];
-
-	// eslint-disable-next-line max-params
-	tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
-		if (escapeChar) {
-			chunk.push(unescape(escapeChar));
-		} else if (style) {
-			const str = chunk.join('');
-			chunk = [];
-			chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
-			styles.push({inverse, styles: parseStyle(style)});
-		} else if (close) {
-			if (styles.length === 0) {
-				throw new Error('Found extraneous } in Chalk template literal');
-			}
-
-			chunks.push(buildStyle(chalk, styles)(chunk.join('')));
-			chunk = [];
-			styles.pop();
-		} else {
-			chunk.push(chr);
-		}
-	});
-
-	chunks.push(chunk.join(''));
-
-	if (styles.length > 0) {
-		const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
-		throw new Error(errMsg);
-	}
-
-	return chunks.join('');
-};
-
-
-/***/ }),
-/* 358 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseGet = __webpack_require__(359);
-
+exports.eq = eq;
+function get(i) {
+    if (i == null) {
+        return this.toArray();
+    }
+    return this[i < 0 ? this.length + i : i];
+}
+exports.get = get;
 /**
- * Gets the value at `path` of `object`. If the resolved value is
- * `undefined`, the `defaultValue` is returned in its place.
+ * Retrieve all the DOM elements contained in the jQuery set as an array.
  *
- * @static
- * @memberOf _
- * @since 3.7.0
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to get.
- * @param {*} [defaultValue] The value returned for `undefined` resolved values.
- * @returns {*} Returns the resolved value.
  * @example
  *
- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ * ```js
+ * $('li').toArray();
+ * //=> [ {...}, {...}, {...} ]
+ * ```
  *
- * _.get(object, 'a[0].b.c');
- * // => 3
+ * @returns The contained items.
+ */
+function toArray() {
+    return Array.prototype.slice.call(this);
+}
+exports.toArray = toArray;
+/**
+ * Search for a given element from among the matched elements.
  *
- * _.get(object, ['a', '0', 'b', 'c']);
- * // => 3
+ * @category Traversing
+ * @example
  *
- * _.get(object, 'a.b.c', 'default');
- * // => 'default'
+ * ```js
+ * $('.pear').index();
+ * //=> 2 $('.orange').index('li');
+ * //=> 1
+ * $('.apple').index($('#fruit, li'));
+ * //=> 1
+ * ```
+ *
+ * @param selectorOrNeedle - Element to look for.
+ * @returns The index of the element.
+ * @see {@link https://api.jquery.com/index/}
  */
-function get(object, path, defaultValue) {
-  var result = object == null ? undefined : baseGet(object, path);
-  return result === undefined ? defaultValue : result;
+function index(selectorOrNeedle) {
+    var $haystack;
+    var needle;
+    if (selectorOrNeedle == null) {
+        $haystack = this.parent().children();
+        needle = this[0];
+    }
+    else if (typeof selectorOrNeedle === 'string') {
+        $haystack = this._make(selectorOrNeedle);
+        needle = this[0];
+    }
+    else {
+        $haystack = this;
+        needle = utils_1.isCheerio(selectorOrNeedle)
+            ? selectorOrNeedle[0]
+            : selectorOrNeedle;
+    }
+    return Array.prototype.indexOf.call($haystack, needle);
 }
-
-module.exports = get;
-
-
-/***/ }),
-/* 359 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var castPath = __webpack_require__(360),
-    toKey = __webpack_require__(399);
-
+exports.index = index;
 /**
- * The base implementation of `_.get` without support for default values.
+ * Gets the elements matching the specified range (0-based position).
  *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to get.
- * @returns {*} Returns the resolved value.
+ * @category Traversing
+ * @example
+ *
+ * ```js
+ * $('li').slice(1).eq(0).text();
+ * //=> 'Orange'
+ *
+ * $('li').slice(1, 2).length;
+ * //=> 1
+ * ```
+ *
+ * @param start - An position at which the elements begin to be selected. If
+ *   negative, it indicates an offset from the end of the set.
+ * @param end - An position at which the elements stop being selected. If
+ *   negative, it indicates an offset from the end of the set. If omitted, the
+ *   range continues until the end of the set.
+ * @returns The elements matching the specified range.
+ * @see {@link https://api.jquery.com/slice/}
  */
-function baseGet(object, path) {
-  path = castPath(path, object);
-
-  var index = 0,
-      length = path.length;
-
-  while (object != null && index < length) {
-    object = object[toKey(path[index++])];
-  }
-  return (index && index == length) ? object : undefined;
+function slice(start, end) {
+    return this._make(Array.prototype.slice.call(this, start, end));
 }
-
-module.exports = baseGet;
-
-
-/***/ }),
-/* 360 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var isArray = __webpack_require__(55),
-    isKey = __webpack_require__(361),
-    stringToPath = __webpack_require__(363),
-    toString = __webpack_require__(396);
-
+exports.slice = slice;
 /**
- * Casts `value` to a path array if it's not one.
+ * End the most recent filtering operation in the current chain and return the
+ * set of matched elements to its previous state.
  *
- * @private
- * @param {*} value The value to inspect.
- * @param {Object} [object] The object to query keys on.
- * @returns {Array} Returns the cast property path array.
+ * @category Traversing
+ * @example
+ *
+ * ```js
+ * $('li').eq(0).end().length;
+ * //=> 3
+ * ```
+ *
+ * @returns The previous state of the set of matched elements.
+ * @see {@link https://api.jquery.com/end/}
  */
-function castPath(value, object) {
-  if (isArray(value)) {
-    return value;
-  }
-  return isKey(value, object) ? [value] : stringToPath(toString(value));
+function end() {
+    var _a;
+    return (_a = this.prevObject) !== null && _a !== void 0 ? _a : this._make([]);
 }
-
-module.exports = castPath;
-
-
-/***/ }),
-/* 361 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var isArray = __webpack_require__(55),
-    isSymbol = __webpack_require__(362);
-
-/** Used to match property names within property paths. */
-var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
-    reIsPlainProp = /^\w*$/;
-
+exports.end = end;
 /**
- * Checks if `value` is a property name and not a property path.
+ * Add elements to the set of matched elements.
  *
- * @private
- * @param {*} value The value to check.
- * @param {Object} [object] The object to query keys on.
- * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ * @category Traversing
+ * @example
+ *
+ * ```js
+ * $('.apple').add('.orange').length;
+ * //=> 2
+ * ```
+ *
+ * @param other - Elements to add.
+ * @param context - Optionally the context of the new selection.
+ * @returns The combined set.
+ * @see {@link https://api.jquery.com/add/}
  */
-function isKey(value, object) {
-  if (isArray(value)) {
-    return false;
-  }
-  var type = typeof value;
-  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
-      value == null || isSymbol(value)) {
-    return true;
-  }
-  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
-    (object != null && value in Object(object));
+function add(other, context) {
+    var selection = this._make(other, context);
+    var contents = uniqueSort(tslib_1.__spreadArray(tslib_1.__spreadArray([], this.get()), selection.get()));
+    return this._make(contents);
 }
-
-module.exports = isKey;
-
-
-/***/ }),
-/* 362 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseGetTag = __webpack_require__(46),
-    isObjectLike = __webpack_require__(53);
-
-/** `Object#toString` result references. */
-var symbolTag = '[object Symbol]';
-
+exports.add = add;
 /**
- * Checks if `value` is classified as a `Symbol` primitive or object.
+ * Add the previous set of elements on the stack to the current set, optionally
+ * filtered by a selector.
  *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
+ * @category Traversing
  * @example
  *
- * _.isSymbol(Symbol.iterator);
- * // => true
+ * ```js
+ * $('li').eq(0).addBack('.orange').length;
+ * //=> 2
+ * ```
  *
- * _.isSymbol('abc');
- * // => false
+ * @param selector - Selector for the elements to add.
+ * @returns The combined set.
+ * @see {@link https://api.jquery.com/addBack/}
  */
-function isSymbol(value) {
-  return typeof value == 'symbol' ||
-    (isObjectLike(value) && baseGetTag(value) == symbolTag);
+function addBack(selector) {
+    return this.prevObject
+        ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject)
+        : this;
 }
-
-module.exports = isSymbol;
+exports.addBack = addBack;
 
 
 /***/ }),
-/* 363 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var memoizeCapped = __webpack_require__(364);
-
-/** Used to match property names within property paths. */
-var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
+/* 350 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-/** Used to match backslashes in property paths. */
-var reEscapeChar = /\\(\\)?/g;
+"use strict";
 
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.clone = exports.text = exports.toString = exports.html = exports.empty = exports.replaceWith = exports.remove = exports.insertBefore = exports.before = exports.insertAfter = exports.after = exports.wrapAll = exports.unwrap = exports.wrapInner = exports.wrap = exports.prepend = exports.append = exports.prependTo = exports.appendTo = exports._makeDomArray = void 0;
+var tslib_1 = __webpack_require__(257);
+var domhandler_1 = __webpack_require__(317);
 /**
- * Converts `string` to a property path array.
+ * Methods for modifying the DOM structure.
+ *
+ * @module cheerio/manipulation
+ */
+var domhandler_2 = __webpack_require__(317);
+var parse_1 = tslib_1.__importStar(__webpack_require__(346));
+var static_1 = __webpack_require__(261);
+var utils_1 = __webpack_require__(347);
+var htmlparser2_1 = __webpack_require__(303);
+/**
+ * Create an array of nodes, recursing into arrays and parsing strings if necessary.
  *
  * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the property path array.
+ * @category Manipulation
+ * @param elem - Elements to make an array of.
+ * @param clone - Optionally clone nodes.
+ * @returns The array of nodes.
  */
-var stringToPath = memoizeCapped(function(string) {
-  var result = [];
-  if (string.charCodeAt(0) === 46 /* . */) {
-    result.push('');
-  }
-  string.replace(rePropName, function(match, number, quote, subString) {
-    result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
-  });
-  return result;
-});
-
-module.exports = stringToPath;
-
-
-/***/ }),
-/* 364 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var memoize = __webpack_require__(365);
-
-/** Used as the maximum memoize cache size. */
-var MAX_MEMOIZE_SIZE = 500;
-
+function _makeDomArray(elem, clone) {
+    var _this = this;
+    if (elem == null) {
+        return [];
+    }
+    if (utils_1.isCheerio(elem)) {
+        return clone ? utils_1.cloneDom(elem.get()) : elem.get();
+    }
+    if (Array.isArray(elem)) {
+        return elem.reduce(function (newElems, el) { return newElems.concat(_this._makeDomArray(el, clone)); }, []);
+    }
+    if (typeof elem === 'string') {
+        return parse_1.default(elem, this.options, false).children;
+    }
+    return clone ? utils_1.cloneDom([elem]) : [elem];
+}
+exports._makeDomArray = _makeDomArray;
+function _insert(concatenator) {
+    return function () {
+        var _this = this;
+        var elems = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            elems[_i] = arguments[_i];
+        }
+        var lastIdx = this.length - 1;
+        return utils_1.domEach(this, function (el, i) {
+            if (!domhandler_1.hasChildren(el))
+                return;
+            var domSrc = typeof elems[0] === 'function'
+                ? elems[0].call(el, i, static_1.html(el.children))
+                : elems;
+            var dom = _this._makeDomArray(domSrc, i < lastIdx);
+            concatenator(dom, el.children, el);
+        });
+    };
+}
 /**
- * A specialized version of `_.memoize` which clears the memoized function's
- * cache when it exceeds `MAX_MEMOIZE_SIZE`.
+ * Modify an array in-place, removing some number of elements and adding new
+ * elements directly following them.
  *
  * @private
- * @param {Function} func The function to have its output memoized.
- * @returns {Function} Returns the new memoized function.
+ * @category Manipulation
+ * @param array - Target array to splice.
+ * @param spliceIdx - Index at which to begin changing the array.
+ * @param spliceCount - Number of elements to remove from the array.
+ * @param newElems - Elements to insert into the array.
+ * @param parent - The parent of the node.
+ * @returns The spliced array.
  */
-function memoizeCapped(func) {
-  var result = memoize(func, function(key) {
-    if (cache.size === MAX_MEMOIZE_SIZE) {
-      cache.clear();
+function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) {
+    var _a, _b;
+    var spliceArgs = tslib_1.__spreadArray([
+        spliceIdx,
+        spliceCount
+    ], newElems);
+    var prev = array[spliceIdx - 1] || null;
+    var next = array[spliceIdx + spliceCount] || null;
+    /*
+     * Before splicing in new elements, ensure they do not already appear in the
+     * current array.
+     */
+    for (var idx = 0; idx < newElems.length; ++idx) {
+        var node = newElems[idx];
+        var oldParent = node.parent;
+        if (oldParent) {
+            var prevIdx = oldParent.children.indexOf(newElems[idx]);
+            if (prevIdx > -1) {
+                oldParent.children.splice(prevIdx, 1);
+                if (parent === oldParent && spliceIdx > prevIdx) {
+                    spliceArgs[0]--;
+                }
+            }
+        }
+        node.parent = parent;
+        if (node.prev) {
+            node.prev.next = (_a = node.next) !== null && _a !== void 0 ? _a : null;
+        }
+        if (node.next) {
+            node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null;
+        }
+        node.prev = newElems[idx - 1] || prev;
+        node.next = newElems[idx + 1] || next;
     }
-    return key;
-  });
-
-  var cache = result.cache;
-  return result;
+    if (prev) {
+        prev.next = newElems[0];
+    }
+    if (next) {
+        next.prev = newElems[newElems.length - 1];
+    }
+    return array.splice.apply(array, spliceArgs);
 }
-
-module.exports = memoizeCapped;
-
-
-/***/ }),
-/* 365 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var MapCache = __webpack_require__(366);
-
-/** Error message constants. */
-var FUNC_ERROR_TEXT = 'Expected a function';
-
 /**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided, it determines the cache key for storing the result based on the
- * arguments provided to the memoized function. By default, the first argument
- * provided to the memoized function is used as the map cache key. The `func`
- * is invoked with the `this` binding of the memoized function.
+ * Insert every element in the set of matched elements to the end of the target.
  *
- * **Note:** The cache is exposed as the `cache` property on the memoized
- * function. Its creation may be customized by replacing the `_.memoize.Cache`
- * constructor with one whose instances implement the
- * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
- * method interface of `clear`, `delete`, `get`, `has`, and `set`.
+ * @category Manipulation
+ * @example
  *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Function
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] The function to resolve the cache key.
- * @returns {Function} Returns the new memoized function.
+ * ```js
+ * $('<li class="plum">Plum</li>').appendTo('#fruits');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //      <li class="plum">Plum</li>
+ * //    </ul>
+ * ```
+ *
+ * @param target - Element to append elements to.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/appendTo/}
+ */
+function appendTo(target) {
+    var appendTarget = utils_1.isCheerio(target) ? target : this._make(target);
+    appendTarget.append(this);
+    return this;
+}
+exports.appendTo = appendTo;
+/**
+ * Insert every element in the set of matched elements to the beginning of the target.
+ *
+ * @category Manipulation
  * @example
  *
- * var object = { 'a': 1, 'b': 2 };
- * var other = { 'c': 3, 'd': 4 };
+ * ```js
+ * $('<li class="plum">Plum</li>').prependTo('#fruits');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="plum">Plum</li>
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //    </ul>
+ * ```
  *
- * var values = _.memoize(_.values);
- * values(object);
- * // => [1, 2]
+ * @param target - Element to prepend elements to.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/prependTo/}
+ */
+function prependTo(target) {
+    var prependTarget = utils_1.isCheerio(target) ? target : this._make(target);
+    prependTarget.prepend(this);
+    return this;
+}
+exports.prependTo = prependTo;
+/**
+ * Inserts content as the *last* child of each of the selected elements.
  *
- * values(other);
- * // => [3, 4]
+ * @category Manipulation
+ * @example
  *
- * object.a = 2;
- * values(object);
- * // => [1, 2]
+ * ```js
+ * $('ul').append('<li class="plum">Plum</li>');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //      <li class="plum">Plum</li>
+ * //    </ul>
+ * ```
  *
- * // Modify the result cache.
- * values.cache.set(object, ['a', 'b']);
- * values(object);
- * // => ['a', 'b']
+ * @see {@link https://api.jquery.com/append/}
+ */
+exports.append = _insert(function (dom, children, parent) {
+    uniqueSplice(children, children.length, 0, dom, parent);
+});
+/**
+ * Inserts content as the *first* child of each of the selected elements.
  *
- * // Replace `_.memoize.Cache`.
- * _.memoize.Cache = WeakMap;
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('ul').prepend('<li class="plum">Plum</li>');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="plum">Plum</li>
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //    </ul>
+ * ```
+ *
+ * @see {@link https://api.jquery.com/prepend/}
  */
-function memoize(func, resolver) {
-  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
-    throw new TypeError(FUNC_ERROR_TEXT);
-  }
-  var memoized = function() {
-    var args = arguments,
-        key = resolver ? resolver.apply(this, args) : args[0],
-        cache = memoized.cache;
-
-    if (cache.has(key)) {
-      return cache.get(key);
-    }
-    var result = func.apply(this, args);
-    memoized.cache = cache.set(key, result) || cache;
-    return result;
-  };
-  memoized.cache = new (memoize.Cache || MapCache);
-  return memoized;
+exports.prepend = _insert(function (dom, children, parent) {
+    uniqueSplice(children, 0, 0, dom, parent);
+});
+function _wrap(insert) {
+    return function (wrapper) {
+        var lastIdx = this.length - 1;
+        var lastParent = this.parents().last();
+        for (var i = 0; i < this.length; i++) {
+            var el = this[i];
+            var wrap_1 = typeof wrapper === 'function'
+                ? wrapper.call(el, i, el)
+                : typeof wrapper === 'string' && !utils_1.isHtml(wrapper)
+                    ? lastParent.find(wrapper).clone()
+                    : wrapper;
+            var wrapperDom = this._makeDomArray(wrap_1, i < lastIdx)[0];
+            if (!wrapperDom || !htmlparser2_1.DomUtils.hasChildren(wrapperDom))
+                continue;
+            var elInsertLocation = wrapperDom;
+            /*
+             * Find the deepest child. Only consider the first tag child of each node
+             * (ignore text); stop if no children are found.
+             */
+            var j = 0;
+            while (j < elInsertLocation.children.length) {
+                var child = elInsertLocation.children[j];
+                if (utils_1.isTag(child)) {
+                    elInsertLocation = child;
+                    j = 0;
+                }
+                else {
+                    j++;
+                }
+            }
+            insert(el, elInsertLocation, [wrapperDom]);
+        }
+        return this;
+    };
 }
-
-// Expose `MapCache`.
-memoize.Cache = MapCache;
-
-module.exports = memoize;
-
-
-/***/ }),
-/* 366 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var mapCacheClear = __webpack_require__(367),
-    mapCacheDelete = __webpack_require__(390),
-    mapCacheGet = __webpack_require__(393),
-    mapCacheHas = __webpack_require__(394),
-    mapCacheSet = __webpack_require__(395);
-
 /**
- * Creates a map cache object to store key-value pairs.
+ * The .wrap() function can take any string or object that could be passed to
+ * the $() factory function to specify a DOM structure. This structure may be
+ * nested several levels deep, but should contain only one inmost element. A
+ * copy of this structure will be wrapped around each of the elements in the set
+ * of matched elements. This method returns the original set of elements for
+ * chaining purposes.
  *
- * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * const redFruit = $('<div class="red-fruit"></div>');
+ * $('.apple').wrap(redFruit);
+ *
+ * //=> <ul id="fruits">
+ * //     <div class="red-fruit">
+ * //      <li class="apple">Apple</li>
+ * //     </div>
+ * //     <li class="orange">Orange</li>
+ * //     <li class="plum">Plum</li>
+ * //   </ul>
+ *
+ * const healthy = $('<div class="healthy"></div>');
+ * $('li').wrap(healthy);
+ *
+ * //=> <ul id="fruits">
+ * //     <div class="healthy">
+ * //       <li class="apple">Apple</li>
+ * //     </div>
+ * //     <div class="healthy">
+ * //       <li class="orange">Orange</li>
+ * //     </div>
+ * //     <div class="healthy">
+ * //        <li class="plum">Plum</li>
+ * //     </div>
+ * //   </ul>
+ * ```
+ *
+ * @param wrapper - The DOM structure to wrap around each element in the selection.
+ * @see {@link https://api.jquery.com/wrap/}
  */
-function MapCache(entries) {
-  var index = -1,
-      length = entries == null ? 0 : entries.length;
-
-  this.clear();
-  while (++index < length) {
-    var entry = entries[index];
-    this.set(entry[0], entry[1]);
-  }
-}
-
-// Add methods to `MapCache`.
-MapCache.prototype.clear = mapCacheClear;
-MapCache.prototype['delete'] = mapCacheDelete;
-MapCache.prototype.get = mapCacheGet;
-MapCache.prototype.has = mapCacheHas;
-MapCache.prototype.set = mapCacheSet;
-
-module.exports = MapCache;
-
-
-/***/ }),
-/* 367 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var Hash = __webpack_require__(368),
-    ListCache = __webpack_require__(381),
-    Map = __webpack_require__(389);
-
+exports.wrap = _wrap(function (el, elInsertLocation, wrapperDom) {
+    var parent = el.parent;
+    if (!parent)
+        return;
+    var siblings = parent.children;
+    var index = siblings.indexOf(el);
+    parse_1.update([el], elInsertLocation);
+    /*
+     * The previous operation removed the current element from the `siblings`
+     * array, so the `dom` array can be inserted without removing any
+     * additional elements.
+     */
+    uniqueSplice(siblings, index, 0, wrapperDom, parent);
+});
 /**
- * Removes all key-value entries from the map.
+ * The .wrapInner() function can take any string or object that could be passed
+ * to the $() factory function to specify a DOM structure. This structure may be
+ * nested several levels deep, but should contain only one inmost element. The
+ * structure will be wrapped around the content of each of the elements in the
+ * set of matched elements.
  *
- * @private
- * @name clear
- * @memberOf MapCache
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * const redFruit = $('<div class="red-fruit"></div>');
+ * $('.apple').wrapInner(redFruit);
+ *
+ * //=> <ul id="fruits">
+ * //     <li class="apple">
+ * //       <div class="red-fruit">Apple</div>
+ * //     </li>
+ * //     <li class="orange">Orange</li>
+ * //     <li class="pear">Pear</li>
+ * //   </ul>
+ *
+ * const healthy = $('<div class="healthy"></div>');
+ * $('li').wrapInner(healthy);
+ *
+ * //=> <ul id="fruits">
+ * //     <li class="apple">
+ * //       <div class="healthy">Apple</div>
+ * //     </li>
+ * //     <li class="orange">
+ * //       <div class="healthy">Orange</div>
+ * //     </li>
+ * //     <li class="pear">
+ * //       <div class="healthy">Pear</div>
+ * //     </li>
+ * //   </ul>
+ * ```
+ *
+ * @param wrapper - The DOM structure to wrap around the content of each element
+ *   in the selection.
+ * @returns The instance itself, for chaining.
+ * @see {@link https://api.jquery.com/wrapInner/}
  */
-function mapCacheClear() {
-  this.size = 0;
-  this.__data__ = {
-    'hash': new Hash,
-    'map': new (Map || ListCache),
-    'string': new Hash
-  };
-}
-
-module.exports = mapCacheClear;
-
-
-/***/ }),
-/* 368 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var hashClear = __webpack_require__(369),
-    hashDelete = __webpack_require__(377),
-    hashGet = __webpack_require__(378),
-    hashHas = __webpack_require__(379),
-    hashSet = __webpack_require__(380);
-
+exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) {
+    if (!domhandler_1.hasChildren(el))
+        return;
+    parse_1.update(el.children, elInsertLocation);
+    parse_1.update(wrapperDom, el);
+});
 /**
- * Creates a hash object.
+ * The .unwrap() function, removes the parents of the set of matched elements
+ * from the DOM, leaving the matched elements in their place.
  *
- * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
+ * @category Manipulation
+ * @example <caption>without selector</caption>
+ *
+ * ```js
+ * const $ = cheerio.load(
+ *   '<div id=test>\n  <div><p>Hello</p></div>\n  <div><p>World</p></div>\n</div>'
+ * );
+ * $('#test p').unwrap();
+ *
+ * //=> <div id=test>
+ * //     <p>Hello</p>
+ * //     <p>World</p>
+ * //   </div>
+ * ```
+ *
+ * @example <caption>with selector</caption>
+ *
+ * ```js
+ * const $ = cheerio.load(
+ *   '<div id=test>\n  <p>Hello</p>\n  <b><p>World</p></b>\n</div>'
+ * );
+ * $('#test p').unwrap('b');
+ *
+ * //=> <div id=test>
+ * //     <p>Hello</p>
+ * //     <p>World</p>
+ * //   </div>
+ * ```
+ *
+ * @param selector - A selector to check the parent element against. If an
+ *   element's parent does not match the selector, the element won't be unwrapped.
+ * @returns The instance itself, for chaining.
+ * @see {@link https://api.jquery.com/unwrap/}
  */
-function Hash(entries) {
-  var index = -1,
-      length = entries == null ? 0 : entries.length;
-
-  this.clear();
-  while (++index < length) {
-    var entry = entries[index];
-    this.set(entry[0], entry[1]);
-  }
+function unwrap(selector) {
+    var _this = this;
+    this.parent(selector)
+        .not('body')
+        .each(function (_, el) {
+        _this._make(el).replaceWith(el.children);
+    });
+    return this;
 }
-
-// Add methods to `Hash`.
-Hash.prototype.clear = hashClear;
-Hash.prototype['delete'] = hashDelete;
-Hash.prototype.get = hashGet;
-Hash.prototype.has = hashHas;
-Hash.prototype.set = hashSet;
-
-module.exports = Hash;
-
-
-/***/ }),
-/* 369 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var nativeCreate = __webpack_require__(370);
-
+exports.unwrap = unwrap;
 /**
- * Removes all key-value entries from the hash.
+ * The .wrapAll() function can take any string or object that could be passed to
+ * the $() function to specify a DOM structure. This structure may be nested
+ * several levels deep, but should contain only one inmost element. The
+ * structure will be wrapped around all of the elements in the set of matched
+ * elements, as a single group.
  *
- * @private
- * @name clear
- * @memberOf Hash
+ * @category Manipulation
+ * @example <caption>With markup passed to `wrapAll`</caption>
+ *
+ * ```js
+ * const $ = cheerio.load(
+ *   '<div class="container"><div class="inner">First</div><div class="inner">Second</div></div>'
+ * );
+ * $('.inner').wrapAll("<div class='new'></div>");
+ *
+ * //=> <div class="container">
+ * //     <div class='new'>
+ * //       <div class="inner">First</div>
+ * //       <div class="inner">Second</div>
+ * //     </div>
+ * //   </div>
+ * ```
+ *
+ * @example <caption>With an existing cheerio instance</caption>
+ *
+ * ```js
+ * const $ = cheerio.load(
+ *   '<span>Span 1</span><strong>Strong</strong><span>Span 2</span>'
+ * );
+ * const wrap = $('<div><p><em><b></b></em></p></div>');
+ * $('span').wrapAll(wrap);
+ *
+ * //=> <div>
+ * //     <p>
+ * //       <em>
+ * //         <b>
+ * //           <span>Span 1</span>
+ * //           <span>Span 2</span>
+ * //         </b>
+ * //       </em>
+ * //     </p>
+ * //   </div>
+ * //   <strong>Strong</strong>
+ * ```
+ *
+ * @param wrapper - The DOM structure to wrap around all matched elements in the
+ *   selection.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/wrapAll/}
  */
-function hashClear() {
-  this.__data__ = nativeCreate ? nativeCreate(null) : {};
-  this.size = 0;
+function wrapAll(wrapper) {
+    var el = this[0];
+    if (el) {
+        var wrap_2 = this._make(typeof wrapper === 'function' ? wrapper.call(el, 0, el) : wrapper).insertBefore(el);
+        // If html is given as wrapper, wrap may contain text elements
+        var elInsertLocation = void 0;
+        for (var i = 0; i < wrap_2.length; i++) {
+            if (wrap_2[i].type === 'tag')
+                elInsertLocation = wrap_2[i];
+        }
+        var j = 0;
+        /*
+         * Find the deepest child. Only consider the first tag child of each node
+         * (ignore text); stop if no children are found.
+         */
+        while (elInsertLocation && j < elInsertLocation.children.length) {
+            var child = elInsertLocation.children[j];
+            if (child.type === 'tag') {
+                elInsertLocation = child;
+                j = 0;
+            }
+            else {
+                j++;
+            }
+        }
+        if (elInsertLocation)
+            this._make(elInsertLocation).append(this);
+    }
+    return this;
 }
-
-module.exports = hashClear;
-
-
-/***/ }),
-/* 370 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var getNative = __webpack_require__(371);
-
-/* Built-in method references that are verified to be native. */
-var nativeCreate = getNative(Object, 'create');
-
-module.exports = nativeCreate;
-
-
-/***/ }),
-/* 371 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseIsNative = __webpack_require__(372),
-    getValue = __webpack_require__(376);
-
+exports.wrapAll = wrapAll;
+/* eslint-disable jsdoc/check-param-names*/
 /**
- * Gets the native function at `key` of `object`.
+ * Insert content next to each element in the set of matched elements.
  *
- * @private
- * @param {Object} object The object to query.
- * @param {string} key The key of the method to get.
- * @returns {*} Returns the function if it's native, else `undefined`.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('.apple').after('<li class="plum">Plum</li>');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="apple">Apple</li>
+ * //      <li class="plum">Plum</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //    </ul>
+ * ```
+ *
+ * @param content - HTML string, DOM element, array of DOM elements or Cheerio
+ *   to insert after each element in the set of matched elements.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/after/}
  */
-function getNative(object, key) {
-  var value = getValue(object, key);
-  return baseIsNative(value) ? value : undefined;
+function after() {
+    var _this = this;
+    var elems = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        elems[_i] = arguments[_i];
+    }
+    var lastIdx = this.length - 1;
+    return utils_1.domEach(this, function (el, i) {
+        var parent = el.parent;
+        if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) {
+            return;
+        }
+        var siblings = parent.children;
+        var index = siblings.indexOf(el);
+        // If not found, move on
+        /* istanbul ignore next */
+        if (index < 0)
+            return;
+        var domSrc = typeof elems[0] === 'function'
+            ? elems[0].call(el, i, static_1.html(el.children))
+            : elems;
+        var dom = _this._makeDomArray(domSrc, i < lastIdx);
+        // Add element after `this` element
+        uniqueSplice(siblings, index + 1, 0, dom, parent);
+    });
 }
-
-module.exports = getNative;
-
-
-/***/ }),
-/* 372 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var isFunction = __webpack_require__(45),
-    isMasked = __webpack_require__(373),
-    isObject = __webpack_require__(52),
-    toSource = __webpack_require__(375);
-
-/**
- * Used to match `RegExp`
- * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
- */
-var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
-
-/** Used to detect host constructors (Safari). */
-var reIsHostCtor = /^\[object .+?Constructor\]$/;
-
-/** Used for built-in method references. */
-var funcProto = Function.prototype,
-    objectProto = Object.prototype;
-
-/** Used to resolve the decompiled source of functions. */
-var funcToString = funcProto.toString;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/** Used to detect if a method is native. */
-var reIsNative = RegExp('^' +
-  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
-  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
-);
-
+exports.after = after;
+/* eslint-enable jsdoc/check-param-names*/
 /**
- * The base implementation of `_.isNative` without bad shim checks.
+ * Insert every element in the set of matched elements after the target.
  *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a native function,
- *  else `false`.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('<li class="plum">Plum</li>').insertAfter('.apple');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="apple">Apple</li>
+ * //      <li class="plum">Plum</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //    </ul>
+ * ```
+ *
+ * @param target - Element to insert elements after.
+ * @returns The set of newly inserted elements.
+ * @see {@link https://api.jquery.com/insertAfter/}
  */
-function baseIsNative(value) {
-  if (!isObject(value) || isMasked(value)) {
-    return false;
-  }
-  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
-  return pattern.test(toSource(value));
+function insertAfter(target) {
+    var _this = this;
+    if (typeof target === 'string') {
+        target = this._make(target);
+    }
+    this.remove();
+    var clones = [];
+    this._makeDomArray(target).forEach(function (el) {
+        var clonedSelf = _this.clone().toArray();
+        var parent = el.parent;
+        if (!parent) {
+            return;
+        }
+        var siblings = parent.children;
+        var index = siblings.indexOf(el);
+        // If not found, move on
+        /* istanbul ignore next */
+        if (index < 0)
+            return;
+        // Add cloned `this` element(s) after target element
+        uniqueSplice(siblings, index + 1, 0, clonedSelf, parent);
+        clones.push.apply(clones, clonedSelf);
+    });
+    return this._make(clones);
 }
-
-module.exports = baseIsNative;
-
-
-/***/ }),
-/* 373 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var coreJsData = __webpack_require__(374);
-
-/** Used to detect methods masquerading as native. */
-var maskSrcKey = (function() {
-  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
-  return uid ? ('Symbol(src)_1.' + uid) : '';
-}());
-
+exports.insertAfter = insertAfter;
+/* eslint-disable jsdoc/check-param-names*/
 /**
- * Checks if `func` has its source masked.
+ * Insert content previous to each element in the set of matched elements.
  *
- * @private
- * @param {Function} func The function to check.
- * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('.apple').before('<li class="plum">Plum</li>');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="plum">Plum</li>
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //    </ul>
+ * ```
+ *
+ * @param content - HTML string, DOM element, array of DOM elements or Cheerio
+ *   to insert before each element in the set of matched elements.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/before/}
  */
-function isMasked(func) {
-  return !!maskSrcKey && (maskSrcKey in func);
+function before() {
+    var _this = this;
+    var elems = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        elems[_i] = arguments[_i];
+    }
+    var lastIdx = this.length - 1;
+    return utils_1.domEach(this, function (el, i) {
+        var parent = el.parent;
+        if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) {
+            return;
+        }
+        var siblings = parent.children;
+        var index = siblings.indexOf(el);
+        // If not found, move on
+        /* istanbul ignore next */
+        if (index < 0)
+            return;
+        var domSrc = typeof elems[0] === 'function'
+            ? elems[0].call(el, i, static_1.html(el.children))
+            : elems;
+        var dom = _this._makeDomArray(domSrc, i < lastIdx);
+        // Add element before `el` element
+        uniqueSplice(siblings, index, 0, dom, parent);
+    });
 }
-
-module.exports = isMasked;
-
-
-/***/ }),
-/* 374 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var root = __webpack_require__(48);
-
-/** Used to detect overreaching core-js shims. */
-var coreJsData = root['__core-js_shared__'];
-
-module.exports = coreJsData;
-
-
-/***/ }),
-/* 375 */
-/***/ ((module) => {
-
-/** Used for built-in method references. */
-var funcProto = Function.prototype;
-
-/** Used to resolve the decompiled source of functions. */
-var funcToString = funcProto.toString;
-
+exports.before = before;
+/* eslint-enable jsdoc/check-param-names*/
 /**
- * Converts `func` to its source code.
+ * Insert every element in the set of matched elements before the target.
  *
- * @private
- * @param {Function} func The function to convert.
- * @returns {string} Returns the source code.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('<li class="plum">Plum</li>').insertBefore('.apple');
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="plum">Plum</li>
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //      <li class="pear">Pear</li>
+ * //    </ul>
+ * ```
+ *
+ * @param target - Element to insert elements before.
+ * @returns The set of newly inserted elements.
+ * @see {@link https://api.jquery.com/insertBefore/}
  */
-function toSource(func) {
-  if (func != null) {
-    try {
-      return funcToString.call(func);
-    } catch (e) {}
-    try {
-      return (func + '');
-    } catch (e) {}
-  }
-  return '';
+function insertBefore(target) {
+    var _this = this;
+    var targetArr = this._make(target);
+    this.remove();
+    var clones = [];
+    utils_1.domEach(targetArr, function (el) {
+        var clonedSelf = _this.clone().toArray();
+        var parent = el.parent;
+        if (!parent) {
+            return;
+        }
+        var siblings = parent.children;
+        var index = siblings.indexOf(el);
+        // If not found, move on
+        /* istanbul ignore next */
+        if (index < 0)
+            return;
+        // Add cloned `this` element(s) after target element
+        uniqueSplice(siblings, index, 0, clonedSelf, parent);
+        clones.push.apply(clones, clonedSelf);
+    });
+    return this._make(clones);
 }
-
-module.exports = toSource;
-
-
-/***/ }),
-/* 376 */
-/***/ ((module) => {
-
+exports.insertBefore = insertBefore;
 /**
- * Gets the value at `key` of `object`.
+ * Removes the set of matched elements from the DOM and all their children.
+ * `selector` filters the set of matched elements to be removed.
  *
- * @private
- * @param {Object} [object] The object to query.
- * @param {string} key The key of the property to get.
- * @returns {*} Returns the property value.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('.pear').remove();
+ * $.html();
+ * //=>  <ul id="fruits">
+ * //      <li class="apple">Apple</li>
+ * //      <li class="orange">Orange</li>
+ * //    </ul>
+ * ```
+ *
+ * @param selector - Optional selector for elements to remove.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/remove/}
  */
-function getValue(object, key) {
-  return object == null ? undefined : object[key];
+function remove(selector) {
+    // Filter if we have selector
+    var elems = selector ? this.filter(selector) : this;
+    utils_1.domEach(elems, function (el) {
+        htmlparser2_1.DomUtils.removeElement(el);
+        el.prev = el.next = el.parent = null;
+    });
+    return this;
 }
-
-module.exports = getValue;
-
-
-/***/ }),
-/* 377 */
-/***/ ((module) => {
-
+exports.remove = remove;
 /**
- * Removes `key` and its value from the hash.
+ * Replaces matched elements with `content`.
  *
- * @private
- * @name delete
- * @memberOf Hash
- * @param {Object} hash The hash to modify.
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * const plum = $('<li class="plum">Plum</li>');
+ * $('.pear').replaceWith(plum);
+ * $.html();
+ * //=> <ul id="fruits">
+ * //     <li class="apple">Apple</li>
+ * //     <li class="orange">Orange</li>
+ * //     <li class="plum">Plum</li>
+ * //   </ul>
+ * ```
+ *
+ * @param content - Replacement for matched elements.
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/replaceWith/}
  */
-function hashDelete(key) {
-  var result = this.has(key) && delete this.__data__[key];
-  this.size -= result ? 1 : 0;
-  return result;
+function replaceWith(content) {
+    var _this = this;
+    return utils_1.domEach(this, function (el, i) {
+        var parent = el.parent;
+        if (!parent) {
+            return;
+        }
+        var siblings = parent.children;
+        var cont = typeof content === 'function' ? content.call(el, i, el) : content;
+        var dom = _this._makeDomArray(cont);
+        /*
+         * In the case that `dom` contains nodes that already exist in other
+         * structures, ensure those nodes are properly removed.
+         */
+        parse_1.update(dom, null);
+        var index = siblings.indexOf(el);
+        // Completely remove old element
+        uniqueSplice(siblings, index, 1, dom, parent);
+        if (!dom.includes(el)) {
+            el.parent = el.prev = el.next = null;
+        }
+    });
 }
-
-module.exports = hashDelete;
-
-
-/***/ }),
-/* 378 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var nativeCreate = __webpack_require__(370);
-
-/** Used to stand-in for `undefined` hash values. */
-var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
+exports.replaceWith = replaceWith;
 /**
- * Gets the hash value for `key`.
+ * Empties an element, removing all its children.
  *
- * @private
- * @name get
- * @memberOf Hash
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * $('ul').empty();
+ * $.html();
+ * //=>  <ul id="fruits"></ul>
+ * ```
+ *
+ * @returns The instance itself.
+ * @see {@link https://api.jquery.com/empty/}
  */
-function hashGet(key) {
-  var data = this.__data__;
-  if (nativeCreate) {
-    var result = data[key];
-    return result === HASH_UNDEFINED ? undefined : result;
-  }
-  return hasOwnProperty.call(data, key) ? data[key] : undefined;
+function empty() {
+    return utils_1.domEach(this, function (el) {
+        if (!htmlparser2_1.DomUtils.hasChildren(el))
+            return;
+        el.children.forEach(function (child) {
+            child.next = child.prev = child.parent = null;
+        });
+        el.children.length = 0;
+    });
 }
-
-module.exports = hashGet;
-
-
-/***/ }),
-/* 379 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var nativeCreate = __webpack_require__(370);
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
+exports.empty = empty;
+function html(str) {
+    if (str === undefined) {
+        var el = this[0];
+        if (!el || !htmlparser2_1.DomUtils.hasChildren(el))
+            return null;
+        return static_1.html(el.children, this.options);
+    }
+    // Keep main options unchanged
+    var opts = tslib_1.__assign(tslib_1.__assign({}, this.options), { context: null });
+    return utils_1.domEach(this, function (el) {
+        if (!htmlparser2_1.DomUtils.hasChildren(el))
+            return;
+        el.children.forEach(function (child) {
+            child.next = child.prev = child.parent = null;
+        });
+        opts.context = el;
+        var content = utils_1.isCheerio(str)
+            ? str.toArray()
+            : parse_1.default("" + str, opts, false).children;
+        parse_1.update(content, el);
+    });
+}
+exports.html = html;
 /**
- * Checks if a hash value for `key` exists.
+ * Turns the collection to a string. Alias for `.html()`.
  *
- * @private
- * @name has
- * @memberOf Hash
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ * @category Manipulation
+ * @returns The rendered document.
  */
-function hashHas(key) {
-  var data = this.__data__;
-  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
+function toString() {
+    return static_1.html(this, this.options);
 }
-
-module.exports = hashHas;
-
-
-/***/ }),
-/* 380 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var nativeCreate = __webpack_require__(370);
-
-/** Used to stand-in for `undefined` hash values. */
-var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
+exports.toString = toString;
+function text(str) {
+    var _this = this;
+    // If `str` is undefined, act as a "getter"
+    if (str === undefined) {
+        return static_1.text(this);
+    }
+    if (typeof str === 'function') {
+        // Function support
+        return utils_1.domEach(this, function (el, i) {
+            text.call(_this._make(el), str.call(el, i, static_1.text([el])));
+        });
+    }
+    // Append text node to each selected elements
+    return utils_1.domEach(this, function (el) {
+        if (!htmlparser2_1.DomUtils.hasChildren(el))
+            return;
+        el.children.forEach(function (child) {
+            child.next = child.prev = child.parent = null;
+        });
+        var textNode = new domhandler_2.Text(str);
+        parse_1.update(textNode, el);
+    });
+}
+exports.text = text;
 /**
- * Sets the hash `key` to `value`.
+ * Clone the cheerio object.
  *
- * @private
- * @name set
- * @memberOf Hash
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the hash instance.
+ * @category Manipulation
+ * @example
+ *
+ * ```js
+ * const moreFruit = $('#fruits').clone();
+ * ```
+ *
+ * @returns The cloned object.
+ * @see {@link https://api.jquery.com/clone/}
  */
-function hashSet(key, value) {
-  var data = this.__data__;
-  this.size += this.has(key) ? 0 : 1;
-  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
-  return this;
+function clone() {
+    return this._make(utils_1.cloneDom(this.get()));
 }
-
-module.exports = hashSet;
+exports.clone = clone;
 
 
 /***/ }),
-/* 381 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 351 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var listCacheClear = __webpack_require__(382),
-    listCacheDelete = __webpack_require__(383),
-    listCacheGet = __webpack_require__(386),
-    listCacheHas = __webpack_require__(387),
-    listCacheSet = __webpack_require__(388);
+"use strict";
 
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.css = void 0;
+var utils_1 = __webpack_require__(347);
+function css(prop, val) {
+    if ((prop != null && val != null) ||
+        // When `prop` is a "plain" object
+        (typeof prop === 'object' && !Array.isArray(prop))) {
+        return utils_1.domEach(this, function (el, i) {
+            if (utils_1.isTag(el)) {
+                // `prop` can't be an array here anymore.
+                setCss(el, prop, val, i);
+            }
+        });
+    }
+    return getCss(this[0], prop);
+}
+exports.css = css;
 /**
- * Creates an list cache object.
+ * Set styles of all elements.
  *
  * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
+ * @param el - Element to set style of.
+ * @param prop - Name of property.
+ * @param value - Value to set property to.
+ * @param idx - Optional index within the selection.
  */
-function ListCache(entries) {
-  var index = -1,
-      length = entries == null ? 0 : entries.length;
-
-  this.clear();
-  while (++index < length) {
-    var entry = entries[index];
-    this.set(entry[0], entry[1]);
-  }
+function setCss(el, prop, value, idx) {
+    if (typeof prop === 'string') {
+        var styles = getCss(el);
+        var val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value;
+        if (val === '') {
+            delete styles[prop];
+        }
+        else if (val != null) {
+            styles[prop] = val;
+        }
+        el.attribs.style = stringify(styles);
+    }
+    else if (typeof prop === 'object') {
+        Object.keys(prop).forEach(function (k, i) {
+            setCss(el, k, prop[k], i);
+        });
+    }
+}
+function getCss(el, prop) {
+    if (!el || !utils_1.isTag(el))
+        return;
+    var styles = parse(el.attribs.style);
+    if (typeof prop === 'string') {
+        return styles[prop];
+    }
+    if (Array.isArray(prop)) {
+        var newStyles_1 = {};
+        prop.forEach(function (item) {
+            if (styles[item] != null) {
+                newStyles_1[item] = styles[item];
+            }
+        });
+        return newStyles_1;
+    }
+    return styles;
 }
-
-// Add methods to `ListCache`.
-ListCache.prototype.clear = listCacheClear;
-ListCache.prototype['delete'] = listCacheDelete;
-ListCache.prototype.get = listCacheGet;
-ListCache.prototype.has = listCacheHas;
-ListCache.prototype.set = listCacheSet;
-
-module.exports = ListCache;
-
-
-/***/ }),
-/* 382 */
-/***/ ((module) => {
-
 /**
- * Removes all key-value entries from the list cache.
+ * Stringify `obj` to styles.
  *
  * @private
- * @name clear
- * @memberOf ListCache
+ * @category CSS
+ * @param obj - Object to stringify.
+ * @returns The serialized styles.
  */
-function listCacheClear() {
-  this.__data__ = [];
-  this.size = 0;
+function stringify(obj) {
+    return Object.keys(obj).reduce(function (str, prop) { return "" + str + (str ? ' ' : '') + prop + ": " + obj[prop] + ";"; }, '');
 }
-
-module.exports = listCacheClear;
-
-
-/***/ }),
-/* 383 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var assocIndexOf = __webpack_require__(384);
-
-/** Used for built-in method references. */
-var arrayProto = Array.prototype;
-
-/** Built-in value references. */
-var splice = arrayProto.splice;
-
 /**
- * Removes `key` and its value from the list cache.
+ * Parse `styles`.
  *
  * @private
- * @name delete
- * @memberOf ListCache
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ * @category CSS
+ * @param styles - Styles to be parsed.
+ * @returns The parsed styles.
  */
-function listCacheDelete(key) {
-  var data = this.__data__,
-      index = assocIndexOf(data, key);
-
-  if (index < 0) {
-    return false;
-  }
-  var lastIndex = data.length - 1;
-  if (index == lastIndex) {
-    data.pop();
-  } else {
-    splice.call(data, index, 1);
-  }
-  --this.size;
-  return true;
+function parse(styles) {
+    styles = (styles || '').trim();
+    if (!styles)
+        return {};
+    return styles.split(';').reduce(function (obj, str) {
+        var n = str.indexOf(':');
+        // Skip if there is no :, or if it is the first/last character
+        if (n < 1 || n === str.length - 1)
+            return obj;
+        obj[str.slice(0, n).trim()] = str.slice(n + 1).trim();
+        return obj;
+    }, {});
 }
 
-module.exports = listCacheDelete;
-
 
 /***/ }),
-/* 384 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 352 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var eq = __webpack_require__(385);
+"use strict";
 
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.serializeArray = exports.serialize = void 0;
+var utils_1 = __webpack_require__(347);
+/*
+ * https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
+ * https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
+ */
+var submittableSelector = 'input,select,textarea,keygen';
+var r20 = /%20/g;
+var rCRLF = /\r?\n/g;
 /**
- * Gets the index at which the `key` is found in `array` of key-value pairs.
+ * Encode a set of form elements as a string for submission.
  *
- * @private
- * @param {Array} array The array to inspect.
- * @param {*} key The key to search for.
- * @returns {number} Returns the index of the matched value, else `-1`.
+ * @category Forms
+ * @returns The serialized form.
+ * @see {@link https://api.jquery.com/serialize/}
  */
-function assocIndexOf(array, key) {
-  var length = array.length;
-  while (length--) {
-    if (eq(array[length][0], key)) {
-      return length;
-    }
-  }
-  return -1;
+function serialize() {
+    // Convert form elements into name/value objects
+    var arr = this.serializeArray();
+    // Serialize each element into a key/value string
+    var retArr = arr.map(function (data) {
+        return encodeURIComponent(data.name) + "=" + encodeURIComponent(data.value);
+    });
+    // Return the resulting serialization
+    return retArr.join('&').replace(r20, '+');
 }
-
-module.exports = assocIndexOf;
-
-
-/***/ }),
-/* 385 */
-/***/ ((module) => {
-
+exports.serialize = serialize;
 /**
- * Performs a
- * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * comparison between two values to determine if they are equivalent.
+ * Encode a set of form elements as an array of names and values.
  *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @category Forms
  * @example
  *
- * var object = { 'a': 1 };
- * var other = { 'a': 1 };
- *
- * _.eq(object, object);
- * // => true
- *
- * _.eq(object, other);
- * // => false
- *
- * _.eq('a', 'a');
- * // => true
- *
- * _.eq('a', Object('a'));
- * // => false
+ * ```js
+ * $('<form><input name="foo" value="bar" /></form>').serializeArray();
+ * //=> [ { name: 'foo', value: 'bar' } ]
+ * ```
  *
- * _.eq(NaN, NaN);
- * // => true
+ * @returns The serialized form.
+ * @see {@link https://api.jquery.com/serializeArray/}
  */
-function eq(value, other) {
-  return value === other || (value !== value && other !== other);
+function serializeArray() {
+    var _this = this;
+    // Resolve all form elements from either forms or collections of form elements
+    return this.map(function (_, elem) {
+        var $elem = _this._make(elem);
+        if (utils_1.isTag(elem) && elem.name === 'form') {
+            return $elem.find(submittableSelector).toArray();
+        }
+        return $elem.filter(submittableSelector).toArray();
+    })
+        .filter(
+    // Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
+    '[name!=""]:enabled' +
+        // And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)
+        ':not(:submit, :button, :image, :reset, :file)' +
+        // And are either checked/don't have a checkable state
+        ':matches([checked], :not(:checkbox, :radio))'
+    // Convert each of the elements to its value(s)
+    )
+        .map(function (_, elem) {
+        var _a;
+        var $elem = _this._make(elem);
+        var name = $elem.attr('name'); // We have filtered for elements with a name before.
+        // If there is no value set (e.g. `undefined`, `null`), then default value to empty
+        var value = (_a = $elem.val()) !== null && _a !== void 0 ? _a : '';
+        // If we have an array of values (e.g. `<select multiple>`), return an array of key/value pairs
+        if (Array.isArray(value)) {
+            return value.map(function (val) {
+                /*
+                 * We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms
+                 * These can occur inside of `<textarea>'s`
+                 */
+                return ({ name: name, value: val.replace(rCRLF, '\r\n') });
+            });
+        }
+        // Otherwise (e.g. `<input type="text">`, return only one key/value pair
+        return { name: name, value: value.replace(rCRLF, '\r\n') };
+    })
+        .toArray();
 }
-
-module.exports = eq;
+exports.serializeArray = serializeArray;
 
 
 /***/ }),
-/* 386 */
+/* 353 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var assocIndexOf = __webpack_require__(384);
-
 /**
- * Gets the list cache value for `key`.
+ * Filters the passed array from data already present in the cozy so that there is
+ * not duplicated data in the Cozy.
  *
- * @private
- * @name get
- * @memberOf ListCache
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
+ * @module hydrateAndFilter
  */
-function listCacheGet(key) {
-  var data = this.__data__,
-      index = assocIndexOf(data, key);
-
-  return index < 0 ? undefined : data[index][1];
-}
-
-module.exports = listCacheGet;
+const bluebird = __webpack_require__(5);
 
+const log = (__webpack_require__(354).namespace)('hydrateAndFilter');
 
-/***/ }),
-/* 387 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+const get = __webpack_require__(370);
 
-var assocIndexOf = __webpack_require__(384);
+const uniqBy = __webpack_require__(412);
 
+const {
+  queryAll
+} = __webpack_require__(484);
 /**
- * Checks if a list cache value for `key` exists.
+ * Since we can use methods or basic functions for
+ * `shouldSave` and `shouldUpdate` we pass the
+ * appropriate `this` and `arguments`.
  *
- * @private
- * @name has
- * @memberOf ListCache
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ * If `funcOrMethod` is a method, it will be called
+ * with args[0] as `this` and the rest as `arguments`
+ * Otherwise, `this` will be null and `args` will be passed
+ * as `arguments`.
  */
-function listCacheHas(key) {
-  return assocIndexOf(this.__data__, key) > -1;
-}
-
-module.exports = listCacheHas;
-
-
-/***/ }),
-/* 388 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var assocIndexOf = __webpack_require__(384);
 
-/**
- * Sets the list cache `key` to `value`.
- *
- * @private
- * @name set
- * @memberOf ListCache
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the list cache instance.
- */
-function listCacheSet(key, value) {
-  var data = this.__data__,
-      index = assocIndexOf(data, key);
+const suitableCall = (funcOrMethod, ...args) => {
+  const arity = funcOrMethod.length;
 
-  if (index < 0) {
-    ++this.size;
-    data.push([key, value]);
+  if (arity < args.length) {
+    // must be a method
+    return funcOrMethod.apply(args[0], args.slice(1));
   } else {
-    data[index][1] = value;
+    // must be a function
+    return funcOrMethod.apply(null, args);
   }
-  return this;
-}
-
-module.exports = listCacheSet;
-
-
-/***/ }),
-/* 389 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var getNative = __webpack_require__(371),
-    root = __webpack_require__(48);
-
-/* Built-in method references that are verified to be native. */
-var Map = getNative(root, 'Map');
-
-module.exports = Map;
-
-
-/***/ }),
-/* 390 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var getMapData = __webpack_require__(391);
-
+};
 /**
- * Removes `key` and its value from the map.
+ * Filters the passed array from data already present in the cozy so that there is
+ * not duplicated data in the Cozy.
  *
- * @private
- * @name delete
- * @memberOf MapCache
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
- */
-function mapCacheDelete(key) {
-  var result = getMapData(this, key)['delete'](key);
-  this.size -= result ? 1 : 0;
-  return result;
-}
-
-module.exports = mapCacheDelete;
-
-
-/***/ }),
-/* 391 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var isKeyable = __webpack_require__(392);
-
-/**
- * Gets the data for `map`.
+ * You need at least the `GET` permission for the given doctype in your manifest, to be able to
+ * use this function.
  *
- * @private
- * @param {Object} map The map to query.
- * @param {string} key The reference key.
- * @returns {*} Returns the map data.
- */
-function getMapData(map, key) {
-  var data = map.__data__;
-  return isKeyable(key)
-    ? data[typeof key == 'string' ? 'string' : 'hash']
-    : data.map;
-}
-
-module.exports = getMapData;
-
-
-/***/ }),
-/* 392 */
-/***/ ((module) => {
-
-/**
- * Checks if `value` is suitable for use as unique object key.
+ * Parameters:
  *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
- */
-function isKeyable(value) {
-  var type = typeof value;
-  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
-    ? (value !== '__proto__')
-    : (value === null);
-}
+ * `documents`: an array of objects corresponding to the data you want to save in the cozy
+ * `doctype` (string): the doctype where you want to save data (ex: 'io.cozy.bills')
+ * `options` :
+ *    - `keys` (array) : List of keys used to check that two items are the same. By default it is set to `['id']'.
+ *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
+ *    - `selector` (optionnal object) : Mango request to get records. Default is built from the keys `{selector: {_id: {"$gt": null}}}` to get all the records.
+ *
+ * ```javascript
+ * const documents = [
+ *   {
+ *     name: 'toto',
+ *     height: 1.8
+ *   },
+ *   {
+ *     name: 'titi',
+ *     height: 1.7
+ *   }
+ * ]
+ *
+ * return hydrateAndFilter(documents, 'io.cozy.height', {
+ *   keys: ['name']
+ * }).then(filteredDocuments => addData(filteredDocuments, 'io.cozy.height'))
+ *
+ * ```
+ *
+ * @alias module:hydrateAndFilter
+ */
 
-module.exports = isKeyable;
 
+const hydrateAndFilter = (documents = [], doctype, options = {}) => {
+  const cozy = __webpack_require__(485);
 
-/***/ }),
-/* 393 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  log('debug', `${documents.length} items before hydrateAndFilter`);
+  if (!doctype) return Promise.reject(new Error(`Doctype is mandatory to filter the connector data.`));
+  const keys = options.keys ? options.keys : ['_id'];
+  const store = {};
 
-var getMapData = __webpack_require__(391);
+  const createHash = item => {
+    return keys.map(key => {
+      let result = get(item, key);
+      if (key === 'date') result = new Date(result);
+      return result;
+    }).join('####');
+  };
 
-/**
- * Gets the map value for `key`.
- *
- * @private
- * @name get
- * @memberOf MapCache
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
- */
-function mapCacheGet(key) {
-  return getMapData(this, key).get(key);
-}
+  const getIndex = () => {
+    const index = options.index ? Promise.resolve(options.index) : cozy.data.defineIndex(doctype, keys);
+    return index;
+  };
 
-module.exports = mapCacheGet;
+  const getItems = async index => {
+    const selector = options.selector ? options.selector : null;
+    return await queryAll(doctype, selector, index);
+  };
 
+  const populateStore = store => dbitems => {
+    dbitems.forEach(dbitem => {
+      store[createHash(dbitem)] = dbitem;
+    });
+  }; // We add _id to `documents` that we find in the database.
+  // This is useful when linking with bank operations (a bill
+  // can already be in the database but not already matched
+  // to an operation) since the linking operation need the _id
+  // of the document
 
-/***/ }),
-/* 394 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var getMapData = __webpack_require__(391);
+  const hydrateExistingEntries = store => () => {
+    documents.forEach(document => {
+      const key = createHash(document);
 
-/**
- * Checks if a map value for `key` exists.
- *
- * @private
- * @name has
- * @memberOf MapCache
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
- */
-function mapCacheHas(key) {
-  return getMapData(this, key).has(key);
-}
+      if (store[key]) {
+        document._id = store[key]._id;
+        document._rev = store[key]._rev;
+        if (!document.cozyMetadata && store[key].cozyMetadata) document.cozyMetadata = store[key].cozyMetadata;
+      }
+    });
+    return documents;
+  };
 
-module.exports = mapCacheHas;
+  const defaultShouldSave = () => true;
 
+  const defaultShouldUpdate = existing => false; // eslint-disable-line no-unused-vars
 
-/***/ }),
-/* 395 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var getMapData = __webpack_require__(391);
+  const filterEntries = store => async () => {
+    // Filter out items according to shouldSave / shouldUpdate.
+    // Both can be passed as option or can be part of the entry.
+    return uniqBy(await bluebird.filter(documents, entry => {
+      const shouldSave = entry.shouldSave || options.shouldSave || defaultShouldSave;
+      const shouldUpdate = entry.shouldUpdate || options.shouldUpdate || defaultShouldUpdate;
+      const existing = store[createHash(entry)];
 
-/**
- * Sets the map `key` to `value`.
- *
- * @private
- * @name set
- * @memberOf MapCache
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the map cache instance.
- */
-function mapCacheSet(key, value) {
-  var data = getMapData(this, key),
-      size = data.size;
+      if (existing) {
+        return suitableCall(shouldUpdate, entry, existing);
+      } else {
+        return suitableCall(shouldSave, entry);
+      }
+    }), entry => entry && entry._id || entry);
+  };
 
-  data.set(key, value);
-  this.size += data.size == size ? 0 : 1;
-  return this;
-}
+  const formatOutput = entries => {
+    log('debug', `${entries.length} items after hydrateAndFilter`);
+    return entries;
+  };
 
-module.exports = mapCacheSet;
+  return getIndex().then(getItems).then(populateStore(store)).then(hydrateExistingEntries(store)).then(filterEntries(store)).then(entries => entries.filter(Boolean)) // Filter out wrong entries
+  .then(formatOutput);
+};
 
+module.exports = hydrateAndFilter;
 
 /***/ }),
-/* 396 */
+/* 354 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseToString = __webpack_require__(397);
+const { filterLevel, filterSecrets } = __webpack_require__(355)
+const Secret = __webpack_require__(356)
+const { LOG_LEVEL } = process.env
+let level = LOG_LEVEL || 'debug'
+const format = __webpack_require__(357)
+const filters = [filterLevel, filterSecrets]
+
+const filterOut = function () {
+  for (const filter of filters) {
+    if (filter.apply(null, arguments) === false) {
+      return true
+    }
+  }
+  return false
+}
 
 /**
- * Converts `value` to a string. An empty string is returned for `null`
- * and `undefined` values. The sign of `-0` is preserved.
+ * Use it to log messages in your konnector. Typical types are
  *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {string} Returns the converted string.
- * @example
+ * - `debug`
+ * - `warning`
+ * - `info`
+ * - `error`
+ * - `ok`
  *
- * _.toString(null);
- * // => ''
  *
- * _.toString(-0);
- * // => '-0'
+ * @example
  *
- * _.toString([1, 2, 3]);
- * // => '1,2,3'
+ * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector.
+ *
+ * ```js
+ * logger = log('my-namespace')
+ * logger('debug', '365 bills')
+ * // my-namespace : debug : 365 bills
+ * logger('info', 'Page fetched')
+ * // my-namespace : info : Page fetched
+ * ```
+ * @param  {string} type
+ * @param  {string} message
+ * @param  {string} label
+ * @param  {string} namespace
  */
-function toString(value) {
-  return value == null ? '' : baseToString(value);
+function log(type, message, label, namespace) {
+  if (filterOut(level, type, message, label, namespace)) {
+    return
+  }
+  // eslint-disable-next-line no-console
+  console.log(format(type, message, label, namespace))
 }
 
-module.exports = toString;
-
-
-/***/ }),
-/* 397 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+log.addFilter = function (filter) {
+  return filters.push(filter)
+}
 
-var Symbol = __webpack_require__(47),
-    arrayMap = __webpack_require__(398),
-    isArray = __webpack_require__(55),
-    isSymbol = __webpack_require__(362);
+log.setLevel = function (lvl) {
+  level = lvl
+}
 
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0;
+// Short-hands
+const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical']
+methods.forEach(level => {
+  log[level] = function (message, label, namespace) {
+    return log(level, message, label, namespace)
+  }
+})
 
-/** Used to convert symbols to primitives and strings. */
-var symbolProto = Symbol ? Symbol.prototype : undefined,
-    symbolToString = symbolProto ? symbolProto.toString : undefined;
+module.exports = log
 
-/**
- * The base implementation of `_.toString` which doesn't convert nullish
- * values to empty strings.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- */
-function baseToString(value) {
-  // Exit early for strings to avoid a performance hit in some environments.
-  if (typeof value == 'string') {
-    return value;
-  }
-  if (isArray(value)) {
-    // Recursively convert values (susceptible to call stack limits).
-    return arrayMap(value, baseToString) + '';
-  }
-  if (isSymbol(value)) {
-    return symbolToString ? symbolToString.call(value) : '';
+log.setNoRetry = obj => {
+  if (obj) obj.no_retry = true
+  else obj = { no_retry: true }
+  return obj.no_retry
+}
+log.Secret = Secret
+log.namespace = function (namespace) {
+  return function (type, message, label, ns = namespace) {
+    log(type, message, label, ns)
   }
-  var result = (value + '');
-  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
 }
 
-module.exports = baseToString;
-
 
 /***/ }),
-/* 398 */
-/***/ ((module) => {
+/* 355 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/**
- * A specialized version of `_.map` for arrays without support for iteratee
- * shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the new mapped array.
- */
-function arrayMap(array, iteratee) {
-  var index = -1,
-      length = array == null ? 0 : array.length,
-      result = Array(length);
+const levels = {
+  secret: 0,
+  debug: 10,
+  info: 20,
+  warn: 30,
+  error: 40,
+  ok: 50,
+  critical: 50
+}
 
-  while (++index < length) {
-    result[index] = iteratee(array[index], index, array);
+const Secret = __webpack_require__(356)
+
+const filterSecrets = function (level, type, message) {
+  if (type !== 'secret' && message instanceof Secret) {
+    throw new Error('You should log a secret with log.secret')
   }
-  return result;
 }
 
-module.exports = arrayMap;
+const filterLevel = function (level, type) {
+  return levels[type] >= levels[level]
+}
 
+module.exports = {
+  filterSecrets,
+  filterLevel
+}
 
-/***/ }),
-/* 399 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var isSymbol = __webpack_require__(362);
+/***/ }),
+/* 356 */
+/***/ ((module) => {
 
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0;
+const Secret = function (data) {
+  Object.assign(this, data)
+  return this
+}
 
-/**
- * Converts `value` to a string key if it's not a string or symbol.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {string|symbol} Returns the key.
- */
-function toKey(value) {
-  if (typeof value == 'string' || isSymbol(value)) {
-    return value;
-  }
-  var result = (value + '');
-  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+Secret.prototype.toString = function () {
+  throw new Error('Cannot convert Secret to string')
 }
 
-module.exports = toKey;
+module.exports = Secret
 
 
 /***/ }),
-/* 400 */
+/* 357 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIteratee = __webpack_require__(401),
-    baseUniq = __webpack_require__(463);
+const prodFormat = __webpack_require__(358)
+const devFormat = __webpack_require__(359)
 
-/**
- * This method is like `_.uniq` except that it accepts `iteratee` which is
- * invoked for each element in `array` to generate the criterion by which
- * uniqueness is computed. The order of result values is determined by the
- * order they occur in the array. The iteratee is invoked with one argument:
- * (value).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Array
- * @param {Array} array The array to inspect.
- * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
- * @returns {Array} Returns the new duplicate free array.
- * @example
- *
- * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
- * // => [2.1, 1.2]
- *
- * // The `_.property` iteratee shorthand.
- * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
-function uniqBy(array, iteratee) {
-  return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];
+switch (process.env.NODE_ENV) {
+  case 'production':
+    module.exports = prodFormat
+    break
+  case 'development':
+    module.exports = devFormat
+    break
+  case 'standalone':
+    module.exports = devFormat
+    break
+  case 'test':
+    module.exports = devFormat
+    break
+  default:
+    module.exports = prodFormat
 }
 
-module.exports = uniqBy;
-
 
 /***/ }),
-/* 401 */
+/* 358 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseMatches = __webpack_require__(402),
-    baseMatchesProperty = __webpack_require__(455),
-    identity = __webpack_require__(459),
-    isArray = __webpack_require__(55),
-    property = __webpack_require__(460);
+const stringify = __webpack_require__(75)
 
-/**
- * The base implementation of `_.iteratee`.
- *
- * @private
- * @param {*} [value=_.identity] The value to convert to an iteratee.
- * @returns {Function} Returns the iteratee.
- */
-function baseIteratee(value) {
-  // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
-  // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
-  if (typeof value == 'function') {
-    return value;
+const LOG_LENGTH_LIMIT = 64 * 1024 - 1
+
+function prodFormat(type, message, label, namespace) {
+  const log = { time: new Date(), type, label, namespace }
+
+  if (typeof message === 'object') {
+    if (message && message.no_retry) {
+      log.no_retry = message.no_retry
+    }
+    if (message && message.message) {
+      log.message = message.message
+    }
+  } else {
+    log.message = message
   }
-  if (value == null) {
-    return identity;
+
+  // properly display error messages
+  if (log.message && log.message.stack) {
+    log.message = log.message.stack
   }
-  if (typeof value == 'object') {
-    return isArray(value)
-      ? baseMatchesProperty(value[0], value[1])
-      : baseMatches(value);
+
+  // cut the string to avoid a fail in the stack
+  let result = log
+  try {
+    result = stringify(log).substr(0, LOG_LENGTH_LIMIT)
+  } catch (err) {
+    // eslint-disable-next-line no-console
+    console.log(err.message, 'cozy-logger: Failed to convert message to JSON')
   }
-  return property(value);
+  return result
 }
 
-module.exports = baseIteratee;
+module.exports = prodFormat
 
 
 /***/ }),
-/* 402 */
+/* 359 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIsMatch = __webpack_require__(403),
-    getMatchData = __webpack_require__(452),
-    matchesStrictComparable = __webpack_require__(454);
+const util = __webpack_require__(64)
+const chalk = __webpack_require__(360)
 
-/**
- * The base implementation of `_.matches` which doesn't clone `source`.
- *
- * @private
- * @param {Object} source The object of property values to match.
- * @returns {Function} Returns the new spec function.
- */
-function baseMatches(source) {
-  var matchData = getMatchData(source);
-  if (matchData.length == 1 && matchData[0][2]) {
-    return matchesStrictComparable(matchData[0][0], matchData[0][1]);
-  }
-  return function(object) {
-    return object === source || baseIsMatch(object, source, matchData);
-  };
+if (util && util.inspect && util.inspect.defaultOptions) {
+  util.inspect.defaultOptions.maxArrayLength = null
+  util.inspect.defaultOptions.depth = 2
+  util.inspect.defaultOptions.colors = true
 }
 
-module.exports = baseMatches;
-
-
-/***/ }),
-/* 403 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+const type2color = {
+  debug: 'cyan',
+  warn: 'yellow',
+  info: 'blue',
+  error: 'red',
+  ok: 'green',
+  secret: 'red',
+  critical: 'red'
+}
 
-var Stack = __webpack_require__(404),
-    baseIsEqual = __webpack_require__(410);
+function devFormat(type, message, label, namespace) {
+  let formatmessage = message
 
-/** Used to compose bitmasks for value comparisons. */
-var COMPARE_PARTIAL_FLAG = 1,
-    COMPARE_UNORDERED_FLAG = 2;
+  if (typeof formatmessage !== 'string') {
+    formatmessage = util.inspect(formatmessage)
+  }
 
-/**
- * The base implementation of `_.isMatch` without support for iteratee shorthands.
- *
- * @private
- * @param {Object} object The object to inspect.
- * @param {Object} source The object of property values to match.
- * @param {Array} matchData The property names, values, and compare flags to match.
- * @param {Function} [customizer] The function to customize comparisons.
- * @returns {boolean} Returns `true` if `object` is a match, else `false`.
- */
-function baseIsMatch(object, source, matchData, customizer) {
-  var index = matchData.length,
-      length = index,
-      noCustomizer = !customizer;
+  let formatlabel = label ? ` : "${label}" ` : ''
+  let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : ''
 
-  if (object == null) {
-    return !length;
-  }
-  object = Object(object);
-  while (index--) {
-    var data = matchData[index];
-    if ((noCustomizer && data[2])
-          ? data[1] !== object[data[0]]
-          : !(data[0] in object)
-        ) {
-      return false;
-    }
-  }
-  while (++index < length) {
-    data = matchData[index];
-    var key = data[0],
-        objValue = object[key],
-        srcValue = data[1];
+  let color = type2color[type]
+  let formattype = color ? chalk[color](type) : type
 
-    if (noCustomizer && data[2]) {
-      if (objValue === undefined && !(key in object)) {
-        return false;
-      }
-    } else {
-      var stack = new Stack;
-      if (customizer) {
-        var result = customizer(objValue, srcValue, key, object, source, stack);
-      }
-      if (!(result === undefined
-            ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
-            : result
-          )) {
-        return false;
-      }
-    }
-  }
-  return true;
+  return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}`
 }
 
-module.exports = baseIsMatch;
+module.exports = devFormat
 
 
 /***/ }),
-/* 404 */
+/* 360 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var ListCache = __webpack_require__(381),
-    stackClear = __webpack_require__(405),
-    stackDelete = __webpack_require__(406),
-    stackGet = __webpack_require__(407),
-    stackHas = __webpack_require__(408),
-    stackSet = __webpack_require__(409);
+"use strict";
 
-/**
- * Creates a stack cache object to store key-value pairs.
- *
- * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
- */
-function Stack(entries) {
-  var data = this.__data__ = new ListCache(entries);
-  this.size = data.size;
-}
+const escapeStringRegexp = __webpack_require__(361);
+const ansiStyles = __webpack_require__(362);
+const stdoutColor = (__webpack_require__(367).stdout);
 
-// Add methods to `Stack`.
-Stack.prototype.clear = stackClear;
-Stack.prototype['delete'] = stackDelete;
-Stack.prototype.get = stackGet;
-Stack.prototype.has = stackHas;
-Stack.prototype.set = stackSet;
+const template = __webpack_require__(369);
 
-module.exports = Stack;
+const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
 
+// `supportsColor.level` → `ansiStyles.color[name]` mapping
+const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
 
-/***/ }),
-/* 405 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+// `color-convert` models to exclude from the Chalk API due to conflicts and such
+const skipModels = new Set(['gray']);
 
-var ListCache = __webpack_require__(381);
+const styles = Object.create(null);
 
-/**
- * Removes all key-value entries from the stack.
- *
- * @private
- * @name clear
- * @memberOf Stack
- */
-function stackClear() {
-  this.__data__ = new ListCache;
-  this.size = 0;
+function applyOptions(obj, options) {
+	options = options || {};
+
+	// Detect level if not set manually
+	const scLevel = stdoutColor ? stdoutColor.level : 0;
+	obj.level = options.level === undefined ? scLevel : options.level;
+	obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
 }
 
-module.exports = stackClear;
+function Chalk(options) {
+	// We check for this.template here since calling `chalk.constructor()`
+	// by itself will have a `this` of a previously constructed chalk object
+	if (!this || !(this instanceof Chalk) || this.template) {
+		const chalk = {};
+		applyOptions(chalk, options);
 
+		chalk.template = function () {
+			const args = [].slice.call(arguments);
+			return chalkTag.apply(null, [chalk.template].concat(args));
+		};
 
-/***/ }),
-/* 406 */
-/***/ ((module) => {
+		Object.setPrototypeOf(chalk, Chalk.prototype);
+		Object.setPrototypeOf(chalk.template, chalk);
 
-/**
- * Removes `key` and its value from the stack.
- *
- * @private
- * @name delete
- * @memberOf Stack
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
- */
-function stackDelete(key) {
-  var data = this.__data__,
-      result = data['delete'](key);
+		chalk.template.constructor = Chalk;
 
-  this.size = data.size;
-  return result;
-}
+		return chalk.template;
+	}
 
-module.exports = stackDelete;
+	applyOptions(this, options);
+}
 
+// Use bright blue on Windows as the normal blue color is illegible
+if (isSimpleWindowsTerm) {
+	ansiStyles.blue.open = '\u001B[94m';
+}
 
-/***/ }),
-/* 407 */
-/***/ ((module) => {
+for (const key of Object.keys(ansiStyles)) {
+	ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
 
-/**
- * Gets the stack value for `key`.
- *
- * @private
- * @name get
- * @memberOf Stack
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
- */
-function stackGet(key) {
-  return this.__data__.get(key);
+	styles[key] = {
+		get() {
+			const codes = ansiStyles[key];
+			return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
+		}
+	};
 }
 
-module.exports = stackGet;
-
+styles.visible = {
+	get() {
+		return build.call(this, this._styles || [], true, 'visible');
+	}
+};
 
-/***/ }),
-/* 408 */
-/***/ ((module) => {
+ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
+for (const model of Object.keys(ansiStyles.color.ansi)) {
+	if (skipModels.has(model)) {
+		continue;
+	}
 
-/**
- * Checks if a stack value for `key` exists.
- *
- * @private
- * @name has
- * @memberOf Stack
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
- */
-function stackHas(key) {
-  return this.__data__.has(key);
+	styles[model] = {
+		get() {
+			const level = this.level;
+			return function () {
+				const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
+				const codes = {
+					open,
+					close: ansiStyles.color.close,
+					closeRe: ansiStyles.color.closeRe
+				};
+				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
+			};
+		}
+	};
 }
 
-module.exports = stackHas;
+ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
+for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
+	if (skipModels.has(model)) {
+		continue;
+	}
 
+	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
+	styles[bgModel] = {
+		get() {
+			const level = this.level;
+			return function () {
+				const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
+				const codes = {
+					open,
+					close: ansiStyles.bgColor.close,
+					closeRe: ansiStyles.bgColor.closeRe
+				};
+				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
+			};
+		}
+	};
+}
 
-/***/ }),
-/* 409 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+const proto = Object.defineProperties(() => {}, styles);
 
-var ListCache = __webpack_require__(381),
-    Map = __webpack_require__(389),
-    MapCache = __webpack_require__(366);
+function build(_styles, _empty, key) {
+	const builder = function () {
+		return applyStyle.apply(builder, arguments);
+	};
 
-/** Used as the size to enable large array optimizations. */
-var LARGE_ARRAY_SIZE = 200;
+	builder._styles = _styles;
+	builder._empty = _empty;
 
-/**
- * Sets the stack `key` to `value`.
- *
- * @private
- * @name set
- * @memberOf Stack
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the stack cache instance.
- */
-function stackSet(key, value) {
-  var data = this.__data__;
-  if (data instanceof ListCache) {
-    var pairs = data.__data__;
-    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
-      pairs.push([key, value]);
-      this.size = ++data.size;
-      return this;
-    }
-    data = this.__data__ = new MapCache(pairs);
-  }
-  data.set(key, value);
-  this.size = data.size;
-  return this;
-}
+	const self = this;
 
-module.exports = stackSet;
+	Object.defineProperty(builder, 'level', {
+		enumerable: true,
+		get() {
+			return self.level;
+		},
+		set(level) {
+			self.level = level;
+		}
+	});
 
+	Object.defineProperty(builder, 'enabled', {
+		enumerable: true,
+		get() {
+			return self.enabled;
+		},
+		set(enabled) {
+			self.enabled = enabled;
+		}
+	});
 
-/***/ }),
-/* 410 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	// See below for fix regarding invisible grey/dim combination on Windows
+	builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
 
-var baseIsEqualDeep = __webpack_require__(411),
-    isObjectLike = __webpack_require__(53);
+	// `__proto__` is used because we must return a function, but there is
+	// no way to create a function with a different prototype
+	builder.__proto__ = proto; // eslint-disable-line no-proto
 
-/**
- * The base implementation of `_.isEqual` which supports partial comparisons
- * and tracks traversed objects.
- *
- * @private
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @param {boolean} bitmask The bitmask flags.
- *  1 - Unordered comparison
- *  2 - Partial comparison
- * @param {Function} [customizer] The function to customize comparisons.
- * @param {Object} [stack] Tracks traversed `value` and `other` objects.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- */
-function baseIsEqual(value, other, bitmask, customizer, stack) {
-  if (value === other) {
-    return true;
-  }
-  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
-    return value !== value && other !== other;
-  }
-  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
+	return builder;
 }
 
-module.exports = baseIsEqual;
-
+function applyStyle() {
+	// Support varags, but simply cast to string in case there's only one arg
+	const args = arguments;
+	const argsLen = args.length;
+	let str = String(arguments[0]);
 
-/***/ }),
-/* 411 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	if (argsLen === 0) {
+		return '';
+	}
 
-var Stack = __webpack_require__(404),
-    equalArrays = __webpack_require__(412),
-    equalByTag = __webpack_require__(418),
-    equalObjects = __webpack_require__(422),
-    getTag = __webpack_require__(447),
-    isArray = __webpack_require__(55),
-    isBuffer = __webpack_require__(434),
-    isTypedArray = __webpack_require__(437);
+	if (argsLen > 1) {
+		// Don't slice `arguments`, it prevents V8 optimizations
+		for (let a = 1; a < argsLen; a++) {
+			str += ' ' + args[a];
+		}
+	}
 
-/** Used to compose bitmasks for value comparisons. */
-var COMPARE_PARTIAL_FLAG = 1;
+	if (!this.enabled || this.level <= 0 || !str) {
+		return this._empty ? '' : str;
+	}
 
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]',
-    arrayTag = '[object Array]',
-    objectTag = '[object Object]';
+	// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
+	// see https://github.com/chalk/chalk/issues/58
+	// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
+	const originalDim = ansiStyles.dim.open;
+	if (isSimpleWindowsTerm && this.hasGrey) {
+		ansiStyles.dim.open = '';
+	}
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+	for (const code of this._styles.slice().reverse()) {
+		// Replace any instances already present with a re-opening code
+		// otherwise only the part of the string until said closing code
+		// will be colored, and the rest will simply be 'plain'.
+		str = code.open + str.replace(code.closeRe, code.open) + code.close;
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+		// Close the styling before a linebreak and reopen
+		// after next line to fix a bleed issue on macOS
+		// https://github.com/chalk/chalk/pull/92
+		str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
+	}
 
-/**
- * A specialized version of `baseIsEqual` for arrays and objects which performs
- * deep comparisons and tracks traversed objects enabling objects with circular
- * references to be compared.
- *
- * @private
- * @param {Object} object The object to compare.
- * @param {Object} other The other object to compare.
- * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
- * @param {Function} customizer The function to customize comparisons.
- * @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Object} [stack] Tracks traversed `object` and `other` objects.
- * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
- */
-function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
-  var objIsArr = isArray(object),
-      othIsArr = isArray(other),
-      objTag = objIsArr ? arrayTag : getTag(object),
-      othTag = othIsArr ? arrayTag : getTag(other);
+	// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
+	ansiStyles.dim.open = originalDim;
 
-  objTag = objTag == argsTag ? objectTag : objTag;
-  othTag = othTag == argsTag ? objectTag : othTag;
+	return str;
+}
 
-  var objIsObj = objTag == objectTag,
-      othIsObj = othTag == objectTag,
-      isSameTag = objTag == othTag;
+function chalkTag(chalk, strings) {
+	if (!Array.isArray(strings)) {
+		// If chalk() was called by itself or with a string,
+		// return the string itself as a string.
+		return [].slice.call(arguments, 1).join(' ');
+	}
 
-  if (isSameTag && isBuffer(object)) {
-    if (!isBuffer(other)) {
-      return false;
-    }
-    objIsArr = true;
-    objIsObj = false;
-  }
-  if (isSameTag && !objIsObj) {
-    stack || (stack = new Stack);
-    return (objIsArr || isTypedArray(object))
-      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
-      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
-  }
-  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
-    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
-        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+	const args = [].slice.call(arguments, 2);
+	const parts = [strings.raw[0]];
 
-    if (objIsWrapped || othIsWrapped) {
-      var objUnwrapped = objIsWrapped ? object.value() : object,
-          othUnwrapped = othIsWrapped ? other.value() : other;
+	for (let i = 1; i < strings.length; i++) {
+		parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
+		parts.push(String(strings.raw[i]));
+	}
 
-      stack || (stack = new Stack);
-      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
-    }
-  }
-  if (!isSameTag) {
-    return false;
-  }
-  stack || (stack = new Stack);
-  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
+	return template(chalk, parts.join(''));
 }
 
-module.exports = baseIsEqualDeep;
+Object.defineProperties(Chalk.prototype, styles);
+
+module.exports = Chalk(); // eslint-disable-line new-cap
+module.exports.supportsColor = stdoutColor;
+module.exports["default"] = module.exports; // For TypeScript
 
 
 /***/ }),
-/* 412 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 361 */
+/***/ ((module) => {
 
-var SetCache = __webpack_require__(413),
-    arraySome = __webpack_require__(416),
-    cacheHas = __webpack_require__(417);
+"use strict";
 
-/** Used to compose bitmasks for value comparisons. */
-var COMPARE_PARTIAL_FLAG = 1,
-    COMPARE_UNORDERED_FLAG = 2;
 
-/**
- * A specialized version of `baseIsEqualDeep` for arrays with support for
- * partial deep comparisons.
- *
- * @private
- * @param {Array} array The array to compare.
- * @param {Array} other The other array to compare.
- * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
- * @param {Function} customizer The function to customize comparisons.
- * @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Object} stack Tracks traversed `array` and `other` objects.
- * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
- */
-function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
-  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
-      arrLength = array.length,
-      othLength = other.length;
+var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
 
-  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
-    return false;
-  }
-  // Check that cyclic values are equal.
-  var arrStacked = stack.get(array);
-  var othStacked = stack.get(other);
-  if (arrStacked && othStacked) {
-    return arrStacked == other && othStacked == array;
-  }
-  var index = -1,
-      result = true,
-      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
+module.exports = function (str) {
+	if (typeof str !== 'string') {
+		throw new TypeError('Expected a string');
+	}
 
-  stack.set(array, other);
-  stack.set(other, array);
+	return str.replace(matchOperatorsRe, '\\$&');
+};
 
-  // Ignore non-index properties.
-  while (++index < arrLength) {
-    var arrValue = array[index],
-        othValue = other[index];
 
-    if (customizer) {
-      var compared = isPartial
-        ? customizer(othValue, arrValue, index, other, array, stack)
-        : customizer(arrValue, othValue, index, array, other, stack);
-    }
-    if (compared !== undefined) {
-      if (compared) {
-        continue;
-      }
-      result = false;
-      break;
-    }
-    // Recursively compare arrays (susceptible to call stack limits).
-    if (seen) {
-      if (!arraySome(other, function(othValue, othIndex) {
-            if (!cacheHas(seen, othIndex) &&
-                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
-              return seen.push(othIndex);
-            }
-          })) {
-        result = false;
-        break;
-      }
-    } else if (!(
-          arrValue === othValue ||
-            equalFunc(arrValue, othValue, bitmask, customizer, stack)
-        )) {
-      result = false;
-      break;
-    }
-  }
-  stack['delete'](array);
-  stack['delete'](other);
-  return result;
-}
+/***/ }),
+/* 362 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-module.exports = equalArrays;
+"use strict";
+/* module decorator */ module = __webpack_require__.nmd(module);
 
+const colorConvert = __webpack_require__(363);
 
-/***/ }),
-/* 413 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+const wrapAnsi16 = (fn, offset) => function () {
+	const code = fn.apply(colorConvert, arguments);
+	return `\u001B[${code + offset}m`;
+};
+
+const wrapAnsi256 = (fn, offset) => function () {
+	const code = fn.apply(colorConvert, arguments);
+	return `\u001B[${38 + offset};5;${code}m`;
+};
+
+const wrapAnsi16m = (fn, offset) => function () {
+	const rgb = fn.apply(colorConvert, arguments);
+	return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
+};
 
-var MapCache = __webpack_require__(366),
-    setCacheAdd = __webpack_require__(414),
-    setCacheHas = __webpack_require__(415);
+function assembleStyles() {
+	const codes = new Map();
+	const styles = {
+		modifier: {
+			reset: [0, 0],
+			// 21 isn't widely supported and 22 does the same thing
+			bold: [1, 22],
+			dim: [2, 22],
+			italic: [3, 23],
+			underline: [4, 24],
+			inverse: [7, 27],
+			hidden: [8, 28],
+			strikethrough: [9, 29]
+		},
+		color: {
+			black: [30, 39],
+			red: [31, 39],
+			green: [32, 39],
+			yellow: [33, 39],
+			blue: [34, 39],
+			magenta: [35, 39],
+			cyan: [36, 39],
+			white: [37, 39],
+			gray: [90, 39],
 
-/**
- *
- * Creates an array cache object to store unique values.
- *
- * @private
- * @constructor
- * @param {Array} [values] The values to cache.
- */
-function SetCache(values) {
-  var index = -1,
-      length = values == null ? 0 : values.length;
+			// Bright color
+			redBright: [91, 39],
+			greenBright: [92, 39],
+			yellowBright: [93, 39],
+			blueBright: [94, 39],
+			magentaBright: [95, 39],
+			cyanBright: [96, 39],
+			whiteBright: [97, 39]
+		},
+		bgColor: {
+			bgBlack: [40, 49],
+			bgRed: [41, 49],
+			bgGreen: [42, 49],
+			bgYellow: [43, 49],
+			bgBlue: [44, 49],
+			bgMagenta: [45, 49],
+			bgCyan: [46, 49],
+			bgWhite: [47, 49],
 
-  this.__data__ = new MapCache;
-  while (++index < length) {
-    this.add(values[index]);
-  }
-}
+			// Bright color
+			bgBlackBright: [100, 49],
+			bgRedBright: [101, 49],
+			bgGreenBright: [102, 49],
+			bgYellowBright: [103, 49],
+			bgBlueBright: [104, 49],
+			bgMagentaBright: [105, 49],
+			bgCyanBright: [106, 49],
+			bgWhiteBright: [107, 49]
+		}
+	};
 
-// Add methods to `SetCache`.
-SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
-SetCache.prototype.has = setCacheHas;
+	// Fix humans
+	styles.color.grey = styles.color.gray;
 
-module.exports = SetCache;
+	for (const groupName of Object.keys(styles)) {
+		const group = styles[groupName];
 
+		for (const styleName of Object.keys(group)) {
+			const style = group[styleName];
 
-/***/ }),
-/* 414 */
-/***/ ((module) => {
+			styles[styleName] = {
+				open: `\u001B[${style[0]}m`,
+				close: `\u001B[${style[1]}m`
+			};
 
-/** Used to stand-in for `undefined` hash values. */
-var HASH_UNDEFINED = '__lodash_hash_undefined__';
+			group[styleName] = styles[styleName];
 
-/**
- * Adds `value` to the array cache.
- *
- * @private
- * @name add
- * @memberOf SetCache
- * @alias push
- * @param {*} value The value to cache.
- * @returns {Object} Returns the cache instance.
- */
-function setCacheAdd(value) {
-  this.__data__.set(value, HASH_UNDEFINED);
-  return this;
-}
+			codes.set(style[0], style[1]);
+		}
 
-module.exports = setCacheAdd;
+		Object.defineProperty(styles, groupName, {
+			value: group,
+			enumerable: false
+		});
 
+		Object.defineProperty(styles, 'codes', {
+			value: codes,
+			enumerable: false
+		});
+	}
 
-/***/ }),
-/* 415 */
-/***/ ((module) => {
+	const ansi2ansi = n => n;
+	const rgb2rgb = (r, g, b) => [r, g, b];
 
-/**
- * Checks if `value` is in the array cache.
- *
- * @private
- * @name has
- * @memberOf SetCache
- * @param {*} value The value to search for.
- * @returns {number} Returns `true` if `value` is found, else `false`.
- */
-function setCacheHas(value) {
-  return this.__data__.has(value);
-}
+	styles.color.close = '\u001B[39m';
+	styles.bgColor.close = '\u001B[49m';
 
-module.exports = setCacheHas;
+	styles.color.ansi = {
+		ansi: wrapAnsi16(ansi2ansi, 0)
+	};
+	styles.color.ansi256 = {
+		ansi256: wrapAnsi256(ansi2ansi, 0)
+	};
+	styles.color.ansi16m = {
+		rgb: wrapAnsi16m(rgb2rgb, 0)
+	};
 
+	styles.bgColor.ansi = {
+		ansi: wrapAnsi16(ansi2ansi, 10)
+	};
+	styles.bgColor.ansi256 = {
+		ansi256: wrapAnsi256(ansi2ansi, 10)
+	};
+	styles.bgColor.ansi16m = {
+		rgb: wrapAnsi16m(rgb2rgb, 10)
+	};
 
-/***/ }),
-/* 416 */
-/***/ ((module) => {
+	for (let key of Object.keys(colorConvert)) {
+		if (typeof colorConvert[key] !== 'object') {
+			continue;
+		}
 
-/**
- * A specialized version of `_.some` for arrays without support for iteratee
- * shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- *  else `false`.
- */
-function arraySome(array, predicate) {
-  var index = -1,
-      length = array == null ? 0 : array.length;
+		const suite = colorConvert[key];
 
-  while (++index < length) {
-    if (predicate(array[index], index, array)) {
-      return true;
-    }
-  }
-  return false;
-}
+		if (key === 'ansi16') {
+			key = 'ansi';
+		}
 
-module.exports = arraySome;
+		if ('ansi16' in suite) {
+			styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0);
+			styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10);
+		}
 
+		if ('ansi256' in suite) {
+			styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0);
+			styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10);
+		}
 
-/***/ }),
-/* 417 */
-/***/ ((module) => {
+		if ('rgb' in suite) {
+			styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0);
+			styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10);
+		}
+	}
 
-/**
- * Checks if a `cache` value for `key` exists.
- *
- * @private
- * @param {Object} cache The cache to query.
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
- */
-function cacheHas(cache, key) {
-  return cache.has(key);
+	return styles;
 }
 
-module.exports = cacheHas;
+// Make the export immutable
+Object.defineProperty(module, 'exports', {
+	enumerable: true,
+	get: assembleStyles
+});
 
 
 /***/ }),
-/* 418 */
+/* 363 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var Symbol = __webpack_require__(47),
-    Uint8Array = __webpack_require__(419),
-    eq = __webpack_require__(385),
-    equalArrays = __webpack_require__(412),
-    mapToArray = __webpack_require__(420),
-    setToArray = __webpack_require__(421);
+var conversions = __webpack_require__(364);
+var route = __webpack_require__(366);
 
-/** Used to compose bitmasks for value comparisons. */
-var COMPARE_PARTIAL_FLAG = 1,
-    COMPARE_UNORDERED_FLAG = 2;
+var convert = {};
 
-/** `Object#toString` result references. */
-var boolTag = '[object Boolean]',
-    dateTag = '[object Date]',
-    errorTag = '[object Error]',
-    mapTag = '[object Map]',
-    numberTag = '[object Number]',
-    regexpTag = '[object RegExp]',
-    setTag = '[object Set]',
-    stringTag = '[object String]',
-    symbolTag = '[object Symbol]';
+var models = Object.keys(conversions);
 
-var arrayBufferTag = '[object ArrayBuffer]',
-    dataViewTag = '[object DataView]';
+function wrapRaw(fn) {
+	var wrappedFn = function (args) {
+		if (args === undefined || args === null) {
+			return args;
+		}
 
-/** Used to convert symbols to primitives and strings. */
-var symbolProto = Symbol ? Symbol.prototype : undefined,
-    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
+		if (arguments.length > 1) {
+			args = Array.prototype.slice.call(arguments);
+		}
 
-/**
- * A specialized version of `baseIsEqualDeep` for comparing objects of
- * the same `toStringTag`.
- *
- * **Note:** This function only supports comparing values with tags of
- * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
- *
- * @private
- * @param {Object} object The object to compare.
- * @param {Object} other The other object to compare.
- * @param {string} tag The `toStringTag` of the objects to compare.
- * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
- * @param {Function} customizer The function to customize comparisons.
- * @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Object} stack Tracks traversed `object` and `other` objects.
- * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
- */
-function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
-  switch (tag) {
-    case dataViewTag:
-      if ((object.byteLength != other.byteLength) ||
-          (object.byteOffset != other.byteOffset)) {
-        return false;
-      }
-      object = object.buffer;
-      other = other.buffer;
+		return fn(args);
+	};
 
-    case arrayBufferTag:
-      if ((object.byteLength != other.byteLength) ||
-          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
-        return false;
-      }
-      return true;
+	// preserve .conversion property if there is one
+	if ('conversion' in fn) {
+		wrappedFn.conversion = fn.conversion;
+	}
 
-    case boolTag:
-    case dateTag:
-    case numberTag:
-      // Coerce booleans to `1` or `0` and dates to milliseconds.
-      // Invalid dates are coerced to `NaN`.
-      return eq(+object, +other);
+	return wrappedFn;
+}
 
-    case errorTag:
-      return object.name == other.name && object.message == other.message;
+function wrapRounded(fn) {
+	var wrappedFn = function (args) {
+		if (args === undefined || args === null) {
+			return args;
+		}
 
-    case regexpTag:
-    case stringTag:
-      // Coerce regexes to strings and treat strings, primitives and objects,
-      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
-      // for more details.
-      return object == (other + '');
+		if (arguments.length > 1) {
+			args = Array.prototype.slice.call(arguments);
+		}
 
-    case mapTag:
-      var convert = mapToArray;
+		var result = fn(args);
 
-    case setTag:
-      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
-      convert || (convert = setToArray);
+		// we're assuming the result is an array here.
+		// see notice in conversions.js; don't use box types
+		// in conversion functions.
+		if (typeof result === 'object') {
+			for (var len = result.length, i = 0; i < len; i++) {
+				result[i] = Math.round(result[i]);
+			}
+		}
 
-      if (object.size != other.size && !isPartial) {
-        return false;
-      }
-      // Assume cyclic values are equal.
-      var stacked = stack.get(object);
-      if (stacked) {
-        return stacked == other;
-      }
-      bitmask |= COMPARE_UNORDERED_FLAG;
+		return result;
+	};
 
-      // Recursively compare objects (susceptible to call stack limits).
-      stack.set(object, other);
-      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
-      stack['delete'](object);
-      return result;
+	// preserve .conversion property if there is one
+	if ('conversion' in fn) {
+		wrappedFn.conversion = fn.conversion;
+	}
 
-    case symbolTag:
-      if (symbolValueOf) {
-        return symbolValueOf.call(object) == symbolValueOf.call(other);
-      }
-  }
-  return false;
+	return wrappedFn;
 }
 
-module.exports = equalByTag;
+models.forEach(function (fromModel) {
+	convert[fromModel] = {};
 
+	Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
+	Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
 
-/***/ }),
-/* 419 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	var routes = route(fromModel);
+	var routeModels = Object.keys(routes);
 
-var root = __webpack_require__(48);
+	routeModels.forEach(function (toModel) {
+		var fn = routes[toModel];
 
-/** Built-in value references. */
-var Uint8Array = root.Uint8Array;
+		convert[fromModel][toModel] = wrapRounded(fn);
+		convert[fromModel][toModel].raw = wrapRaw(fn);
+	});
+});
 
-module.exports = Uint8Array;
+module.exports = convert;
 
 
 /***/ }),
-/* 420 */
-/***/ ((module) => {
+/* 364 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/**
- * Converts `map` to its key-value pairs.
- *
- * @private
- * @param {Object} map The map to convert.
- * @returns {Array} Returns the key-value pairs.
- */
-function mapToArray(map) {
-  var index = -1,
-      result = Array(map.size);
+/* MIT license */
+var cssKeywords = __webpack_require__(365);
 
-  map.forEach(function(value, key) {
-    result[++index] = [key, value];
-  });
-  return result;
+// NOTE: conversions should only return primitive values (i.e. arrays, or
+//       values that give correct `typeof` results).
+//       do not use box values types (i.e. Number(), String(), etc.)
+
+var reverseKeywords = {};
+for (var key in cssKeywords) {
+	if (cssKeywords.hasOwnProperty(key)) {
+		reverseKeywords[cssKeywords[key]] = key;
+	}
 }
 
-module.exports = mapToArray;
+var convert = module.exports = {
+	rgb: {channels: 3, labels: 'rgb'},
+	hsl: {channels: 3, labels: 'hsl'},
+	hsv: {channels: 3, labels: 'hsv'},
+	hwb: {channels: 3, labels: 'hwb'},
+	cmyk: {channels: 4, labels: 'cmyk'},
+	xyz: {channels: 3, labels: 'xyz'},
+	lab: {channels: 3, labels: 'lab'},
+	lch: {channels: 3, labels: 'lch'},
+	hex: {channels: 1, labels: ['hex']},
+	keyword: {channels: 1, labels: ['keyword']},
+	ansi16: {channels: 1, labels: ['ansi16']},
+	ansi256: {channels: 1, labels: ['ansi256']},
+	hcg: {channels: 3, labels: ['h', 'c', 'g']},
+	apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
+	gray: {channels: 1, labels: ['gray']}
+};
 
+// hide .channels and .labels properties
+for (var model in convert) {
+	if (convert.hasOwnProperty(model)) {
+		if (!('channels' in convert[model])) {
+			throw new Error('missing channels property: ' + model);
+		}
 
-/***/ }),
-/* 421 */
-/***/ ((module) => {
+		if (!('labels' in convert[model])) {
+			throw new Error('missing channel labels property: ' + model);
+		}
 
-/**
- * Converts `set` to an array of its values.
- *
- * @private
- * @param {Object} set The set to convert.
- * @returns {Array} Returns the values.
- */
-function setToArray(set) {
-  var index = -1,
-      result = Array(set.size);
+		if (convert[model].labels.length !== convert[model].channels) {
+			throw new Error('channel and label counts mismatch: ' + model);
+		}
 
-  set.forEach(function(value) {
-    result[++index] = value;
-  });
-  return result;
+		var channels = convert[model].channels;
+		var labels = convert[model].labels;
+		delete convert[model].channels;
+		delete convert[model].labels;
+		Object.defineProperty(convert[model], 'channels', {value: channels});
+		Object.defineProperty(convert[model], 'labels', {value: labels});
+	}
 }
 
-module.exports = setToArray;
+convert.rgb.hsl = function (rgb) {
+	var r = rgb[0] / 255;
+	var g = rgb[1] / 255;
+	var b = rgb[2] / 255;
+	var min = Math.min(r, g, b);
+	var max = Math.max(r, g, b);
+	var delta = max - min;
+	var h;
+	var s;
+	var l;
 
+	if (max === min) {
+		h = 0;
+	} else if (r === max) {
+		h = (g - b) / delta;
+	} else if (g === max) {
+		h = 2 + (b - r) / delta;
+	} else if (b === max) {
+		h = 4 + (r - g) / delta;
+	}
 
-/***/ }),
-/* 422 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	h = Math.min(h * 60, 360);
 
-var getAllKeys = __webpack_require__(423);
+	if (h < 0) {
+		h += 360;
+	}
 
-/** Used to compose bitmasks for value comparisons. */
-var COMPARE_PARTIAL_FLAG = 1;
+	l = (min + max) / 2;
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+	if (max === min) {
+		s = 0;
+	} else if (l <= 0.5) {
+		s = delta / (max + min);
+	} else {
+		s = delta / (2 - max - min);
+	}
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+	return [h, s * 100, l * 100];
+};
 
-/**
- * A specialized version of `baseIsEqualDeep` for objects with support for
- * partial deep comparisons.
- *
- * @private
- * @param {Object} object The object to compare.
- * @param {Object} other The other object to compare.
- * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
- * @param {Function} customizer The function to customize comparisons.
- * @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Object} stack Tracks traversed `object` and `other` objects.
- * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
- */
-function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
-  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
-      objProps = getAllKeys(object),
-      objLength = objProps.length,
-      othProps = getAllKeys(other),
-      othLength = othProps.length;
+convert.rgb.hsv = function (rgb) {
+	var rdif;
+	var gdif;
+	var bdif;
+	var h;
+	var s;
 
-  if (objLength != othLength && !isPartial) {
-    return false;
-  }
-  var index = objLength;
-  while (index--) {
-    var key = objProps[index];
-    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
-      return false;
-    }
-  }
-  // Check that cyclic values are equal.
-  var objStacked = stack.get(object);
-  var othStacked = stack.get(other);
-  if (objStacked && othStacked) {
-    return objStacked == other && othStacked == object;
-  }
-  var result = true;
-  stack.set(object, other);
-  stack.set(other, object);
+	var r = rgb[0] / 255;
+	var g = rgb[1] / 255;
+	var b = rgb[2] / 255;
+	var v = Math.max(r, g, b);
+	var diff = v - Math.min(r, g, b);
+	var diffc = function (c) {
+		return (v - c) / 6 / diff + 1 / 2;
+	};
 
-  var skipCtor = isPartial;
-  while (++index < objLength) {
-    key = objProps[index];
-    var objValue = object[key],
-        othValue = other[key];
+	if (diff === 0) {
+		h = s = 0;
+	} else {
+		s = diff / v;
+		rdif = diffc(r);
+		gdif = diffc(g);
+		bdif = diffc(b);
 
-    if (customizer) {
-      var compared = isPartial
-        ? customizer(othValue, objValue, key, other, object, stack)
-        : customizer(objValue, othValue, key, object, other, stack);
-    }
-    // Recursively compare objects (susceptible to call stack limits).
-    if (!(compared === undefined
-          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
-          : compared
-        )) {
-      result = false;
-      break;
-    }
-    skipCtor || (skipCtor = key == 'constructor');
-  }
-  if (result && !skipCtor) {
-    var objCtor = object.constructor,
-        othCtor = other.constructor;
+		if (r === v) {
+			h = bdif - gdif;
+		} else if (g === v) {
+			h = (1 / 3) + rdif - bdif;
+		} else if (b === v) {
+			h = (2 / 3) + gdif - rdif;
+		}
+		if (h < 0) {
+			h += 1;
+		} else if (h > 1) {
+			h -= 1;
+		}
+	}
 
-    // Non `Object` object instances with different constructors are not equal.
-    if (objCtor != othCtor &&
-        ('constructor' in object && 'constructor' in other) &&
-        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
-          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
-      result = false;
-    }
-  }
-  stack['delete'](object);
-  stack['delete'](other);
-  return result;
-}
+	return [
+		h * 360,
+		s * 100,
+		v * 100
+	];
+};
 
-module.exports = equalObjects;
+convert.rgb.hwb = function (rgb) {
+	var r = rgb[0];
+	var g = rgb[1];
+	var b = rgb[2];
+	var h = convert.rgb.hsl(rgb)[0];
+	var w = 1 / 255 * Math.min(r, Math.min(g, b));
 
+	b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
 
-/***/ }),
-/* 423 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	return [h, w * 100, b * 100];
+};
+
+convert.rgb.cmyk = function (rgb) {
+	var r = rgb[0] / 255;
+	var g = rgb[1] / 255;
+	var b = rgb[2] / 255;
+	var c;
+	var m;
+	var y;
+	var k;
+
+	k = Math.min(1 - r, 1 - g, 1 - b);
+	c = (1 - r - k) / (1 - k) || 0;
+	m = (1 - g - k) / (1 - k) || 0;
+	y = (1 - b - k) / (1 - k) || 0;
 
-var baseGetAllKeys = __webpack_require__(424),
-    getSymbols = __webpack_require__(426),
-    keys = __webpack_require__(429);
+	return [c * 100, m * 100, y * 100, k * 100];
+};
 
 /**
- * Creates an array of own enumerable property names and symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names and symbols.
- */
-function getAllKeys(object) {
-  return baseGetAllKeys(object, keys, getSymbols);
+ * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
+ * */
+function comparativeDistance(x, y) {
+	return (
+		Math.pow(x[0] - y[0], 2) +
+		Math.pow(x[1] - y[1], 2) +
+		Math.pow(x[2] - y[2], 2)
+	);
 }
 
-module.exports = getAllKeys;
+convert.rgb.keyword = function (rgb) {
+	var reversed = reverseKeywords[rgb];
+	if (reversed) {
+		return reversed;
+	}
 
+	var currentClosestDistance = Infinity;
+	var currentClosestKeyword;
 
-/***/ }),
-/* 424 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	for (var keyword in cssKeywords) {
+		if (cssKeywords.hasOwnProperty(keyword)) {
+			var value = cssKeywords[keyword];
 
-var arrayPush = __webpack_require__(425),
-    isArray = __webpack_require__(55);
+			// Compute comparative distance
+			var distance = comparativeDistance(rgb, value);
 
-/**
- * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
- * `keysFunc` and `symbolsFunc` to get the enumerable property names and
- * symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Function} keysFunc The function to get the keys of `object`.
- * @param {Function} symbolsFunc The function to get the symbols of `object`.
- * @returns {Array} Returns the array of property names and symbols.
- */
-function baseGetAllKeys(object, keysFunc, symbolsFunc) {
-  var result = keysFunc(object);
-  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
-}
+			// Check if its less, if so set as closest
+			if (distance < currentClosestDistance) {
+				currentClosestDistance = distance;
+				currentClosestKeyword = keyword;
+			}
+		}
+	}
 
-module.exports = baseGetAllKeys;
+	return currentClosestKeyword;
+};
 
+convert.keyword.rgb = function (keyword) {
+	return cssKeywords[keyword];
+};
 
-/***/ }),
-/* 425 */
-/***/ ((module) => {
+convert.rgb.xyz = function (rgb) {
+	var r = rgb[0] / 255;
+	var g = rgb[1] / 255;
+	var b = rgb[2] / 255;
 
-/**
- * Appends the elements of `values` to `array`.
- *
- * @private
- * @param {Array} array The array to modify.
- * @param {Array} values The values to append.
- * @returns {Array} Returns `array`.
- */
-function arrayPush(array, values) {
-  var index = -1,
-      length = values.length,
-      offset = array.length;
+	// assume sRGB
+	r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
+	g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
+	b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
 
-  while (++index < length) {
-    array[offset + index] = values[index];
-  }
-  return array;
-}
+	var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
+	var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
+	var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
 
-module.exports = arrayPush;
+	return [x * 100, y * 100, z * 100];
+};
 
+convert.rgb.lab = function (rgb) {
+	var xyz = convert.rgb.xyz(rgb);
+	var x = xyz[0];
+	var y = xyz[1];
+	var z = xyz[2];
+	var l;
+	var a;
+	var b;
 
-/***/ }),
-/* 426 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	x /= 95.047;
+	y /= 100;
+	z /= 108.883;
 
-var arrayFilter = __webpack_require__(427),
-    stubArray = __webpack_require__(428);
+	x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
+	y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
+	z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+	l = (116 * y) - 16;
+	a = 500 * (x - y);
+	b = 200 * (y - z);
 
-/** Built-in value references. */
-var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+	return [l, a, b];
+};
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeGetSymbols = Object.getOwnPropertySymbols;
+convert.hsl.rgb = function (hsl) {
+	var h = hsl[0] / 360;
+	var s = hsl[1] / 100;
+	var l = hsl[2] / 100;
+	var t1;
+	var t2;
+	var t3;
+	var rgb;
+	var val;
 
-/**
- * Creates an array of the own enumerable symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of symbols.
- */
-var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
-  if (object == null) {
-    return [];
-  }
-  object = Object(object);
-  return arrayFilter(nativeGetSymbols(object), function(symbol) {
-    return propertyIsEnumerable.call(object, symbol);
-  });
-};
+	if (s === 0) {
+		val = l * 255;
+		return [val, val, val];
+	}
 
-module.exports = getSymbols;
+	if (l < 0.5) {
+		t2 = l * (1 + s);
+	} else {
+		t2 = l + s - l * s;
+	}
 
+	t1 = 2 * l - t2;
 
-/***/ }),
-/* 427 */
-/***/ ((module) => {
+	rgb = [0, 0, 0];
+	for (var i = 0; i < 3; i++) {
+		t3 = h + 1 / 3 * -(i - 1);
+		if (t3 < 0) {
+			t3++;
+		}
+		if (t3 > 1) {
+			t3--;
+		}
 
-/**
- * A specialized version of `_.filter` for arrays without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {Array} Returns the new filtered array.
- */
-function arrayFilter(array, predicate) {
-  var index = -1,
-      length = array == null ? 0 : array.length,
-      resIndex = 0,
-      result = [];
+		if (6 * t3 < 1) {
+			val = t1 + (t2 - t1) * 6 * t3;
+		} else if (2 * t3 < 1) {
+			val = t2;
+		} else if (3 * t3 < 2) {
+			val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
+		} else {
+			val = t1;
+		}
 
-  while (++index < length) {
-    var value = array[index];
-    if (predicate(value, index, array)) {
-      result[resIndex++] = value;
-    }
-  }
-  return result;
-}
+		rgb[i] = val * 255;
+	}
 
-module.exports = arrayFilter;
+	return rgb;
+};
 
+convert.hsl.hsv = function (hsl) {
+	var h = hsl[0];
+	var s = hsl[1] / 100;
+	var l = hsl[2] / 100;
+	var smin = s;
+	var lmin = Math.max(l, 0.01);
+	var sv;
+	var v;
 
-/***/ }),
-/* 428 */
-/***/ ((module) => {
+	l *= 2;
+	s *= (l <= 1) ? l : 2 - l;
+	smin *= lmin <= 1 ? lmin : 2 - lmin;
+	v = (l + s) / 2;
+	sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
 
-/**
- * This method returns a new empty array.
- *
- * @static
- * @memberOf _
- * @since 4.13.0
- * @category Util
- * @returns {Array} Returns the new empty array.
- * @example
- *
- * var arrays = _.times(2, _.stubArray);
- *
- * console.log(arrays);
- * // => [[], []]
- *
- * console.log(arrays[0] === arrays[1]);
- * // => false
- */
-function stubArray() {
-  return [];
-}
+	return [h, sv * 100, v * 100];
+};
 
-module.exports = stubArray;
+convert.hsv.rgb = function (hsv) {
+	var h = hsv[0] / 60;
+	var s = hsv[1] / 100;
+	var v = hsv[2] / 100;
+	var hi = Math.floor(h) % 6;
 
+	var f = h - Math.floor(h);
+	var p = 255 * v * (1 - s);
+	var q = 255 * v * (1 - (s * f));
+	var t = 255 * v * (1 - (s * (1 - f)));
+	v *= 255;
 
-/***/ }),
-/* 429 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	switch (hi) {
+		case 0:
+			return [v, t, p];
+		case 1:
+			return [q, v, p];
+		case 2:
+			return [p, v, t];
+		case 3:
+			return [p, q, v];
+		case 4:
+			return [t, p, v];
+		case 5:
+			return [v, p, q];
+	}
+};
+
+convert.hsv.hsl = function (hsv) {
+	var h = hsv[0];
+	var s = hsv[1] / 100;
+	var v = hsv[2] / 100;
+	var vmin = Math.max(v, 0.01);
+	var lmin;
+	var sl;
+	var l;
 
-var arrayLikeKeys = __webpack_require__(430),
-    baseKeys = __webpack_require__(442),
-    isArrayLike = __webpack_require__(446);
+	l = (2 - s) * v;
+	lmin = (2 - s) * vmin;
+	sl = s * vmin;
+	sl /= (lmin <= 1) ? lmin : 2 - lmin;
+	sl = sl || 0;
+	l /= 2;
 
-/**
- * Creates an array of the own enumerable property names of `object`.
- *
- * **Note:** Non-object values are coerced to objects. See the
- * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
- * for more details.
- *
- * @static
- * @since 0.1.0
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- * @example
- *
- * function Foo() {
- *   this.a = 1;
- *   this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.keys(new Foo);
- * // => ['a', 'b'] (iteration order is not guaranteed)
- *
- * _.keys('hi');
- * // => ['0', '1']
- */
-function keys(object) {
-  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
-}
+	return [h, sl * 100, l * 100];
+};
 
-module.exports = keys;
+// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
+convert.hwb.rgb = function (hwb) {
+	var h = hwb[0] / 360;
+	var wh = hwb[1] / 100;
+	var bl = hwb[2] / 100;
+	var ratio = wh + bl;
+	var i;
+	var v;
+	var f;
+	var n;
 
+	// wh + bl cant be > 1
+	if (ratio > 1) {
+		wh /= ratio;
+		bl /= ratio;
+	}
 
-/***/ }),
-/* 430 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	i = Math.floor(6 * h);
+	v = 1 - bl;
+	f = 6 * h - i;
 
-var baseTimes = __webpack_require__(431),
-    isArguments = __webpack_require__(432),
-    isArray = __webpack_require__(55),
-    isBuffer = __webpack_require__(434),
-    isIndex = __webpack_require__(436),
-    isTypedArray = __webpack_require__(437);
+	if ((i & 0x01) !== 0) {
+		f = 1 - f;
+	}
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+	n = wh + f * (v - wh); // linear interpolation
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+	var r;
+	var g;
+	var b;
+	switch (i) {
+		default:
+		case 6:
+		case 0: r = v; g = n; b = wh; break;
+		case 1: r = n; g = v; b = wh; break;
+		case 2: r = wh; g = v; b = n; break;
+		case 3: r = wh; g = n; b = v; break;
+		case 4: r = n; g = wh; b = v; break;
+		case 5: r = v; g = wh; b = n; break;
+	}
 
-/**
- * Creates an array of the enumerable property names of the array-like `value`.
- *
- * @private
- * @param {*} value The value to query.
- * @param {boolean} inherited Specify returning inherited property names.
- * @returns {Array} Returns the array of property names.
- */
-function arrayLikeKeys(value, inherited) {
-  var isArr = isArray(value),
-      isArg = !isArr && isArguments(value),
-      isBuff = !isArr && !isArg && isBuffer(value),
-      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
-      skipIndexes = isArr || isArg || isBuff || isType,
-      result = skipIndexes ? baseTimes(value.length, String) : [],
-      length = result.length;
+	return [r * 255, g * 255, b * 255];
+};
 
-  for (var key in value) {
-    if ((inherited || hasOwnProperty.call(value, key)) &&
-        !(skipIndexes && (
-           // Safari 9 has enumerable `arguments.length` in strict mode.
-           key == 'length' ||
-           // Node.js 0.10 has enumerable non-index properties on buffers.
-           (isBuff && (key == 'offset' || key == 'parent')) ||
-           // PhantomJS 2 has enumerable non-index properties on typed arrays.
-           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
-           // Skip index properties.
-           isIndex(key, length)
-        ))) {
-      result.push(key);
-    }
-  }
-  return result;
-}
+convert.cmyk.rgb = function (cmyk) {
+	var c = cmyk[0] / 100;
+	var m = cmyk[1] / 100;
+	var y = cmyk[2] / 100;
+	var k = cmyk[3] / 100;
+	var r;
+	var g;
+	var b;
 
-module.exports = arrayLikeKeys;
+	r = 1 - Math.min(1, c * (1 - k) + k);
+	g = 1 - Math.min(1, m * (1 - k) + k);
+	b = 1 - Math.min(1, y * (1 - k) + k);
 
+	return [r * 255, g * 255, b * 255];
+};
 
-/***/ }),
-/* 431 */
-/***/ ((module) => {
+convert.xyz.rgb = function (xyz) {
+	var x = xyz[0] / 100;
+	var y = xyz[1] / 100;
+	var z = xyz[2] / 100;
+	var r;
+	var g;
+	var b;
 
-/**
- * The base implementation of `_.times` without support for iteratee shorthands
- * or max array length checks.
- *
- * @private
- * @param {number} n The number of times to invoke `iteratee`.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the array of results.
- */
-function baseTimes(n, iteratee) {
-  var index = -1,
-      result = Array(n);
+	r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
+	g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
+	b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
 
-  while (++index < n) {
-    result[index] = iteratee(index);
-  }
-  return result;
-}
+	// assume sRGB
+	r = r > 0.0031308
+		? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
+		: r * 12.92;
 
-module.exports = baseTimes;
+	g = g > 0.0031308
+		? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
+		: g * 12.92;
 
+	b = b > 0.0031308
+		? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
+		: b * 12.92;
 
-/***/ }),
-/* 432 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	r = Math.min(Math.max(0, r), 1);
+	g = Math.min(Math.max(0, g), 1);
+	b = Math.min(Math.max(0, b), 1);
 
-var baseIsArguments = __webpack_require__(433),
-    isObjectLike = __webpack_require__(53);
+	return [r * 255, g * 255, b * 255];
+};
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+convert.xyz.lab = function (xyz) {
+	var x = xyz[0];
+	var y = xyz[1];
+	var z = xyz[2];
+	var l;
+	var a;
+	var b;
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+	x /= 95.047;
+	y /= 100;
+	z /= 108.883;
 
-/** Built-in value references. */
-var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+	x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
+	y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
+	z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
 
-/**
- * Checks if `value` is likely an `arguments` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an `arguments` object,
- *  else `false`.
- * @example
- *
- * _.isArguments(function() { return arguments; }());
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
-var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
-  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
-    !propertyIsEnumerable.call(value, 'callee');
+	l = (116 * y) - 16;
+	a = 500 * (x - y);
+	b = 200 * (y - z);
+
+	return [l, a, b];
 };
 
-module.exports = isArguments;
+convert.lab.xyz = function (lab) {
+	var l = lab[0];
+	var a = lab[1];
+	var b = lab[2];
+	var x;
+	var y;
+	var z;
 
+	y = (l + 16) / 116;
+	x = a / 500 + y;
+	z = y - b / 200;
 
-/***/ }),
-/* 433 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	var y2 = Math.pow(y, 3);
+	var x2 = Math.pow(x, 3);
+	var z2 = Math.pow(z, 3);
+	y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
+	x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
+	z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
 
-var baseGetTag = __webpack_require__(46),
-    isObjectLike = __webpack_require__(53);
+	x *= 95.047;
+	y *= 100;
+	z *= 108.883;
 
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]';
+	return [x, y, z];
+};
 
-/**
- * The base implementation of `_.isArguments`.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an `arguments` object,
- */
-function baseIsArguments(value) {
-  return isObjectLike(value) && baseGetTag(value) == argsTag;
-}
+convert.lab.lch = function (lab) {
+	var l = lab[0];
+	var a = lab[1];
+	var b = lab[2];
+	var hr;
+	var h;
+	var c;
 
-module.exports = baseIsArguments;
+	hr = Math.atan2(b, a);
+	h = hr * 360 / 2 / Math.PI;
 
+	if (h < 0) {
+		h += 360;
+	}
 
-/***/ }),
-/* 434 */
-/***/ ((module, exports, __webpack_require__) => {
+	c = Math.sqrt(a * a + b * b);
 
-/* module decorator */ module = __webpack_require__.nmd(module);
-var root = __webpack_require__(48),
-    stubFalse = __webpack_require__(435);
+	return [l, c, h];
+};
 
-/** Detect free variable `exports`. */
-var freeExports =  true && exports && !exports.nodeType && exports;
+convert.lch.lab = function (lch) {
+	var l = lch[0];
+	var c = lch[1];
+	var h = lch[2];
+	var a;
+	var b;
+	var hr;
 
-/** Detect free variable `module`. */
-var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
+	hr = h / 360 * 2 * Math.PI;
+	a = c * Math.cos(hr);
+	b = c * Math.sin(hr);
 
-/** Detect the popular CommonJS extension `module.exports`. */
-var moduleExports = freeModule && freeModule.exports === freeExports;
+	return [l, a, b];
+};
 
-/** Built-in value references. */
-var Buffer = moduleExports ? root.Buffer : undefined;
+convert.rgb.ansi16 = function (args) {
+	var r = args[0];
+	var g = args[1];
+	var b = args[2];
+	var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
+	value = Math.round(value / 50);
 
-/**
- * Checks if `value` is a buffer.
- *
- * @static
- * @memberOf _
- * @since 4.3.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
- * @example
- *
- * _.isBuffer(new Buffer(2));
- * // => true
- *
- * _.isBuffer(new Uint8Array(2));
- * // => false
- */
-var isBuffer = nativeIsBuffer || stubFalse;
+	if (value === 0) {
+		return 30;
+	}
 
-module.exports = isBuffer;
+	var ansi = 30
+		+ ((Math.round(b / 255) << 2)
+		| (Math.round(g / 255) << 1)
+		| Math.round(r / 255));
 
+	if (value === 2) {
+		ansi += 60;
+	}
 
-/***/ }),
-/* 435 */
-/***/ ((module) => {
+	return ansi;
+};
 
-/**
- * This method returns `false`.
- *
- * @static
- * @memberOf _
- * @since 4.13.0
- * @category Util
- * @returns {boolean} Returns `false`.
- * @example
- *
- * _.times(2, _.stubFalse);
- * // => [false, false]
- */
-function stubFalse() {
-  return false;
-}
+convert.hsv.ansi16 = function (args) {
+	// optimization here; we already know the value and don't need to get
+	// it converted for us.
+	return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
+};
 
-module.exports = stubFalse;
+convert.rgb.ansi256 = function (args) {
+	var r = args[0];
+	var g = args[1];
+	var b = args[2];
 
+	// we use the extended greyscale palette here, with the exception of
+	// black and white. normal palette only has 4 greyscale shades.
+	if (r === g && g === b) {
+		if (r < 8) {
+			return 16;
+		}
 
-/***/ }),
-/* 436 */
-/***/ ((module) => {
+		if (r > 248) {
+			return 231;
+		}
 
-/** Used as references for various `Number` constants. */
-var MAX_SAFE_INTEGER = 9007199254740991;
+		return Math.round(((r - 8) / 247) * 24) + 232;
+	}
 
-/** Used to detect unsigned integer values. */
-var reIsUint = /^(?:0|[1-9]\d*)$/;
+	var ansi = 16
+		+ (36 * Math.round(r / 255 * 5))
+		+ (6 * Math.round(g / 255 * 5))
+		+ Math.round(b / 255 * 5);
 
-/**
- * Checks if `value` is a valid array-like index.
- *
- * @private
- * @param {*} value The value to check.
- * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
- * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
- */
-function isIndex(value, length) {
-  var type = typeof value;
-  length = length == null ? MAX_SAFE_INTEGER : length;
+	return ansi;
+};
 
-  return !!length &&
-    (type == 'number' ||
-      (type != 'symbol' && reIsUint.test(value))) &&
-        (value > -1 && value % 1 == 0 && value < length);
-}
+convert.ansi16.rgb = function (args) {
+	var color = args % 10;
 
-module.exports = isIndex;
+	// handle greyscale
+	if (color === 0 || color === 7) {
+		if (args > 50) {
+			color += 3.5;
+		}
 
+		color = color / 10.5 * 255;
 
-/***/ }),
-/* 437 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+		return [color, color, color];
+	}
 
-var baseIsTypedArray = __webpack_require__(438),
-    baseUnary = __webpack_require__(440),
-    nodeUtil = __webpack_require__(441);
+	var mult = (~~(args > 50) + 1) * 0.5;
+	var r = ((color & 1) * mult) * 255;
+	var g = (((color >> 1) & 1) * mult) * 255;
+	var b = (((color >> 2) & 1) * mult) * 255;
 
-/* Node.js helper references. */
-var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
+	return [r, g, b];
+};
 
-/**
- * Checks if `value` is classified as a typed array.
- *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
- * @example
- *
- * _.isTypedArray(new Uint8Array);
- * // => true
- *
- * _.isTypedArray([]);
- * // => false
- */
-var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
+convert.ansi256.rgb = function (args) {
+	// handle greyscale
+	if (args >= 232) {
+		var c = (args - 232) * 10 + 8;
+		return [c, c, c];
+	}
 
-module.exports = isTypedArray;
+	args -= 16;
 
+	var rem;
+	var r = Math.floor(args / 36) / 5 * 255;
+	var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
+	var b = (rem % 6) / 5 * 255;
 
-/***/ }),
-/* 438 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	return [r, g, b];
+};
 
-var baseGetTag = __webpack_require__(46),
-    isLength = __webpack_require__(439),
-    isObjectLike = __webpack_require__(53);
+convert.rgb.hex = function (args) {
+	var integer = ((Math.round(args[0]) & 0xFF) << 16)
+		+ ((Math.round(args[1]) & 0xFF) << 8)
+		+ (Math.round(args[2]) & 0xFF);
 
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]',
-    arrayTag = '[object Array]',
-    boolTag = '[object Boolean]',
-    dateTag = '[object Date]',
-    errorTag = '[object Error]',
-    funcTag = '[object Function]',
-    mapTag = '[object Map]',
-    numberTag = '[object Number]',
-    objectTag = '[object Object]',
-    regexpTag = '[object RegExp]',
-    setTag = '[object Set]',
-    stringTag = '[object String]',
-    weakMapTag = '[object WeakMap]';
+	var string = integer.toString(16).toUpperCase();
+	return '000000'.substring(string.length) + string;
+};
 
-var arrayBufferTag = '[object ArrayBuffer]',
-    dataViewTag = '[object DataView]',
-    float32Tag = '[object Float32Array]',
-    float64Tag = '[object Float64Array]',
-    int8Tag = '[object Int8Array]',
-    int16Tag = '[object Int16Array]',
-    int32Tag = '[object Int32Array]',
-    uint8Tag = '[object Uint8Array]',
-    uint8ClampedTag = '[object Uint8ClampedArray]',
-    uint16Tag = '[object Uint16Array]',
-    uint32Tag = '[object Uint32Array]';
+convert.hex.rgb = function (args) {
+	var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
+	if (!match) {
+		return [0, 0, 0];
+	}
 
-/** Used to identify `toStringTag` values of typed arrays. */
-var typedArrayTags = {};
-typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
-typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
-typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
-typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
-typedArrayTags[uint32Tag] = true;
-typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
-typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
-typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
-typedArrayTags[errorTag] = typedArrayTags[funcTag] =
-typedArrayTags[mapTag] = typedArrayTags[numberTag] =
-typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
-typedArrayTags[setTag] = typedArrayTags[stringTag] =
-typedArrayTags[weakMapTag] = false;
+	var colorString = match[0];
 
-/**
- * The base implementation of `_.isTypedArray` without Node.js optimizations.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
- */
-function baseIsTypedArray(value) {
-  return isObjectLike(value) &&
-    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
-}
+	if (match[0].length === 3) {
+		colorString = colorString.split('').map(function (char) {
+			return char + char;
+		}).join('');
+	}
 
-module.exports = baseIsTypedArray;
+	var integer = parseInt(colorString, 16);
+	var r = (integer >> 16) & 0xFF;
+	var g = (integer >> 8) & 0xFF;
+	var b = integer & 0xFF;
 
+	return [r, g, b];
+};
 
-/***/ }),
-/* 439 */
-/***/ ((module) => {
+convert.rgb.hcg = function (rgb) {
+	var r = rgb[0] / 255;
+	var g = rgb[1] / 255;
+	var b = rgb[2] / 255;
+	var max = Math.max(Math.max(r, g), b);
+	var min = Math.min(Math.min(r, g), b);
+	var chroma = (max - min);
+	var grayscale;
+	var hue;
 
-/** Used as references for various `Number` constants. */
-var MAX_SAFE_INTEGER = 9007199254740991;
+	if (chroma < 1) {
+		grayscale = min / (1 - chroma);
+	} else {
+		grayscale = 0;
+	}
 
-/**
- * Checks if `value` is a valid array-like length.
- *
- * **Note:** This method is loosely based on
- * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
- * @example
- *
- * _.isLength(3);
- * // => true
- *
- * _.isLength(Number.MIN_VALUE);
- * // => false
- *
- * _.isLength(Infinity);
- * // => false
- *
- * _.isLength('3');
- * // => false
- */
-function isLength(value) {
-  return typeof value == 'number' &&
-    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
-}
+	if (chroma <= 0) {
+		hue = 0;
+	} else
+	if (max === r) {
+		hue = ((g - b) / chroma) % 6;
+	} else
+	if (max === g) {
+		hue = 2 + (b - r) / chroma;
+	} else {
+		hue = 4 + (r - g) / chroma + 4;
+	}
 
-module.exports = isLength;
+	hue /= 6;
+	hue %= 1;
 
+	return [hue * 360, chroma * 100, grayscale * 100];
+};
 
-/***/ }),
-/* 440 */
-/***/ ((module) => {
+convert.hsl.hcg = function (hsl) {
+	var s = hsl[1] / 100;
+	var l = hsl[2] / 100;
+	var c = 1;
+	var f = 0;
 
-/**
- * The base implementation of `_.unary` without support for storing metadata.
- *
- * @private
- * @param {Function} func The function to cap arguments for.
- * @returns {Function} Returns the new capped function.
- */
-function baseUnary(func) {
-  return function(value) {
-    return func(value);
-  };
-}
+	if (l < 0.5) {
+		c = 2.0 * s * l;
+	} else {
+		c = 2.0 * s * (1.0 - l);
+	}
 
-module.exports = baseUnary;
+	if (c < 1.0) {
+		f = (l - 0.5 * c) / (1.0 - c);
+	}
 
+	return [hsl[0], c * 100, f * 100];
+};
 
-/***/ }),
-/* 441 */
-/***/ ((module, exports, __webpack_require__) => {
+convert.hsv.hcg = function (hsv) {
+	var s = hsv[1] / 100;
+	var v = hsv[2] / 100;
 
-/* module decorator */ module = __webpack_require__.nmd(module);
-var freeGlobal = __webpack_require__(49);
+	var c = s * v;
+	var f = 0;
 
-/** Detect free variable `exports`. */
-var freeExports =  true && exports && !exports.nodeType && exports;
+	if (c < 1.0) {
+		f = (v - c) / (1 - c);
+	}
 
-/** Detect free variable `module`. */
-var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
+	return [hsv[0], c * 100, f * 100];
+};
 
-/** Detect the popular CommonJS extension `module.exports`. */
-var moduleExports = freeModule && freeModule.exports === freeExports;
+convert.hcg.rgb = function (hcg) {
+	var h = hcg[0] / 360;
+	var c = hcg[1] / 100;
+	var g = hcg[2] / 100;
 
-/** Detect free variable `process` from Node.js. */
-var freeProcess = moduleExports && freeGlobal.process;
+	if (c === 0.0) {
+		return [g * 255, g * 255, g * 255];
+	}
 
-/** Used to access faster Node.js helpers. */
-var nodeUtil = (function() {
-  try {
-    // Use `util.types` for Node.js 10+.
-    var types = freeModule && freeModule.require && freeModule.require('util').types;
+	var pure = [0, 0, 0];
+	var hi = (h % 1) * 6;
+	var v = hi % 1;
+	var w = 1 - v;
+	var mg = 0;
 
-    if (types) {
-      return types;
-    }
+	switch (Math.floor(hi)) {
+		case 0:
+			pure[0] = 1; pure[1] = v; pure[2] = 0; break;
+		case 1:
+			pure[0] = w; pure[1] = 1; pure[2] = 0; break;
+		case 2:
+			pure[0] = 0; pure[1] = 1; pure[2] = v; break;
+		case 3:
+			pure[0] = 0; pure[1] = w; pure[2] = 1; break;
+		case 4:
+			pure[0] = v; pure[1] = 0; pure[2] = 1; break;
+		default:
+			pure[0] = 1; pure[1] = 0; pure[2] = w;
+	}
 
-    // Legacy `process.binding('util')` for Node.js < 10.
-    return freeProcess && freeProcess.binding && freeProcess.binding('util');
-  } catch (e) {}
-}());
+	mg = (1.0 - c) * g;
 
-module.exports = nodeUtil;
+	return [
+		(c * pure[0] + mg) * 255,
+		(c * pure[1] + mg) * 255,
+		(c * pure[2] + mg) * 255
+	];
+};
 
+convert.hcg.hsv = function (hcg) {
+	var c = hcg[1] / 100;
+	var g = hcg[2] / 100;
 
-/***/ }),
-/* 442 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	var v = c + g * (1.0 - c);
+	var f = 0;
 
-var isPrototype = __webpack_require__(443),
-    nativeKeys = __webpack_require__(444);
+	if (v > 0.0) {
+		f = c / v;
+	}
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+	return [hcg[0], f * 100, v * 100];
+};
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+convert.hcg.hsl = function (hcg) {
+	var c = hcg[1] / 100;
+	var g = hcg[2] / 100;
 
-/**
- * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- */
-function baseKeys(object) {
-  if (!isPrototype(object)) {
-    return nativeKeys(object);
-  }
-  var result = [];
-  for (var key in Object(object)) {
-    if (hasOwnProperty.call(object, key) && key != 'constructor') {
-      result.push(key);
-    }
-  }
-  return result;
-}
+	var l = g * (1.0 - c) + 0.5 * c;
+	var s = 0;
 
-module.exports = baseKeys;
+	if (l > 0.0 && l < 0.5) {
+		s = c / (2 * l);
+	} else
+	if (l >= 0.5 && l < 1.0) {
+		s = c / (2 * (1 - l));
+	}
+
+	return [hcg[0], s * 100, l * 100];
+};
 
+convert.hcg.hwb = function (hcg) {
+	var c = hcg[1] / 100;
+	var g = hcg[2] / 100;
+	var v = c + g * (1.0 - c);
+	return [hcg[0], (v - c) * 100, (1 - v) * 100];
+};
 
-/***/ }),
-/* 443 */
-/***/ ((module) => {
+convert.hwb.hcg = function (hwb) {
+	var w = hwb[1] / 100;
+	var b = hwb[2] / 100;
+	var v = 1 - b;
+	var c = v - w;
+	var g = 0;
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+	if (c < 1) {
+		g = (v - c) / (1 - c);
+	}
 
-/**
- * Checks if `value` is likely a prototype object.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
- */
-function isPrototype(value) {
-  var Ctor = value && value.constructor,
-      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+	return [hwb[0], c * 100, g * 100];
+};
 
-  return value === proto;
-}
+convert.apple.rgb = function (apple) {
+	return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
+};
 
-module.exports = isPrototype;
+convert.rgb.apple = function (rgb) {
+	return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
+};
 
+convert.gray.rgb = function (args) {
+	return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
+};
 
-/***/ }),
-/* 444 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+convert.gray.hsl = convert.gray.hsv = function (args) {
+	return [0, 0, args[0]];
+};
 
-var overArg = __webpack_require__(445);
+convert.gray.hwb = function (gray) {
+	return [0, 100, gray[0]];
+};
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeKeys = overArg(Object.keys, Object);
+convert.gray.cmyk = function (gray) {
+	return [0, 0, 0, gray[0]];
+};
 
-module.exports = nativeKeys;
+convert.gray.lab = function (gray) {
+	return [gray[0], 0, 0];
+};
+
+convert.gray.hex = function (gray) {
+	var val = Math.round(gray[0] / 100 * 255) & 0xFF;
+	var integer = (val << 16) + (val << 8) + val;
+
+	var string = integer.toString(16).toUpperCase();
+	return '000000'.substring(string.length) + string;
+};
+
+convert.rgb.gray = function (rgb) {
+	var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
+	return [val / 255 * 100];
+};
 
 
 /***/ }),
-/* 445 */
+/* 365 */
 /***/ ((module) => {
 
-/**
- * Creates a unary function that invokes `func` with its argument transformed.
- *
- * @private
- * @param {Function} func The function to wrap.
- * @param {Function} transform The argument transform.
- * @returns {Function} Returns the new function.
- */
-function overArg(func, transform) {
-  return function(arg) {
-    return func(transform(arg));
-  };
-}
-
-module.exports = overArg;
+"use strict";
+
+
+module.exports = {
+	"aliceblue": [240, 248, 255],
+	"antiquewhite": [250, 235, 215],
+	"aqua": [0, 255, 255],
+	"aquamarine": [127, 255, 212],
+	"azure": [240, 255, 255],
+	"beige": [245, 245, 220],
+	"bisque": [255, 228, 196],
+	"black": [0, 0, 0],
+	"blanchedalmond": [255, 235, 205],
+	"blue": [0, 0, 255],
+	"blueviolet": [138, 43, 226],
+	"brown": [165, 42, 42],
+	"burlywood": [222, 184, 135],
+	"cadetblue": [95, 158, 160],
+	"chartreuse": [127, 255, 0],
+	"chocolate": [210, 105, 30],
+	"coral": [255, 127, 80],
+	"cornflowerblue": [100, 149, 237],
+	"cornsilk": [255, 248, 220],
+	"crimson": [220, 20, 60],
+	"cyan": [0, 255, 255],
+	"darkblue": [0, 0, 139],
+	"darkcyan": [0, 139, 139],
+	"darkgoldenrod": [184, 134, 11],
+	"darkgray": [169, 169, 169],
+	"darkgreen": [0, 100, 0],
+	"darkgrey": [169, 169, 169],
+	"darkkhaki": [189, 183, 107],
+	"darkmagenta": [139, 0, 139],
+	"darkolivegreen": [85, 107, 47],
+	"darkorange": [255, 140, 0],
+	"darkorchid": [153, 50, 204],
+	"darkred": [139, 0, 0],
+	"darksalmon": [233, 150, 122],
+	"darkseagreen": [143, 188, 143],
+	"darkslateblue": [72, 61, 139],
+	"darkslategray": [47, 79, 79],
+	"darkslategrey": [47, 79, 79],
+	"darkturquoise": [0, 206, 209],
+	"darkviolet": [148, 0, 211],
+	"deeppink": [255, 20, 147],
+	"deepskyblue": [0, 191, 255],
+	"dimgray": [105, 105, 105],
+	"dimgrey": [105, 105, 105],
+	"dodgerblue": [30, 144, 255],
+	"firebrick": [178, 34, 34],
+	"floralwhite": [255, 250, 240],
+	"forestgreen": [34, 139, 34],
+	"fuchsia": [255, 0, 255],
+	"gainsboro": [220, 220, 220],
+	"ghostwhite": [248, 248, 255],
+	"gold": [255, 215, 0],
+	"goldenrod": [218, 165, 32],
+	"gray": [128, 128, 128],
+	"green": [0, 128, 0],
+	"greenyellow": [173, 255, 47],
+	"grey": [128, 128, 128],
+	"honeydew": [240, 255, 240],
+	"hotpink": [255, 105, 180],
+	"indianred": [205, 92, 92],
+	"indigo": [75, 0, 130],
+	"ivory": [255, 255, 240],
+	"khaki": [240, 230, 140],
+	"lavender": [230, 230, 250],
+	"lavenderblush": [255, 240, 245],
+	"lawngreen": [124, 252, 0],
+	"lemonchiffon": [255, 250, 205],
+	"lightblue": [173, 216, 230],
+	"lightcoral": [240, 128, 128],
+	"lightcyan": [224, 255, 255],
+	"lightgoldenrodyellow": [250, 250, 210],
+	"lightgray": [211, 211, 211],
+	"lightgreen": [144, 238, 144],
+	"lightgrey": [211, 211, 211],
+	"lightpink": [255, 182, 193],
+	"lightsalmon": [255, 160, 122],
+	"lightseagreen": [32, 178, 170],
+	"lightskyblue": [135, 206, 250],
+	"lightslategray": [119, 136, 153],
+	"lightslategrey": [119, 136, 153],
+	"lightsteelblue": [176, 196, 222],
+	"lightyellow": [255, 255, 224],
+	"lime": [0, 255, 0],
+	"limegreen": [50, 205, 50],
+	"linen": [250, 240, 230],
+	"magenta": [255, 0, 255],
+	"maroon": [128, 0, 0],
+	"mediumaquamarine": [102, 205, 170],
+	"mediumblue": [0, 0, 205],
+	"mediumorchid": [186, 85, 211],
+	"mediumpurple": [147, 112, 219],
+	"mediumseagreen": [60, 179, 113],
+	"mediumslateblue": [123, 104, 238],
+	"mediumspringgreen": [0, 250, 154],
+	"mediumturquoise": [72, 209, 204],
+	"mediumvioletred": [199, 21, 133],
+	"midnightblue": [25, 25, 112],
+	"mintcream": [245, 255, 250],
+	"mistyrose": [255, 228, 225],
+	"moccasin": [255, 228, 181],
+	"navajowhite": [255, 222, 173],
+	"navy": [0, 0, 128],
+	"oldlace": [253, 245, 230],
+	"olive": [128, 128, 0],
+	"olivedrab": [107, 142, 35],
+	"orange": [255, 165, 0],
+	"orangered": [255, 69, 0],
+	"orchid": [218, 112, 214],
+	"palegoldenrod": [238, 232, 170],
+	"palegreen": [152, 251, 152],
+	"paleturquoise": [175, 238, 238],
+	"palevioletred": [219, 112, 147],
+	"papayawhip": [255, 239, 213],
+	"peachpuff": [255, 218, 185],
+	"peru": [205, 133, 63],
+	"pink": [255, 192, 203],
+	"plum": [221, 160, 221],
+	"powderblue": [176, 224, 230],
+	"purple": [128, 0, 128],
+	"rebeccapurple": [102, 51, 153],
+	"red": [255, 0, 0],
+	"rosybrown": [188, 143, 143],
+	"royalblue": [65, 105, 225],
+	"saddlebrown": [139, 69, 19],
+	"salmon": [250, 128, 114],
+	"sandybrown": [244, 164, 96],
+	"seagreen": [46, 139, 87],
+	"seashell": [255, 245, 238],
+	"sienna": [160, 82, 45],
+	"silver": [192, 192, 192],
+	"skyblue": [135, 206, 235],
+	"slateblue": [106, 90, 205],
+	"slategray": [112, 128, 144],
+	"slategrey": [112, 128, 144],
+	"snow": [255, 250, 250],
+	"springgreen": [0, 255, 127],
+	"steelblue": [70, 130, 180],
+	"tan": [210, 180, 140],
+	"teal": [0, 128, 128],
+	"thistle": [216, 191, 216],
+	"tomato": [255, 99, 71],
+	"turquoise": [64, 224, 208],
+	"violet": [238, 130, 238],
+	"wheat": [245, 222, 179],
+	"white": [255, 255, 255],
+	"whitesmoke": [245, 245, 245],
+	"yellow": [255, 255, 0],
+	"yellowgreen": [154, 205, 50]
+};
 
 
 /***/ }),
-/* 446 */
+/* 366 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var isFunction = __webpack_require__(45),
-    isLength = __webpack_require__(439);
+var conversions = __webpack_require__(364);
 
-/**
- * Checks if `value` is array-like. A value is considered array-like if it's
- * not a function and has a `value.length` that's an integer greater than or
- * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
- * @example
- *
- * _.isArrayLike([1, 2, 3]);
- * // => true
- *
- * _.isArrayLike(document.body.children);
- * // => true
- *
- * _.isArrayLike('abc');
- * // => true
- *
- * _.isArrayLike(_.noop);
- * // => false
- */
-function isArrayLike(value) {
-  return value != null && isLength(value.length) && !isFunction(value);
+/*
+	this function routes a model to all other models.
+
+	all functions that are routed have a property `.conversion` attached
+	to the returned synthetic function. This property is an array
+	of strings, each with the steps in between the 'from' and 'to'
+	color models (inclusive).
+
+	conversions that are not possible simply are not included.
+*/
+
+function buildGraph() {
+	var graph = {};
+	// https://jsperf.com/object-keys-vs-for-in-with-closure/3
+	var models = Object.keys(conversions);
+
+	for (var len = models.length, i = 0; i < len; i++) {
+		graph[models[i]] = {
+			// http://jsperf.com/1-vs-infinity
+			// micro-opt, but this is simple.
+			distance: -1,
+			parent: null
+		};
+	}
+
+	return graph;
 }
 
-module.exports = isArrayLike;
+// https://en.wikipedia.org/wiki/Breadth-first_search
+function deriveBFS(fromModel) {
+	var graph = buildGraph();
+	var queue = [fromModel]; // unshift -> queue -> pop
 
+	graph[fromModel].distance = 0;
 
-/***/ }),
-/* 447 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	while (queue.length) {
+		var current = queue.pop();
+		var adjacents = Object.keys(conversions[current]);
 
-var DataView = __webpack_require__(448),
-    Map = __webpack_require__(389),
-    Promise = __webpack_require__(449),
-    Set = __webpack_require__(450),
-    WeakMap = __webpack_require__(451),
-    baseGetTag = __webpack_require__(46),
-    toSource = __webpack_require__(375);
+		for (var len = adjacents.length, i = 0; i < len; i++) {
+			var adjacent = adjacents[i];
+			var node = graph[adjacent];
 
-/** `Object#toString` result references. */
-var mapTag = '[object Map]',
-    objectTag = '[object Object]',
-    promiseTag = '[object Promise]',
-    setTag = '[object Set]',
-    weakMapTag = '[object WeakMap]';
+			if (node.distance === -1) {
+				node.distance = graph[current].distance + 1;
+				node.parent = current;
+				queue.unshift(adjacent);
+			}
+		}
+	}
 
-var dataViewTag = '[object DataView]';
+	return graph;
+}
 
-/** Used to detect maps, sets, and weakmaps. */
-var dataViewCtorString = toSource(DataView),
-    mapCtorString = toSource(Map),
-    promiseCtorString = toSource(Promise),
-    setCtorString = toSource(Set),
-    weakMapCtorString = toSource(WeakMap);
+function link(from, to) {
+	return function (args) {
+		return to(from(args));
+	};
+}
 
-/**
- * Gets the `toStringTag` of `value`.
- *
- * @private
- * @param {*} value The value to query.
- * @returns {string} Returns the `toStringTag`.
- */
-var getTag = baseGetTag;
+function wrapConversion(toModel, graph) {
+	var path = [graph[toModel].parent, toModel];
+	var fn = conversions[graph[toModel].parent][toModel];
 
-// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
-if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
-    (Map && getTag(new Map) != mapTag) ||
-    (Promise && getTag(Promise.resolve()) != promiseTag) ||
-    (Set && getTag(new Set) != setTag) ||
-    (WeakMap && getTag(new WeakMap) != weakMapTag)) {
-  getTag = function(value) {
-    var result = baseGetTag(value),
-        Ctor = result == objectTag ? value.constructor : undefined,
-        ctorString = Ctor ? toSource(Ctor) : '';
+	var cur = graph[toModel].parent;
+	while (graph[cur].parent) {
+		path.unshift(graph[cur].parent);
+		fn = link(conversions[graph[cur].parent][cur], fn);
+		cur = graph[cur].parent;
+	}
 
-    if (ctorString) {
-      switch (ctorString) {
-        case dataViewCtorString: return dataViewTag;
-        case mapCtorString: return mapTag;
-        case promiseCtorString: return promiseTag;
-        case setCtorString: return setTag;
-        case weakMapCtorString: return weakMapTag;
-      }
-    }
-    return result;
-  };
+	fn.conversion = path;
+	return fn;
 }
 
-module.exports = getTag;
+module.exports = function (fromModel) {
+	var graph = deriveBFS(fromModel);
+	var conversion = {};
 
+	var models = Object.keys(graph);
+	for (var len = models.length, i = 0; i < len; i++) {
+		var toModel = models[i];
+		var node = graph[toModel];
 
-/***/ }),
-/* 448 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+		if (node.parent === null) {
+			// no possible conversion, or this node is the source model.
+			continue;
+		}
 
-var getNative = __webpack_require__(371),
-    root = __webpack_require__(48);
+		conversion[toModel] = wrapConversion(toModel, graph);
+	}
 
-/* Built-in method references that are verified to be native. */
-var DataView = getNative(root, 'DataView');
+	return conversion;
+};
 
-module.exports = DataView;
 
 
 /***/ }),
-/* 449 */
+/* 367 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var getNative = __webpack_require__(371),
-    root = __webpack_require__(48);
+"use strict";
 
-/* Built-in method references that are verified to be native. */
-var Promise = getNative(root, 'Promise');
+const os = __webpack_require__(253);
+const hasFlag = __webpack_require__(368);
 
-module.exports = Promise;
+const env = process.env;
 
+let forceColor;
+if (hasFlag('no-color') ||
+	hasFlag('no-colors') ||
+	hasFlag('color=false')) {
+	forceColor = false;
+} else if (hasFlag('color') ||
+	hasFlag('colors') ||
+	hasFlag('color=true') ||
+	hasFlag('color=always')) {
+	forceColor = true;
+}
+if ('FORCE_COLOR' in env) {
+	forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
+}
 
-/***/ }),
-/* 450 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function translateLevel(level) {
+	if (level === 0) {
+		return false;
+	}
 
-var getNative = __webpack_require__(371),
-    root = __webpack_require__(48);
+	return {
+		level,
+		hasBasic: true,
+		has256: level >= 2,
+		has16m: level >= 3
+	};
+}
 
-/* Built-in method references that are verified to be native. */
-var Set = getNative(root, 'Set');
+function supportsColor(stream) {
+	if (forceColor === false) {
+		return 0;
+	}
 
-module.exports = Set;
+	if (hasFlag('color=16m') ||
+		hasFlag('color=full') ||
+		hasFlag('color=truecolor')) {
+		return 3;
+	}
 
+	if (hasFlag('color=256')) {
+		return 2;
+	}
 
-/***/ }),
-/* 451 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	if (stream && !stream.isTTY && forceColor !== true) {
+		return 0;
+	}
 
-var getNative = __webpack_require__(371),
-    root = __webpack_require__(48);
+	const min = forceColor ? 1 : 0;
 
-/* Built-in method references that are verified to be native. */
-var WeakMap = getNative(root, 'WeakMap');
+	if (process.platform === 'win32') {
+		// Node.js 7.5.0 is the first version of Node.js to include a patch to
+		// libuv that enables 256 color output on Windows. Anything earlier and it
+		// won't work. However, here we target Node.js 8 at minimum as it is an LTS
+		// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
+		// release that supports 256 colors. Windows 10 build 14931 is the first release
+		// that supports 16m/TrueColor.
+		const osRelease = os.release().split('.');
+		if (
+			Number(process.versions.node.split('.')[0]) >= 8 &&
+			Number(osRelease[0]) >= 10 &&
+			Number(osRelease[2]) >= 10586
+		) {
+			return Number(osRelease[2]) >= 14931 ? 3 : 2;
+		}
 
-module.exports = WeakMap;
+		return 1;
+	}
 
+	if ('CI' in env) {
+		if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
+			return 1;
+		}
 
-/***/ }),
-/* 452 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+		return min;
+	}
 
-var isStrictComparable = __webpack_require__(453),
-    keys = __webpack_require__(429);
+	if ('TEAMCITY_VERSION' in env) {
+		return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
+	}
 
-/**
- * Gets the property names, values, and compare flags of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the match data of `object`.
- */
-function getMatchData(object) {
-  var result = keys(object),
-      length = result.length;
+	if (env.COLORTERM === 'truecolor') {
+		return 3;
+	}
 
-  while (length--) {
-    var key = result[length],
-        value = object[key];
+	if ('TERM_PROGRAM' in env) {
+		const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
 
-    result[length] = [key, value, isStrictComparable(value)];
-  }
-  return result;
-}
+		switch (env.TERM_PROGRAM) {
+			case 'iTerm.app':
+				return version >= 3 ? 3 : 2;
+			case 'Apple_Terminal':
+				return 2;
+			// No default
+		}
+	}
 
-module.exports = getMatchData;
+	if (/-256(color)?$/i.test(env.TERM)) {
+		return 2;
+	}
 
+	if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
+		return 1;
+	}
 
-/***/ }),
-/* 453 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+	if ('COLORTERM' in env) {
+		return 1;
+	}
 
-var isObject = __webpack_require__(52);
+	if (env.TERM === 'dumb') {
+		return min;
+	}
 
-/**
- * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` if suitable for strict
- *  equality comparisons, else `false`.
- */
-function isStrictComparable(value) {
-  return value === value && !isObject(value);
+	return min;
 }
 
-module.exports = isStrictComparable;
+function getSupportLevel(stream) {
+	const level = supportsColor(stream);
+	return translateLevel(level);
+}
+
+module.exports = {
+	supportsColor: getSupportLevel,
+	stdout: getSupportLevel(process.stdout),
+	stderr: getSupportLevel(process.stderr)
+};
 
 
 /***/ }),
-/* 454 */
+/* 368 */
 /***/ ((module) => {
 
-/**
- * A specialized version of `matchesProperty` for source values suitable
- * for strict equality comparisons, i.e. `===`.
- *
- * @private
- * @param {string} key The key of the property to get.
- * @param {*} srcValue The value to match.
- * @returns {Function} Returns the new spec function.
- */
-function matchesStrictComparable(key, srcValue) {
-  return function(object) {
-    if (object == null) {
-      return false;
-    }
-    return object[key] === srcValue &&
-      (srcValue !== undefined || (key in Object(object)));
-  };
-}
+"use strict";
 
-module.exports = matchesStrictComparable;
+module.exports = (flag, argv) => {
+	argv = argv || process.argv;
+	const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
+	const pos = argv.indexOf(prefix + flag);
+	const terminatorPos = argv.indexOf('--');
+	return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
+};
 
 
 /***/ }),
-/* 455 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 369 */
+/***/ ((module) => {
 
-var baseIsEqual = __webpack_require__(410),
-    get = __webpack_require__(358),
-    hasIn = __webpack_require__(456),
-    isKey = __webpack_require__(361),
-    isStrictComparable = __webpack_require__(453),
-    matchesStrictComparable = __webpack_require__(454),
-    toKey = __webpack_require__(399);
+"use strict";
 
-/** Used to compose bitmasks for value comparisons. */
-var COMPARE_PARTIAL_FLAG = 1,
-    COMPARE_UNORDERED_FLAG = 2;
+const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
+const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
+const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
+const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
 
-/**
- * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
- *
- * @private
- * @param {string} path The path of the property to get.
- * @param {*} srcValue The value to match.
- * @returns {Function} Returns the new spec function.
- */
-function baseMatchesProperty(path, srcValue) {
-  if (isKey(path) && isStrictComparable(srcValue)) {
-    return matchesStrictComparable(toKey(path), srcValue);
-  }
-  return function(object) {
-    var objValue = get(object, path);
-    return (objValue === undefined && objValue === srcValue)
-      ? hasIn(object, path)
-      : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
-  };
-}
+const ESCAPES = new Map([
+	['n', '\n'],
+	['r', '\r'],
+	['t', '\t'],
+	['b', '\b'],
+	['f', '\f'],
+	['v', '\v'],
+	['0', '\0'],
+	['\\', '\\'],
+	['e', '\u001B'],
+	['a', '\u0007']
+]);
 
-module.exports = baseMatchesProperty;
+function unescape(c) {
+	if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
+		return String.fromCharCode(parseInt(c.slice(1), 16));
+	}
 
+	return ESCAPES.get(c) || c;
+}
 
-/***/ }),
-/* 456 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function parseArguments(name, args) {
+	const results = [];
+	const chunks = args.trim().split(/\s*,\s*/g);
+	let matches;
 
-var baseHasIn = __webpack_require__(457),
-    hasPath = __webpack_require__(458);
+	for (const chunk of chunks) {
+		if (!isNaN(chunk)) {
+			results.push(Number(chunk));
+		} else if ((matches = chunk.match(STRING_REGEX))) {
+			results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
+		} else {
+			throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
+		}
+	}
 
-/**
- * Checks if `path` is a direct or inherited property of `object`.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
- * @example
- *
- * var object = _.create({ 'a': _.create({ 'b': 2 }) });
- *
- * _.hasIn(object, 'a');
- * // => true
- *
- * _.hasIn(object, 'a.b');
- * // => true
- *
- * _.hasIn(object, ['a', 'b']);
- * // => true
- *
- * _.hasIn(object, 'b');
- * // => false
- */
-function hasIn(object, path) {
-  return object != null && hasPath(object, path, baseHasIn);
+	return results;
 }
 
-module.exports = hasIn;
-
+function parseStyle(style) {
+	STYLE_REGEX.lastIndex = 0;
 
-/***/ }),
-/* 457 */
-/***/ ((module) => {
+	const results = [];
+	let matches;
 
-/**
- * The base implementation of `_.hasIn` without support for deep paths.
- *
- * @private
- * @param {Object} [object] The object to query.
- * @param {Array|string} key The key to check.
- * @returns {boolean} Returns `true` if `key` exists, else `false`.
- */
-function baseHasIn(object, key) {
-  return object != null && key in Object(object);
-}
+	while ((matches = STYLE_REGEX.exec(style)) !== null) {
+		const name = matches[1];
 
-module.exports = baseHasIn;
+		if (matches[2]) {
+			const args = parseArguments(name, matches[2]);
+			results.push([name].concat(args));
+		} else {
+			results.push([name]);
+		}
+	}
 
+	return results;
+}
 
-/***/ }),
-/* 458 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function buildStyle(chalk, styles) {
+	const enabled = {};
 
-var castPath = __webpack_require__(360),
-    isArguments = __webpack_require__(432),
-    isArray = __webpack_require__(55),
-    isIndex = __webpack_require__(436),
-    isLength = __webpack_require__(439),
-    toKey = __webpack_require__(399);
+	for (const layer of styles) {
+		for (const style of layer.styles) {
+			enabled[style[0]] = layer.inverse ? null : style.slice(1);
+		}
+	}
 
-/**
- * Checks if `path` exists on `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @param {Function} hasFunc The function to check properties.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
- */
-function hasPath(object, path, hasFunc) {
-  path = castPath(path, object);
+	let current = chalk;
+	for (const styleName of Object.keys(enabled)) {
+		if (Array.isArray(enabled[styleName])) {
+			if (!(styleName in current)) {
+				throw new Error(`Unknown Chalk style: ${styleName}`);
+			}
 
-  var index = -1,
-      length = path.length,
-      result = false;
+			if (enabled[styleName].length > 0) {
+				current = current[styleName].apply(current, enabled[styleName]);
+			} else {
+				current = current[styleName];
+			}
+		}
+	}
 
-  while (++index < length) {
-    var key = toKey(path[index]);
-    if (!(result = object != null && hasFunc(object, key))) {
-      break;
-    }
-    object = object[key];
-  }
-  if (result || ++index != length) {
-    return result;
-  }
-  length = object == null ? 0 : object.length;
-  return !!length && isLength(length) && isIndex(key, length) &&
-    (isArray(object) || isArguments(object));
+	return current;
 }
 
-module.exports = hasPath;
+module.exports = (chalk, tmp) => {
+	const styles = [];
+	const chunks = [];
+	let chunk = [];
 
+	// eslint-disable-next-line max-params
+	tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
+		if (escapeChar) {
+			chunk.push(unescape(escapeChar));
+		} else if (style) {
+			const str = chunk.join('');
+			chunk = [];
+			chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
+			styles.push({inverse, styles: parseStyle(style)});
+		} else if (close) {
+			if (styles.length === 0) {
+				throw new Error('Found extraneous } in Chalk template literal');
+			}
 
-/***/ }),
-/* 459 */
-/***/ ((module) => {
+			chunks.push(buildStyle(chalk, styles)(chunk.join('')));
+			chunk = [];
+			styles.pop();
+		} else {
+			chunk.push(chr);
+		}
+	});
 
-/**
- * This method returns the first argument it receives.
- *
- * @static
- * @since 0.1.0
- * @memberOf _
- * @category Util
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'a': 1 };
- *
- * console.log(_.identity(object) === object);
- * // => true
- */
-function identity(value) {
-  return value;
-}
+	chunks.push(chunk.join(''));
 
-module.exports = identity;
+	if (styles.length > 0) {
+		const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
+		throw new Error(errMsg);
+	}
+
+	return chunks.join('');
+};
 
 
 /***/ }),
-/* 460 */
+/* 370 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseProperty = __webpack_require__(461),
-    basePropertyDeep = __webpack_require__(462),
-    isKey = __webpack_require__(361),
-    toKey = __webpack_require__(399);
+var baseGet = __webpack_require__(371);
 
 /**
- * Creates a function that returns the value at `path` of a given object.
+ * Gets the value at `path` of `object`. If the resolved value is
+ * `undefined`, the `defaultValue` is returned in its place.
  *
  * @static
  * @memberOf _
- * @since 2.4.0
- * @category Util
+ * @since 3.7.0
+ * @category Object
+ * @param {Object} object The object to query.
  * @param {Array|string} path The path of the property to get.
- * @returns {Function} Returns the new accessor function.
+ * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @returns {*} Returns the resolved value.
  * @example
  *
- * var objects = [
- *   { 'a': { 'b': 2 } },
- *   { 'a': { 'b': 1 } }
- * ];
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  *
- * _.map(objects, _.property('a.b'));
- * // => [2, 1]
+ * _.get(object, 'a[0].b.c');
+ * // => 3
  *
- * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
- * // => [1, 2]
- */
-function property(path) {
-  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
-}
-
-module.exports = property;
-
-
-/***/ }),
-/* 461 */
-/***/ ((module) => {
-
-/**
- * The base implementation of `_.property` without support for deep paths.
+ * _.get(object, ['a', '0', 'b', 'c']);
+ * // => 3
  *
- * @private
- * @param {string} key The key of the property to get.
- * @returns {Function} Returns the new accessor function.
+ * _.get(object, 'a.b.c', 'default');
+ * // => 'default'
  */
-function baseProperty(key) {
-  return function(object) {
-    return object == null ? undefined : object[key];
-  };
+function get(object, path, defaultValue) {
+  var result = object == null ? undefined : baseGet(object, path);
+  return result === undefined ? defaultValue : result;
 }
 
-module.exports = baseProperty;
+module.exports = get;
 
 
 /***/ }),
-/* 462 */
+/* 371 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseGet = __webpack_require__(359);
+var castPath = __webpack_require__(372),
+    toKey = __webpack_require__(411);
 
 /**
- * A specialized version of `baseProperty` which supports deep paths.
+ * The base implementation of `_.get` without support for default values.
  *
  * @private
+ * @param {Object} object The object to query.
  * @param {Array|string} path The path of the property to get.
- * @returns {Function} Returns the new accessor function.
- */
-function basePropertyDeep(path) {
-  return function(object) {
-    return baseGet(object, path);
-  };
-}
-
-module.exports = basePropertyDeep;
-
-
-/***/ }),
-/* 463 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var SetCache = __webpack_require__(413),
-    arrayIncludes = __webpack_require__(464),
-    arrayIncludesWith = __webpack_require__(469),
-    cacheHas = __webpack_require__(417),
-    createSet = __webpack_require__(470),
-    setToArray = __webpack_require__(421);
-
-/** Used as the size to enable large array optimizations. */
-var LARGE_ARRAY_SIZE = 200;
-
-/**
- * The base implementation of `_.uniqBy` without support for iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Function} [iteratee] The iteratee invoked per element.
- * @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns the new duplicate free array.
+ * @returns {*} Returns the resolved value.
  */
-function baseUniq(array, iteratee, comparator) {
-  var index = -1,
-      includes = arrayIncludes,
-      length = array.length,
-      isCommon = true,
-      result = [],
-      seen = result;
+function baseGet(object, path) {
+  path = castPath(path, object);
 
-  if (comparator) {
-    isCommon = false;
-    includes = arrayIncludesWith;
-  }
-  else if (length >= LARGE_ARRAY_SIZE) {
-    var set = iteratee ? null : createSet(array);
-    if (set) {
-      return setToArray(set);
-    }
-    isCommon = false;
-    includes = cacheHas;
-    seen = new SetCache;
-  }
-  else {
-    seen = iteratee ? [] : result;
-  }
-  outer:
-  while (++index < length) {
-    var value = array[index],
-        computed = iteratee ? iteratee(value) : value;
+  var index = 0,
+      length = path.length;
 
-    value = (comparator || value !== 0) ? value : 0;
-    if (isCommon && computed === computed) {
-      var seenIndex = seen.length;
-      while (seenIndex--) {
-        if (seen[seenIndex] === computed) {
-          continue outer;
-        }
-      }
-      if (iteratee) {
-        seen.push(computed);
-      }
-      result.push(value);
-    }
-    else if (!includes(seen, computed, comparator)) {
-      if (seen !== result) {
-        seen.push(computed);
-      }
-      result.push(value);
-    }
+  while (object != null && index < length) {
+    object = object[toKey(path[index++])];
   }
-  return result;
+  return (index && index == length) ? object : undefined;
 }
 
-module.exports = baseUniq;
+module.exports = baseGet;
 
 
 /***/ }),
-/* 464 */
+/* 372 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIndexOf = __webpack_require__(465);
+var isArray = __webpack_require__(55),
+    isKey = __webpack_require__(373),
+    stringToPath = __webpack_require__(375),
+    toString = __webpack_require__(408);
 
 /**
- * A specialized version of `_.includes` for arrays without support for
- * specifying an index to search from.
+ * Casts `value` to a path array if it's not one.
  *
  * @private
- * @param {Array} [array] The array to inspect.
- * @param {*} target The value to search for.
- * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ * @param {*} value The value to inspect.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {Array} Returns the cast property path array.
  */
-function arrayIncludes(array, value) {
-  var length = array == null ? 0 : array.length;
-  return !!length && baseIndexOf(array, value, 0) > -1;
+function castPath(value, object) {
+  if (isArray(value)) {
+    return value;
+  }
+  return isKey(value, object) ? [value] : stringToPath(toString(value));
 }
 
-module.exports = arrayIncludes;
+module.exports = castPath;
 
 
 /***/ }),
-/* 465 */
+/* 373 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseFindIndex = __webpack_require__(466),
-    baseIsNaN = __webpack_require__(467),
-    strictIndexOf = __webpack_require__(468);
-
-/**
- * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
-function baseIndexOf(array, value, fromIndex) {
-  return value === value
-    ? strictIndexOf(array, value, fromIndex)
-    : baseFindIndex(array, baseIsNaN, fromIndex);
-}
-
-module.exports = baseIndexOf;
-
-
-/***/ }),
-/* 466 */
-/***/ ((module) => {
-
-/**
- * The base implementation of `_.findIndex` and `_.findLastIndex` without
- * support for iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Function} predicate The function invoked per iteration.
- * @param {number} fromIndex The index to search from.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
-function baseFindIndex(array, predicate, fromIndex, fromRight) {
-  var length = array.length,
-      index = fromIndex + (fromRight ? 1 : -1);
-
-  while ((fromRight ? index-- : ++index < length)) {
-    if (predicate(array[index], index, array)) {
-      return index;
-    }
-  }
-  return -1;
-}
-
-module.exports = baseFindIndex;
-
+var isArray = __webpack_require__(55),
+    isSymbol = __webpack_require__(374);
 
-/***/ }),
-/* 467 */
-/***/ ((module) => {
+/** Used to match property names within property paths. */
+var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
+    reIsPlainProp = /^\w*$/;
 
 /**
- * The base implementation of `_.isNaN` without support for number objects.
+ * Checks if `value` is a property name and not a property path.
  *
  * @private
  * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
- */
-function baseIsNaN(value) {
-  return value !== value;
-}
-
-module.exports = baseIsNaN;
-
-
-/***/ }),
-/* 468 */
-/***/ ((module) => {
-
-/**
- * A specialized version of `_.indexOf` which performs strict equality
- * comparisons of values, i.e. `===`.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
  */
-function strictIndexOf(array, value, fromIndex) {
-  var index = fromIndex - 1,
-      length = array.length;
-
-  while (++index < length) {
-    if (array[index] === value) {
-      return index;
-    }
+function isKey(value, object) {
+  if (isArray(value)) {
+    return false;
   }
-  return -1;
-}
-
-module.exports = strictIndexOf;
-
-
-/***/ }),
-/* 469 */
-/***/ ((module) => {
-
-/**
- * This function is like `arrayIncludes` except that it accepts a comparator.
- *
- * @private
- * @param {Array} [array] The array to inspect.
- * @param {*} target The value to search for.
- * @param {Function} comparator The comparator invoked per element.
- * @returns {boolean} Returns `true` if `target` is found, else `false`.
- */
-function arrayIncludesWith(array, value, comparator) {
-  var index = -1,
-      length = array == null ? 0 : array.length;
-
-  while (++index < length) {
-    if (comparator(value, array[index])) {
-      return true;
-    }
+  var type = typeof value;
+  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
+      value == null || isSymbol(value)) {
+    return true;
   }
-  return false;
+  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+    (object != null && value in Object(object));
 }
 
-module.exports = arrayIncludesWith;
+module.exports = isKey;
 
 
 /***/ }),
-/* 470 */
+/* 374 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var Set = __webpack_require__(450),
-    noop = __webpack_require__(471),
-    setToArray = __webpack_require__(421);
-
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0;
-
-/**
- * Creates a set object of `values`.
- *
- * @private
- * @param {Array} values The values to add to the set.
- * @returns {Object} Returns the new set.
- */
-var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
-  return new Set(values);
-};
-
-module.exports = createSet;
-
+var baseGetTag = __webpack_require__(46),
+    isObjectLike = __webpack_require__(53);
 
-/***/ }),
-/* 471 */
-/***/ ((module) => {
+/** `Object#toString` result references. */
+var symbolTag = '[object Symbol]';
 
 /**
- * This method returns `undefined`.
+ * Checks if `value` is classified as a `Symbol` primitive or object.
  *
  * @static
  * @memberOf _
- * @since 2.3.0
- * @category Util
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  * @example
  *
- * _.times(2, _.noop);
- * // => [undefined, undefined]
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
  */
-function noop() {
-  // No operation performed.
+function isSymbol(value) {
+  return typeof value == 'symbol' ||
+    (isObjectLike(value) && baseGetTag(value) == symbolTag);
 }
 
-module.exports = noop;
+module.exports = isSymbol;
 
 
 /***/ }),
-/* 472 */
+/* 375 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/**
- * Small utilities helping to develop konnectors.
- *
- * @module utils
- */
-const cozyClient = __webpack_require__(473);
-
-const groupBy = __webpack_require__(724);
-
-const keyBy = __webpack_require__(699);
-
-const sortBy = __webpack_require__(840);
-
-const range = __webpack_require__(959);
+var memoizeCapped = __webpack_require__(376);
 
-const {
-  format
-} = __webpack_require__(962);
-/**
- * This function allows to fetch all documents for a given doctype. It is the fastest to get all
- * documents but without filtering possibilities
- * deprecated by the findAll method from cozyClient
- *
- * Parameters:
- *
- * `doctype` (string): the doctype from which you want to fetch the data
- *
- */
+/** Used to match property names within property paths. */
+var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
 
+/** Used to match backslashes in property paths. */
+var reEscapeChar = /\\(\\)?/g;
 
-const fetchAll = async doctype => {
-  return cozyClient.data.findAll(doctype);
-};
 /**
- * This function allows to fetch all documents for a given doctype exceeding the 100 limit.
- * It is slower that fetchAll because it fetches the data 100 by 100 but allows to filter the data
- * with a selector and an index
- *
- * Parameters:
- *
- * `doctype` (string): the doctype from which you want to fetch the data
- * `selector` (object): the mango query selector
- * `index` (object): (optional) the query selector index. If not defined, the function will
- * create it's own index with the keys specified in the selector
- *
+ * Converts `string` to a property path array.
  *
- * ```javascript
- * const documents = await queryAll('io.cozy.bills', {vendor: 'Direct Energie'})
- * ```
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the property path array.
  */
-
-
-const queryAll = async (doctype, selector, index) => {
-  if (!selector) {
-    // fetchAll is faster in this case
-    return await cozyClient.data.findAll(doctype);
-  }
-
-  if (!index) {
-    index = await cozyClient.data.defineIndex(doctype, Object.keys(selector));
-  }
-
-  const result = [];
-  let resp = {
-    next: true
-  };
-
-  while (resp && resp.next) {
-    resp = await cozyClient.data.query(index, {
-      selector,
-      wholeResponse: true,
-      skip: result.length
-    });
-    result.push(...resp.docs);
+var stringToPath = memoizeCapped(function(string) {
+  var result = [];
+  if (string.charCodeAt(0) === 46 /* . */) {
+    result.push('');
   }
-
+  string.replace(rePropName, function(match, number, quote, subString) {
+    result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
+  });
   return result;
-};
-/**
- * This function find duplicates in a given doctype, filtered by an optional mango selector
- *
- * Parameters:
- *
- * `doctype` (string): the doctype from which you want to fetch the data
- * `selector` (object): (optional) the mango query selector
- * `options` :
- *    - `keys` (array) : List of keys used to check that two items are the same.
- *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
- *    - `selector` (optionnal object) : Mango request to get records. Gets all the records by default
- *
- * Returns an object with the following keys:
- * `toKeep`: this is the list of unique documents that you should keep in db
- * `toRemove`: this is the list of documents that can remove from db. If this is io.cozy.bills
- * documents, do not forget to clean linked bank operations
- *
- * ```javascript
- * const {toKeep, toRemove} = await findDuplicates('io.cozy.bills', {selector: {vendor: 'Direct Energie'}})
- * ```
- */
-
-
-const findDuplicates = async (doctype, options) => {
-  let hash = null;
-
-  if (options.keys) {
-    hash = doc => options.keys.map(key => {
-      let result = doc[key];
-      if (key === 'date') result = new Date(result);
-      return result;
-    }).join(',');
-  } else if (options.hash) {
-    hash = options.hash;
-  } else {
-    throw new Error('findDuplicates: you must specify keys or hash option');
-  }
+});
 
-  let documents = await queryAll(doctype, options.selector);
+module.exports = stringToPath;
 
-  if (doctype === 'io.cozy.bills') {
-    // keep the bills with the highest number of operations linked to it
-    const operations = await fetchAll('io.cozy.bank.operations');
-    documents = sortBillsByLinkedOperationNumber(documents, operations);
-  }
 
-  const groups = groupBy(documents, hash);
-  const toKeep = [];
-  const toRemove = [];
+/***/ }),
+/* 376 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  for (let key in groups) {
-    const group = groups[key];
-    toKeep.push(group[0]);
-    toRemove.push.apply(toRemove, group.slice(1).map(doc => ({ ...doc,
-      original: group[0]._id
-    })));
-  }
+var memoize = __webpack_require__(377);
 
-  return {
-    toKeep,
-    toRemove
-  };
-};
+/** Used as the maximum memoize cache size. */
+var MAX_MEMOIZE_SIZE = 500;
 
-const sortBillsByLinkedOperationNumber = (bills, operations) => {
-  bills = bills.map(bill => {
-    bill.opNb = 0;
-    return bill;
-  });
-  const billsIndex = keyBy(bills, '_id');
-  if (operations) operations.forEach(op => {
-    if (op.bills) op.bills.forEach(billId => {
-      const bill = billsIndex[billId];
-      if (bill) bill.opNb++;
-    });
-  });
-  const sorted = sortBy(Object.values(billsIndex), 'opNb').reverse();
-  return sorted;
-};
 /**
- * This is a shortcut to update multiple documents in one call
- *
- * Parameters:
- *
- * `doctype` (string): the doctype from which you want to fetch the data
- * `ids` (array): array of ids of documents to update
- * `transformation` (object): attributes to change with their values
- * `options` :
- *    - `keys` (array) : List of keys used to check that two items are the same.
- *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
- *    - `selector` (optionnal object) : Mango request to get records. Gets all the records by default
- *
- * Returns a promise which resolves with all the return values of updateAttributes
+ * A specialized version of `_.memoize` which clears the memoized function's
+ * cache when it exceeds `MAX_MEMOIZE_SIZE`.
  *
- * ```javascript
- * await batchUpdateAttributes('io.cozy.bills', [1, 2, 3], {vendor: 'Direct Energie'})
- * ```
+ * @private
+ * @param {Function} func The function to have its output memoized.
+ * @returns {Function} Returns the new memoized function.
  */
+function memoizeCapped(func) {
+  var result = memoize(func, function(key) {
+    if (cache.size === MAX_MEMOIZE_SIZE) {
+      cache.clear();
+    }
+    return key;
+  });
 
+  var cache = result.cache;
+  return result;
+}
 
-const batchUpdateAttributes = async (doctype, ids, transformation) => {
-  const result = [];
-
-  for (const id of ids) {
-    const updateResult = await cozyClient.data.updateAttributes(doctype, id, transformation);
-    result.push(updateResult);
-  }
+module.exports = memoizeCapped;
 
-  return result;
-};
-/**
- * This is a shortcut to delete multiple documents in one call
- *
- * Parameters:
- *
- * `doctype` (string): the doctype from which you want to fetch the data
- * `documents` (array): documents to delete with their ids
- * `transformation` (object): attributes to change with their values
- * `options` :
- *    - `keys` (array) : List of keys used to check that two items are the same.
- *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
- *    - `selector` (optionnal object) : Mango request to get records. Gets all the records by default
- *
- * Returns a promise which resolves with all the return values of updateAttributes
- *
- * Example to remove all the documents for a given doctype
- *
- * ```javascript
- * const documents = await fetchAll('io.cozy.marvel')
- * await batchDelete('io.cozy.marvel', documents)
- * ```
- */
 
+/***/ }),
+/* 377 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const batchDelete = async (doctype, documents) => {
-  const result = [];
+var MapCache = __webpack_require__(378);
 
-  for (const doc of documents) {
-    const deleteResult = await cozyClient.data.delete(doctype, doc);
-    result.push(deleteResult);
-  }
+/** Error message constants. */
+var FUNC_ERROR_TEXT = 'Expected a function';
 
-  return result;
-};
 /**
- * This function can read the content of a cozy pdf file and output its text
+ * Creates a function that memoizes the result of `func`. If `resolver` is
+ * provided, it determines the cache key for storing the result based on the
+ * arguments provided to the memoized function. By default, the first argument
+ * provided to the memoized function is used as the map cache key. The `func`
+ * is invoked with the `this` binding of the memoized function.
  *
- * Parameters:
+ * **Note:** The cache is exposed as the `cache` property on the memoized
+ * function. Its creation may be customized by replacing the `_.memoize.Cache`
+ * constructor with one whose instances implement the
+ * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
+ * method interface of `clear`, `delete`, `get`, `has`, and `set`.
  *
- * `fileId` (string): the id of the file in the cozy
- * `options` :
- *    - `pages` (array or number) : The list of page you want to interpret
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Function
+ * @param {Function} func The function to have its output memoized.
+ * @param {Function} [resolver] The function to resolve the cache key.
+ * @returns {Function} Returns the new memoized function.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': 2 };
+ * var other = { 'c': 3, 'd': 4 };
  *
+ * var values = _.memoize(_.values);
+ * values(object);
+ * // => [1, 2]
  *
- * You need to add pdfjs-dist package as a dependency to your connector to allow this to work
+ * values(other);
+ * // => [3, 4]
  *
- * Returns a promise which resolves with an object with the following attributes:
- *    - `text` (string) : The full text of the pdf
- *    - `1` : The full pdfjs data for page 1
- *    - `n` : The full pdfjs data for page n
+ * object.a = 2;
+ * values(object);
+ * // => [1, 2]
  *
- * Example:
+ * // Modify the result cache.
+ * values.cache.set(object, ['a', 'b']);
+ * values(object);
+ * // => ['a', 'b']
  *
- * ```javascript
- * const pdfText = (await getPdfText('887ABCFE87687')).text
- * ```
+ * // Replace `_.memoize.Cache`.
+ * _.memoize.Cache = WeakMap;
  */
+function memoize(func, resolver) {
+  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
+    throw new TypeError(FUNC_ERROR_TEXT);
+  }
+  var memoized = function() {
+    var args = arguments,
+        key = resolver ? resolver.apply(this, args) : args[0],
+        cache = memoized.cache;
 
+    if (cache.has(key)) {
+      return cache.get(key);
+    }
+    var result = func.apply(this, args);
+    memoized.cache = cache.set(key, result) || cache;
+    return result;
+  };
+  memoized.cache = new (memoize.Cache || MapCache);
+  return memoized;
+}
 
-const getPdfText = async (fileId, options = {}) => {
-  let pdfjs;
+// Expose `MapCache`.
+memoize.Cache = MapCache;
 
-  try {
-    pdfjs = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs-dist/legacy/build/pdf'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
-  } catch (err) {
-    throw new Error('pdfjs-dist dependency is missing. Please add it in your package.json');
-  }
+module.exports = memoize;
 
-  const response = await cozyClient.files.downloadById(fileId);
-  const buffer = await response.buffer();
-  const document = await pdfjs.getDocument(buffer).promise;
-  let pages;
 
-  if (options.pages) {
-    pages = Array.isArray(options.pages) ? options.pages : [options.pages];
-  } else {
-    pages = range(1, document.numPages + 1);
-  }
+/***/ }),
+/* 378 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  const result = {
-    text: ''
-  };
+var mapCacheClear = __webpack_require__(379),
+    mapCacheDelete = __webpack_require__(402),
+    mapCacheGet = __webpack_require__(405),
+    mapCacheHas = __webpack_require__(406),
+    mapCacheSet = __webpack_require__(407);
 
-  for (const pageNum of pages) {
-    const page = await document.getPage(pageNum);
-    const pageItems = (await page.getTextContent()).items;
-    result.text += pageItems.map(doc => doc.str).join('\n');
-    result[pageNum] = pageItems;
+/**
+ * Creates a map cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function MapCache(entries) {
+  var index = -1,
+      length = entries == null ? 0 : entries.length;
+
+  this.clear();
+  while (++index < length) {
+    var entry = entries[index];
+    this.set(entry[0], entry[1]);
   }
+}
 
-  return result;
-};
+// Add methods to `MapCache`.
+MapCache.prototype.clear = mapCacheClear;
+MapCache.prototype['delete'] = mapCacheDelete;
+MapCache.prototype.get = mapCacheGet;
+MapCache.prototype.has = mapCacheHas;
+MapCache.prototype.set = mapCacheSet;
+
+module.exports = MapCache;
+
+
+/***/ }),
+/* 379 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var Hash = __webpack_require__(380),
+    ListCache = __webpack_require__(393),
+    Map = __webpack_require__(401);
 
-module.exports = {
-  fetchAll,
-  queryAll,
-  findDuplicates,
-  sortBillsByLinkedOperationNumber,
-  batchUpdateAttributes,
-  batchDelete,
-  getPdfText,
-  formatDate
-};
 /**
- * This function convert a Date Object to a ISO date string (2018-07-31)
- *
- * Parameters:
- *
- * `date` (Date): the id of the file in the cozy
- *
- * Returns a string
- *
- * Example:
+ * Removes all key-value entries from the map.
  *
- * ```javascript
- * const date = formatFrenchDate(New Date.now())
- * ```
+ * @private
+ * @name clear
+ * @memberOf MapCache
  */
-
-function formatDate(date) {
-  return format(new Date(date), 'yyyy-MM-dd');
+function mapCacheClear() {
+  this.size = 0;
+  this.__data__ = {
+    'hash': new Hash,
+    'map': new (Map || ListCache),
+    'string': new Hash
+  };
 }
 
+module.exports = mapCacheClear;
+
+
 /***/ }),
-/* 473 */
+/* 380 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var hashClear = __webpack_require__(381),
+    hashDelete = __webpack_require__(389),
+    hashGet = __webpack_require__(390),
+    hashHas = __webpack_require__(391),
+    hashSet = __webpack_require__(392);
+
 /**
- * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already
- * initialized and ready to use.
+ * Creates a hash object.
  *
- * @module cozyClient
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
  */
+function Hash(entries) {
+  var index = -1,
+      length = entries == null ? 0 : entries.length;
 
-/* eslint no-console: off */
-const {
-  Client,
-  MemoryStorage
-} = __webpack_require__(474);
-
-const NewCozyClient = (__webpack_require__(509)["default"]);
+  this.clear();
+  while (++index < length) {
+    var entry = entries[index];
+    this.set(entry[0], entry[1]);
+  }
+}
 
-const {
-  models
-} = __webpack_require__(509);
+// Add methods to `Hash`.
+Hash.prototype.clear = hashClear;
+Hash.prototype['delete'] = hashDelete;
+Hash.prototype.get = hashGet;
+Hash.prototype.has = hashHas;
+Hash.prototype.set = hashSet;
 
-const globalFetch = (__webpack_require__(481)["default"]);
+module.exports = Hash;
 
-global.fetch = globalFetch;
-global.Headers = globalFetch.Headers; // fixes an import problem of isomorphic fetch in cozy-client and cozy-client-js
 
-const manifest = __webpack_require__(909);
+/***/ }),
+/* 381 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const getCozyClient = function (environment = 'production') {
-  if (environment === 'standalone' || environment === 'test') {
-    return __webpack_require__(910);
-  }
+var nativeCreate = __webpack_require__(382);
 
-  const cozyFields = JSON.parse(process.env.COZY_FIELDS || '{}');
-  const newCozyClient = NewCozyClient.fromEnv(process.env, {
-    appMetadata: {
-      slug: manifest.data.slug,
-      sourceAccount: cozyFields.account,
-      version: manifest.data.version
-    }
-  });
-  newCozyClient.models = models;
-  const cozyClient = cozyClientJsFromEnv(newCozyClient.stackClient.uri);
-  cozyClient.new = newCozyClient;
-  return cozyClient;
-};
 /**
- * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already initialized and ready to use.
- *
- * If you want to access cozy-client-js directly, this method gives you directly an instance of it,
- * initialized according to `COZY_URL` and `COZY_CREDENTIALS` environment variable given by cozy-stack
- * You can refer to the [cozy-client-js documentation](https://github.com/cozy/cozy-client-js) for more information.
- *
- * Example :
- *
- * ```javascript
- * const {cozyClient} = require('cozy-konnector-libs')
- *
- * cozyClient.data.defineIndex('my.doctype', ['_id'])
- * ```
+ * Removes all key-value entries from the hash.
  *
- * @alias module:cozyClient
+ * @private
+ * @name clear
+ * @memberOf Hash
  */
+function hashClear() {
+  this.__data__ = nativeCreate ? nativeCreate(null) : {};
+  this.size = 0;
+}
 
+module.exports = hashClear;
 
-const cozyClient = getCozyClient( // webpack 4 now changes the NODE_ENV environment variable when you change its 'mode' option
-// since we do not want to minimize the built file, we recognize the 'none' mode as production mode
-process.env.NODE_ENV === 'none' ? 'production' : process.env.NODE_ENV);
 
-function cozyClientJsFromEnv(cozyURL) {
-  const options = {
-    cozyURL
-  };
-  let jsonCredentials = null;
+/***/ }),
+/* 382 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  if (process.env.COZY_CREDENTIALS) {
-    try {
-      jsonCredentials = JSON.parse(process.env.COZY_CREDENTIALS);
-    } catch (err) {
-      options.token = process.env.COZY_CREDENTIALS;
-    }
-  }
+var getNative = __webpack_require__(383);
 
-  if (jsonCredentials) {
-    options.oauth = {
-      storage: new MemoryStorage()
-    };
-  }
+/* Built-in method references that are verified to be native. */
+var nativeCreate = getNative(Object, 'create');
 
-  const cozyClient = new Client(options);
+module.exports = nativeCreate;
 
-  if (jsonCredentials) {
-    jsonCredentials.token.toAuthHeader = function () {
-      return 'Bearer ' + jsonCredentials.client.registrationAccessToken;
-    };
 
-    cozyClient.saveCredentials(jsonCredentials.oauthOptions, jsonCredentials.token);
-  }
+/***/ }),
+/* 383 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  return cozyClient;
+var baseIsNative = __webpack_require__(384),
+    getValue = __webpack_require__(388);
+
+/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+function getNative(object, key) {
+  var value = getValue(object, key);
+  return baseIsNative(value) ? value : undefined;
 }
 
-module.exports = cozyClient;
+module.exports = getNative;
+
 
 /***/ }),
-/* 474 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 384 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
-/******/ 	// The module cache
-/******/ 	var installedModules = {};
-/******/
-/******/ 	// The require function
-/******/ 	function __nested_webpack_require_228__(moduleId) {
-/******/
-/******/ 		// Check if module is in cache
-/******/ 		if(installedModules[moduleId]) {
-/******/ 			return installedModules[moduleId].exports;
-/******/ 		}
-/******/ 		// Create a new module (and put it into the cache)
-/******/ 		var module = installedModules[moduleId] = {
-/******/ 			i: moduleId,
-/******/ 			l: false,
-/******/ 			exports: {}
-/******/ 		};
-/******/
-/******/ 		// Execute the module function
-/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_228__);
-/******/
-/******/ 		// Flag the module as loaded
-/******/ 		module.l = true;
-/******/
-/******/ 		// Return the exports of the module
-/******/ 		return module.exports;
-/******/ 	}
-/******/
-/******/
-/******/ 	// expose the modules object (__webpack_modules__)
-/******/ 	__nested_webpack_require_228__.m = modules;
-/******/
-/******/ 	// expose the module cache
-/******/ 	__nested_webpack_require_228__.c = installedModules;
-/******/
-/******/ 	// define getter function for harmony exports
-/******/ 	__nested_webpack_require_228__.d = function(exports, name, getter) {
-/******/ 		if(!__nested_webpack_require_228__.o(exports, name)) {
-/******/ 			Object.defineProperty(exports, name, {
-/******/ 				configurable: false,
-/******/ 				enumerable: true,
-/******/ 				get: getter
-/******/ 			});
-/******/ 		}
-/******/ 	};
-/******/
-/******/ 	// getDefaultExport function for compatibility with non-harmony modules
-/******/ 	__nested_webpack_require_228__.n = function(module) {
-/******/ 		var getter = module && module.__esModule ?
-/******/ 			function getDefault() { return module['default']; } :
-/******/ 			function getModuleExports() { return module; };
-/******/ 		__nested_webpack_require_228__.d(getter, 'a', getter);
-/******/ 		return getter;
-/******/ 	};
-/******/
-/******/ 	// Object.prototype.hasOwnProperty.call
-/******/ 	__nested_webpack_require_228__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-/******/
-/******/ 	// __webpack_public_path__
-/******/ 	__nested_webpack_require_228__.p = "";
-/******/
-/******/ 	// Load entry module and return exports
-/******/ 	return __nested_webpack_require_228__(__nested_webpack_require_228__.s = 9);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ (function(module, exports, __nested_webpack_require_2505__) {
+var isFunction = __webpack_require__(45),
+    isMasked = __webpack_require__(385),
+    isObject = __webpack_require__(52),
+    toSource = __webpack_require__(387);
 
-"use strict";
+/**
+ * Used to match `RegExp`
+ * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
+ */
+var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
 
+/** Used to detect host constructors (Safari). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.FetchError = undefined;
+/** Used for built-in method references. */
+var funcProto = Function.prototype,
+    objectProto = Object.prototype;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* global fetch */
+/** Used to resolve the decompiled source of functions. */
+var funcToString = funcProto.toString;
 
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-exports.cozyFetch = cozyFetch;
-exports.cozyFetchJSON = cozyFetchJSON;
-exports.cozyFetchRawJSON = cozyFetchRawJSON;
-exports.handleInvalidTokenError = handleInvalidTokenError;
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
+  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
 
-var _auth_v = __nested_webpack_require_2505__(3);
+/**
+ * The base implementation of `_.isNative` without bad shim checks.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function,
+ *  else `false`.
+ */
+function baseIsNative(value) {
+  if (!isObject(value) || isMasked(value)) {
+    return false;
+  }
+  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
+  return pattern.test(toSource(value));
+}
 
-var _utils = __nested_webpack_require_2505__(1);
+module.exports = baseIsNative;
 
-var _jsonapi = __nested_webpack_require_2505__(7);
 
-var _jsonapi2 = _interopRequireDefault(_jsonapi);
+/***/ }),
+/* 385 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+var coreJsData = __webpack_require__(386);
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+/** Used to detect methods masquerading as native. */
+var maskSrcKey = (function() {
+  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
+  return uid ? ('Symbol(src)_1.' + uid) : '';
+}());
 
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+/**
+ * Checks if `func` has its source masked.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+ */
+function isMasked(func) {
+  return !!maskSrcKey && (maskSrcKey in func);
+}
 
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+module.exports = isMasked;
 
-function cozyFetch(cozy, path) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
 
-  return cozy.fullpath(path).then(function (fullpath) {
-    var resp = void 0;
-    if (options.disableAuth) {
-      resp = fetch(fullpath, options);
-    } else if (options.manualAuthCredentials) {
-      resp = cozyFetchWithAuth(cozy, fullpath, options, options.manualAuthCredentials);
-    } else {
-      resp = cozy.authorize().then(function (credentials) {
-        return cozyFetchWithAuth(cozy, fullpath, options, credentials);
-      });
-    }
-    return resp.then(function (res) {
-      return handleResponse(res, cozy._invalidTokenErrorHandler);
-    });
-  });
-}
+/***/ }),
+/* 386 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function cozyFetchWithAuth(cozy, fullpath, options, credentials) {
-  if (credentials) {
-    options.headers = options.headers || {};
-    options.headers['Authorization'] = credentials.token.toAuthHeader();
-  }
+var root = __webpack_require__(48);
 
-  // the option credentials:include tells fetch to include the cookies in the
-  // request even for cross-origin requests
-  options.credentials = 'include';
+/** Used to detect overreaching core-js shims. */
+var coreJsData = root['__core-js_shared__'];
 
-  return Promise.all([cozy.isV2(), fetch(fullpath, options)]).then(function (_ref) {
-    var _ref2 = _slicedToArray(_ref, 2),
-        isV2 = _ref2[0],
-        res = _ref2[1];
+module.exports = coreJsData;
 
-    if (res.status !== 400 && res.status !== 401 || isV2 || !credentials || options.dontRetry) {
-      return res;
-    }
-    // we try to refresh the token only for OAuth, ie, the client defined
-    // and the token is an instance of AccessToken.
-    var client = credentials.client,
-        token = credentials.token;
 
-    if (!client || !(token instanceof _auth_v.AccessToken)) {
-      return res;
-    }
-    options.dontRetry = true;
-    return (0, _utils.retry)(function () {
-      return (0, _auth_v.refreshToken)(cozy, client, token);
-    }, 3)().then(function (newToken) {
-      return cozy.saveCredentials(client, newToken);
-    }).then(function (credentials) {
-      return cozyFetchWithAuth(cozy, fullpath, options, credentials);
-    });
-  });
-}
+/***/ }),
+/* 387 */
+/***/ ((module) => {
 
-function cozyFetchJSON(cozy, method, path, body) {
-  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+/** Used for built-in method references. */
+var funcProto = Function.prototype;
 
-  var processJSONAPI = typeof options.processJSONAPI === 'undefined' || options.processJSONAPI;
-  return fetchJSON(cozy, method, path, body, options).then(function (response) {
-    return handleJSONResponse(response, processJSONAPI);
-  });
+/** Used to resolve the decompiled source of functions. */
+var funcToString = funcProto.toString;
+
+/**
+ * Converts `func` to its source code.
+ *
+ * @private
+ * @param {Function} func The function to convert.
+ * @returns {string} Returns the source code.
+ */
+function toSource(func) {
+  if (func != null) {
+    try {
+      return funcToString.call(func);
+    } catch (e) {}
+    try {
+      return (func + '');
+    } catch (e) {}
+  }
+  return '';
 }
 
-function cozyFetchRawJSON(cozy, method, path, body) {
-  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+module.exports = toSource;
 
-  return fetchJSON(cozy, method, path, body, options).then(function (response) {
-    return handleJSONResponse(response, false);
-  });
-}
 
-function fetchJSON(cozy, method, path, body) {
-  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+/***/ }),
+/* 388 */
+/***/ ((module) => {
 
-  options.method = method;
+/**
+ * Gets the value at `key` of `object`.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
+ */
+function getValue(object, key) {
+  return object == null ? undefined : object[key];
+}
 
-  var headers = options.headers = options.headers || {};
+module.exports = getValue;
 
-  headers['Accept'] = 'application/json';
 
-  if (method !== 'GET' && method !== 'HEAD' && body !== undefined) {
-    if (headers['Content-Type']) {
-      options.body = body;
-    } else {
-      headers['Content-Type'] = 'application/json';
-      options.body = JSON.stringify(body);
-    }
-  }
+/***/ }),
+/* 389 */
+/***/ ((module) => {
 
-  return cozyFetch(cozy, path, options);
+/**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @name delete
+ * @memberOf Hash
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function hashDelete(key) {
+  var result = this.has(key) && delete this.__data__[key];
+  this.size -= result ? 1 : 0;
+  return result;
 }
 
-function handleResponse(res, invalidTokenErrorHandler) {
-  if (res.ok) {
-    return res;
-  }
-  var data = void 0;
-  var contentType = res.headers.get('content-type');
-  if (contentType && contentType.indexOf('json') >= 0) {
-    data = res.json();
-  } else {
-    data = res.text();
-  }
-  return data.then(function (err) {
-    var error = new FetchError(res, err);
-    if (FetchError.isInvalidToken(error) && invalidTokenErrorHandler) {
-      invalidTokenErrorHandler(error);
-    }
-    throw error;
-  });
-}
+module.exports = hashDelete;
 
-function handleJSONResponse(res) {
-  var processJSONAPI = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
 
-  var contentType = res.headers.get('content-type');
-  if (!contentType || contentType.indexOf('json') < 0) {
-    return res.text(function (data) {
-      throw new FetchError(res, new Error('Response is not JSON: ' + data));
-    });
-  }
+/***/ }),
+/* 390 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var json = res.json();
-  if (contentType.indexOf('application/vnd.api+json') === 0 && processJSONAPI) {
-    return json.then(_jsonapi2.default);
-  } else {
-    return json;
-  }
-}
+var nativeCreate = __webpack_require__(382);
 
-function handleInvalidTokenError(error) {
-  try {
-    var currentOrigin = window.location.origin;
-    var requestUrl = error.url;
+/** Used to stand-in for `undefined` hash values. */
+var HASH_UNDEFINED = '__lodash_hash_undefined__';
 
-    if (requestUrl.indexOf(currentOrigin.replace(/^(https?:\/\/\w+)-\w+\./, '$1.')) === 0) {
-      var redirectURL = currentOrigin + '?' + (0, _utils.encodeQuery)({ disconnect: 1 });
-      window.location = redirectURL;
-    }
-  } catch (e) {
-    console.warn('Unable to handle invalid token error', e, error);
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Hash
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function hashGet(key) {
+  var data = this.__data__;
+  if (nativeCreate) {
+    var result = data[key];
+    return result === HASH_UNDEFINED ? undefined : result;
   }
+  return hasOwnProperty.call(data, key) ? data[key] : undefined;
 }
 
-var FetchError = exports.FetchError = function (_Error) {
-  _inherits(FetchError, _Error);
+module.exports = hashGet;
 
-  function FetchError(res, reason) {
-    _classCallCheck(this, FetchError);
 
-    var _this = _possibleConstructorReturn(this, (FetchError.__proto__ || Object.getPrototypeOf(FetchError)).call(this));
+/***/ }),
+/* 391 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    if (Error.captureStackTrace) {
-      Error.captureStackTrace(_this, _this.constructor);
-    }
-    // XXX We have to hardcode this because babel doesn't play nice when extending Error
-    _this.name = 'FetchError';
-    _this.response = res;
-    _this.url = res.url;
-    _this.status = res.status;
-    _this.reason = reason;
+var nativeCreate = __webpack_require__(382);
 
-    Object.defineProperty(_this, 'message', {
-      value: reason.message || (typeof reason === 'string' ? reason : JSON.stringify(reason))
-    });
-    return _this;
-  }
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-  return FetchError;
-}(Error);
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-FetchError.isUnauthorized = function (err) {
-  // XXX We can't use err instanceof FetchError because of the caveats of babel
-  return err.name === 'FetchError' && err.status === 401;
-};
+/**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Hash
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function hashHas(key) {
+  var data = this.__data__;
+  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
+}
 
-FetchError.isNotFound = function (err) {
-  // XXX We can't use err instanceof FetchError because of the caveats of babel
-  return err.name === 'FetchError' && err.status === 404;
-};
+module.exports = hashHas;
 
-FetchError.isInvalidToken = function (err) {
-  // XXX We can't use err instanceof FetchError because of the caveats of babel
-  return err.name === 'FetchError' && err.status === 400 && err.reason && (err.reason.error === 'Invalid JWT token' || err.reason.error === 'Expired token');
-};
 
 /***/ }),
-/* 1 */
-/***/ (function(module, exports, __webpack_require__) {
+/* 392 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var nativeCreate = __webpack_require__(382);
 
+/** Used to stand-in for `undefined` hash values. */
+var HASH_UNDEFINED = '__lodash_hash_undefined__';
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.unpromiser = unpromiser;
-exports.isPromise = isPromise;
-exports.isOnline = isOnline;
-exports.isOffline = isOffline;
-exports.sleep = sleep;
-exports.retry = retry;
-exports.getFuzzedDelay = getFuzzedDelay;
-exports.getBackedoffDelay = getBackedoffDelay;
-exports.createPath = createPath;
-exports.encodeQuery = encodeQuery;
-exports.decodeQuery = decodeQuery;
-exports.warn = warn;
-/* global navigator */
-var FuzzFactor = 0.3;
+/**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Hash
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the hash instance.
+ */
+function hashSet(key, value) {
+  var data = this.__data__;
+  this.size += this.has(key) ? 0 : 1;
+  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+  return this;
+}
 
-function unpromiser(fn) {
-  return function () {
-    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-      args[_key] = arguments[_key];
-    }
+module.exports = hashSet;
 
-    var value = fn.apply(this, args);
-    if (!isPromise(value)) {
-      return value;
-    }
-    var l = args.length;
-    if (l === 0 || typeof args[l - 1] !== 'function') {
-      return;
-    }
-    var cb = args[l - 1];
-    value.then(function (res) {
-      return cb(null, res);
-    }, function (err) {
-      return cb(err, null);
-    });
-  };
-}
 
-function isPromise(value) {
-  return !!value && typeof value.then === 'function';
-}
+/***/ }),
+/* 393 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function isOnline() {
-  return typeof navigator !== 'undefined' ? navigator.onLine : true;
-}
+var listCacheClear = __webpack_require__(394),
+    listCacheDelete = __webpack_require__(395),
+    listCacheGet = __webpack_require__(398),
+    listCacheHas = __webpack_require__(399),
+    listCacheSet = __webpack_require__(400);
 
-function isOffline() {
-  return !isOnline();
-}
+/**
+ * Creates an list cache object.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function ListCache(entries) {
+  var index = -1,
+      length = entries == null ? 0 : entries.length;
 
-function sleep(time, args) {
-  return new Promise(function (resolve) {
-    setTimeout(resolve, time, args);
-  });
+  this.clear();
+  while (++index < length) {
+    var entry = entries[index];
+    this.set(entry[0], entry[1]);
+  }
 }
 
-function retry(fn, count) {
-  var delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 300;
+// Add methods to `ListCache`.
+ListCache.prototype.clear = listCacheClear;
+ListCache.prototype['delete'] = listCacheDelete;
+ListCache.prototype.get = listCacheGet;
+ListCache.prototype.has = listCacheHas;
+ListCache.prototype.set = listCacheSet;
 
-  return function doTry() {
-    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
-      args[_key2] = arguments[_key2];
-    }
+module.exports = ListCache;
 
-    return fn.apply(undefined, args).catch(function (err) {
-      if (--count < 0) {
-        throw err;
-      }
-      return sleep(getBackedoffDelay(delay, count)).then(function () {
-        return doTry.apply(undefined, args);
-      });
-    });
-  };
-}
 
-function getFuzzedDelay(retryDelay) {
-  var fuzzingFactor = (Math.random() * 2 - 1) * FuzzFactor;
-  return retryDelay * (1.0 + fuzzingFactor);
+/***/ }),
+/* 394 */
+/***/ ((module) => {
+
+/**
+ * Removes all key-value entries from the list cache.
+ *
+ * @private
+ * @name clear
+ * @memberOf ListCache
+ */
+function listCacheClear() {
+  this.__data__ = [];
+  this.size = 0;
 }
 
-function getBackedoffDelay(retryDelay) {
-  var retryCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
+module.exports = listCacheClear;
 
-  return getFuzzedDelay(retryDelay * Math.pow(2, retryCount - 1));
-}
 
-function createPath(cozy, isV2, doctype) {
-  var id = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
-  var query = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
+/***/ }),
+/* 395 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var route = '/data/';
-  if (!isV2) {
-    route += encodeURIComponent(doctype) + '/';
-  }
-  if (id !== '') {
-    route += encodeURIComponent(id);
-  }
-  var q = encodeQuery(query);
-  if (q !== '') {
-    route += '?' + q;
-  }
-  return route;
-}
+var assocIndexOf = __webpack_require__(396);
 
-function encodeQuery(query) {
-  if (!query) {
-    return '';
+/** Used for built-in method references. */
+var arrayProto = Array.prototype;
+
+/** Built-in value references. */
+var splice = arrayProto.splice;
+
+/**
+ * Removes `key` and its value from the list cache.
+ *
+ * @private
+ * @name delete
+ * @memberOf ListCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function listCacheDelete(key) {
+  var data = this.__data__,
+      index = assocIndexOf(data, key);
+
+  if (index < 0) {
+    return false;
   }
-  var q = '';
-  for (var qname in query) {
-    if (q !== '') {
-      q += '&';
-    }
-    q += encodeURIComponent(qname) + '=' + encodeURIComponent(query[qname]);
+  var lastIndex = data.length - 1;
+  if (index == lastIndex) {
+    data.pop();
+  } else {
+    splice.call(data, index, 1);
   }
-  return q;
+  --this.size;
+  return true;
 }
 
-function decodeQuery(url) {
-  var queryIndex = url.indexOf('?');
-  if (queryIndex < 0) {
-    queryIndex = url.length;
-  }
-  var queries = {};
-  var fragIndex = url.indexOf('#');
-  if (fragIndex < 0) {
-    fragIndex = url.length;
-  }
-  if (fragIndex < queryIndex) {
-    return queries;
-  }
-  var queryStr = url.slice(queryIndex + 1, fragIndex);
-  if (queryStr === '') {
-    return queries;
-  }
-  var parts = queryStr.split('&');
-  for (var i = 0; i < parts.length; i++) {
-    var pair = parts[i].split('=');
-    if (pair.length === 0 || pair[0] === '') {
-      continue;
-    }
-    var qname = decodeURIComponent(pair[0]);
-    if (queries.hasOwnProperty(qname)) {
-      continue;
-    }
-    if (pair.length === 1) {
-      queries[qname] = true;
-    } else if (pair.length === 2) {
-      queries[qname] = decodeURIComponent(pair[1]);
-    } else {
-      throw new Error('Malformed URL');
+module.exports = listCacheDelete;
+
+
+/***/ }),
+/* 396 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var eq = __webpack_require__(397);
+
+/**
+ * Gets the index at which the `key` is found in `array` of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function assocIndexOf(array, key) {
+  var length = array.length;
+  while (length--) {
+    if (eq(array[length][0], key)) {
+      return length;
     }
   }
-  return queries;
+  return -1;
 }
 
-var warned = [];
-function warn(text) {
-  if (warned.indexOf(text) === -1) {
-    warned.push(text);
-    console.warn('cozy-client-js', text);
-  }
+module.exports = assocIndexOf;
+
+
+/***/ }),
+/* 397 */
+/***/ ((module) => {
+
+/**
+ * Performs a
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+function eq(value, other) {
+  return value === other || (value !== value && other !== other);
 }
 
+module.exports = eq;
+
+
 /***/ }),
-/* 2 */
-/***/ (function(module, exports, __nested_webpack_require_15027__) {
+/* 398 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var assocIndexOf = __webpack_require__(396);
 
+/**
+ * Gets the list cache value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf ListCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function listCacheGet(key) {
+  var data = this.__data__,
+      index = assocIndexOf(data, key);
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.DOCTYPE_FILES = undefined;
-exports.normalizeDoctype = normalizeDoctype;
+  return index < 0 ? undefined : data[index][1];
+}
 
-var _utils = __nested_webpack_require_15027__(1);
+module.exports = listCacheGet;
 
-var DOCTYPE_FILES = exports.DOCTYPE_FILES = 'io.cozy.files';
 
-var KNOWN_DOCTYPES = {
-  files: DOCTYPE_FILES,
-  folder: DOCTYPE_FILES,
-  contact: 'io.cozy.contacts',
-  event: 'io.cozy.events',
-  track: 'io.cozy.labs.music.track',
-  playlist: 'io.cozy.labs.music.playlist'
-};
+/***/ }),
+/* 399 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var REVERSE_KNOWN = {};
-Object.keys(KNOWN_DOCTYPES).forEach(function (k) {
-  REVERSE_KNOWN[KNOWN_DOCTYPES[k]] = k;
-});
+var assocIndexOf = __webpack_require__(396);
 
-function normalizeDoctype(cozy, isV2, doctype) {
-  var isQualified = doctype.indexOf('.') !== -1;
-  if (isV2 && isQualified) {
-    var known = REVERSE_KNOWN[doctype];
-    if (known) return known;
-    return doctype.replace(/\./g, '-');
-  }
-  if (!isV2 && !isQualified) {
-    var _known = KNOWN_DOCTYPES[doctype];
-    if (_known) {
-      (0, _utils.warn)('you are using a non-qualified doctype ' + doctype + ' assumed to be ' + _known);
-      return _known;
-    }
-    throw new Error('Doctype ' + doctype + ' should be qualified.');
-  }
-  return doctype;
+/**
+ * Checks if a list cache value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf ListCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function listCacheHas(key) {
+  return assocIndexOf(this.__data__, key) > -1;
 }
 
-/***/ }),
-/* 3 */
-/***/ (function(module, exports, __nested_webpack_require_16254__) {
+module.exports = listCacheHas;
 
-"use strict";
-/* WEBPACK VAR INJECTION */(function(btoa) {
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.AppToken = exports.AccessToken = exports.Client = exports.StateKey = exports.CredsKey = undefined;
+/***/ }),
+/* 400 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+var assocIndexOf = __webpack_require__(396);
 
-var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global btoa */
+/**
+ * Sets the list cache `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf ListCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the list cache instance.
+ */
+function listCacheSet(key, value) {
+  var data = this.__data__,
+      index = assocIndexOf(data, key);
 
+  if (index < 0) {
+    ++this.size;
+    data.push([key, value]);
+  } else {
+    data[index][1] = value;
+  }
+  return this;
+}
 
-exports.client = client;
-exports.registerClient = registerClient;
-exports.updateClient = updateClient;
-exports.unregisterClient = unregisterClient;
-exports.getClient = getClient;
-exports.getAuthCodeURL = getAuthCodeURL;
-exports.getAccessToken = getAccessToken;
-exports.refreshToken = refreshToken;
-exports.oauthFlow = oauthFlow;
+module.exports = listCacheSet;
 
-var _utils = __nested_webpack_require_16254__(1);
 
-var _fetch = __nested_webpack_require_16254__(0);
+/***/ }),
+/* 401 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+var getNative = __webpack_require__(383),
+    root = __webpack_require__(48);
 
-var StateSize = 16;
+/* Built-in method references that are verified to be native. */
+var Map = getNative(root, 'Map');
 
-var CredsKey = exports.CredsKey = 'creds';
-var StateKey = exports.StateKey = 'state';
+module.exports = Map;
 
-var Client = exports.Client = function () {
-  function Client(opts) {
-    _classCallCheck(this, Client);
 
-    this.clientID = opts.clientID || opts.client_id || '';
-    this.clientSecret = opts.clientSecret || opts.client_secret || '';
-    this.registrationAccessToken = opts.registrationAccessToken || opts.registration_access_token || '';
+/***/ }),
+/* 402 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    if (opts.redirect_uris) {
-      this.redirectURI = opts.redirect_uris[0] || '';
-    } else {
-      this.redirectURI = opts.redirectURI || '';
-    }
+var getMapData = __webpack_require__(403);
 
-    this.softwareID = opts.softwareID || opts.software_id || '';
-    this.softwareVersion = opts.softwareVersion || opts.software_version || '';
-    this.clientName = opts.clientName || opts.client_name || '';
-    this.clientKind = opts.clientKind || opts.client_kind || '';
-    this.clientURI = opts.clientURI || opts.client_uri || '';
+/**
+ * Removes `key` and its value from the map.
+ *
+ * @private
+ * @name delete
+ * @memberOf MapCache
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function mapCacheDelete(key) {
+  var result = getMapData(this, key)['delete'](key);
+  this.size -= result ? 1 : 0;
+  return result;
+}
 
-    this.logoURI = opts.logoURI || opts.logo_uri || '';
-    this.policyURI = opts.policyURI || opts.policy_uri || '';
+module.exports = mapCacheDelete;
 
-    this.notificationPlatform = opts.notificationPlatform || opts.notification_platform || '';
-    this.notificationDeviceToken = opts.notificationDeviceToken || opts.notification_device_token || '';
 
-    if (!this.registrationAccessToken) {
-      if (this.redirectURI === '') {
-        throw new Error('Missing redirectURI field');
-      }
-      if (this.softwareID === '') {
-        throw new Error('Missing softwareID field');
-      }
-      if (this.clientName === '') {
-        throw new Error('Missing clientName field');
-      }
-    }
-  }
+/***/ }),
+/* 403 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  _createClass(Client, [{
-    key: 'isRegistered',
-    value: function isRegistered() {
-      return this.clientID !== '';
-    }
-  }, {
-    key: 'toRegisterJSON',
-    value: function toRegisterJSON() {
-      return {
-        redirect_uris: [this.redirectURI],
-        software_id: this.softwareID,
-        software_version: this.softwareVersion,
-        client_name: this.clientName,
-        client_kind: this.clientKind,
-        client_uri: this.clientURI,
-        logo_uri: this.logoURI,
-        policy_uri: this.policyURI,
-        notification_platform: this.notificationPlatform,
-        notification_device_token: this.notificationDeviceToken
-      };
-    }
-  }, {
-    key: 'toAuthHeader',
-    value: function toAuthHeader() {
-      return 'Bearer ' + this.registrationAccessToken;
-    }
-  }]);
+var isKeyable = __webpack_require__(404);
 
-  return Client;
-}();
+/**
+ * Gets the data for `map`.
+ *
+ * @private
+ * @param {Object} map The map to query.
+ * @param {string} key The reference key.
+ * @returns {*} Returns the map data.
+ */
+function getMapData(map, key) {
+  var data = map.__data__;
+  return isKeyable(key)
+    ? data[typeof key == 'string' ? 'string' : 'hash']
+    : data.map;
+}
 
-var AccessToken = exports.AccessToken = function () {
-  function AccessToken(opts) {
-    _classCallCheck(this, AccessToken);
+module.exports = getMapData;
 
-    this.tokenType = opts.tokenType || opts.token_type;
-    this.accessToken = opts.accessToken || opts.access_token;
-    this.refreshToken = opts.refreshToken || opts.refresh_token;
-    this.scope = opts.scope;
-  }
 
-  _createClass(AccessToken, [{
-    key: 'toAuthHeader',
-    value: function toAuthHeader() {
-      return 'Bearer ' + this.accessToken;
-    }
-  }, {
-    key: 'toBasicAuth',
-    value: function toBasicAuth() {
-      return 'user:' + this.accessToken + '@';
-    }
-  }]);
+/***/ }),
+/* 404 */
+/***/ ((module) => {
 
-  return AccessToken;
-}();
+/**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */
+function isKeyable(value) {
+  var type = typeof value;
+  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
+    ? (value !== '__proto__')
+    : (value === null);
+}
 
-var AppToken = exports.AppToken = function () {
-  function AppToken(opts) {
-    _classCallCheck(this, AppToken);
+module.exports = isKeyable;
 
-    this.token = opts.token || '';
-  }
 
-  _createClass(AppToken, [{
-    key: 'toAuthHeader',
-    value: function toAuthHeader() {
-      return 'Bearer ' + this.token;
-    }
-  }, {
-    key: 'toBasicAuth',
-    value: function toBasicAuth() {
-      return 'user:' + this.token + '@';
-    }
-  }]);
+/***/ }),
+/* 405 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  return AppToken;
-}();
+var getMapData = __webpack_require__(403);
 
-function client(cozy, clientParams) {
-  if (!clientParams) {
-    clientParams = cozy._clientParams;
-  }
-  if (clientParams instanceof Client) {
-    return clientParams;
-  }
-  return new Client(clientParams);
+/**
+ * Gets the map value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf MapCache
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function mapCacheGet(key) {
+  return getMapData(this, key).get(key);
 }
 
-function registerClient(cozy, clientParams) {
-  var cli = client(cozy, clientParams);
-  if (cli.isRegistered()) {
-    return Promise.reject(new Error('Client already registered'));
-  }
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/register', cli.toRegisterJSON(), {
-    disableAuth: true
-  }).then(function (data) {
-    return new Client(data);
-  });
-}
+module.exports = mapCacheGet;
 
-function updateClient(cozy, clientParams) {
-  var resetSecret = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
 
-  var cli = client(cozy, clientParams);
-  if (!cli.isRegistered()) {
-    return Promise.reject(new Error('Client not registered'));
-  }
-  var data = cli.toRegisterJSON();
-  data.client_id = cli.clientID;
-  if (resetSecret) data.client_secret = cli.clientSecret;
+/***/ }),
+/* 406 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/auth/register/' + cli.clientID, data, {
-    manualAuthCredentials: {
-      token: cli
-    }
-  }).then(function (data) {
-    return createClient(data, cli);
-  });
-}
+var getMapData = __webpack_require__(403);
 
-function unregisterClient(cozy, clientParams) {
-  var cli = client(cozy, clientParams);
-  if (!cli.isRegistered()) {
-    return Promise.reject(new Error('Client not registered'));
-  }
-  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/auth/register/' + cli.clientID, null, {
-    manualAuthCredentials: {
-      token: cli
-    }
-  });
+/**
+ * Checks if a map value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf MapCache
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function mapCacheHas(key) {
+  return getMapData(this, key).has(key);
 }
 
-// getClient will retrive the registered client informations from the server.
-function getClient(cozy, clientParams) {
-  var cli = client(cozy, clientParams);
-  if (!cli.isRegistered()) {
-    return Promise.reject(new Error('Client not registered'));
-  }
-  if ((0, _utils.isOffline)()) {
-    return Promise.resolve(cli);
-  }
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/auth/register/' + cli.clientID, null, {
-    manualAuthCredentials: {
-      token: cli
-    }
-  }).then(function (data) {
-    return createClient(data, cli);
-  }).catch(function (err) {
-    // If we fall into an error while fetching the client (because of a
-    // bad connectivity for instance), we do not bail the whole process
-    // since the client should be able to continue with the persisted
-    // client and token.
-    //
-    // If it is an explicit Unauthorized error though, we bail, clear th
-    // cache and retry.
-    if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) {
-      throw new Error('Client has been revoked');
-    }
-    throw err;
-  });
-}
+module.exports = mapCacheHas;
 
-// createClient returns a new Client instance given on object containing the
-// data of the client, from the API, and an old instance of the client.
-function createClient(data, oldClient) {
-  var newClient = new Client(data);
-  // we need to keep track of the registrationAccessToken since it is send
-  // only on registration. The GET /auth/register/:client-id endpoint does
-  // not return this token.
-  var shouldPassRegistration = !!oldClient && oldClient.registrationAccessToken !== '' && newClient.registrationAccessToken === '';
-  if (shouldPassRegistration) {
-    newClient.registrationAccessToken = oldClient.registrationAccessToken;
-  }
-  return newClient;
-}
 
-// getAuthCodeURL returns a pair {authURL,state} given a registered client. The
-// state should be stored in order to be checked against on the user validation
-// phase.
-function getAuthCodeURL(cozy, client) {
-  var scopes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
+/***/ }),
+/* 407 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  if (!(client instanceof Client)) {
-    client = new Client(client);
-  }
-  if (!client.isRegistered()) {
-    throw new Error('Client not registered');
-  }
-  var state = generateRandomState();
-  var query = {
-    client_id: client.clientID,
-    redirect_uri: client.redirectURI,
-    state: state,
-    response_type: 'code',
-    scope: scopes.join(' ')
-  };
-  return {
-    url: cozy._url + ('/auth/authorize?' + (0, _utils.encodeQuery)(query)),
-    state: state
-  };
-}
+var getMapData = __webpack_require__(403);
 
-// getAccessToken perform a request on the access_token entrypoint with the
-// authorization_code grant type in order to generate a new access token for a
-// newly registered client.
-//
-// This method extracts the access code and state from the given URL. By
-// default it uses window.location.href. Also, it checks the given state with
-// the one specified in the URL query parameter to prevent CSRF attacks.
-function getAccessToken(cozy, client, state) {
-  var pageURL = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
+/**
+ * Sets the map `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache instance.
+ */
+function mapCacheSet(key, value) {
+  var data = getMapData(this, key),
+      size = data.size;
 
-  if (!state) {
-    return Promise.reject(new Error('Missing state value'));
-  }
-  var grantQueries = getGrantCodeFromPageURL(pageURL);
-  if (grantQueries === null) {
-    return Promise.reject(new Error('Missing states from current URL'));
-  }
-  if (state !== grantQueries.state) {
-    return Promise.reject(new Error('Given state does not match url query state'));
-  }
-  return retrieveToken(cozy, client, null, {
-    grant_type: 'authorization_code',
-    code: grantQueries.code
-  });
+  data.set(key, value);
+  this.size += data.size == size ? 0 : 1;
+  return this;
 }
 
-// refreshToken perform a request on the access_token entrypoint with the
-// refresh_token grant type in order to refresh the given token.
-function refreshToken(cozy, client, token) {
-  return retrieveToken(cozy, client, token, {
-    grant_type: 'refresh_token',
-    refresh_token: token.refreshToken
-  });
-}
+module.exports = mapCacheSet;
 
-// oauthFlow performs the stateful registration and access granting of an OAuth
-// client.
-function oauthFlow(cozy, storage, clientParams, onRegistered) {
-  var ignoreCachedCredentials = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
 
-  if (ignoreCachedCredentials) {
-    return storage.clear().then(function () {
-      return oauthFlow(cozy, storage, clientParams, onRegistered, false);
-    });
-  }
+/***/ }),
+/* 408 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var tryCount = 0;
+var baseToString = __webpack_require__(409);
 
-  function clearAndRetry(err) {
-    if (tryCount++ > 0) {
-      throw err;
-    }
-    return storage.clear().then(function () {
-      return oauthFlow(cozy, storage, clientParams, onRegistered);
-    });
-  }
+/**
+ * Converts `value` to a string. An empty string is returned for `null`
+ * and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+function toString(value) {
+  return value == null ? '' : baseToString(value);
+}
 
-  function registerNewClient() {
-    return storage.clear().then(function () {
-      return registerClient(cozy, clientParams);
-    }).then(function (client) {
-      var _getAuthCodeURL = getAuthCodeURL(cozy, client, clientParams.scopes),
-          url = _getAuthCodeURL.url,
-          state = _getAuthCodeURL.state;
+module.exports = toString;
 
-      return storage.save(StateKey, { client: client, url: url, state: state });
-    });
-  }
 
-  return Promise.all([storage.load(CredsKey), storage.load(StateKey)]).then(function (_ref) {
-    var _ref2 = _slicedToArray(_ref, 2),
-        credentials = _ref2[0],
-        storedState = _ref2[1];
+/***/ }),
+/* 409 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    // If credentials are cached we re-fetch the registered client with the
-    // said token. Fetching the client, if the token is outdated we should try
-    // the token is refreshed.
-    if (credentials) {
-      var oldClient = void 0,
-          _token = void 0;
-      try {
-        oldClient = new Client(credentials.client);
-        _token = new AccessToken(credentials.token);
-      } catch (err) {
-        // bad cache, we should clear and retry the process
-        return clearAndRetry(err);
-      }
-      return getClient(cozy, oldClient).then(function (client) {
-        return { client: client, token: _token };
-      }).catch(function (err) {
-        // If we fall into an error while fetching the client (because of a
-        // bad connectivity for instance), we do not bail the whole process
-        // since the client should be able to continue with the persisted
-        // client and token.
-        //
-        // If it is an explicit Unauthorized error though, we bail, clear th
-        // cache and retry.
-        if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) {
-          throw new Error('Client has been revoked');
-        }
-        return { client: oldClient, token: _token };
-      });
-    }
+var Symbol = __webpack_require__(47),
+    arrayMap = __webpack_require__(410),
+    isArray = __webpack_require__(55),
+    isSymbol = __webpack_require__(374);
 
-    // Otherwise register a new client if necessary (ie. no client is stored)
-    // and call the onRegistered callback to wait for the user to grant the
-    // access. Finally fetches to access token on success.
-    var statePromise = void 0;
-    if (!storedState) {
-      statePromise = registerNewClient();
-    } else {
-      statePromise = Promise.resolve(storedState);
-    }
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0;
 
-    var client = void 0,
-        state = void 0,
-        token = void 0;
-    return statePromise.then(function (data) {
-      client = data.client;
-      state = data.state;
-      return Promise.resolve(onRegistered(client, data.url));
-    }).then(function (pageURL) {
-      return getAccessToken(cozy, client, state, pageURL);
-    }).then(function (t) {
-      token = t;
-    }).then(function () {
-      return storage.delete(StateKey);
-    }).then(function () {
-      return { client: client, token: token };
-    });
-  }).then(function (creds) {
-    return storage.save(CredsKey, creds);
-  }, function (err) {
-    if (_fetch.FetchError.isUnauthorized(err)) {
-      return clearAndRetry(err);
-    } else {
-      throw err;
-    }
-  });
-}
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+    symbolToString = symbolProto ? symbolProto.toString : undefined;
 
-// retrieveToken perform a request on the access_token entrypoint in order to
-// fetch a token.
-function retrieveToken(cozy, client, token, query) {
-  if (!(client instanceof Client)) {
-    client = new Client(client);
+/**
+ * The base implementation of `_.toString` which doesn't convert nullish
+ * values to empty strings.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */
+function baseToString(value) {
+  // Exit early for strings to avoid a performance hit in some environments.
+  if (typeof value == 'string') {
+    return value;
   }
-  if (!client.isRegistered()) {
-    return Promise.reject(new Error('Client not registered'));
+  if (isArray(value)) {
+    // Recursively convert values (susceptible to call stack limits).
+    return arrayMap(value, baseToString) + '';
   }
-  var body = (0, _utils.encodeQuery)(Object.assign({}, query, {
-    client_id: client.clientID,
-    client_secret: client.clientSecret
-  }));
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/access_token', body, {
-    disableAuth: token === null,
-    dontRetry: true,
-    manualAuthCredentials: { client: client, token: token },
-    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
-  }).then(function (data) {
-    data.refreshToken = data.refreshToken || query.refresh_token;
-    return new AccessToken(data);
-  });
+  if (isSymbol(value)) {
+    return symbolToString ? symbolToString.call(value) : '';
+  }
+  var result = (value + '');
+  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
 }
 
-// getGrantCodeFromPageURL extract the state and code query parameters from the
-// given url
-function getGrantCodeFromPageURL() {
-  var pageURL = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
+module.exports = baseToString;
 
-  if (pageURL === '' && typeof window !== 'undefined') {
-    pageURL = window.location.href;
-  }
-  var queries = (0, _utils.decodeQuery)(pageURL);
-  if (!queries.hasOwnProperty('state')) {
-    return null;
-  }
-  return {
-    state: queries['state'],
-    code: queries['code']
-  };
-}
 
-// generateRandomState will try to generate a 128bits random value from a secure
-// pseudo random generator. It will fallback on Math.random if it cannot find
-// such generator.
-function generateRandomState() {
-  var buffer = void 0;
-  if (typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function') {
-    buffer = new Uint8Array(StateSize);
-    window.crypto.getRandomValues(buffer);
-  } else {
-    try {
-      buffer = __nested_webpack_require_16254__(12).randomBytes(StateSize);
-    } catch (e) {
-      buffer = null;
-    }
-  }
-  if (!buffer) {
-    buffer = new Array(StateSize);
-    for (var i = 0; i < buffer.length; i++) {
-      buffer[i] = Math.floor(Math.random() * 255);
-    }
+/***/ }),
+/* 410 */
+/***/ ((module) => {
+
+/**
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+function arrayMap(array, iteratee) {
+  var index = -1,
+      length = array == null ? 0 : array.length,
+      result = Array(length);
+
+  while (++index < length) {
+    result[index] = iteratee(array[index], index, array);
   }
-  return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-');
+  return result;
 }
-/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_16254__(6)))
 
-/***/ }),
-/* 4 */
-/***/ (function(module, exports) {
+module.exports = arrayMap;
 
-module.exports = __webpack_require__(475);
 
 /***/ }),
-/* 5 */
-/***/ (function(module, exports, __webpack_require__) {
+/* 411 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var isSymbol = __webpack_require__(374);
 
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.pickService = pickService;
-// helper to serialize/deserialize an error for/from postMessage
-var errorSerializer = exports.errorSerializer = function () {
-  function mapErrorProperties(from, to) {
-    var result = Object.assign(to, from);
-    var nativeProperties = ['name', 'message'];
-    return nativeProperties.reduce(function (result, property) {
-      if (from[property]) {
-        to[property] = from[property];
-      }
-      return result;
-    }, result);
+/**
+ * Converts `value` to a string key if it's not a string or symbol.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {string|symbol} Returns the key.
+ */
+function toKey(value) {
+  if (typeof value == 'string' || isSymbol(value)) {
+    return value;
   }
-  return {
-    serialize: function serialize(error) {
-      return mapErrorProperties(error, {});
-    },
-    deserialize: function deserialize(data) {
-      return mapErrorProperties(data, new Error(data.message));
-    }
-  };
-}();
-
-var first = function first(arr) {
-  return arr && arr[0];
-};
-// In a far future, the user will have to pick the desired service from a list.
-// For now it's our job, an easy job as we arbitrary pick the first service of
-// the list.
-function pickService(intent, filterServices) {
-  var services = intent.attributes.services;
-  var filteredServices = filterServices ? (services || []).filter(filterServices) : services;
-  return first(filteredServices);
+  var result = (value + '');
+  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
 }
 
-/***/ }),
-/* 6 */
-/***/ (function(module, exports) {
+module.exports = toKey;
 
-module.exports = __webpack_require__(478);
 
 /***/ }),
-/* 7 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
+/* 412 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-function indexKey(doc) {
-  return doc.type + '/' + doc.id;
-}
+var baseIteratee = __webpack_require__(413),
+    baseUniq = __webpack_require__(475);
 
-function findByRef(resources, ref) {
-  return resources[indexKey(ref)];
+/**
+ * This method is like `_.uniq` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * uniqueness is computed. The order of result values is determined by the
+ * order they occur in the array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */
+function uniqBy(array, iteratee) {
+  return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];
 }
 
-function handleResource(rawResource, resources, links) {
-  var resource = {
-    _id: rawResource.id,
-    _type: rawResource.type,
-    _rev: rawResource.meta && rawResource.meta.rev,
-    links: Object.assign({}, rawResource.links, links),
-    attributes: rawResource.attributes,
-    relations: function relations(name) {
-      var rels = rawResource.relationships[name];
-      if (rels === undefined || rels.data === undefined) return undefined;
-      if (rels.data === null) return null;
-      if (!Array.isArray(rels.data)) return findByRef(resources, rels.data);
-      return rels.data.map(function (ref) {
-        return findByRef(resources, ref);
-      });
-    }
-  };
-  if (rawResource.relationships) {
-    resource.relationships = rawResource.relationships;
-  }
-
-  resources[indexKey(rawResource)] = resource;
+module.exports = uniqBy;
 
-  return resource;
-}
 
-function handleTopLevel(doc) {
-  var resources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+/***/ }),
+/* 413 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  // build an index of included resource by Type & ID
-  var included = doc.included;
+var baseMatches = __webpack_require__(414),
+    baseMatchesProperty = __webpack_require__(467),
+    identity = __webpack_require__(471),
+    isArray = __webpack_require__(55),
+    property = __webpack_require__(472);
 
-  if (Array.isArray(included)) {
-    included.forEach(function (r) {
-      return handleResource(r, resources, doc.links);
-    });
+/**
+ * The base implementation of `_.iteratee`.
+ *
+ * @private
+ * @param {*} [value=_.identity] The value to convert to an iteratee.
+ * @returns {Function} Returns the iteratee.
+ */
+function baseIteratee(value) {
+  // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
+  // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
+  if (typeof value == 'function') {
+    return value;
   }
-
-  if (Array.isArray(doc.data)) {
-    return doc.data.map(function (r) {
-      return handleResource(r, resources, doc.links);
-    });
-  } else {
-    return handleResource(doc.data, resources, doc.links);
+  if (value == null) {
+    return identity;
+  }
+  if (typeof value == 'object') {
+    return isArray(value)
+      ? baseMatchesProperty(value[0], value[1])
+      : baseMatches(value);
   }
+  return property(value);
 }
 
-exports.default = handleTopLevel;
-
-/***/ }),
-/* 8 */
-/***/ (function(module, exports, __nested_webpack_require_36434__) {
-
-"use strict";
-
+module.exports = baseIteratee;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.redirect = exports.getRedirectionURL = undefined;
 
-var _regenerator = __nested_webpack_require_36434__(4);
+/***/ }),
+/* 414 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _regenerator2 = _interopRequireDefault(_regenerator);
+var baseIsMatch = __webpack_require__(415),
+    getMatchData = __webpack_require__(464),
+    matchesStrictComparable = __webpack_require__(466);
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+/**
+ * The base implementation of `_.matches` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new spec function.
+ */
+function baseMatches(source) {
+  var matchData = getMatchData(source);
+  if (matchData.length == 1 && matchData[0][2]) {
+    return matchesStrictComparable(matchData[0][0], matchData[0][1]);
+  }
+  return function(object) {
+    return object === source || baseIsMatch(object, source, matchData);
+  };
+}
 
-// Redirect to an app able to handle the doctype
-// Redirections are more or less a hack of the intent API to retrieve an URL for
-// accessing a given doctype or a given document.
-// It needs to use a special action `REDIRECT`
-var getRedirectionURL = exports.getRedirectionURL = function () {
-  var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, type, data) {
-    var intent, service, baseURL;
-    return _regenerator2.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            if (!(!type && !data)) {
-              _context.next = 2;
-              break;
-            }
+module.exports = baseMatches;
 
-            throw new Error('Cannot retrieve redirection, at least type or doc must be provided');
 
-          case 2:
-            _context.next = 4;
-            return create(cozy, 'REDIRECT', type, data);
+/***/ }),
+/* 415 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-          case 4:
-            intent = _context.sent;
-            service = (0, _helpers.pickService)(intent);
+var Stack = __webpack_require__(416),
+    baseIsEqual = __webpack_require__(422);
 
-            if (service) {
-              _context.next = 8;
-              break;
-            }
+/** Used to compose bitmasks for value comparisons. */
+var COMPARE_PARTIAL_FLAG = 1,
+    COMPARE_UNORDERED_FLAG = 2;
 
-            throw new Error('Unable to find a service');
+/**
+ * The base implementation of `_.isMatch` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Array} matchData The property names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ */
+function baseIsMatch(object, source, matchData, customizer) {
+  var index = matchData.length,
+      length = index,
+      noCustomizer = !customizer;
 
-          case 8:
+  if (object == null) {
+    return !length;
+  }
+  object = Object(object);
+  while (index--) {
+    var data = matchData[index];
+    if ((noCustomizer && data[2])
+          ? data[1] !== object[data[0]]
+          : !(data[0] in object)
+        ) {
+      return false;
+    }
+  }
+  while (++index < length) {
+    data = matchData[index];
+    var key = data[0],
+        objValue = object[key],
+        srcValue = data[1];
 
-            // Intents cannot be deleted now
-            // await deleteIntent(cozy, intent)
+    if (noCustomizer && data[2]) {
+      if (objValue === undefined && !(key in object)) {
+        return false;
+      }
+    } else {
+      var stack = new Stack;
+      if (customizer) {
+        var result = customizer(objValue, srcValue, key, object, source, stack);
+      }
+      if (!(result === undefined
+            ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
+            : result
+          )) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
 
-            baseURL = removeQueryString(service.href);
-            return _context.abrupt('return', data ? buildRedirectionURL(baseURL, data) : baseURL);
+module.exports = baseIsMatch;
 
-          case 10:
-          case 'end':
-            return _context.stop();
-        }
-      }
-    }, _callee, this);
-  }));
 
-  return function getRedirectionURL(_x3, _x4, _x5) {
-    return _ref.apply(this, arguments);
-  };
-}();
+/***/ }),
+/* 416 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var redirect = exports.redirect = function () {
-  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, type, doc, redirectFn) {
-    var redirectionURL;
-    return _regenerator2.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            if (window) {
-              _context2.next = 2;
-              break;
-            }
+var ListCache = __webpack_require__(393),
+    stackClear = __webpack_require__(417),
+    stackDelete = __webpack_require__(418),
+    stackGet = __webpack_require__(419),
+    stackHas = __webpack_require__(420),
+    stackSet = __webpack_require__(421);
 
-            throw new Error('redirect() method can only be called in a browser');
+/**
+ * Creates a stack cache object to store key-value pairs.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [entries] The key-value pairs to cache.
+ */
+function Stack(entries) {
+  var data = this.__data__ = new ListCache(entries);
+  this.size = data.size;
+}
 
-          case 2:
-            _context2.next = 4;
-            return getRedirectionURL(cozy, type, doc);
+// Add methods to `Stack`.
+Stack.prototype.clear = stackClear;
+Stack.prototype['delete'] = stackDelete;
+Stack.prototype.get = stackGet;
+Stack.prototype.has = stackHas;
+Stack.prototype.set = stackSet;
 
-          case 4:
-            redirectionURL = _context2.sent;
+module.exports = Stack;
 
-            if (!(redirectFn && typeof redirectFn === 'function')) {
-              _context2.next = 7;
-              break;
-            }
 
-            return _context2.abrupt('return', redirectFn(redirectionURL));
+/***/ }),
+/* 417 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-          case 7:
+var ListCache = __webpack_require__(393);
 
-            window.location.href = redirectionURL;
+/**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */
+function stackClear() {
+  this.__data__ = new ListCache;
+  this.size = 0;
+}
 
-          case 8:
-          case 'end':
-            return _context2.stop();
-        }
-      }
-    }, _callee2, this);
-  }));
+module.exports = stackClear;
 
-  return function redirect(_x6, _x7, _x8, _x9) {
-    return _ref2.apply(this, arguments);
-  };
-}();
 
-exports.create = create;
-exports.createService = createService;
+/***/ }),
+/* 418 */
+/***/ ((module) => {
 
-var _fetch = __nested_webpack_require_36434__(0);
+/**
+ * Removes `key` and its value from the stack.
+ *
+ * @private
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+function stackDelete(key) {
+  var data = this.__data__,
+      result = data['delete'](key);
 
-var _helpers = __nested_webpack_require_36434__(5);
+  this.size = data.size;
+  return result;
+}
 
-var _client = __nested_webpack_require_36434__(16);
+module.exports = stackDelete;
 
-var client = _interopRequireWildcard(_client);
 
-var _service = __nested_webpack_require_36434__(17);
+/***/ }),
+/* 419 */
+/***/ ((module) => {
 
-var service = _interopRequireWildcard(_service);
+/**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+function stackGet(key) {
+  return this.__data__.get(key);
+}
 
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+module.exports = stackGet;
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
+/***/ }),
+/* 420 */
+/***/ ((module) => {
 
-function create(cozy, action, type) {
-  var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-  var permissions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
+/**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function stackHas(key) {
+  return this.__data__.has(key);
+}
 
-  if (!action) throw new Error('Misformed intent, "action" property must be provided');
-  if (!type) throw new Error('Misformed intent, "type" property must be provided');
+module.exports = stackHas;
 
-  var createPromise = (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/intents', {
-    data: {
-      type: 'io.cozy.intents',
-      attributes: {
-        action: action,
-        type: type,
-        data: data,
-        permissions: permissions
-      }
-    }
-  });
 
-  createPromise.start = function (element, onReadyCallback) {
-    var options = {
-      filteredServices: data.filteredServices,
-      onReadyCallback: onReadyCallback
-    };
+/***/ }),
+/* 421 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    delete data.filteredServices;
+var ListCache = __webpack_require__(393),
+    Map = __webpack_require__(401),
+    MapCache = __webpack_require__(378);
 
-    return createPromise.then(function (intent) {
-      return client.start(cozy, intent, element, data, options);
-    });
-  };
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
 
-  return createPromise;
+/**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache instance.
+ */
+function stackSet(key, value) {
+  var data = this.__data__;
+  if (data instanceof ListCache) {
+    var pairs = data.__data__;
+    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
+      pairs.push([key, value]);
+      this.size = ++data.size;
+      return this;
+    }
+    data = this.__data__ = new MapCache(pairs);
+  }
+  data.set(key, value);
+  this.size = data.size;
+  return this;
 }
 
-// returns a service to communicate with intent client
-function createService(cozy, intentId, serviceWindow) {
-  return service.start(cozy, intentId, serviceWindow);
-}
+module.exports = stackSet;
 
-function removeQueryString(url) {
-  return url.replace(/\?[^/#]*/, '');
-}
 
-function isSerializable(value) {
-  return !['object', 'function'].includes(typeof value === 'undefined' ? 'undefined' : _typeof(value));
-}
+/***/ }),
+/* 422 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function buildRedirectionURL(url, data) {
-  var parameterStrings = Object.keys(data).filter(function (key) {
-    return isSerializable(data[key]);
-  }).map(function (key) {
-    return key + '=' + data[key];
-  });
+var baseIsEqualDeep = __webpack_require__(423),
+    isObjectLike = __webpack_require__(53);
 
-  return parameterStrings.length ? url + '?' + parameterStrings.join('&') : url;
+/**
+ * The base implementation of `_.isEqual` which supports partial comparisons
+ * and tracks traversed objects.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {boolean} bitmask The bitmask flags.
+ *  1 - Unordered comparison
+ *  2 - Partial comparison
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ */
+function baseIsEqual(value, other, bitmask, customizer, stack) {
+  if (value === other) {
+    return true;
+  }
+  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
+    return value !== value && other !== other;
+  }
+  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
 }
 
-/***/ }),
-/* 9 */
-/***/ (function(module, exports, __nested_webpack_require_42748__) {
+module.exports = baseIsEqual;
 
-"use strict";
 
+/***/ }),
+/* 423 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+var Stack = __webpack_require__(416),
+    equalArrays = __webpack_require__(424),
+    equalByTag = __webpack_require__(430),
+    equalObjects = __webpack_require__(434),
+    getTag = __webpack_require__(459),
+    isArray = __webpack_require__(55),
+    isBuffer = __webpack_require__(446),
+    isTypedArray = __webpack_require__(449);
 
-var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global fetch URL */
+/** Used to compose bitmasks for value comparisons. */
+var COMPARE_PARTIAL_FLAG = 1;
 
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    objectTag = '[object Object]';
 
-var _utils = __nested_webpack_require_42748__(1);
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-var _auth_storage = __nested_webpack_require_42748__(10);
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-var _auth_v = __nested_webpack_require_42748__(11);
+/**
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
+ * deep comparisons and tracks traversed objects enabling objects with circular
+ * references to be compared.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
+  var objIsArr = isArray(object),
+      othIsArr = isArray(other),
+      objTag = objIsArr ? arrayTag : getTag(object),
+      othTag = othIsArr ? arrayTag : getTag(other);
 
-var _auth_v2 = __nested_webpack_require_42748__(3);
+  objTag = objTag == argsTag ? objectTag : objTag;
+  othTag = othTag == argsTag ? objectTag : othTag;
 
-var auth = _interopRequireWildcard(_auth_v2);
+  var objIsObj = objTag == objectTag,
+      othIsObj = othTag == objectTag,
+      isSameTag = objTag == othTag;
 
-var _data = __nested_webpack_require_42748__(13);
+  if (isSameTag && isBuffer(object)) {
+    if (!isBuffer(other)) {
+      return false;
+    }
+    objIsArr = true;
+    objIsObj = false;
+  }
+  if (isSameTag && !objIsObj) {
+    stack || (stack = new Stack);
+    return (objIsArr || isTypedArray(object))
+      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
+      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
+  }
+  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
+    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
 
-var data = _interopRequireWildcard(_data);
+    if (objIsWrapped || othIsWrapped) {
+      var objUnwrapped = objIsWrapped ? object.value() : object,
+          othUnwrapped = othIsWrapped ? other.value() : other;
 
-var _fetch2 = __nested_webpack_require_42748__(0);
+      stack || (stack = new Stack);
+      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
+    }
+  }
+  if (!isSameTag) {
+    return false;
+  }
+  stack || (stack = new Stack);
+  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
+}
 
-var cozyFetch = _interopRequireWildcard(_fetch2);
+module.exports = baseIsEqualDeep;
 
-var _mango = __nested_webpack_require_42748__(14);
 
-var mango = _interopRequireWildcard(_mango);
+/***/ }),
+/* 424 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _files = __nested_webpack_require_42748__(15);
+var SetCache = __webpack_require__(425),
+    arraySome = __webpack_require__(428),
+    cacheHas = __webpack_require__(429);
 
-var files = _interopRequireWildcard(_files);
+/** Used to compose bitmasks for value comparisons. */
+var COMPARE_PARTIAL_FLAG = 1,
+    COMPARE_UNORDERED_FLAG = 2;
 
-var _intents = __nested_webpack_require_42748__(8);
+/**
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Array} array The array to compare.
+ * @param {Array} other The other array to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `array` and `other` objects.
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+ */
+function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
+  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
+      arrLength = array.length,
+      othLength = other.length;
 
-var intents = _interopRequireWildcard(_intents);
+  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
+    return false;
+  }
+  // Check that cyclic values are equal.
+  var arrStacked = stack.get(array);
+  var othStacked = stack.get(other);
+  if (arrStacked && othStacked) {
+    return arrStacked == other && othStacked == array;
+  }
+  var index = -1,
+      result = true,
+      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
 
-var _jobs = __nested_webpack_require_42748__(18);
+  stack.set(array, other);
+  stack.set(other, array);
 
-var jobs = _interopRequireWildcard(_jobs);
+  // Ignore non-index properties.
+  while (++index < arrLength) {
+    var arrValue = array[index],
+        othValue = other[index];
 
-var _offline = __nested_webpack_require_42748__(19);
+    if (customizer) {
+      var compared = isPartial
+        ? customizer(othValue, arrValue, index, other, array, stack)
+        : customizer(arrValue, othValue, index, array, other, stack);
+    }
+    if (compared !== undefined) {
+      if (compared) {
+        continue;
+      }
+      result = false;
+      break;
+    }
+    // Recursively compare arrays (susceptible to call stack limits).
+    if (seen) {
+      if (!arraySome(other, function(othValue, othIndex) {
+            if (!cacheHas(seen, othIndex) &&
+                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
+              return seen.push(othIndex);
+            }
+          })) {
+        result = false;
+        break;
+      }
+    } else if (!(
+          arrValue === othValue ||
+            equalFunc(arrValue, othValue, bitmask, customizer, stack)
+        )) {
+      result = false;
+      break;
+    }
+  }
+  stack['delete'](array);
+  stack['delete'](other);
+  return result;
+}
 
-var offline = _interopRequireWildcard(_offline);
+module.exports = equalArrays;
 
-var _settings = __nested_webpack_require_42748__(23);
 
-var settings = _interopRequireWildcard(_settings);
+/***/ }),
+/* 425 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _relations = __nested_webpack_require_42748__(24);
+var MapCache = __webpack_require__(378),
+    setCacheAdd = __webpack_require__(426),
+    setCacheHas = __webpack_require__(427);
 
-var relations = _interopRequireWildcard(_relations);
+/**
+ *
+ * Creates an array cache object to store unique values.
+ *
+ * @private
+ * @constructor
+ * @param {Array} [values] The values to cache.
+ */
+function SetCache(values) {
+  var index = -1,
+      length = values == null ? 0 : values.length;
 
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  this.__data__ = new MapCache;
+  while (++index < length) {
+    this.add(values[index]);
+  }
+}
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+// Add methods to `SetCache`.
+SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
+SetCache.prototype.has = setCacheHas;
 
-var AppTokenV3 = auth.AppToken,
-    AccessTokenV3 = auth.AccessToken,
-    ClientV3 = auth.Client;
+module.exports = SetCache;
 
 
-var AuthNone = 0;
-var AuthRunning = 1;
-var AuthError = 2;
-var AuthOK = 3;
+/***/ }),
+/* 426 */
+/***/ ((module) => {
 
-var defaultClientParams = {
-  softwareID: 'github.com/cozy/cozy-client-js'
-};
+/** Used to stand-in for `undefined` hash values. */
+var HASH_UNDEFINED = '__lodash_hash_undefined__';
 
-var dataProto = {
-  create: data.create,
-  find: data.find,
-  findMany: data.findMany,
-  findAll: data.findAll,
-  update: data.update,
-  delete: data._delete,
-  updateAttributes: data.updateAttributes,
-  changesFeed: data.changesFeed,
-  defineIndex: mango.defineIndex,
-  query: mango.query,
-  addReferencedFiles: relations.addReferencedFiles,
-  removeReferencedFiles: relations.removeReferencedFiles,
-  listReferencedFiles: relations.listReferencedFiles,
-  fetchReferencedFiles: relations.fetchReferencedFiles,
-  destroy: function destroy() {
-    (0, _utils.warn)('destroy is deprecated, use cozy.data.delete instead.');
-    return data._delete.apply(data, arguments);
-  }
-};
+/**
+ * Adds `value` to the array cache.
+ *
+ * @private
+ * @name add
+ * @memberOf SetCache
+ * @alias push
+ * @param {*} value The value to cache.
+ * @returns {Object} Returns the cache instance.
+ */
+function setCacheAdd(value) {
+  this.__data__.set(value, HASH_UNDEFINED);
+  return this;
+}
 
-var authProto = {
-  client: auth.client,
-  registerClient: auth.registerClient,
-  updateClient: auth.updateClient,
-  unregisterClient: auth.unregisterClient,
-  getClient: auth.getClient,
-  getAuthCodeURL: auth.getAuthCodeURL,
-  getAccessToken: auth.getAccessToken,
-  refreshToken: auth.refreshToken
-};
+module.exports = setCacheAdd;
 
-var filesProto = {
-  create: files.create,
-  createDirectory: files.createDirectory,
-  createDirectoryByPath: files.createDirectoryByPath,
-  updateById: files.updateById,
-  updateAttributesById: files.updateAttributesById,
-  updateAttributesByPath: files.updateAttributesByPath,
-  trashById: files.trashById,
-  statById: files.statById,
-  statByPath: files.statByPath,
-  downloadById: files.downloadById,
-  downloadByPath: files.downloadByPath,
-  getDownloadLinkById: files.getDownloadLinkById,
-  getDownloadLink: files.getDownloadLinkByPath, // DEPRECATED, should be removed very soon
-  getDownloadLinkByPath: files.getDownloadLinkByPath,
-  getArchiveLink: function getArchiveLink() {
-    (0, _utils.warn)('getArchiveLink is deprecated, use cozy.files.getArchiveLinkByPaths instead.');
-    return files.getArchiveLinkByPaths.apply(files, arguments);
-  },
-  getArchiveLinkByPaths: files.getArchiveLinkByPaths,
-  getArchiveLinkByIds: files.getArchiveLinkByIds,
-  getFilePath: files.getFilePath,
-  getCollectionShareLink: files.getCollectionShareLink,
-  query: mango.queryFiles,
-  listTrash: files.listTrash,
-  clearTrash: files.clearTrash,
-  restoreById: files.restoreById,
-  destroyById: files.destroyById
-};
 
-var intentsProto = {
-  create: intents.create,
-  createService: intents.createService,
-  getRedirectionURL: intents.getRedirectionURL,
-  redirect: intents.redirect
-};
+/***/ }),
+/* 427 */
+/***/ ((module) => {
 
-var jobsProto = {
-  create: jobs.create,
-  count: jobs.count,
-  queued: jobs.queued
-};
+/**
+ * Checks if `value` is in the array cache.
+ *
+ * @private
+ * @name has
+ * @memberOf SetCache
+ * @param {*} value The value to search for.
+ * @returns {number} Returns `true` if `value` is found, else `false`.
+ */
+function setCacheHas(value) {
+  return this.__data__.has(value);
+}
 
-var offlineProto = {
-  init: offline.init,
-  getDoctypes: offline.getDoctypes,
-  // database
-  hasDatabase: offline.hasDatabase,
-  getDatabase: offline.getDatabase,
-  createDatabase: offline.createDatabase,
-  migrateDatabase: offline.migrateDatabase,
-  destroyDatabase: offline.destroyDatabase,
-  destroyAllDatabase: offline.destroyAllDatabase,
-  // replication
-  hasReplication: offline.hasReplication,
-  replicateFromCozy: offline.replicateFromCozy,
-  stopReplication: offline.stopReplication,
-  stopAllReplication: offline.stopAllReplication,
-  // repeated replication
-  hasRepeatedReplication: offline.hasRepeatedReplication,
-  startRepeatedReplication: offline.startRepeatedReplication,
-  stopRepeatedReplication: offline.stopRepeatedReplication,
-  stopAllRepeatedReplication: offline.stopAllRepeatedReplication
-};
+module.exports = setCacheHas;
 
-var settingsProto = {
-  diskUsage: settings.diskUsage,
-  changePassphrase: settings.changePassphrase,
-  getInstance: settings.getInstance,
-  updateInstance: settings.updateInstance,
-  getClients: settings.getClients,
-  deleteClientById: settings.deleteClientById,
-  updateLastSync: settings.updateLastSync
-};
 
-var ensureHasReconnectParam = function ensureHasReconnectParam(_url) {
-  var url = new URL(_url);
-  if (url.searchParams && !url.searchParams.has('reconnect')) {
-    url.searchParams.append('reconnect', 1);
-  } else if (!url.search || url.search.indexOf('reconnect') === -1) {
-    // Some old navigators do not have the searchParams API
-    // and it is not polyfilled by babel-polyfill
-    url.search = url.search + '&reconnect=1';
-  }
-  return url.toString();
-};
+/***/ }),
+/* 428 */
+/***/ ((module) => {
 
-var Client = function () {
-  function Client(options) {
-    _classCallCheck(this, Client);
+/**
+ * A specialized version of `_.some` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ *  else `false`.
+ */
+function arraySome(array, predicate) {
+  var index = -1,
+      length = array == null ? 0 : array.length;
 
-    this.data = {};
-    this.files = {};
-    this.intents = {};
-    this.jobs = {};
-    this.offline = {};
-    this.settings = {};
-    this.auth = {
-      Client: ClientV3,
-      AccessToken: AccessTokenV3,
-      AppToken: AppTokenV3,
-      AppTokenV2: _auth_v.AppToken,
-      LocalStorage: _auth_storage.LocalStorage,
-      MemoryStorage: _auth_storage.MemoryStorage
-    };
-    this._inited = false;
-    if (options) {
-      this.init(options);
+  while (++index < length) {
+    if (predicate(array[index], index, array)) {
+      return true;
     }
   }
+  return false;
+}
 
-  _createClass(Client, [{
-    key: 'init',
-    value: function init() {
-      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+module.exports = arraySome;
 
-      this._inited = true;
-      this._oauth = false; // is oauth activated or not
-      this._token = null; // application token
-      this._authstate = AuthNone;
-      this._authcreds = null;
-      this._storage = null;
-      this._version = options.version || null;
-      this._offline = null;
 
-      var token = options.token;
-      var oauth = options.oauth;
-      if (token && oauth) {
-        throw new Error('Cannot specify an application token with a oauth activated');
-      }
+/***/ }),
+/* 429 */
+/***/ ((module) => {
 
-      if (token) {
-        this._token = new AppTokenV3({ token: token });
-      } else if (oauth) {
-        this._oauth = true;
-        this._storage = oauth.storage;
-        this._clientParams = Object.assign({}, defaultClientParams, oauth.clientParams);
-        this._onRegistered = oauth.onRegistered || nopOnRegistered;
-      }
+/**
+ * Checks if a `cache` value for `key` exists.
+ *
+ * @private
+ * @param {Object} cache The cache to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+function cacheHas(cache, key) {
+  return cache.has(key);
+}
 
-      var url = options.cozyURL || '';
-      while (url[url.length - 1] === '/') {
-        url = url.slice(0, -1);
-      }
+module.exports = cacheHas;
 
-      this._url = url;
 
-      this._invalidTokenErrorHandler = options.onInvalidTokenError !== undefined ? options.onInvalidTokenError : cozyFetch.handleInvalidTokenError;
+/***/ }),
+/* 430 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      var disablePromises = !!options.disablePromises;
-      addToProto(this, this.data, dataProto, disablePromises);
-      addToProto(this, this.auth, authProto, disablePromises);
-      addToProto(this, this.files, filesProto, disablePromises);
-      addToProto(this, this.intents, intentsProto, disablePromises);
-      addToProto(this, this.jobs, jobsProto, disablePromises);
-      addToProto(this, this.offline, offlineProto, disablePromises);
-      addToProto(this, this.settings, settingsProto, disablePromises);
+var Symbol = __webpack_require__(47),
+    Uint8Array = __webpack_require__(431),
+    eq = __webpack_require__(397),
+    equalArrays = __webpack_require__(424),
+    mapToArray = __webpack_require__(432),
+    setToArray = __webpack_require__(433);
 
-      if (options.offline) {
-        this.offline.init(options.offline);
-      }
+/** Used to compose bitmasks for value comparisons. */
+var COMPARE_PARTIAL_FLAG = 1,
+    COMPARE_UNORDERED_FLAG = 2;
 
-      this.fetch = function _fetch(method, url) {
-        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+/** `Object#toString` result references. */
+var boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    symbolTag = '[object Symbol]';
 
-        return cozyFetch.cozyFetch(this, url, _extends({}, options, { method: method }));
-      };
+var arrayBufferTag = '[object ArrayBuffer]',
+    dataViewTag = '[object DataView]';
 
-      this.fetchJSON = function _fetchJSON() {
-        var args = [this].concat(Array.prototype.slice.call(arguments));
-        return cozyFetch.cozyFetchJSON.apply(this, args);
-      };
-    }
-  }, {
-    key: 'authorize',
-    value: function authorize() {
-      var _this = this;
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
 
-      var forceTokenRefresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+/**
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
+ * the same `toStringTag`.
+ *
+ * **Note:** This function only supports comparing values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {string} tag The `toStringTag` of the objects to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
+  switch (tag) {
+    case dataViewTag:
+      if ((object.byteLength != other.byteLength) ||
+          (object.byteOffset != other.byteOffset)) {
+        return false;
+      }
+      object = object.buffer;
+      other = other.buffer;
 
-      var state = this._authstate;
-      if (state === AuthOK || state === AuthRunning) {
-        return this._authcreds;
+    case arrayBufferTag:
+      if ((object.byteLength != other.byteLength) ||
+          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
+        return false;
       }
+      return true;
 
-      this._authstate = AuthRunning;
-      this._authcreds = this.isV2().then(function (isV2) {
-        if (isV2 && _this._oauth) {
-          throw new Error('OAuth is not supported on the V2 stack');
-        }
-        if (_this._oauth) {
-          if (forceTokenRefresh && _this._clientParams.redirectURI) {
-            _this._clientParams.redirectURI = ensureHasReconnectParam(_this._clientParams.redirectURI);
-          }
-          return auth.oauthFlow(_this, _this._storage, _this._clientParams, _this._onRegistered, forceTokenRefresh);
-        }
-        // we expect to be on a client side application running in a browser
-        // with cookie-based authentication.
-        if (isV2) {
-          return (0, _auth_v.getAppToken)();
-        } else if (_this._token) {
-          return Promise.resolve({ client: null, token: _this._token });
-        } else {
-          throw new Error('Missing application token');
-        }
-      });
+    case boolTag:
+    case dateTag:
+    case numberTag:
+      // Coerce booleans to `1` or `0` and dates to milliseconds.
+      // Invalid dates are coerced to `NaN`.
+      return eq(+object, +other);
 
-      this._authcreds.then(function () {
-        _this._authstate = AuthOK;
-      }, function () {
-        _this._authstate = AuthError;
-      });
+    case errorTag:
+      return object.name == other.name && object.message == other.message;
 
-      return this._authcreds;
-    }
-  }, {
-    key: 'saveCredentials',
-    value: function saveCredentials(client, token) {
-      var creds = { client: client, token: token };
-      if (!this._storage || this._authstate === AuthRunning) {
-        return Promise.resolve(creds);
-      }
-      this._storage.save(auth.CredsKey, creds);
-      this._authcreds = Promise.resolve(creds);
-      return this._authcreds;
-    }
-  }, {
-    key: 'fullpath',
-    value: function fullpath(path) {
-      var _this2 = this;
+    case regexpTag:
+    case stringTag:
+      // Coerce regexes to strings and treat strings, primitives and objects,
+      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
+      // for more details.
+      return object == (other + '');
 
-      return this.isV2().then(function (isV2) {
-        var pathprefix = isV2 ? '/ds-api' : '';
-        return _this2._url + pathprefix + path;
-      });
-    }
-  }, {
-    key: 'isV2',
-    value: function isV2() {
-      var _this3 = this;
+    case mapTag:
+      var convert = mapToArray;
 
-      if (!this._version) {
-        return (0, _utils.retry)(function () {
-          return fetch(_this3._url + '/status/');
-        }, 3)().then(function (res) {
-          if (!res.ok) {
-            throw new Error('Could not fetch cozy status');
-          } else {
-            return res.json();
-          }
-        }).then(function (status) {
-          _this3._version = status.datasystem !== undefined ? 2 : 3;
-          return _this3.isV2();
-        });
+    case setTag:
+      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
+      convert || (convert = setToArray);
+
+      if (object.size != other.size && !isPartial) {
+        return false;
       }
-      return Promise.resolve(this._version === 2);
-    }
-  }]);
+      // Assume cyclic values are equal.
+      var stacked = stack.get(object);
+      if (stacked) {
+        return stacked == other;
+      }
+      bitmask |= COMPARE_UNORDERED_FLAG;
 
-  return Client;
-}();
+      // Recursively compare objects (susceptible to call stack limits).
+      stack.set(object, other);
+      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
+      stack['delete'](object);
+      return result;
 
-function nopOnRegistered() {
-  throw new Error('Missing onRegistered callback');
+    case symbolTag:
+      if (symbolValueOf) {
+        return symbolValueOf.call(object) == symbolValueOf.call(other);
+      }
+  }
+  return false;
 }
 
-function protoify(context, fn) {
-  return function prototyped() {
-    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-      args[_key] = arguments[_key];
-    }
+module.exports = equalByTag;
 
-    return fn.apply(undefined, [context].concat(args));
-  };
-}
 
-function addToProto(ctx, obj, proto, disablePromises) {
-  for (var attr in proto) {
-    var fn = protoify(ctx, proto[attr]);
-    if (disablePromises) {
-      fn = (0, _utils.unpromiser)(fn);
-    }
-    obj[attr] = fn;
-  }
-}
+/***/ }),
+/* 431 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var root = __webpack_require__(48);
+
+/** Built-in value references. */
+var Uint8Array = root.Uint8Array;
+
+module.exports = Uint8Array;
 
-module.exports = new Client();
-Object.assign(module.exports, { Client: Client, LocalStorage: _auth_storage.LocalStorage, MemoryStorage: _auth_storage.MemoryStorage });
 
 /***/ }),
-/* 10 */
-/***/ (function(module, exports, __webpack_require__) {
+/* 432 */
+/***/ ((module) => {
 
-"use strict";
+/**
+ * Converts `map` to its key-value pairs.
+ *
+ * @private
+ * @param {Object} map The map to convert.
+ * @returns {Array} Returns the key-value pairs.
+ */
+function mapToArray(map) {
+  var index = -1,
+      result = Array(map.size);
 
+  map.forEach(function(value, key) {
+    result[++index] = [key, value];
+  });
+  return result;
+}
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
+module.exports = mapToArray;
 
-var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+/***/ }),
+/* 433 */
+/***/ ((module) => {
 
-var LocalStorage = exports.LocalStorage = function () {
-  function LocalStorage(storage, prefix) {
-    _classCallCheck(this, LocalStorage);
+/**
+ * Converts `set` to an array of its values.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the values.
+ */
+function setToArray(set) {
+  var index = -1,
+      result = Array(set.size);
 
-    if (!storage && typeof window !== 'undefined') {
-      storage = window.localStorage;
-    }
-    this.storage = storage;
-    this.prefix = prefix || 'cozy:oauth:';
-  }
+  set.forEach(function(value) {
+    result[++index] = value;
+  });
+  return result;
+}
 
-  _createClass(LocalStorage, [{
-    key: 'save',
-    value: function save(key, value) {
-      var _this = this;
+module.exports = setToArray;
 
-      return new Promise(function (resolve) {
-        _this.storage.setItem(_this.prefix + key, JSON.stringify(value));
-        resolve(value);
-      });
-    }
-  }, {
-    key: 'load',
-    value: function load(key) {
-      var _this2 = this;
 
-      return new Promise(function (resolve) {
-        var item = _this2.storage.getItem(_this2.prefix + key);
-        if (!item) {
-          resolve();
-        } else {
-          resolve(JSON.parse(item));
-        }
-      });
-    }
-  }, {
-    key: 'delete',
-    value: function _delete(key) {
-      var _this3 = this;
+/***/ }),
+/* 434 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return new Promise(function (resolve) {
-        return resolve(_this3.storage.removeItem(_this3.prefix + key));
-      });
-    }
-  }, {
-    key: 'clear',
-    value: function clear() {
-      var _this4 = this;
+var getAllKeys = __webpack_require__(435);
 
-      return new Promise(function (resolve) {
-        var storage = _this4.storage;
-        for (var i = 0; i < storage.length; i++) {
-          var key = storage.key(i);
-          if (key.indexOf(_this4.prefix) === 0) {
-            storage.removeItem(key);
-          }
-        }
-        resolve();
-      });
-    }
-  }]);
+/** Used to compose bitmasks for value comparisons. */
+var COMPARE_PARTIAL_FLAG = 1;
 
-  return LocalStorage;
-}();
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-var MemoryStorage = exports.MemoryStorage = function () {
-  function MemoryStorage() {
-    _classCallCheck(this, MemoryStorage);
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-    this.hash = Object.create(null);
+/**
+ * A specialized version of `baseIsEqualDeep` for objects with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+ * @param {Function} customizer The function to customize comparisons.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
+  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
+      objProps = getAllKeys(object),
+      objLength = objProps.length,
+      othProps = getAllKeys(other),
+      othLength = othProps.length;
+
+  if (objLength != othLength && !isPartial) {
+    return false;
+  }
+  var index = objLength;
+  while (index--) {
+    var key = objProps[index];
+    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
+      return false;
+    }
+  }
+  // Check that cyclic values are equal.
+  var objStacked = stack.get(object);
+  var othStacked = stack.get(other);
+  if (objStacked && othStacked) {
+    return objStacked == other && othStacked == object;
   }
+  var result = true;
+  stack.set(object, other);
+  stack.set(other, object);
 
-  _createClass(MemoryStorage, [{
-    key: 'save',
-    value: function save(key, value) {
-      this.hash[key] = value;
-      return Promise.resolve(value);
-    }
-  }, {
-    key: 'load',
-    value: function load(key) {
-      return Promise.resolve(this.hash[key]);
+  var skipCtor = isPartial;
+  while (++index < objLength) {
+    key = objProps[index];
+    var objValue = object[key],
+        othValue = other[key];
+
+    if (customizer) {
+      var compared = isPartial
+        ? customizer(othValue, objValue, key, other, object, stack)
+        : customizer(objValue, othValue, key, object, other, stack);
     }
-  }, {
-    key: 'delete',
-    value: function _delete(key) {
-      var deleted = delete this.hash[key];
-      return Promise.resolve(deleted);
+    // Recursively compare objects (susceptible to call stack limits).
+    if (!(compared === undefined
+          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
+          : compared
+        )) {
+      result = false;
+      break;
     }
-  }, {
-    key: 'clear',
-    value: function clear() {
-      this.hash = Object.create(null);
-      return Promise.resolve();
+    skipCtor || (skipCtor = key == 'constructor');
+  }
+  if (result && !skipCtor) {
+    var objCtor = object.constructor,
+        othCtor = other.constructor;
+
+    // Non `Object` object instances with different constructors are not equal.
+    if (objCtor != othCtor &&
+        ('constructor' in object && 'constructor' in other) &&
+        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+      result = false;
     }
-  }]);
+  }
+  stack['delete'](object);
+  stack['delete'](other);
+  return result;
+}
+
+module.exports = equalObjects;
 
-  return MemoryStorage;
-}();
 
 /***/ }),
-/* 11 */
-/***/ (function(module, exports, __nested_webpack_require_58943__) {
+/* 435 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
-/* WEBPACK VAR INJECTION */(function(btoa) {
+var baseGetAllKeys = __webpack_require__(436),
+    getSymbols = __webpack_require__(438),
+    keys = __webpack_require__(441);
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
+/**
+ * Creates an array of own enumerable property names and symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names and symbols.
+ */
+function getAllKeys(object) {
+  return baseGetAllKeys(object, keys, getSymbols);
+}
 
-var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+module.exports = getAllKeys;
 
-exports.getAppToken = getAppToken;
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+/***/ }),
+/* 436 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/* global btoa */
-var V2TOKEN_ABORT_TIMEOUT = 3000;
+var arrayPush = __webpack_require__(437),
+    isArray = __webpack_require__(55);
 
-function getAppToken() {
-  return new Promise(function (resolve, reject) {
-    if (typeof window === 'undefined') {
-      return reject(new Error('getV2Token should be used in browser'));
-    } else if (!window.parent) {
-      return reject(new Error('getV2Token should be used in iframe'));
-    } else if (!window.parent.postMessage) {
-      return reject(new Error('getV2Token should be used in modern browser'));
-    }
-    var origin = window.location.origin;
-    var intent = { action: 'getToken' };
-    var timeout = null;
-    var receiver = function receiver(event) {
-      var token = void 0;
-      try {
-        token = new AppToken({
-          appName: event.data.appName,
-          token: event.data.token
-        });
-      } catch (e) {
-        reject(e);
-        return;
-      }
-      window.removeEventListener('message', receiver);
-      clearTimeout(timeout);
-      resolve({ client: null, token: token });
-    };
-    window.addEventListener('message', receiver, false);
-    window.parent.postMessage(intent, origin);
-    timeout = setTimeout(function () {
-      reject(new Error('No response from parent iframe after 3s'));
-    }, V2TOKEN_ABORT_TIMEOUT);
-  });
+/**
+ * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
+ * `keysFunc` and `symbolsFunc` to get the enumerable property names and
+ * symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @param {Function} symbolsFunc The function to get the symbols of `object`.
+ * @returns {Array} Returns the array of property names and symbols.
+ */
+function baseGetAllKeys(object, keysFunc, symbolsFunc) {
+  var result = keysFunc(object);
+  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
 }
 
-var AppToken = exports.AppToken = function () {
-  function AppToken(opts) {
-    _classCallCheck(this, AppToken);
+module.exports = baseGetAllKeys;
 
-    this.appName = opts.appName || '';
-    this.token = opts.token || '';
+
+/***/ }),
+/* 437 */
+/***/ ((module) => {
+
+/**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */
+function arrayPush(array, values) {
+  var index = -1,
+      length = values.length,
+      offset = array.length;
+
+  while (++index < length) {
+    array[offset + index] = values[index];
   }
+  return array;
+}
 
-  _createClass(AppToken, [{
-    key: 'toAuthHeader',
-    value: function toAuthHeader() {
-      return 'Basic ' + btoa(this.appName + ':' + this.token);
-    }
-  }]);
+module.exports = arrayPush;
 
-  return AppToken;
-}();
-/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_58943__(6)))
 
 /***/ }),
-/* 12 */
-/***/ (function(module, exports) {
+/* 438 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-module.exports = __webpack_require__(76);
+var arrayFilter = __webpack_require__(439),
+    stubArray = __webpack_require__(440);
 
-/***/ }),
-/* 13 */
-/***/ (function(module, exports, __nested_webpack_require_61680__) {
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-"use strict";
+/** Built-in value references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
 
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeGetSymbols = Object.getOwnPropertySymbols;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.create = create;
-exports.find = find;
-exports.findMany = findMany;
-exports.findAll = findAll;
-exports.changesFeed = changesFeed;
-exports.update = update;
-exports.updateAttributes = updateAttributes;
-exports._delete = _delete;
+/**
+ * Creates an array of the own enumerable symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
+  if (object == null) {
+    return [];
+  }
+  object = Object(object);
+  return arrayFilter(nativeGetSymbols(object), function(symbol) {
+    return propertyIsEnumerable.call(object, symbol);
+  });
+};
 
-var _utils = __nested_webpack_require_61680__(1);
+module.exports = getSymbols;
 
-var _doctypes = __nested_webpack_require_61680__(2);
 
-var _fetch = __nested_webpack_require_61680__(0);
+/***/ }),
+/* 439 */
+/***/ ((module) => {
 
-var NOREV = 'stack-v2-no-rev';
+/**
+ * A specialized version of `_.filter` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */
+function arrayFilter(array, predicate) {
+  var index = -1,
+      length = array == null ? 0 : array.length,
+      resIndex = 0,
+      result = [];
 
-function create(cozy, doctype, attributes) {
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-    if (isV2) {
-      attributes.docType = doctype;
+  while (++index < length) {
+    var value = array[index];
+    if (predicate(value, index, array)) {
+      result[resIndex++] = value;
     }
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, attributes._id);
-    var httpVerb = attributes._id ? 'PUT' : 'POST';
-    delete attributes._id;
-    return (0, _fetch.cozyFetchJSON)(cozy, httpVerb, path, attributes).then(function (resp) {
-      if (isV2) {
-        return find(cozy, doctype, resp._id);
-      } else {
-        return resp.data;
-      }
-    });
-  });
+  }
+  return result;
 }
 
-function find(cozy, doctype, id) {
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-
-    if (!id) {
-      return Promise.reject(new Error('Missing id parameter'));
-    }
+module.exports = arrayFilter;
 
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, id);
-    return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path).then(function (resp) {
-      if (isV2) {
-        return Object.assign(resp, { _rev: NOREV });
-      } else {
-        return resp;
-      }
-    });
-  });
-}
 
-function findMany(cozy, doctype, ids) {
-  if (!(ids instanceof Array)) {
-    return Promise.reject(new Error('Parameter ids must be a non-empty array'));
-  }
-  if (ids.length === 0) {
-    // So users don't need to be defensive regarding the array content.
-    // This should not hide issues in user code since the result will be an
-    // empty object anyway.
-    return Promise.resolve({});
-  }
+/***/ }),
+/* 440 */
+/***/ ((module) => {
 
-  return cozy.isV2().then(function (isV2) {
-    if (isV2) {
-      return Promise.reject(new Error('findMany is not available on v2'));
-    }
+/**
+ * This method returns a new empty array.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {Array} Returns the new empty array.
+ * @example
+ *
+ * var arrays = _.times(2, _.stubArray);
+ *
+ * console.log(arrays);
+ * // => [[], []]
+ *
+ * console.log(arrays[0] === arrays[1]);
+ * // => false
+ */
+function stubArray() {
+  return [];
+}
 
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', {
-      include_docs: true
-    });
+module.exports = stubArray;
 
-    return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, { keys: ids }).then(function (resp) {
-      var docs = {};
 
-      var _iteratorNormalCompletion = true;
-      var _didIteratorError = false;
-      var _iteratorError = undefined;
+/***/ }),
+/* 441 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      try {
-        for (var _iterator = resp.rows[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
-          var row = _step.value;
-          var key = row.key,
-              doc = row.doc,
-              error = row.error;
+var arrayLikeKeys = __webpack_require__(442),
+    baseKeys = __webpack_require__(454),
+    isArrayLike = __webpack_require__(458);
 
-          docs[key] = error ? { error: error } : { doc: doc };
-        }
-      } catch (err) {
-        _didIteratorError = true;
-        _iteratorError = err;
-      } finally {
-        try {
-          if (!_iteratorNormalCompletion && _iterator.return) {
-            _iterator.return();
-          }
-        } finally {
-          if (_didIteratorError) {
-            throw _iteratorError;
-          }
-        }
-      }
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+function keys(object) {
+  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
+}
 
-      return docs;
-    }).catch(function (error) {
-      if (error.status !== 404) return Promise.reject(error);
+module.exports = keys;
 
-      // When no doc was ever created and the database does not exist yet,
-      // the response will be a 404 error.
-      var docs = {};
 
-      var _iteratorNormalCompletion2 = true;
-      var _didIteratorError2 = false;
-      var _iteratorError2 = undefined;
+/***/ }),
+/* 442 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      try {
-        for (var _iterator2 = ids[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
-          var id = _step2.value;
+var baseTimes = __webpack_require__(443),
+    isArguments = __webpack_require__(444),
+    isArray = __webpack_require__(55),
+    isBuffer = __webpack_require__(446),
+    isIndex = __webpack_require__(448),
+    isTypedArray = __webpack_require__(449);
 
-          docs[id] = { error: error };
-        }
-      } catch (err) {
-        _didIteratorError2 = true;
-        _iteratorError2 = err;
-      } finally {
-        try {
-          if (!_iteratorNormalCompletion2 && _iterator2.return) {
-            _iterator2.return();
-          }
-        } finally {
-          if (_didIteratorError2) {
-            throw _iteratorError2;
-          }
-        }
-      }
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-      return docs;
-    });
-  });
-}
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-function findAll(cozy, doctype) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { include_docs: true };
+/**
+ * Creates an array of the enumerable property names of the array-like `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @param {boolean} inherited Specify returning inherited property names.
+ * @returns {Array} Returns the array of property names.
+ */
+function arrayLikeKeys(value, inherited) {
+  var isArr = isArray(value),
+      isArg = !isArr && isArguments(value),
+      isBuff = !isArr && !isArg && isBuffer(value),
+      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
+      skipIndexes = isArr || isArg || isBuff || isType,
+      result = skipIndexes ? baseTimes(value.length, String) : [],
+      length = result.length;
 
-  return cozy.isV2().then(function (isV2) {
-    if (isV2) {
-      return Promise.reject(new Error('findAll is not available on v2'));
+  for (var key in value) {
+    if ((inherited || hasOwnProperty.call(value, key)) &&
+        !(skipIndexes && (
+           // Safari 9 has enumerable `arguments.length` in strict mode.
+           key == 'length' ||
+           // Node.js 0.10 has enumerable non-index properties on buffers.
+           (isBuff && (key == 'offset' || key == 'parent')) ||
+           // PhantomJS 2 has enumerable non-index properties on typed arrays.
+           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
+           // Skip index properties.
+           isIndex(key, length)
+        ))) {
+      result.push(key);
     }
+  }
+  return result;
+}
 
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', options);
-
-    return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, {}).then(function (resp) {
-      var docs = [];
+module.exports = arrayLikeKeys;
 
-      var _iteratorNormalCompletion3 = true;
-      var _didIteratorError3 = false;
-      var _iteratorError3 = undefined;
 
-      try {
-        for (var _iterator3 = resp.rows[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
-          var row = _step3.value;
-          var doc = row.doc;
-          // if not couchDB indexes
+/***/ }),
+/* 443 */
+/***/ ((module) => {
 
-          if (!doc._id.match(/_design\//)) docs.push(doc);
-        }
-      } catch (err) {
-        _didIteratorError3 = true;
-        _iteratorError3 = err;
-      } finally {
-        try {
-          if (!_iteratorNormalCompletion3 && _iterator3.return) {
-            _iterator3.return();
-          }
-        } finally {
-          if (_didIteratorError3) {
-            throw _iteratorError3;
-          }
-        }
-      }
+/**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+function baseTimes(n, iteratee) {
+  var index = -1,
+      result = Array(n);
 
-      return docs;
-    }).catch(function (error) {
-      // the _all_docs endpoint returns a 404 error if no document with the given
-      // doctype exists.
-      if (error.status === 404) return [];
-      throw error;
-    });
-  });
+  while (++index < n) {
+    result[index] = iteratee(index);
+  }
+  return result;
 }
 
-function changesFeed(cozy, doctype, options) {
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, '_changes', options);
-    return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path);
-  });
-}
+module.exports = baseTimes;
 
-function update(cozy, doctype, doc, changes) {
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-    var _id = doc._id,
-        _rev = doc._rev;
 
+/***/ }),
+/* 444 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    if (!_id) {
-      return Promise.reject(new Error('Missing _id field in passed document'));
-    }
+var baseIsArguments = __webpack_require__(445),
+    isObjectLike = __webpack_require__(53);
 
-    if (!isV2 && !_rev) {
-      return Promise.reject(new Error('Missing _rev field in passed document'));
-    }
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-    if (isV2) {
-      changes = Object.assign({ _id: _id }, changes);
-    } else {
-      changes = Object.assign({ _id: _id, _rev: _rev }, changes);
-    }
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, _id);
-    return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, changes).then(function (resp) {
-      if (isV2) {
-        return find(cozy, doctype, _id);
-      } else {
-        return resp.data;
-      }
-    });
-  });
-}
+/** Built-in value references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
 
-function updateAttributes(cozy, doctype, _id, changes) {
-  var tries = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 3;
+/**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ *  else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
+  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
+    !propertyIsEnumerable.call(value, 'callee');
+};
 
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-    return find(cozy, doctype, _id).then(function (doc) {
-      return update(cozy, doctype, doc, Object.assign({ _id: _id }, doc, changes));
-    }).catch(function (err) {
-      if (tries > 0) {
-        return updateAttributes(cozy, doctype, _id, changes, tries - 1);
-      } else {
-        throw err;
-      }
-    });
-  });
-}
+module.exports = isArguments;
 
-function _delete(cozy, doctype, doc) {
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-    var _id = doc._id,
-        _rev = doc._rev;
 
+/***/ }),
+/* 445 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    if (!_id) {
-      return Promise.reject(new Error('Missing _id field in passed document'));
-    }
+var baseGetTag = __webpack_require__(46),
+    isObjectLike = __webpack_require__(53);
 
-    if (!isV2 && !_rev) {
-      return Promise.reject(new Error('Missing _rev field in passed document'));
-    }
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]';
 
-    var query = isV2 ? null : { rev: _rev };
-    var path = (0, _utils.createPath)(cozy, isV2, doctype, _id, query);
-    return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', path).then(function (resp) {
-      if (isV2) {
-        return { id: _id, rev: NOREV };
-      } else {
-        return resp;
-      }
-    });
-  });
+/**
+ * The base implementation of `_.isArguments`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ */
+function baseIsArguments(value) {
+  return isObjectLike(value) && baseGetTag(value) == argsTag;
 }
 
+module.exports = baseIsArguments;
+
+
 /***/ }),
-/* 14 */
-/***/ (function(module, exports, __nested_webpack_require_69980__) {
+/* 446 */
+/***/ ((module, exports, __webpack_require__) => {
 
-"use strict";
+/* module decorator */ module = __webpack_require__.nmd(module);
+var root = __webpack_require__(48),
+    stubFalse = __webpack_require__(447);
 
+/** Detect free variable `exports`. */
+var freeExports =  true && exports && !exports.nodeType && exports;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
+/** Detect free variable `module`. */
+var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+/** Detect the popular CommonJS extension `module.exports`. */
+var moduleExports = freeModule && freeModule.exports === freeExports;
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+/** Built-in value references. */
+var Buffer = moduleExports ? root.Buffer : undefined;
 
-exports.defineIndex = defineIndex;
-exports.query = query;
-exports.queryFiles = queryFiles;
-exports.parseSelector = parseSelector;
-exports.normalizeSelector = normalizeSelector;
-exports.makeMapReduceQuery = makeMapReduceQuery;
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
 
-var _utils = __nested_webpack_require_69980__(1);
+/**
+ * Checks if `value` is a buffer.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+ * @example
+ *
+ * _.isBuffer(new Buffer(2));
+ * // => true
+ *
+ * _.isBuffer(new Uint8Array(2));
+ * // => false
+ */
+var isBuffer = nativeIsBuffer || stubFalse;
 
-var _doctypes = __nested_webpack_require_69980__(2);
+module.exports = isBuffer;
 
-var _fetch = __nested_webpack_require_69980__(0);
 
-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; }
+/***/ }),
+/* 447 */
+/***/ ((module) => {
 
-function defineIndex(cozy, doctype, fields) {
-  return cozy.isV2().then(function (isV2) {
-    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
-    if (!Array.isArray(fields) || fields.length === 0) {
-      throw new Error('defineIndex fields should be a non-empty array');
-    }
-    if (isV2) {
-      return defineIndexV2(cozy, doctype, fields);
-    } else {
-      return defineIndexV3(cozy, doctype, fields);
-    }
-  });
+/**
+ * This method returns `false`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.13.0
+ * @category Util
+ * @returns {boolean} Returns `false`.
+ * @example
+ *
+ * _.times(2, _.stubFalse);
+ * // => [false, false]
+ */
+function stubFalse() {
+  return false;
 }
 
-function query(cozy, indexRef, options) {
-  return cozy.isV2().then(function (isV2) {
-    if (!indexRef) {
-      throw new Error('query should be passed the indexRef');
-    }
-    if (isV2) {
-      return queryV2(cozy, indexRef, options);
-    } else {
-      return queryV3(cozy, indexRef, options);
-    }
-  });
-}
+module.exports = stubFalse;
 
-function queryFiles(cozy, indexRef, options) {
-  var opts = getV3Options(indexRef, options);
-  return (0, _fetch.cozyFetchRawJSON)(cozy, 'POST', '/files/_find', opts).then(function (response) {
-    return options.wholeResponse ? response : response.docs;
-  });
-}
 
-// Internals
+/***/ }),
+/* 448 */
+/***/ ((module) => {
 
-var VALUEOPERATORS = ['$eq', '$gt', '$gte', '$lt', '$lte'];
-var LOGICOPERATORS = ['$or', '$and', '$not'];
+/** Used as references for various `Number` constants. */
+var MAX_SAFE_INTEGER = 9007199254740991;
 
-/* eslint-disable */
-var MAP_TEMPLATE = function (doc) {
-  if (doc.docType.toLowerCase() === 'DOCTYPEPLACEHOLDER') {
-    emit(FIELDSPLACEHOLDER, doc);
-  }
-}.toString().replace(/ /g, '').replace(/\n/g, '');
-var COUCHDB_INFINITY = { '\uFFFF': '\uFFFF' };
-var COUCHDB_LOWEST = null;
-/* eslint-enable */
+/** Used to detect unsigned integer values. */
+var reIsUint = /^(?:0|[1-9]\d*)$/;
 
-// defineIndexV2 is equivalent to defineIndex but only works for V2.
-// It transforms the index fields into a map reduce view.
-function defineIndexV2(cozy, doctype, fields) {
-  var indexName = 'by' + fields.map(capitalize).join('');
-  var indexDefinition = {
-    map: makeMapFunction(doctype, fields),
-    reduce: '_count'
-  };
-  var path = '/request/' + doctype + '/' + indexName + '/';
-  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, indexDefinition).then(function () {
-    return {
-      doctype: doctype,
-      type: 'mapreduce',
-      name: indexName,
-      fields: fields
-    };
-  });
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+  var type = typeof value;
+  length = length == null ? MAX_SAFE_INTEGER : length;
+
+  return !!length &&
+    (type == 'number' ||
+      (type != 'symbol' && reIsUint.test(value))) &&
+        (value > -1 && value % 1 == 0 && value < length);
 }
 
-function defineIndexV3(cozy, doctype, fields) {
-  var path = (0, _utils.createPath)(cozy, false, doctype, '_index');
-  var indexDefinition = { index: { fields: fields } };
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, indexDefinition).then(function (response) {
-    var indexResult = {
-      doctype: doctype,
-      type: 'mango',
-      name: response.id,
-      fields: fields
-    };
+module.exports = isIndex;
 
-    if (response.result === 'exists') return indexResult;
 
-    // indexes might not be usable right after being created; so we delay the resolving until they are
-    var selector = {};
-    selector[fields[0]] = { $gt: null };
+/***/ }),
+/* 449 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    var opts = getV3Options(indexResult, { selector: selector });
-    var path = (0, _utils.createPath)(cozy, false, indexResult.doctype, '_find');
-    return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function () {
-      return indexResult;
-    }).catch(function () {
-      // one retry
-      return (0, _utils.sleep)(1000).then(function () {
-        return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts);
-      }).then(function () {
-        return indexResult;
-      }).catch(function () {
-        return (0, _utils.sleep)(500).then(function () {
-          return indexResult;
-        });
-      });
-    });
-  });
-}
+var baseIsTypedArray = __webpack_require__(450),
+    baseUnary = __webpack_require__(452),
+    nodeUtil = __webpack_require__(453);
 
-// queryV2 is equivalent to query but only works for V2.
-// It transforms the query into a _views call using makeMapReduceQuery
-function queryV2(cozy, indexRef, options) {
-  if (indexRef.type !== 'mapreduce') {
-    throw new Error('query indexRef should be the return value of defineIndexV2');
-  }
-  if (options.fields) {
-    (0, _utils.warn)('query fields will be ignored on v2');
-  }
+/* Node.js helper references. */
+var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
 
-  var path = '/request/' + indexRef.doctype + '/' + indexRef.name + '/';
-  var opts = makeMapReduceQuery(indexRef, options);
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) {
-    return response.map(function (r) {
-      return r.value;
-    });
-  });
-}
+/**
+ * Checks if `value` is classified as a typed array.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ * @example
+ *
+ * _.isTypedArray(new Uint8Array);
+ * // => true
+ *
+ * _.isTypedArray([]);
+ * // => false
+ */
+var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
 
-// queryV3 is equivalent to query but only works for V3
-function queryV3(cozy, indexRef, options) {
-  var opts = getV3Options(indexRef, options);
+module.exports = isTypedArray;
 
-  var path = (0, _utils.createPath)(cozy, false, indexRef.doctype, '_find');
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) {
-    return options.wholeResponse ? response : response.docs;
-  });
-}
 
-function getV3Options(indexRef, options) {
-  if (indexRef.type !== 'mango') {
-    throw new Error('indexRef should be the return value of defineIndexV3');
-  }
+/***/ }),
+/* 450 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var opts = {
-    use_index: indexRef.name,
-    fields: options.fields,
-    selector: options.selector,
-    limit: options.limit,
-    skip: options.skip,
-    since: options.since,
-    sort: options.sort
-  };
+var baseGetTag = __webpack_require__(46),
+    isLength = __webpack_require__(451),
+    isObjectLike = __webpack_require__(53);
 
-  if (options.descending) {
-    opts.sort = indexRef.fields.map(function (f) {
-      return _defineProperty({}, f, 'desc');
-    });
-  }
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    weakMapTag = '[object WeakMap]';
 
-  return opts;
-}
+var arrayBufferTag = '[object ArrayBuffer]',
+    dataViewTag = '[object DataView]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
 
-// misc
-function capitalize(name) {
-  return name.charAt(0).toUpperCase() + name.slice(1);
+/** Used to identify `toStringTag` values of typed arrays. */
+var typedArrayTags = {};
+typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+typedArrayTags[uint32Tag] = true;
+typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
+typedArrayTags[errorTag] = typedArrayTags[funcTag] =
+typedArrayTags[mapTag] = typedArrayTags[numberTag] =
+typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
+typedArrayTags[setTag] = typedArrayTags[stringTag] =
+typedArrayTags[weakMapTag] = false;
+
+/**
+ * The base implementation of `_.isTypedArray` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+ */
+function baseIsTypedArray(value) {
+  return isObjectLike(value) &&
+    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
 }
 
-function makeMapFunction(doctype, fields) {
-  fields = '[' + fields.map(function (name) {
-    return 'doc.' + name;
-  }).join(',') + ']';
+module.exports = baseIsTypedArray;
 
-  return MAP_TEMPLATE.replace('DOCTYPEPLACEHOLDER', doctype.toLowerCase()).replace('FIELDSPLACEHOLDER', fields);
-}
 
-// parseSelector takes a mango selector and returns it as an array of filter
-// a filter is [path, operator, value] array
-// a path is an array of field names
-// This function is only exported so it can be unit tested.
-// Example :
-// parseSelector({"test":{"deep": {"$gt": 3}}})
-// [[['test', 'deep'], '$gt', 3 ]]
-function parseSelector(selector) {
-  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
-  var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '$eq';
+/***/ }),
+/* 451 */
+/***/ ((module) => {
 
-  if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) !== 'object') {
-    return [[path, operator, selector]];
-  }
+/** Used as references for various `Number` constants. */
+var MAX_SAFE_INTEGER = 9007199254740991;
 
-  var keys = Object.keys(selector);
-  if (keys.length === 0) {
-    throw new Error('empty selector');
-  } else {
-    return keys.reduce(function (acc, k) {
-      if (LOGICOPERATORS.indexOf(k) !== -1) {
-        throw new Error('cozy-client-js does not support mango logic ops');
-      } else if (VALUEOPERATORS.indexOf(k) !== -1) {
-        return acc.concat(parseSelector(selector[k], path, k));
-      } else {
-        return acc.concat(parseSelector(selector[k], path.concat(k), '$eq'));
-      }
-    }, []);
-  }
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+function isLength(value) {
+  return typeof value == 'number' &&
+    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
 }
 
-// normalizeSelector takes a mango selector and returns it as an object
-// normalized.
-// This function is only exported so it can be unit tested.
-// Example :
-// parseSelector({"test":{"deep": {"$gt": 3}}})
-// {"test.deep": {"$gt": 3}}
-function normalizeSelector(selector) {
-  var filters = parseSelector(selector);
-  return filters.reduce(function (acc, filter) {
-    var _filter = _slicedToArray(filter, 3),
-        path = _filter[0],
-        op = _filter[1],
-        value = _filter[2];
+module.exports = isLength;
 
-    var field = path.join('.');
-    acc[field] = acc[field] || {};
-    acc[field][op] = value;
-    return acc;
-  }, {});
+
+/***/ }),
+/* 452 */
+/***/ ((module) => {
+
+/**
+ * The base implementation of `_.unary` without support for storing metadata.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new capped function.
+ */
+function baseUnary(func) {
+  return function(value) {
+    return func(value);
+  };
 }
 
-// applySelector takes the normalized selector for the current field
-// and append the proper values to opts.startkey, opts.endkey
-function applySelector(selector, opts) {
-  var value = selector['$eq'];
-  var lower = COUCHDB_LOWEST;
-  var upper = COUCHDB_INFINITY;
-  var inclusiveEnd = void 0;
+module.exports = baseUnary;
 
-  if (value) {
-    opts.startkey.push(value);
-    opts.endkey.push(value);
-    return false;
-  }
 
-  value = selector['$gt'];
-  if (value) {
-    throw new Error('operator $gt (strict greater than) not supported');
-  }
+/***/ }),
+/* 453 */
+/***/ ((module, exports, __webpack_require__) => {
 
-  value = selector['$gte'];
-  if (value) {
-    lower = value;
-  }
+/* module decorator */ module = __webpack_require__.nmd(module);
+var freeGlobal = __webpack_require__(49);
 
-  value = selector['$lte'];
-  if (value) {
-    upper = value;
-    inclusiveEnd = true;
-  }
+/** Detect free variable `exports`. */
+var freeExports =  true && exports && !exports.nodeType && exports;
 
-  value = selector['$lt'];
-  if (value) {
-    upper = value;
-    inclusiveEnd = false;
-  }
+/** Detect free variable `module`. */
+var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
 
-  opts.startkey.push(lower);
-  opts.endkey.push(upper);
-  if (inclusiveEnd !== undefined) opts.inclusive_end = inclusiveEnd;
-  return true;
-}
+/** Detect the popular CommonJS extension `module.exports`. */
+var moduleExports = freeModule && freeModule.exports === freeExports;
 
-// makeMapReduceQuery takes a mango query and generate _views call parameters
-// to obtain same results depending on fields in the passed indexRef.
-function makeMapReduceQuery(indexRef, query) {
-  var mrquery = {
-    startkey: [],
-    endkey: [],
-    reduce: false
-  };
-  var firstFreeValueField = null;
-  var normalizedSelector = normalizeSelector(query.selector);
+/** Detect free variable `process` from Node.js. */
+var freeProcess = moduleExports && freeGlobal.process;
 
-  indexRef.fields.forEach(function (field) {
-    var selector = normalizedSelector[field];
+/** Used to access faster Node.js helpers. */
+var nodeUtil = (function() {
+  try {
+    // Use `util.types` for Node.js 10+.
+    var types = freeModule && freeModule.require && freeModule.require('util').types;
 
-    if (selector && firstFreeValueField != null) {
-      throw new Error('Selector on field ' + field + ', but not on ' + firstFreeValueField + ' which is higher in index fields.');
-    } else if (selector) {
-      selector.used = true;
-      var isFreeValue = applySelector(selector, mrquery);
-      if (isFreeValue) firstFreeValueField = field;
-    } else if (firstFreeValueField == null) {
-      firstFreeValueField = field;
-      mrquery.endkey.push(COUCHDB_INFINITY);
+    if (types) {
+      return types;
     }
-  });
 
-  Object.keys(normalizedSelector).forEach(function (field) {
-    if (!normalizedSelector[field].used) {
-      throw new Error('Cant apply selector on ' + field + ', it is not in index');
-    }
-  });
+    // Legacy `process.binding('util')` for Node.js < 10.
+    return freeProcess && freeProcess.binding && freeProcess.binding('util');
+  } catch (e) {}
+}());
 
-  if (query.descending) {
-    mrquery = {
-      descending: true,
-      reduce: false,
-      startkey: mrquery.endkey,
-      endkey: mrquery.startkey,
-      inclusive_end: mrquery.inclusive_end
-    };
-  }
+module.exports = nodeUtil;
 
-  return mrquery;
-}
 
 /***/ }),
-/* 15 */
-/***/ (function(module, exports, __nested_webpack_require_80935__) {
+/* 454 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var isPrototype = __webpack_require__(455),
+    nativeKeys = __webpack_require__(456);
 
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.TRASH_DIR_ID = exports.ROOT_DIR_ID = undefined;
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-var _regenerator = __nested_webpack_require_80935__(4);
+/**
+ * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function baseKeys(object) {
+  if (!isPrototype(object)) {
+    return nativeKeys(object);
+  }
+  var result = [];
+  for (var key in Object(object)) {
+    if (hasOwnProperty.call(object, key) && key != 'constructor') {
+      result.push(key);
+    }
+  }
+  return result;
+}
 
-var _regenerator2 = _interopRequireDefault(_regenerator);
+module.exports = baseKeys;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* global Blob, File */
+/***/ }),
+/* 455 */
+/***/ ((module) => {
 
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-var doUpload = function () {
-  var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, data, method, path, options) {
-    var isBuffer, isFile, isBlob, isStream, isString, _ref2, contentType, contentLength, checksum, createdAt, updatedAt, executable, lastModifiedDate, ifMatch, metadata, sourceAccount, sourceAccountIdentifier, signal, finalpath, metadataId, headers;
+/**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+function isPrototype(value) {
+  var Ctor = value && value.constructor,
+      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
 
-    return _regenerator2.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            if (data) {
-              _context.next = 2;
-              break;
-            }
+  return value === proto;
+}
 
-            throw new Error('missing data argument');
+module.exports = isPrototype;
 
-          case 2:
 
-            // transform any ArrayBufferView to ArrayBuffer
-            if (data.buffer && data.buffer instanceof ArrayBuffer) {
-              data = data.buffer;
-            }
+/***/ }),
+/* 456 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-            isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer;
-            isFile = typeof File !== 'undefined' && data instanceof File;
-            isBlob = typeof Blob !== 'undefined' && data instanceof Blob;
-            isStream = data.readable === true && typeof data.pipe === 'function';
-            isString = typeof data === 'string';
+var overArg = __webpack_require__(457);
 
-            if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) {
-              _context.next = 10;
-              break;
-            }
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeKeys = overArg(Object.keys, Object);
 
-            throw new Error('invalid data type');
+module.exports = nativeKeys;
 
-          case 10:
-            _ref2 = options || {}, contentType = _ref2.contentType, contentLength = _ref2.contentLength, checksum = _ref2.checksum, createdAt = _ref2.createdAt, updatedAt = _ref2.updatedAt, executable = _ref2.executable, lastModifiedDate = _ref2.lastModifiedDate, ifMatch = _ref2.ifMatch, metadata = _ref2.metadata, sourceAccount = _ref2.sourceAccount, sourceAccountIdentifier = _ref2.sourceAccountIdentifier, signal = _ref2.signal;
 
-            if (!contentType) {
-              if (isBuffer) {
-                contentType = contentTypeOctetStream;
-              } else if (isFile) {
-                contentType = data.type || getFileTypeFromName(data.name.toLowerCase()) || contentTypeOctetStream;
-                if (!lastModifiedDate) {
-                  lastModifiedDate = data.lastModifiedDate;
-                }
-              } else if (isBlob) {
-                contentType = data.type || contentTypeOctetStream;
-              } else if (isStream) {
-                contentType = contentTypeOctetStream;
-              } else if (typeof data === 'string') {
-                contentType = 'text/plain';
-              }
-            }
+/***/ }),
+/* 457 */
+/***/ ((module) => {
 
-            if (lastModifiedDate && typeof lastModifiedDate === 'string') {
-              lastModifiedDate = new Date(lastModifiedDate);
-            }
-            if (!createdAt) {
-              createdAt = lastModifiedDate;
-            }
-            if (!updatedAt) {
-              updatedAt = lastModifiedDate;
-            }
+/**
+ * Creates a unary function that invokes `func` with its argument transformed.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {Function} transform The argument transform.
+ * @returns {Function} Returns the new function.
+ */
+function overArg(func, transform) {
+  return function(arg) {
+    return func(transform(arg));
+  };
+}
 
-            if (!executable) {
-              executable = false;
-            }
+module.exports = overArg;
 
-            finalpath = path;
 
-            if (!metadata) {
-              _context.next = 22;
-              break;
-            }
+/***/ }),
+/* 458 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-            _context.next = 20;
-            return sendMetadata(cozy, metadata);
+var isFunction = __webpack_require__(45),
+    isLength = __webpack_require__(451);
 
-          case 20:
-            metadataId = _context.sent;
+/**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+function isArrayLike(value) {
+  return value != null && isLength(value.length) && !isFunction(value);
+}
 
-            if (metadataId) {
-              finalpath = addQuerystringParam(finalpath, 'MetadataID', metadataId);
-            }
+module.exports = isArrayLike;
 
-          case 22:
-            if (sourceAccount) {
-              finalpath = addQuerystringParam(finalpath, 'SourceAccount', sourceAccount);
-            }
-            if (sourceAccountIdentifier) {
-              finalpath = addQuerystringParam(finalpath, 'SourceAccountIdentifier', sourceAccountIdentifier);
-            }
-            if (createdAt) {
-              finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt));
-            }
-            if (updatedAt) {
-              finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt));
-            }
-            if (executable) {
-              finalpath = addQuerystringParam(finalpath, 'Executable', executable);
-            }
 
-            headers = {
-              'Content-Type': contentType
-            };
+/***/ }),
+/* 459 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-            if (contentLength) {
-              headers['Content-Length'] = String(contentLength);
-              finalpath = addQuerystringParam(finalpath, 'Size', String(contentLength));
-            }
-            if (checksum) headers['Content-MD5'] = checksum;
-            if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString();
-            if (ifMatch) headers['If-Match'] = ifMatch;
+var DataView = __webpack_require__(460),
+    Map = __webpack_require__(401),
+    Promise = __webpack_require__(461),
+    Set = __webpack_require__(462),
+    WeakMap = __webpack_require__(463),
+    baseGetTag = __webpack_require__(46),
+    toSource = __webpack_require__(387);
 
-            return _context.abrupt('return', (0, _fetch.cozyFetch)(cozy, finalpath, {
-              method: method,
-              headers: headers,
-              body: data,
-              signal: signal
-            }).then(function (res) {
-              var json = res.json();
-              if (!res.ok) {
-                return json.then(function (err) {
-                  throw err;
-                });
-              } else {
-                return json.then(_jsonapi2.default);
-              }
-            }));
+/** `Object#toString` result references. */
+var mapTag = '[object Map]',
+    objectTag = '[object Object]',
+    promiseTag = '[object Promise]',
+    setTag = '[object Set]',
+    weakMapTag = '[object WeakMap]';
 
-          case 33:
-          case 'end':
-            return _context.stop();
-        }
-      }
-    }, _callee, this);
-  }));
+var dataViewTag = '[object DataView]';
 
-  return function doUpload(_x, _x2, _x3, _x4, _x5) {
-    return _ref.apply(this, arguments);
-  };
-}();
+/** Used to detect maps, sets, and weakmaps. */
+var dataViewCtorString = toSource(DataView),
+    mapCtorString = toSource(Map),
+    promiseCtorString = toSource(Promise),
+    setCtorString = toSource(Set),
+    weakMapCtorString = toSource(WeakMap);
 
-var sendMetadata = function () {
-  var _ref3 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, metadata) {
-    var result;
-    return _regenerator2.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            _context2.next = 2;
-            return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/upload/metadata', {
-              data: { type: 'io.cozy.files.metadata', attributes: metadata }
-            });
+/**
+ * Gets the `toStringTag` of `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+var getTag = baseGetTag;
 
-          case 2:
-            result = _context2.sent;
-            return _context2.abrupt('return', result && result._id ? result._id : false);
+// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
+if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
+    (Map && getTag(new Map) != mapTag) ||
+    (Promise && getTag(Promise.resolve()) != promiseTag) ||
+    (Set && getTag(new Set) != setTag) ||
+    (WeakMap && getTag(new WeakMap) != weakMapTag)) {
+  getTag = function(value) {
+    var result = baseGetTag(value),
+        Ctor = result == objectTag ? value.constructor : undefined,
+        ctorString = Ctor ? toSource(Ctor) : '';
 
-          case 4:
-          case 'end':
-            return _context2.stop();
-        }
+    if (ctorString) {
+      switch (ctorString) {
+        case dataViewCtorString: return dataViewTag;
+        case mapCtorString: return mapTag;
+        case promiseCtorString: return promiseTag;
+        case setCtorString: return setTag;
+        case weakMapCtorString: return weakMapTag;
       }
-    }, _callee2, this);
-  }));
-
-  return function sendMetadata(_x6, _x7) {
-    return _ref3.apply(this, arguments);
+    }
+    return result;
   };
-}();
+}
 
-exports.create = create;
-exports.createDirectory = createDirectory;
-exports.createDirectoryByPath = createDirectoryByPath;
-exports.updateById = updateById;
-exports.updateAttributesById = updateAttributesById;
-exports.updateAttributesByPath = updateAttributesByPath;
-exports.trashById = trashById;
-exports.statById = statById;
-exports.statByPath = statByPath;
-exports.downloadById = downloadById;
-exports.downloadByPath = downloadByPath;
-exports.getDownloadLinkByPath = getDownloadLinkByPath;
-exports.getDownloadLinkById = getDownloadLinkById;
-exports.getFilePath = getFilePath;
-exports.getCollectionShareLink = getCollectionShareLink;
-exports.getArchiveLinkByPaths = getArchiveLinkByPaths;
-exports.getArchiveLinkByIds = getArchiveLinkByIds;
-exports.listTrash = listTrash;
-exports.clearTrash = clearTrash;
-exports.restoreById = restoreById;
-exports.destroyById = destroyById;
+module.exports = getTag;
 
-var _fetch = __nested_webpack_require_80935__(0);
 
-var _jsonapi = __nested_webpack_require_80935__(7);
+/***/ }),
+/* 460 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _jsonapi2 = _interopRequireDefault(_jsonapi);
+var getNative = __webpack_require__(383),
+    root = __webpack_require__(48);
 
-var _doctypes = __nested_webpack_require_80935__(2);
+/* Built-in method references that are verified to be native. */
+var DataView = getNative(root, 'DataView');
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+module.exports = DataView;
 
-function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
-// global variables
-var ROOT_DIR_ID = exports.ROOT_DIR_ID = 'io.cozy.files.root-dir';
-var TRASH_DIR_ID = exports.TRASH_DIR_ID = 'io.cozy.files.trash-dir';
+/***/ }),
+/* 461 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var contentTypeOctetStream = 'application/octet-stream';
+var getNative = __webpack_require__(383),
+    root = __webpack_require__(48);
 
-function sanitizeFileName(name) {
-  return name && name.trim();
-}
+/* Built-in method references that are verified to be native. */
+var Promise = getNative(root, 'Promise');
 
-function getFileTypeFromName(name) {
-  if (/\.heic$/i.test(name)) return 'image/heic';else if (/\.heif$/i.test(name)) return 'image/heif';else return null;
-}
+module.exports = Promise;
 
-function dateString(date) {
-  return (typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object' ? date.toISOString() : date;
-}
 
-function create(cozy, data, options) {
-  var _ref4 = options || {},
-      name = _ref4.name,
-      dirID = _ref4.dirID,
-      noSanitize = _ref4.noSanitize;
+/***/ }),
+/* 462 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  // handle case where data is a file and contains the name
+var getNative = __webpack_require__(383),
+    root = __webpack_require__(48);
 
+/* Built-in method references that are verified to be native. */
+var Set = getNative(root, 'Set');
 
-  if (!name && typeof data.name === 'string') {
-    name = data.name;
-  }
+module.exports = Set;
 
-  if (!noSanitize) {
-    name = sanitizeFileName(name);
-  }
 
-  if (typeof name !== 'string' || name === '') {
-    throw new Error('missing name argument');
-  }
+/***/ }),
+/* 463 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var path = '/files/' + encodeURIComponent(dirID || '');
-  var query = '?Name=' + encodeURIComponent(name) + '&Type=file';
-  return doUpload(cozy, data, 'POST', '' + path + query, options);
-}
+var getNative = __webpack_require__(383),
+    root = __webpack_require__(48);
 
-function createDirectory(cozy, options) {
-  var _ref5 = options || {},
-      name = _ref5.name,
-      dirID = _ref5.dirID,
-      createdAt = _ref5.createdAt,
-      updatedAt = _ref5.updatedAt,
-      lastModifiedDate = _ref5.lastModifiedDate,
-      noSanitize = _ref5.noSanitize;
+/* Built-in method references that are verified to be native. */
+var WeakMap = getNative(root, 'WeakMap');
 
-  if (!noSanitize) {
-    name = sanitizeFileName(name);
-  }
+module.exports = WeakMap;
 
-  if (typeof name !== 'string' || name === '') {
-    throw new Error('missing name argument');
-  }
 
-  if (lastModifiedDate && typeof lastModifiedDate === 'string') {
-    lastModifiedDate = new Date(lastModifiedDate);
-  }
-  if (!createdAt) {
-    createdAt = lastModifiedDate;
-  }
-  if (!updatedAt) {
-    updatedAt = lastModifiedDate;
-  }
+/***/ }),
+/* 464 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var path = '/files/' + encodeURIComponent(dirID || '');
-  var query = '?Name=' + encodeURIComponent(name) + '&Type=directory';
+var isStrictComparable = __webpack_require__(465),
+    keys = __webpack_require__(441);
 
-  var finalpath = '' + path + query;
-  if (createdAt) {
-    finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt));
-  }
-  if (updatedAt) {
-    finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt));
-  }
+/**
+ * Gets the property names, values, and compare flags of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the match data of `object`.
+ */
+function getMatchData(object) {
+  var result = keys(object),
+      length = result.length;
 
-  var headers = {};
-  if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString();
+  while (length--) {
+    var key = result[length],
+        value = object[key];
 
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', finalpath, undefined, {
-    headers: headers
-  });
+    result[length] = [key, value, isStrictComparable(value)];
+  }
+  return result;
 }
 
-function getDirectoryOrCreate(cozy, name, parentDirectory, options) {
-  if (parentDirectory && !parentDirectory.attributes) throw new Error('Malformed parent directory');
-
-  var _ref6 = options || {},
-      noSanitize = _ref6.noSanitize;
+module.exports = getMatchData;
 
-  if (!noSanitize) {
-    name = sanitizeFileName(name);
-  }
 
-  var path = (parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path) + '/' + name;
+/***/ }),
+/* 465 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  return cozy.files.statByPath(path || '/').catch(function (error) {
-    var parsedError = JSON.parse(error.message);
-    var errors = parsedError.errors;
-    if (errors && errors.length && errors[0].status === '404') {
-      return cozy.files.createDirectory({
-        name: name,
-        dirID: parentDirectory && parentDirectory._id
-      });
-    }
+var isObject = __webpack_require__(52);
 
-    throw errors;
-  });
+/**
+ * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` if suitable for strict
+ *  equality comparisons, else `false`.
+ */
+function isStrictComparable(value) {
+  return value === value && !isObject(value);
 }
 
-function createDirectoryByPath(cozy, path, offline, options) {
-  var parts = path.split('/').filter(function (part) {
-    return part !== '';
-  });
+module.exports = isStrictComparable;
 
-  var rootDirectoryPromise = cozy.files.statById(ROOT_DIR_ID, offline);
 
-  return parts.length ? parts.reduce(function (parentDirectoryPromise, part) {
-    return parentDirectoryPromise.then(function (parentDirectory) {
-      return getDirectoryOrCreate(cozy, part, parentDirectory, options);
-    });
-  }, rootDirectoryPromise) : rootDirectoryPromise;
-}
+/***/ }),
+/* 466 */
+/***/ ((module) => {
 
-function updateById(cozy, id, data, options) {
-  return doUpload(cozy, data, 'PUT', '/files/' + encodeURIComponent(id), options);
+/**
+ * A specialized version of `matchesProperty` for source values suitable
+ * for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ */
+function matchesStrictComparable(key, srcValue) {
+  return function(object) {
+    if (object == null) {
+      return false;
+    }
+    return object[key] === srcValue &&
+      (srcValue !== undefined || (key in Object(object)));
+  };
 }
 
-function doUpdateAttributes(cozy, attrs, path, options) {
-  if (!attrs || (typeof attrs === 'undefined' ? 'undefined' : _typeof(attrs)) !== 'object') {
-    throw new Error('missing attrs argument');
-  }
+module.exports = matchesStrictComparable;
 
-  var _ref7 = options || {},
-      ifMatch = _ref7.ifMatch,
-      noSanitize = _ref7.noSanitize;
 
-  var name = attrs.name;
-  if (!noSanitize) {
-    name = sanitizeFileName(name);
-  }
+/***/ }),
+/* 467 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var body = {
-    data: {
-      attributes: Object.assign({}, attrs, {
-        name: name
-      })
-    }
+var baseIsEqual = __webpack_require__(422),
+    get = __webpack_require__(370),
+    hasIn = __webpack_require__(468),
+    isKey = __webpack_require__(373),
+    isStrictComparable = __webpack_require__(465),
+    matchesStrictComparable = __webpack_require__(466),
+    toKey = __webpack_require__(411);
+
+/** Used to compose bitmasks for value comparisons. */
+var COMPARE_PARTIAL_FLAG = 1,
+    COMPARE_UNORDERED_FLAG = 2;
+
+/**
+ * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
+ *
+ * @private
+ * @param {string} path The path of the property to get.
+ * @param {*} srcValue The value to match.
+ * @returns {Function} Returns the new spec function.
+ */
+function baseMatchesProperty(path, srcValue) {
+  if (isKey(path) && isStrictComparable(srcValue)) {
+    return matchesStrictComparable(toKey(path), srcValue);
+  }
+  return function(object) {
+    var objValue = get(object, path);
+    return (objValue === undefined && objValue === srcValue)
+      ? hasIn(object, path)
+      : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
   };
-  return (0, _fetch.cozyFetchJSON)(cozy, 'PATCH', path, body, {
-    headers: {
-      'If-Match': ifMatch || ''
-    }
-  });
 }
 
-function updateAttributesById(cozy, id, attrs, options) {
-  return doUpdateAttributes(cozy, attrs, '/files/' + encodeURIComponent(id), options);
-}
+module.exports = baseMatchesProperty;
 
-function updateAttributesByPath(cozy, path, attrs, options) {
-  return doUpdateAttributes(cozy, attrs, '/files/metadata?Path=' + encodeURIComponent(path), options);
-}
 
-function trashById(cozy, id, options) {
-  if (typeof id !== 'string' || id === '') {
-    throw new Error('missing id argument');
-  }
+/***/ }),
+/* 468 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var _ref8 = options || {},
-      ifMatch = _ref8.ifMatch;
+var baseHasIn = __webpack_require__(469),
+    hasPath = __webpack_require__(470);
 
-  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/' + encodeURIComponent(id), undefined, {
-    headers: {
-      'If-Match': ifMatch || ''
-    }
-  });
+/**
+ * Checks if `path` is a direct or inherited property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = _.create({ 'a': _.create({ 'b': 2 }) });
+ *
+ * _.hasIn(object, 'a');
+ * // => true
+ *
+ * _.hasIn(object, 'a.b');
+ * // => true
+ *
+ * _.hasIn(object, ['a', 'b']);
+ * // => true
+ *
+ * _.hasIn(object, 'b');
+ * // => false
+ */
+function hasIn(object, path) {
+  return object != null && hasPath(object, path, baseHasIn);
 }
 
-function statById(cozy, id) {
-  var offline = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
-  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+module.exports = hasIn;
 
-  if (offline && cozy.offline.hasDatabase(_doctypes.DOCTYPE_FILES)) {
-    var db = cozy.offline.getDatabase(_doctypes.DOCTYPE_FILES);
-    return Promise.all([db.get(id), db.find(Object.assign({ selector: { dir_id: id } }, options))]).then(function (_ref9) {
-      var _ref10 = _slicedToArray(_ref9, 2),
-          doc = _ref10[0],
-          children = _ref10[1];
 
-      if (id === ROOT_DIR_ID) {
-        children.docs = children.docs.filter(function (doc) {
-          return doc._id !== TRASH_DIR_ID;
-        });
-      }
-      children = sortFiles(children.docs.map(function (doc) {
-        return addIsDir(toJsonApi(cozy, doc));
-      }));
-      return addIsDir(toJsonApi(cozy, doc, children));
-    });
-  }
-  var query = Object.keys(options).length === 0 ? '' : '?' + encodePageOptions(options);
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/' + encodeURIComponent(id) + query).then(addIsDir);
-}
+/***/ }),
+/* 469 */
+/***/ ((module) => {
 
-function statByPath(cozy, path) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/metadata?Path=' + encodeURIComponent(path)).then(addIsDir);
+/**
+ * The base implementation of `_.hasIn` without support for deep paths.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+function baseHasIn(object, key) {
+  return object != null && key in Object(object);
 }
 
-function downloadById(cozy, id) {
-  return (0, _fetch.cozyFetch)(cozy, '/files/download/' + encodeURIComponent(id));
-}
+module.exports = baseHasIn;
 
-function downloadByPath(cozy, path) {
-  return (0, _fetch.cozyFetch)(cozy, '/files/download?Path=' + encodeURIComponent(path));
-}
 
-function extractResponseLinkRelated(res) {
-  var href = res.links && res.links.related;
-  if (!href) throw new Error('No related link in server response');
-  return href;
-}
+/***/ }),
+/* 470 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function getDownloadLinkByPath(cozy, path) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Path=' + encodeURIComponent(path)).then(extractResponseLinkRelated);
-}
+var castPath = __webpack_require__(372),
+    isArguments = __webpack_require__(444),
+    isArray = __webpack_require__(55),
+    isIndex = __webpack_require__(448),
+    isLength = __webpack_require__(451),
+    toKey = __webpack_require__(411);
 
-function getDownloadLinkById(cozy, id) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Id=' + encodeURIComponent(id)).then(extractResponseLinkRelated);
-}
+/**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */
+function hasPath(object, path, hasFunc) {
+  path = castPath(path, object);
 
-function getFilePath(cozy) {
-  var file = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-  var folder = arguments[2];
+  var index = -1,
+      length = path.length,
+      result = false;
 
-  if (!folder || !folder.attributes) {
-    throw Error('Folder should be valid with an attributes.path property');
+  while (++index < length) {
+    var key = toKey(path[index]);
+    if (!(result = object != null && hasFunc(object, key))) {
+      break;
+    }
+    object = object[key];
+  }
+  if (result || ++index != length) {
+    return result;
   }
+  length = object == null ? 0 : object.length;
+  return !!length && isLength(length) && isIndex(key, length) &&
+    (isArray(object) || isArguments(object));
+}
 
-  var folderPath = folder.attributes.path.endsWith('/') ? folder.attributes.path : folder.attributes.path + '/';
+module.exports = hasPath;
 
-  return '' + folderPath + file.name;
+
+/***/ }),
+/* 471 */
+/***/ ((module) => {
+
+/**
+ * This method returns the first argument it receives.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Util
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'a': 1 };
+ *
+ * console.log(_.identity(object) === object);
+ * // => true
+ */
+function identity(value) {
+  return value;
 }
 
-function getCollectionShareLink(cozy, id, collectionType) {
-  if (!id) {
-    return Promise.reject(Error('An id should be provided to create a share link'));
-  }
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/permissions?codes=email', {
-    data: {
-      type: 'io.cozy.permissions',
-      attributes: {
-        permissions: {
-          files: {
-            type: 'io.cozy.files',
-            verbs: ['GET'],
-            values: [id],
-            selector: 'referenced_by'
-          },
-          collection: {
-            type: collectionType,
-            verbs: ['GET'],
-            values: [id]
-          }
-        }
-      }
-    }
-  }).then(function (data) {
-    return {
-      sharecode: 'sharecode=' + data.attributes.codes.email,
-      id: 'id=' + id
-    };
-  });
+module.exports = identity;
+
+
+/***/ }),
+/* 472 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var baseProperty = __webpack_require__(473),
+    basePropertyDeep = __webpack_require__(474),
+    isKey = __webpack_require__(373),
+    toKey = __webpack_require__(411);
+
+/**
+ * Creates a function that returns the value at `path` of a given object.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Util
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ * @example
+ *
+ * var objects = [
+ *   { 'a': { 'b': 2 } },
+ *   { 'a': { 'b': 1 } }
+ * ];
+ *
+ * _.map(objects, _.property('a.b'));
+ * // => [2, 1]
+ *
+ * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
+ * // => [1, 2]
+ */
+function property(path) {
+  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
 }
 
-function getArchiveLinkByPaths(cozy, paths) {
-  var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files';
+module.exports = property;
 
-  var archive = {
-    type: 'io.cozy.archives',
-    attributes: {
-      name: name,
-      files: paths
-    }
+
+/***/ }),
+/* 473 */
+/***/ ((module) => {
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */
+function baseProperty(key) {
+  return function(object) {
+    return object == null ? undefined : object[key];
   };
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated);
 }
 
-function getArchiveLinkByIds(cozy, ids) {
-  var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files';
+module.exports = baseProperty;
 
-  var archive = {
-    type: 'io.cozy.archives',
-    attributes: {
-      name: name,
-      ids: ids
-    }
+
+/***/ }),
+/* 474 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var baseGet = __webpack_require__(371);
+
+/**
+ * A specialized version of `baseProperty` which supports deep paths.
+ *
+ * @private
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */
+function basePropertyDeep(path) {
+  return function(object) {
+    return baseGet(object, path);
   };
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated);
 }
 
-function listTrash(cozy) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/trash');
-}
+module.exports = basePropertyDeep;
 
-function clearTrash(cozy) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash');
-}
 
-function restoreById(cozy, id) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/trash/' + encodeURIComponent(id));
-}
+/***/ }),
+/* 475 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function destroyById(cozy, id, options) {
-  var _ref11 = options || {},
-      ifMatch = _ref11.ifMatch;
+var SetCache = __webpack_require__(425),
+    arrayIncludes = __webpack_require__(476),
+    arrayIncludesWith = __webpack_require__(481),
+    cacheHas = __webpack_require__(429),
+    createSet = __webpack_require__(482),
+    setToArray = __webpack_require__(433);
 
-  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash/' + encodeURIComponent(id), undefined, {
-    headers: {
-      'If-Match': ifMatch || ''
-    }
-  });
-}
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
 
-function addIsDir(obj) {
-  obj.isDir = obj.attributes.type === 'directory';
-  return obj;
-}
+/**
+ * The base implementation of `_.uniqBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+function baseUniq(array, iteratee, comparator) {
+  var index = -1,
+      includes = arrayIncludes,
+      length = array.length,
+      isCommon = true,
+      result = [],
+      seen = result;
 
-function encodePageOptions(options) {
-  var opts = [];
-  for (var name in options) {
-    opts.push('page[' + encodeURIComponent(name) + ']=' + encodeURIComponent(options[name]));
+  if (comparator) {
+    isCommon = false;
+    includes = arrayIncludesWith;
   }
-  return opts.join('&');
-}
-
-function toJsonApi(cozy, doc) {
-  var contents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
+  else if (length >= LARGE_ARRAY_SIZE) {
+    var set = iteratee ? null : createSet(array);
+    if (set) {
+      return setToArray(set);
+    }
+    isCommon = false;
+    includes = cacheHas;
+    seen = new SetCache;
+  }
+  else {
+    seen = iteratee ? [] : result;
+  }
+  outer:
+  while (++index < length) {
+    var value = array[index],
+        computed = iteratee ? iteratee(value) : value;
 
-  var clone = JSON.parse(JSON.stringify(doc));
-  delete clone._id;
-  delete clone._rev;
-  return {
-    _id: doc._id,
-    _rev: doc._rev,
-    _type: _doctypes.DOCTYPE_FILES,
-    attributes: clone,
-    relationships: {
-      contents: {
-        data: contents,
-        meta: {
-          count: contents.length
+    value = (comparator || value !== 0) ? value : 0;
+    if (isCommon && computed === computed) {
+      var seenIndex = seen.length;
+      while (seenIndex--) {
+        if (seen[seenIndex] === computed) {
+          continue outer;
         }
       }
-    },
-    relations: function relations(name) {
-      if (name === 'contents') {
-        return contents;
+      if (iteratee) {
+        seen.push(computed);
+      }
+      result.push(value);
+    }
+    else if (!includes(seen, computed, comparator)) {
+      if (seen !== result) {
+        seen.push(computed);
       }
+      result.push(value);
     }
-  };
+  }
+  return result;
 }
 
-function sortFiles(allFiles) {
-  var folders = allFiles.filter(function (f) {
-    return f.attributes.type === 'directory';
-  });
-  var files = allFiles.filter(function (f) {
-    return f.attributes.type !== 'directory';
-  });
-  var sort = function sort(files) {
-    return files.sort(function (a, b) {
-      return a.attributes.name.localeCompare(b.attributes.name);
-    });
-  };
-  return sort(folders).concat(sort(files));
-}
+module.exports = baseUniq;
 
-function addQuerystringParam(path, key, value) {
-  return '' + path + (path.includes('?') ? '&' : '?') + key + '=' + value;
-}
 
 /***/ }),
-/* 16 */
-/***/ (function(module, exports, __nested_webpack_require_101343__) {
-
-"use strict";
+/* 476 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var baseIndexOf = __webpack_require__(477);
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
+/**
+ * A specialized version of `_.includes` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} [array] The array to inspect.
+ * @param {*} target The value to search for.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+function arrayIncludes(array, value) {
+  var length = array == null ? 0 : array.length;
+  return !!length && baseIndexOf(array, value, 0) > -1;
+}
 
-var _regenerator = __nested_webpack_require_101343__(4);
+module.exports = arrayIncludes;
 
-var _regenerator2 = _interopRequireDefault(_regenerator);
 
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+/***/ }),
+/* 477 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-exports.start = start;
+var baseFindIndex = __webpack_require__(478),
+    baseIsNaN = __webpack_require__(479),
+    strictIndexOf = __webpack_require__(480);
 
-var _helpers = __nested_webpack_require_101343__(5);
+/**
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseIndexOf(array, value, fromIndex) {
+  return value === value
+    ? strictIndexOf(array, value, fromIndex)
+    : baseFindIndex(array, baseIsNaN, fromIndex);
+}
 
-var _ = __nested_webpack_require_101343__(8);
+module.exports = baseIndexOf;
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
+/***/ }),
+/* 478 */
+/***/ ((module) => {
 
-var intentClass = 'coz-intent';
+/**
+ * The base implementation of `_.findIndex` and `_.findLastIndex` without
+ * support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseFindIndex(array, predicate, fromIndex, fromRight) {
+  var length = array.length,
+      index = fromIndex + (fromRight ? 1 : -1);
 
-function hideIntentIframe(iframe) {
-  iframe.style.display = 'none';
+  while ((fromRight ? index-- : ++index < length)) {
+    if (predicate(array[index], index, array)) {
+      return index;
+    }
+  }
+  return -1;
 }
 
-function showIntentFrame(iframe) {
-  iframe.style.display = 'block';
-}
+module.exports = baseFindIndex;
 
-function buildIntentIframe(intent, element, url) {
-  var document = element.ownerDocument;
-  if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element'));
 
-  var iframe = document.createElement('iframe');
-  // TODO: implement 'title' attribute
-  iframe.setAttribute('id', 'intent-' + intent._id);
-  iframe.setAttribute('src', url);
-  iframe.classList.add(intentClass);
-  return iframe;
+/***/ }),
+/* 479 */
+/***/ ((module) => {
+
+/**
+ * The base implementation of `_.isNaN` without support for number objects.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+ */
+function baseIsNaN(value) {
+  return value !== value;
 }
 
-function injectIntentIframe(intent, element, url, options) {
-  var onReadyCallback = options.onReadyCallback;
+module.exports = baseIsNaN;
 
-  var iframe = buildIntentIframe(intent, element, url, options.onReadyCallback);
-  // if callback provided for when iframe is loaded
-  if (typeof onReadyCallback === 'function') iframe.onload = onReadyCallback;
-  element.appendChild(iframe);
-  iframe.focus();
-  return iframe;
-}
 
-// inject iframe for service in given element
-function connectIntentIframe(cozy, iframe, element, intent, data) {
-  var _this = this;
+/***/ }),
+/* 480 */
+/***/ ((module) => {
 
-  var compose = function () {
-    var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, action, doctype, data) {
-      var intent, doc;
-      return _regenerator2.default.wrap(function _callee$(_context) {
-        while (1) {
-          switch (_context.prev = _context.next) {
-            case 0:
-              _context.next = 2;
-              return (0, _.create)(cozy, action, doctype, data);
+/**
+ * A specialized version of `_.indexOf` which performs strict equality
+ * comparisons of values, i.e. `===`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function strictIndexOf(array, value, fromIndex) {
+  var index = fromIndex - 1,
+      length = array.length;
 
-            case 2:
-              intent = _context.sent;
+  while (++index < length) {
+    if (array[index] === value) {
+      return index;
+    }
+  }
+  return -1;
+}
 
-              hideIntentIframe(iframe);
-              _context.next = 6;
-              return start(cozy, intent, element, _extends({}, data, {
-                exposeIntentFrameRemoval: false
-              }));
+module.exports = strictIndexOf;
 
-            case 6:
-              doc = _context.sent;
 
-              showIntentFrame(iframe);
-              return _context.abrupt('return', doc);
+/***/ }),
+/* 481 */
+/***/ ((module) => {
 
-            case 9:
-            case 'end':
-              return _context.stop();
-          }
-        }
-      }, _callee, this);
-    }));
+/**
+ * This function is like `arrayIncludes` except that it accepts a comparator.
+ *
+ * @private
+ * @param {Array} [array] The array to inspect.
+ * @param {*} target The value to search for.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+function arrayIncludesWith(array, value, comparator) {
+  var index = -1,
+      length = array == null ? 0 : array.length;
 
-    return function compose(_x, _x2, _x3, _x4) {
-      return _ref.apply(this, arguments);
-    };
-  }();
+  while (++index < length) {
+    if (comparator(value, array[index])) {
+      return true;
+    }
+  }
+  return false;
+}
 
-  var document = element.ownerDocument;
-  if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element'));
+module.exports = arrayIncludesWith;
 
-  var window = document.defaultView;
-  if (!window) return Promise.reject(new Error('Cannot retrieve window object from document'));
 
-  // Keeps only http://domain:port/
-  var serviceOrigin = iframe.src.split('/', 3).join('/');
+/***/ }),
+/* 482 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  return new Promise(function (resolve, reject) {
-    var handshaken = false;
-    var messageHandler = function () {
-      var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(event) {
-        var eventType, _event$data, action, doctype, _data, doc, removeIntentFrame;
+var Set = __webpack_require__(462),
+    noop = __webpack_require__(483),
+    setToArray = __webpack_require__(433);
 
-        return _regenerator2.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                if (!(event.origin !== serviceOrigin)) {
-                  _context2.next = 2;
-                  break;
-                }
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0;
 
-                return _context2.abrupt('return');
+/**
+ * Creates a set object of `values`.
+ *
+ * @private
+ * @param {Array} values The values to add to the set.
+ * @returns {Object} Returns the new set.
+ */
+var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
+  return new Set(values);
+};
 
-              case 2:
-                eventType = event.data.type;
+module.exports = createSet;
 
-                if (!(eventType === 'load')) {
-                  _context2.next = 6;
-                  break;
-                }
 
-                // Safari 9.1 (At least) send a MessageEvent when the iframe loads,
-                // making the handshake fails.
-                console.warn && console.warn('Cozy Client ignored MessageEvent having data.type `load`.');
-                return _context2.abrupt('return');
+/***/ }),
+/* 483 */
+/***/ ((module) => {
 
-              case 6:
-                if (!(eventType === 'intent-' + intent._id + ':ready')) {
-                  _context2.next = 9;
-                  break;
-                }
+/**
+ * This method returns `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.3.0
+ * @category Util
+ * @example
+ *
+ * _.times(2, _.noop);
+ * // => [undefined, undefined]
+ */
+function noop() {
+  // No operation performed.
+}
 
-                handshaken = true;
-                return _context2.abrupt('return', event.source.postMessage(data, event.origin));
+module.exports = noop;
 
-              case 9:
-                if (!(handshaken && eventType === 'intent-' + intent._id + ':resize')) {
-                  _context2.next = 13;
-                  break;
-                }
 
-                ;['width', 'height', 'maxWidth', 'maxHeight'].forEach(function (prop) {
-                  if (event.data.transition) element.style.transition = event.data.transition;
-                  if (event.data.dimensions[prop]) element.style[prop] = event.data.dimensions[prop] + 'px';
-                });
+/***/ }),
+/* 484 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                return _context2.abrupt('return', true);
+/**
+ * Small utilities helping to develop konnectors.
+ *
+ * @module utils
+ */
+const cozyClient = __webpack_require__(485);
 
-              case 13:
-                if (!(handshaken && eventType === 'intent-' + intent._id + ':compose')) {
-                  _context2.next = 19;
-                  break;
-                }
+const groupBy = __webpack_require__(736);
 
-                // Let start to name `type` as `doctype`, as `event.data` already have a `type` attribute.
-                _event$data = event.data, action = _event$data.action, doctype = _event$data.doctype, _data = _event$data.data;
-                _context2.next = 17;
-                return compose(cozy, action, doctype, _data);
+const keyBy = __webpack_require__(711);
 
-              case 17:
-                doc = _context2.sent;
-                return _context2.abrupt('return', event.source.postMessage(doc, event.origin));
+const sortBy = __webpack_require__(838);
 
-              case 19:
+const range = __webpack_require__(959);
 
-                window.removeEventListener('message', messageHandler);
+const {
+  format
+} = __webpack_require__(962);
+/**
+ * This function allows to fetch all documents for a given doctype. It is the fastest to get all
+ * documents but without filtering possibilities
+ * deprecated by the findAll method from cozyClient
+ *
+ * Parameters:
+ *
+ * `doctype` (string): the doctype from which you want to fetch the data
+ *
+ */
 
-                removeIntentFrame = function removeIntentFrame() {
-                  // check if the parent node has not been already removed from the DOM
-                  iframe.parentNode && iframe.parentNode.removeChild(iframe);
-                };
 
-                if (!(handshaken && eventType === 'intent-' + intent._id + ':exposeFrameRemoval')) {
-                  _context2.next = 23;
-                  break;
-                }
+const fetchAll = async doctype => {
+  return cozyClient.data.findAll(doctype);
+};
+/**
+ * This function allows to fetch all documents for a given doctype exceeding the 100 limit.
+ * It is slower that fetchAll because it fetches the data 100 by 100 but allows to filter the data
+ * with a selector and an index
+ *
+ * Parameters:
+ *
+ * `doctype` (string): the doctype from which you want to fetch the data
+ * `selector` (object): the mango query selector
+ * `index` (object): (optional) the query selector index. If not defined, the function will
+ * create it's own index with the keys specified in the selector
+ *
+ *
+ * ```javascript
+ * const documents = await queryAll('io.cozy.bills', {vendor: 'Direct Energie'})
+ * ```
+ */
 
-                return _context2.abrupt('return', resolve({ removeIntentFrame: removeIntentFrame, doc: event.data.document }));
 
-              case 23:
+const queryAll = async (doctype, selector, index) => {
+  if (!selector) {
+    // fetchAll is faster in this case
+    return await cozyClient.data.findAll(doctype);
+  }
 
-                removeIntentFrame();
+  if (!index) {
+    index = await cozyClient.data.defineIndex(doctype, Object.keys(selector));
+  }
 
-                if (!(eventType === 'intent-' + intent._id + ':error')) {
-                  _context2.next = 26;
-                  break;
-                }
+  const result = [];
+  let resp = {
+    next: true
+  };
 
-                return _context2.abrupt('return', reject(_helpers.errorSerializer.deserialize(event.data.error)));
+  while (resp && resp.next) {
+    resp = await cozyClient.data.query(index, {
+      selector,
+      wholeResponse: true,
+      skip: result.length
+    });
+    result.push(...resp.docs);
+  }
 
-              case 26:
-                if (!(handshaken && eventType === 'intent-' + intent._id + ':cancel')) {
-                  _context2.next = 28;
-                  break;
-                }
+  return result;
+};
+/**
+ * This function find duplicates in a given doctype, filtered by an optional mango selector
+ *
+ * Parameters:
+ *
+ * `doctype` (string): the doctype from which you want to fetch the data
+ * `selector` (object): (optional) the mango query selector
+ * `options` :
+ *    - `keys` (array) : List of keys used to check that two items are the same.
+ *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
+ *    - `selector` (optionnal object) : Mango request to get records. Gets all the records by default
+ *
+ * Returns an object with the following keys:
+ * `toKeep`: this is the list of unique documents that you should keep in db
+ * `toRemove`: this is the list of documents that can remove from db. If this is io.cozy.bills
+ * documents, do not forget to clean linked bank operations
+ *
+ * ```javascript
+ * const {toKeep, toRemove} = await findDuplicates('io.cozy.bills', {selector: {vendor: 'Direct Energie'}})
+ * ```
+ */
 
-                return _context2.abrupt('return', resolve(null));
 
-              case 28:
-                if (!(handshaken && eventType === 'intent-' + intent._id + ':done')) {
-                  _context2.next = 30;
-                  break;
-                }
+const findDuplicates = async (doctype, options) => {
+  let hash = null;
 
-                return _context2.abrupt('return', resolve(event.data.document));
+  if (options.keys) {
+    hash = doc => options.keys.map(key => {
+      let result = doc[key];
+      if (key === 'date') result = new Date(result);
+      return result;
+    }).join(',');
+  } else if (options.hash) {
+    hash = options.hash;
+  } else {
+    throw new Error('findDuplicates: you must specify keys or hash option');
+  }
 
-              case 30:
-                if (handshaken) {
-                  _context2.next = 32;
-                  break;
-                }
+  let documents = await queryAll(doctype, options.selector);
 
-                return _context2.abrupt('return', reject(new Error('Unexpected handshake message from intent service')));
+  if (doctype === 'io.cozy.bills') {
+    // keep the bills with the highest number of operations linked to it
+    const operations = await fetchAll('io.cozy.bank.operations');
+    documents = sortBillsByLinkedOperationNumber(documents, operations);
+  }
 
-              case 32:
-              case 'end':
-                return _context2.stop();
-            }
-          }
-        }, _callee2, _this);
-      }));
+  const groups = groupBy(documents, hash);
+  const toKeep = [];
+  const toRemove = [];
 
-      return function messageHandler(_x5) {
-        return _ref2.apply(this, arguments);
-      };
-    }();
+  for (let key in groups) {
+    const group = groups[key];
+    toKeep.push(group[0]);
+    toRemove.push.apply(toRemove, group.slice(1).map(doc => ({ ...doc,
+      original: group[0]._id
+    })));
+  }
 
-    window.addEventListener('message', messageHandler);
+  return {
+    toKeep,
+    toRemove
+  };
+};
+
+const sortBillsByLinkedOperationNumber = (bills, operations) => {
+  bills = bills.map(bill => {
+    bill.opNb = 0;
+    return bill;
   });
-}
+  const billsIndex = keyBy(bills, '_id');
+  if (operations) operations.forEach(op => {
+    if (op.bills) op.bills.forEach(billId => {
+      const bill = billsIndex[billId];
+      if (bill) bill.opNb++;
+    });
+  });
+  const sorted = sortBy(Object.values(billsIndex), 'opNb').reverse();
+  return sorted;
+};
+/**
+ * This is a shortcut to update multiple documents in one call
+ *
+ * Parameters:
+ *
+ * `doctype` (string): the doctype from which you want to fetch the data
+ * `ids` (array): array of ids of documents to update
+ * `transformation` (object): attributes to change with their values
+ * `options` :
+ *    - `keys` (array) : List of keys used to check that two items are the same.
+ *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
+ *    - `selector` (optionnal object) : Mango request to get records. Gets all the records by default
+ *
+ * Returns a promise which resolves with all the return values of updateAttributes
+ *
+ * ```javascript
+ * await batchUpdateAttributes('io.cozy.bills', [1, 2, 3], {vendor: 'Direct Energie'})
+ * ```
+ */
 
-function start(cozy, intent, element) {
-  var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
 
-  var service = (0, _helpers.pickService)(intent, options.filterServices);
+const batchUpdateAttributes = async (doctype, ids, transformation) => {
+  const result = [];
 
-  if (!service) {
-    throw new Error('Unable to find a service');
+  for (const id of ids) {
+    const updateResult = await cozyClient.data.updateAttributes(doctype, id, transformation);
+    result.push(updateResult);
   }
 
-  var iframe = injectIntentIframe(intent, element, service.href, options);
-
-  return connectIntentIframe(cozy, iframe, element, intent, data, options.onReadyCallback);
-}
-
-/***/ }),
-/* 17 */
-/***/ (function(module, exports, __nested_webpack_require_110507__) {
+  return result;
+};
+/**
+ * This is a shortcut to delete multiple documents in one call
+ *
+ * Parameters:
+ *
+ * `doctype` (string): the doctype from which you want to fetch the data
+ * `documents` (array): documents to delete with their ids
+ * `transformation` (object): attributes to change with their values
+ * `options` :
+ *    - `keys` (array) : List of keys used to check that two items are the same.
+ *    - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype.
+ *    - `selector` (optionnal object) : Mango request to get records. Gets all the records by default
+ *
+ * Returns a promise which resolves with all the return values of updateAttributes
+ *
+ * Example to remove all the documents for a given doctype
+ *
+ * ```javascript
+ * const documents = await fetchAll('io.cozy.marvel')
+ * await batchDelete('io.cozy.marvel', documents)
+ * ```
+ */
 
-"use strict";
 
+const batchDelete = async (doctype, documents) => {
+  const result = [];
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.start = start;
+  for (const doc of documents) {
+    const deleteResult = await cozyClient.data.delete(doctype, doc);
+    result.push(deleteResult);
+  }
 
-var _fetch = __nested_webpack_require_110507__(0);
+  return result;
+};
+/**
+ * This function can read the content of a cozy pdf file and output its text
+ *
+ * Parameters:
+ *
+ * `fileId` (string): the id of the file in the cozy
+ * `options` :
+ *    - `pages` (array or number) : The list of page you want to interpret
+ *
+ *
+ * You need to add pdfjs-dist package as a dependency to your connector to allow this to work
+ *
+ * Returns a promise which resolves with an object with the following attributes:
+ *    - `text` (string) : The full text of the pdf
+ *    - `1` : The full pdfjs data for page 1
+ *    - `n` : The full pdfjs data for page n
+ *
+ * Example:
+ *
+ * ```javascript
+ * const pdfText = (await getPdfText('887ABCFE87687')).text
+ * ```
+ */
 
-var _helpers = __nested_webpack_require_110507__(5);
 
-function listenClientData(intent, window) {
-  return new Promise(function (resolve) {
-    var messageEventListener = function messageEventListener(event) {
-      if (event.origin !== intent.attributes.client) return;
+const getPdfText = async (fileId, options = {}) => {
+  let pdfjs;
 
-      window.removeEventListener('message', messageEventListener);
-      resolve(event.data);
-    };
+  try {
+    pdfjs = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs-dist/legacy/build/pdf'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
+  } catch (err) {
+    throw new Error('pdfjs-dist dependency is missing. Please add it in your package.json');
+  }
 
-    window.addEventListener('message', messageEventListener);
-    window.parent.postMessage({
-      type: 'intent-' + intent._id + ':ready'
-    }, intent.attributes.client);
-  });
-}
+  const response = await cozyClient.files.downloadById(fileId);
+  const buffer = await response.buffer();
+  const document = await pdfjs.getDocument(buffer).promise;
+  let pages;
 
-// maximize the height of an element
-function maximize(element) {
-  if (element && element.style) {
-    element.style.height = '100%';
+  if (options.pages) {
+    pages = Array.isArray(options.pages) ? options.pages : [options.pages];
+  } else {
+    pages = range(1, document.numPages + 1);
   }
-}
 
-function start(cozy, intentId, serviceWindow) {
-  serviceWindow = serviceWindow || typeof window !== 'undefined' && window;
-  if (!serviceWindow || !serviceWindow.document) {
-    return Promise.reject(new Error('Intent service should be used in browser'));
+  const result = {
+    text: ''
+  };
+
+  for (const pageNum of pages) {
+    const page = await document.getPage(pageNum);
+    const pageItems = (await page.getTextContent()).items;
+    result.text += pageItems.map(doc => doc.str).join('\n');
+    result[pageNum] = pageItems;
   }
 
-  // Maximize document, the whole iframe is handled by intents, clients and
-  // services
-  serviceWindow.addEventListener('load', function () {
-    var _serviceWindow = serviceWindow,
-        document = _serviceWindow.document;
-    [document.documentElement, document.body].forEach(maximize);
-  });
+  return result;
+};
 
-  intentId = intentId || serviceWindow.location.search.split('=')[1];
-  if (!intentId) return Promise.reject(new Error('Cannot retrieve intent from URL'));
+module.exports = {
+  fetchAll,
+  queryAll,
+  findDuplicates,
+  sortBillsByLinkedOperationNumber,
+  batchUpdateAttributes,
+  batchDelete,
+  getPdfText,
+  formatDate
+};
+/**
+ * This function convert a Date Object to a ISO date string (2018-07-31)
+ *
+ * Parameters:
+ *
+ * `date` (Date): the id of the file in the cozy
+ *
+ * Returns a string
+ *
+ * Example:
+ *
+ * ```javascript
+ * const date = formatFrenchDate(New Date.now())
+ * ```
+ */
 
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/intents/' + intentId).then(function (intent) {
-    var terminated = false;
+function formatDate(date) {
+  return format(new Date(date), 'yyyy-MM-dd');
+}
 
-    var sendMessage = function sendMessage(message) {
-      if (terminated) throw new Error('Intent service has already been terminated');
-      serviceWindow.parent.postMessage(message, intent.attributes.client);
-    };
+/***/ }),
+/* 485 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    var compose = function compose(action, doctype, data) {
-      return new Promise(function (resolve) {
-        var composeEventListener = function composeEventListener(event) {
-          if (event.origin !== intent.attributes.client) return;
-          serviceWindow.removeEventListener('message', composeEventListener);
-          return resolve(event.data);
-        };
+/**
+ * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already
+ * initialized and ready to use.
+ *
+ * @module cozyClient
+ */
 
-        serviceWindow.addEventListener('message', composeEventListener);
+/* eslint no-console: off */
+const {
+  Client,
+  MemoryStorage
+} = __webpack_require__(486);
 
-        sendMessage({
-          type: 'intent-' + intent._id + ':compose',
-          action: action,
-          doctype: doctype,
-          data: data
-        });
-      });
-    };
+const NewCozyClient = (__webpack_require__(521)["default"]);
 
-    var _terminate = function _terminate(message) {
-      sendMessage(message);
-      terminated = true;
-    };
+const {
+  models
+} = __webpack_require__(521);
 
-    var resizeClient = function resizeClient(dimensions, transitionProperty) {
-      if (terminated) throw new Error('Intent service has been terminated');
+const globalFetch = (__webpack_require__(493)["default"]);
 
-      sendMessage({
-        type: 'intent-' + intent._id + ':resize',
-        // if a dom element is passed, calculate its size
-        dimensions: dimensions.element ? Object.assign({}, dimensions, {
-          maxHeight: dimensions.element.clientHeight,
-          maxWidth: dimensions.element.clientWidth
-        }) : dimensions,
-        transition: transitionProperty
-      });
-    };
+global.fetch = globalFetch;
+global.Headers = globalFetch.Headers; // fixes an import problem of isomorphic fetch in cozy-client and cozy-client-js
 
-    var cancel = function cancel() {
-      _terminate({ type: 'intent-' + intent._id + ':cancel' });
-    };
+const manifest = __webpack_require__(909);
 
-    // Prevent unfulfilled client promises when this window unloads for a
-    // reason or another.
-    serviceWindow.addEventListener('unload', function () {
-      if (!terminated) cancel();
-    });
+const getCozyClient = function (environment = 'production') {
+  if (environment === 'standalone' || environment === 'test') {
+    return __webpack_require__(910);
+  }
 
-    return listenClientData(intent, serviceWindow).then(function (data) {
-      return {
-        compose: compose,
-        getData: function getData() {
-          return data;
-        },
-        getIntent: function getIntent() {
-          return intent;
-        },
-        terminate: function terminate(doc) {
-          var eventName = data && data.exposeIntentFrameRemoval ? 'exposeFrameRemoval' : 'done';
-          return _terminate({
-            type: 'intent-' + intent._id + ':' + eventName,
-            document: doc
-          });
-        },
-        throw: function _throw(error) {
-          return _terminate({
-            type: 'intent-' + intent._id + ':error',
-            error: _helpers.errorSerializer.serialize(error)
-          });
-        },
-        resizeClient: resizeClient,
-        cancel: cancel
-      };
-    });
+  const cozyFields = JSON.parse(process.env.COZY_FIELDS || '{}');
+  const newCozyClient = NewCozyClient.fromEnv(process.env, {
+    appMetadata: {
+      slug: manifest.data.slug,
+      sourceAccount: cozyFields.account,
+      version: manifest.data.version
+    }
   });
-}
+  newCozyClient.models = models;
+  const cozyClient = cozyClientJsFromEnv(newCozyClient.stackClient.uri);
+  cozyClient.new = newCozyClient;
+  return cozyClient;
+};
+/**
+ * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already initialized and ready to use.
+ *
+ * If you want to access cozy-client-js directly, this method gives you directly an instance of it,
+ * initialized according to `COZY_URL` and `COZY_CREDENTIALS` environment variable given by cozy-stack
+ * You can refer to the [cozy-client-js documentation](https://github.com/cozy/cozy-client-js) for more information.
+ *
+ * Example :
+ *
+ * ```javascript
+ * const {cozyClient} = require('cozy-konnector-libs')
+ *
+ * cozyClient.data.defineIndex('my.doctype', ['_id'])
+ * ```
+ *
+ * @alias module:cozyClient
+ */
 
-/***/ }),
-/* 18 */
-/***/ (function(module, exports, __nested_webpack_require_114916__) {
 
-"use strict";
+const cozyClient = getCozyClient( // webpack 4 now changes the NODE_ENV environment variable when you change its 'mode' option
+// since we do not want to minimize the built file, we recognize the 'none' mode as production mode
+process.env.NODE_ENV === 'none' ? 'production' : process.env.NODE_ENV);
 
+function cozyClientJsFromEnv(cozyURL) {
+  const options = {
+    cozyURL
+  };
+  let jsonCredentials = null;
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.count = count;
-exports.queued = queued;
-exports.create = create;
+  if (process.env.COZY_CREDENTIALS) {
+    try {
+      jsonCredentials = JSON.parse(process.env.COZY_CREDENTIALS);
+    } catch (err) {
+      options.token = process.env.COZY_CREDENTIALS;
+    }
+  }
 
-var _fetch = __nested_webpack_require_114916__(0);
+  if (jsonCredentials) {
+    options.oauth = {
+      storage: new MemoryStorage()
+    };
+  }
 
-function count(cozy, workerType) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType).then(function (data) {
-    return data.length;
-  });
-}
+  const cozyClient = new Client(options);
 
-function queued(cozy, workerType) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType);
-}
+  if (jsonCredentials) {
+    jsonCredentials.token.toAuthHeader = function () {
+      return 'Bearer ' + jsonCredentials.client.registrationAccessToken;
+    };
 
-function create(cozy, workerType, args, options) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/jobs/queue/' + workerType, {
-    data: {
-      type: 'io.cozy.jobs',
-      attributes: {
-        arguments: args || {},
-        options: options || {}
-      }
-    }
-  });
+    cozyClient.saveCredentials(jsonCredentials.oauthOptions, jsonCredentials.token);
+  }
+
+  return cozyClient;
 }
 
+module.exports = cozyClient;
+
 /***/ }),
-/* 19 */
-/***/ (function(module, exports, __nested_webpack_require_115746__) {
+/* 486 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __nested_webpack_require_228__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_228__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__nested_webpack_require_228__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__nested_webpack_require_228__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__nested_webpack_require_228__.d = function(exports, name, getter) {
+/******/ 		if(!__nested_webpack_require_228__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__nested_webpack_require_228__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__nested_webpack_require_228__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__nested_webpack_require_228__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__nested_webpack_require_228__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __nested_webpack_require_228__(__nested_webpack_require_228__.s = 9);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __nested_webpack_require_2505__) {
 
 "use strict";
 
@@ -68573,371 +67044,398 @@ function create(cozy, workerType, args, options) {
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.replicationOfflineError = undefined;
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // Define global `fetch` so it's made available to `pouchdb-browser`
+exports.FetchError = undefined;
 
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* global fetch */
 
-exports.init = init;
-exports.getDoctypes = getDoctypes;
-exports.hasDatabase = hasDatabase;
-exports.getDatabase = getDatabase;
-exports.setDatabase = setDatabase;
-exports.migrateDatabase = migrateDatabase;
-exports.createDatabase = createDatabase;
-exports.destroyDatabase = destroyDatabase;
-exports.destroyAllDatabase = destroyAllDatabase;
-exports.hasReplication = hasReplication;
-exports.replicateFromCozy = replicateFromCozy;
-exports.stopReplication = stopReplication;
-exports.stopAllReplication = stopAllReplication;
-exports.hasRepeatedReplication = hasRepeatedReplication;
-exports.startRepeatedReplication = startRepeatedReplication;
-exports.stopRepeatedReplication = stopRepeatedReplication;
-exports.stopAllRepeatedReplication = stopAllRepeatedReplication;
 
-__nested_webpack_require_115746__(20);
+exports.cozyFetch = cozyFetch;
+exports.cozyFetchJSON = cozyFetchJSON;
+exports.cozyFetchRawJSON = cozyFetchRawJSON;
+exports.handleInvalidTokenError = handleInvalidTokenError;
 
-var _doctypes = __nested_webpack_require_115746__(2);
+var _auth_v = __nested_webpack_require_2505__(3);
 
-var _auth_v = __nested_webpack_require_115746__(3);
+var _utils = __nested_webpack_require_2505__(1);
 
-var _utils = __nested_webpack_require_115746__(1);
+var _jsonapi = __nested_webpack_require_2505__(7);
 
-var _pouchdbBrowser = __nested_webpack_require_115746__(21);
+var _jsonapi2 = _interopRequireDefault(_jsonapi);
 
-var _pouchdbBrowser2 = _interopRequireDefault(_pouchdbBrowser);
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-var _pouchdbFind = __nested_webpack_require_115746__(22);
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var _pouchdbFind2 = _interopRequireDefault(_pouchdbFind);
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var replicationOfflineError = exports.replicationOfflineError = 'Replication abort, your device is actually offline.';
+function cozyFetch(cozy, path) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
 
-var pluginLoaded = false;
+  return cozy.fullpath(path).then(function (fullpath) {
+    var resp = void 0;
+    if (options.disableAuth) {
+      resp = fetch(fullpath, options);
+    } else if (options.manualAuthCredentials) {
+      resp = cozyFetchWithAuth(cozy, fullpath, options, options.manualAuthCredentials);
+    } else {
+      resp = cozy.authorize().then(function (credentials) {
+        return cozyFetchWithAuth(cozy, fullpath, options, credentials);
+      });
+    }
+    return resp.then(function (res) {
+      return handleResponse(res, cozy._invalidTokenErrorHandler);
+    });
+  });
+}
 
-/*
-  For each doctype we have some parameters:
-  cozy._offline[doctype] = {
-    database: pouchdb database
-    replication: the pouchdb replication
-    replicationPromise: promise of replication
-    interval: repeated replication interval
+function cozyFetchWithAuth(cozy, fullpath, options, credentials) {
+  if (credentials) {
+    options.headers = options.headers || {};
+    options.headers['Authorization'] = credentials.token.toAuthHeader();
   }
-*/
 
-function init(cozy, _ref) {
-  var _ref$options = _ref.options,
-      options = _ref$options === undefined ? {} : _ref$options,
-      _ref$doctypes = _ref.doctypes,
-      doctypes = _ref$doctypes === undefined ? [] : _ref$doctypes;
-  var _iteratorNormalCompletion = true;
-  var _didIteratorError = false;
-  var _iteratorError = undefined;
+  // the option credentials:include tells fetch to include the cookies in the
+  // request even for cross-origin requests
+  options.credentials = 'include';
 
-  try {
-    for (var _iterator = doctypes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
-      var doctype = _step.value;
+  return Promise.all([cozy.isV2(), fetch(fullpath, options)]).then(function (_ref) {
+    var _ref2 = _slicedToArray(_ref, 2),
+        isV2 = _ref2[0],
+        res = _ref2[1];
 
-      createDatabase(cozy, doctype, options);
+    if (res.status !== 400 && res.status !== 401 || isV2 || !credentials || options.dontRetry) {
+      return res;
     }
-  } catch (err) {
-    _didIteratorError = true;
-    _iteratorError = err;
-  } finally {
-    try {
-      if (!_iteratorNormalCompletion && _iterator.return) {
-        _iterator.return();
-      }
-    } finally {
-      if (_didIteratorError) {
-        throw _iteratorError;
-      }
+    // we try to refresh the token only for OAuth, ie, the client defined
+    // and the token is an instance of AccessToken.
+    var client = credentials.client,
+        token = credentials.token;
+
+    if (!client || !(token instanceof _auth_v.AccessToken)) {
+      return res;
     }
-  }
+    options.dontRetry = true;
+    return (0, _utils.retry)(function () {
+      return (0, _auth_v.refreshToken)(cozy, client, token);
+    }, 3)().then(function (newToken) {
+      return cozy.saveCredentials(client, newToken);
+    }).then(function (credentials) {
+      return cozyFetchWithAuth(cozy, fullpath, options, credentials);
+    });
+  });
 }
 
-// helper
+function cozyFetchJSON(cozy, method, path, body) {
+  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
 
-function getInfo(cozy, doctype) {
-  cozy._offline = cozy._offline || [];
-  cozy._offline[doctype] = cozy._offline[doctype] || {};
-  return cozy._offline[doctype];
+  var processJSONAPI = typeof options.processJSONAPI === 'undefined' || options.processJSONAPI;
+  return fetchJSON(cozy, method, path, body, options).then(function (response) {
+    return handleJSONResponse(response, processJSONAPI);
+  });
 }
 
-function getDoctypes(cozy) {
-  cozy._offline = cozy._offline || [];
-  return Object.keys(cozy._offline);
+function cozyFetchRawJSON(cozy, method, path, body) {
+  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+
+  return fetchJSON(cozy, method, path, body, options).then(function (response) {
+    return handleJSONResponse(response, false);
+  });
 }
 
-//
-// DATABASE
-//
+function fetchJSON(cozy, method, path, body) {
+  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
 
-function hasDatabase(cozy, doctype) {
-  return getDatabase(cozy, doctype) !== undefined;
-}
+  options.method = method;
 
-function getDatabase(cozy, doctype) {
-  return getInfo(cozy, doctype).database;
-}
+  var headers = options.headers = options.headers || {};
 
-function setDatabase(cozy, doctype, database) {
-  cozy._offline[doctype].database = database;
-  return getDatabase(cozy, doctype);
-}
+  headers['Accept'] = 'application/json';
 
-function migrateDatabase(cozy, doctype) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+  if (method !== 'GET' && method !== 'HEAD' && body !== undefined) {
+    if (headers['Content-Type']) {
+      options.body = body;
+    } else {
+      headers['Content-Type'] = 'application/json';
+      options.body = JSON.stringify(body);
+    }
+  }
 
-  var oldDb = getDatabase(cozy, doctype);
-  var newOptions = _extends({
-    adapter: 'idb'
-  }, options);
-  var newDb = new _pouchdbBrowser2.default(doctype, newOptions);
+  return cozyFetch(cozy, path, options);
+}
 
-  return oldDb.replicate.to(newDb).then(function () {
-    setDatabase(cozy, doctype, newDb);
-    oldDb.destroy();
-    return newDb;
+function handleResponse(res, invalidTokenErrorHandler) {
+  if (res.ok) {
+    return res;
+  }
+  var data = void 0;
+  var contentType = res.headers.get('content-type');
+  if (contentType && contentType.indexOf('json') >= 0) {
+    data = res.json();
+  } else {
+    data = res.text();
+  }
+  return data.then(function (err) {
+    var error = new FetchError(res, err);
+    if (FetchError.isInvalidToken(error) && invalidTokenErrorHandler) {
+      invalidTokenErrorHandler(error);
+    }
+    throw error;
   });
 }
 
-function createDatabase(cozy, doctype) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+function handleJSONResponse(res) {
+  var processJSONAPI = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
 
-  if (!pluginLoaded) {
-    _pouchdbBrowser2.default.plugin(_pouchdbFind2.default);
-    pluginLoaded = true;
+  var contentType = res.headers.get('content-type');
+  if (!contentType || contentType.indexOf('json') < 0) {
+    return res.text(function (data) {
+      throw new FetchError(res, new Error('Response is not JSON: ' + data));
+    });
   }
 
-  if (hasDatabase(cozy, doctype)) {
-    return Promise.resolve(getDatabase(cozy, doctype));
+  var json = res.json();
+  if (contentType.indexOf('application/vnd.api+json') === 0 && processJSONAPI) {
+    return json.then(_jsonapi2.default);
+  } else {
+    return json;
   }
-
-  setDatabase(cozy, doctype, new _pouchdbBrowser2.default(doctype, options));
-  return createIndexes(cozy, doctype).then(function () {
-    return getDatabase(cozy, doctype);
-  });
 }
 
-function destroyDatabase(cozy, doctype) {
-  if (!hasDatabase(cozy, doctype)) {
-    return Promise.resolve(false);
-  }
+function handleInvalidTokenError(error) {
+  try {
+    var currentOrigin = window.location.origin;
+    var requestUrl = error.url;
 
-  return stopRepeatedReplication(cozy, doctype).then(function () {
-    return stopReplication(cozy, doctype);
-  }).then(function () {
-    return getDatabase(cozy, doctype).destroy();
-  }).then(function (response) {
-    setDatabase(cozy, doctype, undefined);
-    return response;
-  });
+    if (requestUrl.indexOf(currentOrigin.replace(/^(https?:\/\/\w+)-\w+\./, '$1.')) === 0) {
+      var redirectURL = currentOrigin + '?' + (0, _utils.encodeQuery)({ disconnect: 1 });
+      window.location = redirectURL;
+    }
+  } catch (e) {
+    console.warn('Unable to handle invalid token error', e, error);
+  }
 }
 
-function destroyAllDatabase(cozy) {
-  var doctypes = getDoctypes(cozy);
-  var destroy = function destroy(doctype) {
-    return destroyDatabase(cozy, doctype);
-  };
-  return Promise.all(doctypes.map(destroy));
-}
+var FetchError = exports.FetchError = function (_Error) {
+  _inherits(FetchError, _Error);
 
-function createIndexes(cozy, doctype) {
-  if (doctype === _doctypes.DOCTYPE_FILES) {
-    return getDatabase(cozy, doctype).createIndex({
-      index: { fields: ['dir_id'] }
+  function FetchError(res, reason) {
+    _classCallCheck(this, FetchError);
+
+    var _this = _possibleConstructorReturn(this, (FetchError.__proto__ || Object.getPrototypeOf(FetchError)).call(this));
+
+    if (Error.captureStackTrace) {
+      Error.captureStackTrace(_this, _this.constructor);
+    }
+    // XXX We have to hardcode this because babel doesn't play nice when extending Error
+    _this.name = 'FetchError';
+    _this.response = res;
+    _this.url = res.url;
+    _this.status = res.status;
+    _this.reason = reason;
+
+    Object.defineProperty(_this, 'message', {
+      value: reason.message || (typeof reason === 'string' ? reason : JSON.stringify(reason))
     });
+    return _this;
   }
-  return Promise.resolve();
-}
 
-//
-// REPLICATION
-//
+  return FetchError;
+}(Error);
 
-function hasReplication(cozy, doctype) {
-  return getReplication(cozy, doctype) !== undefined;
-}
+FetchError.isUnauthorized = function (err) {
+  // XXX We can't use err instanceof FetchError because of the caveats of babel
+  return err.name === 'FetchError' && err.status === 401;
+};
 
-function getReplication(cozy, doctype) {
-  return getInfo(cozy, doctype).replication;
-}
+FetchError.isNotFound = function (err) {
+  // XXX We can't use err instanceof FetchError because of the caveats of babel
+  return err.name === 'FetchError' && err.status === 404;
+};
 
-function setReplication(cozy, doctype, replication) {
-  cozy._offline[doctype].replication = replication;
-  return getReplication(cozy, doctype);
-}
+FetchError.isInvalidToken = function (err) {
+  // XXX We can't use err instanceof FetchError because of the caveats of babel
+  return err.name === 'FetchError' && err.status === 400 && err.reason && (err.reason.error === 'Invalid JWT token' || err.reason.error === 'Expired token');
+};
 
-function getReplicationUrl(cozy, doctype) {
-  return cozy.authorize().then(function (credentials) {
-    var basic = credentials.token.toBasicAuth();
-    return (cozy._url + '/data/' + doctype).replace('//', '//' + basic);
-  });
-}
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
 
-function getReplicationPromise(cozy, doctype) {
-  return getInfo(cozy, doctype).replicationPromise;
-}
+"use strict";
 
-function setReplicationPromise(cozy, doctype, promise) {
-  cozy._offline[doctype].replicationPromise = promise;
-  return getReplicationPromise(cozy, doctype);
-}
 
-function replicateFromCozy(cozy, doctype) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.unpromiser = unpromiser;
+exports.isPromise = isPromise;
+exports.isOnline = isOnline;
+exports.isOffline = isOffline;
+exports.sleep = sleep;
+exports.retry = retry;
+exports.getFuzzedDelay = getFuzzedDelay;
+exports.getBackedoffDelay = getBackedoffDelay;
+exports.createPath = createPath;
+exports.encodeQuery = encodeQuery;
+exports.decodeQuery = decodeQuery;
+exports.warn = warn;
+/* global navigator */
+var FuzzFactor = 0.3;
 
-  return setReplicationPromise(cozy, doctype, new Promise(function (resolve, reject) {
-    if (!hasDatabase(cozy, doctype)) {
-      createDatabase(cozy, doctype);
-    }
-    if (options.live === true) {
-      return reject(new Error("You can't use `live` option with Cozy couchdb."));
+function unpromiser(fn) {
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
     }
 
-    if ((0, _utils.isOffline)()) {
-      reject(replicationOfflineError);
-      options.onError && options.onError(replicationOfflineError);
+    var value = fn.apply(this, args);
+    if (!isPromise(value)) {
+      return value;
+    }
+    var l = args.length;
+    if (l === 0 || typeof args[l - 1] !== 'function') {
       return;
     }
+    var cb = args[l - 1];
+    value.then(function (res) {
+      return cb(null, res);
+    }, function (err) {
+      return cb(err, null);
+    });
+  };
+}
 
-    getReplicationUrl(cozy, doctype).then(function (url) {
-      return setReplication(cozy, doctype, getDatabase(cozy, doctype).replicate.from(url, options).on('complete', function (info) {
-        setReplication(cozy, doctype, undefined);
-        resolve(info);
-        options.onComplete && options.onComplete(info);
-      }).on('error', function (err) {
-        if (err.error === 'code=400, message=Expired token') {
-          cozy.authorize().then(function (_ref2) {
-            var client = _ref2.client,
-                token = _ref2.token;
+function isPromise(value) {
+  return !!value && typeof value.then === 'function';
+}
 
-            (0, _auth_v.refreshToken)(cozy, client, token).then(function (newToken) {
-              return cozy.saveCredentials(client, newToken);
-            }).then(function () {
-              return replicateFromCozy(cozy, doctype, options);
-            });
-          });
-        } else {
-          console.warn('ReplicateFromCozy \'' + doctype + '\' Error:');
-          console.warn(err);
-          setReplication(cozy, doctype, undefined);
-          reject(err);
-          options.onError && options.onError(err);
-        }
-      }));
-    });
-  }));
+function isOnline() {
+  return typeof navigator !== 'undefined' ? navigator.onLine : true;
 }
 
-function stopReplication(cozy, doctype) {
-  if (!getDatabase(cozy, doctype) || !hasReplication(cozy, doctype)) {
-    return Promise.resolve();
-  }
+function isOffline() {
+  return !isOnline();
+}
 
+function sleep(time, args) {
   return new Promise(function (resolve) {
-    try {
-      getReplicationPromise(cozy, doctype).then(function () {
-        resolve();
-      });
-      getReplication(cozy, doctype).cancel();
-      // replication is set to undefined by complete replication
-    } catch (e) {
-      resolve();
-    }
+    setTimeout(resolve, time, args);
   });
 }
 
-function stopAllReplication(cozy) {
-  var doctypes = getDoctypes(cozy);
-  var stop = function stop(doctype) {
-    return stopReplication(cozy, doctype);
-  };
-  return Promise.all(doctypes.map(stop));
-}
+function retry(fn, count) {
+  var delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 300;
 
-//
-// REPEATED REPLICATION
-//
+  return function doTry() {
+    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+      args[_key2] = arguments[_key2];
+    }
 
-function getRepeatedReplication(cozy, doctype) {
-  return getInfo(cozy, doctype).interval;
+    return fn.apply(undefined, args).catch(function (err) {
+      if (--count < 0) {
+        throw err;
+      }
+      return sleep(getBackedoffDelay(delay, count)).then(function () {
+        return doTry.apply(undefined, args);
+      });
+    });
+  };
 }
 
-function setRepeatedReplication(cozy, doctype, interval) {
-  cozy._offline[doctype].interval = interval;
+function getFuzzedDelay(retryDelay) {
+  var fuzzingFactor = (Math.random() * 2 - 1) * FuzzFactor;
+  return retryDelay * (1.0 + fuzzingFactor);
 }
 
-function hasRepeatedReplication(cozy, doctype) {
-  return getRepeatedReplication(cozy, doctype) !== undefined;
+function getBackedoffDelay(retryDelay) {
+  var retryCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
+
+  return getFuzzedDelay(retryDelay * Math.pow(2, retryCount - 1));
 }
 
-function startRepeatedReplication(cozy, doctype, timer) {
-  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+function createPath(cozy, isV2, doctype) {
+  var id = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
+  var query = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
 
-  // TODO: add timer limitation for not flooding Gozy
-  if (hasRepeatedReplication(cozy, doctype)) {
-    return getRepeatedReplication(cozy, doctype);
+  var route = '/data/';
+  if (!isV2) {
+    route += encodeURIComponent(doctype) + '/';
+  }
+  if (id !== '') {
+    route += encodeURIComponent(id);
+  }
+  var q = encodeQuery(query);
+  if (q !== '') {
+    route += '?' + q;
   }
+  return route;
+}
 
-  return setRepeatedReplication(cozy, doctype, setInterval(function () {
-    if ((0, _utils.isOffline)()) {
-      // network is offline, replication cannot be launched
-      console.info(replicationOfflineError);
-      return;
-    }
-    if (!hasReplication(cozy, doctype)) {
-      replicateFromCozy(cozy, doctype, options);
-      // TODO: add replicationToCozy
+function encodeQuery(query) {
+  if (!query) {
+    return '';
+  }
+  var q = '';
+  for (var qname in query) {
+    if (q !== '') {
+      q += '&';
     }
-  }, timer * 1000));
+    q += encodeURIComponent(qname) + '=' + encodeURIComponent(query[qname]);
+  }
+  return q;
 }
 
-function stopRepeatedReplication(cozy, doctype) {
-  if (hasRepeatedReplication(cozy, doctype)) {
-    clearInterval(getRepeatedReplication(cozy, doctype));
-    setRepeatedReplication(cozy, doctype, undefined);
+function decodeQuery(url) {
+  var queryIndex = url.indexOf('?');
+  if (queryIndex < 0) {
+    queryIndex = url.length;
   }
-  if (hasReplication(cozy, doctype)) {
-    return stopReplication(cozy, doctype);
+  var queries = {};
+  var fragIndex = url.indexOf('#');
+  if (fragIndex < 0) {
+    fragIndex = url.length;
   }
-
-  return Promise.resolve();
+  if (fragIndex < queryIndex) {
+    return queries;
+  }
+  var queryStr = url.slice(queryIndex + 1, fragIndex);
+  if (queryStr === '') {
+    return queries;
+  }
+  var parts = queryStr.split('&');
+  for (var i = 0; i < parts.length; i++) {
+    var pair = parts[i].split('=');
+    if (pair.length === 0 || pair[0] === '') {
+      continue;
+    }
+    var qname = decodeURIComponent(pair[0]);
+    if (queries.hasOwnProperty(qname)) {
+      continue;
+    }
+    if (pair.length === 1) {
+      queries[qname] = true;
+    } else if (pair.length === 2) {
+      queries[qname] = decodeURIComponent(pair[1]);
+    } else {
+      throw new Error('Malformed URL');
+    }
+  }
+  return queries;
 }
 
-function stopAllRepeatedReplication(cozy) {
-  var doctypes = getDoctypes(cozy);
-  var stop = function stop(doctype) {
-    return stopRepeatedReplication(cozy, doctype);
-  };
-  return Promise.all(doctypes.map(stop));
+var warned = [];
+function warn(text) {
+  if (warned.indexOf(text) === -1) {
+    warned.push(text);
+    console.warn('cozy-client-js', text);
+  }
 }
 
 /***/ }),
-/* 20 */
-/***/ (function(module, exports) {
-
-module.exports = __webpack_require__(479);
-
-/***/ }),
-/* 21 */
-/***/ (function(module, exports) {
-
-module.exports = __webpack_require__(482);
-
-/***/ }),
-/* 22 */
-/***/ (function(module, exports) {
-
-module.exports = __webpack_require__(494);
-
-/***/ }),
-/* 23 */
-/***/ (function(module, exports, __nested_webpack_require_126289__) {
+/* 2 */
+/***/ (function(module, exports, __nested_webpack_require_15027__) {
 
 "use strict";
 
@@ -68945,37555 +67443,37810 @@ module.exports = __webpack_require__(494);
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.diskUsage = diskUsage;
-exports.changePassphrase = changePassphrase;
-exports.getInstance = getInstance;
-exports.updateInstance = updateInstance;
-exports.getClients = getClients;
-exports.deleteClientById = deleteClientById;
-exports.updateLastSync = updateLastSync;
-
-var _fetch = __nested_webpack_require_126289__(0);
-
-function diskUsage(cozy) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/disk-usage');
-}
-
-function changePassphrase(cozy, currentPassPhrase, newPassPhrase) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/passphrase', {
-    current_passphrase: currentPassPhrase,
-    new_passphrase: newPassPhrase
-  });
-}
+exports.DOCTYPE_FILES = undefined;
+exports.normalizeDoctype = normalizeDoctype;
 
-function getInstance(cozy) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/instance');
-}
+var _utils = __nested_webpack_require_15027__(1);
 
-function updateInstance(cozy, instance) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/instance', instance);
-}
+var DOCTYPE_FILES = exports.DOCTYPE_FILES = 'io.cozy.files';
 
-function getClients(cozy) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/clients');
-}
+var KNOWN_DOCTYPES = {
+  files: DOCTYPE_FILES,
+  folder: DOCTYPE_FILES,
+  contact: 'io.cozy.contacts',
+  event: 'io.cozy.events',
+  track: 'io.cozy.labs.music.track',
+  playlist: 'io.cozy.labs.music.playlist'
+};
 
-function deleteClientById(cozy, id) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/settings/clients/' + id);
-}
+var REVERSE_KNOWN = {};
+Object.keys(KNOWN_DOCTYPES).forEach(function (k) {
+  REVERSE_KNOWN[KNOWN_DOCTYPES[k]] = k;
+});
 
-function updateLastSync(cozy) {
-  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/settings/synchronized');
+function normalizeDoctype(cozy, isV2, doctype) {
+  var isQualified = doctype.indexOf('.') !== -1;
+  if (isV2 && isQualified) {
+    var known = REVERSE_KNOWN[doctype];
+    if (known) return known;
+    return doctype.replace(/\./g, '-');
+  }
+  if (!isV2 && !isQualified) {
+    var _known = KNOWN_DOCTYPES[doctype];
+    if (_known) {
+      (0, _utils.warn)('you are using a non-qualified doctype ' + doctype + ' assumed to be ' + _known);
+      return _known;
+    }
+    throw new Error('Doctype ' + doctype + ' should be qualified.');
+  }
+  return doctype;
 }
 
 /***/ }),
-/* 24 */
-/***/ (function(module, exports, __nested_webpack_require_127648__) {
+/* 3 */
+/***/ (function(module, exports, __nested_webpack_require_16254__) {
 
 "use strict";
-
+/* WEBPACK VAR INJECTION */(function(btoa) {
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.removeReferencedFiles = exports.addReferencedFiles = undefined;
-exports.listReferencedFiles = listReferencedFiles;
-exports.fetchReferencedFiles = fetchReferencedFiles;
-
-var _fetch = __nested_webpack_require_127648__(0);
-
-var _doctypes = __nested_webpack_require_127648__(2);
-
-function updateRelations(verb) {
-  return function (cozy, doc, ids) {
-    if (!doc) throw new Error('missing doc argument');
-    if (!Array.isArray(ids)) ids = [ids];
-
-    var refs = ids.map(function (id) {
-      return { type: _doctypes.DOCTYPE_FILES, id: id };
-    });
-
-    return (0, _fetch.cozyFetchJSON)(cozy, verb, makeReferencesPath(doc), { data: refs });
-  };
-}
+exports.AppToken = exports.AccessToken = exports.Client = exports.StateKey = exports.CredsKey = undefined;
 
-var addReferencedFiles = exports.addReferencedFiles = updateRelations('POST');
-var removeReferencedFiles = exports.removeReferencedFiles = updateRelations('DELETE');
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
 
-function listReferencedFiles(cozy, doc) {
-  if (!doc) throw new Error('missing doc argument');
-  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', makeReferencesPath(doc)).then(function (files) {
-    return files.map(function (file) {
-      return file._id;
-    });
-  });
-}
+var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global btoa */
 
-function fetchReferencedFiles(cozy, doc, options, sort) {
-  if (!doc) throw new Error('missing doc argument');
-  var params = Object.keys(options).map(function (key) {
-    var value = encodeURIComponent(JSON.stringify(options[key]));
-    return '&page[' + key + ']=' + value;
-  }).join('');
-  // Datetime is the default sort, but 'id' is also available
-  if (!sort) {
-    sort = 'datetime';
-  }
-  return (0, _fetch.cozyFetchRawJSON)(cozy, 'GET', makeReferencesPath(doc) + '?include=files&sort=' + sort + params);
-}
 
-function makeReferencesPath(doc) {
-  var type = encodeURIComponent(doc._type);
-  var id = encodeURIComponent(doc._id);
-  return '/data/' + type + '/' + id + '/relationships/references';
-}
+exports.client = client;
+exports.registerClient = registerClient;
+exports.updateClient = updateClient;
+exports.unregisterClient = unregisterClient;
+exports.getClient = getClient;
+exports.getAuthCodeURL = getAuthCodeURL;
+exports.getAccessToken = getAccessToken;
+exports.refreshToken = refreshToken;
+exports.oauthFlow = oauthFlow;
 
-/***/ })
-/******/ ])));
-//# sourceMappingURL=cozy-client.node.js.map
+var _utils = __nested_webpack_require_16254__(1);
 
-/***/ }),
-/* 475 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _fetch = __nested_webpack_require_16254__(0);
 
-module.exports = __webpack_require__(476);
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
+var StateSize = 16;
 
-/***/ }),
-/* 476 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var CredsKey = exports.CredsKey = 'creds';
+var StateKey = exports.StateKey = 'state';
 
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
+var Client = exports.Client = function () {
+  function Client(opts) {
+    _classCallCheck(this, Client);
 
-// This method of obtaining a reference to the global object needs to be
-// kept identical to the way it is obtained in runtime.js
-var g = (function() { return this })() || Function("return this")();
+    this.clientID = opts.clientID || opts.client_id || '';
+    this.clientSecret = opts.clientSecret || opts.client_secret || '';
+    this.registrationAccessToken = opts.registrationAccessToken || opts.registration_access_token || '';
 
-// Use `getOwnPropertyNames` because not all browsers support calling
-// `hasOwnProperty` on the global `self` object in a worker. See #183.
-var hadRuntime = g.regeneratorRuntime &&
-  Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0;
+    if (opts.redirect_uris) {
+      this.redirectURI = opts.redirect_uris[0] || '';
+    } else {
+      this.redirectURI = opts.redirectURI || '';
+    }
 
-// Save the old regeneratorRuntime in case it needs to be restored later.
-var oldRuntime = hadRuntime && g.regeneratorRuntime;
+    this.softwareID = opts.softwareID || opts.software_id || '';
+    this.softwareVersion = opts.softwareVersion || opts.software_version || '';
+    this.clientName = opts.clientName || opts.client_name || '';
+    this.clientKind = opts.clientKind || opts.client_kind || '';
+    this.clientURI = opts.clientURI || opts.client_uri || '';
 
-// Force reevalutation of runtime.js.
-g.regeneratorRuntime = undefined;
+    this.logoURI = opts.logoURI || opts.logo_uri || '';
+    this.policyURI = opts.policyURI || opts.policy_uri || '';
 
-module.exports = __webpack_require__(477);
+    this.notificationPlatform = opts.notificationPlatform || opts.notification_platform || '';
+    this.notificationDeviceToken = opts.notificationDeviceToken || opts.notification_device_token || '';
 
-if (hadRuntime) {
-  // Restore the original runtime.
-  g.regeneratorRuntime = oldRuntime;
-} else {
-  // Remove the global property added by runtime.js.
-  try {
-    delete g.regeneratorRuntime;
-  } catch(e) {
-    g.regeneratorRuntime = undefined;
+    if (!this.registrationAccessToken) {
+      if (this.redirectURI === '') {
+        throw new Error('Missing redirectURI field');
+      }
+      if (this.softwareID === '') {
+        throw new Error('Missing softwareID field');
+      }
+      if (this.clientName === '') {
+        throw new Error('Missing clientName field');
+      }
+    }
   }
-}
-
-
-/***/ }),
-/* 477 */
-/***/ ((module) => {
 
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
+  _createClass(Client, [{
+    key: 'isRegistered',
+    value: function isRegistered() {
+      return this.clientID !== '';
+    }
+  }, {
+    key: 'toRegisterJSON',
+    value: function toRegisterJSON() {
+      return {
+        redirect_uris: [this.redirectURI],
+        software_id: this.softwareID,
+        software_version: this.softwareVersion,
+        client_name: this.clientName,
+        client_kind: this.clientKind,
+        client_uri: this.clientURI,
+        logo_uri: this.logoURI,
+        policy_uri: this.policyURI,
+        notification_platform: this.notificationPlatform,
+        notification_device_token: this.notificationDeviceToken
+      };
+    }
+  }, {
+    key: 'toAuthHeader',
+    value: function toAuthHeader() {
+      return 'Bearer ' + this.registrationAccessToken;
+    }
+  }]);
 
-!(function(global) {
-  "use strict";
+  return Client;
+}();
 
-  var Op = Object.prototype;
-  var hasOwn = Op.hasOwnProperty;
-  var undefined; // More compressible than void 0.
-  var $Symbol = typeof Symbol === "function" ? Symbol : {};
-  var iteratorSymbol = $Symbol.iterator || "@@iterator";
-  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
-  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+var AccessToken = exports.AccessToken = function () {
+  function AccessToken(opts) {
+    _classCallCheck(this, AccessToken);
 
-  var inModule = "object" === "object";
-  var runtime = global.regeneratorRuntime;
-  if (runtime) {
-    if (inModule) {
-      // If regeneratorRuntime is defined globally and we're in a module,
-      // make the exports object identical to regeneratorRuntime.
-      module.exports = runtime;
-    }
-    // Don't bother evaluating the rest of this file if the runtime was
-    // already defined globally.
-    return;
+    this.tokenType = opts.tokenType || opts.token_type;
+    this.accessToken = opts.accessToken || opts.access_token;
+    this.refreshToken = opts.refreshToken || opts.refresh_token;
+    this.scope = opts.scope;
   }
 
-  // Define the runtime globally (as expected by generated code) as either
-  // module.exports (if we're in a module) or a new, empty object.
-  runtime = global.regeneratorRuntime = inModule ? module.exports : {};
+  _createClass(AccessToken, [{
+    key: 'toAuthHeader',
+    value: function toAuthHeader() {
+      return 'Bearer ' + this.accessToken;
+    }
+  }, {
+    key: 'toBasicAuth',
+    value: function toBasicAuth() {
+      return 'user:' + this.accessToken + '@';
+    }
+  }]);
 
-  function wrap(innerFn, outerFn, self, tryLocsList) {
-    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
-    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
-    var generator = Object.create(protoGenerator.prototype);
-    var context = new Context(tryLocsList || []);
+  return AccessToken;
+}();
 
-    // The ._invoke method unifies the implementations of the .next,
-    // .throw, and .return methods.
-    generator._invoke = makeInvokeMethod(innerFn, self, context);
+var AppToken = exports.AppToken = function () {
+  function AppToken(opts) {
+    _classCallCheck(this, AppToken);
 
-    return generator;
+    this.token = opts.token || '';
   }
-  runtime.wrap = wrap;
 
-  // Try/catch helper to minimize deoptimizations. Returns a completion
-  // record like context.tryEntries[i].completion. This interface could
-  // have been (and was previously) designed to take a closure to be
-  // invoked without arguments, but in all the cases we care about we
-  // already have an existing method we want to call, so there's no need
-  // to create a new function object. We can even get away with assuming
-  // the method takes exactly one argument, since that happens to be true
-  // in every case, so we don't have to touch the arguments object. The
-  // only additional allocation required is the completion record, which
-  // has a stable shape and so hopefully should be cheap to allocate.
-  function tryCatch(fn, obj, arg) {
-    try {
-      return { type: "normal", arg: fn.call(obj, arg) };
-    } catch (err) {
-      return { type: "throw", arg: err };
+  _createClass(AppToken, [{
+    key: 'toAuthHeader',
+    value: function toAuthHeader() {
+      return 'Bearer ' + this.token;
     }
-  }
-
-  var GenStateSuspendedStart = "suspendedStart";
-  var GenStateSuspendedYield = "suspendedYield";
-  var GenStateExecuting = "executing";
-  var GenStateCompleted = "completed";
-
-  // Returning this object from the innerFn has the same effect as
-  // breaking out of the dispatch switch statement.
-  var ContinueSentinel = {};
-
-  // Dummy constructor functions that we use as the .constructor and
-  // .constructor.prototype properties for functions that return Generator
-  // objects. For full spec compliance, you may wish to configure your
-  // minifier not to mangle the names of these two functions.
-  function Generator() {}
-  function GeneratorFunction() {}
-  function GeneratorFunctionPrototype() {}
+  }, {
+    key: 'toBasicAuth',
+    value: function toBasicAuth() {
+      return 'user:' + this.token + '@';
+    }
+  }]);
 
-  // This is a polyfill for %IteratorPrototype% for environments that
-  // don't natively support it.
-  var IteratorPrototype = {};
-  IteratorPrototype[iteratorSymbol] = function () {
-    return this;
-  };
+  return AppToken;
+}();
 
-  var getProto = Object.getPrototypeOf;
-  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
-  if (NativeIteratorPrototype &&
-      NativeIteratorPrototype !== Op &&
-      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
-    // This environment has a native %IteratorPrototype%; use it instead
-    // of the polyfill.
-    IteratorPrototype = NativeIteratorPrototype;
+function client(cozy, clientParams) {
+  if (!clientParams) {
+    clientParams = cozy._clientParams;
   }
-
-  var Gp = GeneratorFunctionPrototype.prototype =
-    Generator.prototype = Object.create(IteratorPrototype);
-  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
-  GeneratorFunctionPrototype.constructor = GeneratorFunction;
-  GeneratorFunctionPrototype[toStringTagSymbol] =
-    GeneratorFunction.displayName = "GeneratorFunction";
-
-  // Helper for defining the .next, .throw, and .return methods of the
-  // Iterator interface in terms of a single ._invoke method.
-  function defineIteratorMethods(prototype) {
-    ["next", "throw", "return"].forEach(function(method) {
-      prototype[method] = function(arg) {
-        return this._invoke(method, arg);
-      };
-    });
+  if (clientParams instanceof Client) {
+    return clientParams;
   }
+  return new Client(clientParams);
+}
 
-  runtime.isGeneratorFunction = function(genFun) {
-    var ctor = typeof genFun === "function" && genFun.constructor;
-    return ctor
-      ? ctor === GeneratorFunction ||
-        // For the native GeneratorFunction constructor, the best we can
-        // do is to check its .name property.
-        (ctor.displayName || ctor.name) === "GeneratorFunction"
-      : false;
-  };
-
-  runtime.mark = function(genFun) {
-    if (Object.setPrototypeOf) {
-      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
-    } else {
-      genFun.__proto__ = GeneratorFunctionPrototype;
-      if (!(toStringTagSymbol in genFun)) {
-        genFun[toStringTagSymbol] = "GeneratorFunction";
-      }
-    }
-    genFun.prototype = Object.create(Gp);
-    return genFun;
-  };
-
-  // Within the body of any async function, `await x` is transformed to
-  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
-  // `hasOwn.call(value, "__await")` to determine if the yielded value is
-  // meant to be awaited.
-  runtime.awrap = function(arg) {
-    return { __await: arg };
-  };
-
-  function AsyncIterator(generator) {
-    function invoke(method, arg, resolve, reject) {
-      var record = tryCatch(generator[method], generator, arg);
-      if (record.type === "throw") {
-        reject(record.arg);
-      } else {
-        var result = record.arg;
-        var value = result.value;
-        if (value &&
-            typeof value === "object" &&
-            hasOwn.call(value, "__await")) {
-          return Promise.resolve(value.__await).then(function(value) {
-            invoke("next", value, resolve, reject);
-          }, function(err) {
-            invoke("throw", err, resolve, reject);
-          });
-        }
+function registerClient(cozy, clientParams) {
+  var cli = client(cozy, clientParams);
+  if (cli.isRegistered()) {
+    return Promise.reject(new Error('Client already registered'));
+  }
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/register', cli.toRegisterJSON(), {
+    disableAuth: true
+  }).then(function (data) {
+    return new Client(data);
+  });
+}
 
-        return Promise.resolve(value).then(function(unwrapped) {
-          // When a yielded Promise is resolved, its final value becomes
-          // the .value of the Promise<{value,done}> result for the
-          // current iteration. If the Promise is rejected, however, the
-          // result for this iteration will be rejected with the same
-          // reason. Note that rejections of yielded Promises are not
-          // thrown back into the generator function, as is the case
-          // when an awaited Promise is rejected. This difference in
-          // behavior between yield and await is important, because it
-          // allows the consumer to decide what to do with the yielded
-          // rejection (swallow it and continue, manually .throw it back
-          // into the generator, abandon iteration, whatever). With
-          // await, by contrast, there is no opportunity to examine the
-          // rejection reason outside the generator function, so the
-          // only option is to throw it from the await expression, and
-          // let the generator function handle the exception.
-          result.value = unwrapped;
-          resolve(result);
-        }, reject);
-      }
-    }
+function updateClient(cozy, clientParams) {
+  var resetSecret = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
 
-    var previousPromise;
+  var cli = client(cozy, clientParams);
+  if (!cli.isRegistered()) {
+    return Promise.reject(new Error('Client not registered'));
+  }
+  var data = cli.toRegisterJSON();
+  data.client_id = cli.clientID;
+  if (resetSecret) data.client_secret = cli.clientSecret;
 
-    function enqueue(method, arg) {
-      function callInvokeWithMethodAndArg() {
-        return new Promise(function(resolve, reject) {
-          invoke(method, arg, resolve, reject);
-        });
-      }
+  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/auth/register/' + cli.clientID, data, {
+    manualAuthCredentials: {
+      token: cli
+    }
+  }).then(function (data) {
+    return createClient(data, cli);
+  });
+}
 
-      return previousPromise =
-        // If enqueue has been called before, then we want to wait until
-        // all previous Promises have been resolved before calling invoke,
-        // so that results are always delivered in the correct order. If
-        // enqueue has not been called before, then it is important to
-        // call invoke immediately, without waiting on a callback to fire,
-        // so that the async generator function has the opportunity to do
-        // any necessary setup in a predictable way. This predictability
-        // is why the Promise constructor synchronously invokes its
-        // executor callback, and why async functions synchronously
-        // execute code before the first await. Since we implement simple
-        // async functions in terms of async generators, it is especially
-        // important to get this right, even though it requires care.
-        previousPromise ? previousPromise.then(
-          callInvokeWithMethodAndArg,
-          // Avoid propagating failures to Promises returned by later
-          // invocations of the iterator.
-          callInvokeWithMethodAndArg
-        ) : callInvokeWithMethodAndArg();
+function unregisterClient(cozy, clientParams) {
+  var cli = client(cozy, clientParams);
+  if (!cli.isRegistered()) {
+    return Promise.reject(new Error('Client not registered'));
+  }
+  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/auth/register/' + cli.clientID, null, {
+    manualAuthCredentials: {
+      token: cli
     }
+  });
+}
 
-    // Define the unified helper method that is used to implement .next,
-    // .throw, and .return (see defineIteratorMethods).
-    this._invoke = enqueue;
+// getClient will retrive the registered client informations from the server.
+function getClient(cozy, clientParams) {
+  var cli = client(cozy, clientParams);
+  if (!cli.isRegistered()) {
+    return Promise.reject(new Error('Client not registered'));
+  }
+  if ((0, _utils.isOffline)()) {
+    return Promise.resolve(cli);
   }
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/auth/register/' + cli.clientID, null, {
+    manualAuthCredentials: {
+      token: cli
+    }
+  }).then(function (data) {
+    return createClient(data, cli);
+  }).catch(function (err) {
+    // If we fall into an error while fetching the client (because of a
+    // bad connectivity for instance), we do not bail the whole process
+    // since the client should be able to continue with the persisted
+    // client and token.
+    //
+    // If it is an explicit Unauthorized error though, we bail, clear th
+    // cache and retry.
+    if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) {
+      throw new Error('Client has been revoked');
+    }
+    throw err;
+  });
+}
 
-  defineIteratorMethods(AsyncIterator.prototype);
-  AsyncIterator.prototype[asyncIteratorSymbol] = function () {
-    return this;
-  };
-  runtime.AsyncIterator = AsyncIterator;
+// createClient returns a new Client instance given on object containing the
+// data of the client, from the API, and an old instance of the client.
+function createClient(data, oldClient) {
+  var newClient = new Client(data);
+  // we need to keep track of the registrationAccessToken since it is send
+  // only on registration. The GET /auth/register/:client-id endpoint does
+  // not return this token.
+  var shouldPassRegistration = !!oldClient && oldClient.registrationAccessToken !== '' && newClient.registrationAccessToken === '';
+  if (shouldPassRegistration) {
+    newClient.registrationAccessToken = oldClient.registrationAccessToken;
+  }
+  return newClient;
+}
 
-  // Note that simple async functions are implemented on top of
-  // AsyncIterator objects; they just return a Promise for the value of
-  // the final result produced by the iterator.
-  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
-    var iter = new AsyncIterator(
-      wrap(innerFn, outerFn, self, tryLocsList)
-    );
+// getAuthCodeURL returns a pair {authURL,state} given a registered client. The
+// state should be stored in order to be checked against on the user validation
+// phase.
+function getAuthCodeURL(cozy, client) {
+  var scopes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
 
-    return runtime.isGeneratorFunction(outerFn)
-      ? iter // If outerFn is a generator, return the full iterator.
-      : iter.next().then(function(result) {
-          return result.done ? result.value : iter.next();
-        });
+  if (!(client instanceof Client)) {
+    client = new Client(client);
+  }
+  if (!client.isRegistered()) {
+    throw new Error('Client not registered');
+  }
+  var state = generateRandomState();
+  var query = {
+    client_id: client.clientID,
+    redirect_uri: client.redirectURI,
+    state: state,
+    response_type: 'code',
+    scope: scopes.join(' ')
+  };
+  return {
+    url: cozy._url + ('/auth/authorize?' + (0, _utils.encodeQuery)(query)),
+    state: state
   };
+}
 
-  function makeInvokeMethod(innerFn, self, context) {
-    var state = GenStateSuspendedStart;
+// getAccessToken perform a request on the access_token entrypoint with the
+// authorization_code grant type in order to generate a new access token for a
+// newly registered client.
+//
+// This method extracts the access code and state from the given URL. By
+// default it uses window.location.href. Also, it checks the given state with
+// the one specified in the URL query parameter to prevent CSRF attacks.
+function getAccessToken(cozy, client, state) {
+  var pageURL = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
 
-    return function invoke(method, arg) {
-      if (state === GenStateExecuting) {
-        throw new Error("Generator is already running");
-      }
+  if (!state) {
+    return Promise.reject(new Error('Missing state value'));
+  }
+  var grantQueries = getGrantCodeFromPageURL(pageURL);
+  if (grantQueries === null) {
+    return Promise.reject(new Error('Missing states from current URL'));
+  }
+  if (state !== grantQueries.state) {
+    return Promise.reject(new Error('Given state does not match url query state'));
+  }
+  return retrieveToken(cozy, client, null, {
+    grant_type: 'authorization_code',
+    code: grantQueries.code
+  });
+}
 
-      if (state === GenStateCompleted) {
-        if (method === "throw") {
-          throw arg;
-        }
+// refreshToken perform a request on the access_token entrypoint with the
+// refresh_token grant type in order to refresh the given token.
+function refreshToken(cozy, client, token) {
+  return retrieveToken(cozy, client, token, {
+    grant_type: 'refresh_token',
+    refresh_token: token.refreshToken
+  });
+}
 
-        // Be forgiving, per 25.3.3.3.3 of the spec:
-        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
-        return doneResult();
-      }
+// oauthFlow performs the stateful registration and access granting of an OAuth
+// client.
+function oauthFlow(cozy, storage, clientParams, onRegistered) {
+  var ignoreCachedCredentials = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
 
-      context.method = method;
-      context.arg = arg;
+  if (ignoreCachedCredentials) {
+    return storage.clear().then(function () {
+      return oauthFlow(cozy, storage, clientParams, onRegistered, false);
+    });
+  }
 
-      while (true) {
-        var delegate = context.delegate;
-        if (delegate) {
-          var delegateResult = maybeInvokeDelegate(delegate, context);
-          if (delegateResult) {
-            if (delegateResult === ContinueSentinel) continue;
-            return delegateResult;
-          }
-        }
+  var tryCount = 0;
 
-        if (context.method === "next") {
-          // Setting context._sent for legacy support of Babel's
-          // function.sent implementation.
-          context.sent = context._sent = context.arg;
+  function clearAndRetry(err) {
+    if (tryCount++ > 0) {
+      throw err;
+    }
+    return storage.clear().then(function () {
+      return oauthFlow(cozy, storage, clientParams, onRegistered);
+    });
+  }
 
-        } else if (context.method === "throw") {
-          if (state === GenStateSuspendedStart) {
-            state = GenStateCompleted;
-            throw context.arg;
-          }
+  function registerNewClient() {
+    return storage.clear().then(function () {
+      return registerClient(cozy, clientParams);
+    }).then(function (client) {
+      var _getAuthCodeURL = getAuthCodeURL(cozy, client, clientParams.scopes),
+          url = _getAuthCodeURL.url,
+          state = _getAuthCodeURL.state;
 
-          context.dispatchException(context.arg);
+      return storage.save(StateKey, { client: client, url: url, state: state });
+    });
+  }
 
-        } else if (context.method === "return") {
-          context.abrupt("return", context.arg);
+  return Promise.all([storage.load(CredsKey), storage.load(StateKey)]).then(function (_ref) {
+    var _ref2 = _slicedToArray(_ref, 2),
+        credentials = _ref2[0],
+        storedState = _ref2[1];
+
+    // If credentials are cached we re-fetch the registered client with the
+    // said token. Fetching the client, if the token is outdated we should try
+    // the token is refreshed.
+    if (credentials) {
+      var oldClient = void 0,
+          _token = void 0;
+      try {
+        oldClient = new Client(credentials.client);
+        _token = new AccessToken(credentials.token);
+      } catch (err) {
+        // bad cache, we should clear and retry the process
+        return clearAndRetry(err);
+      }
+      return getClient(cozy, oldClient).then(function (client) {
+        return { client: client, token: _token };
+      }).catch(function (err) {
+        // If we fall into an error while fetching the client (because of a
+        // bad connectivity for instance), we do not bail the whole process
+        // since the client should be able to continue with the persisted
+        // client and token.
+        //
+        // If it is an explicit Unauthorized error though, we bail, clear th
+        // cache and retry.
+        if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) {
+          throw new Error('Client has been revoked');
         }
+        return { client: oldClient, token: _token };
+      });
+    }
 
-        state = GenStateExecuting;
+    // Otherwise register a new client if necessary (ie. no client is stored)
+    // and call the onRegistered callback to wait for the user to grant the
+    // access. Finally fetches to access token on success.
+    var statePromise = void 0;
+    if (!storedState) {
+      statePromise = registerNewClient();
+    } else {
+      statePromise = Promise.resolve(storedState);
+    }
 
-        var record = tryCatch(innerFn, self, context);
-        if (record.type === "normal") {
-          // If an exception is thrown from innerFn, we leave state ===
-          // GenStateExecuting and loop back for another invocation.
-          state = context.done
-            ? GenStateCompleted
-            : GenStateSuspendedYield;
+    var client = void 0,
+        state = void 0,
+        token = void 0;
+    return statePromise.then(function (data) {
+      client = data.client;
+      state = data.state;
+      return Promise.resolve(onRegistered(client, data.url));
+    }).then(function (pageURL) {
+      return getAccessToken(cozy, client, state, pageURL);
+    }).then(function (t) {
+      token = t;
+    }).then(function () {
+      return storage.delete(StateKey);
+    }).then(function () {
+      return { client: client, token: token };
+    });
+  }).then(function (creds) {
+    return storage.save(CredsKey, creds);
+  }, function (err) {
+    if (_fetch.FetchError.isUnauthorized(err)) {
+      return clearAndRetry(err);
+    } else {
+      throw err;
+    }
+  });
+}
 
-          if (record.arg === ContinueSentinel) {
-            continue;
-          }
+// retrieveToken perform a request on the access_token entrypoint in order to
+// fetch a token.
+function retrieveToken(cozy, client, token, query) {
+  if (!(client instanceof Client)) {
+    client = new Client(client);
+  }
+  if (!client.isRegistered()) {
+    return Promise.reject(new Error('Client not registered'));
+  }
+  var body = (0, _utils.encodeQuery)(Object.assign({}, query, {
+    client_id: client.clientID,
+    client_secret: client.clientSecret
+  }));
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/access_token', body, {
+    disableAuth: token === null,
+    dontRetry: true,
+    manualAuthCredentials: { client: client, token: token },
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+  }).then(function (data) {
+    data.refreshToken = data.refreshToken || query.refresh_token;
+    return new AccessToken(data);
+  });
+}
 
-          return {
-            value: record.arg,
-            done: context.done
-          };
+// getGrantCodeFromPageURL extract the state and code query parameters from the
+// given url
+function getGrantCodeFromPageURL() {
+  var pageURL = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
 
-        } else if (record.type === "throw") {
-          state = GenStateCompleted;
-          // Dispatch the exception by looping back around to the
-          // context.dispatchException(context.arg) call above.
-          context.method = "throw";
-          context.arg = record.arg;
-        }
-      }
-    };
+  if (pageURL === '' && typeof window !== 'undefined') {
+    pageURL = window.location.href;
+  }
+  var queries = (0, _utils.decodeQuery)(pageURL);
+  if (!queries.hasOwnProperty('state')) {
+    return null;
   }
+  return {
+    state: queries['state'],
+    code: queries['code']
+  };
+}
 
-  // Call delegate.iterator[context.method](context.arg) and handle the
-  // result, either by returning a { value, done } result from the
-  // delegate iterator, or by modifying context.method and context.arg,
-  // setting context.delegate to null, and returning the ContinueSentinel.
-  function maybeInvokeDelegate(delegate, context) {
-    var method = delegate.iterator[context.method];
-    if (method === undefined) {
-      // A .throw or .return when the delegate iterator has no .throw
-      // method always terminates the yield* loop.
-      context.delegate = null;
+// generateRandomState will try to generate a 128bits random value from a secure
+// pseudo random generator. It will fallback on Math.random if it cannot find
+// such generator.
+function generateRandomState() {
+  var buffer = void 0;
+  if (typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function') {
+    buffer = new Uint8Array(StateSize);
+    window.crypto.getRandomValues(buffer);
+  } else {
+    try {
+      buffer = __nested_webpack_require_16254__(12).randomBytes(StateSize);
+    } catch (e) {
+      buffer = null;
+    }
+  }
+  if (!buffer) {
+    buffer = new Array(StateSize);
+    for (var i = 0; i < buffer.length; i++) {
+      buffer[i] = Math.floor(Math.random() * 255);
+    }
+  }
+  return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-');
+}
+/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_16254__(6)))
 
-      if (context.method === "throw") {
-        if (delegate.iterator.return) {
-          // If the delegate iterator has a return method, give it a
-          // chance to clean up.
-          context.method = "return";
-          context.arg = undefined;
-          maybeInvokeDelegate(delegate, context);
+/***/ }),
+/* 4 */
+/***/ (function(module, exports) {
 
-          if (context.method === "throw") {
-            // If maybeInvokeDelegate(context) changed context.method from
-            // "return" to "throw", let that override the TypeError below.
-            return ContinueSentinel;
-          }
-        }
+module.exports = __webpack_require__(487);
 
-        context.method = "throw";
-        context.arg = new TypeError(
-          "The iterator does not provide a 'throw' method");
-      }
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
 
-      return ContinueSentinel;
-    }
+"use strict";
 
-    var record = tryCatch(method, delegate.iterator, context.arg);
 
-    if (record.type === "throw") {
-      context.method = "throw";
-      context.arg = record.arg;
-      context.delegate = null;
-      return ContinueSentinel;
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.pickService = pickService;
+// helper to serialize/deserialize an error for/from postMessage
+var errorSerializer = exports.errorSerializer = function () {
+  function mapErrorProperties(from, to) {
+    var result = Object.assign(to, from);
+    var nativeProperties = ['name', 'message'];
+    return nativeProperties.reduce(function (result, property) {
+      if (from[property]) {
+        to[property] = from[property];
+      }
+      return result;
+    }, result);
+  }
+  return {
+    serialize: function serialize(error) {
+      return mapErrorProperties(error, {});
+    },
+    deserialize: function deserialize(data) {
+      return mapErrorProperties(data, new Error(data.message));
     }
+  };
+}();
 
-    var info = record.arg;
-
-    if (! info) {
-      context.method = "throw";
-      context.arg = new TypeError("iterator result is not an object");
-      context.delegate = null;
-      return ContinueSentinel;
-    }
+var first = function first(arr) {
+  return arr && arr[0];
+};
+// In a far future, the user will have to pick the desired service from a list.
+// For now it's our job, an easy job as we arbitrary pick the first service of
+// the list.
+function pickService(intent, filterServices) {
+  var services = intent.attributes.services;
+  var filteredServices = filterServices ? (services || []).filter(filterServices) : services;
+  return first(filteredServices);
+}
 
-    if (info.done) {
-      // Assign the result of the finished delegate to the temporary
-      // variable specified by delegate.resultName (see delegateYield).
-      context[delegate.resultName] = info.value;
+/***/ }),
+/* 6 */
+/***/ (function(module, exports) {
 
-      // Resume execution at the desired location (see delegateYield).
-      context.next = delegate.nextLoc;
+module.exports = __webpack_require__(490);
 
-      // If context.method was "throw" but the delegate handled the
-      // exception, let the outer generator proceed normally. If
-      // context.method was "next", forget context.arg since it has been
-      // "consumed" by the delegate iterator. If context.method was
-      // "return", allow the original .return call to continue in the
-      // outer generator.
-      if (context.method !== "return") {
-        context.method = "next";
-        context.arg = undefined;
-      }
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
 
-    } else {
-      // Re-yield the result returned by the delegate method.
-      return info;
-    }
+"use strict";
 
-    // The delegate iterator is finished, so forget it and continue with
-    // the outer generator.
-    context.delegate = null;
-    return ContinueSentinel;
-  }
 
-  // Define Generator.prototype.{next,throw,return} in terms of the
-  // unified ._invoke helper method.
-  defineIteratorMethods(Gp);
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+function indexKey(doc) {
+  return doc.type + '/' + doc.id;
+}
 
-  Gp[toStringTagSymbol] = "Generator";
+function findByRef(resources, ref) {
+  return resources[indexKey(ref)];
+}
 
-  // A Generator should always return itself as the iterator object when the
-  // @@iterator function is called on it. Some browsers' implementations of the
-  // iterator prototype chain incorrectly implement this, causing the Generator
-  // object to not be returned from this call. This ensures that doesn't happen.
-  // See https://github.com/facebook/regenerator/issues/274 for more details.
-  Gp[iteratorSymbol] = function() {
-    return this;
+function handleResource(rawResource, resources, links) {
+  var resource = {
+    _id: rawResource.id,
+    _type: rawResource.type,
+    _rev: rawResource.meta && rawResource.meta.rev,
+    links: Object.assign({}, rawResource.links, links),
+    attributes: rawResource.attributes,
+    relations: function relations(name) {
+      var rels = rawResource.relationships[name];
+      if (rels === undefined || rels.data === undefined) return undefined;
+      if (rels.data === null) return null;
+      if (!Array.isArray(rels.data)) return findByRef(resources, rels.data);
+      return rels.data.map(function (ref) {
+        return findByRef(resources, ref);
+      });
+    }
   };
+  if (rawResource.relationships) {
+    resource.relationships = rawResource.relationships;
+  }
 
-  Gp.toString = function() {
-    return "[object Generator]";
-  };
+  resources[indexKey(rawResource)] = resource;
 
-  function pushTryEntry(locs) {
-    var entry = { tryLoc: locs[0] };
+  return resource;
+}
 
-    if (1 in locs) {
-      entry.catchLoc = locs[1];
-    }
+function handleTopLevel(doc) {
+  var resources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 
-    if (2 in locs) {
-      entry.finallyLoc = locs[2];
-      entry.afterLoc = locs[3];
-    }
+  // build an index of included resource by Type & ID
+  var included = doc.included;
 
-    this.tryEntries.push(entry);
+  if (Array.isArray(included)) {
+    included.forEach(function (r) {
+      return handleResource(r, resources, doc.links);
+    });
   }
 
-  function resetTryEntry(entry) {
-    var record = entry.completion || {};
-    record.type = "normal";
-    delete record.arg;
-    entry.completion = record;
+  if (Array.isArray(doc.data)) {
+    return doc.data.map(function (r) {
+      return handleResource(r, resources, doc.links);
+    });
+  } else {
+    return handleResource(doc.data, resources, doc.links);
   }
+}
 
-  function Context(tryLocsList) {
-    // The root entry object (effectively a try statement without a catch
-    // or a finally block) gives us a place to store values thrown from
-    // locations where there is no enclosing try statement.
-    this.tryEntries = [{ tryLoc: "root" }];
-    tryLocsList.forEach(pushTryEntry, this);
-    this.reset(true);
-  }
+exports.default = handleTopLevel;
 
-  runtime.keys = function(object) {
-    var keys = [];
-    for (var key in object) {
-      keys.push(key);
-    }
-    keys.reverse();
+/***/ }),
+/* 8 */
+/***/ (function(module, exports, __nested_webpack_require_36434__) {
 
-    // Rather than returning an object with a next method, we keep
-    // things simple and return the next function itself.
-    return function next() {
-      while (keys.length) {
-        var key = keys.pop();
-        if (key in object) {
-          next.value = key;
-          next.done = false;
-          return next;
-        }
-      }
+"use strict";
 
-      // To avoid creating an additional object, we just hang the .value
-      // and .done properties off the next function object itself. This
-      // also ensures that the minifier will not anonymize the function.
-      next.done = true;
-      return next;
-    };
-  };
 
-  function values(iterable) {
-    if (iterable) {
-      var iteratorMethod = iterable[iteratorSymbol];
-      if (iteratorMethod) {
-        return iteratorMethod.call(iterable);
-      }
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.redirect = exports.getRedirectionURL = undefined;
 
-      if (typeof iterable.next === "function") {
-        return iterable;
-      }
+var _regenerator = __nested_webpack_require_36434__(4);
 
-      if (!isNaN(iterable.length)) {
-        var i = -1, next = function next() {
-          while (++i < iterable.length) {
-            if (hasOwn.call(iterable, i)) {
-              next.value = iterable[i];
-              next.done = false;
-              return next;
-            }
-          }
+var _regenerator2 = _interopRequireDefault(_regenerator);
 
-          next.value = undefined;
-          next.done = true;
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
 
-          return next;
-        };
+// Redirect to an app able to handle the doctype
+// Redirections are more or less a hack of the intent API to retrieve an URL for
+// accessing a given doctype or a given document.
+// It needs to use a special action `REDIRECT`
+var getRedirectionURL = exports.getRedirectionURL = function () {
+  var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, type, data) {
+    var intent, service, baseURL;
+    return _regenerator2.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            if (!(!type && !data)) {
+              _context.next = 2;
+              break;
+            }
 
-        return next.next = next;
-      }
-    }
+            throw new Error('Cannot retrieve redirection, at least type or doc must be provided');
 
-    // Return an iterator with no values.
-    return { next: doneResult };
-  }
-  runtime.values = values;
+          case 2:
+            _context.next = 4;
+            return create(cozy, 'REDIRECT', type, data);
 
-  function doneResult() {
-    return { value: undefined, done: true };
-  }
+          case 4:
+            intent = _context.sent;
+            service = (0, _helpers.pickService)(intent);
 
-  Context.prototype = {
-    constructor: Context,
+            if (service) {
+              _context.next = 8;
+              break;
+            }
 
-    reset: function(skipTempReset) {
-      this.prev = 0;
-      this.next = 0;
-      // Resetting context._sent for legacy support of Babel's
-      // function.sent implementation.
-      this.sent = this._sent = undefined;
-      this.done = false;
-      this.delegate = null;
+            throw new Error('Unable to find a service');
 
-      this.method = "next";
-      this.arg = undefined;
+          case 8:
 
-      this.tryEntries.forEach(resetTryEntry);
+            // Intents cannot be deleted now
+            // await deleteIntent(cozy, intent)
 
-      if (!skipTempReset) {
-        for (var name in this) {
-          // Not sure about the optimal order of these conditions:
-          if (name.charAt(0) === "t" &&
-              hasOwn.call(this, name) &&
-              !isNaN(+name.slice(1))) {
-            this[name] = undefined;
-          }
+            baseURL = removeQueryString(service.href);
+            return _context.abrupt('return', data ? buildRedirectionURL(baseURL, data) : baseURL);
+
+          case 10:
+          case 'end':
+            return _context.stop();
         }
       }
-    },
+    }, _callee, this);
+  }));
 
-    stop: function() {
-      this.done = true;
+  return function getRedirectionURL(_x3, _x4, _x5) {
+    return _ref.apply(this, arguments);
+  };
+}();
 
-      var rootEntry = this.tryEntries[0];
-      var rootRecord = rootEntry.completion;
-      if (rootRecord.type === "throw") {
-        throw rootRecord.arg;
-      }
+var redirect = exports.redirect = function () {
+  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, type, doc, redirectFn) {
+    var redirectionURL;
+    return _regenerator2.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            if (window) {
+              _context2.next = 2;
+              break;
+            }
 
-      return this.rval;
-    },
+            throw new Error('redirect() method can only be called in a browser');
 
-    dispatchException: function(exception) {
-      if (this.done) {
-        throw exception;
-      }
+          case 2:
+            _context2.next = 4;
+            return getRedirectionURL(cozy, type, doc);
 
-      var context = this;
-      function handle(loc, caught) {
-        record.type = "throw";
-        record.arg = exception;
-        context.next = loc;
+          case 4:
+            redirectionURL = _context2.sent;
 
-        if (caught) {
-          // If the dispatched exception was caught by a catch block,
-          // then let that catch block handle the exception normally.
-          context.method = "next";
-          context.arg = undefined;
-        }
+            if (!(redirectFn && typeof redirectFn === 'function')) {
+              _context2.next = 7;
+              break;
+            }
 
-        return !! caught;
-      }
+            return _context2.abrupt('return', redirectFn(redirectionURL));
 
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        var record = entry.completion;
+          case 7:
 
-        if (entry.tryLoc === "root") {
-          // Exception thrown outside of any try block that could handle
-          // it, so set the completion value of the entire function to
-          // throw the exception.
-          return handle("end");
+            window.location.href = redirectionURL;
+
+          case 8:
+          case 'end':
+            return _context2.stop();
         }
+      }
+    }, _callee2, this);
+  }));
 
-        if (entry.tryLoc <= this.prev) {
-          var hasCatch = hasOwn.call(entry, "catchLoc");
-          var hasFinally = hasOwn.call(entry, "finallyLoc");
+  return function redirect(_x6, _x7, _x8, _x9) {
+    return _ref2.apply(this, arguments);
+  };
+}();
 
-          if (hasCatch && hasFinally) {
-            if (this.prev < entry.catchLoc) {
-              return handle(entry.catchLoc, true);
-            } else if (this.prev < entry.finallyLoc) {
-              return handle(entry.finallyLoc);
-            }
+exports.create = create;
+exports.createService = createService;
 
-          } else if (hasCatch) {
-            if (this.prev < entry.catchLoc) {
-              return handle(entry.catchLoc, true);
-            }
+var _fetch = __nested_webpack_require_36434__(0);
 
-          } else if (hasFinally) {
-            if (this.prev < entry.finallyLoc) {
-              return handle(entry.finallyLoc);
-            }
+var _helpers = __nested_webpack_require_36434__(5);
 
-          } else {
-            throw new Error("try statement without catch or finally");
-          }
-        }
-      }
-    },
+var _client = __nested_webpack_require_36434__(16);
 
-    abrupt: function(type, arg) {
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        if (entry.tryLoc <= this.prev &&
-            hasOwn.call(entry, "finallyLoc") &&
-            this.prev < entry.finallyLoc) {
-          var finallyEntry = entry;
-          break;
-        }
-      }
+var client = _interopRequireWildcard(_client);
 
-      if (finallyEntry &&
-          (type === "break" ||
-           type === "continue") &&
-          finallyEntry.tryLoc <= arg &&
-          arg <= finallyEntry.finallyLoc) {
-        // Ignore the finally entry if control is not jumping to a
-        // location outside the try/catch block.
-        finallyEntry = null;
-      }
+var _service = __nested_webpack_require_36434__(17);
 
-      var record = finallyEntry ? finallyEntry.completion : {};
-      record.type = type;
-      record.arg = arg;
+var service = _interopRequireWildcard(_service);
 
-      if (finallyEntry) {
-        this.method = "next";
-        this.next = finallyEntry.finallyLoc;
-        return ContinueSentinel;
-      }
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-      return this.complete(record);
-    },
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-    complete: function(record, afterLoc) {
-      if (record.type === "throw") {
-        throw record.arg;
-      }
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
-      if (record.type === "break" ||
-          record.type === "continue") {
-        this.next = record.arg;
-      } else if (record.type === "return") {
-        this.rval = this.arg = record.arg;
-        this.method = "return";
-        this.next = "end";
-      } else if (record.type === "normal" && afterLoc) {
-        this.next = afterLoc;
-      }
+function create(cozy, action, type) {
+  var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+  var permissions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
 
-      return ContinueSentinel;
-    },
+  if (!action) throw new Error('Misformed intent, "action" property must be provided');
+  if (!type) throw new Error('Misformed intent, "type" property must be provided');
 
-    finish: function(finallyLoc) {
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        if (entry.finallyLoc === finallyLoc) {
-          this.complete(entry.completion, entry.afterLoc);
-          resetTryEntry(entry);
-          return ContinueSentinel;
-        }
+  var createPromise = (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/intents', {
+    data: {
+      type: 'io.cozy.intents',
+      attributes: {
+        action: action,
+        type: type,
+        data: data,
+        permissions: permissions
       }
-    },
+    }
+  });
 
-    "catch": function(tryLoc) {
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        if (entry.tryLoc === tryLoc) {
-          var record = entry.completion;
-          if (record.type === "throw") {
-            var thrown = record.arg;
-            resetTryEntry(entry);
-          }
-          return thrown;
-        }
-      }
+  createPromise.start = function (element, onReadyCallback) {
+    var options = {
+      filteredServices: data.filteredServices,
+      onReadyCallback: onReadyCallback
+    };
 
-      // The context.catch method must only be called with a location
-      // argument that corresponds to a known catch block.
-      throw new Error("illegal catch attempt");
-    },
+    delete data.filteredServices;
 
-    delegateYield: function(iterable, resultName, nextLoc) {
-      this.delegate = {
-        iterator: values(iterable),
-        resultName: resultName,
-        nextLoc: nextLoc
-      };
+    return createPromise.then(function (intent) {
+      return client.start(cozy, intent, element, data, options);
+    });
+  };
 
-      if (this.method === "next") {
-        // Deliberately forget the last sent value so that we don't
-        // accidentally pass it on to the delegate.
-        this.arg = undefined;
-      }
+  return createPromise;
+}
 
-      return ContinueSentinel;
-    }
-  };
-})(
-  // In sloppy mode, unbound `this` refers to the global object, fallback to
-  // Function constructor if we're in global strict mode. That is sadly a form
-  // of indirect eval which violates Content Security Policy.
-  (function() { return this })() || Function("return this")()
-);
+// returns a service to communicate with intent client
+function createService(cozy, intentId, serviceWindow) {
+  return service.start(cozy, intentId, serviceWindow);
+}
 
+function removeQueryString(url) {
+  return url.replace(/\?[^/#]*/, '');
+}
 
-/***/ }),
-/* 478 */
-/***/ ((module) => {
+function isSerializable(value) {
+  return !['object', 'function'].includes(typeof value === 'undefined' ? 'undefined' : _typeof(value));
+}
 
-(function () {
-  "use strict";
+function buildRedirectionURL(url, data) {
+  var parameterStrings = Object.keys(data).filter(function (key) {
+    return isSerializable(data[key]);
+  }).map(function (key) {
+    return key + '=' + data[key];
+  });
 
-  function btoa(str) {
-    var buffer;
+  return parameterStrings.length ? url + '?' + parameterStrings.join('&') : url;
+}
 
-    if (str instanceof Buffer) {
-      buffer = str;
-    } else {
-      buffer = Buffer.from(str.toString(), 'binary');
-    }
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __nested_webpack_require_42748__) {
 
-    return buffer.toString('base64');
-  }
+"use strict";
 
-  module.exports = btoa;
-}());
 
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
 
-/***/ }),
-/* 479 */
-/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
+var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global fetch URL */
 
-const fetchNode = __webpack_require__(480)
-const fetch = fetchNode.fetch.bind({})
 
-fetch.polyfill = true
+var _utils = __nested_webpack_require_42748__(1);
 
-if (!global.fetch) {
-  global.fetch = fetch
-  global.Response = fetchNode.Response
-  global.Headers = fetchNode.Headers
-  global.Request = fetchNode.Request
-}
+var _auth_storage = __nested_webpack_require_42748__(10);
 
+var _auth_v = __nested_webpack_require_42748__(11);
 
-/***/ }),
-/* 480 */
-/***/ ((module, exports, __webpack_require__) => {
+var _auth_v2 = __nested_webpack_require_42748__(3);
 
-const nodeFetch = __webpack_require__(481)
-const realFetch = nodeFetch.default || nodeFetch
+var auth = _interopRequireWildcard(_auth_v2);
 
-const fetch = function (url, options) {
-  // Support schemaless URIs on the server for parity with the browser.
-  // Ex: //github.com/ -> https://github.com/
-  if (/^\/\//.test(url)) {
-    url = 'https:' + url
-  }
-  return realFetch.call(this, url, options)
-}
+var _data = __nested_webpack_require_42748__(13);
 
-fetch.ponyfill = true
+var data = _interopRequireWildcard(_data);
 
-module.exports = exports = fetch
-exports.fetch = fetch
-exports.Headers = nodeFetch.Headers
-exports.Request = nodeFetch.Request
-exports.Response = nodeFetch.Response
+var _fetch2 = __nested_webpack_require_42748__(0);
 
-// Needed for TypeScript consumers without esModuleInterop.
-exports["default"] = fetch
+var cozyFetch = _interopRequireWildcard(_fetch2);
 
+var _mango = __nested_webpack_require_42748__(14);
 
-/***/ }),
-/* 481 */
-/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+var mango = _interopRequireWildcard(_mango);
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
-/* harmony export */   "Headers": () => (/* binding */ Headers),
-/* harmony export */   "Request": () => (/* binding */ Request),
-/* harmony export */   "Response": () => (/* binding */ Response),
-/* harmony export */   "FetchError": () => (/* binding */ FetchError)
-/* harmony export */ });
-/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82);
-/* harmony import */ var http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(80);
-/* harmony import */ var url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(63);
-/* harmony import */ var https__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(81);
-/* harmony import */ var zlib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(83);
+var _files = __nested_webpack_require_42748__(15);
+
+var files = _interopRequireWildcard(_files);
 
+var _intents = __nested_webpack_require_42748__(8);
 
+var intents = _interopRequireWildcard(_intents);
 
+var _jobs = __nested_webpack_require_42748__(18);
 
+var jobs = _interopRequireWildcard(_jobs);
 
+var _offline = __nested_webpack_require_42748__(19);
 
-// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
+var offline = _interopRequireWildcard(_offline);
 
-// fix for "Readable" isn't a named export issue
-const Readable = stream__WEBPACK_IMPORTED_MODULE_0__.Readable;
+var _settings = __nested_webpack_require_42748__(23);
 
-const BUFFER = Symbol('buffer');
-const TYPE = Symbol('type');
+var settings = _interopRequireWildcard(_settings);
 
-class Blob {
-	constructor() {
-		this[TYPE] = '';
+var _relations = __nested_webpack_require_42748__(24);
 
-		const blobParts = arguments[0];
-		const options = arguments[1];
+var relations = _interopRequireWildcard(_relations);
 
-		const buffers = [];
-		let size = 0;
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-		if (blobParts) {
-			const a = blobParts;
-			const length = Number(a.length);
-			for (let i = 0; i < length; i++) {
-				const element = a[i];
-				let buffer;
-				if (element instanceof Buffer) {
-					buffer = element;
-				} else if (ArrayBuffer.isView(element)) {
-					buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
-				} else if (element instanceof ArrayBuffer) {
-					buffer = Buffer.from(element);
-				} else if (element instanceof Blob) {
-					buffer = element[BUFFER];
-				} else {
-					buffer = Buffer.from(typeof element === 'string' ? element : String(element));
-				}
-				size += buffer.length;
-				buffers.push(buffer);
-			}
-		}
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-		this[BUFFER] = Buffer.concat(buffers);
+var AppTokenV3 = auth.AppToken,
+    AccessTokenV3 = auth.AccessToken,
+    ClientV3 = auth.Client;
 
-		let type = options && options.type !== undefined && String(options.type).toLowerCase();
-		if (type && !/[^\u0020-\u007E]/.test(type)) {
-			this[TYPE] = type;
-		}
-	}
-	get size() {
-		return this[BUFFER].length;
-	}
-	get type() {
-		return this[TYPE];
-	}
-	text() {
-		return Promise.resolve(this[BUFFER].toString());
-	}
-	arrayBuffer() {
-		const buf = this[BUFFER];
-		const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
-		return Promise.resolve(ab);
-	}
-	stream() {
-		const readable = new Readable();
-		readable._read = function () {};
-		readable.push(this[BUFFER]);
-		readable.push(null);
-		return readable;
-	}
-	toString() {
-		return '[object Blob]';
-	}
-	slice() {
-		const size = this.size;
 
-		const start = arguments[0];
-		const end = arguments[1];
-		let relativeStart, relativeEnd;
-		if (start === undefined) {
-			relativeStart = 0;
-		} else if (start < 0) {
-			relativeStart = Math.max(size + start, 0);
-		} else {
-			relativeStart = Math.min(start, size);
-		}
-		if (end === undefined) {
-			relativeEnd = size;
-		} else if (end < 0) {
-			relativeEnd = Math.max(size + end, 0);
-		} else {
-			relativeEnd = Math.min(end, size);
-		}
-		const span = Math.max(relativeEnd - relativeStart, 0);
+var AuthNone = 0;
+var AuthRunning = 1;
+var AuthError = 2;
+var AuthOK = 3;
 
-		const buffer = this[BUFFER];
-		const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
-		const blob = new Blob([], { type: arguments[2] });
-		blob[BUFFER] = slicedBuffer;
-		return blob;
-	}
-}
+var defaultClientParams = {
+  softwareID: 'github.com/cozy/cozy-client-js'
+};
 
-Object.defineProperties(Blob.prototype, {
-	size: { enumerable: true },
-	type: { enumerable: true },
-	slice: { enumerable: true }
-});
+var dataProto = {
+  create: data.create,
+  find: data.find,
+  findMany: data.findMany,
+  findAll: data.findAll,
+  update: data.update,
+  delete: data._delete,
+  updateAttributes: data.updateAttributes,
+  changesFeed: data.changesFeed,
+  defineIndex: mango.defineIndex,
+  query: mango.query,
+  addReferencedFiles: relations.addReferencedFiles,
+  removeReferencedFiles: relations.removeReferencedFiles,
+  listReferencedFiles: relations.listReferencedFiles,
+  fetchReferencedFiles: relations.fetchReferencedFiles,
+  destroy: function destroy() {
+    (0, _utils.warn)('destroy is deprecated, use cozy.data.delete instead.');
+    return data._delete.apply(data, arguments);
+  }
+};
 
-Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
-	value: 'Blob',
-	writable: false,
-	enumerable: false,
-	configurable: true
-});
+var authProto = {
+  client: auth.client,
+  registerClient: auth.registerClient,
+  updateClient: auth.updateClient,
+  unregisterClient: auth.unregisterClient,
+  getClient: auth.getClient,
+  getAuthCodeURL: auth.getAuthCodeURL,
+  getAccessToken: auth.getAccessToken,
+  refreshToken: auth.refreshToken
+};
 
-/**
- * fetch-error.js
- *
- * FetchError interface for operational errors
- */
+var filesProto = {
+  create: files.create,
+  createDirectory: files.createDirectory,
+  createDirectoryByPath: files.createDirectoryByPath,
+  updateById: files.updateById,
+  updateAttributesById: files.updateAttributesById,
+  updateAttributesByPath: files.updateAttributesByPath,
+  trashById: files.trashById,
+  statById: files.statById,
+  statByPath: files.statByPath,
+  downloadById: files.downloadById,
+  downloadByPath: files.downloadByPath,
+  getDownloadLinkById: files.getDownloadLinkById,
+  getDownloadLink: files.getDownloadLinkByPath, // DEPRECATED, should be removed very soon
+  getDownloadLinkByPath: files.getDownloadLinkByPath,
+  getArchiveLink: function getArchiveLink() {
+    (0, _utils.warn)('getArchiveLink is deprecated, use cozy.files.getArchiveLinkByPaths instead.');
+    return files.getArchiveLinkByPaths.apply(files, arguments);
+  },
+  getArchiveLinkByPaths: files.getArchiveLinkByPaths,
+  getArchiveLinkByIds: files.getArchiveLinkByIds,
+  getFilePath: files.getFilePath,
+  getCollectionShareLink: files.getCollectionShareLink,
+  query: mango.queryFiles,
+  listTrash: files.listTrash,
+  clearTrash: files.clearTrash,
+  restoreById: files.restoreById,
+  destroyById: files.destroyById
+};
 
-/**
- * Create FetchError instance
- *
- * @param   String      message      Error message for human
- * @param   String      type         Error type for machine
- * @param   String      systemError  For Node.js system error
- * @return  FetchError
- */
-function FetchError(message, type, systemError) {
-  Error.call(this, message);
+var intentsProto = {
+  create: intents.create,
+  createService: intents.createService,
+  getRedirectionURL: intents.getRedirectionURL,
+  redirect: intents.redirect
+};
 
-  this.message = message;
-  this.type = type;
+var jobsProto = {
+  create: jobs.create,
+  count: jobs.count,
+  queued: jobs.queued
+};
 
-  // when err.type is `system`, err.code contains system error code
-  if (systemError) {
-    this.code = this.errno = systemError.code;
-  }
+var offlineProto = {
+  init: offline.init,
+  getDoctypes: offline.getDoctypes,
+  // database
+  hasDatabase: offline.hasDatabase,
+  getDatabase: offline.getDatabase,
+  createDatabase: offline.createDatabase,
+  migrateDatabase: offline.migrateDatabase,
+  destroyDatabase: offline.destroyDatabase,
+  destroyAllDatabase: offline.destroyAllDatabase,
+  // replication
+  hasReplication: offline.hasReplication,
+  replicateFromCozy: offline.replicateFromCozy,
+  stopReplication: offline.stopReplication,
+  stopAllReplication: offline.stopAllReplication,
+  // repeated replication
+  hasRepeatedReplication: offline.hasRepeatedReplication,
+  startRepeatedReplication: offline.startRepeatedReplication,
+  stopRepeatedReplication: offline.stopRepeatedReplication,
+  stopAllRepeatedReplication: offline.stopAllRepeatedReplication
+};
 
-  // hide custom error implementation details from end-users
-  Error.captureStackTrace(this, this.constructor);
-}
+var settingsProto = {
+  diskUsage: settings.diskUsage,
+  changePassphrase: settings.changePassphrase,
+  getInstance: settings.getInstance,
+  updateInstance: settings.updateInstance,
+  getClients: settings.getClients,
+  deleteClientById: settings.deleteClientById,
+  updateLastSync: settings.updateLastSync
+};
 
-FetchError.prototype = Object.create(Error.prototype);
-FetchError.prototype.constructor = FetchError;
-FetchError.prototype.name = 'FetchError';
+var ensureHasReconnectParam = function ensureHasReconnectParam(_url) {
+  var url = new URL(_url);
+  if (url.searchParams && !url.searchParams.has('reconnect')) {
+    url.searchParams.append('reconnect', 1);
+  } else if (!url.search || url.search.indexOf('reconnect') === -1) {
+    // Some old navigators do not have the searchParams API
+    // and it is not polyfilled by babel-polyfill
+    url.search = url.search + '&reconnect=1';
+  }
+  return url.toString();
+};
 
-let convert;
-try {
-	convert = require('encoding').convert;
-} catch (e) {}
+var Client = function () {
+  function Client(options) {
+    _classCallCheck(this, Client);
 
-const INTERNALS = Symbol('Body internals');
+    this.data = {};
+    this.files = {};
+    this.intents = {};
+    this.jobs = {};
+    this.offline = {};
+    this.settings = {};
+    this.auth = {
+      Client: ClientV3,
+      AccessToken: AccessTokenV3,
+      AppToken: AppTokenV3,
+      AppTokenV2: _auth_v.AppToken,
+      LocalStorage: _auth_storage.LocalStorage,
+      MemoryStorage: _auth_storage.MemoryStorage
+    };
+    this._inited = false;
+    if (options) {
+      this.init(options);
+    }
+  }
 
-// fix an issue where "PassThrough" isn't a named export for node <10
-const PassThrough = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough;
+  _createClass(Client, [{
+    key: 'init',
+    value: function init() {
+      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
 
-/**
- * Body mixin
- *
- * Ref: https://fetch.spec.whatwg.org/#body
- *
- * @param   Stream  body  Readable stream
- * @param   Object  opts  Response options
- * @return  Void
- */
-function Body(body) {
-	var _this = this;
+      this._inited = true;
+      this._oauth = false; // is oauth activated or not
+      this._token = null; // application token
+      this._authstate = AuthNone;
+      this._authcreds = null;
+      this._storage = null;
+      this._version = options.version || null;
+      this._offline = null;
 
-	var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
-	    _ref$size = _ref.size;
+      var token = options.token;
+      var oauth = options.oauth;
+      if (token && oauth) {
+        throw new Error('Cannot specify an application token with a oauth activated');
+      }
 
-	let size = _ref$size === undefined ? 0 : _ref$size;
-	var _ref$timeout = _ref.timeout;
-	let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
+      if (token) {
+        this._token = new AppTokenV3({ token: token });
+      } else if (oauth) {
+        this._oauth = true;
+        this._storage = oauth.storage;
+        this._clientParams = Object.assign({}, defaultClientParams, oauth.clientParams);
+        this._onRegistered = oauth.onRegistered || nopOnRegistered;
+      }
 
-	if (body == null) {
-		// body is undefined or null
-		body = null;
-	} else if (isURLSearchParams(body)) {
-		// body is a URLSearchParams
-		body = Buffer.from(body.toString());
-	} else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
-		// body is ArrayBuffer
-		body = Buffer.from(body);
-	} else if (ArrayBuffer.isView(body)) {
-		// body is ArrayBufferView
-		body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
-	} else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) ; else {
-		// none of the above
-		// coerce to string then buffer
-		body = Buffer.from(String(body));
-	}
-	this[INTERNALS] = {
-		body,
-		disturbed: false,
-		error: null
-	};
-	this.size = size;
-	this.timeout = timeout;
+      var url = options.cozyURL || '';
+      while (url[url.length - 1] === '/') {
+        url = url.slice(0, -1);
+      }
 
-	if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) {
-		body.on('error', function (err) {
-			const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);
-			_this[INTERNALS].error = error;
-		});
-	}
-}
+      this._url = url;
 
-Body.prototype = {
-	get body() {
-		return this[INTERNALS].body;
-	},
+      this._invalidTokenErrorHandler = options.onInvalidTokenError !== undefined ? options.onInvalidTokenError : cozyFetch.handleInvalidTokenError;
 
-	get bodyUsed() {
-		return this[INTERNALS].disturbed;
-	},
+      var disablePromises = !!options.disablePromises;
+      addToProto(this, this.data, dataProto, disablePromises);
+      addToProto(this, this.auth, authProto, disablePromises);
+      addToProto(this, this.files, filesProto, disablePromises);
+      addToProto(this, this.intents, intentsProto, disablePromises);
+      addToProto(this, this.jobs, jobsProto, disablePromises);
+      addToProto(this, this.offline, offlineProto, disablePromises);
+      addToProto(this, this.settings, settingsProto, disablePromises);
 
-	/**
-  * Decode response as ArrayBuffer
-  *
-  * @return  Promise
-  */
-	arrayBuffer() {
-		return consumeBody.call(this).then(function (buf) {
-			return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
-		});
-	},
+      if (options.offline) {
+        this.offline.init(options.offline);
+      }
 
-	/**
-  * Return raw response as Blob
-  *
-  * @return Promise
-  */
-	blob() {
-		let ct = this.headers && this.headers.get('content-type') || '';
-		return consumeBody.call(this).then(function (buf) {
-			return Object.assign(
-			// Prevent copying
-			new Blob([], {
-				type: ct.toLowerCase()
-			}), {
-				[BUFFER]: buf
-			});
-		});
-	},
+      this.fetch = function _fetch(method, url) {
+        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
 
-	/**
-  * Decode response as json
-  *
-  * @return  Promise
-  */
-	json() {
-		var _this2 = this;
+        return cozyFetch.cozyFetch(this, url, _extends({}, options, { method: method }));
+      };
 
-		return consumeBody.call(this).then(function (buffer) {
-			try {
-				return JSON.parse(buffer.toString());
-			} catch (err) {
-				return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));
-			}
-		});
-	},
+      this.fetchJSON = function _fetchJSON() {
+        var args = [this].concat(Array.prototype.slice.call(arguments));
+        return cozyFetch.cozyFetchJSON.apply(this, args);
+      };
+    }
+  }, {
+    key: 'authorize',
+    value: function authorize() {
+      var _this = this;
 
-	/**
-  * Decode response as text
-  *
-  * @return  Promise
-  */
-	text() {
-		return consumeBody.call(this).then(function (buffer) {
-			return buffer.toString();
-		});
-	},
+      var forceTokenRefresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
 
-	/**
-  * Decode response as buffer (non-spec api)
-  *
-  * @return  Promise
-  */
-	buffer() {
-		return consumeBody.call(this);
-	},
+      var state = this._authstate;
+      if (state === AuthOK || state === AuthRunning) {
+        return this._authcreds;
+      }
 
-	/**
-  * Decode response as text, while automatically detecting the encoding and
-  * trying to decode to UTF-8 (non-spec api)
-  *
-  * @return  Promise
-  */
-	textConverted() {
-		var _this3 = this;
+      this._authstate = AuthRunning;
+      this._authcreds = this.isV2().then(function (isV2) {
+        if (isV2 && _this._oauth) {
+          throw new Error('OAuth is not supported on the V2 stack');
+        }
+        if (_this._oauth) {
+          if (forceTokenRefresh && _this._clientParams.redirectURI) {
+            _this._clientParams.redirectURI = ensureHasReconnectParam(_this._clientParams.redirectURI);
+          }
+          return auth.oauthFlow(_this, _this._storage, _this._clientParams, _this._onRegistered, forceTokenRefresh);
+        }
+        // we expect to be on a client side application running in a browser
+        // with cookie-based authentication.
+        if (isV2) {
+          return (0, _auth_v.getAppToken)();
+        } else if (_this._token) {
+          return Promise.resolve({ client: null, token: _this._token });
+        } else {
+          throw new Error('Missing application token');
+        }
+      });
 
-		return consumeBody.call(this).then(function (buffer) {
-			return convertBody(buffer, _this3.headers);
-		});
-	}
-};
+      this._authcreds.then(function () {
+        _this._authstate = AuthOK;
+      }, function () {
+        _this._authstate = AuthError;
+      });
 
-// In browsers, all properties are enumerable.
-Object.defineProperties(Body.prototype, {
-	body: { enumerable: true },
-	bodyUsed: { enumerable: true },
-	arrayBuffer: { enumerable: true },
-	blob: { enumerable: true },
-	json: { enumerable: true },
-	text: { enumerable: true }
-});
+      return this._authcreds;
+    }
+  }, {
+    key: 'saveCredentials',
+    value: function saveCredentials(client, token) {
+      var creds = { client: client, token: token };
+      if (!this._storage || this._authstate === AuthRunning) {
+        return Promise.resolve(creds);
+      }
+      this._storage.save(auth.CredsKey, creds);
+      this._authcreds = Promise.resolve(creds);
+      return this._authcreds;
+    }
+  }, {
+    key: 'fullpath',
+    value: function fullpath(path) {
+      var _this2 = this;
 
-Body.mixIn = function (proto) {
-	for (const name of Object.getOwnPropertyNames(Body.prototype)) {
-		// istanbul ignore else: future proof
-		if (!(name in proto)) {
-			const desc = Object.getOwnPropertyDescriptor(Body.prototype, name);
-			Object.defineProperty(proto, name, desc);
-		}
-	}
-};
+      return this.isV2().then(function (isV2) {
+        var pathprefix = isV2 ? '/ds-api' : '';
+        return _this2._url + pathprefix + path;
+      });
+    }
+  }, {
+    key: 'isV2',
+    value: function isV2() {
+      var _this3 = this;
 
-/**
- * Consume and convert an entire Body to a Buffer.
- *
- * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
- *
- * @return  Promise
- */
-function consumeBody() {
-	var _this4 = this;
+      if (!this._version) {
+        return (0, _utils.retry)(function () {
+          return fetch(_this3._url + '/status/');
+        }, 3)().then(function (res) {
+          if (!res.ok) {
+            throw new Error('Could not fetch cozy status');
+          } else {
+            return res.json();
+          }
+        }).then(function (status) {
+          _this3._version = status.datasystem !== undefined ? 2 : 3;
+          return _this3.isV2();
+        });
+      }
+      return Promise.resolve(this._version === 2);
+    }
+  }]);
 
-	if (this[INTERNALS].disturbed) {
-		return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));
-	}
+  return Client;
+}();
 
-	this[INTERNALS].disturbed = true;
+function nopOnRegistered() {
+  throw new Error('Missing onRegistered callback');
+}
 
-	if (this[INTERNALS].error) {
-		return Body.Promise.reject(this[INTERNALS].error);
-	}
+function protoify(context, fn) {
+  return function prototyped() {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
 
-	let body = this.body;
+    return fn.apply(undefined, [context].concat(args));
+  };
+}
 
-	// body is null
-	if (body === null) {
-		return Body.Promise.resolve(Buffer.alloc(0));
-	}
+function addToProto(ctx, obj, proto, disablePromises) {
+  for (var attr in proto) {
+    var fn = protoify(ctx, proto[attr]);
+    if (disablePromises) {
+      fn = (0, _utils.unpromiser)(fn);
+    }
+    obj[attr] = fn;
+  }
+}
 
-	// body is blob
-	if (isBlob(body)) {
-		body = body.stream();
-	}
+module.exports = new Client();
+Object.assign(module.exports, { Client: Client, LocalStorage: _auth_storage.LocalStorage, MemoryStorage: _auth_storage.MemoryStorage });
 
-	// body is buffer
-	if (Buffer.isBuffer(body)) {
-		return Body.Promise.resolve(body);
-	}
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
 
-	// istanbul ignore if: should never happen
-	if (!(body instanceof stream__WEBPACK_IMPORTED_MODULE_0__)) {
-		return Body.Promise.resolve(Buffer.alloc(0));
-	}
+"use strict";
 
-	// body is stream
-	// get ready to actually consume the body
-	let accum = [];
-	let accumBytes = 0;
-	let abort = false;
 
-	return new Body.Promise(function (resolve, reject) {
-		let resTimeout;
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
 
-		// allow timeout on slow response body
-		if (_this4.timeout) {
-			resTimeout = setTimeout(function () {
-				abort = true;
-				reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));
-			}, _this4.timeout);
-		}
+var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
-		// handle stream errors
-		body.on('error', function (err) {
-			if (err.name === 'AbortError') {
-				// if the request was aborted, reject with this Error
-				abort = true;
-				reject(err);
-			} else {
-				// other errors, such as incorrect content-encoding
-				reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));
-			}
-		});
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-		body.on('data', function (chunk) {
-			if (abort || chunk === null) {
-				return;
-			}
+var LocalStorage = exports.LocalStorage = function () {
+  function LocalStorage(storage, prefix) {
+    _classCallCheck(this, LocalStorage);
 
-			if (_this4.size && accumBytes + chunk.length > _this4.size) {
-				abort = true;
-				reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));
-				return;
-			}
+    if (!storage && typeof window !== 'undefined') {
+      storage = window.localStorage;
+    }
+    this.storage = storage;
+    this.prefix = prefix || 'cozy:oauth:';
+  }
 
-			accumBytes += chunk.length;
-			accum.push(chunk);
-		});
+  _createClass(LocalStorage, [{
+    key: 'save',
+    value: function save(key, value) {
+      var _this = this;
 
-		body.on('end', function () {
-			if (abort) {
-				return;
-			}
+      return new Promise(function (resolve) {
+        _this.storage.setItem(_this.prefix + key, JSON.stringify(value));
+        resolve(value);
+      });
+    }
+  }, {
+    key: 'load',
+    value: function load(key) {
+      var _this2 = this;
 
-			clearTimeout(resTimeout);
+      return new Promise(function (resolve) {
+        var item = _this2.storage.getItem(_this2.prefix + key);
+        if (!item) {
+          resolve();
+        } else {
+          resolve(JSON.parse(item));
+        }
+      });
+    }
+  }, {
+    key: 'delete',
+    value: function _delete(key) {
+      var _this3 = this;
 
-			try {
-				resolve(Buffer.concat(accum, accumBytes));
-			} catch (err) {
-				// handle streams that have accumulated too much data (issue #414)
-				reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));
-			}
-		});
-	});
-}
+      return new Promise(function (resolve) {
+        return resolve(_this3.storage.removeItem(_this3.prefix + key));
+      });
+    }
+  }, {
+    key: 'clear',
+    value: function clear() {
+      var _this4 = this;
 
-/**
- * Detect buffer encoding and convert to target encoding
- * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
- *
- * @param   Buffer  buffer    Incoming buffer
- * @param   String  encoding  Target encoding
- * @return  String
- */
-function convertBody(buffer, headers) {
-	if (typeof convert !== 'function') {
-		throw new Error('The package `encoding` must be installed to use the textConverted() function');
-	}
+      return new Promise(function (resolve) {
+        var storage = _this4.storage;
+        for (var i = 0; i < storage.length; i++) {
+          var key = storage.key(i);
+          if (key.indexOf(_this4.prefix) === 0) {
+            storage.removeItem(key);
+          }
+        }
+        resolve();
+      });
+    }
+  }]);
 
-	const ct = headers.get('content-type');
-	let charset = 'utf-8';
-	let res, str;
+  return LocalStorage;
+}();
 
-	// header
-	if (ct) {
-		res = /charset=([^;]*)/i.exec(ct);
-	}
+var MemoryStorage = exports.MemoryStorage = function () {
+  function MemoryStorage() {
+    _classCallCheck(this, MemoryStorage);
 
-	// no charset in content type, peek at response body for at most 1024 bytes
-	str = buffer.slice(0, 1024).toString();
+    this.hash = Object.create(null);
+  }
 
-	// html5
-	if (!res && str) {
-		res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
-	}
+  _createClass(MemoryStorage, [{
+    key: 'save',
+    value: function save(key, value) {
+      this.hash[key] = value;
+      return Promise.resolve(value);
+    }
+  }, {
+    key: 'load',
+    value: function load(key) {
+      return Promise.resolve(this.hash[key]);
+    }
+  }, {
+    key: 'delete',
+    value: function _delete(key) {
+      var deleted = delete this.hash[key];
+      return Promise.resolve(deleted);
+    }
+  }, {
+    key: 'clear',
+    value: function clear() {
+      this.hash = Object.create(null);
+      return Promise.resolve();
+    }
+  }]);
 
-	// html4
-	if (!res && str) {
-		res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
-		if (!res) {
-			res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str);
-			if (res) {
-				res.pop(); // drop last quote
-			}
-		}
+  return MemoryStorage;
+}();
 
-		if (res) {
-			res = /charset=(.*)/i.exec(res.pop());
-		}
-	}
+/***/ }),
+/* 11 */
+/***/ (function(module, exports, __nested_webpack_require_58943__) {
 
-	// xml
-	if (!res && str) {
-		res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
-	}
+"use strict";
+/* WEBPACK VAR INJECTION */(function(btoa) {
 
-	// found charset
-	if (res) {
-		charset = res.pop();
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
 
-		// prevent decode issues when sites use incorrect encoding
-		// ref: https://hsivonen.fi/encoding-menu/
-		if (charset === 'gb2312' || charset === 'gbk') {
-			charset = 'gb18030';
-		}
-	}
+var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
-	// turn raw buffers into a single utf-8 buffer
-	return convert(buffer, 'UTF-8', charset).toString();
-}
+exports.getAppToken = getAppToken;
 
-/**
- * Detect a URLSearchParams object
- * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143
- *
- * @param   Object  obj     Object to detect by type or brand
- * @return  String
- */
-function isURLSearchParams(obj) {
-	// Duck-typing as a necessary condition.
-	if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {
-		return false;
-	}
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-	// Brand-checking and more duck-typing as optional condition.
-	return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';
-}
+/* global btoa */
+var V2TOKEN_ABORT_TIMEOUT = 3000;
 
-/**
- * Check if `obj` is a W3C `Blob` object (which `File` inherits from)
- * @param  {*} obj
- * @return {boolean}
- */
-function isBlob(obj) {
-	return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);
+function getAppToken() {
+  return new Promise(function (resolve, reject) {
+    if (typeof window === 'undefined') {
+      return reject(new Error('getV2Token should be used in browser'));
+    } else if (!window.parent) {
+      return reject(new Error('getV2Token should be used in iframe'));
+    } else if (!window.parent.postMessage) {
+      return reject(new Error('getV2Token should be used in modern browser'));
+    }
+    var origin = window.location.origin;
+    var intent = { action: 'getToken' };
+    var timeout = null;
+    var receiver = function receiver(event) {
+      var token = void 0;
+      try {
+        token = new AppToken({
+          appName: event.data.appName,
+          token: event.data.token
+        });
+      } catch (e) {
+        reject(e);
+        return;
+      }
+      window.removeEventListener('message', receiver);
+      clearTimeout(timeout);
+      resolve({ client: null, token: token });
+    };
+    window.addEventListener('message', receiver, false);
+    window.parent.postMessage(intent, origin);
+    timeout = setTimeout(function () {
+      reject(new Error('No response from parent iframe after 3s'));
+    }, V2TOKEN_ABORT_TIMEOUT);
+  });
 }
 
-/**
- * Clone body given Res/Req instance
- *
- * @param   Mixed  instance  Response or Request instance
- * @return  Mixed
- */
-function clone(instance) {
-	let p1, p2;
-	let body = instance.body;
-
-	// don't allow cloning a used body
-	if (instance.bodyUsed) {
-		throw new Error('cannot clone body after it is used');
-	}
-
-	// check that body is a stream and not form-data object
-	// note: we can't clone the form-data object without having it as a dependency
-	if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__ && typeof body.getBoundary !== 'function') {
-		// tee instance body
-		p1 = new PassThrough();
-		p2 = new PassThrough();
-		body.pipe(p1);
-		body.pipe(p2);
-		// set instance body to teed body and return the other teed body
-		instance[INTERNALS].body = p1;
-		body = p2;
-	}
+var AppToken = exports.AppToken = function () {
+  function AppToken(opts) {
+    _classCallCheck(this, AppToken);
 
-	return body;
-}
+    this.appName = opts.appName || '';
+    this.token = opts.token || '';
+  }
 
-/**
- * Performs the operation "extract a `Content-Type` value from |object|" as
- * specified in the specification:
- * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
- *
- * This function assumes that instance.body is present.
- *
- * @param   Mixed  instance  Any options.body input
- */
-function extractContentType(body) {
-	if (body === null) {
-		// body is null
-		return null;
-	} else if (typeof body === 'string') {
-		// body is string
-		return 'text/plain;charset=UTF-8';
-	} else if (isURLSearchParams(body)) {
-		// body is a URLSearchParams
-		return 'application/x-www-form-urlencoded;charset=UTF-8';
-	} else if (isBlob(body)) {
-		// body is blob
-		return body.type || null;
-	} else if (Buffer.isBuffer(body)) {
-		// body is buffer
-		return null;
-	} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
-		// body is ArrayBuffer
-		return null;
-	} else if (ArrayBuffer.isView(body)) {
-		// body is ArrayBufferView
-		return null;
-	} else if (typeof body.getBoundary === 'function') {
-		// detect form data input from form-data module
-		return `multipart/form-data;boundary=${body.getBoundary()}`;
-	} else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) {
-		// body is stream
-		// can't really do much about this
-		return null;
-	} else {
-		// Body constructor defaults other things to string
-		return 'text/plain;charset=UTF-8';
-	}
-}
+  _createClass(AppToken, [{
+    key: 'toAuthHeader',
+    value: function toAuthHeader() {
+      return 'Basic ' + btoa(this.appName + ':' + this.token);
+    }
+  }]);
 
-/**
- * The Fetch Standard treats this as if "total bytes" is a property on the body.
- * For us, we have to explicitly get it with a function.
- *
- * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
- *
- * @param   Body    instance   Instance of Body
- * @return  Number?            Number of bytes, or null if not possible
- */
-function getTotalBytes(instance) {
-	const body = instance.body;
+  return AppToken;
+}();
+/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_58943__(6)))
 
+/***/ }),
+/* 12 */
+/***/ (function(module, exports) {
 
-	if (body === null) {
-		// body is null
-		return 0;
-	} else if (isBlob(body)) {
-		return body.size;
-	} else if (Buffer.isBuffer(body)) {
-		// body is buffer
-		return body.length;
-	} else if (body && typeof body.getLengthSync === 'function') {
-		// detect form data input from form-data module
-		if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x
-		body.hasKnownLength && body.hasKnownLength()) {
-			// 2.x
-			return body.getLengthSync();
-		}
-		return null;
-	} else {
-		// body is stream
-		return null;
-	}
-}
+module.exports = __webpack_require__(76);
 
-/**
- * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
- *
- * @param   Body    instance   Instance of Body
- * @return  Void
- */
-function writeToStream(dest, instance) {
-	const body = instance.body;
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __nested_webpack_require_61680__) {
 
+"use strict";
 
-	if (body === null) {
-		// body is null
-		dest.end();
-	} else if (isBlob(body)) {
-		body.stream().pipe(dest);
-	} else if (Buffer.isBuffer(body)) {
-		// body is buffer
-		dest.write(body);
-		dest.end();
-	} else {
-		// body is stream
-		body.pipe(dest);
-	}
-}
 
-// expose Promise
-Body.Promise = global.Promise;
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.create = create;
+exports.find = find;
+exports.findMany = findMany;
+exports.findAll = findAll;
+exports.changesFeed = changesFeed;
+exports.update = update;
+exports.updateAttributes = updateAttributes;
+exports._delete = _delete;
 
-/**
- * headers.js
- *
- * Headers class offers convenient helpers
- */
+var _utils = __nested_webpack_require_61680__(1);
 
-const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
-const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
+var _doctypes = __nested_webpack_require_61680__(2);
 
-function validateName(name) {
-	name = `${name}`;
-	if (invalidTokenRegex.test(name) || name === '') {
-		throw new TypeError(`${name} is not a legal HTTP header name`);
-	}
-}
+var _fetch = __nested_webpack_require_61680__(0);
 
-function validateValue(value) {
-	value = `${value}`;
-	if (invalidHeaderCharRegex.test(value)) {
-		throw new TypeError(`${value} is not a legal HTTP header value`);
-	}
+var NOREV = 'stack-v2-no-rev';
+
+function create(cozy, doctype, attributes) {
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+    if (isV2) {
+      attributes.docType = doctype;
+    }
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, attributes._id);
+    var httpVerb = attributes._id ? 'PUT' : 'POST';
+    delete attributes._id;
+    return (0, _fetch.cozyFetchJSON)(cozy, httpVerb, path, attributes).then(function (resp) {
+      if (isV2) {
+        return find(cozy, doctype, resp._id);
+      } else {
+        return resp.data;
+      }
+    });
+  });
 }
 
-/**
- * Find the key in the map object given a header name.
- *
- * Returns undefined if not found.
- *
- * @param   String  name  Header name
- * @return  String|Undefined
- */
-function find(map, name) {
-	name = name.toLowerCase();
-	for (const key in map) {
-		if (key.toLowerCase() === name) {
-			return key;
-		}
-	}
-	return undefined;
+function find(cozy, doctype, id) {
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+
+    if (!id) {
+      return Promise.reject(new Error('Missing id parameter'));
+    }
+
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, id);
+    return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path).then(function (resp) {
+      if (isV2) {
+        return Object.assign(resp, { _rev: NOREV });
+      } else {
+        return resp;
+      }
+    });
+  });
 }
 
-const MAP = Symbol('map');
-class Headers {
-	/**
-  * Headers class
-  *
-  * @param   Object  headers  Response headers
-  * @return  Void
-  */
-	constructor() {
-		let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
+function findMany(cozy, doctype, ids) {
+  if (!(ids instanceof Array)) {
+    return Promise.reject(new Error('Parameter ids must be a non-empty array'));
+  }
+  if (ids.length === 0) {
+    // So users don't need to be defensive regarding the array content.
+    // This should not hide issues in user code since the result will be an
+    // empty object anyway.
+    return Promise.resolve({});
+  }
 
-		this[MAP] = Object.create(null);
+  return cozy.isV2().then(function (isV2) {
+    if (isV2) {
+      return Promise.reject(new Error('findMany is not available on v2'));
+    }
 
-		if (init instanceof Headers) {
-			const rawHeaders = init.raw();
-			const headerNames = Object.keys(rawHeaders);
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', {
+      include_docs: true
+    });
 
-			for (const headerName of headerNames) {
-				for (const value of rawHeaders[headerName]) {
-					this.append(headerName, value);
-				}
-			}
+    return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, { keys: ids }).then(function (resp) {
+      var docs = {};
 
-			return;
-		}
+      var _iteratorNormalCompletion = true;
+      var _didIteratorError = false;
+      var _iteratorError = undefined;
 
-		// We don't worry about converting prop to ByteString here as append()
-		// will handle it.
-		if (init == null) ; else if (typeof init === 'object') {
-			const method = init[Symbol.iterator];
-			if (method != null) {
-				if (typeof method !== 'function') {
-					throw new TypeError('Header pairs must be iterable');
-				}
+      try {
+        for (var _iterator = resp.rows[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+          var row = _step.value;
+          var key = row.key,
+              doc = row.doc,
+              error = row.error;
 
-				// sequence<sequence<ByteString>>
-				// Note: per spec we have to first exhaust the lists then process them
-				const pairs = [];
-				for (const pair of init) {
-					if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
-						throw new TypeError('Each header pair must be iterable');
-					}
-					pairs.push(Array.from(pair));
-				}
+          docs[key] = error ? { error: error } : { doc: doc };
+        }
+      } catch (err) {
+        _didIteratorError = true;
+        _iteratorError = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion && _iterator.return) {
+            _iterator.return();
+          }
+        } finally {
+          if (_didIteratorError) {
+            throw _iteratorError;
+          }
+        }
+      }
 
-				for (const pair of pairs) {
-					if (pair.length !== 2) {
-						throw new TypeError('Each header pair must be a name/value tuple');
-					}
-					this.append(pair[0], pair[1]);
-				}
-			} else {
-				// record<ByteString, ByteString>
-				for (const key of Object.keys(init)) {
-					const value = init[key];
-					this.append(key, value);
-				}
-			}
-		} else {
-			throw new TypeError('Provided initializer must be an object');
-		}
-	}
+      return docs;
+    }).catch(function (error) {
+      if (error.status !== 404) return Promise.reject(error);
 
-	/**
-  * Return combined header value given name
-  *
-  * @param   String  name  Header name
-  * @return  Mixed
-  */
-	get(name) {
-		name = `${name}`;
-		validateName(name);
-		const key = find(this[MAP], name);
-		if (key === undefined) {
-			return null;
-		}
+      // When no doc was ever created and the database does not exist yet,
+      // the response will be a 404 error.
+      var docs = {};
 
-		return this[MAP][key].join(', ');
-	}
+      var _iteratorNormalCompletion2 = true;
+      var _didIteratorError2 = false;
+      var _iteratorError2 = undefined;
 
-	/**
-  * Iterate over all headers
-  *
-  * @param   Function  callback  Executed for each item with parameters (value, name, thisArg)
-  * @param   Boolean   thisArg   `this` context for callback function
-  * @return  Void
-  */
-	forEach(callback) {
-		let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
+      try {
+        for (var _iterator2 = ids[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+          var id = _step2.value;
 
-		let pairs = getHeaders(this);
-		let i = 0;
-		while (i < pairs.length) {
-			var _pairs$i = pairs[i];
-			const name = _pairs$i[0],
-			      value = _pairs$i[1];
+          docs[id] = { error: error };
+        }
+      } catch (err) {
+        _didIteratorError2 = true;
+        _iteratorError2 = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion2 && _iterator2.return) {
+            _iterator2.return();
+          }
+        } finally {
+          if (_didIteratorError2) {
+            throw _iteratorError2;
+          }
+        }
+      }
 
-			callback.call(thisArg, value, name, this);
-			pairs = getHeaders(this);
-			i++;
-		}
-	}
+      return docs;
+    });
+  });
+}
 
-	/**
-  * Overwrite header values given name
-  *
-  * @param   String  name   Header name
-  * @param   String  value  Header value
-  * @return  Void
-  */
-	set(name, value) {
-		name = `${name}`;
-		value = `${value}`;
-		validateName(name);
-		validateValue(value);
-		const key = find(this[MAP], name);
-		this[MAP][key !== undefined ? key : name] = [value];
-	}
+function findAll(cozy, doctype) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { include_docs: true };
 
-	/**
-  * Append a value onto existing header
-  *
-  * @param   String  name   Header name
-  * @param   String  value  Header value
-  * @return  Void
-  */
-	append(name, value) {
-		name = `${name}`;
-		value = `${value}`;
-		validateName(name);
-		validateValue(value);
-		const key = find(this[MAP], name);
-		if (key !== undefined) {
-			this[MAP][key].push(value);
-		} else {
-			this[MAP][name] = [value];
-		}
-	}
+  return cozy.isV2().then(function (isV2) {
+    if (isV2) {
+      return Promise.reject(new Error('findAll is not available on v2'));
+    }
 
-	/**
-  * Check for header name existence
-  *
-  * @param   String   name  Header name
-  * @return  Boolean
-  */
-	has(name) {
-		name = `${name}`;
-		validateName(name);
-		return find(this[MAP], name) !== undefined;
-	}
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', options);
 
-	/**
-  * Delete all header values given name
-  *
-  * @param   String  name  Header name
-  * @return  Void
-  */
-	delete(name) {
-		name = `${name}`;
-		validateName(name);
-		const key = find(this[MAP], name);
-		if (key !== undefined) {
-			delete this[MAP][key];
-		}
-	}
+    return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, {}).then(function (resp) {
+      var docs = [];
 
-	/**
-  * Return raw headers (non-spec api)
-  *
-  * @return  Object
-  */
-	raw() {
-		return this[MAP];
-	}
+      var _iteratorNormalCompletion3 = true;
+      var _didIteratorError3 = false;
+      var _iteratorError3 = undefined;
 
-	/**
-  * Get an iterator on keys.
-  *
-  * @return  Iterator
-  */
-	keys() {
-		return createHeadersIterator(this, 'key');
-	}
+      try {
+        for (var _iterator3 = resp.rows[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+          var row = _step3.value;
+          var doc = row.doc;
+          // if not couchDB indexes
 
-	/**
-  * Get an iterator on values.
-  *
-  * @return  Iterator
-  */
-	values() {
-		return createHeadersIterator(this, 'value');
-	}
+          if (!doc._id.match(/_design\//)) docs.push(doc);
+        }
+      } catch (err) {
+        _didIteratorError3 = true;
+        _iteratorError3 = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion3 && _iterator3.return) {
+            _iterator3.return();
+          }
+        } finally {
+          if (_didIteratorError3) {
+            throw _iteratorError3;
+          }
+        }
+      }
 
-	/**
-  * Get an iterator on entries.
-  *
-  * This is the default iterator of the Headers object.
-  *
-  * @return  Iterator
-  */
-	[Symbol.iterator]() {
-		return createHeadersIterator(this, 'key+value');
-	}
+      return docs;
+    }).catch(function (error) {
+      // the _all_docs endpoint returns a 404 error if no document with the given
+      // doctype exists.
+      if (error.status === 404) return [];
+      throw error;
+    });
+  });
 }
-Headers.prototype.entries = Headers.prototype[Symbol.iterator];
 
-Object.defineProperty(Headers.prototype, Symbol.toStringTag, {
-	value: 'Headers',
-	writable: false,
-	enumerable: false,
-	configurable: true
-});
+function changesFeed(cozy, doctype, options) {
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, '_changes', options);
+    return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path);
+  });
+}
 
-Object.defineProperties(Headers.prototype, {
-	get: { enumerable: true },
-	forEach: { enumerable: true },
-	set: { enumerable: true },
-	append: { enumerable: true },
-	has: { enumerable: true },
-	delete: { enumerable: true },
-	keys: { enumerable: true },
-	values: { enumerable: true },
-	entries: { enumerable: true }
-});
+function update(cozy, doctype, doc, changes) {
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+    var _id = doc._id,
+        _rev = doc._rev;
 
-function getHeaders(headers) {
-	let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';
 
-	const keys = Object.keys(headers[MAP]).sort();
-	return keys.map(kind === 'key' ? function (k) {
-		return k.toLowerCase();
-	} : kind === 'value' ? function (k) {
-		return headers[MAP][k].join(', ');
-	} : function (k) {
-		return [k.toLowerCase(), headers[MAP][k].join(', ')];
-	});
+    if (!_id) {
+      return Promise.reject(new Error('Missing _id field in passed document'));
+    }
+
+    if (!isV2 && !_rev) {
+      return Promise.reject(new Error('Missing _rev field in passed document'));
+    }
+
+    if (isV2) {
+      changes = Object.assign({ _id: _id }, changes);
+    } else {
+      changes = Object.assign({ _id: _id, _rev: _rev }, changes);
+    }
+
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, _id);
+    return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, changes).then(function (resp) {
+      if (isV2) {
+        return find(cozy, doctype, _id);
+      } else {
+        return resp.data;
+      }
+    });
+  });
 }
 
-const INTERNAL = Symbol('internal');
+function updateAttributes(cozy, doctype, _id, changes) {
+  var tries = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 3;
 
-function createHeadersIterator(target, kind) {
-	const iterator = Object.create(HeadersIteratorPrototype);
-	iterator[INTERNAL] = {
-		target,
-		kind,
-		index: 0
-	};
-	return iterator;
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+    return find(cozy, doctype, _id).then(function (doc) {
+      return update(cozy, doctype, doc, Object.assign({ _id: _id }, doc, changes));
+    }).catch(function (err) {
+      if (tries > 0) {
+        return updateAttributes(cozy, doctype, _id, changes, tries - 1);
+      } else {
+        throw err;
+      }
+    });
+  });
 }
 
-const HeadersIteratorPrototype = Object.setPrototypeOf({
-	next() {
-		// istanbul ignore if
-		if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
-			throw new TypeError('Value of `this` is not a HeadersIterator');
-		}
+function _delete(cozy, doctype, doc) {
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+    var _id = doc._id,
+        _rev = doc._rev;
 
-		var _INTERNAL = this[INTERNAL];
-		const target = _INTERNAL.target,
-		      kind = _INTERNAL.kind,
-		      index = _INTERNAL.index;
 
-		const values = getHeaders(target, kind);
-		const len = values.length;
-		if (index >= len) {
-			return {
-				value: undefined,
-				done: true
-			};
-		}
+    if (!_id) {
+      return Promise.reject(new Error('Missing _id field in passed document'));
+    }
 
-		this[INTERNAL].index = index + 1;
+    if (!isV2 && !_rev) {
+      return Promise.reject(new Error('Missing _rev field in passed document'));
+    }
 
-		return {
-			value: values[index],
-			done: false
-		};
-	}
-}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
+    var query = isV2 ? null : { rev: _rev };
+    var path = (0, _utils.createPath)(cozy, isV2, doctype, _id, query);
+    return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', path).then(function (resp) {
+      if (isV2) {
+        return { id: _id, rev: NOREV };
+      } else {
+        return resp;
+      }
+    });
+  });
+}
 
-Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {
-	value: 'HeadersIterator',
-	writable: false,
-	enumerable: false,
-	configurable: true
+/***/ }),
+/* 14 */
+/***/ (function(module, exports, __nested_webpack_require_69980__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
 });
 
-/**
- * Export the Headers object in a form that Node.js can consume.
- *
- * @param   Headers  headers
- * @return  Object
- */
-function exportNodeCompatibleHeaders(headers) {
-	const obj = Object.assign({ __proto__: null }, headers[MAP]);
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
 
-	// http.request() only supports string as Host header. This hack makes
-	// specifying custom Host header possible.
-	const hostHeaderKey = find(headers[MAP], 'Host');
-	if (hostHeaderKey !== undefined) {
-		obj[hostHeaderKey] = obj[hostHeaderKey][0];
-	}
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
 
-	return obj;
-}
+exports.defineIndex = defineIndex;
+exports.query = query;
+exports.queryFiles = queryFiles;
+exports.parseSelector = parseSelector;
+exports.normalizeSelector = normalizeSelector;
+exports.makeMapReduceQuery = makeMapReduceQuery;
 
-/**
- * Create a Headers object from an object of headers, ignoring those that do
- * not conform to HTTP grammar productions.
- *
- * @param   Object  obj  Object of headers
- * @return  Headers
- */
-function createHeadersLenient(obj) {
-	const headers = new Headers();
-	for (const name of Object.keys(obj)) {
-		if (invalidTokenRegex.test(name)) {
-			continue;
-		}
-		if (Array.isArray(obj[name])) {
-			for (const val of obj[name]) {
-				if (invalidHeaderCharRegex.test(val)) {
-					continue;
-				}
-				if (headers[MAP][name] === undefined) {
-					headers[MAP][name] = [val];
-				} else {
-					headers[MAP][name].push(val);
-				}
-			}
-		} else if (!invalidHeaderCharRegex.test(obj[name])) {
-			headers[MAP][name] = [obj[name]];
-		}
-	}
-	return headers;
-}
+var _utils = __nested_webpack_require_69980__(1);
 
-const INTERNALS$1 = Symbol('Response internals');
+var _doctypes = __nested_webpack_require_69980__(2);
 
-// fix an issue where "STATUS_CODES" aren't a named export for node <10
-const STATUS_CODES = http__WEBPACK_IMPORTED_MODULE_1__.STATUS_CODES;
+var _fetch = __nested_webpack_require_69980__(0);
 
-/**
- * Response class
- *
- * @param   Stream  body  Readable stream
- * @param   Object  opts  Response options
- * @return  Void
- */
-class Response {
-	constructor() {
-		let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
-		let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+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; }
 
-		Body.call(this, body, opts);
+function defineIndex(cozy, doctype, fields) {
+  return cozy.isV2().then(function (isV2) {
+    doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype);
+    if (!Array.isArray(fields) || fields.length === 0) {
+      throw new Error('defineIndex fields should be a non-empty array');
+    }
+    if (isV2) {
+      return defineIndexV2(cozy, doctype, fields);
+    } else {
+      return defineIndexV3(cozy, doctype, fields);
+    }
+  });
+}
 
-		const status = opts.status || 200;
-		const headers = new Headers(opts.headers);
+function query(cozy, indexRef, options) {
+  return cozy.isV2().then(function (isV2) {
+    if (!indexRef) {
+      throw new Error('query should be passed the indexRef');
+    }
+    if (isV2) {
+      return queryV2(cozy, indexRef, options);
+    } else {
+      return queryV3(cozy, indexRef, options);
+    }
+  });
+}
 
-		if (body != null && !headers.has('Content-Type')) {
-			const contentType = extractContentType(body);
-			if (contentType) {
-				headers.append('Content-Type', contentType);
-			}
-		}
+function queryFiles(cozy, indexRef, options) {
+  var opts = getV3Options(indexRef, options);
+  return (0, _fetch.cozyFetchRawJSON)(cozy, 'POST', '/files/_find', opts).then(function (response) {
+    return options.wholeResponse ? response : response.docs;
+  });
+}
 
-		this[INTERNALS$1] = {
-			url: opts.url,
-			status,
-			statusText: opts.statusText || STATUS_CODES[status],
-			headers,
-			counter: opts.counter
-		};
-	}
+// Internals
 
-	get url() {
-		return this[INTERNALS$1].url || '';
-	}
+var VALUEOPERATORS = ['$eq', '$gt', '$gte', '$lt', '$lte'];
+var LOGICOPERATORS = ['$or', '$and', '$not'];
 
-	get status() {
-		return this[INTERNALS$1].status;
-	}
+/* eslint-disable */
+var MAP_TEMPLATE = function (doc) {
+  if (doc.docType.toLowerCase() === 'DOCTYPEPLACEHOLDER') {
+    emit(FIELDSPLACEHOLDER, doc);
+  }
+}.toString().replace(/ /g, '').replace(/\n/g, '');
+var COUCHDB_INFINITY = { '\uFFFF': '\uFFFF' };
+var COUCHDB_LOWEST = null;
+/* eslint-enable */
 
-	/**
-  * Convenience property representing if the request ended normally
-  */
-	get ok() {
-		return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;
-	}
+// defineIndexV2 is equivalent to defineIndex but only works for V2.
+// It transforms the index fields into a map reduce view.
+function defineIndexV2(cozy, doctype, fields) {
+  var indexName = 'by' + fields.map(capitalize).join('');
+  var indexDefinition = {
+    map: makeMapFunction(doctype, fields),
+    reduce: '_count'
+  };
+  var path = '/request/' + doctype + '/' + indexName + '/';
+  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, indexDefinition).then(function () {
+    return {
+      doctype: doctype,
+      type: 'mapreduce',
+      name: indexName,
+      fields: fields
+    };
+  });
+}
 
-	get redirected() {
-		return this[INTERNALS$1].counter > 0;
-	}
+function defineIndexV3(cozy, doctype, fields) {
+  var path = (0, _utils.createPath)(cozy, false, doctype, '_index');
+  var indexDefinition = { index: { fields: fields } };
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, indexDefinition).then(function (response) {
+    var indexResult = {
+      doctype: doctype,
+      type: 'mango',
+      name: response.id,
+      fields: fields
+    };
 
-	get statusText() {
-		return this[INTERNALS$1].statusText;
-	}
+    if (response.result === 'exists') return indexResult;
 
-	get headers() {
-		return this[INTERNALS$1].headers;
-	}
+    // indexes might not be usable right after being created; so we delay the resolving until they are
+    var selector = {};
+    selector[fields[0]] = { $gt: null };
 
-	/**
-  * Clone this response
-  *
-  * @return  Response
-  */
-	clone() {
-		return new Response(clone(this), {
-			url: this.url,
-			status: this.status,
-			statusText: this.statusText,
-			headers: this.headers,
-			ok: this.ok,
-			redirected: this.redirected
-		});
-	}
+    var opts = getV3Options(indexResult, { selector: selector });
+    var path = (0, _utils.createPath)(cozy, false, indexResult.doctype, '_find');
+    return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function () {
+      return indexResult;
+    }).catch(function () {
+      // one retry
+      return (0, _utils.sleep)(1000).then(function () {
+        return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts);
+      }).then(function () {
+        return indexResult;
+      }).catch(function () {
+        return (0, _utils.sleep)(500).then(function () {
+          return indexResult;
+        });
+      });
+    });
+  });
 }
 
-Body.mixIn(Response.prototype);
+// queryV2 is equivalent to query but only works for V2.
+// It transforms the query into a _views call using makeMapReduceQuery
+function queryV2(cozy, indexRef, options) {
+  if (indexRef.type !== 'mapreduce') {
+    throw new Error('query indexRef should be the return value of defineIndexV2');
+  }
+  if (options.fields) {
+    (0, _utils.warn)('query fields will be ignored on v2');
+  }
 
-Object.defineProperties(Response.prototype, {
-	url: { enumerable: true },
-	status: { enumerable: true },
-	ok: { enumerable: true },
-	redirected: { enumerable: true },
-	statusText: { enumerable: true },
-	headers: { enumerable: true },
-	clone: { enumerable: true }
-});
+  var path = '/request/' + indexRef.doctype + '/' + indexRef.name + '/';
+  var opts = makeMapReduceQuery(indexRef, options);
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) {
+    return response.map(function (r) {
+      return r.value;
+    });
+  });
+}
 
-Object.defineProperty(Response.prototype, Symbol.toStringTag, {
-	value: 'Response',
-	writable: false,
-	enumerable: false,
-	configurable: true
-});
+// queryV3 is equivalent to query but only works for V3
+function queryV3(cozy, indexRef, options) {
+  var opts = getV3Options(indexRef, options);
 
-const INTERNALS$2 = Symbol('Request internals');
+  var path = (0, _utils.createPath)(cozy, false, indexRef.doctype, '_find');
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) {
+    return options.wholeResponse ? response : response.docs;
+  });
+}
 
-// fix an issue where "format", "parse" aren't a named export for node <10
-const parse_url = url__WEBPACK_IMPORTED_MODULE_2__.parse;
-const format_url = url__WEBPACK_IMPORTED_MODULE_2__.format;
+function getV3Options(indexRef, options) {
+  if (indexRef.type !== 'mango') {
+    throw new Error('indexRef should be the return value of defineIndexV3');
+  }
 
-const streamDestructionSupported = 'destroy' in stream__WEBPACK_IMPORTED_MODULE_0__.Readable.prototype;
+  var opts = {
+    use_index: indexRef.name,
+    fields: options.fields,
+    selector: options.selector,
+    limit: options.limit,
+    skip: options.skip,
+    since: options.since,
+    sort: options.sort
+  };
 
-/**
- * Check if a value is an instance of Request.
- *
- * @param   Mixed   input
- * @return  Boolean
- */
-function isRequest(input) {
-	return typeof input === 'object' && typeof input[INTERNALS$2] === 'object';
+  if (options.descending) {
+    opts.sort = indexRef.fields.map(function (f) {
+      return _defineProperty({}, f, 'desc');
+    });
+  }
+
+  return opts;
 }
 
-function isAbortSignal(signal) {
-	const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);
-	return !!(proto && proto.constructor.name === 'AbortSignal');
+// misc
+function capitalize(name) {
+  return name.charAt(0).toUpperCase() + name.slice(1);
 }
 
-/**
- * Request class
- *
- * @param   Mixed   input  Url or Request instance
- * @param   Object  init   Custom options
- * @return  Void
- */
-class Request {
-	constructor(input) {
-		let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+function makeMapFunction(doctype, fields) {
+  fields = '[' + fields.map(function (name) {
+    return 'doc.' + name;
+  }).join(',') + ']';
 
-		let parsedURL;
+  return MAP_TEMPLATE.replace('DOCTYPEPLACEHOLDER', doctype.toLowerCase()).replace('FIELDSPLACEHOLDER', fields);
+}
 
-		// normalize input
-		if (!isRequest(input)) {
-			if (input && input.href) {
-				// in order to support Node.js' Url objects; though WHATWG's URL objects
-				// will fall into this branch also (since their `toString()` will return
-				// `href` property anyway)
-				parsedURL = parse_url(input.href);
-			} else {
-				// coerce input to a string before attempting to parse
-				parsedURL = parse_url(`${input}`);
-			}
-			input = {};
-		} else {
-			parsedURL = parse_url(input.url);
-		}
+// parseSelector takes a mango selector and returns it as an array of filter
+// a filter is [path, operator, value] array
+// a path is an array of field names
+// This function is only exported so it can be unit tested.
+// Example :
+// parseSelector({"test":{"deep": {"$gt": 3}}})
+// [[['test', 'deep'], '$gt', 3 ]]
+function parseSelector(selector) {
+  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
+  var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '$eq';
 
-		let method = init.method || input.method || 'GET';
-		method = method.toUpperCase();
+  if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) !== 'object') {
+    return [[path, operator, selector]];
+  }
 
-		if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {
-			throw new TypeError('Request with GET/HEAD method cannot have body');
-		}
+  var keys = Object.keys(selector);
+  if (keys.length === 0) {
+    throw new Error('empty selector');
+  } else {
+    return keys.reduce(function (acc, k) {
+      if (LOGICOPERATORS.indexOf(k) !== -1) {
+        throw new Error('cozy-client-js does not support mango logic ops');
+      } else if (VALUEOPERATORS.indexOf(k) !== -1) {
+        return acc.concat(parseSelector(selector[k], path, k));
+      } else {
+        return acc.concat(parseSelector(selector[k], path.concat(k), '$eq'));
+      }
+    }, []);
+  }
+}
 
-		let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;
+// normalizeSelector takes a mango selector and returns it as an object
+// normalized.
+// This function is only exported so it can be unit tested.
+// Example :
+// parseSelector({"test":{"deep": {"$gt": 3}}})
+// {"test.deep": {"$gt": 3}}
+function normalizeSelector(selector) {
+  var filters = parseSelector(selector);
+  return filters.reduce(function (acc, filter) {
+    var _filter = _slicedToArray(filter, 3),
+        path = _filter[0],
+        op = _filter[1],
+        value = _filter[2];
 
-		Body.call(this, inputBody, {
-			timeout: init.timeout || input.timeout || 0,
-			size: init.size || input.size || 0
-		});
+    var field = path.join('.');
+    acc[field] = acc[field] || {};
+    acc[field][op] = value;
+    return acc;
+  }, {});
+}
 
-		const headers = new Headers(init.headers || input.headers || {});
+// applySelector takes the normalized selector for the current field
+// and append the proper values to opts.startkey, opts.endkey
+function applySelector(selector, opts) {
+  var value = selector['$eq'];
+  var lower = COUCHDB_LOWEST;
+  var upper = COUCHDB_INFINITY;
+  var inclusiveEnd = void 0;
 
-		if (inputBody != null && !headers.has('Content-Type')) {
-			const contentType = extractContentType(inputBody);
-			if (contentType) {
-				headers.append('Content-Type', contentType);
-			}
-		}
+  if (value) {
+    opts.startkey.push(value);
+    opts.endkey.push(value);
+    return false;
+  }
 
-		let signal = isRequest(input) ? input.signal : null;
-		if ('signal' in init) signal = init.signal;
+  value = selector['$gt'];
+  if (value) {
+    throw new Error('operator $gt (strict greater than) not supported');
+  }
 
-		if (signal != null && !isAbortSignal(signal)) {
-			throw new TypeError('Expected signal to be an instanceof AbortSignal');
-		}
+  value = selector['$gte'];
+  if (value) {
+    lower = value;
+  }
 
-		this[INTERNALS$2] = {
-			method,
-			redirect: init.redirect || input.redirect || 'follow',
-			headers,
-			parsedURL,
-			signal
-		};
+  value = selector['$lte'];
+  if (value) {
+    upper = value;
+    inclusiveEnd = true;
+  }
 
-		// node-fetch-only options
-		this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
-		this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
-		this.counter = init.counter || input.counter || 0;
-		this.agent = init.agent || input.agent;
-	}
+  value = selector['$lt'];
+  if (value) {
+    upper = value;
+    inclusiveEnd = false;
+  }
 
-	get method() {
-		return this[INTERNALS$2].method;
-	}
+  opts.startkey.push(lower);
+  opts.endkey.push(upper);
+  if (inclusiveEnd !== undefined) opts.inclusive_end = inclusiveEnd;
+  return true;
+}
 
-	get url() {
-		return format_url(this[INTERNALS$2].parsedURL);
-	}
+// makeMapReduceQuery takes a mango query and generate _views call parameters
+// to obtain same results depending on fields in the passed indexRef.
+function makeMapReduceQuery(indexRef, query) {
+  var mrquery = {
+    startkey: [],
+    endkey: [],
+    reduce: false
+  };
+  var firstFreeValueField = null;
+  var normalizedSelector = normalizeSelector(query.selector);
 
-	get headers() {
-		return this[INTERNALS$2].headers;
-	}
+  indexRef.fields.forEach(function (field) {
+    var selector = normalizedSelector[field];
+
+    if (selector && firstFreeValueField != null) {
+      throw new Error('Selector on field ' + field + ', but not on ' + firstFreeValueField + ' which is higher in index fields.');
+    } else if (selector) {
+      selector.used = true;
+      var isFreeValue = applySelector(selector, mrquery);
+      if (isFreeValue) firstFreeValueField = field;
+    } else if (firstFreeValueField == null) {
+      firstFreeValueField = field;
+      mrquery.endkey.push(COUCHDB_INFINITY);
+    }
+  });
 
-	get redirect() {
-		return this[INTERNALS$2].redirect;
-	}
+  Object.keys(normalizedSelector).forEach(function (field) {
+    if (!normalizedSelector[field].used) {
+      throw new Error('Cant apply selector on ' + field + ', it is not in index');
+    }
+  });
 
-	get signal() {
-		return this[INTERNALS$2].signal;
-	}
+  if (query.descending) {
+    mrquery = {
+      descending: true,
+      reduce: false,
+      startkey: mrquery.endkey,
+      endkey: mrquery.startkey,
+      inclusive_end: mrquery.inclusive_end
+    };
+  }
 
-	/**
-  * Clone this request
-  *
-  * @return  Request
-  */
-	clone() {
-		return new Request(this);
-	}
+  return mrquery;
 }
 
-Body.mixIn(Request.prototype);
-
-Object.defineProperty(Request.prototype, Symbol.toStringTag, {
-	value: 'Request',
-	writable: false,
-	enumerable: false,
-	configurable: true
-});
+/***/ }),
+/* 15 */
+/***/ (function(module, exports, __nested_webpack_require_80935__) {
 
-Object.defineProperties(Request.prototype, {
-	method: { enumerable: true },
-	url: { enumerable: true },
-	headers: { enumerable: true },
-	redirect: { enumerable: true },
-	clone: { enumerable: true },
-	signal: { enumerable: true }
-});
+"use strict";
 
-/**
- * Convert a Request to Node.js http request options.
- *
- * @param   Request  A Request instance
- * @return  Object   The options object to be passed to http.request
- */
-function getNodeRequestOptions(request) {
-	const parsedURL = request[INTERNALS$2].parsedURL;
-	const headers = new Headers(request[INTERNALS$2].headers);
 
-	// fetch step 1.3
-	if (!headers.has('Accept')) {
-		headers.set('Accept', '*/*');
-	}
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.TRASH_DIR_ID = exports.ROOT_DIR_ID = undefined;
 
-	// Basic fetch
-	if (!parsedURL.protocol || !parsedURL.hostname) {
-		throw new TypeError('Only absolute URLs are supported');
-	}
+var _regenerator = __nested_webpack_require_80935__(4);
 
-	if (!/^https?:$/.test(parsedURL.protocol)) {
-		throw new TypeError('Only HTTP(S) protocols are supported');
-	}
+var _regenerator2 = _interopRequireDefault(_regenerator);
 
-	if (request.signal && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable && !streamDestructionSupported) {
-		throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');
-	}
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
 
-	// HTTP-network-or-cache fetch steps 2.4-2.7
-	let contentLengthValue = null;
-	if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
-		contentLengthValue = '0';
-	}
-	if (request.body != null) {
-		const totalBytes = getTotalBytes(request);
-		if (typeof totalBytes === 'number') {
-			contentLengthValue = String(totalBytes);
-		}
-	}
-	if (contentLengthValue) {
-		headers.set('Content-Length', contentLengthValue);
-	}
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* global Blob, File */
 
-	// HTTP-network-or-cache fetch step 2.11
-	if (!headers.has('User-Agent')) {
-		headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');
-	}
 
-	// HTTP-network-or-cache fetch step 2.15
-	if (request.compress && !headers.has('Accept-Encoding')) {
-		headers.set('Accept-Encoding', 'gzip,deflate');
-	}
+var doUpload = function () {
+  var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, data, method, path, options) {
+    var isBuffer, isFile, isBlob, isStream, isString, _ref2, contentType, contentLength, checksum, createdAt, updatedAt, executable, lastModifiedDate, ifMatch, metadata, sourceAccount, sourceAccountIdentifier, signal, finalpath, metadataId, headers;
 
-	let agent = request.agent;
-	if (typeof agent === 'function') {
-		agent = agent(parsedURL);
-	}
+    return _regenerator2.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            if (data) {
+              _context.next = 2;
+              break;
+            }
 
-	if (!headers.has('Connection') && !agent) {
-		headers.set('Connection', 'close');
-	}
+            throw new Error('missing data argument');
 
-	// HTTP-network fetch step 4.2
-	// chunked encoding is handled by Node.js
+          case 2:
 
-	return Object.assign({}, parsedURL, {
-		method: request.method,
-		headers: exportNodeCompatibleHeaders(headers),
-		agent
-	});
-}
+            // transform any ArrayBufferView to ArrayBuffer
+            if (data.buffer && data.buffer instanceof ArrayBuffer) {
+              data = data.buffer;
+            }
 
-/**
- * abort-error.js
- *
- * AbortError interface for cancelled requests
- */
+            isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer;
+            isFile = typeof File !== 'undefined' && data instanceof File;
+            isBlob = typeof Blob !== 'undefined' && data instanceof Blob;
+            isStream = data.readable === true && typeof data.pipe === 'function';
+            isString = typeof data === 'string';
 
-/**
- * Create AbortError instance
- *
- * @param   String      message      Error message for human
- * @return  AbortError
- */
-function AbortError(message) {
-  Error.call(this, message);
+            if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) {
+              _context.next = 10;
+              break;
+            }
 
-  this.type = 'aborted';
-  this.message = message;
+            throw new Error('invalid data type');
 
-  // hide custom error implementation details from end-users
-  Error.captureStackTrace(this, this.constructor);
-}
+          case 10:
+            _ref2 = options || {}, contentType = _ref2.contentType, contentLength = _ref2.contentLength, checksum = _ref2.checksum, createdAt = _ref2.createdAt, updatedAt = _ref2.updatedAt, executable = _ref2.executable, lastModifiedDate = _ref2.lastModifiedDate, ifMatch = _ref2.ifMatch, metadata = _ref2.metadata, sourceAccount = _ref2.sourceAccount, sourceAccountIdentifier = _ref2.sourceAccountIdentifier, signal = _ref2.signal;
 
-AbortError.prototype = Object.create(Error.prototype);
-AbortError.prototype.constructor = AbortError;
-AbortError.prototype.name = 'AbortError';
+            if (!contentType) {
+              if (isBuffer) {
+                contentType = contentTypeOctetStream;
+              } else if (isFile) {
+                contentType = data.type || getFileTypeFromName(data.name.toLowerCase()) || contentTypeOctetStream;
+                if (!lastModifiedDate) {
+                  lastModifiedDate = data.lastModifiedDate;
+                }
+              } else if (isBlob) {
+                contentType = data.type || contentTypeOctetStream;
+              } else if (isStream) {
+                contentType = contentTypeOctetStream;
+              } else if (typeof data === 'string') {
+                contentType = 'text/plain';
+              }
+            }
 
-// fix an issue where "PassThrough", "resolve" aren't a named export for node <10
-const PassThrough$1 = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough;
-const resolve_url = url__WEBPACK_IMPORTED_MODULE_2__.resolve;
+            if (lastModifiedDate && typeof lastModifiedDate === 'string') {
+              lastModifiedDate = new Date(lastModifiedDate);
+            }
+            if (!createdAt) {
+              createdAt = lastModifiedDate;
+            }
+            if (!updatedAt) {
+              updatedAt = lastModifiedDate;
+            }
 
-/**
- * Fetch function
- *
- * @param   Mixed    url   Absolute url or Request instance
- * @param   Object   opts  Fetch options
- * @return  Promise
- */
-function fetch(url, opts) {
+            if (!executable) {
+              executable = false;
+            }
 
-	// allow custom promise
-	if (!fetch.Promise) {
-		throw new Error('native promise missing, set fetch.Promise to your favorite alternative');
-	}
+            finalpath = path;
 
-	Body.Promise = fetch.Promise;
+            if (!metadata) {
+              _context.next = 22;
+              break;
+            }
 
-	// wrap http.request into fetch
-	return new fetch.Promise(function (resolve, reject) {
-		// build request object
-		const request = new Request(url, opts);
-		const options = getNodeRequestOptions(request);
+            _context.next = 20;
+            return sendMetadata(cozy, metadata);
 
-		const send = (options.protocol === 'https:' ? https__WEBPACK_IMPORTED_MODULE_3__ : http__WEBPACK_IMPORTED_MODULE_1__).request;
-		const signal = request.signal;
+          case 20:
+            metadataId = _context.sent;
 
-		let response = null;
+            if (metadataId) {
+              finalpath = addQuerystringParam(finalpath, 'MetadataID', metadataId);
+            }
 
-		const abort = function abort() {
-			let error = new AbortError('The user aborted a request.');
-			reject(error);
-			if (request.body && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable) {
-				request.body.destroy(error);
-			}
-			if (!response || !response.body) return;
-			response.body.emit('error', error);
-		};
+          case 22:
+            if (sourceAccount) {
+              finalpath = addQuerystringParam(finalpath, 'SourceAccount', sourceAccount);
+            }
+            if (sourceAccountIdentifier) {
+              finalpath = addQuerystringParam(finalpath, 'SourceAccountIdentifier', sourceAccountIdentifier);
+            }
+            if (createdAt) {
+              finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt));
+            }
+            if (updatedAt) {
+              finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt));
+            }
+            if (executable) {
+              finalpath = addQuerystringParam(finalpath, 'Executable', executable);
+            }
 
-		if (signal && signal.aborted) {
-			abort();
-			return;
-		}
+            headers = {
+              'Content-Type': contentType
+            };
 
-		const abortAndFinalize = function abortAndFinalize() {
-			abort();
-			finalize();
-		};
+            if (contentLength) {
+              headers['Content-Length'] = String(contentLength);
+              finalpath = addQuerystringParam(finalpath, 'Size', String(contentLength));
+            }
+            if (checksum) headers['Content-MD5'] = checksum;
+            if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString();
+            if (ifMatch) headers['If-Match'] = ifMatch;
 
-		// send request
-		const req = send(options);
-		let reqTimeout;
+            return _context.abrupt('return', (0, _fetch.cozyFetch)(cozy, finalpath, {
+              method: method,
+              headers: headers,
+              body: data,
+              signal: signal
+            }).then(function (res) {
+              var json = res.json();
+              if (!res.ok) {
+                return json.then(function (err) {
+                  throw err;
+                });
+              } else {
+                return json.then(_jsonapi2.default);
+              }
+            }));
 
-		if (signal) {
-			signal.addEventListener('abort', abortAndFinalize);
-		}
+          case 33:
+          case 'end':
+            return _context.stop();
+        }
+      }
+    }, _callee, this);
+  }));
 
-		function finalize() {
-			req.abort();
-			if (signal) signal.removeEventListener('abort', abortAndFinalize);
-			clearTimeout(reqTimeout);
-		}
+  return function doUpload(_x, _x2, _x3, _x4, _x5) {
+    return _ref.apply(this, arguments);
+  };
+}();
 
-		if (request.timeout) {
-			req.once('socket', function (socket) {
-				reqTimeout = setTimeout(function () {
-					reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
-					finalize();
-				}, request.timeout);
-			});
-		}
+var sendMetadata = function () {
+  var _ref3 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, metadata) {
+    var result;
+    return _regenerator2.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            _context2.next = 2;
+            return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/upload/metadata', {
+              data: { type: 'io.cozy.files.metadata', attributes: metadata }
+            });
 
-		req.on('error', function (err) {
-			reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
-			finalize();
-		});
+          case 2:
+            result = _context2.sent;
+            return _context2.abrupt('return', result && result._id ? result._id : false);
 
-		req.on('response', function (res) {
-			clearTimeout(reqTimeout);
+          case 4:
+          case 'end':
+            return _context2.stop();
+        }
+      }
+    }, _callee2, this);
+  }));
 
-			const headers = createHeadersLenient(res.headers);
+  return function sendMetadata(_x6, _x7) {
+    return _ref3.apply(this, arguments);
+  };
+}();
 
-			// HTTP fetch step 5
-			if (fetch.isRedirect(res.statusCode)) {
-				// HTTP fetch step 5.2
-				const location = headers.get('Location');
+exports.create = create;
+exports.createDirectory = createDirectory;
+exports.createDirectoryByPath = createDirectoryByPath;
+exports.updateById = updateById;
+exports.updateAttributesById = updateAttributesById;
+exports.updateAttributesByPath = updateAttributesByPath;
+exports.trashById = trashById;
+exports.statById = statById;
+exports.statByPath = statByPath;
+exports.downloadById = downloadById;
+exports.downloadByPath = downloadByPath;
+exports.getDownloadLinkByPath = getDownloadLinkByPath;
+exports.getDownloadLinkById = getDownloadLinkById;
+exports.getFilePath = getFilePath;
+exports.getCollectionShareLink = getCollectionShareLink;
+exports.getArchiveLinkByPaths = getArchiveLinkByPaths;
+exports.getArchiveLinkByIds = getArchiveLinkByIds;
+exports.listTrash = listTrash;
+exports.clearTrash = clearTrash;
+exports.restoreById = restoreById;
+exports.destroyById = destroyById;
 
-				// HTTP fetch step 5.3
-				const locationURL = location === null ? null : resolve_url(request.url, location);
+var _fetch = __nested_webpack_require_80935__(0);
 
-				// HTTP fetch step 5.5
-				switch (request.redirect) {
-					case 'error':
-						reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
-						finalize();
-						return;
-					case 'manual':
-						// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
-						if (locationURL !== null) {
-							// handle corrupted header
-							try {
-								headers.set('Location', locationURL);
-							} catch (err) {
-								// istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request
-								reject(err);
-							}
-						}
-						break;
-					case 'follow':
-						// HTTP-redirect fetch step 2
-						if (locationURL === null) {
-							break;
-						}
+var _jsonapi = __nested_webpack_require_80935__(7);
 
-						// HTTP-redirect fetch step 5
-						if (request.counter >= request.follow) {
-							reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
-							finalize();
-							return;
-						}
+var _jsonapi2 = _interopRequireDefault(_jsonapi);
 
-						// HTTP-redirect fetch step 6 (counter increment)
-						// Create a new Request object.
-						const requestOpts = {
-							headers: new Headers(request.headers),
-							follow: request.follow,
-							counter: request.counter + 1,
-							agent: request.agent,
-							compress: request.compress,
-							method: request.method,
-							body: request.body,
-							signal: request.signal,
-							timeout: request.timeout,
-							size: request.size
-						};
+var _doctypes = __nested_webpack_require_80935__(2);
 
-						// HTTP-redirect fetch step 9
-						if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
-							reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
-							finalize();
-							return;
-						}
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-						// HTTP-redirect fetch step 11
-						if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
-							requestOpts.method = 'GET';
-							requestOpts.body = undefined;
-							requestOpts.headers.delete('content-length');
-						}
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
-						// HTTP-redirect fetch step 15
-						resolve(fetch(new Request(locationURL, requestOpts)));
-						finalize();
-						return;
-				}
-			}
+// global variables
+var ROOT_DIR_ID = exports.ROOT_DIR_ID = 'io.cozy.files.root-dir';
+var TRASH_DIR_ID = exports.TRASH_DIR_ID = 'io.cozy.files.trash-dir';
 
-			// prepare response
-			res.once('end', function () {
-				if (signal) signal.removeEventListener('abort', abortAndFinalize);
-			});
-			let body = res.pipe(new PassThrough$1());
+var contentTypeOctetStream = 'application/octet-stream';
 
-			const response_options = {
-				url: request.url,
-				status: res.statusCode,
-				statusText: res.statusMessage,
-				headers: headers,
-				size: request.size,
-				timeout: request.timeout,
-				counter: request.counter
-			};
+function sanitizeFileName(name) {
+  return name && name.trim();
+}
 
-			// HTTP-network fetch step 12.1.1.3
-			const codings = headers.get('Content-Encoding');
+function getFileTypeFromName(name) {
+  if (/\.heic$/i.test(name)) return 'image/heic';else if (/\.heif$/i.test(name)) return 'image/heif';else return null;
+}
 
-			// HTTP-network fetch step 12.1.1.4: handle content codings
+function dateString(date) {
+  return (typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object' ? date.toISOString() : date;
+}
 
-			// in following scenarios we ignore compression support
-			// 1. compression support is disabled
-			// 2. HEAD request
-			// 3. no Content-Encoding header
-			// 4. no content response (204)
-			// 5. content not modified response (304)
-			if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {
-				response = new Response(body, response_options);
-				resolve(response);
-				return;
-			}
+function create(cozy, data, options) {
+  var _ref4 = options || {},
+      name = _ref4.name,
+      dirID = _ref4.dirID,
+      noSanitize = _ref4.noSanitize;
 
-			// For Node v6+
-			// Be less strict when decoding compressed responses, since sometimes
-			// servers send slightly invalid responses that are still accepted
-			// by common browsers.
-			// Always using Z_SYNC_FLUSH is what cURL does.
-			const zlibOptions = {
-				flush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH,
-				finishFlush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH
-			};
+  // handle case where data is a file and contains the name
 
-			// for gzip
-			if (codings == 'gzip' || codings == 'x-gzip') {
-				body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createGunzip(zlibOptions));
-				response = new Response(body, response_options);
-				resolve(response);
-				return;
-			}
 
-			// for deflate
-			if (codings == 'deflate' || codings == 'x-deflate') {
-				// handle the infamous raw deflate response from old servers
-				// a hack for old IIS and Apache servers
-				const raw = res.pipe(new PassThrough$1());
-				raw.once('data', function (chunk) {
-					// see http://stackoverflow.com/questions/37519828
-					if ((chunk[0] & 0x0F) === 0x08) {
-						body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflate());
-					} else {
-						body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflateRaw());
-					}
-					response = new Response(body, response_options);
-					resolve(response);
-				});
-				return;
-			}
+  if (!name && typeof data.name === 'string') {
+    name = data.name;
+  }
 
-			// for br
-			if (codings == 'br' && typeof zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress === 'function') {
-				body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress());
-				response = new Response(body, response_options);
-				resolve(response);
-				return;
-			}
+  if (!noSanitize) {
+    name = sanitizeFileName(name);
+  }
 
-			// otherwise, use response as-is
-			response = new Response(body, response_options);
-			resolve(response);
-		});
+  if (typeof name !== 'string' || name === '') {
+    throw new Error('missing name argument');
+  }
 
-		writeToStream(req, request);
-	});
+  var path = '/files/' + encodeURIComponent(dirID || '');
+  var query = '?Name=' + encodeURIComponent(name) + '&Type=file';
+  return doUpload(cozy, data, 'POST', '' + path + query, options);
 }
-/**
- * Redirect code matching
- *
- * @param   Number   code  Status code
- * @return  Boolean
- */
-fetch.isRedirect = function (code) {
-	return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
-};
 
-// expose Promise
-fetch.Promise = global.Promise;
+function createDirectory(cozy, options) {
+  var _ref5 = options || {},
+      name = _ref5.name,
+      dirID = _ref5.dirID,
+      createdAt = _ref5.createdAt,
+      updatedAt = _ref5.updatedAt,
+      lastModifiedDate = _ref5.lastModifiedDate,
+      noSanitize = _ref5.noSanitize;
 
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (fetch);
+  if (!noSanitize) {
+    name = sanitizeFileName(name);
+  }
 
+  if (typeof name !== 'string' || name === '') {
+    throw new Error('missing name argument');
+  }
 
+  if (lastModifiedDate && typeof lastModifiedDate === 'string') {
+    lastModifiedDate = new Date(lastModifiedDate);
+  }
+  if (!createdAt) {
+    createdAt = lastModifiedDate;
+  }
+  if (!updatedAt) {
+    updatedAt = lastModifiedDate;
+  }
 
-/***/ }),
-/* 482 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+  var path = '/files/' + encodeURIComponent(dirID || '');
+  var query = '?Name=' + encodeURIComponent(name) + '&Type=directory';
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(483);
-/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(484);
-/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(immediate__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(250);
-/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(485);
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(487);
-/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(spark_md5__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(488);
-/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_5__);
-/* harmony import */ var vuvuzela__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(493);
+  var finalpath = '' + path + query;
+  if (createdAt) {
+    finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt));
+  }
+  if (updatedAt) {
+    finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt));
+  }
 
+  var headers = {};
+  if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString();
 
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', finalpath, undefined, {
+    headers: headers
+  });
+}
 
+function getDirectoryOrCreate(cozy, name, parentDirectory, options) {
+  if (parentDirectory && !parentDirectory.attributes) throw new Error('Malformed parent directory');
 
+  var _ref6 = options || {},
+      noSanitize = _ref6.noSanitize;
 
+  if (!noSanitize) {
+    name = sanitizeFileName(name);
+  }
 
+  var path = (parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path) + '/' + name;
 
+  return cozy.files.statByPath(path || '/').catch(function (error) {
+    var parsedError = JSON.parse(error.message);
+    var errors = parsedError.errors;
+    if (errors && errors.length && errors[0].status === '404') {
+      return cozy.files.createDirectory({
+        name: name,
+        dirID: parentDirectory && parentDirectory._id
+      });
+    }
 
-function isBinaryObject(object) {
-  return (typeof ArrayBuffer !== 'undefined' && object instanceof ArrayBuffer) ||
-    (typeof Blob !== 'undefined' && object instanceof Blob);
+    throw errors;
+  });
 }
 
-function cloneArrayBuffer(buff) {
-  if (typeof buff.slice === 'function') {
-    return buff.slice(0);
-  }
-  // IE10-11 slice() polyfill
-  var target = new ArrayBuffer(buff.byteLength);
-  var targetArray = new Uint8Array(target);
-  var sourceArray = new Uint8Array(buff);
-  targetArray.set(sourceArray);
-  return target;
-}
+function createDirectoryByPath(cozy, path, offline, options) {
+  var parts = path.split('/').filter(function (part) {
+    return part !== '';
+  });
 
-function cloneBinaryObject(object) {
-  if (object instanceof ArrayBuffer) {
-    return cloneArrayBuffer(object);
-  }
-  var size = object.size;
-  var type = object.type;
-  // Blob
-  if (typeof object.slice === 'function') {
-    return object.slice(0, size, type);
-  }
-  // PhantomJS slice() replacement
-  return object.webkitSlice(0, size, type);
-}
+  var rootDirectoryPromise = cozy.files.statById(ROOT_DIR_ID, offline);
 
-// most of this is borrowed from lodash.isPlainObject:
-// https://github.com/fis-components/lodash.isplainobject/
-// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js
+  return parts.length ? parts.reduce(function (parentDirectoryPromise, part) {
+    return parentDirectoryPromise.then(function (parentDirectory) {
+      return getDirectoryOrCreate(cozy, part, parentDirectory, options);
+    });
+  }, rootDirectoryPromise) : rootDirectoryPromise;
+}
 
-var funcToString = Function.prototype.toString;
-var objectCtorString = funcToString.call(Object);
+function updateById(cozy, id, data, options) {
+  return doUpload(cozy, data, 'PUT', '/files/' + encodeURIComponent(id), options);
+}
 
-function isPlainObject(value) {
-  var proto = Object.getPrototypeOf(value);
-  /* istanbul ignore if */
-  if (proto === null) { // not sure when this happens, but I guess it can
-    return true;
+function doUpdateAttributes(cozy, attrs, path, options) {
+  if (!attrs || (typeof attrs === 'undefined' ? 'undefined' : _typeof(attrs)) !== 'object') {
+    throw new Error('missing attrs argument');
   }
-  var Ctor = proto.constructor;
-  return (typeof Ctor == 'function' &&
-    Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
-}
 
-function clone(object) {
-  var newObject;
-  var i;
-  var len;
+  var _ref7 = options || {},
+      ifMatch = _ref7.ifMatch,
+      noSanitize = _ref7.noSanitize;
 
-  if (!object || typeof object !== 'object') {
-    return object;
+  var name = attrs.name;
+  if (!noSanitize) {
+    name = sanitizeFileName(name);
   }
 
-  if (Array.isArray(object)) {
-    newObject = [];
-    for (i = 0, len = object.length; i < len; i++) {
-      newObject[i] = clone(object[i]);
+  var body = {
+    data: {
+      attributes: Object.assign({}, attrs, {
+        name: name
+      })
     }
-    return newObject;
-  }
+  };
+  return (0, _fetch.cozyFetchJSON)(cozy, 'PATCH', path, body, {
+    headers: {
+      'If-Match': ifMatch || ''
+    }
+  });
+}
 
-  // special case: to avoid inconsistencies between IndexedDB
-  // and other backends, we automatically stringify Dates
-  if (object instanceof Date) {
-    return object.toISOString();
-  }
+function updateAttributesById(cozy, id, attrs, options) {
+  return doUpdateAttributes(cozy, attrs, '/files/' + encodeURIComponent(id), options);
+}
 
-  if (isBinaryObject(object)) {
-    return cloneBinaryObject(object);
-  }
+function updateAttributesByPath(cozy, path, attrs, options) {
+  return doUpdateAttributes(cozy, attrs, '/files/metadata?Path=' + encodeURIComponent(path), options);
+}
 
-  if (!isPlainObject(object)) {
-    return object; // don't clone objects like Workers
+function trashById(cozy, id, options) {
+  if (typeof id !== 'string' || id === '') {
+    throw new Error('missing id argument');
   }
 
-  newObject = {};
-  for (i in object) {
-    /* istanbul ignore else */
-    if (Object.prototype.hasOwnProperty.call(object, i)) {
-      var value = clone(object[i]);
-      if (typeof value !== 'undefined') {
-        newObject[i] = value;
-      }
-    }
-  }
-  return newObject;
-}
+  var _ref8 = options || {},
+      ifMatch = _ref8.ifMatch;
 
-function once(fun) {
-  var called = false;
-  return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
-    /* istanbul ignore if */
-    if (called) {
-      // this is a smoke test and should never actually happen
-      throw new Error('once called more than once');
-    } else {
-      called = true;
-      fun.apply(this, args);
+  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/' + encodeURIComponent(id), undefined, {
+    headers: {
+      'If-Match': ifMatch || ''
     }
   });
 }
 
-function toPromise(func) {
-  //create the function we will be returning
-  return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
-    // Clone arguments
-    args = clone(args);
-    var self = this;
-    // if the last argument is a function, assume its a callback
-    var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
-    var promise = new Promise(function (fulfill, reject) {
-      var resp;
-      try {
-        var callback = once(function (err, mesg) {
-          if (err) {
-            reject(err);
-          } else {
-            fulfill(mesg);
-          }
+function statById(cozy, id) {
+  var offline = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
+  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+  if (offline && cozy.offline.hasDatabase(_doctypes.DOCTYPE_FILES)) {
+    var db = cozy.offline.getDatabase(_doctypes.DOCTYPE_FILES);
+    return Promise.all([db.get(id), db.find(Object.assign({ selector: { dir_id: id } }, options))]).then(function (_ref9) {
+      var _ref10 = _slicedToArray(_ref9, 2),
+          doc = _ref10[0],
+          children = _ref10[1];
+
+      if (id === ROOT_DIR_ID) {
+        children.docs = children.docs.filter(function (doc) {
+          return doc._id !== TRASH_DIR_ID;
         });
-        // create a callback for this invocation
-        // apply the function in the orig context
-        args.push(callback);
-        resp = func.apply(self, args);
-        if (resp && typeof resp.then === 'function') {
-          fulfill(resp);
-        }
-      } catch (e) {
-        reject(e);
       }
+      children = sortFiles(children.docs.map(function (doc) {
+        return addIsDir(toJsonApi(cozy, doc));
+      }));
+      return addIsDir(toJsonApi(cozy, doc, children));
     });
-    // if there is a callback, call it back
-    if (usedCB) {
-      promise.then(function (result) {
-        usedCB(null, result);
-      }, usedCB);
-    }
-    return promise;
-  });
+  }
+  var query = Object.keys(options).length === 0 ? '' : '?' + encodePageOptions(options);
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/' + encodeURIComponent(id) + query).then(addIsDir);
 }
 
-function logApiCall(self, name, args) {
-  /* istanbul ignore if */
-  if (self.constructor.listeners('debug').length) {
-    var logArgs = ['api', self.name, name];
-    for (var i = 0; i < args.length - 1; i++) {
-      logArgs.push(args[i]);
-    }
-    self.constructor.emit('debug', logArgs);
+function statByPath(cozy, path) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/metadata?Path=' + encodeURIComponent(path)).then(addIsDir);
+}
 
-    // override the callback itself to log the response
-    var origCallback = args[args.length - 1];
-    args[args.length - 1] = function (err, res) {
-      var responseArgs = ['api', self.name, name];
-      responseArgs = responseArgs.concat(
-        err ? ['error', err] : ['success', res]
-      );
-      self.constructor.emit('debug', responseArgs);
-      origCallback(err, res);
-    };
-  }
+function downloadById(cozy, id) {
+  return (0, _fetch.cozyFetch)(cozy, '/files/download/' + encodeURIComponent(id));
 }
 
-function adapterFun(name, callback) {
-  return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
-    if (this._closed) {
-      return Promise.reject(new Error('database is closed'));
-    }
-    if (this._destroyed) {
-      return Promise.reject(new Error('database is destroyed'));
-    }
-    var self = this;
-    logApiCall(self, name, args);
-    if (!this.taskqueue.isReady) {
-      return new Promise(function (fulfill, reject) {
-        self.taskqueue.addTask(function (failed) {
-          if (failed) {
-            reject(failed);
-          } else {
-            fulfill(self[name].apply(self, args));
-          }
-        });
-      });
-    }
-    return callback.apply(this, args);
-  }));
+function downloadByPath(cozy, path) {
+  return (0, _fetch.cozyFetch)(cozy, '/files/download?Path=' + encodeURIComponent(path));
 }
 
-function mangle(key) {
-  return '$' + key;
+function extractResponseLinkRelated(res) {
+  var href = res.links && res.links.related;
+  if (!href) throw new Error('No related link in server response');
+  return href;
 }
-function unmangle(key) {
-  return key.substring(1);
+
+function getDownloadLinkByPath(cozy, path) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Path=' + encodeURIComponent(path)).then(extractResponseLinkRelated);
 }
-function Map$1() {
-  this._store = {};
+
+function getDownloadLinkById(cozy, id) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Id=' + encodeURIComponent(id)).then(extractResponseLinkRelated);
 }
-Map$1.prototype.get = function (key) {
-  var mangled = mangle(key);
-  return this._store[mangled];
-};
-Map$1.prototype.set = function (key, value) {
-  var mangled = mangle(key);
-  this._store[mangled] = value;
-  return true;
-};
-Map$1.prototype.has = function (key) {
-  var mangled = mangle(key);
-  return mangled in this._store;
-};
-Map$1.prototype.delete = function (key) {
-  var mangled = mangle(key);
-  var res = mangled in this._store;
-  delete this._store[mangled];
-  return res;
-};
-Map$1.prototype.forEach = function (cb) {
-  var keys = Object.keys(this._store);
-  for (var i = 0, len = keys.length; i < len; i++) {
-    var key = keys[i];
-    var value = this._store[key];
-    key = unmangle(key);
-    cb(value, key);
-  }
-};
-Object.defineProperty(Map$1.prototype, 'size', {
-  get: function () {
-    return Object.keys(this._store).length;
-  }
-});
 
-function Set$1(array) {
-  this._store = new Map$1();
+function getFilePath(cozy) {
+  var file = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+  var folder = arguments[2];
 
-  // init with an array
-  if (array && Array.isArray(array)) {
-    for (var i = 0, len = array.length; i < len; i++) {
-      this.add(array[i]);
-    }
+  if (!folder || !folder.attributes) {
+    throw Error('Folder should be valid with an attributes.path property');
   }
+
+  var folderPath = folder.attributes.path.endsWith('/') ? folder.attributes.path : folder.attributes.path + '/';
+
+  return '' + folderPath + file.name;
 }
-Set$1.prototype.add = function (key) {
-  return this._store.set(key, true);
-};
-Set$1.prototype.has = function (key) {
-  return this._store.has(key);
-};
-Set$1.prototype.forEach = function (cb) {
-  this._store.forEach(function (value, key) {
-    cb(key);
-  });
-};
-Object.defineProperty(Set$1.prototype, 'size', {
-  get: function () {
-    return this._store.size;
-  }
-});
 
-/* global Map,Set,Symbol */
-// Based on https://kangax.github.io/compat-table/es6/ we can sniff out
-// incomplete Map/Set implementations which would otherwise cause our tests to fail.
-// Notably they fail in IE11 and iOS 8.4, which this prevents.
-function supportsMapAndSet() {
-  if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') {
-    return false;
+function getCollectionShareLink(cozy, id, collectionType) {
+  if (!id) {
+    return Promise.reject(Error('An id should be provided to create a share link'));
   }
-  var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
-  return prop && 'get' in prop && Map[Symbol.species] === Map;
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/permissions?codes=email', {
+    data: {
+      type: 'io.cozy.permissions',
+      attributes: {
+        permissions: {
+          files: {
+            type: 'io.cozy.files',
+            verbs: ['GET'],
+            values: [id],
+            selector: 'referenced_by'
+          },
+          collection: {
+            type: collectionType,
+            verbs: ['GET'],
+            values: [id]
+          }
+        }
+      }
+    }
+  }).then(function (data) {
+    return {
+      sharecode: 'sharecode=' + data.attributes.codes.email,
+      id: 'id=' + id
+    };
+  });
 }
 
-// based on https://github.com/montagejs/collections
-
-var ExportedSet;
-var ExportedMap;
+function getArchiveLinkByPaths(cozy, paths) {
+  var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files';
 
-{
-  if (supportsMapAndSet()) { // prefer built-in Map/Set
-    ExportedSet = Set;
-    ExportedMap = Map;
-  } else { // fall back to our polyfill
-    ExportedSet = Set$1;
-    ExportedMap = Map$1;
-  }
+  var archive = {
+    type: 'io.cozy.archives',
+    attributes: {
+      name: name,
+      files: paths
+    }
+  };
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated);
 }
-
-// like underscore/lodash _.pick()
-function pick(obj, arr) {
-  var res = {};
-  for (var i = 0, len = arr.length; i < len; i++) {
-    var prop = arr[i];
-    if (prop in obj) {
-      res[prop] = obj[prop];
+
+function getArchiveLinkByIds(cozy, ids) {
+  var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files';
+
+  var archive = {
+    type: 'io.cozy.archives',
+    attributes: {
+      name: name,
+      ids: ids
     }
-  }
-  return res;
+  };
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated);
 }
 
-// Most browsers throttle concurrent requests at 6, so it's silly
-// to shim _bulk_get by trying to launch potentially hundreds of requests
-// and then letting the majority time out. We can handle this ourselves.
-var MAX_NUM_CONCURRENT_REQUESTS = 6;
+function listTrash(cozy) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/trash');
+}
 
-function identityFunction(x) {
-  return x;
+function clearTrash(cozy) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash');
 }
 
-function formatResultForOpenRevsGet(result) {
-  return [{
-    ok: result
-  }];
+function restoreById(cozy, id) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/trash/' + encodeURIComponent(id));
 }
 
-// shim for P/CouchDB adapters that don't directly implement _bulk_get
-function bulkGet(db, opts, callback) {
-  var requests = opts.docs;
+function destroyById(cozy, id, options) {
+  var _ref11 = options || {},
+      ifMatch = _ref11.ifMatch;
 
-  // consolidate into one request per doc if possible
-  var requestsById = new ExportedMap();
-  requests.forEach(function (request) {
-    if (requestsById.has(request.id)) {
-      requestsById.get(request.id).push(request);
-    } else {
-      requestsById.set(request.id, [request]);
+  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash/' + encodeURIComponent(id), undefined, {
+    headers: {
+      'If-Match': ifMatch || ''
     }
   });
+}
 
-  var numDocs = requestsById.size;
-  var numDone = 0;
-  var perDocResults = new Array(numDocs);
+function addIsDir(obj) {
+  obj.isDir = obj.attributes.type === 'directory';
+  return obj;
+}
 
-  function collapseResultsAndFinish() {
-    var results = [];
-    perDocResults.forEach(function (res) {
-      res.docs.forEach(function (info) {
-        results.push({
-          id: res.id,
-          docs: [info]
-        });
-      });
-    });
-    callback(null, {results: results});
+function encodePageOptions(options) {
+  var opts = [];
+  for (var name in options) {
+    opts.push('page[' + encodeURIComponent(name) + ']=' + encodeURIComponent(options[name]));
   }
+  return opts.join('&');
+}
 
-  function checkDone() {
-    if (++numDone === numDocs) {
-      collapseResultsAndFinish();
-    }
-  }
+function toJsonApi(cozy, doc) {
+  var contents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
 
-  function gotResult(docIndex, id, docs) {
-    perDocResults[docIndex] = {id: id, docs: docs};
-    checkDone();
-  }
+  var clone = JSON.parse(JSON.stringify(doc));
+  delete clone._id;
+  delete clone._rev;
+  return {
+    _id: doc._id,
+    _rev: doc._rev,
+    _type: _doctypes.DOCTYPE_FILES,
+    attributes: clone,
+    relationships: {
+      contents: {
+        data: contents,
+        meta: {
+          count: contents.length
+        }
+      }
+    },
+    relations: function relations(name) {
+      if (name === 'contents') {
+        return contents;
+      }
+    }
+  };
+}
 
-  var allRequests = [];
-  requestsById.forEach(function (value, key) {
-    allRequests.push(key);
+function sortFiles(allFiles) {
+  var folders = allFiles.filter(function (f) {
+    return f.attributes.type === 'directory';
+  });
+  var files = allFiles.filter(function (f) {
+    return f.attributes.type !== 'directory';
   });
+  var sort = function sort(files) {
+    return files.sort(function (a, b) {
+      return a.attributes.name.localeCompare(b.attributes.name);
+    });
+  };
+  return sort(folders).concat(sort(files));
+}
 
-  var i = 0;
+function addQuerystringParam(path, key, value) {
+  return '' + path + (path.includes('?') ? '&' : '?') + key + '=' + value;
+}
 
-  function nextBatch() {
+/***/ }),
+/* 16 */
+/***/ (function(module, exports, __nested_webpack_require_101343__) {
 
-    if (i >= allRequests.length) {
-      return;
-    }
+"use strict";
 
-    var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length);
-    var batch = allRequests.slice(i, upTo);
-    processBatch(batch, i);
-    i += batch.length;
-  }
 
-  function processBatch(batch, offset) {
-    batch.forEach(function (docId, j) {
-      var docIdx = offset + j;
-      var docRequests = requestsById.get(docId);
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
 
-      // just use the first request as the "template"
-      // TODO: The _bulk_get API allows for more subtle use cases than this,
-      // but for now it is unlikely that there will be a mix of different
-      // "atts_since" or "attachments" in the same request, since it's just
-      // replicate.js that is using this for the moment.
-      // Also, atts_since is aspirational, since we don't support it yet.
-      var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
-      docOpts.open_revs = docRequests.map(function (request) {
-        // rev is optional, open_revs disallowed
-        return request.rev;
-      });
+var _regenerator = __nested_webpack_require_101343__(4);
 
-      // remove falsey / undefined revisions
-      docOpts.open_revs = docOpts.open_revs.filter(identityFunction);
+var _regenerator2 = _interopRequireDefault(_regenerator);
 
-      var formatResult = identityFunction;
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
 
-      if (docOpts.open_revs.length === 0) {
-        delete docOpts.open_revs;
+exports.start = start;
 
-        // when fetching only the "winning" leaf,
-        // transform the result so it looks like an open_revs
-        // request
-        formatResult = formatResultForOpenRevsGet;
-      }
+var _helpers = __nested_webpack_require_101343__(5);
 
-      // globally-supplied options
-      ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) {
-        if (param in opts) {
-          docOpts[param] = opts[param];
-        }
-      });
-      db.get(docId, docOpts, function (err, res) {
-        var result;
-        /* istanbul ignore if */
-        if (err) {
-          result = [{error: err}];
-        } else {
-          result = formatResult(res);
-        }
-        gotResult(docIdx, docId, result);
-        nextBatch();
-      });
-    });
-  }
+var _ = __nested_webpack_require_101343__(8);
 
-  nextBatch();
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-}
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
-var hasLocal;
+var intentClass = 'coz-intent';
 
-try {
-  localStorage.setItem('_pouch_check_localstorage', 1);
-  hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
-} catch (e) {
-  hasLocal = false;
+function hideIntentIframe(iframe) {
+  iframe.style.display = 'none';
 }
 
-function hasLocalStorage() {
-  return hasLocal;
+function showIntentFrame(iframe) {
+  iframe.style.display = 'block';
 }
 
-// Custom nextTick() shim for browsers. In node, this will just be process.nextTick(). We
-
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
+function buildIntentIframe(intent, element, url) {
+  var document = element.ownerDocument;
+  if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element'));
 
-/* istanbul ignore next */
-function attachBrowserEvents(self) {
-  if (hasLocalStorage()) {
-    addEventListener("storage", function (e) {
-      self.emit(e.key);
-    });
-  }
+  var iframe = document.createElement('iframe');
+  // TODO: implement 'title' attribute
+  iframe.setAttribute('id', 'intent-' + intent._id);
+  iframe.setAttribute('src', url);
+  iframe.classList.add(intentClass);
+  return iframe;
 }
 
-function Changes() {
-  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
-  this._listeners = {};
+function injectIntentIframe(intent, element, url, options) {
+  var onReadyCallback = options.onReadyCallback;
 
-  attachBrowserEvents(this);
+  var iframe = buildIntentIframe(intent, element, url, options.onReadyCallback);
+  // if callback provided for when iframe is loaded
+  if (typeof onReadyCallback === 'function') iframe.onload = onReadyCallback;
+  element.appendChild(iframe);
+  iframe.focus();
+  return iframe;
 }
-Changes.prototype.addListener = function (dbName, id, db, opts) {
-  /* istanbul ignore if */
-  if (this._listeners[id]) {
-    return;
-  }
-  var self = this;
-  var inprogress = false;
-  function eventFunction() {
-    /* istanbul ignore if */
-    if (!self._listeners[id]) {
-      return;
-    }
-    if (inprogress) {
-      inprogress = 'waiting';
-      return;
-    }
-    inprogress = true;
-    var changesOpts = pick(opts, [
-      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
-      'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
-    ]);
 
-    /* istanbul ignore next */
-    function onError() {
-      inprogress = false;
-    }
+// inject iframe for service in given element
+function connectIntentIframe(cozy, iframe, element, intent, data) {
+  var _this = this;
 
-    db.changes(changesOpts).on('change', function (c) {
-      if (c.seq > opts.since && !opts.cancelled) {
-        opts.since = c.seq;
-        opts.onChange(c);
-      }
-    }).on('complete', function () {
-      if (inprogress === 'waiting') {
-        immediate__WEBPACK_IMPORTED_MODULE_1___default()(eventFunction);
-      }
-      inprogress = false;
-    }).on('error', onError);
-  }
-  this._listeners[id] = eventFunction;
-  this.on(dbName, eventFunction);
-};
+  var compose = function () {
+    var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, action, doctype, data) {
+      var intent, doc;
+      return _regenerator2.default.wrap(function _callee$(_context) {
+        while (1) {
+          switch (_context.prev = _context.next) {
+            case 0:
+              _context.next = 2;
+              return (0, _.create)(cozy, action, doctype, data);
 
-Changes.prototype.removeListener = function (dbName, id) {
-  /* istanbul ignore if */
-  if (!(id in this._listeners)) {
-    return;
-  }
-  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype.removeListener.call(this, dbName,
-    this._listeners[id]);
-  delete this._listeners[id];
-};
+            case 2:
+              intent = _context.sent;
 
+              hideIntentIframe(iframe);
+              _context.next = 6;
+              return start(cozy, intent, element, _extends({}, data, {
+                exposeIntentFrameRemoval: false
+              }));
 
-/* istanbul ignore next */
-Changes.prototype.notifyLocalWindows = function (dbName) {
-  //do a useless change on a storage thing
-  //in order to get other windows's listeners to activate
-  if (hasLocalStorage()) {
-    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
-  }
-};
+            case 6:
+              doc = _context.sent;
 
-Changes.prototype.notify = function (dbName) {
-  this.emit(dbName);
-  this.notifyLocalWindows(dbName);
-};
+              showIntentFrame(iframe);
+              return _context.abrupt('return', doc);
 
-function guardedConsole(method) {
-  /* istanbul ignore else */
-  if (typeof console !== 'undefined' && typeof console[method] === 'function') {
-    var args = Array.prototype.slice.call(arguments, 1);
-    console[method].apply(console, args);
-  }
-}
+            case 9:
+            case 'end':
+              return _context.stop();
+          }
+        }
+      }, _callee, this);
+    }));
 
-function randomNumber(min, max) {
-  var maxTimeout = 600000; // Hard-coded default of 10 minutes
-  min = parseInt(min, 10) || 0;
-  max = parseInt(max, 10);
-  if (max !== max || max <= min) {
-    max = (min || 1) << 1; //doubling
-  } else {
-    max = max + 1;
-  }
-  // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout
-  if (max > maxTimeout) {
-    min = maxTimeout >> 1; // divide by two
-    max = maxTimeout;
-  }
-  var ratio = Math.random();
-  var range = max - min;
+    return function compose(_x, _x2, _x3, _x4) {
+      return _ref.apply(this, arguments);
+    };
+  }();
 
-  return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
-}
+  var document = element.ownerDocument;
+  if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element'));
 
-function defaultBackOff(min) {
-  var max = 0;
-  if (!min) {
-    max = 2000;
-  }
-  return randomNumber(min, max);
-}
+  var window = document.defaultView;
+  if (!window) return Promise.reject(new Error('Cannot retrieve window object from document'));
 
-// designed to give info to browser users, who are disturbed
-// when they see http errors in the console
-function explainError(status, str) {
-  guardedConsole('info', 'The above ' + status + ' is totally normal. ' + str);
-}
+  // Keeps only http://domain:port/
+  var serviceOrigin = iframe.src.split('/', 3).join('/');
 
-var assign;
-{
-  if (typeof Object.assign === 'function') {
-    assign = Object.assign;
-  } else {
-    // lite Object.assign polyfill based on
-    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
-    assign = function (target) {
-      var to = Object(target);
+  return new Promise(function (resolve, reject) {
+    var handshaken = false;
+    var messageHandler = function () {
+      var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(event) {
+        var eventType, _event$data, action, doctype, _data, doc, removeIntentFrame;
 
-      for (var index = 1; index < arguments.length; index++) {
-        var nextSource = arguments[index];
+        return _regenerator2.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                if (!(event.origin !== serviceOrigin)) {
+                  _context2.next = 2;
+                  break;
+                }
 
-        if (nextSource != null) { // Skip over if undefined or null
-          for (var nextKey in nextSource) {
-            // Avoid bugs when hasOwnProperty is shadowed
-            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
-              to[nextKey] = nextSource[nextKey];
-            }
-          }
-        }
-      }
-      return to;
-    };
-  }
-}
+                return _context2.abrupt('return');
 
-var $inject_Object_assign = assign;
+              case 2:
+                eventType = event.data.type;
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchError, Error);
+                if (!(eventType === 'load')) {
+                  _context2.next = 6;
+                  break;
+                }
 
-function PouchError(status, error, reason) {
-  Error.call(this, reason);
-  this.status = status;
-  this.name = error;
-  this.message = reason;
-  this.error = true;
-}
+                // Safari 9.1 (At least) send a MessageEvent when the iframe loads,
+                // making the handshake fails.
+                console.warn && console.warn('Cozy Client ignored MessageEvent having data.type `load`.');
+                return _context2.abrupt('return');
 
-PouchError.prototype.toString = function () {
-  return JSON.stringify({
-    status: this.status,
-    name: this.name,
-    message: this.message,
-    reason: this.reason
-  });
-};
+              case 6:
+                if (!(eventType === 'intent-' + intent._id + ':ready')) {
+                  _context2.next = 9;
+                  break;
+                }
 
-var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect.");
-var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'");
-var MISSING_DOC = new PouchError(404, 'not_found', 'missing');
-var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict');
-var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string');
-var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts');
-var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.');
-var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open');
-var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error');
-var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid');
-var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid');
-var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid');
-var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member');
-var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request');
-var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object');
-var DB_MISSING = new PouchError(404, 'not_found', 'Database not found');
-var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown');
-var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown');
-var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown');
-var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function');
-var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format');
-var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.');
-var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found');
-var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid');
+                handshaken = true;
+                return _context2.abrupt('return', event.source.postMessage(data, event.origin));
 
-function createError(error, reason) {
-  function CustomPouchError(reason) {
-    // inherit error properties from our parent error manually
-    // so as to allow proper JSON parsing.
-    /* jshint ignore:start */
-    for (var p in error) {
-      if (typeof error[p] !== 'function') {
-        this[p] = error[p];
-      }
-    }
-    /* jshint ignore:end */
-    if (reason !== undefined) {
-      this.reason = reason;
-    }
-  }
-  CustomPouchError.prototype = PouchError.prototype;
-  return new CustomPouchError(reason);
-}
+              case 9:
+                if (!(handshaken && eventType === 'intent-' + intent._id + ':resize')) {
+                  _context2.next = 13;
+                  break;
+                }
 
-function generateErrorFromResponse(err) {
+                ;['width', 'height', 'maxWidth', 'maxHeight'].forEach(function (prop) {
+                  if (event.data.transition) element.style.transition = event.data.transition;
+                  if (event.data.dimensions[prop]) element.style[prop] = event.data.dimensions[prop] + 'px';
+                });
 
-  if (typeof err !== 'object') {
-    var data = err;
-    err = UNKNOWN_ERROR;
-    err.data = data;
-  }
+                return _context2.abrupt('return', true);
 
-  if ('error' in err && err.error === 'conflict') {
-    err.name = 'conflict';
-    err.status = 409;
-  }
+              case 13:
+                if (!(handshaken && eventType === 'intent-' + intent._id + ':compose')) {
+                  _context2.next = 19;
+                  break;
+                }
 
-  if (!('name' in err)) {
-    err.name = err.error || 'unknown';
-  }
+                // Let start to name `type` as `doctype`, as `event.data` already have a `type` attribute.
+                _event$data = event.data, action = _event$data.action, doctype = _event$data.doctype, _data = _event$data.data;
+                _context2.next = 17;
+                return compose(cozy, action, doctype, _data);
 
-  if (!('status' in err)) {
-    err.status = 500;
-  }
+              case 17:
+                doc = _context2.sent;
+                return _context2.abrupt('return', event.source.postMessage(doc, event.origin));
 
-  if (!('message' in err)) {
-    err.message = err.message || err.reason;
-  }
+              case 19:
 
-  return err;
-}
+                window.removeEventListener('message', messageHandler);
 
-function tryFilter(filter, doc, req) {
-  try {
-    return !filter(doc, req);
-  } catch (err) {
-    var msg = 'Filter function threw: ' + err.toString();
-    return createError(BAD_REQUEST, msg);
-  }
-}
+                removeIntentFrame = function removeIntentFrame() {
+                  // check if the parent node has not been already removed from the DOM
+                  iframe.parentNode && iframe.parentNode.removeChild(iframe);
+                };
 
-function filterChange(opts) {
-  var req = {};
-  var hasFilter = opts.filter && typeof opts.filter === 'function';
-  req.query = opts.query_params;
+                if (!(handshaken && eventType === 'intent-' + intent._id + ':exposeFrameRemoval')) {
+                  _context2.next = 23;
+                  break;
+                }
 
-  return function filter(change) {
-    if (!change.doc) {
-      // CSG sends events on the changes feed that don't have documents,
-      // this hack makes a whole lot of existing code robust.
-      change.doc = {};
-    }
+                return _context2.abrupt('return', resolve({ removeIntentFrame: removeIntentFrame, doc: event.data.document }));
 
-    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+              case 23:
 
-    if (typeof filterReturn === 'object') {
-      return filterReturn;
-    }
+                removeIntentFrame();
 
-    if (filterReturn) {
-      return false;
-    }
+                if (!(eventType === 'intent-' + intent._id + ':error')) {
+                  _context2.next = 26;
+                  break;
+                }
 
-    if (!opts.include_docs) {
-      delete change.doc;
-    } else if (!opts.attachments) {
-      for (var att in change.doc._attachments) {
-        /* istanbul ignore else */
-        if (change.doc._attachments.hasOwnProperty(att)) {
-          change.doc._attachments[att].stub = true;
-        }
-      }
-    }
-    return true;
-  };
-}
+                return _context2.abrupt('return', reject(_helpers.errorSerializer.deserialize(event.data.error)));
 
-function flatten(arrs) {
-  var res = [];
-  for (var i = 0, len = arrs.length; i < len; i++) {
-    res = res.concat(arrs[i]);
-  }
-  return res;
-}
+              case 26:
+                if (!(handshaken && eventType === 'intent-' + intent._id + ':cancel')) {
+                  _context2.next = 28;
+                  break;
+                }
 
-// shim for Function.prototype.name,
+                return _context2.abrupt('return', resolve(null));
 
-// Determine id an ID is valid
-//   - invalid IDs begin with an underescore that does not begin '_design' or
-//     '_local'
-//   - any other string value is a valid id
-// Returns the specific error object for each case
-function invalidIdError(id) {
-  var err;
-  if (!id) {
-    err = createError(MISSING_ID);
-  } else if (typeof id !== 'string') {
-    err = createError(INVALID_ID);
-  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
-    err = createError(RESERVED_ID);
-  }
-  if (err) {
-    throw err;
-  }
-}
+              case 28:
+                if (!(handshaken && eventType === 'intent-' + intent._id + ':done')) {
+                  _context2.next = 30;
+                  break;
+                }
 
-// Checks if a PouchDB object is "remote" or not. This is
+                return _context2.abrupt('return', resolve(event.data.document));
 
-function isRemote(db) {
-  if (typeof db._remote === 'boolean') {
-    return db._remote;
-  }
-  /* istanbul ignore next */
-  if (typeof db.type === 'function') {
-    guardedConsole('warn',
-      'db.type() is deprecated and will be removed in ' +
-      'a future version of PouchDB');
-    return db.type() === 'http';
-  }
-  /* istanbul ignore next */
-  return false;
-}
+              case 30:
+                if (handshaken) {
+                  _context2.next = 32;
+                  break;
+                }
 
-function listenerCount(ee, type) {
-  return 'listenerCount' in ee ? ee.listenerCount(type) :
-                                 events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.listenerCount(ee, type);
-}
+                return _context2.abrupt('return', reject(new Error('Unexpected handshake message from intent service')));
 
-function parseDesignDocFunctionName(s) {
-  if (!s) {
-    return null;
-  }
-  var parts = s.split('/');
-  if (parts.length === 2) {
-    return parts;
-  }
-  if (parts.length === 1) {
-    return [s, s];
-  }
-  return null;
-}
+              case 32:
+              case 'end':
+                return _context2.stop();
+            }
+          }
+        }, _callee2, _this);
+      }));
 
-function normalizeDesignDocFunctionName(s) {
-  var normalized = parseDesignDocFunctionName(s);
-  return normalized ? normalized.join('/') : null;
-}
+      return function messageHandler(_x5) {
+        return _ref2.apply(this, arguments);
+      };
+    }();
 
-// originally parseUri 1.2.2, now patched by us
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
-    "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
-var qName ="queryKey";
-var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
+    window.addEventListener('message', messageHandler);
+  });
+}
 
-// use the "loose" parser
-/* eslint maxlen: 0, no-useless-escape: 0 */
-var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+function start(cozy, intent, element) {
+  var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+  var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
 
-function parseUri(str) {
-  var m = parser.exec(str);
-  var uri = {};
-  var i = 14;
+  var service = (0, _helpers.pickService)(intent, options.filterServices);
 
-  while (i--) {
-    var key = keys[i];
-    var value = m[i] || "";
-    var encoded = ['user', 'password'].indexOf(key) !== -1;
-    uri[key] = encoded ? decodeURIComponent(value) : value;
+  if (!service) {
+    throw new Error('Unable to find a service');
   }
 
-  uri[qName] = {};
-  uri[keys[12]].replace(qParser, function ($0, $1, $2) {
-    if ($1) {
-      uri[qName][$1] = $2;
-    }
-  });
+  var iframe = injectIntentIframe(intent, element, service.href, options);
 
-  return uri;
+  return connectIntentIframe(cozy, iframe, element, intent, data, options.onReadyCallback);
 }
 
-// Based on https://github.com/alexdavid/scope-eval v0.0.3
-// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js)
-// This is basically just a wrapper around new Function()
+/***/ }),
+/* 17 */
+/***/ (function(module, exports, __nested_webpack_require_110507__) {
 
-function scopeEval(source, scope) {
-  var keys = [];
-  var values = [];
-  for (var key in scope) {
-    if (scope.hasOwnProperty(key)) {
-      keys.push(key);
-      values.push(scope[key]);
-    }
-  }
-  keys.push(source);
-  return Function.apply(null, keys).apply(null, values);
-}
+"use strict";
 
-// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
-// the diffFun tells us what delta to apply to the doc.  it either returns
-// the doc, or false if it doesn't need to do an update after all
-function upsert(db, docId, diffFun) {
-  return new Promise(function (fulfill, reject) {
-    db.get(docId, function (err, doc) {
-      if (err) {
-        /* istanbul ignore next */
-        if (err.status !== 404) {
-          return reject(err);
-        }
-        doc = {};
-      }
 
-      // the user might change the _rev, so save it for posterity
-      var docRev = doc._rev;
-      var newDoc = diffFun(doc);
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.start = start;
 
-      if (!newDoc) {
-        // if the diffFun returns falsy, we short-circuit as
-        // an optimization
-        return fulfill({updated: false, rev: docRev});
-      }
+var _fetch = __nested_webpack_require_110507__(0);
 
-      // users aren't allowed to modify these values,
-      // so reset them here
-      newDoc._id = docId;
-      newDoc._rev = docRev;
-      fulfill(tryAndPut(db, newDoc, diffFun));
-    });
-  });
-}
+var _helpers = __nested_webpack_require_110507__(5);
 
-function tryAndPut(db, doc, diffFun) {
-  return db.put(doc).then(function (res) {
-    return {
-      updated: true,
-      rev: res.rev
+function listenClientData(intent, window) {
+  return new Promise(function (resolve) {
+    var messageEventListener = function messageEventListener(event) {
+      if (event.origin !== intent.attributes.client) return;
+
+      window.removeEventListener('message', messageEventListener);
+      resolve(event.data);
     };
-  }, function (err) {
-    /* istanbul ignore next */
-    if (err.status !== 409) {
-      throw err;
-    }
-    return upsert(db, doc._id, diffFun);
+
+    window.addEventListener('message', messageEventListener);
+    window.parent.postMessage({
+      type: 'intent-' + intent._id + ':ready'
+    }, intent.attributes.client);
   });
 }
 
-var thisAtob = function (str) {
-  return atob(str);
-};
-
-var thisBtoa = function (str) {
-  return btoa(str);
-};
-
-// Abstracts constructing a Blob object, so it also works in older
-// browsers that don't support the native Blob constructor (e.g.
-// old QtWebKit versions, Android < 4.4).
-function createBlob(parts, properties) {
-  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
-  parts = parts || [];
-  properties = properties || {};
-  try {
-    return new Blob(parts, properties);
-  } catch (e) {
-    if (e.name !== "TypeError") {
-      throw e;
-    }
-    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
-                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
-                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
-                  WebKitBlobBuilder;
-    var builder = new Builder();
-    for (var i = 0; i < parts.length; i += 1) {
-      builder.append(parts[i]);
-    }
-    return builder.getBlob(properties.type);
+// maximize the height of an element
+function maximize(element) {
+  if (element && element.style) {
+    element.style.height = '100%';
   }
 }
 
-// From http://stackoverflow.com/questions/14967647/ (continues on next line)
-// encode-decode-image-with-base64-breaks-image (2013-04-21)
-function binaryStringToArrayBuffer(bin) {
-  var length = bin.length;
-  var buf = new ArrayBuffer(length);
-  var arr = new Uint8Array(buf);
-  for (var i = 0; i < length; i++) {
-    arr[i] = bin.charCodeAt(i);
+function start(cozy, intentId, serviceWindow) {
+  serviceWindow = serviceWindow || typeof window !== 'undefined' && window;
+  if (!serviceWindow || !serviceWindow.document) {
+    return Promise.reject(new Error('Intent service should be used in browser'));
   }
-  return buf;
-}
 
-function binStringToBluffer(binString, type) {
-  return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
-}
+  // Maximize document, the whole iframe is handled by intents, clients and
+  // services
+  serviceWindow.addEventListener('load', function () {
+    var _serviceWindow = serviceWindow,
+        document = _serviceWindow.document;
+    [document.documentElement, document.body].forEach(maximize);
+  });
 
-function b64ToBluffer(b64, type) {
-  return binStringToBluffer(thisAtob(b64), type);
-}
+  intentId = intentId || serviceWindow.location.search.split('=')[1];
+  if (!intentId) return Promise.reject(new Error('Cannot retrieve intent from URL'));
 
-//Can't find original post, but this is close
-//http://stackoverflow.com/questions/6965107/ (continues on next line)
-//converting-between-strings-and-arraybuffers
-function arrayBufferToBinaryString(buffer) {
-  var binary = '';
-  var bytes = new Uint8Array(buffer);
-  var length = bytes.byteLength;
-  for (var i = 0; i < length; i++) {
-    binary += String.fromCharCode(bytes[i]);
-  }
-  return binary;
-}
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/intents/' + intentId).then(function (intent) {
+    var terminated = false;
 
-// shim for browsers that don't support it
-function readAsBinaryString(blob, callback) {
-  var reader = new FileReader();
-  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
-  reader.onloadend = function (e) {
-    var result = e.target.result || '';
-    if (hasBinaryString) {
-      return callback(result);
-    }
-    callback(arrayBufferToBinaryString(result));
-  };
-  if (hasBinaryString) {
-    reader.readAsBinaryString(blob);
-  } else {
-    reader.readAsArrayBuffer(blob);
-  }
-}
+    var sendMessage = function sendMessage(message) {
+      if (terminated) throw new Error('Intent service has already been terminated');
+      serviceWindow.parent.postMessage(message, intent.attributes.client);
+    };
 
-function blobToBinaryString(blobOrBuffer, callback) {
-  readAsBinaryString(blobOrBuffer, function (bin) {
-    callback(bin);
-  });
-}
+    var compose = function compose(action, doctype, data) {
+      return new Promise(function (resolve) {
+        var composeEventListener = function composeEventListener(event) {
+          if (event.origin !== intent.attributes.client) return;
+          serviceWindow.removeEventListener('message', composeEventListener);
+          return resolve(event.data);
+        };
 
-function blobToBase64(blobOrBuffer, callback) {
-  blobToBinaryString(blobOrBuffer, function (base64) {
-    callback(thisBtoa(base64));
-  });
-}
+        serviceWindow.addEventListener('message', composeEventListener);
 
-// simplified API. universal browser support is assumed
-function readAsArrayBuffer(blob, callback) {
-  var reader = new FileReader();
-  reader.onloadend = function (e) {
-    var result = e.target.result || new ArrayBuffer(0);
-    callback(result);
-  };
-  reader.readAsArrayBuffer(blob);
-}
+        sendMessage({
+          type: 'intent-' + intent._id + ':compose',
+          action: action,
+          doctype: doctype,
+          data: data
+        });
+      });
+    };
 
-// this is not used in the browser
+    var _terminate = function _terminate(message) {
+      sendMessage(message);
+      terminated = true;
+    };
 
-var setImmediateShim = global.setImmediate || global.setTimeout;
-var MD5_CHUNK_SIZE = 32768;
+    var resizeClient = function resizeClient(dimensions, transitionProperty) {
+      if (terminated) throw new Error('Intent service has been terminated');
 
-function rawToBase64(raw) {
-  return thisBtoa(raw);
-}
+      sendMessage({
+        type: 'intent-' + intent._id + ':resize',
+        // if a dom element is passed, calculate its size
+        dimensions: dimensions.element ? Object.assign({}, dimensions, {
+          maxHeight: dimensions.element.clientHeight,
+          maxWidth: dimensions.element.clientWidth
+        }) : dimensions,
+        transition: transitionProperty
+      });
+    };
 
-function sliceBlob(blob, start, end) {
-  if (blob.webkitSlice) {
-    return blob.webkitSlice(start, end);
-  }
-  return blob.slice(start, end);
-}
+    var cancel = function cancel() {
+      _terminate({ type: 'intent-' + intent._id + ':cancel' });
+    };
 
-function appendBlob(buffer, blob, start, end, callback) {
-  if (start > 0 || end < blob.size) {
-    // only slice blob if we really need to
-    blob = sliceBlob(blob, start, end);
-  }
-  readAsArrayBuffer(blob, function (arrayBuffer) {
-    buffer.append(arrayBuffer);
-    callback();
+    // Prevent unfulfilled client promises when this window unloads for a
+    // reason or another.
+    serviceWindow.addEventListener('unload', function () {
+      if (!terminated) cancel();
+    });
+
+    return listenClientData(intent, serviceWindow).then(function (data) {
+      return {
+        compose: compose,
+        getData: function getData() {
+          return data;
+        },
+        getIntent: function getIntent() {
+          return intent;
+        },
+        terminate: function terminate(doc) {
+          var eventName = data && data.exposeIntentFrameRemoval ? 'exposeFrameRemoval' : 'done';
+          return _terminate({
+            type: 'intent-' + intent._id + ':' + eventName,
+            document: doc
+          });
+        },
+        throw: function _throw(error) {
+          return _terminate({
+            type: 'intent-' + intent._id + ':error',
+            error: _helpers.errorSerializer.serialize(error)
+          });
+        },
+        resizeClient: resizeClient,
+        cancel: cancel
+      };
+    });
   });
 }
 
-function appendString(buffer, string, start, end, callback) {
-  if (start > 0 || end < string.length) {
-    // only create a substring if we really need to
-    string = string.substring(start, end);
-  }
-  buffer.appendBinary(string);
-  callback();
-}
+/***/ }),
+/* 18 */
+/***/ (function(module, exports, __nested_webpack_require_114916__) {
 
-function binaryMd5(data, callback) {
-  var inputIsString = typeof data === 'string';
-  var len = inputIsString ? data.length : data.size;
-  var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
-  var chunks = Math.ceil(len / chunkSize);
-  var currentChunk = 0;
-  var buffer = inputIsString ? new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default())() : new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default().ArrayBuffer)();
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.count = count;
+exports.queued = queued;
+exports.create = create;
 
-  var append = inputIsString ? appendString : appendBlob;
+var _fetch = __nested_webpack_require_114916__(0);
 
-  function next() {
-    setImmediateShim(loadNextChunk);
-  }
+function count(cozy, workerType) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType).then(function (data) {
+    return data.length;
+  });
+}
 
-  function done() {
-    var raw = buffer.end(true);
-    var base64 = rawToBase64(raw);
-    callback(base64);
-    buffer.destroy();
-  }
+function queued(cozy, workerType) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType);
+}
 
-  function loadNextChunk() {
-    var start = currentChunk * chunkSize;
-    var end = start + chunkSize;
-    currentChunk++;
-    if (currentChunk < chunks) {
-      append(buffer, data, start, end, next);
-    } else {
-      append(buffer, data, start, end, done);
+function create(cozy, workerType, args, options) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/jobs/queue/' + workerType, {
+    data: {
+      type: 'io.cozy.jobs',
+      attributes: {
+        arguments: args || {},
+        options: options || {}
+      }
     }
-  }
-  loadNextChunk();
+  });
 }
 
-function stringMd5(string) {
-  return spark_md5__WEBPACK_IMPORTED_MODULE_4___default().hash(string);
-}
+/***/ }),
+/* 19 */
+/***/ (function(module, exports, __nested_webpack_require_115746__) {
 
-function rev$$1(doc, deterministic_revs) {
-  var clonedDoc = clone(doc);
-  if (!deterministic_revs) {
-    return uuid__WEBPACK_IMPORTED_MODULE_5___default().v4().replace(/-/g, '').toLowerCase();
-  }
+"use strict";
 
-  delete clonedDoc._rev_tree;
-  return stringMd5(JSON.stringify(clonedDoc));
-}
 
-var uuid = (uuid__WEBPACK_IMPORTED_MODULE_5___default().v4);
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.replicationOfflineError = undefined;
 
-// We fetch all leafs of the revision tree, and sort them based on tree length
-// and whether they were deleted, undeleted documents with the longest revision
-// tree (most edits) win
-// The final sort algorithm is slightly documented in a sidebar here:
-// http://guide.couchdb.org/draft/conflicts.html
-function winningRev(metadata) {
-  var winningId;
-  var winningPos;
-  var winningDeleted;
-  var toVisit = metadata.rev_tree.slice();
-  var node;
-  while ((node = toVisit.pop())) {
-    var tree = node.ids;
-    var branches = tree[2];
-    var pos = node.pos;
-    if (branches.length) { // non-leaf
-      for (var i = 0, len = branches.length; i < len; i++) {
-        toVisit.push({pos: pos + 1, ids: branches[i]});
-      }
-      continue;
-    }
-    var deleted = !!tree[1].deleted;
-    var id = tree[0];
-    // sort by deleted, then pos, then id
-    if (!winningId || (winningDeleted !== deleted ? winningDeleted :
-        winningPos !== pos ? winningPos < pos : winningId < id)) {
-      winningId = id;
-      winningPos = pos;
-      winningDeleted = deleted;
-    }
-  }
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // Define global `fetch` so it's made available to `pouchdb-browser`
 
-  return winningPos + '-' + winningId;
-}
 
-// Pretty much all below can be combined into a higher order function to
-// traverse revisions
-// The return value from the callback will be passed as context to all
-// children of that node
-function traverseRevTree(revs, callback) {
-  var toVisit = revs.slice();
+exports.init = init;
+exports.getDoctypes = getDoctypes;
+exports.hasDatabase = hasDatabase;
+exports.getDatabase = getDatabase;
+exports.setDatabase = setDatabase;
+exports.migrateDatabase = migrateDatabase;
+exports.createDatabase = createDatabase;
+exports.destroyDatabase = destroyDatabase;
+exports.destroyAllDatabase = destroyAllDatabase;
+exports.hasReplication = hasReplication;
+exports.replicateFromCozy = replicateFromCozy;
+exports.stopReplication = stopReplication;
+exports.stopAllReplication = stopAllReplication;
+exports.hasRepeatedReplication = hasRepeatedReplication;
+exports.startRepeatedReplication = startRepeatedReplication;
+exports.stopRepeatedReplication = stopRepeatedReplication;
+exports.stopAllRepeatedReplication = stopAllRepeatedReplication;
 
-  var node;
-  while ((node = toVisit.pop())) {
-    var pos = node.pos;
-    var tree = node.ids;
-    var branches = tree[2];
-    var newCtx =
-      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
-    for (var i = 0, len = branches.length; i < len; i++) {
-      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
-    }
-  }
-}
+__nested_webpack_require_115746__(20);
 
-function sortByPos(a, b) {
-  return a.pos - b.pos;
-}
+var _doctypes = __nested_webpack_require_115746__(2);
 
-function collectLeaves(revs) {
-  var leaves = [];
-  traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
-    if (isLeaf) {
-      leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
-    }
-  });
-  leaves.sort(sortByPos).reverse();
-  for (var i = 0, len = leaves.length; i < len; i++) {
-    delete leaves[i].pos;
-  }
-  return leaves;
-}
+var _auth_v = __nested_webpack_require_115746__(3);
 
-// returns revs of all conflicts that is leaves such that
-// 1. are not deleted and
-// 2. are different than winning revision
-function collectConflicts(metadata) {
-  var win = winningRev(metadata);
-  var leaves = collectLeaves(metadata.rev_tree);
-  var conflicts = [];
-  for (var i = 0, len = leaves.length; i < len; i++) {
-    var leaf = leaves[i];
-    if (leaf.rev !== win && !leaf.opts.deleted) {
-      conflicts.push(leaf.rev);
-    }
-  }
-  return conflicts;
-}
+var _utils = __nested_webpack_require_115746__(1);
 
-// compact a tree by marking its non-leafs as missing,
-// and return a list of revs to delete
-function compactTree(metadata) {
-  var revs = [];
-  traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
-                                               revHash, ctx, opts) {
-    if (opts.status === 'available' && !isLeaf) {
-      revs.push(pos + '-' + revHash);
-      opts.status = 'missing';
-    }
-  });
-  return revs;
-}
+var _pouchdbBrowser = __nested_webpack_require_115746__(21);
 
-// build up a list of all the paths to the leafs in this revision tree
-function rootToLeaf(revs) {
-  var paths = [];
-  var toVisit = revs.slice();
-  var node;
-  while ((node = toVisit.pop())) {
-    var pos = node.pos;
-    var tree = node.ids;
-    var id = tree[0];
-    var opts = tree[1];
-    var branches = tree[2];
-    var isLeaf = branches.length === 0;
+var _pouchdbBrowser2 = _interopRequireDefault(_pouchdbBrowser);
 
-    var history = node.history ? node.history.slice() : [];
-    history.push({id: id, opts: opts});
-    if (isLeaf) {
-      paths.push({pos: (pos + 1 - history.length), ids: history});
-    }
-    for (var i = 0, len = branches.length; i < len; i++) {
-      toVisit.push({pos: pos + 1, ids: branches[i], history: history});
-    }
-  }
-  return paths.reverse();
-}
+var _pouchdbFind = __nested_webpack_require_115746__(22);
 
-// for a better overview of what this is doing, read:
+var _pouchdbFind2 = _interopRequireDefault(_pouchdbFind);
 
-function sortByPos$1(a, b) {
-  return a.pos - b.pos;
-}
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-// classic binary search
-function binarySearch(arr, item, comparator) {
-  var low = 0;
-  var high = arr.length;
-  var mid;
-  while (low < high) {
-    mid = (low + high) >>> 1;
-    if (comparator(arr[mid], item) < 0) {
-      low = mid + 1;
-    } else {
-      high = mid;
-    }
-  }
-  return low;
-}
+var replicationOfflineError = exports.replicationOfflineError = 'Replication abort, your device is actually offline.';
 
-// assuming the arr is sorted, insert the item in the proper place
-function insertSorted(arr, item, comparator) {
-  var idx = binarySearch(arr, item, comparator);
-  arr.splice(idx, 0, item);
-}
+var pluginLoaded = false;
 
-// Turn a path as a flat array into a tree with a single branch.
-// If any should be stemmed from the beginning of the array, that's passed
-// in as the second argument
-function pathToTree(path, numStemmed) {
-  var root;
-  var leaf;
-  for (var i = numStemmed, len = path.length; i < len; i++) {
-    var node = path[i];
-    var currentLeaf = [node.id, node.opts, []];
-    if (leaf) {
-      leaf[2].push(currentLeaf);
-      leaf = currentLeaf;
-    } else {
-      root = leaf = currentLeaf;
-    }
+/*
+  For each doctype we have some parameters:
+  cozy._offline[doctype] = {
+    database: pouchdb database
+    replication: the pouchdb replication
+    replicationPromise: promise of replication
+    interval: repeated replication interval
   }
-  return root;
-}
+*/
 
-// compare the IDs of two trees
-function compareTree(a, b) {
-  return a[0] < b[0] ? -1 : 1;
-}
+function init(cozy, _ref) {
+  var _ref$options = _ref.options,
+      options = _ref$options === undefined ? {} : _ref$options,
+      _ref$doctypes = _ref.doctypes,
+      doctypes = _ref$doctypes === undefined ? [] : _ref$doctypes;
+  var _iteratorNormalCompletion = true;
+  var _didIteratorError = false;
+  var _iteratorError = undefined;
 
-// Merge two trees together
-// The roots of tree1 and tree2 must be the same revision
-function mergeTree(in_tree1, in_tree2) {
-  var queue = [{tree1: in_tree1, tree2: in_tree2}];
-  var conflicts = false;
-  while (queue.length > 0) {
-    var item = queue.pop();
-    var tree1 = item.tree1;
-    var tree2 = item.tree2;
+  try {
+    for (var _iterator = doctypes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+      var doctype = _step.value;
 
-    if (tree1[1].status || tree2[1].status) {
-      tree1[1].status =
-        (tree1[1].status ===  'available' ||
-        tree2[1].status === 'available') ? 'available' : 'missing';
+      createDatabase(cozy, doctype, options);
     }
-
-    for (var i = 0; i < tree2[2].length; i++) {
-      if (!tree1[2][0]) {
-        conflicts = 'new_leaf';
-        tree1[2][0] = tree2[2][i];
-        continue;
-      }
-
-      var merged = false;
-      for (var j = 0; j < tree1[2].length; j++) {
-        if (tree1[2][j][0] === tree2[2][i][0]) {
-          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
-          merged = true;
-        }
+  } catch (err) {
+    _didIteratorError = true;
+    _iteratorError = err;
+  } finally {
+    try {
+      if (!_iteratorNormalCompletion && _iterator.return) {
+        _iterator.return();
       }
-      if (!merged) {
-        conflicts = 'new_branch';
-        insertSorted(tree1[2], tree2[2][i], compareTree);
+    } finally {
+      if (_didIteratorError) {
+        throw _iteratorError;
       }
     }
   }
-  return {conflicts: conflicts, tree: in_tree1};
 }
 
-function doMerge(tree, path, dontExpand) {
-  var restree = [];
-  var conflicts = false;
-  var merged = false;
-  var res;
-
-  if (!tree.length) {
-    return {tree: [path], conflicts: 'new_leaf'};
-  }
+// helper
 
-  for (var i = 0, len = tree.length; i < len; i++) {
-    var branch = tree[i];
-    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
-      // Paths start at the same position and have the same root, so they need
-      // merged
-      res = mergeTree(branch.ids, path.ids);
-      restree.push({pos: branch.pos, ids: res.tree});
-      conflicts = conflicts || res.conflicts;
-      merged = true;
-    } else if (dontExpand !== true) {
-      // The paths start at a different position, take the earliest path and
-      // traverse up until it as at the same point from root as the path we
-      // want to merge.  If the keys match we return the longer path with the
-      // other merged After stemming we dont want to expand the trees
+function getInfo(cozy, doctype) {
+  cozy._offline = cozy._offline || [];
+  cozy._offline[doctype] = cozy._offline[doctype] || {};
+  return cozy._offline[doctype];
+}
 
-      var t1 = branch.pos < path.pos ? branch : path;
-      var t2 = branch.pos < path.pos ? path : branch;
-      var diff = t2.pos - t1.pos;
+function getDoctypes(cozy) {
+  cozy._offline = cozy._offline || [];
+  return Object.keys(cozy._offline);
+}
 
-      var candidateParents = [];
+//
+// DATABASE
+//
 
-      var trees = [];
-      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
-      while (trees.length > 0) {
-        var item = trees.pop();
-        if (item.diff === 0) {
-          if (item.ids[0] === t2.ids[0]) {
-            candidateParents.push(item);
-          }
-          continue;
-        }
-        var elements = item.ids[2];
-        for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
-          trees.push({
-            ids: elements[j],
-            diff: item.diff - 1,
-            parent: item.ids,
-            parentIdx: j
-          });
-        }
-      }
+function hasDatabase(cozy, doctype) {
+  return getDatabase(cozy, doctype) !== undefined;
+}
 
-      var el = candidateParents[0];
+function getDatabase(cozy, doctype) {
+  return getInfo(cozy, doctype).database;
+}
 
-      if (!el) {
-        restree.push(branch);
-      } else {
-        res = mergeTree(el.ids, t2.ids);
-        el.parent[2][el.parentIdx] = res.tree;
-        restree.push({pos: t1.pos, ids: t1.ids});
-        conflicts = conflicts || res.conflicts;
-        merged = true;
-      }
-    } else {
-      restree.push(branch);
-    }
-  }
+function setDatabase(cozy, doctype, database) {
+  cozy._offline[doctype].database = database;
+  return getDatabase(cozy, doctype);
+}
 
-  // We didnt find
-  if (!merged) {
-    restree.push(path);
-  }
+function migrateDatabase(cozy, doctype) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
 
-  restree.sort(sortByPos$1);
+  var oldDb = getDatabase(cozy, doctype);
+  var newOptions = _extends({
+    adapter: 'idb'
+  }, options);
+  var newDb = new _pouchdbBrowser2.default(doctype, newOptions);
 
-  return {
-    tree: restree,
-    conflicts: conflicts || 'internal_node'
-  };
+  return oldDb.replicate.to(newDb).then(function () {
+    setDatabase(cozy, doctype, newDb);
+    oldDb.destroy();
+    return newDb;
+  });
 }
 
-// To ensure we dont grow the revision tree infinitely, we stem old revisions
-function stem(tree, depth) {
-  // First we break out the tree into a complete list of root to leaf paths
-  var paths = rootToLeaf(tree);
-  var stemmedRevs;
-
-  var result;
-  for (var i = 0, len = paths.length; i < len; i++) {
-    // Then for each path, we cut off the start of the path based on the
-    // `depth` to stem to, and generate a new set of flat trees
-    var path = paths[i];
-    var stemmed = path.ids;
-    var node;
-    if (stemmed.length > depth) {
-      // only do the stemming work if we actually need to stem
-      if (!stemmedRevs) {
-        stemmedRevs = {}; // avoid allocating this object unnecessarily
-      }
-      var numStemmed = stemmed.length - depth;
-      node = {
-        pos: path.pos + numStemmed,
-        ids: pathToTree(stemmed, numStemmed)
-      };
+function createDatabase(cozy, doctype) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
 
-      for (var s = 0; s < numStemmed; s++) {
-        var rev = (path.pos + s) + '-' + stemmed[s].id;
-        stemmedRevs[rev] = true;
-      }
-    } else { // no need to actually stem
-      node = {
-        pos: path.pos,
-        ids: pathToTree(stemmed, 0)
-      };
-    }
+  if (!pluginLoaded) {
+    _pouchdbBrowser2.default.plugin(_pouchdbFind2.default);
+    pluginLoaded = true;
+  }
 
-    // Then we remerge all those flat trees together, ensuring that we dont
-    // connect trees that would go beyond the depth limit
-    if (result) {
-      result = doMerge(result, node, true).tree;
-    } else {
-      result = [node];
-    }
+  if (hasDatabase(cozy, doctype)) {
+    return Promise.resolve(getDatabase(cozy, doctype));
   }
 
-  // this is memory-heavy per Chrome profiler, avoid unless we actually stemmed
-  if (stemmedRevs) {
-    traverseRevTree(result, function (isLeaf, pos, revHash) {
-      // some revisions may have been removed in a branch but not in another
-      delete stemmedRevs[pos + '-' + revHash];
-    });
+  setDatabase(cozy, doctype, new _pouchdbBrowser2.default(doctype, options));
+  return createIndexes(cozy, doctype).then(function () {
+    return getDatabase(cozy, doctype);
+  });
+}
+
+function destroyDatabase(cozy, doctype) {
+  if (!hasDatabase(cozy, doctype)) {
+    return Promise.resolve(false);
   }
 
-  return {
-    tree: result,
-    revs: stemmedRevs ? Object.keys(stemmedRevs) : []
-  };
+  return stopRepeatedReplication(cozy, doctype).then(function () {
+    return stopReplication(cozy, doctype);
+  }).then(function () {
+    return getDatabase(cozy, doctype).destroy();
+  }).then(function (response) {
+    setDatabase(cozy, doctype, undefined);
+    return response;
+  });
 }
 
-function merge(tree, path, depth) {
-  var newTree = doMerge(tree, path);
-  var stemmed = stem(newTree.tree, depth);
-  return {
-    tree: stemmed.tree,
-    stemmedRevs: stemmed.revs,
-    conflicts: newTree.conflicts
+function destroyAllDatabase(cozy) {
+  var doctypes = getDoctypes(cozy);
+  var destroy = function destroy(doctype) {
+    return destroyDatabase(cozy, doctype);
   };
+  return Promise.all(doctypes.map(destroy));
 }
 
-// return true if a rev exists in the rev tree, false otherwise
-function revExists(revs, rev) {
-  var toVisit = revs.slice();
-  var splitRev = rev.split('-');
-  var targetPos = parseInt(splitRev[0], 10);
-  var targetId = splitRev[1];
-
-  var node;
-  while ((node = toVisit.pop())) {
-    if (node.pos === targetPos && node.ids[0] === targetId) {
-      return true;
-    }
-    var branches = node.ids[2];
-    for (var i = 0, len = branches.length; i < len; i++) {
-      toVisit.push({pos: node.pos + 1, ids: branches[i]});
-    }
+function createIndexes(cozy, doctype) {
+  if (doctype === _doctypes.DOCTYPE_FILES) {
+    return getDatabase(cozy, doctype).createIndex({
+      index: { fields: ['dir_id'] }
+    });
   }
-  return false;
+  return Promise.resolve();
 }
 
-function getTrees(node) {
-  return node.ids;
+//
+// REPLICATION
+//
+
+function hasReplication(cozy, doctype) {
+  return getReplication(cozy, doctype) !== undefined;
 }
 
-// check if a specific revision of a doc has been deleted
-//  - metadata: the metadata object from the doc store
-//  - rev: (optional) the revision to check. defaults to winning revision
-function isDeleted(metadata, rev) {
-  if (!rev) {
-    rev = winningRev(metadata);
-  }
-  var id = rev.substring(rev.indexOf('-') + 1);
-  var toVisit = metadata.rev_tree.map(getTrees);
+function getReplication(cozy, doctype) {
+  return getInfo(cozy, doctype).replication;
+}
 
-  var tree;
-  while ((tree = toVisit.pop())) {
-    if (tree[0] === id) {
-      return !!tree[1].deleted;
-    }
-    toVisit = toVisit.concat(tree[2]);
-  }
+function setReplication(cozy, doctype, replication) {
+  cozy._offline[doctype].replication = replication;
+  return getReplication(cozy, doctype);
 }
 
-function isLocalId(id) {
-  return (/^_local/).test(id);
+function getReplicationUrl(cozy, doctype) {
+  return cozy.authorize().then(function (credentials) {
+    var basic = credentials.token.toBasicAuth();
+    return (cozy._url + '/data/' + doctype).replace('//', '//' + basic);
+  });
 }
 
-// returns the current leaf node for a given revision
-function latest(rev, metadata) {
-  var toVisit = metadata.rev_tree.slice();
-  var node;
-  while ((node = toVisit.pop())) {
-    var pos = node.pos;
-    var tree = node.ids;
-    var id = tree[0];
-    var opts = tree[1];
-    var branches = tree[2];
-    var isLeaf = branches.length === 0;
+function getReplicationPromise(cozy, doctype) {
+  return getInfo(cozy, doctype).replicationPromise;
+}
 
-    var history = node.history ? node.history.slice() : [];
-    history.push({id: id, pos: pos, opts: opts});
+function setReplicationPromise(cozy, doctype, promise) {
+  cozy._offline[doctype].replicationPromise = promise;
+  return getReplicationPromise(cozy, doctype);
+}
 
-    if (isLeaf) {
-      for (var i = 0, len = history.length; i < len; i++) {
-        var historyNode = history[i];
-        var historyRev = historyNode.pos + '-' + historyNode.id;
+function replicateFromCozy(cozy, doctype) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
 
-        if (historyRev === rev) {
-          // return the rev of this leaf
-          return pos + '-' + id;
-        }
-      }
+  return setReplicationPromise(cozy, doctype, new Promise(function (resolve, reject) {
+    if (!hasDatabase(cozy, doctype)) {
+      createDatabase(cozy, doctype);
+    }
+    if (options.live === true) {
+      return reject(new Error("You can't use `live` option with Cozy couchdb."));
     }
 
-    for (var j = 0, l = branches.length; j < l; j++) {
-      toVisit.push({pos: pos + 1, ids: branches[j], history: history});
+    if ((0, _utils.isOffline)()) {
+      reject(replicationOfflineError);
+      options.onError && options.onError(replicationOfflineError);
+      return;
     }
-  }
 
-  /* istanbul ignore next */
-  throw new Error('Unable to resolve latest revision for id ' + metadata.id + ', rev ' + rev);
-}
+    getReplicationUrl(cozy, doctype).then(function (url) {
+      return setReplication(cozy, doctype, getDatabase(cozy, doctype).replicate.from(url, options).on('complete', function (info) {
+        setReplication(cozy, doctype, undefined);
+        resolve(info);
+        options.onComplete && options.onComplete(info);
+      }).on('error', function (err) {
+        if (err.error === 'code=400, message=Expired token') {
+          cozy.authorize().then(function (_ref2) {
+            var client = _ref2.client,
+                token = _ref2.token;
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes$1, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
+            (0, _auth_v.refreshToken)(cozy, client, token).then(function (newToken) {
+              return cozy.saveCredentials(client, newToken);
+            }).then(function () {
+              return replicateFromCozy(cozy, doctype, options);
+            });
+          });
+        } else {
+          console.warn('ReplicateFromCozy \'' + doctype + '\' Error:');
+          console.warn(err);
+          setReplication(cozy, doctype, undefined);
+          reject(err);
+          options.onError && options.onError(err);
+        }
+      }));
+    });
+  }));
+}
 
-function tryCatchInChangeListener(self, change, pending, lastSeq) {
-  // isolate try/catches to avoid V8 deoptimizations
-  try {
-    self.emit('change', change, pending, lastSeq);
-  } catch (e) {
-    guardedConsole('error', 'Error in .on("change", function):', e);
+function stopReplication(cozy, doctype) {
+  if (!getDatabase(cozy, doctype) || !hasReplication(cozy, doctype)) {
+    return Promise.resolve();
   }
-}
 
-function Changes$1(db, opts, callback) {
-  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
-  var self = this;
-  this.db = db;
-  opts = opts ? clone(opts) : {};
-  var complete = opts.complete = once(function (err, resp) {
-    if (err) {
-      if (listenerCount(self, 'error') > 0) {
-        self.emit('error', err);
-      }
-    } else {
-      self.emit('complete', resp);
+  return new Promise(function (resolve) {
+    try {
+      getReplicationPromise(cozy, doctype).then(function () {
+        resolve();
+      });
+      getReplication(cozy, doctype).cancel();
+      // replication is set to undefined by complete replication
+    } catch (e) {
+      resolve();
     }
-    self.removeAllListeners();
-    db.removeListener('destroyed', onDestroy);
   });
-  if (callback) {
-    self.on('complete', function (resp) {
-      callback(null, resp);
-    });
-    self.on('error', callback);
-  }
-  function onDestroy() {
-    self.cancel();
-  }
-  db.once('destroyed', onDestroy);
+}
 
-  opts.onChange = function (change, pending, lastSeq) {
-    /* istanbul ignore if */
-    if (self.isCancelled) {
-      return;
-    }
-    tryCatchInChangeListener(self, change, pending, lastSeq);
+function stopAllReplication(cozy) {
+  var doctypes = getDoctypes(cozy);
+  var stop = function stop(doctype) {
+    return stopReplication(cozy, doctype);
   };
+  return Promise.all(doctypes.map(stop));
+}
 
-  var promise = new Promise(function (fulfill, reject) {
-    opts.complete = function (err, res) {
-      if (err) {
-        reject(err);
-      } else {
-        fulfill(res);
-      }
-    };
-  });
-  self.once('cancel', function () {
-    db.removeListener('destroyed', onDestroy);
-    opts.complete(null, {status: 'cancelled'});
-  });
-  this.then = promise.then.bind(promise);
-  this['catch'] = promise['catch'].bind(promise);
-  this.then(function (result) {
-    complete(null, result);
-  }, complete);
+//
+// REPEATED REPLICATION
+//
 
+function getRepeatedReplication(cozy, doctype) {
+  return getInfo(cozy, doctype).interval;
+}
 
+function setRepeatedReplication(cozy, doctype, interval) {
+  cozy._offline[doctype].interval = interval;
+}
 
-  if (!db.taskqueue.isReady) {
-    db.taskqueue.addTask(function (failed) {
-      if (failed) {
-        opts.complete(failed);
-      } else if (self.isCancelled) {
-        self.emit('cancel');
-      } else {
-        self.validateChanges(opts);
-      }
-    });
-  } else {
-    self.validateChanges(opts);
-  }
+function hasRepeatedReplication(cozy, doctype) {
+  return getRepeatedReplication(cozy, doctype) !== undefined;
 }
-Changes$1.prototype.cancel = function () {
-  this.isCancelled = true;
-  if (this.db.taskqueue.isReady) {
-    this.emit('cancel');
-  }
-};
-function processChange(doc, metadata, opts) {
-  var changeList = [{rev: doc._rev}];
-  if (opts.style === 'all_docs') {
-    changeList = collectLeaves(metadata.rev_tree)
-    .map(function (x) { return {rev: x.rev}; });
-  }
-  var change = {
-    id: metadata.id,
-    changes: changeList,
-    doc: doc
-  };
 
-  if (isDeleted(metadata, doc._rev)) {
-    change.deleted = true;
+function startRepeatedReplication(cozy, doctype, timer) {
+  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+  // TODO: add timer limitation for not flooding Gozy
+  if (hasRepeatedReplication(cozy, doctype)) {
+    return getRepeatedReplication(cozy, doctype);
   }
-  if (opts.conflicts) {
-    change.doc._conflicts = collectConflicts(metadata);
-    if (!change.doc._conflicts.length) {
-      delete change.doc._conflicts;
+
+  return setRepeatedReplication(cozy, doctype, setInterval(function () {
+    if ((0, _utils.isOffline)()) {
+      // network is offline, replication cannot be launched
+      console.info(replicationOfflineError);
+      return;
+    }
+    if (!hasReplication(cozy, doctype)) {
+      replicateFromCozy(cozy, doctype, options);
+      // TODO: add replicationToCozy
     }
+  }, timer * 1000));
+}
+
+function stopRepeatedReplication(cozy, doctype) {
+  if (hasRepeatedReplication(cozy, doctype)) {
+    clearInterval(getRepeatedReplication(cozy, doctype));
+    setRepeatedReplication(cozy, doctype, undefined);
   }
-  return change;
+  if (hasReplication(cozy, doctype)) {
+    return stopReplication(cozy, doctype);
+  }
+
+  return Promise.resolve();
 }
 
-Changes$1.prototype.validateChanges = function (opts) {
-  var callback = opts.complete;
-  var self = this;
+function stopAllRepeatedReplication(cozy) {
+  var doctypes = getDoctypes(cozy);
+  var stop = function stop(doctype) {
+    return stopRepeatedReplication(cozy, doctype);
+  };
+  return Promise.all(doctypes.map(stop));
+}
 
-  /* istanbul ignore else */
-  if (PouchDB._changesFilterPlugin) {
-    PouchDB._changesFilterPlugin.validate(opts, function (err) {
-      if (err) {
-        return callback(err);
-      }
-      self.doChanges(opts);
-    });
-  } else {
-    self.doChanges(opts);
-  }
-};
+/***/ }),
+/* 20 */
+/***/ (function(module, exports) {
 
-Changes$1.prototype.doChanges = function (opts) {
-  var self = this;
-  var callback = opts.complete;
+module.exports = __webpack_require__(491);
 
-  opts = clone(opts);
-  if ('live' in opts && !('continuous' in opts)) {
-    opts.continuous = opts.live;
-  }
-  opts.processChange = processChange;
+/***/ }),
+/* 21 */
+/***/ (function(module, exports) {
 
-  if (opts.since === 'latest') {
-    opts.since = 'now';
-  }
-  if (!opts.since) {
-    opts.since = 0;
-  }
-  if (opts.since === 'now') {
-    this.db.info().then(function (info) {
-      /* istanbul ignore if */
-      if (self.isCancelled) {
-        callback(null, {status: 'cancelled'});
-        return;
-      }
-      opts.since = info.update_seq;
-      self.doChanges(opts);
-    }, callback);
-    return;
-  }
+module.exports = __webpack_require__(494);
 
-  /* istanbul ignore else */
-  if (PouchDB._changesFilterPlugin) {
-    PouchDB._changesFilterPlugin.normalize(opts);
-    if (PouchDB._changesFilterPlugin.shouldFilter(this, opts)) {
-      return PouchDB._changesFilterPlugin.filter(this, opts);
-    }
-  } else {
-    ['doc_ids', 'filter', 'selector', 'view'].forEach(function (key) {
-      if (key in opts) {
-        guardedConsole('warn',
-          'The "' + key + '" option was passed in to changes/replicate, ' +
-          'but pouchdb-changes-filter plugin is not installed, so it ' +
-          'was ignored. Please install the plugin to enable filtering.'
-        );
-      }
-    });
-  }
+/***/ }),
+/* 22 */
+/***/ (function(module, exports) {
 
-  if (!('descending' in opts)) {
-    opts.descending = false;
-  }
+module.exports = __webpack_require__(506);
 
-  // 0 and 1 should return 1 document
-  opts.limit = opts.limit === 0 ? 1 : opts.limit;
-  opts.complete = callback;
-  var newPromise = this.db._changes(opts);
-  /* istanbul ignore else */
-  if (newPromise && typeof newPromise.cancel === 'function') {
-    var cancel = self.cancel;
-    self.cancel = argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
-      newPromise.cancel();
-      cancel.apply(this, args);
-    });
-  }
-};
+/***/ }),
+/* 23 */
+/***/ (function(module, exports, __nested_webpack_require_126289__) {
 
-/*
- * A generic pouch adapter
- */
+"use strict";
 
-function compare(left, right) {
-  return left < right ? -1 : left > right ? 1 : 0;
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.diskUsage = diskUsage;
+exports.changePassphrase = changePassphrase;
+exports.getInstance = getInstance;
+exports.updateInstance = updateInstance;
+exports.getClients = getClients;
+exports.deleteClientById = deleteClientById;
+exports.updateLastSync = updateLastSync;
+
+var _fetch = __nested_webpack_require_126289__(0);
+
+function diskUsage(cozy) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/disk-usage');
 }
 
-// Wrapper for functions that call the bulkdocs api with a single doc,
-// if the first result is an error, return an error
-function yankError(callback, docId) {
-  return function (err, results) {
-    if (err || (results[0] && results[0].error)) {
-      err = err || results[0];
-      err.docId = docId;
-      callback(err);
-    } else {
-      callback(null, results.length ? results[0]  : results);
-    }
-  };
+function changePassphrase(cozy, currentPassPhrase, newPassPhrase) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/passphrase', {
+    current_passphrase: currentPassPhrase,
+    new_passphrase: newPassPhrase
+  });
 }
 
-// clean docs given to us by the user
-function cleanDocs(docs) {
-  for (var i = 0; i < docs.length; i++) {
-    var doc = docs[i];
-    if (doc._deleted) {
-      delete doc._attachments; // ignore atts for deleted docs
-    } else if (doc._attachments) {
-      // filter out extraneous keys from _attachments
-      var atts = Object.keys(doc._attachments);
-      for (var j = 0; j < atts.length; j++) {
-        var att = atts[j];
-        doc._attachments[att] = pick(doc._attachments[att],
-          ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']);
-      }
-    }
-  }
+function getInstance(cozy) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/instance');
 }
 
-// compare two docs, first by _id then by _rev
-function compareByIdThenRev(a, b) {
-  var idCompare = compare(a._id, b._id);
-  if (idCompare !== 0) {
-    return idCompare;
-  }
-  var aStart = a._revisions ? a._revisions.start : 0;
-  var bStart = b._revisions ? b._revisions.start : 0;
-  return compare(aStart, bStart);
+function updateInstance(cozy, instance) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/instance', instance);
 }
 
-// for every node in a revision tree computes its distance from the closest
-// leaf
-function computeHeight(revs) {
-  var height = {};
-  var edges = [];
-  traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
-    var rev = pos + "-" + id;
-    if (isLeaf) {
-      height[rev] = 0;
-    }
-    if (prnt !== undefined) {
-      edges.push({from: prnt, to: rev});
-    }
-    return rev;
-  });
+function getClients(cozy) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/clients');
+}
 
-  edges.reverse();
-  edges.forEach(function (edge) {
-    if (height[edge.from] === undefined) {
-      height[edge.from] = 1 + height[edge.to];
-    } else {
-      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
-    }
-  });
-  return height;
+function deleteClientById(cozy, id) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/settings/clients/' + id);
 }
 
-function allDocsKeysParse(opts) {
-  var keys =  ('limit' in opts) ?
-    opts.keys.slice(opts.skip, opts.limit + opts.skip) :
-    (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
-  opts.keys = keys;
-  opts.skip = 0;
-  delete opts.limit;
-  if (opts.descending) {
-    keys.reverse();
-    opts.descending = false;
-  }
+function updateLastSync(cozy) {
+  return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/settings/synchronized');
+}
+
+/***/ }),
+/* 24 */
+/***/ (function(module, exports, __nested_webpack_require_127648__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.removeReferencedFiles = exports.addReferencedFiles = undefined;
+exports.listReferencedFiles = listReferencedFiles;
+exports.fetchReferencedFiles = fetchReferencedFiles;
+
+var _fetch = __nested_webpack_require_127648__(0);
+
+var _doctypes = __nested_webpack_require_127648__(2);
+
+function updateRelations(verb) {
+  return function (cozy, doc, ids) {
+    if (!doc) throw new Error('missing doc argument');
+    if (!Array.isArray(ids)) ids = [ids];
+
+    var refs = ids.map(function (id) {
+      return { type: _doctypes.DOCTYPE_FILES, id: id };
+    });
+
+    return (0, _fetch.cozyFetchJSON)(cozy, verb, makeReferencesPath(doc), { data: refs });
+  };
 }
 
-// all compaction is done in a queue, to avoid attaching
-// too many listeners at once
-function doNextCompaction(self) {
-  var task = self._compactionQueue[0];
-  var opts = task.opts;
-  var callback = task.callback;
-  self.get('_local/compaction').catch(function () {
-    return false;
-  }).then(function (doc) {
-    if (doc && doc.last_seq) {
-      opts.last_seq = doc.last_seq;
-    }
-    self._compact(opts, function (err, res) {
-      /* istanbul ignore if */
-      if (err) {
-        callback(err);
-      } else {
-        callback(null, res);
-      }
-      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-        self._compactionQueue.shift();
-        if (self._compactionQueue.length) {
-          doNextCompaction(self);
-        }
-      });
+var addReferencedFiles = exports.addReferencedFiles = updateRelations('POST');
+var removeReferencedFiles = exports.removeReferencedFiles = updateRelations('DELETE');
+
+function listReferencedFiles(cozy, doc) {
+  if (!doc) throw new Error('missing doc argument');
+  return (0, _fetch.cozyFetchJSON)(cozy, 'GET', makeReferencesPath(doc)).then(function (files) {
+    return files.map(function (file) {
+      return file._id;
     });
   });
 }
 
-function attachmentNameError(name) {
-  if (name.charAt(0) === '_') {
-    return name + ' is not a valid attachment name, attachment ' +
-      'names cannot start with \'_\'';
+function fetchReferencedFiles(cozy, doc, options, sort) {
+  if (!doc) throw new Error('missing doc argument');
+  var params = Object.keys(options).map(function (key) {
+    var value = encodeURIComponent(JSON.stringify(options[key]));
+    return '&page[' + key + ']=' + value;
+  }).join('');
+  // Datetime is the default sort, but 'id' is also available
+  if (!sort) {
+    sort = 'datetime';
   }
-  return false;
+  return (0, _fetch.cozyFetchRawJSON)(cozy, 'GET', makeReferencesPath(doc) + '?include=files&sort=' + sort + params);
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(AbstractPouchDB, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
+function makeReferencesPath(doc) {
+  var type = encodeURIComponent(doc._type);
+  var id = encodeURIComponent(doc._id);
+  return '/data/' + type + '/' + id + '/relationships/references';
+}
 
-function AbstractPouchDB() {
-  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
+/***/ })
+/******/ ])));
+//# sourceMappingURL=cozy-client.node.js.map
 
-  // re-bind prototyped methods
-  for (var p in AbstractPouchDB.prototype) {
-    if (typeof this[p] === 'function') {
-      this[p] = this[p].bind(this);
-    }
+/***/ }),
+/* 487 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+module.exports = __webpack_require__(488);
+
+
+/***/ }),
+/* 488 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+// This method of obtaining a reference to the global object needs to be
+// kept identical to the way it is obtained in runtime.js
+var g = (function() { return this })() || Function("return this")();
+
+// Use `getOwnPropertyNames` because not all browsers support calling
+// `hasOwnProperty` on the global `self` object in a worker. See #183.
+var hadRuntime = g.regeneratorRuntime &&
+  Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0;
+
+// Save the old regeneratorRuntime in case it needs to be restored later.
+var oldRuntime = hadRuntime && g.regeneratorRuntime;
+
+// Force reevalutation of runtime.js.
+g.regeneratorRuntime = undefined;
+
+module.exports = __webpack_require__(489);
+
+if (hadRuntime) {
+  // Restore the original runtime.
+  g.regeneratorRuntime = oldRuntime;
+} else {
+  // Remove the global property added by runtime.js.
+  try {
+    delete g.regeneratorRuntime;
+  } catch(e) {
+    g.regeneratorRuntime = undefined;
   }
 }
 
-AbstractPouchDB.prototype.post =
-  adapterFun('post', function (doc, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    return callback(createError(NOT_AN_OBJECT));
-  }
-  this.bulkDocs({docs: [doc]}, opts, yankError(callback, doc._id));
-});
 
-AbstractPouchDB.prototype.put = adapterFun('put', function (doc, opts, cb) {
-  if (typeof opts === 'function') {
-    cb = opts;
-    opts = {};
-  }
-  if (typeof doc !== 'object' || Array.isArray(doc)) {
-    return cb(createError(NOT_AN_OBJECT));
-  }
-  invalidIdError(doc._id);
-  if (isLocalId(doc._id) && typeof this._putLocal === 'function') {
-    if (doc._deleted) {
-      return this._removeLocal(doc, cb);
-    } else {
-      return this._putLocal(doc, cb);
-    }
-  }
-  var self = this;
-  if (opts.force && doc._rev) {
-    transformForceOptionToNewEditsOption();
-    putDoc(function (err) {
-      var result = err ? null : {ok: true, id: doc._id, rev: doc._rev};
-      cb(err, result);
-    });
-  } else {
-    putDoc(cb);
-  }
+/***/ }),
+/* 489 */
+/***/ ((module) => {
 
-  function transformForceOptionToNewEditsOption() {
-    var parts = doc._rev.split('-');
-    var oldRevId = parts[1];
-    var oldRevNum = parseInt(parts[0], 10);
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
 
-    var newRevNum = oldRevNum + 1;
-    var newRevId = rev$$1();
+!(function(global) {
+  "use strict";
 
-    doc._revisions = {
-      start: newRevNum,
-      ids: [newRevId, oldRevId]
-    };
-    doc._rev = newRevNum + '-' + newRevId;
-    opts.new_edits = false;
-  }
-  function putDoc(next) {
-    if (typeof self._put === 'function' && opts.new_edits !== false) {
-      self._put(doc, opts, next);
-    } else {
-      self.bulkDocs({docs: [doc]}, opts, yankError(next, doc._id));
+  var Op = Object.prototype;
+  var hasOwn = Op.hasOwnProperty;
+  var undefined; // More compressible than void 0.
+  var $Symbol = typeof Symbol === "function" ? Symbol : {};
+  var iteratorSymbol = $Symbol.iterator || "@@iterator";
+  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
+  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+
+  var inModule = "object" === "object";
+  var runtime = global.regeneratorRuntime;
+  if (runtime) {
+    if (inModule) {
+      // If regeneratorRuntime is defined globally and we're in a module,
+      // make the exports object identical to regeneratorRuntime.
+      module.exports = runtime;
     }
+    // Don't bother evaluating the rest of this file if the runtime was
+    // already defined globally.
+    return;
   }
-});
 
-AbstractPouchDB.prototype.putAttachment =
-  adapterFun('putAttachment', function (docId, attachmentId, rev,
-                                              blob, type) {
-  var api = this;
-  if (typeof type === 'function') {
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-  // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267
-  /* istanbul ignore if */
-  if (typeof type === 'undefined') {
-    type = blob;
-    blob = rev;
-    rev = null;
-  }
-  if (!type) {
-    guardedConsole('warn', 'Attachment', attachmentId, 'on document', docId, 'is missing content_type');
-  }
+  // Define the runtime globally (as expected by generated code) as either
+  // module.exports (if we're in a module) or a new, empty object.
+  runtime = global.regeneratorRuntime = inModule ? module.exports : {};
 
-  function createAttachment(doc) {
-    var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0;
-    doc._attachments = doc._attachments || {};
-    doc._attachments[attachmentId] = {
-      content_type: type,
-      data: blob,
-      revpos: ++prevrevpos
-    };
-    return api.put(doc);
+  function wrap(innerFn, outerFn, self, tryLocsList) {
+    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
+    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
+    var generator = Object.create(protoGenerator.prototype);
+    var context = new Context(tryLocsList || []);
+
+    // The ._invoke method unifies the implementations of the .next,
+    // .throw, and .return methods.
+    generator._invoke = makeInvokeMethod(innerFn, self, context);
+
+    return generator;
   }
+  runtime.wrap = wrap;
 
-  return api.get(docId).then(function (doc) {
-    if (doc._rev !== rev) {
-      throw createError(REV_CONFLICT);
+  // Try/catch helper to minimize deoptimizations. Returns a completion
+  // record like context.tryEntries[i].completion. This interface could
+  // have been (and was previously) designed to take a closure to be
+  // invoked without arguments, but in all the cases we care about we
+  // already have an existing method we want to call, so there's no need
+  // to create a new function object. We can even get away with assuming
+  // the method takes exactly one argument, since that happens to be true
+  // in every case, so we don't have to touch the arguments object. The
+  // only additional allocation required is the completion record, which
+  // has a stable shape and so hopefully should be cheap to allocate.
+  function tryCatch(fn, obj, arg) {
+    try {
+      return { type: "normal", arg: fn.call(obj, arg) };
+    } catch (err) {
+      return { type: "throw", arg: err };
     }
+  }
 
-    return createAttachment(doc);
-  }, function (err) {
-     // create new doc
-    /* istanbul ignore else */
-    if (err.reason === MISSING_DOC.message) {
-      return createAttachment({_id: docId});
-    } else {
-      throw err;
-    }
-  });
-});
+  var GenStateSuspendedStart = "suspendedStart";
+  var GenStateSuspendedYield = "suspendedYield";
+  var GenStateExecuting = "executing";
+  var GenStateCompleted = "completed";
 
-AbstractPouchDB.prototype.removeAttachment =
-  adapterFun('removeAttachment', function (docId, attachmentId, rev,
-                                                 callback) {
-  var self = this;
-  self.get(docId, function (err, obj) {
-    /* istanbul ignore if */
-    if (err) {
-      callback(err);
-      return;
-    }
-    if (obj._rev !== rev) {
-      callback(createError(REV_CONFLICT));
-      return;
-    }
-    /* istanbul ignore if */
-    if (!obj._attachments) {
-      return callback();
-    }
-    delete obj._attachments[attachmentId];
-    if (Object.keys(obj._attachments).length === 0) {
-      delete obj._attachments;
-    }
-    self.put(obj, callback);
-  });
-});
+  // Returning this object from the innerFn has the same effect as
+  // breaking out of the dispatch switch statement.
+  var ContinueSentinel = {};
 
-AbstractPouchDB.prototype.remove =
-  adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
-  var doc;
-  if (typeof optsOrRev === 'string') {
-    // id, rev, opts, callback style
-    doc = {
-      _id: docOrId,
-      _rev: optsOrRev
-    };
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-  } else {
-    // doc, opts, callback style
-    doc = docOrId;
-    if (typeof optsOrRev === 'function') {
-      callback = optsOrRev;
-      opts = {};
-    } else {
-      callback = opts;
-      opts = optsOrRev;
-    }
-  }
-  opts = opts || {};
-  opts.was_delete = true;
-  var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)};
-  newDoc._deleted = true;
-  if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') {
-    return this._removeLocal(doc, callback);
-  }
-  this.bulkDocs({docs: [newDoc]}, opts, yankError(callback, newDoc._id));
-});
+  // Dummy constructor functions that we use as the .constructor and
+  // .constructor.prototype properties for functions that return Generator
+  // objects. For full spec compliance, you may wish to configure your
+  // minifier not to mangle the names of these two functions.
+  function Generator() {}
+  function GeneratorFunction() {}
+  function GeneratorFunctionPrototype() {}
 
-AbstractPouchDB.prototype.revsDiff =
-  adapterFun('revsDiff', function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  var ids = Object.keys(req);
+  // This is a polyfill for %IteratorPrototype% for environments that
+  // don't natively support it.
+  var IteratorPrototype = {};
+  IteratorPrototype[iteratorSymbol] = function () {
+    return this;
+  };
 
-  if (!ids.length) {
-    return callback(null, {});
+  var getProto = Object.getPrototypeOf;
+  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+  if (NativeIteratorPrototype &&
+      NativeIteratorPrototype !== Op &&
+      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
+    // This environment has a native %IteratorPrototype%; use it instead
+    // of the polyfill.
+    IteratorPrototype = NativeIteratorPrototype;
   }
 
-  var count = 0;
-  var missing = new ExportedMap();
+  var Gp = GeneratorFunctionPrototype.prototype =
+    Generator.prototype = Object.create(IteratorPrototype);
+  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
+  GeneratorFunctionPrototype.constructor = GeneratorFunction;
+  GeneratorFunctionPrototype[toStringTagSymbol] =
+    GeneratorFunction.displayName = "GeneratorFunction";
 
-  function addToMissing(id, revId) {
-    if (!missing.has(id)) {
-      missing.set(id, {missing: []});
-    }
-    missing.get(id).missing.push(revId);
+  // Helper for defining the .next, .throw, and .return methods of the
+  // Iterator interface in terms of a single ._invoke method.
+  function defineIteratorMethods(prototype) {
+    ["next", "throw", "return"].forEach(function(method) {
+      prototype[method] = function(arg) {
+        return this._invoke(method, arg);
+      };
+    });
   }
 
-  function processDoc(id, rev_tree) {
-    // Is this fast enough? Maybe we should switch to a set simulated by a map
-    var missingForId = req[id].slice(0);
-    traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
-      opts) {
-        var rev = pos + '-' + revHash;
-        var idx = missingForId.indexOf(rev);
-        if (idx === -1) {
-          return;
-        }
+  runtime.isGeneratorFunction = function(genFun) {
+    var ctor = typeof genFun === "function" && genFun.constructor;
+    return ctor
+      ? ctor === GeneratorFunction ||
+        // For the native GeneratorFunction constructor, the best we can
+        // do is to check its .name property.
+        (ctor.displayName || ctor.name) === "GeneratorFunction"
+      : false;
+  };
 
-        missingForId.splice(idx, 1);
-        /* istanbul ignore if */
-        if (opts.status !== 'available') {
-          addToMissing(id, rev);
-        }
-      });
+  runtime.mark = function(genFun) {
+    if (Object.setPrototypeOf) {
+      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
+    } else {
+      genFun.__proto__ = GeneratorFunctionPrototype;
+      if (!(toStringTagSymbol in genFun)) {
+        genFun[toStringTagSymbol] = "GeneratorFunction";
+      }
+    }
+    genFun.prototype = Object.create(Gp);
+    return genFun;
+  };
 
-    // Traversing the tree is synchronous, so now `missingForId` contains
-    // revisions that were not found in the tree
-    missingForId.forEach(function (rev) {
-      addToMissing(id, rev);
-    });
-  }
+  // Within the body of any async function, `await x` is transformed to
+  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
+  // `hasOwn.call(value, "__await")` to determine if the yielded value is
+  // meant to be awaited.
+  runtime.awrap = function(arg) {
+    return { __await: arg };
+  };
 
-  ids.map(function (id) {
-    this._getRevisionTree(id, function (err, rev_tree) {
-      if (err && err.status === 404 && err.message === 'missing') {
-        missing.set(id, {missing: req[id]});
-      } else if (err) {
-        /* istanbul ignore next */
-        return callback(err);
+  function AsyncIterator(generator) {
+    function invoke(method, arg, resolve, reject) {
+      var record = tryCatch(generator[method], generator, arg);
+      if (record.type === "throw") {
+        reject(record.arg);
       } else {
-        processDoc(id, rev_tree);
-      }
+        var result = record.arg;
+        var value = result.value;
+        if (value &&
+            typeof value === "object" &&
+            hasOwn.call(value, "__await")) {
+          return Promise.resolve(value.__await).then(function(value) {
+            invoke("next", value, resolve, reject);
+          }, function(err) {
+            invoke("throw", err, resolve, reject);
+          });
+        }
 
-      if (++count === ids.length) {
-        // convert LazyMap to object
-        var missingObj = {};
-        missing.forEach(function (value, key) {
-          missingObj[key] = value;
-        });
-        return callback(null, missingObj);
+        return Promise.resolve(value).then(function(unwrapped) {
+          // When a yielded Promise is resolved, its final value becomes
+          // the .value of the Promise<{value,done}> result for the
+          // current iteration. If the Promise is rejected, however, the
+          // result for this iteration will be rejected with the same
+          // reason. Note that rejections of yielded Promises are not
+          // thrown back into the generator function, as is the case
+          // when an awaited Promise is rejected. This difference in
+          // behavior between yield and await is important, because it
+          // allows the consumer to decide what to do with the yielded
+          // rejection (swallow it and continue, manually .throw it back
+          // into the generator, abandon iteration, whatever). With
+          // await, by contrast, there is no opportunity to examine the
+          // rejection reason outside the generator function, so the
+          // only option is to throw it from the await expression, and
+          // let the generator function handle the exception.
+          result.value = unwrapped;
+          resolve(result);
+        }, reject);
       }
-    });
-  }, this);
-});
+    }
 
-// _bulk_get API for faster replication, as described in
-// https://github.com/apache/couchdb-chttpd/pull/33
-// At the "abstract" level, it will just run multiple get()s in
-// parallel, because this isn't much of a performance cost
-// for local databases (except the cost of multiple transactions, which is
-// small). The http adapter overrides this in order
-// to do a more efficient single HTTP request.
-AbstractPouchDB.prototype.bulkGet =
-  adapterFun('bulkGet', function (opts, callback) {
-  bulkGet(this, opts, callback);
-});
+    var previousPromise;
 
-// compact one document and fire callback
-// by compacting we mean removing all revisions which
-// are further from the leaf in revision tree than max_height
-AbstractPouchDB.prototype.compactDocument =
-  adapterFun('compactDocument', function (docId, maxHeight, callback) {
-  var self = this;
-  this._getRevisionTree(docId, function (err, revTree) {
-    /* istanbul ignore if */
-    if (err) {
-      return callback(err);
-    }
-    var height = computeHeight(revTree);
-    var candidates = [];
-    var revs = [];
-    Object.keys(height).forEach(function (rev) {
-      if (height[rev] > maxHeight) {
-        candidates.push(rev);
+    function enqueue(method, arg) {
+      function callInvokeWithMethodAndArg() {
+        return new Promise(function(resolve, reject) {
+          invoke(method, arg, resolve, reject);
+        });
       }
-    });
 
-    traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) {
-      var rev = pos + '-' + revHash;
-      if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
-        revs.push(rev);
-      }
-    });
-    self._doCompaction(docId, revs, callback);
-  });
-});
+      return previousPromise =
+        // If enqueue has been called before, then we want to wait until
+        // all previous Promises have been resolved before calling invoke,
+        // so that results are always delivered in the correct order. If
+        // enqueue has not been called before, then it is important to
+        // call invoke immediately, without waiting on a callback to fire,
+        // so that the async generator function has the opportunity to do
+        // any necessary setup in a predictable way. This predictability
+        // is why the Promise constructor synchronously invokes its
+        // executor callback, and why async functions synchronously
+        // execute code before the first await. Since we implement simple
+        // async functions in terms of async generators, it is especially
+        // important to get this right, even though it requires care.
+        previousPromise ? previousPromise.then(
+          callInvokeWithMethodAndArg,
+          // Avoid propagating failures to Promises returned by later
+          // invocations of the iterator.
+          callInvokeWithMethodAndArg
+        ) : callInvokeWithMethodAndArg();
+    }
 
-// compact the whole database using single document
-// compaction
-AbstractPouchDB.prototype.compact =
-  adapterFun('compact', function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
+    // Define the unified helper method that is used to implement .next,
+    // .throw, and .return (see defineIteratorMethods).
+    this._invoke = enqueue;
   }
 
-  var self = this;
-  opts = opts || {};
+  defineIteratorMethods(AsyncIterator.prototype);
+  AsyncIterator.prototype[asyncIteratorSymbol] = function () {
+    return this;
+  };
+  runtime.AsyncIterator = AsyncIterator;
 
-  self._compactionQueue = self._compactionQueue || [];
-  self._compactionQueue.push({opts: opts, callback: callback});
-  if (self._compactionQueue.length === 1) {
-    doNextCompaction(self);
-  }
-});
-AbstractPouchDB.prototype._compact = function (opts, callback) {
-  var self = this;
-  var changesOpts = {
-    return_docs: false,
-    last_seq: opts.last_seq || 0
+  // Note that simple async functions are implemented on top of
+  // AsyncIterator objects; they just return a Promise for the value of
+  // the final result produced by the iterator.
+  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
+    var iter = new AsyncIterator(
+      wrap(innerFn, outerFn, self, tryLocsList)
+    );
+
+    return runtime.isGeneratorFunction(outerFn)
+      ? iter // If outerFn is a generator, return the full iterator.
+      : iter.next().then(function(result) {
+          return result.done ? result.value : iter.next();
+        });
   };
-  var promises = [];
 
-  function onChange(row) {
-    promises.push(self.compactDocument(row.id, 0));
-  }
-  function onComplete(resp) {
-    var lastSeq = resp.last_seq;
-    Promise.all(promises).then(function () {
-      return upsert(self, '_local/compaction', function deltaFunc(doc) {
-        if (!doc.last_seq || doc.last_seq < lastSeq) {
-          doc.last_seq = lastSeq;
-          return doc;
+  function makeInvokeMethod(innerFn, self, context) {
+    var state = GenStateSuspendedStart;
+
+    return function invoke(method, arg) {
+      if (state === GenStateExecuting) {
+        throw new Error("Generator is already running");
+      }
+
+      if (state === GenStateCompleted) {
+        if (method === "throw") {
+          throw arg;
         }
-        return false; // somebody else got here first, don't update
-      });
-    }).then(function () {
-      callback(null, {ok: true});
-    }).catch(callback);
-  }
-  self.changes(changesOpts)
-    .on('change', onChange)
-    .on('complete', onComplete)
-    .on('error', callback);
-};
 
-/* Begin api wrappers. Specific functionality to storage belongs in the
-   _[method] */
-AbstractPouchDB.prototype.get = adapterFun('get', function (id, opts, cb) {
-  if (typeof opts === 'function') {
-    cb = opts;
-    opts = {};
-  }
-  if (typeof id !== 'string') {
-    return cb(createError(INVALID_ID));
-  }
-  if (isLocalId(id) && typeof this._getLocal === 'function') {
-    return this._getLocal(id, cb);
-  }
-  var leaves = [], self = this;
+        // Be forgiving, per 25.3.3.3.3 of the spec:
+        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
+        return doneResult();
+      }
 
-  function finishOpenRevs() {
-    var result = [];
-    var count = leaves.length;
-    /* istanbul ignore if */
-    if (!count) {
-      return cb(null, result);
-    }
+      context.method = method;
+      context.arg = arg;
 
-    // order with open_revs is unspecified
-    leaves.forEach(function (leaf) {
-      self.get(id, {
-        rev: leaf,
-        revs: opts.revs,
-        latest: opts.latest,
-        attachments: opts.attachments,
-        binary: opts.binary
-      }, function (err, doc) {
-        if (!err) {
-          // using latest=true can produce duplicates
-          var existing;
-          for (var i = 0, l = result.length; i < l; i++) {
-            if (result[i].ok && result[i].ok._rev === doc._rev) {
-              existing = true;
-              break;
-            }
-          }
-          if (!existing) {
-            result.push({ok: doc});
+      while (true) {
+        var delegate = context.delegate;
+        if (delegate) {
+          var delegateResult = maybeInvokeDelegate(delegate, context);
+          if (delegateResult) {
+            if (delegateResult === ContinueSentinel) continue;
+            return delegateResult;
           }
-        } else {
-          result.push({missing: leaf});
         }
-        count--;
-        if (!count) {
-          cb(null, result);
-        }
-      });
-    });
-  }
 
-  if (opts.open_revs) {
-    if (opts.open_revs === "all") {
-      this._getRevisionTree(id, function (err, rev_tree) {
-        /* istanbul ignore if */
-        if (err) {
-          return cb(err);
+        if (context.method === "next") {
+          // Setting context._sent for legacy support of Babel's
+          // function.sent implementation.
+          context.sent = context._sent = context.arg;
+
+        } else if (context.method === "throw") {
+          if (state === GenStateSuspendedStart) {
+            state = GenStateCompleted;
+            throw context.arg;
+          }
+
+          context.dispatchException(context.arg);
+
+        } else if (context.method === "return") {
+          context.abrupt("return", context.arg);
         }
-        leaves = collectLeaves(rev_tree).map(function (leaf) {
-          return leaf.rev;
-        });
-        finishOpenRevs();
-      });
-    } else {
-      if (Array.isArray(opts.open_revs)) {
-        leaves = opts.open_revs;
-        for (var i = 0; i < leaves.length; i++) {
-          var l = leaves[i];
-          // looks like it's the only thing couchdb checks
-          if (!(typeof (l) === "string" && /^\d+-/.test(l))) {
-            return cb(createError(INVALID_REV));
+
+        state = GenStateExecuting;
+
+        var record = tryCatch(innerFn, self, context);
+        if (record.type === "normal") {
+          // If an exception is thrown from innerFn, we leave state ===
+          // GenStateExecuting and loop back for another invocation.
+          state = context.done
+            ? GenStateCompleted
+            : GenStateSuspendedYield;
+
+          if (record.arg === ContinueSentinel) {
+            continue;
           }
+
+          return {
+            value: record.arg,
+            done: context.done
+          };
+
+        } else if (record.type === "throw") {
+          state = GenStateCompleted;
+          // Dispatch the exception by looping back around to the
+          // context.dispatchException(context.arg) call above.
+          context.method = "throw";
+          context.arg = record.arg;
         }
-        finishOpenRevs();
-      } else {
-        return cb(createError(UNKNOWN_ERROR, 'function_clause'));
       }
-    }
-    return; // open_revs does not like other options
+    };
   }
 
-  return this._get(id, opts, function (err, result) {
-    if (err) {
-      err.docId = id;
-      return cb(err);
-    }
+  // Call delegate.iterator[context.method](context.arg) and handle the
+  // result, either by returning a { value, done } result from the
+  // delegate iterator, or by modifying context.method and context.arg,
+  // setting context.delegate to null, and returning the ContinueSentinel.
+  function maybeInvokeDelegate(delegate, context) {
+    var method = delegate.iterator[context.method];
+    if (method === undefined) {
+      // A .throw or .return when the delegate iterator has no .throw
+      // method always terminates the yield* loop.
+      context.delegate = null;
 
-    var doc = result.doc;
-    var metadata = result.metadata;
-    var ctx = result.ctx;
+      if (context.method === "throw") {
+        if (delegate.iterator.return) {
+          // If the delegate iterator has a return method, give it a
+          // chance to clean up.
+          context.method = "return";
+          context.arg = undefined;
+          maybeInvokeDelegate(delegate, context);
 
-    if (opts.conflicts) {
-      var conflicts = collectConflicts(metadata);
-      if (conflicts.length) {
-        doc._conflicts = conflicts;
+          if (context.method === "throw") {
+            // If maybeInvokeDelegate(context) changed context.method from
+            // "return" to "throw", let that override the TypeError below.
+            return ContinueSentinel;
+          }
+        }
+
+        context.method = "throw";
+        context.arg = new TypeError(
+          "The iterator does not provide a 'throw' method");
       }
-    }
 
-    if (isDeleted(metadata, doc._rev)) {
-      doc._deleted = true;
+      return ContinueSentinel;
     }
 
-    if (opts.revs || opts.revs_info) {
-      var splittedRev = doc._rev.split('-');
-      var revNo       = parseInt(splittedRev[0], 10);
-      var revHash     = splittedRev[1];
+    var record = tryCatch(method, delegate.iterator, context.arg);
 
-      var paths = rootToLeaf(metadata.rev_tree);
-      var path = null;
+    if (record.type === "throw") {
+      context.method = "throw";
+      context.arg = record.arg;
+      context.delegate = null;
+      return ContinueSentinel;
+    }
 
-      for (var i = 0; i < paths.length; i++) {
-        var currentPath = paths[i];
-        var hashIndex = currentPath.ids.map(function (x) { return x.id; })
-          .indexOf(revHash);
-        var hashFoundAtRevPos = hashIndex === (revNo - 1);
+    var info = record.arg;
 
-        if (hashFoundAtRevPos || (!path && hashIndex !== -1)) {
-          path = currentPath;
-        }
-      }
+    if (! info) {
+      context.method = "throw";
+      context.arg = new TypeError("iterator result is not an object");
+      context.delegate = null;
+      return ContinueSentinel;
+    }
 
-      var indexOfRev = path.ids.map(function (x) { return x.id; })
-        .indexOf(doc._rev.split('-')[1]) + 1;
-      var howMany = path.ids.length - indexOfRev;
-      path.ids.splice(indexOfRev, howMany);
-      path.ids.reverse();
+    if (info.done) {
+      // Assign the result of the finished delegate to the temporary
+      // variable specified by delegate.resultName (see delegateYield).
+      context[delegate.resultName] = info.value;
 
-      if (opts.revs) {
-        doc._revisions = {
-          start: (path.pos + path.ids.length) - 1,
-          ids: path.ids.map(function (rev) {
-            return rev.id;
-          })
-        };
-      }
-      if (opts.revs_info) {
-        var pos =  path.pos + path.ids.length;
-        doc._revs_info = path.ids.map(function (rev) {
-          pos--;
-          return {
-            rev: pos + '-' + rev.id,
-            status: rev.opts.status
-          };
-        });
-      }
-    }
+      // Resume execution at the desired location (see delegateYield).
+      context.next = delegate.nextLoc;
 
-    if (opts.attachments && doc._attachments) {
-      var attachments = doc._attachments;
-      var count = Object.keys(attachments).length;
-      if (count === 0) {
-        return cb(null, doc);
+      // If context.method was "throw" but the delegate handled the
+      // exception, let the outer generator proceed normally. If
+      // context.method was "next", forget context.arg since it has been
+      // "consumed" by the delegate iterator. If context.method was
+      // "return", allow the original .return call to continue in the
+      // outer generator.
+      if (context.method !== "return") {
+        context.method = "next";
+        context.arg = undefined;
       }
-      Object.keys(attachments).forEach(function (key) {
-        this._getAttachment(doc._id, key, attachments[key], {
-          // Previously the revision handling was done in adapter.js
-          // getAttachment, however since idb-next doesnt we need to
-          // pass the rev through
-          rev: doc._rev,
-          binary: opts.binary,
-          ctx: ctx
-        }, function (err, data) {
-          var att = doc._attachments[key];
-          att.data = data;
-          delete att.stub;
-          delete att.length;
-          if (!--count) {
-            cb(null, doc);
-          }
-        });
-      }, self);
+
     } else {
-      if (doc._attachments) {
-        for (var key in doc._attachments) {
-          /* istanbul ignore else */
-          if (doc._attachments.hasOwnProperty(key)) {
-            doc._attachments[key].stub = true;
-          }
-        }
-      }
-      cb(null, doc);
+      // Re-yield the result returned by the delegate method.
+      return info;
     }
-  });
-});
 
-// TODO: I dont like this, it forces an extra read for every
-// attachment read and enforces a confusing api between
-// adapter.js and the adapter implementation
-AbstractPouchDB.prototype.getAttachment =
-  adapterFun('getAttachment', function (docId, attachmentId, opts, callback) {
-  var self = this;
-  if (opts instanceof Function) {
-    callback = opts;
-    opts = {};
+    // The delegate iterator is finished, so forget it and continue with
+    // the outer generator.
+    context.delegate = null;
+    return ContinueSentinel;
   }
-  this._get(docId, opts, function (err, res) {
-    if (err) {
-      return callback(err);
+
+  // Define Generator.prototype.{next,throw,return} in terms of the
+  // unified ._invoke helper method.
+  defineIteratorMethods(Gp);
+
+  Gp[toStringTagSymbol] = "Generator";
+
+  // A Generator should always return itself as the iterator object when the
+  // @@iterator function is called on it. Some browsers' implementations of the
+  // iterator prototype chain incorrectly implement this, causing the Generator
+  // object to not be returned from this call. This ensures that doesn't happen.
+  // See https://github.com/facebook/regenerator/issues/274 for more details.
+  Gp[iteratorSymbol] = function() {
+    return this;
+  };
+
+  Gp.toString = function() {
+    return "[object Generator]";
+  };
+
+  function pushTryEntry(locs) {
+    var entry = { tryLoc: locs[0] };
+
+    if (1 in locs) {
+      entry.catchLoc = locs[1];
     }
-    if (res.doc._attachments && res.doc._attachments[attachmentId]) {
-      opts.ctx = res.ctx;
-      opts.binary = true;
-      self._getAttachment(docId, attachmentId,
-                          res.doc._attachments[attachmentId], opts, callback);
-    } else {
-      return callback(createError(MISSING_DOC));
+
+    if (2 in locs) {
+      entry.finallyLoc = locs[2];
+      entry.afterLoc = locs[3];
     }
-  });
-});
 
-AbstractPouchDB.prototype.allDocs =
-  adapterFun('allDocs', function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
+    this.tryEntries.push(entry);
   }
-  opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
-  if (opts.start_key) {
-    opts.startkey = opts.start_key;
+
+  function resetTryEntry(entry) {
+    var record = entry.completion || {};
+    record.type = "normal";
+    delete record.arg;
+    entry.completion = record;
   }
-  if (opts.end_key) {
-    opts.endkey = opts.end_key;
+
+  function Context(tryLocsList) {
+    // The root entry object (effectively a try statement without a catch
+    // or a finally block) gives us a place to store values thrown from
+    // locations where there is no enclosing try statement.
+    this.tryEntries = [{ tryLoc: "root" }];
+    tryLocsList.forEach(pushTryEntry, this);
+    this.reset(true);
   }
-  if ('keys' in opts) {
-    if (!Array.isArray(opts.keys)) {
-      return callback(new TypeError('options.keys must be an array'));
-    }
-    var incompatibleOpt =
-      ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
-      return incompatibleOpt in opts;
-    })[0];
-    if (incompatibleOpt) {
-      callback(createError(QUERY_PARSE_ERROR,
-        'Query parameter `' + incompatibleOpt +
-        '` is not compatible with multi-get'
-      ));
-      return;
+
+  runtime.keys = function(object) {
+    var keys = [];
+    for (var key in object) {
+      keys.push(key);
     }
-    if (!isRemote(this)) {
-      allDocsKeysParse(opts);
-      if (opts.keys.length === 0) {
-        return this._allDocs({limit: 0}, callback);
+    keys.reverse();
+
+    // Rather than returning an object with a next method, we keep
+    // things simple and return the next function itself.
+    return function next() {
+      while (keys.length) {
+        var key = keys.pop();
+        if (key in object) {
+          next.value = key;
+          next.done = false;
+          return next;
+        }
       }
-    }
-  }
 
-  return this._allDocs(opts, callback);
-});
+      // To avoid creating an additional object, we just hang the .value
+      // and .done properties off the next function object itself. This
+      // also ensures that the minifier will not anonymize the function.
+      next.done = true;
+      return next;
+    };
+  };
 
-AbstractPouchDB.prototype.changes = function (opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
+  function values(iterable) {
+    if (iterable) {
+      var iteratorMethod = iterable[iteratorSymbol];
+      if (iteratorMethod) {
+        return iteratorMethod.call(iterable);
+      }
 
-  opts = opts || {};
+      if (typeof iterable.next === "function") {
+        return iterable;
+      }
 
-  // By default set return_docs to false if the caller has opts.live = true,
-  // this will prevent us from collecting the set of changes indefinitely
-  // resulting in growing memory
-  opts.return_docs = ('return_docs' in opts) ? opts.return_docs : !opts.live;
+      if (!isNaN(iterable.length)) {
+        var i = -1, next = function next() {
+          while (++i < iterable.length) {
+            if (hasOwn.call(iterable, i)) {
+              next.value = iterable[i];
+              next.done = false;
+              return next;
+            }
+          }
 
-  return new Changes$1(this, opts, callback);
-};
+          next.value = undefined;
+          next.done = true;
 
-AbstractPouchDB.prototype.close = adapterFun('close', function (callback) {
-  this._closed = true;
-  this.emit('closed');
-  return this._close(callback);
-});
+          return next;
+        };
 
-AbstractPouchDB.prototype.info = adapterFun('info', function (callback) {
-  var self = this;
-  this._info(function (err, info) {
-    if (err) {
-      return callback(err);
+        return next.next = next;
+      }
     }
-    // assume we know better than the adapter, unless it informs us
-    info.db_name = info.db_name || self.name;
-    info.auto_compaction = !!(self.auto_compaction && !isRemote(self));
-    info.adapter = self.adapter;
-    callback(null, info);
-  });
-});
-
-AbstractPouchDB.prototype.id = adapterFun('id', function (callback) {
-  return this._id(callback);
-});
 
-/* istanbul ignore next */
-AbstractPouchDB.prototype.type = function () {
-  return (typeof this._type === 'function') ? this._type() : this.adapter;
-};
+    // Return an iterator with no values.
+    return { next: doneResult };
+  }
+  runtime.values = values;
 
-AbstractPouchDB.prototype.bulkDocs =
-  adapterFun('bulkDocs', function (req, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
+  function doneResult() {
+    return { value: undefined, done: true };
   }
 
-  opts = opts || {};
+  Context.prototype = {
+    constructor: Context,
 
-  if (Array.isArray(req)) {
-    req = {
-      docs: req
-    };
-  }
+    reset: function(skipTempReset) {
+      this.prev = 0;
+      this.next = 0;
+      // Resetting context._sent for legacy support of Babel's
+      // function.sent implementation.
+      this.sent = this._sent = undefined;
+      this.done = false;
+      this.delegate = null;
 
-  if (!req || !req.docs || !Array.isArray(req.docs)) {
-    return callback(createError(MISSING_BULK_DOCS));
-  }
+      this.method = "next";
+      this.arg = undefined;
 
-  for (var i = 0; i < req.docs.length; ++i) {
-    if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
-      return callback(createError(NOT_AN_OBJECT));
-    }
-  }
+      this.tryEntries.forEach(resetTryEntry);
 
-  var attachmentError;
-  req.docs.forEach(function (doc) {
-    if (doc._attachments) {
-      Object.keys(doc._attachments).forEach(function (name) {
-        attachmentError = attachmentError || attachmentNameError(name);
-        if (!doc._attachments[name].content_type) {
-          guardedConsole('warn', 'Attachment', name, 'on document', doc._id, 'is missing content_type');
+      if (!skipTempReset) {
+        for (var name in this) {
+          // Not sure about the optimal order of these conditions:
+          if (name.charAt(0) === "t" &&
+              hasOwn.call(this, name) &&
+              !isNaN(+name.slice(1))) {
+            this[name] = undefined;
+          }
         }
-      });
-    }
-  });
+      }
+    },
 
-  if (attachmentError) {
-    return callback(createError(BAD_REQUEST, attachmentError));
-  }
+    stop: function() {
+      this.done = true;
 
-  if (!('new_edits' in opts)) {
-    if ('new_edits' in req) {
-      opts.new_edits = req.new_edits;
-    } else {
-      opts.new_edits = true;
-    }
-  }
+      var rootEntry = this.tryEntries[0];
+      var rootRecord = rootEntry.completion;
+      if (rootRecord.type === "throw") {
+        throw rootRecord.arg;
+      }
 
-  var adapter = this;
-  if (!opts.new_edits && !isRemote(adapter)) {
-    // ensure revisions of the same doc are sorted, so that
-    // the local adapter processes them correctly (#2935)
-    req.docs.sort(compareByIdThenRev);
-  }
+      return this.rval;
+    },
 
-  cleanDocs(req.docs);
+    dispatchException: function(exception) {
+      if (this.done) {
+        throw exception;
+      }
 
-  // in the case of conflicts, we want to return the _ids to the user
-  // however, the underlying adapter may destroy the docs array, so
-  // create a copy here
-  var ids = req.docs.map(function (doc) {
-    return doc._id;
-  });
+      var context = this;
+      function handle(loc, caught) {
+        record.type = "throw";
+        record.arg = exception;
+        context.next = loc;
 
-  return this._bulkDocs(req, opts, function (err, res) {
-    if (err) {
-      return callback(err);
-    }
-    if (!opts.new_edits) {
-      // this is what couch does when new_edits is false
-      res = res.filter(function (x) {
-        return x.error;
-      });
-    }
-    // add ids for error/conflict responses (not required for CouchDB)
-    if (!isRemote(adapter)) {
-      for (var i = 0, l = res.length; i < l; i++) {
-        res[i].id = res[i].id || ids[i];
+        if (caught) {
+          // If the dispatched exception was caught by a catch block,
+          // then let that catch block handle the exception normally.
+          context.method = "next";
+          context.arg = undefined;
+        }
+
+        return !! caught;
       }
-    }
 
-    callback(null, res);
-  });
-});
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        var record = entry.completion;
 
-AbstractPouchDB.prototype.registerDependentDatabase =
-  adapterFun('registerDependentDatabase', function (dependentDb,
-                                                          callback) {
-  var depDB = new this.constructor(dependentDb, this.__opts);
+        if (entry.tryLoc === "root") {
+          // Exception thrown outside of any try block that could handle
+          // it, so set the completion value of the entire function to
+          // throw the exception.
+          return handle("end");
+        }
 
-  function diffFun(doc) {
-    doc.dependentDbs = doc.dependentDbs || {};
-    if (doc.dependentDbs[dependentDb]) {
-      return false; // no update required
-    }
-    doc.dependentDbs[dependentDb] = true;
-    return doc;
-  }
-  upsert(this, '_local/_pouch_dependentDbs', diffFun)
-    .then(function () {
-      callback(null, {db: depDB});
-    }).catch(callback);
-});
+        if (entry.tryLoc <= this.prev) {
+          var hasCatch = hasOwn.call(entry, "catchLoc");
+          var hasFinally = hasOwn.call(entry, "finallyLoc");
 
-AbstractPouchDB.prototype.destroy =
-  adapterFun('destroy', function (opts, callback) {
+          if (hasCatch && hasFinally) {
+            if (this.prev < entry.catchLoc) {
+              return handle(entry.catchLoc, true);
+            } else if (this.prev < entry.finallyLoc) {
+              return handle(entry.finallyLoc);
+            }
 
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
+          } else if (hasCatch) {
+            if (this.prev < entry.catchLoc) {
+              return handle(entry.catchLoc, true);
+            }
 
-  var self = this;
-  var usePrefix = 'use_prefix' in self ? self.use_prefix : true;
+          } else if (hasFinally) {
+            if (this.prev < entry.finallyLoc) {
+              return handle(entry.finallyLoc);
+            }
 
-  function destroyDb() {
-    // call destroy method of the particular adaptor
-    self._destroy(opts, function (err, resp) {
-      if (err) {
-        return callback(err);
+          } else {
+            throw new Error("try statement without catch or finally");
+          }
+        }
       }
-      self._destroyed = true;
-      self.emit('destroyed');
-      callback(null, resp || { 'ok': true });
-    });
-  }
+    },
 
-  if (isRemote(self)) {
-    // no need to check for dependent DBs if it's a remote DB
-    return destroyDb();
-  }
+    abrupt: function(type, arg) {
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        if (entry.tryLoc <= this.prev &&
+            hasOwn.call(entry, "finallyLoc") &&
+            this.prev < entry.finallyLoc) {
+          var finallyEntry = entry;
+          break;
+        }
+      }
 
-  self.get('_local/_pouch_dependentDbs', function (err, localDoc) {
-    if (err) {
-      /* istanbul ignore if */
-      if (err.status !== 404) {
-        return callback(err);
-      } else { // no dependencies
-        return destroyDb();
+      if (finallyEntry &&
+          (type === "break" ||
+           type === "continue") &&
+          finallyEntry.tryLoc <= arg &&
+          arg <= finallyEntry.finallyLoc) {
+        // Ignore the finally entry if control is not jumping to a
+        // location outside the try/catch block.
+        finallyEntry = null;
       }
-    }
-    var dependentDbs = localDoc.dependentDbs;
-    var PouchDB = self.constructor;
-    var deletedMap = Object.keys(dependentDbs).map(function (name) {
-      // use_prefix is only false in the browser
-      /* istanbul ignore next */
-      var trueName = usePrefix ?
-        name.replace(new RegExp('^' + PouchDB.prefix), '') : name;
-      return new PouchDB(trueName, self.__opts).destroy();
-    });
-    Promise.all(deletedMap).then(destroyDb, callback);
-  });
-});
 
-function TaskQueue() {
-  this.isReady = false;
-  this.failed = false;
-  this.queue = [];
-}
+      var record = finallyEntry ? finallyEntry.completion : {};
+      record.type = type;
+      record.arg = arg;
 
-TaskQueue.prototype.execute = function () {
-  var fun;
-  if (this.failed) {
-    while ((fun = this.queue.shift())) {
-      fun(this.failed);
-    }
-  } else {
-    while ((fun = this.queue.shift())) {
-      fun();
-    }
-  }
-};
+      if (finallyEntry) {
+        this.method = "next";
+        this.next = finallyEntry.finallyLoc;
+        return ContinueSentinel;
+      }
 
-TaskQueue.prototype.fail = function (err) {
-  this.failed = err;
-  this.execute();
-};
+      return this.complete(record);
+    },
 
-TaskQueue.prototype.ready = function (db) {
-  this.isReady = true;
-  this.db = db;
-  this.execute();
-};
+    complete: function(record, afterLoc) {
+      if (record.type === "throw") {
+        throw record.arg;
+      }
 
-TaskQueue.prototype.addTask = function (fun) {
-  this.queue.push(fun);
-  if (this.failed) {
-    this.execute();
-  }
-};
+      if (record.type === "break" ||
+          record.type === "continue") {
+        this.next = record.arg;
+      } else if (record.type === "return") {
+        this.rval = this.arg = record.arg;
+        this.method = "return";
+        this.next = "end";
+      } else if (record.type === "normal" && afterLoc) {
+        this.next = afterLoc;
+      }
 
-function parseAdapter(name, opts) {
-  var match = name.match(/([a-z-]*):\/\/(.*)/);
-  if (match) {
-    // the http adapter expects the fully qualified name
-    return {
-      name: /https?/.test(match[1]) ? match[1] + '://' + match[2] : match[2],
-      adapter: match[1]
-    };
-  }
+      return ContinueSentinel;
+    },
 
-  var adapters = PouchDB.adapters;
-  var preferredAdapters = PouchDB.preferredAdapters;
-  var prefix = PouchDB.prefix;
-  var adapterName = opts.adapter;
+    finish: function(finallyLoc) {
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        if (entry.finallyLoc === finallyLoc) {
+          this.complete(entry.completion, entry.afterLoc);
+          resetTryEntry(entry);
+          return ContinueSentinel;
+        }
+      }
+    },
 
-  if (!adapterName) { // automatically determine adapter
-    for (var i = 0; i < preferredAdapters.length; ++i) {
-      adapterName = preferredAdapters[i];
-      // check for browsers that have been upgraded from websql-only to websql+idb
-      /* istanbul ignore if */
-      if (adapterName === 'idb' && 'websql' in adapters &&
-          hasLocalStorage() && localStorage['_pouch__websqldb_' + prefix + name]) {
-        // log it, because this can be confusing during development
-        guardedConsole('log', 'PouchDB is downgrading "' + name + '" to WebSQL to' +
-          ' avoid data loss, because it was already opened with WebSQL.');
-        continue; // keep using websql to avoid user data loss
+    "catch": function(tryLoc) {
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        if (entry.tryLoc === tryLoc) {
+          var record = entry.completion;
+          if (record.type === "throw") {
+            var thrown = record.arg;
+            resetTryEntry(entry);
+          }
+          return thrown;
+        }
       }
-      break;
-    }
-  }
 
-  var adapter = adapters[adapterName];
+      // The context.catch method must only be called with a location
+      // argument that corresponds to a known catch block.
+      throw new Error("illegal catch attempt");
+    },
 
-  // if adapter is invalid, then an error will be thrown later
-  var usePrefix = (adapter && 'use_prefix' in adapter) ?
-    adapter.use_prefix : true;
+    delegateYield: function(iterable, resultName, nextLoc) {
+      this.delegate = {
+        iterator: values(iterable),
+        resultName: resultName,
+        nextLoc: nextLoc
+      };
 
-  return {
-    name: usePrefix ? (prefix + name) : name,
-    adapter: adapterName
+      if (this.method === "next") {
+        // Deliberately forget the last sent value so that we don't
+        // accidentally pass it on to the delegate.
+        this.arg = undefined;
+      }
+
+      return ContinueSentinel;
+    }
   };
-}
+})(
+  // In sloppy mode, unbound `this` refers to the global object, fallback to
+  // Function constructor if we're in global strict mode. That is sadly a form
+  // of indirect eval which violates Content Security Policy.
+  (function() { return this })() || Function("return this")()
+);
 
-// OK, so here's the deal. Consider this code:
-//     var db1 = new PouchDB('foo');
-//     var db2 = new PouchDB('foo');
-//     db1.destroy();
-// ^ these two both need to emit 'destroyed' events,
-// as well as the PouchDB constructor itself.
-// So we have one db object (whichever one got destroy() called on it)
-// responsible for emitting the initial event, which then gets emitted
-// by the constructor, which then broadcasts it to any other dbs
-// that may have been created with the same name.
-function prepareForDestruction(self) {
 
-  function onDestroyed(from_constructor) {
-    self.removeListener('closed', onClosed);
-    if (!from_constructor) {
-      self.constructor.emit('destroyed', self.name);
+/***/ }),
+/* 490 */
+/***/ ((module) => {
+
+(function () {
+  "use strict";
+
+  function btoa(str) {
+    var buffer;
+
+    if (str instanceof Buffer) {
+      buffer = str;
+    } else {
+      buffer = Buffer.from(str.toString(), 'binary');
     }
-  }
 
-  function onClosed() {
-    self.removeListener('destroyed', onDestroyed);
-    self.constructor.emit('unref', self);
+    return buffer.toString('base64');
   }
 
-  self.once('destroyed', onDestroyed);
-  self.once('closed', onClosed);
-  self.constructor.emit('ref', self);
+  module.exports = btoa;
+}());
+
+
+/***/ }),
+/* 491 */
+/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
+
+const fetchNode = __webpack_require__(492)
+const fetch = fetchNode.fetch.bind({})
+
+fetch.polyfill = true
+
+if (!global.fetch) {
+  global.fetch = fetch
+  global.Response = fetchNode.Response
+  global.Headers = fetchNode.Headers
+  global.Request = fetchNode.Request
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchDB, AbstractPouchDB);
-function PouchDB(name, opts) {
-  // In Node our test suite only tests this for PouchAlt unfortunately
-  /* istanbul ignore if */
-  if (!(this instanceof PouchDB)) {
-    return new PouchDB(name, opts);
-  }
 
-  var self = this;
-  opts = opts || {};
+/***/ }),
+/* 492 */
+/***/ ((module, exports, __webpack_require__) => {
 
-  if (name && typeof name === 'object') {
-    opts = name;
-    name = opts.name;
-    delete opts.name;
-  }
+const nodeFetch = __webpack_require__(493)
+const realFetch = nodeFetch.default || nodeFetch
 
-  if (opts.deterministic_revs === undefined) {
-    opts.deterministic_revs = true;
+const fetch = function (url, options) {
+  // Support schemaless URIs on the server for parity with the browser.
+  // Ex: //github.com/ -> https://github.com/
+  if (/^\/\//.test(url)) {
+    url = 'https:' + url
   }
+  return realFetch.call(this, url, options)
+}
 
-  this.__opts = opts = clone(opts);
+fetch.ponyfill = true
 
-  self.auto_compaction = opts.auto_compaction;
-  self.prefix = PouchDB.prefix;
+module.exports = exports = fetch
+exports.fetch = fetch
+exports.Headers = nodeFetch.Headers
+exports.Request = nodeFetch.Request
+exports.Response = nodeFetch.Response
 
-  if (typeof name !== 'string') {
-    throw new Error('Missing/invalid DB name');
-  }
+// Needed for TypeScript consumers without esModuleInterop.
+exports["default"] = fetch
 
-  var prefixedName = (opts.prefix || '') + name;
-  var backend = parseAdapter(prefixedName, opts);
 
-  opts.name = backend.name;
-  opts.adapter = opts.adapter || backend.adapter;
+/***/ }),
+/* 493 */
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-  self.name = name;
-  self._adapter = opts.adapter;
-  PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]);
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
+/* harmony export */   "Headers": () => (/* binding */ Headers),
+/* harmony export */   "Request": () => (/* binding */ Request),
+/* harmony export */   "Response": () => (/* binding */ Response),
+/* harmony export */   "FetchError": () => (/* binding */ FetchError)
+/* harmony export */ });
+/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82);
+/* harmony import */ var http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(80);
+/* harmony import */ var url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(63);
+/* harmony import */ var https__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(81);
+/* harmony import */ var zlib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(83);
 
-  if (!PouchDB.adapters[opts.adapter] ||
-      !PouchDB.adapters[opts.adapter].valid()) {
-    throw new Error('Invalid Adapter: ' + opts.adapter);
-  }
 
-  AbstractPouchDB.call(self);
-  self.taskqueue = new TaskQueue();
 
-  self.adapter = opts.adapter;
 
-  PouchDB.adapters[opts.adapter].call(self, opts, function (err) {
-    if (err) {
-      return self.taskqueue.fail(err);
-    }
-    prepareForDestruction(self);
 
-    self.emit('created', self);
-    PouchDB.emit('created', self.name);
-    self.taskqueue.ready(self);
-  });
 
-}
+// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
 
-// AbortController was introduced quite a while after fetch and
-// isnt required for PouchDB to function so polyfill if needed
-var a = (typeof AbortController !== 'undefined')
-    ? AbortController
-    : function () { return {abort: function () {}}; };
+// fix for "Readable" isn't a named export issue
+const Readable = stream__WEBPACK_IMPORTED_MODULE_0__.Readable;
 
-var f$1 = fetch;
-var h = Headers;
+const BUFFER = Symbol('buffer');
+const TYPE = Symbol('type');
 
-PouchDB.adapters = {};
-PouchDB.preferredAdapters = [];
+class Blob {
+	constructor() {
+		this[TYPE] = '';
 
-PouchDB.prefix = '_pouch_';
+		const blobParts = arguments[0];
+		const options = arguments[1];
 
-var eventEmitter = new events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
+		const buffers = [];
+		let size = 0;
 
-function setUpEventEmitter(Pouch) {
-  Object.keys(events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype).forEach(function (key) {
-    if (typeof events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype[key] === 'function') {
-      Pouch[key] = eventEmitter[key].bind(eventEmitter);
-    }
-  });
+		if (blobParts) {
+			const a = blobParts;
+			const length = Number(a.length);
+			for (let i = 0; i < length; i++) {
+				const element = a[i];
+				let buffer;
+				if (element instanceof Buffer) {
+					buffer = element;
+				} else if (ArrayBuffer.isView(element)) {
+					buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
+				} else if (element instanceof ArrayBuffer) {
+					buffer = Buffer.from(element);
+				} else if (element instanceof Blob) {
+					buffer = element[BUFFER];
+				} else {
+					buffer = Buffer.from(typeof element === 'string' ? element : String(element));
+				}
+				size += buffer.length;
+				buffers.push(buffer);
+			}
+		}
 
-  // these are created in constructor.js, and allow us to notify each DB with
-  // the same name that it was destroyed, via the constructor object
-  var destructListeners = Pouch._destructionListeners = new ExportedMap();
+		this[BUFFER] = Buffer.concat(buffers);
 
-  Pouch.on('ref', function onConstructorRef(db) {
-    if (!destructListeners.has(db.name)) {
-      destructListeners.set(db.name, []);
-    }
-    destructListeners.get(db.name).push(db);
-  });
+		let type = options && options.type !== undefined && String(options.type).toLowerCase();
+		if (type && !/[^\u0020-\u007E]/.test(type)) {
+			this[TYPE] = type;
+		}
+	}
+	get size() {
+		return this[BUFFER].length;
+	}
+	get type() {
+		return this[TYPE];
+	}
+	text() {
+		return Promise.resolve(this[BUFFER].toString());
+	}
+	arrayBuffer() {
+		const buf = this[BUFFER];
+		const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
+		return Promise.resolve(ab);
+	}
+	stream() {
+		const readable = new Readable();
+		readable._read = function () {};
+		readable.push(this[BUFFER]);
+		readable.push(null);
+		return readable;
+	}
+	toString() {
+		return '[object Blob]';
+	}
+	slice() {
+		const size = this.size;
 
-  Pouch.on('unref', function onConstructorUnref(db) {
-    if (!destructListeners.has(db.name)) {
-      return;
-    }
-    var dbList = destructListeners.get(db.name);
-    var pos = dbList.indexOf(db);
-    if (pos < 0) {
-      /* istanbul ignore next */
-      return;
-    }
-    dbList.splice(pos, 1);
-    if (dbList.length > 1) {
-      /* istanbul ignore next */
-      destructListeners.set(db.name, dbList);
-    } else {
-      destructListeners.delete(db.name);
-    }
-  });
+		const start = arguments[0];
+		const end = arguments[1];
+		let relativeStart, relativeEnd;
+		if (start === undefined) {
+			relativeStart = 0;
+		} else if (start < 0) {
+			relativeStart = Math.max(size + start, 0);
+		} else {
+			relativeStart = Math.min(start, size);
+		}
+		if (end === undefined) {
+			relativeEnd = size;
+		} else if (end < 0) {
+			relativeEnd = Math.max(size + end, 0);
+		} else {
+			relativeEnd = Math.min(end, size);
+		}
+		const span = Math.max(relativeEnd - relativeStart, 0);
 
-  Pouch.on('destroyed', function onConstructorDestroyed(name) {
-    if (!destructListeners.has(name)) {
-      return;
-    }
-    var dbList = destructListeners.get(name);
-    destructListeners.delete(name);
-    dbList.forEach(function (db) {
-      db.emit('destroyed',true);
-    });
-  });
+		const buffer = this[BUFFER];
+		const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
+		const blob = new Blob([], { type: arguments[2] });
+		blob[BUFFER] = slicedBuffer;
+		return blob;
+	}
 }
 
-setUpEventEmitter(PouchDB);
-
-PouchDB.adapter = function (id, obj, addToPreferredAdapters) {
-  /* istanbul ignore else */
-  if (obj.valid()) {
-    PouchDB.adapters[id] = obj;
-    if (addToPreferredAdapters) {
-      PouchDB.preferredAdapters.push(id);
-    }
-  }
-};
+Object.defineProperties(Blob.prototype, {
+	size: { enumerable: true },
+	type: { enumerable: true },
+	slice: { enumerable: true }
+});
 
-PouchDB.plugin = function (obj) {
-  if (typeof obj === 'function') { // function style for plugins
-    obj(PouchDB);
-  } else if (typeof obj !== 'object' || Object.keys(obj).length === 0) {
-    throw new Error('Invalid plugin: got "' + obj + '", expected an object or a function');
-  } else {
-    Object.keys(obj).forEach(function (id) { // object style for plugins
-      PouchDB.prototype[id] = obj[id];
-    });
-  }
-  if (this.__defaults) {
-    PouchDB.__defaults = $inject_Object_assign({}, this.__defaults);
-  }
-  return PouchDB;
-};
+Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
+	value: 'Blob',
+	writable: false,
+	enumerable: false,
+	configurable: true
+});
 
-PouchDB.defaults = function (defaultOpts) {
-  function PouchAlt(name, opts) {
-    if (!(this instanceof PouchAlt)) {
-      return new PouchAlt(name, opts);
-    }
+/**
+ * fetch-error.js
+ *
+ * FetchError interface for operational errors
+ */
 
-    opts = opts || {};
+/**
+ * Create FetchError instance
+ *
+ * @param   String      message      Error message for human
+ * @param   String      type         Error type for machine
+ * @param   String      systemError  For Node.js system error
+ * @return  FetchError
+ */
+function FetchError(message, type, systemError) {
+  Error.call(this, message);
 
-    if (name && typeof name === 'object') {
-      opts = name;
-      name = opts.name;
-      delete opts.name;
-    }
+  this.message = message;
+  this.type = type;
 
-    opts = $inject_Object_assign({}, PouchAlt.__defaults, opts);
-    PouchDB.call(this, name, opts);
+  // when err.type is `system`, err.code contains system error code
+  if (systemError) {
+    this.code = this.errno = systemError.code;
   }
 
-  inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchAlt, PouchDB);
+  // hide custom error implementation details from end-users
+  Error.captureStackTrace(this, this.constructor);
+}
 
-  PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice();
-  Object.keys(PouchDB).forEach(function (key) {
-    if (!(key in PouchAlt)) {
-      PouchAlt[key] = PouchDB[key];
-    }
-  });
+FetchError.prototype = Object.create(Error.prototype);
+FetchError.prototype.constructor = FetchError;
+FetchError.prototype.name = 'FetchError';
 
-  // make default options transitive
-  // https://github.com/pouchdb/pouchdb/issues/5922
-  PouchAlt.__defaults = $inject_Object_assign({}, this.__defaults, defaultOpts);
+let convert;
+try {
+	convert = require('encoding').convert;
+} catch (e) {}
 
-  return PouchAlt;
-};
+const INTERNALS = Symbol('Body internals');
 
-PouchDB.fetch = function (url, opts) {
-  return f$1(url, opts);
-};
+// fix an issue where "PassThrough" isn't a named export for node <10
+const PassThrough = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough;
 
-// managed automatically by set-version.js
-var version = "7.0.0";
+/**
+ * Body mixin
+ *
+ * Ref: https://fetch.spec.whatwg.org/#body
+ *
+ * @param   Stream  body  Readable stream
+ * @param   Object  opts  Response options
+ * @return  Void
+ */
+function Body(body) {
+	var _this = this;
 
-// this would just be "return doc[field]", but fields
-// can be "deep" due to dot notation
-function getFieldFromDoc(doc, parsedField) {
-  var value = doc;
-  for (var i = 0, len = parsedField.length; i < len; i++) {
-    var key = parsedField[i];
-    value = value[key];
-    if (!value) {
-      break;
-    }
-  }
-  return value;
-}
+	var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
+	    _ref$size = _ref.size;
 
-function compare$1(left, right) {
-  return left < right ? -1 : left > right ? 1 : 0;
-}
+	let size = _ref$size === undefined ? 0 : _ref$size;
+	var _ref$timeout = _ref.timeout;
+	let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
 
-// Converts a string in dot notation to an array of its components, with backslash escaping
-function parseField(fieldName) {
-  // fields may be deep (e.g. "foo.bar.baz"), so parse
-  var fields = [];
-  var current = '';
-  for (var i = 0, len = fieldName.length; i < len; i++) {
-    var ch = fieldName[i];
-    if (ch === '.') {
-      if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter
-        current = current.substring(0, current.length - 1) + '.';
-      } else { // not escaped, so delimiter
-        fields.push(current);
-        current = '';
-      }
-    } else { // normal character
-      current += ch;
-    }
-  }
-  fields.push(current);
-  return fields;
-}
+	if (body == null) {
+		// body is undefined or null
+		body = null;
+	} else if (isURLSearchParams(body)) {
+		// body is a URLSearchParams
+		body = Buffer.from(body.toString());
+	} else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
+		// body is ArrayBuffer
+		body = Buffer.from(body);
+	} else if (ArrayBuffer.isView(body)) {
+		// body is ArrayBufferView
+		body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
+	} else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) ; else {
+		// none of the above
+		// coerce to string then buffer
+		body = Buffer.from(String(body));
+	}
+	this[INTERNALS] = {
+		body,
+		disturbed: false,
+		error: null
+	};
+	this.size = size;
+	this.timeout = timeout;
 
-var combinationFields = ['$or', '$nor', '$not'];
-function isCombinationalField(field) {
-  return combinationFields.indexOf(field) > -1;
+	if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) {
+		body.on('error', function (err) {
+			const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);
+			_this[INTERNALS].error = error;
+		});
+	}
 }
 
-function getKey(obj) {
-  return Object.keys(obj)[0];
-}
+Body.prototype = {
+	get body() {
+		return this[INTERNALS].body;
+	},
 
-function getValue(obj) {
-  return obj[getKey(obj)];
-}
+	get bodyUsed() {
+		return this[INTERNALS].disturbed;
+	},
+
+	/**
+  * Decode response as ArrayBuffer
+  *
+  * @return  Promise
+  */
+	arrayBuffer() {
+		return consumeBody.call(this).then(function (buf) {
+			return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
+		});
+	},
+
+	/**
+  * Return raw response as Blob
+  *
+  * @return Promise
+  */
+	blob() {
+		let ct = this.headers && this.headers.get('content-type') || '';
+		return consumeBody.call(this).then(function (buf) {
+			return Object.assign(
+			// Prevent copying
+			new Blob([], {
+				type: ct.toLowerCase()
+			}), {
+				[BUFFER]: buf
+			});
+		});
+	},
+
+	/**
+  * Decode response as json
+  *
+  * @return  Promise
+  */
+	json() {
+		var _this2 = this;
+
+		return consumeBody.call(this).then(function (buffer) {
+			try {
+				return JSON.parse(buffer.toString());
+			} catch (err) {
+				return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));
+			}
+		});
+	},
+
+	/**
+  * Decode response as text
+  *
+  * @return  Promise
+  */
+	text() {
+		return consumeBody.call(this).then(function (buffer) {
+			return buffer.toString();
+		});
+	},
+
+	/**
+  * Decode response as buffer (non-spec api)
+  *
+  * @return  Promise
+  */
+	buffer() {
+		return consumeBody.call(this);
+	},
+
+	/**
+  * Decode response as text, while automatically detecting the encoding and
+  * trying to decode to UTF-8 (non-spec api)
+  *
+  * @return  Promise
+  */
+	textConverted() {
+		var _this3 = this;
+
+		return consumeBody.call(this).then(function (buffer) {
+			return convertBody(buffer, _this3.headers);
+		});
+	}
+};
 
+// In browsers, all properties are enumerable.
+Object.defineProperties(Body.prototype, {
+	body: { enumerable: true },
+	bodyUsed: { enumerable: true },
+	arrayBuffer: { enumerable: true },
+	blob: { enumerable: true },
+	json: { enumerable: true },
+	text: { enumerable: true }
+});
+
+Body.mixIn = function (proto) {
+	for (const name of Object.getOwnPropertyNames(Body.prototype)) {
+		// istanbul ignore else: future proof
+		if (!(name in proto)) {
+			const desc = Object.getOwnPropertyDescriptor(Body.prototype, name);
+			Object.defineProperty(proto, name, desc);
+		}
+	}
+};
+
+/**
+ * Consume and convert an entire Body to a Buffer.
+ *
+ * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
+ *
+ * @return  Promise
+ */
+function consumeBody() {
+	var _this4 = this;
+
+	if (this[INTERNALS].disturbed) {
+		return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));
+	}
 
-// flatten an array of selectors joined by an $and operator
-function mergeAndedSelectors(selectors) {
+	this[INTERNALS].disturbed = true;
 
-  // sort to ensure that e.g. if the user specified
-  // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into
-  // just {$gt: 'b'}
-  var res = {};
+	if (this[INTERNALS].error) {
+		return Body.Promise.reject(this[INTERNALS].error);
+	}
 
-  selectors.forEach(function (selector) {
-    Object.keys(selector).forEach(function (field) {
-      var matcher = selector[field];
-      if (typeof matcher !== 'object') {
-        matcher = {$eq: matcher};
-      }
+	let body = this.body;
 
-      if (isCombinationalField(field)) {
-        if (matcher instanceof Array) {
-          res[field] = matcher.map(function (m) {
-            return mergeAndedSelectors([m]);
-          });
-        } else {
-          res[field] = mergeAndedSelectors([matcher]);
-        }
-      } else {
-        var fieldMatchers = res[field] = res[field] || {};
-        Object.keys(matcher).forEach(function (operator) {
-          var value = matcher[operator];
+	// body is null
+	if (body === null) {
+		return Body.Promise.resolve(Buffer.alloc(0));
+	}
 
-          if (operator === '$gt' || operator === '$gte') {
-            return mergeGtGte(operator, value, fieldMatchers);
-          } else if (operator === '$lt' || operator === '$lte') {
-            return mergeLtLte(operator, value, fieldMatchers);
-          } else if (operator === '$ne') {
-            return mergeNe(value, fieldMatchers);
-          } else if (operator === '$eq') {
-            return mergeEq(value, fieldMatchers);
-          }
-          fieldMatchers[operator] = value;
-        });
-      }
-    });
-  });
+	// body is blob
+	if (isBlob(body)) {
+		body = body.stream();
+	}
 
-  return res;
-}
+	// body is buffer
+	if (Buffer.isBuffer(body)) {
+		return Body.Promise.resolve(body);
+	}
 
+	// istanbul ignore if: should never happen
+	if (!(body instanceof stream__WEBPACK_IMPORTED_MODULE_0__)) {
+		return Body.Promise.resolve(Buffer.alloc(0));
+	}
 
+	// body is stream
+	// get ready to actually consume the body
+	let accum = [];
+	let accumBytes = 0;
+	let abort = false;
 
-// collapse logically equivalent gt/gte values
-function mergeGtGte(operator, value, fieldMatchers) {
-  if (typeof fieldMatchers.$eq !== 'undefined') {
-    return; // do nothing
-  }
-  if (typeof fieldMatchers.$gte !== 'undefined') {
-    if (operator === '$gte') {
-      if (value > fieldMatchers.$gte) { // more specificity
-        fieldMatchers.$gte = value;
-      }
-    } else { // operator === '$gt'
-      if (value >= fieldMatchers.$gte) { // more specificity
-        delete fieldMatchers.$gte;
-        fieldMatchers.$gt = value;
-      }
-    }
-  } else if (typeof fieldMatchers.$gt !== 'undefined') {
-    if (operator === '$gte') {
-      if (value > fieldMatchers.$gt) { // more specificity
-        delete fieldMatchers.$gt;
-        fieldMatchers.$gte = value;
-      }
-    } else { // operator === '$gt'
-      if (value > fieldMatchers.$gt) { // more specificity
-        fieldMatchers.$gt = value;
-      }
-    }
-  } else {
-    fieldMatchers[operator] = value;
-  }
-}
+	return new Body.Promise(function (resolve, reject) {
+		let resTimeout;
 
-// collapse logically equivalent lt/lte values
-function mergeLtLte(operator, value, fieldMatchers) {
-  if (typeof fieldMatchers.$eq !== 'undefined') {
-    return; // do nothing
-  }
-  if (typeof fieldMatchers.$lte !== 'undefined') {
-    if (operator === '$lte') {
-      if (value < fieldMatchers.$lte) { // more specificity
-        fieldMatchers.$lte = value;
-      }
-    } else { // operator === '$gt'
-      if (value <= fieldMatchers.$lte) { // more specificity
-        delete fieldMatchers.$lte;
-        fieldMatchers.$lt = value;
-      }
-    }
-  } else if (typeof fieldMatchers.$lt !== 'undefined') {
-    if (operator === '$lte') {
-      if (value < fieldMatchers.$lt) { // more specificity
-        delete fieldMatchers.$lt;
-        fieldMatchers.$lte = value;
-      }
-    } else { // operator === '$gt'
-      if (value < fieldMatchers.$lt) { // more specificity
-        fieldMatchers.$lt = value;
-      }
-    }
-  } else {
-    fieldMatchers[operator] = value;
-  }
-}
+		// allow timeout on slow response body
+		if (_this4.timeout) {
+			resTimeout = setTimeout(function () {
+				abort = true;
+				reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));
+			}, _this4.timeout);
+		}
 
-// combine $ne values into one array
-function mergeNe(value, fieldMatchers) {
-  if ('$ne' in fieldMatchers) {
-    // there are many things this could "not" be
-    fieldMatchers.$ne.push(value);
-  } else { // doesn't exist yet
-    fieldMatchers.$ne = [value];
-  }
-}
+		// handle stream errors
+		body.on('error', function (err) {
+			if (err.name === 'AbortError') {
+				// if the request was aborted, reject with this Error
+				abort = true;
+				reject(err);
+			} else {
+				// other errors, such as incorrect content-encoding
+				reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));
+			}
+		});
 
-// add $eq into the mix
-function mergeEq(value, fieldMatchers) {
-  // these all have less specificity than the $eq
-  // TODO: check for user errors here
-  delete fieldMatchers.$gt;
-  delete fieldMatchers.$gte;
-  delete fieldMatchers.$lt;
-  delete fieldMatchers.$lte;
-  delete fieldMatchers.$ne;
-  fieldMatchers.$eq = value;
-}
+		body.on('data', function (chunk) {
+			if (abort || chunk === null) {
+				return;
+			}
 
+			if (_this4.size && accumBytes + chunk.length > _this4.size) {
+				abort = true;
+				reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));
+				return;
+			}
 
-//
-// normalize the selector
-//
-function massageSelector(input) {
-  var result = clone(input);
-  var wasAnded = false;
-  if ('$and' in result) {
-    result = mergeAndedSelectors(result['$and']);
-    wasAnded = true;
-  }
+			accumBytes += chunk.length;
+			accum.push(chunk);
+		});
 
-  ['$or', '$nor'].forEach(function (orOrNor) {
-    if (orOrNor in result) {
-      // message each individual selector
-      // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}}
-      result[orOrNor].forEach(function (subSelector) {
-        var fields = Object.keys(subSelector);
-        for (var i = 0; i < fields.length; i++) {
-          var field = fields[i];
-          var matcher = subSelector[field];
-          if (typeof matcher !== 'object' || matcher === null) {
-            subSelector[field] = {$eq: matcher};
-          }
-        }
-      });
-    }
-  });
+		body.on('end', function () {
+			if (abort) {
+				return;
+			}
 
-  if ('$not' in result) {
-    //This feels a little like forcing, but it will work for now,
-    //I would like to come back to this and make the merging of selectors a little more generic
-    result['$not'] = mergeAndedSelectors([result['$not']]);
-  }
+			clearTimeout(resTimeout);
 
-  var fields = Object.keys(result);
+			try {
+				resolve(Buffer.concat(accum, accumBytes));
+			} catch (err) {
+				// handle streams that have accumulated too much data (issue #414)
+				reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));
+			}
+		});
+	});
+}
 
-  for (var i = 0; i < fields.length; i++) {
-    var field = fields[i];
-    var matcher = result[field];
+/**
+ * Detect buffer encoding and convert to target encoding
+ * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
+ *
+ * @param   Buffer  buffer    Incoming buffer
+ * @param   String  encoding  Target encoding
+ * @return  String
+ */
+function convertBody(buffer, headers) {
+	if (typeof convert !== 'function') {
+		throw new Error('The package `encoding` must be installed to use the textConverted() function');
+	}
 
-    if (typeof matcher !== 'object' || matcher === null) {
-      matcher = {$eq: matcher};
-    } else if ('$ne' in matcher && !wasAnded) {
-      // I put these in an array, since there may be more than one
-      // but in the "mergeAnded" operation, I already take care of that
-      matcher.$ne = [matcher.$ne];
-    }
-    result[field] = matcher;
-  }
+	const ct = headers.get('content-type');
+	let charset = 'utf-8';
+	let res, str;
 
-  return result;
-}
+	// header
+	if (ct) {
+		res = /charset=([^;]*)/i.exec(ct);
+	}
 
-function pad(str, padWith, upToLength) {
-  var padding = '';
-  var targetLength = upToLength - str.length;
-  /* istanbul ignore next */
-  while (padding.length < targetLength) {
-    padding += padWith;
-  }
-  return padding;
-}
+	// no charset in content type, peek at response body for at most 1024 bytes
+	str = buffer.slice(0, 1024).toString();
 
-function padLeft(str, padWith, upToLength) {
-  var padding = pad(str, padWith, upToLength);
-  return padding + str;
-}
+	// html5
+	if (!res && str) {
+		res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
+	}
 
-var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
-var MAGNITUDE_DIGITS = 3; // ditto
-var SEP = ''; // set to '_' for easier debugging 
+	// html4
+	if (!res && str) {
+		res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
+		if (!res) {
+			res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str);
+			if (res) {
+				res.pop(); // drop last quote
+			}
+		}
 
-function collate(a, b) {
+		if (res) {
+			res = /charset=(.*)/i.exec(res.pop());
+		}
+	}
 
-  if (a === b) {
-    return 0;
-  }
+	// xml
+	if (!res && str) {
+		res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
+	}
 
-  a = normalizeKey(a);
-  b = normalizeKey(b);
+	// found charset
+	if (res) {
+		charset = res.pop();
 
-  var ai = collationIndex(a);
-  var bi = collationIndex(b);
-  if ((ai - bi) !== 0) {
-    return ai - bi;
-  }
-  switch (typeof a) {
-    case 'number':
-      return a - b;
-    case 'boolean':
-      return a < b ? -1 : 1;
-    case 'string':
-      return stringCollate(a, b);
-  }
-  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
-}
+		// prevent decode issues when sites use incorrect encoding
+		// ref: https://hsivonen.fi/encoding-menu/
+		if (charset === 'gb2312' || charset === 'gbk') {
+			charset = 'gb18030';
+		}
+	}
 
-// couch considers null/NaN/Infinity/-Infinity === undefined,
-// for the purposes of mapreduce indexes. also, dates get stringified.
-function normalizeKey(key) {
-  switch (typeof key) {
-    case 'undefined':
-      return null;
-    case 'number':
-      if (key === Infinity || key === -Infinity || isNaN(key)) {
-        return null;
-      }
-      return key;
-    case 'object':
-      var origKey = key;
-      if (Array.isArray(key)) {
-        var len = key.length;
-        key = new Array(len);
-        for (var i = 0; i < len; i++) {
-          key[i] = normalizeKey(origKey[i]);
-        }
-      /* istanbul ignore next */
-      } else if (key instanceof Date) {
-        return key.toJSON();
-      } else if (key !== null) { // generic object
-        key = {};
-        for (var k in origKey) {
-          if (origKey.hasOwnProperty(k)) {
-            var val = origKey[k];
-            if (typeof val !== 'undefined') {
-              key[k] = normalizeKey(val);
-            }
-          }
-        }
-      }
-  }
-  return key;
+	// turn raw buffers into a single utf-8 buffer
+	return convert(buffer, 'UTF-8', charset).toString();
 }
 
-function indexify(key) {
-  if (key !== null) {
-    switch (typeof key) {
-      case 'boolean':
-        return key ? 1 : 0;
-      case 'number':
-        return numToIndexableString(key);
-      case 'string':
-        // We've to be sure that key does not contain \u0000
-        // Do order-preserving replacements:
-        // 0 -> 1, 1
-        // 1 -> 1, 2
-        // 2 -> 2, 2
-        /* eslint-disable no-control-regex */
-        return key
-          .replace(/\u0002/g, '\u0002\u0002')
-          .replace(/\u0001/g, '\u0001\u0002')
-          .replace(/\u0000/g, '\u0001\u0001');
-        /* eslint-enable no-control-regex */
-      case 'object':
-        var isArray = Array.isArray(key);
-        var arr = isArray ? key : Object.keys(key);
-        var i = -1;
-        var len = arr.length;
-        var result = '';
-        if (isArray) {
-          while (++i < len) {
-            result += toIndexableString(arr[i]);
-          }
-        } else {
-          while (++i < len) {
-            var objKey = arr[i];
-            result += toIndexableString(objKey) +
-                toIndexableString(key[objKey]);
-          }
-        }
-        return result;
-    }
-  }
-  return '';
-}
+/**
+ * Detect a URLSearchParams object
+ * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143
+ *
+ * @param   Object  obj     Object to detect by type or brand
+ * @return  String
+ */
+function isURLSearchParams(obj) {
+	// Duck-typing as a necessary condition.
+	if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {
+		return false;
+	}
 
-// convert the given key to a string that would be appropriate
-// for lexical sorting, e.g. within a database, where the
-// sorting is the same given by the collate() function.
-function toIndexableString(key) {
-  var zero = '\u0000';
-  key = normalizeKey(key);
-  return collationIndex(key) + SEP + indexify(key) + zero;
+	// Brand-checking and more duck-typing as optional condition.
+	return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';
 }
 
-function parseNumber(str, i) {
-  var originalIdx = i;
-  var num;
-  var zero = str[i] === '1';
-  if (zero) {
-    num = 0;
-    i++;
-  } else {
-    var neg = str[i] === '0';
-    i++;
-    var numAsString = '';
-    var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
-    var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
-    /* istanbul ignore next */
-    if (neg) {
-      magnitude = -magnitude;
-    }
-    i += MAGNITUDE_DIGITS;
-    while (true) {
-      var ch = str[i];
-      if (ch === '\u0000') {
-        break;
-      } else {
-        numAsString += ch;
-      }
-      i++;
-    }
-    numAsString = numAsString.split('.');
-    if (numAsString.length === 1) {
-      num = parseInt(numAsString, 10);
-    } else {
-      /* istanbul ignore next */
-      num = parseFloat(numAsString[0] + '.' + numAsString[1]);
-    }
-    /* istanbul ignore next */
-    if (neg) {
-      num = num - 10;
-    }
-    /* istanbul ignore next */
-    if (magnitude !== 0) {
-      // parseFloat is more reliable than pow due to rounding errors
-      // e.g. Number.MAX_VALUE would return Infinity if we did
-      // num * Math.pow(10, magnitude);
-      num = parseFloat(num + 'e' + magnitude);
-    }
-  }
-  return {num: num, length : i - originalIdx};
+/**
+ * Check if `obj` is a W3C `Blob` object (which `File` inherits from)
+ * @param  {*} obj
+ * @return {boolean}
+ */
+function isBlob(obj) {
+	return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);
 }
 
-// move up the stack while parsing
-// this function moved outside of parseIndexableString for performance
-function pop(stack, metaStack) {
-  var obj = stack.pop();
-
-  if (metaStack.length) {
-    var lastMetaElement = metaStack[metaStack.length - 1];
-    if (obj === lastMetaElement.element) {
-      // popping a meta-element, e.g. an object whose value is another object
-      metaStack.pop();
-      lastMetaElement = metaStack[metaStack.length - 1];
-    }
-    var element = lastMetaElement.element;
-    var lastElementIndex = lastMetaElement.index;
-    if (Array.isArray(element)) {
-      element.push(obj);
-    } else if (lastElementIndex === stack.length - 2) { // obj with key+value
-      var key = stack.pop();
-      element[key] = obj;
-    } else {
-      stack.push(obj); // obj with key only
-    }
-  }
-}
+/**
+ * Clone body given Res/Req instance
+ *
+ * @param   Mixed  instance  Response or Request instance
+ * @return  Mixed
+ */
+function clone(instance) {
+	let p1, p2;
+	let body = instance.body;
 
-function parseIndexableString(str) {
-  var stack = [];
-  var metaStack = []; // stack for arrays and objects
-  var i = 0;
+	// don't allow cloning a used body
+	if (instance.bodyUsed) {
+		throw new Error('cannot clone body after it is used');
+	}
 
-  /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
-  while (true) {
-    var collationIndex = str[i++];
-    if (collationIndex === '\u0000') {
-      if (stack.length === 1) {
-        return stack.pop();
-      } else {
-        pop(stack, metaStack);
-        continue;
-      }
-    }
-    switch (collationIndex) {
-      case '1':
-        stack.push(null);
-        break;
-      case '2':
-        stack.push(str[i] === '1');
-        i++;
-        break;
-      case '3':
-        var parsedNum = parseNumber(str, i);
-        stack.push(parsedNum.num);
-        i += parsedNum.length;
-        break;
-      case '4':
-        var parsedStr = '';
-        /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
-        while (true) {
-          var ch = str[i];
-          if (ch === '\u0000') {
-            break;
-          }
-          parsedStr += ch;
-          i++;
-        }
-        // perform the reverse of the order-preserving replacement
-        // algorithm (see above)
-        /* eslint-disable no-control-regex */
-        parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
-          .replace(/\u0001\u0002/g, '\u0001')
-          .replace(/\u0002\u0002/g, '\u0002');
-        /* eslint-enable no-control-regex */
-        stack.push(parsedStr);
-        break;
-      case '5':
-        var arrayElement = { element: [], index: stack.length };
-        stack.push(arrayElement.element);
-        metaStack.push(arrayElement);
-        break;
-      case '6':
-        var objElement = { element: {}, index: stack.length };
-        stack.push(objElement.element);
-        metaStack.push(objElement);
-        break;
-      /* istanbul ignore next */
-      default:
-        throw new Error(
-          'bad collationIndex or unexpectedly reached end of input: ' +
-            collationIndex);
-    }
-  }
-}
+	// check that body is a stream and not form-data object
+	// note: we can't clone the form-data object without having it as a dependency
+	if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__ && typeof body.getBoundary !== 'function') {
+		// tee instance body
+		p1 = new PassThrough();
+		p2 = new PassThrough();
+		body.pipe(p1);
+		body.pipe(p2);
+		// set instance body to teed body and return the other teed body
+		instance[INTERNALS].body = p1;
+		body = p2;
+	}
 
-function arrayCollate(a, b) {
-  var len = Math.min(a.length, b.length);
-  for (var i = 0; i < len; i++) {
-    var sort = collate(a[i], b[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-  }
-  return (a.length === b.length) ? 0 :
-    (a.length > b.length) ? 1 : -1;
-}
-function stringCollate(a, b) {
-  // See: https://github.com/daleharvey/pouchdb/issues/40
-  // This is incompatible with the CouchDB implementation, but its the
-  // best we can do for now
-  return (a === b) ? 0 : ((a > b) ? 1 : -1);
+	return body;
 }
-function objectCollate(a, b) {
-  var ak = Object.keys(a), bk = Object.keys(b);
-  var len = Math.min(ak.length, bk.length);
-  for (var i = 0; i < len; i++) {
-    // First sort the keys
-    var sort = collate(ak[i], bk[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-    // if the keys are equal sort the values
-    sort = collate(a[ak[i]], b[bk[i]]);
-    if (sort !== 0) {
-      return sort;
-    }
 
-  }
-  return (ak.length === bk.length) ? 0 :
-    (ak.length > bk.length) ? 1 : -1;
-}
-// The collation is defined by erlangs ordered terms
-// the atoms null, true, false come first, then numbers, strings,
-// arrays, then objects
-// null/undefined/NaN/Infinity/-Infinity are all considered null
-function collationIndex(x) {
-  var id = ['boolean', 'number', 'string', 'object'];
-  var idx = id.indexOf(typeof x);
-  //false if -1 otherwise true, but fast!!!!1
-  if (~idx) {
-    if (x === null) {
-      return 1;
-    }
-    if (Array.isArray(x)) {
-      return 5;
-    }
-    return idx < 3 ? (idx + 2) : (idx + 3);
-  }
-  /* istanbul ignore next */
-  if (Array.isArray(x)) {
-    return 5;
-  }
+/**
+ * Performs the operation "extract a `Content-Type` value from |object|" as
+ * specified in the specification:
+ * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
+ *
+ * This function assumes that instance.body is present.
+ *
+ * @param   Mixed  instance  Any options.body input
+ */
+function extractContentType(body) {
+	if (body === null) {
+		// body is null
+		return null;
+	} else if (typeof body === 'string') {
+		// body is string
+		return 'text/plain;charset=UTF-8';
+	} else if (isURLSearchParams(body)) {
+		// body is a URLSearchParams
+		return 'application/x-www-form-urlencoded;charset=UTF-8';
+	} else if (isBlob(body)) {
+		// body is blob
+		return body.type || null;
+	} else if (Buffer.isBuffer(body)) {
+		// body is buffer
+		return null;
+	} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
+		// body is ArrayBuffer
+		return null;
+	} else if (ArrayBuffer.isView(body)) {
+		// body is ArrayBufferView
+		return null;
+	} else if (typeof body.getBoundary === 'function') {
+		// detect form data input from form-data module
+		return `multipart/form-data;boundary=${body.getBoundary()}`;
+	} else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) {
+		// body is stream
+		// can't really do much about this
+		return null;
+	} else {
+		// Body constructor defaults other things to string
+		return 'text/plain;charset=UTF-8';
+	}
 }
 
-// conversion:
-// x yyy zz...zz
-// x = 0 for negative, 1 for 0, 2 for positive
-// y = exponent (for negative numbers negated) moved so that it's >= 0
-// z = mantisse
-function numToIndexableString(num) {
-
-  if (num === 0) {
-    return '1';
-  }
-
-  // convert number to exponential format for easier and
-  // more succinct string sorting
-  var expFormat = num.toExponential().split(/e\+?/);
-  var magnitude = parseInt(expFormat[1], 10);
+/**
+ * The Fetch Standard treats this as if "total bytes" is a property on the body.
+ * For us, we have to explicitly get it with a function.
+ *
+ * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
+ *
+ * @param   Body    instance   Instance of Body
+ * @return  Number?            Number of bytes, or null if not possible
+ */
+function getTotalBytes(instance) {
+	const body = instance.body;
 
-  var neg = num < 0;
 
-  var result = neg ? '0' : '2';
+	if (body === null) {
+		// body is null
+		return 0;
+	} else if (isBlob(body)) {
+		return body.size;
+	} else if (Buffer.isBuffer(body)) {
+		// body is buffer
+		return body.length;
+	} else if (body && typeof body.getLengthSync === 'function') {
+		// detect form data input from form-data module
+		if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x
+		body.hasKnownLength && body.hasKnownLength()) {
+			// 2.x
+			return body.getLengthSync();
+		}
+		return null;
+	} else {
+		// body is stream
+		return null;
+	}
+}
 
-  // first sort by magnitude
-  // it's easier if all magnitudes are positive
-  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
-  var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
+/**
+ * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
+ *
+ * @param   Body    instance   Instance of Body
+ * @return  Void
+ */
+function writeToStream(dest, instance) {
+	const body = instance.body;
 
-  result += SEP + magString;
 
-  // then sort by the factor
-  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
-  /* istanbul ignore next */
-  if (neg) { // for negative reverse ordering
-    factor = 10 - factor;
-  }
+	if (body === null) {
+		// body is null
+		dest.end();
+	} else if (isBlob(body)) {
+		body.stream().pipe(dest);
+	} else if (Buffer.isBuffer(body)) {
+		// body is buffer
+		dest.write(body);
+		dest.end();
+	} else {
+		// body is stream
+		body.pipe(dest);
+	}
+}
 
-  var factorStr = factor.toFixed(20);
+// expose Promise
+Body.Promise = global.Promise;
 
-  // strip zeros from the end
-  factorStr = factorStr.replace(/\.?0+$/, '');
+/**
+ * headers.js
+ *
+ * Headers class offers convenient helpers
+ */
 
-  result += SEP + factorStr;
+const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
+const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
 
-  return result;
+function validateName(name) {
+	name = `${name}`;
+	if (invalidTokenRegex.test(name) || name === '') {
+		throw new TypeError(`${name} is not a legal HTTP header name`);
+	}
 }
 
-// create a comparator based on the sort object
-function createFieldSorter(sort) {
-
-  function getFieldValuesAsArray(doc) {
-    return sort.map(function (sorting) {
-      var fieldName = getKey(sorting);
-      var parsedField = parseField(fieldName);
-      var docFieldValue = getFieldFromDoc(doc, parsedField);
-      return docFieldValue;
-    });
-  }
+function validateValue(value) {
+	value = `${value}`;
+	if (invalidHeaderCharRegex.test(value)) {
+		throw new TypeError(`${value} is not a legal HTTP header value`);
+	}
+}
 
-  return function (aRow, bRow) {
-    var aFieldValues = getFieldValuesAsArray(aRow.doc);
-    var bFieldValues = getFieldValuesAsArray(bRow.doc);
-    var collation = collate(aFieldValues, bFieldValues);
-    if (collation !== 0) {
-      return collation;
-    }
-    // this is what mango seems to do
-    return compare$1(aRow.doc._id, bRow.doc._id);
-  };
+/**
+ * Find the key in the map object given a header name.
+ *
+ * Returns undefined if not found.
+ *
+ * @param   String  name  Header name
+ * @return  String|Undefined
+ */
+function find(map, name) {
+	name = name.toLowerCase();
+	for (const key in map) {
+		if (key.toLowerCase() === name) {
+			return key;
+		}
+	}
+	return undefined;
 }
 
-function filterInMemoryFields(rows, requestDef, inMemoryFields) {
-  rows = rows.filter(function (row) {
-    return rowFilter(row.doc, requestDef.selector, inMemoryFields);
-  });
+const MAP = Symbol('map');
+class Headers {
+	/**
+  * Headers class
+  *
+  * @param   Object  headers  Response headers
+  * @return  Void
+  */
+	constructor() {
+		let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
 
-  if (requestDef.sort) {
-    // in-memory sort
-    var fieldSorter = createFieldSorter(requestDef.sort);
-    rows = rows.sort(fieldSorter);
-    if (typeof requestDef.sort[0] !== 'string' &&
-        getValue(requestDef.sort[0]) === 'desc') {
-      rows = rows.reverse();
-    }
-  }
+		this[MAP] = Object.create(null);
 
-  if ('limit' in requestDef || 'skip' in requestDef) {
-    // have to do the limit in-memory
-    var skip = requestDef.skip || 0;
-    var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip;
-    rows = rows.slice(skip, limit);
-  }
-  return rows;
-}
+		if (init instanceof Headers) {
+			const rawHeaders = init.raw();
+			const headerNames = Object.keys(rawHeaders);
 
-function rowFilter(doc, selector, inMemoryFields) {
-  return inMemoryFields.every(function (field) {
-    var matcher = selector[field];
-    var parsedField = parseField(field);
-    var docFieldValue = getFieldFromDoc(doc, parsedField);
-    if (isCombinationalField(field)) {
-      return matchCominationalSelector(field, matcher, doc);
-    }
+			for (const headerName of headerNames) {
+				for (const value of rawHeaders[headerName]) {
+					this.append(headerName, value);
+				}
+			}
 
-    return matchSelector(matcher, doc, parsedField, docFieldValue);
-  });
-}
+			return;
+		}
 
-function matchSelector(matcher, doc, parsedField, docFieldValue) {
-  if (!matcher) {
-    // no filtering necessary; this field is just needed for sorting
-    return true;
-  }
+		// We don't worry about converting prop to ByteString here as append()
+		// will handle it.
+		if (init == null) ; else if (typeof init === 'object') {
+			const method = init[Symbol.iterator];
+			if (method != null) {
+				if (typeof method !== 'function') {
+					throw new TypeError('Header pairs must be iterable');
+				}
 
-  return Object.keys(matcher).every(function (userOperator) {
-    var userValue = matcher[userOperator];
-    return match(userOperator, doc, userValue, parsedField, docFieldValue);
-  });
-}
+				// sequence<sequence<ByteString>>
+				// Note: per spec we have to first exhaust the lists then process them
+				const pairs = [];
+				for (const pair of init) {
+					if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
+						throw new TypeError('Each header pair must be iterable');
+					}
+					pairs.push(Array.from(pair));
+				}
 
-function matchCominationalSelector(field, matcher, doc) {
+				for (const pair of pairs) {
+					if (pair.length !== 2) {
+						throw new TypeError('Each header pair must be a name/value tuple');
+					}
+					this.append(pair[0], pair[1]);
+				}
+			} else {
+				// record<ByteString, ByteString>
+				for (const key of Object.keys(init)) {
+					const value = init[key];
+					this.append(key, value);
+				}
+			}
+		} else {
+			throw new TypeError('Provided initializer must be an object');
+		}
+	}
 
-  if (field === '$or') {
-    return matcher.some(function (orMatchers) {
-      return rowFilter(doc, orMatchers, Object.keys(orMatchers));
-    });
-  }
+	/**
+  * Return combined header value given name
+  *
+  * @param   String  name  Header name
+  * @return  Mixed
+  */
+	get(name) {
+		name = `${name}`;
+		validateName(name);
+		const key = find(this[MAP], name);
+		if (key === undefined) {
+			return null;
+		}
 
-  if (field === '$not') {
-    return !rowFilter(doc, matcher, Object.keys(matcher));
-  }
+		return this[MAP][key].join(', ');
+	}
 
-  //`$nor`
-  return !matcher.find(function (orMatchers) {
-    return rowFilter(doc, orMatchers, Object.keys(orMatchers));
-  });
+	/**
+  * Iterate over all headers
+  *
+  * @param   Function  callback  Executed for each item with parameters (value, name, thisArg)
+  * @param   Boolean   thisArg   `this` context for callback function
+  * @return  Void
+  */
+	forEach(callback) {
+		let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
 
-}
+		let pairs = getHeaders(this);
+		let i = 0;
+		while (i < pairs.length) {
+			var _pairs$i = pairs[i];
+			const name = _pairs$i[0],
+			      value = _pairs$i[1];
 
-function match(userOperator, doc, userValue, parsedField, docFieldValue) {
-  if (!matchers[userOperator]) {
-    throw new Error('unknown operator "' + userOperator +
-      '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' +
-      '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all');
-  }
-  return matchers[userOperator](doc, userValue, parsedField, docFieldValue);
-}
+			callback.call(thisArg, value, name, this);
+			pairs = getHeaders(this);
+			i++;
+		}
+	}
 
-function fieldExists(docFieldValue) {
-  return typeof docFieldValue !== 'undefined' && docFieldValue !== null;
-}
+	/**
+  * Overwrite header values given name
+  *
+  * @param   String  name   Header name
+  * @param   String  value  Header value
+  * @return  Void
+  */
+	set(name, value) {
+		name = `${name}`;
+		value = `${value}`;
+		validateName(name);
+		validateValue(value);
+		const key = find(this[MAP], name);
+		this[MAP][key !== undefined ? key : name] = [value];
+	}
+
+	/**
+  * Append a value onto existing header
+  *
+  * @param   String  name   Header name
+  * @param   String  value  Header value
+  * @return  Void
+  */
+	append(name, value) {
+		name = `${name}`;
+		value = `${value}`;
+		validateName(name);
+		validateValue(value);
+		const key = find(this[MAP], name);
+		if (key !== undefined) {
+			this[MAP][key].push(value);
+		} else {
+			this[MAP][name] = [value];
+		}
+	}
 
-function fieldIsNotUndefined(docFieldValue) {
-  return typeof docFieldValue !== 'undefined';
-}
+	/**
+  * Check for header name existence
+  *
+  * @param   String   name  Header name
+  * @return  Boolean
+  */
+	has(name) {
+		name = `${name}`;
+		validateName(name);
+		return find(this[MAP], name) !== undefined;
+	}
 
-function modField(docFieldValue, userValue) {
-  var divisor = userValue[0];
-  var mod = userValue[1];
-  if (divisor === 0) {
-    throw new Error('Bad divisor, cannot divide by zero');
-  }
+	/**
+  * Delete all header values given name
+  *
+  * @param   String  name  Header name
+  * @return  Void
+  */
+	delete(name) {
+		name = `${name}`;
+		validateName(name);
+		const key = find(this[MAP], name);
+		if (key !== undefined) {
+			delete this[MAP][key];
+		}
+	}
 
-  if (parseInt(divisor, 10) !== divisor ) {
-    throw new Error('Divisor is not an integer');
-  }
+	/**
+  * Return raw headers (non-spec api)
+  *
+  * @return  Object
+  */
+	raw() {
+		return this[MAP];
+	}
 
-  if (parseInt(mod, 10) !== mod ) {
-    throw new Error('Modulus is not an integer');
-  }
+	/**
+  * Get an iterator on keys.
+  *
+  * @return  Iterator
+  */
+	keys() {
+		return createHeadersIterator(this, 'key');
+	}
 
-  if (parseInt(docFieldValue, 10) !== docFieldValue) {
-    return false;
-  }
+	/**
+  * Get an iterator on values.
+  *
+  * @return  Iterator
+  */
+	values() {
+		return createHeadersIterator(this, 'value');
+	}
 
-  return docFieldValue % divisor === mod;
+	/**
+  * Get an iterator on entries.
+  *
+  * This is the default iterator of the Headers object.
+  *
+  * @return  Iterator
+  */
+	[Symbol.iterator]() {
+		return createHeadersIterator(this, 'key+value');
+	}
 }
+Headers.prototype.entries = Headers.prototype[Symbol.iterator];
 
-function arrayContainsValue(docFieldValue, userValue) {
-  return userValue.some(function (val) {
-    if (docFieldValue instanceof Array) {
-      return docFieldValue.indexOf(val) > -1;
-    }
+Object.defineProperty(Headers.prototype, Symbol.toStringTag, {
+	value: 'Headers',
+	writable: false,
+	enumerable: false,
+	configurable: true
+});
 
-    return docFieldValue === val;
-  });
-}
+Object.defineProperties(Headers.prototype, {
+	get: { enumerable: true },
+	forEach: { enumerable: true },
+	set: { enumerable: true },
+	append: { enumerable: true },
+	has: { enumerable: true },
+	delete: { enumerable: true },
+	keys: { enumerable: true },
+	values: { enumerable: true },
+	entries: { enumerable: true }
+});
 
-function arrayContainsAllValues(docFieldValue, userValue) {
-  return userValue.every(function (val) {
-    return docFieldValue.indexOf(val) > -1;
-  });
-}
+function getHeaders(headers) {
+	let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';
 
-function arraySize(docFieldValue, userValue) {
-  return docFieldValue.length === userValue;
+	const keys = Object.keys(headers[MAP]).sort();
+	return keys.map(kind === 'key' ? function (k) {
+		return k.toLowerCase();
+	} : kind === 'value' ? function (k) {
+		return headers[MAP][k].join(', ');
+	} : function (k) {
+		return [k.toLowerCase(), headers[MAP][k].join(', ')];
+	});
 }
 
-function regexMatch(docFieldValue, userValue) {
-  var re = new RegExp(userValue);
+const INTERNAL = Symbol('internal');
 
-  return re.test(docFieldValue);
+function createHeadersIterator(target, kind) {
+	const iterator = Object.create(HeadersIteratorPrototype);
+	iterator[INTERNAL] = {
+		target,
+		kind,
+		index: 0
+	};
+	return iterator;
 }
 
-function typeMatch(docFieldValue, userValue) {
+const HeadersIteratorPrototype = Object.setPrototypeOf({
+	next() {
+		// istanbul ignore if
+		if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
+			throw new TypeError('Value of `this` is not a HeadersIterator');
+		}
 
-  switch (userValue) {
-    case 'null':
-      return docFieldValue === null;
-    case 'boolean':
-      return typeof (docFieldValue) === 'boolean';
-    case 'number':
-      return typeof (docFieldValue) === 'number';
-    case 'string':
-      return typeof (docFieldValue) === 'string';
-    case 'array':
-      return docFieldValue instanceof Array;
-    case 'object':
-      return ({}).toString.call(docFieldValue) === '[object Object]';
-  }
+		var _INTERNAL = this[INTERNAL];
+		const target = _INTERNAL.target,
+		      kind = _INTERNAL.kind,
+		      index = _INTERNAL.index;
 
-  throw new Error(userValue + ' not supported as a type.' +
-                  'Please use one of object, string, array, number, boolean or null.');
+		const values = getHeaders(target, kind);
+		const len = values.length;
+		if (index >= len) {
+			return {
+				value: undefined,
+				done: true
+			};
+		}
 
-}
+		this[INTERNAL].index = index + 1;
 
-var matchers = {
+		return {
+			value: values[index],
+			done: false
+		};
+	}
+}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
 
-  '$elemMatch': function (doc, userValue, parsedField, docFieldValue) {
-    if (!Array.isArray(docFieldValue)) {
-      return false;
-    }
+Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {
+	value: 'HeadersIterator',
+	writable: false,
+	enumerable: false,
+	configurable: true
+});
 
-    if (docFieldValue.length === 0) {
-      return false;
-    }
+/**
+ * Export the Headers object in a form that Node.js can consume.
+ *
+ * @param   Headers  headers
+ * @return  Object
+ */
+function exportNodeCompatibleHeaders(headers) {
+	const obj = Object.assign({ __proto__: null }, headers[MAP]);
 
-    if (typeof docFieldValue[0] === 'object') {
-      return docFieldValue.some(function (val) {
-        return rowFilter(val, userValue, Object.keys(userValue));
-      });
-    }
+	// http.request() only supports string as Host header. This hack makes
+	// specifying custom Host header possible.
+	const hostHeaderKey = find(headers[MAP], 'Host');
+	if (hostHeaderKey !== undefined) {
+		obj[hostHeaderKey] = obj[hostHeaderKey][0];
+	}
 
-    return docFieldValue.some(function (val) {
-      return matchSelector(userValue, doc, parsedField, val);
-    });
-  },
+	return obj;
+}
 
-  '$allMatch': function (doc, userValue, parsedField, docFieldValue) {
-    if (!Array.isArray(docFieldValue)) {
-      return false;
-    }
+/**
+ * Create a Headers object from an object of headers, ignoring those that do
+ * not conform to HTTP grammar productions.
+ *
+ * @param   Object  obj  Object of headers
+ * @return  Headers
+ */
+function createHeadersLenient(obj) {
+	const headers = new Headers();
+	for (const name of Object.keys(obj)) {
+		if (invalidTokenRegex.test(name)) {
+			continue;
+		}
+		if (Array.isArray(obj[name])) {
+			for (const val of obj[name]) {
+				if (invalidHeaderCharRegex.test(val)) {
+					continue;
+				}
+				if (headers[MAP][name] === undefined) {
+					headers[MAP][name] = [val];
+				} else {
+					headers[MAP][name].push(val);
+				}
+			}
+		} else if (!invalidHeaderCharRegex.test(obj[name])) {
+			headers[MAP][name] = [obj[name]];
+		}
+	}
+	return headers;
+}
 
-    /* istanbul ignore next */
-    if (docFieldValue.length === 0) {
-      return false;
-    }
+const INTERNALS$1 = Symbol('Response internals');
 
-    if (typeof docFieldValue[0] === 'object') {
-      return docFieldValue.every(function (val) {
-        return rowFilter(val, userValue, Object.keys(userValue));
-      });
-    }
+// fix an issue where "STATUS_CODES" aren't a named export for node <10
+const STATUS_CODES = http__WEBPACK_IMPORTED_MODULE_1__.STATUS_CODES;
 
-    return docFieldValue.every(function (val) {
-      return matchSelector(userValue, doc, parsedField, val);
-    });
-  },
+/**
+ * Response class
+ *
+ * @param   Stream  body  Readable stream
+ * @param   Object  opts  Response options
+ * @return  Void
+ */
+class Response {
+	constructor() {
+		let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
+		let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 
-  '$eq': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) === 0;
-  },
+		Body.call(this, body, opts);
 
-  '$gte': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) >= 0;
-  },
+		const status = opts.status || 200;
+		const headers = new Headers(opts.headers);
 
-  '$gt': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) > 0;
-  },
+		if (body != null && !headers.has('Content-Type')) {
+			const contentType = extractContentType(body);
+			if (contentType) {
+				headers.append('Content-Type', contentType);
+			}
+		}
 
-  '$lte': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) <= 0;
-  },
+		this[INTERNALS$1] = {
+			url: opts.url,
+			status,
+			statusText: opts.statusText || STATUS_CODES[status],
+			headers,
+			counter: opts.counter
+		};
+	}
 
-  '$lt': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) < 0;
-  },
+	get url() {
+		return this[INTERNALS$1].url || '';
+	}
 
-  '$exists': function (doc, userValue, parsedField, docFieldValue) {
-    //a field that is null is still considered to exist
-    if (userValue) {
-      return fieldIsNotUndefined(docFieldValue);
-    }
+	get status() {
+		return this[INTERNALS$1].status;
+	}
 
-    return !fieldIsNotUndefined(docFieldValue);
-  },
+	/**
+  * Convenience property representing if the request ended normally
+  */
+	get ok() {
+		return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;
+	}
 
-  '$mod': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && modField(docFieldValue, userValue);
-  },
+	get redirected() {
+		return this[INTERNALS$1].counter > 0;
+	}
 
-  '$ne': function (doc, userValue, parsedField, docFieldValue) {
-    return userValue.every(function (neValue) {
-      return collate(docFieldValue, neValue) !== 0;
-    });
-  },
-  '$in': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue);
-  },
+	get statusText() {
+		return this[INTERNALS$1].statusText;
+	}
 
-  '$nin': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue);
-  },
+	get headers() {
+		return this[INTERNALS$1].headers;
+	}
 
-  '$size': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue);
-  },
+	/**
+  * Clone this response
+  *
+  * @return  Response
+  */
+	clone() {
+		return new Response(clone(this), {
+			url: this.url,
+			status: this.status,
+			statusText: this.statusText,
+			headers: this.headers,
+			ok: this.ok,
+			redirected: this.redirected
+		});
+	}
+}
 
-  '$all': function (doc, userValue, parsedField, docFieldValue) {
-    return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue);
-  },
+Body.mixIn(Response.prototype);
 
-  '$regex': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue);
-  },
+Object.defineProperties(Response.prototype, {
+	url: { enumerable: true },
+	status: { enumerable: true },
+	ok: { enumerable: true },
+	redirected: { enumerable: true },
+	statusText: { enumerable: true },
+	headers: { enumerable: true },
+	clone: { enumerable: true }
+});
 
-  '$type': function (doc, userValue, parsedField, docFieldValue) {
-    return typeMatch(docFieldValue, userValue);
-  }
-};
+Object.defineProperty(Response.prototype, Symbol.toStringTag, {
+	value: 'Response',
+	writable: false,
+	enumerable: false,
+	configurable: true
+});
 
-// return true if the given doc matches the supplied selector
-function matchesSelector(doc, selector) {
-  /* istanbul ignore if */
-  if (typeof selector !== 'object') {
-    // match the CouchDB error message
-    throw new Error('Selector error: expected a JSON object');
-  }
+const INTERNALS$2 = Symbol('Request internals');
 
-  selector = massageSelector(selector);
-  var row = {
-    'doc': doc
-  };
+// fix an issue where "format", "parse" aren't a named export for node <10
+const parse_url = url__WEBPACK_IMPORTED_MODULE_2__.parse;
+const format_url = url__WEBPACK_IMPORTED_MODULE_2__.format;
 
-  var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector));
-  return rowsMatched && rowsMatched.length === 1;
+const streamDestructionSupported = 'destroy' in stream__WEBPACK_IMPORTED_MODULE_0__.Readable.prototype;
+
+/**
+ * Check if a value is an instance of Request.
+ *
+ * @param   Mixed   input
+ * @return  Boolean
+ */
+function isRequest(input) {
+	return typeof input === 'object' && typeof input[INTERNALS$2] === 'object';
 }
 
-function evalFilter(input) {
-  return scopeEval('"use strict";\nreturn ' + input + ';', {});
+function isAbortSignal(signal) {
+	const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);
+	return !!(proto && proto.constructor.name === 'AbortSignal');
 }
 
-function evalView(input) {
-  var code = [
-    'return function(doc) {',
-    '  "use strict";',
-    '  var emitted = false;',
-    '  var emit = function (a, b) {',
-    '    emitted = true;',
-    '  };',
-    '  var view = ' + input + ';',
-    '  view(doc);',
-    '  if (emitted) {',
-    '    return true;',
-    '  }',
-    '};'
-  ].join('\n');
+/**
+ * Request class
+ *
+ * @param   Mixed   input  Url or Request instance
+ * @param   Object  init   Custom options
+ * @return  Void
+ */
+class Request {
+	constructor(input) {
+		let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 
-  return scopeEval(code, {});
-}
+		let parsedURL;
 
-function validate(opts, callback) {
-  if (opts.selector) {
-    if (opts.filter && opts.filter !== '_selector') {
-      var filterName = typeof opts.filter === 'string' ?
-        opts.filter : 'function';
-      return callback(new Error('selector invalid for filter "' + filterName + '"'));
-    }
-  }
-  callback();
-}
+		// normalize input
+		if (!isRequest(input)) {
+			if (input && input.href) {
+				// in order to support Node.js' Url objects; though WHATWG's URL objects
+				// will fall into this branch also (since their `toString()` will return
+				// `href` property anyway)
+				parsedURL = parse_url(input.href);
+			} else {
+				// coerce input to a string before attempting to parse
+				parsedURL = parse_url(`${input}`);
+			}
+			input = {};
+		} else {
+			parsedURL = parse_url(input.url);
+		}
 
-function normalize(opts) {
-  if (opts.view && !opts.filter) {
-    opts.filter = '_view';
-  }
+		let method = init.method || input.method || 'GET';
+		method = method.toUpperCase();
 
-  if (opts.selector && !opts.filter) {
-    opts.filter = '_selector';
-  }
+		if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {
+			throw new TypeError('Request with GET/HEAD method cannot have body');
+		}
 
-  if (opts.filter && typeof opts.filter === 'string') {
-    if (opts.filter === '_view') {
-      opts.view = normalizeDesignDocFunctionName(opts.view);
-    } else {
-      opts.filter = normalizeDesignDocFunctionName(opts.filter);
-    }
-  }
-}
+		let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;
 
-function shouldFilter(changesHandler, opts) {
-  return opts.filter && typeof opts.filter === 'string' &&
-    !opts.doc_ids && !isRemote(changesHandler.db);
-}
+		Body.call(this, inputBody, {
+			timeout: init.timeout || input.timeout || 0,
+			size: init.size || input.size || 0
+		});
 
-function filter(changesHandler, opts) {
-  var callback = opts.complete;
-  if (opts.filter === '_view') {
-    if (!opts.view || typeof opts.view !== 'string') {
-      var err = createError(BAD_REQUEST,
-        '`view` filter parameter not found or invalid.');
-      return callback(err);
-    }
-    // fetch a view from a design doc, make it behave like a filter
-    var viewName = parseDesignDocFunctionName(opts.view);
-    changesHandler.db.get('_design/' + viewName[0], function (err, ddoc) {
-      /* istanbul ignore if */
-      if (changesHandler.isCancelled) {
-        return callback(null, {status: 'cancelled'});
-      }
-      /* istanbul ignore next */
-      if (err) {
-        return callback(generateErrorFromResponse(err));
-      }
-      var mapFun = ddoc && ddoc.views && ddoc.views[viewName[1]] &&
-        ddoc.views[viewName[1]].map;
-      if (!mapFun) {
-        return callback(createError(MISSING_DOC,
-          (ddoc.views ? 'missing json key: ' + viewName[1] :
-            'missing json key: views')));
-      }
-      opts.filter = evalView(mapFun);
-      changesHandler.doChanges(opts);
-    });
-  } else if (opts.selector) {
-    opts.filter = function (doc) {
-      return matchesSelector(doc, opts.selector);
-    };
-    changesHandler.doChanges(opts);
-  } else {
-    // fetch a filter from a design doc
-    var filterName = parseDesignDocFunctionName(opts.filter);
-    changesHandler.db.get('_design/' + filterName[0], function (err, ddoc) {
-      /* istanbul ignore if */
-      if (changesHandler.isCancelled) {
-        return callback(null, {status: 'cancelled'});
-      }
-      /* istanbul ignore next */
-      if (err) {
-        return callback(generateErrorFromResponse(err));
-      }
-      var filterFun = ddoc && ddoc.filters && ddoc.filters[filterName[1]];
-      if (!filterFun) {
-        return callback(createError(MISSING_DOC,
-          ((ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
-            : 'missing json key: filters')));
-      }
-      opts.filter = evalFilter(filterFun);
-      changesHandler.doChanges(opts);
-    });
-  }
-}
+		const headers = new Headers(init.headers || input.headers || {});
 
-function applyChangesFilterPlugin(PouchDB) {
-  PouchDB._changesFilterPlugin = {
-    validate: validate,
-    normalize: normalize,
-    shouldFilter: shouldFilter,
-    filter: filter
-  };
-}
+		if (inputBody != null && !headers.has('Content-Type')) {
+			const contentType = extractContentType(inputBody);
+			if (contentType) {
+				headers.append('Content-Type', contentType);
+			}
+		}
 
-// TODO: remove from pouchdb-core (breaking)
-PouchDB.plugin(applyChangesFilterPlugin);
+		let signal = isRequest(input) ? input.signal : null;
+		if ('signal' in init) signal = init.signal;
 
-PouchDB.version = version;
+		if (signal != null && !isAbortSignal(signal)) {
+			throw new TypeError('Expected signal to be an instanceof AbortSignal');
+		}
 
-function toObject(array) {
-  return array.reduce(function (obj, item) {
-    obj[item] = true;
-    return obj;
-  }, {});
-}
-// List of top level reserved words for doc
-var reservedWords = toObject([
-  '_id',
-  '_rev',
-  '_attachments',
-  '_deleted',
-  '_revisions',
-  '_revs_info',
-  '_conflicts',
-  '_deleted_conflicts',
-  '_local_seq',
-  '_rev_tree',
-  //replication documents
-  '_replication_id',
-  '_replication_state',
-  '_replication_state_time',
-  '_replication_state_reason',
-  '_replication_stats',
-  // Specific to Couchbase Sync Gateway
-  '_removed'
-]);
+		this[INTERNALS$2] = {
+			method,
+			redirect: init.redirect || input.redirect || 'follow',
+			headers,
+			parsedURL,
+			signal
+		};
 
-// List of reserved words that should end up the document
-var dataWords = toObject([
-  '_attachments',
-  //replication documents
-  '_replication_id',
-  '_replication_state',
-  '_replication_state_time',
-  '_replication_state_reason',
-  '_replication_stats'
-]);
+		// node-fetch-only options
+		this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
+		this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
+		this.counter = init.counter || input.counter || 0;
+		this.agent = init.agent || input.agent;
+	}
 
-function parseRevisionInfo(rev) {
-  if (!/^\d+-./.test(rev)) {
-    return createError(INVALID_REV);
-  }
-  var idx = rev.indexOf('-');
-  var left = rev.substring(0, idx);
-  var right = rev.substring(idx + 1);
-  return {
-    prefix: parseInt(left, 10),
-    id: right
-  };
-}
+	get method() {
+		return this[INTERNALS$2].method;
+	}
 
-function makeRevTreeFromRevisions(revisions, opts) {
-  var pos = revisions.start - revisions.ids.length + 1;
+	get url() {
+		return format_url(this[INTERNALS$2].parsedURL);
+	}
 
-  var revisionIds = revisions.ids;
-  var ids = [revisionIds[0], opts, []];
+	get headers() {
+		return this[INTERNALS$2].headers;
+	}
 
-  for (var i = 1, len = revisionIds.length; i < len; i++) {
-    ids = [revisionIds[i], {status: 'missing'}, [ids]];
-  }
+	get redirect() {
+		return this[INTERNALS$2].redirect;
+	}
 
-  return [{
-    pos: pos,
-    ids: ids
-  }];
+	get signal() {
+		return this[INTERNALS$2].signal;
+	}
+
+	/**
+  * Clone this request
+  *
+  * @return  Request
+  */
+	clone() {
+		return new Request(this);
+	}
 }
 
-// Preprocess documents, parse their revisions, assign an id and a
-// revision for new writes that are missing them, etc
-function parseDoc(doc, newEdits, dbOpts) {
-  if (!dbOpts) {
-    dbOpts = {
-      deterministic_revs: true
-    };
-  }
+Body.mixIn(Request.prototype);
 
-  var nRevNum;
-  var newRevId;
-  var revInfo;
-  var opts = {status: 'available'};
-  if (doc._deleted) {
-    opts.deleted = true;
-  }
+Object.defineProperty(Request.prototype, Symbol.toStringTag, {
+	value: 'Request',
+	writable: false,
+	enumerable: false,
+	configurable: true
+});
 
-  if (newEdits) {
-    if (!doc._id) {
-      doc._id = uuid();
-    }
-    newRevId = rev$$1(doc, dbOpts.deterministic_revs);
-    if (doc._rev) {
-      revInfo = parseRevisionInfo(doc._rev);
-      if (revInfo.error) {
-        return revInfo;
-      }
-      doc._rev_tree = [{
-        pos: revInfo.prefix,
-        ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
-      }];
-      nRevNum = revInfo.prefix + 1;
-    } else {
-      doc._rev_tree = [{
-        pos: 1,
-        ids : [newRevId, opts, []]
-      }];
-      nRevNum = 1;
-    }
-  } else {
-    if (doc._revisions) {
-      doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
-      nRevNum = doc._revisions.start;
-      newRevId = doc._revisions.ids[0];
-    }
-    if (!doc._rev_tree) {
-      revInfo = parseRevisionInfo(doc._rev);
-      if (revInfo.error) {
-        return revInfo;
-      }
-      nRevNum = revInfo.prefix;
-      newRevId = revInfo.id;
-      doc._rev_tree = [{
-        pos: nRevNum,
-        ids: [newRevId, opts, []]
-      }];
-    }
-  }
+Object.defineProperties(Request.prototype, {
+	method: { enumerable: true },
+	url: { enumerable: true },
+	headers: { enumerable: true },
+	redirect: { enumerable: true },
+	clone: { enumerable: true },
+	signal: { enumerable: true }
+});
 
-  invalidIdError(doc._id);
+/**
+ * Convert a Request to Node.js http request options.
+ *
+ * @param   Request  A Request instance
+ * @return  Object   The options object to be passed to http.request
+ */
+function getNodeRequestOptions(request) {
+	const parsedURL = request[INTERNALS$2].parsedURL;
+	const headers = new Headers(request[INTERNALS$2].headers);
 
-  doc._rev = nRevNum + '-' + newRevId;
+	// fetch step 1.3
+	if (!headers.has('Accept')) {
+		headers.set('Accept', '*/*');
+	}
 
-  var result = {metadata : {}, data : {}};
-  for (var key in doc) {
-    /* istanbul ignore else */
-    if (Object.prototype.hasOwnProperty.call(doc, key)) {
-      var specialKey = key[0] === '_';
-      if (specialKey && !reservedWords[key]) {
-        var error = createError(DOC_VALIDATION, key);
-        error.message = DOC_VALIDATION.message + ': ' + key;
-        throw error;
-      } else if (specialKey && !dataWords[key]) {
-        result.metadata[key.slice(1)] = doc[key];
-      } else {
-        result.data[key] = doc[key];
-      }
-    }
-  }
-  return result;
-}
+	// Basic fetch
+	if (!parsedURL.protocol || !parsedURL.hostname) {
+		throw new TypeError('Only absolute URLs are supported');
+	}
 
-function parseBase64(data) {
-  try {
-    return thisAtob(data);
-  } catch (e) {
-    var err = createError(BAD_ARG,
-      'Attachment is not a valid base64 string');
-    return {error: err};
-  }
-}
+	if (!/^https?:$/.test(parsedURL.protocol)) {
+		throw new TypeError('Only HTTP(S) protocols are supported');
+	}
 
-function preprocessString(att, blobType, callback) {
-  var asBinary = parseBase64(att.data);
-  if (asBinary.error) {
-    return callback(asBinary.error);
-  }
+	if (request.signal && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable && !streamDestructionSupported) {
+		throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');
+	}
 
-  att.length = asBinary.length;
-  if (blobType === 'blob') {
-    att.data = binStringToBluffer(asBinary, att.content_type);
-  } else if (blobType === 'base64') {
-    att.data = thisBtoa(asBinary);
-  } else { // binary
-    att.data = asBinary;
-  }
-  binaryMd5(asBinary, function (result) {
-    att.digest = 'md5-' + result;
-    callback();
-  });
-}
+	// HTTP-network-or-cache fetch steps 2.4-2.7
+	let contentLengthValue = null;
+	if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
+		contentLengthValue = '0';
+	}
+	if (request.body != null) {
+		const totalBytes = getTotalBytes(request);
+		if (typeof totalBytes === 'number') {
+			contentLengthValue = String(totalBytes);
+		}
+	}
+	if (contentLengthValue) {
+		headers.set('Content-Length', contentLengthValue);
+	}
 
-function preprocessBlob(att, blobType, callback) {
-  binaryMd5(att.data, function (md5) {
-    att.digest = 'md5-' + md5;
-    // size is for blobs (browser), length is for buffers (node)
-    att.length = att.data.size || att.data.length || 0;
-    if (blobType === 'binary') {
-      blobToBinaryString(att.data, function (binString) {
-        att.data = binString;
-        callback();
-      });
-    } else if (blobType === 'base64') {
-      blobToBase64(att.data, function (b64) {
-        att.data = b64;
-        callback();
-      });
-    } else {
-      callback();
-    }
-  });
-}
+	// HTTP-network-or-cache fetch step 2.11
+	if (!headers.has('User-Agent')) {
+		headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');
+	}
 
-function preprocessAttachment(att, blobType, callback) {
-  if (att.stub) {
-    return callback();
-  }
-  if (typeof att.data === 'string') { // input is a base64 string
-    preprocessString(att, blobType, callback);
-  } else { // input is a blob
-    preprocessBlob(att, blobType, callback);
-  }
-}
+	// HTTP-network-or-cache fetch step 2.15
+	if (request.compress && !headers.has('Accept-Encoding')) {
+		headers.set('Accept-Encoding', 'gzip,deflate');
+	}
 
-function preprocessAttachments(docInfos, blobType, callback) {
+	let agent = request.agent;
+	if (typeof agent === 'function') {
+		agent = agent(parsedURL);
+	}
 
-  if (!docInfos.length) {
-    return callback();
-  }
+	if (!headers.has('Connection') && !agent) {
+		headers.set('Connection', 'close');
+	}
 
-  var docv = 0;
-  var overallErr;
+	// HTTP-network fetch step 4.2
+	// chunked encoding is handled by Node.js
 
-  docInfos.forEach(function (docInfo) {
-    var attachments = docInfo.data && docInfo.data._attachments ?
-      Object.keys(docInfo.data._attachments) : [];
-    var recv = 0;
+	return Object.assign({}, parsedURL, {
+		method: request.method,
+		headers: exportNodeCompatibleHeaders(headers),
+		agent
+	});
+}
 
-    if (!attachments.length) {
-      return done();
-    }
+/**
+ * abort-error.js
+ *
+ * AbortError interface for cancelled requests
+ */
 
-    function processedAttachment(err) {
-      overallErr = err;
-      recv++;
-      if (recv === attachments.length) {
-        done();
-      }
-    }
+/**
+ * Create AbortError instance
+ *
+ * @param   String      message      Error message for human
+ * @return  AbortError
+ */
+function AbortError(message) {
+  Error.call(this, message);
 
-    for (var key in docInfo.data._attachments) {
-      if (docInfo.data._attachments.hasOwnProperty(key)) {
-        preprocessAttachment(docInfo.data._attachments[key],
-          blobType, processedAttachment);
-      }
-    }
-  });
+  this.type = 'aborted';
+  this.message = message;
 
-  function done() {
-    docv++;
-    if (docInfos.length === docv) {
-      if (overallErr) {
-        callback(overallErr);
-      } else {
-        callback();
-      }
-    }
-  }
+  // hide custom error implementation details from end-users
+  Error.captureStackTrace(this, this.constructor);
 }
 
-function updateDoc(revLimit, prev, docInfo, results,
-                   i, cb, writeDoc, newEdits) {
+AbortError.prototype = Object.create(Error.prototype);
+AbortError.prototype.constructor = AbortError;
+AbortError.prototype.name = 'AbortError';
 
-  if (revExists(prev.rev_tree, docInfo.metadata.rev) && !newEdits) {
-    results[i] = docInfo;
-    return cb();
-  }
+// fix an issue where "PassThrough", "resolve" aren't a named export for node <10
+const PassThrough$1 = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough;
+const resolve_url = url__WEBPACK_IMPORTED_MODULE_2__.resolve;
 
-  // sometimes this is pre-calculated. historically not always
-  var previousWinningRev = prev.winningRev || winningRev(prev);
-  var previouslyDeleted = 'deleted' in prev ? prev.deleted :
-    isDeleted(prev, previousWinningRev);
-  var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
-    isDeleted(docInfo.metadata);
-  var isRoot = /^1-/.test(docInfo.metadata.rev);
+/**
+ * Fetch function
+ *
+ * @param   Mixed    url   Absolute url or Request instance
+ * @param   Object   opts  Fetch options
+ * @return  Promise
+ */
+function fetch(url, opts) {
 
-  if (previouslyDeleted && !deleted && newEdits && isRoot) {
-    var newDoc = docInfo.data;
-    newDoc._rev = previousWinningRev;
-    newDoc._id = docInfo.metadata.id;
-    docInfo = parseDoc(newDoc, newEdits);
-  }
+	// allow custom promise
+	if (!fetch.Promise) {
+		throw new Error('native promise missing, set fetch.Promise to your favorite alternative');
+	}
 
-  var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+	Body.Promise = fetch.Promise;
 
-  var inConflict = newEdits && ((
-    (previouslyDeleted && deleted && merged.conflicts !== 'new_leaf') ||
-    (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
-    (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+	// wrap http.request into fetch
+	return new fetch.Promise(function (resolve, reject) {
+		// build request object
+		const request = new Request(url, opts);
+		const options = getNodeRequestOptions(request);
 
-  if (inConflict) {
-    var err = createError(REV_CONFLICT);
-    results[i] = err;
-    return cb();
-  }
+		const send = (options.protocol === 'https:' ? https__WEBPACK_IMPORTED_MODULE_3__ : http__WEBPACK_IMPORTED_MODULE_1__).request;
+		const signal = request.signal;
 
-  var newRev = docInfo.metadata.rev;
-  docInfo.metadata.rev_tree = merged.tree;
-  docInfo.stemmedRevs = merged.stemmedRevs || [];
-  /* istanbul ignore else */
-  if (prev.rev_map) {
-    docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
-  }
+		let response = null;
 
-  // recalculate
-  var winningRev$$1 = winningRev(docInfo.metadata);
-  var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$1);
+		const abort = function abort() {
+			let error = new AbortError('The user aborted a request.');
+			reject(error);
+			if (request.body && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable) {
+				request.body.destroy(error);
+			}
+			if (!response || !response.body) return;
+			response.body.emit('error', error);
+		};
 
-  // calculate the total number of documents that were added/removed,
-  // from the perspective of total_rows/doc_count
-  var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
-    previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+		if (signal && signal.aborted) {
+			abort();
+			return;
+		}
 
-  var newRevIsDeleted;
-  if (newRev === winningRev$$1) {
-    // if the new rev is the same as the winning rev, we can reuse that value
-    newRevIsDeleted = winningRevIsDeleted;
-  } else {
-    // if they're not the same, then we need to recalculate
-    newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
-  }
+		const abortAndFinalize = function abortAndFinalize() {
+			abort();
+			finalize();
+		};
 
-  writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
-    true, delta, i, cb);
-}
+		// send request
+		const req = send(options);
+		let reqTimeout;
 
-function rootIsMissing(docInfo) {
-  return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
-}
+		if (signal) {
+			signal.addEventListener('abort', abortAndFinalize);
+		}
 
-function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
-                     writeDoc, opts, overallCallback) {
+		function finalize() {
+			req.abort();
+			if (signal) signal.removeEventListener('abort', abortAndFinalize);
+			clearTimeout(reqTimeout);
+		}
 
-  // Default to 1000 locally
-  revLimit = revLimit || 1000;
+		if (request.timeout) {
+			req.once('socket', function (socket) {
+				reqTimeout = setTimeout(function () {
+					reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
+					finalize();
+				}, request.timeout);
+			});
+		}
 
-  function insertDoc(docInfo, resultsIdx, callback) {
-    // Cant insert new deleted documents
-    var winningRev$$1 = winningRev(docInfo.metadata);
-    var deleted = isDeleted(docInfo.metadata, winningRev$$1);
-    if ('was_delete' in opts && deleted) {
-      results[resultsIdx] = createError(MISSING_DOC, 'deleted');
-      return callback();
-    }
+		req.on('error', function (err) {
+			reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
+			finalize();
+		});
 
-    // 4712 - detect whether a new document was inserted with a _rev
-    var inConflict = newEdits && rootIsMissing(docInfo);
+		req.on('response', function (res) {
+			clearTimeout(reqTimeout);
 
-    if (inConflict) {
-      var err = createError(REV_CONFLICT);
-      results[resultsIdx] = err;
-      return callback();
-    }
+			const headers = createHeadersLenient(res.headers);
 
-    var delta = deleted ? 0 : 1;
+			// HTTP fetch step 5
+			if (fetch.isRedirect(res.statusCode)) {
+				// HTTP fetch step 5.2
+				const location = headers.get('Location');
 
-    writeDoc(docInfo, winningRev$$1, deleted, deleted, false,
-      delta, resultsIdx, callback);
-  }
+				// HTTP fetch step 5.3
+				const locationURL = location === null ? null : resolve_url(request.url, location);
 
-  var newEdits = opts.new_edits;
-  var idsToDocs = new ExportedMap();
+				// HTTP fetch step 5.5
+				switch (request.redirect) {
+					case 'error':
+						reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
+						finalize();
+						return;
+					case 'manual':
+						// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
+						if (locationURL !== null) {
+							// handle corrupted header
+							try {
+								headers.set('Location', locationURL);
+							} catch (err) {
+								// istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request
+								reject(err);
+							}
+						}
+						break;
+					case 'follow':
+						// HTTP-redirect fetch step 2
+						if (locationURL === null) {
+							break;
+						}
 
-  var docsDone = 0;
-  var docsToDo = docInfos.length;
+						// HTTP-redirect fetch step 5
+						if (request.counter >= request.follow) {
+							reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
+							finalize();
+							return;
+						}
 
-  function checkAllDocsDone() {
-    if (++docsDone === docsToDo && overallCallback) {
-      overallCallback();
-    }
-  }
+						// HTTP-redirect fetch step 6 (counter increment)
+						// Create a new Request object.
+						const requestOpts = {
+							headers: new Headers(request.headers),
+							follow: request.follow,
+							counter: request.counter + 1,
+							agent: request.agent,
+							compress: request.compress,
+							method: request.method,
+							body: request.body,
+							signal: request.signal,
+							timeout: request.timeout,
+							size: request.size
+						};
 
-  docInfos.forEach(function (currentDoc, resultsIdx) {
+						// HTTP-redirect fetch step 9
+						if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
+							reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
+							finalize();
+							return;
+						}
 
-    if (currentDoc._id && isLocalId(currentDoc._id)) {
-      var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
-      api[fun](currentDoc, {ctx: tx}, function (err, res) {
-        results[resultsIdx] = err || res;
-        checkAllDocsDone();
-      });
-      return;
-    }
+						// HTTP-redirect fetch step 11
+						if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
+							requestOpts.method = 'GET';
+							requestOpts.body = undefined;
+							requestOpts.headers.delete('content-length');
+						}
 
-    var id = currentDoc.metadata.id;
-    if (idsToDocs.has(id)) {
-      docsToDo--; // duplicate
-      idsToDocs.get(id).push([currentDoc, resultsIdx]);
-    } else {
-      idsToDocs.set(id, [[currentDoc, resultsIdx]]);
-    }
-  });
+						// HTTP-redirect fetch step 15
+						resolve(fetch(new Request(locationURL, requestOpts)));
+						finalize();
+						return;
+				}
+			}
 
-  // in the case of new_edits, the user can provide multiple docs
-  // with the same id. these need to be processed sequentially
-  idsToDocs.forEach(function (docs, id) {
-    var numDone = 0;
+			// prepare response
+			res.once('end', function () {
+				if (signal) signal.removeEventListener('abort', abortAndFinalize);
+			});
+			let body = res.pipe(new PassThrough$1());
 
-    function docWritten() {
-      if (++numDone < docs.length) {
-        nextDoc();
-      } else {
-        checkAllDocsDone();
-      }
-    }
-    function nextDoc() {
-      var value = docs[numDone];
-      var currentDoc = value[0];
-      var resultsIdx = value[1];
+			const response_options = {
+				url: request.url,
+				status: res.statusCode,
+				statusText: res.statusMessage,
+				headers: headers,
+				size: request.size,
+				timeout: request.timeout,
+				counter: request.counter
+			};
 
-      if (fetchedDocs.has(id)) {
-        updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
-          resultsIdx, docWritten, writeDoc, newEdits);
-      } else {
-        // Ensure stemming applies to new writes as well
-        var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
-        currentDoc.metadata.rev_tree = merged.tree;
-        currentDoc.stemmedRevs = merged.stemmedRevs || [];
-        insertDoc(currentDoc, resultsIdx, docWritten);
-      }
-    }
-    nextDoc();
-  });
-}
+			// HTTP-network fetch step 12.1.1.3
+			const codings = headers.get('Content-Encoding');
 
-// IndexedDB requires a versioned database structure, so we use the
-// version here to manage migrations.
-var ADAPTER_VERSION = 5;
+			// HTTP-network fetch step 12.1.1.4: handle content codings
 
-// The object stores created for each database
-// DOC_STORE stores the document meta data, its revision history and state
-// Keyed by document id
-var DOC_STORE = 'document-store';
-// BY_SEQ_STORE stores a particular version of a document, keyed by its
-// sequence id
-var BY_SEQ_STORE = 'by-sequence';
-// Where we store attachments
-var ATTACH_STORE = 'attach-store';
-// Where we store many-to-many relations
-// between attachment digests and seqs
-var ATTACH_AND_SEQ_STORE = 'attach-seq-store';
+			// in following scenarios we ignore compression support
+			// 1. compression support is disabled
+			// 2. HEAD request
+			// 3. no Content-Encoding header
+			// 4. no content response (204)
+			// 5. content not modified response (304)
+			if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {
+				response = new Response(body, response_options);
+				resolve(response);
+				return;
+			}
 
-// Where we store database-wide meta data in a single record
-// keyed by id: META_STORE
-var META_STORE = 'meta-store';
-// Where we store local documents
-var LOCAL_STORE = 'local-store';
-// Where we detect blob support
-var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
+			// For Node v6+
+			// Be less strict when decoding compressed responses, since sometimes
+			// servers send slightly invalid responses that are still accepted
+			// by common browsers.
+			// Always using Z_SYNC_FLUSH is what cURL does.
+			const zlibOptions = {
+				flush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH,
+				finishFlush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH
+			};
 
-function safeJsonParse(str) {
-  // This try/catch guards against stack overflow errors.
-  // JSON.parse() is faster than vuvuzela.parse() but vuvuzela
-  // cannot overflow.
-  try {
-    return JSON.parse(str);
-  } catch (e) {
-    /* istanbul ignore next */
-    return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.parse(str);
-  }
-}
+			// for gzip
+			if (codings == 'gzip' || codings == 'x-gzip') {
+				body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createGunzip(zlibOptions));
+				response = new Response(body, response_options);
+				resolve(response);
+				return;
+			}
 
-function safeJsonStringify(json) {
-  try {
-    return JSON.stringify(json);
-  } catch (e) {
-    /* istanbul ignore next */
-    return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.stringify(json);
-  }
-}
+			// for deflate
+			if (codings == 'deflate' || codings == 'x-deflate') {
+				// handle the infamous raw deflate response from old servers
+				// a hack for old IIS and Apache servers
+				const raw = res.pipe(new PassThrough$1());
+				raw.once('data', function (chunk) {
+					// see http://stackoverflow.com/questions/37519828
+					if ((chunk[0] & 0x0F) === 0x08) {
+						body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflate());
+					} else {
+						body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflateRaw());
+					}
+					response = new Response(body, response_options);
+					resolve(response);
+				});
+				return;
+			}
 
-function idbError(callback) {
-  return function (evt) {
-    var message = 'unknown_error';
-    if (evt.target && evt.target.error) {
-      message = evt.target.error.name || evt.target.error.message;
-    }
-    callback(createError(IDB_ERROR, message, evt.type));
-  };
-}
+			// for br
+			if (codings == 'br' && typeof zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress === 'function') {
+				body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress());
+				response = new Response(body, response_options);
+				resolve(response);
+				return;
+			}
 
-// Unfortunately, the metadata has to be stringified
-// when it is put into the database, because otherwise
-// IndexedDB can throw errors for deeply-nested objects.
-// Originally we just used JSON.parse/JSON.stringify; now
-// we use this custom vuvuzela library that avoids recursion.
-// If we could do it all over again, we'd probably use a
-// format for the revision trees other than JSON.
-function encodeMetadata(metadata, winningRev, deleted) {
-  return {
-    data: safeJsonStringify(metadata),
-    winningRev: winningRev,
-    deletedOrLocal: deleted ? '1' : '0',
-    seq: metadata.seq, // highest seq for this doc
-    id: metadata.id
-  };
-}
+			// otherwise, use response as-is
+			response = new Response(body, response_options);
+			resolve(response);
+		});
 
-function decodeMetadata(storedObject) {
-  if (!storedObject) {
-    return null;
-  }
-  var metadata = safeJsonParse(storedObject.data);
-  metadata.winningRev = storedObject.winningRev;
-  metadata.deleted = storedObject.deletedOrLocal === '1';
-  metadata.seq = storedObject.seq;
-  return metadata;
+		writeToStream(req, request);
+	});
 }
+/**
+ * Redirect code matching
+ *
+ * @param   Number   code  Status code
+ * @return  Boolean
+ */
+fetch.isRedirect = function (code) {
+	return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
+};
 
-// read the doc back out from the database. we don't store the
-// _id or _rev because we already have _doc_id_rev.
-function decodeDoc(doc) {
-  if (!doc) {
-    return doc;
-  }
-  var idx = doc._doc_id_rev.lastIndexOf(':');
-  doc._id = doc._doc_id_rev.substring(0, idx - 1);
-  doc._rev = doc._doc_id_rev.substring(idx + 1);
-  delete doc._doc_id_rev;
-  return doc;
-}
+// expose Promise
+fetch.Promise = global.Promise;
 
-// Read a blob from the database, encoding as necessary
-// and translating from base64 if the IDB doesn't support
-// native Blobs
-function readBlobData(body, type, asBlob, callback) {
-  if (asBlob) {
-    if (!body) {
-      callback(createBlob([''], {type: type}));
-    } else if (typeof body !== 'string') { // we have blob support
-      callback(body);
-    } else { // no blob support
-      callback(b64ToBluffer(body, type));
-    }
-  } else { // as base64 string
-    if (!body) {
-      callback('');
-    } else if (typeof body !== 'string') { // we have blob support
-      readAsBinaryString(body, function (binary) {
-        callback(thisBtoa(binary));
-      });
-    } else { // no blob support
-      callback(body);
-    }
-  }
-}
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (fetch);
 
-function fetchAttachmentsIfNecessary(doc, opts, txn, cb) {
-  var attachments = Object.keys(doc._attachments || {});
-  if (!attachments.length) {
-    return cb && cb();
-  }
-  var numDone = 0;
 
-  function checkDone() {
-    if (++numDone === attachments.length && cb) {
-      cb();
-    }
-  }
 
-  function fetchAttachment(doc, att) {
-    var attObj = doc._attachments[att];
-    var digest = attObj.digest;
-    var req = txn.objectStore(ATTACH_STORE).get(digest);
-    req.onsuccess = function (e) {
-      attObj.body = e.target.result.body;
-      checkDone();
-    };
-  }
+/***/ }),
+/* 494 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-  attachments.forEach(function (att) {
-    if (opts.attachments && opts.include_docs) {
-      fetchAttachment(doc, att);
-    } else {
-      doc._attachments[att].stub = true;
-      checkDone();
-    }
-  });
-}
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495);
+/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(496);
+/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(immediate__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(250);
+/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(497);
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_3__);
+/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(499);
+/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(spark_md5__WEBPACK_IMPORTED_MODULE_4__);
+/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(500);
+/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_5__);
+/* harmony import */ var vuvuzela__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(505);
 
-// IDB-specific postprocessing necessary because
-// we don't know whether we stored a true Blob or
-// a base64-encoded string, and if it's a Blob it
-// needs to be read outside of the transaction context
-function postProcessAttachments(results, asBlob) {
-  return Promise.all(results.map(function (row) {
-    if (row.doc && row.doc._attachments) {
-      var attNames = Object.keys(row.doc._attachments);
-      return Promise.all(attNames.map(function (att) {
-        var attObj = row.doc._attachments[att];
-        if (!('body' in attObj)) { // already processed
-          return;
-        }
-        var body = attObj.body;
-        var type = attObj.content_type;
-        return new Promise(function (resolve) {
-          readBlobData(body, type, asBlob, function (data) {
-            row.doc._attachments[att] = $inject_Object_assign(
-              pick(attObj, ['digest', 'content_type']),
-              {data: data}
-            );
-            resolve();
-          });
-        });
-      }));
-    }
-  }));
-}
 
-function compactRevs(revs, docId, txn) {
 
-  var possiblyOrphanedDigests = [];
-  var seqStore = txn.objectStore(BY_SEQ_STORE);
-  var attStore = txn.objectStore(ATTACH_STORE);
-  var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
-  var count = revs.length;
 
-  function checkDone() {
-    count--;
-    if (!count) { // done processing all revs
-      deleteOrphanedAttachments();
-    }
-  }
 
-  function deleteOrphanedAttachments() {
-    if (!possiblyOrphanedDigests.length) {
-      return;
-    }
-    possiblyOrphanedDigests.forEach(function (digest) {
-      var countReq = attAndSeqStore.index('digestSeq').count(
-        IDBKeyRange.bound(
-          digest + '::', digest + '::\uffff', false, false));
-      countReq.onsuccess = function (e) {
-        var count = e.target.result;
-        if (!count) {
-          // orphaned
-          attStore.delete(digest);
-        }
-      };
-    });
-  }
 
-  revs.forEach(function (rev) {
-    var index = seqStore.index('_doc_id_rev');
-    var key = docId + "::" + rev;
-    index.getKey(key).onsuccess = function (e) {
-      var seq = e.target.result;
-      if (typeof seq !== 'number') {
-        return checkDone();
-      }
-      seqStore.delete(seq);
 
-      var cursor = attAndSeqStore.index('seq')
-        .openCursor(IDBKeyRange.only(seq));
 
-      cursor.onsuccess = function (event) {
-        var cursor = event.target.result;
-        if (cursor) {
-          var digest = cursor.value.digestSeq.split('::')[0];
-          possiblyOrphanedDigests.push(digest);
-          attAndSeqStore.delete(cursor.primaryKey);
-          cursor.continue();
-        } else { // done
-          checkDone();
-        }
-      };
-    };
-  });
+function isBinaryObject(object) {
+  return (typeof ArrayBuffer !== 'undefined' && object instanceof ArrayBuffer) ||
+    (typeof Blob !== 'undefined' && object instanceof Blob);
 }
 
-function openTransactionSafely(idb, stores, mode) {
-  try {
-    return {
-      txn: idb.transaction(stores, mode)
-    };
-  } catch (err) {
-    return {
-      error: err
-    };
+function cloneArrayBuffer(buff) {
+  if (typeof buff.slice === 'function') {
+    return buff.slice(0);
   }
+  // IE10-11 slice() polyfill
+  var target = new ArrayBuffer(buff.byteLength);
+  var targetArray = new Uint8Array(target);
+  var sourceArray = new Uint8Array(buff);
+  targetArray.set(sourceArray);
+  return target;
 }
 
-var changesHandler = new Changes();
-
-function idbBulkDocs(dbOpts, req, opts, api, idb, callback) {
-  var docInfos = req.docs;
-  var txn;
-  var docStore;
-  var bySeqStore;
-  var attachStore;
-  var attachAndSeqStore;
-  var metaStore;
-  var docInfoError;
-  var metaDoc;
-
-  for (var i = 0, len = docInfos.length; i < len; i++) {
-    var doc = docInfos[i];
-    if (doc._id && isLocalId(doc._id)) {
-      continue;
-    }
-    doc = docInfos[i] = parseDoc(doc, opts.new_edits, dbOpts);
-    if (doc.error && !docInfoError) {
-      docInfoError = doc;
-    }
+function cloneBinaryObject(object) {
+  if (object instanceof ArrayBuffer) {
+    return cloneArrayBuffer(object);
   }
-
-  if (docInfoError) {
-    return callback(docInfoError);
+  var size = object.size;
+  var type = object.type;
+  // Blob
+  if (typeof object.slice === 'function') {
+    return object.slice(0, size, type);
   }
+  // PhantomJS slice() replacement
+  return object.webkitSlice(0, size, type);
+}
 
-  var allDocsProcessed = false;
-  var docCountDelta = 0;
-  var results = new Array(docInfos.length);
-  var fetchedDocs = new ExportedMap();
-  var preconditionErrored = false;
-  var blobType = api._meta.blobSupport ? 'blob' : 'base64';
-
-  preprocessAttachments(docInfos, blobType, function (err) {
-    if (err) {
-      return callback(err);
-    }
-    startTransaction();
-  });
-
-  function startTransaction() {
-
-    var stores = [
-      DOC_STORE, BY_SEQ_STORE,
-      ATTACH_STORE,
-      LOCAL_STORE, ATTACH_AND_SEQ_STORE,
-      META_STORE
-    ];
-    var txnResult = openTransactionSafely(idb, stores, 'readwrite');
-    if (txnResult.error) {
-      return callback(txnResult.error);
-    }
-    txn = txnResult.txn;
-    txn.onabort = idbError(callback);
-    txn.ontimeout = idbError(callback);
-    txn.oncomplete = complete;
-    docStore = txn.objectStore(DOC_STORE);
-    bySeqStore = txn.objectStore(BY_SEQ_STORE);
-    attachStore = txn.objectStore(ATTACH_STORE);
-    attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
-    metaStore = txn.objectStore(META_STORE);
+// most of this is borrowed from lodash.isPlainObject:
+// https://github.com/fis-components/lodash.isplainobject/
+// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js
 
-    metaStore.get(META_STORE).onsuccess = function (e) {
-      metaDoc = e.target.result;
-      updateDocCountIfReady();
-    };
+var funcToString = Function.prototype.toString;
+var objectCtorString = funcToString.call(Object);
 
-    verifyAttachments(function (err) {
-      if (err) {
-        preconditionErrored = true;
-        return callback(err);
-      }
-      fetchExistingDocs();
-    });
+function isPlainObject(value) {
+  var proto = Object.getPrototypeOf(value);
+  /* istanbul ignore if */
+  if (proto === null) { // not sure when this happens, but I guess it can
+    return true;
   }
+  var Ctor = proto.constructor;
+  return (typeof Ctor == 'function' &&
+    Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
+}
 
-  function onAllDocsProcessed() {
-    allDocsProcessed = true;
-    updateDocCountIfReady();
-  }
+function clone(object) {
+  var newObject;
+  var i;
+  var len;
 
-  function idbProcessDocs() {
-    processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs,
-                txn, results, writeDoc, opts, onAllDocsProcessed);
+  if (!object || typeof object !== 'object') {
+    return object;
   }
 
-  function updateDocCountIfReady() {
-    if (!metaDoc || !allDocsProcessed) {
-      return;
+  if (Array.isArray(object)) {
+    newObject = [];
+    for (i = 0, len = object.length; i < len; i++) {
+      newObject[i] = clone(object[i]);
     }
-    // caching the docCount saves a lot of time in allDocs() and
-    // info(), which is why we go to all the trouble of doing this
-    metaDoc.docCount += docCountDelta;
-    metaStore.put(metaDoc);
+    return newObject;
   }
 
-  function fetchExistingDocs() {
+  // special case: to avoid inconsistencies between IndexedDB
+  // and other backends, we automatically stringify Dates
+  if (object instanceof Date) {
+    return object.toISOString();
+  }
 
-    if (!docInfos.length) {
-      return;
-    }
+  if (isBinaryObject(object)) {
+    return cloneBinaryObject(object);
+  }
 
-    var numFetched = 0;
+  if (!isPlainObject(object)) {
+    return object; // don't clone objects like Workers
+  }
 
-    function checkDone() {
-      if (++numFetched === docInfos.length) {
-        idbProcessDocs();
+  newObject = {};
+  for (i in object) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(object, i)) {
+      var value = clone(object[i]);
+      if (typeof value !== 'undefined') {
+        newObject[i] = value;
       }
     }
+  }
+  return newObject;
+}
 
-    function readMetadata(event) {
-      var metadata = decodeMetadata(event.target.result);
-
-      if (metadata) {
-        fetchedDocs.set(metadata.id, metadata);
-      }
-      checkDone();
+function once(fun) {
+  var called = false;
+  return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
+    /* istanbul ignore if */
+    if (called) {
+      // this is a smoke test and should never actually happen
+      throw new Error('once called more than once');
+    } else {
+      called = true;
+      fun.apply(this, args);
     }
+  });
+}
 
-    for (var i = 0, len = docInfos.length; i < len; i++) {
-      var docInfo = docInfos[i];
-      if (docInfo._id && isLocalId(docInfo._id)) {
-        checkDone(); // skip local docs
-        continue;
+function toPromise(func) {
+  //create the function we will be returning
+  return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
+    // Clone arguments
+    args = clone(args);
+    var self = this;
+    // if the last argument is a function, assume its a callback
+    var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+    var promise = new Promise(function (fulfill, reject) {
+      var resp;
+      try {
+        var callback = once(function (err, mesg) {
+          if (err) {
+            reject(err);
+          } else {
+            fulfill(mesg);
+          }
+        });
+        // create a callback for this invocation
+        // apply the function in the orig context
+        args.push(callback);
+        resp = func.apply(self, args);
+        if (resp && typeof resp.then === 'function') {
+          fulfill(resp);
+        }
+      } catch (e) {
+        reject(e);
       }
-      var req = docStore.get(docInfo.metadata.id);
-      req.onsuccess = readMetadata;
+    });
+    // if there is a callback, call it back
+    if (usedCB) {
+      promise.then(function (result) {
+        usedCB(null, result);
+      }, usedCB);
     }
-  }
+    return promise;
+  });
+}
 
-  function complete() {
-    if (preconditionErrored) {
-      return;
+function logApiCall(self, name, args) {
+  /* istanbul ignore if */
+  if (self.constructor.listeners('debug').length) {
+    var logArgs = ['api', self.name, name];
+    for (var i = 0; i < args.length - 1; i++) {
+      logArgs.push(args[i]);
     }
+    self.constructor.emit('debug', logArgs);
 
-    changesHandler.notify(api._meta.name);
-    callback(null, results);
-  }
-
-  function verifyAttachment(digest, callback) {
-
-    var req = attachStore.get(digest);
-    req.onsuccess = function (e) {
-      if (!e.target.result) {
-        var err = createError(MISSING_STUB,
-          'unknown stub attachment with digest ' +
-          digest);
-        err.status = 412;
-        callback(err);
-      } else {
-        callback();
-      }
+    // override the callback itself to log the response
+    var origCallback = args[args.length - 1];
+    args[args.length - 1] = function (err, res) {
+      var responseArgs = ['api', self.name, name];
+      responseArgs = responseArgs.concat(
+        err ? ['error', err] : ['success', res]
+      );
+      self.constructor.emit('debug', responseArgs);
+      origCallback(err, res);
     };
   }
+}
 
-  function verifyAttachments(finish) {
-
-
-    var digests = [];
-    docInfos.forEach(function (docInfo) {
-      if (docInfo.data && docInfo.data._attachments) {
-        Object.keys(docInfo.data._attachments).forEach(function (filename) {
-          var att = docInfo.data._attachments[filename];
-          if (att.stub) {
-            digests.push(att.digest);
+function adapterFun(name, callback) {
+  return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
+    if (this._closed) {
+      return Promise.reject(new Error('database is closed'));
+    }
+    if (this._destroyed) {
+      return Promise.reject(new Error('database is destroyed'));
+    }
+    var self = this;
+    logApiCall(self, name, args);
+    if (!this.taskqueue.isReady) {
+      return new Promise(function (fulfill, reject) {
+        self.taskqueue.addTask(function (failed) {
+          if (failed) {
+            reject(failed);
+          } else {
+            fulfill(self[name].apply(self, args));
           }
         });
-      }
-    });
-    if (!digests.length) {
-      return finish();
+      });
     }
-    var numDone = 0;
-    var err;
+    return callback.apply(this, args);
+  }));
+}
 
-    function checkDone() {
-      if (++numDone === digests.length) {
-        finish(err);
-      }
-    }
-    digests.forEach(function (digest) {
-      verifyAttachment(digest, function (attErr) {
-        if (attErr && !err) {
-          err = attErr;
-        }
-        checkDone();
-      });
-    });
+function mangle(key) {
+  return '$' + key;
+}
+function unmangle(key) {
+  return key.substring(1);
+}
+function Map$1() {
+  this._store = {};
+}
+Map$1.prototype.get = function (key) {
+  var mangled = mangle(key);
+  return this._store[mangled];
+};
+Map$1.prototype.set = function (key, value) {
+  var mangled = mangle(key);
+  this._store[mangled] = value;
+  return true;
+};
+Map$1.prototype.has = function (key) {
+  var mangled = mangle(key);
+  return mangled in this._store;
+};
+Map$1.prototype.delete = function (key) {
+  var mangled = mangle(key);
+  var res = mangled in this._store;
+  delete this._store[mangled];
+  return res;
+};
+Map$1.prototype.forEach = function (cb) {
+  var keys = Object.keys(this._store);
+  for (var i = 0, len = keys.length; i < len; i++) {
+    var key = keys[i];
+    var value = this._store[key];
+    key = unmangle(key);
+    cb(value, key);
   }
+};
+Object.defineProperty(Map$1.prototype, 'size', {
+  get: function () {
+    return Object.keys(this._store).length;
+  }
+});
 
-  function writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
-                    isUpdate, delta, resultsIdx, callback) {
-
-    docInfo.metadata.winningRev = winningRev$$1;
-    docInfo.metadata.deleted = winningRevIsDeleted;
-
-    var doc = docInfo.data;
-    doc._id = docInfo.metadata.id;
-    doc._rev = docInfo.metadata.rev;
-
-    if (newRevIsDeleted) {
-      doc._deleted = true;
-    }
+function Set$1(array) {
+  this._store = new Map$1();
 
-    var hasAttachments = doc._attachments &&
-      Object.keys(doc._attachments).length;
-    if (hasAttachments) {
-      return writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
-        isUpdate, resultsIdx, callback);
+  // init with an array
+  if (array && Array.isArray(array)) {
+    for (var i = 0, len = array.length; i < len; i++) {
+      this.add(array[i]);
     }
-
-    docCountDelta += delta;
-    updateDocCountIfReady();
-
-    finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
-      isUpdate, resultsIdx, callback);
   }
+}
+Set$1.prototype.add = function (key) {
+  return this._store.set(key, true);
+};
+Set$1.prototype.has = function (key) {
+  return this._store.has(key);
+};
+Set$1.prototype.forEach = function (cb) {
+  this._store.forEach(function (value, key) {
+    cb(key);
+  });
+};
+Object.defineProperty(Set$1.prototype, 'size', {
+  get: function () {
+    return this._store.size;
+  }
+});
 
-  function finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
-                     isUpdate, resultsIdx, callback) {
+/* global Map,Set,Symbol */
+// Based on https://kangax.github.io/compat-table/es6/ we can sniff out
+// incomplete Map/Set implementations which would otherwise cause our tests to fail.
+// Notably they fail in IE11 and iOS 8.4, which this prevents.
+function supportsMapAndSet() {
+  if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') {
+    return false;
+  }
+  var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
+  return prop && 'get' in prop && Map[Symbol.species] === Map;
+}
 
-    var doc = docInfo.data;
-    var metadata = docInfo.metadata;
+// based on https://github.com/montagejs/collections
 
-    doc._doc_id_rev = metadata.id + '::' + metadata.rev;
-    delete doc._id;
-    delete doc._rev;
+var ExportedSet;
+var ExportedMap;
 
-    function afterPutDoc(e) {
-      var revsToDelete = docInfo.stemmedRevs || [];
+{
+  if (supportsMapAndSet()) { // prefer built-in Map/Set
+    ExportedSet = Set;
+    ExportedMap = Map;
+  } else { // fall back to our polyfill
+    ExportedSet = Set$1;
+    ExportedMap = Map$1;
+  }
+}
 
-      if (isUpdate && api.auto_compaction) {
-        revsToDelete = revsToDelete.concat(compactTree(docInfo.metadata));
-      }
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var prop = arr[i];
+    if (prop in obj) {
+      res[prop] = obj[prop];
+    }
+  }
+  return res;
+}
 
-      if (revsToDelete && revsToDelete.length) {
-        compactRevs(revsToDelete, docInfo.metadata.id, txn);
-      }
+// Most browsers throttle concurrent requests at 6, so it's silly
+// to shim _bulk_get by trying to launch potentially hundreds of requests
+// and then letting the majority time out. We can handle this ourselves.
+var MAX_NUM_CONCURRENT_REQUESTS = 6;
 
-      metadata.seq = e.target.result;
-      // Current _rev is calculated from _rev_tree on read
-      // delete metadata.rev;
-      var metadataToStore = encodeMetadata(metadata, winningRev$$1,
-        winningRevIsDeleted);
-      var metaDataReq = docStore.put(metadataToStore);
-      metaDataReq.onsuccess = afterPutMetadata;
-    }
+function identityFunction(x) {
+  return x;
+}
 
-    function afterPutDocError(e) {
-      // ConstraintError, need to update, not put (see #1638 for details)
-      e.preventDefault(); // avoid transaction abort
-      e.stopPropagation(); // avoid transaction onerror
-      var index = bySeqStore.index('_doc_id_rev');
-      var getKeyReq = index.getKey(doc._doc_id_rev);
-      getKeyReq.onsuccess = function (e) {
-        var putReq = bySeqStore.put(doc, e.target.result);
-        putReq.onsuccess = afterPutDoc;
-      };
-    }
+function formatResultForOpenRevsGet(result) {
+  return [{
+    ok: result
+  }];
+}
 
-    function afterPutMetadata() {
-      results[resultsIdx] = {
-        ok: true,
-        id: metadata.id,
-        rev: metadata.rev
-      };
-      fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
-      insertAttachmentMappings(docInfo, metadata.seq, callback);
+// shim for P/CouchDB adapters that don't directly implement _bulk_get
+function bulkGet(db, opts, callback) {
+  var requests = opts.docs;
+
+  // consolidate into one request per doc if possible
+  var requestsById = new ExportedMap();
+  requests.forEach(function (request) {
+    if (requestsById.has(request.id)) {
+      requestsById.get(request.id).push(request);
+    } else {
+      requestsById.set(request.id, [request]);
     }
+  });
 
-    var putReq = bySeqStore.put(doc);
+  var numDocs = requestsById.size;
+  var numDone = 0;
+  var perDocResults = new Array(numDocs);
 
-    putReq.onsuccess = afterPutDoc;
-    putReq.onerror = afterPutDocError;
+  function collapseResultsAndFinish() {
+    var results = [];
+    perDocResults.forEach(function (res) {
+      res.docs.forEach(function (info) {
+        results.push({
+          id: res.id,
+          docs: [info]
+        });
+      });
+    });
+    callback(null, {results: results});
   }
 
-  function writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
-                            isUpdate, resultsIdx, callback) {
+  function checkDone() {
+    if (++numDone === numDocs) {
+      collapseResultsAndFinish();
+    }
+  }
 
+  function gotResult(docIndex, id, docs) {
+    perDocResults[docIndex] = {id: id, docs: docs};
+    checkDone();
+  }
 
-    var doc = docInfo.data;
+  var allRequests = [];
+  requestsById.forEach(function (value, key) {
+    allRequests.push(key);
+  });
 
-    var numDone = 0;
-    var attachments = Object.keys(doc._attachments);
+  var i = 0;
 
-    function collectResults() {
-      if (numDone === attachments.length) {
-        finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
-          isUpdate, resultsIdx, callback);
-      }
-    }
+  function nextBatch() {
 
-    function attachmentSaved() {
-      numDone++;
-      collectResults();
+    if (i >= allRequests.length) {
+      return;
     }
 
-    attachments.forEach(function (key) {
-      var att = docInfo.data._attachments[key];
-      if (!att.stub) {
-        var data = att.data;
-        delete att.data;
-        att.revpos = parseInt(winningRev$$1, 10);
-        var digest = att.digest;
-        saveAttachment(digest, data, attachmentSaved);
-      } else {
-        numDone++;
-        collectResults();
-      }
-    });
+    var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length);
+    var batch = allRequests.slice(i, upTo);
+    processBatch(batch, i);
+    i += batch.length;
   }
 
-  // map seqs to attachment digests, which
-  // we will need later during compaction
-  function insertAttachmentMappings(docInfo, seq, callback) {
+  function processBatch(batch, offset) {
+    batch.forEach(function (docId, j) {
+      var docIdx = offset + j;
+      var docRequests = requestsById.get(docId);
 
-    var attsAdded = 0;
-    var attsToAdd = Object.keys(docInfo.data._attachments || {});
+      // just use the first request as the "template"
+      // TODO: The _bulk_get API allows for more subtle use cases than this,
+      // but for now it is unlikely that there will be a mix of different
+      // "atts_since" or "attachments" in the same request, since it's just
+      // replicate.js that is using this for the moment.
+      // Also, atts_since is aspirational, since we don't support it yet.
+      var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
+      docOpts.open_revs = docRequests.map(function (request) {
+        // rev is optional, open_revs disallowed
+        return request.rev;
+      });
 
-    if (!attsToAdd.length) {
-      return callback();
-    }
+      // remove falsey / undefined revisions
+      docOpts.open_revs = docOpts.open_revs.filter(identityFunction);
 
-    function checkDone() {
-      if (++attsAdded === attsToAdd.length) {
-        callback();
+      var formatResult = identityFunction;
+
+      if (docOpts.open_revs.length === 0) {
+        delete docOpts.open_revs;
+
+        // when fetching only the "winning" leaf,
+        // transform the result so it looks like an open_revs
+        // request
+        formatResult = formatResultForOpenRevsGet;
       }
-    }
 
-    function add(att) {
-      var digest = docInfo.data._attachments[att].digest;
-      var req = attachAndSeqStore.put({
-        seq: seq,
-        digestSeq: digest + '::' + seq
+      // globally-supplied options
+      ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) {
+        if (param in opts) {
+          docOpts[param] = opts[param];
+        }
       });
-
-      req.onsuccess = checkDone;
-      req.onerror = function (e) {
-        // this callback is for a constaint error, which we ignore
-        // because this docid/rev has already been associated with
-        // the digest (e.g. when new_edits == false)
-        e.preventDefault(); // avoid transaction abort
-        e.stopPropagation(); // avoid transaction onerror
-        checkDone();
-      };
-    }
-    for (var i = 0; i < attsToAdd.length; i++) {
-      add(attsToAdd[i]); // do in parallel
-    }
+      db.get(docId, docOpts, function (err, res) {
+        var result;
+        /* istanbul ignore if */
+        if (err) {
+          result = [{error: err}];
+        } else {
+          result = formatResult(res);
+        }
+        gotResult(docIdx, docId, result);
+        nextBatch();
+      });
+    });
   }
 
-  function saveAttachment(digest, data, callback) {
-
+  nextBatch();
 
-    var getKeyReq = attachStore.count(digest);
-    getKeyReq.onsuccess = function (e) {
-      var count = e.target.result;
-      if (count) {
-        return callback(); // already exists
-      }
-      var newAtt = {
-        digest: digest,
-        body: data
-      };
-      var putReq = attachStore.put(newAtt);
-      putReq.onsuccess = callback;
-    };
-  }
 }
 
-// Abstraction over IDBCursor and getAll()/getAllKeys() that allows us to batch our operations
-// while falling back to a normal IDBCursor operation on browsers that don't support getAll() or
-// getAllKeys(). This allows for a much faster implementation than just straight-up cursors, because
-// we're not processing each document one-at-a-time.
-function runBatchedCursor(objectStore, keyRange, descending, batchSize, onBatch) {
+var hasLocal;
 
-  if (batchSize === -1) {
-    batchSize = 1000;
-  }
+try {
+  localStorage.setItem('_pouch_check_localstorage', 1);
+  hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+} catch (e) {
+  hasLocal = false;
+}
 
-  // Bail out of getAll()/getAllKeys() in the following cases:
-  // 1) either method is unsupported - we need both
-  // 2) batchSize is 1 (might as well use IDBCursor)
-  // 3) descending – no real way to do this via getAll()/getAllKeys()
+function hasLocalStorage() {
+  return hasLocal;
+}
 
-  var useGetAll = typeof objectStore.getAll === 'function' &&
-    typeof objectStore.getAllKeys === 'function' &&
-    batchSize > 1 && !descending;
+// Custom nextTick() shim for browsers. In node, this will just be process.nextTick(). We
 
-  var keysBatch;
-  var valuesBatch;
-  var pseudoCursor;
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
 
-  function onGetAll(e) {
-    valuesBatch = e.target.result;
-    if (keysBatch) {
-      onBatch(keysBatch, valuesBatch, pseudoCursor);
-    }
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+  if (hasLocalStorage()) {
+    addEventListener("storage", function (e) {
+      self.emit(e.key);
+    });
   }
+}
 
-  function onGetAllKeys(e) {
-    keysBatch = e.target.result;
-    if (valuesBatch) {
-      onBatch(keysBatch, valuesBatch, pseudoCursor);
-    }
-  }
+function Changes() {
+  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
+  this._listeners = {};
 
-  function continuePseudoCursor() {
-    if (!keysBatch.length) { // no more results
-      return onBatch();
+  attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+  /* istanbul ignore if */
+  if (this._listeners[id]) {
+    return;
+  }
+  var self = this;
+  var inprogress = false;
+  function eventFunction() {
+    /* istanbul ignore if */
+    if (!self._listeners[id]) {
+      return;
     }
-    // fetch next batch, exclusive start
-    var lastKey = keysBatch[keysBatch.length - 1];
-    var newKeyRange;
-    if (keyRange && keyRange.upper) {
-      try {
-        newKeyRange = IDBKeyRange.bound(lastKey, keyRange.upper,
-          true, keyRange.upperOpen);
-      } catch (e) {
-        if (e.name === "DataError" && e.code === 0) {
-          return onBatch(); // we're done, startkey and endkey are equal
-        }
-      }
-    } else {
-      newKeyRange = IDBKeyRange.lowerBound(lastKey, true);
+    if (inprogress) {
+      inprogress = 'waiting';
+      return;
     }
-    keyRange = newKeyRange;
-    keysBatch = null;
-    valuesBatch = null;
-    objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
-    objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
-  }
+    inprogress = true;
+    var changesOpts = pick(opts, [
+      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+      'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
+    ]);
 
-  function onCursor(e) {
-    var cursor = e.target.result;
-    if (!cursor) { // done
-      return onBatch();
+    /* istanbul ignore next */
+    function onError() {
+      inprogress = false;
     }
-    // regular IDBCursor acts like a batch where batch size is always 1
-    onBatch([cursor.key], [cursor.value], cursor);
-  }
 
-  if (useGetAll) {
-    pseudoCursor = {"continue": continuePseudoCursor};
-    objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
-    objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
-  } else if (descending) {
-    objectStore.openCursor(keyRange, 'prev').onsuccess = onCursor;
-  } else {
-    objectStore.openCursor(keyRange).onsuccess = onCursor;
+    db.changes(changesOpts).on('change', function (c) {
+      if (c.seq > opts.since && !opts.cancelled) {
+        opts.since = c.seq;
+        opts.onChange(c);
+      }
+    }).on('complete', function () {
+      if (inprogress === 'waiting') {
+        immediate__WEBPACK_IMPORTED_MODULE_1___default()(eventFunction);
+      }
+      inprogress = false;
+    }).on('error', onError);
   }
-}
+  this._listeners[id] = eventFunction;
+  this.on(dbName, eventFunction);
+};
 
-// simple shim for objectStore.getAll(), falling back to IDBCursor
-function getAll(objectStore, keyRange, onSuccess) {
-  if (typeof objectStore.getAll === 'function') {
-    // use native getAll
-    objectStore.getAll(keyRange).onsuccess = onSuccess;
+Changes.prototype.removeListener = function (dbName, id) {
+  /* istanbul ignore if */
+  if (!(id in this._listeners)) {
     return;
   }
-  // fall back to cursors
-  var values = [];
+  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype.removeListener.call(this, dbName,
+    this._listeners[id]);
+  delete this._listeners[id];
+};
 
-  function onCursor(e) {
-    var cursor = e.target.result;
-    if (cursor) {
-      values.push(cursor.value);
-      cursor.continue();
-    } else {
-      onSuccess({
-        target: {
-          result: values
-        }
-      });
-    }
-  }
 
-  objectStore.openCursor(keyRange).onsuccess = onCursor;
-}
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+  //do a useless change on a storage thing
+  //in order to get other windows's listeners to activate
+  if (hasLocalStorage()) {
+    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+  }
+};
 
-function allDocsKeys(keys, docStore, onBatch) {
-  // It's not guaranted to be returned in right order  
-  var valuesBatch = new Array(keys.length);
-  var count = 0;
-  keys.forEach(function (key, index) {
-    docStore.get(key).onsuccess = function (event) {
-      if (event.target.result) {
-        valuesBatch[index] = event.target.result;
-      } else {
-        valuesBatch[index] = {key: key, error: 'not_found'};
-      }
-      count++;
-      if (count === keys.length) {
-        onBatch(keys, valuesBatch, {});
-      }
-    };
-  });
-}
+Changes.prototype.notify = function (dbName) {
+  this.emit(dbName);
+  this.notifyLocalWindows(dbName);
+};
 
-function createKeyRange(start, end, inclusiveEnd, key, descending) {
-  try {
-    if (start && end) {
-      if (descending) {
-        return IDBKeyRange.bound(end, start, !inclusiveEnd, false);
-      } else {
-        return IDBKeyRange.bound(start, end, false, !inclusiveEnd);
-      }
-    } else if (start) {
-      if (descending) {
-        return IDBKeyRange.upperBound(start);
-      } else {
-        return IDBKeyRange.lowerBound(start);
-      }
-    } else if (end) {
-      if (descending) {
-        return IDBKeyRange.lowerBound(end, !inclusiveEnd);
-      } else {
-        return IDBKeyRange.upperBound(end, !inclusiveEnd);
-      }
-    } else if (key) {
-      return IDBKeyRange.only(key);
-    }
-  } catch (e) {
-    return {error: e};
+function guardedConsole(method) {
+  /* istanbul ignore else */
+  if (typeof console !== 'undefined' && typeof console[method] === 'function') {
+    var args = Array.prototype.slice.call(arguments, 1);
+    console[method].apply(console, args);
   }
-  return null;
 }
 
-function idbAllDocs(opts, idb, callback) {
-  var start = 'startkey' in opts ? opts.startkey : false;
-  var end = 'endkey' in opts ? opts.endkey : false;
-  var key = 'key' in opts ? opts.key : false;
-  var keys = 'keys' in opts ? opts.keys : false; 
-  var skip = opts.skip || 0;
-  var limit = typeof opts.limit === 'number' ? opts.limit : -1;
-  var inclusiveEnd = opts.inclusive_end !== false;
-
-  var keyRange ; 
-  var keyRangeError;
-  if (!keys) {
-    keyRange = createKeyRange(start, end, inclusiveEnd, key, opts.descending);
-    keyRangeError = keyRange && keyRange.error;
-    if (keyRangeError && 
-      !(keyRangeError.name === "DataError" && keyRangeError.code === 0)) {
-      // DataError with error code 0 indicates start is less than end, so
-      // can just do an empty query. Else need to throw
-      return callback(createError(IDB_ERROR,
-        keyRangeError.name, keyRangeError.message));
-    }
+function randomNumber(min, max) {
+  var maxTimeout = 600000; // Hard-coded default of 10 minutes
+  min = parseInt(min, 10) || 0;
+  max = parseInt(max, 10);
+  if (max !== max || max <= min) {
+    max = (min || 1) << 1; //doubling
+  } else {
+    max = max + 1;
+  }
+  // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout
+  if (max > maxTimeout) {
+    min = maxTimeout >> 1; // divide by two
+    max = maxTimeout;
   }
+  var ratio = Math.random();
+  var range = max - min;
 
-  var stores = [DOC_STORE, BY_SEQ_STORE, META_STORE];
+  return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
+}
 
-  if (opts.attachments) {
-    stores.push(ATTACH_STORE);
-  }
-  var txnResult = openTransactionSafely(idb, stores, 'readonly');
-  if (txnResult.error) {
-    return callback(txnResult.error);
+function defaultBackOff(min) {
+  var max = 0;
+  if (!min) {
+    max = 2000;
   }
-  var txn = txnResult.txn;
-  txn.oncomplete = onTxnComplete;
-  txn.onabort = idbError(callback);
-  var docStore = txn.objectStore(DOC_STORE);
-  var seqStore = txn.objectStore(BY_SEQ_STORE);
-  var metaStore = txn.objectStore(META_STORE);
-  var docIdRevIndex = seqStore.index('_doc_id_rev');
-  var results = [];
-  var docCount;
-  var updateSeq;
+  return randomNumber(min, max);
+}
 
-  metaStore.get(META_STORE).onsuccess = function (e) {
-    docCount = e.target.result.docCount;
-  };
+// designed to give info to browser users, who are disturbed
+// when they see http errors in the console
+function explainError(status, str) {
+  guardedConsole('info', 'The above ' + status + ' is totally normal. ' + str);
+}
 
-  /* istanbul ignore if */
-  if (opts.update_seq) {
-    getMaxUpdateSeq(seqStore, function (e) { 
-      if (e.target.result && e.target.result.length > 0) {
-        updateSeq = e.target.result[0];
-      }
-    });
-  }
+var assign;
+{
+  if (typeof Object.assign === 'function') {
+    assign = Object.assign;
+  } else {
+    // lite Object.assign polyfill based on
+    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+    assign = function (target) {
+      var to = Object(target);
 
-  function getMaxUpdateSeq(objectStore, onSuccess) {
-    function onCursor(e) {
-      var cursor = e.target.result;
-      var maxKey = undefined;
-      if (cursor && cursor.key) {
-        maxKey = cursor.key;
-      } 
-      return onSuccess({
-        target: {
-          result: [maxKey]
-        }
-      });
-    }
-    objectStore.openCursor(null, 'prev').onsuccess = onCursor;
-  }
+      for (var index = 1; index < arguments.length; index++) {
+        var nextSource = arguments[index];
 
-  // if the user specifies include_docs=true, then we don't
-  // want to block the main cursor while we're fetching the doc
-  function fetchDocAsynchronously(metadata, row, winningRev$$1) {
-    var key = metadata.id + "::" + winningRev$$1;
-    docIdRevIndex.get(key).onsuccess =  function onGetDoc(e) {
-      row.doc = decodeDoc(e.target.result) || {};
-      if (opts.conflicts) {
-        var conflicts = collectConflicts(metadata);
-        if (conflicts.length) {
-          row.doc._conflicts = conflicts;
+        if (nextSource != null) { // Skip over if undefined or null
+          for (var nextKey in nextSource) {
+            // Avoid bugs when hasOwnProperty is shadowed
+            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+              to[nextKey] = nextSource[nextKey];
+            }
+          }
         }
       }
-      fetchAttachmentsIfNecessary(row.doc, opts, txn);
+      return to;
     };
   }
+}
 
-  function allDocsInner(winningRev$$1, metadata) {
-    var row = {
-      id: metadata.id,
-      key: metadata.id,
-      value: {
-        rev: winningRev$$1
-      }
-    };
-    var deleted = metadata.deleted;
-    if (deleted) {
-      if (keys) {
-        results.push(row);
-        // deleted docs are okay with "keys" requests
-        row.value.deleted = true;
-        row.doc = null;
-      }
-    } else if (skip-- <= 0) {
-      results.push(row);
-      if (opts.include_docs) {
-        fetchDocAsynchronously(metadata, row, winningRev$$1);
-      }
-    }
-  }
+var $inject_Object_assign = assign;
 
-  function processBatch(batchValues) {
-    for (var i = 0, len = batchValues.length; i < len; i++) {
-      if (results.length === limit) {
-        break;
-      }
-      var batchValue = batchValues[i];
-      if (batchValue.error && keys) {
-        // key was not found with "keys" requests
-        results.push(batchValue);
-        continue;
-      }
-      var metadata = decodeMetadata(batchValue);
-      var winningRev$$1 = metadata.winningRev;
-      allDocsInner(winningRev$$1, metadata);
-    }
-  }
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchError, Error);
 
-  function onBatch(batchKeys, batchValues, cursor) {
-    if (!cursor) {
-      return;
+function PouchError(status, error, reason) {
+  Error.call(this, reason);
+  this.status = status;
+  this.name = error;
+  this.message = reason;
+  this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+  return JSON.stringify({
+    status: this.status,
+    name: this.name,
+    message: this.message,
+    reason: this.reason
+  });
+};
+
+var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect.");
+var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'");
+var MISSING_DOC = new PouchError(404, 'not_found', 'missing');
+var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict');
+var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string');
+var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts');
+var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.');
+var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open');
+var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error');
+var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid');
+var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid');
+var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid');
+var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member');
+var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request');
+var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object');
+var DB_MISSING = new PouchError(404, 'not_found', 'Database not found');
+var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown');
+var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown');
+var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown');
+var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function');
+var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format');
+var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.');
+var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found');
+var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid');
+
+function createError(error, reason) {
+  function CustomPouchError(reason) {
+    // inherit error properties from our parent error manually
+    // so as to allow proper JSON parsing.
+    /* jshint ignore:start */
+    for (var p in error) {
+      if (typeof error[p] !== 'function') {
+        this[p] = error[p];
+      }
     }
-    processBatch(batchValues);
-    if (results.length < limit) {
-      cursor.continue();
+    /* jshint ignore:end */
+    if (reason !== undefined) {
+      this.reason = reason;
     }
   }
+  CustomPouchError.prototype = PouchError.prototype;
+  return new CustomPouchError(reason);
+}
 
-  function onGetAll(e) {
-    var values = e.target.result;
-    if (opts.descending) {
-      values = values.reverse();
-    }
-    processBatch(values);
+function generateErrorFromResponse(err) {
+
+  if (typeof err !== 'object') {
+    var data = err;
+    err = UNKNOWN_ERROR;
+    err.data = data;
   }
 
-  function onResultsReady() {
-    var returnVal = {
-      total_rows: docCount,
-      offset: opts.skip,
-      rows: results
-    };
-    
-    /* istanbul ignore if */
-    if (opts.update_seq && updateSeq !== undefined) {
-      returnVal.update_seq = updateSeq;
-    }
-    callback(null, returnVal);
+  if ('error' in err && err.error === 'conflict') {
+    err.name = 'conflict';
+    err.status = 409;
   }
 
-  function onTxnComplete() {
-    if (opts.attachments) {
-      postProcessAttachments(results, opts.binary).then(onResultsReady);
-    } else {
-      onResultsReady();
-    }
+  if (!('name' in err)) {
+    err.name = err.error || 'unknown';
   }
 
-  // don't bother doing any requests if start > end or limit === 0
-  if (keyRangeError || limit === 0) {
-    return;
+  if (!('status' in err)) {
+    err.status = 500;
   }
-  if (keys) {
-    return allDocsKeys(opts.keys, docStore, onBatch);
+
+  if (!('message' in err)) {
+    err.message = err.message || err.reason;
   }
-  if (limit === -1) { // just fetch everything
-    return getAll(docStore, keyRange, onGetAll);
+
+  return err;
+}
+
+function tryFilter(filter, doc, req) {
+  try {
+    return !filter(doc, req);
+  } catch (err) {
+    var msg = 'Filter function threw: ' + err.toString();
+    return createError(BAD_REQUEST, msg);
   }
-  // else do a cursor
-  // choose a batch size based on the skip, since we'll need to skip that many
-  runBatchedCursor(docStore, keyRange, opts.descending, limit + skip, onBatch);
 }
 
-//
-// Blobs are not supported in all versions of IndexedDB, notably
-// Chrome <37 and Android <5. In those versions, storing a blob will throw.
-//
-// Various other blob bugs exist in Chrome v37-42 (inclusive).
-// Detecting them is expensive and confusing to users, and Chrome 37-42
-// is at very low usage worldwide, so we do a hacky userAgent check instead.
-//
-// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120
-// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916
-// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836
-//
-function checkBlobSupport(txn) {
-  return new Promise(function (resolve) {
-    var blob$$1 = createBlob(['']);
-    var req = txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob$$1, 'key');
+function filterChange(opts) {
+  var req = {};
+  var hasFilter = opts.filter && typeof opts.filter === 'function';
+  req.query = opts.query_params;
 
-    req.onsuccess = function () {
-      var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/);
-      var matchedEdge = navigator.userAgent.match(/Edge\//);
-      // MS Edge pretends to be Chrome 42:
-      // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx
-      resolve(matchedEdge || !matchedChrome ||
-        parseInt(matchedChrome[1], 10) >= 43);
-    };
+  return function filter(change) {
+    if (!change.doc) {
+      // CSG sends events on the changes feed that don't have documents,
+      // this hack makes a whole lot of existing code robust.
+      change.doc = {};
+    }
 
-    req.onerror = txn.onabort = function (e) {
-      // If the transaction aborts now its due to not being able to
-      // write to the database, likely due to the disk being full
-      e.preventDefault();
-      e.stopPropagation();
-      resolve(false);
-    };
-  }).catch(function () {
-    return false; // error, so assume unsupported
-  });
-}
+    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
 
-function countDocs(txn, cb) {
-  var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
-  index.count(IDBKeyRange.only('0')).onsuccess = function (e) {
-    cb(e.target.result);
+    if (typeof filterReturn === 'object') {
+      return filterReturn;
+    }
+
+    if (filterReturn) {
+      return false;
+    }
+
+    if (!opts.include_docs) {
+      delete change.doc;
+    } else if (!opts.attachments) {
+      for (var att in change.doc._attachments) {
+        /* istanbul ignore else */
+        if (change.doc._attachments.hasOwnProperty(att)) {
+          change.doc._attachments[att].stub = true;
+        }
+      }
+    }
+    return true;
   };
 }
 
-// This task queue ensures that IDB open calls are done in their own tick
+function flatten(arrs) {
+  var res = [];
+  for (var i = 0, len = arrs.length; i < len; i++) {
+    res = res.concat(arrs[i]);
+  }
+  return res;
+}
 
-var running = false;
-var queue = [];
+// shim for Function.prototype.name,
 
-function tryCode(fun, err, res, PouchDB) {
-  try {
-    fun(err, res);
-  } catch (err) {
-    // Shouldn't happen, but in some odd cases
-    // IndexedDB implementations might throw a sync
-    // error, in which case this will at least log it.
-    PouchDB.emit('error', err);
+// Determine id an ID is valid
+//   - invalid IDs begin with an underescore that does not begin '_design' or
+//     '_local'
+//   - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+  var err;
+  if (!id) {
+    err = createError(MISSING_ID);
+  } else if (typeof id !== 'string') {
+    err = createError(INVALID_ID);
+  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+    err = createError(RESERVED_ID);
+  }
+  if (err) {
+    throw err;
   }
 }
 
-function applyNext() {
-  if (running || !queue.length) {
-    return;
+// Checks if a PouchDB object is "remote" or not. This is
+
+function isRemote(db) {
+  if (typeof db._remote === 'boolean') {
+    return db._remote;
   }
-  running = true;
-  queue.shift()();
+  /* istanbul ignore next */
+  if (typeof db.type === 'function') {
+    guardedConsole('warn',
+      'db.type() is deprecated and will be removed in ' +
+      'a future version of PouchDB');
+    return db.type() === 'http';
+  }
+  /* istanbul ignore next */
+  return false;
 }
 
-function enqueueTask(action, callback, PouchDB) {
-  queue.push(function runAction() {
-    action(function runCallback(err, res) {
-      tryCode(callback, err, res, PouchDB);
-      running = false;
-      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function runNext() {
-        applyNext(PouchDB);
-      });
-    });
-  });
-  applyNext();
+function listenerCount(ee, type) {
+  return 'listenerCount' in ee ? ee.listenerCount(type) :
+                                 events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.listenerCount(ee, type);
 }
 
-function changes(opts, api, dbName, idb) {
-  opts = clone(opts);
-
-  if (opts.continuous) {
-    var id = dbName + ':' + uuid();
-    changesHandler.addListener(dbName, id, api, opts);
-    changesHandler.notify(dbName);
-    return {
-      cancel: function () {
-        changesHandler.removeListener(dbName, id);
-      }
-    };
+function parseDesignDocFunctionName(s) {
+  if (!s) {
+    return null;
+  }
+  var parts = s.split('/');
+  if (parts.length === 2) {
+    return parts;
+  }
+  if (parts.length === 1) {
+    return [s, s];
   }
+  return null;
+}
 
-  var docIds = opts.doc_ids && new ExportedSet(opts.doc_ids);
+function normalizeDesignDocFunctionName(s) {
+  var normalized = parseDesignDocFunctionName(s);
+  return normalized ? normalized.join('/') : null;
+}
 
-  opts.since = opts.since || 0;
-  var lastSeq = opts.since;
+// originally parseUri 1.2.2, now patched by us
+// (c) Steven Levithan <stevenlevithan.com>
+// MIT License
+var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
+    "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
+var qName ="queryKey";
+var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
 
-  var limit = 'limit' in opts ? opts.limit : -1;
-  if (limit === 0) {
-    limit = 1; // per CouchDB _changes spec
-  }
+// use the "loose" parser
+/* eslint maxlen: 0, no-useless-escape: 0 */
+var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
 
-  var results = [];
-  var numResults = 0;
-  var filter = filterChange(opts);
-  var docIdsToMetadata = new ExportedMap();
+function parseUri(str) {
+  var m = parser.exec(str);
+  var uri = {};
+  var i = 14;
 
-  var txn;
-  var bySeqStore;
-  var docStore;
-  var docIdRevIndex;
+  while (i--) {
+    var key = keys[i];
+    var value = m[i] || "";
+    var encoded = ['user', 'password'].indexOf(key) !== -1;
+    uri[key] = encoded ? decodeURIComponent(value) : value;
+  }
 
-  function onBatch(batchKeys, batchValues, cursor) {
-    if (!cursor || !batchKeys.length) { // done
-      return;
+  uri[qName] = {};
+  uri[keys[12]].replace(qParser, function ($0, $1, $2) {
+    if ($1) {
+      uri[qName][$1] = $2;
     }
+  });
 
-    var winningDocs = new Array(batchKeys.length);
-    var metadatas = new Array(batchKeys.length);
-
-    function processMetadataAndWinningDoc(metadata, winningDoc) {
-      var change = opts.processChange(winningDoc, metadata, opts);
-      lastSeq = change.seq = metadata.seq;
+  return uri;
+}
 
-      var filtered = filter(change);
-      if (typeof filtered === 'object') { // anything but true/false indicates error
-        return Promise.reject(filtered);
-      }
+// Based on https://github.com/alexdavid/scope-eval v0.0.3
+// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js)
+// This is basically just a wrapper around new Function()
 
-      if (!filtered) {
-        return Promise.resolve();
-      }
-      numResults++;
-      if (opts.return_docs) {
-        results.push(change);
-      }
-      // process the attachment immediately
-      // for the benefit of live listeners
-      if (opts.attachments && opts.include_docs) {
-        return new Promise(function (resolve) {
-          fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () {
-            postProcessAttachments([change], opts.binary).then(function () {
-              resolve(change);
-            });
-          });
-        });
-      } else {
-        return Promise.resolve(change);
-      }
+function scopeEval(source, scope) {
+  var keys = [];
+  var values = [];
+  for (var key in scope) {
+    if (scope.hasOwnProperty(key)) {
+      keys.push(key);
+      values.push(scope[key]);
     }
+  }
+  keys.push(source);
+  return Function.apply(null, keys).apply(null, values);
+}
 
-    function onBatchDone() {
-      var promises = [];
-      for (var i = 0, len = winningDocs.length; i < len; i++) {
-        if (numResults === limit) {
-          break;
-        }
-        var winningDoc = winningDocs[i];
-        if (!winningDoc) {
-          continue;
+// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
+// the diffFun tells us what delta to apply to the doc.  it either returns
+// the doc, or false if it doesn't need to do an update after all
+function upsert(db, docId, diffFun) {
+  return new Promise(function (fulfill, reject) {
+    db.get(docId, function (err, doc) {
+      if (err) {
+        /* istanbul ignore next */
+        if (err.status !== 404) {
+          return reject(err);
         }
-        var metadata = metadatas[i];
-        promises.push(processMetadataAndWinningDoc(metadata, winningDoc));
+        doc = {};
       }
 
-      Promise.all(promises).then(function (changes) {
-        for (var i = 0, len = changes.length; i < len; i++) {
-          if (changes[i]) {
-            opts.onChange(changes[i]);
-          }
-        }
-      }).catch(opts.complete);
+      // the user might change the _rev, so save it for posterity
+      var docRev = doc._rev;
+      var newDoc = diffFun(doc);
 
-      if (numResults !== limit) {
-        cursor.continue();
+      if (!newDoc) {
+        // if the diffFun returns falsy, we short-circuit as
+        // an optimization
+        return fulfill({updated: false, rev: docRev});
       }
-    }
 
-    // Fetch all metadatas/winningdocs from this batch in parallel, then process
-    // them all only once all data has been collected. This is done in parallel
-    // because it's faster than doing it one-at-a-time.
-    var numDone = 0;
-    batchValues.forEach(function (value, i) {
-      var doc = decodeDoc(value);
-      var seq = batchKeys[i];
-      fetchWinningDocAndMetadata(doc, seq, function (metadata, winningDoc) {
-        metadatas[i] = metadata;
-        winningDocs[i] = winningDoc;
-        if (++numDone === batchKeys.length) {
-          onBatchDone();
-        }
-      });
+      // users aren't allowed to modify these values,
+      // so reset them here
+      newDoc._id = docId;
+      newDoc._rev = docRev;
+      fulfill(tryAndPut(db, newDoc, diffFun));
     });
-  }
+  });
+}
 
-  function onGetMetadata(doc, seq, metadata, cb) {
-    if (metadata.seq !== seq) {
-      // some other seq is later
-      return cb();
+function tryAndPut(db, doc, diffFun) {
+  return db.put(doc).then(function (res) {
+    return {
+      updated: true,
+      rev: res.rev
+    };
+  }, function (err) {
+    /* istanbul ignore next */
+    if (err.status !== 409) {
+      throw err;
+    }
+    return upsert(db, doc._id, diffFun);
+  });
+}
+
+var thisAtob = function (str) {
+  return atob(str);
+};
+
+var thisBtoa = function (str) {
+  return btoa(str);
+};
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+  parts = parts || [];
+  properties = properties || {};
+  try {
+    return new Blob(parts, properties);
+  } catch (e) {
+    if (e.name !== "TypeError") {
+      throw e;
     }
-
-    if (metadata.winningRev === doc._rev) {
-      // this is the winning doc
-      return cb(metadata, doc);
+    var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+                  typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+                  typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+                  WebKitBlobBuilder;
+    var builder = new Builder();
+    for (var i = 0; i < parts.length; i += 1) {
+      builder.append(parts[i]);
     }
+    return builder.getBlob(properties.type);
+  }
+}
 
-    // fetch winning doc in separate request
-    var docIdRev = doc._id + '::' + metadata.winningRev;
-    var req = docIdRevIndex.get(docIdRev);
-    req.onsuccess = function (e) {
-      cb(metadata, decodeDoc(e.target.result));
-    };
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+  var length = bin.length;
+  var buf = new ArrayBuffer(length);
+  var arr = new Uint8Array(buf);
+  for (var i = 0; i < length; i++) {
+    arr[i] = bin.charCodeAt(i);
   }
+  return buf;
+}
 
-  function fetchWinningDocAndMetadata(doc, seq, cb) {
-    if (docIds && !docIds.has(doc._id)) {
-      return cb();
-    }
+function binStringToBluffer(binString, type) {
+  return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
 
-    var metadata = docIdsToMetadata.get(doc._id);
-    if (metadata) { // cached
-      return onGetMetadata(doc, seq, metadata, cb);
-    }
-    // metadata not cached, have to go fetch it
-    docStore.get(doc._id).onsuccess = function (e) {
-      metadata = decodeMetadata(e.target.result);
-      docIdsToMetadata.set(doc._id, metadata);
-      onGetMetadata(doc, seq, metadata, cb);
-    };
-  }
+function b64ToBluffer(b64, type) {
+  return binStringToBluffer(thisAtob(b64), type);
+}
 
-  function finish() {
-    opts.complete(null, {
-      results: results,
-      last_seq: lastSeq
-    });
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+  var binary = '';
+  var bytes = new Uint8Array(buffer);
+  var length = bytes.byteLength;
+  for (var i = 0; i < length; i++) {
+    binary += String.fromCharCode(bytes[i]);
   }
+  return binary;
+}
 
-  function onTxnComplete() {
-    if (!opts.continuous && opts.attachments) {
-      // cannot guarantee that postProcessing was already done,
-      // so do it again
-      postProcessAttachments(results).then(finish);
-    } else {
-      finish();
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+  var reader = new FileReader();
+  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+  reader.onloadend = function (e) {
+    var result = e.target.result || '';
+    if (hasBinaryString) {
+      return callback(result);
     }
+    callback(arrayBufferToBinaryString(result));
+  };
+  if (hasBinaryString) {
+    reader.readAsBinaryString(blob);
+  } else {
+    reader.readAsArrayBuffer(blob);
   }
+}
 
-  var objectStores = [DOC_STORE, BY_SEQ_STORE];
-  if (opts.attachments) {
-    objectStores.push(ATTACH_STORE);
-  }
-  var txnResult = openTransactionSafely(idb, objectStores, 'readonly');
-  if (txnResult.error) {
-    return opts.complete(txnResult.error);
-  }
-  txn = txnResult.txn;
-  txn.onabort = idbError(opts.complete);
-  txn.oncomplete = onTxnComplete;
-
-  bySeqStore = txn.objectStore(BY_SEQ_STORE);
-  docStore = txn.objectStore(DOC_STORE);
-  docIdRevIndex = bySeqStore.index('_doc_id_rev');
+function blobToBinaryString(blobOrBuffer, callback) {
+  readAsBinaryString(blobOrBuffer, function (bin) {
+    callback(bin);
+  });
+}
 
-  var keyRange = (opts.since && !opts.descending) ?
-    IDBKeyRange.lowerBound(opts.since, true) : null;
+function blobToBase64(blobOrBuffer, callback) {
+  blobToBinaryString(blobOrBuffer, function (base64) {
+    callback(thisBtoa(base64));
+  });
+}
 
-  runBatchedCursor(bySeqStore, keyRange, opts.descending, limit, onBatch);
+// simplified API. universal browser support is assumed
+function readAsArrayBuffer(blob, callback) {
+  var reader = new FileReader();
+  reader.onloadend = function (e) {
+    var result = e.target.result || new ArrayBuffer(0);
+    callback(result);
+  };
+  reader.readAsArrayBuffer(blob);
 }
 
-var cachedDBs = new ExportedMap();
-var blobSupportPromise;
-var openReqList = new ExportedMap();
+// this is not used in the browser
 
-function IdbPouch(opts, callback) {
-  var api = this;
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
 
-  enqueueTask(function (thisCallback) {
-    init(api, opts, thisCallback);
-  }, callback, api.constructor);
+function rawToBase64(raw) {
+  return thisBtoa(raw);
 }
 
-function init(api, opts, callback) {
-
-  var dbName = opts.name;
+function sliceBlob(blob, start, end) {
+  if (blob.webkitSlice) {
+    return blob.webkitSlice(start, end);
+  }
+  return blob.slice(start, end);
+}
 
-  var idb = null;
-  api._meta = null;
+function appendBlob(buffer, blob, start, end, callback) {
+  if (start > 0 || end < blob.size) {
+    // only slice blob if we really need to
+    blob = sliceBlob(blob, start, end);
+  }
+  readAsArrayBuffer(blob, function (arrayBuffer) {
+    buffer.append(arrayBuffer);
+    callback();
+  });
+}
 
-  // called when creating a fresh new database
-  function createSchema(db) {
-    var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'});
-    db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
-    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
-    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
-    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
+function appendString(buffer, string, start, end, callback) {
+  if (start > 0 || end < string.length) {
+    // only create a substring if we really need to
+    string = string.substring(start, end);
+  }
+  buffer.appendBinary(string);
+  callback();
+}
 
-    // added in v2
-    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+function binaryMd5(data, callback) {
+  var inputIsString = typeof data === 'string';
+  var len = inputIsString ? data.length : data.size;
+  var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+  var chunks = Math.ceil(len / chunkSize);
+  var currentChunk = 0;
+  var buffer = inputIsString ? new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default())() : new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default().ArrayBuffer)();
 
-    // added in v3
-    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'});
+  var append = inputIsString ? appendString : appendBlob;
 
-    // added in v4
-    var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
-      {autoIncrement: true});
-    attAndSeqStore.createIndex('seq', 'seq');
-    attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+  function next() {
+    setImmediateShim(loadNextChunk);
   }
 
-  // migration to version 2
-  // unfortunately "deletedOrLocal" is a misnomer now that we no longer
-  // store local docs in the main doc-store, but whaddyagonnado
-  function addDeletedOrLocalIndex(txn, callback) {
-    var docStore = txn.objectStore(DOC_STORE);
-    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
-
-    docStore.openCursor().onsuccess = function (event) {
-      var cursor = event.target.result;
-      if (cursor) {
-        var metadata = cursor.value;
-        var deleted = isDeleted(metadata);
-        metadata.deletedOrLocal = deleted ? "1" : "0";
-        docStore.put(metadata);
-        cursor.continue();
-      } else {
-        callback();
-      }
-    };
+  function done() {
+    var raw = buffer.end(true);
+    var base64 = rawToBase64(raw);
+    callback(base64);
+    buffer.destroy();
   }
 
-  // migration to version 3 (part 1)
-  function createLocalStoreSchema(db) {
-    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'})
-      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+  function loadNextChunk() {
+    var start = currentChunk * chunkSize;
+    var end = start + chunkSize;
+    currentChunk++;
+    if (currentChunk < chunks) {
+      append(buffer, data, start, end, next);
+    } else {
+      append(buffer, data, start, end, done);
+    }
   }
+  loadNextChunk();
+}
 
-  // migration to version 3 (part 2)
-  function migrateLocalStore(txn, cb) {
-    var localStore = txn.objectStore(LOCAL_STORE);
-    var docStore = txn.objectStore(DOC_STORE);
-    var seqStore = txn.objectStore(BY_SEQ_STORE);
+function stringMd5(string) {
+  return spark_md5__WEBPACK_IMPORTED_MODULE_4___default().hash(string);
+}
 
-    var cursor = docStore.openCursor();
-    cursor.onsuccess = function (event) {
-      var cursor = event.target.result;
-      if (cursor) {
-        var metadata = cursor.value;
-        var docId = metadata.id;
-        var local = isLocalId(docId);
-        var rev = winningRev(metadata);
-        if (local) {
-          var docIdRev = docId + "::" + rev;
-          // remove all seq entries
-          // associated with this docId
-          var start = docId + "::";
-          var end = docId + "::~";
-          var index = seqStore.index('_doc_id_rev');
-          var range = IDBKeyRange.bound(start, end, false, false);
-          var seqCursor = index.openCursor(range);
-          seqCursor.onsuccess = function (e) {
-            seqCursor = e.target.result;
-            if (!seqCursor) {
-              // done
-              docStore.delete(cursor.primaryKey);
-              cursor.continue();
-            } else {
-              var data = seqCursor.value;
-              if (data._doc_id_rev === docIdRev) {
-                localStore.put(data);
-              }
-              seqStore.delete(seqCursor.primaryKey);
-              seqCursor.continue();
-            }
-          };
-        } else {
-          cursor.continue();
-        }
-      } else if (cb) {
-        cb();
-      }
-    };
+function rev$$1(doc, deterministic_revs) {
+  var clonedDoc = clone(doc);
+  if (!deterministic_revs) {
+    return uuid__WEBPACK_IMPORTED_MODULE_5___default().v4().replace(/-/g, '').toLowerCase();
   }
 
-  // migration to version 4 (part 1)
-  function addAttachAndSeqStore(db) {
-    var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
-      {autoIncrement: true});
-    attAndSeqStore.createIndex('seq', 'seq');
-    attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
-  }
+  delete clonedDoc._rev_tree;
+  return stringMd5(JSON.stringify(clonedDoc));
+}
 
-  // migration to version 4 (part 2)
-  function migrateAttsAndSeqs(txn, callback) {
-    var seqStore = txn.objectStore(BY_SEQ_STORE);
-    var attStore = txn.objectStore(ATTACH_STORE);
-    var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+var uuid = (uuid__WEBPACK_IMPORTED_MODULE_5___default().v4);
 
-    // need to actually populate the table. this is the expensive part,
-    // so as an optimization, check first that this database even
-    // contains attachments
-    var req = attStore.count();
-    req.onsuccess = function (e) {
-      var count = e.target.result;
-      if (!count) {
-        return callback(); // done
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+  var winningId;
+  var winningPos;
+  var winningDeleted;
+  var toVisit = metadata.rev_tree.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var tree = node.ids;
+    var branches = tree[2];
+    var pos = node.pos;
+    if (branches.length) { // non-leaf
+      for (var i = 0, len = branches.length; i < len; i++) {
+        toVisit.push({pos: pos + 1, ids: branches[i]});
       }
-
-      seqStore.openCursor().onsuccess = function (e) {
-        var cursor = e.target.result;
-        if (!cursor) {
-          return callback(); // done
-        }
-        var doc = cursor.value;
-        var seq = cursor.primaryKey;
-        var atts = Object.keys(doc._attachments || {});
-        var digestMap = {};
-        for (var j = 0; j < atts.length; j++) {
-          var att = doc._attachments[atts[j]];
-          digestMap[att.digest] = true; // uniq digests, just in case
-        }
-        var digests = Object.keys(digestMap);
-        for (j = 0; j < digests.length; j++) {
-          var digest = digests[j];
-          attAndSeqStore.put({
-            seq: seq,
-            digestSeq: digest + '::' + seq
-          });
-        }
-        cursor.continue();
-      };
-    };
+      continue;
+    }
+    var deleted = !!tree[1].deleted;
+    var id = tree[0];
+    // sort by deleted, then pos, then id
+    if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+        winningPos !== pos ? winningPos < pos : winningId < id)) {
+      winningId = id;
+      winningPos = pos;
+      winningDeleted = deleted;
+    }
   }
 
-  // migration to version 5
-  // Instead of relying on on-the-fly migration of metadata,
-  // this brings the doc-store to its modern form:
-  // - metadata.winningrev
-  // - metadata.seq
-  // - stringify the metadata when storing it
-  function migrateMetadata(txn) {
+  return winningPos + '-' + winningId;
+}
 
-    function decodeMetadataCompat(storedObject) {
-      if (!storedObject.data) {
-        // old format, when we didn't store it stringified
-        storedObject.deleted = storedObject.deletedOrLocal === '1';
-        return storedObject;
-      }
-      return decodeMetadata(storedObject);
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+  var toVisit = revs.slice();
+
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var branches = tree[2];
+    var newCtx =
+      callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
     }
+  }
+}
 
-    // ensure that every metadata has a winningRev and seq,
-    // which was previously created on-the-fly but better to migrate
-    var bySeqStore = txn.objectStore(BY_SEQ_STORE);
-    var docStore = txn.objectStore(DOC_STORE);
-    var cursor = docStore.openCursor();
-    cursor.onsuccess = function (e) {
-      var cursor = e.target.result;
-      if (!cursor) {
-        return; // done
-      }
-      var metadata = decodeMetadataCompat(cursor.value);
+function sortByPos(a, b) {
+  return a.pos - b.pos;
+}
 
-      metadata.winningRev = metadata.winningRev ||
-        winningRev(metadata);
+function collectLeaves(revs) {
+  var leaves = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+    if (isLeaf) {
+      leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+    }
+  });
+  leaves.sort(sortByPos).reverse();
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    delete leaves[i].pos;
+  }
+  return leaves;
+}
 
-      function fetchMetadataSeq() {
-        // metadata.seq was added post-3.2.0, so if it's missing,
-        // we need to fetch it manually
-        var start = metadata.id + '::';
-        var end = metadata.id + '::\uffff';
-        var req = bySeqStore.index('_doc_id_rev').openCursor(
-          IDBKeyRange.bound(start, end));
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+  var win = winningRev(metadata);
+  var leaves = collectLeaves(metadata.rev_tree);
+  var conflicts = [];
+  for (var i = 0, len = leaves.length; i < len; i++) {
+    var leaf = leaves[i];
+    if (leaf.rev !== win && !leaf.opts.deleted) {
+      conflicts.push(leaf.rev);
+    }
+  }
+  return conflicts;
+}
 
-        var metadataSeq = 0;
-        req.onsuccess = function (e) {
-          var cursor = e.target.result;
-          if (!cursor) {
-            metadata.seq = metadataSeq;
-            return onGetMetadataSeq();
-          }
-          var seq = cursor.primaryKey;
-          if (seq > metadataSeq) {
-            metadataSeq = seq;
-          }
-          cursor.continue();
-        };
-      }
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+  var revs = [];
+  traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                               revHash, ctx, opts) {
+    if (opts.status === 'available' && !isLeaf) {
+      revs.push(pos + '-' + revHash);
+      opts.status = 'missing';
+    }
+  });
+  return revs;
+}
 
-      function onGetMetadataSeq() {
-        var metadataToStore = encodeMetadata(metadata,
-          metadata.winningRev, metadata.deleted);
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+  var paths = [];
+  var toVisit = revs.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var id = tree[0];
+    var opts = tree[1];
+    var branches = tree[2];
+    var isLeaf = branches.length === 0;
 
-        var req = docStore.put(metadataToStore);
-        req.onsuccess = function () {
-          cursor.continue();
-        };
-      }
+    var history = node.history ? node.history.slice() : [];
+    history.push({id: id, opts: opts});
+    if (isLeaf) {
+      paths.push({pos: (pos + 1 - history.length), ids: history});
+    }
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+    }
+  }
+  return paths.reverse();
+}
 
-      if (metadata.seq) {
-        return onGetMetadataSeq();
-      }
+// for a better overview of what this is doing, read:
 
-      fetchMetadataSeq();
-    };
+function sortByPos$1(a, b) {
+  return a.pos - b.pos;
+}
 
+// classic binary search
+function binarySearch(arr, item, comparator) {
+  var low = 0;
+  var high = arr.length;
+  var mid;
+  while (low < high) {
+    mid = (low + high) >>> 1;
+    if (comparator(arr[mid], item) < 0) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
   }
+  return low;
+}
 
-  api._remote = false;
-  api.type = function () {
-    return 'idb';
-  };
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+  var idx = binarySearch(arr, item, comparator);
+  arr.splice(idx, 0, item);
+}
 
-  api._id = toPromise(function (callback) {
-    callback(null, api._meta.instanceId);
-  });
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+  var root;
+  var leaf;
+  for (var i = numStemmed, len = path.length; i < len; i++) {
+    var node = path[i];
+    var currentLeaf = [node.id, node.opts, []];
+    if (leaf) {
+      leaf[2].push(currentLeaf);
+      leaf = currentLeaf;
+    } else {
+      root = leaf = currentLeaf;
+    }
+  }
+  return root;
+}
 
-  api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) {
-    idbBulkDocs(opts, req, reqOpts, api, idb, callback);
-  };
+// compare the IDs of two trees
+function compareTree(a, b) {
+  return a[0] < b[0] ? -1 : 1;
+}
 
-  // First we look up the metadata in the ids database, then we fetch the
-  // current revision(s) from the by sequence store
-  api._get = function idb_get(id, opts, callback) {
-    var doc;
-    var metadata;
-    var err;
-    var txn = opts.ctx;
-    if (!txn) {
-      var txnResult = openTransactionSafely(idb,
-        [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-      if (txnResult.error) {
-        return callback(txnResult.error);
-      }
-      txn = txnResult.txn;
-    }
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+  var queue = [{tree1: in_tree1, tree2: in_tree2}];
+  var conflicts = false;
+  while (queue.length > 0) {
+    var item = queue.pop();
+    var tree1 = item.tree1;
+    var tree2 = item.tree2;
 
-    function finish() {
-      callback(err, {doc: doc, metadata: metadata, ctx: txn});
+    if (tree1[1].status || tree2[1].status) {
+      tree1[1].status =
+        (tree1[1].status ===  'available' ||
+        tree2[1].status === 'available') ? 'available' : 'missing';
     }
 
-    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
-      metadata = decodeMetadata(e.target.result);
-      // we can determine the result here if:
-      // 1. there is no such document
-      // 2. the document is deleted and we don't ask about specific rev
-      // When we ask with opts.rev we expect the answer to be either
-      // doc (possibly with _deleted=true) or missing error
-      if (!metadata) {
-        err = createError(MISSING_DOC, 'missing');
-        return finish();
+    for (var i = 0; i < tree2[2].length; i++) {
+      if (!tree1[2][0]) {
+        conflicts = 'new_leaf';
+        tree1[2][0] = tree2[2][i];
+        continue;
       }
 
-      var rev;
-      if (!opts.rev) {
-        rev = metadata.winningRev;
-        var deleted = isDeleted(metadata);
-        if (deleted) {
-          err = createError(MISSING_DOC, "deleted");
-          return finish();
+      var merged = false;
+      for (var j = 0; j < tree1[2].length; j++) {
+        if (tree1[2][j][0] === tree2[2][i][0]) {
+          queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+          merged = true;
         }
-      } else {
-        rev = opts.latest ? latest(opts.rev, metadata) : opts.rev;
       }
-
-      var objectStore = txn.objectStore(BY_SEQ_STORE);
-      var key = metadata.id + '::' + rev;
-
-      objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
-        doc = e.target.result;
-        if (doc) {
-          doc = decodeDoc(doc);
-        }
-        if (!doc) {
-          err = createError(MISSING_DOC, 'missing');
-          return finish();
-        }
-        finish();
-      };
-    };
-  };
-
-  api._getAttachment = function (docId, attachId, attachment, opts, callback) {
-    var txn;
-    if (opts.ctx) {
-      txn = opts.ctx;
-    } else {
-      var txnResult = openTransactionSafely(idb,
-        [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
-      if (txnResult.error) {
-        return callback(txnResult.error);
+      if (!merged) {
+        conflicts = 'new_branch';
+        insertSorted(tree1[2], tree2[2][i], compareTree);
       }
-      txn = txnResult.txn;
     }
-    var digest = attachment.digest;
-    var type = attachment.content_type;
+  }
+  return {conflicts: conflicts, tree: in_tree1};
+}
 
-    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
-      var body = e.target.result.body;
-      readBlobData(body, type, opts.binary, function (blobData) {
-        callback(null, blobData);
-      });
-    };
-  };
+function doMerge(tree, path, dontExpand) {
+  var restree = [];
+  var conflicts = false;
+  var merged = false;
+  var res;
 
-  api._info = function idb_info(callback) {
-    var updateSeq;
-    var docCount;
+  if (!tree.length) {
+    return {tree: [path], conflicts: 'new_leaf'};
+  }
 
-    var txnResult = openTransactionSafely(idb, [META_STORE, BY_SEQ_STORE], 'readonly');
-    if (txnResult.error) {
-      return callback(txnResult.error);
-    }
-    var txn = txnResult.txn;
-    txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
-      docCount = e.target.result.docCount;
-    };
-    txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev').onsuccess = function (e) {
-      var cursor = e.target.result;
-      updateSeq = cursor ? cursor.key : 0;
-    };
+  for (var i = 0, len = tree.length; i < len; i++) {
+    var branch = tree[i];
+    if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+      // Paths start at the same position and have the same root, so they need
+      // merged
+      res = mergeTree(branch.ids, path.ids);
+      restree.push({pos: branch.pos, ids: res.tree});
+      conflicts = conflicts || res.conflicts;
+      merged = true;
+    } else if (dontExpand !== true) {
+      // The paths start at a different position, take the earliest path and
+      // traverse up until it as at the same point from root as the path we
+      // want to merge.  If the keys match we return the longer path with the
+      // other merged After stemming we dont want to expand the trees
 
-    txn.oncomplete = function () {
-      callback(null, {
-        doc_count: docCount,
-        update_seq: updateSeq,
-        // for debugging
-        idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64')
-      });
-    };
-  };
+      var t1 = branch.pos < path.pos ? branch : path;
+      var t2 = branch.pos < path.pos ? path : branch;
+      var diff = t2.pos - t1.pos;
 
-  api._allDocs = function idb_allDocs(opts, callback) {
-    idbAllDocs(opts, idb, callback);
-  };
+      var candidateParents = [];
 
-  api._changes = function idbChanges(opts) {
-    return changes(opts, api, dbName, idb);
-  };
+      var trees = [];
+      trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+      while (trees.length > 0) {
+        var item = trees.pop();
+        if (item.diff === 0) {
+          if (item.ids[0] === t2.ids[0]) {
+            candidateParents.push(item);
+          }
+          continue;
+        }
+        var elements = item.ids[2];
+        for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+          trees.push({
+            ids: elements[j],
+            diff: item.diff - 1,
+            parent: item.ids,
+            parentIdx: j
+          });
+        }
+      }
 
-  api._close = function (callback) {
-    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
-    // "Returns immediately and closes the connection in a separate thread..."
-    idb.close();
-    cachedDBs.delete(dbName);
-    callback();
-  };
+      var el = candidateParents[0];
 
-  api._getRevisionTree = function (docId, callback) {
-    var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly');
-    if (txnResult.error) {
-      return callback(txnResult.error);
-    }
-    var txn = txnResult.txn;
-    var req = txn.objectStore(DOC_STORE).get(docId);
-    req.onsuccess = function (event) {
-      var doc = decodeMetadata(event.target.result);
-      if (!doc) {
-        callback(createError(MISSING_DOC));
+      if (!el) {
+        restree.push(branch);
       } else {
-        callback(null, doc.rev_tree);
+        res = mergeTree(el.ids, t2.ids);
+        el.parent[2][el.parentIdx] = res.tree;
+        restree.push({pos: t1.pos, ids: t1.ids});
+        conflicts = conflicts || res.conflicts;
+        merged = true;
       }
-    };
-  };
-
-  // This function removes revisions of document docId
-  // which are listed in revs and sets this document
-  // revision to to rev_tree
-  api._doCompaction = function (docId, revs, callback) {
-    var stores = [
-      DOC_STORE,
-      BY_SEQ_STORE,
-      ATTACH_STORE,
-      ATTACH_AND_SEQ_STORE
-    ];
-    var txnResult = openTransactionSafely(idb, stores, 'readwrite');
-    if (txnResult.error) {
-      return callback(txnResult.error);
+    } else {
+      restree.push(branch);
     }
-    var txn = txnResult.txn;
-
-    var docStore = txn.objectStore(DOC_STORE);
-
-    docStore.get(docId).onsuccess = function (event) {
-      var metadata = decodeMetadata(event.target.result);
-      traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
-                                                         revHash, ctx, opts) {
-        var rev = pos + '-' + revHash;
-        if (revs.indexOf(rev) !== -1) {
-          opts.status = 'missing';
-        }
-      });
-      compactRevs(revs, docId, txn);
-      var winningRev$$1 = metadata.winningRev;
-      var deleted = metadata.deleted;
-      txn.objectStore(DOC_STORE).put(
-        encodeMetadata(metadata, winningRev$$1, deleted));
-    };
-    txn.onabort = idbError(callback);
-    txn.oncomplete = function () {
-      callback();
-    };
-  };
+  }
 
+  // We didnt find
+  if (!merged) {
+    restree.push(path);
+  }
 
-  api._getLocal = function (id, callback) {
-    var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly');
-    if (txnResult.error) {
-      return callback(txnResult.error);
-    }
-    var tx = txnResult.txn;
-    var req = tx.objectStore(LOCAL_STORE).get(id);
+  restree.sort(sortByPos$1);
 
-    req.onerror = idbError(callback);
-    req.onsuccess = function (e) {
-      var doc = e.target.result;
-      if (!doc) {
-        callback(createError(MISSING_DOC));
-      } else {
-        delete doc['_doc_id_rev']; // for backwards compat
-        callback(null, doc);
-      }
-    };
+  return {
+    tree: restree,
+    conflicts: conflicts || 'internal_node'
   };
+}
 
-  api._putLocal = function (doc, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    delete doc._revisions; // ignore this, trust the rev
-    var oldRev = doc._rev;
-    var id = doc._id;
-    if (!oldRev) {
-      doc._rev = '0-1';
-    } else {
-      doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
-    }
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+  // First we break out the tree into a complete list of root to leaf paths
+  var paths = rootToLeaf(tree);
+  var stemmedRevs;
 
-    var tx = opts.ctx;
-    var ret;
-    if (!tx) {
-      var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
-      if (txnResult.error) {
-        return callback(txnResult.error);
+  var result;
+  for (var i = 0, len = paths.length; i < len; i++) {
+    // Then for each path, we cut off the start of the path based on the
+    // `depth` to stem to, and generate a new set of flat trees
+    var path = paths[i];
+    var stemmed = path.ids;
+    var node;
+    if (stemmed.length > depth) {
+      // only do the stemming work if we actually need to stem
+      if (!stemmedRevs) {
+        stemmedRevs = {}; // avoid allocating this object unnecessarily
       }
-      tx = txnResult.txn;
-      tx.onerror = idbError(callback);
-      tx.oncomplete = function () {
-        if (ret) {
-          callback(null, ret);
-        }
-      };
-    }
-
-    var oStore = tx.objectStore(LOCAL_STORE);
-    var req;
-    if (oldRev) {
-      req = oStore.get(id);
-      req.onsuccess = function (e) {
-        var oldDoc = e.target.result;
-        if (!oldDoc || oldDoc._rev !== oldRev) {
-          callback(createError(REV_CONFLICT));
-        } else { // update
-          var req = oStore.put(doc);
-          req.onsuccess = function () {
-            ret = {ok: true, id: doc._id, rev: doc._rev};
-            if (opts.ctx) { // return immediately
-              callback(null, ret);
-            }
-          };
-        }
-      };
-    } else { // new doc
-      req = oStore.add(doc);
-      req.onerror = function (e) {
-        // constraint error, already exists
-        callback(createError(REV_CONFLICT));
-        e.preventDefault(); // avoid transaction abort
-        e.stopPropagation(); // avoid transaction onerror
-      };
-      req.onsuccess = function () {
-        ret = {ok: true, id: doc._id, rev: doc._rev};
-        if (opts.ctx) { // return immediately
-          callback(null, ret);
-        }
+      var numStemmed = stemmed.length - depth;
+      node = {
+        pos: path.pos + numStemmed,
+        ids: pathToTree(stemmed, numStemmed)
       };
-    }
-  };
 
-  api._removeLocal = function (doc, opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    var tx = opts.ctx;
-    if (!tx) {
-      var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
-      if (txnResult.error) {
-        return callback(txnResult.error);
+      for (var s = 0; s < numStemmed; s++) {
+        var rev = (path.pos + s) + '-' + stemmed[s].id;
+        stemmedRevs[rev] = true;
       }
-      tx = txnResult.txn;
-      tx.oncomplete = function () {
-        if (ret) {
-          callback(null, ret);
-        }
+    } else { // no need to actually stem
+      node = {
+        pos: path.pos,
+        ids: pathToTree(stemmed, 0)
       };
     }
-    var ret;
-    var id = doc._id;
-    var oStore = tx.objectStore(LOCAL_STORE);
-    var req = oStore.get(id);
-
-    req.onerror = idbError(callback);
-    req.onsuccess = function (e) {
-      var oldDoc = e.target.result;
-      if (!oldDoc || oldDoc._rev !== doc._rev) {
-        callback(createError(MISSING_DOC));
-      } else {
-        oStore.delete(id);
-        ret = {ok: true, id: id, rev: '0-0'};
-        if (opts.ctx) { // return immediately
-          callback(null, ret);
-        }
-      }
-    };
-  };
-
-  api._destroy = function (opts, callback) {
-    changesHandler.removeAllListeners(dbName);
 
-    //Close open request for "dbName" database to fix ie delay.
-    var openReq = openReqList.get(dbName);
-    if (openReq && openReq.result) {
-      openReq.result.close();
-      cachedDBs.delete(dbName);
+    // Then we remerge all those flat trees together, ensuring that we dont
+    // connect trees that would go beyond the depth limit
+    if (result) {
+      result = doMerge(result, node, true).tree;
+    } else {
+      result = [node];
     }
-    var req = indexedDB.deleteDatabase(dbName);
-
-    req.onsuccess = function () {
-      //Remove open request from the list.
-      openReqList.delete(dbName);
-      if (hasLocalStorage() && (dbName in localStorage)) {
-        delete localStorage[dbName];
-      }
-      callback(null, { 'ok': true });
-    };
-
-    req.onerror = idbError(callback);
-  };
-
-  var cached = cachedDBs.get(dbName);
+  }
 
-  if (cached) {
-    idb = cached.idb;
-    api._meta = cached.global;
-    return immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-      callback(null, api);
+  // this is memory-heavy per Chrome profiler, avoid unless we actually stemmed
+  if (stemmedRevs) {
+    traverseRevTree(result, function (isLeaf, pos, revHash) {
+      // some revisions may have been removed in a branch but not in another
+      delete stemmedRevs[pos + '-' + revHash];
     });
   }
 
-  var req = indexedDB.open(dbName, ADAPTER_VERSION);
-  openReqList.set(dbName, req);
+  return {
+    tree: result,
+    revs: stemmedRevs ? Object.keys(stemmedRevs) : []
+  };
+}
 
-  req.onupgradeneeded = function (e) {
-    var db = e.target.result;
-    if (e.oldVersion < 1) {
-      return createSchema(db); // new db, initial schema
-    }
-    // do migrations
+function merge(tree, path, depth) {
+  var newTree = doMerge(tree, path);
+  var stemmed = stem(newTree.tree, depth);
+  return {
+    tree: stemmed.tree,
+    stemmedRevs: stemmed.revs,
+    conflicts: newTree.conflicts
+  };
+}
 
-    var txn = e.currentTarget.transaction;
-    // these migrations have to be done in this function, before
-    // control is returned to the event loop, because IndexedDB
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+  var toVisit = revs.slice();
+  var splitRev = rev.split('-');
+  var targetPos = parseInt(splitRev[0], 10);
+  var targetId = splitRev[1];
 
-    if (e.oldVersion < 3) {
-      createLocalStoreSchema(db); // v2 -> v3
+  var node;
+  while ((node = toVisit.pop())) {
+    if (node.pos === targetPos && node.ids[0] === targetId) {
+      return true;
     }
-    if (e.oldVersion < 4) {
-      addAttachAndSeqStore(db); // v3 -> v4
+    var branches = node.ids[2];
+    for (var i = 0, len = branches.length; i < len; i++) {
+      toVisit.push({pos: node.pos + 1, ids: branches[i]});
     }
+  }
+  return false;
+}
 
-    var migrations = [
-      addDeletedOrLocalIndex, // v1 -> v2
-      migrateLocalStore,      // v2 -> v3
-      migrateAttsAndSeqs,     // v3 -> v4
-      migrateMetadata         // v4 -> v5
-    ];
+function getTrees(node) {
+  return node.ids;
+}
 
-    var i = e.oldVersion;
+// check if a specific revision of a doc has been deleted
+//  - metadata: the metadata object from the doc store
+//  - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+  if (!rev) {
+    rev = winningRev(metadata);
+  }
+  var id = rev.substring(rev.indexOf('-') + 1);
+  var toVisit = metadata.rev_tree.map(getTrees);
 
-    function next() {
-      var migration = migrations[i - 1];
-      i++;
-      if (migration) {
-        migration(txn, next);
-      }
+  var tree;
+  while ((tree = toVisit.pop())) {
+    if (tree[0] === id) {
+      return !!tree[1].deleted;
     }
+    toVisit = toVisit.concat(tree[2]);
+  }
+}
 
-    next();
-  };
+function isLocalId(id) {
+  return (/^_local/).test(id);
+}
 
-  req.onsuccess = function (e) {
+// returns the current leaf node for a given revision
+function latest(rev, metadata) {
+  var toVisit = metadata.rev_tree.slice();
+  var node;
+  while ((node = toVisit.pop())) {
+    var pos = node.pos;
+    var tree = node.ids;
+    var id = tree[0];
+    var opts = tree[1];
+    var branches = tree[2];
+    var isLeaf = branches.length === 0;
 
-    idb = e.target.result;
+    var history = node.history ? node.history.slice() : [];
+    history.push({id: id, pos: pos, opts: opts});
 
-    idb.onversionchange = function () {
-      idb.close();
-      cachedDBs.delete(dbName);
-    };
+    if (isLeaf) {
+      for (var i = 0, len = history.length; i < len; i++) {
+        var historyNode = history[i];
+        var historyRev = historyNode.pos + '-' + historyNode.id;
 
-    idb.onabort = function (e) {
-      guardedConsole('error', 'Database has a global failure', e.target.error);
-      idb.close();
-      cachedDBs.delete(dbName);
-    };
+        if (historyRev === rev) {
+          // return the rev of this leaf
+          return pos + '-' + id;
+        }
+      }
+    }
 
-    // Do a few setup operations (in parallel as much as possible):
-    // 1. Fetch meta doc
-    // 2. Check blob support
-    // 3. Calculate docCount
-    // 4. Generate an instanceId if necessary
-    // 5. Store docCount and instanceId on meta doc
+    for (var j = 0, l = branches.length; j < l; j++) {
+      toVisit.push({pos: pos + 1, ids: branches[j], history: history});
+    }
+  }
 
-    var txn = idb.transaction([
-      META_STORE,
-      DETECT_BLOB_SUPPORT_STORE,
-      DOC_STORE
-    ], 'readwrite');
+  /* istanbul ignore next */
+  throw new Error('Unable to resolve latest revision for id ' + metadata.id + ', rev ' + rev);
+}
 
-    var storedMetaDoc = false;
-    var metaDoc;
-    var docCount;
-    var blobSupport;
-    var instanceId;
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes$1, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
 
-    function completeSetup() {
-      if (typeof blobSupport === 'undefined' || !storedMetaDoc) {
-        return;
+function tryCatchInChangeListener(self, change, pending, lastSeq) {
+  // isolate try/catches to avoid V8 deoptimizations
+  try {
+    self.emit('change', change, pending, lastSeq);
+  } catch (e) {
+    guardedConsole('error', 'Error in .on("change", function):', e);
+  }
+}
+
+function Changes$1(db, opts, callback) {
+  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
+  var self = this;
+  this.db = db;
+  opts = opts ? clone(opts) : {};
+  var complete = opts.complete = once(function (err, resp) {
+    if (err) {
+      if (listenerCount(self, 'error') > 0) {
+        self.emit('error', err);
       }
-      api._meta = {
-        name: dbName,
-        instanceId: instanceId,
-        blobSupport: blobSupport
-      };
+    } else {
+      self.emit('complete', resp);
+    }
+    self.removeAllListeners();
+    db.removeListener('destroyed', onDestroy);
+  });
+  if (callback) {
+    self.on('complete', function (resp) {
+      callback(null, resp);
+    });
+    self.on('error', callback);
+  }
+  function onDestroy() {
+    self.cancel();
+  }
+  db.once('destroyed', onDestroy);
 
-      cachedDBs.set(dbName, {
-        idb: idb,
-        global: api._meta
-      });
-      callback(null, api);
+  opts.onChange = function (change, pending, lastSeq) {
+    /* istanbul ignore if */
+    if (self.isCancelled) {
+      return;
     }
+    tryCatchInChangeListener(self, change, pending, lastSeq);
+  };
 
-    function storeMetaDocIfReady() {
-      if (typeof docCount === 'undefined' || typeof metaDoc === 'undefined') {
-        return;
-      }
-      var instanceKey = dbName + '_id';
-      if (instanceKey in metaDoc) {
-        instanceId = metaDoc[instanceKey];
+  var promise = new Promise(function (fulfill, reject) {
+    opts.complete = function (err, res) {
+      if (err) {
+        reject(err);
       } else {
-        metaDoc[instanceKey] = instanceId = uuid();
+        fulfill(res);
       }
-      metaDoc.docCount = docCount;
-      txn.objectStore(META_STORE).put(metaDoc);
-    }
-
-    //
-    // fetch or generate the instanceId
-    //
-    txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
-      metaDoc = e.target.result || { id: META_STORE };
-      storeMetaDocIfReady();
     };
+  });
+  self.once('cancel', function () {
+    db.removeListener('destroyed', onDestroy);
+    opts.complete(null, {status: 'cancelled'});
+  });
+  this.then = promise.then.bind(promise);
+  this['catch'] = promise['catch'].bind(promise);
+  this.then(function (result) {
+    complete(null, result);
+  }, complete);
 
-    //
-    // countDocs
-    //
-    countDocs(txn, function (count) {
-      docCount = count;
-      storeMetaDocIfReady();
-    });
 
-    //
-    // check blob support
-    //
-    if (!blobSupportPromise) {
-      // make sure blob support is only checked once
-      blobSupportPromise = checkBlobSupport(txn);
-    }
 
-    blobSupportPromise.then(function (val) {
-      blobSupport = val;
-      completeSetup();
+  if (!db.taskqueue.isReady) {
+    db.taskqueue.addTask(function (failed) {
+      if (failed) {
+        opts.complete(failed);
+      } else if (self.isCancelled) {
+        self.emit('cancel');
+      } else {
+        self.validateChanges(opts);
+      }
     });
-
-    // only when the metadata put transaction has completed,
-    // consider the setup done
-    txn.oncomplete = function () {
-      storedMetaDoc = true;
-      completeSetup();
-    };
-    txn.onabort = idbError(callback);
+  } else {
+    self.validateChanges(opts);
+  }
+}
+Changes$1.prototype.cancel = function () {
+  this.isCancelled = true;
+  if (this.db.taskqueue.isReady) {
+    this.emit('cancel');
+  }
+};
+function processChange(doc, metadata, opts) {
+  var changeList = [{rev: doc._rev}];
+  if (opts.style === 'all_docs') {
+    changeList = collectLeaves(metadata.rev_tree)
+    .map(function (x) { return {rev: x.rev}; });
+  }
+  var change = {
+    id: metadata.id,
+    changes: changeList,
+    doc: doc
   };
 
-  req.onerror = function () {
-    var msg = 'Failed to open indexedDB, are you in private browsing mode?';
-    guardedConsole('error', msg);
-    callback(createError(IDB_ERROR, msg));
-  };
+  if (isDeleted(metadata, doc._rev)) {
+    change.deleted = true;
+  }
+  if (opts.conflicts) {
+    change.doc._conflicts = collectConflicts(metadata);
+    if (!change.doc._conflicts.length) {
+      delete change.doc._conflicts;
+    }
+  }
+  return change;
 }
 
-IdbPouch.valid = function () {
-  // Following #7085 buggy idb versions (typically Safari < 10.1) are
-  // considered valid.
+Changes$1.prototype.validateChanges = function (opts) {
+  var callback = opts.complete;
+  var self = this;
 
-  // On Firefox SecurityError is thrown while referencing indexedDB if cookies
-  // are not allowed. `typeof indexedDB` also triggers the error.
-  try {
-    // some outdated implementations of IDB that appear on Samsung
-    // and HTC Android devices <4.4 are missing IDBKeyRange
-    return typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined';
-  } catch (e) {
-    return false;
+  /* istanbul ignore else */
+  if (PouchDB._changesFilterPlugin) {
+    PouchDB._changesFilterPlugin.validate(opts, function (err) {
+      if (err) {
+        return callback(err);
+      }
+      self.doChanges(opts);
+    });
+  } else {
+    self.doChanges(opts);
   }
 };
 
-function IDBPouch (PouchDB) {
-  PouchDB.adapter('idb', IdbPouch, true);
-}
-
-// dead simple promise pool, inspired by https://github.com/timdp/es6-promise-pool
-// but much smaller in code size. limits the number of concurrent promises that are executed
+Changes$1.prototype.doChanges = function (opts) {
+  var self = this;
+  var callback = opts.complete;
 
+  opts = clone(opts);
+  if ('live' in opts && !('continuous' in opts)) {
+    opts.continuous = opts.live;
+  }
+  opts.processChange = processChange;
 
-function pool(promiseFactories, limit) {
-  return new Promise(function (resolve, reject) {
-    var running = 0;
-    var current = 0;
-    var done = 0;
-    var len = promiseFactories.length;
-    var err;
+  if (opts.since === 'latest') {
+    opts.since = 'now';
+  }
+  if (!opts.since) {
+    opts.since = 0;
+  }
+  if (opts.since === 'now') {
+    this.db.info().then(function (info) {
+      /* istanbul ignore if */
+      if (self.isCancelled) {
+        callback(null, {status: 'cancelled'});
+        return;
+      }
+      opts.since = info.update_seq;
+      self.doChanges(opts);
+    }, callback);
+    return;
+  }
 
-    function runNext() {
-      running++;
-      promiseFactories[current++]().then(onSuccess, onError);
+  /* istanbul ignore else */
+  if (PouchDB._changesFilterPlugin) {
+    PouchDB._changesFilterPlugin.normalize(opts);
+    if (PouchDB._changesFilterPlugin.shouldFilter(this, opts)) {
+      return PouchDB._changesFilterPlugin.filter(this, opts);
     }
-
-    function doNext() {
-      if (++done === len) {
-        /* istanbul ignore if */
-        if (err) {
-          reject(err);
-        } else {
-          resolve();
-        }
-      } else {
-        runNextBatch();
+  } else {
+    ['doc_ids', 'filter', 'selector', 'view'].forEach(function (key) {
+      if (key in opts) {
+        guardedConsole('warn',
+          'The "' + key + '" option was passed in to changes/replicate, ' +
+          'but pouchdb-changes-filter plugin is not installed, so it ' +
+          'was ignored. Please install the plugin to enable filtering.'
+        );
       }
-    }
+    });
+  }
 
-    function onSuccess() {
-      running--;
-      doNext();
-    }
+  if (!('descending' in opts)) {
+    opts.descending = false;
+  }
 
-    /* istanbul ignore next */
-    function onError(thisErr) {
-      running--;
-      err = err || thisErr;
-      doNext();
+  // 0 and 1 should return 1 document
+  opts.limit = opts.limit === 0 ? 1 : opts.limit;
+  opts.complete = callback;
+  var newPromise = this.db._changes(opts);
+  /* istanbul ignore else */
+  if (newPromise && typeof newPromise.cancel === 'function') {
+    var cancel = self.cancel;
+    self.cancel = argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
+      newPromise.cancel();
+      cancel.apply(this, args);
+    });
+  }
+};
+
+/*
+ * A generic pouch adapter
+ */
+
+function compare(left, right) {
+  return left < right ? -1 : left > right ? 1 : 0;
+}
+
+// Wrapper for functions that call the bulkdocs api with a single doc,
+// if the first result is an error, return an error
+function yankError(callback, docId) {
+  return function (err, results) {
+    if (err || (results[0] && results[0].error)) {
+      err = err || results[0];
+      err.docId = docId;
+      callback(err);
+    } else {
+      callback(null, results.length ? results[0]  : results);
     }
+  };
+}
 
-    function runNextBatch() {
-      while (running < limit && current < len) {
-        runNext();
+// clean docs given to us by the user
+function cleanDocs(docs) {
+  for (var i = 0; i < docs.length; i++) {
+    var doc = docs[i];
+    if (doc._deleted) {
+      delete doc._attachments; // ignore atts for deleted docs
+    } else if (doc._attachments) {
+      // filter out extraneous keys from _attachments
+      var atts = Object.keys(doc._attachments);
+      for (var j = 0; j < atts.length; j++) {
+        var att = atts[j];
+        doc._attachments[att] = pick(doc._attachments[att],
+          ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']);
       }
     }
+  }
+}
 
-    runNextBatch();
-  });
+// compare two docs, first by _id then by _rev
+function compareByIdThenRev(a, b) {
+  var idCompare = compare(a._id, b._id);
+  if (idCompare !== 0) {
+    return idCompare;
+  }
+  var aStart = a._revisions ? a._revisions.start : 0;
+  var bStart = b._revisions ? b._revisions.start : 0;
+  return compare(aStart, bStart);
 }
 
-var CHANGES_BATCH_SIZE = 25;
-var MAX_SIMULTANEOUS_REVS = 50;
-var CHANGES_TIMEOUT_BUFFER = 5000;
-var DEFAULT_HEARTBEAT = 10000;
+// for every node in a revision tree computes its distance from the closest
+// leaf
+function computeHeight(revs) {
+  var height = {};
+  var edges = [];
+  traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
+    var rev = pos + "-" + id;
+    if (isLeaf) {
+      height[rev] = 0;
+    }
+    if (prnt !== undefined) {
+      edges.push({from: prnt, to: rev});
+    }
+    return rev;
+  });
 
-var supportsBulkGetMap = {};
+  edges.reverse();
+  edges.forEach(function (edge) {
+    if (height[edge.from] === undefined) {
+      height[edge.from] = 1 + height[edge.to];
+    } else {
+      height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
+    }
+  });
+  return height;
+}
 
-function readAttachmentsAsBlobOrBuffer(row) {
-  var doc = row.doc || row.ok;
-  var atts = doc._attachments;
-  if (!atts) {
-    return;
+function allDocsKeysParse(opts) {
+  var keys =  ('limit' in opts) ?
+    opts.keys.slice(opts.skip, opts.limit + opts.skip) :
+    (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
+  opts.keys = keys;
+  opts.skip = 0;
+  delete opts.limit;
+  if (opts.descending) {
+    keys.reverse();
+    opts.descending = false;
   }
-  Object.keys(atts).forEach(function (filename) {
-    var att = atts[filename];
-    att.data = b64ToBluffer(att.data, att.content_type);
+}
+
+// all compaction is done in a queue, to avoid attaching
+// too many listeners at once
+function doNextCompaction(self) {
+  var task = self._compactionQueue[0];
+  var opts = task.opts;
+  var callback = task.callback;
+  self.get('_local/compaction').catch(function () {
+    return false;
+  }).then(function (doc) {
+    if (doc && doc.last_seq) {
+      opts.last_seq = doc.last_seq;
+    }
+    self._compact(opts, function (err, res) {
+      /* istanbul ignore if */
+      if (err) {
+        callback(err);
+      } else {
+        callback(null, res);
+      }
+      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+        self._compactionQueue.shift();
+        if (self._compactionQueue.length) {
+          doNextCompaction(self);
+        }
+      });
+    });
   });
 }
 
-function encodeDocId(id) {
-  if (/^_design/.test(id)) {
-    return '_design/' + encodeURIComponent(id.slice(8));
-  }
-  if (/^_local/.test(id)) {
-    return '_local/' + encodeURIComponent(id.slice(7));
+function attachmentNameError(name) {
+  if (name.charAt(0) === '_') {
+    return name + ' is not a valid attachment name, attachment ' +
+      'names cannot start with \'_\'';
   }
-  return encodeURIComponent(id);
+  return false;
 }
 
-function preprocessAttachments$1(doc) {
-  if (!doc._attachments || !Object.keys(doc._attachments)) {
-    return Promise.resolve();
-  }
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(AbstractPouchDB, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
 
-  return Promise.all(Object.keys(doc._attachments).map(function (key) {
-    var attachment = doc._attachments[key];
-    if (attachment.data && typeof attachment.data !== 'string') {
-      return new Promise(function (resolve) {
-        blobToBase64(attachment.data, resolve);
-      }).then(function (b64) {
-        attachment.data = b64;
-      });
-    }
-  }));
-}
+function AbstractPouchDB() {
+  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
 
-function hasUrlPrefix(opts) {
-  if (!opts.prefix) {
-    return false;
+  // re-bind prototyped methods
+  for (var p in AbstractPouchDB.prototype) {
+    if (typeof this[p] === 'function') {
+      this[p] = this[p].bind(this);
+    }
   }
-  var protocol = parseUri(opts.prefix).protocol;
-  return protocol === 'http' || protocol === 'https';
 }
 
-// Get all the information you possibly can about the URI given by name and
-// return it as a suitable object.
-function getHost(name, opts) {
-  // encode db name if opts.prefix is a url (#5574)
-  if (hasUrlPrefix(opts)) {
-    var dbName = opts.name.substr(opts.prefix.length);
-    // Ensure prefix has a trailing slash
-    var prefix = opts.prefix.replace(/\/?$/, '/');
-    name = prefix + encodeURIComponent(dbName);
+AbstractPouchDB.prototype.post =
+  adapterFun('post', function (doc, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  if (typeof doc !== 'object' || Array.isArray(doc)) {
+    return callback(createError(NOT_AN_OBJECT));
   }
+  this.bulkDocs({docs: [doc]}, opts, yankError(callback, doc._id));
+});
 
-  var uri = parseUri(name);
-  if (uri.user || uri.password) {
-    uri.auth = {username: uri.user, password: uri.password};
+AbstractPouchDB.prototype.put = adapterFun('put', function (doc, opts, cb) {
+  if (typeof opts === 'function') {
+    cb = opts;
+    opts = {};
+  }
+  if (typeof doc !== 'object' || Array.isArray(doc)) {
+    return cb(createError(NOT_AN_OBJECT));
+  }
+  invalidIdError(doc._id);
+  if (isLocalId(doc._id) && typeof this._putLocal === 'function') {
+    if (doc._deleted) {
+      return this._removeLocal(doc, cb);
+    } else {
+      return this._putLocal(doc, cb);
+    }
+  }
+  var self = this;
+  if (opts.force && doc._rev) {
+    transformForceOptionToNewEditsOption();
+    putDoc(function (err) {
+      var result = err ? null : {ok: true, id: doc._id, rev: doc._rev};
+      cb(err, result);
+    });
+  } else {
+    putDoc(cb);
   }
 
-  // Split the path part of the URI into parts using '/' as the delimiter
-  // after removing any leading '/' and any trailing '/'
-  var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
+  function transformForceOptionToNewEditsOption() {
+    var parts = doc._rev.split('-');
+    var oldRevId = parts[1];
+    var oldRevNum = parseInt(parts[0], 10);
 
-  uri.db = parts.pop();
-  // Prevent double encoding of URI component
-  if (uri.db.indexOf('%') === -1) {
-    uri.db = encodeURIComponent(uri.db);
+    var newRevNum = oldRevNum + 1;
+    var newRevId = rev$$1();
+
+    doc._revisions = {
+      start: newRevNum,
+      ids: [newRevId, oldRevId]
+    };
+    doc._rev = newRevNum + '-' + newRevId;
+    opts.new_edits = false;
   }
+  function putDoc(next) {
+    if (typeof self._put === 'function' && opts.new_edits !== false) {
+      self._put(doc, opts, next);
+    } else {
+      self.bulkDocs({docs: [doc]}, opts, yankError(next, doc._id));
+    }
+  }
+});
 
-  uri.path = parts.join('/');
+AbstractPouchDB.prototype.putAttachment =
+  adapterFun('putAttachment', function (docId, attachmentId, rev,
+                                              blob, type) {
+  var api = this;
+  if (typeof type === 'function') {
+    type = blob;
+    blob = rev;
+    rev = null;
+  }
+  // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267
+  /* istanbul ignore if */
+  if (typeof type === 'undefined') {
+    type = blob;
+    blob = rev;
+    rev = null;
+  }
+  if (!type) {
+    guardedConsole('warn', 'Attachment', attachmentId, 'on document', docId, 'is missing content_type');
+  }
 
-  return uri;
-}
+  function createAttachment(doc) {
+    var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0;
+    doc._attachments = doc._attachments || {};
+    doc._attachments[attachmentId] = {
+      content_type: type,
+      data: blob,
+      revpos: ++prevrevpos
+    };
+    return api.put(doc);
+  }
 
-// Generate a URL with the host data given by opts and the given path
-function genDBUrl(opts, path) {
-  return genUrl(opts, opts.db + '/' + path);
-}
+  return api.get(docId).then(function (doc) {
+    if (doc._rev !== rev) {
+      throw createError(REV_CONFLICT);
+    }
 
-// Generate a URL with the host data given by opts and the given path
-function genUrl(opts, path) {
-  // If the host already has a path, then we need to have a path delimiter
-  // Otherwise, the path delimiter is the empty string
-  var pathDel = !opts.path ? '' : '/';
+    return createAttachment(doc);
+  }, function (err) {
+     // create new doc
+    /* istanbul ignore else */
+    if (err.reason === MISSING_DOC.message) {
+      return createAttachment({_id: docId});
+    } else {
+      throw err;
+    }
+  });
+});
 
-  // If the host already has a path, then we need to have a path delimiter
-  // Otherwise, the path delimiter is the empty string
-  return opts.protocol + '://' + opts.host +
-         (opts.port ? (':' + opts.port) : '') +
-         '/' + opts.path + pathDel + path;
-}
+AbstractPouchDB.prototype.removeAttachment =
+  adapterFun('removeAttachment', function (docId, attachmentId, rev,
+                                                 callback) {
+  var self = this;
+  self.get(docId, function (err, obj) {
+    /* istanbul ignore if */
+    if (err) {
+      callback(err);
+      return;
+    }
+    if (obj._rev !== rev) {
+      callback(createError(REV_CONFLICT));
+      return;
+    }
+    /* istanbul ignore if */
+    if (!obj._attachments) {
+      return callback();
+    }
+    delete obj._attachments[attachmentId];
+    if (Object.keys(obj._attachments).length === 0) {
+      delete obj._attachments;
+    }
+    self.put(obj, callback);
+  });
+});
 
-function paramsToStr(params) {
-  return '?' + Object.keys(params).map(function (k) {
-    return k + '=' + encodeURIComponent(params[k]);
-  }).join('&');
-}
+AbstractPouchDB.prototype.remove =
+  adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
+  var doc;
+  if (typeof optsOrRev === 'string') {
+    // id, rev, opts, callback style
+    doc = {
+      _id: docOrId,
+      _rev: optsOrRev
+    };
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+  } else {
+    // doc, opts, callback style
+    doc = docOrId;
+    if (typeof optsOrRev === 'function') {
+      callback = optsOrRev;
+      opts = {};
+    } else {
+      callback = opts;
+      opts = optsOrRev;
+    }
+  }
+  opts = opts || {};
+  opts.was_delete = true;
+  var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)};
+  newDoc._deleted = true;
+  if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') {
+    return this._removeLocal(doc, callback);
+  }
+  this.bulkDocs({docs: [newDoc]}, opts, yankError(callback, newDoc._id));
+});
 
-function shouldCacheBust(opts) {
-  var ua = (typeof navigator !== 'undefined' && navigator.userAgent) ?
-      navigator.userAgent.toLowerCase() : '';
-  var isIE = ua.indexOf('msie') !== -1;
-  var isTrident = ua.indexOf('trident') !== -1;
-  var isEdge = ua.indexOf('edge') !== -1;
-  var isGET = !('method' in opts) || opts.method === 'GET';
-  return (isIE || isTrident || isEdge) && isGET;
-}
+AbstractPouchDB.prototype.revsDiff =
+  adapterFun('revsDiff', function (req, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  var ids = Object.keys(req);
 
-// Implements the PouchDB API for dealing with CouchDB instances over HTTP
-function HttpPouch(opts, callback) {
+  if (!ids.length) {
+    return callback(null, {});
+  }
 
-  // The functions that will be publicly available for HttpPouch
-  var api = this;
+  var count = 0;
+  var missing = new ExportedMap();
 
-  var host = getHost(opts.name, opts);
-  var dbUrl = genDBUrl(host, '');
+  function addToMissing(id, revId) {
+    if (!missing.has(id)) {
+      missing.set(id, {missing: []});
+    }
+    missing.get(id).missing.push(revId);
+  }
 
-  opts = clone(opts);
+  function processDoc(id, rev_tree) {
+    // Is this fast enough? Maybe we should switch to a set simulated by a map
+    var missingForId = req[id].slice(0);
+    traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
+      opts) {
+        var rev = pos + '-' + revHash;
+        var idx = missingForId.indexOf(rev);
+        if (idx === -1) {
+          return;
+        }
 
-  var ourFetch = function (url, options) {
+        missingForId.splice(idx, 1);
+        /* istanbul ignore if */
+        if (opts.status !== 'available') {
+          addToMissing(id, rev);
+        }
+      });
 
-    options = options || {};
-    options.headers = options.headers || new h();
+    // Traversing the tree is synchronous, so now `missingForId` contains
+    // revisions that were not found in the tree
+    missingForId.forEach(function (rev) {
+      addToMissing(id, rev);
+    });
+  }
 
-    if (opts.auth || host.auth) {
-      var nAuth = opts.auth || host.auth;
-      var str = nAuth.username + ':' + nAuth.password;
-      var token = thisBtoa(unescape(encodeURIComponent(str)));
-      options.headers.set('Authorization', 'Basic ' + token);
-    }
+  ids.map(function (id) {
+    this._getRevisionTree(id, function (err, rev_tree) {
+      if (err && err.status === 404 && err.message === 'missing') {
+        missing.set(id, {missing: req[id]});
+      } else if (err) {
+        /* istanbul ignore next */
+        return callback(err);
+      } else {
+        processDoc(id, rev_tree);
+      }
 
-    var headers = opts.headers || {};
-    Object.keys(headers).forEach(function (key) {
-      options.headers.append(key, headers[key]);
+      if (++count === ids.length) {
+        // convert LazyMap to object
+        var missingObj = {};
+        missing.forEach(function (value, key) {
+          missingObj[key] = value;
+        });
+        return callback(null, missingObj);
+      }
     });
+  }, this);
+});
+
+// _bulk_get API for faster replication, as described in
+// https://github.com/apache/couchdb-chttpd/pull/33
+// At the "abstract" level, it will just run multiple get()s in
+// parallel, because this isn't much of a performance cost
+// for local databases (except the cost of multiple transactions, which is
+// small). The http adapter overrides this in order
+// to do a more efficient single HTTP request.
+AbstractPouchDB.prototype.bulkGet =
+  adapterFun('bulkGet', function (opts, callback) {
+  bulkGet(this, opts, callback);
+});
 
+// compact one document and fire callback
+// by compacting we mean removing all revisions which
+// are further from the leaf in revision tree than max_height
+AbstractPouchDB.prototype.compactDocument =
+  adapterFun('compactDocument', function (docId, maxHeight, callback) {
+  var self = this;
+  this._getRevisionTree(docId, function (err, revTree) {
     /* istanbul ignore if */
-    if (shouldCacheBust(options)) {
-      url += (url.indexOf('?') === -1 ? '?' : '&') + '_nonce=' + Date.now();
+    if (err) {
+      return callback(err);
     }
+    var height = computeHeight(revTree);
+    var candidates = [];
+    var revs = [];
+    Object.keys(height).forEach(function (rev) {
+      if (height[rev] > maxHeight) {
+        candidates.push(rev);
+      }
+    });
 
-    var fetchFun = opts.fetch || f$1;
-    return fetchFun(url, options);
-  };
+    traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) {
+      var rev = pos + '-' + revHash;
+      if (opts.status === 'available' && candidates.indexOf(rev) !== -1) {
+        revs.push(rev);
+      }
+    });
+    self._doCompaction(docId, revs, callback);
+  });
+});
 
-  function adapterFun$$1(name, fun) {
-    return adapterFun(name, argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
-      setup().then(function () {
-        return fun.apply(this, args);
-      }).catch(function (e) {
-        var callback = args.pop();
-        callback(e);
-      });
-    })).bind(api);
+// compact the whole database using single document
+// compaction
+AbstractPouchDB.prototype.compact =
+  adapterFun('compact', function (opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
   }
 
-  function fetchJSON(url, options, callback) {
+  var self = this;
+  opts = opts || {};
 
-    var result = {};
+  self._compactionQueue = self._compactionQueue || [];
+  self._compactionQueue.push({opts: opts, callback: callback});
+  if (self._compactionQueue.length === 1) {
+    doNextCompaction(self);
+  }
+});
+AbstractPouchDB.prototype._compact = function (opts, callback) {
+  var self = this;
+  var changesOpts = {
+    return_docs: false,
+    last_seq: opts.last_seq || 0
+  };
+  var promises = [];
 
-    options = options || {};
-    options.headers = options.headers || new h();
+  function onChange(row) {
+    promises.push(self.compactDocument(row.id, 0));
+  }
+  function onComplete(resp) {
+    var lastSeq = resp.last_seq;
+    Promise.all(promises).then(function () {
+      return upsert(self, '_local/compaction', function deltaFunc(doc) {
+        if (!doc.last_seq || doc.last_seq < lastSeq) {
+          doc.last_seq = lastSeq;
+          return doc;
+        }
+        return false; // somebody else got here first, don't update
+      });
+    }).then(function () {
+      callback(null, {ok: true});
+    }).catch(callback);
+  }
+  self.changes(changesOpts)
+    .on('change', onChange)
+    .on('complete', onComplete)
+    .on('error', callback);
+};
 
-    if (!options.headers.get('Content-Type')) {
-      options.headers.set('Content-Type', 'application/json');
-    }
-    if (!options.headers.get('Accept')) {
-      options.headers.set('Accept', 'application/json');
+/* Begin api wrappers. Specific functionality to storage belongs in the
+   _[method] */
+AbstractPouchDB.prototype.get = adapterFun('get', function (id, opts, cb) {
+  if (typeof opts === 'function') {
+    cb = opts;
+    opts = {};
+  }
+  if (typeof id !== 'string') {
+    return cb(createError(INVALID_ID));
+  }
+  if (isLocalId(id) && typeof this._getLocal === 'function') {
+    return this._getLocal(id, cb);
+  }
+  var leaves = [], self = this;
+
+  function finishOpenRevs() {
+    var result = [];
+    var count = leaves.length;
+    /* istanbul ignore if */
+    if (!count) {
+      return cb(null, result);
     }
 
-    return ourFetch(url, options).then(function (response) {
-      result.ok = response.ok;
-      result.status = response.status;
-      return response.json();
-    }).then(function (json) {
-      result.data = json;
-      if (!result.ok) {
-        result.data.status = result.status;
-        var err = generateErrorFromResponse(result.data);
-        if (callback) {
-          return callback(err);
+    // order with open_revs is unspecified
+    leaves.forEach(function (leaf) {
+      self.get(id, {
+        rev: leaf,
+        revs: opts.revs,
+        latest: opts.latest,
+        attachments: opts.attachments,
+        binary: opts.binary
+      }, function (err, doc) {
+        if (!err) {
+          // using latest=true can produce duplicates
+          var existing;
+          for (var i = 0, l = result.length; i < l; i++) {
+            if (result[i].ok && result[i].ok._rev === doc._rev) {
+              existing = true;
+              break;
+            }
+          }
+          if (!existing) {
+            result.push({ok: doc});
+          }
         } else {
-          throw err;
+          result.push({missing: leaf});
         }
-      }
+        count--;
+        if (!count) {
+          cb(null, result);
+        }
+      });
+    });
+  }
 
-      if (Array.isArray(result.data)) {
-        result.data = result.data.map(function (v) {
-          if (v.error || v.missing) {
-            return generateErrorFromResponse(v);
-          } else {
-            return v;
-          }
+  if (opts.open_revs) {
+    if (opts.open_revs === "all") {
+      this._getRevisionTree(id, function (err, rev_tree) {
+        /* istanbul ignore if */
+        if (err) {
+          return cb(err);
+        }
+        leaves = collectLeaves(rev_tree).map(function (leaf) {
+          return leaf.rev;
         });
-      }
-
-      if (callback) {
-        callback(null, result.data);
+        finishOpenRevs();
+      });
+    } else {
+      if (Array.isArray(opts.open_revs)) {
+        leaves = opts.open_revs;
+        for (var i = 0; i < leaves.length; i++) {
+          var l = leaves[i];
+          // looks like it's the only thing couchdb checks
+          if (!(typeof (l) === "string" && /^\d+-/.test(l))) {
+            return cb(createError(INVALID_REV));
+          }
+        }
+        finishOpenRevs();
       } else {
-        return result;
+        return cb(createError(UNKNOWN_ERROR, 'function_clause'));
       }
-    });
+    }
+    return; // open_revs does not like other options
   }
 
-  var setupPromise;
-
-  function setup() {
-    if (opts.skip_setup) {
-      return Promise.resolve();
+  return this._get(id, opts, function (err, result) {
+    if (err) {
+      err.docId = id;
+      return cb(err);
     }
 
-    // If there is a setup in process or previous successful setup
-    // done then we will use that
-    // If previous setups have been rejected we will try again
-    if (setupPromise) {
-      return setupPromise;
-    }
+    var doc = result.doc;
+    var metadata = result.metadata;
+    var ctx = result.ctx;
 
-    setupPromise = fetchJSON(dbUrl).catch(function (err) {
-      if (err && err.status && err.status === 404) {
-        // Doesnt exist, create it
-        explainError(404, 'PouchDB is just detecting if the remote exists.');
-        return fetchJSON(dbUrl, {method: 'PUT'});
-      } else {
-        return Promise.reject(err);
-      }
-    }).catch(function (err) {
-      // If we try to create a database that already exists, skipped in
-      // istanbul since its catching a race condition.
-      /* istanbul ignore if */
-      if (err && err.status && err.status === 412) {
-        return true;
+    if (opts.conflicts) {
+      var conflicts = collectConflicts(metadata);
+      if (conflicts.length) {
+        doc._conflicts = conflicts;
       }
-      return Promise.reject(err);
-    });
+    }
 
-    setupPromise.catch(function () {
-      setupPromise = null;
-    });
+    if (isDeleted(metadata, doc._rev)) {
+      doc._deleted = true;
+    }
 
-    return setupPromise;
-  }
+    if (opts.revs || opts.revs_info) {
+      var splittedRev = doc._rev.split('-');
+      var revNo       = parseInt(splittedRev[0], 10);
+      var revHash     = splittedRev[1];
 
-  immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-    callback(null, api);
-  });
+      var paths = rootToLeaf(metadata.rev_tree);
+      var path = null;
 
-  api._remote = true;
+      for (var i = 0; i < paths.length; i++) {
+        var currentPath = paths[i];
+        var hashIndex = currentPath.ids.map(function (x) { return x.id; })
+          .indexOf(revHash);
+        var hashFoundAtRevPos = hashIndex === (revNo - 1);
 
-  /* istanbul ignore next */
-  api.type = function () {
-    return 'http';
-  };
+        if (hashFoundAtRevPos || (!path && hashIndex !== -1)) {
+          path = currentPath;
+        }
+      }
 
-  api.id = adapterFun$$1('id', function (callback) {
-    ourFetch(genUrl(host, '')).then(function (response) {
-      return response.json();
-    }).then(function (result) {
-      var uuid$$1 = (result && result.uuid) ?
-          (result.uuid + host.db) : genDBUrl(host, '');
-      callback(null, uuid$$1);
-    }).catch(function (err) {
-      callback(err);
-    });
-  });
+      var indexOfRev = path.ids.map(function (x) { return x.id; })
+        .indexOf(doc._rev.split('-')[1]) + 1;
+      var howMany = path.ids.length - indexOfRev;
+      path.ids.splice(indexOfRev, howMany);
+      path.ids.reverse();
 
-  // Sends a POST request to the host calling the couchdb _compact function
-  //    version: The version of CouchDB it is running
-  api.compact = adapterFun$$1('compact', function (opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
+      if (opts.revs) {
+        doc._revisions = {
+          start: (path.pos + path.ids.length) - 1,
+          ids: path.ids.map(function (rev) {
+            return rev.id;
+          })
+        };
+      }
+      if (opts.revs_info) {
+        var pos =  path.pos + path.ids.length;
+        doc._revs_info = path.ids.map(function (rev) {
+          pos--;
+          return {
+            rev: pos + '-' + rev.id,
+            status: rev.opts.status
+          };
+        });
+      }
     }
-    opts = clone(opts);
 
-    fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () {
-      function ping() {
-        api.info(function (err, res) {
-          // CouchDB may send a "compact_running:true" if it's
-          // already compacting. PouchDB Server doesn't.
-          /* istanbul ignore else */
-          if (res && !res.compact_running) {
-            callback(null, {ok: true});
-          } else {
-            setTimeout(ping, opts.interval || 200);
+    if (opts.attachments && doc._attachments) {
+      var attachments = doc._attachments;
+      var count = Object.keys(attachments).length;
+      if (count === 0) {
+        return cb(null, doc);
+      }
+      Object.keys(attachments).forEach(function (key) {
+        this._getAttachment(doc._id, key, attachments[key], {
+          // Previously the revision handling was done in adapter.js
+          // getAttachment, however since idb-next doesnt we need to
+          // pass the rev through
+          rev: doc._rev,
+          binary: opts.binary,
+          ctx: ctx
+        }, function (err, data) {
+          var att = doc._attachments[key];
+          att.data = data;
+          delete att.stub;
+          delete att.length;
+          if (!--count) {
+            cb(null, doc);
           }
         });
+      }, self);
+    } else {
+      if (doc._attachments) {
+        for (var key in doc._attachments) {
+          /* istanbul ignore else */
+          if (doc._attachments.hasOwnProperty(key)) {
+            doc._attachments[key].stub = true;
+          }
+        }
       }
-      // Ping the http if it's finished compaction
-      ping();
-    });
+      cb(null, doc);
+    }
   });
+});
 
-  api.bulkGet = adapterFun('bulkGet', function (opts, callback) {
-    var self = this;
+// TODO: I dont like this, it forces an extra read for every
+// attachment read and enforces a confusing api between
+// adapter.js and the adapter implementation
+AbstractPouchDB.prototype.getAttachment =
+  adapterFun('getAttachment', function (docId, attachmentId, opts, callback) {
+  var self = this;
+  if (opts instanceof Function) {
+    callback = opts;
+    opts = {};
+  }
+  this._get(docId, opts, function (err, res) {
+    if (err) {
+      return callback(err);
+    }
+    if (res.doc._attachments && res.doc._attachments[attachmentId]) {
+      opts.ctx = res.ctx;
+      opts.binary = true;
+      self._getAttachment(docId, attachmentId,
+                          res.doc._attachments[attachmentId], opts, callback);
+    } else {
+      return callback(createError(MISSING_DOC));
+    }
+  });
+});
 
-    function doBulkGet(cb) {
-      var params = {};
-      if (opts.revs) {
-        params.revs = true;
-      }
-      if (opts.attachments) {
-        /* istanbul ignore next */
-        params.attachments = true;
-      }
-      if (opts.latest) {
-        params.latest = true;
+AbstractPouchDB.prototype.allDocs =
+  adapterFun('allDocs', function (opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
+  if (opts.start_key) {
+    opts.startkey = opts.start_key;
+  }
+  if (opts.end_key) {
+    opts.endkey = opts.end_key;
+  }
+  if ('keys' in opts) {
+    if (!Array.isArray(opts.keys)) {
+      return callback(new TypeError('options.keys must be an array'));
+    }
+    var incompatibleOpt =
+      ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
+      return incompatibleOpt in opts;
+    })[0];
+    if (incompatibleOpt) {
+      callback(createError(QUERY_PARSE_ERROR,
+        'Query parameter `' + incompatibleOpt +
+        '` is not compatible with multi-get'
+      ));
+      return;
+    }
+    if (!isRemote(this)) {
+      allDocsKeysParse(opts);
+      if (opts.keys.length === 0) {
+        return this._allDocs({limit: 0}, callback);
       }
-      fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), {
-        method: 'POST',
-        body: JSON.stringify({ docs: opts.docs})
-      }).then(function (result) {
-        if (opts.attachments && opts.binary) {
-          result.data.results.forEach(function (res) {
-            res.docs.forEach(readAttachmentsAsBlobOrBuffer);
-          });
-        }
-        cb(null, result.data);
-      }).catch(cb);
     }
+  }
 
-    /* istanbul ignore next */
-    function doBulkGetShim() {
-      // avoid "url too long error" by splitting up into multiple requests
-      var batchSize = MAX_SIMULTANEOUS_REVS;
-      var numBatches = Math.ceil(opts.docs.length / batchSize);
-      var numDone = 0;
-      var results = new Array(numBatches);
+  return this._allDocs(opts, callback);
+});
 
-      function onResult(batchNum) {
-        return function (err, res) {
-          // err is impossible because shim returns a list of errs in that case
-          results[batchNum] = res.results;
-          if (++numDone === numBatches) {
-            callback(null, {results: flatten(results)});
-          }
-        };
-      }
+AbstractPouchDB.prototype.changes = function (opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
 
-      for (var i = 0; i < numBatches; i++) {
-        var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']);
-        subOpts.docs = opts.docs.slice(i * batchSize,
-          Math.min(opts.docs.length, (i + 1) * batchSize));
-        bulkGet(self, subOpts, onResult(i));
-      }
-    }
+  opts = opts || {};
 
-    // mark the whole database as either supporting or not supporting _bulk_get
-    var dbUrl = genUrl(host, '');
-    var supportsBulkGet = supportsBulkGetMap[dbUrl];
+  // By default set return_docs to false if the caller has opts.live = true,
+  // this will prevent us from collecting the set of changes indefinitely
+  // resulting in growing memory
+  opts.return_docs = ('return_docs' in opts) ? opts.return_docs : !opts.live;
 
-    /* istanbul ignore next */
-    if (typeof supportsBulkGet !== 'boolean') {
-      // check if this database supports _bulk_get
-      doBulkGet(function (err, res) {
-        if (err) {
-          supportsBulkGetMap[dbUrl] = false;
-          explainError(
-            err.status,
-            'PouchDB is just detecting if the remote ' +
-            'supports the _bulk_get API.'
-          );
-          doBulkGetShim();
-        } else {
-          supportsBulkGetMap[dbUrl] = true;
-          callback(null, res);
-        }
-      });
-    } else if (supportsBulkGet) {
-      doBulkGet(callback);
-    } else {
-      doBulkGetShim();
+  return new Changes$1(this, opts, callback);
+};
+
+AbstractPouchDB.prototype.close = adapterFun('close', function (callback) {
+  this._closed = true;
+  this.emit('closed');
+  return this._close(callback);
+});
+
+AbstractPouchDB.prototype.info = adapterFun('info', function (callback) {
+  var self = this;
+  this._info(function (err, info) {
+    if (err) {
+      return callback(err);
     }
+    // assume we know better than the adapter, unless it informs us
+    info.db_name = info.db_name || self.name;
+    info.auto_compaction = !!(self.auto_compaction && !isRemote(self));
+    info.adapter = self.adapter;
+    callback(null, info);
   });
+});
 
-  // Calls GET on the host, which gets back a JSON string containing
-  //    couchdb: A welcome string
-  //    version: The version of CouchDB it is running
-  api._info = function (callback) {
-    setup().then(function () {
-      return ourFetch(genDBUrl(host, ''));
-    }).then(function (response) {
-      return response.json();
-    }).then(function (info) {
-      info.host = genDBUrl(host, '');
-      callback(null, info);
-    }).catch(callback);
-  };
+AbstractPouchDB.prototype.id = adapterFun('id', function (callback) {
+  return this._id(callback);
+});
 
-  api.fetch = function (path, options) {
-    return setup().then(function () {
-      return ourFetch(genDBUrl(host, path), options);
-    });
-  };
+/* istanbul ignore next */
+AbstractPouchDB.prototype.type = function () {
+  return (typeof this._type === 'function') ? this._type() : this.adapter;
+};
 
-  // Get the document with the given id from the database given by host.
-  // The id could be solely the _id in the database, or it may be a
-  // _design/ID or _local/ID path
-  api.get = adapterFun$$1('get', function (id, opts, callback) {
-    // If no options were given, set the callback to the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = clone(opts);
+AbstractPouchDB.prototype.bulkDocs =
+  adapterFun('bulkDocs', function (req, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
 
-    // List of parameters to add to the GET request
-    var params = {};
+  opts = opts || {};
 
-    if (opts.revs) {
-      params.revs = true;
-    }
+  if (Array.isArray(req)) {
+    req = {
+      docs: req
+    };
+  }
 
-    if (opts.revs_info) {
-      params.revs_info = true;
-    }
+  if (!req || !req.docs || !Array.isArray(req.docs)) {
+    return callback(createError(MISSING_BULK_DOCS));
+  }
 
-    if (opts.latest) {
-      params.latest = true;
+  for (var i = 0; i < req.docs.length; ++i) {
+    if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
+      return callback(createError(NOT_AN_OBJECT));
     }
+  }
 
-    if (opts.open_revs) {
-      if (opts.open_revs !== "all") {
-        opts.open_revs = JSON.stringify(opts.open_revs);
-      }
-      params.open_revs = opts.open_revs;
+  var attachmentError;
+  req.docs.forEach(function (doc) {
+    if (doc._attachments) {
+      Object.keys(doc._attachments).forEach(function (name) {
+        attachmentError = attachmentError || attachmentNameError(name);
+        if (!doc._attachments[name].content_type) {
+          guardedConsole('warn', 'Attachment', name, 'on document', doc._id, 'is missing content_type');
+        }
+      });
     }
+  });
 
-    if (opts.rev) {
-      params.rev = opts.rev;
-    }
+  if (attachmentError) {
+    return callback(createError(BAD_REQUEST, attachmentError));
+  }
 
-    if (opts.conflicts) {
-      params.conflicts = opts.conflicts;
+  if (!('new_edits' in opts)) {
+    if ('new_edits' in req) {
+      opts.new_edits = req.new_edits;
+    } else {
+      opts.new_edits = true;
     }
+  }
 
-    /* istanbul ignore if */
-    if (opts.update_seq) {
-      params.update_seq = opts.update_seq;
-    }
+  var adapter = this;
+  if (!opts.new_edits && !isRemote(adapter)) {
+    // ensure revisions of the same doc are sorted, so that
+    // the local adapter processes them correctly (#2935)
+    req.docs.sort(compareByIdThenRev);
+  }
 
-    id = encodeDocId(id);
+  cleanDocs(req.docs);
 
-    function fetchAttachments(doc) {
-      var atts = doc._attachments;
-      var filenames = atts && Object.keys(atts);
-      if (!atts || !filenames.length) {
-        return;
-      }
-      // we fetch these manually in separate XHRs, because
-      // Sync Gateway would normally send it back as multipart/mixed,
-      // which we cannot parse. Also, this is more efficient than
-      // receiving attachments as base64-encoded strings.
-      function fetchData(filename) {
-        var att = atts[filename];
-        var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) +
-            '?rev=' + doc._rev;
-        return ourFetch(genDBUrl(host, path)).then(function (response) {
-          if (typeof process !== 'undefined' && !process.browser) {
-            return response.buffer();
-          } else {
-            /* istanbul ignore next */
-            return response.blob();
-          }
-        }).then(function (blob) {
-          if (opts.binary) {
-            // TODO: Can we remove this?
-            if (typeof process !== 'undefined' && !process.browser) {
-              blob.type = att.content_type;
-            }
-            return blob;
-          }
-          return new Promise(function (resolve) {
-            blobToBase64(blob, resolve);
-          });
-        }).then(function (data) {
-          delete att.stub;
-          delete att.length;
-          att.data = data;
-        });
-      }
+  // in the case of conflicts, we want to return the _ids to the user
+  // however, the underlying adapter may destroy the docs array, so
+  // create a copy here
+  var ids = req.docs.map(function (doc) {
+    return doc._id;
+  });
 
-      var promiseFactories = filenames.map(function (filename) {
-        return function () {
-          return fetchData(filename);
-        };
+  return this._bulkDocs(req, opts, function (err, res) {
+    if (err) {
+      return callback(err);
+    }
+    if (!opts.new_edits) {
+      // this is what couch does when new_edits is false
+      res = res.filter(function (x) {
+        return x.error;
       });
-
-      // This limits the number of parallel xhr requests to 5 any time
-      // to avoid issues with maximum browser request limits
-      return pool(promiseFactories, 5);
     }
-
-    function fetchAllAttachments(docOrDocs) {
-      if (Array.isArray(docOrDocs)) {
-        return Promise.all(docOrDocs.map(function (doc) {
-          if (doc.ok) {
-            return fetchAttachments(doc.ok);
-          }
-        }));
+    // add ids for error/conflict responses (not required for CouchDB)
+    if (!isRemote(adapter)) {
+      for (var i = 0, l = res.length; i < l; i++) {
+        res[i].id = res[i].id || ids[i];
       }
-      return fetchAttachments(docOrDocs);
     }
 
-    var url = genDBUrl(host, id + paramsToStr(params));
-    fetchJSON(url).then(function (res) {
-      return Promise.resolve().then(function () {
-        if (opts.attachments) {
-          return fetchAllAttachments(res.data);
-        }
-      }).then(function () {
-        callback(null, res.data);
-      });
-    }).catch(function (e) {
-      e.docId = id;
-      callback(e);
-    });
+    callback(null, res);
   });
+});
 
+AbstractPouchDB.prototype.registerDependentDatabase =
+  adapterFun('registerDependentDatabase', function (dependentDb,
+                                                          callback) {
+  var depDB = new this.constructor(dependentDb, this.__opts);
 
-  // Delete the document given by doc from the database given by host.
-  api.remove = adapterFun$$1('remove', function (docOrId, optsOrRev, opts, cb) {
-    var doc;
-    if (typeof optsOrRev === 'string') {
-      // id, rev, opts, callback style
-      doc = {
-        _id: docOrId,
-        _rev: optsOrRev
-      };
-      if (typeof opts === 'function') {
-        cb = opts;
-        opts = {};
-      }
-    } else {
-      // doc, opts, callback style
-      doc = docOrId;
-      if (typeof optsOrRev === 'function') {
-        cb = optsOrRev;
-        opts = {};
-      } else {
-        cb = opts;
-        opts = optsOrRev;
-      }
+  function diffFun(doc) {
+    doc.dependentDbs = doc.dependentDbs || {};
+    if (doc.dependentDbs[dependentDb]) {
+      return false; // no update required
     }
+    doc.dependentDbs[dependentDb] = true;
+    return doc;
+  }
+  upsert(this, '_local/_pouch_dependentDbs', diffFun)
+    .then(function () {
+      callback(null, {db: depDB});
+    }).catch(callback);
+});
 
-    var rev = (doc._rev || opts.rev);
-    var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev;
-
-    fetchJSON(url, {method: 'DELETE'}, cb).catch(cb);
-  });
+AbstractPouchDB.prototype.destroy =
+  adapterFun('destroy', function (opts, callback) {
 
-  function encodeAttachmentId(attachmentId) {
-    return attachmentId.split("/").map(encodeURIComponent).join("/");
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
   }
 
-  // Get the attachment
-  api.getAttachment = adapterFun$$1('getAttachment', function (docId, attachmentId,
-                                                            opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    var params = opts.rev ? ('?rev=' + opts.rev) : '';
-    var url = genDBUrl(host, encodeDocId(docId)) + '/' +
-        encodeAttachmentId(attachmentId) + params;
-    var contentType;
-    ourFetch(url, {method: 'GET'}).then(function (response) {
-      contentType = response.headers.get('content-type');
-      if (!response.ok) {
-        throw response;
-      } else {
-        if (typeof process !== 'undefined' && !process.browser) {
-          return response.buffer();
-        } else {
-          /* istanbul ignore next */
-          return response.blob();
-        }
+  var self = this;
+  var usePrefix = 'use_prefix' in self ? self.use_prefix : true;
+
+  function destroyDb() {
+    // call destroy method of the particular adaptor
+    self._destroy(opts, function (err, resp) {
+      if (err) {
+        return callback(err);
       }
-    }).then(function (blob) {
-      // TODO: also remove
-      if (typeof process !== 'undefined' && !process.browser) {
-        blob.type = contentType;
+      self._destroyed = true;
+      self.emit('destroyed');
+      callback(null, resp || { 'ok': true });
+    });
+  }
+
+  if (isRemote(self)) {
+    // no need to check for dependent DBs if it's a remote DB
+    return destroyDb();
+  }
+
+  self.get('_local/_pouch_dependentDbs', function (err, localDoc) {
+    if (err) {
+      /* istanbul ignore if */
+      if (err.status !== 404) {
+        return callback(err);
+      } else { // no dependencies
+        return destroyDb();
       }
-      callback(null, blob);
-    }).catch(function (err) {
-      callback(err);
+    }
+    var dependentDbs = localDoc.dependentDbs;
+    var PouchDB = self.constructor;
+    var deletedMap = Object.keys(dependentDbs).map(function (name) {
+      // use_prefix is only false in the browser
+      /* istanbul ignore next */
+      var trueName = usePrefix ?
+        name.replace(new RegExp('^' + PouchDB.prefix), '') : name;
+      return new PouchDB(trueName, self.__opts).destroy();
     });
+    Promise.all(deletedMap).then(destroyDb, callback);
   });
+});
 
-  // Remove the attachment given by the id and rev
-  api.removeAttachment =  adapterFun$$1('removeAttachment', function (docId,
-                                                                   attachmentId,
-                                                                   rev,
-                                                                   callback) {
-    var url = genDBUrl(host, encodeDocId(docId) + '/' +
-                       encodeAttachmentId(attachmentId)) + '?rev=' + rev;
-    fetchJSON(url, {method: 'DELETE'}, callback).catch(callback);
-  });
+function TaskQueue() {
+  this.isReady = false;
+  this.failed = false;
+  this.queue = [];
+}
 
-  // Add the attachment given by blob and its contentType property
-  // to the document with the given id, the revision given by rev, and
-  // add it to the database given by host.
-  api.putAttachment = adapterFun$$1('putAttachment', function (docId, attachmentId,
-                                                            rev, blob,
-                                                            type, callback) {
-    if (typeof type === 'function') {
-      callback = type;
-      type = blob;
-      blob = rev;
-      rev = null;
+TaskQueue.prototype.execute = function () {
+  var fun;
+  if (this.failed) {
+    while ((fun = this.queue.shift())) {
+      fun(this.failed);
     }
-    var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId);
-    var url = genDBUrl(host, id);
-    if (rev) {
-      url += '?rev=' + rev;
+  } else {
+    while ((fun = this.queue.shift())) {
+      fun();
     }
+  }
+};
 
-    if (typeof blob === 'string') {
-      // input is assumed to be a base64 string
-      var binary;
-      try {
-        binary = thisAtob(blob);
-      } catch (err) {
-        return callback(createError(BAD_ARG,
-                        'Attachment is not a valid base64 string'));
+TaskQueue.prototype.fail = function (err) {
+  this.failed = err;
+  this.execute();
+};
+
+TaskQueue.prototype.ready = function (db) {
+  this.isReady = true;
+  this.db = db;
+  this.execute();
+};
+
+TaskQueue.prototype.addTask = function (fun) {
+  this.queue.push(fun);
+  if (this.failed) {
+    this.execute();
+  }
+};
+
+function parseAdapter(name, opts) {
+  var match = name.match(/([a-z-]*):\/\/(.*)/);
+  if (match) {
+    // the http adapter expects the fully qualified name
+    return {
+      name: /https?/.test(match[1]) ? match[1] + '://' + match[2] : match[2],
+      adapter: match[1]
+    };
+  }
+
+  var adapters = PouchDB.adapters;
+  var preferredAdapters = PouchDB.preferredAdapters;
+  var prefix = PouchDB.prefix;
+  var adapterName = opts.adapter;
+
+  if (!adapterName) { // automatically determine adapter
+    for (var i = 0; i < preferredAdapters.length; ++i) {
+      adapterName = preferredAdapters[i];
+      // check for browsers that have been upgraded from websql-only to websql+idb
+      /* istanbul ignore if */
+      if (adapterName === 'idb' && 'websql' in adapters &&
+          hasLocalStorage() && localStorage['_pouch__websqldb_' + prefix + name]) {
+        // log it, because this can be confusing during development
+        guardedConsole('log', 'PouchDB is downgrading "' + name + '" to WebSQL to' +
+          ' avoid data loss, because it was already opened with WebSQL.');
+        continue; // keep using websql to avoid user data loss
       }
-      blob = binary ? binStringToBluffer(binary, type) : '';
+      break;
     }
+  }
 
-    // Add the attachment
-    fetchJSON(url, {
-      headers: new h({'Content-Type': type}),
-      method: 'PUT',
-      body: blob
-    }, callback).catch(callback);
-  });
+  var adapter = adapters[adapterName];
 
-  // Update/create multiple documents given by req in the database
-  // given by host.
-  api._bulkDocs = function (req, opts, callback) {
-    // If new_edits=false then it prevents the database from creating
-    // new revision numbers for the documents. Instead it just uses
-    // the old ones. This is used in database replication.
-    req.new_edits = opts.new_edits;
+  // if adapter is invalid, then an error will be thrown later
+  var usePrefix = (adapter && 'use_prefix' in adapter) ?
+    adapter.use_prefix : true;
 
-    setup().then(function () {
-      return Promise.all(req.docs.map(preprocessAttachments$1));
-    }).then(function () {
-      // Update/create the documents
-      return fetchJSON(genDBUrl(host, '_bulk_docs'), {
-        method: 'POST',
-        body: JSON.stringify(req)
-      }, callback);
-    }).catch(callback);
+  return {
+    name: usePrefix ? (prefix + name) : name,
+    adapter: adapterName
   };
+}
 
+// OK, so here's the deal. Consider this code:
+//     var db1 = new PouchDB('foo');
+//     var db2 = new PouchDB('foo');
+//     db1.destroy();
+// ^ these two both need to emit 'destroyed' events,
+// as well as the PouchDB constructor itself.
+// So we have one db object (whichever one got destroy() called on it)
+// responsible for emitting the initial event, which then gets emitted
+// by the constructor, which then broadcasts it to any other dbs
+// that may have been created with the same name.
+function prepareForDestruction(self) {
 
-  // Update/create document
-  api._put = function (doc, opts, callback) {
-    setup().then(function () {
-      return preprocessAttachments$1(doc);
-    }).then(function () {
-      return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), {
-        method: 'PUT',
-        body: JSON.stringify(doc)
-      });
-    }).then(function (result) {
-      callback(null, result.data);
-    }).catch(function (err) {
-      err.docId = doc && doc._id;
-      callback(err);
-    });
-  };
+  function onDestroyed(from_constructor) {
+    self.removeListener('closed', onClosed);
+    if (!from_constructor) {
+      self.constructor.emit('destroyed', self.name);
+    }
+  }
 
+  function onClosed() {
+    self.removeListener('destroyed', onDestroyed);
+    self.constructor.emit('unref', self);
+  }
 
-  // Get a listing of the documents in the database given
-  // by host and ordered by increasing id.
-  api.allDocs = adapterFun$$1('allDocs', function (opts, callback) {
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = clone(opts);
+  self.once('destroyed', onDestroyed);
+  self.once('closed', onClosed);
+  self.constructor.emit('ref', self);
+}
 
-    // List of parameters to add to the GET request
-    var params = {};
-    var body;
-    var method = 'GET';
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchDB, AbstractPouchDB);
+function PouchDB(name, opts) {
+  // In Node our test suite only tests this for PouchAlt unfortunately
+  /* istanbul ignore if */
+  if (!(this instanceof PouchDB)) {
+    return new PouchDB(name, opts);
+  }
 
-    if (opts.conflicts) {
-      params.conflicts = true;
-    }
+  var self = this;
+  opts = opts || {};
 
-    /* istanbul ignore if */
-    if (opts.update_seq) {
-      params.update_seq = true;
-    }
+  if (name && typeof name === 'object') {
+    opts = name;
+    name = opts.name;
+    delete opts.name;
+  }
 
-    if (opts.descending) {
-      params.descending = true;
-    }
+  if (opts.deterministic_revs === undefined) {
+    opts.deterministic_revs = true;
+  }
 
-    if (opts.include_docs) {
-      params.include_docs = true;
-    }
+  this.__opts = opts = clone(opts);
 
-    // added in CouchDB 1.6.0
-    if (opts.attachments) {
-      params.attachments = true;
-    }
+  self.auto_compaction = opts.auto_compaction;
+  self.prefix = PouchDB.prefix;
 
-    if (opts.key) {
-      params.key = JSON.stringify(opts.key);
-    }
+  if (typeof name !== 'string') {
+    throw new Error('Missing/invalid DB name');
+  }
 
-    if (opts.start_key) {
-      opts.startkey = opts.start_key;
-    }
+  var prefixedName = (opts.prefix || '') + name;
+  var backend = parseAdapter(prefixedName, opts);
 
-    if (opts.startkey) {
-      params.startkey = JSON.stringify(opts.startkey);
-    }
+  opts.name = backend.name;
+  opts.adapter = opts.adapter || backend.adapter;
 
-    if (opts.end_key) {
-      opts.endkey = opts.end_key;
-    }
+  self.name = name;
+  self._adapter = opts.adapter;
+  PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]);
 
-    if (opts.endkey) {
-      params.endkey = JSON.stringify(opts.endkey);
-    }
+  if (!PouchDB.adapters[opts.adapter] ||
+      !PouchDB.adapters[opts.adapter].valid()) {
+    throw new Error('Invalid Adapter: ' + opts.adapter);
+  }
 
-    if (typeof opts.inclusive_end !== 'undefined') {
-      params.inclusive_end = !!opts.inclusive_end;
-    }
+  AbstractPouchDB.call(self);
+  self.taskqueue = new TaskQueue();
 
-    if (typeof opts.limit !== 'undefined') {
-      params.limit = opts.limit;
+  self.adapter = opts.adapter;
+
+  PouchDB.adapters[opts.adapter].call(self, opts, function (err) {
+    if (err) {
+      return self.taskqueue.fail(err);
     }
+    prepareForDestruction(self);
 
-    if (typeof opts.skip !== 'undefined') {
-      params.skip = opts.skip;
+    self.emit('created', self);
+    PouchDB.emit('created', self.name);
+    self.taskqueue.ready(self);
+  });
+
+}
+
+// AbortController was introduced quite a while after fetch and
+// isnt required for PouchDB to function so polyfill if needed
+var a = (typeof AbortController !== 'undefined')
+    ? AbortController
+    : function () { return {abort: function () {}}; };
+
+var f$1 = fetch;
+var h = Headers;
+
+PouchDB.adapters = {};
+PouchDB.preferredAdapters = [];
+
+PouchDB.prefix = '_pouch_';
+
+var eventEmitter = new events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
+
+function setUpEventEmitter(Pouch) {
+  Object.keys(events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype).forEach(function (key) {
+    if (typeof events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype[key] === 'function') {
+      Pouch[key] = eventEmitter[key].bind(eventEmitter);
     }
+  });
 
-    var paramStr = paramsToStr(params);
+  // these are created in constructor.js, and allow us to notify each DB with
+  // the same name that it was destroyed, via the constructor object
+  var destructListeners = Pouch._destructionListeners = new ExportedMap();
 
-    if (typeof opts.keys !== 'undefined') {
-      method = 'POST';
-      body = {keys: opts.keys};
+  Pouch.on('ref', function onConstructorRef(db) {
+    if (!destructListeners.has(db.name)) {
+      destructListeners.set(db.name, []);
     }
+    destructListeners.get(db.name).push(db);
+  });
 
-    fetchJSON(genDBUrl(host, '_all_docs' + paramStr), {
-       method: method,
-      body: JSON.stringify(body)
-    }).then(function (result) {
-      if (opts.include_docs && opts.attachments && opts.binary) {
-        result.data.rows.forEach(readAttachmentsAsBlobOrBuffer);
-      }
-      callback(null, result.data);
-    }).catch(callback);
+  Pouch.on('unref', function onConstructorUnref(db) {
+    if (!destructListeners.has(db.name)) {
+      return;
+    }
+    var dbList = destructListeners.get(db.name);
+    var pos = dbList.indexOf(db);
+    if (pos < 0) {
+      /* istanbul ignore next */
+      return;
+    }
+    dbList.splice(pos, 1);
+    if (dbList.length > 1) {
+      /* istanbul ignore next */
+      destructListeners.set(db.name, dbList);
+    } else {
+      destructListeners.delete(db.name);
+    }
   });
 
-  // Get a list of changes made to documents in the database given by host.
-  // TODO According to the README, there should be two other methods here,
-  // api.changes.addListener and api.changes.removeListener.
-  api._changes = function (opts) {
+  Pouch.on('destroyed', function onConstructorDestroyed(name) {
+    if (!destructListeners.has(name)) {
+      return;
+    }
+    var dbList = destructListeners.get(name);
+    destructListeners.delete(name);
+    dbList.forEach(function (db) {
+      db.emit('destroyed',true);
+    });
+  });
+}
 
-    // We internally page the results of a changes request, this means
-    // if there is a large set of changes to be returned we can start
-    // processing them quicker instead of waiting on the entire
-    // set of changes to return and attempting to process them at once
-    var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE;
+setUpEventEmitter(PouchDB);
 
-    opts = clone(opts);
+PouchDB.adapter = function (id, obj, addToPreferredAdapters) {
+  /* istanbul ignore else */
+  if (obj.valid()) {
+    PouchDB.adapters[id] = obj;
+    if (addToPreferredAdapters) {
+      PouchDB.preferredAdapters.push(id);
+    }
+  }
+};
+
+PouchDB.plugin = function (obj) {
+  if (typeof obj === 'function') { // function style for plugins
+    obj(PouchDB);
+  } else if (typeof obj !== 'object' || Object.keys(obj).length === 0) {
+    throw new Error('Invalid plugin: got "' + obj + '", expected an object or a function');
+  } else {
+    Object.keys(obj).forEach(function (id) { // object style for plugins
+      PouchDB.prototype[id] = obj[id];
+    });
+  }
+  if (this.__defaults) {
+    PouchDB.__defaults = $inject_Object_assign({}, this.__defaults);
+  }
+  return PouchDB;
+};
 
-    if (opts.continuous && !('heartbeat' in opts)) {
-      opts.heartbeat = DEFAULT_HEARTBEAT;
+PouchDB.defaults = function (defaultOpts) {
+  function PouchAlt(name, opts) {
+    if (!(this instanceof PouchAlt)) {
+      return new PouchAlt(name, opts);
     }
 
-    var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000;
-
-    // ensure CHANGES_TIMEOUT_BUFFER applies
-    if ('timeout' in opts && opts.timeout &&
-      (requestTimeout - opts.timeout) < CHANGES_TIMEOUT_BUFFER) {
-        requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER;
-    }
+    opts = opts || {};
 
-    /* istanbul ignore if */
-    if ('heartbeat' in opts && opts.heartbeat &&
-       (requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) {
-        requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER;
+    if (name && typeof name === 'object') {
+      opts = name;
+      name = opts.name;
+      delete opts.name;
     }
 
-    var params = {};
-    if ('timeout' in opts && opts.timeout) {
-      params.timeout = opts.timeout;
-    }
+    opts = $inject_Object_assign({}, PouchAlt.__defaults, opts);
+    PouchDB.call(this, name, opts);
+  }
 
-    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
-    var leftToFetch = limit;
+  inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchAlt, PouchDB);
 
-    if (opts.style) {
-      params.style = opts.style;
+  PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice();
+  Object.keys(PouchDB).forEach(function (key) {
+    if (!(key in PouchAlt)) {
+      PouchAlt[key] = PouchDB[key];
     }
+  });
 
-    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
-      params.include_docs = true;
-    }
+  // make default options transitive
+  // https://github.com/pouchdb/pouchdb/issues/5922
+  PouchAlt.__defaults = $inject_Object_assign({}, this.__defaults, defaultOpts);
 
-    if (opts.attachments) {
-      params.attachments = true;
-    }
+  return PouchAlt;
+};
 
-    if (opts.continuous) {
-      params.feed = 'longpoll';
-    }
+PouchDB.fetch = function (url, opts) {
+  return f$1(url, opts);
+};
 
-    if (opts.seq_interval) {
-      params.seq_interval = opts.seq_interval;
-    }
+// managed automatically by set-version.js
+var version = "7.0.0";
 
-    if (opts.conflicts) {
-      params.conflicts = true;
+// this would just be "return doc[field]", but fields
+// can be "deep" due to dot notation
+function getFieldFromDoc(doc, parsedField) {
+  var value = doc;
+  for (var i = 0, len = parsedField.length; i < len; i++) {
+    var key = parsedField[i];
+    value = value[key];
+    if (!value) {
+      break;
     }
+  }
+  return value;
+}
 
-    if (opts.descending) {
-      params.descending = true;
-    }
-    
-    /* istanbul ignore if */
-    if (opts.update_seq) {
-      params.update_seq = true;
-    }
+function compare$1(left, right) {
+  return left < right ? -1 : left > right ? 1 : 0;
+}
 
-    if ('heartbeat' in opts) {
-      // If the heartbeat value is false, it disables the default heartbeat
-      if (opts.heartbeat) {
-        params.heartbeat = opts.heartbeat;
+// Converts a string in dot notation to an array of its components, with backslash escaping
+function parseField(fieldName) {
+  // fields may be deep (e.g. "foo.bar.baz"), so parse
+  var fields = [];
+  var current = '';
+  for (var i = 0, len = fieldName.length; i < len; i++) {
+    var ch = fieldName[i];
+    if (ch === '.') {
+      if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter
+        current = current.substring(0, current.length - 1) + '.';
+      } else { // not escaped, so delimiter
+        fields.push(current);
+        current = '';
       }
+    } else { // normal character
+      current += ch;
     }
+  }
+  fields.push(current);
+  return fields;
+}
 
-    if (opts.filter && typeof opts.filter === 'string') {
-      params.filter = opts.filter;
-    }
+var combinationFields = ['$or', '$nor', '$not'];
+function isCombinationalField(field) {
+  return combinationFields.indexOf(field) > -1;
+}
 
-    if (opts.view && typeof opts.view === 'string') {
-      params.filter = '_view';
-      params.view = opts.view;
-    }
+function getKey(obj) {
+  return Object.keys(obj)[0];
+}
 
-    // If opts.query_params exists, pass it through to the changes request.
-    // These parameters may be used by the filter on the source database.
-    if (opts.query_params && typeof opts.query_params === 'object') {
-      for (var param_name in opts.query_params) {
-        /* istanbul ignore else */
-        if (opts.query_params.hasOwnProperty(param_name)) {
-          params[param_name] = opts.query_params[param_name];
-        }
-      }
-    }
+function getValue(obj) {
+  return obj[getKey(obj)];
+}
 
-    var method = 'GET';
-    var body;
 
-    if (opts.doc_ids) {
-      // set this automagically for the user; it's annoying that couchdb
-      // requires both a "filter" and a "doc_ids" param.
-      params.filter = '_doc_ids';
-      method = 'POST';
-      body = {doc_ids: opts.doc_ids };
-    }
-    /* istanbul ignore next */
-    else if (opts.selector) {
-      // set this automagically for the user, similar to above
-      params.filter = '_selector';
-      method = 'POST';
-      body = {selector: opts.selector };
-    }
+// flatten an array of selectors joined by an $and operator
+function mergeAndedSelectors(selectors) {
 
-    var controller = new a();
-    var lastFetchedSeq;
+  // sort to ensure that e.g. if the user specified
+  // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into
+  // just {$gt: 'b'}
+  var res = {};
 
-    // Get all the changes starting wtih the one immediately after the
-    // sequence number given by since.
-    var fetchData = function (since, callback) {
-      if (opts.aborted) {
-        return;
-      }
-      params.since = since;
-      // "since" can be any kind of json object in Cloudant/CouchDB 2.x
-      /* istanbul ignore next */
-      if (typeof params.since === "object") {
-        params.since = JSON.stringify(params.since);
+  selectors.forEach(function (selector) {
+    Object.keys(selector).forEach(function (field) {
+      var matcher = selector[field];
+      if (typeof matcher !== 'object') {
+        matcher = {$eq: matcher};
       }
 
-      if (opts.descending) {
-        if (limit) {
-          params.limit = leftToFetch;
+      if (isCombinationalField(field)) {
+        if (matcher instanceof Array) {
+          res[field] = matcher.map(function (m) {
+            return mergeAndedSelectors([m]);
+          });
+        } else {
+          res[field] = mergeAndedSelectors([matcher]);
         }
       } else {
-        params.limit = (!limit || leftToFetch > batchSize) ?
-          batchSize : leftToFetch;
-      }
-
-      // Set the options for the ajax call
-      var url = genDBUrl(host, '_changes' + paramsToStr(params));
-      var fetchOpts = {
-        signal: controller.signal,
-        method: method,
-        body: JSON.stringify(body)
-      };
-      lastFetchedSeq = since;
-
-      /* istanbul ignore if */
-      if (opts.aborted) {
-        return;
-      }
-
-      // Get the changes
-      setup().then(function () {
-        return fetchJSON(url, fetchOpts, callback);
-      }).catch(callback);
-    };
-
-    // If opts.since exists, get all the changes from the sequence
-    // number given by opts.since. Otherwise, get all the changes
-    // from the sequence number 0.
-    var results = {results: []};
+        var fieldMatchers = res[field] = res[field] || {};
+        Object.keys(matcher).forEach(function (operator) {
+          var value = matcher[operator];
 
-    var fetched = function (err, res) {
-      if (opts.aborted) {
-        return;
-      }
-      var raw_results_length = 0;
-      // If the result of the ajax call (res) contains changes (res.results)
-      if (res && res.results) {
-        raw_results_length = res.results.length;
-        results.last_seq = res.last_seq;
-        var pending = null;
-        var lastSeq = null;
-        // Attach 'pending' property if server supports it (CouchDB 2.0+)
-        /* istanbul ignore if */
-        if (typeof res.pending === 'number') {
-          pending = res.pending;
-        }
-        if (typeof results.last_seq === 'string' || typeof results.last_seq === 'number') {
-          lastSeq = results.last_seq;
-        }
-        // For each change
-        var req = {};
-        req.query = opts.query_params;
-        res.results = res.results.filter(function (c) {
-          leftToFetch--;
-          var ret = filterChange(opts)(c);
-          if (ret) {
-            if (opts.include_docs && opts.attachments && opts.binary) {
-              readAttachmentsAsBlobOrBuffer(c);
-            }
-            if (opts.return_docs) {
-              results.results.push(c);
-            }
-            opts.onChange(c, pending, lastSeq);
+          if (operator === '$gt' || operator === '$gte') {
+            return mergeGtGte(operator, value, fieldMatchers);
+          } else if (operator === '$lt' || operator === '$lte') {
+            return mergeLtLte(operator, value, fieldMatchers);
+          } else if (operator === '$ne') {
+            return mergeNe(value, fieldMatchers);
+          } else if (operator === '$eq') {
+            return mergeEq(value, fieldMatchers);
           }
-          return ret;
+          fieldMatchers[operator] = value;
         });
-      } else if (err) {
-        // In case of an error, stop listening for changes and call
-        // opts.complete
-        opts.aborted = true;
-        opts.complete(err);
-        return;
-      }
-
-      // The changes feed may have timed out with no results
-      // if so reuse last update sequence
-      if (res && res.last_seq) {
-        lastFetchedSeq = res.last_seq;
       }
+    });
+  });
 
-      var finished = (limit && leftToFetch <= 0) ||
-        (res && raw_results_length < batchSize) ||
-        (opts.descending);
+  return res;
+}
 
-      if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
-        // Queue a call to fetch again with the newest sequence number
-        immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { fetchData(lastFetchedSeq, fetched); });
-      } else {
-        // We're done, call the callback
-        opts.complete(null, results);
-      }
-    };
 
-    fetchData(opts.since || 0, fetched);
 
-    // Return a method to cancel this method from processing any more
-    return {
-      cancel: function () {
-        opts.aborted = true;
-        controller.abort();
+// collapse logically equivalent gt/gte values
+function mergeGtGte(operator, value, fieldMatchers) {
+  if (typeof fieldMatchers.$eq !== 'undefined') {
+    return; // do nothing
+  }
+  if (typeof fieldMatchers.$gte !== 'undefined') {
+    if (operator === '$gte') {
+      if (value > fieldMatchers.$gte) { // more specificity
+        fieldMatchers.$gte = value;
+      }
+    } else { // operator === '$gt'
+      if (value >= fieldMatchers.$gte) { // more specificity
+        delete fieldMatchers.$gte;
+        fieldMatchers.$gt = value;
       }
-    };
-  };
-
-  // Given a set of document/revision IDs (given by req), tets the subset of
-  // those that do NOT correspond to revisions stored in the database.
-  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
-  api.revsDiff = adapterFun$$1('revsDiff', function (req, opts, callback) {
-    // If no options were given, set the callback to be the second parameter
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
     }
-
-    // Get the missing document/revision IDs
-    fetchJSON(genDBUrl(host, '_revs_diff'), {
-      method: 'POST',
-      body: JSON.stringify(req)
-    }, callback).catch(callback);
-  });
-
-  api._close = function (callback) {
-    callback();
-  };
-
-  api._destroy = function (options, callback) {
-    fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) {
-      callback(null, json);
-    }).catch(function (err) {
-      /* istanbul ignore if */
-      if (err.status === 404) {
-        callback(null, {ok: true});
-      } else {
-        callback(err);
+  } else if (typeof fieldMatchers.$gt !== 'undefined') {
+    if (operator === '$gte') {
+      if (value > fieldMatchers.$gt) { // more specificity
+        delete fieldMatchers.$gt;
+        fieldMatchers.$gte = value;
       }
-    });
-  };
-}
-
-// HttpPouch is a valid adapter.
-HttpPouch.valid = function () {
-  return true;
-};
-
-function HttpPouch$1 (PouchDB) {
-  PouchDB.adapter('http', HttpPouch, false);
-  PouchDB.adapter('https', HttpPouch, false);
+    } else { // operator === '$gt'
+      if (value > fieldMatchers.$gt) { // more specificity
+        fieldMatchers.$gt = value;
+      }
+    }
+  } else {
+    fieldMatchers[operator] = value;
+  }
 }
 
-function QueryParseError(message) {
-  this.status = 400;
-  this.name = 'query_parse_error';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, QueryParseError);
-  } catch (e) {}
+// collapse logically equivalent lt/lte values
+function mergeLtLte(operator, value, fieldMatchers) {
+  if (typeof fieldMatchers.$eq !== 'undefined') {
+    return; // do nothing
+  }
+  if (typeof fieldMatchers.$lte !== 'undefined') {
+    if (operator === '$lte') {
+      if (value < fieldMatchers.$lte) { // more specificity
+        fieldMatchers.$lte = value;
+      }
+    } else { // operator === '$gt'
+      if (value <= fieldMatchers.$lte) { // more specificity
+        delete fieldMatchers.$lte;
+        fieldMatchers.$lt = value;
+      }
+    }
+  } else if (typeof fieldMatchers.$lt !== 'undefined') {
+    if (operator === '$lte') {
+      if (value < fieldMatchers.$lt) { // more specificity
+        delete fieldMatchers.$lt;
+        fieldMatchers.$lte = value;
+      }
+    } else { // operator === '$gt'
+      if (value < fieldMatchers.$lt) { // more specificity
+        fieldMatchers.$lt = value;
+      }
+    }
+  } else {
+    fieldMatchers[operator] = value;
+  }
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(QueryParseError, Error);
-
-function NotFoundError(message) {
-  this.status = 404;
-  this.name = 'not_found';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, NotFoundError);
-  } catch (e) {}
+// combine $ne values into one array
+function mergeNe(value, fieldMatchers) {
+  if ('$ne' in fieldMatchers) {
+    // there are many things this could "not" be
+    fieldMatchers.$ne.push(value);
+  } else { // doesn't exist yet
+    fieldMatchers.$ne = [value];
+  }
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(NotFoundError, Error);
-
-function BuiltInError(message) {
-  this.status = 500;
-  this.name = 'invalid_value';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, BuiltInError);
-  } catch (e) {}
+// add $eq into the mix
+function mergeEq(value, fieldMatchers) {
+  // these all have less specificity than the $eq
+  // TODO: check for user errors here
+  delete fieldMatchers.$gt;
+  delete fieldMatchers.$gte;
+  delete fieldMatchers.$lt;
+  delete fieldMatchers.$lte;
+  delete fieldMatchers.$ne;
+  fieldMatchers.$eq = value;
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(BuiltInError, Error);
 
-function promisedCallback(promise, callback) {
-  if (callback) {
-    promise.then(function (res) {
-      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-        callback(null, res);
-      });
-    }, function (reason) {
-      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-        callback(reason);
-      });
-    });
+//
+// normalize the selector
+//
+function massageSelector(input) {
+  var result = clone(input);
+  var wasAnded = false;
+  if ('$and' in result) {
+    result = mergeAndedSelectors(result['$and']);
+    wasAnded = true;
   }
-  return promise;
-}
 
-function callbackify(fun) {
-  return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
-    var cb = args.pop();
-    var promise = fun.apply(this, args);
-    if (typeof cb === 'function') {
-      promisedCallback(promise, cb);
+  ['$or', '$nor'].forEach(function (orOrNor) {
+    if (orOrNor in result) {
+      // message each individual selector
+      // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}}
+      result[orOrNor].forEach(function (subSelector) {
+        var fields = Object.keys(subSelector);
+        for (var i = 0; i < fields.length; i++) {
+          var field = fields[i];
+          var matcher = subSelector[field];
+          if (typeof matcher !== 'object' || matcher === null) {
+            subSelector[field] = {$eq: matcher};
+          }
+        }
+      });
     }
-    return promise;
-  });
-}
-
-// Promise finally util similar to Q.finally
-function fin(promise, finalPromiseFactory) {
-  return promise.then(function (res) {
-    return finalPromiseFactory().then(function () {
-      return res;
-    });
-  }, function (reason) {
-    return finalPromiseFactory().then(function () {
-      throw reason;
-    });
   });
-}
-
-function sequentialize(queue, promiseFactory) {
-  return function () {
-    var args = arguments;
-    var that = this;
-    return queue.add(function () {
-      return promiseFactory.apply(that, args);
-    });
-  };
-}
 
-// uniq an array of strings, order not guaranteed
-// similar to underscore/lodash _.uniq
-function uniq(arr) {
-  var theSet = new ExportedSet(arr);
-  var result = new Array(theSet.size);
-  var index = -1;
-  theSet.forEach(function (value) {
-    result[++index] = value;
-  });
-  return result;
-}
+  if ('$not' in result) {
+    //This feels a little like forcing, but it will work for now,
+    //I would like to come back to this and make the merging of selectors a little more generic
+    result['$not'] = mergeAndedSelectors([result['$not']]);
+  }
 
-function mapToKeysArray(map) {
-  var result = new Array(map.size);
-  var index = -1;
-  map.forEach(function (value, key) {
-    result[++index] = key;
-  });
-  return result;
-}
+  var fields = Object.keys(result);
 
-function createBuiltInError(name) {
-  var message = 'builtin ' + name +
-    ' function requires map values to be numbers' +
-    ' or number arrays';
-  return new BuiltInError(message);
-}
+  for (var i = 0; i < fields.length; i++) {
+    var field = fields[i];
+    var matcher = result[field];
 
-function sum(values) {
-  var result = 0;
-  for (var i = 0, len = values.length; i < len; i++) {
-    var num = values[i];
-    if (typeof num !== 'number') {
-      if (Array.isArray(num)) {
-        // lists of numbers are also allowed, sum them separately
-        result = typeof result === 'number' ? [result] : result;
-        for (var j = 0, jLen = num.length; j < jLen; j++) {
-          var jNum = num[j];
-          if (typeof jNum !== 'number') {
-            throw createBuiltInError('_sum');
-          } else if (typeof result[j] === 'undefined') {
-            result.push(jNum);
-          } else {
-            result[j] += jNum;
-          }
-        }
-      } else { // not array/number
-        throw createBuiltInError('_sum');
-      }
-    } else if (typeof result === 'number') {
-      result += num;
-    } else { // add number to array
-      result[0] += num;
+    if (typeof matcher !== 'object' || matcher === null) {
+      matcher = {$eq: matcher};
+    } else if ('$ne' in matcher && !wasAnded) {
+      // I put these in an array, since there may be more than one
+      // but in the "mergeAnded" operation, I already take care of that
+      matcher.$ne = [matcher.$ne];
     }
+    result[field] = matcher;
   }
+
   return result;
 }
 
-var log = guardedConsole.bind(null, 'log');
-var isArray = Array.isArray;
-var toJSON = JSON.parse;
+function pad(str, padWith, upToLength) {
+  var padding = '';
+  var targetLength = upToLength - str.length;
+  /* istanbul ignore next */
+  while (padding.length < targetLength) {
+    padding += padWith;
+  }
+  return padding;
+}
 
-function evalFunctionWithEval(func, emit) {
-  return scopeEval(
-    "return (" + func.replace(/;\s*$/, "") + ");",
-    {
-      emit: emit,
-      sum: sum,
-      log: log,
-      isArray: isArray,
-      toJSON: toJSON
-    }
-  );
+function padLeft(str, padWith, upToLength) {
+  var padding = pad(str, padWith, upToLength);
+  return padding + str;
 }
 
-/*
- * Simple task queue to sequentialize actions. Assumes
- * callbacks will eventually fire (once).
- */
+var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
+var MAGNITUDE_DIGITS = 3; // ditto
+var SEP = ''; // set to '_' for easier debugging 
 
+function collate(a, b) {
 
-function TaskQueue$1() {
-  this.promise = new Promise(function (fulfill) {fulfill(); });
-}
-TaskQueue$1.prototype.add = function (promiseFactory) {
-  this.promise = this.promise.catch(function () {
-    // just recover
-  }).then(function () {
-    return promiseFactory();
-  });
-  return this.promise;
-};
-TaskQueue$1.prototype.finish = function () {
-  return this.promise;
-};
+  if (a === b) {
+    return 0;
+  }
 
-function stringify(input) {
-  if (!input) {
-    return 'undefined'; // backwards compat for empty reduce
+  a = normalizeKey(a);
+  b = normalizeKey(b);
+
+  var ai = collationIndex(a);
+  var bi = collationIndex(b);
+  if ((ai - bi) !== 0) {
+    return ai - bi;
   }
-  // for backwards compat with mapreduce, functions/strings are stringified
-  // as-is. everything else is JSON-stringified.
-  switch (typeof input) {
-    case 'function':
-      // e.g. a mapreduce map
-      return input.toString();
+  switch (typeof a) {
+    case 'number':
+      return a - b;
+    case 'boolean':
+      return a < b ? -1 : 1;
     case 'string':
-      // e.g. a mapreduce built-in _reduce function
-      return input.toString();
-    default:
-      // e.g. a JSON object in the case of mango queries
-      return JSON.stringify(input);
+      return stringCollate(a, b);
   }
+  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
 }
 
-/* create a string signature for a view so we can cache it and uniq it */
-function createViewSignature(mapFun, reduceFun) {
-  // the "undefined" part is for backwards compatibility
-  return stringify(mapFun) + stringify(reduceFun) + 'undefined';
+// couch considers null/NaN/Infinity/-Infinity === undefined,
+// for the purposes of mapreduce indexes. also, dates get stringified.
+function normalizeKey(key) {
+  switch (typeof key) {
+    case 'undefined':
+      return null;
+    case 'number':
+      if (key === Infinity || key === -Infinity || isNaN(key)) {
+        return null;
+      }
+      return key;
+    case 'object':
+      var origKey = key;
+      if (Array.isArray(key)) {
+        var len = key.length;
+        key = new Array(len);
+        for (var i = 0; i < len; i++) {
+          key[i] = normalizeKey(origKey[i]);
+        }
+      /* istanbul ignore next */
+      } else if (key instanceof Date) {
+        return key.toJSON();
+      } else if (key !== null) { // generic object
+        key = {};
+        for (var k in origKey) {
+          if (origKey.hasOwnProperty(k)) {
+            var val = origKey[k];
+            if (typeof val !== 'undefined') {
+              key[k] = normalizeKey(val);
+            }
+          }
+        }
+      }
+  }
+  return key;
 }
 
-function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) {
-  var viewSignature = createViewSignature(mapFun, reduceFun);
-
-  var cachedViews;
-  if (!temporary) {
-    // cache this to ensure we don't try to update the same view twice
-    cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {};
-    if (cachedViews[viewSignature]) {
-      return cachedViews[viewSignature];
+function indexify(key) {
+  if (key !== null) {
+    switch (typeof key) {
+      case 'boolean':
+        return key ? 1 : 0;
+      case 'number':
+        return numToIndexableString(key);
+      case 'string':
+        // We've to be sure that key does not contain \u0000
+        // Do order-preserving replacements:
+        // 0 -> 1, 1
+        // 1 -> 1, 2
+        // 2 -> 2, 2
+        /* eslint-disable no-control-regex */
+        return key
+          .replace(/\u0002/g, '\u0002\u0002')
+          .replace(/\u0001/g, '\u0001\u0002')
+          .replace(/\u0000/g, '\u0001\u0001');
+        /* eslint-enable no-control-regex */
+      case 'object':
+        var isArray = Array.isArray(key);
+        var arr = isArray ? key : Object.keys(key);
+        var i = -1;
+        var len = arr.length;
+        var result = '';
+        if (isArray) {
+          while (++i < len) {
+            result += toIndexableString(arr[i]);
+          }
+        } else {
+          while (++i < len) {
+            var objKey = arr[i];
+            result += toIndexableString(objKey) +
+                toIndexableString(key[objKey]);
+          }
+        }
+        return result;
     }
   }
+  return '';
+}
 
-  var promiseForView = sourceDB.info().then(function (info) {
-
-    var depDbName = info.db_name + '-mrview-' +
-      (temporary ? 'temp' : stringMd5(viewSignature));
+// convert the given key to a string that would be appropriate
+// for lexical sorting, e.g. within a database, where the
+// sorting is the same given by the collate() function.
+function toIndexableString(key) {
+  var zero = '\u0000';
+  key = normalizeKey(key);
+  return collationIndex(key) + SEP + indexify(key) + zero;
+}
 
-    // save the view name in the source db so it can be cleaned up if necessary
-    // (e.g. when the _design doc is deleted, remove all associated view data)
-    function diffFunction(doc) {
-      doc.views = doc.views || {};
-      var fullViewName = viewName;
-      if (fullViewName.indexOf('/') === -1) {
-        fullViewName = viewName + '/' + viewName;
-      }
-      var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
-      /* istanbul ignore if */
-      if (depDbs[depDbName]) {
-        return; // no update necessary
+function parseNumber(str, i) {
+  var originalIdx = i;
+  var num;
+  var zero = str[i] === '1';
+  if (zero) {
+    num = 0;
+    i++;
+  } else {
+    var neg = str[i] === '0';
+    i++;
+    var numAsString = '';
+    var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
+    var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
+    /* istanbul ignore next */
+    if (neg) {
+      magnitude = -magnitude;
+    }
+    i += MAGNITUDE_DIGITS;
+    while (true) {
+      var ch = str[i];
+      if (ch === '\u0000') {
+        break;
+      } else {
+        numAsString += ch;
       }
-      depDbs[depDbName] = true;
-      return doc;
+      i++;
+    }
+    numAsString = numAsString.split('.');
+    if (numAsString.length === 1) {
+      num = parseInt(numAsString, 10);
+    } else {
+      /* istanbul ignore next */
+      num = parseFloat(numAsString[0] + '.' + numAsString[1]);
+    }
+    /* istanbul ignore next */
+    if (neg) {
+      num = num - 10;
+    }
+    /* istanbul ignore next */
+    if (magnitude !== 0) {
+      // parseFloat is more reliable than pow due to rounding errors
+      // e.g. Number.MAX_VALUE would return Infinity if we did
+      // num * Math.pow(10, magnitude);
+      num = parseFloat(num + 'e' + magnitude);
     }
-    return upsert(sourceDB, '_local/' + localDocName, diffFunction).then(function () {
-      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
-        var db = res.db;
-        db.auto_compaction = true;
-        var view = {
-          name: depDbName,
-          db: db,
-          sourceDB: sourceDB,
-          adapter: sourceDB.adapter,
-          mapFun: mapFun,
-          reduceFun: reduceFun
-        };
-        return view.db.get('_local/lastSeq').catch(function (err) {
-          /* istanbul ignore if */
-          if (err.status !== 404) {
-            throw err;
-          }
-        }).then(function (lastSeqDoc) {
-          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
-          if (cachedViews) {
-            view.db.once('destroyed', function () {
-              delete cachedViews[viewSignature];
-            });
-          }
-          return view;
-        });
-      });
-    });
-  });
-
-  if (cachedViews) {
-    cachedViews[viewSignature] = promiseForView;
   }
-  return promiseForView;
+  return {num: num, length : i - originalIdx};
 }
 
-var persistentQueues = {};
-var tempViewQueue = new TaskQueue$1();
-var CHANGES_BATCH_SIZE$1 = 50;
+// move up the stack while parsing
+// this function moved outside of parseIndexableString for performance
+function pop(stack, metaStack) {
+  var obj = stack.pop();
 
-function parseViewName(name) {
-  // can be either 'ddocname/viewname' or just 'viewname'
-  // (where the ddoc name is the same)
-  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+  if (metaStack.length) {
+    var lastMetaElement = metaStack[metaStack.length - 1];
+    if (obj === lastMetaElement.element) {
+      // popping a meta-element, e.g. an object whose value is another object
+      metaStack.pop();
+      lastMetaElement = metaStack[metaStack.length - 1];
+    }
+    var element = lastMetaElement.element;
+    var lastElementIndex = lastMetaElement.index;
+    if (Array.isArray(element)) {
+      element.push(obj);
+    } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+      var key = stack.pop();
+      element[key] = obj;
+    } else {
+      stack.push(obj); // obj with key only
+    }
+  }
 }
 
-function isGenOne(changes) {
-  // only return true if the current change is 1-
-  // and there are no other leafs
-  return changes.length === 1 && /^1-/.test(changes[0].rev);
-}
+function parseIndexableString(str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
 
-function emitError(db, e) {
-  try {
-    db.emit('error', e);
-  } catch (err) {
-    guardedConsole('error',
-      'The user\'s map/reduce function threw an uncaught error.\n' +
-      'You can debug this error by doing:\n' +
-      'myDatabase.on(\'error\', function (err) { debugger; });\n' +
-      'Please double-check your map/reduce function.');
-    guardedConsole('error', e);
+  /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+  while (true) {
+    var collationIndex = str[i++];
+    if (collationIndex === '\u0000') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case '1':
+        stack.push(null);
+        break;
+      case '2':
+        stack.push(str[i] === '1');
+        i++;
+        break;
+      case '3':
+        var parsedNum = parseNumber(str, i);
+        stack.push(parsedNum.num);
+        i += parsedNum.length;
+        break;
+      case '4':
+        var parsedStr = '';
+        /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+        while (true) {
+          var ch = str[i];
+          if (ch === '\u0000') {
+            break;
+          }
+          parsedStr += ch;
+          i++;
+        }
+        // perform the reverse of the order-preserving replacement
+        // algorithm (see above)
+        /* eslint-disable no-control-regex */
+        parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
+          .replace(/\u0001\u0002/g, '\u0001')
+          .replace(/\u0002\u0002/g, '\u0002');
+        /* eslint-enable no-control-regex */
+        stack.push(parsedStr);
+        break;
+      case '5':
+        var arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '6':
+        var objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      /* istanbul ignore next */
+      default:
+        throw new Error(
+          'bad collationIndex or unexpectedly reached end of input: ' +
+            collationIndex);
+    }
   }
 }
 
-/**
- * Returns an "abstract" mapreduce object of the form:
- *
- *   {
- *     query: queryFun,
- *     viewCleanup: viewCleanupFun
- *   }
- *
- * Arguments are:
- *
- * localDoc: string
- *   This is for the local doc that gets saved in order to track the
- *   "dependent" DBs and clean them up for viewCleanup. It should be
- *   unique, so that indexer plugins don't collide with each other.
- * mapper: function (mapFunDef, emit)
- *   Returns a map function based on the mapFunDef, which in the case of
- *   normal map/reduce is just the de-stringified function, but may be
- *   something else, such as an object in the case of pouchdb-find.
- * reducer: function (reduceFunDef)
- *   Ditto, but for reducing. Modules don't have to support reducing
- *   (e.g. pouchdb-find).
- * ddocValidator: function (ddoc, viewName)
- *   Throws an error if the ddoc or viewName is not valid.
- *   This could be a way to communicate to the user that the configuration for the
- *   indexer is invalid.
- */
-function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) {
-
-  function tryMap(db, fun, doc) {
-    // emit an event if there was an error thrown by a map function.
-    // putting try/catches in a single function also avoids deoptimizations.
-    try {
-      fun(doc);
-    } catch (e) {
-      emitError(db, e);
+function arrayCollate(a, b) {
+  var len = Math.min(a.length, b.length);
+  for (var i = 0; i < len; i++) {
+    var sort = collate(a[i], b[i]);
+    if (sort !== 0) {
+      return sort;
     }
   }
-
-  function tryReduce(db, fun, keys, values, rereduce) {
-    // same as above, but returning the result or an error. there are two separate
-    // functions to avoid extra memory allocations since the tryCode() case is used
-    // for custom map functions (common) vs this function, which is only used for
-    // custom reduce functions (rare)
-    try {
-      return {output : fun(keys, values, rereduce)};
-    } catch (e) {
-      emitError(db, e);
-      return {error: e};
+  return (a.length === b.length) ? 0 :
+    (a.length > b.length) ? 1 : -1;
+}
+function stringCollate(a, b) {
+  // See: https://github.com/daleharvey/pouchdb/issues/40
+  // This is incompatible with the CouchDB implementation, but its the
+  // best we can do for now
+  return (a === b) ? 0 : ((a > b) ? 1 : -1);
+}
+function objectCollate(a, b) {
+  var ak = Object.keys(a), bk = Object.keys(b);
+  var len = Math.min(ak.length, bk.length);
+  for (var i = 0; i < len; i++) {
+    // First sort the keys
+    var sort = collate(ak[i], bk[i]);
+    if (sort !== 0) {
+      return sort;
+    }
+    // if the keys are equal sort the values
+    sort = collate(a[ak[i]], b[bk[i]]);
+    if (sort !== 0) {
+      return sort;
     }
-  }
 
-  function sortByKeyThenValue(x, y) {
-    var keyCompare = collate(x.key, y.key);
-    return keyCompare !== 0 ? keyCompare : collate(x.value, y.value);
   }
-
-  function sliceResults(results, limit, skip) {
-    skip = skip || 0;
-    if (typeof limit === 'number') {
-      return results.slice(skip, limit + skip);
-    } else if (skip > 0) {
-      return results.slice(skip);
+  return (ak.length === bk.length) ? 0 :
+    (ak.length > bk.length) ? 1 : -1;
+}
+// The collation is defined by erlangs ordered terms
+// the atoms null, true, false come first, then numbers, strings,
+// arrays, then objects
+// null/undefined/NaN/Infinity/-Infinity are all considered null
+function collationIndex(x) {
+  var id = ['boolean', 'number', 'string', 'object'];
+  var idx = id.indexOf(typeof x);
+  //false if -1 otherwise true, but fast!!!!1
+  if (~idx) {
+    if (x === null) {
+      return 1;
     }
-    return results;
+    if (Array.isArray(x)) {
+      return 5;
+    }
+    return idx < 3 ? (idx + 2) : (idx + 3);
   }
-
-  function rowToDocId(row) {
-    var val = row.value;
-    // Users can explicitly specify a joined doc _id, or it
-    // defaults to the doc _id that emitted the key/value.
-    var docId = (val && typeof val === 'object' && val._id) || row.id;
-    return docId;
+  /* istanbul ignore next */
+  if (Array.isArray(x)) {
+    return 5;
   }
+}
 
-  function readAttachmentsAsBlobOrBuffer(res) {
-    res.rows.forEach(function (row) {
-      var atts = row.doc && row.doc._attachments;
-      if (!atts) {
-        return;
-      }
-      Object.keys(atts).forEach(function (filename) {
-        var att = atts[filename];
-        atts[filename].data = b64ToBluffer(att.data, att.content_type);
-      });
-    });
-  }
+// conversion:
+// x yyy zz...zz
+// x = 0 for negative, 1 for 0, 2 for positive
+// y = exponent (for negative numbers negated) moved so that it's >= 0
+// z = mantisse
+function numToIndexableString(num) {
 
-  function postprocessAttachments(opts) {
-    return function (res) {
-      if (opts.include_docs && opts.attachments && opts.binary) {
-        readAttachmentsAsBlobOrBuffer(res);
-      }
-      return res;
-    };
+  if (num === 0) {
+    return '1';
   }
 
-  function addHttpParam(paramName, opts, params, asJson) {
-    // add an http param from opts to params, optionally json-encoded
-    var val = opts[paramName];
-    if (typeof val !== 'undefined') {
-      if (asJson) {
-        val = encodeURIComponent(JSON.stringify(val));
-      }
-      params.push(paramName + '=' + val);
-    }
-  }
+  // convert number to exponential format for easier and
+  // more succinct string sorting
+  var expFormat = num.toExponential().split(/e\+?/);
+  var magnitude = parseInt(expFormat[1], 10);
 
-  function coerceInteger(integerCandidate) {
-    if (typeof integerCandidate !== 'undefined') {
-      var asNumber = Number(integerCandidate);
-      // prevents e.g. '1foo' or '1.1' being coerced to 1
-      if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
-        return asNumber;
-      } else {
-        return integerCandidate;
-      }
-    }
-  }
+  var neg = num < 0;
 
-  function coerceOptions(opts) {
-    opts.group_level = coerceInteger(opts.group_level);
-    opts.limit = coerceInteger(opts.limit);
-    opts.skip = coerceInteger(opts.skip);
-    return opts;
-  }
+  var result = neg ? '0' : '2';
 
-  function checkPositiveInteger(number) {
-    if (number) {
-      if (typeof number !== 'number') {
-        return  new QueryParseError('Invalid value for integer: "' +
-          number + '"');
-      }
-      if (number < 0) {
-        return new QueryParseError('Invalid value for positive integer: ' +
-          '"' + number + '"');
-      }
-    }
-  }
+  // first sort by magnitude
+  // it's easier if all magnitudes are positive
+  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
+  var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
 
-  function checkQueryParseError(options, fun) {
-    var startkeyName = options.descending ? 'endkey' : 'startkey';
-    var endkeyName = options.descending ? 'startkey' : 'endkey';
+  result += SEP + magString;
 
-    if (typeof options[startkeyName] !== 'undefined' &&
-      typeof options[endkeyName] !== 'undefined' &&
-      collate(options[startkeyName], options[endkeyName]) > 0) {
-      throw new QueryParseError('No rows can match your key range, ' +
-        'reverse your start_key and end_key or set {descending : true}');
-    } else if (fun.reduce && options.reduce !== false) {
-      if (options.include_docs) {
-        throw new QueryParseError('{include_docs:true} is invalid for reduce');
-      } else if (options.keys && options.keys.length > 1 &&
-        !options.group && !options.group_level) {
-        throw new QueryParseError('Multi-key fetches for reduce views must use ' +
-          '{group: true}');
-      }
-    }
-    ['group_level', 'limit', 'skip'].forEach(function (optionName) {
-      var error = checkPositiveInteger(options[optionName]);
-      if (error) {
-        throw error;
-      }
-    });
+  // then sort by the factor
+  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
+  /* istanbul ignore next */
+  if (neg) { // for negative reverse ordering
+    factor = 10 - factor;
   }
 
-  function httpQuery(db, fun, opts) {
-    // List of parameters to add to the PUT request
-    var params = [];
-    var body;
-    var method = 'GET';
-    var ok, status;
-
-    // If opts.reduce exists and is defined, then add it to the list
-    // of parameters.
-    // If reduce=false then the results are that of only the map function
-    // not the final result of map and reduce.
-    addHttpParam('reduce', opts, params);
-    addHttpParam('include_docs', opts, params);
-    addHttpParam('attachments', opts, params);
-    addHttpParam('limit', opts, params);
-    addHttpParam('descending', opts, params);
-    addHttpParam('group', opts, params);
-    addHttpParam('group_level', opts, params);
-    addHttpParam('skip', opts, params);
-    addHttpParam('stale', opts, params);
-    addHttpParam('conflicts', opts, params);
-    addHttpParam('startkey', opts, params, true);
-    addHttpParam('start_key', opts, params, true);
-    addHttpParam('endkey', opts, params, true);
-    addHttpParam('end_key', opts, params, true);
-    addHttpParam('inclusive_end', opts, params);
-    addHttpParam('key', opts, params, true);
-    addHttpParam('update_seq', opts, params);
+  var factorStr = factor.toFixed(20);
 
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
+  // strip zeros from the end
+  factorStr = factorStr.replace(/\.?0+$/, '');
 
-    // If keys are supplied, issue a POST to circumvent GET query string limits
-    // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-    if (typeof opts.keys !== 'undefined') {
-      var MAX_URL_LENGTH = 2000;
-      // according to http://stackoverflow.com/a/417184/680742,
-      // the de facto URL length limit is 2000 characters
+  result += SEP + factorStr;
 
-      var keysAsString =
-        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-        // If the keys are short enough, do a GET. we do this to work around
-        // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
-        params += (params[0] === '?' ? '&' : '?') + keysAsString;
-      } else {
-        method = 'POST';
-        if (typeof fun === 'string') {
-          body = {keys: opts.keys};
-        } else { // fun is {map : mapfun}, so append to this
-          fun.keys = opts.keys;
-        }
-      }
-    }
+  return result;
+}
 
-    // We are referencing a query defined in the design doc
-    if (typeof fun === 'string') {
-      var parts = parseViewName(fun);
-      return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
-        headers: new h({'Content-Type': 'application/json'}),
-        method: method,
-        body: JSON.stringify(body)
-      }).then(function (response) {
-        ok = response.ok;
-        status = response.status;
-        return response.json();
-      }).then(function (result) {
-        if (!ok) {
-          result.status = status;
-          throw generateErrorFromResponse(result);
-        }
-        // fail the entire request if the result contains an error
-        result.rows.forEach(function (row) {
-          /* istanbul ignore if */
-          if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
-            throw new Error(row.reason);
-          }
-        });
-        return result;
-      }).then(postprocessAttachments(opts));
-    }
+// create a comparator based on the sort object
+function createFieldSorter(sort) {
 
-    // We are using a temporary view, terrible for performance, good for testing
-    body = body || {};
-    Object.keys(fun).forEach(function (key) {
-      if (Array.isArray(fun[key])) {
-        body[key] = fun[key];
-      } else {
-        body[key] = fun[key].toString();
-      }
+  function getFieldValuesAsArray(doc) {
+    return sort.map(function (sorting) {
+      var fieldName = getKey(sorting);
+      var parsedField = parseField(fieldName);
+      var docFieldValue = getFieldFromDoc(doc, parsedField);
+      return docFieldValue;
     });
-
-    return db.fetch('_temp_view' + params, {
-      headers: new h({'Content-Type': 'application/json'}),
-      method: 'POST',
-      body: JSON.stringify(body)
-    }).then(function (response) {
-        ok = response.ok;
-        status = response.status;
-      return response.json();
-    }).then(function (result) {
-      if (!ok) {
-        result.status = status;
-        throw generateErrorFromResponse(result);
-      }
-      return result;
-    }).then(postprocessAttachments(opts));
   }
 
-  // custom adapters can define their own api._query
-  // and override the default behavior
-  /* istanbul ignore next */
-  function customQuery(db, fun, opts) {
-    return new Promise(function (resolve, reject) {
-      db._query(fun, opts, function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        resolve(res);
-      });
-    });
-  }
+  return function (aRow, bRow) {
+    var aFieldValues = getFieldValuesAsArray(aRow.doc);
+    var bFieldValues = getFieldValuesAsArray(bRow.doc);
+    var collation = collate(aFieldValues, bFieldValues);
+    if (collation !== 0) {
+      return collation;
+    }
+    // this is what mango seems to do
+    return compare$1(aRow.doc._id, bRow.doc._id);
+  };
+}
 
-  // custom adapters can define their own api._viewCleanup
-  // and override the default behavior
-  /* istanbul ignore next */
-  function customViewCleanup(db) {
-    return new Promise(function (resolve, reject) {
-      db._viewCleanup(function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        resolve(res);
-      });
-    });
-  }
+function filterInMemoryFields(rows, requestDef, inMemoryFields) {
+  rows = rows.filter(function (row) {
+    return rowFilter(row.doc, requestDef.selector, inMemoryFields);
+  });
 
-  function defaultsTo(value) {
-    return function (reason) {
-      /* istanbul ignore else */
-      if (reason.status === 404) {
-        return value;
-      } else {
-        throw reason;
-      }
-    };
+  if (requestDef.sort) {
+    // in-memory sort
+    var fieldSorter = createFieldSorter(requestDef.sort);
+    rows = rows.sort(fieldSorter);
+    if (typeof requestDef.sort[0] !== 'string' &&
+        getValue(requestDef.sort[0]) === 'desc') {
+      rows = rows.reverse();
+    }
   }
 
-  // returns a promise for a list of docs to update, based on the input docId.
-  // the order doesn't matter, because post-3.2.0, bulkDocs
-  // is an atomic operation in all three adapters.
-  function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
-    var metaDocId = '_local/doc_' + docId;
-    var defaultMetaDoc = {_id: metaDocId, keys: []};
-    var docData = docIdsToChangesAndEmits.get(docId);
-    var indexableKeysToKeyValues = docData[0];
-    var changes = docData[1];
+  if ('limit' in requestDef || 'skip' in requestDef) {
+    // have to do the limit in-memory
+    var skip = requestDef.skip || 0;
+    var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip;
+    rows = rows.slice(skip, limit);
+  }
+  return rows;
+}
 
-    function getMetaDoc() {
-      if (isGenOne(changes)) {
-        // generation 1, so we can safely assume initial state
-        // for performance reasons (avoids unnecessary GETs)
-        return Promise.resolve(defaultMetaDoc);
-      }
-      return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc));
+function rowFilter(doc, selector, inMemoryFields) {
+  return inMemoryFields.every(function (field) {
+    var matcher = selector[field];
+    var parsedField = parseField(field);
+    var docFieldValue = getFieldFromDoc(doc, parsedField);
+    if (isCombinationalField(field)) {
+      return matchCominationalSelector(field, matcher, doc);
     }
 
-    function getKeyValueDocs(metaDoc) {
-      if (!metaDoc.keys.length) {
-        // no keys, no need for a lookup
-        return Promise.resolve({rows: []});
-      }
-      return view.db.allDocs({
-        keys: metaDoc.keys,
-        include_docs: true
-      });
-    }
+    return matchSelector(matcher, doc, parsedField, docFieldValue);
+  });
+}
 
-    function processKeyValueDocs(metaDoc, kvDocsRes) {
-      var kvDocs = [];
-      var oldKeys = new ExportedSet();
+function matchSelector(matcher, doc, parsedField, docFieldValue) {
+  if (!matcher) {
+    // no filtering necessary; this field is just needed for sorting
+    return true;
+  }
 
-      for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
-        var row = kvDocsRes.rows[i];
-        var doc = row.doc;
-        if (!doc) { // deleted
-          continue;
-        }
-        kvDocs.push(doc);
-        oldKeys.add(doc._id);
-        doc._deleted = !indexableKeysToKeyValues.has(doc._id);
-        if (!doc._deleted) {
-          var keyValue = indexableKeysToKeyValues.get(doc._id);
-          if ('value' in keyValue) {
-            doc.value = keyValue.value;
-          }
-        }
-      }
-      var newKeys = mapToKeysArray(indexableKeysToKeyValues);
-      newKeys.forEach(function (key) {
-        if (!oldKeys.has(key)) {
-          // new doc
-          var kvDoc = {
-            _id: key
-          };
-          var keyValue = indexableKeysToKeyValues.get(key);
-          if ('value' in keyValue) {
-            kvDoc.value = keyValue.value;
-          }
-          kvDocs.push(kvDoc);
-        }
-      });
-      metaDoc.keys = uniq(newKeys.concat(metaDoc.keys));
-      kvDocs.push(metaDoc);
+  return Object.keys(matcher).every(function (userOperator) {
+    var userValue = matcher[userOperator];
+    return match(userOperator, doc, userValue, parsedField, docFieldValue);
+  });
+}
 
-      return kvDocs;
-    }
+function matchCominationalSelector(field, matcher, doc) {
 
-    return getMetaDoc().then(function (metaDoc) {
-      return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
-        return processKeyValueDocs(metaDoc, kvDocsRes);
-      });
+  if (field === '$or') {
+    return matcher.some(function (orMatchers) {
+      return rowFilter(doc, orMatchers, Object.keys(orMatchers));
     });
   }
 
-  // updates all emitted key/value docs and metaDocs in the mrview database
-  // for the given batch of documents from the source database
-  function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
-    var seqDocId = '_local/lastSeq';
-    return view.db.get(seqDocId)
-      .catch(defaultsTo({_id: seqDocId, seq: 0}))
-      .then(function (lastSeqDoc) {
-        var docIds = mapToKeysArray(docIdsToChangesAndEmits);
-        return Promise.all(docIds.map(function (docId) {
-          return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
-        })).then(function (listOfDocsToPersist) {
-          var docsToPersist = flatten(listOfDocsToPersist);
-          lastSeqDoc.seq = seq;
-          docsToPersist.push(lastSeqDoc);
-          // write all docs in a single operation, update the seq once
-          return view.db.bulkDocs({docs : docsToPersist});
-        });
-      });
+  if (field === '$not') {
+    return !rowFilter(doc, matcher, Object.keys(matcher));
   }
 
-  function getQueue(view) {
-    var viewName = typeof view === 'string' ? view : view.name;
-    var queue = persistentQueues[viewName];
-    if (!queue) {
-      queue = persistentQueues[viewName] = new TaskQueue$1();
-    }
-    return queue;
-  }
+  //`$nor`
+  return !matcher.find(function (orMatchers) {
+    return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+  });
 
-  function updateView(view) {
-    return sequentialize(getQueue(view), function () {
-      return updateViewInQueue(view);
-    })();
+}
+
+function match(userOperator, doc, userValue, parsedField, docFieldValue) {
+  if (!matchers[userOperator]) {
+    throw new Error('unknown operator "' + userOperator +
+      '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' +
+      '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all');
   }
+  return matchers[userOperator](doc, userValue, parsedField, docFieldValue);
+}
 
-  function updateViewInQueue(view) {
-    // bind the emit function once
-    var mapResults;
-    var doc;
+function fieldExists(docFieldValue) {
+  return typeof docFieldValue !== 'undefined' && docFieldValue !== null;
+}
 
-    function emit(key, value) {
-      var output = {id: doc._id, key: normalizeKey(key)};
-      // Don't explicitly store the value unless it's defined and non-null.
-      // This saves on storage space, because often people don't use it.
-      if (typeof value !== 'undefined' && value !== null) {
-        output.value = normalizeKey(value);
-      }
-      mapResults.push(output);
-    }
+function fieldIsNotUndefined(docFieldValue) {
+  return typeof docFieldValue !== 'undefined';
+}
 
-    var mapFun = mapper(view.mapFun, emit);
+function modField(docFieldValue, userValue) {
+  var divisor = userValue[0];
+  var mod = userValue[1];
+  if (divisor === 0) {
+    throw new Error('Bad divisor, cannot divide by zero');
+  }
 
-    var currentSeq = view.seq || 0;
+  if (parseInt(divisor, 10) !== divisor ) {
+    throw new Error('Divisor is not an integer');
+  }
 
-    function processChange(docIdsToChangesAndEmits, seq) {
-      return function () {
-        return saveKeyValues(view, docIdsToChangesAndEmits, seq);
-      };
-    }
+  if (parseInt(mod, 10) !== mod ) {
+    throw new Error('Modulus is not an integer');
+  }
 
-    var queue = new TaskQueue$1();
+  if (parseInt(docFieldValue, 10) !== docFieldValue) {
+    return false;
+  }
 
-    function processNextBatch() {
-      return view.sourceDB.changes({
-        return_docs: true,
-        conflicts: true,
-        include_docs: true,
-        style: 'all_docs',
-        since: currentSeq,
-        limit: CHANGES_BATCH_SIZE$1
-      }).then(processBatch);
-    }
+  return docFieldValue % divisor === mod;
+}
 
-    function processBatch(response) {
-      var results = response.results;
-      if (!results.length) {
-        return;
-      }
-      var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results);
-      queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
-      if (results.length < CHANGES_BATCH_SIZE$1) {
-        return;
-      }
-      return processNextBatch();
+function arrayContainsValue(docFieldValue, userValue) {
+  return userValue.some(function (val) {
+    if (docFieldValue instanceof Array) {
+      return docFieldValue.indexOf(val) > -1;
     }
 
-    function createDocIdsToChangesAndEmits(results) {
-      var docIdsToChangesAndEmits = new ExportedMap();
-      for (var i = 0, len = results.length; i < len; i++) {
-        var change = results[i];
-        if (change.doc._id[0] !== '_') {
-          mapResults = [];
-          doc = change.doc;
+    return docFieldValue === val;
+  });
+}
 
-          if (!doc._deleted) {
-            tryMap(view.sourceDB, mapFun, doc);
-          }
-          mapResults.sort(sortByKeyThenValue);
+function arrayContainsAllValues(docFieldValue, userValue) {
+  return userValue.every(function (val) {
+    return docFieldValue.indexOf(val) > -1;
+  });
+}
 
-          var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults);
-          docIdsToChangesAndEmits.set(change.doc._id, [
-            indexableKeysToKeyValues,
-            change.changes
-          ]);
-        }
-        currentSeq = change.seq;
-      }
-      return docIdsToChangesAndEmits;
-    }
+function arraySize(docFieldValue, userValue) {
+  return docFieldValue.length === userValue;
+}
 
-    function createIndexableKeysToKeyValues(mapResults) {
-      var indexableKeysToKeyValues = new ExportedMap();
-      var lastKey;
-      for (var i = 0, len = mapResults.length; i < len; i++) {
-        var emittedKeyValue = mapResults[i];
-        var complexKey = [emittedKeyValue.key, emittedKeyValue.id];
-        if (i > 0 && collate(emittedKeyValue.key, lastKey) === 0) {
-          complexKey.push(i); // dup key+id, so make it unique
-        }
-        indexableKeysToKeyValues.set(toIndexableString(complexKey), emittedKeyValue);
-        lastKey = emittedKeyValue.key;
-      }
-      return indexableKeysToKeyValues;
-    }
+function regexMatch(docFieldValue, userValue) {
+  var re = new RegExp(userValue);
 
-    return processNextBatch().then(function () {
-      return queue.finish();
-    }).then(function () {
-      view.seq = currentSeq;
-    });
-  }
+  return re.test(docFieldValue);
+}
 
-  function reduceView(view, results, options) {
-    if (options.group_level === 0) {
-      delete options.group_level;
-    }
+function typeMatch(docFieldValue, userValue) {
 
-    var shouldGroup = options.group || options.group_level;
+  switch (userValue) {
+    case 'null':
+      return docFieldValue === null;
+    case 'boolean':
+      return typeof (docFieldValue) === 'boolean';
+    case 'number':
+      return typeof (docFieldValue) === 'number';
+    case 'string':
+      return typeof (docFieldValue) === 'string';
+    case 'array':
+      return docFieldValue instanceof Array;
+    case 'object':
+      return ({}).toString.call(docFieldValue) === '[object Object]';
+  }
 
-    var reduceFun = reducer(view.reduceFun);
+  throw new Error(userValue + ' not supported as a type.' +
+                  'Please use one of object, string, array, number, boolean or null.');
 
-    var groups = [];
-    var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
-      options.group_level;
-    results.forEach(function (e) {
-      var last = groups[groups.length - 1];
-      var groupKey = shouldGroup ? e.key : null;
+}
 
-      // only set group_level for array keys
-      if (shouldGroup && Array.isArray(groupKey)) {
-        groupKey = groupKey.slice(0, lvl);
-      }
+var matchers = {
 
-      if (last && collate(last.groupKey, groupKey) === 0) {
-        last.keys.push([e.key, e.id]);
-        last.values.push(e.value);
-        return;
-      }
-      groups.push({
-        keys: [[e.key, e.id]],
-        values: [e.value],
-        groupKey: groupKey
-      });
-    });
-    results = [];
-    for (var i = 0, len = groups.length; i < len; i++) {
-      var e = groups[i];
-      var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false);
-      if (reduceTry.error && reduceTry.error instanceof BuiltInError) {
-        // CouchDB returns an error if a built-in errors out
-        throw reduceTry.error;
-      }
-      results.push({
-        // CouchDB just sets the value to null if a non-built-in errors out
-        value: reduceTry.error ? null : reduceTry.output,
-        key: e.groupKey
-      });
+  '$elemMatch': function (doc, userValue, parsedField, docFieldValue) {
+    if (!Array.isArray(docFieldValue)) {
+      return false;
     }
-    // no total_rows/offset when reducing
-    return {rows: sliceResults(results, options.limit, options.skip)};
-  }
-
-  function queryView(view, opts) {
-    return sequentialize(getQueue(view), function () {
-      return queryViewInQueue(view, opts);
-    })();
-  }
 
-  function queryViewInQueue(view, opts) {
-    var totalRows;
-    var shouldReduce = view.reduceFun && opts.reduce !== false;
-    var skip = opts.skip || 0;
-    if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
-      // equivalent query
-      opts.limit = 0;
-      delete opts.keys;
+    if (docFieldValue.length === 0) {
+      return false;
     }
 
-    function fetchFromView(viewOpts) {
-      viewOpts.include_docs = true;
-      return view.db.allDocs(viewOpts).then(function (res) {
-        totalRows = res.total_rows;
-        return res.rows.map(function (result) {
-
-          // implicit migration - in older versions of PouchDB,
-          // we explicitly stored the doc as {id: ..., key: ..., value: ...}
-          // this is tested in a migration test
-          /* istanbul ignore next */
-          if ('value' in result.doc && typeof result.doc.value === 'object' &&
-            result.doc.value !== null) {
-            var keys = Object.keys(result.doc.value).sort();
-            // this detection method is not perfect, but it's unlikely the user
-            // emitted a value which was an object with these 3 exact keys
-            var expectedKeys = ['id', 'key', 'value'];
-            if (!(keys < expectedKeys || keys > expectedKeys)) {
-              return result.doc.value;
-            }
-          }
-
-          var parsedKeyAndDocId = parseIndexableString(result.doc._id);
-          return {
-            key: parsedKeyAndDocId[0],
-            id: parsedKeyAndDocId[1],
-            value: ('value' in result.doc ? result.doc.value : null)
-          };
-        });
+    if (typeof docFieldValue[0] === 'object') {
+      return docFieldValue.some(function (val) {
+        return rowFilter(val, userValue, Object.keys(userValue));
       });
     }
 
-    function onMapResultsReady(rows) {
-      var finalResults;
-      if (shouldReduce) {
-        finalResults = reduceView(view, rows, opts);
-      } else {
-        finalResults = {
-          total_rows: totalRows,
-          offset: skip,
-          rows: rows
-        };
-      }
-      /* istanbul ignore if */
-      if (opts.update_seq) {
-        finalResults.update_seq = view.seq;
-      }
-      if (opts.include_docs) {
-        var docIds = uniq(rows.map(rowToDocId));
+    return docFieldValue.some(function (val) {
+      return matchSelector(userValue, doc, parsedField, val);
+    });
+  },
 
-        return view.sourceDB.allDocs({
-          keys: docIds,
-          include_docs: true,
-          conflicts: opts.conflicts,
-          attachments: opts.attachments,
-          binary: opts.binary
-        }).then(function (allDocsRes) {
-          var docIdsToDocs = new ExportedMap();
-          allDocsRes.rows.forEach(function (row) {
-            docIdsToDocs.set(row.id, row.doc);
-          });
-          rows.forEach(function (row) {
-            var docId = rowToDocId(row);
-            var doc = docIdsToDocs.get(docId);
-            if (doc) {
-              row.doc = doc;
-            }
-          });
-          return finalResults;
-        });
-      } else {
-        return finalResults;
-      }
+  '$allMatch': function (doc, userValue, parsedField, docFieldValue) {
+    if (!Array.isArray(docFieldValue)) {
+      return false;
     }
 
-    if (typeof opts.keys !== 'undefined') {
-      var keys = opts.keys;
-      var fetchPromises = keys.map(function (key) {
-        var viewOpts = {
-          startkey : toIndexableString([key]),
-          endkey   : toIndexableString([key, {}])
-        };
-        /* istanbul ignore if */
-        if (opts.update_seq) {
-          viewOpts.update_seq = true;
-        }
-        return fetchFromView(viewOpts);
-      });
-      return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady);
-    } else { // normal query, no 'keys'
-      var viewOpts = {
-        descending : opts.descending
-      };
-      /* istanbul ignore if */
-      if (opts.update_seq) {
-        viewOpts.update_seq = true;
-      }
-      var startkey;
-      var endkey;
-      if ('start_key' in opts) {
-        startkey = opts.start_key;
-      }
-      if ('startkey' in opts) {
-        startkey = opts.startkey;
-      }
-      if ('end_key' in opts) {
-        endkey = opts.end_key;
-      }
-      if ('endkey' in opts) {
-        endkey = opts.endkey;
-      }
-      if (typeof startkey !== 'undefined') {
-        viewOpts.startkey = opts.descending ?
-          toIndexableString([startkey, {}]) :
-          toIndexableString([startkey]);
-      }
-      if (typeof endkey !== 'undefined') {
-        var inclusiveEnd = opts.inclusive_end !== false;
-        if (opts.descending) {
-          inclusiveEnd = !inclusiveEnd;
-        }
+    /* istanbul ignore next */
+    if (docFieldValue.length === 0) {
+      return false;
+    }
 
-        viewOpts.endkey = toIndexableString(
-          inclusiveEnd ? [endkey, {}] : [endkey]);
-      }
-      if (typeof opts.key !== 'undefined') {
-        var keyStart = toIndexableString([opts.key]);
-        var keyEnd = toIndexableString([opts.key, {}]);
-        if (viewOpts.descending) {
-          viewOpts.endkey = keyStart;
-          viewOpts.startkey = keyEnd;
-        } else {
-          viewOpts.startkey = keyStart;
-          viewOpts.endkey = keyEnd;
-        }
-      }
-      if (!shouldReduce) {
-        if (typeof opts.limit === 'number') {
-          viewOpts.limit = opts.limit;
-        }
-        viewOpts.skip = skip;
-      }
-      return fetchFromView(viewOpts).then(onMapResultsReady);
+    if (typeof docFieldValue[0] === 'object') {
+      return docFieldValue.every(function (val) {
+        return rowFilter(val, userValue, Object.keys(userValue));
+      });
     }
-  }
 
-  function httpViewCleanup(db) {
-    return db.fetch('_view_cleanup', {
-      headers: new h({'Content-Type': 'application/json'}),
-      method: 'POST'
-    }).then(function (response) {
-      return response.json();
+    return docFieldValue.every(function (val) {
+      return matchSelector(userValue, doc, parsedField, val);
     });
-  }
-
-  function localViewCleanup(db) {
-    return db.get('_local/' + localDocName).then(function (metaDoc) {
-      var docsToViews = new ExportedMap();
-      Object.keys(metaDoc.views).forEach(function (fullViewName) {
-        var parts = parseViewName(fullViewName);
-        var designDocName = '_design/' + parts[0];
-        var viewName = parts[1];
-        var views = docsToViews.get(designDocName);
-        if (!views) {
-          views = new ExportedSet();
-          docsToViews.set(designDocName, views);
-        }
-        views.add(viewName);
-      });
-      var opts = {
-        keys : mapToKeysArray(docsToViews),
-        include_docs : true
-      };
-      return db.allDocs(opts).then(function (res) {
-        var viewsToStatus = {};
-        res.rows.forEach(function (row) {
-          var ddocName = row.key.substring(8); // cuts off '_design/'
-          docsToViews.get(row.key).forEach(function (viewName) {
-            var fullViewName = ddocName + '/' + viewName;
-            /* istanbul ignore if */
-            if (!metaDoc.views[fullViewName]) {
-              // new format, without slashes, to support PouchDB 2.2.0
-              // migration test in pouchdb's browser.migration.js verifies this
-              fullViewName = viewName;
-            }
-            var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
-            // design doc deleted, or view function nonexistent
-            var statusIsGood = row.doc && row.doc.views &&
-              row.doc.views[viewName];
-            viewDBNames.forEach(function (viewDBName) {
-              viewsToStatus[viewDBName] =
-                viewsToStatus[viewDBName] || statusIsGood;
-            });
-          });
-        });
-        var dbsToDelete = Object.keys(viewsToStatus).filter(
-          function (viewDBName) { return !viewsToStatus[viewDBName]; });
-        var destroyPromises = dbsToDelete.map(function (viewDBName) {
-          return sequentialize(getQueue(viewDBName), function () {
-            return new db.constructor(viewDBName, db.__opts).destroy();
-          })();
-        });
-        return Promise.all(destroyPromises).then(function () {
-          return {ok: true};
-        });
-      });
-    }, defaultsTo({ok: true}));
-  }
+  },
 
-  function queryPromised(db, fun, opts) {
-    /* istanbul ignore next */
-    if (typeof db._query === 'function') {
-      return customQuery(db, fun, opts);
-    }
-    if (isRemote(db)) {
-      return httpQuery(db, fun, opts);
-    }
+  '$eq': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) === 0;
+  },
 
-    if (typeof fun !== 'string') {
-      // temp_view
-      checkQueryParseError(opts, fun);
+  '$gte': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) >= 0;
+  },
 
-      tempViewQueue.add(function () {
-        var createViewPromise = createView(
-          /* sourceDB */ db,
-          /* viewName */ 'temp_view/temp_view',
-          /* mapFun */ fun.map,
-          /* reduceFun */ fun.reduce,
-          /* temporary */ true,
-          /* localDocName */ localDocName);
-        return createViewPromise.then(function (view) {
-          return fin(updateView(view).then(function () {
-            return queryView(view, opts);
-          }), function () {
-            return view.db.destroy();
-          });
-        });
-      });
-      return tempViewQueue.finish();
-    } else {
-      // persistent view
-      var fullViewName = fun;
-      var parts = parseViewName(fullViewName);
-      var designDocName = parts[0];
-      var viewName = parts[1];
-      return db.get('_design/' + designDocName).then(function (doc) {
-        var fun = doc.views && doc.views[viewName];
+  '$gt': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) > 0;
+  },
 
-        if (!fun) {
-          // basic validator; it's assumed that every subclass would want this
-          throw new NotFoundError('ddoc ' + doc._id + ' has no view named ' +
-            viewName);
-        }
+  '$lte': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) <= 0;
+  },
 
-        ddocValidator(doc, viewName);
-        checkQueryParseError(opts, fun);
+  '$lt': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) < 0;
+  },
 
-        var createViewPromise = createView(
-          /* sourceDB */ db,
-          /* viewName */ fullViewName,
-          /* mapFun */ fun.map,
-          /* reduceFun */ fun.reduce,
-          /* temporary */ false,
-          /* localDocName */ localDocName);
-        return createViewPromise.then(function (view) {
-          if (opts.stale === 'ok' || opts.stale === 'update_after') {
-            if (opts.stale === 'update_after') {
-              immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-                updateView(view);
-              });
-            }
-            return queryView(view, opts);
-          } else { // stale not ok
-            return updateView(view).then(function () {
-              return queryView(view, opts);
-            });
-          }
-        });
-      });
+  '$exists': function (doc, userValue, parsedField, docFieldValue) {
+    //a field that is null is still considered to exist
+    if (userValue) {
+      return fieldIsNotUndefined(docFieldValue);
     }
-  }
 
-  function abstractQuery(fun, opts, callback) {
-    var db = this;
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = opts ? coerceOptions(opts) : {};
+    return !fieldIsNotUndefined(docFieldValue);
+  },
 
-    if (typeof fun === 'function') {
-      fun = {map : fun};
-    }
+  '$mod': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && modField(docFieldValue, userValue);
+  },
 
-    var promise = Promise.resolve().then(function () {
-      return queryPromised(db, fun, opts);
+  '$ne': function (doc, userValue, parsedField, docFieldValue) {
+    return userValue.every(function (neValue) {
+      return collate(docFieldValue, neValue) !== 0;
     });
-    promisedCallback(promise, callback);
-    return promise;
-  }
-
-  var abstractViewCleanup = callbackify(function () {
-    var db = this;
-    /* istanbul ignore next */
-    if (typeof db._viewCleanup === 'function') {
-      return customViewCleanup(db);
-    }
-    if (isRemote(db)) {
-      return httpViewCleanup(db);
-    }
-    return localViewCleanup(db);
-  });
+  },
+  '$in': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue);
+  },
 
-  return {
-    query: abstractQuery,
-    viewCleanup: abstractViewCleanup
-  };
-}
+  '$nin': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue);
+  },
 
-var builtInReduce = {
-  _sum: function (keys, values) {
-    return sum(values);
+  '$size': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue);
   },
 
-  _count: function (keys, values) {
-    return values.length;
+  '$all': function (doc, userValue, parsedField, docFieldValue) {
+    return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue);
   },
 
-  _stats: function (keys, values) {
-    // no need to implement rereduce=true, because Pouch
-    // will never call it
-    function sumsqr(values) {
-      var _sumsqr = 0;
-      for (var i = 0, len = values.length; i < len; i++) {
-        var num = values[i];
-        _sumsqr += (num * num);
-      }
-      return _sumsqr;
-    }
-    return {
-      sum     : sum(values),
-      min     : Math.min.apply(null, values),
-      max     : Math.max.apply(null, values),
-      count   : values.length,
-      sumsqr : sumsqr(values)
-    };
+  '$regex': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue);
+  },
+
+  '$type': function (doc, userValue, parsedField, docFieldValue) {
+    return typeMatch(docFieldValue, userValue);
   }
 };
 
-function getBuiltIn(reduceFunString) {
-  if (/^_sum/.test(reduceFunString)) {
-    return builtInReduce._sum;
-  } else if (/^_count/.test(reduceFunString)) {
-    return builtInReduce._count;
-  } else if (/^_stats/.test(reduceFunString)) {
-    return builtInReduce._stats;
-  } else if (/^_/.test(reduceFunString)) {
-    throw new Error(reduceFunString + ' is not a supported reduce function.');
+// return true if the given doc matches the supplied selector
+function matchesSelector(doc, selector) {
+  /* istanbul ignore if */
+  if (typeof selector !== 'object') {
+    // match the CouchDB error message
+    throw new Error('Selector error: expected a JSON object');
   }
+
+  selector = massageSelector(selector);
+  var row = {
+    'doc': doc
+  };
+
+  var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector));
+  return rowsMatched && rowsMatched.length === 1;
 }
 
-function mapper(mapFun, emit) {
-  // for temp_views one can use emit(doc, emit), see #38
-  if (typeof mapFun === "function" && mapFun.length === 2) {
-    var origMap = mapFun;
-    return function (doc) {
-      return origMap(doc, emit);
-    };
-  } else {
-    return evalFunctionWithEval(mapFun.toString(), emit);
-  }
+function evalFilter(input) {
+  return scopeEval('"use strict";\nreturn ' + input + ';', {});
 }
 
-function reducer(reduceFun) {
-  var reduceFunString = reduceFun.toString();
-  var builtIn = getBuiltIn(reduceFunString);
-  if (builtIn) {
-    return builtIn;
-  } else {
-    return evalFunctionWithEval(reduceFunString);
+function evalView(input) {
+  var code = [
+    'return function(doc) {',
+    '  "use strict";',
+    '  var emitted = false;',
+    '  var emit = function (a, b) {',
+    '    emitted = true;',
+    '  };',
+    '  var view = ' + input + ';',
+    '  view(doc);',
+    '  if (emitted) {',
+    '    return true;',
+    '  }',
+    '};'
+  ].join('\n');
+
+  return scopeEval(code, {});
+}
+
+function validate(opts, callback) {
+  if (opts.selector) {
+    if (opts.filter && opts.filter !== '_selector') {
+      var filterName = typeof opts.filter === 'string' ?
+        opts.filter : 'function';
+      return callback(new Error('selector invalid for filter "' + filterName + '"'));
+    }
   }
+  callback();
 }
 
-function ddocValidator(ddoc, viewName) {
-  var fun = ddoc.views && ddoc.views[viewName];
-  if (typeof fun.map !== 'string') {
-    throw new NotFoundError('ddoc ' + ddoc._id + ' has no string view named ' +
-      viewName + ', instead found object of type: ' + typeof fun.map);
+function normalize(opts) {
+  if (opts.view && !opts.filter) {
+    opts.filter = '_view';
+  }
+
+  if (opts.selector && !opts.filter) {
+    opts.filter = '_selector';
+  }
+
+  if (opts.filter && typeof opts.filter === 'string') {
+    if (opts.filter === '_view') {
+      opts.view = normalizeDesignDocFunctionName(opts.view);
+    } else {
+      opts.filter = normalizeDesignDocFunctionName(opts.filter);
+    }
   }
 }
 
-var localDocName = 'mrviews';
-var abstract = createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator);
+function shouldFilter(changesHandler, opts) {
+  return opts.filter && typeof opts.filter === 'string' &&
+    !opts.doc_ids && !isRemote(changesHandler.db);
+}
 
-function query(fun, opts, callback) {
-  return abstract.query.call(this, fun, opts, callback);
+function filter(changesHandler, opts) {
+  var callback = opts.complete;
+  if (opts.filter === '_view') {
+    if (!opts.view || typeof opts.view !== 'string') {
+      var err = createError(BAD_REQUEST,
+        '`view` filter parameter not found or invalid.');
+      return callback(err);
+    }
+    // fetch a view from a design doc, make it behave like a filter
+    var viewName = parseDesignDocFunctionName(opts.view);
+    changesHandler.db.get('_design/' + viewName[0], function (err, ddoc) {
+      /* istanbul ignore if */
+      if (changesHandler.isCancelled) {
+        return callback(null, {status: 'cancelled'});
+      }
+      /* istanbul ignore next */
+      if (err) {
+        return callback(generateErrorFromResponse(err));
+      }
+      var mapFun = ddoc && ddoc.views && ddoc.views[viewName[1]] &&
+        ddoc.views[viewName[1]].map;
+      if (!mapFun) {
+        return callback(createError(MISSING_DOC,
+          (ddoc.views ? 'missing json key: ' + viewName[1] :
+            'missing json key: views')));
+      }
+      opts.filter = evalView(mapFun);
+      changesHandler.doChanges(opts);
+    });
+  } else if (opts.selector) {
+    opts.filter = function (doc) {
+      return matchesSelector(doc, opts.selector);
+    };
+    changesHandler.doChanges(opts);
+  } else {
+    // fetch a filter from a design doc
+    var filterName = parseDesignDocFunctionName(opts.filter);
+    changesHandler.db.get('_design/' + filterName[0], function (err, ddoc) {
+      /* istanbul ignore if */
+      if (changesHandler.isCancelled) {
+        return callback(null, {status: 'cancelled'});
+      }
+      /* istanbul ignore next */
+      if (err) {
+        return callback(generateErrorFromResponse(err));
+      }
+      var filterFun = ddoc && ddoc.filters && ddoc.filters[filterName[1]];
+      if (!filterFun) {
+        return callback(createError(MISSING_DOC,
+          ((ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
+            : 'missing json key: filters')));
+      }
+      opts.filter = evalFilter(filterFun);
+      changesHandler.doChanges(opts);
+    });
+  }
 }
 
-function viewCleanup(callback) {
-  return abstract.viewCleanup.call(this, callback);
+function applyChangesFilterPlugin(PouchDB) {
+  PouchDB._changesFilterPlugin = {
+    validate: validate,
+    normalize: normalize,
+    shouldFilter: shouldFilter,
+    filter: filter
+  };
 }
 
-var mapreduce = {
-  query: query,
-  viewCleanup: viewCleanup
-};
+// TODO: remove from pouchdb-core (breaking)
+PouchDB.plugin(applyChangesFilterPlugin);
 
-function isGenOne$1(rev) {
-  return /^1-/.test(rev);
+PouchDB.version = version;
+
+function toObject(array) {
+  return array.reduce(function (obj, item) {
+    obj[item] = true;
+    return obj;
+  }, {});
 }
+// List of top level reserved words for doc
+var reservedWords = toObject([
+  '_id',
+  '_rev',
+  '_attachments',
+  '_deleted',
+  '_revisions',
+  '_revs_info',
+  '_conflicts',
+  '_deleted_conflicts',
+  '_local_seq',
+  '_rev_tree',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats',
+  // Specific to Couchbase Sync Gateway
+  '_removed'
+]);
 
-function fileHasChanged(localDoc, remoteDoc, filename) {
-  return !localDoc._attachments ||
-         !localDoc._attachments[filename] ||
-         localDoc._attachments[filename].digest !== remoteDoc._attachments[filename].digest;
+// List of reserved words that should end up the document
+var dataWords = toObject([
+  '_attachments',
+  //replication documents
+  '_replication_id',
+  '_replication_state',
+  '_replication_state_time',
+  '_replication_state_reason',
+  '_replication_stats'
+]);
+
+function parseRevisionInfo(rev) {
+  if (!/^\d+-./.test(rev)) {
+    return createError(INVALID_REV);
+  }
+  var idx = rev.indexOf('-');
+  var left = rev.substring(0, idx);
+  var right = rev.substring(idx + 1);
+  return {
+    prefix: parseInt(left, 10),
+    id: right
+  };
 }
 
-function getDocAttachments(db, doc) {
-  var filenames = Object.keys(doc._attachments);
-  return Promise.all(filenames.map(function (filename) {
-    return db.getAttachment(doc._id, filename, {rev: doc._rev});
-  }));
+function makeRevTreeFromRevisions(revisions, opts) {
+  var pos = revisions.start - revisions.ids.length + 1;
+
+  var revisionIds = revisions.ids;
+  var ids = [revisionIds[0], opts, []];
+
+  for (var i = 1, len = revisionIds.length; i < len; i++) {
+    ids = [revisionIds[i], {status: 'missing'}, [ids]];
+  }
+
+  return [{
+    pos: pos,
+    ids: ids
+  }];
 }
 
-function getDocAttachmentsFromTargetOrSource(target, src, doc) {
-  var doCheckForLocalAttachments = isRemote(src) && !isRemote(target);
-  var filenames = Object.keys(doc._attachments);
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits, dbOpts) {
+  if (!dbOpts) {
+    dbOpts = {
+      deterministic_revs: true
+    };
+  }
 
-  if (!doCheckForLocalAttachments) {
-    return getDocAttachments(src, doc);
+  var nRevNum;
+  var newRevId;
+  var revInfo;
+  var opts = {status: 'available'};
+  if (doc._deleted) {
+    opts.deleted = true;
   }
 
-  return target.get(doc._id).then(function (localDoc) {
-    return Promise.all(filenames.map(function (filename) {
-      if (fileHasChanged(localDoc, doc, filename)) {
-        return src.getAttachment(doc._id, filename);
+  if (newEdits) {
+    if (!doc._id) {
+      doc._id = uuid();
+    }
+    newRevId = rev$$1(doc, dbOpts.deterministic_revs);
+    if (doc._rev) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
+      }
+      doc._rev_tree = [{
+        pos: revInfo.prefix,
+        ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+      }];
+      nRevNum = revInfo.prefix + 1;
+    } else {
+      doc._rev_tree = [{
+        pos: 1,
+        ids : [newRevId, opts, []]
+      }];
+      nRevNum = 1;
+    }
+  } else {
+    if (doc._revisions) {
+      doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+      nRevNum = doc._revisions.start;
+      newRevId = doc._revisions.ids[0];
+    }
+    if (!doc._rev_tree) {
+      revInfo = parseRevisionInfo(doc._rev);
+      if (revInfo.error) {
+        return revInfo;
       }
+      nRevNum = revInfo.prefix;
+      newRevId = revInfo.id;
+      doc._rev_tree = [{
+        pos: nRevNum,
+        ids: [newRevId, opts, []]
+      }];
+    }
+  }
 
-      return target.getAttachment(localDoc._id, filename);
-    }));
-  }).catch(function (error) {
-    /* istanbul ignore if */
-    if (error.status !== 404) {
-      throw error;
+  invalidIdError(doc._id);
+
+  doc._rev = nRevNum + '-' + newRevId;
+
+  var result = {metadata : {}, data : {}};
+  for (var key in doc) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(doc, key)) {
+      var specialKey = key[0] === '_';
+      if (specialKey && !reservedWords[key]) {
+        var error = createError(DOC_VALIDATION, key);
+        error.message = DOC_VALIDATION.message + ': ' + key;
+        throw error;
+      } else if (specialKey && !dataWords[key]) {
+        result.metadata[key.slice(1)] = doc[key];
+      } else {
+        result.data[key] = doc[key];
+      }
     }
+  }
+  return result;
+}
 
-    return getDocAttachments(src, doc);
+function parseBase64(data) {
+  try {
+    return thisAtob(data);
+  } catch (e) {
+    var err = createError(BAD_ARG,
+      'Attachment is not a valid base64 string');
+    return {error: err};
+  }
+}
+
+function preprocessString(att, blobType, callback) {
+  var asBinary = parseBase64(att.data);
+  if (asBinary.error) {
+    return callback(asBinary.error);
+  }
+
+  att.length = asBinary.length;
+  if (blobType === 'blob') {
+    att.data = binStringToBluffer(asBinary, att.content_type);
+  } else if (blobType === 'base64') {
+    att.data = thisBtoa(asBinary);
+  } else { // binary
+    att.data = asBinary;
+  }
+  binaryMd5(asBinary, function (result) {
+    att.digest = 'md5-' + result;
+    callback();
   });
 }
 
-function createBulkGetOpts(diffs) {
-  var requests = [];
-  Object.keys(diffs).forEach(function (id) {
-    var missingRevs = diffs[id].missing;
-    missingRevs.forEach(function (missingRev) {
-      requests.push({
-        id: id,
-        rev: missingRev
+function preprocessBlob(att, blobType, callback) {
+  binaryMd5(att.data, function (md5) {
+    att.digest = 'md5-' + md5;
+    // size is for blobs (browser), length is for buffers (node)
+    att.length = att.data.size || att.data.length || 0;
+    if (blobType === 'binary') {
+      blobToBinaryString(att.data, function (binString) {
+        att.data = binString;
+        callback();
       });
-    });
+    } else if (blobType === 'base64') {
+      blobToBase64(att.data, function (b64) {
+        att.data = b64;
+        callback();
+      });
+    } else {
+      callback();
+    }
   });
+}
 
-  return {
-    docs: requests,
-    revs: true,
-    latest: true
-  };
+function preprocessAttachment(att, blobType, callback) {
+  if (att.stub) {
+    return callback();
+  }
+  if (typeof att.data === 'string') { // input is a base64 string
+    preprocessString(att, blobType, callback);
+  } else { // input is a blob
+    preprocessBlob(att, blobType, callback);
+  }
 }
 
-//
-// Fetch all the documents from the src as described in the "diffs",
-// which is a mapping of docs IDs to revisions. If the state ever
-// changes to "cancelled", then the returned promise will be rejected.
-// Else it will be resolved with a list of fetched documents.
-//
-function getDocs(src, target, diffs, state) {
-  diffs = clone(diffs); // we do not need to modify this
+function preprocessAttachments(docInfos, blobType, callback) {
 
-  var resultDocs = [],
-      ok = true;
+  if (!docInfos.length) {
+    return callback();
+  }
 
-  function getAllDocs() {
+  var docv = 0;
+  var overallErr;
 
-    var bulkGetOpts = createBulkGetOpts(diffs);
+  docInfos.forEach(function (docInfo) {
+    var attachments = docInfo.data && docInfo.data._attachments ?
+      Object.keys(docInfo.data._attachments) : [];
+    var recv = 0;
 
-    if (!bulkGetOpts.docs.length) { // optimization: skip empty requests
-      return;
+    if (!attachments.length) {
+      return done();
     }
 
-    return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) {
-      /* istanbul ignore if */
-      if (state.cancelled) {
-        throw new Error('cancelled');
+    function processedAttachment(err) {
+      overallErr = err;
+      recv++;
+      if (recv === attachments.length) {
+        done();
       }
-      return Promise.all(bulkGetResponse.results.map(function (bulkGetInfo) {
-        return Promise.all(bulkGetInfo.docs.map(function (doc) {
-          var remoteDoc = doc.ok;
-
-          if (doc.error) {
-            // when AUTO_COMPACTION is set, docs can be returned which look
-            // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"}
-            ok = false;
-          }
+    }
 
-          if (!remoteDoc || !remoteDoc._attachments) {
-            return remoteDoc;
-          }
+    for (var key in docInfo.data._attachments) {
+      if (docInfo.data._attachments.hasOwnProperty(key)) {
+        preprocessAttachment(docInfo.data._attachments[key],
+          blobType, processedAttachment);
+      }
+    }
+  });
 
-          return getDocAttachmentsFromTargetOrSource(target, src, remoteDoc)
-                   .then(function (attachments) {
-                           var filenames = Object.keys(remoteDoc._attachments);
-                           attachments
-                             .forEach(function (attachment, i) {
-                                        var att = remoteDoc._attachments[filenames[i]];
-                                        delete att.stub;
-                                        delete att.length;
-                                        att.data = attachment;
-                                      });
+  function done() {
+    docv++;
+    if (docInfos.length === docv) {
+      if (overallErr) {
+        callback(overallErr);
+      } else {
+        callback();
+      }
+    }
+  }
+}
 
-                                      return remoteDoc;
-                                    });
-        }));
-      }))
+function updateDoc(revLimit, prev, docInfo, results,
+                   i, cb, writeDoc, newEdits) {
 
-      .then(function (results) {
-        resultDocs = resultDocs.concat(flatten(results).filter(Boolean));
-      });
-    });
+  if (revExists(prev.rev_tree, docInfo.metadata.rev) && !newEdits) {
+    results[i] = docInfo;
+    return cb();
   }
 
-  function hasAttachments(doc) {
-    return doc._attachments && Object.keys(doc._attachments).length > 0;
-  }
+  // sometimes this is pre-calculated. historically not always
+  var previousWinningRev = prev.winningRev || winningRev(prev);
+  var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+    isDeleted(prev, previousWinningRev);
+  var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+    isDeleted(docInfo.metadata);
+  var isRoot = /^1-/.test(docInfo.metadata.rev);
 
-  function hasConflicts(doc) {
-    return doc._conflicts && doc._conflicts.length > 0;
+  if (previouslyDeleted && !deleted && newEdits && isRoot) {
+    var newDoc = docInfo.data;
+    newDoc._rev = previousWinningRev;
+    newDoc._id = docInfo.metadata.id;
+    docInfo = parseDoc(newDoc, newEdits);
   }
 
-  function fetchRevisionOneDocs(ids) {
-    // Optimization: fetch gen-1 docs and attachments in
-    // a single request using _all_docs
-    return src.allDocs({
-      keys: ids,
-      include_docs: true,
-      conflicts: true
-    }).then(function (res) {
-      if (state.cancelled) {
-        throw new Error('cancelled');
-      }
-      res.rows.forEach(function (row) {
-        if (row.deleted || !row.doc || !isGenOne$1(row.value.rev) ||
-            hasAttachments(row.doc) || hasConflicts(row.doc)) {
-          // if any of these conditions apply, we need to fetch using get()
-          return;
-        }
+  var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
 
-        // strip _conflicts array to appease CSG (#5793)
-        /* istanbul ignore if */
-        if (row.doc._conflicts) {
-          delete row.doc._conflicts;
-        }
+  var inConflict = newEdits && ((
+    (previouslyDeleted && deleted && merged.conflicts !== 'new_leaf') ||
+    (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+    (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
 
-        // the doc we got back from allDocs() is sufficient
-        resultDocs.push(row.doc);
-        delete diffs[row.id];
-      });
-    });
+  if (inConflict) {
+    var err = createError(REV_CONFLICT);
+    results[i] = err;
+    return cb();
   }
 
-  function getRevisionOneDocs() {
-    // filter out the generation 1 docs and get them
-    // leaving the non-generation one docs to be got otherwise
-    var ids = Object.keys(diffs).filter(function (id) {
-      var missing = diffs[id].missing;
-      return missing.length === 1 && isGenOne$1(missing[0]);
-    });
-    if (ids.length > 0) {
-      return fetchRevisionOneDocs(ids);
-    }
+  var newRev = docInfo.metadata.rev;
+  docInfo.metadata.rev_tree = merged.tree;
+  docInfo.stemmedRevs = merged.stemmedRevs || [];
+  /* istanbul ignore else */
+  if (prev.rev_map) {
+    docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
   }
 
-  function returnResult() {
-    return { ok:ok, docs:resultDocs };
+  // recalculate
+  var winningRev$$1 = winningRev(docInfo.metadata);
+  var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$1);
+
+  // calculate the total number of documents that were added/removed,
+  // from the perspective of total_rows/doc_count
+  var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+    previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+  var newRevIsDeleted;
+  if (newRev === winningRev$$1) {
+    // if the new rev is the same as the winning rev, we can reuse that value
+    newRevIsDeleted = winningRevIsDeleted;
+  } else {
+    // if they're not the same, then we need to recalculate
+    newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
   }
 
-  return Promise.resolve()
-    .then(getRevisionOneDocs)
-    .then(getAllDocs)
-    .then(returnResult);
+  writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
+    true, delta, i, cb);
 }
 
-var CHECKPOINT_VERSION = 1;
-var REPLICATOR = "pouchdb";
-// This is an arbitrary number to limit the
-// amount of replication history we save in the checkpoint.
-// If we save too much, the checkpoing docs will become very big,
-// if we save fewer, we'll run a greater risk of having to
-// read all the changes from 0 when checkpoint PUTs fail
-// CouchDB 2.0 has a more involved history pruning,
-// but let's go for the simple version for now.
-var CHECKPOINT_HISTORY_SIZE = 5;
-var LOWEST_SEQ = 0;
+function rootIsMissing(docInfo) {
+  return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
 
-function updateCheckpoint(db, id, checkpoint, session, returnValue) {
-  return db.get(id).catch(function (err) {
-    if (err.status === 404) {
-      if (db.adapter === 'http' || db.adapter === 'https') {
-        explainError(
-          404, 'PouchDB is just checking if a remote checkpoint exists.'
-        );
-      }
-      return {
-        session_id: session,
-        _id: id,
-        history: [],
-        replicator: REPLICATOR,
-        version: CHECKPOINT_VERSION
-      };
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+                     writeDoc, opts, overallCallback) {
+
+  // Default to 1000 locally
+  revLimit = revLimit || 1000;
+
+  function insertDoc(docInfo, resultsIdx, callback) {
+    // Cant insert new deleted documents
+    var winningRev$$1 = winningRev(docInfo.metadata);
+    var deleted = isDeleted(docInfo.metadata, winningRev$$1);
+    if ('was_delete' in opts && deleted) {
+      results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+      return callback();
     }
-    throw err;
-  }).then(function (doc) {
-    if (returnValue.cancelled) {
-      return;
+
+    // 4712 - detect whether a new document was inserted with a _rev
+    var inConflict = newEdits && rootIsMissing(docInfo);
+
+    if (inConflict) {
+      var err = createError(REV_CONFLICT);
+      results[resultsIdx] = err;
+      return callback();
     }
 
-    // if the checkpoint has not changed, do not update
-    if (doc.last_seq === checkpoint) {
-      return;
+    var delta = deleted ? 0 : 1;
+
+    writeDoc(docInfo, winningRev$$1, deleted, deleted, false,
+      delta, resultsIdx, callback);
+  }
+
+  var newEdits = opts.new_edits;
+  var idsToDocs = new ExportedMap();
+
+  var docsDone = 0;
+  var docsToDo = docInfos.length;
+
+  function checkAllDocsDone() {
+    if (++docsDone === docsToDo && overallCallback) {
+      overallCallback();
     }
+  }
 
-    // Filter out current entry for this replication
-    doc.history = (doc.history || []).filter(function (item) {
-      return item.session_id !== session;
-    });
+  docInfos.forEach(function (currentDoc, resultsIdx) {
 
-    // Add the latest checkpoint to history
-    doc.history.unshift({
-      last_seq: checkpoint,
-      session_id: session
-    });
+    if (currentDoc._id && isLocalId(currentDoc._id)) {
+      var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+      api[fun](currentDoc, {ctx: tx}, function (err, res) {
+        results[resultsIdx] = err || res;
+        checkAllDocsDone();
+      });
+      return;
+    }
 
-    // Just take the last pieces in history, to
-    // avoid really big checkpoint docs.
-    // see comment on history size above
-    doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE);
+    var id = currentDoc.metadata.id;
+    if (idsToDocs.has(id)) {
+      docsToDo--; // duplicate
+      idsToDocs.get(id).push([currentDoc, resultsIdx]);
+    } else {
+      idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+    }
+  });
 
-    doc.version = CHECKPOINT_VERSION;
-    doc.replicator = REPLICATOR;
+  // in the case of new_edits, the user can provide multiple docs
+  // with the same id. these need to be processed sequentially
+  idsToDocs.forEach(function (docs, id) {
+    var numDone = 0;
 
-    doc.session_id = session;
-    doc.last_seq = checkpoint;
+    function docWritten() {
+      if (++numDone < docs.length) {
+        nextDoc();
+      } else {
+        checkAllDocsDone();
+      }
+    }
+    function nextDoc() {
+      var value = docs[numDone];
+      var currentDoc = value[0];
+      var resultsIdx = value[1];
 
-    return db.put(doc).catch(function (err) {
-      if (err.status === 409) {
-        // retry; someone is trying to write a checkpoint simultaneously
-        return updateCheckpoint(db, id, checkpoint, session, returnValue);
+      if (fetchedDocs.has(id)) {
+        updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+          resultsIdx, docWritten, writeDoc, newEdits);
+      } else {
+        // Ensure stemming applies to new writes as well
+        var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+        currentDoc.metadata.rev_tree = merged.tree;
+        currentDoc.stemmedRevs = merged.stemmedRevs || [];
+        insertDoc(currentDoc, resultsIdx, docWritten);
       }
-      throw err;
-    });
+    }
+    nextDoc();
   });
 }
 
-function Checkpointer(src, target, id, returnValue, opts) {
-  this.src = src;
-  this.target = target;
-  this.id = id;
-  this.returnValue = returnValue;
-  this.opts = opts || {};
-}
+// IndexedDB requires a versioned database structure, so we use the
+// version here to manage migrations.
+var ADAPTER_VERSION = 5;
 
-Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) {
-  var self = this;
-  return this.updateTarget(checkpoint, session).then(function () {
-    return self.updateSource(checkpoint, session);
-  });
-};
+// The object stores created for each database
+// DOC_STORE stores the document meta data, its revision history and state
+// Keyed by document id
+var DOC_STORE = 'document-store';
+// BY_SEQ_STORE stores a particular version of a document, keyed by its
+// sequence id
+var BY_SEQ_STORE = 'by-sequence';
+// Where we store attachments
+var ATTACH_STORE = 'attach-store';
+// Where we store many-to-many relations
+// between attachment digests and seqs
+var ATTACH_AND_SEQ_STORE = 'attach-seq-store';
 
-Checkpointer.prototype.updateTarget = function (checkpoint, session) {
-  if (this.opts.writeTargetCheckpoint) {
-    return updateCheckpoint(this.target, this.id, checkpoint,
-      session, this.returnValue);
-  } else {
-    return Promise.resolve(true);
+// Where we store database-wide meta data in a single record
+// keyed by id: META_STORE
+var META_STORE = 'meta-store';
+// Where we store local documents
+var LOCAL_STORE = 'local-store';
+// Where we detect blob support
+var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
+
+function safeJsonParse(str) {
+  // This try/catch guards against stack overflow errors.
+  // JSON.parse() is faster than vuvuzela.parse() but vuvuzela
+  // cannot overflow.
+  try {
+    return JSON.parse(str);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.parse(str);
   }
-};
+}
 
-Checkpointer.prototype.updateSource = function (checkpoint, session) {
-  if (this.opts.writeSourceCheckpoint) {
-    var self = this;
-    return updateCheckpoint(this.src, this.id, checkpoint,
-      session, this.returnValue)
-      .catch(function (err) {
-        if (isForbiddenError(err)) {
-          self.opts.writeSourceCheckpoint = false;
-          return true;
-        }
-        throw err;
-      });
-  } else {
-    return Promise.resolve(true);
+function safeJsonStringify(json) {
+  try {
+    return JSON.stringify(json);
+  } catch (e) {
+    /* istanbul ignore next */
+    return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.stringify(json);
   }
-};
+}
 
-var comparisons = {
-  "undefined": function (targetDoc, sourceDoc) {
-    // This is the previous comparison function
-    if (collate(targetDoc.last_seq, sourceDoc.last_seq) === 0) {
-      return sourceDoc.last_seq;
+function idbError(callback) {
+  return function (evt) {
+    var message = 'unknown_error';
+    if (evt.target && evt.target.error) {
+      message = evt.target.error.name || evt.target.error.message;
     }
-    /* istanbul ignore next */
-    return 0;
-  },
-  "1": function (targetDoc, sourceDoc) {
-    // This is the comparison function ported from CouchDB
-    return compareReplicationLogs(sourceDoc, targetDoc).last_seq;
+    callback(createError(IDB_ERROR, message, evt.type));
+  };
+}
+
+// Unfortunately, the metadata has to be stringified
+// when it is put into the database, because otherwise
+// IndexedDB can throw errors for deeply-nested objects.
+// Originally we just used JSON.parse/JSON.stringify; now
+// we use this custom vuvuzela library that avoids recursion.
+// If we could do it all over again, we'd probably use a
+// format for the revision trees other than JSON.
+function encodeMetadata(metadata, winningRev, deleted) {
+  return {
+    data: safeJsonStringify(metadata),
+    winningRev: winningRev,
+    deletedOrLocal: deleted ? '1' : '0',
+    seq: metadata.seq, // highest seq for this doc
+    id: metadata.id
+  };
+}
+
+function decodeMetadata(storedObject) {
+  if (!storedObject) {
+    return null;
   }
-};
+  var metadata = safeJsonParse(storedObject.data);
+  metadata.winningRev = storedObject.winningRev;
+  metadata.deleted = storedObject.deletedOrLocal === '1';
+  metadata.seq = storedObject.seq;
+  return metadata;
+}
 
-Checkpointer.prototype.getCheckpoint = function () {
-  var self = this;
+// read the doc back out from the database. we don't store the
+// _id or _rev because we already have _doc_id_rev.
+function decodeDoc(doc) {
+  if (!doc) {
+    return doc;
+  }
+  var idx = doc._doc_id_rev.lastIndexOf(':');
+  doc._id = doc._doc_id_rev.substring(0, idx - 1);
+  doc._rev = doc._doc_id_rev.substring(idx + 1);
+  delete doc._doc_id_rev;
+  return doc;
+}
 
-  if (self.opts && self.opts.writeSourceCheckpoint && !self.opts.writeTargetCheckpoint) {
-    return self.src.get(self.id).then(function (sourceDoc) {
-      return sourceDoc.last_seq || LOWEST_SEQ;
-    }).catch(function (err) {
-      /* istanbul ignore if */
-      if (err.status !== 404) {
-        throw err;
-      }
-      return LOWEST_SEQ;
-    });
+// Read a blob from the database, encoding as necessary
+// and translating from base64 if the IDB doesn't support
+// native Blobs
+function readBlobData(body, type, asBlob, callback) {
+  if (asBlob) {
+    if (!body) {
+      callback(createBlob([''], {type: type}));
+    } else if (typeof body !== 'string') { // we have blob support
+      callback(body);
+    } else { // no blob support
+      callback(b64ToBluffer(body, type));
+    }
+  } else { // as base64 string
+    if (!body) {
+      callback('');
+    } else if (typeof body !== 'string') { // we have blob support
+      readAsBinaryString(body, function (binary) {
+        callback(thisBtoa(binary));
+      });
+    } else { // no blob support
+      callback(body);
+    }
   }
+}
 
-  return self.target.get(self.id).then(function (targetDoc) {
-    if (self.opts && self.opts.writeTargetCheckpoint && !self.opts.writeSourceCheckpoint) {
-      return targetDoc.last_seq || LOWEST_SEQ;
+function fetchAttachmentsIfNecessary(doc, opts, txn, cb) {
+  var attachments = Object.keys(doc._attachments || {});
+  if (!attachments.length) {
+    return cb && cb();
+  }
+  var numDone = 0;
+
+  function checkDone() {
+    if (++numDone === attachments.length && cb) {
+      cb();
     }
+  }
 
-    return self.src.get(self.id).then(function (sourceDoc) {
-      // Since we can't migrate an old version doc to a new one
-      // (no session id), we just go with the lowest seq in this case
-      /* istanbul ignore if */
-      if (targetDoc.version !== sourceDoc.version) {
-        return LOWEST_SEQ;
-      }
+  function fetchAttachment(doc, att) {
+    var attObj = doc._attachments[att];
+    var digest = attObj.digest;
+    var req = txn.objectStore(ATTACH_STORE).get(digest);
+    req.onsuccess = function (e) {
+      attObj.body = e.target.result.body;
+      checkDone();
+    };
+  }
 
-      var version;
-      if (targetDoc.version) {
-        version = targetDoc.version.toString();
-      } else {
-        version = "undefined";
-      }
+  attachments.forEach(function (att) {
+    if (opts.attachments && opts.include_docs) {
+      fetchAttachment(doc, att);
+    } else {
+      doc._attachments[att].stub = true;
+      checkDone();
+    }
+  });
+}
 
-      if (version in comparisons) {
-        return comparisons[version](targetDoc, sourceDoc);
-      }
-      /* istanbul ignore next */
-      return LOWEST_SEQ;
-    }, function (err) {
-      if (err.status === 404 && targetDoc.last_seq) {
-        return self.src.put({
-          _id: self.id,
-          last_seq: LOWEST_SEQ
-        }).then(function () {
-          return LOWEST_SEQ;
-        }, function (err) {
-          if (isForbiddenError(err)) {
-            self.opts.writeSourceCheckpoint = false;
-            return targetDoc.last_seq;
-          }
-          /* istanbul ignore next */
-          return LOWEST_SEQ;
+// IDB-specific postprocessing necessary because
+// we don't know whether we stored a true Blob or
+// a base64-encoded string, and if it's a Blob it
+// needs to be read outside of the transaction context
+function postProcessAttachments(results, asBlob) {
+  return Promise.all(results.map(function (row) {
+    if (row.doc && row.doc._attachments) {
+      var attNames = Object.keys(row.doc._attachments);
+      return Promise.all(attNames.map(function (att) {
+        var attObj = row.doc._attachments[att];
+        if (!('body' in attObj)) { // already processed
+          return;
+        }
+        var body = attObj.body;
+        var type = attObj.content_type;
+        return new Promise(function (resolve) {
+          readBlobData(body, type, asBlob, function (data) {
+            row.doc._attachments[att] = $inject_Object_assign(
+              pick(attObj, ['digest', 'content_type']),
+              {data: data}
+            );
+            resolve();
+          });
         });
-      }
-      throw err;
-    });
-  }).catch(function (err) {
-    if (err.status !== 404) {
-      throw err;
+      }));
+    }
+  }));
+}
+
+function compactRevs(revs, docId, txn) {
+
+  var possiblyOrphanedDigests = [];
+  var seqStore = txn.objectStore(BY_SEQ_STORE);
+  var attStore = txn.objectStore(ATTACH_STORE);
+  var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+  var count = revs.length;
+
+  function checkDone() {
+    count--;
+    if (!count) { // done processing all revs
+      deleteOrphanedAttachments();
     }
-    return LOWEST_SEQ;
-  });
-};
-// This checkpoint comparison is ported from CouchDBs source
-// they come from here:
-// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906
+  }
 
-function compareReplicationLogs(srcDoc, tgtDoc) {
-  if (srcDoc.session_id === tgtDoc.session_id) {
-    return {
-      last_seq: srcDoc.last_seq,
-      history: srcDoc.history
-    };
+  function deleteOrphanedAttachments() {
+    if (!possiblyOrphanedDigests.length) {
+      return;
+    }
+    possiblyOrphanedDigests.forEach(function (digest) {
+      var countReq = attAndSeqStore.index('digestSeq').count(
+        IDBKeyRange.bound(
+          digest + '::', digest + '::\uffff', false, false));
+      countReq.onsuccess = function (e) {
+        var count = e.target.result;
+        if (!count) {
+          // orphaned
+          attStore.delete(digest);
+        }
+      };
+    });
   }
 
-  return compareReplicationHistory(srcDoc.history, tgtDoc.history);
-}
+  revs.forEach(function (rev) {
+    var index = seqStore.index('_doc_id_rev');
+    var key = docId + "::" + rev;
+    index.getKey(key).onsuccess = function (e) {
+      var seq = e.target.result;
+      if (typeof seq !== 'number') {
+        return checkDone();
+      }
+      seqStore.delete(seq);
 
-function compareReplicationHistory(sourceHistory, targetHistory) {
-  // the erlang loop via function arguments is not so easy to repeat in JS
-  // therefore, doing this as recursion
-  var S = sourceHistory[0];
-  var sourceRest = sourceHistory.slice(1);
-  var T = targetHistory[0];
-  var targetRest = targetHistory.slice(1);
+      var cursor = attAndSeqStore.index('seq')
+        .openCursor(IDBKeyRange.only(seq));
 
-  if (!S || targetHistory.length === 0) {
-    return {
-      last_seq: LOWEST_SEQ,
-      history: []
+      cursor.onsuccess = function (event) {
+        var cursor = event.target.result;
+        if (cursor) {
+          var digest = cursor.value.digestSeq.split('::')[0];
+          possiblyOrphanedDigests.push(digest);
+          attAndSeqStore.delete(cursor.primaryKey);
+          cursor.continue();
+        } else { // done
+          checkDone();
+        }
+      };
     };
-  }
+  });
+}
 
-  var sourceId = S.session_id;
-  /* istanbul ignore if */
-  if (hasSessionId(sourceId, targetHistory)) {
+function openTransactionSafely(idb, stores, mode) {
+  try {
     return {
-      last_seq: S.last_seq,
-      history: sourceHistory
+      txn: idb.transaction(stores, mode)
     };
-  }
-
-  var targetId = T.session_id;
-  if (hasSessionId(targetId, sourceRest)) {
+  } catch (err) {
     return {
-      last_seq: T.last_seq,
-      history: targetRest
+      error: err
     };
   }
-
-  return compareReplicationHistory(sourceRest, targetRest);
 }
 
-function hasSessionId(sessionId, history) {
-  var props = history[0];
-  var rest = history.slice(1);
+var changesHandler = new Changes();
 
-  if (!sessionId || history.length === 0) {
-    return false;
-  }
+function idbBulkDocs(dbOpts, req, opts, api, idb, callback) {
+  var docInfos = req.docs;
+  var txn;
+  var docStore;
+  var bySeqStore;
+  var attachStore;
+  var attachAndSeqStore;
+  var metaStore;
+  var docInfoError;
+  var metaDoc;
 
-  if (sessionId === props.session_id) {
-    return true;
+  for (var i = 0, len = docInfos.length; i < len; i++) {
+    var doc = docInfos[i];
+    if (doc._id && isLocalId(doc._id)) {
+      continue;
+    }
+    doc = docInfos[i] = parseDoc(doc, opts.new_edits, dbOpts);
+    if (doc.error && !docInfoError) {
+      docInfoError = doc;
+    }
   }
 
-  return hasSessionId(sessionId, rest);
-}
-
-function isForbiddenError(err) {
-  return typeof err.status === 'number' && Math.floor(err.status / 100) === 4;
-}
+  if (docInfoError) {
+    return callback(docInfoError);
+  }
 
-var STARTING_BACK_OFF = 0;
+  var allDocsProcessed = false;
+  var docCountDelta = 0;
+  var results = new Array(docInfos.length);
+  var fetchedDocs = new ExportedMap();
+  var preconditionErrored = false;
+  var blobType = api._meta.blobSupport ? 'blob' : 'base64';
 
-function backOff(opts, returnValue, error, callback) {
-  if (opts.retry === false) {
-    returnValue.emit('error', error);
-    returnValue.removeAllListeners();
-    return;
-  }
-  /* istanbul ignore if */
-  if (typeof opts.back_off_function !== 'function') {
-    opts.back_off_function = defaultBackOff;
-  }
-  returnValue.emit('requestError', error);
-  if (returnValue.state === 'active' || returnValue.state === 'pending') {
-    returnValue.emit('paused', error);
-    returnValue.state = 'stopped';
-    var backOffSet = function backoffTimeSet() {
-      opts.current_back_off = STARTING_BACK_OFF;
-    };
-    var removeBackOffSetter = function removeBackOffTimeSet() {
-      returnValue.removeListener('active', backOffSet);
-    };
-    returnValue.once('paused', removeBackOffSetter);
-    returnValue.once('active', backOffSet);
-  }
+  preprocessAttachments(docInfos, blobType, function (err) {
+    if (err) {
+      return callback(err);
+    }
+    startTransaction();
+  });
 
-  opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF;
-  opts.current_back_off = opts.back_off_function(opts.current_back_off);
-  setTimeout(callback, opts.current_back_off);
-}
+  function startTransaction() {
 
-function sortObjectPropertiesByKey(queryParams) {
-  return Object.keys(queryParams).sort(collate).reduce(function (result, key) {
-    result[key] = queryParams[key];
-    return result;
-  }, {});
-}
+    var stores = [
+      DOC_STORE, BY_SEQ_STORE,
+      ATTACH_STORE,
+      LOCAL_STORE, ATTACH_AND_SEQ_STORE,
+      META_STORE
+    ];
+    var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    txn = txnResult.txn;
+    txn.onabort = idbError(callback);
+    txn.ontimeout = idbError(callback);
+    txn.oncomplete = complete;
+    docStore = txn.objectStore(DOC_STORE);
+    bySeqStore = txn.objectStore(BY_SEQ_STORE);
+    attachStore = txn.objectStore(ATTACH_STORE);
+    attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+    metaStore = txn.objectStore(META_STORE);
 
-// Generate a unique id particular to this replication.
-// Not guaranteed to align perfectly with CouchDB's rep ids.
-function generateReplicationId(src, target, opts) {
-  var docIds = opts.doc_ids ? opts.doc_ids.sort(collate) : '';
-  var filterFun = opts.filter ? opts.filter.toString() : '';
-  var queryParams = '';
-  var filterViewName =  '';
-  var selector = '';
+    metaStore.get(META_STORE).onsuccess = function (e) {
+      metaDoc = e.target.result;
+      updateDocCountIfReady();
+    };
 
-  // possibility for checkpoints to be lost here as behaviour of
-  // JSON.stringify is not stable (see #6226)
-  /* istanbul ignore if */
-  if (opts.selector) {
-    selector = JSON.stringify(opts.selector);
+    verifyAttachments(function (err) {
+      if (err) {
+        preconditionErrored = true;
+        return callback(err);
+      }
+      fetchExistingDocs();
+    });
   }
 
-  if (opts.filter && opts.query_params) {
-    queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params));
+  function onAllDocsProcessed() {
+    allDocsProcessed = true;
+    updateDocCountIfReady();
   }
 
-  if (opts.filter && opts.filter === '_view') {
-    filterViewName = opts.view.toString();
+  function idbProcessDocs() {
+    processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs,
+                txn, results, writeDoc, opts, onAllDocsProcessed);
   }
 
-  return Promise.all([src.id(), target.id()]).then(function (res) {
-    var queryData = res[0] + res[1] + filterFun + filterViewName +
-      queryParams + docIds + selector;
-    return new Promise(function (resolve) {
-      binaryMd5(queryData, resolve);
-    });
-  }).then(function (md5sum) {
-    // can't use straight-up md5 alphabet, because
-    // the char '/' is interpreted as being for attachments,
-    // and + is also not url-safe
-    md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_');
-    return '_local/' + md5sum;
-  });
-}
+  function updateDocCountIfReady() {
+    if (!metaDoc || !allDocsProcessed) {
+      return;
+    }
+    // caching the docCount saves a lot of time in allDocs() and
+    // info(), which is why we go to all the trouble of doing this
+    metaDoc.docCount += docCountDelta;
+    metaStore.put(metaDoc);
+  }
 
-function replicate(src, target, opts, returnValue, result) {
-  var batches = [];               // list of batches to be processed
-  var currentBatch;               // the batch currently being processed
-  var pendingBatch = {
-    seq: 0,
-    changes: [],
-    docs: []
-  }; // next batch, not yet ready to be processed
-  var writingCheckpoint = false;  // true while checkpoint is being written
-  var changesCompleted = false;   // true when all changes received
-  var replicationCompleted = false; // true when replication has completed
-  var last_seq = 0;
-  var continuous = opts.continuous || opts.live || false;
-  var batch_size = opts.batch_size || 100;
-  var batches_limit = opts.batches_limit || 10;
-  var changesPending = false;     // true while src.changes is running
-  var doc_ids = opts.doc_ids;
-  var selector = opts.selector;
-  var repId;
-  var checkpointer;
-  var changedDocs = [];
-  // Like couchdb, every replication gets a unique session id
-  var session = uuid();
+  function fetchExistingDocs() {
 
-  result = result || {
-    ok: true,
-    start_time: new Date().toISOString(),
-    docs_read: 0,
-    docs_written: 0,
-    doc_write_failures: 0,
-    errors: []
-  };
+    if (!docInfos.length) {
+      return;
+    }
 
-  var changesOpts = {};
-  returnValue.ready(src, target);
+    var numFetched = 0;
 
-  function initCheckpointer() {
-    if (checkpointer) {
-      return Promise.resolve();
+    function checkDone() {
+      if (++numFetched === docInfos.length) {
+        idbProcessDocs();
+      }
     }
-    return generateReplicationId(src, target, opts).then(function (res) {
-      repId = res;
 
-      var checkpointOpts = {};
-      if (opts.checkpoint === false) {
-        checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: false };
-      } else if (opts.checkpoint === 'source') {
-        checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: false };
-      } else if (opts.checkpoint === 'target') {
-        checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: true };
-      } else {
-        checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: true };
+    function readMetadata(event) {
+      var metadata = decodeMetadata(event.target.result);
+
+      if (metadata) {
+        fetchedDocs.set(metadata.id, metadata);
       }
+      checkDone();
+    }
 
-      checkpointer = new Checkpointer(src, target, repId, returnValue, checkpointOpts);
-    });
+    for (var i = 0, len = docInfos.length; i < len; i++) {
+      var docInfo = docInfos[i];
+      if (docInfo._id && isLocalId(docInfo._id)) {
+        checkDone(); // skip local docs
+        continue;
+      }
+      var req = docStore.get(docInfo.metadata.id);
+      req.onsuccess = readMetadata;
+    }
   }
 
-  function writeDocs() {
-    changedDocs = [];
-
-    if (currentBatch.docs.length === 0) {
+  function complete() {
+    if (preconditionErrored) {
       return;
     }
-    var docs = currentBatch.docs;
-    var bulkOpts = {timeout: opts.timeout};
-    return target.bulkDocs({docs: docs, new_edits: false}, bulkOpts).then(function (res) {
-      /* istanbul ignore if */
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-
-      // `res` doesn't include full documents (which live in `docs`), so we create a map of 
-      // (id -> error), and check for errors while iterating over `docs`
-      var errorsById = Object.create(null);
-      res.forEach(function (res) {
-        if (res.error) {
-          errorsById[res.id] = res;
-        }
-      });
 
-      var errorsNo = Object.keys(errorsById).length;
-      result.doc_write_failures += errorsNo;
-      result.docs_written += docs.length - errorsNo;
+    changesHandler.notify(api._meta.name);
+    callback(null, results);
+  }
 
-      docs.forEach(function (doc) {
-        var error = errorsById[doc._id];
-        if (error) {
-          result.errors.push(error);
-          // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
-          var errorName = (error.name || '').toLowerCase();
-          if (errorName === 'unauthorized' || errorName === 'forbidden') {
-            returnValue.emit('denied', clone(error));
-          } else {
-            throw error;
-          }
-        } else {
-          changedDocs.push(doc);
-        }
-      });
+  function verifyAttachment(digest, callback) {
 
-    }, function (err) {
-      result.doc_write_failures += docs.length;
-      throw err;
-    });
+    var req = attachStore.get(digest);
+    req.onsuccess = function (e) {
+      if (!e.target.result) {
+        var err = createError(MISSING_STUB,
+          'unknown stub attachment with digest ' +
+          digest);
+        err.status = 412;
+        callback(err);
+      } else {
+        callback();
+      }
+    };
   }
 
-  function finishBatch() {
-    if (currentBatch.error) {
-      throw new Error('There was a problem getting docs.');
-    }
-    result.last_seq = last_seq = currentBatch.seq;
-    var outResult = clone(result);
-    if (changedDocs.length) {
-      outResult.docs = changedDocs;
-      // Attach 'pending' property if server supports it (CouchDB 2.0+)
-      /* istanbul ignore if */
-      if (typeof currentBatch.pending === 'number') {
-        outResult.pending = currentBatch.pending;
-        delete currentBatch.pending;
-      }
-      returnValue.emit('change', outResult);
-    }
-    writingCheckpoint = true;
-    return checkpointer.writeCheckpoint(currentBatch.seq,
-        session).then(function () {
-      writingCheckpoint = false;
-      /* istanbul ignore if */
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
+  function verifyAttachments(finish) {
+
+
+    var digests = [];
+    docInfos.forEach(function (docInfo) {
+      if (docInfo.data && docInfo.data._attachments) {
+        Object.keys(docInfo.data._attachments).forEach(function (filename) {
+          var att = docInfo.data._attachments[filename];
+          if (att.stub) {
+            digests.push(att.digest);
+          }
+        });
       }
-      currentBatch = undefined;
-      getChanges();
-    }).catch(function (err) {
-      onCheckpointError(err);
-      throw err;
     });
-  }
+    if (!digests.length) {
+      return finish();
+    }
+    var numDone = 0;
+    var err;
 
-  function getDiffs() {
-    var diff = {};
-    currentBatch.changes.forEach(function (change) {
-      // Couchbase Sync Gateway emits these, but we can ignore them
-      /* istanbul ignore if */
-      if (change.id === "_user/") {
-        return;
+    function checkDone() {
+      if (++numDone === digests.length) {
+        finish(err);
       }
-      diff[change.id] = change.changes.map(function (x) {
-        return x.rev;
+    }
+    digests.forEach(function (digest) {
+      verifyAttachment(digest, function (attErr) {
+        if (attErr && !err) {
+          err = attErr;
+        }
+        checkDone();
       });
     });
-    return target.revsDiff(diff).then(function (diffs) {
-      /* istanbul ignore if */
-      if (returnValue.cancelled) {
-        completeReplication();
-        throw new Error('cancelled');
-      }
-      // currentBatch.diffs elements are deleted as the documents are written
-      currentBatch.diffs = diffs;
-    });
   }
 
-  function getBatchDocs() {
-    return getDocs(src, target, currentBatch.diffs, returnValue).then(function (got) {
-      currentBatch.error = !got.ok;
-      got.docs.forEach(function (doc) {
-        delete currentBatch.diffs[doc._id];
-        result.docs_read++;
-        currentBatch.docs.push(doc);
-      });
-    });
-  }
+  function writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
+                    isUpdate, delta, resultsIdx, callback) {
 
-  function startNextBatch() {
-    if (returnValue.cancelled || currentBatch) {
-      return;
+    docInfo.metadata.winningRev = winningRev$$1;
+    docInfo.metadata.deleted = winningRevIsDeleted;
+
+    var doc = docInfo.data;
+    doc._id = docInfo.metadata.id;
+    doc._rev = docInfo.metadata.rev;
+
+    if (newRevIsDeleted) {
+      doc._deleted = true;
     }
-    if (batches.length === 0) {
-      processPendingBatch(true);
-      return;
+
+    var hasAttachments = doc._attachments &&
+      Object.keys(doc._attachments).length;
+    if (hasAttachments) {
+      return writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
+        isUpdate, resultsIdx, callback);
     }
-    currentBatch = batches.shift();
-    getDiffs()
-      .then(getBatchDocs)
-      .then(writeDocs)
-      .then(finishBatch)
-      .then(startNextBatch)
-      .catch(function (err) {
-        abortReplication('batch processing terminated with error', err);
-      });
+
+    docCountDelta += delta;
+    updateDocCountIfReady();
+
+    finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+      isUpdate, resultsIdx, callback);
   }
 
+  function finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+                     isUpdate, resultsIdx, callback) {
 
-  function processPendingBatch(immediate) {
-    if (pendingBatch.changes.length === 0) {
-      if (batches.length === 0 && !currentBatch) {
-        if ((continuous && changesOpts.live) || changesCompleted) {
-          returnValue.state = 'pending';
-          returnValue.emit('paused');
-        }
-        if (changesCompleted) {
-          completeReplication();
-        }
+    var doc = docInfo.data;
+    var metadata = docInfo.metadata;
+
+    doc._doc_id_rev = metadata.id + '::' + metadata.rev;
+    delete doc._id;
+    delete doc._rev;
+
+    function afterPutDoc(e) {
+      var revsToDelete = docInfo.stemmedRevs || [];
+
+      if (isUpdate && api.auto_compaction) {
+        revsToDelete = revsToDelete.concat(compactTree(docInfo.metadata));
       }
-      return;
-    }
-    if (
-      immediate ||
-      changesCompleted ||
-      pendingBatch.changes.length >= batch_size
-    ) {
-      batches.push(pendingBatch);
-      pendingBatch = {
-        seq: 0,
-        changes: [],
-        docs: []
-      };
-      if (returnValue.state === 'pending' || returnValue.state === 'stopped') {
-        returnValue.state = 'active';
-        returnValue.emit('active');
+
+      if (revsToDelete && revsToDelete.length) {
+        compactRevs(revsToDelete, docInfo.metadata.id, txn);
       }
-      startNextBatch();
-    }
-  }
 
+      metadata.seq = e.target.result;
+      // Current _rev is calculated from _rev_tree on read
+      // delete metadata.rev;
+      var metadataToStore = encodeMetadata(metadata, winningRev$$1,
+        winningRevIsDeleted);
+      var metaDataReq = docStore.put(metadataToStore);
+      metaDataReq.onsuccess = afterPutMetadata;
+    }
 
-  function abortReplication(reason, err) {
-    if (replicationCompleted) {
-      return;
+    function afterPutDocError(e) {
+      // ConstraintError, need to update, not put (see #1638 for details)
+      e.preventDefault(); // avoid transaction abort
+      e.stopPropagation(); // avoid transaction onerror
+      var index = bySeqStore.index('_doc_id_rev');
+      var getKeyReq = index.getKey(doc._doc_id_rev);
+      getKeyReq.onsuccess = function (e) {
+        var putReq = bySeqStore.put(doc, e.target.result);
+        putReq.onsuccess = afterPutDoc;
+      };
     }
-    if (!err.message) {
-      err.message = reason;
+
+    function afterPutMetadata() {
+      results[resultsIdx] = {
+        ok: true,
+        id: metadata.id,
+        rev: metadata.rev
+      };
+      fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+      insertAttachmentMappings(docInfo, metadata.seq, callback);
     }
-    result.ok = false;
-    result.status = 'aborting';
-    batches = [];
-    pendingBatch = {
-      seq: 0,
-      changes: [],
-      docs: []
-    };
-    completeReplication(err);
+
+    var putReq = bySeqStore.put(doc);
+
+    putReq.onsuccess = afterPutDoc;
+    putReq.onerror = afterPutDocError;
   }
 
+  function writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
+                            isUpdate, resultsIdx, callback) {
+
 
-  function completeReplication(fatalError) {
-    if (replicationCompleted) {
-      return;
-    }
-    /* istanbul ignore if */
-    if (returnValue.cancelled) {
-      result.status = 'cancelled';
-      if (writingCheckpoint) {
-        return;
+    var doc = docInfo.data;
+
+    var numDone = 0;
+    var attachments = Object.keys(doc._attachments);
+
+    function collectResults() {
+      if (numDone === attachments.length) {
+        finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+          isUpdate, resultsIdx, callback);
       }
     }
-    result.status = result.status || 'complete';
-    result.end_time = new Date().toISOString();
-    result.last_seq = last_seq;
-    replicationCompleted = true;
 
-    if (fatalError) {
-      // need to extend the error because Firefox considers ".result" read-only
-      fatalError = createError(fatalError);
-      fatalError.result = result;
+    function attachmentSaved() {
+      numDone++;
+      collectResults();
+    }
 
-      // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
-      var errorName = (fatalError.name || '').toLowerCase();
-      if (errorName === 'unauthorized' || errorName === 'forbidden') {
-        returnValue.emit('error', fatalError);
-        returnValue.removeAllListeners();
+    attachments.forEach(function (key) {
+      var att = docInfo.data._attachments[key];
+      if (!att.stub) {
+        var data = att.data;
+        delete att.data;
+        att.revpos = parseInt(winningRev$$1, 10);
+        var digest = att.digest;
+        saveAttachment(digest, data, attachmentSaved);
       } else {
-        backOff(opts, returnValue, fatalError, function () {
-          replicate(src, target, opts, returnValue);
-        });
+        numDone++;
+        collectResults();
       }
-    } else {
-      returnValue.emit('complete', result);
-      returnValue.removeAllListeners();
-    }
+    });
   }
 
+  // map seqs to attachment digests, which
+  // we will need later during compaction
+  function insertAttachmentMappings(docInfo, seq, callback) {
 
-  function onChange(change, pending, lastSeq) {
-    /* istanbul ignore if */
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    // Attach 'pending' property if server supports it (CouchDB 2.0+)
-    /* istanbul ignore if */
-    if (typeof pending === 'number') {
-      pendingBatch.pending = pending;
+    var attsAdded = 0;
+    var attsToAdd = Object.keys(docInfo.data._attachments || {});
+
+    if (!attsToAdd.length) {
+      return callback();
     }
 
-    var filter = filterChange(opts)(change);
-    if (!filter) {
-      return;
+    function checkDone() {
+      if (++attsAdded === attsToAdd.length) {
+        callback();
+      }
     }
-    pendingBatch.seq = change.seq || lastSeq;
-    pendingBatch.changes.push(change);
-    immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
-      processPendingBatch(batches.length === 0 && changesOpts.live);
-    });
-  }
 
+    function add(att) {
+      var digest = docInfo.data._attachments[att].digest;
+      var req = attachAndSeqStore.put({
+        seq: seq,
+        digestSeq: digest + '::' + seq
+      });
 
-  function onChangesComplete(changes) {
-    changesPending = false;
-    /* istanbul ignore if */
-    if (returnValue.cancelled) {
-      return completeReplication();
+      req.onsuccess = checkDone;
+      req.onerror = function (e) {
+        // this callback is for a constaint error, which we ignore
+        // because this docid/rev has already been associated with
+        // the digest (e.g. when new_edits == false)
+        e.preventDefault(); // avoid transaction abort
+        e.stopPropagation(); // avoid transaction onerror
+        checkDone();
+      };
     }
+    for (var i = 0; i < attsToAdd.length; i++) {
+      add(attsToAdd[i]); // do in parallel
+    }
+  }
 
-    // if no results were returned then we're done,
-    // else fetch more
-    if (changes.results.length > 0) {
-      changesOpts.since = changes.results[changes.results.length - 1].seq;
-      getChanges();
-      processPendingBatch(true);
-    } else {
+  function saveAttachment(digest, data, callback) {
 
-      var complete = function () {
-        if (continuous) {
-          changesOpts.live = true;
-          getChanges();
-        } else {
-          changesCompleted = true;
-        }
-        processPendingBatch(true);
-      };
 
-      // update the checkpoint so we start from the right seq next time
-      if (!currentBatch && changes.results.length === 0) {
-        writingCheckpoint = true;
-        checkpointer.writeCheckpoint(changes.last_seq,
-            session).then(function () {
-          writingCheckpoint = false;
-          result.last_seq = last_seq = changes.last_seq;
-          complete();
-        })
-        .catch(onCheckpointError);
-      } else {
-        complete();
+    var getKeyReq = attachStore.count(digest);
+    getKeyReq.onsuccess = function (e) {
+      var count = e.target.result;
+      if (count) {
+        return callback(); // already exists
       }
-    }
+      var newAtt = {
+        digest: digest,
+        body: data
+      };
+      var putReq = attachStore.put(newAtt);
+      putReq.onsuccess = callback;
+    };
   }
+}
 
+// Abstraction over IDBCursor and getAll()/getAllKeys() that allows us to batch our operations
+// while falling back to a normal IDBCursor operation on browsers that don't support getAll() or
+// getAllKeys(). This allows for a much faster implementation than just straight-up cursors, because
+// we're not processing each document one-at-a-time.
+function runBatchedCursor(objectStore, keyRange, descending, batchSize, onBatch) {
 
-  function onChangesError(err) {
-    changesPending = false;
-    /* istanbul ignore if */
-    if (returnValue.cancelled) {
-      return completeReplication();
-    }
-    abortReplication('changes rejected', err);
+  if (batchSize === -1) {
+    batchSize = 1000;
   }
 
+  // Bail out of getAll()/getAllKeys() in the following cases:
+  // 1) either method is unsupported - we need both
+  // 2) batchSize is 1 (might as well use IDBCursor)
+  // 3) descending – no real way to do this via getAll()/getAllKeys()
 
-  function getChanges() {
-    if (!(
-      !changesPending &&
-      !changesCompleted &&
-      batches.length < batches_limit
-      )) {
-      return;
-    }
-    changesPending = true;
-    function abortChanges() {
-      changes.cancel();
-    }
-    function removeListener() {
-      returnValue.removeListener('cancel', abortChanges);
-    }
-
-    if (returnValue._changes) { // remove old changes() and listeners
-      returnValue.removeListener('cancel', returnValue._abortChanges);
-      returnValue._changes.cancel();
-    }
-    returnValue.once('cancel', abortChanges);
+  var useGetAll = typeof objectStore.getAll === 'function' &&
+    typeof objectStore.getAllKeys === 'function' &&
+    batchSize > 1 && !descending;
 
-    var changes = src.changes(changesOpts)
-      .on('change', onChange);
-    changes.then(removeListener, removeListener);
-    changes.then(onChangesComplete)
-      .catch(onChangesError);
+  var keysBatch;
+  var valuesBatch;
+  var pseudoCursor;
 
-    if (opts.retry) {
-      // save for later so we can cancel if necessary
-      returnValue._changes = changes;
-      returnValue._abortChanges = abortChanges;
+  function onGetAll(e) {
+    valuesBatch = e.target.result;
+    if (keysBatch) {
+      onBatch(keysBatch, valuesBatch, pseudoCursor);
     }
   }
 
+  function onGetAllKeys(e) {
+    keysBatch = e.target.result;
+    if (valuesBatch) {
+      onBatch(keysBatch, valuesBatch, pseudoCursor);
+    }
+  }
 
-  function startChanges() {
-    initCheckpointer().then(function () {
-      /* istanbul ignore if */
-      if (returnValue.cancelled) {
-        completeReplication();
-        return;
-      }
-      return checkpointer.getCheckpoint().then(function (checkpoint) {
-        last_seq = checkpoint;
-        changesOpts = {
-          since: last_seq,
-          limit: batch_size,
-          batch_size: batch_size,
-          style: 'all_docs',
-          doc_ids: doc_ids,
-          selector: selector,
-          return_docs: true // required so we know when we're done
-        };
-        if (opts.filter) {
-          if (typeof opts.filter !== 'string') {
-            // required for the client-side filter in onChange
-            changesOpts.include_docs = true;
-          } else { // ddoc filter
-            changesOpts.filter = opts.filter;
-          }
-        }
-        if ('heartbeat' in opts) {
-          changesOpts.heartbeat = opts.heartbeat;
-        }
-        if ('timeout' in opts) {
-          changesOpts.timeout = opts.timeout;
-        }
-        if (opts.query_params) {
-          changesOpts.query_params = opts.query_params;
-        }
-        if (opts.view) {
-          changesOpts.view = opts.view;
+  function continuePseudoCursor() {
+    if (!keysBatch.length) { // no more results
+      return onBatch();
+    }
+    // fetch next batch, exclusive start
+    var lastKey = keysBatch[keysBatch.length - 1];
+    var newKeyRange;
+    if (keyRange && keyRange.upper) {
+      try {
+        newKeyRange = IDBKeyRange.bound(lastKey, keyRange.upper,
+          true, keyRange.upperOpen);
+      } catch (e) {
+        if (e.name === "DataError" && e.code === 0) {
+          return onBatch(); // we're done, startkey and endkey are equal
         }
-        getChanges();
-      });
-    }).catch(function (err) {
-      abortReplication('getCheckpoint rejected with ', err);
-    });
+      }
+    } else {
+      newKeyRange = IDBKeyRange.lowerBound(lastKey, true);
+    }
+    keyRange = newKeyRange;
+    keysBatch = null;
+    valuesBatch = null;
+    objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
+    objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
   }
 
-  /* istanbul ignore next */
-  function onCheckpointError(err) {
-    writingCheckpoint = false;
-    abortReplication('writeCheckpoint completed with error', err);
+  function onCursor(e) {
+    var cursor = e.target.result;
+    if (!cursor) { // done
+      return onBatch();
+    }
+    // regular IDBCursor acts like a batch where batch size is always 1
+    onBatch([cursor.key], [cursor.value], cursor);
   }
 
-  /* istanbul ignore if */
-  if (returnValue.cancelled) { // cancelled immediately
-    completeReplication();
-    return;
+  if (useGetAll) {
+    pseudoCursor = {"continue": continuePseudoCursor};
+    objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
+    objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
+  } else if (descending) {
+    objectStore.openCursor(keyRange, 'prev').onsuccess = onCursor;
+  } else {
+    objectStore.openCursor(keyRange).onsuccess = onCursor;
   }
+}
 
-  if (!returnValue._addedListeners) {
-    returnValue.once('cancel', completeReplication);
+// simple shim for objectStore.getAll(), falling back to IDBCursor
+function getAll(objectStore, keyRange, onSuccess) {
+  if (typeof objectStore.getAll === 'function') {
+    // use native getAll
+    objectStore.getAll(keyRange).onsuccess = onSuccess;
+    return;
+  }
+  // fall back to cursors
+  var values = [];
 
-    if (typeof opts.complete === 'function') {
-      returnValue.once('error', opts.complete);
-      returnValue.once('complete', function (result) {
-        opts.complete(null, result);
+  function onCursor(e) {
+    var cursor = e.target.result;
+    if (cursor) {
+      values.push(cursor.value);
+      cursor.continue();
+    } else {
+      onSuccess({
+        target: {
+          result: values
+        }
       });
     }
-    returnValue._addedListeners = true;
   }
 
-  if (typeof opts.since === 'undefined') {
-    startChanges();
-  } else {
-    initCheckpointer().then(function () {
-      writingCheckpoint = true;
-      return checkpointer.writeCheckpoint(opts.since, session);
-    }).then(function () {
-      writingCheckpoint = false;
-      /* istanbul ignore if */
-      if (returnValue.cancelled) {
-        completeReplication();
-        return;
-      }
-      last_seq = opts.since;
-      startChanges();
-    }).catch(onCheckpointError);
-  }
+  objectStore.openCursor(keyRange).onsuccess = onCursor;
 }
 
-// We create a basic promise so the caller can cancel the replication possibly
-// before we have actually started listening to changes etc
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(Replication, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
-function Replication() {
-  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
-  this.cancelled = false;
-  this.state = 'pending';
-  var self = this;
-  var promise = new Promise(function (fulfill, reject) {
-    self.once('complete', fulfill);
-    self.once('error', reject);
+function allDocsKeys(keys, docStore, onBatch) {
+  // It's not guaranted to be returned in right order  
+  var valuesBatch = new Array(keys.length);
+  var count = 0;
+  keys.forEach(function (key, index) {
+    docStore.get(key).onsuccess = function (event) {
+      if (event.target.result) {
+        valuesBatch[index] = event.target.result;
+      } else {
+        valuesBatch[index] = {key: key, error: 'not_found'};
+      }
+      count++;
+      if (count === keys.length) {
+        onBatch(keys, valuesBatch, {});
+      }
+    };
   });
-  self.then = function (resolve, reject) {
-    return promise.then(resolve, reject);
-  };
-  self.catch = function (reject) {
-    return promise.catch(reject);
-  };
-  // As we allow error handling via "error" event as well,
-  // put a stub in here so that rejecting never throws UnhandledError.
-  self.catch(function () {});
 }
 
-Replication.prototype.cancel = function () {
-  this.cancelled = true;
-  this.state = 'cancelled';
-  this.emit('cancel');
-};
-
-Replication.prototype.ready = function (src, target) {
-  var self = this;
-  if (self._readyCalled) {
-    return;
-  }
-  self._readyCalled = true;
-
-  function onDestroy() {
-    self.cancel();
-  }
-  src.once('destroyed', onDestroy);
-  target.once('destroyed', onDestroy);
-  function cleanup() {
-    src.removeListener('destroyed', onDestroy);
-    target.removeListener('destroyed', onDestroy);
-  }
-  self.once('complete', cleanup);
-};
-
-function toPouch(db, opts) {
-  var PouchConstructor = opts.PouchConstructor;
-  if (typeof db === 'string') {
-    return new PouchConstructor(db, opts);
-  } else {
-    return db;
+function createKeyRange(start, end, inclusiveEnd, key, descending) {
+  try {
+    if (start && end) {
+      if (descending) {
+        return IDBKeyRange.bound(end, start, !inclusiveEnd, false);
+      } else {
+        return IDBKeyRange.bound(start, end, false, !inclusiveEnd);
+      }
+    } else if (start) {
+      if (descending) {
+        return IDBKeyRange.upperBound(start);
+      } else {
+        return IDBKeyRange.lowerBound(start);
+      }
+    } else if (end) {
+      if (descending) {
+        return IDBKeyRange.lowerBound(end, !inclusiveEnd);
+      } else {
+        return IDBKeyRange.upperBound(end, !inclusiveEnd);
+      }
+    } else if (key) {
+      return IDBKeyRange.only(key);
+    }
+  } catch (e) {
+    return {error: e};
   }
+  return null;
 }
 
-function replicateWrapper(src, target, opts, callback) {
-
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
-  }
-  if (typeof opts === 'undefined') {
-    opts = {};
-  }
+function idbAllDocs(opts, idb, callback) {
+  var start = 'startkey' in opts ? opts.startkey : false;
+  var end = 'endkey' in opts ? opts.endkey : false;
+  var key = 'key' in opts ? opts.key : false;
+  var keys = 'keys' in opts ? opts.keys : false; 
+  var skip = opts.skip || 0;
+  var limit = typeof opts.limit === 'number' ? opts.limit : -1;
+  var inclusiveEnd = opts.inclusive_end !== false;
 
-  if (opts.doc_ids && !Array.isArray(opts.doc_ids)) {
-    throw createError(BAD_REQUEST,
-                       "`doc_ids` filter parameter is not a list.");
+  var keyRange ; 
+  var keyRangeError;
+  if (!keys) {
+    keyRange = createKeyRange(start, end, inclusiveEnd, key, opts.descending);
+    keyRangeError = keyRange && keyRange.error;
+    if (keyRangeError && 
+      !(keyRangeError.name === "DataError" && keyRangeError.code === 0)) {
+      // DataError with error code 0 indicates start is less than end, so
+      // can just do an empty query. Else need to throw
+      return callback(createError(IDB_ERROR,
+        keyRangeError.name, keyRangeError.message));
+    }
   }
 
-  opts.complete = callback;
-  opts = clone(opts);
-  opts.continuous = opts.continuous || opts.live;
-  opts.retry = ('retry' in opts) ? opts.retry : false;
-  /*jshint validthis:true */
-  opts.PouchConstructor = opts.PouchConstructor || this;
-  var replicateRet = new Replication(opts);
-  var srcPouch = toPouch(src, opts);
-  var targetPouch = toPouch(target, opts);
-  replicate(srcPouch, targetPouch, opts, replicateRet);
-  return replicateRet;
-}
+  var stores = [DOC_STORE, BY_SEQ_STORE, META_STORE];
 
-inherits__WEBPACK_IMPORTED_MODULE_3___default()(Sync, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
-function sync(src, target, opts, callback) {
-  if (typeof opts === 'function') {
-    callback = opts;
-    opts = {};
+  if (opts.attachments) {
+    stores.push(ATTACH_STORE);
   }
-  if (typeof opts === 'undefined') {
-    opts = {};
+  var txnResult = openTransactionSafely(idb, stores, 'readonly');
+  if (txnResult.error) {
+    return callback(txnResult.error);
   }
-  opts = clone(opts);
-  /*jshint validthis:true */
-  opts.PouchConstructor = opts.PouchConstructor || this;
-  src = toPouch(src, opts);
-  target = toPouch(target, opts);
-  return new Sync(src, target, opts, callback);
-}
-
-function Sync(src, target, opts, callback) {
-  var self = this;
-  this.canceled = false;
-
-  var optsPush = opts.push ? $inject_Object_assign({}, opts, opts.push) : opts;
-  var optsPull = opts.pull ? $inject_Object_assign({}, opts, opts.pull) : opts;
-
-  this.push = replicateWrapper(src, target, optsPush);
-  this.pull = replicateWrapper(target, src, optsPull);
+  var txn = txnResult.txn;
+  txn.oncomplete = onTxnComplete;
+  txn.onabort = idbError(callback);
+  var docStore = txn.objectStore(DOC_STORE);
+  var seqStore = txn.objectStore(BY_SEQ_STORE);
+  var metaStore = txn.objectStore(META_STORE);
+  var docIdRevIndex = seqStore.index('_doc_id_rev');
+  var results = [];
+  var docCount;
+  var updateSeq;
 
-  this.pushPaused = true;
-  this.pullPaused = true;
+  metaStore.get(META_STORE).onsuccess = function (e) {
+    docCount = e.target.result.docCount;
+  };
 
-  function pullChange(change) {
-    self.emit('change', {
-      direction: 'pull',
-      change: change
-    });
-  }
-  function pushChange(change) {
-    self.emit('change', {
-      direction: 'push',
-      change: change
-    });
-  }
-  function pushDenied(doc) {
-    self.emit('denied', {
-      direction: 'push',
-      doc: doc
-    });
-  }
-  function pullDenied(doc) {
-    self.emit('denied', {
-      direction: 'pull',
-      doc: doc
+  /* istanbul ignore if */
+  if (opts.update_seq) {
+    getMaxUpdateSeq(seqStore, function (e) { 
+      if (e.target.result && e.target.result.length > 0) {
+        updateSeq = e.target.result[0];
+      }
     });
   }
-  function pushPaused() {
-    self.pushPaused = true;
-    /* istanbul ignore if */
-    if (self.pullPaused) {
-      self.emit('paused');
-    }
-  }
-  function pullPaused() {
-    self.pullPaused = true;
-    /* istanbul ignore if */
-    if (self.pushPaused) {
-      self.emit('paused');
-    }
-  }
-  function pushActive() {
-    self.pushPaused = false;
-    /* istanbul ignore if */
-    if (self.pullPaused) {
-      self.emit('active', {
-        direction: 'push'
-      });
-    }
-  }
-  function pullActive() {
-    self.pullPaused = false;
-    /* istanbul ignore if */
-    if (self.pushPaused) {
-      self.emit('active', {
-        direction: 'pull'
+
+  function getMaxUpdateSeq(objectStore, onSuccess) {
+    function onCursor(e) {
+      var cursor = e.target.result;
+      var maxKey = undefined;
+      if (cursor && cursor.key) {
+        maxKey = cursor.key;
+      } 
+      return onSuccess({
+        target: {
+          result: [maxKey]
+        }
       });
     }
+    objectStore.openCursor(null, 'prev').onsuccess = onCursor;
   }
 
-  var removed = {};
-
-  function removeAll(type) { // type is 'push' or 'pull'
-    return function (event, func) {
-      var isChange = event === 'change' &&
-        (func === pullChange || func === pushChange);
-      var isDenied = event === 'denied' &&
-        (func === pullDenied || func === pushDenied);
-      var isPaused = event === 'paused' &&
-        (func === pullPaused || func === pushPaused);
-      var isActive = event === 'active' &&
-        (func === pullActive || func === pushActive);
-
-      if (isChange || isDenied || isPaused || isActive) {
-        if (!(event in removed)) {
-          removed[event] = {};
-        }
-        removed[event][type] = true;
-        if (Object.keys(removed[event]).length === 2) {
-          // both push and pull have asked to be removed
-          self.removeAllListeners(event);
+  // if the user specifies include_docs=true, then we don't
+  // want to block the main cursor while we're fetching the doc
+  function fetchDocAsynchronously(metadata, row, winningRev$$1) {
+    var key = metadata.id + "::" + winningRev$$1;
+    docIdRevIndex.get(key).onsuccess =  function onGetDoc(e) {
+      row.doc = decodeDoc(e.target.result) || {};
+      if (opts.conflicts) {
+        var conflicts = collectConflicts(metadata);
+        if (conflicts.length) {
+          row.doc._conflicts = conflicts;
         }
       }
+      fetchAttachmentsIfNecessary(row.doc, opts, txn);
     };
   }
 
-  if (opts.live) {
-    this.push.on('complete', self.pull.cancel.bind(self.pull));
-    this.pull.on('complete', self.push.cancel.bind(self.push));
+  function allDocsInner(winningRev$$1, metadata) {
+    var row = {
+      id: metadata.id,
+      key: metadata.id,
+      value: {
+        rev: winningRev$$1
+      }
+    };
+    var deleted = metadata.deleted;
+    if (deleted) {
+      if (keys) {
+        results.push(row);
+        // deleted docs are okay with "keys" requests
+        row.value.deleted = true;
+        row.doc = null;
+      }
+    } else if (skip-- <= 0) {
+      results.push(row);
+      if (opts.include_docs) {
+        fetchDocAsynchronously(metadata, row, winningRev$$1);
+      }
+    }
   }
 
-  function addOneListener(ee, event, listener) {
-    if (ee.listeners(event).indexOf(listener) == -1) {
-      ee.on(event, listener);
+  function processBatch(batchValues) {
+    for (var i = 0, len = batchValues.length; i < len; i++) {
+      if (results.length === limit) {
+        break;
+      }
+      var batchValue = batchValues[i];
+      if (batchValue.error && keys) {
+        // key was not found with "keys" requests
+        results.push(batchValue);
+        continue;
+      }
+      var metadata = decodeMetadata(batchValue);
+      var winningRev$$1 = metadata.winningRev;
+      allDocsInner(winningRev$$1, metadata);
     }
   }
 
-  this.on('newListener', function (event) {
-    if (event === 'change') {
-      addOneListener(self.pull, 'change', pullChange);
-      addOneListener(self.push, 'change', pushChange);
-    } else if (event === 'denied') {
-      addOneListener(self.pull, 'denied', pullDenied);
-      addOneListener(self.push, 'denied', pushDenied);
-    } else if (event === 'active') {
-      addOneListener(self.pull, 'active', pullActive);
-      addOneListener(self.push, 'active', pushActive);
-    } else if (event === 'paused') {
-      addOneListener(self.pull, 'paused', pullPaused);
-      addOneListener(self.push, 'paused', pushPaused);
+  function onBatch(batchKeys, batchValues, cursor) {
+    if (!cursor) {
+      return;
     }
-  });
-
-  this.on('removeListener', function (event) {
-    if (event === 'change') {
-      self.pull.removeListener('change', pullChange);
-      self.push.removeListener('change', pushChange);
-    } else if (event === 'denied') {
-      self.pull.removeListener('denied', pullDenied);
-      self.push.removeListener('denied', pushDenied);
-    } else if (event === 'active') {
-      self.pull.removeListener('active', pullActive);
-      self.push.removeListener('active', pushActive);
-    } else if (event === 'paused') {
-      self.pull.removeListener('paused', pullPaused);
-      self.push.removeListener('paused', pushPaused);
+    processBatch(batchValues);
+    if (results.length < limit) {
+      cursor.continue();
     }
-  });
+  }
 
-  this.pull.on('removeListener', removeAll('pull'));
-  this.push.on('removeListener', removeAll('push'));
+  function onGetAll(e) {
+    var values = e.target.result;
+    if (opts.descending) {
+      values = values.reverse();
+    }
+    processBatch(values);
+  }
 
-  var promise = Promise.all([
-    this.push,
-    this.pull
-  ]).then(function (resp) {
-    var out = {
-      push: resp[0],
-      pull: resp[1]
+  function onResultsReady() {
+    var returnVal = {
+      total_rows: docCount,
+      offset: opts.skip,
+      rows: results
     };
-    self.emit('complete', out);
-    if (callback) {
-      callback(null, out);
+    
+    /* istanbul ignore if */
+    if (opts.update_seq && updateSeq !== undefined) {
+      returnVal.update_seq = updateSeq;
     }
-    self.removeAllListeners();
-    return out;
-  }, function (err) {
-    self.cancel();
-    if (callback) {
-      // if there's a callback, then the callback can receive
-      // the error event
-      callback(err);
+    callback(null, returnVal);
+  }
+
+  function onTxnComplete() {
+    if (opts.attachments) {
+      postProcessAttachments(results, opts.binary).then(onResultsReady);
     } else {
-      // if there's no callback, then we're safe to emit an error
-      // event, which would otherwise throw an unhandled error
-      // due to 'error' being a special event in EventEmitters
-      self.emit('error', err);
-    }
-    self.removeAllListeners();
-    if (callback) {
-      // no sense throwing if we're already emitting an 'error' event
-      throw err;
+      onResultsReady();
     }
+  }
+
+  // don't bother doing any requests if start > end or limit === 0
+  if (keyRangeError || limit === 0) {
+    return;
+  }
+  if (keys) {
+    return allDocsKeys(opts.keys, docStore, onBatch);
+  }
+  if (limit === -1) { // just fetch everything
+    return getAll(docStore, keyRange, onGetAll);
+  }
+  // else do a cursor
+  // choose a batch size based on the skip, since we'll need to skip that many
+  runBatchedCursor(docStore, keyRange, opts.descending, limit + skip, onBatch);
+}
+
+//
+// Blobs are not supported in all versions of IndexedDB, notably
+// Chrome <37 and Android <5. In those versions, storing a blob will throw.
+//
+// Various other blob bugs exist in Chrome v37-42 (inclusive).
+// Detecting them is expensive and confusing to users, and Chrome 37-42
+// is at very low usage worldwide, so we do a hacky userAgent check instead.
+//
+// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120
+// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916
+// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836
+//
+function checkBlobSupport(txn) {
+  return new Promise(function (resolve) {
+    var blob$$1 = createBlob(['']);
+    var req = txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob$$1, 'key');
+
+    req.onsuccess = function () {
+      var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/);
+      var matchedEdge = navigator.userAgent.match(/Edge\//);
+      // MS Edge pretends to be Chrome 42:
+      // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx
+      resolve(matchedEdge || !matchedChrome ||
+        parseInt(matchedChrome[1], 10) >= 43);
+    };
+
+    req.onerror = txn.onabort = function (e) {
+      // If the transaction aborts now its due to not being able to
+      // write to the database, likely due to the disk being full
+      e.preventDefault();
+      e.stopPropagation();
+      resolve(false);
+    };
+  }).catch(function () {
+    return false; // error, so assume unsupported
   });
+}
 
-  this.then = function (success, err) {
-    return promise.then(success, err);
+function countDocs(txn, cb) {
+  var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
+  index.count(IDBKeyRange.only('0')).onsuccess = function (e) {
+    cb(e.target.result);
   };
+}
 
-  this.catch = function (err) {
-    return promise.catch(err);
-  };
+// This task queue ensures that IDB open calls are done in their own tick
+
+var running = false;
+var queue = [];
+
+function tryCode(fun, err, res, PouchDB) {
+  try {
+    fun(err, res);
+  } catch (err) {
+    // Shouldn't happen, but in some odd cases
+    // IndexedDB implementations might throw a sync
+    // error, in which case this will at least log it.
+    PouchDB.emit('error', err);
+  }
 }
 
-Sync.prototype.cancel = function () {
-  if (!this.canceled) {
-    this.canceled = true;
-    this.push.cancel();
-    this.pull.cancel();
+function applyNext() {
+  if (running || !queue.length) {
+    return;
   }
-};
+  running = true;
+  queue.shift()();
+}
 
-function replication(PouchDB) {
-  PouchDB.replicate = replicateWrapper;
-  PouchDB.sync = sync;
+function enqueueTask(action, callback, PouchDB) {
+  queue.push(function runAction() {
+    action(function runCallback(err, res) {
+      tryCode(callback, err, res, PouchDB);
+      running = false;
+      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function runNext() {
+        applyNext(PouchDB);
+      });
+    });
+  });
+  applyNext();
+}
 
-  Object.defineProperty(PouchDB.prototype, 'replicate', {
-    get: function () {
-      var self = this;
-      if (typeof this.replicateMethods === 'undefined') {
-        this.replicateMethods = {
-          from: function (other, opts, callback) {
-            return self.constructor.replicate(other, self, opts, callback);
-          },
-          to: function (other, opts, callback) {
-            return self.constructor.replicate(self, other, opts, callback);
-          }
-        };
+function changes(opts, api, dbName, idb) {
+  opts = clone(opts);
+
+  if (opts.continuous) {
+    var id = dbName + ':' + uuid();
+    changesHandler.addListener(dbName, id, api, opts);
+    changesHandler.notify(dbName);
+    return {
+      cancel: function () {
+        changesHandler.removeListener(dbName, id);
       }
-      return this.replicateMethods;
-    }
-  });
+    };
+  }
 
-  PouchDB.prototype.sync = function (dbName, opts, callback) {
-    return this.constructor.sync(this, dbName, opts, callback);
-  };
-}
+  var docIds = opts.doc_ids && new ExportedSet(opts.doc_ids);
 
-PouchDB.plugin(IDBPouch)
-  .plugin(HttpPouch$1)
-  .plugin(mapreduce)
-  .plugin(replication);
+  opts.since = opts.since || 0;
+  var lastSeq = opts.since;
 
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PouchDB);
+  var limit = 'limit' in opts ? opts.limit : -1;
+  if (limit === 0) {
+    limit = 1; // per CouchDB _changes spec
+  }
 
+  var results = [];
+  var numResults = 0;
+  var filter = filterChange(opts);
+  var docIdsToMetadata = new ExportedMap();
 
-/***/ }),
-/* 483 */
-/***/ ((module) => {
+  var txn;
+  var bySeqStore;
+  var docStore;
+  var docIdRevIndex;
 
-"use strict";
+  function onBatch(batchKeys, batchValues, cursor) {
+    if (!cursor || !batchKeys.length) { // done
+      return;
+    }
 
+    var winningDocs = new Array(batchKeys.length);
+    var metadatas = new Array(batchKeys.length);
 
-module.exports = argsArray;
+    function processMetadataAndWinningDoc(metadata, winningDoc) {
+      var change = opts.processChange(winningDoc, metadata, opts);
+      lastSeq = change.seq = metadata.seq;
 
-function argsArray(fun) {
-  return function () {
-    var len = arguments.length;
-    if (len) {
-      var args = [];
-      var i = -1;
-      while (++i < len) {
-        args[i] = arguments[i];
+      var filtered = filter(change);
+      if (typeof filtered === 'object') { // anything but true/false indicates error
+        return Promise.reject(filtered);
       }
-      return fun.call(this, args);
-    } else {
-      return fun.call(this, []);
-    }
-  };
-}
 
-/***/ }),
-/* 484 */
-/***/ ((module) => {
+      if (!filtered) {
+        return Promise.resolve();
+      }
+      numResults++;
+      if (opts.return_docs) {
+        results.push(change);
+      }
+      // process the attachment immediately
+      // for the benefit of live listeners
+      if (opts.attachments && opts.include_docs) {
+        return new Promise(function (resolve) {
+          fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () {
+            postProcessAttachments([change], opts.binary).then(function () {
+              resolve(change);
+            });
+          });
+        });
+      } else {
+        return Promise.resolve(change);
+      }
+    }
 
-"use strict";
+    function onBatchDone() {
+      var promises = [];
+      for (var i = 0, len = winningDocs.length; i < len; i++) {
+        if (numResults === limit) {
+          break;
+        }
+        var winningDoc = winningDocs[i];
+        if (!winningDoc) {
+          continue;
+        }
+        var metadata = metadatas[i];
+        promises.push(processMetadataAndWinningDoc(metadata, winningDoc));
+      }
 
-var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+      Promise.all(promises).then(function (changes) {
+        for (var i = 0, len = changes.length; i < len; i++) {
+          if (changes[i]) {
+            opts.onChange(changes[i]);
+          }
+        }
+      }).catch(opts.complete);
 
-var scheduleDrain;
+      if (numResults !== limit) {
+        cursor.continue();
+      }
+    }
 
-if (process.browser) {
-  if (Mutation) {
-    var called = 0;
-    var observer = new Mutation(nextTick);
-    var element = global.document.createTextNode('');
-    observer.observe(element, {
-      characterData: true
+    // Fetch all metadatas/winningdocs from this batch in parallel, then process
+    // them all only once all data has been collected. This is done in parallel
+    // because it's faster than doing it one-at-a-time.
+    var numDone = 0;
+    batchValues.forEach(function (value, i) {
+      var doc = decodeDoc(value);
+      var seq = batchKeys[i];
+      fetchWinningDocAndMetadata(doc, seq, function (metadata, winningDoc) {
+        metadatas[i] = metadata;
+        winningDocs[i] = winningDoc;
+        if (++numDone === batchKeys.length) {
+          onBatchDone();
+        }
+      });
     });
-    scheduleDrain = function () {
-      element.data = (called = ++called % 2);
-    };
-  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
-    var channel = new global.MessageChannel();
-    channel.port1.onmessage = nextTick;
-    scheduleDrain = function () {
-      channel.port2.postMessage(0);
-    };
-  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
-    scheduleDrain = function () {
+  }
 
-      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-      var scriptEl = global.document.createElement('script');
-      scriptEl.onreadystatechange = function () {
-        nextTick();
+  function onGetMetadata(doc, seq, metadata, cb) {
+    if (metadata.seq !== seq) {
+      // some other seq is later
+      return cb();
+    }
 
-        scriptEl.onreadystatechange = null;
-        scriptEl.parentNode.removeChild(scriptEl);
-        scriptEl = null;
-      };
-      global.document.documentElement.appendChild(scriptEl);
+    if (metadata.winningRev === doc._rev) {
+      // this is the winning doc
+      return cb(metadata, doc);
+    }
+
+    // fetch winning doc in separate request
+    var docIdRev = doc._id + '::' + metadata.winningRev;
+    var req = docIdRevIndex.get(docIdRev);
+    req.onsuccess = function (e) {
+      cb(metadata, decodeDoc(e.target.result));
     };
-  } else {
-    scheduleDrain = function () {
-      setTimeout(nextTick, 0);
+  }
+
+  function fetchWinningDocAndMetadata(doc, seq, cb) {
+    if (docIds && !docIds.has(doc._id)) {
+      return cb();
+    }
+
+    var metadata = docIdsToMetadata.get(doc._id);
+    if (metadata) { // cached
+      return onGetMetadata(doc, seq, metadata, cb);
+    }
+    // metadata not cached, have to go fetch it
+    docStore.get(doc._id).onsuccess = function (e) {
+      metadata = decodeMetadata(e.target.result);
+      docIdsToMetadata.set(doc._id, metadata);
+      onGetMetadata(doc, seq, metadata, cb);
     };
   }
-} else {
-  scheduleDrain = function () {
-    process.nextTick(nextTick);
-  };
-}
 
-var draining;
-var queue = [];
-//named nextTick for less confusing stack traces
-function nextTick() {
-  draining = true;
-  var i, oldQueue;
-  var len = queue.length;
-  while (len) {
-    oldQueue = queue;
-    queue = [];
-    i = -1;
-    while (++i < len) {
-      oldQueue[i]();
+  function finish() {
+    opts.complete(null, {
+      results: results,
+      last_seq: lastSeq
+    });
+  }
+
+  function onTxnComplete() {
+    if (!opts.continuous && opts.attachments) {
+      // cannot guarantee that postProcessing was already done,
+      // so do it again
+      postProcessAttachments(results).then(finish);
+    } else {
+      finish();
     }
-    len = queue.length;
   }
-  draining = false;
-}
 
-module.exports = immediate;
-function immediate(task) {
-  if (queue.push(task) === 1 && !draining) {
-    scheduleDrain();
+  var objectStores = [DOC_STORE, BY_SEQ_STORE];
+  if (opts.attachments) {
+    objectStores.push(ATTACH_STORE);
   }
-}
+  var txnResult = openTransactionSafely(idb, objectStores, 'readonly');
+  if (txnResult.error) {
+    return opts.complete(txnResult.error);
+  }
+  txn = txnResult.txn;
+  txn.onabort = idbError(opts.complete);
+  txn.oncomplete = onTxnComplete;
 
+  bySeqStore = txn.objectStore(BY_SEQ_STORE);
+  docStore = txn.objectStore(DOC_STORE);
+  docIdRevIndex = bySeqStore.index('_doc_id_rev');
 
-/***/ }),
-/* 485 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  var keyRange = (opts.since && !opts.descending) ?
+    IDBKeyRange.lowerBound(opts.since, true) : null;
 
-try {
-  var util = __webpack_require__(64);
-  if (typeof util.inherits !== 'function') throw '';
-  module.exports = util.inherits;
-} catch (e) {
-  module.exports = __webpack_require__(486);
+  runBatchedCursor(bySeqStore, keyRange, opts.descending, limit, onBatch);
 }
 
+var cachedDBs = new ExportedMap();
+var blobSupportPromise;
+var openReqList = new ExportedMap();
 
-/***/ }),
-/* 486 */
-/***/ ((module) => {
+function IdbPouch(opts, callback) {
+  var api = this;
 
-if (typeof Object.create === 'function') {
-  // implementation from standard node.js 'util' module
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    ctor.prototype = Object.create(superCtor.prototype, {
-      constructor: {
-        value: ctor,
-        enumerable: false,
-        writable: true,
-        configurable: true
-      }
-    });
-  };
-} else {
-  // old school shim for old browsers
-  module.exports = function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor
-    var TempCtor = function () {}
-    TempCtor.prototype = superCtor.prototype
-    ctor.prototype = new TempCtor()
-    ctor.prototype.constructor = ctor
-  }
+  enqueueTask(function (thisCallback) {
+    init(api, opts, thisCallback);
+  }, callback, api.constructor);
 }
 
+function init(api, opts, callback) {
 
-/***/ }),
-/* 487 */
-/***/ ((module) => {
-
-(function (factory) {
-    if (true) {
-        // Node/CommonJS
-        module.exports = factory();
-    } else { var glob; }
-}(function (undefined) {
+  var dbName = opts.name;
 
-    'use strict';
+  var idb = null;
+  api._meta = null;
 
-    /*
-     * Fastest md5 implementation around (JKM md5).
-     * Credits: Joseph Myers
-     *
-     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
-     * @see http://jsperf.com/md5-shootout/7
-     */
+  // called when creating a fresh new database
+  function createSchema(db) {
+    var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'});
+    db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
+      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+    db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
+    db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
+    db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
 
-    /* this function is much faster,
-      so if possible we use it. Some IEs
-      are the only ones I know of that
-      need the idiotic second function,
-      generated by an if clause.  */
-    var add32 = function (a, b) {
-        return (a + b) & 0xFFFFFFFF;
-    },
-        hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+    // added in v2
+    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
 
+    // added in v3
+    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'});
 
-    function cmn(q, a, b, x, s, t) {
-        a = add32(add32(a, q), add32(x, t));
-        return add32((a << s) | (a >>> (32 - s)), b);
-    }
+    // added in v4
+    var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+      {autoIncrement: true});
+    attAndSeqStore.createIndex('seq', 'seq');
+    attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+  }
 
-    function md5cycle(x, k) {
-        var a = x[0],
-            b = x[1],
-            c = x[2],
-            d = x[3];
+  // migration to version 2
+  // unfortunately "deletedOrLocal" is a misnomer now that we no longer
+  // store local docs in the main doc-store, but whaddyagonnado
+  function addDeletedOrLocalIndex(txn, callback) {
+    var docStore = txn.objectStore(DOC_STORE);
+    docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
 
-        a += (b & c | ~b & d) + k[0] - 680876936 | 0;
-        a  = (a << 7 | a >>> 25) + b | 0;
-        d += (a & b | ~a & c) + k[1] - 389564586 | 0;
-        d  = (d << 12 | d >>> 20) + a | 0;
-        c += (d & a | ~d & b) + k[2] + 606105819 | 0;
-        c  = (c << 17 | c >>> 15) + d | 0;
-        b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
-        b  = (b << 22 | b >>> 10) + c | 0;
-        a += (b & c | ~b & d) + k[4] - 176418897 | 0;
-        a  = (a << 7 | a >>> 25) + b | 0;
-        d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
-        d  = (d << 12 | d >>> 20) + a | 0;
-        c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
-        c  = (c << 17 | c >>> 15) + d | 0;
-        b += (c & d | ~c & a) + k[7] - 45705983 | 0;
-        b  = (b << 22 | b >>> 10) + c | 0;
-        a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
-        a  = (a << 7 | a >>> 25) + b | 0;
-        d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
-        d  = (d << 12 | d >>> 20) + a | 0;
-        c += (d & a | ~d & b) + k[10] - 42063 | 0;
-        c  = (c << 17 | c >>> 15) + d | 0;
-        b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
-        b  = (b << 22 | b >>> 10) + c | 0;
-        a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
-        a  = (a << 7 | a >>> 25) + b | 0;
-        d += (a & b | ~a & c) + k[13] - 40341101 | 0;
-        d  = (d << 12 | d >>> 20) + a | 0;
-        c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
-        c  = (c << 17 | c >>> 15) + d | 0;
-        b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
-        b  = (b << 22 | b >>> 10) + c | 0;
+    docStore.openCursor().onsuccess = function (event) {
+      var cursor = event.target.result;
+      if (cursor) {
+        var metadata = cursor.value;
+        var deleted = isDeleted(metadata);
+        metadata.deletedOrLocal = deleted ? "1" : "0";
+        docStore.put(metadata);
+        cursor.continue();
+      } else {
+        callback();
+      }
+    };
+  }
 
-        a += (b & d | c & ~d) + k[1] - 165796510 | 0;
-        a  = (a << 5 | a >>> 27) + b | 0;
-        d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
-        d  = (d << 9 | d >>> 23) + a | 0;
-        c += (d & b | a & ~b) + k[11] + 643717713 | 0;
-        c  = (c << 14 | c >>> 18) + d | 0;
-        b += (c & a | d & ~a) + k[0] - 373897302 | 0;
-        b  = (b << 20 | b >>> 12) + c | 0;
-        a += (b & d | c & ~d) + k[5] - 701558691 | 0;
-        a  = (a << 5 | a >>> 27) + b | 0;
-        d += (a & c | b & ~c) + k[10] + 38016083 | 0;
-        d  = (d << 9 | d >>> 23) + a | 0;
-        c += (d & b | a & ~b) + k[15] - 660478335 | 0;
-        c  = (c << 14 | c >>> 18) + d | 0;
-        b += (c & a | d & ~a) + k[4] - 405537848 | 0;
-        b  = (b << 20 | b >>> 12) + c | 0;
-        a += (b & d | c & ~d) + k[9] + 568446438 | 0;
-        a  = (a << 5 | a >>> 27) + b | 0;
-        d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
-        d  = (d << 9 | d >>> 23) + a | 0;
-        c += (d & b | a & ~b) + k[3] - 187363961 | 0;
-        c  = (c << 14 | c >>> 18) + d | 0;
-        b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
-        b  = (b << 20 | b >>> 12) + c | 0;
-        a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
-        a  = (a << 5 | a >>> 27) + b | 0;
-        d += (a & c | b & ~c) + k[2] - 51403784 | 0;
-        d  = (d << 9 | d >>> 23) + a | 0;
-        c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
-        c  = (c << 14 | c >>> 18) + d | 0;
-        b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
-        b  = (b << 20 | b >>> 12) + c | 0;
+  // migration to version 3 (part 1)
+  function createLocalStoreSchema(db) {
+    db.createObjectStore(LOCAL_STORE, {keyPath: '_id'})
+      .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+  }
 
-        a += (b ^ c ^ d) + k[5] - 378558 | 0;
-        a  = (a << 4 | a >>> 28) + b | 0;
-        d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
-        d  = (d << 11 | d >>> 21) + a | 0;
-        c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
-        c  = (c << 16 | c >>> 16) + d | 0;
-        b += (c ^ d ^ a) + k[14] - 35309556 | 0;
-        b  = (b << 23 | b >>> 9) + c | 0;
-        a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
-        a  = (a << 4 | a >>> 28) + b | 0;
-        d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
-        d  = (d << 11 | d >>> 21) + a | 0;
-        c += (d ^ a ^ b) + k[7] - 155497632 | 0;
-        c  = (c << 16 | c >>> 16) + d | 0;
-        b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
-        b  = (b << 23 | b >>> 9) + c | 0;
-        a += (b ^ c ^ d) + k[13] + 681279174 | 0;
-        a  = (a << 4 | a >>> 28) + b | 0;
-        d += (a ^ b ^ c) + k[0] - 358537222 | 0;
-        d  = (d << 11 | d >>> 21) + a | 0;
-        c += (d ^ a ^ b) + k[3] - 722521979 | 0;
-        c  = (c << 16 | c >>> 16) + d | 0;
-        b += (c ^ d ^ a) + k[6] + 76029189 | 0;
-        b  = (b << 23 | b >>> 9) + c | 0;
-        a += (b ^ c ^ d) + k[9] - 640364487 | 0;
-        a  = (a << 4 | a >>> 28) + b | 0;
-        d += (a ^ b ^ c) + k[12] - 421815835 | 0;
-        d  = (d << 11 | d >>> 21) + a | 0;
-        c += (d ^ a ^ b) + k[15] + 530742520 | 0;
-        c  = (c << 16 | c >>> 16) + d | 0;
-        b += (c ^ d ^ a) + k[2] - 995338651 | 0;
-        b  = (b << 23 | b >>> 9) + c | 0;
+  // migration to version 3 (part 2)
+  function migrateLocalStore(txn, cb) {
+    var localStore = txn.objectStore(LOCAL_STORE);
+    var docStore = txn.objectStore(DOC_STORE);
+    var seqStore = txn.objectStore(BY_SEQ_STORE);
 
-        a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
-        a  = (a << 6 | a >>> 26) + b | 0;
-        d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
-        d  = (d << 10 | d >>> 22) + a | 0;
-        c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
-        c  = (c << 15 | c >>> 17) + d | 0;
-        b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
-        b  = (b << 21 |b >>> 11) + c | 0;
-        a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
-        a  = (a << 6 | a >>> 26) + b | 0;
-        d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
-        d  = (d << 10 | d >>> 22) + a | 0;
-        c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
-        c  = (c << 15 | c >>> 17) + d | 0;
-        b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
-        b  = (b << 21 |b >>> 11) + c | 0;
-        a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
-        a  = (a << 6 | a >>> 26) + b | 0;
-        d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
-        d  = (d << 10 | d >>> 22) + a | 0;
-        c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
-        c  = (c << 15 | c >>> 17) + d | 0;
-        b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
-        b  = (b << 21 |b >>> 11) + c | 0;
-        a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
-        a  = (a << 6 | a >>> 26) + b | 0;
-        d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
-        d  = (d << 10 | d >>> 22) + a | 0;
-        c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
-        c  = (c << 15 | c >>> 17) + d | 0;
-        b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
-        b  = (b << 21 | b >>> 11) + c | 0;
+    var cursor = docStore.openCursor();
+    cursor.onsuccess = function (event) {
+      var cursor = event.target.result;
+      if (cursor) {
+        var metadata = cursor.value;
+        var docId = metadata.id;
+        var local = isLocalId(docId);
+        var rev = winningRev(metadata);
+        if (local) {
+          var docIdRev = docId + "::" + rev;
+          // remove all seq entries
+          // associated with this docId
+          var start = docId + "::";
+          var end = docId + "::~";
+          var index = seqStore.index('_doc_id_rev');
+          var range = IDBKeyRange.bound(start, end, false, false);
+          var seqCursor = index.openCursor(range);
+          seqCursor.onsuccess = function (e) {
+            seqCursor = e.target.result;
+            if (!seqCursor) {
+              // done
+              docStore.delete(cursor.primaryKey);
+              cursor.continue();
+            } else {
+              var data = seqCursor.value;
+              if (data._doc_id_rev === docIdRev) {
+                localStore.put(data);
+              }
+              seqStore.delete(seqCursor.primaryKey);
+              seqCursor.continue();
+            }
+          };
+        } else {
+          cursor.continue();
+        }
+      } else if (cb) {
+        cb();
+      }
+    };
+  }
 
-        x[0] = a + x[0] | 0;
-        x[1] = b + x[1] | 0;
-        x[2] = c + x[2] | 0;
-        x[3] = d + x[3] | 0;
-    }
+  // migration to version 4 (part 1)
+  function addAttachAndSeqStore(db) {
+    var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+      {autoIncrement: true});
+    attAndSeqStore.createIndex('seq', 'seq');
+    attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+  }
 
-    function md5blk(s) {
-        var md5blks = [],
-            i; /* Andy King said do it this way. */
+  // migration to version 4 (part 2)
+  function migrateAttsAndSeqs(txn, callback) {
+    var seqStore = txn.objectStore(BY_SEQ_STORE);
+    var attStore = txn.objectStore(ATTACH_STORE);
+    var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
 
-        for (i = 0; i < 64; i += 4) {
-            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+    // need to actually populate the table. this is the expensive part,
+    // so as an optimization, check first that this database even
+    // contains attachments
+    var req = attStore.count();
+    req.onsuccess = function (e) {
+      var count = e.target.result;
+      if (!count) {
+        return callback(); // done
+      }
+
+      seqStore.openCursor().onsuccess = function (e) {
+        var cursor = e.target.result;
+        if (!cursor) {
+          return callback(); // done
         }
-        return md5blks;
-    }
+        var doc = cursor.value;
+        var seq = cursor.primaryKey;
+        var atts = Object.keys(doc._attachments || {});
+        var digestMap = {};
+        for (var j = 0; j < atts.length; j++) {
+          var att = doc._attachments[atts[j]];
+          digestMap[att.digest] = true; // uniq digests, just in case
+        }
+        var digests = Object.keys(digestMap);
+        for (j = 0; j < digests.length; j++) {
+          var digest = digests[j];
+          attAndSeqStore.put({
+            seq: seq,
+            digestSeq: digest + '::' + seq
+          });
+        }
+        cursor.continue();
+      };
+    };
+  }
 
-    function md5blk_array(a) {
-        var md5blks = [],
-            i; /* Andy King said do it this way. */
+  // migration to version 5
+  // Instead of relying on on-the-fly migration of metadata,
+  // this brings the doc-store to its modern form:
+  // - metadata.winningrev
+  // - metadata.seq
+  // - stringify the metadata when storing it
+  function migrateMetadata(txn) {
 
-        for (i = 0; i < 64; i += 4) {
-            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
-        }
-        return md5blks;
+    function decodeMetadataCompat(storedObject) {
+      if (!storedObject.data) {
+        // old format, when we didn't store it stringified
+        storedObject.deleted = storedObject.deletedOrLocal === '1';
+        return storedObject;
+      }
+      return decodeMetadata(storedObject);
     }
 
-    function md51(s) {
-        var n = s.length,
-            state = [1732584193, -271733879, -1732584194, 271733878],
-            i,
-            length,
-            tail,
-            tmp,
-            lo,
-            hi;
+    // ensure that every metadata has a winningRev and seq,
+    // which was previously created on-the-fly but better to migrate
+    var bySeqStore = txn.objectStore(BY_SEQ_STORE);
+    var docStore = txn.objectStore(DOC_STORE);
+    var cursor = docStore.openCursor();
+    cursor.onsuccess = function (e) {
+      var cursor = e.target.result;
+      if (!cursor) {
+        return; // done
+      }
+      var metadata = decodeMetadataCompat(cursor.value);
 
-        for (i = 64; i <= n; i += 64) {
-            md5cycle(state, md5blk(s.substring(i - 64, i)));
-        }
-        s = s.substring(i - 64);
-        length = s.length;
-        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
-        }
-        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
-        if (i > 55) {
-            md5cycle(state, tail);
-            for (i = 0; i < 16; i += 1) {
-                tail[i] = 0;
-            }
-        }
+      metadata.winningRev = metadata.winningRev ||
+        winningRev(metadata);
 
-        // Beware that the final length might not fit in 32 bits so we take care of that
-        tmp = n * 8;
-        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
-        lo = parseInt(tmp[2], 16);
-        hi = parseInt(tmp[1], 16) || 0;
+      function fetchMetadataSeq() {
+        // metadata.seq was added post-3.2.0, so if it's missing,
+        // we need to fetch it manually
+        var start = metadata.id + '::';
+        var end = metadata.id + '::\uffff';
+        var req = bySeqStore.index('_doc_id_rev').openCursor(
+          IDBKeyRange.bound(start, end));
 
-        tail[14] = lo;
-        tail[15] = hi;
+        var metadataSeq = 0;
+        req.onsuccess = function (e) {
+          var cursor = e.target.result;
+          if (!cursor) {
+            metadata.seq = metadataSeq;
+            return onGetMetadataSeq();
+          }
+          var seq = cursor.primaryKey;
+          if (seq > metadataSeq) {
+            metadataSeq = seq;
+          }
+          cursor.continue();
+        };
+      }
 
-        md5cycle(state, tail);
-        return state;
-    }
+      function onGetMetadataSeq() {
+        var metadataToStore = encodeMetadata(metadata,
+          metadata.winningRev, metadata.deleted);
 
-    function md51_array(a) {
-        var n = a.length,
-            state = [1732584193, -271733879, -1732584194, 271733878],
-            i,
-            length,
-            tail,
-            tmp,
-            lo,
-            hi;
+        var req = docStore.put(metadataToStore);
+        req.onsuccess = function () {
+          cursor.continue();
+        };
+      }
 
-        for (i = 64; i <= n; i += 64) {
-            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
-        }
+      if (metadata.seq) {
+        return onGetMetadataSeq();
+      }
 
-        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
-        // containing the last element of the parent array if the sub array specified starts
-        // beyond the length of the parent array - weird.
-        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
-        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+      fetchMetadataSeq();
+    };
 
-        length = a.length;
-        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= a[i] << ((i % 4) << 3);
-        }
+  }
 
-        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
-        if (i > 55) {
-            md5cycle(state, tail);
-            for (i = 0; i < 16; i += 1) {
-                tail[i] = 0;
-            }
-        }
+  api._remote = false;
+  api.type = function () {
+    return 'idb';
+  };
 
-        // Beware that the final length might not fit in 32 bits so we take care of that
-        tmp = n * 8;
-        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
-        lo = parseInt(tmp[2], 16);
-        hi = parseInt(tmp[1], 16) || 0;
+  api._id = toPromise(function (callback) {
+    callback(null, api._meta.instanceId);
+  });
 
-        tail[14] = lo;
-        tail[15] = hi;
+  api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) {
+    idbBulkDocs(opts, req, reqOpts, api, idb, callback);
+  };
 
-        md5cycle(state, tail);
+  // First we look up the metadata in the ids database, then we fetch the
+  // current revision(s) from the by sequence store
+  api._get = function idb_get(id, opts, callback) {
+    var doc;
+    var metadata;
+    var err;
+    var txn = opts.ctx;
+    if (!txn) {
+      var txnResult = openTransactionSafely(idb,
+        [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      txn = txnResult.txn;
+    }
 
-        return state;
+    function finish() {
+      callback(err, {doc: doc, metadata: metadata, ctx: txn});
     }
 
-    function rhex(n) {
-        var s = '',
-            j;
-        for (j = 0; j < 4; j += 1) {
-            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+    txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
+      metadata = decodeMetadata(e.target.result);
+      // we can determine the result here if:
+      // 1. there is no such document
+      // 2. the document is deleted and we don't ask about specific rev
+      // When we ask with opts.rev we expect the answer to be either
+      // doc (possibly with _deleted=true) or missing error
+      if (!metadata) {
+        err = createError(MISSING_DOC, 'missing');
+        return finish();
+      }
+
+      var rev;
+      if (!opts.rev) {
+        rev = metadata.winningRev;
+        var deleted = isDeleted(metadata);
+        if (deleted) {
+          err = createError(MISSING_DOC, "deleted");
+          return finish();
         }
-        return s;
-    }
+      } else {
+        rev = opts.latest ? latest(opts.rev, metadata) : opts.rev;
+      }
 
-    function hex(x) {
-        var i;
-        for (i = 0; i < x.length; i += 1) {
-            x[i] = rhex(x[i]);
+      var objectStore = txn.objectStore(BY_SEQ_STORE);
+      var key = metadata.id + '::' + rev;
+
+      objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
+        doc = e.target.result;
+        if (doc) {
+          doc = decodeDoc(doc);
         }
-        return x.join('');
-    }
+        if (!doc) {
+          err = createError(MISSING_DOC, 'missing');
+          return finish();
+        }
+        finish();
+      };
+    };
+  };
 
-    // In some cases the fast add32 function cannot be used..
-    if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
-        add32 = function (x, y) {
-            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
-                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-            return (msw << 16) | (lsw & 0xFFFF);
-        };
+  api._getAttachment = function (docId, attachId, attachment, opts, callback) {
+    var txn;
+    if (opts.ctx) {
+      txn = opts.ctx;
+    } else {
+      var txnResult = openTransactionSafely(idb,
+        [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      txn = txnResult.txn;
     }
+    var digest = attachment.digest;
+    var type = attachment.content_type;
 
-    // ---------------------------------------------------
+    txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
+      var body = e.target.result.body;
+      readBlobData(body, type, opts.binary, function (blobData) {
+        callback(null, blobData);
+      });
+    };
+  };
 
-    /**
-     * ArrayBuffer slice polyfill.
-     *
-     * @see https://github.com/ttaubert/node-arraybuffer-slice
-     */
+  api._info = function idb_info(callback) {
+    var updateSeq;
+    var docCount;
 
-    if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
-        (function () {
-            function clamp(val, length) {
-                val = (val | 0) || 0;
+    var txnResult = openTransactionSafely(idb, [META_STORE, BY_SEQ_STORE], 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
+    txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
+      docCount = e.target.result.docCount;
+    };
+    txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev').onsuccess = function (e) {
+      var cursor = e.target.result;
+      updateSeq = cursor ? cursor.key : 0;
+    };
 
-                if (val < 0) {
-                    return Math.max(val + length, 0);
-                }
+    txn.oncomplete = function () {
+      callback(null, {
+        doc_count: docCount,
+        update_seq: updateSeq,
+        // for debugging
+        idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64')
+      });
+    };
+  };
 
-                return Math.min(val, length);
-            }
+  api._allDocs = function idb_allDocs(opts, callback) {
+    idbAllDocs(opts, idb, callback);
+  };
 
-            ArrayBuffer.prototype.slice = function (from, to) {
-                var length = this.byteLength,
-                    begin = clamp(from, length),
-                    end = length,
-                    num,
-                    target,
-                    targetArray,
-                    sourceArray;
+  api._changes = function idbChanges(opts) {
+    return changes(opts, api, dbName, idb);
+  };
 
-                if (to !== undefined) {
-                    end = clamp(to, length);
-                }
+  api._close = function (callback) {
+    // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
+    // "Returns immediately and closes the connection in a separate thread..."
+    idb.close();
+    cachedDBs.delete(dbName);
+    callback();
+  };
 
-                if (begin > end) {
-                    return new ArrayBuffer(0);
-                }
+  api._getRevisionTree = function (docId, callback) {
+    var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
+    var req = txn.objectStore(DOC_STORE).get(docId);
+    req.onsuccess = function (event) {
+      var doc = decodeMetadata(event.target.result);
+      if (!doc) {
+        callback(createError(MISSING_DOC));
+      } else {
+        callback(null, doc.rev_tree);
+      }
+    };
+  };
 
-                num = end - begin;
-                target = new ArrayBuffer(num);
-                targetArray = new Uint8Array(target);
+  // This function removes revisions of document docId
+  // which are listed in revs and sets this document
+  // revision to to rev_tree
+  api._doCompaction = function (docId, revs, callback) {
+    var stores = [
+      DOC_STORE,
+      BY_SEQ_STORE,
+      ATTACH_STORE,
+      ATTACH_AND_SEQ_STORE
+    ];
+    var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+    if (txnResult.error) {
+      return callback(txnResult.error);
+    }
+    var txn = txnResult.txn;
 
-                sourceArray = new Uint8Array(this, begin, num);
-                targetArray.set(sourceArray);
+    var docStore = txn.objectStore(DOC_STORE);
 
-                return target;
-            };
-        })();
+    docStore.get(docId).onsuccess = function (event) {
+      var metadata = decodeMetadata(event.target.result);
+      traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+                                                         revHash, ctx, opts) {
+        var rev = pos + '-' + revHash;
+        if (revs.indexOf(rev) !== -1) {
+          opts.status = 'missing';
+        }
+      });
+      compactRevs(revs, docId, txn);
+      var winningRev$$1 = metadata.winningRev;
+      var deleted = metadata.deleted;
+      txn.objectStore(DOC_STORE).put(
+        encodeMetadata(metadata, winningRev$$1, deleted));
+    };
+    txn.onabort = idbError(callback);
+    txn.oncomplete = function () {
+      callback();
+    };
+  };
+
+
+  api._getLocal = function (id, callback) {
+    var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly');
+    if (txnResult.error) {
+      return callback(txnResult.error);
     }
+    var tx = txnResult.txn;
+    var req = tx.objectStore(LOCAL_STORE).get(id);
 
-    // ---------------------------------------------------
+    req.onerror = idbError(callback);
+    req.onsuccess = function (e) {
+      var doc = e.target.result;
+      if (!doc) {
+        callback(createError(MISSING_DOC));
+      } else {
+        delete doc['_doc_id_rev']; // for backwards compat
+        callback(null, doc);
+      }
+    };
+  };
 
-    /**
-     * Helpers.
-     */
+  api._putLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    delete doc._revisions; // ignore this, trust the rev
+    var oldRev = doc._rev;
+    var id = doc._id;
+    if (!oldRev) {
+      doc._rev = '0-1';
+    } else {
+      doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
+    }
 
-    function toUtf8(str) {
-        if (/[\u0080-\uFFFF]/.test(str)) {
-            str = unescape(encodeURIComponent(str));
+    var tx = opts.ctx;
+    var ret;
+    if (!tx) {
+      var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      tx = txnResult.txn;
+      tx.onerror = idbError(callback);
+      tx.oncomplete = function () {
+        if (ret) {
+          callback(null, ret);
         }
+      };
+    }
 
-        return str;
+    var oStore = tx.objectStore(LOCAL_STORE);
+    var req;
+    if (oldRev) {
+      req = oStore.get(id);
+      req.onsuccess = function (e) {
+        var oldDoc = e.target.result;
+        if (!oldDoc || oldDoc._rev !== oldRev) {
+          callback(createError(REV_CONFLICT));
+        } else { // update
+          var req = oStore.put(doc);
+          req.onsuccess = function () {
+            ret = {ok: true, id: doc._id, rev: doc._rev};
+            if (opts.ctx) { // return immediately
+              callback(null, ret);
+            }
+          };
+        }
+      };
+    } else { // new doc
+      req = oStore.add(doc);
+      req.onerror = function (e) {
+        // constraint error, already exists
+        callback(createError(REV_CONFLICT));
+        e.preventDefault(); // avoid transaction abort
+        e.stopPropagation(); // avoid transaction onerror
+      };
+      req.onsuccess = function () {
+        ret = {ok: true, id: doc._id, rev: doc._rev};
+        if (opts.ctx) { // return immediately
+          callback(null, ret);
+        }
+      };
     }
+  };
 
-    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
-        var length = str.length,
-           buff = new ArrayBuffer(length),
-           arr = new Uint8Array(buff),
-           i;
+  api._removeLocal = function (doc, opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    var tx = opts.ctx;
+    if (!tx) {
+      var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+      if (txnResult.error) {
+        return callback(txnResult.error);
+      }
+      tx = txnResult.txn;
+      tx.oncomplete = function () {
+        if (ret) {
+          callback(null, ret);
+        }
+      };
+    }
+    var ret;
+    var id = doc._id;
+    var oStore = tx.objectStore(LOCAL_STORE);
+    var req = oStore.get(id);
 
-        for (i = 0; i < length; i += 1) {
-            arr[i] = str.charCodeAt(i);
+    req.onerror = idbError(callback);
+    req.onsuccess = function (e) {
+      var oldDoc = e.target.result;
+      if (!oldDoc || oldDoc._rev !== doc._rev) {
+        callback(createError(MISSING_DOC));
+      } else {
+        oStore.delete(id);
+        ret = {ok: true, id: id, rev: '0-0'};
+        if (opts.ctx) { // return immediately
+          callback(null, ret);
         }
+      }
+    };
+  };
 
-        return returnUInt8Array ? arr : buff;
-    }
+  api._destroy = function (opts, callback) {
+    changesHandler.removeAllListeners(dbName);
 
-    function arrayBuffer2Utf8Str(buff) {
-        return String.fromCharCode.apply(null, new Uint8Array(buff));
+    //Close open request for "dbName" database to fix ie delay.
+    var openReq = openReqList.get(dbName);
+    if (openReq && openReq.result) {
+      openReq.result.close();
+      cachedDBs.delete(dbName);
     }
+    var req = indexedDB.deleteDatabase(dbName);
 
-    function concatenateArrayBuffers(first, second, returnUInt8Array) {
-        var result = new Uint8Array(first.byteLength + second.byteLength);
+    req.onsuccess = function () {
+      //Remove open request from the list.
+      openReqList.delete(dbName);
+      if (hasLocalStorage() && (dbName in localStorage)) {
+        delete localStorage[dbName];
+      }
+      callback(null, { 'ok': true });
+    };
 
-        result.set(new Uint8Array(first));
-        result.set(new Uint8Array(second), first.byteLength);
+    req.onerror = idbError(callback);
+  };
 
-        return returnUInt8Array ? result : result.buffer;
-    }
+  var cached = cachedDBs.get(dbName);
 
-    function hexToBinaryString(hex) {
-        var bytes = [],
-            length = hex.length,
-            x;
+  if (cached) {
+    idb = cached.idb;
+    api._meta = cached.global;
+    return immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+      callback(null, api);
+    });
+  }
 
-        for (x = 0; x < length - 1; x += 2) {
-            bytes.push(parseInt(hex.substr(x, 2), 16));
-        }
+  var req = indexedDB.open(dbName, ADAPTER_VERSION);
+  openReqList.set(dbName, req);
 
-        return String.fromCharCode.apply(String, bytes);
+  req.onupgradeneeded = function (e) {
+    var db = e.target.result;
+    if (e.oldVersion < 1) {
+      return createSchema(db); // new db, initial schema
     }
+    // do migrations
 
-    // ---------------------------------------------------
-
-    /**
-     * SparkMD5 OOP implementation.
-     *
-     * Use this class to perform an incremental md5, otherwise use the
-     * static methods instead.
-     */
+    var txn = e.currentTarget.transaction;
+    // these migrations have to be done in this function, before
+    // control is returned to the event loop, because IndexedDB
 
-    function SparkMD5() {
-        // call reset to init the instance
-        this.reset();
+    if (e.oldVersion < 3) {
+      createLocalStoreSchema(db); // v2 -> v3
+    }
+    if (e.oldVersion < 4) {
+      addAttachAndSeqStore(db); // v3 -> v4
     }
 
-    /**
-     * Appends a string.
-     * A conversion will be applied if an utf8 string is detected.
-     *
-     * @param {String} str The string to be appended
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.append = function (str) {
-        // Converts the string to utf8 bytes if necessary
-        // Then append as binary
-        this.appendBinary(toUtf8(str));
+    var migrations = [
+      addDeletedOrLocalIndex, // v1 -> v2
+      migrateLocalStore,      // v2 -> v3
+      migrateAttsAndSeqs,     // v3 -> v4
+      migrateMetadata         // v4 -> v5
+    ];
 
-        return this;
-    };
+    var i = e.oldVersion;
 
-    /**
-     * Appends a binary string.
-     *
-     * @param {String} contents The binary string to be appended
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.appendBinary = function (contents) {
-        this._buff += contents;
-        this._length += contents.length;
+    function next() {
+      var migration = migrations[i - 1];
+      i++;
+      if (migration) {
+        migration(txn, next);
+      }
+    }
 
-        var length = this._buff.length,
-            i;
+    next();
+  };
 
-        for (i = 64; i <= length; i += 64) {
-            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
-        }
+  req.onsuccess = function (e) {
 
-        this._buff = this._buff.substring(i - 64);
+    idb = e.target.result;
 
-        return this;
+    idb.onversionchange = function () {
+      idb.close();
+      cachedDBs.delete(dbName);
     };
 
-    /**
-     * Finishes the incremental computation, reseting the internal state and
-     * returning the result.
-     *
-     * @param {Boolean} raw True to get the raw string, false to get the hex string
-     *
-     * @return {String} The result
-     */
-    SparkMD5.prototype.end = function (raw) {
-        var buff = this._buff,
-            length = buff.length,
-            i,
-            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            ret;
+    idb.onabort = function (e) {
+      guardedConsole('error', 'Database has a global failure', e.target.error);
+      idb.close();
+      cachedDBs.delete(dbName);
+    };
 
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
-        }
+    // Do a few setup operations (in parallel as much as possible):
+    // 1. Fetch meta doc
+    // 2. Check blob support
+    // 3. Calculate docCount
+    // 4. Generate an instanceId if necessary
+    // 5. Store docCount and instanceId on meta doc
 
-        this._finish(tail, length);
-        ret = hex(this._hash);
+    var txn = idb.transaction([
+      META_STORE,
+      DETECT_BLOB_SUPPORT_STORE,
+      DOC_STORE
+    ], 'readwrite');
 
-        if (raw) {
-            ret = hexToBinaryString(ret);
-        }
+    var storedMetaDoc = false;
+    var metaDoc;
+    var docCount;
+    var blobSupport;
+    var instanceId;
 
-        this.reset();
+    function completeSetup() {
+      if (typeof blobSupport === 'undefined' || !storedMetaDoc) {
+        return;
+      }
+      api._meta = {
+        name: dbName,
+        instanceId: instanceId,
+        blobSupport: blobSupport
+      };
 
-        return ret;
-    };
+      cachedDBs.set(dbName, {
+        idb: idb,
+        global: api._meta
+      });
+      callback(null, api);
+    }
 
-    /**
-     * Resets the internal state of the computation.
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.reset = function () {
-        this._buff = '';
-        this._length = 0;
-        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+    function storeMetaDocIfReady() {
+      if (typeof docCount === 'undefined' || typeof metaDoc === 'undefined') {
+        return;
+      }
+      var instanceKey = dbName + '_id';
+      if (instanceKey in metaDoc) {
+        instanceId = metaDoc[instanceKey];
+      } else {
+        metaDoc[instanceKey] = instanceId = uuid();
+      }
+      metaDoc.docCount = docCount;
+      txn.objectStore(META_STORE).put(metaDoc);
+    }
 
-        return this;
+    //
+    // fetch or generate the instanceId
+    //
+    txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
+      metaDoc = e.target.result || { id: META_STORE };
+      storeMetaDocIfReady();
     };
 
-    /**
-     * Gets the internal state of the computation.
-     *
-     * @return {Object} The state
-     */
-    SparkMD5.prototype.getState = function () {
-        return {
-            buff: this._buff,
-            length: this._length,
-            hash: this._hash
-        };
-    };
+    //
+    // countDocs
+    //
+    countDocs(txn, function (count) {
+      docCount = count;
+      storeMetaDocIfReady();
+    });
 
-    /**
-     * Gets the internal state of the computation.
-     *
-     * @param {Object} state The state
-     *
-     * @return {SparkMD5} The instance itself
-     */
-    SparkMD5.prototype.setState = function (state) {
-        this._buff = state.buff;
-        this._length = state.length;
-        this._hash = state.hash;
+    //
+    // check blob support
+    //
+    if (!blobSupportPromise) {
+      // make sure blob support is only checked once
+      blobSupportPromise = checkBlobSupport(txn);
+    }
 
-        return this;
-    };
+    blobSupportPromise.then(function (val) {
+      blobSupport = val;
+      completeSetup();
+    });
 
-    /**
-     * Releases memory used by the incremental buffer and other additional
-     * resources. If you plan to use the instance again, use reset instead.
-     */
-    SparkMD5.prototype.destroy = function () {
-        delete this._hash;
-        delete this._buff;
-        delete this._length;
+    // only when the metadata put transaction has completed,
+    // consider the setup done
+    txn.oncomplete = function () {
+      storedMetaDoc = true;
+      completeSetup();
     };
+    txn.onabort = idbError(callback);
+  };
 
-    /**
-     * Finish the final calculation based on the tail.
-     *
-     * @param {Array}  tail   The tail (will be modified)
-     * @param {Number} length The length of the remaining buffer
-     */
-    SparkMD5.prototype._finish = function (tail, length) {
-        var i = length,
-            tmp,
-            lo,
-            hi;
+  req.onerror = function () {
+    var msg = 'Failed to open indexedDB, are you in private browsing mode?';
+    guardedConsole('error', msg);
+    callback(createError(IDB_ERROR, msg));
+  };
+}
 
-        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
-        if (i > 55) {
-            md5cycle(this._hash, tail);
-            for (i = 0; i < 16; i += 1) {
-                tail[i] = 0;
-            }
-        }
+IdbPouch.valid = function () {
+  // Following #7085 buggy idb versions (typically Safari < 10.1) are
+  // considered valid.
 
-        // Do the final computation based on the tail and length
-        // Beware that the final length may not fit in 32 bits so we take care of that
-        tmp = this._length * 8;
-        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
-        lo = parseInt(tmp[2], 16);
-        hi = parseInt(tmp[1], 16) || 0;
+  // On Firefox SecurityError is thrown while referencing indexedDB if cookies
+  // are not allowed. `typeof indexedDB` also triggers the error.
+  try {
+    // some outdated implementations of IDB that appear on Samsung
+    // and HTC Android devices <4.4 are missing IDBKeyRange
+    return typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined';
+  } catch (e) {
+    return false;
+  }
+};
 
-        tail[14] = lo;
-        tail[15] = hi;
-        md5cycle(this._hash, tail);
-    };
+function IDBPouch (PouchDB) {
+  PouchDB.adapter('idb', IdbPouch, true);
+}
 
-    /**
-     * Performs the md5 hash on a string.
-     * A conversion will be applied if utf8 string is detected.
-     *
-     * @param {String}  str The string
-     * @param {Boolean} raw True to get the raw string, false to get the hex string
-     *
-     * @return {String} The result
-     */
-    SparkMD5.hash = function (str, raw) {
-        // Converts the string to utf8 bytes if necessary
-        // Then compute it using the binary function
-        return SparkMD5.hashBinary(toUtf8(str), raw);
-    };
+// dead simple promise pool, inspired by https://github.com/timdp/es6-promise-pool
+// but much smaller in code size. limits the number of concurrent promises that are executed
 
-    /**
-     * Performs the md5 hash on a binary string.
-     *
-     * @param {String}  content The binary string
-     * @param {Boolean} raw     True to get the raw string, false to get the hex string
-     *
-     * @return {String} The result
-     */
-    SparkMD5.hashBinary = function (content, raw) {
-        var hash = md51(content),
-            ret = hex(hash);
 
-        return raw ? hexToBinaryString(ret) : ret;
-    };
+function pool(promiseFactories, limit) {
+  return new Promise(function (resolve, reject) {
+    var running = 0;
+    var current = 0;
+    var done = 0;
+    var len = promiseFactories.length;
+    var err;
 
-    // ---------------------------------------------------
+    function runNext() {
+      running++;
+      promiseFactories[current++]().then(onSuccess, onError);
+    }
 
-    /**
-     * SparkMD5 OOP implementation for array buffers.
-     *
-     * Use this class to perform an incremental md5 ONLY for array buffers.
-     */
-    SparkMD5.ArrayBuffer = function () {
-        // call reset to init the instance
-        this.reset();
-    };
+    function doNext() {
+      if (++done === len) {
+        /* istanbul ignore if */
+        if (err) {
+          reject(err);
+        } else {
+          resolve();
+        }
+      } else {
+        runNextBatch();
+      }
+    }
 
-    /**
-     * Appends an array buffer.
-     *
-     * @param {ArrayBuffer} arr The array to be appended
-     *
-     * @return {SparkMD5.ArrayBuffer} The instance itself
-     */
-    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
-        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
-            length = buff.length,
-            i;
+    function onSuccess() {
+      running--;
+      doNext();
+    }
 
-        this._length += arr.byteLength;
+    /* istanbul ignore next */
+    function onError(thisErr) {
+      running--;
+      err = err || thisErr;
+      doNext();
+    }
 
-        for (i = 64; i <= length; i += 64) {
-            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
-        }
+    function runNextBatch() {
+      while (running < limit && current < len) {
+        runNext();
+      }
+    }
 
-        this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+    runNextBatch();
+  });
+}
 
-        return this;
-    };
+var CHANGES_BATCH_SIZE = 25;
+var MAX_SIMULTANEOUS_REVS = 50;
+var CHANGES_TIMEOUT_BUFFER = 5000;
+var DEFAULT_HEARTBEAT = 10000;
 
-    /**
-     * Finishes the incremental computation, reseting the internal state and
-     * returning the result.
-     *
-     * @param {Boolean} raw True to get the raw string, false to get the hex string
-     *
-     * @return {String} The result
-     */
-    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
-        var buff = this._buff,
-            length = buff.length,
-            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            i,
-            ret;
+var supportsBulkGetMap = {};
 
-        for (i = 0; i < length; i += 1) {
-            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
-        }
+function readAttachmentsAsBlobOrBuffer(row) {
+  var doc = row.doc || row.ok;
+  var atts = doc._attachments;
+  if (!atts) {
+    return;
+  }
+  Object.keys(atts).forEach(function (filename) {
+    var att = atts[filename];
+    att.data = b64ToBluffer(att.data, att.content_type);
+  });
+}
 
-        this._finish(tail, length);
-        ret = hex(this._hash);
+function encodeDocId(id) {
+  if (/^_design/.test(id)) {
+    return '_design/' + encodeURIComponent(id.slice(8));
+  }
+  if (/^_local/.test(id)) {
+    return '_local/' + encodeURIComponent(id.slice(7));
+  }
+  return encodeURIComponent(id);
+}
 
-        if (raw) {
-            ret = hexToBinaryString(ret);
-        }
+function preprocessAttachments$1(doc) {
+  if (!doc._attachments || !Object.keys(doc._attachments)) {
+    return Promise.resolve();
+  }
 
-        this.reset();
+  return Promise.all(Object.keys(doc._attachments).map(function (key) {
+    var attachment = doc._attachments[key];
+    if (attachment.data && typeof attachment.data !== 'string') {
+      return new Promise(function (resolve) {
+        blobToBase64(attachment.data, resolve);
+      }).then(function (b64) {
+        attachment.data = b64;
+      });
+    }
+  }));
+}
 
-        return ret;
-    };
+function hasUrlPrefix(opts) {
+  if (!opts.prefix) {
+    return false;
+  }
+  var protocol = parseUri(opts.prefix).protocol;
+  return protocol === 'http' || protocol === 'https';
+}
 
-    /**
-     * Resets the internal state of the computation.
-     *
-     * @return {SparkMD5.ArrayBuffer} The instance itself
-     */
-    SparkMD5.ArrayBuffer.prototype.reset = function () {
-        this._buff = new Uint8Array(0);
-        this._length = 0;
-        this._hash = [1732584193, -271733879, -1732584194, 271733878];
+// Get all the information you possibly can about the URI given by name and
+// return it as a suitable object.
+function getHost(name, opts) {
+  // encode db name if opts.prefix is a url (#5574)
+  if (hasUrlPrefix(opts)) {
+    var dbName = opts.name.substr(opts.prefix.length);
+    // Ensure prefix has a trailing slash
+    var prefix = opts.prefix.replace(/\/?$/, '/');
+    name = prefix + encodeURIComponent(dbName);
+  }
 
-        return this;
-    };
+  var uri = parseUri(name);
+  if (uri.user || uri.password) {
+    uri.auth = {username: uri.user, password: uri.password};
+  }
 
-    /**
-     * Gets the internal state of the computation.
-     *
-     * @return {Object} The state
-     */
-    SparkMD5.ArrayBuffer.prototype.getState = function () {
-        var state = SparkMD5.prototype.getState.call(this);
+  // Split the path part of the URI into parts using '/' as the delimiter
+  // after removing any leading '/' and any trailing '/'
+  var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
 
-        // Convert buffer to a string
-        state.buff = arrayBuffer2Utf8Str(state.buff);
+  uri.db = parts.pop();
+  // Prevent double encoding of URI component
+  if (uri.db.indexOf('%') === -1) {
+    uri.db = encodeURIComponent(uri.db);
+  }
 
-        return state;
-    };
+  uri.path = parts.join('/');
 
-    /**
-     * Gets the internal state of the computation.
-     *
-     * @param {Object} state The state
-     *
-     * @return {SparkMD5.ArrayBuffer} The instance itself
-     */
-    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
-        // Convert string to buffer
-        state.buff = utf8Str2ArrayBuffer(state.buff, true);
+  return uri;
+}
 
-        return SparkMD5.prototype.setState.call(this, state);
-    };
+// Generate a URL with the host data given by opts and the given path
+function genDBUrl(opts, path) {
+  return genUrl(opts, opts.db + '/' + path);
+}
 
-    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+// Generate a URL with the host data given by opts and the given path
+function genUrl(opts, path) {
+  // If the host already has a path, then we need to have a path delimiter
+  // Otherwise, the path delimiter is the empty string
+  var pathDel = !opts.path ? '' : '/';
 
-    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+  // If the host already has a path, then we need to have a path delimiter
+  // Otherwise, the path delimiter is the empty string
+  return opts.protocol + '://' + opts.host +
+         (opts.port ? (':' + opts.port) : '') +
+         '/' + opts.path + pathDel + path;
+}
 
-    /**
-     * Performs the md5 hash on an array buffer.
-     *
-     * @param {ArrayBuffer} arr The array buffer
-     * @param {Boolean}     raw True to get the raw string, false to get the hex one
-     *
-     * @return {String} The result
-     */
-    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
-        var hash = md51_array(new Uint8Array(arr)),
-            ret = hex(hash);
+function paramsToStr(params) {
+  return '?' + Object.keys(params).map(function (k) {
+    return k + '=' + encodeURIComponent(params[k]);
+  }).join('&');
+}
 
-        return raw ? hexToBinaryString(ret) : ret;
-    };
+function shouldCacheBust(opts) {
+  var ua = (typeof navigator !== 'undefined' && navigator.userAgent) ?
+      navigator.userAgent.toLowerCase() : '';
+  var isIE = ua.indexOf('msie') !== -1;
+  var isTrident = ua.indexOf('trident') !== -1;
+  var isEdge = ua.indexOf('edge') !== -1;
+  var isGET = !('method' in opts) || opts.method === 'GET';
+  return (isIE || isTrident || isEdge) && isGET;
+}
 
-    return SparkMD5;
-}));
+// Implements the PouchDB API for dealing with CouchDB instances over HTTP
+function HttpPouch(opts, callback) {
 
+  // The functions that will be publicly available for HttpPouch
+  var api = this;
 
-/***/ }),
-/* 488 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  var host = getHost(opts.name, opts);
+  var dbUrl = genDBUrl(host, '');
 
-var v1 = __webpack_require__(489);
-var v4 = __webpack_require__(492);
+  opts = clone(opts);
 
-var uuid = v4;
-uuid.v1 = v1;
-uuid.v4 = v4;
+  var ourFetch = function (url, options) {
 
-module.exports = uuid;
+    options = options || {};
+    options.headers = options.headers || new h();
 
+    if (opts.auth || host.auth) {
+      var nAuth = opts.auth || host.auth;
+      var str = nAuth.username + ':' + nAuth.password;
+      var token = thisBtoa(unescape(encodeURIComponent(str)));
+      options.headers.set('Authorization', 'Basic ' + token);
+    }
 
-/***/ }),
-/* 489 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    var headers = opts.headers || {};
+    Object.keys(headers).forEach(function (key) {
+      options.headers.append(key, headers[key]);
+    });
 
-var rng = __webpack_require__(490);
-var bytesToUuid = __webpack_require__(491);
+    /* istanbul ignore if */
+    if (shouldCacheBust(options)) {
+      url += (url.indexOf('?') === -1 ? '?' : '&') + '_nonce=' + Date.now();
+    }
 
-// **`v1()` - Generate time-based UUID**
-//
-// Inspired by https://github.com/LiosK/UUID.js
-// and http://docs.python.org/library/uuid.html
+    var fetchFun = opts.fetch || f$1;
+    return fetchFun(url, options);
+  };
 
-var _nodeId;
-var _clockseq;
+  function adapterFun$$1(name, fun) {
+    return adapterFun(name, argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
+      setup().then(function () {
+        return fun.apply(this, args);
+      }).catch(function (e) {
+        var callback = args.pop();
+        callback(e);
+      });
+    })).bind(api);
+  }
 
-// Previous uuid creation time
-var _lastMSecs = 0;
-var _lastNSecs = 0;
+  function fetchJSON(url, options, callback) {
 
-// See https://github.com/broofa/node-uuid for API details
-function v1(options, buf, offset) {
-  var i = buf && offset || 0;
-  var b = buf || [];
+    var result = {};
 
-  options = options || {};
-  var node = options.node || _nodeId;
-  var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
+    options = options || {};
+    options.headers = options.headers || new h();
 
-  // node and clockseq need to be initialized to random values if they're not
-  // specified.  We do this lazily to minimize issues related to insufficient
-  // system entropy.  See #189
-  if (node == null || clockseq == null) {
-    var seedBytes = rng();
-    if (node == null) {
-      // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
-      node = _nodeId = [
-        seedBytes[0] | 0x01,
-        seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]
-      ];
+    if (!options.headers.get('Content-Type')) {
+      options.headers.set('Content-Type', 'application/json');
     }
-    if (clockseq == null) {
-      // Per 4.2.2, randomize (14 bit) clockseq
-      clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
+    if (!options.headers.get('Accept')) {
+      options.headers.set('Accept', 'application/json');
     }
-  }
-
-  // UUID timestamps are 100 nano-second units since the Gregorian epoch,
-  // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
-  // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
-  // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
-  var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
 
-  // Per 4.2.1.2, use count of uuid's generated during the current clock
-  // cycle to simulate higher resolution clock
-  var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
+    return ourFetch(url, options).then(function (response) {
+      result.ok = response.ok;
+      result.status = response.status;
+      return response.json();
+    }).then(function (json) {
+      result.data = json;
+      if (!result.ok) {
+        result.data.status = result.status;
+        var err = generateErrorFromResponse(result.data);
+        if (callback) {
+          return callback(err);
+        } else {
+          throw err;
+        }
+      }
 
-  // Time since last uuid creation (in msecs)
-  var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
+      if (Array.isArray(result.data)) {
+        result.data = result.data.map(function (v) {
+          if (v.error || v.missing) {
+            return generateErrorFromResponse(v);
+          } else {
+            return v;
+          }
+        });
+      }
 
-  // Per 4.2.1.2, Bump clockseq on clock regression
-  if (dt < 0 && options.clockseq === undefined) {
-    clockseq = clockseq + 1 & 0x3fff;
+      if (callback) {
+        callback(null, result.data);
+      } else {
+        return result;
+      }
+    });
   }
 
-  // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
-  // time interval
-  if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
-    nsecs = 0;
-  }
+  var setupPromise;
 
-  // Per 4.2.1.2 Throw error if too many uuids are requested
-  if (nsecs >= 10000) {
-    throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
-  }
+  function setup() {
+    if (opts.skip_setup) {
+      return Promise.resolve();
+    }
 
-  _lastMSecs = msecs;
-  _lastNSecs = nsecs;
-  _clockseq = clockseq;
+    // If there is a setup in process or previous successful setup
+    // done then we will use that
+    // If previous setups have been rejected we will try again
+    if (setupPromise) {
+      return setupPromise;
+    }
 
-  // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
-  msecs += 12219292800000;
+    setupPromise = fetchJSON(dbUrl).catch(function (err) {
+      if (err && err.status && err.status === 404) {
+        // Doesnt exist, create it
+        explainError(404, 'PouchDB is just detecting if the remote exists.');
+        return fetchJSON(dbUrl, {method: 'PUT'});
+      } else {
+        return Promise.reject(err);
+      }
+    }).catch(function (err) {
+      // If we try to create a database that already exists, skipped in
+      // istanbul since its catching a race condition.
+      /* istanbul ignore if */
+      if (err && err.status && err.status === 412) {
+        return true;
+      }
+      return Promise.reject(err);
+    });
 
-  // `time_low`
-  var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
-  b[i++] = tl >>> 24 & 0xff;
-  b[i++] = tl >>> 16 & 0xff;
-  b[i++] = tl >>> 8 & 0xff;
-  b[i++] = tl & 0xff;
+    setupPromise.catch(function () {
+      setupPromise = null;
+    });
 
-  // `time_mid`
-  var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
-  b[i++] = tmh >>> 8 & 0xff;
-  b[i++] = tmh & 0xff;
+    return setupPromise;
+  }
 
-  // `time_high_and_version`
-  b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
-  b[i++] = tmh >>> 16 & 0xff;
+  immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+    callback(null, api);
+  });
 
-  // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
-  b[i++] = clockseq >>> 8 | 0x80;
+  api._remote = true;
 
-  // `clock_seq_low`
-  b[i++] = clockseq & 0xff;
+  /* istanbul ignore next */
+  api.type = function () {
+    return 'http';
+  };
 
-  // `node`
-  for (var n = 0; n < 6; ++n) {
-    b[i + n] = node[n];
-  }
+  api.id = adapterFun$$1('id', function (callback) {
+    ourFetch(genUrl(host, '')).then(function (response) {
+      return response.json();
+    }).then(function (result) {
+      var uuid$$1 = (result && result.uuid) ?
+          (result.uuid + host.db) : genDBUrl(host, '');
+      callback(null, uuid$$1);
+    }).catch(function (err) {
+      callback(err);
+    });
+  });
 
-  return buf ? buf : bytesToUuid(b);
-}
+  // Sends a POST request to the host calling the couchdb _compact function
+  //    version: The version of CouchDB it is running
+  api.compact = adapterFun$$1('compact', function (opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = clone(opts);
 
-module.exports = v1;
+    fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () {
+      function ping() {
+        api.info(function (err, res) {
+          // CouchDB may send a "compact_running:true" if it's
+          // already compacting. PouchDB Server doesn't.
+          /* istanbul ignore else */
+          if (res && !res.compact_running) {
+            callback(null, {ok: true});
+          } else {
+            setTimeout(ping, opts.interval || 200);
+          }
+        });
+      }
+      // Ping the http if it's finished compaction
+      ping();
+    });
+  });
 
+  api.bulkGet = adapterFun('bulkGet', function (opts, callback) {
+    var self = this;
 
-/***/ }),
-/* 490 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    function doBulkGet(cb) {
+      var params = {};
+      if (opts.revs) {
+        params.revs = true;
+      }
+      if (opts.attachments) {
+        /* istanbul ignore next */
+        params.attachments = true;
+      }
+      if (opts.latest) {
+        params.latest = true;
+      }
+      fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), {
+        method: 'POST',
+        body: JSON.stringify({ docs: opts.docs})
+      }).then(function (result) {
+        if (opts.attachments && opts.binary) {
+          result.data.results.forEach(function (res) {
+            res.docs.forEach(readAttachmentsAsBlobOrBuffer);
+          });
+        }
+        cb(null, result.data);
+      }).catch(cb);
+    }
 
-// Unique ID creation requires a high quality random # generator.  In node.js
-// this is pretty straight-forward - we use the crypto API.
+    /* istanbul ignore next */
+    function doBulkGetShim() {
+      // avoid "url too long error" by splitting up into multiple requests
+      var batchSize = MAX_SIMULTANEOUS_REVS;
+      var numBatches = Math.ceil(opts.docs.length / batchSize);
+      var numDone = 0;
+      var results = new Array(numBatches);
 
-var crypto = __webpack_require__(76);
+      function onResult(batchNum) {
+        return function (err, res) {
+          // err is impossible because shim returns a list of errs in that case
+          results[batchNum] = res.results;
+          if (++numDone === numBatches) {
+            callback(null, {results: flatten(results)});
+          }
+        };
+      }
 
-module.exports = function nodeRNG() {
-  return crypto.randomBytes(16);
-};
+      for (var i = 0; i < numBatches; i++) {
+        var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']);
+        subOpts.docs = opts.docs.slice(i * batchSize,
+          Math.min(opts.docs.length, (i + 1) * batchSize));
+        bulkGet(self, subOpts, onResult(i));
+      }
+    }
 
+    // mark the whole database as either supporting or not supporting _bulk_get
+    var dbUrl = genUrl(host, '');
+    var supportsBulkGet = supportsBulkGetMap[dbUrl];
 
-/***/ }),
-/* 491 */
-/***/ ((module) => {
+    /* istanbul ignore next */
+    if (typeof supportsBulkGet !== 'boolean') {
+      // check if this database supports _bulk_get
+      doBulkGet(function (err, res) {
+        if (err) {
+          supportsBulkGetMap[dbUrl] = false;
+          explainError(
+            err.status,
+            'PouchDB is just detecting if the remote ' +
+            'supports the _bulk_get API.'
+          );
+          doBulkGetShim();
+        } else {
+          supportsBulkGetMap[dbUrl] = true;
+          callback(null, res);
+        }
+      });
+    } else if (supportsBulkGet) {
+      doBulkGet(callback);
+    } else {
+      doBulkGetShim();
+    }
+  });
 
-/**
- * Convert array of 16 byte values to UUID string format of the form:
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
- */
-var byteToHex = [];
-for (var i = 0; i < 256; ++i) {
-  byteToHex[i] = (i + 0x100).toString(16).substr(1);
-}
+  // Calls GET on the host, which gets back a JSON string containing
+  //    couchdb: A welcome string
+  //    version: The version of CouchDB it is running
+  api._info = function (callback) {
+    setup().then(function () {
+      return ourFetch(genDBUrl(host, ''));
+    }).then(function (response) {
+      return response.json();
+    }).then(function (info) {
+      info.host = genDBUrl(host, '');
+      callback(null, info);
+    }).catch(callback);
+  };
 
-function bytesToUuid(buf, offset) {
-  var i = offset || 0;
-  var bth = byteToHex;
-  return bth[buf[i++]] + bth[buf[i++]] +
-          bth[buf[i++]] + bth[buf[i++]] + '-' +
-          bth[buf[i++]] + bth[buf[i++]] + '-' +
-          bth[buf[i++]] + bth[buf[i++]] + '-' +
-          bth[buf[i++]] + bth[buf[i++]] + '-' +
-          bth[buf[i++]] + bth[buf[i++]] +
-          bth[buf[i++]] + bth[buf[i++]] +
-          bth[buf[i++]] + bth[buf[i++]];
-}
+  api.fetch = function (path, options) {
+    return setup().then(function () {
+      return ourFetch(genDBUrl(host, path), options);
+    });
+  };
 
-module.exports = bytesToUuid;
+  // Get the document with the given id from the database given by host.
+  // The id could be solely the _id in the database, or it may be a
+  // _design/ID or _local/ID path
+  api.get = adapterFun$$1('get', function (id, opts, callback) {
+    // If no options were given, set the callback to the second parameter
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = clone(opts);
 
+    // List of parameters to add to the GET request
+    var params = {};
 
-/***/ }),
-/* 492 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    if (opts.revs) {
+      params.revs = true;
+    }
 
-var rng = __webpack_require__(490);
-var bytesToUuid = __webpack_require__(491);
+    if (opts.revs_info) {
+      params.revs_info = true;
+    }
 
-function v4(options, buf, offset) {
-  var i = buf && offset || 0;
+    if (opts.latest) {
+      params.latest = true;
+    }
 
-  if (typeof(options) == 'string') {
-    buf = options === 'binary' ? new Array(16) : null;
-    options = null;
-  }
-  options = options || {};
+    if (opts.open_revs) {
+      if (opts.open_revs !== "all") {
+        opts.open_revs = JSON.stringify(opts.open_revs);
+      }
+      params.open_revs = opts.open_revs;
+    }
 
-  var rnds = options.random || (options.rng || rng)();
+    if (opts.rev) {
+      params.rev = opts.rev;
+    }
 
-  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
-  rnds[6] = (rnds[6] & 0x0f) | 0x40;
-  rnds[8] = (rnds[8] & 0x3f) | 0x80;
+    if (opts.conflicts) {
+      params.conflicts = opts.conflicts;
+    }
 
-  // Copy bytes to buffer, if provided
-  if (buf) {
-    for (var ii = 0; ii < 16; ++ii) {
-      buf[i + ii] = rnds[ii];
+    /* istanbul ignore if */
+    if (opts.update_seq) {
+      params.update_seq = opts.update_seq;
     }
-  }
 
-  return buf || bytesToUuid(rnds);
-}
+    id = encodeDocId(id);
 
-module.exports = v4;
+    function fetchAttachments(doc) {
+      var atts = doc._attachments;
+      var filenames = atts && Object.keys(atts);
+      if (!atts || !filenames.length) {
+        return;
+      }
+      // we fetch these manually in separate XHRs, because
+      // Sync Gateway would normally send it back as multipart/mixed,
+      // which we cannot parse. Also, this is more efficient than
+      // receiving attachments as base64-encoded strings.
+      function fetchData(filename) {
+        var att = atts[filename];
+        var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) +
+            '?rev=' + doc._rev;
+        return ourFetch(genDBUrl(host, path)).then(function (response) {
+          if (typeof process !== 'undefined' && !process.browser) {
+            return response.buffer();
+          } else {
+            /* istanbul ignore next */
+            return response.blob();
+          }
+        }).then(function (blob) {
+          if (opts.binary) {
+            // TODO: Can we remove this?
+            if (typeof process !== 'undefined' && !process.browser) {
+              blob.type = att.content_type;
+            }
+            return blob;
+          }
+          return new Promise(function (resolve) {
+            blobToBase64(blob, resolve);
+          });
+        }).then(function (data) {
+          delete att.stub;
+          delete att.length;
+          att.data = data;
+        });
+      }
 
+      var promiseFactories = filenames.map(function (filename) {
+        return function () {
+          return fetchData(filename);
+        };
+      });
 
-/***/ }),
-/* 493 */
-/***/ ((__unused_webpack_module, exports) => {
+      // This limits the number of parallel xhr requests to 5 any time
+      // to avoid issues with maximum browser request limits
+      return pool(promiseFactories, 5);
+    }
 
-"use strict";
+    function fetchAllAttachments(docOrDocs) {
+      if (Array.isArray(docOrDocs)) {
+        return Promise.all(docOrDocs.map(function (doc) {
+          if (doc.ok) {
+            return fetchAttachments(doc.ok);
+          }
+        }));
+      }
+      return fetchAttachments(docOrDocs);
+    }
 
+    var url = genDBUrl(host, id + paramsToStr(params));
+    fetchJSON(url).then(function (res) {
+      return Promise.resolve().then(function () {
+        if (opts.attachments) {
+          return fetchAllAttachments(res.data);
+        }
+      }).then(function () {
+        callback(null, res.data);
+      });
+    }).catch(function (e) {
+      e.docId = id;
+      callback(e);
+    });
+  });
 
-/**
- * Stringify/parse functions that don't operate
- * recursively, so they avoid call stack exceeded
- * errors.
- */
-exports.stringify = function stringify(input) {
-  var queue = [];
-  queue.push({obj: input});
 
-  var res = '';
-  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
-  while ((next = queue.pop())) {
-    obj = next.obj;
-    prefix = next.prefix || '';
-    val = next.val || '';
-    res += prefix;
-    if (val) {
-      res += val;
-    } else if (typeof obj !== 'object') {
-      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
-    } else if (obj === null) {
-      res += 'null';
-    } else if (Array.isArray(obj)) {
-      queue.push({val: ']'});
-      for (i = obj.length - 1; i >= 0; i--) {
-        arrayPrefix = i === 0 ? '' : ',';
-        queue.push({obj: obj[i], prefix: arrayPrefix});
-      }
-      queue.push({val: '['});
-    } else { // object
-      keys = [];
-      for (k in obj) {
-        if (obj.hasOwnProperty(k)) {
-          keys.push(k);
-        }
+  // Delete the document given by doc from the database given by host.
+  api.remove = adapterFun$$1('remove', function (docOrId, optsOrRev, opts, cb) {
+    var doc;
+    if (typeof optsOrRev === 'string') {
+      // id, rev, opts, callback style
+      doc = {
+        _id: docOrId,
+        _rev: optsOrRev
+      };
+      if (typeof opts === 'function') {
+        cb = opts;
+        opts = {};
       }
-      queue.push({val: '}'});
-      for (i = keys.length - 1; i >= 0; i--) {
-        key = keys[i];
-        value = obj[key];
-        objPrefix = (i > 0 ? ',' : '');
-        objPrefix += JSON.stringify(key) + ':';
-        queue.push({obj: value, prefix: objPrefix});
+    } else {
+      // doc, opts, callback style
+      doc = docOrId;
+      if (typeof optsOrRev === 'function') {
+        cb = optsOrRev;
+        opts = {};
+      } else {
+        cb = opts;
+        opts = optsOrRev;
       }
-      queue.push({val: '{'});
     }
-  }
-  return res;
-};
 
-// Convenience function for the parse function.
-// This pop function is basically copied from
-// pouchCollate.parseIndexableString
-function pop(obj, stack, metaStack) {
-  var lastMetaElement = metaStack[metaStack.length - 1];
-  if (obj === lastMetaElement.element) {
-    // popping a meta-element, e.g. an object whose value is another object
-    metaStack.pop();
-    lastMetaElement = metaStack[metaStack.length - 1];
-  }
-  var element = lastMetaElement.element;
-  var lastElementIndex = lastMetaElement.index;
-  if (Array.isArray(element)) {
-    element.push(obj);
-  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
-    var key = stack.pop();
-    element[key] = obj;
-  } else {
-    stack.push(obj); // obj with key only
+    var rev = (doc._rev || opts.rev);
+    var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev;
+
+    fetchJSON(url, {method: 'DELETE'}, cb).catch(cb);
+  });
+
+  function encodeAttachmentId(attachmentId) {
+    return attachmentId.split("/").map(encodeURIComponent).join("/");
   }
-}
 
-exports.parse = function (str) {
-  var stack = [];
-  var metaStack = []; // stack for arrays and objects
-  var i = 0;
-  var collationIndex,parsedNum,numChar;
-  var parsedString,lastCh,numConsecutiveSlashes,ch;
-  var arrayElement, objElement;
-  while (true) {
-    collationIndex = str[i++];
-    if (collationIndex === '}' ||
-        collationIndex === ']' ||
-        typeof collationIndex === 'undefined') {
-      if (stack.length === 1) {
-        return stack.pop();
-      } else {
-        pop(stack.pop(), stack, metaStack);
-        continue;
-      }
+  // Get the attachment
+  api.getAttachment = adapterFun$$1('getAttachment', function (docId, attachmentId,
+                                                            opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
     }
-    switch (collationIndex) {
-      case ' ':
-      case '\t':
-      case '\n':
-      case ':':
-      case ',':
-        break;
-      case 'n':
-        i += 3; // 'ull'
-        pop(null, stack, metaStack);
-        break;
-      case 't':
-        i += 3; // 'rue'
-        pop(true, stack, metaStack);
-        break;
-      case 'f':
-        i += 4; // 'alse'
-        pop(false, stack, metaStack);
-        break;
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9':
-      case '-':
-        parsedNum = '';
-        i--;
-        while (true) {
-          numChar = str[i++];
-          if (/[\d\.\-e\+]/.test(numChar)) {
-            parsedNum += numChar;
-          } else {
-            i--;
-            break;
-          }
-        }
-        pop(parseFloat(parsedNum), stack, metaStack);
-        break;
-      case '"':
-        parsedString = '';
-        lastCh = void 0;
-        numConsecutiveSlashes = 0;
-        while (true) {
-          ch = str[i++];
-          if (ch !== '"' || (lastCh === '\\' &&
-              numConsecutiveSlashes % 2 === 1)) {
-            parsedString += ch;
-            lastCh = ch;
-            if (lastCh === '\\') {
-              numConsecutiveSlashes++;
-            } else {
-              numConsecutiveSlashes = 0;
-            }
-          } else {
-            break;
-          }
+    var params = opts.rev ? ('?rev=' + opts.rev) : '';
+    var url = genDBUrl(host, encodeDocId(docId)) + '/' +
+        encodeAttachmentId(attachmentId) + params;
+    var contentType;
+    ourFetch(url, {method: 'GET'}).then(function (response) {
+      contentType = response.headers.get('content-type');
+      if (!response.ok) {
+        throw response;
+      } else {
+        if (typeof process !== 'undefined' && !process.browser) {
+          return response.buffer();
+        } else {
+          /* istanbul ignore next */
+          return response.blob();
         }
-        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
-        break;
-      case '[':
-        arrayElement = { element: [], index: stack.length };
-        stack.push(arrayElement.element);
-        metaStack.push(arrayElement);
-        break;
-      case '{':
-        objElement = { element: {}, index: stack.length };
-        stack.push(objElement.element);
-        metaStack.push(objElement);
-        break;
-      default:
-        throw new Error(
-          'unexpectedly reached end of input: ' + collationIndex);
-    }
-  }
-};
-
-
-/***/ }),
-/* 494 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495);
-/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(498);
-/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500);
-/* harmony import */ var pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(503);
-/* harmony import */ var pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(505);
-/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(504);
-/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(499);
+      }
+    }).then(function (blob) {
+      // TODO: also remove
+      if (typeof process !== 'undefined' && !process.browser) {
+        blob.type = contentType;
+      }
+      callback(null, blob);
+    }).catch(function (err) {
+      callback(err);
+    });
+  });
 
+  // Remove the attachment given by the id and rev
+  api.removeAttachment =  adapterFun$$1('removeAttachment', function (docId,
+                                                                   attachmentId,
+                                                                   rev,
+                                                                   callback) {
+    var url = genDBUrl(host, encodeDocId(docId) + '/' +
+                       encodeAttachmentId(attachmentId)) + '?rev=' + rev;
+    fetchJSON(url, {method: 'DELETE'}, callback).catch(callback);
+  });
 
+  // Add the attachment given by blob and its contentType property
+  // to the document with the given id, the revision given by rev, and
+  // add it to the database given by host.
+  api.putAttachment = adapterFun$$1('putAttachment', function (docId, attachmentId,
+                                                            rev, blob,
+                                                            type, callback) {
+    if (typeof type === 'function') {
+      callback = type;
+      type = blob;
+      blob = rev;
+      rev = null;
+    }
+    var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId);
+    var url = genDBUrl(host, id);
+    if (rev) {
+      url += '?rev=' + rev;
+    }
 
+    if (typeof blob === 'string') {
+      // input is assumed to be a base64 string
+      var binary;
+      try {
+        binary = thisAtob(blob);
+      } catch (err) {
+        return callback(createError(BAD_ARG,
+                        'Attachment is not a valid base64 string'));
+      }
+      blob = binary ? binStringToBluffer(binary, type) : '';
+    }
 
+    // Add the attachment
+    fetchJSON(url, {
+      headers: new h({'Content-Type': type}),
+      method: 'PUT',
+      body: blob
+    }, callback).catch(callback);
+  });
 
+  // Update/create multiple documents given by req in the database
+  // given by host.
+  api._bulkDocs = function (req, opts, callback) {
+    // If new_edits=false then it prevents the database from creating
+    // new revision numbers for the documents. Instead it just uses
+    // the old ones. This is used in database replication.
+    req.new_edits = opts.new_edits;
 
+    setup().then(function () {
+      return Promise.all(req.docs.map(preprocessAttachments$1));
+    }).then(function () {
+      // Update/create the documents
+      return fetchJSON(genDBUrl(host, '_bulk_docs'), {
+        method: 'POST',
+        body: JSON.stringify(req)
+      }, callback);
+    }).catch(callback);
+  };
 
 
-// we restucture the supplied JSON considerably, because the official
-// Mango API is very particular about a lot of this stuff, but we like
-// to be liberal with what we accept in order to prevent mental
-// breakdowns in our users
-function massageCreateIndexRequest(requestDef) {
-  requestDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef);
+  // Update/create document
+  api._put = function (doc, opts, callback) {
+    setup().then(function () {
+      return preprocessAttachments$1(doc);
+    }).then(function () {
+      return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), {
+        method: 'PUT',
+        body: JSON.stringify(doc)
+      });
+    }).then(function (result) {
+      callback(null, result.data);
+    }).catch(function (err) {
+      err.docId = doc && doc._id;
+      callback(err);
+    });
+  };
 
-  if (!requestDef.index) {
-    requestDef.index = {};
-  }
 
-  ['type', 'name', 'ddoc'].forEach(function (key) {
-    if (requestDef.index[key]) {
-      requestDef[key] = requestDef.index[key];
-      delete requestDef.index[key];
+  // Get a listing of the documents in the database given
+  // by host and ordered by increasing id.
+  api.allDocs = adapterFun$$1('allDocs', function (opts, callback) {
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
     }
-  });
+    opts = clone(opts);
 
-  if (requestDef.fields) {
-    requestDef.index.fields = requestDef.fields;
-    delete requestDef.fields;
-  }
+    // List of parameters to add to the GET request
+    var params = {};
+    var body;
+    var method = 'GET';
 
-  if (!requestDef.type) {
-    requestDef.type = 'json';
-  }
-  return requestDef;
-}
+    if (opts.conflicts) {
+      params.conflicts = true;
+    }
 
-function dbFetch(db, path, opts, callback) {
-  var status, ok;
-  opts.headers = new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__.Headers({'Content-type': 'application/json'});
-  db.fetch(path, opts).then(function (response) {
-    status = response.status;
-    ok = response.ok;
-    return response.json();
-  }).then(function (json) {
-    if (!ok) {
-      json.status = status;
-      var err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__.generateErrorFromResponse)(json);
-      callback(err);
-    } else {
-      callback(null, json);
+    /* istanbul ignore if */
+    if (opts.update_seq) {
+      params.update_seq = true;
     }
-  }).catch(callback);
-}
 
-function createIndex(db, requestDef, callback) {
-  requestDef = massageCreateIndexRequest(requestDef);
-  dbFetch(db, '_index', {
-    method: 'POST',
-    body: JSON.stringify(requestDef)
-  }, callback);
-}
+    if (opts.descending) {
+      params.descending = true;
+    }
 
-function find(db, requestDef, callback) {
-  dbFetch(db, '_find', {
-    method: 'POST',
-    body: JSON.stringify(requestDef)
-  }, callback);
-}
+    if (opts.include_docs) {
+      params.include_docs = true;
+    }
 
-function explain(db, requestDef, callback) {
-  dbFetch(db, '_explain', {
-    method: 'POST',
-    body: JSON.stringify(requestDef)
-  }, callback);
-}
+    // added in CouchDB 1.6.0
+    if (opts.attachments) {
+      params.attachments = true;
+    }
 
-function getIndexes(db, callback) {
-  dbFetch(db, '_index', {
-    method: 'GET'
-  }, callback);
-}
+    if (opts.key) {
+      params.key = JSON.stringify(opts.key);
+    }
 
-function deleteIndex(db, indexDef, callback) {
+    if (opts.start_key) {
+      opts.startkey = opts.start_key;
+    }
 
+    if (opts.startkey) {
+      params.startkey = JSON.stringify(opts.startkey);
+    }
 
-  var ddoc = indexDef.ddoc;
-  var type = indexDef.type || 'json';
-  var name = indexDef.name;
+    if (opts.end_key) {
+      opts.endkey = opts.end_key;
+    }
 
-  if (!ddoc) {
-    return callback(new Error('you must provide an index\'s ddoc'));
-  }
+    if (opts.endkey) {
+      params.endkey = JSON.stringify(opts.endkey);
+    }
 
-  if (!name) {
-    return callback(new Error('you must provide an index\'s name'));
-  }
+    if (typeof opts.inclusive_end !== 'undefined') {
+      params.inclusive_end = !!opts.inclusive_end;
+    }
 
-  var url = '_index/' + [ddoc, type, name].map(encodeURIComponent).join('/');
+    if (typeof opts.limit !== 'undefined') {
+      params.limit = opts.limit;
+    }
 
-  dbFetch(db, url, {method: 'DELETE'}, callback);
-}
+    if (typeof opts.skip !== 'undefined') {
+      params.skip = opts.skip;
+    }
 
-function getArguments(fun) {
-  return function () {
-    var len = arguments.length;
-    var args = new Array(len);
-    var i = -1;
-    while (++i < len) {
-      args[i] = arguments[i];
+    var paramStr = paramsToStr(params);
+
+    if (typeof opts.keys !== 'undefined') {
+      method = 'POST';
+      body = {keys: opts.keys};
     }
-    return fun.call(this, args);
-  };
-}
 
-function callbackify(fun) {
-  return getArguments(function (args) {
-    var cb = args.pop();
-    var promise = fun.apply(this, args);
-    promisedCallback(promise, cb);
-    return promise;
+    fetchJSON(genDBUrl(host, '_all_docs' + paramStr), {
+       method: method,
+      body: JSON.stringify(body)
+    }).then(function (result) {
+      if (opts.include_docs && opts.attachments && opts.binary) {
+        result.data.rows.forEach(readAttachmentsAsBlobOrBuffer);
+      }
+      callback(null, result.data);
+    }).catch(callback);
   });
-}
 
-function promisedCallback(promise, callback) {
-  promise.then(function (res) {
-    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () {
-      callback(null, res);
-    });
-  }, function (reason) {
-    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () {
-      callback(reason);
-    });
-  });
-  return promise;
-}
+  // Get a list of changes made to documents in the database given by host.
+  // TODO According to the README, there should be two other methods here,
+  // api.changes.addListener and api.changes.removeListener.
+  api._changes = function (opts) {
 
-var flatten = getArguments(function (args) {
-  var res = [];
-  for (var i = 0, len = args.length; i < len; i++) {
-    var subArr = args[i];
-    if (Array.isArray(subArr)) {
-      res = res.concat(flatten.apply(null, subArr));
-    } else {
-      res.push(subArr);
-    }
-  }
-  return res;
-});
+    // We internally page the results of a changes request, this means
+    // if there is a large set of changes to be returned we can start
+    // processing them quicker instead of waiting on the entire
+    // set of changes to return and attempting to process them at once
+    var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE;
 
-function mergeObjects(arr) {
-  var res = {};
-  for (var i = 0, len = arr.length; i < len; i++) {
-    res = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)(res, arr[i]);
-  }
-  return res;
-}
+    opts = clone(opts);
 
-// Selects a list of fields defined in dot notation from one doc
-// and copies them to a new doc. Like underscore _.pick but supports nesting.
-function pick(obj, arr) {
-  var res = {};
-  for (var i = 0, len = arr.length; i < len; i++) {
-    var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(arr[i]);
-    var value = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getFieldFromDoc)(obj, parsedField);
-    if (typeof value !== 'undefined') {
-      (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.setFieldInDoc)(res, parsedField, value);
+    if (opts.continuous && !('heartbeat' in opts)) {
+      opts.heartbeat = DEFAULT_HEARTBEAT;
     }
-  }
-  return res;
-}
 
-// e.g. ['a'], ['a', 'b'] is true, but ['b'], ['a', 'b'] is false
-function oneArrayIsSubArrayOfOther(left, right) {
+    var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000;
 
-  for (var i = 0, len = Math.min(left.length, right.length); i < len; i++) {
-    if (left[i] !== right[i]) {
-      return false;
+    // ensure CHANGES_TIMEOUT_BUFFER applies
+    if ('timeout' in opts && opts.timeout &&
+      (requestTimeout - opts.timeout) < CHANGES_TIMEOUT_BUFFER) {
+        requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER;
     }
-  }
-  return true;
-}
 
-// e.g.['a', 'b', 'c'], ['a', 'b'] is false
-function oneArrayIsStrictSubArrayOfOther(left, right) {
+    /* istanbul ignore if */
+    if ('heartbeat' in opts && opts.heartbeat &&
+       (requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) {
+        requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER;
+    }
 
-  if (left.length > right.length) {
-    return false;
-  }
+    var params = {};
+    if ('timeout' in opts && opts.timeout) {
+      params.timeout = opts.timeout;
+    }
 
-  return oneArrayIsSubArrayOfOther(left, right);
-}
+    var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
+    var leftToFetch = limit;
 
-// same as above, but treat the left array as an unordered set
-// e.g. ['b', 'a'], ['a', 'b', 'c'] is true, but ['c'], ['a', 'b', 'c'] is false
-function oneSetIsSubArrayOfOther(left, right) {
-  left = left.slice();
-  for (var i = 0, len = right.length; i < len; i++) {
-    var field = right[i];
-    if (!left.length) {
-      break;
-    }
-    var leftIdx = left.indexOf(field);
-    if (leftIdx === -1) {
-      return false;
-    } else {
-      left.splice(leftIdx, 1);
+    if (opts.style) {
+      params.style = opts.style;
     }
-  }
-  return true;
-}
-
-function arrayToObject(arr) {
-  var res = {};
-  for (var i = 0, len = arr.length; i < len; i++) {
-    res[arr[i]] = true;
-  }
-  return res;
-}
 
-function max(arr, fun) {
-  var max = null;
-  var maxScore = -1;
-  for (var i = 0, len = arr.length; i < len; i++) {
-    var element = arr[i];
-    var score = fun(element);
-    if (score > maxScore) {
-      maxScore = score;
-      max = element;
+    if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
+      params.include_docs = true;
     }
-  }
-  return max;
-}
 
-function arrayEquals(arr1, arr2) {
-  if (arr1.length !== arr2.length) {
-    return false;
-  }
-  for (var i = 0, len = arr1.length; i < len; i++) {
-    if (arr1[i] !== arr2[i]) {
-      return false;
+    if (opts.attachments) {
+      params.attachments = true;
     }
-  }
-  return true;
-}
 
-function uniq(arr) {
-  var obj = {};
-  for (var i = 0; i < arr.length; i++) {
-    obj['$' + arr[i]] = true;
-  }
-  return Object.keys(obj).map(function (key) {
-    return key.substring(1);
-  });
-}
+    if (opts.continuous) {
+      params.feed = 'longpoll';
+    }
 
-//
-// One thing about these mappers:
-//
-// Per the advice of John-David Dalton (http://youtu.be/NthmeLEhDDM),
-// what you want to do in this case is optimize for the smallest possible
-// function, since that's the thing that gets run over and over again.
-//
-// This code would be a lot simpler if all the if/elses were inside
-// the function, but it would also be a lot less performant.
-//
+    if (opts.seq_interval) {
+      params.seq_interval = opts.seq_interval;
+    }
 
+    if (opts.conflicts) {
+      params.conflicts = true;
+    }
 
-function createDeepMultiMapper(fields, emit) {
-  return function (doc) {
-    var toEmit = [];
-    for (var i = 0, iLen = fields.length; i < iLen; i++) {
-      var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(fields[i]);
-      var value = doc;
-      for (var j = 0, jLen = parsedField.length; j < jLen; j++) {
-        var key = parsedField[j];
-        value = value[key];
-        if (typeof value === 'undefined') {
-          return; // don't emit
-        }
-      }
-      toEmit.push(value);
+    if (opts.descending) {
+      params.descending = true;
+    }
+    
+    /* istanbul ignore if */
+    if (opts.update_seq) {
+      params.update_seq = true;
     }
-    emit(toEmit);
-  };
-}
 
-function createDeepSingleMapper(field, emit) {
-  var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(field);
-  return function (doc) {
-    var value = doc;
-    for (var i = 0, len = parsedField.length; i < len; i++) {
-      var key = parsedField[i];
-      value = value[key];
-      if (typeof value === 'undefined') {
-        return; // do nothing
+    if ('heartbeat' in opts) {
+      // If the heartbeat value is false, it disables the default heartbeat
+      if (opts.heartbeat) {
+        params.heartbeat = opts.heartbeat;
       }
     }
-    emit(value);
-  };
-}
 
-function createShallowSingleMapper(field, emit) {
-  return function (doc) {
-    emit(doc[field]);
-  };
-}
+    if (opts.filter && typeof opts.filter === 'string') {
+      params.filter = opts.filter;
+    }
 
-function createShallowMultiMapper(fields, emit) {
-  return function (doc) {
-    var toEmit = [];
-    for (var i = 0, len = fields.length; i < len; i++) {
-      toEmit.push(doc[fields[i]]);
+    if (opts.view && typeof opts.view === 'string') {
+      params.filter = '_view';
+      params.view = opts.view;
     }
-    emit(toEmit);
-  };
-}
 
-function checkShallow(fields) {
-  for (var i = 0, len = fields.length; i < len; i++) {
-    var field = fields[i];
-    if (field.indexOf('.') !== -1) {
-      return false;
+    // If opts.query_params exists, pass it through to the changes request.
+    // These parameters may be used by the filter on the source database.
+    if (opts.query_params && typeof opts.query_params === 'object') {
+      for (var param_name in opts.query_params) {
+        /* istanbul ignore else */
+        if (opts.query_params.hasOwnProperty(param_name)) {
+          params[param_name] = opts.query_params[param_name];
+        }
+      }
     }
-  }
-  return true;
-}
 
-function createMapper(fields, emit) {
-  var isShallow = checkShallow(fields);
-  var isSingle = fields.length === 1;
+    var method = 'GET';
+    var body;
 
-  // notice we try to optimize for the most common case,
-  // i.e. single shallow indexes
-  if (isShallow) {
-    if (isSingle) {
-      return createShallowSingleMapper(fields[0], emit);
-    } else { // multi
-      return createShallowMultiMapper(fields, emit);
+    if (opts.doc_ids) {
+      // set this automagically for the user; it's annoying that couchdb
+      // requires both a "filter" and a "doc_ids" param.
+      params.filter = '_doc_ids';
+      method = 'POST';
+      body = {doc_ids: opts.doc_ids };
     }
-  } else { // deep
-    if (isSingle) {
-      return createDeepSingleMapper(fields[0], emit);
-    } else { // multi
-      return createDeepMultiMapper(fields, emit);
+    /* istanbul ignore next */
+    else if (opts.selector) {
+      // set this automagically for the user, similar to above
+      params.filter = '_selector';
+      method = 'POST';
+      body = {selector: opts.selector };
     }
-  }
-}
 
-function mapper(mapFunDef, emit) {
-  // mapFunDef is a list of fields
+    var controller = new a();
+    var lastFetchedSeq;
 
-  var fields = Object.keys(mapFunDef.fields);
+    // Get all the changes starting wtih the one immediately after the
+    // sequence number given by since.
+    var fetchData = function (since, callback) {
+      if (opts.aborted) {
+        return;
+      }
+      params.since = since;
+      // "since" can be any kind of json object in Cloudant/CouchDB 2.x
+      /* istanbul ignore next */
+      if (typeof params.since === "object") {
+        params.since = JSON.stringify(params.since);
+      }
 
-  return createMapper(fields, emit);
-}
+      if (opts.descending) {
+        if (limit) {
+          params.limit = leftToFetch;
+        }
+      } else {
+        params.limit = (!limit || leftToFetch > batchSize) ?
+          batchSize : leftToFetch;
+      }
 
-/* istanbul ignore next */
-function reducer(/*reduceFunDef*/) {
-  throw new Error('reduce not supported');
-}
+      // Set the options for the ajax call
+      var url = genDBUrl(host, '_changes' + paramsToStr(params));
+      var fetchOpts = {
+        signal: controller.signal,
+        method: method,
+        body: JSON.stringify(body)
+      };
+      lastFetchedSeq = since;
 
-function ddocValidator(ddoc, viewName) {
-  var view = ddoc.views[viewName];
-  // This doesn't actually need to be here apparently, but
-  // I feel safer keeping it.
-  /* istanbul ignore if */
-  if (!view.map || !view.map.fields) {
-    throw new Error('ddoc ' + ddoc._id +' with view ' + viewName +
-      ' doesn\'t have map.fields defined. ' +
-      'maybe it wasn\'t created by this plugin?');
-  }
-}
+      /* istanbul ignore if */
+      if (opts.aborted) {
+        return;
+      }
 
-var abstractMapper = (0,pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__["default"])(
-  /* localDocName */ 'indexes',
-  mapper,
-  reducer,
-  ddocValidator
-);
+      // Get the changes
+      setup().then(function () {
+        return fetchJSON(url, fetchOpts, callback);
+      }).catch(callback);
+    };
 
-// normalize the "sort" value
-function massageSort(sort) {
-  if (!Array.isArray(sort)) {
-    throw new Error('invalid sort json - should be an array');
-  }
-  return sort.map(function (sorting) {
-    if (typeof sorting === 'string') {
-      var obj = {};
-      obj[sorting] = 'asc';
-      return obj;
-    } else {
-      return sorting;
+    // If opts.since exists, get all the changes from the sequence
+    // number given by opts.since. Otherwise, get all the changes
+    // from the sequence number 0.
+    var results = {results: []};
+
+    var fetched = function (err, res) {
+      if (opts.aborted) {
+        return;
+      }
+      var raw_results_length = 0;
+      // If the result of the ajax call (res) contains changes (res.results)
+      if (res && res.results) {
+        raw_results_length = res.results.length;
+        results.last_seq = res.last_seq;
+        var pending = null;
+        var lastSeq = null;
+        // Attach 'pending' property if server supports it (CouchDB 2.0+)
+        /* istanbul ignore if */
+        if (typeof res.pending === 'number') {
+          pending = res.pending;
+        }
+        if (typeof results.last_seq === 'string' || typeof results.last_seq === 'number') {
+          lastSeq = results.last_seq;
+        }
+        // For each change
+        var req = {};
+        req.query = opts.query_params;
+        res.results = res.results.filter(function (c) {
+          leftToFetch--;
+          var ret = filterChange(opts)(c);
+          if (ret) {
+            if (opts.include_docs && opts.attachments && opts.binary) {
+              readAttachmentsAsBlobOrBuffer(c);
+            }
+            if (opts.return_docs) {
+              results.results.push(c);
+            }
+            opts.onChange(c, pending, lastSeq);
+          }
+          return ret;
+        });
+      } else if (err) {
+        // In case of an error, stop listening for changes and call
+        // opts.complete
+        opts.aborted = true;
+        opts.complete(err);
+        return;
+      }
+
+      // The changes feed may have timed out with no results
+      // if so reuse last update sequence
+      if (res && res.last_seq) {
+        lastFetchedSeq = res.last_seq;
+      }
+
+      var finished = (limit && leftToFetch <= 0) ||
+        (res && raw_results_length < batchSize) ||
+        (opts.descending);
+
+      if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
+        // Queue a call to fetch again with the newest sequence number
+        immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { fetchData(lastFetchedSeq, fetched); });
+      } else {
+        // We're done, call the callback
+        opts.complete(null, results);
+      }
+    };
+
+    fetchData(opts.since || 0, fetched);
+
+    // Return a method to cancel this method from processing any more
+    return {
+      cancel: function () {
+        opts.aborted = true;
+        controller.abort();
+      }
+    };
+  };
+
+  // Given a set of document/revision IDs (given by req), tets the subset of
+  // those that do NOT correspond to revisions stored in the database.
+  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
+  api.revsDiff = adapterFun$$1('revsDiff', function (req, opts, callback) {
+    // If no options were given, set the callback to be the second parameter
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
     }
+
+    // Get the missing document/revision IDs
+    fetchJSON(genDBUrl(host, '_revs_diff'), {
+      method: 'POST',
+      body: JSON.stringify(req)
+    }, callback).catch(callback);
   });
-}
 
-function massageUseIndex(useIndex) {
-  var cleanedUseIndex = [];
-  if (typeof useIndex === 'string') {
-    cleanedUseIndex.push(useIndex);
-  } else {
-    cleanedUseIndex = useIndex;
-  }
+  api._close = function (callback) {
+    callback();
+  };
 
-  return cleanedUseIndex.map(function (name) {
-    return name.replace('_design/', '');
-  });
+  api._destroy = function (options, callback) {
+    fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) {
+      callback(null, json);
+    }).catch(function (err) {
+      /* istanbul ignore if */
+      if (err.status === 404) {
+        callback(null, {ok: true});
+      } else {
+        callback(err);
+      }
+    });
+  };
 }
 
-function massageIndexDef(indexDef) {
-  indexDef.fields = indexDef.fields.map(function (field) {
-    if (typeof field === 'string') {
-      var obj = {};
-      obj[field] = 'asc';
-      return obj;
-    }
-    return field;
-  });
-  return indexDef;
+// HttpPouch is a valid adapter.
+HttpPouch.valid = function () {
+  return true;
+};
+
+function HttpPouch$1 (PouchDB) {
+  PouchDB.adapter('http', HttpPouch, false);
+  PouchDB.adapter('https', HttpPouch, false);
 }
 
-function getKeyFromDoc(doc, index) {
-  var res = [];
-  for (var i = 0; i < index.def.fields.length; i++) {
-    var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[i]);
-    res.push(doc[field]);
-  }
-  return res;
+function QueryParseError(message) {
+  this.status = 400;
+  this.name = 'query_parse_error';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, QueryParseError);
+  } catch (e) {}
 }
 
-// have to do this manually because REASONS. I don't know why
-// CouchDB didn't implement inclusive_start
-function filterInclusiveStart(rows, targetValue, index) {
-  var indexFields = index.def.fields;
-  for (var i = 0, len = rows.length; i < len; i++) {
-    var row = rows[i];
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(QueryParseError, Error);
 
-    // shave off any docs at the beginning that are <= the
-    // target value
+function NotFoundError(message) {
+  this.status = 404;
+  this.name = 'not_found';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, NotFoundError);
+  } catch (e) {}
+}
 
-    var docKey = getKeyFromDoc(row.doc, index);
-    if (indexFields.length === 1) {
-      docKey = docKey[0]; // only one field, not multi-field
-    } else { // more than one field in index
-      // in the case where e.g. the user is searching {$gt: {a: 1}}
-      // but the index is [a, b], then we need to shorten the doc key
-      while (docKey.length > targetValue.length) {
-        docKey.pop();
-      }
-    }
-    //ABS as we just looking for values that don't match
-    if (Math.abs((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(docKey, targetValue)) > 0) {
-      // no need to filter any further; we're past the key
-      break;
-    }
-  }
-  return i > 0 ? rows.slice(i) : rows;
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(NotFoundError, Error);
+
+function BuiltInError(message) {
+  this.status = 500;
+  this.name = 'invalid_value';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, BuiltInError);
+  } catch (e) {}
 }
 
-function reverseOptions(opts) {
-  var newOpts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(opts);
-  delete newOpts.startkey;
-  delete newOpts.endkey;
-  delete newOpts.inclusive_start;
-  delete newOpts.inclusive_end;
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(BuiltInError, Error);
 
-  if ('endkey' in opts) {
-    newOpts.startkey = opts.endkey;
-  }
-  if ('startkey' in opts) {
-    newOpts.endkey = opts.startkey;
-  }
-  if ('inclusive_start' in opts) {
-    newOpts.inclusive_end = opts.inclusive_start;
-  }
-  if ('inclusive_end' in opts) {
-    newOpts.inclusive_start = opts.inclusive_end;
+function promisedCallback(promise, callback) {
+  if (callback) {
+    promise.then(function (res) {
+      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+        callback(null, res);
+      });
+    }, function (reason) {
+      immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+        callback(reason);
+      });
+    });
   }
-  return newOpts;
+  return promise;
 }
 
-function validateIndex(index) {
-  var ascFields = index.fields.filter(function (field) {
-    return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(field) === 'asc';
+function callbackify(fun) {
+  return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) {
+    var cb = args.pop();
+    var promise = fun.apply(this, args);
+    if (typeof cb === 'function') {
+      promisedCallback(promise, cb);
+    }
+    return promise;
   });
-  if (ascFields.length !== 0 && ascFields.length !== index.fields.length) {
-    throw new Error('unsupported mixed sorting');
-  }
 }
 
-function validateSort(requestDef, index) {
-  if (index.defaultUsed && requestDef.sort) {
-    var noneIdSorts = requestDef.sort.filter(function (sortItem) {
-      return Object.keys(sortItem)[0] !== '_id';
-    }).map(function (sortItem) {
-      return Object.keys(sortItem)[0];
+// Promise finally util similar to Q.finally
+function fin(promise, finalPromiseFactory) {
+  return promise.then(function (res) {
+    return finalPromiseFactory().then(function () {
+      return res;
+    });
+  }, function (reason) {
+    return finalPromiseFactory().then(function () {
+      throw reason;
     });
+  });
+}
 
-    if (noneIdSorts.length > 0) {
-      throw new Error('Cannot sort on field(s) "' + noneIdSorts.join(',') +
-      '" when using the default index');
-    }
-  }
+function sequentialize(queue, promiseFactory) {
+  return function () {
+    var args = arguments;
+    var that = this;
+    return queue.add(function () {
+      return promiseFactory.apply(that, args);
+    });
+  };
+}
 
-  if (index.defaultUsed) {
-    return;
-  }
+// uniq an array of strings, order not guaranteed
+// similar to underscore/lodash _.uniq
+function uniq(arr) {
+  var theSet = new ExportedSet(arr);
+  var result = new Array(theSet.size);
+  var index = -1;
+  theSet.forEach(function (value) {
+    result[++index] = value;
+  });
+  return result;
 }
 
-function validateFindRequest(requestDef) {
-  if (typeof requestDef.selector !== 'object') {
-    throw new Error('you must provide a selector when you find()');
-  }
+function mapToKeysArray(map) {
+  var result = new Array(map.size);
+  var index = -1;
+  map.forEach(function (value, key) {
+    result[++index] = key;
+  });
+  return result;
+}
 
-  /*var selectors = requestDef.selector['$and'] || [requestDef.selector];
-  for (var i = 0; i < selectors.length; i++) {
-    var selector = selectors[i];
-    var keys = Object.keys(selector);
-    if (keys.length === 0) {
-      throw new Error('invalid empty selector');
-    }
-    //var selection = selector[keys[0]];
-    /*if (Object.keys(selection).length !== 1) {
-      throw new Error('invalid selector: ' + JSON.stringify(selection) +
-        ' - it must have exactly one key/value');
-    }
-  }*/
+function createBuiltInError(name) {
+  var message = 'builtin ' + name +
+    ' function requires map values to be numbers' +
+    ' or number arrays';
+  return new BuiltInError(message);
 }
 
-// determine the maximum number of fields
-// we're going to need to query, e.g. if the user
-// has selection ['a'] and sorting ['a', 'b'], then we
-// need to use the longer of the two: ['a', 'b']
-function getUserFields(selector, sort) {
-  var selectorFields = Object.keys(selector);
-  var sortFields = sort? sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey) : [];
-  var userFields;
-  if (selectorFields.length >= sortFields.length) {
-    userFields = selectorFields;
-  } else {
-    userFields = sortFields;
+function sum(values) {
+  var result = 0;
+  for (var i = 0, len = values.length; i < len; i++) {
+    var num = values[i];
+    if (typeof num !== 'number') {
+      if (Array.isArray(num)) {
+        // lists of numbers are also allowed, sum them separately
+        result = typeof result === 'number' ? [result] : result;
+        for (var j = 0, jLen = num.length; j < jLen; j++) {
+          var jNum = num[j];
+          if (typeof jNum !== 'number') {
+            throw createBuiltInError('_sum');
+          } else if (typeof result[j] === 'undefined') {
+            result.push(jNum);
+          } else {
+            result[j] += jNum;
+          }
+        }
+      } else { // not array/number
+        throw createBuiltInError('_sum');
+      }
+    } else if (typeof result === 'number') {
+      result += num;
+    } else { // add number to array
+      result[0] += num;
+    }
   }
+  return result;
+}
 
-  if (sortFields.length === 0) {
-    return {
-      fields: userFields
-    };
-  }
+var log = guardedConsole.bind(null, 'log');
+var isArray = Array.isArray;
+var toJSON = JSON.parse;
 
-  // sort according to the user's preferred sorting
-  userFields = userFields.sort(function (left, right) {
-    var leftIdx = sortFields.indexOf(left);
-    if (leftIdx === -1) {
-      leftIdx = Number.MAX_VALUE;
-    }
-    var rightIdx = sortFields.indexOf(right);
-    if (rightIdx === -1) {
-      rightIdx = Number.MAX_VALUE;
+function evalFunctionWithEval(func, emit) {
+  return scopeEval(
+    "return (" + func.replace(/;\s*$/, "") + ");",
+    {
+      emit: emit,
+      sum: sum,
+      log: log,
+      isArray: isArray,
+      toJSON: toJSON
     }
-    return leftIdx < rightIdx ? -1 : leftIdx > rightIdx ? 1 : 0;
-  });
-
-  return {
-    fields: userFields,
-    sortOrder: sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)
-  };
+  );
 }
 
-function createIndex$1(db, requestDef) {
-  requestDef = massageCreateIndexRequest(requestDef);
-  var originalIndexDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef.index);
-  requestDef.index = massageIndexDef(requestDef.index);
+/*
+ * Simple task queue to sequentialize actions. Assumes
+ * callbacks will eventually fire (once).
+ */
 
-  validateIndex(requestDef.index);
 
-  // calculating md5 is expensive - memoize and only
-  // run if required
-  var md5;
-  function getMd5() {
-    return md5 || (md5 = (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__.stringMd5)(JSON.stringify(requestDef)));
-  }
+function TaskQueue$1() {
+  this.promise = new Promise(function (fulfill) {fulfill(); });
+}
+TaskQueue$1.prototype.add = function (promiseFactory) {
+  this.promise = this.promise.catch(function () {
+    // just recover
+  }).then(function () {
+    return promiseFactory();
+  });
+  return this.promise;
+};
+TaskQueue$1.prototype.finish = function () {
+  return this.promise;
+};
 
-  var viewName = requestDef.name || ('idx-' + getMd5());
+function stringify(input) {
+  if (!input) {
+    return 'undefined'; // backwards compat for empty reduce
+  }
+  // for backwards compat with mapreduce, functions/strings are stringified
+  // as-is. everything else is JSON-stringified.
+  switch (typeof input) {
+    case 'function':
+      // e.g. a mapreduce map
+      return input.toString();
+    case 'string':
+      // e.g. a mapreduce built-in _reduce function
+      return input.toString();
+    default:
+      // e.g. a JSON object in the case of mango queries
+      return JSON.stringify(input);
+  }
+}
 
-  var ddocName = requestDef.ddoc || ('idx-' + getMd5());
-  var ddocId = '_design/' + ddocName;
+/* create a string signature for a view so we can cache it and uniq it */
+function createViewSignature(mapFun, reduceFun) {
+  // the "undefined" part is for backwards compatibility
+  return stringify(mapFun) + stringify(reduceFun) + 'undefined';
+}
 
-  var hasInvalidLanguage = false;
-  var viewExists = false;
+function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) {
+  var viewSignature = createViewSignature(mapFun, reduceFun);
 
-  function updateDdoc(doc) {
-    if (doc._rev && doc.language !== 'query') {
-      hasInvalidLanguage = true;
+  var cachedViews;
+  if (!temporary) {
+    // cache this to ensure we don't try to update the same view twice
+    cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {};
+    if (cachedViews[viewSignature]) {
+      return cachedViews[viewSignature];
     }
-    doc.language = 'query';
-    doc.views = doc.views || {};
+  }
 
-    viewExists = !!doc.views[viewName];
+  var promiseForView = sourceDB.info().then(function (info) {
 
-    if (viewExists) {
-      return false;
-    }
+    var depDbName = info.db_name + '-mrview-' +
+      (temporary ? 'temp' : stringMd5(viewSignature));
 
-    doc.views[viewName] = {
-      map: {
-        fields: mergeObjects(requestDef.index.fields)
-      },
-      reduce: '_count',
-      options: {
-        def: originalIndexDef
+    // save the view name in the source db so it can be cleaned up if necessary
+    // (e.g. when the _design doc is deleted, remove all associated view data)
+    function diffFunction(doc) {
+      doc.views = doc.views || {};
+      var fullViewName = viewName;
+      if (fullViewName.indexOf('/') === -1) {
+        fullViewName = viewName + '/' + viewName;
       }
-    };
-
-    return doc;
-  }
-
-  db.constructor.emit('debug', ['find', 'creating index', ddocId]);
-
-  return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, ddocId, updateDdoc).then(function () {
-    if (hasInvalidLanguage) {
-      throw new Error('invalid language for ddoc with id "' +
-      ddocId +
-      '" (should be "query")');
+      var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
+      /* istanbul ignore if */
+      if (depDbs[depDbName]) {
+        return; // no update necessary
+      }
+      depDbs[depDbName] = true;
+      return doc;
     }
-  }).then(function () {
-    // kick off a build
-    // TODO: abstract-pouchdb-mapreduce should support auto-updating
-    // TODO: should also use update_after, but pouchdb/pouchdb#3415 blocks me
-    var signature = ddocName + '/' + viewName;
-    return abstractMapper.query.call(db, signature, {
-      limit: 0,
-      reduce: false
-    }).then(function () {
-      return {
-        id: ddocId,
-        name: viewName,
-        result: viewExists ? 'exists' : 'created'
-      };
+    return upsert(sourceDB, '_local/' + localDocName, diffFunction).then(function () {
+      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
+        var db = res.db;
+        db.auto_compaction = true;
+        var view = {
+          name: depDbName,
+          db: db,
+          sourceDB: sourceDB,
+          adapter: sourceDB.adapter,
+          mapFun: mapFun,
+          reduceFun: reduceFun
+        };
+        return view.db.get('_local/lastSeq').catch(function (err) {
+          /* istanbul ignore if */
+          if (err.status !== 404) {
+            throw err;
+          }
+        }).then(function (lastSeqDoc) {
+          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
+          if (cachedViews) {
+            view.db.once('destroyed', function () {
+              delete cachedViews[viewSignature];
+            });
+          }
+          return view;
+        });
+      });
     });
   });
+
+  if (cachedViews) {
+    cachedViews[viewSignature] = promiseForView;
+  }
+  return promiseForView;
 }
 
-function getIndexes$1(db) {
-  // just search through all the design docs and filter in-memory.
-  // hopefully there aren't that many ddocs.
-  return db.allDocs({
-    startkey: '_design/',
-    endkey: '_design/\uffff',
-    include_docs: true
-  }).then(function (allDocsRes) {
-    var res = {
-      indexes: [{
-        ddoc: null,
-        name: '_all_docs',
-        type: 'special',
-        def: {
-          fields: [{_id: 'asc'}]
-        }
-      }]
-    };
+var persistentQueues = {};
+var tempViewQueue = new TaskQueue$1();
+var CHANGES_BATCH_SIZE$1 = 50;
 
-    res.indexes = flatten(res.indexes, allDocsRes.rows.filter(function (row) {
-      return row.doc.language === 'query';
-    }).map(function (row) {
-      var viewNames = row.doc.views !== undefined ? Object.keys(row.doc.views) : [];
+function parseViewName(name) {
+  // can be either 'ddocname/viewname' or just 'viewname'
+  // (where the ddoc name is the same)
+  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+}
 
-      return viewNames.map(function (viewName) {
-        var view = row.doc.views[viewName];
-        return {
-          ddoc: row.id,
-          name: viewName,
-          type: 'json',
-          def: massageIndexDef(view.options.def)
-        };
-      });
-    }));
+function isGenOne(changes) {
+  // only return true if the current change is 1-
+  // and there are no other leafs
+  return changes.length === 1 && /^1-/.test(changes[0].rev);
+}
 
-    // these are sorted by view name for some reason
-    res.indexes.sort(function (left, right) {
-      return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(left.name, right.name);
-    });
-    res.total_rows = res.indexes.length;
-    return res;
-  });
+function emitError(db, e) {
+  try {
+    db.emit('error', e);
+  } catch (err) {
+    guardedConsole('error',
+      'The user\'s map/reduce function threw an uncaught error.\n' +
+      'You can debug this error by doing:\n' +
+      'myDatabase.on(\'error\', function (err) { debugger; });\n' +
+      'Please double-check your map/reduce function.');
+    guardedConsole('error', e);
+  }
 }
 
-// couchdb lowest collation value
-var COLLATE_LO = null;
+/**
+ * Returns an "abstract" mapreduce object of the form:
+ *
+ *   {
+ *     query: queryFun,
+ *     viewCleanup: viewCleanupFun
+ *   }
+ *
+ * Arguments are:
+ *
+ * localDoc: string
+ *   This is for the local doc that gets saved in order to track the
+ *   "dependent" DBs and clean them up for viewCleanup. It should be
+ *   unique, so that indexer plugins don't collide with each other.
+ * mapper: function (mapFunDef, emit)
+ *   Returns a map function based on the mapFunDef, which in the case of
+ *   normal map/reduce is just the de-stringified function, but may be
+ *   something else, such as an object in the case of pouchdb-find.
+ * reducer: function (reduceFunDef)
+ *   Ditto, but for reducing. Modules don't have to support reducing
+ *   (e.g. pouchdb-find).
+ * ddocValidator: function (ddoc, viewName)
+ *   Throws an error if the ddoc or viewName is not valid.
+ *   This could be a way to communicate to the user that the configuration for the
+ *   indexer is invalid.
+ */
+function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) {
 
-// couchdb highest collation value (TODO: well not really, but close enough amirite)
-var COLLATE_HI = {"\uffff": {}};
+  function tryMap(db, fun, doc) {
+    // emit an event if there was an error thrown by a map function.
+    // putting try/catches in a single function also avoids deoptimizations.
+    try {
+      fun(doc);
+    } catch (e) {
+      emitError(db, e);
+    }
+  }
 
-// couchdb second-lowest collation value
+  function tryReduce(db, fun, keys, values, rereduce) {
+    // same as above, but returning the result or an error. there are two separate
+    // functions to avoid extra memory allocations since the tryCode() case is used
+    // for custom map functions (common) vs this function, which is only used for
+    // custom reduce functions (rare)
+    try {
+      return {output : fun(keys, values, rereduce)};
+    } catch (e) {
+      emitError(db, e);
+      return {error: e};
+    }
+  }
 
-function checkFieldInIndex(index, field) {
-  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
-  for (var i = 0, len = indexFields.length; i < len; i++) {
-    var indexField = indexFields[i];
-    if (field === indexField) {
-      return true;
+  function sortByKeyThenValue(x, y) {
+    var keyCompare = collate(x.key, y.key);
+    return keyCompare !== 0 ? keyCompare : collate(x.value, y.value);
+  }
+
+  function sliceResults(results, limit, skip) {
+    skip = skip || 0;
+    if (typeof limit === 'number') {
+      return results.slice(skip, limit + skip);
+    } else if (skip > 0) {
+      return results.slice(skip);
     }
+    return results;
   }
-  return false;
-}
 
-// so when you do e.g. $eq/$eq, we can do it entirely in the database.
-// but when you do e.g. $gt/$eq, the first part can be done
-// in the database, but the second part has to be done in-memory,
-// because $gt has forced us to lose precision.
-// so that's what this determines
-function userOperatorLosesPrecision(selector, field) {
-  var matcher = selector[field];
-  var userOperator = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher);
+  function rowToDocId(row) {
+    var val = row.value;
+    // Users can explicitly specify a joined doc _id, or it
+    // defaults to the doc _id that emitted the key/value.
+    var docId = (val && typeof val === 'object' && val._id) || row.id;
+    return docId;
+  }
 
-  return userOperator !== '$eq';
-}
+  function readAttachmentsAsBlobOrBuffer(res) {
+    res.rows.forEach(function (row) {
+      var atts = row.doc && row.doc._attachments;
+      if (!atts) {
+        return;
+      }
+      Object.keys(atts).forEach(function (filename) {
+        var att = atts[filename];
+        atts[filename].data = b64ToBluffer(att.data, att.content_type);
+      });
+    });
+  }
 
-// sort the user fields by their position in the index,
-// if they're in the index
-function sortFieldsByIndex(userFields, index) {
-  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
+  function postprocessAttachments(opts) {
+    return function (res) {
+      if (opts.include_docs && opts.attachments && opts.binary) {
+        readAttachmentsAsBlobOrBuffer(res);
+      }
+      return res;
+    };
+  }
 
-  return userFields.slice().sort(function (a, b) {
-    var aIdx = indexFields.indexOf(a);
-    var bIdx = indexFields.indexOf(b);
-    if (aIdx === -1) {
-      aIdx = Number.MAX_VALUE;
-    }
-    if (bIdx === -1) {
-      bIdx = Number.MAX_VALUE;
+  function addHttpParam(paramName, opts, params, asJson) {
+    // add an http param from opts to params, optionally json-encoded
+    var val = opts[paramName];
+    if (typeof val !== 'undefined') {
+      if (asJson) {
+        val = encodeURIComponent(JSON.stringify(val));
+      }
+      params.push(paramName + '=' + val);
     }
-    return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(aIdx, bIdx);
-  });
-}
+  }
 
-// first pass to try to find fields that will need to be sorted in-memory
-function getBasicInMemoryFields(index, selector, userFields) {
+  function coerceInteger(integerCandidate) {
+    if (typeof integerCandidate !== 'undefined') {
+      var asNumber = Number(integerCandidate);
+      // prevents e.g. '1foo' or '1.1' being coerced to 1
+      if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
+        return asNumber;
+      } else {
+        return integerCandidate;
+      }
+    }
+  }
 
-  userFields = sortFieldsByIndex(userFields, index);
+  function coerceOptions(opts) {
+    opts.group_level = coerceInteger(opts.group_level);
+    opts.limit = coerceInteger(opts.limit);
+    opts.skip = coerceInteger(opts.skip);
+    return opts;
+  }
 
-  // check if any of the user selectors lose precision
-  var needToFilterInMemory = false;
-  for (var i = 0, len = userFields.length; i < len; i++) {
-    var field = userFields[i];
-    if (needToFilterInMemory || !checkFieldInIndex(index, field)) {
-      return userFields.slice(i);
-    }
-    if (i < len - 1 && userOperatorLosesPrecision(selector, field)) {
-      needToFilterInMemory = true;
+  function checkPositiveInteger(number) {
+    if (number) {
+      if (typeof number !== 'number') {
+        return  new QueryParseError('Invalid value for integer: "' +
+          number + '"');
+      }
+      if (number < 0) {
+        return new QueryParseError('Invalid value for positive integer: ' +
+          '"' + number + '"');
+      }
     }
   }
-  return [];
-}
 
-function getInMemoryFieldsFromNe(selector) {
-  var fields = [];
-  Object.keys(selector).forEach(function (field) {
-    var matcher = selector[field];
-    Object.keys(matcher).forEach(function (operator) {
-      if (operator === '$ne') {
-        fields.push(field);
+  function checkQueryParseError(options, fun) {
+    var startkeyName = options.descending ? 'endkey' : 'startkey';
+    var endkeyName = options.descending ? 'startkey' : 'endkey';
+
+    if (typeof options[startkeyName] !== 'undefined' &&
+      typeof options[endkeyName] !== 'undefined' &&
+      collate(options[startkeyName], options[endkeyName]) > 0) {
+      throw new QueryParseError('No rows can match your key range, ' +
+        'reverse your start_key and end_key or set {descending : true}');
+    } else if (fun.reduce && options.reduce !== false) {
+      if (options.include_docs) {
+        throw new QueryParseError('{include_docs:true} is invalid for reduce');
+      } else if (options.keys && options.keys.length > 1 &&
+        !options.group && !options.group_level) {
+        throw new QueryParseError('Multi-key fetches for reduce views must use ' +
+          '{group: true}');
+      }
+    }
+    ['group_level', 'limit', 'skip'].forEach(function (optionName) {
+      var error = checkPositiveInteger(options[optionName]);
+      if (error) {
+        throw error;
       }
     });
-  });
-  return fields;
-}
+  }
 
-function getInMemoryFields(coreInMemoryFields, index, selector, userFields) {
-  var result = flatten(
-    // in-memory fields reported as necessary by the query planner
-    coreInMemoryFields,
-    // combine with another pass that checks for any we may have missed
-    getBasicInMemoryFields(index, selector, userFields),
-    // combine with another pass that checks for $ne's
-    getInMemoryFieldsFromNe(selector)
-  );
+  function httpQuery(db, fun, opts) {
+    // List of parameters to add to the PUT request
+    var params = [];
+    var body;
+    var method = 'GET';
+    var ok, status;
 
-  return sortFieldsByIndex(uniq(result), index);
-}
+    // If opts.reduce exists and is defined, then add it to the list
+    // of parameters.
+    // If reduce=false then the results are that of only the map function
+    // not the final result of map and reduce.
+    addHttpParam('reduce', opts, params);
+    addHttpParam('include_docs', opts, params);
+    addHttpParam('attachments', opts, params);
+    addHttpParam('limit', opts, params);
+    addHttpParam('descending', opts, params);
+    addHttpParam('group', opts, params);
+    addHttpParam('group_level', opts, params);
+    addHttpParam('skip', opts, params);
+    addHttpParam('stale', opts, params);
+    addHttpParam('conflicts', opts, params);
+    addHttpParam('startkey', opts, params, true);
+    addHttpParam('start_key', opts, params, true);
+    addHttpParam('endkey', opts, params, true);
+    addHttpParam('end_key', opts, params, true);
+    addHttpParam('inclusive_end', opts, params);
+    addHttpParam('key', opts, params, true);
+    addHttpParam('update_seq', opts, params);
 
-// check that at least one field in the user's query is represented
-// in the index. order matters in the case of sorts
-function checkIndexFieldsMatch(indexFields, sortOrder, fields) {
-  if (sortOrder) {
-    // array has to be a strict subarray of index array. furthermore,
-    // the sortOrder fields need to all be represented in the index
-    var sortMatches = oneArrayIsStrictSubArrayOfOther(sortOrder, indexFields);
-    var selectorMatches = oneArrayIsSubArrayOfOther(fields, indexFields);
+    // Format the list of parameters into a valid URI query string
+    params = params.join('&');
+    params = params === '' ? '' : '?' + params;
 
-    return sortMatches && selectorMatches;
-  }
+    // If keys are supplied, issue a POST to circumvent GET query string limits
+    // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+    if (typeof opts.keys !== 'undefined') {
+      var MAX_URL_LENGTH = 2000;
+      // according to http://stackoverflow.com/a/417184/680742,
+      // the de facto URL length limit is 2000 characters
 
-  // all of the user's specified fields still need to be
-  // on the left side of the index array, although the order
-  // doesn't matter
-  return oneSetIsSubArrayOfOther(fields, indexFields);
-}
+      var keysAsString =
+        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
+      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
+        // If the keys are short enough, do a GET. we do this to work around
+        // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
+        params += (params[0] === '?' ? '&' : '?') + keysAsString;
+      } else {
+        method = 'POST';
+        if (typeof fun === 'string') {
+          body = {keys: opts.keys};
+        } else { // fun is {map : mapfun}, so append to this
+          fun.keys = opts.keys;
+        }
+      }
+    }
 
-var logicalMatchers = ['$eq', '$gt', '$gte', '$lt', '$lte'];
-function isNonLogicalMatcher(matcher) {
-  return logicalMatchers.indexOf(matcher) === -1;
-}
+    // We are referencing a query defined in the design doc
+    if (typeof fun === 'string') {
+      var parts = parseViewName(fun);
+      return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
+        headers: new h({'Content-Type': 'application/json'}),
+        method: method,
+        body: JSON.stringify(body)
+      }).then(function (response) {
+        ok = response.ok;
+        status = response.status;
+        return response.json();
+      }).then(function (result) {
+        if (!ok) {
+          result.status = status;
+          throw generateErrorFromResponse(result);
+        }
+        // fail the entire request if the result contains an error
+        result.rows.forEach(function (row) {
+          /* istanbul ignore if */
+          if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
+            throw new Error(row.reason);
+          }
+        });
+        return result;
+      }).then(postprocessAttachments(opts));
+    }
 
-// check all the index fields for usages of '$ne'
-// e.g. if the user queries {foo: {$ne: 'foo'}, bar: {$eq: 'bar'}},
-// then we can neither use an index on ['foo'] nor an index on
-// ['foo', 'bar'], but we can use an index on ['bar'] or ['bar', 'foo']
-function checkFieldsLogicallySound(indexFields, selector) {
-  var firstField = indexFields[0];
-  var matcher = selector[firstField];
+    // We are using a temporary view, terrible for performance, good for testing
+    body = body || {};
+    Object.keys(fun).forEach(function (key) {
+      if (Array.isArray(fun[key])) {
+        body[key] = fun[key];
+      } else {
+        body[key] = fun[key].toString();
+      }
+    });
 
-  if (typeof matcher === 'undefined') {
-    /* istanbul ignore next */
-    return true;
+    return db.fetch('_temp_view' + params, {
+      headers: new h({'Content-Type': 'application/json'}),
+      method: 'POST',
+      body: JSON.stringify(body)
+    }).then(function (response) {
+        ok = response.ok;
+        status = response.status;
+      return response.json();
+    }).then(function (result) {
+      if (!ok) {
+        result.status = status;
+        throw generateErrorFromResponse(result);
+      }
+      return result;
+    }).then(postprocessAttachments(opts));
   }
 
-  var hasLogicalOperator = Object.keys(matcher).some(function (matcherKey) {
-    return !(isNonLogicalMatcher(matcherKey));
-  });
-
-  if (!hasLogicalOperator) {
-    return false;
+  // custom adapters can define their own api._query
+  // and override the default behavior
+  /* istanbul ignore next */
+  function customQuery(db, fun, opts) {
+    return new Promise(function (resolve, reject) {
+      db._query(fun, opts, function (err, res) {
+        if (err) {
+          return reject(err);
+        }
+        resolve(res);
+      });
+    });
   }
 
-  var isInvalidNe = Object.keys(matcher).length === 1 &&
-    (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher) === '$ne';
-
-  return !isInvalidNe;
-}
+  // custom adapters can define their own api._viewCleanup
+  // and override the default behavior
+  /* istanbul ignore next */
+  function customViewCleanup(db) {
+    return new Promise(function (resolve, reject) {
+      db._viewCleanup(function (err, res) {
+        if (err) {
+          return reject(err);
+        }
+        resolve(res);
+      });
+    });
+  }
 
-function checkIndexMatches(index, sortOrder, fields, selector) {
+  function defaultsTo(value) {
+    return function (reason) {
+      /* istanbul ignore else */
+      if (reason.status === 404) {
+        return value;
+      } else {
+        throw reason;
+      }
+    };
+  }
 
-  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
+  // returns a promise for a list of docs to update, based on the input docId.
+  // the order doesn't matter, because post-3.2.0, bulkDocs
+  // is an atomic operation in all three adapters.
+  function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
+    var metaDocId = '_local/doc_' + docId;
+    var defaultMetaDoc = {_id: metaDocId, keys: []};
+    var docData = docIdsToChangesAndEmits.get(docId);
+    var indexableKeysToKeyValues = docData[0];
+    var changes = docData[1];
 
-  var fieldsMatch = checkIndexFieldsMatch(indexFields, sortOrder, fields);
+    function getMetaDoc() {
+      if (isGenOne(changes)) {
+        // generation 1, so we can safely assume initial state
+        // for performance reasons (avoids unnecessary GETs)
+        return Promise.resolve(defaultMetaDoc);
+      }
+      return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc));
+    }
 
-  if (!fieldsMatch) {
-    return false;
-  }
+    function getKeyValueDocs(metaDoc) {
+      if (!metaDoc.keys.length) {
+        // no keys, no need for a lookup
+        return Promise.resolve({rows: []});
+      }
+      return view.db.allDocs({
+        keys: metaDoc.keys,
+        include_docs: true
+      });
+    }
 
-  return checkFieldsLogicallySound(indexFields, selector);
-}
+    function processKeyValueDocs(metaDoc, kvDocsRes) {
+      var kvDocs = [];
+      var oldKeys = new ExportedSet();
 
-//
-// the algorithm is very simple:
-// take all the fields the user supplies, and if those fields
-// are a strict subset of the fields in some index,
-// then use that index
-//
-//
-function findMatchingIndexes(selector, userFields, sortOrder, indexes) {
+      for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
+        var row = kvDocsRes.rows[i];
+        var doc = row.doc;
+        if (!doc) { // deleted
+          continue;
+        }
+        kvDocs.push(doc);
+        oldKeys.add(doc._id);
+        doc._deleted = !indexableKeysToKeyValues.has(doc._id);
+        if (!doc._deleted) {
+          var keyValue = indexableKeysToKeyValues.get(doc._id);
+          if ('value' in keyValue) {
+            doc.value = keyValue.value;
+          }
+        }
+      }
+      var newKeys = mapToKeysArray(indexableKeysToKeyValues);
+      newKeys.forEach(function (key) {
+        if (!oldKeys.has(key)) {
+          // new doc
+          var kvDoc = {
+            _id: key
+          };
+          var keyValue = indexableKeysToKeyValues.get(key);
+          if ('value' in keyValue) {
+            kvDoc.value = keyValue.value;
+          }
+          kvDocs.push(kvDoc);
+        }
+      });
+      metaDoc.keys = uniq(newKeys.concat(metaDoc.keys));
+      kvDocs.push(metaDoc);
 
-  return indexes.reduce(function (res, index) {
-    var indexMatches = checkIndexMatches(index, sortOrder, userFields, selector);
-    if (indexMatches) {
-      res.push(index);
+      return kvDocs;
     }
-    return res;
-  }, []);
-}
 
-// find the best index, i.e. the one that matches the most fields
-// in the user's query
-function findBestMatchingIndex(selector, userFields, sortOrder, indexes, useIndex) {
+    return getMetaDoc().then(function (metaDoc) {
+      return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
+        return processKeyValueDocs(metaDoc, kvDocsRes);
+      });
+    });
+  }
 
-  var matchingIndexes = findMatchingIndexes(selector, userFields, sortOrder, indexes);
+  // updates all emitted key/value docs and metaDocs in the mrview database
+  // for the given batch of documents from the source database
+  function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
+    var seqDocId = '_local/lastSeq';
+    return view.db.get(seqDocId)
+      .catch(defaultsTo({_id: seqDocId, seq: 0}))
+      .then(function (lastSeqDoc) {
+        var docIds = mapToKeysArray(docIdsToChangesAndEmits);
+        return Promise.all(docIds.map(function (docId) {
+          return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
+        })).then(function (listOfDocsToPersist) {
+          var docsToPersist = flatten(listOfDocsToPersist);
+          lastSeqDoc.seq = seq;
+          docsToPersist.push(lastSeqDoc);
+          // write all docs in a single operation, update the seq once
+          return view.db.bulkDocs({docs : docsToPersist});
+        });
+      });
+  }
 
-  if (matchingIndexes.length === 0) {
-    if (useIndex) {
-      throw {
-        error: "no_usable_index",
-        message: "There is no index available for this selector."
-      };
+  function getQueue(view) {
+    var viewName = typeof view === 'string' ? view : view.name;
+    var queue = persistentQueues[viewName];
+    if (!queue) {
+      queue = persistentQueues[viewName] = new TaskQueue$1();
     }
-    //return `all_docs` as a default index;
-    //I'm assuming that _all_docs is always first
-    var defaultIndex = indexes[0];
-    defaultIndex.defaultUsed = true;
-    return defaultIndex;
+    return queue;
   }
-  if (matchingIndexes.length === 1 && !useIndex) {
-    return matchingIndexes[0];
+
+  function updateView(view) {
+    return sequentialize(getQueue(view), function () {
+      return updateViewInQueue(view);
+    })();
   }
 
-  var userFieldsMap = arrayToObject(userFields);
+  function updateViewInQueue(view) {
+    // bind the emit function once
+    var mapResults;
+    var doc;
 
-  function scoreIndex(index) {
-    var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
-    var score = 0;
-    for (var i = 0, len = indexFields.length; i < len; i++) {
-      var indexField = indexFields[i];
-      if (userFieldsMap[indexField]) {
-        score++;
+    function emit(key, value) {
+      var output = {id: doc._id, key: normalizeKey(key)};
+      // Don't explicitly store the value unless it's defined and non-null.
+      // This saves on storage space, because often people don't use it.
+      if (typeof value !== 'undefined' && value !== null) {
+        output.value = normalizeKey(value);
       }
+      mapResults.push(output);
     }
-    return score;
-  }
-
-  if (useIndex) {
-    var useIndexDdoc = '_design/' + useIndex[0];
-    var useIndexName = useIndex.length === 2 ? useIndex[1] : false;
-    var index = matchingIndexes.find(function (index) {
-      if (useIndexName && index.ddoc === useIndexDdoc && useIndexName === index.name) {
-        return true;
-      }
 
-      if (index.ddoc === useIndexDdoc) {
-        /* istanbul ignore next */
-        return true;
-      }
+    var mapFun = mapper(view.mapFun, emit);
 
-      return false;
-    });
+    var currentSeq = view.seq || 0;
 
-    if (!index) {
-      throw {
-        error: "unknown_error",
-        message: "Could not find that index or could not use that index for the query"
+    function processChange(docIdsToChangesAndEmits, seq) {
+      return function () {
+        return saveKeyValues(view, docIdsToChangesAndEmits, seq);
       };
     }
-    return index;
-  }
-
-  return max(matchingIndexes, scoreIndex);
-}
-
-function getSingleFieldQueryOptsFor(userOperator, userValue) {
-  switch (userOperator) {
-    case '$eq':
-      return {key: userValue};
-    case '$lte':
-      return {endkey: userValue};
-    case '$gte':
-      return {startkey: userValue};
-    case '$lt':
-      return {
-        endkey: userValue,
-        inclusive_end: false
-      };
-    case '$gt':
-      return {
-        startkey: userValue,
-        inclusive_start: false
-      };
-  }
-}
 
-function getSingleFieldCoreQueryPlan(selector, index) {
-  var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[0]);
-  //ignoring this because the test to exercise the branch is skipped at the moment
-  /* istanbul ignore next */
-  var matcher = selector[field] || {};
-  var inMemoryFields = [];
-
-  var userOperators = Object.keys(matcher);
-
-  var combinedOpts;
+    var queue = new TaskQueue$1();
 
-  userOperators.forEach(function (userOperator) {
+    function processNextBatch() {
+      return view.sourceDB.changes({
+        return_docs: true,
+        conflicts: true,
+        include_docs: true,
+        style: 'all_docs',
+        since: currentSeq,
+        limit: CHANGES_BATCH_SIZE$1
+      }).then(processBatch);
+    }
 
-    if (isNonLogicalMatcher(userOperator)) {
-      inMemoryFields.push(field);
-      return;
+    function processBatch(response) {
+      var results = response.results;
+      if (!results.length) {
+        return;
+      }
+      var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results);
+      queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
+      if (results.length < CHANGES_BATCH_SIZE$1) {
+        return;
+      }
+      return processNextBatch();
     }
 
-    var userValue = matcher[userOperator];
+    function createDocIdsToChangesAndEmits(results) {
+      var docIdsToChangesAndEmits = new ExportedMap();
+      for (var i = 0, len = results.length; i < len; i++) {
+        var change = results[i];
+        if (change.doc._id[0] !== '_') {
+          mapResults = [];
+          doc = change.doc;
 
-    var newQueryOpts = getSingleFieldQueryOptsFor(userOperator, userValue);
+          if (!doc._deleted) {
+            tryMap(view.sourceDB, mapFun, doc);
+          }
+          mapResults.sort(sortByKeyThenValue);
 
-    if (combinedOpts) {
-      combinedOpts = mergeObjects([combinedOpts, newQueryOpts]);
-    } else {
-      combinedOpts = newQueryOpts;
+          var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults);
+          docIdsToChangesAndEmits.set(change.doc._id, [
+            indexableKeysToKeyValues,
+            change.changes
+          ]);
+        }
+        currentSeq = change.seq;
+      }
+      return docIdsToChangesAndEmits;
     }
-  });
 
-  return {
-    queryOpts: combinedOpts,
-    inMemoryFields: inMemoryFields
-  };
-}
+    function createIndexableKeysToKeyValues(mapResults) {
+      var indexableKeysToKeyValues = new ExportedMap();
+      var lastKey;
+      for (var i = 0, len = mapResults.length; i < len; i++) {
+        var emittedKeyValue = mapResults[i];
+        var complexKey = [emittedKeyValue.key, emittedKeyValue.id];
+        if (i > 0 && collate(emittedKeyValue.key, lastKey) === 0) {
+          complexKey.push(i); // dup key+id, so make it unique
+        }
+        indexableKeysToKeyValues.set(toIndexableString(complexKey), emittedKeyValue);
+        lastKey = emittedKeyValue.key;
+      }
+      return indexableKeysToKeyValues;
+    }
 
-function getMultiFieldCoreQueryPlan(userOperator, userValue) {
-  switch (userOperator) {
-    case '$eq':
-      return {
-        startkey: userValue,
-        endkey: userValue
-      };
-    case '$lte':
-      return {
-        endkey: userValue
-      };
-    case '$gte':
-      return {
-        startkey: userValue
-      };
-    case '$lt':
-      return {
-        endkey: userValue,
-        inclusive_end: false
-      };
-    case '$gt':
-      return {
-        startkey: userValue,
-        inclusive_start: false
-      };
+    return processNextBatch().then(function () {
+      return queue.finish();
+    }).then(function () {
+      view.seq = currentSeq;
+    });
   }
-}
 
-function getMultiFieldQueryOpts(selector, index) {
+  function reduceView(view, results, options) {
+    if (options.group_level === 0) {
+      delete options.group_level;
+    }
 
-  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
+    var shouldGroup = options.group || options.group_level;
 
-  var inMemoryFields = [];
-  var startkey = [];
-  var endkey = [];
-  var inclusiveStart;
-  var inclusiveEnd;
+    var reduceFun = reducer(view.reduceFun);
 
+    var groups = [];
+    var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
+      options.group_level;
+    results.forEach(function (e) {
+      var last = groups[groups.length - 1];
+      var groupKey = shouldGroup ? e.key : null;
 
-  function finish(i) {
+      // only set group_level for array keys
+      if (shouldGroup && Array.isArray(groupKey)) {
+        groupKey = groupKey.slice(0, lvl);
+      }
 
-    if (inclusiveStart !== false) {
-      startkey.push(COLLATE_LO);
-    }
-    if (inclusiveEnd !== false) {
-      endkey.push(COLLATE_HI);
+      if (last && collate(last.groupKey, groupKey) === 0) {
+        last.keys.push([e.key, e.id]);
+        last.values.push(e.value);
+        return;
+      }
+      groups.push({
+        keys: [[e.key, e.id]],
+        values: [e.value],
+        groupKey: groupKey
+      });
+    });
+    results = [];
+    for (var i = 0, len = groups.length; i < len; i++) {
+      var e = groups[i];
+      var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false);
+      if (reduceTry.error && reduceTry.error instanceof BuiltInError) {
+        // CouchDB returns an error if a built-in errors out
+        throw reduceTry.error;
+      }
+      results.push({
+        // CouchDB just sets the value to null if a non-built-in errors out
+        value: reduceTry.error ? null : reduceTry.output,
+        key: e.groupKey
+      });
     }
-    // keep track of the fields where we lost specificity,
-    // and therefore need to filter in-memory
-    inMemoryFields = indexFields.slice(i);
+    // no total_rows/offset when reducing
+    return {rows: sliceResults(results, options.limit, options.skip)};
   }
 
-  for (var i = 0, len = indexFields.length; i < len; i++) {
-    var indexField = indexFields[i];
-
-    var matcher = selector[indexField];
+  function queryView(view, opts) {
+    return sequentialize(getQueue(view), function () {
+      return queryViewInQueue(view, opts);
+    })();
+  }
 
-    if (!matcher || !Object.keys(matcher).length) { // fewer fields in user query than in index
-      finish(i);
-      break;
-    } else if (i > 0) {
-      if (Object.keys(matcher).some(isNonLogicalMatcher)) { // non-logical are ignored
-        finish(i);
-        break;
-      }
-      var usingGtlt = (
-        '$gt' in matcher || '$gte' in matcher ||
-        '$lt' in matcher || '$lte' in matcher);
-      var previousKeys = Object.keys(selector[indexFields[i - 1]]);
-      var previousWasEq = arrayEquals(previousKeys, ['$eq']);
-      var previousWasSame = arrayEquals(previousKeys, Object.keys(matcher));
-      var gtltLostSpecificity = usingGtlt && !previousWasEq && !previousWasSame;
-      if (gtltLostSpecificity) {
-        finish(i);
-        break;
-      }
+  function queryViewInQueue(view, opts) {
+    var totalRows;
+    var shouldReduce = view.reduceFun && opts.reduce !== false;
+    var skip = opts.skip || 0;
+    if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
+      // equivalent query
+      opts.limit = 0;
+      delete opts.keys;
     }
 
-    var userOperators = Object.keys(matcher);
+    function fetchFromView(viewOpts) {
+      viewOpts.include_docs = true;
+      return view.db.allDocs(viewOpts).then(function (res) {
+        totalRows = res.total_rows;
+        return res.rows.map(function (result) {
 
-    var combinedOpts = null;
+          // implicit migration - in older versions of PouchDB,
+          // we explicitly stored the doc as {id: ..., key: ..., value: ...}
+          // this is tested in a migration test
+          /* istanbul ignore next */
+          if ('value' in result.doc && typeof result.doc.value === 'object' &&
+            result.doc.value !== null) {
+            var keys = Object.keys(result.doc.value).sort();
+            // this detection method is not perfect, but it's unlikely the user
+            // emitted a value which was an object with these 3 exact keys
+            var expectedKeys = ['id', 'key', 'value'];
+            if (!(keys < expectedKeys || keys > expectedKeys)) {
+              return result.doc.value;
+            }
+          }
 
-    for (var j = 0; j < userOperators.length; j++) {
-      var userOperator = userOperators[j];
-      var userValue = matcher[userOperator];
+          var parsedKeyAndDocId = parseIndexableString(result.doc._id);
+          return {
+            key: parsedKeyAndDocId[0],
+            id: parsedKeyAndDocId[1],
+            value: ('value' in result.doc ? result.doc.value : null)
+          };
+        });
+      });
+    }
 
-      var newOpts = getMultiFieldCoreQueryPlan(userOperator, userValue);
+    function onMapResultsReady(rows) {
+      var finalResults;
+      if (shouldReduce) {
+        finalResults = reduceView(view, rows, opts);
+      } else {
+        finalResults = {
+          total_rows: totalRows,
+          offset: skip,
+          rows: rows
+        };
+      }
+      /* istanbul ignore if */
+      if (opts.update_seq) {
+        finalResults.update_seq = view.seq;
+      }
+      if (opts.include_docs) {
+        var docIds = uniq(rows.map(rowToDocId));
 
-      if (combinedOpts) {
-        combinedOpts = mergeObjects([combinedOpts, newOpts]);
+        return view.sourceDB.allDocs({
+          keys: docIds,
+          include_docs: true,
+          conflicts: opts.conflicts,
+          attachments: opts.attachments,
+          binary: opts.binary
+        }).then(function (allDocsRes) {
+          var docIdsToDocs = new ExportedMap();
+          allDocsRes.rows.forEach(function (row) {
+            docIdsToDocs.set(row.id, row.doc);
+          });
+          rows.forEach(function (row) {
+            var docId = rowToDocId(row);
+            var doc = docIdsToDocs.get(docId);
+            if (doc) {
+              row.doc = doc;
+            }
+          });
+          return finalResults;
+        });
       } else {
-        combinedOpts = newOpts;
+        return finalResults;
       }
     }
 
-    startkey.push('startkey' in combinedOpts ? combinedOpts.startkey : COLLATE_LO);
-    endkey.push('endkey' in combinedOpts ? combinedOpts.endkey : COLLATE_HI);
-    if ('inclusive_start' in combinedOpts) {
-      inclusiveStart = combinedOpts.inclusive_start;
-    }
-    if ('inclusive_end' in combinedOpts) {
-      inclusiveEnd = combinedOpts.inclusive_end;
+    if (typeof opts.keys !== 'undefined') {
+      var keys = opts.keys;
+      var fetchPromises = keys.map(function (key) {
+        var viewOpts = {
+          startkey : toIndexableString([key]),
+          endkey   : toIndexableString([key, {}])
+        };
+        /* istanbul ignore if */
+        if (opts.update_seq) {
+          viewOpts.update_seq = true;
+        }
+        return fetchFromView(viewOpts);
+      });
+      return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady);
+    } else { // normal query, no 'keys'
+      var viewOpts = {
+        descending : opts.descending
+      };
+      /* istanbul ignore if */
+      if (opts.update_seq) {
+        viewOpts.update_seq = true;
+      }
+      var startkey;
+      var endkey;
+      if ('start_key' in opts) {
+        startkey = opts.start_key;
+      }
+      if ('startkey' in opts) {
+        startkey = opts.startkey;
+      }
+      if ('end_key' in opts) {
+        endkey = opts.end_key;
+      }
+      if ('endkey' in opts) {
+        endkey = opts.endkey;
+      }
+      if (typeof startkey !== 'undefined') {
+        viewOpts.startkey = opts.descending ?
+          toIndexableString([startkey, {}]) :
+          toIndexableString([startkey]);
+      }
+      if (typeof endkey !== 'undefined') {
+        var inclusiveEnd = opts.inclusive_end !== false;
+        if (opts.descending) {
+          inclusiveEnd = !inclusiveEnd;
+        }
+
+        viewOpts.endkey = toIndexableString(
+          inclusiveEnd ? [endkey, {}] : [endkey]);
+      }
+      if (typeof opts.key !== 'undefined') {
+        var keyStart = toIndexableString([opts.key]);
+        var keyEnd = toIndexableString([opts.key, {}]);
+        if (viewOpts.descending) {
+          viewOpts.endkey = keyStart;
+          viewOpts.startkey = keyEnd;
+        } else {
+          viewOpts.startkey = keyStart;
+          viewOpts.endkey = keyEnd;
+        }
+      }
+      if (!shouldReduce) {
+        if (typeof opts.limit === 'number') {
+          viewOpts.limit = opts.limit;
+        }
+        viewOpts.skip = skip;
+      }
+      return fetchFromView(viewOpts).then(onMapResultsReady);
     }
   }
 
-  var res = {
-    startkey: startkey,
-    endkey: endkey
-  };
+  function httpViewCleanup(db) {
+    return db.fetch('_view_cleanup', {
+      headers: new h({'Content-Type': 'application/json'}),
+      method: 'POST'
+    }).then(function (response) {
+      return response.json();
+    });
+  }
+
+  function localViewCleanup(db) {
+    return db.get('_local/' + localDocName).then(function (metaDoc) {
+      var docsToViews = new ExportedMap();
+      Object.keys(metaDoc.views).forEach(function (fullViewName) {
+        var parts = parseViewName(fullViewName);
+        var designDocName = '_design/' + parts[0];
+        var viewName = parts[1];
+        var views = docsToViews.get(designDocName);
+        if (!views) {
+          views = new ExportedSet();
+          docsToViews.set(designDocName, views);
+        }
+        views.add(viewName);
+      });
+      var opts = {
+        keys : mapToKeysArray(docsToViews),
+        include_docs : true
+      };
+      return db.allDocs(opts).then(function (res) {
+        var viewsToStatus = {};
+        res.rows.forEach(function (row) {
+          var ddocName = row.key.substring(8); // cuts off '_design/'
+          docsToViews.get(row.key).forEach(function (viewName) {
+            var fullViewName = ddocName + '/' + viewName;
+            /* istanbul ignore if */
+            if (!metaDoc.views[fullViewName]) {
+              // new format, without slashes, to support PouchDB 2.2.0
+              // migration test in pouchdb's browser.migration.js verifies this
+              fullViewName = viewName;
+            }
+            var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
+            // design doc deleted, or view function nonexistent
+            var statusIsGood = row.doc && row.doc.views &&
+              row.doc.views[viewName];
+            viewDBNames.forEach(function (viewDBName) {
+              viewsToStatus[viewDBName] =
+                viewsToStatus[viewDBName] || statusIsGood;
+            });
+          });
+        });
+        var dbsToDelete = Object.keys(viewsToStatus).filter(
+          function (viewDBName) { return !viewsToStatus[viewDBName]; });
+        var destroyPromises = dbsToDelete.map(function (viewDBName) {
+          return sequentialize(getQueue(viewDBName), function () {
+            return new db.constructor(viewDBName, db.__opts).destroy();
+          })();
+        });
+        return Promise.all(destroyPromises).then(function () {
+          return {ok: true};
+        });
+      });
+    }, defaultsTo({ok: true}));
+  }
+
+  function queryPromised(db, fun, opts) {
+    /* istanbul ignore next */
+    if (typeof db._query === 'function') {
+      return customQuery(db, fun, opts);
+    }
+    if (isRemote(db)) {
+      return httpQuery(db, fun, opts);
+    }
 
-  if (typeof inclusiveStart !== 'undefined') {
-    res.inclusive_start = inclusiveStart;
-  }
-  if (typeof inclusiveEnd !== 'undefined') {
-    res.inclusive_end = inclusiveEnd;
-  }
+    if (typeof fun !== 'string') {
+      // temp_view
+      checkQueryParseError(opts, fun);
 
-  return {
-    queryOpts: res,
-    inMemoryFields: inMemoryFields
-  };
-}
+      tempViewQueue.add(function () {
+        var createViewPromise = createView(
+          /* sourceDB */ db,
+          /* viewName */ 'temp_view/temp_view',
+          /* mapFun */ fun.map,
+          /* reduceFun */ fun.reduce,
+          /* temporary */ true,
+          /* localDocName */ localDocName);
+        return createViewPromise.then(function (view) {
+          return fin(updateView(view).then(function () {
+            return queryView(view, opts);
+          }), function () {
+            return view.db.destroy();
+          });
+        });
+      });
+      return tempViewQueue.finish();
+    } else {
+      // persistent view
+      var fullViewName = fun;
+      var parts = parseViewName(fullViewName);
+      var designDocName = parts[0];
+      var viewName = parts[1];
+      return db.get('_design/' + designDocName).then(function (doc) {
+        var fun = doc.views && doc.views[viewName];
 
-function getDefaultQueryPlan(selector) {
-  //using default index, so all fields need to be done in memory
-  return {
-    queryOpts: {startkey: null},
-    inMemoryFields: [Object.keys(selector)]
-  };
-}
+        if (!fun) {
+          // basic validator; it's assumed that every subclass would want this
+          throw new NotFoundError('ddoc ' + doc._id + ' has no view named ' +
+            viewName);
+        }
 
-function getCoreQueryPlan(selector, index) {
-  if (index.defaultUsed) {
-    return getDefaultQueryPlan(selector, index);
-  }
+        ddocValidator(doc, viewName);
+        checkQueryParseError(opts, fun);
 
-  if (index.def.fields.length === 1) {
-    // one field in index, so the value was indexed as a singleton
-    return getSingleFieldCoreQueryPlan(selector, index);
+        var createViewPromise = createView(
+          /* sourceDB */ db,
+          /* viewName */ fullViewName,
+          /* mapFun */ fun.map,
+          /* reduceFun */ fun.reduce,
+          /* temporary */ false,
+          /* localDocName */ localDocName);
+        return createViewPromise.then(function (view) {
+          if (opts.stale === 'ok' || opts.stale === 'update_after') {
+            if (opts.stale === 'update_after') {
+              immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+                updateView(view);
+              });
+            }
+            return queryView(view, opts);
+          } else { // stale not ok
+            return updateView(view).then(function () {
+              return queryView(view, opts);
+            });
+          }
+        });
+      });
+    }
   }
-  // else index has multiple fields, so the value was indexed as an array
-  return getMultiFieldQueryOpts(selector, index);
-}
-
-function planQuery(request, indexes) {
 
-  var selector = request.selector;
-  var sort = request.sort;
-
-  var userFieldsRes = getUserFields(selector, sort);
+  function abstractQuery(fun, opts, callback) {
+    var db = this;
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = opts ? coerceOptions(opts) : {};
 
-  var userFields = userFieldsRes.fields;
-  var sortOrder = userFieldsRes.sortOrder;
-  var index = findBestMatchingIndex(selector, userFields, sortOrder, indexes, request.use_index);
+    if (typeof fun === 'function') {
+      fun = {map : fun};
+    }
 
-  var coreQueryPlan = getCoreQueryPlan(selector, index);
-  var queryOpts = coreQueryPlan.queryOpts;
-  var coreInMemoryFields = coreQueryPlan.inMemoryFields;
+    var promise = Promise.resolve().then(function () {
+      return queryPromised(db, fun, opts);
+    });
+    promisedCallback(promise, callback);
+    return promise;
+  }
 
-  var inMemoryFields = getInMemoryFields(coreInMemoryFields, index, selector, userFields);
+  var abstractViewCleanup = callbackify(function () {
+    var db = this;
+    /* istanbul ignore next */
+    if (typeof db._viewCleanup === 'function') {
+      return customViewCleanup(db);
+    }
+    if (isRemote(db)) {
+      return httpViewCleanup(db);
+    }
+    return localViewCleanup(db);
+  });
 
-  var res = {
-    queryOpts: queryOpts,
-    index: index,
-    inMemoryFields: inMemoryFields
+  return {
+    query: abstractQuery,
+    viewCleanup: abstractViewCleanup
   };
-  return res;
-}
-
-function indexToSignature(index) {
-  // remove '_design/'
-  return index.ddoc.substring(8) + '/' + index.name;
 }
 
-function doAllDocs(db, originalOpts) {
-  var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(originalOpts);
+var builtInReduce = {
+  _sum: function (keys, values) {
+    return sum(values);
+  },
 
-  // CouchDB responds in weird ways when you provide a non-string to _id;
-  // we mimic the behavior for consistency. See issue66 tests for details.
+  _count: function (keys, values) {
+    return values.length;
+  },
 
-  if (opts.descending) {
-    if ('endkey' in opts && typeof opts.endkey !== 'string') {
-      opts.endkey = '';
-    }
-    if ('startkey' in opts && typeof opts.startkey !== 'string') {
-      opts.limit = 0;
-    }
-  } else {
-    if ('startkey' in opts && typeof opts.startkey !== 'string') {
-      opts.startkey = '';
-    }
-    if ('endkey' in opts && typeof opts.endkey !== 'string') {
-      opts.limit = 0;
+  _stats: function (keys, values) {
+    // no need to implement rereduce=true, because Pouch
+    // will never call it
+    function sumsqr(values) {
+      var _sumsqr = 0;
+      for (var i = 0, len = values.length; i < len; i++) {
+        var num = values[i];
+        _sumsqr += (num * num);
+      }
+      return _sumsqr;
     }
+    return {
+      sum     : sum(values),
+      min     : Math.min.apply(null, values),
+      max     : Math.max.apply(null, values),
+      count   : values.length,
+      sumsqr : sumsqr(values)
+    };
   }
-  if ('key' in opts && typeof opts.key !== 'string') {
-    opts.limit = 0;
-  }
+};
 
-  return db.allDocs(opts)
-  .then(function (res) {
-    // filter out any design docs that _all_docs might return
-    res.rows = res.rows.filter(function (row) {
-      return !/^_design\//.test(row.id);
-    });
-    return res;
-  });
+function getBuiltIn(reduceFunString) {
+  if (/^_sum/.test(reduceFunString)) {
+    return builtInReduce._sum;
+  } else if (/^_count/.test(reduceFunString)) {
+    return builtInReduce._count;
+  } else if (/^_stats/.test(reduceFunString)) {
+    return builtInReduce._stats;
+  } else if (/^_/.test(reduceFunString)) {
+    throw new Error(reduceFunString + ' is not a supported reduce function.');
+  }
 }
 
-function find$1(db, requestDef, explain) {
-  if (requestDef.selector) {
-    requestDef.selector = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.massageSelector)(requestDef.selector);
+function mapper(mapFun, emit) {
+  // for temp_views one can use emit(doc, emit), see #38
+  if (typeof mapFun === "function" && mapFun.length === 2) {
+    var origMap = mapFun;
+    return function (doc) {
+      return origMap(doc, emit);
+    };
+  } else {
+    return evalFunctionWithEval(mapFun.toString(), emit);
   }
+}
 
-  if (requestDef.sort) {
-    requestDef.sort = massageSort(requestDef.sort);
+function reducer(reduceFun) {
+  var reduceFunString = reduceFun.toString();
+  var builtIn = getBuiltIn(reduceFunString);
+  if (builtIn) {
+    return builtIn;
+  } else {
+    return evalFunctionWithEval(reduceFunString);
   }
+}
 
-  if (requestDef.use_index) {
-    requestDef.use_index = massageUseIndex(requestDef.use_index);
+function ddocValidator(ddoc, viewName) {
+  var fun = ddoc.views && ddoc.views[viewName];
+  if (typeof fun.map !== 'string') {
+    throw new NotFoundError('ddoc ' + ddoc._id + ' has no string view named ' +
+      viewName + ', instead found object of type: ' + typeof fun.map);
   }
+}
 
-  validateFindRequest(requestDef);
+var localDocName = 'mrviews';
+var abstract = createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator);
 
-  return getIndexes$1(db).then(function (getIndexesRes) {
+function query(fun, opts, callback) {
+  return abstract.query.call(this, fun, opts, callback);
+}
 
-    db.constructor.emit('debug', ['find', 'planning query', requestDef]);
-    var queryPlan = planQuery(requestDef, getIndexesRes.indexes);
-    db.constructor.emit('debug', ['find', 'query plan', queryPlan]);
+function viewCleanup(callback) {
+  return abstract.viewCleanup.call(this, callback);
+}
 
-    var indexToUse = queryPlan.index;
+var mapreduce = {
+  query: query,
+  viewCleanup: viewCleanup
+};
 
-    validateSort(requestDef, indexToUse);
+function isGenOne$1(rev) {
+  return /^1-/.test(rev);
+}
 
-    var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)({
-      include_docs: true,
-      reduce: false
-    }, queryPlan.queryOpts);
+function fileHasChanged(localDoc, remoteDoc, filename) {
+  return !localDoc._attachments ||
+         !localDoc._attachments[filename] ||
+         localDoc._attachments[filename].digest !== remoteDoc._attachments[filename].digest;
+}
 
-    if ('startkey' in opts && 'endkey' in opts &&
-        (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(opts.startkey, opts.endkey) > 0) {
-      // can't possibly return any results, startkey > endkey
-      /* istanbul ignore next */
-      return {docs: []};
-    }
+function getDocAttachments(db, doc) {
+  var filenames = Object.keys(doc._attachments);
+  return Promise.all(filenames.map(function (filename) {
+    return db.getAttachment(doc._id, filename, {rev: doc._rev});
+  }));
+}
 
-    var isDescending = requestDef.sort &&
-      typeof requestDef.sort[0] !== 'string' &&
-      (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(requestDef.sort[0]) === 'desc';
+function getDocAttachmentsFromTargetOrSource(target, src, doc) {
+  var doCheckForLocalAttachments = isRemote(src) && !isRemote(target);
+  var filenames = Object.keys(doc._attachments);
 
-    if (isDescending) {
-      // either all descending or all ascending
-      opts.descending = true;
-      opts = reverseOptions(opts);
-    }
+  if (!doCheckForLocalAttachments) {
+    return getDocAttachments(src, doc);
+  }
 
-    if (!queryPlan.inMemoryFields.length) {
-      // no in-memory filtering necessary, so we can let the
-      // database do the limit/skip for us
-      if ('limit' in requestDef) {
-        opts.limit = requestDef.limit;
-      }
-      if ('skip' in requestDef) {
-        opts.skip = requestDef.skip;
+  return target.get(doc._id).then(function (localDoc) {
+    return Promise.all(filenames.map(function (filename) {
+      if (fileHasChanged(localDoc, doc, filename)) {
+        return src.getAttachment(doc._id, filename);
       }
-    }
 
-    if (explain) {
-      return Promise.resolve(queryPlan, opts);
+      return target.getAttachment(localDoc._id, filename);
+    }));
+  }).catch(function (error) {
+    /* istanbul ignore if */
+    if (error.status !== 404) {
+      throw error;
     }
 
-    return Promise.resolve().then(function () {
-      if (indexToUse.name === '_all_docs') {
-        return doAllDocs(db, opts);
-      } else {
-        var signature = indexToSignature(indexToUse);
-        return abstractMapper.query.call(db, signature, opts);
-      }
-    }).then(function (res) {
-      if (opts.inclusive_start === false) {
-        // may have to manually filter the first one,
-        // since couchdb has no true inclusive_start option
-        res.rows = filterInclusiveStart(res.rows, opts.startkey, indexToUse);
-      }
-
-      if (queryPlan.inMemoryFields.length) {
-        // need to filter some stuff in-memory
-        res.rows = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.filterInMemoryFields)(res.rows, requestDef, queryPlan.inMemoryFields);
-      }
-
-      var resp = {
-        docs: res.rows.map(function (row) {
-          var doc = row.doc;
-          if (requestDef.fields) {
-            return pick(doc, requestDef.fields);
-          }
-          return doc;
-        })
-      };
-
-      if (indexToUse.defaultUsed) {
-        resp.warning = 'no matching index found, create an index to optimize query time';
-      }
-
-      return resp;
-    });
+    return getDocAttachments(src, doc);
   });
 }
 
-function explain$1(db, requestDef) {
-  return find$1(db, requestDef, true)
-  .then(function (queryPlan) {
-    return {
-      dbname: db.name,
-      index: queryPlan.index,
-      selector: requestDef.selector,
-      range: {
-        start_key: queryPlan.queryOpts.startkey,
-        end_key: queryPlan.queryOpts.endkey,
-      },
-      opts: {
-        use_index: requestDef.use_index || [],
-        bookmark: "nil", //hardcoded to match CouchDB since its not supported,
-        limit: requestDef.limit,
-        skip: requestDef.skip,
-        sort: requestDef.sort || {},
-        fields: requestDef.fields,
-        conflicts: false, //hardcoded to match CouchDB since its not supported,
-        r: [49], // hardcoded to match CouchDB since its not support
-      },
-      limit: requestDef.limit,
-      skip: requestDef.skip || 0,
-      fields: requestDef.fields,
-    };
+function createBulkGetOpts(diffs) {
+  var requests = [];
+  Object.keys(diffs).forEach(function (id) {
+    var missingRevs = diffs[id].missing;
+    missingRevs.forEach(function (missingRev) {
+      requests.push({
+        id: id,
+        rev: missingRev
+      });
+    });
   });
+
+  return {
+    docs: requests,
+    revs: true,
+    latest: true
+  };
 }
 
-function deleteIndex$1(db, index) {
+//
+// Fetch all the documents from the src as described in the "diffs",
+// which is a mapping of docs IDs to revisions. If the state ever
+// changes to "cancelled", then the returned promise will be rejected.
+// Else it will be resolved with a list of fetched documents.
+//
+function getDocs(src, target, diffs, state) {
+  diffs = clone(diffs); // we do not need to modify this
 
-  if (!index.ddoc) {
-    throw new Error('you must supply an index.ddoc when deleting');
-  }
+  var resultDocs = [],
+      ok = true;
 
-  if (!index.name) {
-    throw new Error('you must supply an index.name when deleting');
-  }
+  function getAllDocs() {
 
-  var docId = index.ddoc;
-  var viewName = index.name;
+    var bulkGetOpts = createBulkGetOpts(diffs);
 
-  function deltaFun(doc) {
-    if (Object.keys(doc.views).length === 1 && doc.views[viewName]) {
-      // only one view in this ddoc, delete the whole ddoc
-      return {_id: docId, _deleted: true};
+    if (!bulkGetOpts.docs.length) { // optimization: skip empty requests
+      return;
     }
-    // more than one view here, just remove the view
-    delete doc.views[viewName];
-    return doc;
-  }
 
-  return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, docId, deltaFun).then(function () {
-    return abstractMapper.viewCleanup.apply(db);
-  }).then(function () {
-    return {ok: true};
-  });
-}
+    return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) {
+      /* istanbul ignore if */
+      if (state.cancelled) {
+        throw new Error('cancelled');
+      }
+      return Promise.all(bulkGetResponse.results.map(function (bulkGetInfo) {
+        return Promise.all(bulkGetInfo.docs.map(function (doc) {
+          var remoteDoc = doc.ok;
 
-var createIndexAsCallback = callbackify(createIndex$1);
-var findAsCallback = callbackify(find$1);
-var explainAsCallback = callbackify(explain$1);
-var getIndexesAsCallback = callbackify(getIndexes$1);
-var deleteIndexAsCallback = callbackify(deleteIndex$1);
+          if (doc.error) {
+            // when AUTO_COMPACTION is set, docs can be returned which look
+            // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"}
+            ok = false;
+          }
 
-var plugin = {};
-plugin.createIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) {
+          if (!remoteDoc || !remoteDoc._attachments) {
+            return remoteDoc;
+          }
 
-  if (typeof requestDef !== 'object') {
-    return callback(new Error('you must provide an index to create'));
-  }
+          return getDocAttachmentsFromTargetOrSource(target, src, remoteDoc)
+                   .then(function (attachments) {
+                           var filenames = Object.keys(remoteDoc._attachments);
+                           attachments
+                             .forEach(function (attachment, i) {
+                                        var att = remoteDoc._attachments[filenames[i]];
+                                        delete att.stub;
+                                        delete att.length;
+                                        att.data = attachment;
+                                      });
 
-  var createIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ?
-    createIndex : createIndexAsCallback;
-  createIndex$$1(this, requestDef, callback);
-});
+                                      return remoteDoc;
+                                    });
+        }));
+      }))
 
-plugin.find = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) {
+      .then(function (results) {
+        resultDocs = resultDocs.concat(flatten(results).filter(Boolean));
+      });
+    });
+  }
 
-  if (typeof callback === 'undefined') {
-    callback = requestDef;
-    requestDef = undefined;
+  function hasAttachments(doc) {
+    return doc._attachments && Object.keys(doc._attachments).length > 0;
   }
 
-  if (typeof requestDef !== 'object') {
-    return callback(new Error('you must provide search parameters to find()'));
+  function hasConflicts(doc) {
+    return doc._conflicts && doc._conflicts.length > 0;
   }
 
-  var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? find : findAsCallback;
-  find$$1(this, requestDef, callback);
-});
+  function fetchRevisionOneDocs(ids) {
+    // Optimization: fetch gen-1 docs and attachments in
+    // a single request using _all_docs
+    return src.allDocs({
+      keys: ids,
+      include_docs: true,
+      conflicts: true
+    }).then(function (res) {
+      if (state.cancelled) {
+        throw new Error('cancelled');
+      }
+      res.rows.forEach(function (row) {
+        if (row.deleted || !row.doc || !isGenOne$1(row.value.rev) ||
+            hasAttachments(row.doc) || hasConflicts(row.doc)) {
+          // if any of these conditions apply, we need to fetch using get()
+          return;
+        }
 
-plugin.explain = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) {
+        // strip _conflicts array to appease CSG (#5793)
+        /* istanbul ignore if */
+        if (row.doc._conflicts) {
+          delete row.doc._conflicts;
+        }
 
-  if (typeof callback === 'undefined') {
-    callback = requestDef;
-    requestDef = undefined;
+        // the doc we got back from allDocs() is sufficient
+        resultDocs.push(row.doc);
+        delete diffs[row.id];
+      });
+    });
   }
 
-  if (typeof requestDef !== 'object') {
-    return callback(new Error('you must provide search parameters to explain()'));
+  function getRevisionOneDocs() {
+    // filter out the generation 1 docs and get them
+    // leaving the non-generation one docs to be got otherwise
+    var ids = Object.keys(diffs).filter(function (id) {
+      var missing = diffs[id].missing;
+      return missing.length === 1 && isGenOne$1(missing[0]);
+    });
+    if (ids.length > 0) {
+      return fetchRevisionOneDocs(ids);
+    }
   }
 
-  var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? explain : explainAsCallback;
-  find$$1(this, requestDef, callback);
-});
-
-plugin.getIndexes = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (callback) {
-
-  var getIndexes$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? getIndexes : getIndexesAsCallback;
-  getIndexes$$1(this, callback);
-});
-
-plugin.deleteIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (indexDef, callback) {
-
-  if (typeof indexDef !== 'object') {
-    return callback(new Error('you must provide an index to delete'));
+  function returnResult() {
+    return { ok:ok, docs:resultDocs };
   }
 
-  var deleteIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ?
-    deleteIndex : deleteIndexAsCallback;
-  deleteIndex$$1(this, indexDef, callback);
-});
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (plugin);
-
-
-/***/ }),
-/* 495 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "adapterFun": () => (/* binding */ adapterFun),
-/* harmony export */   "assign": () => (/* binding */ assign$1),
-/* harmony export */   "bulkGetShim": () => (/* binding */ bulkGet),
-/* harmony export */   "changesHandler": () => (/* binding */ Changes),
-/* harmony export */   "clone": () => (/* binding */ clone$1),
-/* harmony export */   "defaultBackOff": () => (/* binding */ defaultBackOff),
-/* harmony export */   "explainError": () => (/* binding */ res),
-/* harmony export */   "filterChange": () => (/* binding */ filterChange),
-/* harmony export */   "flatten": () => (/* binding */ flatten),
-/* harmony export */   "functionName": () => (/* binding */ res$2),
-/* harmony export */   "guardedConsole": () => (/* binding */ guardedConsole),
-/* harmony export */   "hasLocalStorage": () => (/* binding */ hasLocalStorage),
-/* harmony export */   "invalidIdError": () => (/* binding */ invalidIdError),
-/* harmony export */   "isRemote": () => (/* binding */ isRemote),
-/* harmony export */   "listenerCount": () => (/* binding */ listenerCount),
-/* harmony export */   "nextTick": () => (/* binding */ nextTick),
-/* harmony export */   "normalizeDdocFunctionName": () => (/* binding */ normalizeDesignDocFunctionName),
-/* harmony export */   "once": () => (/* binding */ once),
-/* harmony export */   "parseDdocFunctionName": () => (/* binding */ parseDesignDocFunctionName),
-/* harmony export */   "parseUri": () => (/* binding */ parseUri),
-/* harmony export */   "pick": () => (/* binding */ pick),
-/* harmony export */   "rev": () => (/* binding */ rev),
-/* harmony export */   "scopeEval": () => (/* binding */ scopeEval),
-/* harmony export */   "toPromise": () => (/* binding */ toPromise),
-/* harmony export */   "upsert": () => (/* binding */ upsert),
-/* harmony export */   "uuid": () => (/* binding */ uuid)
-/* harmony export */ });
-/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(496);
-/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(clone_buffer__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(483);
-/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(497);
-/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(250);
-/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(485);
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(498);
-/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(488);
-/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_6__);
-/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(499);
-/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(495);
-
+  return Promise.resolve()
+    .then(getRevisionOneDocs)
+    .then(getAllDocs)
+    .then(returnResult);
+}
 
+var CHECKPOINT_VERSION = 1;
+var REPLICATOR = "pouchdb";
+// This is an arbitrary number to limit the
+// amount of replication history we save in the checkpoint.
+// If we save too much, the checkpoing docs will become very big,
+// if we save fewer, we'll run a greater risk of having to
+// read all the changes from 0 when checkpoint PUTs fail
+// CouchDB 2.0 has a more involved history pruning,
+// but let's go for the simple version for now.
+var CHECKPOINT_HISTORY_SIZE = 5;
+var LOWEST_SEQ = 0;
 
+function updateCheckpoint(db, id, checkpoint, session, returnValue) {
+  return db.get(id).catch(function (err) {
+    if (err.status === 404) {
+      if (db.adapter === 'http' || db.adapter === 'https') {
+        explainError(
+          404, 'PouchDB is just checking if a remote checkpoint exists.'
+        );
+      }
+      return {
+        session_id: session,
+        _id: id,
+        history: [],
+        replicator: REPLICATOR,
+        version: CHECKPOINT_VERSION
+      };
+    }
+    throw err;
+  }).then(function (doc) {
+    if (returnValue.cancelled) {
+      return;
+    }
 
+    // if the checkpoint has not changed, do not update
+    if (doc.last_seq === checkpoint) {
+      return;
+    }
 
+    // Filter out current entry for this replication
+    doc.history = (doc.history || []).filter(function (item) {
+      return item.session_id !== session;
+    });
 
+    // Add the latest checkpoint to history
+    doc.history.unshift({
+      last_seq: checkpoint,
+      session_id: session
+    });
 
+    // Just take the last pieces in history, to
+    // avoid really big checkpoint docs.
+    // see comment on history size above
+    doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE);
 
+    doc.version = CHECKPOINT_VERSION;
+    doc.replicator = REPLICATOR;
 
+    doc.session_id = session;
+    doc.last_seq = checkpoint;
 
-function isBinaryObject(object) {
-  return object instanceof Buffer;
+    return db.put(doc).catch(function (err) {
+      if (err.status === 409) {
+        // retry; someone is trying to write a checkpoint simultaneously
+        return updateCheckpoint(db, id, checkpoint, session, returnValue);
+      }
+      throw err;
+    });
+  });
 }
 
-// most of this is borrowed from lodash.isPlainObject:
-// https://github.com/fis-components/lodash.isplainobject/
-// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js
+function Checkpointer(src, target, id, returnValue, opts) {
+  this.src = src;
+  this.target = target;
+  this.id = id;
+  this.returnValue = returnValue;
+  this.opts = opts || {};
+}
 
-var funcToString = Function.prototype.toString;
-var objectCtorString = funcToString.call(Object);
+Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) {
+  var self = this;
+  return this.updateTarget(checkpoint, session).then(function () {
+    return self.updateSource(checkpoint, session);
+  });
+};
 
-function isPlainObject(value) {
-  var proto = Object.getPrototypeOf(value);
-  /* istanbul ignore if */
-  if (proto === null) { // not sure when this happens, but I guess it can
-    return true;
+Checkpointer.prototype.updateTarget = function (checkpoint, session) {
+  if (this.opts.writeTargetCheckpoint) {
+    return updateCheckpoint(this.target, this.id, checkpoint,
+      session, this.returnValue);
+  } else {
+    return Promise.resolve(true);
   }
-  var Ctor = proto.constructor;
-  return (typeof Ctor == 'function' &&
-    Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
-}
-
-function clone$1(object) {
-  var newObject;
-  var i;
-  var len;
+};
 
-  if (!object || typeof object !== 'object') {
-    return object;
+Checkpointer.prototype.updateSource = function (checkpoint, session) {
+  if (this.opts.writeSourceCheckpoint) {
+    var self = this;
+    return updateCheckpoint(this.src, this.id, checkpoint,
+      session, this.returnValue)
+      .catch(function (err) {
+        if (isForbiddenError(err)) {
+          self.opts.writeSourceCheckpoint = false;
+          return true;
+        }
+        throw err;
+      });
+  } else {
+    return Promise.resolve(true);
   }
+};
 
-  if (Array.isArray(object)) {
-    newObject = [];
-    for (i = 0, len = object.length; i < len; i++) {
-      newObject[i] = clone$1(object[i]);
+var comparisons = {
+  "undefined": function (targetDoc, sourceDoc) {
+    // This is the previous comparison function
+    if (collate(targetDoc.last_seq, sourceDoc.last_seq) === 0) {
+      return sourceDoc.last_seq;
     }
-    return newObject;
+    /* istanbul ignore next */
+    return 0;
+  },
+  "1": function (targetDoc, sourceDoc) {
+    // This is the comparison function ported from CouchDB
+    return compareReplicationLogs(sourceDoc, targetDoc).last_seq;
   }
+};
 
-  // special case: to avoid inconsistencies between IndexedDB
-  // and other backends, we automatically stringify Dates
-  if (object instanceof Date) {
-    return object.toISOString();
-  }
+Checkpointer.prototype.getCheckpoint = function () {
+  var self = this;
 
-  if (isBinaryObject(object)) {
-    return clone_buffer__WEBPACK_IMPORTED_MODULE_0___default()(object);
+  if (self.opts && self.opts.writeSourceCheckpoint && !self.opts.writeTargetCheckpoint) {
+    return self.src.get(self.id).then(function (sourceDoc) {
+      return sourceDoc.last_seq || LOWEST_SEQ;
+    }).catch(function (err) {
+      /* istanbul ignore if */
+      if (err.status !== 404) {
+        throw err;
+      }
+      return LOWEST_SEQ;
+    });
   }
 
-  if (!isPlainObject(object)) {
-    return object; // don't clone objects like Workers
-  }
+  return self.target.get(self.id).then(function (targetDoc) {
+    if (self.opts && self.opts.writeTargetCheckpoint && !self.opts.writeSourceCheckpoint) {
+      return targetDoc.last_seq || LOWEST_SEQ;
+    }
 
-  newObject = {};
-  for (i in object) {
-    /* istanbul ignore else */
-    if (Object.prototype.hasOwnProperty.call(object, i)) {
-      var value = clone$1(object[i]);
-      if (typeof value !== 'undefined') {
-        newObject[i] = value;
+    return self.src.get(self.id).then(function (sourceDoc) {
+      // Since we can't migrate an old version doc to a new one
+      // (no session id), we just go with the lowest seq in this case
+      /* istanbul ignore if */
+      if (targetDoc.version !== sourceDoc.version) {
+        return LOWEST_SEQ;
       }
-    }
-  }
-  return newObject;
-}
 
-function once(fun) {
-  var called = false;
-  return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) {
-    /* istanbul ignore if */
-    if (called) {
-      // this is a smoke test and should never actually happen
-      throw new Error('once called more than once');
-    } else {
-      called = true;
-      fun.apply(this, args);
-    }
-  });
-}
+      var version;
+      if (targetDoc.version) {
+        version = targetDoc.version.toString();
+      } else {
+        version = "undefined";
+      }
 
-function toPromise(func) {
-  //create the function we will be returning
-  return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) {
-    // Clone arguments
-    args = clone$1(args);
-    var self = this;
-    // if the last argument is a function, assume its a callback
-    var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
-    var promise = new Promise(function (fulfill, reject) {
-      var resp;
-      try {
-        var callback = once(function (err, mesg) {
-          if (err) {
-            reject(err);
-          } else {
-            fulfill(mesg);
+      if (version in comparisons) {
+        return comparisons[version](targetDoc, sourceDoc);
+      }
+      /* istanbul ignore next */
+      return LOWEST_SEQ;
+    }, function (err) {
+      if (err.status === 404 && targetDoc.last_seq) {
+        return self.src.put({
+          _id: self.id,
+          last_seq: LOWEST_SEQ
+        }).then(function () {
+          return LOWEST_SEQ;
+        }, function (err) {
+          if (isForbiddenError(err)) {
+            self.opts.writeSourceCheckpoint = false;
+            return targetDoc.last_seq;
           }
+          /* istanbul ignore next */
+          return LOWEST_SEQ;
         });
-        // create a callback for this invocation
-        // apply the function in the orig context
-        args.push(callback);
-        resp = func.apply(self, args);
-        if (resp && typeof resp.then === 'function') {
-          fulfill(resp);
-        }
-      } catch (e) {
-        reject(e);
       }
+      throw err;
     });
-    // if there is a callback, call it back
-    if (usedCB) {
-      promise.then(function (result) {
-        usedCB(null, result);
-      }, usedCB);
+  }).catch(function (err) {
+    if (err.status !== 404) {
+      throw err;
     }
-    return promise;
+    return LOWEST_SEQ;
   });
+};
+// This checkpoint comparison is ported from CouchDBs source
+// they come from here:
+// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906
+
+function compareReplicationLogs(srcDoc, tgtDoc) {
+  if (srcDoc.session_id === tgtDoc.session_id) {
+    return {
+      last_seq: srcDoc.last_seq,
+      history: srcDoc.history
+    };
+  }
+
+  return compareReplicationHistory(srcDoc.history, tgtDoc.history);
 }
 
-function logApiCall(self, name, args) {
+function compareReplicationHistory(sourceHistory, targetHistory) {
+  // the erlang loop via function arguments is not so easy to repeat in JS
+  // therefore, doing this as recursion
+  var S = sourceHistory[0];
+  var sourceRest = sourceHistory.slice(1);
+  var T = targetHistory[0];
+  var targetRest = targetHistory.slice(1);
+
+  if (!S || targetHistory.length === 0) {
+    return {
+      last_seq: LOWEST_SEQ,
+      history: []
+    };
+  }
+
+  var sourceId = S.session_id;
   /* istanbul ignore if */
-  if (self.constructor.listeners('debug').length) {
-    var logArgs = ['api', self.name, name];
-    for (var i = 0; i < args.length - 1; i++) {
-      logArgs.push(args[i]);
-    }
-    self.constructor.emit('debug', logArgs);
+  if (hasSessionId(sourceId, targetHistory)) {
+    return {
+      last_seq: S.last_seq,
+      history: sourceHistory
+    };
+  }
 
-    // override the callback itself to log the response
-    var origCallback = args[args.length - 1];
-    args[args.length - 1] = function (err, res) {
-      var responseArgs = ['api', self.name, name];
-      responseArgs = responseArgs.concat(
-        err ? ['error', err] : ['success', res]
-      );
-      self.constructor.emit('debug', responseArgs);
-      origCallback(err, res);
+  var targetId = T.session_id;
+  if (hasSessionId(targetId, sourceRest)) {
+    return {
+      last_seq: T.last_seq,
+      history: targetRest
     };
   }
-}
 
-function adapterFun(name, callback) {
-  return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) {
-    if (this._closed) {
-      return Promise.reject(new Error('database is closed'));
-    }
-    if (this._destroyed) {
-      return Promise.reject(new Error('database is destroyed'));
-    }
-    var self = this;
-    logApiCall(self, name, args);
-    if (!this.taskqueue.isReady) {
-      return new Promise(function (fulfill, reject) {
-        self.taskqueue.addTask(function (failed) {
-          if (failed) {
-            reject(failed);
-          } else {
-            fulfill(self[name].apply(self, args));
-          }
-        });
-      });
-    }
-    return callback.apply(this, args);
-  }));
+  return compareReplicationHistory(sourceRest, targetRest);
 }
 
-// like underscore/lodash _.pick()
-function pick(obj, arr) {
-  var res = {};
-  for (var i = 0, len = arr.length; i < len; i++) {
-    var prop = arr[i];
-    if (prop in obj) {
-      res[prop] = obj[prop];
-    }
+function hasSessionId(sessionId, history) {
+  var props = history[0];
+  var rest = history.slice(1);
+
+  if (!sessionId || history.length === 0) {
+    return false;
   }
-  return res;
-}
 
-// Most browsers throttle concurrent requests at 6, so it's silly
-// to shim _bulk_get by trying to launch potentially hundreds of requests
-// and then letting the majority time out. We can handle this ourselves.
-var MAX_NUM_CONCURRENT_REQUESTS = 6;
+  if (sessionId === props.session_id) {
+    return true;
+  }
 
-function identityFunction(x) {
-  return x;
+  return hasSessionId(sessionId, rest);
 }
 
-function formatResultForOpenRevsGet(result) {
-  return [{
-    ok: result
-  }];
+function isForbiddenError(err) {
+  return typeof err.status === 'number' && Math.floor(err.status / 100) === 4;
 }
 
-// shim for P/CouchDB adapters that don't directly implement _bulk_get
-function bulkGet(db, opts, callback) {
-  var requests = opts.docs;
+var STARTING_BACK_OFF = 0;
 
-  // consolidate into one request per doc if possible
-  var requestsById = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
-  requests.forEach(function (request) {
-    if (requestsById.has(request.id)) {
-      requestsById.get(request.id).push(request);
-    } else {
-      requestsById.set(request.id, [request]);
-    }
-  });
+function backOff(opts, returnValue, error, callback) {
+  if (opts.retry === false) {
+    returnValue.emit('error', error);
+    returnValue.removeAllListeners();
+    return;
+  }
+  /* istanbul ignore if */
+  if (typeof opts.back_off_function !== 'function') {
+    opts.back_off_function = defaultBackOff;
+  }
+  returnValue.emit('requestError', error);
+  if (returnValue.state === 'active' || returnValue.state === 'pending') {
+    returnValue.emit('paused', error);
+    returnValue.state = 'stopped';
+    var backOffSet = function backoffTimeSet() {
+      opts.current_back_off = STARTING_BACK_OFF;
+    };
+    var removeBackOffSetter = function removeBackOffTimeSet() {
+      returnValue.removeListener('active', backOffSet);
+    };
+    returnValue.once('paused', removeBackOffSetter);
+    returnValue.once('active', backOffSet);
+  }
+
+  opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF;
+  opts.current_back_off = opts.back_off_function(opts.current_back_off);
+  setTimeout(callback, opts.current_back_off);
+}
+
+function sortObjectPropertiesByKey(queryParams) {
+  return Object.keys(queryParams).sort(collate).reduce(function (result, key) {
+    result[key] = queryParams[key];
+    return result;
+  }, {});
+}
 
-  var numDocs = requestsById.size;
-  var numDone = 0;
-  var perDocResults = new Array(numDocs);
+// Generate a unique id particular to this replication.
+// Not guaranteed to align perfectly with CouchDB's rep ids.
+function generateReplicationId(src, target, opts) {
+  var docIds = opts.doc_ids ? opts.doc_ids.sort(collate) : '';
+  var filterFun = opts.filter ? opts.filter.toString() : '';
+  var queryParams = '';
+  var filterViewName =  '';
+  var selector = '';
 
-  function collapseResultsAndFinish() {
-    var results = [];
-    perDocResults.forEach(function (res) {
-      res.docs.forEach(function (info) {
-        results.push({
-          id: res.id,
-          docs: [info]
-        });
-      });
-    });
-    callback(null, {results: results});
+  // possibility for checkpoints to be lost here as behaviour of
+  // JSON.stringify is not stable (see #6226)
+  /* istanbul ignore if */
+  if (opts.selector) {
+    selector = JSON.stringify(opts.selector);
   }
 
-  function checkDone() {
-    if (++numDone === numDocs) {
-      collapseResultsAndFinish();
-    }
+  if (opts.filter && opts.query_params) {
+    queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params));
   }
 
-  function gotResult(docIndex, id, docs) {
-    perDocResults[docIndex] = {id: id, docs: docs};
-    checkDone();
+  if (opts.filter && opts.filter === '_view') {
+    filterViewName = opts.view.toString();
   }
 
-  var allRequests = [];
-  requestsById.forEach(function (value, key) {
-    allRequests.push(key);
+  return Promise.all([src.id(), target.id()]).then(function (res) {
+    var queryData = res[0] + res[1] + filterFun + filterViewName +
+      queryParams + docIds + selector;
+    return new Promise(function (resolve) {
+      binaryMd5(queryData, resolve);
+    });
+  }).then(function (md5sum) {
+    // can't use straight-up md5 alphabet, because
+    // the char '/' is interpreted as being for attachments,
+    // and + is also not url-safe
+    md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_');
+    return '_local/' + md5sum;
   });
+}
 
-  var i = 0;
-
-  function nextBatch() {
-
-    if (i >= allRequests.length) {
-      return;
-    }
+function replicate(src, target, opts, returnValue, result) {
+  var batches = [];               // list of batches to be processed
+  var currentBatch;               // the batch currently being processed
+  var pendingBatch = {
+    seq: 0,
+    changes: [],
+    docs: []
+  }; // next batch, not yet ready to be processed
+  var writingCheckpoint = false;  // true while checkpoint is being written
+  var changesCompleted = false;   // true when all changes received
+  var replicationCompleted = false; // true when replication has completed
+  var last_seq = 0;
+  var continuous = opts.continuous || opts.live || false;
+  var batch_size = opts.batch_size || 100;
+  var batches_limit = opts.batches_limit || 10;
+  var changesPending = false;     // true while src.changes is running
+  var doc_ids = opts.doc_ids;
+  var selector = opts.selector;
+  var repId;
+  var checkpointer;
+  var changedDocs = [];
+  // Like couchdb, every replication gets a unique session id
+  var session = uuid();
 
-    var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length);
-    var batch = allRequests.slice(i, upTo);
-    processBatch(batch, i);
-    i += batch.length;
-  }
+  result = result || {
+    ok: true,
+    start_time: new Date().toISOString(),
+    docs_read: 0,
+    docs_written: 0,
+    doc_write_failures: 0,
+    errors: []
+  };
 
-  function processBatch(batch, offset) {
-    batch.forEach(function (docId, j) {
-      var docIdx = offset + j;
-      var docRequests = requestsById.get(docId);
+  var changesOpts = {};
+  returnValue.ready(src, target);
 
-      // just use the first request as the "template"
-      // TODO: The _bulk_get API allows for more subtle use cases than this,
-      // but for now it is unlikely that there will be a mix of different
-      // "atts_since" or "attachments" in the same request, since it's just
-      // replicate.js that is using this for the moment.
-      // Also, atts_since is aspirational, since we don't support it yet.
-      var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
-      docOpts.open_revs = docRequests.map(function (request) {
-        // rev is optional, open_revs disallowed
-        return request.rev;
-      });
+  function initCheckpointer() {
+    if (checkpointer) {
+      return Promise.resolve();
+    }
+    return generateReplicationId(src, target, opts).then(function (res) {
+      repId = res;
 
-      // remove falsey / undefined revisions
-      docOpts.open_revs = docOpts.open_revs.filter(identityFunction);
+      var checkpointOpts = {};
+      if (opts.checkpoint === false) {
+        checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: false };
+      } else if (opts.checkpoint === 'source') {
+        checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: false };
+      } else if (opts.checkpoint === 'target') {
+        checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: true };
+      } else {
+        checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: true };
+      }
 
-      var formatResult = identityFunction;
+      checkpointer = new Checkpointer(src, target, repId, returnValue, checkpointOpts);
+    });
+  }
 
-      if (docOpts.open_revs.length === 0) {
-        delete docOpts.open_revs;
+  function writeDocs() {
+    changedDocs = [];
 
-        // when fetching only the "winning" leaf,
-        // transform the result so it looks like an open_revs
-        // request
-        formatResult = formatResultForOpenRevsGet;
+    if (currentBatch.docs.length === 0) {
+      return;
+    }
+    var docs = currentBatch.docs;
+    var bulkOpts = {timeout: opts.timeout};
+    return target.bulkDocs({docs: docs, new_edits: false}, bulkOpts).then(function (res) {
+      /* istanbul ignore if */
+      if (returnValue.cancelled) {
+        completeReplication();
+        throw new Error('cancelled');
       }
 
-      // globally-supplied options
-      ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) {
-        if (param in opts) {
-          docOpts[param] = opts[param];
+      // `res` doesn't include full documents (which live in `docs`), so we create a map of 
+      // (id -> error), and check for errors while iterating over `docs`
+      var errorsById = Object.create(null);
+      res.forEach(function (res) {
+        if (res.error) {
+          errorsById[res.id] = res;
         }
       });
-      db.get(docId, docOpts, function (err, res) {
-        var result;
-        /* istanbul ignore if */
-        if (err) {
-          result = [{error: err}];
+
+      var errorsNo = Object.keys(errorsById).length;
+      result.doc_write_failures += errorsNo;
+      result.docs_written += docs.length - errorsNo;
+
+      docs.forEach(function (doc) {
+        var error = errorsById[doc._id];
+        if (error) {
+          result.errors.push(error);
+          // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
+          var errorName = (error.name || '').toLowerCase();
+          if (errorName === 'unauthorized' || errorName === 'forbidden') {
+            returnValue.emit('denied', clone(error));
+          } else {
+            throw error;
+          }
         } else {
-          result = formatResult(res);
+          changedDocs.push(doc);
         }
-        gotResult(docIdx, docId, result);
-        nextBatch();
       });
+
+    }, function (err) {
+      result.doc_write_failures += docs.length;
+      throw err;
     });
   }
 
-  nextBatch();
-
-}
-
-// in Node of course this is false
-function hasLocalStorage() {
-  return false;
-}
-
-function nextTick(fn) {
-  process.nextTick(fn);
-}
-
-inherits__WEBPACK_IMPORTED_MODULE_4___default()(Changes, events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter);
-
-/* istanbul ignore next */
-function attachBrowserEvents(self) {
-  if (hasLocalStorage()) {
-    addEventListener("storage", function (e) {
-      self.emit(e.key);
+  function finishBatch() {
+    if (currentBatch.error) {
+      throw new Error('There was a problem getting docs.');
+    }
+    result.last_seq = last_seq = currentBatch.seq;
+    var outResult = clone(result);
+    if (changedDocs.length) {
+      outResult.docs = changedDocs;
+      // Attach 'pending' property if server supports it (CouchDB 2.0+)
+      /* istanbul ignore if */
+      if (typeof currentBatch.pending === 'number') {
+        outResult.pending = currentBatch.pending;
+        delete currentBatch.pending;
+      }
+      returnValue.emit('change', outResult);
+    }
+    writingCheckpoint = true;
+    return checkpointer.writeCheckpoint(currentBatch.seq,
+        session).then(function () {
+      writingCheckpoint = false;
+      /* istanbul ignore if */
+      if (returnValue.cancelled) {
+        completeReplication();
+        throw new Error('cancelled');
+      }
+      currentBatch = undefined;
+      getChanges();
+    }).catch(function (err) {
+      onCheckpointError(err);
+      throw err;
     });
   }
-}
 
-function Changes() {
-  events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.call(this);
-  this._listeners = {};
+  function getDiffs() {
+    var diff = {};
+    currentBatch.changes.forEach(function (change) {
+      // Couchbase Sync Gateway emits these, but we can ignore them
+      /* istanbul ignore if */
+      if (change.id === "_user/") {
+        return;
+      }
+      diff[change.id] = change.changes.map(function (x) {
+        return x.rev;
+      });
+    });
+    return target.revsDiff(diff).then(function (diffs) {
+      /* istanbul ignore if */
+      if (returnValue.cancelled) {
+        completeReplication();
+        throw new Error('cancelled');
+      }
+      // currentBatch.diffs elements are deleted as the documents are written
+      currentBatch.diffs = diffs;
+    });
+  }
 
-  attachBrowserEvents(this);
-}
-Changes.prototype.addListener = function (dbName, id, db, opts) {
-  /* istanbul ignore if */
-  if (this._listeners[id]) {
-    return;
+  function getBatchDocs() {
+    return getDocs(src, target, currentBatch.diffs, returnValue).then(function (got) {
+      currentBatch.error = !got.ok;
+      got.docs.forEach(function (doc) {
+        delete currentBatch.diffs[doc._id];
+        result.docs_read++;
+        currentBatch.docs.push(doc);
+      });
+    });
   }
-  var self = this;
-  var inprogress = false;
-  function eventFunction() {
-    /* istanbul ignore if */
-    if (!self._listeners[id]) {
+
+  function startNextBatch() {
+    if (returnValue.cancelled || currentBatch) {
       return;
     }
-    if (inprogress) {
-      inprogress = 'waiting';
+    if (batches.length === 0) {
+      processPendingBatch(true);
       return;
     }
-    inprogress = true;
-    var changesOpts = pick(opts, [
-      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
-      'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
-    ]);
+    currentBatch = batches.shift();
+    getDiffs()
+      .then(getBatchDocs)
+      .then(writeDocs)
+      .then(finishBatch)
+      .then(startNextBatch)
+      .catch(function (err) {
+        abortReplication('batch processing terminated with error', err);
+      });
+  }
 
-    /* istanbul ignore next */
-    function onError() {
-      inprogress = false;
-    }
 
-    db.changes(changesOpts).on('change', function (c) {
-      if (c.seq > opts.since && !opts.cancelled) {
-        opts.since = c.seq;
-        opts.onChange(c);
+  function processPendingBatch(immediate) {
+    if (pendingBatch.changes.length === 0) {
+      if (batches.length === 0 && !currentBatch) {
+        if ((continuous && changesOpts.live) || changesCompleted) {
+          returnValue.state = 'pending';
+          returnValue.emit('paused');
+        }
+        if (changesCompleted) {
+          completeReplication();
+        }
       }
-    }).on('complete', function () {
-      if (inprogress === 'waiting') {
-        nextTick(eventFunction);
+      return;
+    }
+    if (
+      immediate ||
+      changesCompleted ||
+      pendingBatch.changes.length >= batch_size
+    ) {
+      batches.push(pendingBatch);
+      pendingBatch = {
+        seq: 0,
+        changes: [],
+        docs: []
+      };
+      if (returnValue.state === 'pending' || returnValue.state === 'stopped') {
+        returnValue.state = 'active';
+        returnValue.emit('active');
       }
-      inprogress = false;
-    }).on('error', onError);
+      startNextBatch();
+    }
   }
-  this._listeners[id] = eventFunction;
-  this.on(dbName, eventFunction);
-};
 
-Changes.prototype.removeListener = function (dbName, id) {
-  /* istanbul ignore if */
-  if (!(id in this._listeners)) {
-    return;
+
+  function abortReplication(reason, err) {
+    if (replicationCompleted) {
+      return;
+    }
+    if (!err.message) {
+      err.message = reason;
+    }
+    result.ok = false;
+    result.status = 'aborting';
+    batches = [];
+    pendingBatch = {
+      seq: 0,
+      changes: [],
+      docs: []
+    };
+    completeReplication(err);
   }
-  events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.prototype.removeListener.call(this, dbName,
-    this._listeners[id]);
-  delete this._listeners[id];
-};
 
 
-/* istanbul ignore next */
-Changes.prototype.notifyLocalWindows = function (dbName) {
-  //do a useless change on a storage thing
-  //in order to get other windows's listeners to activate
-  if (hasLocalStorage()) {
-    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
-  }
-};
+  function completeReplication(fatalError) {
+    if (replicationCompleted) {
+      return;
+    }
+    /* istanbul ignore if */
+    if (returnValue.cancelled) {
+      result.status = 'cancelled';
+      if (writingCheckpoint) {
+        return;
+      }
+    }
+    result.status = result.status || 'complete';
+    result.end_time = new Date().toISOString();
+    result.last_seq = last_seq;
+    replicationCompleted = true;
 
-Changes.prototype.notify = function (dbName) {
-  this.emit(dbName);
-  this.notifyLocalWindows(dbName);
-};
+    if (fatalError) {
+      // need to extend the error because Firefox considers ".result" read-only
+      fatalError = createError(fatalError);
+      fatalError.result = result;
 
-function guardedConsole(method) {
-  /* istanbul ignore else */
-  if (typeof console !== 'undefined' && typeof console[method] === 'function') {
-    var args = Array.prototype.slice.call(arguments, 1);
-    console[method].apply(console, args);
+      // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
+      var errorName = (fatalError.name || '').toLowerCase();
+      if (errorName === 'unauthorized' || errorName === 'forbidden') {
+        returnValue.emit('error', fatalError);
+        returnValue.removeAllListeners();
+      } else {
+        backOff(opts, returnValue, fatalError, function () {
+          replicate(src, target, opts, returnValue);
+        });
+      }
+    } else {
+      returnValue.emit('complete', result);
+      returnValue.removeAllListeners();
+    }
   }
-}
 
-function randomNumber(min, max) {
-  var maxTimeout = 600000; // Hard-coded default of 10 minutes
-  min = parseInt(min, 10) || 0;
-  max = parseInt(max, 10);
-  if (max !== max || max <= min) {
-    max = (min || 1) << 1; //doubling
-  } else {
-    max = max + 1;
-  }
-  // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout
-  if (max > maxTimeout) {
-    min = maxTimeout >> 1; // divide by two
-    max = maxTimeout;
-  }
-  var ratio = Math.random();
-  var range = max - min;
 
-  return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
-}
+  function onChange(change, pending, lastSeq) {
+    /* istanbul ignore if */
+    if (returnValue.cancelled) {
+      return completeReplication();
+    }
+    // Attach 'pending' property if server supports it (CouchDB 2.0+)
+    /* istanbul ignore if */
+    if (typeof pending === 'number') {
+      pendingBatch.pending = pending;
+    }
 
-function defaultBackOff(min) {
-  var max = 0;
-  if (!min) {
-    max = 2000;
+    var filter = filterChange(opts)(change);
+    if (!filter) {
+      return;
+    }
+    pendingBatch.seq = change.seq || lastSeq;
+    pendingBatch.changes.push(change);
+    immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () {
+      processPendingBatch(batches.length === 0 && changesOpts.live);
+    });
   }
-  return randomNumber(min, max);
-}
 
-// We assume Node users don't need to see this warning
-var res = function () {};
 
-var assign;
-{
-  if (typeof Object.assign === 'function') {
-    assign = Object.assign;
-  } else {
-    // lite Object.assign polyfill based on
-    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
-    assign = function (target) {
-      var to = Object(target);
+  function onChangesComplete(changes) {
+    changesPending = false;
+    /* istanbul ignore if */
+    if (returnValue.cancelled) {
+      return completeReplication();
+    }
 
-      for (var index = 1; index < arguments.length; index++) {
-        var nextSource = arguments[index];
+    // if no results were returned then we're done,
+    // else fetch more
+    if (changes.results.length > 0) {
+      changesOpts.since = changes.results[changes.results.length - 1].seq;
+      getChanges();
+      processPendingBatch(true);
+    } else {
 
-        if (nextSource != null) { // Skip over if undefined or null
-          for (var nextKey in nextSource) {
-            // Avoid bugs when hasOwnProperty is shadowed
-            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
-              to[nextKey] = nextSource[nextKey];
-            }
-          }
+      var complete = function () {
+        if (continuous) {
+          changesOpts.live = true;
+          getChanges();
+        } else {
+          changesCompleted = true;
         }
+        processPendingBatch(true);
+      };
+
+      // update the checkpoint so we start from the right seq next time
+      if (!currentBatch && changes.results.length === 0) {
+        writingCheckpoint = true;
+        checkpointer.writeCheckpoint(changes.last_seq,
+            session).then(function () {
+          writingCheckpoint = false;
+          result.last_seq = last_seq = changes.last_seq;
+          complete();
+        })
+        .catch(onCheckpointError);
+      } else {
+        complete();
       }
-      return to;
-    };
+    }
   }
-}
 
-var assign$1 = assign;
 
-function tryFilter(filter, doc, req) {
-  try {
-    return !filter(doc, req);
-  } catch (err) {
-    var msg = 'Filter function threw: ' + err.toString();
-    return (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.BAD_REQUEST, msg);
+  function onChangesError(err) {
+    changesPending = false;
+    /* istanbul ignore if */
+    if (returnValue.cancelled) {
+      return completeReplication();
+    }
+    abortReplication('changes rejected', err);
   }
-}
 
-function filterChange(opts) {
-  var req = {};
-  var hasFilter = opts.filter && typeof opts.filter === 'function';
-  req.query = opts.query_params;
 
-  return function filter(change) {
-    if (!change.doc) {
-      // CSG sends events on the changes feed that don't have documents,
-      // this hack makes a whole lot of existing code robust.
-      change.doc = {};
+  function getChanges() {
+    if (!(
+      !changesPending &&
+      !changesCompleted &&
+      batches.length < batches_limit
+      )) {
+      return;
+    }
+    changesPending = true;
+    function abortChanges() {
+      changes.cancel();
+    }
+    function removeListener() {
+      returnValue.removeListener('cancel', abortChanges);
     }
 
-    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
-
-    if (typeof filterReturn === 'object') {
-      return filterReturn;
+    if (returnValue._changes) { // remove old changes() and listeners
+      returnValue.removeListener('cancel', returnValue._abortChanges);
+      returnValue._changes.cancel();
     }
+    returnValue.once('cancel', abortChanges);
 
-    if (filterReturn) {
-      return false;
+    var changes = src.changes(changesOpts)
+      .on('change', onChange);
+    changes.then(removeListener, removeListener);
+    changes.then(onChangesComplete)
+      .catch(onChangesError);
+
+    if (opts.retry) {
+      // save for later so we can cancel if necessary
+      returnValue._changes = changes;
+      returnValue._abortChanges = abortChanges;
     }
+  }
 
-    if (!opts.include_docs) {
-      delete change.doc;
-    } else if (!opts.attachments) {
-      for (var att in change.doc._attachments) {
-        /* istanbul ignore else */
-        if (change.doc._attachments.hasOwnProperty(att)) {
-          change.doc._attachments[att].stub = true;
-        }
+
+  function startChanges() {
+    initCheckpointer().then(function () {
+      /* istanbul ignore if */
+      if (returnValue.cancelled) {
+        completeReplication();
+        return;
       }
-    }
-    return true;
-  };
-}
+      return checkpointer.getCheckpoint().then(function (checkpoint) {
+        last_seq = checkpoint;
+        changesOpts = {
+          since: last_seq,
+          limit: batch_size,
+          batch_size: batch_size,
+          style: 'all_docs',
+          doc_ids: doc_ids,
+          selector: selector,
+          return_docs: true // required so we know when we're done
+        };
+        if (opts.filter) {
+          if (typeof opts.filter !== 'string') {
+            // required for the client-side filter in onChange
+            changesOpts.include_docs = true;
+          } else { // ddoc filter
+            changesOpts.filter = opts.filter;
+          }
+        }
+        if ('heartbeat' in opts) {
+          changesOpts.heartbeat = opts.heartbeat;
+        }
+        if ('timeout' in opts) {
+          changesOpts.timeout = opts.timeout;
+        }
+        if (opts.query_params) {
+          changesOpts.query_params = opts.query_params;
+        }
+        if (opts.view) {
+          changesOpts.view = opts.view;
+        }
+        getChanges();
+      });
+    }).catch(function (err) {
+      abortReplication('getCheckpoint rejected with ', err);
+    });
+  }
 
-function flatten(arrs) {
-  var res = [];
-  for (var i = 0, len = arrs.length; i < len; i++) {
-    res = res.concat(arrs[i]);
+  /* istanbul ignore next */
+  function onCheckpointError(err) {
+    writingCheckpoint = false;
+    abortReplication('writeCheckpoint completed with error', err);
   }
-  return res;
-}
 
-// shim for Function.prototype.name,
-// for browsers that don't support it like IE
+  /* istanbul ignore if */
+  if (returnValue.cancelled) { // cancelled immediately
+    completeReplication();
+    return;
+  }
 
-/* istanbul ignore next */
-function f() {}
+  if (!returnValue._addedListeners) {
+    returnValue.once('cancel', completeReplication);
 
-var hasName = f.name;
-var res$1;
+    if (typeof opts.complete === 'function') {
+      returnValue.once('error', opts.complete);
+      returnValue.once('complete', function (result) {
+        opts.complete(null, result);
+      });
+    }
+    returnValue._addedListeners = true;
+  }
 
-// We dont run coverage in IE
-/* istanbul ignore else */
-if (hasName) {
-  res$1 = function (fun) {
-    return fun.name;
+  if (typeof opts.since === 'undefined') {
+    startChanges();
+  } else {
+    initCheckpointer().then(function () {
+      writingCheckpoint = true;
+      return checkpointer.writeCheckpoint(opts.since, session);
+    }).then(function () {
+      writingCheckpoint = false;
+      /* istanbul ignore if */
+      if (returnValue.cancelled) {
+        completeReplication();
+        return;
+      }
+      last_seq = opts.since;
+      startChanges();
+    }).catch(onCheckpointError);
+  }
+}
+
+// We create a basic promise so the caller can cancel the replication possibly
+// before we have actually started listening to changes etc
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(Replication, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
+function Replication() {
+  events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this);
+  this.cancelled = false;
+  this.state = 'pending';
+  var self = this;
+  var promise = new Promise(function (fulfill, reject) {
+    self.once('complete', fulfill);
+    self.once('error', reject);
+  });
+  self.then = function (resolve, reject) {
+    return promise.then(resolve, reject);
   };
-} else {
-  res$1 = function (fun) {
-    var match = fun.toString().match(/^\s*function\s*(?:(\S+)\s*)?\(/);
-    if (match && match[1]) {
-      return match[1];
-    }
-    else {
-      return '';
-    }
+  self.catch = function (reject) {
+    return promise.catch(reject);
   };
+  // As we allow error handling via "error" event as well,
+  // put a stub in here so that rejecting never throws UnhandledError.
+  self.catch(function () {});
 }
 
-var res$2 = res$1;
+Replication.prototype.cancel = function () {
+  this.cancelled = true;
+  this.state = 'cancelled';
+  this.emit('cancel');
+};
 
-// Determine id an ID is valid
-//   - invalid IDs begin with an underescore that does not begin '_design' or
-//     '_local'
-//   - any other string value is a valid id
-// Returns the specific error object for each case
-function invalidIdError(id) {
-  var err;
-  if (!id) {
-    err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.MISSING_ID);
-  } else if (typeof id !== 'string') {
-    err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.INVALID_ID);
-  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
-    err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.RESERVED_ID);
+Replication.prototype.ready = function (src, target) {
+  var self = this;
+  if (self._readyCalled) {
+    return;
   }
-  if (err) {
-    throw err;
+  self._readyCalled = true;
+
+  function onDestroy() {
+    self.cancel();
+  }
+  src.once('destroyed', onDestroy);
+  target.once('destroyed', onDestroy);
+  function cleanup() {
+    src.removeListener('destroyed', onDestroy);
+    target.removeListener('destroyed', onDestroy);
+  }
+  self.once('complete', cleanup);
+};
+
+function toPouch(db, opts) {
+  var PouchConstructor = opts.PouchConstructor;
+  if (typeof db === 'string') {
+    return new PouchConstructor(db, opts);
+  } else {
+    return db;
   }
 }
 
-// Checks if a PouchDB object is "remote" or not. This is
+function replicateWrapper(src, target, opts, callback) {
 
-function isRemote(db) {
-  if (typeof db._remote === 'boolean') {
-    return db._remote;
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
   }
-  /* istanbul ignore next */
-  if (typeof db.type === 'function') {
-    guardedConsole('warn',
-      'db.type() is deprecated and will be removed in ' +
-      'a future version of PouchDB');
-    return db.type() === 'http';
+  if (typeof opts === 'undefined') {
+    opts = {};
   }
-  /* istanbul ignore next */
-  return false;
-}
 
-function listenerCount(ee, type) {
-  return 'listenerCount' in ee ? ee.listenerCount(type) :
-                                 events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.listenerCount(ee, type);
+  if (opts.doc_ids && !Array.isArray(opts.doc_ids)) {
+    throw createError(BAD_REQUEST,
+                       "`doc_ids` filter parameter is not a list.");
+  }
+
+  opts.complete = callback;
+  opts = clone(opts);
+  opts.continuous = opts.continuous || opts.live;
+  opts.retry = ('retry' in opts) ? opts.retry : false;
+  /*jshint validthis:true */
+  opts.PouchConstructor = opts.PouchConstructor || this;
+  var replicateRet = new Replication(opts);
+  var srcPouch = toPouch(src, opts);
+  var targetPouch = toPouch(target, opts);
+  replicate(srcPouch, targetPouch, opts, replicateRet);
+  return replicateRet;
 }
 
-function parseDesignDocFunctionName(s) {
-  if (!s) {
-    return null;
-  }
-  var parts = s.split('/');
-  if (parts.length === 2) {
-    return parts;
+inherits__WEBPACK_IMPORTED_MODULE_3___default()(Sync, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter);
+function sync(src, target, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
   }
-  if (parts.length === 1) {
-    return [s, s];
+  if (typeof opts === 'undefined') {
+    opts = {};
   }
-  return null;
+  opts = clone(opts);
+  /*jshint validthis:true */
+  opts.PouchConstructor = opts.PouchConstructor || this;
+  src = toPouch(src, opts);
+  target = toPouch(target, opts);
+  return new Sync(src, target, opts, callback);
 }
 
-function normalizeDesignDocFunctionName(s) {
-  var normalized = parseDesignDocFunctionName(s);
-  return normalized ? normalized.join('/') : null;
-}
+function Sync(src, target, opts, callback) {
+  var self = this;
+  this.canceled = false;
 
-// originally parseUri 1.2.2, now patched by us
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
-    "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
-var qName ="queryKey";
-var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
+  var optsPush = opts.push ? $inject_Object_assign({}, opts, opts.push) : opts;
+  var optsPull = opts.pull ? $inject_Object_assign({}, opts, opts.pull) : opts;
 
-// use the "loose" parser
-/* eslint maxlen: 0, no-useless-escape: 0 */
-var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+  this.push = replicateWrapper(src, target, optsPush);
+  this.pull = replicateWrapper(target, src, optsPull);
 
-function parseUri(str) {
-  var m = parser.exec(str);
-  var uri = {};
-  var i = 14;
+  this.pushPaused = true;
+  this.pullPaused = true;
 
-  while (i--) {
-    var key = keys[i];
-    var value = m[i] || "";
-    var encoded = ['user', 'password'].indexOf(key) !== -1;
-    uri[key] = encoded ? decodeURIComponent(value) : value;
+  function pullChange(change) {
+    self.emit('change', {
+      direction: 'pull',
+      change: change
+    });
   }
-
-  uri[qName] = {};
-  uri[keys[12]].replace(qParser, function ($0, $1, $2) {
-    if ($1) {
-      uri[qName][$1] = $2;
+  function pushChange(change) {
+    self.emit('change', {
+      direction: 'push',
+      change: change
+    });
+  }
+  function pushDenied(doc) {
+    self.emit('denied', {
+      direction: 'push',
+      doc: doc
+    });
+  }
+  function pullDenied(doc) {
+    self.emit('denied', {
+      direction: 'pull',
+      doc: doc
+    });
+  }
+  function pushPaused() {
+    self.pushPaused = true;
+    /* istanbul ignore if */
+    if (self.pullPaused) {
+      self.emit('paused');
     }
-  });
-
-  return uri;
-}
-
-// Based on https://github.com/alexdavid/scope-eval v0.0.3
-// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js)
-// This is basically just a wrapper around new Function()
-
-function scopeEval(source, scope) {
-  var keys = [];
-  var values = [];
-  for (var key in scope) {
-    if (scope.hasOwnProperty(key)) {
-      keys.push(key);
-      values.push(scope[key]);
+  }
+  function pullPaused() {
+    self.pullPaused = true;
+    /* istanbul ignore if */
+    if (self.pushPaused) {
+      self.emit('paused');
+    }
+  }
+  function pushActive() {
+    self.pushPaused = false;
+    /* istanbul ignore if */
+    if (self.pullPaused) {
+      self.emit('active', {
+        direction: 'push'
+      });
+    }
+  }
+  function pullActive() {
+    self.pullPaused = false;
+    /* istanbul ignore if */
+    if (self.pushPaused) {
+      self.emit('active', {
+        direction: 'pull'
+      });
     }
   }
-  keys.push(source);
-  return Function.apply(null, keys).apply(null, values);
-}
 
-// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
-// the diffFun tells us what delta to apply to the doc.  it either returns
-// the doc, or false if it doesn't need to do an update after all
-function upsert(db, docId, diffFun) {
-  return new Promise(function (fulfill, reject) {
-    db.get(docId, function (err, doc) {
-      if (err) {
-        /* istanbul ignore next */
-        if (err.status !== 404) {
-          return reject(err);
+  var removed = {};
+
+  function removeAll(type) { // type is 'push' or 'pull'
+    return function (event, func) {
+      var isChange = event === 'change' &&
+        (func === pullChange || func === pushChange);
+      var isDenied = event === 'denied' &&
+        (func === pullDenied || func === pushDenied);
+      var isPaused = event === 'paused' &&
+        (func === pullPaused || func === pushPaused);
+      var isActive = event === 'active' &&
+        (func === pullActive || func === pushActive);
+
+      if (isChange || isDenied || isPaused || isActive) {
+        if (!(event in removed)) {
+          removed[event] = {};
+        }
+        removed[event][type] = true;
+        if (Object.keys(removed[event]).length === 2) {
+          // both push and pull have asked to be removed
+          self.removeAllListeners(event);
         }
-        doc = {};
       }
+    };
+  }
 
-      // the user might change the _rev, so save it for posterity
-      var docRev = doc._rev;
-      var newDoc = diffFun(doc);
+  if (opts.live) {
+    this.push.on('complete', self.pull.cancel.bind(self.pull));
+    this.pull.on('complete', self.push.cancel.bind(self.push));
+  }
 
-      if (!newDoc) {
-        // if the diffFun returns falsy, we short-circuit as
-        // an optimization
-        return fulfill({updated: false, rev: docRev});
-      }
+  function addOneListener(ee, event, listener) {
+    if (ee.listeners(event).indexOf(listener) == -1) {
+      ee.on(event, listener);
+    }
+  }
 
-      // users aren't allowed to modify these values,
-      // so reset them here
-      newDoc._id = docId;
-      newDoc._rev = docRev;
-      fulfill(tryAndPut(db, newDoc, diffFun));
-    });
+  this.on('newListener', function (event) {
+    if (event === 'change') {
+      addOneListener(self.pull, 'change', pullChange);
+      addOneListener(self.push, 'change', pushChange);
+    } else if (event === 'denied') {
+      addOneListener(self.pull, 'denied', pullDenied);
+      addOneListener(self.push, 'denied', pushDenied);
+    } else if (event === 'active') {
+      addOneListener(self.pull, 'active', pullActive);
+      addOneListener(self.push, 'active', pushActive);
+    } else if (event === 'paused') {
+      addOneListener(self.pull, 'paused', pullPaused);
+      addOneListener(self.push, 'paused', pushPaused);
+    }
+  });
+
+  this.on('removeListener', function (event) {
+    if (event === 'change') {
+      self.pull.removeListener('change', pullChange);
+      self.push.removeListener('change', pushChange);
+    } else if (event === 'denied') {
+      self.pull.removeListener('denied', pullDenied);
+      self.push.removeListener('denied', pushDenied);
+    } else if (event === 'active') {
+      self.pull.removeListener('active', pullActive);
+      self.push.removeListener('active', pushActive);
+    } else if (event === 'paused') {
+      self.pull.removeListener('paused', pullPaused);
+      self.push.removeListener('paused', pushPaused);
+    }
   });
-}
 
-function tryAndPut(db, doc, diffFun) {
-  return db.put(doc).then(function (res) {
-    return {
-      updated: true,
-      rev: res.rev
+  this.pull.on('removeListener', removeAll('pull'));
+  this.push.on('removeListener', removeAll('push'));
+
+  var promise = Promise.all([
+    this.push,
+    this.pull
+  ]).then(function (resp) {
+    var out = {
+      push: resp[0],
+      pull: resp[1]
     };
+    self.emit('complete', out);
+    if (callback) {
+      callback(null, out);
+    }
+    self.removeAllListeners();
+    return out;
   }, function (err) {
-    /* istanbul ignore next */
-    if (err.status !== 409) {
+    self.cancel();
+    if (callback) {
+      // if there's a callback, then the callback can receive
+      // the error event
+      callback(err);
+    } else {
+      // if there's no callback, then we're safe to emit an error
+      // event, which would otherwise throw an unhandled error
+      // due to 'error' being a special event in EventEmitters
+      self.emit('error', err);
+    }
+    self.removeAllListeners();
+    if (callback) {
+      // no sense throwing if we're already emitting an 'error' event
       throw err;
     }
-    return upsert(db, doc._id, diffFun);
   });
+
+  this.then = function (success, err) {
+    return promise.then(success, err);
+  };
+
+  this.catch = function (err) {
+    return promise.catch(err);
+  };
 }
 
-function rev(doc, deterministic_revs) {
-  var clonedDoc = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__.clone)(doc);
-  if (!deterministic_revs) {
-    return uuid__WEBPACK_IMPORTED_MODULE_6___default().v4().replace(/-/g, '').toLowerCase();
+Sync.prototype.cancel = function () {
+  if (!this.canceled) {
+    this.canceled = true;
+    this.push.cancel();
+    this.pull.cancel();
   }
+};
 
-  delete clonedDoc._rev_tree;
-  return (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__.stringMd5)(JSON.stringify(clonedDoc));
+function replication(PouchDB) {
+  PouchDB.replicate = replicateWrapper;
+  PouchDB.sync = sync;
+
+  Object.defineProperty(PouchDB.prototype, 'replicate', {
+    get: function () {
+      var self = this;
+      if (typeof this.replicateMethods === 'undefined') {
+        this.replicateMethods = {
+          from: function (other, opts, callback) {
+            return self.constructor.replicate(other, self, opts, callback);
+          },
+          to: function (other, opts, callback) {
+            return self.constructor.replicate(self, other, opts, callback);
+          }
+        };
+      }
+      return this.replicateMethods;
+    }
+  });
+
+  PouchDB.prototype.sync = function (dbName, opts, callback) {
+    return this.constructor.sync(this, dbName, opts, callback);
+  };
 }
 
-var uuid = (uuid__WEBPACK_IMPORTED_MODULE_6___default().v4);
+PouchDB.plugin(IDBPouch)
+  .plugin(HttpPouch$1)
+  .plugin(mapreduce)
+  .plugin(replication);
+
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PouchDB);
+
+
+/***/ }),
+/* 495 */
+/***/ ((module) => {
+
+"use strict";
 
 
+module.exports = argsArray;
 
+function argsArray(fun) {
+  return function () {
+    var len = arguments.length;
+    if (len) {
+      var args = [];
+      var i = -1;
+      while (++i < len) {
+        args[i] = arguments[i];
+      }
+      return fun.call(this, args);
+    } else {
+      return fun.call(this, []);
+    }
+  };
+}
 
 /***/ }),
 /* 496 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/***/ ((module) => {
 
 "use strict";
 
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
 
-var Buffer = (__webpack_require__(78).Buffer);
+var scheduleDrain;
 
-function hasFrom() {
-  // Node versions 5.x below 5.10 seem to have a `from` method
-  // However, it doesn't clone Buffers
-  // Luckily, it reports as `false` to hasOwnProperty
-  return (Buffer.hasOwnProperty('from') && typeof Buffer.from === 'function');
-}
+if (process.browser) {
+  if (Mutation) {
+    var called = 0;
+    var observer = new Mutation(nextTick);
+    var element = global.document.createTextNode('');
+    observer.observe(element, {
+      characterData: true
+    });
+    scheduleDrain = function () {
+      element.data = (called = ++called % 2);
+    };
+  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+    var channel = new global.MessageChannel();
+    channel.port1.onmessage = nextTick;
+    scheduleDrain = function () {
+      channel.port2.postMessage(0);
+    };
+  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+    scheduleDrain = function () {
 
-function cloneBuffer(buf) {
-  if (!Buffer.isBuffer(buf)) {
-    throw new Error('Can only clone Buffer.');
-  }
+      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+      var scriptEl = global.document.createElement('script');
+      scriptEl.onreadystatechange = function () {
+        nextTick();
 
-  if (hasFrom()) {
-    return Buffer.from(buf);
+        scriptEl.onreadystatechange = null;
+        scriptEl.parentNode.removeChild(scriptEl);
+        scriptEl = null;
+      };
+      global.document.documentElement.appendChild(scriptEl);
+    };
+  } else {
+    scheduleDrain = function () {
+      setTimeout(nextTick, 0);
+    };
   }
-
-  var copy = new Buffer(buf.length);
-  buf.copy(copy);
-  return copy;
+} else {
+  scheduleDrain = function () {
+    process.nextTick(nextTick);
+  };
 }
 
-cloneBuffer.hasFrom = hasFrom;
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+  draining = true;
+  var i, oldQueue;
+  var len = queue.length;
+  while (len) {
+    oldQueue = queue;
+    queue = [];
+    i = -1;
+    while (++i < len) {
+      oldQueue[i]();
+    }
+    len = queue.length;
+  }
+  draining = false;
+}
 
-module.exports = cloneBuffer;
+module.exports = immediate;
+function immediate(task) {
+  if (queue.push(task) === 1 && !draining) {
+    scheduleDrain();
+  }
+}
 
 
 /***/ }),
 /* 497 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "Set": () => (/* binding */ ExportedSet),
-/* harmony export */   "Map": () => (/* binding */ ExportedMap)
-/* harmony export */ });
-function mangle(key) {
-  return '$' + key;
-}
-function unmangle(key) {
-  return key.substring(1);
-}
-function Map$1() {
-  this._store = {};
+try {
+  var util = __webpack_require__(64);
+  if (typeof util.inherits !== 'function') throw '';
+  module.exports = util.inherits;
+} catch (e) {
+  module.exports = __webpack_require__(498);
 }
-Map$1.prototype.get = function (key) {
-  var mangled = mangle(key);
-  return this._store[mangled];
-};
-Map$1.prototype.set = function (key, value) {
-  var mangled = mangle(key);
-  this._store[mangled] = value;
-  return true;
-};
-Map$1.prototype.has = function (key) {
-  var mangled = mangle(key);
-  return mangled in this._store;
-};
-Map$1.prototype.delete = function (key) {
-  var mangled = mangle(key);
-  var res = mangled in this._store;
-  delete this._store[mangled];
-  return res;
-};
-Map$1.prototype.forEach = function (cb) {
-  var keys = Object.keys(this._store);
-  for (var i = 0, len = keys.length; i < len; i++) {
-    var key = keys[i];
-    var value = this._store[key];
-    key = unmangle(key);
-    cb(value, key);
-  }
-};
-Object.defineProperty(Map$1.prototype, 'size', {
-  get: function () {
-    return Object.keys(this._store).length;
-  }
-});
 
-function Set$1(array) {
-  this._store = new Map$1();
 
-  // init with an array
-  if (array && Array.isArray(array)) {
-    for (var i = 0, len = array.length; i < len; i++) {
-      this.add(array[i]);
-    }
-  }
-}
-Set$1.prototype.add = function (key) {
-  return this._store.set(key, true);
-};
-Set$1.prototype.has = function (key) {
-  return this._store.has(key);
-};
-Set$1.prototype.forEach = function (cb) {
-  this._store.forEach(function (value, key) {
-    cb(key);
-  });
-};
-Object.defineProperty(Set$1.prototype, 'size', {
-  get: function () {
-    return this._store.size;
-  }
-});
+/***/ }),
+/* 498 */
+/***/ ((module) => {
 
-/* global Map,Set,Symbol */
-// Based on https://kangax.github.io/compat-table/es6/ we can sniff out
-// incomplete Map/Set implementations which would otherwise cause our tests to fail.
-// Notably they fail in IE11 and iOS 8.4, which this prevents.
-function supportsMapAndSet() {
-  if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') {
-    return false;
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
   }
-  var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
-  return prop && 'get' in prop && Map[Symbol.species] === Map;
 }
 
-// based on https://github.com/montagejs/collections
 
-var ExportedSet;
-var ExportedMap;
+/***/ }),
+/* 499 */
+/***/ ((module) => {
 
-{
-  if (supportsMapAndSet()) { // prefer built-in Map/Set
-    ExportedSet = Set;
-    ExportedMap = Map;
-  } else { // fall back to our polyfill
-    ExportedSet = Set$1;
-    ExportedMap = Map$1;
-  }
-}
+(function (factory) {
+    if (true) {
+        // Node/CommonJS
+        module.exports = factory();
+    } else { var glob; }
+}(function (undefined) {
 
+    'use strict';
 
+    /*
+     * Fastest md5 implementation around (JKM md5).
+     * Credits: Joseph Myers
+     *
+     * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+     * @see http://jsperf.com/md5-shootout/7
+     */
 
+    /* this function is much faster,
+      so if possible we use it. Some IEs
+      are the only ones I know of that
+      need the idiotic second function,
+      generated by an if clause.  */
+    var add32 = function (a, b) {
+        return (a + b) & 0xFFFFFFFF;
+    },
+        hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
 
-/***/ }),
-/* 498 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "UNAUTHORIZED": () => (/* binding */ UNAUTHORIZED),
-/* harmony export */   "MISSING_BULK_DOCS": () => (/* binding */ MISSING_BULK_DOCS),
-/* harmony export */   "MISSING_DOC": () => (/* binding */ MISSING_DOC),
-/* harmony export */   "REV_CONFLICT": () => (/* binding */ REV_CONFLICT),
-/* harmony export */   "INVALID_ID": () => (/* binding */ INVALID_ID),
-/* harmony export */   "MISSING_ID": () => (/* binding */ MISSING_ID),
-/* harmony export */   "RESERVED_ID": () => (/* binding */ RESERVED_ID),
-/* harmony export */   "NOT_OPEN": () => (/* binding */ NOT_OPEN),
-/* harmony export */   "UNKNOWN_ERROR": () => (/* binding */ UNKNOWN_ERROR),
-/* harmony export */   "BAD_ARG": () => (/* binding */ BAD_ARG),
-/* harmony export */   "INVALID_REQUEST": () => (/* binding */ INVALID_REQUEST),
-/* harmony export */   "QUERY_PARSE_ERROR": () => (/* binding */ QUERY_PARSE_ERROR),
-/* harmony export */   "DOC_VALIDATION": () => (/* binding */ DOC_VALIDATION),
-/* harmony export */   "BAD_REQUEST": () => (/* binding */ BAD_REQUEST),
-/* harmony export */   "NOT_AN_OBJECT": () => (/* binding */ NOT_AN_OBJECT),
-/* harmony export */   "DB_MISSING": () => (/* binding */ DB_MISSING),
-/* harmony export */   "WSQ_ERROR": () => (/* binding */ WSQ_ERROR),
-/* harmony export */   "LDB_ERROR": () => (/* binding */ LDB_ERROR),
-/* harmony export */   "FORBIDDEN": () => (/* binding */ FORBIDDEN),
-/* harmony export */   "INVALID_REV": () => (/* binding */ INVALID_REV),
-/* harmony export */   "FILE_EXISTS": () => (/* binding */ FILE_EXISTS),
-/* harmony export */   "MISSING_STUB": () => (/* binding */ MISSING_STUB),
-/* harmony export */   "IDB_ERROR": () => (/* binding */ IDB_ERROR),
-/* harmony export */   "INVALID_URL": () => (/* binding */ INVALID_URL),
-/* harmony export */   "createError": () => (/* binding */ createError),
-/* harmony export */   "generateErrorFromResponse": () => (/* binding */ generateErrorFromResponse)
-/* harmony export */ });
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(485);
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__);
+    function cmn(q, a, b, x, s, t) {
+        a = add32(add32(a, q), add32(x, t));
+        return add32((a << s) | (a >>> (32 - s)), b);
+    }
 
+    function md5cycle(x, k) {
+        var a = x[0],
+            b = x[1],
+            c = x[2],
+            d = x[3];
 
-inherits__WEBPACK_IMPORTED_MODULE_0___default()(PouchError, Error);
+        a += (b & c | ~b & d) + k[0] - 680876936 | 0;
+        a  = (a << 7 | a >>> 25) + b | 0;
+        d += (a & b | ~a & c) + k[1] - 389564586 | 0;
+        d  = (d << 12 | d >>> 20) + a | 0;
+        c += (d & a | ~d & b) + k[2] + 606105819 | 0;
+        c  = (c << 17 | c >>> 15) + d | 0;
+        b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
+        b  = (b << 22 | b >>> 10) + c | 0;
+        a += (b & c | ~b & d) + k[4] - 176418897 | 0;
+        a  = (a << 7 | a >>> 25) + b | 0;
+        d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
+        d  = (d << 12 | d >>> 20) + a | 0;
+        c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
+        c  = (c << 17 | c >>> 15) + d | 0;
+        b += (c & d | ~c & a) + k[7] - 45705983 | 0;
+        b  = (b << 22 | b >>> 10) + c | 0;
+        a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
+        a  = (a << 7 | a >>> 25) + b | 0;
+        d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
+        d  = (d << 12 | d >>> 20) + a | 0;
+        c += (d & a | ~d & b) + k[10] - 42063 | 0;
+        c  = (c << 17 | c >>> 15) + d | 0;
+        b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
+        b  = (b << 22 | b >>> 10) + c | 0;
+        a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
+        a  = (a << 7 | a >>> 25) + b | 0;
+        d += (a & b | ~a & c) + k[13] - 40341101 | 0;
+        d  = (d << 12 | d >>> 20) + a | 0;
+        c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
+        c  = (c << 17 | c >>> 15) + d | 0;
+        b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
+        b  = (b << 22 | b >>> 10) + c | 0;
 
-function PouchError(status, error, reason) {
-  Error.call(this, reason);
-  this.status = status;
-  this.name = error;
-  this.message = reason;
-  this.error = true;
-}
+        a += (b & d | c & ~d) + k[1] - 165796510 | 0;
+        a  = (a << 5 | a >>> 27) + b | 0;
+        d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
+        d  = (d << 9 | d >>> 23) + a | 0;
+        c += (d & b | a & ~b) + k[11] + 643717713 | 0;
+        c  = (c << 14 | c >>> 18) + d | 0;
+        b += (c & a | d & ~a) + k[0] - 373897302 | 0;
+        b  = (b << 20 | b >>> 12) + c | 0;
+        a += (b & d | c & ~d) + k[5] - 701558691 | 0;
+        a  = (a << 5 | a >>> 27) + b | 0;
+        d += (a & c | b & ~c) + k[10] + 38016083 | 0;
+        d  = (d << 9 | d >>> 23) + a | 0;
+        c += (d & b | a & ~b) + k[15] - 660478335 | 0;
+        c  = (c << 14 | c >>> 18) + d | 0;
+        b += (c & a | d & ~a) + k[4] - 405537848 | 0;
+        b  = (b << 20 | b >>> 12) + c | 0;
+        a += (b & d | c & ~d) + k[9] + 568446438 | 0;
+        a  = (a << 5 | a >>> 27) + b | 0;
+        d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
+        d  = (d << 9 | d >>> 23) + a | 0;
+        c += (d & b | a & ~b) + k[3] - 187363961 | 0;
+        c  = (c << 14 | c >>> 18) + d | 0;
+        b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
+        b  = (b << 20 | b >>> 12) + c | 0;
+        a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
+        a  = (a << 5 | a >>> 27) + b | 0;
+        d += (a & c | b & ~c) + k[2] - 51403784 | 0;
+        d  = (d << 9 | d >>> 23) + a | 0;
+        c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
+        c  = (c << 14 | c >>> 18) + d | 0;
+        b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
+        b  = (b << 20 | b >>> 12) + c | 0;
 
-PouchError.prototype.toString = function () {
-  return JSON.stringify({
-    status: this.status,
-    name: this.name,
-    message: this.message,
-    reason: this.reason
-  });
-};
+        a += (b ^ c ^ d) + k[5] - 378558 | 0;
+        a  = (a << 4 | a >>> 28) + b | 0;
+        d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
+        d  = (d << 11 | d >>> 21) + a | 0;
+        c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
+        c  = (c << 16 | c >>> 16) + d | 0;
+        b += (c ^ d ^ a) + k[14] - 35309556 | 0;
+        b  = (b << 23 | b >>> 9) + c | 0;
+        a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
+        a  = (a << 4 | a >>> 28) + b | 0;
+        d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
+        d  = (d << 11 | d >>> 21) + a | 0;
+        c += (d ^ a ^ b) + k[7] - 155497632 | 0;
+        c  = (c << 16 | c >>> 16) + d | 0;
+        b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
+        b  = (b << 23 | b >>> 9) + c | 0;
+        a += (b ^ c ^ d) + k[13] + 681279174 | 0;
+        a  = (a << 4 | a >>> 28) + b | 0;
+        d += (a ^ b ^ c) + k[0] - 358537222 | 0;
+        d  = (d << 11 | d >>> 21) + a | 0;
+        c += (d ^ a ^ b) + k[3] - 722521979 | 0;
+        c  = (c << 16 | c >>> 16) + d | 0;
+        b += (c ^ d ^ a) + k[6] + 76029189 | 0;
+        b  = (b << 23 | b >>> 9) + c | 0;
+        a += (b ^ c ^ d) + k[9] - 640364487 | 0;
+        a  = (a << 4 | a >>> 28) + b | 0;
+        d += (a ^ b ^ c) + k[12] - 421815835 | 0;
+        d  = (d << 11 | d >>> 21) + a | 0;
+        c += (d ^ a ^ b) + k[15] + 530742520 | 0;
+        c  = (c << 16 | c >>> 16) + d | 0;
+        b += (c ^ d ^ a) + k[2] - 995338651 | 0;
+        b  = (b << 23 | b >>> 9) + c | 0;
 
-var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect.");
-var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'");
-var MISSING_DOC = new PouchError(404, 'not_found', 'missing');
-var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict');
-var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string');
-var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts');
-var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.');
-var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open');
-var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error');
-var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid');
-var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid');
-var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid');
-var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member');
-var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request');
-var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object');
-var DB_MISSING = new PouchError(404, 'not_found', 'Database not found');
-var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown');
-var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown');
-var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown');
-var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function');
-var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format');
-var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.');
-var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found');
-var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid');
+        a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
+        a  = (a << 6 | a >>> 26) + b | 0;
+        d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
+        d  = (d << 10 | d >>> 22) + a | 0;
+        c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
+        c  = (c << 15 | c >>> 17) + d | 0;
+        b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
+        b  = (b << 21 |b >>> 11) + c | 0;
+        a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
+        a  = (a << 6 | a >>> 26) + b | 0;
+        d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
+        d  = (d << 10 | d >>> 22) + a | 0;
+        c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
+        c  = (c << 15 | c >>> 17) + d | 0;
+        b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
+        b  = (b << 21 |b >>> 11) + c | 0;
+        a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
+        a  = (a << 6 | a >>> 26) + b | 0;
+        d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
+        d  = (d << 10 | d >>> 22) + a | 0;
+        c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
+        c  = (c << 15 | c >>> 17) + d | 0;
+        b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
+        b  = (b << 21 |b >>> 11) + c | 0;
+        a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
+        a  = (a << 6 | a >>> 26) + b | 0;
+        d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
+        d  = (d << 10 | d >>> 22) + a | 0;
+        c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
+        c  = (c << 15 | c >>> 17) + d | 0;
+        b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
+        b  = (b << 21 | b >>> 11) + c | 0;
 
-function createError(error, reason) {
-  function CustomPouchError(reason) {
-    // inherit error properties from our parent error manually
-    // so as to allow proper JSON parsing.
-    /* jshint ignore:start */
-    for (var p in error) {
-      if (typeof error[p] !== 'function') {
-        this[p] = error[p];
-      }
-    }
-    /* jshint ignore:end */
-    if (reason !== undefined) {
-      this.reason = reason;
+        x[0] = a + x[0] | 0;
+        x[1] = b + x[1] | 0;
+        x[2] = c + x[2] | 0;
+        x[3] = d + x[3] | 0;
     }
-  }
-  CustomPouchError.prototype = PouchError.prototype;
-  return new CustomPouchError(reason);
-}
 
-function generateErrorFromResponse(err) {
+    function md5blk(s) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
 
-  if (typeof err !== 'object') {
-    var data = err;
-    err = UNKNOWN_ERROR;
-    err.data = data;
-  }
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+        }
+        return md5blks;
+    }
 
-  if ('error' in err && err.error === 'conflict') {
-    err.name = 'conflict';
-    err.status = 409;
-  }
+    function md5blk_array(a) {
+        var md5blks = [],
+            i; /* Andy King said do it this way. */
 
-  if (!('name' in err)) {
-    err.name = err.error || 'unknown';
-  }
+        for (i = 0; i < 64; i += 4) {
+            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+        }
+        return md5blks;
+    }
 
-  if (!('status' in err)) {
-    err.status = 500;
-  }
+    function md51(s) {
+        var n = s.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
 
-  if (!('message' in err)) {
-    err.message = err.message || err.reason;
-  }
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk(s.substring(i - 64, i)));
+        }
+        s = s.substring(i - 64);
+        length = s.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+        }
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
 
-  return err;
-}
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
 
+        tail[14] = lo;
+        tail[15] = hi;
 
+        md5cycle(state, tail);
+        return state;
+    }
 
+    function md51_array(a) {
+        var n = a.length,
+            state = [1732584193, -271733879, -1732584194, 271733878],
+            i,
+            length,
+            tail,
+            tmp,
+            lo,
+            hi;
 
-/***/ }),
-/* 499 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+        for (i = 64; i <= n; i += 64) {
+            md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+        }
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "binaryMd5": () => (/* binding */ binaryMd5),
-/* harmony export */   "stringMd5": () => (/* binding */ stringMd5)
-/* harmony export */ });
-/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76);
-/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_0__);
+        // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+        // containing the last element of the parent array if the sub array specified starts
+        // beyond the length of the parent array - weird.
+        // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+        a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
 
+        length = a.length;
+        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= a[i] << ((i % 4) << 3);
+        }
 
-function binaryMd5(data, callback) {
-  var base64 = crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(data, 'binary').digest('base64');
-  callback(base64);
-}
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(state, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
 
-function stringMd5(string) {
-  return crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(string, 'binary').digest('hex');
-}
+        // Beware that the final length might not fit in 32 bits so we take care of that
+        tmp = n * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
 
+        tail[14] = lo;
+        tail[15] = hi;
 
+        md5cycle(state, tail);
 
+        return state;
+    }
 
-/***/ }),
-/* 500 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+    function rhex(n) {
+        var s = '',
+            j;
+        for (j = 0; j < 4; j += 1) {
+            s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+        }
+        return s;
+    }
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "fetch": () => (/* binding */ fetch),
-/* harmony export */   "Headers": () => (/* binding */ Headers),
-/* harmony export */   "AbortController": () => (/* binding */ AbortController)
-/* harmony export */ });
-/* harmony import */ var node_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(481);
-/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(501);
-/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fetch_cookie__WEBPACK_IMPORTED_MODULE_1__);
+    function hex(x) {
+        var i;
+        for (i = 0; i < x.length; i += 1) {
+            x[i] = rhex(x[i]);
+        }
+        return x.join('');
+    }
 
+    // In some cases the fast add32 function cannot be used..
+    if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+        add32 = function (x, y) {
+            var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+            return (msw << 16) | (lsw & 0xFFFF);
+        };
+    }
 
+    // ---------------------------------------------------
 
-var fetch = fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default()(node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"]);
+    /**
+     * ArrayBuffer slice polyfill.
+     *
+     * @see https://github.com/ttaubert/node-arraybuffer-slice
+     */
 
-/* We can fake the abort, the http adapter keeps track
-   of ignoring the result */
-function AbortController() {
-  return {abort: function () {}};
-}
+    if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+        (function () {
+            function clamp(val, length) {
+                val = (val | 0) || 0;
 
-var Headers = node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"].Headers;
+                if (val < 0) {
+                    return Math.max(val + length, 0);
+                }
 
+                return Math.min(val, length);
+            }
 
+            ArrayBuffer.prototype.slice = function (from, to) {
+                var length = this.byteLength,
+                    begin = clamp(from, length),
+                    end = length,
+                    num,
+                    target,
+                    targetArray,
+                    sourceArray;
 
+                if (to !== undefined) {
+                    end = clamp(to, length);
+                }
 
-/***/ }),
-/* 501 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                if (begin > end) {
+                    return new ArrayBuffer(0);
+                }
 
-var denodeify = __webpack_require__(502)(Promise)
-var tough = __webpack_require__(61)
+                num = end - begin;
+                target = new ArrayBuffer(num);
+                targetArray = new Uint8Array(target);
 
-module.exports = function fetchCookieDecorator (fetch, jar) {
-  fetch = fetch || window.fetch
-  jar = jar || new tough.CookieJar()
+                sourceArray = new Uint8Array(this, begin, num);
+                targetArray.set(sourceArray);
 
-  var getCookieString = denodeify(jar.getCookieString.bind(jar))
-  var setCookie = denodeify(jar.setCookie.bind(jar))
+                return target;
+            };
+        })();
+    }
 
-  return function fetchCookie (url, opts) {
-    opts = opts || {}
+    // ---------------------------------------------------
 
-    return getCookieString(url)
-      .then(function (cookie) {
-        return fetch(url, Object.assign(opts, {
-          headers: Object.assign(opts.headers || {}, (cookie ? { cookie: cookie } : {}))
-        }))
-      })
-      .then(function (res) {
-        var cookies
+    /**
+     * Helpers.
+     */
 
-        if (res.headers.getAll) {
-          // node-fetch v1
-          cookies = res.headers.getAll('set-cookie')
-        } else {
-          // node-fetch v2
-          var cookie = res.headers.get('set-cookie')
-          cookies = cookie && cookie.split(',') || []
+    function toUtf8(str) {
+        if (/[\u0080-\uFFFF]/.test(str)) {
+            str = unescape(encodeURIComponent(str));
         }
 
-        if (!cookies.length) {
-          return res
-        }
+        return str;
+    }
 
-        return Promise.all(cookies.map(function (cookie) {
-          return setCookie(cookie, res.url)
-        })).then(function () {
-          return res
-        })
-      })
-  }
-}
+    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+        var length = str.length,
+           buff = new ArrayBuffer(length),
+           arr = new Uint8Array(buff),
+           i;
 
+        for (i = 0; i < length; i += 1) {
+            arr[i] = str.charCodeAt(i);
+        }
 
-/***/ }),
-/* 502 */
-/***/ ((module, exports) => {
+        return returnUInt8Array ? arr : buff;
+    }
 
-"use strict";
+    function arrayBuffer2Utf8Str(buff) {
+        return String.fromCharCode.apply(null, new Uint8Array(buff));
+    }
 
+    function concatenateArrayBuffers(first, second, returnUInt8Array) {
+        var result = new Uint8Array(first.byteLength + second.byteLength);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
+        result.set(new Uint8Array(first));
+        result.set(new Uint8Array(second), first.byteLength);
 
-exports["default"] = function () {
-  var PromiseArg = arguments[0] === undefined ? Promise : arguments[0];
-  return function (f) {
-    return function () {
-      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-        args[_key] = arguments[_key];
-      }
+        return returnUInt8Array ? result : result.buffer;
+    }
 
-      return new PromiseArg(function (resolve, reject) {
-        return f.apply(undefined, args.concat([function (err, val) {
-          return err ? reject(err) : resolve(val);
-        }]));
-      });
-    };
-  };
-};
+    function hexToBinaryString(hex) {
+        var bytes = [],
+            length = hex.length,
+            x;
 
-module.exports = exports["default"];
+        for (x = 0; x < length - 1; x += 2) {
+            bytes.push(parseInt(hex.substr(x, 2), 16));
+        }
 
+        return String.fromCharCode.apply(String, bytes);
+    }
 
+    // ---------------------------------------------------
 
-/***/ }),
-/* 503 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+    /**
+     * SparkMD5 OOP implementation.
+     *
+     * Use this class to perform an incremental md5, otherwise use the
+     * static methods instead.
+     */
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "massageSelector": () => (/* binding */ massageSelector),
-/* harmony export */   "matchesSelector": () => (/* binding */ matchesSelector),
-/* harmony export */   "filterInMemoryFields": () => (/* binding */ filterInMemoryFields),
-/* harmony export */   "createFieldSorter": () => (/* binding */ createFieldSorter),
-/* harmony export */   "rowFilter": () => (/* binding */ rowFilter),
-/* harmony export */   "isCombinationalField": () => (/* binding */ isCombinationalField),
-/* harmony export */   "getKey": () => (/* binding */ getKey),
-/* harmony export */   "getValue": () => (/* binding */ getValue),
-/* harmony export */   "getFieldFromDoc": () => (/* binding */ getFieldFromDoc),
-/* harmony export */   "setFieldInDoc": () => (/* binding */ setFieldInDoc),
-/* harmony export */   "compare": () => (/* binding */ compare),
-/* harmony export */   "parseField": () => (/* binding */ parseField)
-/* harmony export */ });
-/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495);
-/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(504);
+    function SparkMD5() {
+        // call reset to init the instance
+        this.reset();
+    }
 
+    /**
+     * Appends a string.
+     * A conversion will be applied if an utf8 string is detected.
+     *
+     * @param {String} str The string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.append = function (str) {
+        // Converts the string to utf8 bytes if necessary
+        // Then append as binary
+        this.appendBinary(toUtf8(str));
 
+        return this;
+    };
 
-// this would just be "return doc[field]", but fields
-// can be "deep" due to dot notation
-function getFieldFromDoc(doc, parsedField) {
-  var value = doc;
-  for (var i = 0, len = parsedField.length; i < len; i++) {
-    var key = parsedField[i];
-    value = value[key];
-    if (!value) {
-      break;
-    }
-  }
-  return value;
-}
+    /**
+     * Appends a binary string.
+     *
+     * @param {String} contents The binary string to be appended
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.appendBinary = function (contents) {
+        this._buff += contents;
+        this._length += contents.length;
 
-function setFieldInDoc(doc, parsedField, value) {
-  for (var i = 0, len = parsedField.length; i < len-1; i++) {
-    var elem = parsedField[i];
-    doc = doc[elem] = {};
-  }
-  doc[parsedField[len-1]] = value;
-}
+        var length = this._buff.length,
+            i;
 
-function compare(left, right) {
-  return left < right ? -1 : left > right ? 1 : 0;
-}
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+        }
 
-// Converts a string in dot notation to an array of its components, with backslash escaping
-function parseField(fieldName) {
-  // fields may be deep (e.g. "foo.bar.baz"), so parse
-  var fields = [];
-  var current = '';
-  for (var i = 0, len = fieldName.length; i < len; i++) {
-    var ch = fieldName[i];
-    if (ch === '.') {
-      if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter
-        current = current.substring(0, current.length - 1) + '.';
-      } else { // not escaped, so delimiter
-        fields.push(current);
-        current = '';
-      }
-    } else { // normal character
-      current += ch;
-    }
-  }
-  fields.push(current);
-  return fields;
-}
+        this._buff = this._buff.substring(i - 64);
 
-var combinationFields = ['$or', '$nor', '$not'];
-function isCombinationalField(field) {
-  return combinationFields.indexOf(field) > -1;
-}
+        return this;
+    };
 
-function getKey(obj) {
-  return Object.keys(obj)[0];
-}
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            i,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            ret;
 
-function getValue(obj) {
-  return obj[getKey(obj)];
-}
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+        }
 
+        this._finish(tail, length);
+        ret = hex(this._hash);
 
-// flatten an array of selectors joined by an $and operator
-function mergeAndedSelectors(selectors) {
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
 
-  // sort to ensure that e.g. if the user specified
-  // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into
-  // just {$gt: 'b'}
-  var res = {};
+        this.reset();
 
-  selectors.forEach(function (selector) {
-    Object.keys(selector).forEach(function (field) {
-      var matcher = selector[field];
-      if (typeof matcher !== 'object') {
-        matcher = {$eq: matcher};
-      }
+        return ret;
+    };
 
-      if (isCombinationalField(field)) {
-        if (matcher instanceof Array) {
-          res[field] = matcher.map(function (m) {
-            return mergeAndedSelectors([m]);
-          });
-        } else {
-          res[field] = mergeAndedSelectors([matcher]);
-        }
-      } else {
-        var fieldMatchers = res[field] = res[field] || {};
-        Object.keys(matcher).forEach(function (operator) {
-          var value = matcher[operator];
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.reset = function () {
+        this._buff = '';
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
 
-          if (operator === '$gt' || operator === '$gte') {
-            return mergeGtGte(operator, value, fieldMatchers);
-          } else if (operator === '$lt' || operator === '$lte') {
-            return mergeLtLte(operator, value, fieldMatchers);
-          } else if (operator === '$ne') {
-            return mergeNe(value, fieldMatchers);
-          } else if (operator === '$eq') {
-            return mergeEq(value, fieldMatchers);
-          }
-          fieldMatchers[operator] = value;
-        });
-      }
-    });
-  });
+        return this;
+    };
 
-  return res;
-}
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.prototype.getState = function () {
+        return {
+            buff: this._buff,
+            length: this._length,
+            hash: this._hash
+        };
+    };
 
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5} The instance itself
+     */
+    SparkMD5.prototype.setState = function (state) {
+        this._buff = state.buff;
+        this._length = state.length;
+        this._hash = state.hash;
 
+        return this;
+    };
 
-// collapse logically equivalent gt/gte values
-function mergeGtGte(operator, value, fieldMatchers) {
-  if (typeof fieldMatchers.$eq !== 'undefined') {
-    return; // do nothing
-  }
-  if (typeof fieldMatchers.$gte !== 'undefined') {
-    if (operator === '$gte') {
-      if (value > fieldMatchers.$gte) { // more specificity
-        fieldMatchers.$gte = value;
-      }
-    } else { // operator === '$gt'
-      if (value >= fieldMatchers.$gte) { // more specificity
-        delete fieldMatchers.$gte;
-        fieldMatchers.$gt = value;
-      }
-    }
-  } else if (typeof fieldMatchers.$gt !== 'undefined') {
-    if (operator === '$gte') {
-      if (value > fieldMatchers.$gt) { // more specificity
-        delete fieldMatchers.$gt;
-        fieldMatchers.$gte = value;
-      }
-    } else { // operator === '$gt'
-      if (value > fieldMatchers.$gt) { // more specificity
-        fieldMatchers.$gt = value;
-      }
-    }
-  } else {
-    fieldMatchers[operator] = value;
-  }
-}
+    /**
+     * Releases memory used by the incremental buffer and other additional
+     * resources. If you plan to use the instance again, use reset instead.
+     */
+    SparkMD5.prototype.destroy = function () {
+        delete this._hash;
+        delete this._buff;
+        delete this._length;
+    };
 
-// collapse logically equivalent lt/lte values
-function mergeLtLte(operator, value, fieldMatchers) {
-  if (typeof fieldMatchers.$eq !== 'undefined') {
-    return; // do nothing
-  }
-  if (typeof fieldMatchers.$lte !== 'undefined') {
-    if (operator === '$lte') {
-      if (value < fieldMatchers.$lte) { // more specificity
-        fieldMatchers.$lte = value;
-      }
-    } else { // operator === '$gt'
-      if (value <= fieldMatchers.$lte) { // more specificity
-        delete fieldMatchers.$lte;
-        fieldMatchers.$lt = value;
-      }
-    }
-  } else if (typeof fieldMatchers.$lt !== 'undefined') {
-    if (operator === '$lte') {
-      if (value < fieldMatchers.$lt) { // more specificity
-        delete fieldMatchers.$lt;
-        fieldMatchers.$lte = value;
-      }
-    } else { // operator === '$gt'
-      if (value < fieldMatchers.$lt) { // more specificity
-        fieldMatchers.$lt = value;
-      }
-    }
-  } else {
-    fieldMatchers[operator] = value;
-  }
-}
+    /**
+     * Finish the final calculation based on the tail.
+     *
+     * @param {Array}  tail   The tail (will be modified)
+     * @param {Number} length The length of the remaining buffer
+     */
+    SparkMD5.prototype._finish = function (tail, length) {
+        var i = length,
+            tmp,
+            lo,
+            hi;
 
-// combine $ne values into one array
-function mergeNe(value, fieldMatchers) {
-  if ('$ne' in fieldMatchers) {
-    // there are many things this could "not" be
-    fieldMatchers.$ne.push(value);
-  } else { // doesn't exist yet
-    fieldMatchers.$ne = [value];
-  }
-}
+        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+        if (i > 55) {
+            md5cycle(this._hash, tail);
+            for (i = 0; i < 16; i += 1) {
+                tail[i] = 0;
+            }
+        }
 
-// add $eq into the mix
-function mergeEq(value, fieldMatchers) {
-  // these all have less specificity than the $eq
-  // TODO: check for user errors here
-  delete fieldMatchers.$gt;
-  delete fieldMatchers.$gte;
-  delete fieldMatchers.$lt;
-  delete fieldMatchers.$lte;
-  delete fieldMatchers.$ne;
-  fieldMatchers.$eq = value;
-}
+        // Do the final computation based on the tail and length
+        // Beware that the final length may not fit in 32 bits so we take care of that
+        tmp = this._length * 8;
+        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+        lo = parseInt(tmp[2], 16);
+        hi = parseInt(tmp[1], 16) || 0;
 
+        tail[14] = lo;
+        tail[15] = hi;
+        md5cycle(this._hash, tail);
+    };
 
-//
-// normalize the selector
-//
-function massageSelector(input) {
-  var result = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(input);
-  var wasAnded = false;
-  if ('$and' in result) {
-    result = mergeAndedSelectors(result['$and']);
-    wasAnded = true;
-  }
+    /**
+     * Performs the md5 hash on a string.
+     * A conversion will be applied if utf8 string is detected.
+     *
+     * @param {String}  str The string
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hash = function (str, raw) {
+        // Converts the string to utf8 bytes if necessary
+        // Then compute it using the binary function
+        return SparkMD5.hashBinary(toUtf8(str), raw);
+    };
 
-  ['$or', '$nor'].forEach(function (orOrNor) {
-    if (orOrNor in result) {
-      // message each individual selector
-      // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}}
-      result[orOrNor].forEach(function (subSelector) {
-        var fields = Object.keys(subSelector);
-        for (var i = 0; i < fields.length; i++) {
-          var field = fields[i];
-          var matcher = subSelector[field];
-          if (typeof matcher !== 'object' || matcher === null) {
-            subSelector[field] = {$eq: matcher};
-          }
-        }
-      });
-    }
-  });
+    /**
+     * Performs the md5 hash on a binary string.
+     *
+     * @param {String}  content The binary string
+     * @param {Boolean} raw     True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.hashBinary = function (content, raw) {
+        var hash = md51(content),
+            ret = hex(hash);
 
-  if ('$not' in result) {
-    //This feels a little like forcing, but it will work for now,
-    //I would like to come back to this and make the merging of selectors a little more generic
-    result['$not'] = mergeAndedSelectors([result['$not']]);
-  }
+        return raw ? hexToBinaryString(ret) : ret;
+    };
 
-  var fields = Object.keys(result);
+    // ---------------------------------------------------
 
-  for (var i = 0; i < fields.length; i++) {
-    var field = fields[i];
-    var matcher = result[field];
+    /**
+     * SparkMD5 OOP implementation for array buffers.
+     *
+     * Use this class to perform an incremental md5 ONLY for array buffers.
+     */
+    SparkMD5.ArrayBuffer = function () {
+        // call reset to init the instance
+        this.reset();
+    };
 
-    if (typeof matcher !== 'object' || matcher === null) {
-      matcher = {$eq: matcher};
-    } else if ('$ne' in matcher && !wasAnded) {
-      // I put these in an array, since there may be more than one
-      // but in the "mergeAnded" operation, I already take care of that
-      matcher.$ne = [matcher.$ne];
-    }
-    result[field] = matcher;
-  }
+    /**
+     * Appends an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array to be appended
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+            length = buff.length,
+            i;
 
-  return result;
-}
+        this._length += arr.byteLength;
 
-// create a comparator based on the sort object
-function createFieldSorter(sort) {
+        for (i = 64; i <= length; i += 64) {
+            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+        }
 
-  function getFieldValuesAsArray(doc) {
-    return sort.map(function (sorting) {
-      var fieldName = getKey(sorting);
-      var parsedField = parseField(fieldName);
-      var docFieldValue = getFieldFromDoc(doc, parsedField);
-      return docFieldValue;
-    });
-  }
+        this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
 
-  return function (aRow, bRow) {
-    var aFieldValues = getFieldValuesAsArray(aRow.doc);
-    var bFieldValues = getFieldValuesAsArray(bRow.doc);
-    var collation = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(aFieldValues, bFieldValues);
-    if (collation !== 0) {
-      return collation;
-    }
-    // this is what mango seems to do
-    return compare(aRow.doc._id, bRow.doc._id);
-  };
-}
+        return this;
+    };
 
-function filterInMemoryFields(rows, requestDef, inMemoryFields) {
-  rows = rows.filter(function (row) {
-    return rowFilter(row.doc, requestDef.selector, inMemoryFields);
-  });
+    /**
+     * Finishes the incremental computation, reseting the internal state and
+     * returning the result.
+     *
+     * @param {Boolean} raw True to get the raw string, false to get the hex string
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+        var buff = this._buff,
+            length = buff.length,
+            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            i,
+            ret;
 
-  if (requestDef.sort) {
-    // in-memory sort
-    var fieldSorter = createFieldSorter(requestDef.sort);
-    rows = rows.sort(fieldSorter);
-    if (typeof requestDef.sort[0] !== 'string' &&
-        getValue(requestDef.sort[0]) === 'desc') {
-      rows = rows.reverse();
-    }
-  }
+        for (i = 0; i < length; i += 1) {
+            tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+        }
 
-  if ('limit' in requestDef || 'skip' in requestDef) {
-    // have to do the limit in-memory
-    var skip = requestDef.skip || 0;
-    var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip;
-    rows = rows.slice(skip, limit);
-  }
-  return rows;
-}
+        this._finish(tail, length);
+        ret = hex(this._hash);
 
-function rowFilter(doc, selector, inMemoryFields) {
-  return inMemoryFields.every(function (field) {
-    var matcher = selector[field];
-    var parsedField = parseField(field);
-    var docFieldValue = getFieldFromDoc(doc, parsedField);
-    if (isCombinationalField(field)) {
-      return matchCominationalSelector(field, matcher, doc);
-    }
+        if (raw) {
+            ret = hexToBinaryString(ret);
+        }
 
-    return matchSelector(matcher, doc, parsedField, docFieldValue);
-  });
-}
+        this.reset();
 
-function matchSelector(matcher, doc, parsedField, docFieldValue) {
-  if (!matcher) {
-    // no filtering necessary; this field is just needed for sorting
-    return true;
-  }
+        return ret;
+    };
 
-  return Object.keys(matcher).every(function (userOperator) {
-    var userValue = matcher[userOperator];
-    return match(userOperator, doc, userValue, parsedField, docFieldValue);
-  });
-}
+    /**
+     * Resets the internal state of the computation.
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.reset = function () {
+        this._buff = new Uint8Array(0);
+        this._length = 0;
+        this._hash = [1732584193, -271733879, -1732584194, 271733878];
 
-function matchCominationalSelector(field, matcher, doc) {
+        return this;
+    };
 
-  if (field === '$or') {
-    return matcher.some(function (orMatchers) {
-      return rowFilter(doc, orMatchers, Object.keys(orMatchers));
-    });
-  }
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @return {Object} The state
+     */
+    SparkMD5.ArrayBuffer.prototype.getState = function () {
+        var state = SparkMD5.prototype.getState.call(this);
 
-  if (field === '$not') {
-    return !rowFilter(doc, matcher, Object.keys(matcher));
-  }
+        // Convert buffer to a string
+        state.buff = arrayBuffer2Utf8Str(state.buff);
 
-  //`$nor`
-  return !matcher.find(function (orMatchers) {
-    return rowFilter(doc, orMatchers, Object.keys(orMatchers));
-  });
+        return state;
+    };
 
-}
+    /**
+     * Gets the internal state of the computation.
+     *
+     * @param {Object} state The state
+     *
+     * @return {SparkMD5.ArrayBuffer} The instance itself
+     */
+    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+        // Convert string to buffer
+        state.buff = utf8Str2ArrayBuffer(state.buff, true);
 
-function match(userOperator, doc, userValue, parsedField, docFieldValue) {
-  if (!matchers[userOperator]) {
-    throw new Error('unknown operator "' + userOperator +
-      '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' +
-      '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all');
-  }
-  return matchers[userOperator](doc, userValue, parsedField, docFieldValue);
-}
+        return SparkMD5.prototype.setState.call(this, state);
+    };
 
-function fieldExists(docFieldValue) {
-  return typeof docFieldValue !== 'undefined' && docFieldValue !== null;
-}
+    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
 
-function fieldIsNotUndefined(docFieldValue) {
-  return typeof docFieldValue !== 'undefined';
-}
+    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
 
-function modField(docFieldValue, userValue) {
-  var divisor = userValue[0];
-  var mod = userValue[1];
-  if (divisor === 0) {
-    throw new Error('Bad divisor, cannot divide by zero');
-  }
+    /**
+     * Performs the md5 hash on an array buffer.
+     *
+     * @param {ArrayBuffer} arr The array buffer
+     * @param {Boolean}     raw True to get the raw string, false to get the hex one
+     *
+     * @return {String} The result
+     */
+    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+        var hash = md51_array(new Uint8Array(arr)),
+            ret = hex(hash);
 
-  if (parseInt(divisor, 10) !== divisor ) {
-    throw new Error('Divisor is not an integer');
-  }
+        return raw ? hexToBinaryString(ret) : ret;
+    };
 
-  if (parseInt(mod, 10) !== mod ) {
-    throw new Error('Modulus is not an integer');
-  }
+    return SparkMD5;
+}));
 
-  if (parseInt(docFieldValue, 10) !== docFieldValue) {
-    return false;
-  }
 
-  return docFieldValue % divisor === mod;
-}
+/***/ }),
+/* 500 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function arrayContainsValue(docFieldValue, userValue) {
-  return userValue.some(function (val) {
-    if (docFieldValue instanceof Array) {
-      return docFieldValue.indexOf(val) > -1;
-    }
+var v1 = __webpack_require__(501);
+var v4 = __webpack_require__(504);
 
-    return docFieldValue === val;
-  });
-}
+var uuid = v4;
+uuid.v1 = v1;
+uuid.v4 = v4;
 
-function arrayContainsAllValues(docFieldValue, userValue) {
-  return userValue.every(function (val) {
-    return docFieldValue.indexOf(val) > -1;
-  });
-}
+module.exports = uuid;
 
-function arraySize(docFieldValue, userValue) {
-  return docFieldValue.length === userValue;
-}
 
-function regexMatch(docFieldValue, userValue) {
-  var re = new RegExp(userValue);
+/***/ }),
+/* 501 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  return re.test(docFieldValue);
-}
+var rng = __webpack_require__(502);
+var bytesToUuid = __webpack_require__(503);
 
-function typeMatch(docFieldValue, userValue) {
+// **`v1()` - Generate time-based UUID**
+//
+// Inspired by https://github.com/LiosK/UUID.js
+// and http://docs.python.org/library/uuid.html
 
-  switch (userValue) {
-    case 'null':
-      return docFieldValue === null;
-    case 'boolean':
-      return typeof (docFieldValue) === 'boolean';
-    case 'number':
-      return typeof (docFieldValue) === 'number';
-    case 'string':
-      return typeof (docFieldValue) === 'string';
-    case 'array':
-      return docFieldValue instanceof Array;
-    case 'object':
-      return ({}).toString.call(docFieldValue) === '[object Object]';
-  }
+var _nodeId;
+var _clockseq;
 
-  throw new Error(userValue + ' not supported as a type.' +
-                  'Please use one of object, string, array, number, boolean or null.');
+// Previous uuid creation time
+var _lastMSecs = 0;
+var _lastNSecs = 0;
 
-}
+// See https://github.com/broofa/node-uuid for API details
+function v1(options, buf, offset) {
+  var i = buf && offset || 0;
+  var b = buf || [];
 
-var matchers = {
+  options = options || {};
+  var node = options.node || _nodeId;
+  var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
 
-  '$elemMatch': function (doc, userValue, parsedField, docFieldValue) {
-    if (!Array.isArray(docFieldValue)) {
-      return false;
+  // node and clockseq need to be initialized to random values if they're not
+  // specified.  We do this lazily to minimize issues related to insufficient
+  // system entropy.  See #189
+  if (node == null || clockseq == null) {
+    var seedBytes = rng();
+    if (node == null) {
+      // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
+      node = _nodeId = [
+        seedBytes[0] | 0x01,
+        seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]
+      ];
     }
-
-    if (docFieldValue.length === 0) {
-      return false;
+    if (clockseq == null) {
+      // Per 4.2.2, randomize (14 bit) clockseq
+      clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
     }
+  }
 
-    if (typeof docFieldValue[0] === 'object') {
-      return docFieldValue.some(function (val) {
-        return rowFilter(val, userValue, Object.keys(userValue));
-      });
-    }
+  // UUID timestamps are 100 nano-second units since the Gregorian epoch,
+  // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
+  // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
+  // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
+  var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
 
-    return docFieldValue.some(function (val) {
-      return matchSelector(userValue, doc, parsedField, val);
-    });
-  },
+  // Per 4.2.1.2, use count of uuid's generated during the current clock
+  // cycle to simulate higher resolution clock
+  var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
 
-  '$allMatch': function (doc, userValue, parsedField, docFieldValue) {
-    if (!Array.isArray(docFieldValue)) {
-      return false;
-    }
+  // Time since last uuid creation (in msecs)
+  var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
 
-    /* istanbul ignore next */
-    if (docFieldValue.length === 0) {
-      return false;
-    }
+  // Per 4.2.1.2, Bump clockseq on clock regression
+  if (dt < 0 && options.clockseq === undefined) {
+    clockseq = clockseq + 1 & 0x3fff;
+  }
 
-    if (typeof docFieldValue[0] === 'object') {
-      return docFieldValue.every(function (val) {
-        return rowFilter(val, userValue, Object.keys(userValue));
-      });
-    }
+  // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
+  // time interval
+  if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
+    nsecs = 0;
+  }
 
-    return docFieldValue.every(function (val) {
-      return matchSelector(userValue, doc, parsedField, val);
-    });
-  },
+  // Per 4.2.1.2 Throw error if too many uuids are requested
+  if (nsecs >= 10000) {
+    throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
+  }
 
-  '$eq': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) === 0;
-  },
+  _lastMSecs = msecs;
+  _lastNSecs = nsecs;
+  _clockseq = clockseq;
 
-  '$gte': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) >= 0;
-  },
+  // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
+  msecs += 12219292800000;
 
-  '$gt': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) > 0;
-  },
+  // `time_low`
+  var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
+  b[i++] = tl >>> 24 & 0xff;
+  b[i++] = tl >>> 16 & 0xff;
+  b[i++] = tl >>> 8 & 0xff;
+  b[i++] = tl & 0xff;
 
-  '$lte': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) <= 0;
-  },
+  // `time_mid`
+  var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
+  b[i++] = tmh >>> 8 & 0xff;
+  b[i++] = tmh & 0xff;
 
-  '$lt': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) < 0;
-  },
+  // `time_high_and_version`
+  b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
+  b[i++] = tmh >>> 16 & 0xff;
 
-  '$exists': function (doc, userValue, parsedField, docFieldValue) {
-    //a field that is null is still considered to exist
-    if (userValue) {
-      return fieldIsNotUndefined(docFieldValue);
-    }
+  // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
+  b[i++] = clockseq >>> 8 | 0x80;
 
-    return !fieldIsNotUndefined(docFieldValue);
-  },
+  // `clock_seq_low`
+  b[i++] = clockseq & 0xff;
 
-  '$mod': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && modField(docFieldValue, userValue);
-  },
+  // `node`
+  for (var n = 0; n < 6; ++n) {
+    b[i + n] = node[n];
+  }
 
-  '$ne': function (doc, userValue, parsedField, docFieldValue) {
-    return userValue.every(function (neValue) {
-      return (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, neValue) !== 0;
-    });
-  },
-  '$in': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue);
-  },
+  return buf ? buf : bytesToUuid(b);
+}
 
-  '$nin': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue);
-  },
+module.exports = v1;
 
-  '$size': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue);
-  },
 
-  '$all': function (doc, userValue, parsedField, docFieldValue) {
-    return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue);
-  },
+/***/ }),
+/* 502 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  '$regex': function (doc, userValue, parsedField, docFieldValue) {
-    return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue);
-  },
+// Unique ID creation requires a high quality random # generator.  In node.js
+// this is pretty straight-forward - we use the crypto API.
 
-  '$type': function (doc, userValue, parsedField, docFieldValue) {
-    return typeMatch(docFieldValue, userValue);
-  }
+var crypto = __webpack_require__(76);
+
+module.exports = function nodeRNG() {
+  return crypto.randomBytes(16);
 };
 
-// return true if the given doc matches the supplied selector
-function matchesSelector(doc, selector) {
-  /* istanbul ignore if */
-  if (typeof selector !== 'object') {
-    // match the CouchDB error message
-    throw new Error('Selector error: expected a JSON object');
-  }
 
-  selector = massageSelector(selector);
-  var row = {
-    'doc': doc
-  };
+/***/ }),
+/* 503 */
+/***/ ((module) => {
 
-  var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector));
-  return rowsMatched && rowsMatched.length === 1;
+/**
+ * Convert array of 16 byte values to UUID string format of the form:
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ */
+var byteToHex = [];
+for (var i = 0; i < 256; ++i) {
+  byteToHex[i] = (i + 0x100).toString(16).substr(1);
 }
 
+function bytesToUuid(buf, offset) {
+  var i = offset || 0;
+  var bth = byteToHex;
+  return bth[buf[i++]] + bth[buf[i++]] +
+          bth[buf[i++]] + bth[buf[i++]] + '-' +
+          bth[buf[i++]] + bth[buf[i++]] + '-' +
+          bth[buf[i++]] + bth[buf[i++]] + '-' +
+          bth[buf[i++]] + bth[buf[i++]] + '-' +
+          bth[buf[i++]] + bth[buf[i++]] +
+          bth[buf[i++]] + bth[buf[i++]] +
+          bth[buf[i++]] + bth[buf[i++]];
+}
 
+module.exports = bytesToUuid;
 
 
 /***/ }),
 /* 504 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "collate": () => (/* binding */ collate),
-/* harmony export */   "normalizeKey": () => (/* binding */ normalizeKey),
-/* harmony export */   "toIndexableString": () => (/* binding */ toIndexableString),
-/* harmony export */   "parseIndexableString": () => (/* binding */ parseIndexableString)
-/* harmony export */ });
-function pad(str, padWith, upToLength) {
-  var padding = '';
-  var targetLength = upToLength - str.length;
-  /* istanbul ignore next */
-  while (padding.length < targetLength) {
-    padding += padWith;
+var rng = __webpack_require__(502);
+var bytesToUuid = __webpack_require__(503);
+
+function v4(options, buf, offset) {
+  var i = buf && offset || 0;
+
+  if (typeof(options) == 'string') {
+    buf = options === 'binary' ? new Array(16) : null;
+    options = null;
   }
-  return padding;
-}
+  options = options || {};
 
-function padLeft(str, padWith, upToLength) {
-  var padding = pad(str, padWith, upToLength);
-  return padding + str;
+  var rnds = options.random || (options.rng || rng)();
+
+  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
+  rnds[6] = (rnds[6] & 0x0f) | 0x40;
+  rnds[8] = (rnds[8] & 0x3f) | 0x80;
+
+  // Copy bytes to buffer, if provided
+  if (buf) {
+    for (var ii = 0; ii < 16; ++ii) {
+      buf[i + ii] = rnds[ii];
+    }
+  }
+
+  return buf || bytesToUuid(rnds);
 }
 
-var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
-var MAGNITUDE_DIGITS = 3; // ditto
-var SEP = ''; // set to '_' for easier debugging 
+module.exports = v4;
 
-function collate(a, b) {
 
-  if (a === b) {
-    return 0;
-  }
+/***/ }),
+/* 505 */
+/***/ ((__unused_webpack_module, exports) => {
 
-  a = normalizeKey(a);
-  b = normalizeKey(b);
+"use strict";
 
-  var ai = collationIndex(a);
-  var bi = collationIndex(b);
-  if ((ai - bi) !== 0) {
-    return ai - bi;
-  }
-  switch (typeof a) {
-    case 'number':
-      return a - b;
-    case 'boolean':
-      return a < b ? -1 : 1;
-    case 'string':
-      return stringCollate(a, b);
-  }
-  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
-}
 
-// couch considers null/NaN/Infinity/-Infinity === undefined,
-// for the purposes of mapreduce indexes. also, dates get stringified.
-function normalizeKey(key) {
-  switch (typeof key) {
-    case 'undefined':
-      return null;
-    case 'number':
-      if (key === Infinity || key === -Infinity || isNaN(key)) {
-        return null;
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+  var queue = [];
+  queue.push({obj: input});
+
+  var res = '';
+  var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+  while ((next = queue.pop())) {
+    obj = next.obj;
+    prefix = next.prefix || '';
+    val = next.val || '';
+    res += prefix;
+    if (val) {
+      res += val;
+    } else if (typeof obj !== 'object') {
+      res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+    } else if (obj === null) {
+      res += 'null';
+    } else if (Array.isArray(obj)) {
+      queue.push({val: ']'});
+      for (i = obj.length - 1; i >= 0; i--) {
+        arrayPrefix = i === 0 ? '' : ',';
+        queue.push({obj: obj[i], prefix: arrayPrefix});
       }
-      return key;
-    case 'object':
-      var origKey = key;
-      if (Array.isArray(key)) {
-        var len = key.length;
-        key = new Array(len);
-        for (var i = 0; i < len; i++) {
-          key[i] = normalizeKey(origKey[i]);
-        }
-      /* istanbul ignore next */
-      } else if (key instanceof Date) {
-        return key.toJSON();
-      } else if (key !== null) { // generic object
-        key = {};
-        for (var k in origKey) {
-          if (origKey.hasOwnProperty(k)) {
-            var val = origKey[k];
-            if (typeof val !== 'undefined') {
-              key[k] = normalizeKey(val);
-            }
-          }
+      queue.push({val: '['});
+    } else { // object
+      keys = [];
+      for (k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          keys.push(k);
         }
       }
-  }
-  return key;
-}
-
-function indexify(key) {
-  if (key !== null) {
-    switch (typeof key) {
-      case 'boolean':
-        return key ? 1 : 0;
-      case 'number':
-        return numToIndexableString(key);
-      case 'string':
-        // We've to be sure that key does not contain \u0000
-        // Do order-preserving replacements:
-        // 0 -> 1, 1
-        // 1 -> 1, 2
-        // 2 -> 2, 2
-        /* eslint-disable no-control-regex */
-        return key
-          .replace(/\u0002/g, '\u0002\u0002')
-          .replace(/\u0001/g, '\u0001\u0002')
-          .replace(/\u0000/g, '\u0001\u0001');
-        /* eslint-enable no-control-regex */
-      case 'object':
-        var isArray = Array.isArray(key);
-        var arr = isArray ? key : Object.keys(key);
-        var i = -1;
-        var len = arr.length;
-        var result = '';
-        if (isArray) {
-          while (++i < len) {
-            result += toIndexableString(arr[i]);
-          }
-        } else {
-          while (++i < len) {
-            var objKey = arr[i];
-            result += toIndexableString(objKey) +
-                toIndexableString(key[objKey]);
-          }
-        }
-        return result;
-    }
-  }
-  return '';
-}
-
-// convert the given key to a string that would be appropriate
-// for lexical sorting, e.g. within a database, where the
-// sorting is the same given by the collate() function.
-function toIndexableString(key) {
-  var zero = '\u0000';
-  key = normalizeKey(key);
-  return collationIndex(key) + SEP + indexify(key) + zero;
-}
-
-function parseNumber(str, i) {
-  var originalIdx = i;
-  var num;
-  var zero = str[i] === '1';
-  if (zero) {
-    num = 0;
-    i++;
-  } else {
-    var neg = str[i] === '0';
-    i++;
-    var numAsString = '';
-    var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
-    var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
-    /* istanbul ignore next */
-    if (neg) {
-      magnitude = -magnitude;
-    }
-    i += MAGNITUDE_DIGITS;
-    while (true) {
-      var ch = str[i];
-      if (ch === '\u0000') {
-        break;
-      } else {
-        numAsString += ch;
+      queue.push({val: '}'});
+      for (i = keys.length - 1; i >= 0; i--) {
+        key = keys[i];
+        value = obj[key];
+        objPrefix = (i > 0 ? ',' : '');
+        objPrefix += JSON.stringify(key) + ':';
+        queue.push({obj: value, prefix: objPrefix});
       }
-      i++;
-    }
-    numAsString = numAsString.split('.');
-    if (numAsString.length === 1) {
-      num = parseInt(numAsString, 10);
-    } else {
-      /* istanbul ignore next */
-      num = parseFloat(numAsString[0] + '.' + numAsString[1]);
-    }
-    /* istanbul ignore next */
-    if (neg) {
-      num = num - 10;
-    }
-    /* istanbul ignore next */
-    if (magnitude !== 0) {
-      // parseFloat is more reliable than pow due to rounding errors
-      // e.g. Number.MAX_VALUE would return Infinity if we did
-      // num * Math.pow(10, magnitude);
-      num = parseFloat(num + 'e' + magnitude);
+      queue.push({val: '{'});
     }
   }
-  return {num: num, length : i - originalIdx};
-}
-
-// move up the stack while parsing
-// this function moved outside of parseIndexableString for performance
-function pop(stack, metaStack) {
-  var obj = stack.pop();
+  return res;
+};
 
-  if (metaStack.length) {
-    var lastMetaElement = metaStack[metaStack.length - 1];
-    if (obj === lastMetaElement.element) {
-      // popping a meta-element, e.g. an object whose value is another object
-      metaStack.pop();
-      lastMetaElement = metaStack[metaStack.length - 1];
-    }
-    var element = lastMetaElement.element;
-    var lastElementIndex = lastMetaElement.index;
-    if (Array.isArray(element)) {
-      element.push(obj);
-    } else if (lastElementIndex === stack.length - 2) { // obj with key+value
-      var key = stack.pop();
-      element[key] = obj;
-    } else {
-      stack.push(obj); // obj with key only
-    }
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+  var lastMetaElement = metaStack[metaStack.length - 1];
+  if (obj === lastMetaElement.element) {
+    // popping a meta-element, e.g. an object whose value is another object
+    metaStack.pop();
+    lastMetaElement = metaStack[metaStack.length - 1];
+  }
+  var element = lastMetaElement.element;
+  var lastElementIndex = lastMetaElement.index;
+  if (Array.isArray(element)) {
+    element.push(obj);
+  } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+    var key = stack.pop();
+    element[key] = obj;
+  } else {
+    stack.push(obj); // obj with key only
   }
 }
 
-function parseIndexableString(str) {
+exports.parse = function (str) {
   var stack = [];
   var metaStack = []; // stack for arrays and objects
   var i = 0;
-
-  /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+  var collationIndex,parsedNum,numChar;
+  var parsedString,lastCh,numConsecutiveSlashes,ch;
+  var arrayElement, objElement;
   while (true) {
-    var collationIndex = str[i++];
-    if (collationIndex === '\u0000') {
+    collationIndex = str[i++];
+    if (collationIndex === '}' ||
+        collationIndex === ']' ||
+        typeof collationIndex === 'undefined') {
       if (stack.length === 1) {
         return stack.pop();
       } else {
-        pop(stack, metaStack);
+        pop(stack.pop(), stack, metaStack);
         continue;
       }
     }
     switch (collationIndex) {
-      case '1':
-        stack.push(null);
+      case ' ':
+      case '\t':
+      case '\n':
+      case ':':
+      case ',':
         break;
-      case '2':
-        stack.push(str[i] === '1');
-        i++;
+      case 'n':
+        i += 3; // 'ull'
+        pop(null, stack, metaStack);
         break;
-      case '3':
-        var parsedNum = parseNumber(str, i);
-        stack.push(parsedNum.num);
-        i += parsedNum.length;
+      case 't':
+        i += 3; // 'rue'
+        pop(true, stack, metaStack);
+        break;
+      case 'f':
+        i += 4; // 'alse'
+        pop(false, stack, metaStack);
         break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
       case '4':
-        var parsedStr = '';
-        /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '-':
+        parsedNum = '';
+        i--;
         while (true) {
-          var ch = str[i];
-          if (ch === '\u0000') {
+          numChar = str[i++];
+          if (/[\d\.\-e\+]/.test(numChar)) {
+            parsedNum += numChar;
+          } else {
+            i--;
             break;
           }
-          parsedStr += ch;
-          i++;
         }
-        // perform the reverse of the order-preserving replacement
-        // algorithm (see above)
-        /* eslint-disable no-control-regex */
-        parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
-          .replace(/\u0001\u0002/g, '\u0001')
-          .replace(/\u0002\u0002/g, '\u0002');
-        /* eslint-enable no-control-regex */
-        stack.push(parsedStr);
+        pop(parseFloat(parsedNum), stack, metaStack);
         break;
-      case '5':
-        var arrayElement = { element: [], index: stack.length };
+      case '"':
+        parsedString = '';
+        lastCh = void 0;
+        numConsecutiveSlashes = 0;
+        while (true) {
+          ch = str[i++];
+          if (ch !== '"' || (lastCh === '\\' &&
+              numConsecutiveSlashes % 2 === 1)) {
+            parsedString += ch;
+            lastCh = ch;
+            if (lastCh === '\\') {
+              numConsecutiveSlashes++;
+            } else {
+              numConsecutiveSlashes = 0;
+            }
+          } else {
+            break;
+          }
+        }
+        pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+        break;
+      case '[':
+        arrayElement = { element: [], index: stack.length };
         stack.push(arrayElement.element);
         metaStack.push(arrayElement);
         break;
-      case '6':
-        var objElement = { element: {}, index: stack.length };
+      case '{':
+        objElement = { element: {}, index: stack.length };
         stack.push(objElement.element);
         metaStack.push(objElement);
         break;
-      /* istanbul ignore next */
       default:
         throw new Error(
-          'bad collationIndex or unexpectedly reached end of input: ' +
-            collationIndex);
+          'unexpectedly reached end of input: ' + collationIndex);
     }
   }
-}
+};
 
-function arrayCollate(a, b) {
-  var len = Math.min(a.length, b.length);
-  for (var i = 0; i < len; i++) {
-    var sort = collate(a[i], b[i]);
-    if (sort !== 0) {
-      return sort;
-    }
+
+/***/ }),
+/* 506 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507);
+/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(510);
+/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(512);
+/* harmony import */ var pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(515);
+/* harmony import */ var pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(517);
+/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(516);
+/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(511);
+
+
+
+
+
+
+
+
+// we restucture the supplied JSON considerably, because the official
+// Mango API is very particular about a lot of this stuff, but we like
+// to be liberal with what we accept in order to prevent mental
+// breakdowns in our users
+function massageCreateIndexRequest(requestDef) {
+  requestDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef);
+
+  if (!requestDef.index) {
+    requestDef.index = {};
   }
-  return (a.length === b.length) ? 0 :
-    (a.length > b.length) ? 1 : -1;
-}
-function stringCollate(a, b) {
-  // See: https://github.com/daleharvey/pouchdb/issues/40
-  // This is incompatible with the CouchDB implementation, but its the
-  // best we can do for now
-  return (a === b) ? 0 : ((a > b) ? 1 : -1);
-}
-function objectCollate(a, b) {
-  var ak = Object.keys(a), bk = Object.keys(b);
-  var len = Math.min(ak.length, bk.length);
-  for (var i = 0; i < len; i++) {
-    // First sort the keys
-    var sort = collate(ak[i], bk[i]);
-    if (sort !== 0) {
-      return sort;
-    }
-    // if the keys are equal sort the values
-    sort = collate(a[ak[i]], b[bk[i]]);
-    if (sort !== 0) {
-      return sort;
+
+  ['type', 'name', 'ddoc'].forEach(function (key) {
+    if (requestDef.index[key]) {
+      requestDef[key] = requestDef.index[key];
+      delete requestDef.index[key];
     }
+  });
+
+  if (requestDef.fields) {
+    requestDef.index.fields = requestDef.fields;
+    delete requestDef.fields;
+  }
 
+  if (!requestDef.type) {
+    requestDef.type = 'json';
   }
-  return (ak.length === bk.length) ? 0 :
-    (ak.length > bk.length) ? 1 : -1;
+  return requestDef;
 }
-// The collation is defined by erlangs ordered terms
-// the atoms null, true, false come first, then numbers, strings,
-// arrays, then objects
-// null/undefined/NaN/Infinity/-Infinity are all considered null
-function collationIndex(x) {
-  var id = ['boolean', 'number', 'string', 'object'];
-  var idx = id.indexOf(typeof x);
-  //false if -1 otherwise true, but fast!!!!1
-  if (~idx) {
-    if (x === null) {
-      return 1;
-    }
-    if (Array.isArray(x)) {
-      return 5;
+
+function dbFetch(db, path, opts, callback) {
+  var status, ok;
+  opts.headers = new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__.Headers({'Content-type': 'application/json'});
+  db.fetch(path, opts).then(function (response) {
+    status = response.status;
+    ok = response.ok;
+    return response.json();
+  }).then(function (json) {
+    if (!ok) {
+      json.status = status;
+      var err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__.generateErrorFromResponse)(json);
+      callback(err);
+    } else {
+      callback(null, json);
     }
-    return idx < 3 ? (idx + 2) : (idx + 3);
-  }
-  /* istanbul ignore next */
-  if (Array.isArray(x)) {
-    return 5;
-  }
+  }).catch(callback);
 }
 
-// conversion:
-// x yyy zz...zz
-// x = 0 for negative, 1 for 0, 2 for positive
-// y = exponent (for negative numbers negated) moved so that it's >= 0
-// z = mantisse
-function numToIndexableString(num) {
+function createIndex(db, requestDef, callback) {
+  requestDef = massageCreateIndexRequest(requestDef);
+  dbFetch(db, '_index', {
+    method: 'POST',
+    body: JSON.stringify(requestDef)
+  }, callback);
+}
 
-  if (num === 0) {
-    return '1';
-  }
+function find(db, requestDef, callback) {
+  dbFetch(db, '_find', {
+    method: 'POST',
+    body: JSON.stringify(requestDef)
+  }, callback);
+}
 
-  // convert number to exponential format for easier and
-  // more succinct string sorting
-  var expFormat = num.toExponential().split(/e\+?/);
-  var magnitude = parseInt(expFormat[1], 10);
+function explain(db, requestDef, callback) {
+  dbFetch(db, '_explain', {
+    method: 'POST',
+    body: JSON.stringify(requestDef)
+  }, callback);
+}
 
-  var neg = num < 0;
+function getIndexes(db, callback) {
+  dbFetch(db, '_index', {
+    method: 'GET'
+  }, callback);
+}
 
-  var result = neg ? '0' : '2';
+function deleteIndex(db, indexDef, callback) {
 
-  // first sort by magnitude
-  // it's easier if all magnitudes are positive
-  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
-  var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
 
-  result += SEP + magString;
+  var ddoc = indexDef.ddoc;
+  var type = indexDef.type || 'json';
+  var name = indexDef.name;
 
-  // then sort by the factor
-  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
-  /* istanbul ignore next */
-  if (neg) { // for negative reverse ordering
-    factor = 10 - factor;
+  if (!ddoc) {
+    return callback(new Error('you must provide an index\'s ddoc'));
   }
 
-  var factorStr = factor.toFixed(20);
+  if (!name) {
+    return callback(new Error('you must provide an index\'s name'));
+  }
 
-  // strip zeros from the end
-  factorStr = factorStr.replace(/\.?0+$/, '');
+  var url = '_index/' + [ddoc, type, name].map(encodeURIComponent).join('/');
 
-  result += SEP + factorStr;
+  dbFetch(db, url, {method: 'DELETE'}, callback);
+}
 
-  return result;
+function getArguments(fun) {
+  return function () {
+    var len = arguments.length;
+    var args = new Array(len);
+    var i = -1;
+    while (++i < len) {
+      args[i] = arguments[i];
+    }
+    return fun.call(this, args);
+  };
+}
+
+function callbackify(fun) {
+  return getArguments(function (args) {
+    var cb = args.pop();
+    var promise = fun.apply(this, args);
+    promisedCallback(promise, cb);
+    return promise;
+  });
+}
+
+function promisedCallback(promise, callback) {
+  promise.then(function (res) {
+    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () {
+      callback(null, res);
+    });
+  }, function (reason) {
+    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () {
+      callback(reason);
+    });
+  });
+  return promise;
+}
+
+var flatten = getArguments(function (args) {
+  var res = [];
+  for (var i = 0, len = args.length; i < len; i++) {
+    var subArr = args[i];
+    if (Array.isArray(subArr)) {
+      res = res.concat(flatten.apply(null, subArr));
+    } else {
+      res.push(subArr);
+    }
+  }
+  return res;
+});
+
+function mergeObjects(arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    res = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)(res, arr[i]);
+  }
+  return res;
 }
 
+// Selects a list of fields defined in dot notation from one doc
+// and copies them to a new doc. Like underscore _.pick but supports nesting.
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(arr[i]);
+    var value = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getFieldFromDoc)(obj, parsedField);
+    if (typeof value !== 'undefined') {
+      (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.setFieldInDoc)(res, parsedField, value);
+    }
+  }
+  return res;
+}
 
+// e.g. ['a'], ['a', 'b'] is true, but ['b'], ['a', 'b'] is false
+function oneArrayIsSubArrayOfOther(left, right) {
 
+  for (var i = 0, len = Math.min(left.length, right.length); i < len; i++) {
+    if (left[i] !== right[i]) {
+      return false;
+    }
+  }
+  return true;
+}
 
-/***/ }),
-/* 505 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+// e.g.['a', 'b', 'c'], ['a', 'b'] is false
+function oneArrayIsStrictSubArrayOfOther(left, right) {
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495);
-/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(499);
-/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(497);
-/* harmony import */ var pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(506);
-/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(504);
-/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(498);
-/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(500);
-/* harmony import */ var pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(508);
+  if (left.length > right.length) {
+    return false;
+  }
 
+  return oneArrayIsSubArrayOfOther(left, right);
+}
 
+// same as above, but treat the left array as an unordered set
+// e.g. ['b', 'a'], ['a', 'b', 'c'] is true, but ['c'], ['a', 'b', 'c'] is false
+function oneSetIsSubArrayOfOther(left, right) {
+  left = left.slice();
+  for (var i = 0, len = right.length; i < len; i++) {
+    var field = right[i];
+    if (!left.length) {
+      break;
+    }
+    var leftIdx = left.indexOf(field);
+    if (leftIdx === -1) {
+      return false;
+    } else {
+      left.splice(leftIdx, 1);
+    }
+  }
+  return true;
+}
 
+function arrayToObject(arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    res[arr[i]] = true;
+  }
+  return res;
+}
 
+function max(arr, fun) {
+  var max = null;
+  var maxScore = -1;
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var element = arr[i];
+    var score = fun(element);
+    if (score > maxScore) {
+      maxScore = score;
+      max = element;
+    }
+  }
+  return max;
+}
 
+function arrayEquals(arr1, arr2) {
+  if (arr1.length !== arr2.length) {
+    return false;
+  }
+  for (var i = 0, len = arr1.length; i < len; i++) {
+    if (arr1[i] !== arr2[i]) {
+      return false;
+    }
+  }
+  return true;
+}
 
+function uniq(arr) {
+  var obj = {};
+  for (var i = 0; i < arr.length; i++) {
+    obj['$' + arr[i]] = true;
+  }
+  return Object.keys(obj).map(function (key) {
+    return key.substring(1);
+  });
+}
 
+//
+// One thing about these mappers:
+//
+// Per the advice of John-David Dalton (http://youtu.be/NthmeLEhDDM),
+// what you want to do in this case is optimize for the smallest possible
+// function, since that's the thing that gets run over and over again.
+//
+// This code would be a lot simpler if all the if/elses were inside
+// the function, but it would also be a lot less performant.
+//
 
 
-/*
- * Simple task queue to sequentialize actions. Assumes
- * callbacks will eventually fire (once).
- */
+function createDeepMultiMapper(fields, emit) {
+  return function (doc) {
+    var toEmit = [];
+    for (var i = 0, iLen = fields.length; i < iLen; i++) {
+      var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(fields[i]);
+      var value = doc;
+      for (var j = 0, jLen = parsedField.length; j < jLen; j++) {
+        var key = parsedField[j];
+        value = value[key];
+        if (typeof value === 'undefined') {
+          return; // don't emit
+        }
+      }
+      toEmit.push(value);
+    }
+    emit(toEmit);
+  };
+}
 
+function createDeepSingleMapper(field, emit) {
+  var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(field);
+  return function (doc) {
+    var value = doc;
+    for (var i = 0, len = parsedField.length; i < len; i++) {
+      var key = parsedField[i];
+      value = value[key];
+      if (typeof value === 'undefined') {
+        return; // do nothing
+      }
+    }
+    emit(value);
+  };
+}
 
-function TaskQueue() {
-  this.promise = new Promise(function (fulfill) {fulfill(); });
+function createShallowSingleMapper(field, emit) {
+  return function (doc) {
+    emit(doc[field]);
+  };
 }
-TaskQueue.prototype.add = function (promiseFactory) {
-  this.promise = this.promise.catch(function () {
-    // just recover
-  }).then(function () {
-    return promiseFactory();
-  });
-  return this.promise;
-};
-TaskQueue.prototype.finish = function () {
-  return this.promise;
-};
 
-function stringify(input) {
-  if (!input) {
-    return 'undefined'; // backwards compat for empty reduce
+function createShallowMultiMapper(fields, emit) {
+  return function (doc) {
+    var toEmit = [];
+    for (var i = 0, len = fields.length; i < len; i++) {
+      toEmit.push(doc[fields[i]]);
+    }
+    emit(toEmit);
+  };
+}
+
+function checkShallow(fields) {
+  for (var i = 0, len = fields.length; i < len; i++) {
+    var field = fields[i];
+    if (field.indexOf('.') !== -1) {
+      return false;
+    }
   }
-  // for backwards compat with mapreduce, functions/strings are stringified
-  // as-is. everything else is JSON-stringified.
-  switch (typeof input) {
-    case 'function':
-      // e.g. a mapreduce map
-      return input.toString();
-    case 'string':
-      // e.g. a mapreduce built-in _reduce function
-      return input.toString();
-    default:
-      // e.g. a JSON object in the case of mango queries
-      return JSON.stringify(input);
+  return true;
+}
+
+function createMapper(fields, emit) {
+  var isShallow = checkShallow(fields);
+  var isSingle = fields.length === 1;
+
+  // notice we try to optimize for the most common case,
+  // i.e. single shallow indexes
+  if (isShallow) {
+    if (isSingle) {
+      return createShallowSingleMapper(fields[0], emit);
+    } else { // multi
+      return createShallowMultiMapper(fields, emit);
+    }
+  } else { // deep
+    if (isSingle) {
+      return createDeepSingleMapper(fields[0], emit);
+    } else { // multi
+      return createDeepMultiMapper(fields, emit);
+    }
   }
 }
 
-/* create a string signature for a view so we can cache it and uniq it */
-function createViewSignature(mapFun, reduceFun) {
-  // the "undefined" part is for backwards compatibility
-  return stringify(mapFun) + stringify(reduceFun) + 'undefined';
+function mapper(mapFunDef, emit) {
+  // mapFunDef is a list of fields
+
+  var fields = Object.keys(mapFunDef.fields);
+
+  return createMapper(fields, emit);
 }
 
-function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) {
-  var viewSignature = createViewSignature(mapFun, reduceFun);
+/* istanbul ignore next */
+function reducer(/*reduceFunDef*/) {
+  throw new Error('reduce not supported');
+}
 
-  var cachedViews;
-  if (!temporary) {
-    // cache this to ensure we don't try to update the same view twice
-    cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {};
-    if (cachedViews[viewSignature]) {
-      return cachedViews[viewSignature];
-    }
+function ddocValidator(ddoc, viewName) {
+  var view = ddoc.views[viewName];
+  // This doesn't actually need to be here apparently, but
+  // I feel safer keeping it.
+  /* istanbul ignore if */
+  if (!view.map || !view.map.fields) {
+    throw new Error('ddoc ' + ddoc._id +' with view ' + viewName +
+      ' doesn\'t have map.fields defined. ' +
+      'maybe it wasn\'t created by this plugin?');
   }
+}
 
-  var promiseForView = sourceDB.info().then(function (info) {
+var abstractMapper = (0,pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__["default"])(
+  /* localDocName */ 'indexes',
+  mapper,
+  reducer,
+  ddocValidator
+);
 
-    var depDbName = info.db_name + '-mrview-' +
-      (temporary ? 'temp' : (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__.stringMd5)(viewSignature));
+// normalize the "sort" value
+function massageSort(sort) {
+  if (!Array.isArray(sort)) {
+    throw new Error('invalid sort json - should be an array');
+  }
+  return sort.map(function (sorting) {
+    if (typeof sorting === 'string') {
+      var obj = {};
+      obj[sorting] = 'asc';
+      return obj;
+    } else {
+      return sorting;
+    }
+  });
+}
 
-    // save the view name in the source db so it can be cleaned up if necessary
-    // (e.g. when the _design doc is deleted, remove all associated view data)
-    function diffFunction(doc) {
-      doc.views = doc.views || {};
-      var fullViewName = viewName;
-      if (fullViewName.indexOf('/') === -1) {
-        fullViewName = viewName + '/' + viewName;
-      }
-      var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
-      /* istanbul ignore if */
-      if (depDbs[depDbName]) {
-        return; // no update necessary
-      }
-      depDbs[depDbName] = true;
-      return doc;
+function massageUseIndex(useIndex) {
+  var cleanedUseIndex = [];
+  if (typeof useIndex === 'string') {
+    cleanedUseIndex.push(useIndex);
+  } else {
+    cleanedUseIndex = useIndex;
+  }
+
+  return cleanedUseIndex.map(function (name) {
+    return name.replace('_design/', '');
+  });
+}
+
+function massageIndexDef(indexDef) {
+  indexDef.fields = indexDef.fields.map(function (field) {
+    if (typeof field === 'string') {
+      var obj = {};
+      obj[field] = 'asc';
+      return obj;
     }
-    return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(sourceDB, '_local/' + localDocName, diffFunction).then(function () {
-      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
-        var db = res.db;
-        db.auto_compaction = true;
-        var view = {
-          name: depDbName,
-          db: db,
-          sourceDB: sourceDB,
-          adapter: sourceDB.adapter,
-          mapFun: mapFun,
-          reduceFun: reduceFun
-        };
-        return view.db.get('_local/lastSeq').catch(function (err) {
-          /* istanbul ignore if */
-          if (err.status !== 404) {
-            throw err;
-          }
-        }).then(function (lastSeqDoc) {
-          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
-          if (cachedViews) {
-            view.db.once('destroyed', function () {
-              delete cachedViews[viewSignature];
-            });
-          }
-          return view;
-        });
-      });
-    });
+    return field;
   });
+  return indexDef;
+}
 
-  if (cachedViews) {
-    cachedViews[viewSignature] = promiseForView;
+function getKeyFromDoc(doc, index) {
+  var res = [];
+  for (var i = 0; i < index.def.fields.length; i++) {
+    var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[i]);
+    res.push(doc[field]);
   }
-  return promiseForView;
+  return res;
 }
 
-var persistentQueues = {};
-var tempViewQueue = new TaskQueue();
-var CHANGES_BATCH_SIZE = 50;
+// have to do this manually because REASONS. I don't know why
+// CouchDB didn't implement inclusive_start
+function filterInclusiveStart(rows, targetValue, index) {
+  var indexFields = index.def.fields;
+  for (var i = 0, len = rows.length; i < len; i++) {
+    var row = rows[i];
 
-function parseViewName(name) {
-  // can be either 'ddocname/viewname' or just 'viewname'
-  // (where the ddoc name is the same)
-  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+    // shave off any docs at the beginning that are <= the
+    // target value
+
+    var docKey = getKeyFromDoc(row.doc, index);
+    if (indexFields.length === 1) {
+      docKey = docKey[0]; // only one field, not multi-field
+    } else { // more than one field in index
+      // in the case where e.g. the user is searching {$gt: {a: 1}}
+      // but the index is [a, b], then we need to shorten the doc key
+      while (docKey.length > targetValue.length) {
+        docKey.pop();
+      }
+    }
+    //ABS as we just looking for values that don't match
+    if (Math.abs((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(docKey, targetValue)) > 0) {
+      // no need to filter any further; we're past the key
+      break;
+    }
+  }
+  return i > 0 ? rows.slice(i) : rows;
 }
 
-function isGenOne(changes) {
-  // only return true if the current change is 1-
-  // and there are no other leafs
-  return changes.length === 1 && /^1-/.test(changes[0].rev);
+function reverseOptions(opts) {
+  var newOpts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(opts);
+  delete newOpts.startkey;
+  delete newOpts.endkey;
+  delete newOpts.inclusive_start;
+  delete newOpts.inclusive_end;
+
+  if ('endkey' in opts) {
+    newOpts.startkey = opts.endkey;
+  }
+  if ('startkey' in opts) {
+    newOpts.endkey = opts.startkey;
+  }
+  if ('inclusive_start' in opts) {
+    newOpts.inclusive_end = opts.inclusive_start;
+  }
+  if ('inclusive_end' in opts) {
+    newOpts.inclusive_start = opts.inclusive_end;
+  }
+  return newOpts;
 }
 
-function emitError(db, e) {
-  try {
-    db.emit('error', e);
-  } catch (err) {
-    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error',
-      'The user\'s map/reduce function threw an uncaught error.\n' +
-      'You can debug this error by doing:\n' +
-      'myDatabase.on(\'error\', function (err) { debugger; });\n' +
-      'Please double-check your map/reduce function.');
-    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error', e);
+function validateIndex(index) {
+  var ascFields = index.fields.filter(function (field) {
+    return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(field) === 'asc';
+  });
+  if (ascFields.length !== 0 && ascFields.length !== index.fields.length) {
+    throw new Error('unsupported mixed sorting');
   }
 }
 
-/**
- * Returns an "abstract" mapreduce object of the form:
- *
- *   {
- *     query: queryFun,
- *     viewCleanup: viewCleanupFun
- *   }
- *
- * Arguments are:
- *
- * localDoc: string
- *   This is for the local doc that gets saved in order to track the
- *   "dependent" DBs and clean them up for viewCleanup. It should be
- *   unique, so that indexer plugins don't collide with each other.
- * mapper: function (mapFunDef, emit)
- *   Returns a map function based on the mapFunDef, which in the case of
- *   normal map/reduce is just the de-stringified function, but may be
- *   something else, such as an object in the case of pouchdb-find.
- * reducer: function (reduceFunDef)
- *   Ditto, but for reducing. Modules don't have to support reducing
- *   (e.g. pouchdb-find).
- * ddocValidator: function (ddoc, viewName)
- *   Throws an error if the ddoc or viewName is not valid.
- *   This could be a way to communicate to the user that the configuration for the
- *   indexer is invalid.
- */
-function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) {
+function validateSort(requestDef, index) {
+  if (index.defaultUsed && requestDef.sort) {
+    var noneIdSorts = requestDef.sort.filter(function (sortItem) {
+      return Object.keys(sortItem)[0] !== '_id';
+    }).map(function (sortItem) {
+      return Object.keys(sortItem)[0];
+    });
 
-  function tryMap(db, fun, doc) {
-    // emit an event if there was an error thrown by a map function.
-    // putting try/catches in a single function also avoids deoptimizations.
-    try {
-      fun(doc);
-    } catch (e) {
-      emitError(db, e);
+    if (noneIdSorts.length > 0) {
+      throw new Error('Cannot sort on field(s) "' + noneIdSorts.join(',') +
+      '" when using the default index');
     }
   }
 
-  function tryReduce(db, fun, keys, values, rereduce) {
-    // same as above, but returning the result or an error. there are two separate
-    // functions to avoid extra memory allocations since the tryCode() case is used
-    // for custom map functions (common) vs this function, which is only used for
-    // custom reduce functions (rare)
-    try {
-      return {output : fun(keys, values, rereduce)};
-    } catch (e) {
-      emitError(db, e);
-      return {error: e};
-    }
+  if (index.defaultUsed) {
+    return;
   }
+}
 
-  function sortByKeyThenValue(x, y) {
-    var keyCompare = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.key, y.key);
-    return keyCompare !== 0 ? keyCompare : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.value, y.value);
+function validateFindRequest(requestDef) {
+  if (typeof requestDef.selector !== 'object') {
+    throw new Error('you must provide a selector when you find()');
   }
 
-  function sliceResults(results, limit, skip) {
-    skip = skip || 0;
-    if (typeof limit === 'number') {
-      return results.slice(skip, limit + skip);
-    } else if (skip > 0) {
-      return results.slice(skip);
+  /*var selectors = requestDef.selector['$and'] || [requestDef.selector];
+  for (var i = 0; i < selectors.length; i++) {
+    var selector = selectors[i];
+    var keys = Object.keys(selector);
+    if (keys.length === 0) {
+      throw new Error('invalid empty selector');
     }
-    return results;
+    //var selection = selector[keys[0]];
+    /*if (Object.keys(selection).length !== 1) {
+      throw new Error('invalid selector: ' + JSON.stringify(selection) +
+        ' - it must have exactly one key/value');
+    }
+  }*/
+}
+
+// determine the maximum number of fields
+// we're going to need to query, e.g. if the user
+// has selection ['a'] and sorting ['a', 'b'], then we
+// need to use the longer of the two: ['a', 'b']
+function getUserFields(selector, sort) {
+  var selectorFields = Object.keys(selector);
+  var sortFields = sort? sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey) : [];
+  var userFields;
+  if (selectorFields.length >= sortFields.length) {
+    userFields = selectorFields;
+  } else {
+    userFields = sortFields;
   }
 
-  function rowToDocId(row) {
-    var val = row.value;
-    // Users can explicitly specify a joined doc _id, or it
-    // defaults to the doc _id that emitted the key/value.
-    var docId = (val && typeof val === 'object' && val._id) || row.id;
-    return docId;
+  if (sortFields.length === 0) {
+    return {
+      fields: userFields
+    };
   }
 
-  function readAttachmentsAsBlobOrBuffer(res) {
-    res.rows.forEach(function (row) {
-      var atts = row.doc && row.doc._attachments;
-      if (!atts) {
-        return;
-      }
-      Object.keys(atts).forEach(function (filename) {
-        var att = atts[filename];
-        atts[filename].data = (0,pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__.base64StringToBlobOrBuffer)(att.data, att.content_type);
-      });
-    });
+  // sort according to the user's preferred sorting
+  userFields = userFields.sort(function (left, right) {
+    var leftIdx = sortFields.indexOf(left);
+    if (leftIdx === -1) {
+      leftIdx = Number.MAX_VALUE;
+    }
+    var rightIdx = sortFields.indexOf(right);
+    if (rightIdx === -1) {
+      rightIdx = Number.MAX_VALUE;
+    }
+    return leftIdx < rightIdx ? -1 : leftIdx > rightIdx ? 1 : 0;
+  });
+
+  return {
+    fields: userFields,
+    sortOrder: sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)
+  };
+}
+
+function createIndex$1(db, requestDef) {
+  requestDef = massageCreateIndexRequest(requestDef);
+  var originalIndexDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef.index);
+  requestDef.index = massageIndexDef(requestDef.index);
+
+  validateIndex(requestDef.index);
+
+  // calculating md5 is expensive - memoize and only
+  // run if required
+  var md5;
+  function getMd5() {
+    return md5 || (md5 = (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__.stringMd5)(JSON.stringify(requestDef)));
   }
 
-  function postprocessAttachments(opts) {
-    return function (res) {
-      if (opts.include_docs && opts.attachments && opts.binary) {
-        readAttachmentsAsBlobOrBuffer(res);
+  var viewName = requestDef.name || ('idx-' + getMd5());
+
+  var ddocName = requestDef.ddoc || ('idx-' + getMd5());
+  var ddocId = '_design/' + ddocName;
+
+  var hasInvalidLanguage = false;
+  var viewExists = false;
+
+  function updateDdoc(doc) {
+    if (doc._rev && doc.language !== 'query') {
+      hasInvalidLanguage = true;
+    }
+    doc.language = 'query';
+    doc.views = doc.views || {};
+
+    viewExists = !!doc.views[viewName];
+
+    if (viewExists) {
+      return false;
+    }
+
+    doc.views[viewName] = {
+      map: {
+        fields: mergeObjects(requestDef.index.fields)
+      },
+      reduce: '_count',
+      options: {
+        def: originalIndexDef
       }
-      return res;
     };
+
+    return doc;
   }
 
-  function addHttpParam(paramName, opts, params, asJson) {
-    // add an http param from opts to params, optionally json-encoded
-    var val = opts[paramName];
-    if (typeof val !== 'undefined') {
-      if (asJson) {
-        val = encodeURIComponent(JSON.stringify(val));
-      }
-      params.push(paramName + '=' + val);
+  db.constructor.emit('debug', ['find', 'creating index', ddocId]);
+
+  return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, ddocId, updateDdoc).then(function () {
+    if (hasInvalidLanguage) {
+      throw new Error('invalid language for ddoc with id "' +
+      ddocId +
+      '" (should be "query")');
     }
-  }
+  }).then(function () {
+    // kick off a build
+    // TODO: abstract-pouchdb-mapreduce should support auto-updating
+    // TODO: should also use update_after, but pouchdb/pouchdb#3415 blocks me
+    var signature = ddocName + '/' + viewName;
+    return abstractMapper.query.call(db, signature, {
+      limit: 0,
+      reduce: false
+    }).then(function () {
+      return {
+        id: ddocId,
+        name: viewName,
+        result: viewExists ? 'exists' : 'created'
+      };
+    });
+  });
+}
+
+function getIndexes$1(db) {
+  // just search through all the design docs and filter in-memory.
+  // hopefully there aren't that many ddocs.
+  return db.allDocs({
+    startkey: '_design/',
+    endkey: '_design/\uffff',
+    include_docs: true
+  }).then(function (allDocsRes) {
+    var res = {
+      indexes: [{
+        ddoc: null,
+        name: '_all_docs',
+        type: 'special',
+        def: {
+          fields: [{_id: 'asc'}]
+        }
+      }]
+    };
+
+    res.indexes = flatten(res.indexes, allDocsRes.rows.filter(function (row) {
+      return row.doc.language === 'query';
+    }).map(function (row) {
+      var viewNames = row.doc.views !== undefined ? Object.keys(row.doc.views) : [];
+
+      return viewNames.map(function (viewName) {
+        var view = row.doc.views[viewName];
+        return {
+          ddoc: row.id,
+          name: viewName,
+          type: 'json',
+          def: massageIndexDef(view.options.def)
+        };
+      });
+    }));
+
+    // these are sorted by view name for some reason
+    res.indexes.sort(function (left, right) {
+      return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(left.name, right.name);
+    });
+    res.total_rows = res.indexes.length;
+    return res;
+  });
+}
+
+// couchdb lowest collation value
+var COLLATE_LO = null;
 
-  function coerceInteger(integerCandidate) {
-    if (typeof integerCandidate !== 'undefined') {
-      var asNumber = Number(integerCandidate);
-      // prevents e.g. '1foo' or '1.1' being coerced to 1
-      if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
-        return asNumber;
-      } else {
-        return integerCandidate;
-      }
-    }
-  }
+// couchdb highest collation value (TODO: well not really, but close enough amirite)
+var COLLATE_HI = {"\uffff": {}};
 
-  function coerceOptions(opts) {
-    opts.group_level = coerceInteger(opts.group_level);
-    opts.limit = coerceInteger(opts.limit);
-    opts.skip = coerceInteger(opts.skip);
-    return opts;
-  }
+// couchdb second-lowest collation value
 
-  function checkPositiveInteger(number) {
-    if (number) {
-      if (typeof number !== 'number') {
-        return  new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for integer: "' +
-          number + '"');
-      }
-      if (number < 0) {
-        return new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for positive integer: ' +
-          '"' + number + '"');
-      }
+function checkFieldInIndex(index, field) {
+  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
+  for (var i = 0, len = indexFields.length; i < len; i++) {
+    var indexField = indexFields[i];
+    if (field === indexField) {
+      return true;
     }
   }
+  return false;
+}
 
-  function checkQueryParseError(options, fun) {
-    var startkeyName = options.descending ? 'endkey' : 'startkey';
-    var endkeyName = options.descending ? 'startkey' : 'endkey';
+// so when you do e.g. $eq/$eq, we can do it entirely in the database.
+// but when you do e.g. $gt/$eq, the first part can be done
+// in the database, but the second part has to be done in-memory,
+// because $gt has forced us to lose precision.
+// so that's what this determines
+function userOperatorLosesPrecision(selector, field) {
+  var matcher = selector[field];
+  var userOperator = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher);
 
-    if (typeof options[startkeyName] !== 'undefined' &&
-      typeof options[endkeyName] !== 'undefined' &&
-      (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(options[startkeyName], options[endkeyName]) > 0) {
-      throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('No rows can match your key range, ' +
-        'reverse your start_key and end_key or set {descending : true}');
-    } else if (fun.reduce && options.reduce !== false) {
-      if (options.include_docs) {
-        throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('{include_docs:true} is invalid for reduce');
-      } else if (options.keys && options.keys.length > 1 &&
-        !options.group && !options.group_level) {
-        throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Multi-key fetches for reduce views must use ' +
-          '{group: true}');
-      }
-    }
-    ['group_level', 'limit', 'skip'].forEach(function (optionName) {
-      var error = checkPositiveInteger(options[optionName]);
-      if (error) {
-        throw error;
-      }
-    });
-  }
+  return userOperator !== '$eq';
+}
 
-  function httpQuery(db, fun, opts) {
-    // List of parameters to add to the PUT request
-    var params = [];
-    var body;
-    var method = 'GET';
-    var ok, status;
+// sort the user fields by their position in the index,
+// if they're in the index
+function sortFieldsByIndex(userFields, index) {
+  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
 
-    // If opts.reduce exists and is defined, then add it to the list
-    // of parameters.
-    // If reduce=false then the results are that of only the map function
-    // not the final result of map and reduce.
-    addHttpParam('reduce', opts, params);
-    addHttpParam('include_docs', opts, params);
-    addHttpParam('attachments', opts, params);
-    addHttpParam('limit', opts, params);
-    addHttpParam('descending', opts, params);
-    addHttpParam('group', opts, params);
-    addHttpParam('group_level', opts, params);
-    addHttpParam('skip', opts, params);
-    addHttpParam('stale', opts, params);
-    addHttpParam('conflicts', opts, params);
-    addHttpParam('startkey', opts, params, true);
-    addHttpParam('start_key', opts, params, true);
-    addHttpParam('endkey', opts, params, true);
-    addHttpParam('end_key', opts, params, true);
-    addHttpParam('inclusive_end', opts, params);
-    addHttpParam('key', opts, params, true);
-    addHttpParam('update_seq', opts, params);
+  return userFields.slice().sort(function (a, b) {
+    var aIdx = indexFields.indexOf(a);
+    var bIdx = indexFields.indexOf(b);
+    if (aIdx === -1) {
+      aIdx = Number.MAX_VALUE;
+    }
+    if (bIdx === -1) {
+      bIdx = Number.MAX_VALUE;
+    }
+    return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(aIdx, bIdx);
+  });
+}
 
-    // Format the list of parameters into a valid URI query string
-    params = params.join('&');
-    params = params === '' ? '' : '?' + params;
+// first pass to try to find fields that will need to be sorted in-memory
+function getBasicInMemoryFields(index, selector, userFields) {
 
-    // If keys are supplied, issue a POST to circumvent GET query string limits
-    // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
-    if (typeof opts.keys !== 'undefined') {
-      var MAX_URL_LENGTH = 2000;
-      // according to http://stackoverflow.com/a/417184/680742,
-      // the de facto URL length limit is 2000 characters
+  userFields = sortFieldsByIndex(userFields, index);
 
-      var keysAsString =
-        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
-      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
-        // If the keys are short enough, do a GET. we do this to work around
-        // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
-        params += (params[0] === '?' ? '&' : '?') + keysAsString;
-      } else {
-        method = 'POST';
-        if (typeof fun === 'string') {
-          body = {keys: opts.keys};
-        } else { // fun is {map : mapfun}, so append to this
-          fun.keys = opts.keys;
-        }
-      }
+  // check if any of the user selectors lose precision
+  var needToFilterInMemory = false;
+  for (var i = 0, len = userFields.length; i < len; i++) {
+    var field = userFields[i];
+    if (needToFilterInMemory || !checkFieldInIndex(index, field)) {
+      return userFields.slice(i);
     }
-
-    // We are referencing a query defined in the design doc
-    if (typeof fun === 'string') {
-      var parts = parseViewName(fun);
-      return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
-        headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}),
-        method: method,
-        body: JSON.stringify(body)
-      }).then(function (response) {
-        ok = response.ok;
-        status = response.status;
-        return response.json();
-      }).then(function (result) {
-        if (!ok) {
-          result.status = status;
-          throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result);
-        }
-        // fail the entire request if the result contains an error
-        result.rows.forEach(function (row) {
-          /* istanbul ignore if */
-          if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
-            throw new Error(row.reason);
-          }
-        });
-        return result;
-      }).then(postprocessAttachments(opts));
+    if (i < len - 1 && userOperatorLosesPrecision(selector, field)) {
+      needToFilterInMemory = true;
     }
+  }
+  return [];
+}
 
-    // We are using a temporary view, terrible for performance, good for testing
-    body = body || {};
-    Object.keys(fun).forEach(function (key) {
-      if (Array.isArray(fun[key])) {
-        body[key] = fun[key];
-      } else {
-        body[key] = fun[key].toString();
+function getInMemoryFieldsFromNe(selector) {
+  var fields = [];
+  Object.keys(selector).forEach(function (field) {
+    var matcher = selector[field];
+    Object.keys(matcher).forEach(function (operator) {
+      if (operator === '$ne') {
+        fields.push(field);
       }
     });
+  });
+  return fields;
+}
 
-    return db.fetch('_temp_view' + params, {
-      headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}),
-      method: 'POST',
-      body: JSON.stringify(body)
-    }).then(function (response) {
-        ok = response.ok;
-        status = response.status;
-      return response.json();
-    }).then(function (result) {
-      if (!ok) {
-        result.status = status;
-        throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result);
-      }
-      return result;
-    }).then(postprocessAttachments(opts));
-  }
+function getInMemoryFields(coreInMemoryFields, index, selector, userFields) {
+  var result = flatten(
+    // in-memory fields reported as necessary by the query planner
+    coreInMemoryFields,
+    // combine with another pass that checks for any we may have missed
+    getBasicInMemoryFields(index, selector, userFields),
+    // combine with another pass that checks for $ne's
+    getInMemoryFieldsFromNe(selector)
+  );
 
-  // custom adapters can define their own api._query
-  // and override the default behavior
-  /* istanbul ignore next */
-  function customQuery(db, fun, opts) {
-    return new Promise(function (resolve, reject) {
-      db._query(fun, opts, function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        resolve(res);
-      });
-    });
+  return sortFieldsByIndex(uniq(result), index);
+}
+
+// check that at least one field in the user's query is represented
+// in the index. order matters in the case of sorts
+function checkIndexFieldsMatch(indexFields, sortOrder, fields) {
+  if (sortOrder) {
+    // array has to be a strict subarray of index array. furthermore,
+    // the sortOrder fields need to all be represented in the index
+    var sortMatches = oneArrayIsStrictSubArrayOfOther(sortOrder, indexFields);
+    var selectorMatches = oneArrayIsSubArrayOfOther(fields, indexFields);
+
+    return sortMatches && selectorMatches;
   }
 
-  // custom adapters can define their own api._viewCleanup
-  // and override the default behavior
-  /* istanbul ignore next */
-  function customViewCleanup(db) {
-    return new Promise(function (resolve, reject) {
-      db._viewCleanup(function (err, res) {
-        if (err) {
-          return reject(err);
-        }
-        resolve(res);
-      });
-    });
+  // all of the user's specified fields still need to be
+  // on the left side of the index array, although the order
+  // doesn't matter
+  return oneSetIsSubArrayOfOther(fields, indexFields);
+}
+
+var logicalMatchers = ['$eq', '$gt', '$gte', '$lt', '$lte'];
+function isNonLogicalMatcher(matcher) {
+  return logicalMatchers.indexOf(matcher) === -1;
+}
+
+// check all the index fields for usages of '$ne'
+// e.g. if the user queries {foo: {$ne: 'foo'}, bar: {$eq: 'bar'}},
+// then we can neither use an index on ['foo'] nor an index on
+// ['foo', 'bar'], but we can use an index on ['bar'] or ['bar', 'foo']
+function checkFieldsLogicallySound(indexFields, selector) {
+  var firstField = indexFields[0];
+  var matcher = selector[firstField];
+
+  if (typeof matcher === 'undefined') {
+    /* istanbul ignore next */
+    return true;
   }
 
-  function defaultsTo(value) {
-    return function (reason) {
-      /* istanbul ignore else */
-      if (reason.status === 404) {
-        return value;
-      } else {
-        throw reason;
-      }
-    };
+  var hasLogicalOperator = Object.keys(matcher).some(function (matcherKey) {
+    return !(isNonLogicalMatcher(matcherKey));
+  });
+
+  if (!hasLogicalOperator) {
+    return false;
   }
 
-  // returns a promise for a list of docs to update, based on the input docId.
-  // the order doesn't matter, because post-3.2.0, bulkDocs
-  // is an atomic operation in all three adapters.
-  function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
-    var metaDocId = '_local/doc_' + docId;
-    var defaultMetaDoc = {_id: metaDocId, keys: []};
-    var docData = docIdsToChangesAndEmits.get(docId);
-    var indexableKeysToKeyValues = docData[0];
-    var changes = docData[1];
+  var isInvalidNe = Object.keys(matcher).length === 1 &&
+    (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher) === '$ne';
 
-    function getMetaDoc() {
-      if (isGenOne(changes)) {
-        // generation 1, so we can safely assume initial state
-        // for performance reasons (avoids unnecessary GETs)
-        return Promise.resolve(defaultMetaDoc);
-      }
-      return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc));
-    }
+  return !isInvalidNe;
+}
 
-    function getKeyValueDocs(metaDoc) {
-      if (!metaDoc.keys.length) {
-        // no keys, no need for a lookup
-        return Promise.resolve({rows: []});
-      }
-      return view.db.allDocs({
-        keys: metaDoc.keys,
-        include_docs: true
-      });
-    }
+function checkIndexMatches(index, sortOrder, fields, selector) {
 
-    function processKeyValueDocs(metaDoc, kvDocsRes) {
-      var kvDocs = [];
-      var oldKeys = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set();
+  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
 
-      for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
-        var row = kvDocsRes.rows[i];
-        var doc = row.doc;
-        if (!doc) { // deleted
-          continue;
-        }
-        kvDocs.push(doc);
-        oldKeys.add(doc._id);
-        doc._deleted = !indexableKeysToKeyValues.has(doc._id);
-        if (!doc._deleted) {
-          var keyValue = indexableKeysToKeyValues.get(doc._id);
-          if ('value' in keyValue) {
-            doc.value = keyValue.value;
-          }
-        }
-      }
-      var newKeys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(indexableKeysToKeyValues);
-      newKeys.forEach(function (key) {
-        if (!oldKeys.has(key)) {
-          // new doc
-          var kvDoc = {
-            _id: key
-          };
-          var keyValue = indexableKeysToKeyValues.get(key);
-          if ('value' in keyValue) {
-            kvDoc.value = keyValue.value;
-          }
-          kvDocs.push(kvDoc);
-        }
-      });
-      metaDoc.keys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(newKeys.concat(metaDoc.keys));
-      kvDocs.push(metaDoc);
+  var fieldsMatch = checkIndexFieldsMatch(indexFields, sortOrder, fields);
 
-      return kvDocs;
+  if (!fieldsMatch) {
+    return false;
+  }
+
+  return checkFieldsLogicallySound(indexFields, selector);
+}
+
+//
+// the algorithm is very simple:
+// take all the fields the user supplies, and if those fields
+// are a strict subset of the fields in some index,
+// then use that index
+//
+//
+function findMatchingIndexes(selector, userFields, sortOrder, indexes) {
+
+  return indexes.reduce(function (res, index) {
+    var indexMatches = checkIndexMatches(index, sortOrder, userFields, selector);
+    if (indexMatches) {
+      res.push(index);
     }
+    return res;
+  }, []);
+}
 
-    return getMetaDoc().then(function (metaDoc) {
-      return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
-        return processKeyValueDocs(metaDoc, kvDocsRes);
-      });
-    });
-  }
+// find the best index, i.e. the one that matches the most fields
+// in the user's query
+function findBestMatchingIndex(selector, userFields, sortOrder, indexes, useIndex) {
 
-  // updates all emitted key/value docs and metaDocs in the mrview database
-  // for the given batch of documents from the source database
-  function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
-    var seqDocId = '_local/lastSeq';
-    return view.db.get(seqDocId)
-      .catch(defaultsTo({_id: seqDocId, seq: 0}))
-      .then(function (lastSeqDoc) {
-        var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docIdsToChangesAndEmits);
-        return Promise.all(docIds.map(function (docId) {
-          return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
-        })).then(function (listOfDocsToPersist) {
-          var docsToPersist = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten)(listOfDocsToPersist);
-          lastSeqDoc.seq = seq;
-          docsToPersist.push(lastSeqDoc);
-          // write all docs in a single operation, update the seq once
-          return view.db.bulkDocs({docs : docsToPersist});
-        });
-      });
-  }
+  var matchingIndexes = findMatchingIndexes(selector, userFields, sortOrder, indexes);
 
-  function getQueue(view) {
-    var viewName = typeof view === 'string' ? view : view.name;
-    var queue = persistentQueues[viewName];
-    if (!queue) {
-      queue = persistentQueues[viewName] = new TaskQueue();
+  if (matchingIndexes.length === 0) {
+    if (useIndex) {
+      throw {
+        error: "no_usable_index",
+        message: "There is no index available for this selector."
+      };
     }
-    return queue;
+    //return `all_docs` as a default index;
+    //I'm assuming that _all_docs is always first
+    var defaultIndex = indexes[0];
+    defaultIndex.defaultUsed = true;
+    return defaultIndex;
   }
-
-  function updateView(view) {
-    return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () {
-      return updateViewInQueue(view);
-    })();
+  if (matchingIndexes.length === 1 && !useIndex) {
+    return matchingIndexes[0];
   }
 
-  function updateViewInQueue(view) {
-    // bind the emit function once
-    var mapResults;
-    var doc;
+  var userFieldsMap = arrayToObject(userFields);
 
-    function emit(key, value) {
-      var output = {id: doc._id, key: (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(key)};
-      // Don't explicitly store the value unless it's defined and non-null.
-      // This saves on storage space, because often people don't use it.
-      if (typeof value !== 'undefined' && value !== null) {
-        output.value = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(value);
+  function scoreIndex(index) {
+    var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
+    var score = 0;
+    for (var i = 0, len = indexFields.length; i < len; i++) {
+      var indexField = indexFields[i];
+      if (userFieldsMap[indexField]) {
+        score++;
       }
-      mapResults.push(output);
     }
+    return score;
+  }
 
-    var mapFun = mapper(view.mapFun, emit);
+  if (useIndex) {
+    var useIndexDdoc = '_design/' + useIndex[0];
+    var useIndexName = useIndex.length === 2 ? useIndex[1] : false;
+    var index = matchingIndexes.find(function (index) {
+      if (useIndexName && index.ddoc === useIndexDdoc && useIndexName === index.name) {
+        return true;
+      }
 
-    var currentSeq = view.seq || 0;
+      if (index.ddoc === useIndexDdoc) {
+        /* istanbul ignore next */
+        return true;
+      }
 
-    function processChange(docIdsToChangesAndEmits, seq) {
-      return function () {
-        return saveKeyValues(view, docIdsToChangesAndEmits, seq);
+      return false;
+    });
+
+    if (!index) {
+      throw {
+        error: "unknown_error",
+        message: "Could not find that index or could not use that index for the query"
       };
     }
+    return index;
+  }
 
-    var queue = new TaskQueue();
+  return max(matchingIndexes, scoreIndex);
+}
 
-    function processNextBatch() {
-      return view.sourceDB.changes({
-        return_docs: true,
-        conflicts: true,
-        include_docs: true,
-        style: 'all_docs',
-        since: currentSeq,
-        limit: CHANGES_BATCH_SIZE
-      }).then(processBatch);
-    }
+function getSingleFieldQueryOptsFor(userOperator, userValue) {
+  switch (userOperator) {
+    case '$eq':
+      return {key: userValue};
+    case '$lte':
+      return {endkey: userValue};
+    case '$gte':
+      return {startkey: userValue};
+    case '$lt':
+      return {
+        endkey: userValue,
+        inclusive_end: false
+      };
+    case '$gt':
+      return {
+        startkey: userValue,
+        inclusive_start: false
+      };
+  }
+}
 
-    function processBatch(response) {
-      var results = response.results;
-      if (!results.length) {
-        return;
-      }
-      var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results);
-      queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
-      if (results.length < CHANGES_BATCH_SIZE) {
-        return;
-      }
-      return processNextBatch();
-    }
+function getSingleFieldCoreQueryPlan(selector, index) {
+  var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[0]);
+  //ignoring this because the test to exercise the branch is skipped at the moment
+  /* istanbul ignore next */
+  var matcher = selector[field] || {};
+  var inMemoryFields = [];
 
-    function createDocIdsToChangesAndEmits(results) {
-      var docIdsToChangesAndEmits = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
-      for (var i = 0, len = results.length; i < len; i++) {
-        var change = results[i];
-        if (change.doc._id[0] !== '_') {
-          mapResults = [];
-          doc = change.doc;
+  var userOperators = Object.keys(matcher);
 
-          if (!doc._deleted) {
-            tryMap(view.sourceDB, mapFun, doc);
-          }
-          mapResults.sort(sortByKeyThenValue);
+  var combinedOpts;
 
-          var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults);
-          docIdsToChangesAndEmits.set(change.doc._id, [
-            indexableKeysToKeyValues,
-            change.changes
-          ]);
-        }
-        currentSeq = change.seq;
-      }
-      return docIdsToChangesAndEmits;
+  userOperators.forEach(function (userOperator) {
+
+    if (isNonLogicalMatcher(userOperator)) {
+      inMemoryFields.push(field);
+      return;
     }
 
-    function createIndexableKeysToKeyValues(mapResults) {
-      var indexableKeysToKeyValues = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
-      var lastKey;
-      for (var i = 0, len = mapResults.length; i < len; i++) {
-        var emittedKeyValue = mapResults[i];
-        var complexKey = [emittedKeyValue.key, emittedKeyValue.id];
-        if (i > 0 && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(emittedKeyValue.key, lastKey) === 0) {
-          complexKey.push(i); // dup key+id, so make it unique
-        }
-        indexableKeysToKeyValues.set((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)(complexKey), emittedKeyValue);
-        lastKey = emittedKeyValue.key;
-      }
-      return indexableKeysToKeyValues;
+    var userValue = matcher[userOperator];
+
+    var newQueryOpts = getSingleFieldQueryOptsFor(userOperator, userValue);
+
+    if (combinedOpts) {
+      combinedOpts = mergeObjects([combinedOpts, newQueryOpts]);
+    } else {
+      combinedOpts = newQueryOpts;
     }
+  });
 
-    return processNextBatch().then(function () {
-      return queue.finish();
-    }).then(function () {
-      view.seq = currentSeq;
-    });
+  return {
+    queryOpts: combinedOpts,
+    inMemoryFields: inMemoryFields
+  };
+}
+
+function getMultiFieldCoreQueryPlan(userOperator, userValue) {
+  switch (userOperator) {
+    case '$eq':
+      return {
+        startkey: userValue,
+        endkey: userValue
+      };
+    case '$lte':
+      return {
+        endkey: userValue
+      };
+    case '$gte':
+      return {
+        startkey: userValue
+      };
+    case '$lt':
+      return {
+        endkey: userValue,
+        inclusive_end: false
+      };
+    case '$gt':
+      return {
+        startkey: userValue,
+        inclusive_start: false
+      };
   }
+}
 
-  function reduceView(view, results, options) {
-    if (options.group_level === 0) {
-      delete options.group_level;
-    }
+function getMultiFieldQueryOpts(selector, index) {
 
-    var shouldGroup = options.group || options.group_level;
+  var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey);
 
-    var reduceFun = reducer(view.reduceFun);
+  var inMemoryFields = [];
+  var startkey = [];
+  var endkey = [];
+  var inclusiveStart;
+  var inclusiveEnd;
 
-    var groups = [];
-    var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
-      options.group_level;
-    results.forEach(function (e) {
-      var last = groups[groups.length - 1];
-      var groupKey = shouldGroup ? e.key : null;
 
-      // only set group_level for array keys
-      if (shouldGroup && Array.isArray(groupKey)) {
-        groupKey = groupKey.slice(0, lvl);
-      }
+  function finish(i) {
 
-      if (last && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(last.groupKey, groupKey) === 0) {
-        last.keys.push([e.key, e.id]);
-        last.values.push(e.value);
-        return;
-      }
-      groups.push({
-        keys: [[e.key, e.id]],
-        values: [e.value],
-        groupKey: groupKey
-      });
-    });
-    results = [];
-    for (var i = 0, len = groups.length; i < len; i++) {
-      var e = groups[i];
-      var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false);
-      if (reduceTry.error && reduceTry.error instanceof pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.BuiltInError) {
-        // CouchDB returns an error if a built-in errors out
-        throw reduceTry.error;
-      }
-      results.push({
-        // CouchDB just sets the value to null if a non-built-in errors out
-        value: reduceTry.error ? null : reduceTry.output,
-        key: e.groupKey
-      });
+    if (inclusiveStart !== false) {
+      startkey.push(COLLATE_LO);
     }
-    // no total_rows/offset when reducing
-    return {rows: sliceResults(results, options.limit, options.skip)};
+    if (inclusiveEnd !== false) {
+      endkey.push(COLLATE_HI);
+    }
+    // keep track of the fields where we lost specificity,
+    // and therefore need to filter in-memory
+    inMemoryFields = indexFields.slice(i);
   }
 
-  function queryView(view, opts) {
-    return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () {
-      return queryViewInQueue(view, opts);
-    })();
-  }
+  for (var i = 0, len = indexFields.length; i < len; i++) {
+    var indexField = indexFields[i];
 
-  function queryViewInQueue(view, opts) {
-    var totalRows;
-    var shouldReduce = view.reduceFun && opts.reduce !== false;
-    var skip = opts.skip || 0;
-    if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
-      // equivalent query
-      opts.limit = 0;
-      delete opts.keys;
+    var matcher = selector[indexField];
+
+    if (!matcher || !Object.keys(matcher).length) { // fewer fields in user query than in index
+      finish(i);
+      break;
+    } else if (i > 0) {
+      if (Object.keys(matcher).some(isNonLogicalMatcher)) { // non-logical are ignored
+        finish(i);
+        break;
+      }
+      var usingGtlt = (
+        '$gt' in matcher || '$gte' in matcher ||
+        '$lt' in matcher || '$lte' in matcher);
+      var previousKeys = Object.keys(selector[indexFields[i - 1]]);
+      var previousWasEq = arrayEquals(previousKeys, ['$eq']);
+      var previousWasSame = arrayEquals(previousKeys, Object.keys(matcher));
+      var gtltLostSpecificity = usingGtlt && !previousWasEq && !previousWasSame;
+      if (gtltLostSpecificity) {
+        finish(i);
+        break;
+      }
     }
 
-    function fetchFromView(viewOpts) {
-      viewOpts.include_docs = true;
-      return view.db.allDocs(viewOpts).then(function (res) {
-        totalRows = res.total_rows;
-        return res.rows.map(function (result) {
+    var userOperators = Object.keys(matcher);
 
-          // implicit migration - in older versions of PouchDB,
-          // we explicitly stored the doc as {id: ..., key: ..., value: ...}
-          // this is tested in a migration test
-          /* istanbul ignore next */
-          if ('value' in result.doc && typeof result.doc.value === 'object' &&
-            result.doc.value !== null) {
-            var keys = Object.keys(result.doc.value).sort();
-            // this detection method is not perfect, but it's unlikely the user
-            // emitted a value which was an object with these 3 exact keys
-            var expectedKeys = ['id', 'key', 'value'];
-            if (!(keys < expectedKeys || keys > expectedKeys)) {
-              return result.doc.value;
-            }
-          }
+    var combinedOpts = null;
 
-          var parsedKeyAndDocId = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.parseIndexableString)(result.doc._id);
-          return {
-            key: parsedKeyAndDocId[0],
-            id: parsedKeyAndDocId[1],
-            value: ('value' in result.doc ? result.doc.value : null)
-          };
-        });
-      });
-    }
+    for (var j = 0; j < userOperators.length; j++) {
+      var userOperator = userOperators[j];
+      var userValue = matcher[userOperator];
 
-    function onMapResultsReady(rows) {
-      var finalResults;
-      if (shouldReduce) {
-        finalResults = reduceView(view, rows, opts);
-      } else {
-        finalResults = {
-          total_rows: totalRows,
-          offset: skip,
-          rows: rows
-        };
-      }
-      /* istanbul ignore if */
-      if (opts.update_seq) {
-        finalResults.update_seq = view.seq;
-      }
-      if (opts.include_docs) {
-        var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(rows.map(rowToDocId));
+      var newOpts = getMultiFieldCoreQueryPlan(userOperator, userValue);
 
-        return view.sourceDB.allDocs({
-          keys: docIds,
-          include_docs: true,
-          conflicts: opts.conflicts,
-          attachments: opts.attachments,
-          binary: opts.binary
-        }).then(function (allDocsRes) {
-          var docIdsToDocs = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
-          allDocsRes.rows.forEach(function (row) {
-            docIdsToDocs.set(row.id, row.doc);
-          });
-          rows.forEach(function (row) {
-            var docId = rowToDocId(row);
-            var doc = docIdsToDocs.get(docId);
-            if (doc) {
-              row.doc = doc;
-            }
-          });
-          return finalResults;
-        });
+      if (combinedOpts) {
+        combinedOpts = mergeObjects([combinedOpts, newOpts]);
       } else {
-        return finalResults;
+        combinedOpts = newOpts;
       }
     }
 
-    if (typeof opts.keys !== 'undefined') {
-      var keys = opts.keys;
-      var fetchPromises = keys.map(function (key) {
-        var viewOpts = {
-          startkey : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key]),
-          endkey   : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key, {}])
-        };
-        /* istanbul ignore if */
-        if (opts.update_seq) {
-          viewOpts.update_seq = true;
-        }
-        return fetchFromView(viewOpts);
-      });
-      return Promise.all(fetchPromises).then(pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten).then(onMapResultsReady);
-    } else { // normal query, no 'keys'
-      var viewOpts = {
-        descending : opts.descending
-      };
-      /* istanbul ignore if */
-      if (opts.update_seq) {
-        viewOpts.update_seq = true;
-      }
-      var startkey;
-      var endkey;
-      if ('start_key' in opts) {
-        startkey = opts.start_key;
-      }
-      if ('startkey' in opts) {
-        startkey = opts.startkey;
-      }
-      if ('end_key' in opts) {
-        endkey = opts.end_key;
-      }
-      if ('endkey' in opts) {
-        endkey = opts.endkey;
-      }
-      if (typeof startkey !== 'undefined') {
-        viewOpts.startkey = opts.descending ?
-          (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey, {}]) :
-          (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey]);
-      }
-      if (typeof endkey !== 'undefined') {
-        var inclusiveEnd = opts.inclusive_end !== false;
-        if (opts.descending) {
-          inclusiveEnd = !inclusiveEnd;
-        }
-
-        viewOpts.endkey = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)(
-          inclusiveEnd ? [endkey, {}] : [endkey]);
-      }
-      if (typeof opts.key !== 'undefined') {
-        var keyStart = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key]);
-        var keyEnd = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key, {}]);
-        if (viewOpts.descending) {
-          viewOpts.endkey = keyStart;
-          viewOpts.startkey = keyEnd;
-        } else {
-          viewOpts.startkey = keyStart;
-          viewOpts.endkey = keyEnd;
-        }
-      }
-      if (!shouldReduce) {
-        if (typeof opts.limit === 'number') {
-          viewOpts.limit = opts.limit;
-        }
-        viewOpts.skip = skip;
-      }
-      return fetchFromView(viewOpts).then(onMapResultsReady);
+    startkey.push('startkey' in combinedOpts ? combinedOpts.startkey : COLLATE_LO);
+    endkey.push('endkey' in combinedOpts ? combinedOpts.endkey : COLLATE_HI);
+    if ('inclusive_start' in combinedOpts) {
+      inclusiveStart = combinedOpts.inclusive_start;
+    }
+    if ('inclusive_end' in combinedOpts) {
+      inclusiveEnd = combinedOpts.inclusive_end;
     }
   }
 
-  function httpViewCleanup(db) {
-    return db.fetch('_view_cleanup', {
-      headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}),
-      method: 'POST'
-    }).then(function (response) {
-      return response.json();
-    });
-  }
+  var res = {
+    startkey: startkey,
+    endkey: endkey
+  };
 
-  function localViewCleanup(db) {
-    return db.get('_local/' + localDocName).then(function (metaDoc) {
-      var docsToViews = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
-      Object.keys(metaDoc.views).forEach(function (fullViewName) {
-        var parts = parseViewName(fullViewName);
-        var designDocName = '_design/' + parts[0];
-        var viewName = parts[1];
-        var views = docsToViews.get(designDocName);
-        if (!views) {
-          views = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set();
-          docsToViews.set(designDocName, views);
-        }
-        views.add(viewName);
-      });
-      var opts = {
-        keys : (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docsToViews),
-        include_docs : true
-      };
-      return db.allDocs(opts).then(function (res) {
-        var viewsToStatus = {};
-        res.rows.forEach(function (row) {
-          var ddocName = row.key.substring(8); // cuts off '_design/'
-          docsToViews.get(row.key).forEach(function (viewName) {
-            var fullViewName = ddocName + '/' + viewName;
-            /* istanbul ignore if */
-            if (!metaDoc.views[fullViewName]) {
-              // new format, without slashes, to support PouchDB 2.2.0
-              // migration test in pouchdb's browser.migration.js verifies this
-              fullViewName = viewName;
-            }
-            var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
-            // design doc deleted, or view function nonexistent
-            var statusIsGood = row.doc && row.doc.views &&
-              row.doc.views[viewName];
-            viewDBNames.forEach(function (viewDBName) {
-              viewsToStatus[viewDBName] =
-                viewsToStatus[viewDBName] || statusIsGood;
-            });
-          });
-        });
-        var dbsToDelete = Object.keys(viewsToStatus).filter(
-          function (viewDBName) { return !viewsToStatus[viewDBName]; });
-        var destroyPromises = dbsToDelete.map(function (viewDBName) {
-          return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(viewDBName), function () {
-            return new db.constructor(viewDBName, db.__opts).destroy();
-          })();
-        });
-        return Promise.all(destroyPromises).then(function () {
-          return {ok: true};
-        });
-      });
-    }, defaultsTo({ok: true}));
+  if (typeof inclusiveStart !== 'undefined') {
+    res.inclusive_start = inclusiveStart;
+  }
+  if (typeof inclusiveEnd !== 'undefined') {
+    res.inclusive_end = inclusiveEnd;
   }
 
-  function queryPromised(db, fun, opts) {
-    /* istanbul ignore next */
-    if (typeof db._query === 'function') {
-      return customQuery(db, fun, opts);
-    }
-    if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) {
-      return httpQuery(db, fun, opts);
-    }
-
-    if (typeof fun !== 'string') {
-      // temp_view
-      checkQueryParseError(opts, fun);
-
-      tempViewQueue.add(function () {
-        var createViewPromise = createView(
-          /* sourceDB */ db,
-          /* viewName */ 'temp_view/temp_view',
-          /* mapFun */ fun.map,
-          /* reduceFun */ fun.reduce,
-          /* temporary */ true,
-          /* localDocName */ localDocName);
-        return createViewPromise.then(function (view) {
-          return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.fin)(updateView(view).then(function () {
-            return queryView(view, opts);
-          }), function () {
-            return view.db.destroy();
-          });
-        });
-      });
-      return tempViewQueue.finish();
-    } else {
-      // persistent view
-      var fullViewName = fun;
-      var parts = parseViewName(fullViewName);
-      var designDocName = parts[0];
-      var viewName = parts[1];
-      return db.get('_design/' + designDocName).then(function (doc) {
-        var fun = doc.views && doc.views[viewName];
+  return {
+    queryOpts: res,
+    inMemoryFields: inMemoryFields
+  };
+}
 
-        if (!fun) {
-          // basic validator; it's assumed that every subclass would want this
-          throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.NotFoundError('ddoc ' + doc._id + ' has no view named ' +
-            viewName);
-        }
+function getDefaultQueryPlan(selector) {
+  //using default index, so all fields need to be done in memory
+  return {
+    queryOpts: {startkey: null},
+    inMemoryFields: [Object.keys(selector)]
+  };
+}
 
-        ddocValidator(doc, viewName);
-        checkQueryParseError(opts, fun);
+function getCoreQueryPlan(selector, index) {
+  if (index.defaultUsed) {
+    return getDefaultQueryPlan(selector, index);
+  }
 
-        var createViewPromise = createView(
-          /* sourceDB */ db,
-          /* viewName */ fullViewName,
-          /* mapFun */ fun.map,
-          /* reduceFun */ fun.reduce,
-          /* temporary */ false,
-          /* localDocName */ localDocName);
-        return createViewPromise.then(function (view) {
-          if (opts.stale === 'ok' || opts.stale === 'update_after') {
-            if (opts.stale === 'update_after') {
-              (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () {
-                updateView(view);
-              });
-            }
-            return queryView(view, opts);
-          } else { // stale not ok
-            return updateView(view).then(function () {
-              return queryView(view, opts);
-            });
-          }
-        });
-      });
-    }
+  if (index.def.fields.length === 1) {
+    // one field in index, so the value was indexed as a singleton
+    return getSingleFieldCoreQueryPlan(selector, index);
   }
+  // else index has multiple fields, so the value was indexed as an array
+  return getMultiFieldQueryOpts(selector, index);
+}
 
-  function abstractQuery(fun, opts, callback) {
-    var db = this;
-    if (typeof opts === 'function') {
-      callback = opts;
-      opts = {};
-    }
-    opts = opts ? coerceOptions(opts) : {};
+function planQuery(request, indexes) {
 
-    if (typeof fun === 'function') {
-      fun = {map : fun};
-    }
+  var selector = request.selector;
+  var sort = request.sort;
 
-    var promise = Promise.resolve().then(function () {
-      return queryPromised(db, fun, opts);
-    });
-    (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.promisedCallback)(promise, callback);
-    return promise;
-  }
+  var userFieldsRes = getUserFields(selector, sort);
 
-  var abstractViewCleanup = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.callbackify)(function () {
-    var db = this;
-    /* istanbul ignore next */
-    if (typeof db._viewCleanup === 'function') {
-      return customViewCleanup(db);
-    }
-    if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) {
-      return httpViewCleanup(db);
-    }
-    return localViewCleanup(db);
-  });
+  var userFields = userFieldsRes.fields;
+  var sortOrder = userFieldsRes.sortOrder;
+  var index = findBestMatchingIndex(selector, userFields, sortOrder, indexes, request.use_index);
 
-  return {
-    query: abstractQuery,
-    viewCleanup: abstractViewCleanup
-  };
-}
+  var coreQueryPlan = getCoreQueryPlan(selector, index);
+  var queryOpts = coreQueryPlan.queryOpts;
+  var coreInMemoryFields = coreQueryPlan.inMemoryFields;
 
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createAbstractMapReduce);
+  var inMemoryFields = getInMemoryFields(coreInMemoryFields, index, selector, userFields);
 
+  var res = {
+    queryOpts: queryOpts,
+    index: index,
+    inMemoryFields: inMemoryFields
+  };
+  return res;
+}
 
-/***/ }),
-/* 506 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+function indexToSignature(index) {
+  // remove '_design/'
+  return index.ddoc.substring(8) + '/' + index.name;
+}
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "atob": () => (/* binding */ thisAtob),
-/* harmony export */   "btoa": () => (/* binding */ thisBtoa),
-/* harmony export */   "base64StringToBlobOrBuffer": () => (/* binding */ b64ToBluffer),
-/* harmony export */   "binaryStringToArrayBuffer": () => (/* binding */ binaryStringToArrayBuffer),
-/* harmony export */   "binaryStringToBlobOrBuffer": () => (/* binding */ binStringToBluffer),
-/* harmony export */   "blob": () => (/* binding */ createBlob),
-/* harmony export */   "blobOrBufferToBase64": () => (/* binding */ blobToBase64),
-/* harmony export */   "blobOrBufferToBinaryString": () => (/* binding */ blobToBase64$1),
-/* harmony export */   "readAsArrayBuffer": () => (/* binding */ readAsArrayBuffer),
-/* harmony export */   "readAsBinaryString": () => (/* binding */ readAsBinaryString),
-/* harmony export */   "typedBuffer": () => (/* binding */ typedBuffer)
-/* harmony export */ });
-/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507);
-/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer_from__WEBPACK_IMPORTED_MODULE_0__);
+function doAllDocs(db, originalOpts) {
+  var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(originalOpts);
 
+  // CouchDB responds in weird ways when you provide a non-string to _id;
+  // we mimic the behavior for consistency. See issue66 tests for details.
 
-function thisAtob(str) {
-  var base64 = new Buffer(str, 'base64');
-  // Node.js will just skip the characters it can't decode instead of
-  // throwing an exception
-  if (base64.toString('base64') !== str) {
-    throw new Error("attachment is not a valid base64 string");
+  if (opts.descending) {
+    if ('endkey' in opts && typeof opts.endkey !== 'string') {
+      opts.endkey = '';
+    }
+    if ('startkey' in opts && typeof opts.startkey !== 'string') {
+      opts.limit = 0;
+    }
+  } else {
+    if ('startkey' in opts && typeof opts.startkey !== 'string') {
+      opts.startkey = '';
+    }
+    if ('endkey' in opts && typeof opts.endkey !== 'string') {
+      opts.limit = 0;
+    }
+  }
+  if ('key' in opts && typeof opts.key !== 'string') {
+    opts.limit = 0;
   }
-  return base64.toString('binary');
-}
 
-function thisBtoa(str) {
-  return buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(str, 'binary').toString('base64');
+  return db.allDocs(opts)
+  .then(function (res) {
+    // filter out any design docs that _all_docs might return
+    res.rows = res.rows.filter(function (row) {
+      return !/^_design\//.test(row.id);
+    });
+    return res;
+  });
 }
 
-function typedBuffer(binString, buffType, type) {
-  // buffType is either 'binary' or 'base64'
-  var buff = buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(binString, buffType);
-  buff.type = type; // non-standard, but used for consistency with the browser
-  return buff;
-}
+function find$1(db, requestDef, explain) {
+  if (requestDef.selector) {
+    requestDef.selector = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.massageSelector)(requestDef.selector);
+  }
 
-function b64ToBluffer(b64, type) {
-  return typedBuffer(b64, 'base64', type);
-}
+  if (requestDef.sort) {
+    requestDef.sort = massageSort(requestDef.sort);
+  }
 
-// From http://stackoverflow.com/questions/14967647/ (continues on next line)
-// encode-decode-image-with-base64-breaks-image (2013-04-21)
-function binaryStringToArrayBuffer(bin) {
-  var length = bin.length;
-  var buf = new ArrayBuffer(length);
-  var arr = new Uint8Array(buf);
-  for (var i = 0; i < length; i++) {
-    arr[i] = bin.charCodeAt(i);
+  if (requestDef.use_index) {
+    requestDef.use_index = massageUseIndex(requestDef.use_index);
   }
-  return buf;
-}
 
-function binStringToBluffer(binString, type) {
-  return typedBuffer(binString, 'binary', type);
-}
+  validateFindRequest(requestDef);
 
-// This function is unused in Node
-/* istanbul ignore next */
-function createBlob() {
-}
+  return getIndexes$1(db).then(function (getIndexesRes) {
 
-function blobToBase64(blobOrBuffer, callback) {
-  callback(blobOrBuffer.toString('base64'));
-}
+    db.constructor.emit('debug', ['find', 'planning query', requestDef]);
+    var queryPlan = planQuery(requestDef, getIndexesRes.indexes);
+    db.constructor.emit('debug', ['find', 'query plan', queryPlan]);
 
-// not used in Node, but here for completeness
-function blobToBase64$1(blobOrBuffer, callback) {
-  callback(blobOrBuffer.toString('binary'));
-}
+    var indexToUse = queryPlan.index;
 
-// simplified API. universal browser support is assumed
-function readAsArrayBuffer(blob, callback) {
-  var reader = new FileReader();
-  reader.onloadend = function (e) {
-    var result = e.target.result || new ArrayBuffer(0);
-    callback(result);
-  };
-  reader.readAsArrayBuffer(blob);
-}
+    validateSort(requestDef, indexToUse);
 
-//Can't find original post, but this is close
-//http://stackoverflow.com/questions/6965107/ (continues on next line)
-//converting-between-strings-and-arraybuffers
-function arrayBufferToBinaryString(buffer) {
-  var binary = '';
-  var bytes = new Uint8Array(buffer);
-  var length = bytes.byteLength;
-  for (var i = 0; i < length; i++) {
-    binary += String.fromCharCode(bytes[i]);
-  }
-  return binary;
-}
+    var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)({
+      include_docs: true,
+      reduce: false
+    }, queryPlan.queryOpts);
 
-// shim for browsers that don't support it
-function readAsBinaryString(blob, callback) {
-  var reader = new FileReader();
-  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
-  reader.onloadend = function (e) {
-    var result = e.target.result || '';
-    if (hasBinaryString) {
-      return callback(result);
+    if ('startkey' in opts && 'endkey' in opts &&
+        (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(opts.startkey, opts.endkey) > 0) {
+      // can't possibly return any results, startkey > endkey
+      /* istanbul ignore next */
+      return {docs: []};
     }
-    callback(arrayBufferToBinaryString(result));
-  };
-  if (hasBinaryString) {
-    reader.readAsBinaryString(blob);
-  } else {
-    reader.readAsArrayBuffer(blob);
-  }
-}
 
+    var isDescending = requestDef.sort &&
+      typeof requestDef.sort[0] !== 'string' &&
+      (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(requestDef.sort[0]) === 'desc';
 
+    if (isDescending) {
+      // either all descending or all ascending
+      opts.descending = true;
+      opts = reverseOptions(opts);
+    }
 
+    if (!queryPlan.inMemoryFields.length) {
+      // no in-memory filtering necessary, so we can let the
+      // database do the limit/skip for us
+      if ('limit' in requestDef) {
+        opts.limit = requestDef.limit;
+      }
+      if ('skip' in requestDef) {
+        opts.skip = requestDef.skip;
+      }
+    }
 
-/***/ }),
-/* 507 */
-/***/ ((module) => {
+    if (explain) {
+      return Promise.resolve(queryPlan, opts);
+    }
 
-var toString = Object.prototype.toString
+    return Promise.resolve().then(function () {
+      if (indexToUse.name === '_all_docs') {
+        return doAllDocs(db, opts);
+      } else {
+        var signature = indexToSignature(indexToUse);
+        return abstractMapper.query.call(db, signature, opts);
+      }
+    }).then(function (res) {
+      if (opts.inclusive_start === false) {
+        // may have to manually filter the first one,
+        // since couchdb has no true inclusive_start option
+        res.rows = filterInclusiveStart(res.rows, opts.startkey, indexToUse);
+      }
 
-var isModern = (
-  typeof Buffer.alloc === 'function' &&
-  typeof Buffer.allocUnsafe === 'function' &&
-  typeof Buffer.from === 'function'
-)
+      if (queryPlan.inMemoryFields.length) {
+        // need to filter some stuff in-memory
+        res.rows = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.filterInMemoryFields)(res.rows, requestDef, queryPlan.inMemoryFields);
+      }
 
-function isArrayBuffer (input) {
-  return toString.call(input).slice(8, -1) === 'ArrayBuffer'
+      var resp = {
+        docs: res.rows.map(function (row) {
+          var doc = row.doc;
+          if (requestDef.fields) {
+            return pick(doc, requestDef.fields);
+          }
+          return doc;
+        })
+      };
+
+      if (indexToUse.defaultUsed) {
+        resp.warning = 'no matching index found, create an index to optimize query time';
+      }
+
+      return resp;
+    });
+  });
 }
 
-function fromArrayBuffer (obj, byteOffset, length) {
-  byteOffset >>>= 0
+function explain$1(db, requestDef) {
+  return find$1(db, requestDef, true)
+  .then(function (queryPlan) {
+    return {
+      dbname: db.name,
+      index: queryPlan.index,
+      selector: requestDef.selector,
+      range: {
+        start_key: queryPlan.queryOpts.startkey,
+        end_key: queryPlan.queryOpts.endkey,
+      },
+      opts: {
+        use_index: requestDef.use_index || [],
+        bookmark: "nil", //hardcoded to match CouchDB since its not supported,
+        limit: requestDef.limit,
+        skip: requestDef.skip,
+        sort: requestDef.sort || {},
+        fields: requestDef.fields,
+        conflicts: false, //hardcoded to match CouchDB since its not supported,
+        r: [49], // hardcoded to match CouchDB since its not support
+      },
+      limit: requestDef.limit,
+      skip: requestDef.skip || 0,
+      fields: requestDef.fields,
+    };
+  });
+}
 
-  var maxLength = obj.byteLength - byteOffset
+function deleteIndex$1(db, index) {
 
-  if (maxLength < 0) {
-    throw new RangeError("'offset' is out of bounds")
+  if (!index.ddoc) {
+    throw new Error('you must supply an index.ddoc when deleting');
   }
 
-  if (length === undefined) {
-    length = maxLength
-  } else {
-    length >>>= 0
+  if (!index.name) {
+    throw new Error('you must supply an index.name when deleting');
+  }
 
-    if (length > maxLength) {
-      throw new RangeError("'length' is out of bounds")
+  var docId = index.ddoc;
+  var viewName = index.name;
+
+  function deltaFun(doc) {
+    if (Object.keys(doc.views).length === 1 && doc.views[viewName]) {
+      // only one view in this ddoc, delete the whole ddoc
+      return {_id: docId, _deleted: true};
     }
+    // more than one view here, just remove the view
+    delete doc.views[viewName];
+    return doc;
   }
 
-  return isModern
-    ? Buffer.from(obj.slice(byteOffset, byteOffset + length))
-    : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)))
+  return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, docId, deltaFun).then(function () {
+    return abstractMapper.viewCleanup.apply(db);
+  }).then(function () {
+    return {ok: true};
+  });
 }
 
-function fromString (string, encoding) {
-  if (typeof encoding !== 'string' || encoding === '') {
-    encoding = 'utf8'
+var createIndexAsCallback = callbackify(createIndex$1);
+var findAsCallback = callbackify(find$1);
+var explainAsCallback = callbackify(explain$1);
+var getIndexesAsCallback = callbackify(getIndexes$1);
+var deleteIndexAsCallback = callbackify(deleteIndex$1);
+
+var plugin = {};
+plugin.createIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) {
+
+  if (typeof requestDef !== 'object') {
+    return callback(new Error('you must provide an index to create'));
   }
 
-  if (!Buffer.isEncoding(encoding)) {
-    throw new TypeError('"encoding" must be a valid string encoding')
+  var createIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ?
+    createIndex : createIndexAsCallback;
+  createIndex$$1(this, requestDef, callback);
+});
+
+plugin.find = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) {
+
+  if (typeof callback === 'undefined') {
+    callback = requestDef;
+    requestDef = undefined;
   }
 
-  return isModern
-    ? Buffer.from(string, encoding)
-    : new Buffer(string, encoding)
-}
+  if (typeof requestDef !== 'object') {
+    return callback(new Error('you must provide search parameters to find()'));
+  }
 
-function bufferFrom (value, encodingOrOffset, length) {
-  if (typeof value === 'number') {
-    throw new TypeError('"value" argument must not be a number')
+  var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? find : findAsCallback;
+  find$$1(this, requestDef, callback);
+});
+
+plugin.explain = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) {
+
+  if (typeof callback === 'undefined') {
+    callback = requestDef;
+    requestDef = undefined;
   }
 
-  if (isArrayBuffer(value)) {
-    return fromArrayBuffer(value, encodingOrOffset, length)
+  if (typeof requestDef !== 'object') {
+    return callback(new Error('you must provide search parameters to explain()'));
   }
 
-  if (typeof value === 'string') {
-    return fromString(value, encodingOrOffset)
+  var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? explain : explainAsCallback;
+  find$$1(this, requestDef, callback);
+});
+
+plugin.getIndexes = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (callback) {
+
+  var getIndexes$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? getIndexes : getIndexesAsCallback;
+  getIndexes$$1(this, callback);
+});
+
+plugin.deleteIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (indexDef, callback) {
+
+  if (typeof indexDef !== 'object') {
+    return callback(new Error('you must provide an index to delete'));
   }
 
-  return isModern
-    ? Buffer.from(value)
-    : new Buffer(value)
-}
+  var deleteIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ?
+    deleteIndex : deleteIndexAsCallback;
+  deleteIndex$$1(this, indexDef, callback);
+});
 
-module.exports = bufferFrom
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (plugin);
 
 
 /***/ }),
-/* 508 */
+/* 507 */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "uniq": () => (/* binding */ uniq),
-/* harmony export */   "sequentialize": () => (/* binding */ sequentialize),
-/* harmony export */   "fin": () => (/* binding */ fin),
-/* harmony export */   "callbackify": () => (/* binding */ callbackify),
-/* harmony export */   "promisedCallback": () => (/* binding */ promisedCallback),
-/* harmony export */   "mapToKeysArray": () => (/* binding */ mapToKeysArray),
-/* harmony export */   "QueryParseError": () => (/* binding */ QueryParseError),
-/* harmony export */   "NotFoundError": () => (/* binding */ NotFoundError),
-/* harmony export */   "BuiltInError": () => (/* binding */ BuiltInError)
+/* harmony export */   "adapterFun": () => (/* binding */ adapterFun),
+/* harmony export */   "assign": () => (/* binding */ assign$1),
+/* harmony export */   "bulkGetShim": () => (/* binding */ bulkGet),
+/* harmony export */   "changesHandler": () => (/* binding */ Changes),
+/* harmony export */   "clone": () => (/* binding */ clone$1),
+/* harmony export */   "defaultBackOff": () => (/* binding */ defaultBackOff),
+/* harmony export */   "explainError": () => (/* binding */ res),
+/* harmony export */   "filterChange": () => (/* binding */ filterChange),
+/* harmony export */   "flatten": () => (/* binding */ flatten),
+/* harmony export */   "functionName": () => (/* binding */ res$2),
+/* harmony export */   "guardedConsole": () => (/* binding */ guardedConsole),
+/* harmony export */   "hasLocalStorage": () => (/* binding */ hasLocalStorage),
+/* harmony export */   "invalidIdError": () => (/* binding */ invalidIdError),
+/* harmony export */   "isRemote": () => (/* binding */ isRemote),
+/* harmony export */   "listenerCount": () => (/* binding */ listenerCount),
+/* harmony export */   "nextTick": () => (/* binding */ nextTick),
+/* harmony export */   "normalizeDdocFunctionName": () => (/* binding */ normalizeDesignDocFunctionName),
+/* harmony export */   "once": () => (/* binding */ once),
+/* harmony export */   "parseDdocFunctionName": () => (/* binding */ parseDesignDocFunctionName),
+/* harmony export */   "parseUri": () => (/* binding */ parseUri),
+/* harmony export */   "pick": () => (/* binding */ pick),
+/* harmony export */   "rev": () => (/* binding */ rev),
+/* harmony export */   "scopeEval": () => (/* binding */ scopeEval),
+/* harmony export */   "toPromise": () => (/* binding */ toPromise),
+/* harmony export */   "upsert": () => (/* binding */ upsert),
+/* harmony export */   "uuid": () => (/* binding */ uuid)
 /* harmony export */ });
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(485);
-/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(497);
-/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(483);
-/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(495);
+/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(508);
+/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(clone_buffer__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(495);
+/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(509);
+/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(250);
+/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_3__);
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(497);
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_4__);
+/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(510);
+/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(500);
+/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_6__);
+/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(511);
+/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(507);
 
 
 
 
 
-function QueryParseError(message) {
-  this.status = 400;
-  this.name = 'query_parse_error';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, QueryParseError);
-  } catch (e) {}
-}
 
-inherits__WEBPACK_IMPORTED_MODULE_0___default()(QueryParseError, Error);
 
-function NotFoundError(message) {
-  this.status = 404;
-  this.name = 'not_found';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, NotFoundError);
-  } catch (e) {}
+
+
+
+function isBinaryObject(object) {
+  return object instanceof Buffer;
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_0___default()(NotFoundError, Error);
+// most of this is borrowed from lodash.isPlainObject:
+// https://github.com/fis-components/lodash.isplainobject/
+// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js
 
-function BuiltInError(message) {
-  this.status = 500;
-  this.name = 'invalid_value';
-  this.message = message;
-  this.error = true;
-  try {
-    Error.captureStackTrace(this, BuiltInError);
-  } catch (e) {}
+var funcToString = Function.prototype.toString;
+var objectCtorString = funcToString.call(Object);
+
+function isPlainObject(value) {
+  var proto = Object.getPrototypeOf(value);
+  /* istanbul ignore if */
+  if (proto === null) { // not sure when this happens, but I guess it can
+    return true;
+  }
+  var Ctor = proto.constructor;
+  return (typeof Ctor == 'function' &&
+    Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
 }
 
-inherits__WEBPACK_IMPORTED_MODULE_0___default()(BuiltInError, Error);
+function clone$1(object) {
+  var newObject;
+  var i;
+  var len;
 
-function promisedCallback(promise, callback) {
-  if (callback) {
-    promise.then(function (res) {
-      (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () {
-        callback(null, res);
-      });
-    }, function (reason) {
-      (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () {
-        callback(reason);
-      });
-    });
+  if (!object || typeof object !== 'object') {
+    return object;
   }
-  return promise;
+
+  if (Array.isArray(object)) {
+    newObject = [];
+    for (i = 0, len = object.length; i < len; i++) {
+      newObject[i] = clone$1(object[i]);
+    }
+    return newObject;
+  }
+
+  // special case: to avoid inconsistencies between IndexedDB
+  // and other backends, we automatically stringify Dates
+  if (object instanceof Date) {
+    return object.toISOString();
+  }
+
+  if (isBinaryObject(object)) {
+    return clone_buffer__WEBPACK_IMPORTED_MODULE_0___default()(object);
+  }
+
+  if (!isPlainObject(object)) {
+    return object; // don't clone objects like Workers
+  }
+
+  newObject = {};
+  for (i in object) {
+    /* istanbul ignore else */
+    if (Object.prototype.hasOwnProperty.call(object, i)) {
+      var value = clone$1(object[i]);
+      if (typeof value !== 'undefined') {
+        newObject[i] = value;
+      }
+    }
+  }
+  return newObject;
 }
 
-function callbackify(fun) {
-  return argsarray__WEBPACK_IMPORTED_MODULE_2___default()(function (args) {
-    var cb = args.pop();
-    var promise = fun.apply(this, args);
-    if (typeof cb === 'function') {
-      promisedCallback(promise, cb);
+function once(fun) {
+  var called = false;
+  return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) {
+    /* istanbul ignore if */
+    if (called) {
+      // this is a smoke test and should never actually happen
+      throw new Error('once called more than once');
+    } else {
+      called = true;
+      fun.apply(this, args);
     }
-    return promise;
   });
 }
 
-// Promise finally util similar to Q.finally
-function fin(promise, finalPromiseFactory) {
-  return promise.then(function (res) {
-    return finalPromiseFactory().then(function () {
-      return res;
-    });
-  }, function (reason) {
-    return finalPromiseFactory().then(function () {
-      throw reason;
+function toPromise(func) {
+  //create the function we will be returning
+  return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) {
+    // Clone arguments
+    args = clone$1(args);
+    var self = this;
+    // if the last argument is a function, assume its a callback
+    var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+    var promise = new Promise(function (fulfill, reject) {
+      var resp;
+      try {
+        var callback = once(function (err, mesg) {
+          if (err) {
+            reject(err);
+          } else {
+            fulfill(mesg);
+          }
+        });
+        // create a callback for this invocation
+        // apply the function in the orig context
+        args.push(callback);
+        resp = func.apply(self, args);
+        if (resp && typeof resp.then === 'function') {
+          fulfill(resp);
+        }
+      } catch (e) {
+        reject(e);
+      }
     });
+    // if there is a callback, call it back
+    if (usedCB) {
+      promise.then(function (result) {
+        usedCB(null, result);
+      }, usedCB);
+    }
+    return promise;
   });
 }
 
-function sequentialize(queue, promiseFactory) {
-  return function () {
-    var args = arguments;
-    var that = this;
-    return queue.add(function () {
-      return promiseFactory.apply(that, args);
-    });
-  };
-}
+function logApiCall(self, name, args) {
+  /* istanbul ignore if */
+  if (self.constructor.listeners('debug').length) {
+    var logArgs = ['api', self.name, name];
+    for (var i = 0; i < args.length - 1; i++) {
+      logArgs.push(args[i]);
+    }
+    self.constructor.emit('debug', logArgs);
 
-// uniq an array of strings, order not guaranteed
-// similar to underscore/lodash _.uniq
-function uniq(arr) {
-  var theSet = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__.Set(arr);
-  var result = new Array(theSet.size);
-  var index = -1;
-  theSet.forEach(function (value) {
-    result[++index] = value;
-  });
-  return result;
+    // override the callback itself to log the response
+    var origCallback = args[args.length - 1];
+    args[args.length - 1] = function (err, res) {
+      var responseArgs = ['api', self.name, name];
+      responseArgs = responseArgs.concat(
+        err ? ['error', err] : ['success', res]
+      );
+      self.constructor.emit('debug', responseArgs);
+      origCallback(err, res);
+    };
+  }
 }
 
-function mapToKeysArray(map) {
-  var result = new Array(map.size);
-  var index = -1;
-  map.forEach(function (value, key) {
-    result[++index] = key;
-  });
-  return result;
+function adapterFun(name, callback) {
+  return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) {
+    if (this._closed) {
+      return Promise.reject(new Error('database is closed'));
+    }
+    if (this._destroyed) {
+      return Promise.reject(new Error('database is destroyed'));
+    }
+    var self = this;
+    logApiCall(self, name, args);
+    if (!this.taskqueue.isReady) {
+      return new Promise(function (fulfill, reject) {
+        self.taskqueue.addTask(function (failed) {
+          if (failed) {
+            reject(failed);
+          } else {
+            fulfill(self[name].apply(self, args));
+          }
+        });
+      });
+    }
+    return callback.apply(this, args);
+  }));
 }
 
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+  var res = {};
+  for (var i = 0, len = arr.length; i < len; i++) {
+    var prop = arr[i];
+    if (prop in obj) {
+      res[prop] = obj[prop];
+    }
+  }
+  return res;
+}
 
+// Most browsers throttle concurrent requests at 6, so it's silly
+// to shim _bulk_get by trying to launch potentially hundreds of requests
+// and then letting the majority time out. We can handle this ourselves.
+var MAX_NUM_CONCURRENT_REQUESTS = 6;
 
+function identityFunction(x) {
+  return x;
+}
 
-/***/ }),
-/* 509 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
+function formatResultForOpenRevsGet(result) {
+  return [{
+    ok: result
+  }];
+}
 
+// shim for P/CouchDB adapters that don't directly implement _bulk_get
+function bulkGet(db, opts, callback) {
+  var requests = opts.docs;
 
-var _interopRequireWildcard = __webpack_require__(510);
+  // consolidate into one request per doc if possible
+  var requestsById = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
+  requests.forEach(function (request) {
+    if (requestsById.has(request.id)) {
+      requestsById.get(request.id).push(request);
+    } else {
+      requestsById.set(request.id, [request]);
+    }
+  });
 
-var _interopRequireDefault = __webpack_require__(512);
+  var numDocs = requestsById.size;
+  var numDone = 0;
+  var perDocResults = new Array(numDocs);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-var _exportNames = {
-  CozyLink: true,
-  StackLink: true,
-  compose: true,
-  QueryDefinition: true,
-  Mutations: true,
-  MutationTypes: true,
-  getDoctypeFromOperation: true,
-  Q: true,
-  Association: true,
-  HasMany: true,
-  HasOne: true,
-  HasOneInPlace: true,
-  HasManyInPlace: true,
-  HasManyTriggers: true,
-  dehydrate: true,
-  generateWebLink: true,
-  rootCozyUrl: true,
-  InvalidCozyUrlError: true,
-  InvalidProtocolError: true,
-  cancelable: true,
-  getQueryFromState: true,
-  Registry: true,
-  manifest: true,
-  BulkEditError: true,
-  models: true
-};
-Object.defineProperty(exports, "default", ({
-  enumerable: true,
-  get: function get() {
-    return _CozyClient.default;
-  }
-}));
-Object.defineProperty(exports, "CozyLink", ({
-  enumerable: true,
-  get: function get() {
-    return _CozyLink.default;
-  }
-}));
-Object.defineProperty(exports, "StackLink", ({
-  enumerable: true,
-  get: function get() {
-    return _StackLink.default;
-  }
-}));
-Object.defineProperty(exports, "compose", ({
-  enumerable: true,
-  get: function get() {
-    return _flow.default;
-  }
-}));
-Object.defineProperty(exports, "QueryDefinition", ({
-  enumerable: true,
-  get: function get() {
-    return _dsl.QueryDefinition;
-  }
-}));
-Object.defineProperty(exports, "Mutations", ({
-  enumerable: true,
-  get: function get() {
-    return _dsl.Mutations;
-  }
-}));
-Object.defineProperty(exports, "MutationTypes", ({
-  enumerable: true,
-  get: function get() {
-    return _dsl.MutationTypes;
-  }
-}));
-Object.defineProperty(exports, "getDoctypeFromOperation", ({
-  enumerable: true,
-  get: function get() {
-    return _dsl.getDoctypeFromOperation;
-  }
-}));
-Object.defineProperty(exports, "Q", ({
-  enumerable: true,
-  get: function get() {
-    return _dsl.Q;
-  }
-}));
-Object.defineProperty(exports, "Association", ({
-  enumerable: true,
-  get: function get() {
-    return _associations.Association;
-  }
-}));
-Object.defineProperty(exports, "HasMany", ({
-  enumerable: true,
-  get: function get() {
-    return _associations.HasMany;
-  }
-}));
-Object.defineProperty(exports, "HasOne", ({
-  enumerable: true,
-  get: function get() {
-    return _associations.HasOne;
-  }
-}));
-Object.defineProperty(exports, "HasOneInPlace", ({
-  enumerable: true,
-  get: function get() {
-    return _associations.HasOneInPlace;
-  }
-}));
-Object.defineProperty(exports, "HasManyInPlace", ({
-  enumerable: true,
-  get: function get() {
-    return _associations.HasManyInPlace;
-  }
-}));
-Object.defineProperty(exports, "HasManyTriggers", ({
-  enumerable: true,
-  get: function get() {
-    return _associations.HasManyTriggers;
-  }
-}));
-Object.defineProperty(exports, "dehydrate", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.dehydrate;
-  }
-}));
-Object.defineProperty(exports, "generateWebLink", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.generateWebLink;
-  }
-}));
-Object.defineProperty(exports, "rootCozyUrl", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.rootCozyUrl;
+  function collapseResultsAndFinish() {
+    var results = [];
+    perDocResults.forEach(function (res) {
+      res.docs.forEach(function (info) {
+        results.push({
+          id: res.id,
+          docs: [info]
+        });
+      });
+    });
+    callback(null, {results: results});
   }
-}));
-Object.defineProperty(exports, "InvalidCozyUrlError", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.InvalidCozyUrlError;
+
+  function checkDone() {
+    if (++numDone === numDocs) {
+      collapseResultsAndFinish();
+    }
   }
-}));
-Object.defineProperty(exports, "InvalidProtocolError", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.InvalidProtocolError;
+
+  function gotResult(docIndex, id, docs) {
+    perDocResults[docIndex] = {id: id, docs: docs};
+    checkDone();
   }
-}));
-Object.defineProperty(exports, "cancelable", ({
-  enumerable: true,
-  get: function get() {
-    return _utils.cancelable;
+
+  var allRequests = [];
+  requestsById.forEach(function (value, key) {
+    allRequests.push(key);
+  });
+
+  var i = 0;
+
+  function nextBatch() {
+
+    if (i >= allRequests.length) {
+      return;
+    }
+
+    var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length);
+    var batch = allRequests.slice(i, upTo);
+    processBatch(batch, i);
+    i += batch.length;
   }
-}));
-Object.defineProperty(exports, "getQueryFromState", ({
-  enumerable: true,
-  get: function get() {
-    return _store.getQueryFromState;
+
+  function processBatch(batch, offset) {
+    batch.forEach(function (docId, j) {
+      var docIdx = offset + j;
+      var docRequests = requestsById.get(docId);
+
+      // just use the first request as the "template"
+      // TODO: The _bulk_get API allows for more subtle use cases than this,
+      // but for now it is unlikely that there will be a mix of different
+      // "atts_since" or "attachments" in the same request, since it's just
+      // replicate.js that is using this for the moment.
+      // Also, atts_since is aspirational, since we don't support it yet.
+      var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
+      docOpts.open_revs = docRequests.map(function (request) {
+        // rev is optional, open_revs disallowed
+        return request.rev;
+      });
+
+      // remove falsey / undefined revisions
+      docOpts.open_revs = docOpts.open_revs.filter(identityFunction);
+
+      var formatResult = identityFunction;
+
+      if (docOpts.open_revs.length === 0) {
+        delete docOpts.open_revs;
+
+        // when fetching only the "winning" leaf,
+        // transform the result so it looks like an open_revs
+        // request
+        formatResult = formatResultForOpenRevsGet;
+      }
+
+      // globally-supplied options
+      ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) {
+        if (param in opts) {
+          docOpts[param] = opts[param];
+        }
+      });
+      db.get(docId, docOpts, function (err, res) {
+        var result;
+        /* istanbul ignore if */
+        if (err) {
+          result = [{error: err}];
+        } else {
+          result = formatResult(res);
+        }
+        gotResult(docIdx, docId, result);
+        nextBatch();
+      });
+    });
   }
-}));
-Object.defineProperty(exports, "Registry", ({
-  enumerable: true,
-  get: function get() {
-    return _registry.default;
+
+  nextBatch();
+
+}
+
+// in Node of course this is false
+function hasLocalStorage() {
+  return false;
+}
+
+function nextTick(fn) {
+  process.nextTick(fn);
+}
+
+inherits__WEBPACK_IMPORTED_MODULE_4___default()(Changes, events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+  if (hasLocalStorage()) {
+    addEventListener("storage", function (e) {
+      self.emit(e.key);
+    });
   }
-}));
-Object.defineProperty(exports, "BulkEditError", ({
-  enumerable: true,
-  get: function get() {
-    return _errors.BulkEditError;
+}
+
+function Changes() {
+  events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.call(this);
+  this._listeners = {};
+
+  attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+  /* istanbul ignore if */
+  if (this._listeners[id]) {
+    return;
   }
-}));
-exports.models = exports.manifest = void 0;
+  var self = this;
+  var inprogress = false;
+  function eventFunction() {
+    /* istanbul ignore if */
+    if (!self._listeners[id]) {
+      return;
+    }
+    if (inprogress) {
+      inprogress = 'waiting';
+      return;
+    }
+    inprogress = true;
+    var changesOpts = pick(opts, [
+      'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+      'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
+    ]);
+
+    /* istanbul ignore next */
+    function onError() {
+      inprogress = false;
+    }
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+    db.changes(changesOpts).on('change', function (c) {
+      if (c.seq > opts.since && !opts.cancelled) {
+        opts.since = c.seq;
+        opts.onChange(c);
+      }
+    }).on('complete', function () {
+      if (inprogress === 'waiting') {
+        nextTick(eventFunction);
+      }
+      inprogress = false;
+    }).on('error', onError);
+  }
+  this._listeners[id] = eventFunction;
+  this.on(dbName, eventFunction);
+};
 
-var _CozyLink = _interopRequireDefault(__webpack_require__(687));
+Changes.prototype.removeListener = function (dbName, id) {
+  /* istanbul ignore if */
+  if (!(id in this._listeners)) {
+    return;
+  }
+  events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.prototype.removeListener.call(this, dbName,
+    this._listeners[id]);
+  delete this._listeners[id];
+};
 
-var _StackLink = _interopRequireDefault(__webpack_require__(686));
 
-var _flow = _interopRequireDefault(__webpack_require__(792));
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+  //do a useless change on a storage thing
+  //in order to get other windows's listeners to activate
+  if (hasLocalStorage()) {
+    localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+  }
+};
 
-var _dsl = __webpack_require__(607);
+Changes.prototype.notify = function (dbName) {
+  this.emit(dbName);
+  this.notifyLocalWindows(dbName);
+};
 
-var _associations = __webpack_require__(691);
+function guardedConsole(method) {
+  /* istanbul ignore else */
+  if (typeof console !== 'undefined' && typeof console[method] === 'function') {
+    var args = Array.prototype.slice.call(arguments, 1);
+    console[method].apply(console, args);
+  }
+}
 
-var _helpers = __webpack_require__(756);
+function randomNumber(min, max) {
+  var maxTimeout = 600000; // Hard-coded default of 10 minutes
+  min = parseInt(min, 10) || 0;
+  max = parseInt(max, 10);
+  if (max !== max || max <= min) {
+    max = (min || 1) << 1; //doubling
+  } else {
+    max = max + 1;
+  }
+  // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout
+  if (max > maxTimeout) {
+    min = maxTimeout >> 1; // divide by two
+    max = maxTimeout;
+  }
+  var ratio = Math.random();
+  var range = max - min;
 
-var _utils = __webpack_require__(804);
+  return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
+}
 
-var _store = __webpack_require__(693);
+function defaultBackOff(min) {
+  var max = 0;
+  if (!min) {
+    max = 2000;
+  }
+  return randomNumber(min, max);
+}
 
-var _registry = _interopRequireDefault(__webpack_require__(596));
+// We assume Node users don't need to see this warning
+var res = function () {};
 
-var manifest = _interopRequireWildcard(__webpack_require__(805));
+var assign;
+{
+  if (typeof Object.assign === 'function') {
+    assign = Object.assign;
+  } else {
+    // lite Object.assign polyfill based on
+    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+    assign = function (target) {
+      var to = Object(target);
 
-exports.manifest = manifest;
+      for (var index = 1; index < arguments.length; index++) {
+        var nextSource = arguments[index];
 
-var _mock = __webpack_require__(806);
+        if (nextSource != null) { // Skip over if undefined or null
+          for (var nextKey in nextSource) {
+            // Avoid bugs when hasOwnProperty is shadowed
+            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+              to[nextKey] = nextSource[nextKey];
+            }
+          }
+        }
+      }
+      return to;
+    };
+  }
+}
 
-Object.keys(_mock).forEach(function (key) {
-  if (key === "default" || key === "__esModule") return;
-  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-  if (key in exports && exports[key] === _mock[key]) return;
-  Object.defineProperty(exports, key, {
-    enumerable: true,
-    get: function get() {
-      return _mock[key];
-    }
-  });
-});
+var assign$1 = assign;
 
-var _errors = __webpack_require__(688);
+function tryFilter(filter, doc, req) {
+  try {
+    return !filter(doc, req);
+  } catch (err) {
+    var msg = 'Filter function threw: ' + err.toString();
+    return (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.BAD_REQUEST, msg);
+  }
+}
 
-var _cli = __webpack_require__(807);
+function filterChange(opts) {
+  var req = {};
+  var hasFilter = opts.filter && typeof opts.filter === 'function';
+  req.query = opts.query_params;
 
-Object.keys(_cli).forEach(function (key) {
-  if (key === "default" || key === "__esModule") return;
-  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-  if (key in exports && exports[key] === _cli[key]) return;
-  Object.defineProperty(exports, key, {
-    enumerable: true,
-    get: function get() {
-      return _cli[key];
+  return function filter(change) {
+    if (!change.doc) {
+      // CSG sends events on the changes feed that don't have documents,
+      // this hack makes a whole lot of existing code robust.
+      change.doc = {};
     }
-  });
-});
 
-var models = _interopRequireWildcard(__webpack_require__(828));
-
-exports.models = models;
+    var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
 
-/***/ }),
-/* 510 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    if (typeof filterReturn === 'object') {
+      return filterReturn;
+    }
 
-var _typeof = (__webpack_require__(511)["default"]);
+    if (filterReturn) {
+      return false;
+    }
 
-function _getRequireWildcardCache(nodeInterop) {
-  if (typeof WeakMap !== "function") return null;
-  var cacheBabelInterop = new WeakMap();
-  var cacheNodeInterop = new WeakMap();
-  return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) {
-    return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
-  })(nodeInterop);
+    if (!opts.include_docs) {
+      delete change.doc;
+    } else if (!opts.attachments) {
+      for (var att in change.doc._attachments) {
+        /* istanbul ignore else */
+        if (change.doc._attachments.hasOwnProperty(att)) {
+          change.doc._attachments[att].stub = true;
+        }
+      }
+    }
+    return true;
+  };
 }
 
-function _interopRequireWildcard(obj, nodeInterop) {
-  if (!nodeInterop && obj && obj.__esModule) {
-    return obj;
-  }
-
-  if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") {
-    return {
-      "default": obj
-    };
+function flatten(arrs) {
+  var res = [];
+  for (var i = 0, len = arrs.length; i < len; i++) {
+    res = res.concat(arrs[i]);
   }
+  return res;
+}
 
-  var cache = _getRequireWildcardCache(nodeInterop);
-
-  if (cache && cache.has(obj)) {
-    return cache.get(obj);
-  }
+// shim for Function.prototype.name,
+// for browsers that don't support it like IE
 
-  var newObj = {};
-  var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
+/* istanbul ignore next */
+function f() {}
 
-  for (var key in obj) {
-    if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
-      var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
+var hasName = f.name;
+var res$1;
 
-      if (desc && (desc.get || desc.set)) {
-        Object.defineProperty(newObj, key, desc);
-      } else {
-        newObj[key] = obj[key];
-      }
+// We dont run coverage in IE
+/* istanbul ignore else */
+if (hasName) {
+  res$1 = function (fun) {
+    return fun.name;
+  };
+} else {
+  res$1 = function (fun) {
+    var match = fun.toString().match(/^\s*function\s*(?:(\S+)\s*)?\(/);
+    if (match && match[1]) {
+      return match[1];
     }
-  }
+    else {
+      return '';
+    }
+  };
+}
 
-  newObj["default"] = obj;
+var res$2 = res$1;
 
-  if (cache) {
-    cache.set(obj, newObj);
+// Determine id an ID is valid
+//   - invalid IDs begin with an underescore that does not begin '_design' or
+//     '_local'
+//   - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+  var err;
+  if (!id) {
+    err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.MISSING_ID);
+  } else if (typeof id !== 'string') {
+    err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.INVALID_ID);
+  } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+    err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.RESERVED_ID);
+  }
+  if (err) {
+    throw err;
   }
-
-  return newObj;
 }
 
-module.exports = _interopRequireWildcard;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
-
-/***/ }),
-/* 511 */
-/***/ ((module) => {
-
-function _typeof(obj) {
-  "@babel/helpers - typeof";
-
-  if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
-    module.exports = _typeof = function _typeof(obj) {
-      return typeof obj;
-    };
-
-    module.exports["default"] = module.exports, module.exports.__esModule = true;
-  } else {
-    module.exports = _typeof = function _typeof(obj) {
-      return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
-    };
+// Checks if a PouchDB object is "remote" or not. This is
 
-    module.exports["default"] = module.exports, module.exports.__esModule = true;
+function isRemote(db) {
+  if (typeof db._remote === 'boolean') {
+    return db._remote;
   }
-
-  return _typeof(obj);
+  /* istanbul ignore next */
+  if (typeof db.type === 'function') {
+    guardedConsole('warn',
+      'db.type() is deprecated and will be removed in ' +
+      'a future version of PouchDB');
+    return db.type() === 'http';
+  }
+  /* istanbul ignore next */
+  return false;
 }
 
-module.exports = _typeof;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+function listenerCount(ee, type) {
+  return 'listenerCount' in ee ? ee.listenerCount(type) :
+                                 events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.listenerCount(ee, type);
+}
 
-/***/ }),
-/* 512 */
-/***/ ((module) => {
+function parseDesignDocFunctionName(s) {
+  if (!s) {
+    return null;
+  }
+  var parts = s.split('/');
+  if (parts.length === 2) {
+    return parts;
+  }
+  if (parts.length === 1) {
+    return [s, s];
+  }
+  return null;
+}
 
-function _interopRequireDefault(obj) {
-  return obj && obj.__esModule ? obj : {
-    "default": obj
-  };
+function normalizeDesignDocFunctionName(s) {
+  var normalized = parseDesignDocFunctionName(s);
+  return normalized ? normalized.join('/') : null;
 }
 
-module.exports = _interopRequireDefault;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+// originally parseUri 1.2.2, now patched by us
+// (c) Steven Levithan <stevenlevithan.com>
+// MIT License
+var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
+    "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
+var qName ="queryKey";
+var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
 
-/***/ }),
-/* 513 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+// use the "loose" parser
+/* eslint maxlen: 0, no-useless-escape: 0 */
+var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
 
-"use strict";
+function parseUri(str) {
+  var m = parser.exec(str);
+  var uri = {};
+  var i = 14;
 
+  while (i--) {
+    var key = keys[i];
+    var value = m[i] || "";
+    var encoded = ['user', 'password'].indexOf(key) !== -1;
+    uri[key] = encoded ? decodeURIComponent(value) : value;
+  }
 
-var _interopRequireWildcard = __webpack_require__(510);
+  uri[qName] = {};
+  uri[keys[12]].replace(qParser, function ($0, $1, $2) {
+    if ($1) {
+      uri[qName][$1] = $2;
+    }
+  });
 
-var _interopRequireDefault = __webpack_require__(512);
+  return uri;
+}
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+// Based on https://github.com/alexdavid/scope-eval v0.0.3
+// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js)
+// This is basically just a wrapper around new Function()
 
-var _toArray2 = _interopRequireDefault(__webpack_require__(514));
+function scopeEval(source, scope) {
+  var keys = [];
+  var values = [];
+  for (var key in scope) {
+    if (scope.hasOwnProperty(key)) {
+      keys.push(key);
+      values.push(scope[key]);
+    }
+  }
+  keys.push(source);
+  return Function.apply(null, keys).apply(null, values);
+}
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
+// the diffFun tells us what delta to apply to the doc.  it either returns
+// the doc, or false if it doesn't need to do an update after all
+function upsert(db, docId, diffFun) {
+  return new Promise(function (fulfill, reject) {
+    db.get(docId, function (err, doc) {
+      if (err) {
+        /* istanbul ignore next */
+        if (err.status !== 404) {
+          return reject(err);
+        }
+        doc = {};
+      }
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+      // the user might change the _rev, so save it for posterity
+      var docRev = doc._rev;
+      var newDoc = diffFun(doc);
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
+      if (!newDoc) {
+        // if the diffFun returns falsy, we short-circuit as
+        // an optimization
+        return fulfill({updated: false, rev: docRev});
+      }
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+      // users aren't allowed to modify these values,
+      // so reset them here
+      newDoc._id = docId;
+      newDoc._rev = docRev;
+      fulfill(tryAndPut(db, newDoc, diffFun));
+    });
+  });
+}
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+function tryAndPut(db, doc, diffFun) {
+  return db.put(doc).then(function (res) {
+    return {
+      updated: true,
+      rev: res.rev
+    };
+  }, function (err) {
+    /* istanbul ignore next */
+    if (err.status !== 409) {
+      throw err;
+    }
+    return upsert(db, doc._id, diffFun);
+  });
+}
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+function rev(doc, deterministic_revs) {
+  var clonedDoc = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__.clone)(doc);
+  if (!deterministic_revs) {
+    return uuid__WEBPACK_IMPORTED_MODULE_6___default().v4().replace(/-/g, '').toLowerCase();
+  }
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+  delete clonedDoc._rev_tree;
+  return (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__.stringMd5)(JSON.stringify(clonedDoc));
+}
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var uuid = (uuid__WEBPACK_IMPORTED_MODULE_6___default().v4);
 
-var _mapValues = _interopRequireDefault(__webpack_require__(533));
 
-var _fromPairs = _interopRequireDefault(__webpack_require__(539));
 
-var _flatten = _interopRequireDefault(__webpack_require__(540));
 
-var _uniqBy = _interopRequireDefault(__webpack_require__(400));
+/***/ }),
+/* 508 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _zip = _interopRequireDefault(__webpack_require__(543));
+"use strict";
 
-var _forEach = _interopRequireDefault(__webpack_require__(553));
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var Buffer = (__webpack_require__(78).Buffer);
 
-var _microee = _interopRequireDefault(__webpack_require__(558));
+function hasFrom() {
+  // Node versions 5.x below 5.10 seem to have a `from` method
+  // However, it doesn't clone Buffers
+  // Luckily, it reports as `false` to hasOwnProperty
+  return (Buffer.hasOwnProperty('from') && typeof Buffer.from === 'function');
+}
 
-var _cozyStackClient = _interopRequireWildcard(__webpack_require__(559));
+function cloneBuffer(buf) {
+  if (!Buffer.isBuffer(buf)) {
+    throw new Error('Can only clone Buffer.');
+  }
 
-var _const = __webpack_require__(685);
+  if (hasFrom()) {
+    return Buffer.from(buf);
+  }
 
-var _StackLink = _interopRequireDefault(__webpack_require__(686));
+  var copy = new Buffer(buf.length);
+  buf.copy(copy);
+  return copy;
+}
 
-var _associations = __webpack_require__(691);
+cloneBuffer.hasFrom = hasFrom;
 
-var _helpers = __webpack_require__(755);
+module.exports = cloneBuffer;
 
-var _helpers2 = __webpack_require__(756);
 
-var _dsl = __webpack_require__(607);
+/***/ }),
+/* 509 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-var _mobile = __webpack_require__(757);
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Set": () => (/* binding */ ExportedSet),
+/* harmony export */   "Map": () => (/* binding */ ExportedMap)
+/* harmony export */ });
+function mangle(key) {
+  return '$' + key;
+}
+function unmangle(key) {
+  return key.substring(1);
+}
+function Map$1() {
+  this._store = {};
+}
+Map$1.prototype.get = function (key) {
+  var mangled = mangle(key);
+  return this._store[mangled];
+};
+Map$1.prototype.set = function (key, value) {
+  var mangled = mangle(key);
+  this._store[mangled] = value;
+  return true;
+};
+Map$1.prototype.has = function (key) {
+  var mangled = mangle(key);
+  return mangled in this._store;
+};
+Map$1.prototype.delete = function (key) {
+  var mangled = mangle(key);
+  var res = mangled in this._store;
+  delete this._store[mangled];
+  return res;
+};
+Map$1.prototype.forEach = function (cb) {
+  var keys = Object.keys(this._store);
+  for (var i = 0, len = keys.length; i < len; i++) {
+    var key = keys[i];
+    var value = this._store[key];
+    key = unmangle(key);
+    cb(value, key);
+  }
+};
+Object.defineProperty(Map$1.prototype, 'size', {
+  get: function () {
+    return Object.keys(this._store).length;
+  }
+});
 
-var _optimize = _interopRequireDefault(__webpack_require__(774));
+function Set$1(array) {
+  this._store = new Map$1();
 
-var _store = _interopRequireWildcard(__webpack_require__(693));
+  // init with an array
+  if (array && Array.isArray(array)) {
+    for (var i = 0, len = array.length; i < len; i++) {
+      this.add(array[i]);
+    }
+  }
+}
+Set$1.prototype.add = function (key) {
+  return this._store.set(key, true);
+};
+Set$1.prototype.has = function (key) {
+  return this._store.has(key);
+};
+Set$1.prototype.forEach = function (cb) {
+  this._store.forEach(function (value, key) {
+    cb(key);
+  });
+};
+Object.defineProperty(Set$1.prototype, 'size', {
+  get: function () {
+    return this._store.size;
+  }
+});
 
-var _policies = _interopRequireDefault(__webpack_require__(776));
+/* global Map,Set,Symbol */
+// Based on https://kangax.github.io/compat-table/es6/ we can sniff out
+// incomplete Map/Set implementations which would otherwise cause our tests to fail.
+// Notably they fail in IE11 and iOS 8.4, which this prevents.
+function supportsMapAndSet() {
+  if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') {
+    return false;
+  }
+  var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
+  return prop && 'get' in prop && Map[Symbol.species] === Map;
+}
 
-var _Schema = _interopRequireDefault(__webpack_require__(777));
+// based on https://github.com/montagejs/collections
 
-var _CozyLink = __webpack_require__(687);
+var ExportedSet;
+var ExportedMap;
 
-var _ObservableQuery = _interopRequireDefault(__webpack_require__(783));
+{
+  if (supportsMapAndSet()) { // prefer built-in Map/Set
+    ExportedSet = Set;
+    ExportedMap = Map;
+  } else { // fall back to our polyfill
+    ExportedSet = Set$1;
+    ExportedMap = Map$1;
+  }
+}
 
-var _snapshots = __webpack_require__(784);
 
-var _logger = _interopRequireDefault(__webpack_require__(703));
 
-var _types = __webpack_require__(610);
 
-var _queries = __webpack_require__(723);
+/***/ }),
+/* 510 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-var _jsonStableStringify = _interopRequireDefault(__webpack_require__(785));
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "UNAUTHORIZED": () => (/* binding */ UNAUTHORIZED),
+/* harmony export */   "MISSING_BULK_DOCS": () => (/* binding */ MISSING_BULK_DOCS),
+/* harmony export */   "MISSING_DOC": () => (/* binding */ MISSING_DOC),
+/* harmony export */   "REV_CONFLICT": () => (/* binding */ REV_CONFLICT),
+/* harmony export */   "INVALID_ID": () => (/* binding */ INVALID_ID),
+/* harmony export */   "MISSING_ID": () => (/* binding */ MISSING_ID),
+/* harmony export */   "RESERVED_ID": () => (/* binding */ RESERVED_ID),
+/* harmony export */   "NOT_OPEN": () => (/* binding */ NOT_OPEN),
+/* harmony export */   "UNKNOWN_ERROR": () => (/* binding */ UNKNOWN_ERROR),
+/* harmony export */   "BAD_ARG": () => (/* binding */ BAD_ARG),
+/* harmony export */   "INVALID_REQUEST": () => (/* binding */ INVALID_REQUEST),
+/* harmony export */   "QUERY_PARSE_ERROR": () => (/* binding */ QUERY_PARSE_ERROR),
+/* harmony export */   "DOC_VALIDATION": () => (/* binding */ DOC_VALIDATION),
+/* harmony export */   "BAD_REQUEST": () => (/* binding */ BAD_REQUEST),
+/* harmony export */   "NOT_AN_OBJECT": () => (/* binding */ NOT_AN_OBJECT),
+/* harmony export */   "DB_MISSING": () => (/* binding */ DB_MISSING),
+/* harmony export */   "WSQ_ERROR": () => (/* binding */ WSQ_ERROR),
+/* harmony export */   "LDB_ERROR": () => (/* binding */ LDB_ERROR),
+/* harmony export */   "FORBIDDEN": () => (/* binding */ FORBIDDEN),
+/* harmony export */   "INVALID_REV": () => (/* binding */ INVALID_REV),
+/* harmony export */   "FILE_EXISTS": () => (/* binding */ FILE_EXISTS),
+/* harmony export */   "MISSING_STUB": () => (/* binding */ MISSING_STUB),
+/* harmony export */   "IDB_ERROR": () => (/* binding */ IDB_ERROR),
+/* harmony export */   "INVALID_URL": () => (/* binding */ INVALID_URL),
+/* harmony export */   "createError": () => (/* binding */ createError),
+/* harmony export */   "generateErrorFromResponse": () => (/* binding */ generateErrorFromResponse)
+/* harmony export */ });
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(497);
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__);
 
-var _promiseCache = _interopRequireDefault(__webpack_require__(789));
 
-var _flagshipCertification = __webpack_require__(790);
+inherits__WEBPACK_IMPORTED_MODULE_0___default()(PouchError, Error);
 
-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 PouchError(status, error, reason) {
+  Error.call(this, reason);
+  this.status = status;
+  this.name = error;
+  this.message = reason;
+  this.error = true;
+}
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+PouchError.prototype.toString = function () {
+  return JSON.stringify({
+    status: this.status,
+    name: this.name,
+    message: this.message,
+    reason: this.reason
+  });
+};
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect.");
+var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'");
+var MISSING_DOC = new PouchError(404, 'not_found', 'missing');
+var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict');
+var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string');
+var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts');
+var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.');
+var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open');
+var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error');
+var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid');
+var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid');
+var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid');
+var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member');
+var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request');
+var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object');
+var DB_MISSING = new PouchError(404, 'not_found', 'Database not found');
+var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown');
+var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown');
+var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown');
+var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function');
+var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format');
+var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.');
+var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found');
+var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid');
 
-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 createError(error, reason) {
+  function CustomPouchError(reason) {
+    // inherit error properties from our parent error manually
+    // so as to allow proper JSON parsing.
+    /* jshint ignore:start */
+    for (var p in error) {
+      if (typeof error[p] !== 'function') {
+        this[p] = error[p];
+      }
+    }
+    /* jshint ignore:end */
+    if (reason !== undefined) {
+      this.reason = reason;
+    }
+  }
+  CustomPouchError.prototype = PouchError.prototype;
+  return new CustomPouchError(reason);
+}
 
-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 generateErrorFromResponse(err) {
 
-var ensureArray = function ensureArray(arr) {
-  return Array.isArray(arr) ? arr : [arr];
-};
+  if (typeof err !== 'object') {
+    var data = err;
+    err = UNKNOWN_ERROR;
+    err.data = data;
+  }
 
-var deprecatedHandler = function deprecatedHandler(msg) {
-  return {
-    get: function get(target, prop) {
-      console.warn(msg);
-      return target[prop];
-    }
-  };
-};
+  if ('error' in err && err.error === 'conflict') {
+    err.name = 'conflict';
+    err.status = 409;
+  }
 
-var supportsReferences = function supportsReferences(relationshipClass) {
-  return relationshipClass.prototype.addReferences && relationshipClass.prototype.removeReferences;
-};
+  if (!('name' in err)) {
+    err.name = err.error || 'unknown';
+  }
 
-var referencesUnsupportedError = function referencesUnsupportedError(relationshipClassName) {
-  return new Error("The \"".concat(relationshipClassName, "\" relationship does not support references. If you need to add references to a document, its relationship class must have the methods {add,remove}References"));
-};
+  if (!('status' in err)) {
+    err.status = 500;
+  }
 
-var DOC_CREATION = 'creation';
-var DOC_UPDATE = 'update';
-/**
- * @typedef {object} ClientOptions
- * @property {object} [client]
- * @property {object} [link]
- * @property {object} [links]
- * @property {Token} [token]
- * @property {string} [uri]
- * @property {object} [stackClient]
- * @property {boolean} [warningForCustomHandlers]
- * @property {boolean} [autoHydrate]
- * @property {object} [oauth]
- * @property {Function} [onTokenRefresh]
- * @property {Function} [onError] - Default callback if a query is errored
- * @property  {Link}         [link]   - Backward compatibility
- * @property  {Array<Link>}  [links]  - List of links
- * @property  {object}       [schema] - Schema description for each doctypes
- * @property  {AppMetadata}  [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata
- * @property  {ClientCapabilities} [capabilities] - Capabilities sent by the stack
- * @property  {boolean} [store] - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information.
- */
+  if (!('message' in err)) {
+    err.message = err.message || err.reason;
+  }
 
-/**
- * Responsible for
- *
- * - Creating observable queries
- * - Hydration
- * - Creating plan for saving documents
- * - Associations
- */
+  return err;
+}
 
-var CozyClient = /*#__PURE__*/function () {
-  /**
-   * @param  {ClientOptions} rawOptions - Options
-   *
-   * @example
-   * ```js
-   * const client = new CozyClient({
-   *   schema: {
-   *     todos: {
-   *       doctype: 'io.cozy.todos',
-   *       relationships: {
-   *         authors: {
-   *           type: 'has-many',
-   *           doctype: 'io.cozy.persons'
-   *         }
-   *       }
-   *     }
-   *   }
-   * })
-   * ```
-   *
-   * Cozy-Client will automatically call `this.login()` if provided with a token and an uri
-   */
-  function CozyClient() {
-    var _this = this;
 
-    var rawOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-    (0, _classCallCheck2.default)(this, CozyClient);
-    (0, _defineProperty2.default)(this, "fetchQueryAndGetFromState", /*#__PURE__*/function () {
-      var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query) {
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                _context.prev = 0;
-                _context.next = 3;
-                return _this.query(query.definition, query.options);
 
-              case 3:
-                return _context.abrupt("return", _this.getQueryFromState(query.options.as));
 
-              case 6:
-                _context.prev = 6;
-                _context.t0 = _context["catch"](0);
-                throw _context.t0;
+/***/ }),
+/* 511 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-              case 9:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, null, [[0, 6]]);
-      }));
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "binaryMd5": () => (/* binding */ binaryMd5),
+/* harmony export */   "stringMd5": () => (/* binding */ stringMd5)
+/* harmony export */ });
+/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76);
+/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_0__);
 
-      return function (_x) {
-        return _ref.apply(this, arguments);
-      };
-    }());
-    var link = rawOptions.link,
-        links = rawOptions.links,
-        _rawOptions$schema = rawOptions.schema,
-        schema = _rawOptions$schema === void 0 ? {} : _rawOptions$schema,
-        _rawOptions$appMetada = rawOptions.appMetadata,
-        appMetadata = _rawOptions$appMetada === void 0 ? {} : _rawOptions$appMetada,
-        capabilities = rawOptions.capabilities,
-        options = (0, _objectWithoutProperties2.default)(rawOptions, ["link", "links", "schema", "appMetadata", "capabilities"]);
 
-    if (link) {
-      console.warn('`link` is deprecated, use `links`');
-    }
+function binaryMd5(data, callback) {
+  var base64 = crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(data, 'binary').digest('base64');
+  callback(base64);
+}
 
-    this.appMetadata = appMetadata;
-    this.options = options;
-    this.queryIdGenerator = new _queries.QueryIDGenerator();
-    this.isLogged = false;
-    this.instanceOptions = {}; // Bind handlers
+function stringMd5(string) {
+  return crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(string, 'binary').digest('hex');
+}
 
-    this.handleRevocationChange = this.handleRevocationChange.bind(this);
-    this.handleTokenRefresh = this.handleTokenRefresh.bind(this);
-    this.createClient();
-    var stackClient = this.getStackClient();
-    stackClient.on('error', function () {
-      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
-        args[_key] = arguments[_key];
-      }
 
-      return _this.emit.apply(_this, ['error'].concat(args));
-    });
-    this.links = ensureArray(link || links || new _StackLink.default());
-    this.registerClientOnLinks();
-    this.chain = (0, _CozyLink.chain)(this.links);
-    this.schema = new _Schema.default(schema, stackClient);
-    /**
-     * @type {ClientCapabilities}
-     */
 
-    this.capabilities = capabilities || null; // Instances of plugins registered with registerPlugin
 
-    this.plugins = {};
+/***/ }),
+/* 512 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-    try {
-      this.loadInstanceOptionsFromDOM();
-    } catch (err) {// not a critical error, we may be in node or the instance options are not on the default HTML element
-    }
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "fetch": () => (/* binding */ fetch),
+/* harmony export */   "Headers": () => (/* binding */ Headers),
+/* harmony export */   "AbortController": () => (/* binding */ AbortController)
+/* harmony export */ });
+/* harmony import */ var node_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(493);
+/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(513);
+/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fetch_cookie__WEBPACK_IMPORTED_MODULE_1__);
 
-    if (options.uri && options.token) {
-      this.login();
-    }
-    /**
-     * @type {object}
-     */
 
 
-    this.storeAccesors = null;
+var fetch = fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default()(node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"]);
 
-    if (options.store !== false) {
-      this.ensureStore();
-    }
-    /**
-     * Holds in-flight promises for deduplication purpose
-     *
-     * @private
-     * @type {PromiseCache}
-     */
+/* We can fake the abort, the http adapter keeps track
+   of ignoring the result */
+function AbortController() {
+  return {abort: function () {}};
+}
 
+var Headers = node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"].Headers;
 
-    this._promiseCache = new _promiseCache.default();
-  }
-  /**
-   * Gets overrided by MicroEE.mixin
-   * This is here just so typescript does not scream
-   *
-   * TODO Find a better way to make TS understand that emit is
-   * a method from cozy-client
-   */
 
 
-  (0, _createClass2.default)(CozyClient, [{
-    key: "emit",
-    value: function emit() {}
-  }, {
-    key: "on",
-    value: function on() {}
-  }, {
-    key: "removeListener",
-    value: function removeListener() {}
-    /**
-     * A plugin is a class whose constructor receives the client as first argument.
-     * The main mean of interaction with the client should be with events
-     * like "login"/"logout".
-     *
-     * The plugin system is meant to encourage separation of concerns, modularity
-     * and testability : instead of registering events at module level, please
-     * create a plugin that subscribes to events.
-     *
-     * Plugin instances are stored internally in the `plugins` attribute of the client
-     * and can be accessed via this mean. A plugin class must have the attribute
-     * `pluginName` that will be use as the key in the `plugins` object.
-     *
-     * Two plugins with the same `pluginName` cannot co-exist.
-     *
-     * @example
-     * ```js
-     * class AlertPlugin {
-     *   constructor(client, options) {
-     *     this.client = client
-     *     this.options = options
-     *     this.handleLogin = this.handleLogin.bind(this)
-     *     this.handleLogout = this.handleLogout.bind(this)
-     *     this.client.on("login", this.handleLogin)
-     *     this.client.on("logout", this.handleLogout)
-     *   }
-     *
-     *   handleLogin() {
-     *     alert(this.options.onLoginAlert)
-     *   }
-     *
-     *   handleLogout() {
-     *     alert(this.options.onLogoutAlert)
-     *   }
-     * }
-     *
-     * AlertPlugin.pluginName = 'alerts'
-     *
-     * client.registerPlugin(AlertPlugin, {
-     *   onLoginAlert: 'client has logged in !',
-     *   onLogoutAlert: 'client has logged out !'
-     * })
-     *
-     * // the instance of the plugin is accessible via
-     * client.plugins.alerts
-     * ```
-     */
 
-  }, {
-    key: "registerPlugin",
-    value: function registerPlugin(Plugin, options) {
-      if (!Plugin.pluginName) {
-        throw new Error('Cannot register a plugin whose class does not have `pluginName` attribute.');
-      }
+/***/ }),
+/* 513 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      if (this.plugins[Plugin.pluginName]) {
-        throw new Error("Cannot register plugin ".concat(Plugin.pluginName, ". A plugin with the same name has already been registered."));
-      }
+var denodeify = __webpack_require__(514)(Promise)
+var tough = __webpack_require__(61)
 
-      var instance = new Plugin(this, options);
-      this.plugins[Plugin.pluginName] = instance;
-      return instance;
-    }
-    /**
-     * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate
-     * a client with a cookie-based instance of cozy-client-js.
-     *
-     * @param {OldCozyClient} oldClient - An instance of the deprecated cozy-client
-     * @param {object} options - CozyStackClient options
-     * @returns {CozyClient}
-     */
+module.exports = function fetchCookieDecorator (fetch, jar) {
+  fetch = fetch || window.fetch
+  jar = jar || new tough.CookieJar()
 
-  }, {
-    key: "addSchema",
-    value: function addSchema(schemaDefinition) {
-      this.schema.add(schemaDefinition);
-    }
-  }, {
-    key: "registerClientOnLinks",
-    value: function registerClientOnLinks() {
-      var _iterator = _createForOfIteratorHelper(this.links),
-          _step;
+  var getCookieString = denodeify(jar.getCookieString.bind(jar))
+  var setCookie = denodeify(jar.setCookie.bind(jar))
 
-      try {
-        for (_iterator.s(); !(_step = _iterator.n()).done;) {
-          var link = _step.value;
+  return function fetchCookie (url, opts) {
+    opts = opts || {}
 
-          if (link.registerClient) {
-            try {
-              link.registerClient(this);
-            } catch (e) {
-              console.warn(e);
-            }
-          }
-        }
-      } catch (err) {
-        _iterator.e(err);
-      } finally {
-        _iterator.f();
-      }
-    }
-    /**
-     * Notify the links that they can start and set isLogged to true.
-     *
-     * On mobile, where url/token are set after instantiation, use this method
-     * to set the token and uri via options.
-     *
-     * Emits
-     *
-     * - "beforeLogin" at the beginning, before links have been set up
-     * - "login" when the client is fully logged in and links have been set up
-     *
-     * @param  {object}   [options] - Options
-     * @param  {string}   options.token  - If passed, the token is set on the client
-     * @param  {string}   options.uri  - If passed, the uri is set on the client
-     * @returns {Promise} - Resolves when all links have been setup and client is fully logged in
-     *
-     */
+    return getCookieString(url)
+      .then(function (cookie) {
+        return fetch(url, Object.assign(opts, {
+          headers: Object.assign(opts.headers || {}, (cookie ? { cookie: cookie } : {}))
+        }))
+      })
+      .then(function (res) {
+        var cookies
 
-  }, {
-    key: "login",
-    value: function login(options) {
-      // Keep the promise to be able to return it in future calls.
-      // This allows us to autoLogin in constructor without breaking any compatibility
-      // with codes that uses an explicit login.
-      if (this.isLogged && !this.isRevoked) {
-        console.warn("CozyClient is already logged.");
-        return this.loginPromise;
-      }
+        if (res.headers.getAll) {
+          // node-fetch v1
+          cookies = res.headers.getAll('set-cookie')
+        } else {
+          // node-fetch v2
+          var cookie = res.headers.get('set-cookie')
+          cookies = cookie && cookie.split(',') || []
+        }
 
-      return this.loginPromise = this._login(options);
-    }
-  }, {
-    key: "_login",
-    value: function () {
-      var _login2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(options) {
-        var _iterator2, _step2, link;
+        if (!cookies.length) {
+          return res
+        }
 
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                this.emit('beforeLogin');
-                this.registerClientOnLinks();
+        return Promise.all(cookies.map(function (cookie) {
+          return setCookie(cookie, res.url)
+        })).then(function () {
+          return res
+        })
+      })
+  }
+}
 
-                if (options) {
-                  if (options.uri) {
-                    this.stackClient.setUri(options.uri);
-                  }
 
-                  if (options.token) {
-                    this.stackClient.setToken(options.token);
-                  }
-                }
+/***/ }),
+/* 514 */
+/***/ ((module, exports) => {
 
-                _iterator2 = _createForOfIteratorHelper(this.links);
-                _context2.prev = 4;
+"use strict";
 
-                _iterator2.s();
 
-              case 6:
-                if ((_step2 = _iterator2.n()).done) {
-                  _context2.next = 13;
-                  break;
-                }
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
 
-                link = _step2.value;
+exports["default"] = function () {
+  var PromiseArg = arguments[0] === undefined ? Promise : arguments[0];
+  return function (f) {
+    return function () {
+      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+        args[_key] = arguments[_key];
+      }
 
-                if (!link.onLogin) {
-                  _context2.next = 11;
-                  break;
-                }
+      return new PromiseArg(function (resolve, reject) {
+        return f.apply(undefined, args.concat([function (err, val) {
+          return err ? reject(err) : resolve(val);
+        }]));
+      });
+    };
+  };
+};
 
-                _context2.next = 11;
-                return link.onLogin();
+module.exports = exports["default"];
 
-              case 11:
-                _context2.next = 6;
-                break;
 
-              case 13:
-                _context2.next = 18;
-                break;
 
-              case 15:
-                _context2.prev = 15;
-                _context2.t0 = _context2["catch"](4);
+/***/ }),
+/* 515 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-                _iterator2.e(_context2.t0);
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "massageSelector": () => (/* binding */ massageSelector),
+/* harmony export */   "matchesSelector": () => (/* binding */ matchesSelector),
+/* harmony export */   "filterInMemoryFields": () => (/* binding */ filterInMemoryFields),
+/* harmony export */   "createFieldSorter": () => (/* binding */ createFieldSorter),
+/* harmony export */   "rowFilter": () => (/* binding */ rowFilter),
+/* harmony export */   "isCombinationalField": () => (/* binding */ isCombinationalField),
+/* harmony export */   "getKey": () => (/* binding */ getKey),
+/* harmony export */   "getValue": () => (/* binding */ getValue),
+/* harmony export */   "getFieldFromDoc": () => (/* binding */ getFieldFromDoc),
+/* harmony export */   "setFieldInDoc": () => (/* binding */ setFieldInDoc),
+/* harmony export */   "compare": () => (/* binding */ compare),
+/* harmony export */   "parseField": () => (/* binding */ parseField)
+/* harmony export */ });
+/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507);
+/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(516);
 
-              case 18:
-                _context2.prev = 18;
 
-                _iterator2.f();
 
-                return _context2.finish(18);
+// this would just be "return doc[field]", but fields
+// can be "deep" due to dot notation
+function getFieldFromDoc(doc, parsedField) {
+  var value = doc;
+  for (var i = 0, len = parsedField.length; i < len; i++) {
+    var key = parsedField[i];
+    value = value[key];
+    if (!value) {
+      break;
+    }
+  }
+  return value;
+}
 
-              case 21:
-                this.isLogged = true;
-                this.isRevoked = false;
-                this.emit('login');
+function setFieldInDoc(doc, parsedField, value) {
+  for (var i = 0, len = parsedField.length; i < len-1; i++) {
+    var elem = parsedField[i];
+    doc = doc[elem] = {};
+  }
+  doc[parsedField[len-1]] = value;
+}
 
-              case 24:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this, [[4, 15, 18, 21]]);
-      }));
+function compare(left, right) {
+  return left < right ? -1 : left > right ? 1 : 0;
+}
 
-      function _login(_x2) {
-        return _login2.apply(this, arguments);
+// Converts a string in dot notation to an array of its components, with backslash escaping
+function parseField(fieldName) {
+  // fields may be deep (e.g. "foo.bar.baz"), so parse
+  var fields = [];
+  var current = '';
+  for (var i = 0, len = fieldName.length; i < len; i++) {
+    var ch = fieldName[i];
+    if (ch === '.') {
+      if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter
+        current = current.substring(0, current.length - 1) + '.';
+      } else { // not escaped, so delimiter
+        fields.push(current);
+        current = '';
       }
+    } else { // normal character
+      current += ch;
+    }
+  }
+  fields.push(current);
+  return fields;
+}
 
-      return _login;
-    }()
-    /**
-     * Logs out the client and reset all the links
-     *
-     * Emits
-     *
-     * - "beforeLogout" at the beginning, before links have been reset
-     * - "login" when the client is fully logged out and links have been reset
-     *
-     * @returns {Promise} - Resolves when all links have been reset and client is fully logged out
-     */
-
-  }, {
-    key: "logout",
-    value: function () {
-      var _logout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
-        var _iterator3, _step3, link;
+var combinationFields = ['$or', '$nor', '$not'];
+function isCombinationalField(field) {
+  return combinationFields.indexOf(field) > -1;
+}
 
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                if (this.isLogged) {
-                  _context3.next = 3;
-                  break;
-                }
+function getKey(obj) {
+  return Object.keys(obj)[0];
+}
 
-                _logger.default.warn("CozyClient isn't logged.");
+function getValue(obj) {
+  return obj[getKey(obj)];
+}
 
-                return _context3.abrupt("return");
 
-              case 3:
-                this.emit('beforeLogout');
-                this.isLogged = false;
+// flatten an array of selectors joined by an $and operator
+function mergeAndedSelectors(selectors) {
 
-                if (!(this.stackClient instanceof _cozyStackClient.OAuthClient)) {
-                  _context3.next = 17;
-                  break;
-                }
+  // sort to ensure that e.g. if the user specified
+  // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into
+  // just {$gt: 'b'}
+  var res = {};
 
-                _context3.prev = 6;
+  selectors.forEach(function (selector) {
+    Object.keys(selector).forEach(function (field) {
+      var matcher = selector[field];
+      if (typeof matcher !== 'object') {
+        matcher = {$eq: matcher};
+      }
 
-                if (!(this.stackClient.unregister && (!this.stackClient.isRegistered || this.stackClient.isRegistered()))) {
-                  _context3.next = 10;
-                  break;
-                }
+      if (isCombinationalField(field)) {
+        if (matcher instanceof Array) {
+          res[field] = matcher.map(function (m) {
+            return mergeAndedSelectors([m]);
+          });
+        } else {
+          res[field] = mergeAndedSelectors([matcher]);
+        }
+      } else {
+        var fieldMatchers = res[field] = res[field] || {};
+        Object.keys(matcher).forEach(function (operator) {
+          var value = matcher[operator];
 
-                _context3.next = 10;
-                return this.stackClient.unregister();
+          if (operator === '$gt' || operator === '$gte') {
+            return mergeGtGte(operator, value, fieldMatchers);
+          } else if (operator === '$lt' || operator === '$lte') {
+            return mergeLtLte(operator, value, fieldMatchers);
+          } else if (operator === '$ne') {
+            return mergeNe(value, fieldMatchers);
+          } else if (operator === '$eq') {
+            return mergeEq(value, fieldMatchers);
+          }
+          fieldMatchers[operator] = value;
+        });
+      }
+    });
+  });
 
-              case 10:
-                _context3.next = 15;
-                break;
+  return res;
+}
 
-              case 12:
-                _context3.prev = 12;
-                _context3.t0 = _context3["catch"](6);
 
-                _logger.default.warn("Impossible to unregister client on stack: ".concat(_context3.t0));
 
-              case 15:
-                _context3.next = 25;
-                break;
+// collapse logically equivalent gt/gte values
+function mergeGtGte(operator, value, fieldMatchers) {
+  if (typeof fieldMatchers.$eq !== 'undefined') {
+    return; // do nothing
+  }
+  if (typeof fieldMatchers.$gte !== 'undefined') {
+    if (operator === '$gte') {
+      if (value > fieldMatchers.$gte) { // more specificity
+        fieldMatchers.$gte = value;
+      }
+    } else { // operator === '$gt'
+      if (value >= fieldMatchers.$gte) { // more specificity
+        delete fieldMatchers.$gte;
+        fieldMatchers.$gt = value;
+      }
+    }
+  } else if (typeof fieldMatchers.$gt !== 'undefined') {
+    if (operator === '$gte') {
+      if (value > fieldMatchers.$gt) { // more specificity
+        delete fieldMatchers.$gt;
+        fieldMatchers.$gte = value;
+      }
+    } else { // operator === '$gt'
+      if (value > fieldMatchers.$gt) { // more specificity
+        fieldMatchers.$gt = value;
+      }
+    }
+  } else {
+    fieldMatchers[operator] = value;
+  }
+}
 
-              case 17:
-                _context3.prev = 17;
-                _context3.next = 20;
-                return this.stackClient.fetch('DELETE', '/auth/login');
+// collapse logically equivalent lt/lte values
+function mergeLtLte(operator, value, fieldMatchers) {
+  if (typeof fieldMatchers.$eq !== 'undefined') {
+    return; // do nothing
+  }
+  if (typeof fieldMatchers.$lte !== 'undefined') {
+    if (operator === '$lte') {
+      if (value < fieldMatchers.$lte) { // more specificity
+        fieldMatchers.$lte = value;
+      }
+    } else { // operator === '$gt'
+      if (value <= fieldMatchers.$lte) { // more specificity
+        delete fieldMatchers.$lte;
+        fieldMatchers.$lt = value;
+      }
+    }
+  } else if (typeof fieldMatchers.$lt !== 'undefined') {
+    if (operator === '$lte') {
+      if (value < fieldMatchers.$lt) { // more specificity
+        delete fieldMatchers.$lt;
+        fieldMatchers.$lte = value;
+      }
+    } else { // operator === '$gt'
+      if (value < fieldMatchers.$lt) { // more specificity
+        fieldMatchers.$lt = value;
+      }
+    }
+  } else {
+    fieldMatchers[operator] = value;
+  }
+}
 
-              case 20:
-                _context3.next = 25;
-                break;
+// combine $ne values into one array
+function mergeNe(value, fieldMatchers) {
+  if ('$ne' in fieldMatchers) {
+    // there are many things this could "not" be
+    fieldMatchers.$ne.push(value);
+  } else { // doesn't exist yet
+    fieldMatchers.$ne = [value];
+  }
+}
 
-              case 22:
-                _context3.prev = 22;
-                _context3.t1 = _context3["catch"](17);
+// add $eq into the mix
+function mergeEq(value, fieldMatchers) {
+  // these all have less specificity than the $eq
+  // TODO: check for user errors here
+  delete fieldMatchers.$gt;
+  delete fieldMatchers.$gte;
+  delete fieldMatchers.$lt;
+  delete fieldMatchers.$lte;
+  delete fieldMatchers.$ne;
+  fieldMatchers.$eq = value;
+}
 
-                _logger.default.warn("Impossible to log out: ".concat(_context3.t1));
 
-              case 25:
-                // clean information on links
-                _iterator3 = _createForOfIteratorHelper(this.links);
-                _context3.prev = 26;
+//
+// normalize the selector
+//
+function massageSelector(input) {
+  var result = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(input);
+  var wasAnded = false;
+  if ('$and' in result) {
+    result = mergeAndedSelectors(result['$and']);
+    wasAnded = true;
+  }
 
-                _iterator3.s();
+  ['$or', '$nor'].forEach(function (orOrNor) {
+    if (orOrNor in result) {
+      // message each individual selector
+      // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}}
+      result[orOrNor].forEach(function (subSelector) {
+        var fields = Object.keys(subSelector);
+        for (var i = 0; i < fields.length; i++) {
+          var field = fields[i];
+          var matcher = subSelector[field];
+          if (typeof matcher !== 'object' || matcher === null) {
+            subSelector[field] = {$eq: matcher};
+          }
+        }
+      });
+    }
+  });
 
-              case 28:
-                if ((_step3 = _iterator3.n()).done) {
-                  _context3.next = 41;
-                  break;
-                }
+  if ('$not' in result) {
+    //This feels a little like forcing, but it will work for now,
+    //I would like to come back to this and make the merging of selectors a little more generic
+    result['$not'] = mergeAndedSelectors([result['$not']]);
+  }
 
-                link = _step3.value;
+  var fields = Object.keys(result);
 
-                if (!link.reset) {
-                  _context3.next = 39;
-                  break;
-                }
+  for (var i = 0; i < fields.length; i++) {
+    var field = fields[i];
+    var matcher = result[field];
 
-                _context3.prev = 31;
-                _context3.next = 34;
-                return link.reset();
+    if (typeof matcher !== 'object' || matcher === null) {
+      matcher = {$eq: matcher};
+    } else if ('$ne' in matcher && !wasAnded) {
+      // I put these in an array, since there may be more than one
+      // but in the "mergeAnded" operation, I already take care of that
+      matcher.$ne = [matcher.$ne];
+    }
+    result[field] = matcher;
+  }
 
-              case 34:
-                _context3.next = 39;
-                break;
+  return result;
+}
 
-              case 36:
-                _context3.prev = 36;
-                _context3.t2 = _context3["catch"](31);
-                console.warn(_context3.t2);
+// create a comparator based on the sort object
+function createFieldSorter(sort) {
 
-              case 39:
-                _context3.next = 28;
-                break;
+  function getFieldValuesAsArray(doc) {
+    return sort.map(function (sorting) {
+      var fieldName = getKey(sorting);
+      var parsedField = parseField(fieldName);
+      var docFieldValue = getFieldFromDoc(doc, parsedField);
+      return docFieldValue;
+    });
+  }
 
-              case 41:
-                _context3.next = 46;
-                break;
+  return function (aRow, bRow) {
+    var aFieldValues = getFieldValuesAsArray(aRow.doc);
+    var bFieldValues = getFieldValuesAsArray(bRow.doc);
+    var collation = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(aFieldValues, bFieldValues);
+    if (collation !== 0) {
+      return collation;
+    }
+    // this is what mango seems to do
+    return compare(aRow.doc._id, bRow.doc._id);
+  };
+}
 
-              case 43:
-                _context3.prev = 43;
-                _context3.t3 = _context3["catch"](26);
+function filterInMemoryFields(rows, requestDef, inMemoryFields) {
+  rows = rows.filter(function (row) {
+    return rowFilter(row.doc, requestDef.selector, inMemoryFields);
+  });
 
-                _iterator3.e(_context3.t3);
+  if (requestDef.sort) {
+    // in-memory sort
+    var fieldSorter = createFieldSorter(requestDef.sort);
+    rows = rows.sort(fieldSorter);
+    if (typeof requestDef.sort[0] !== 'string' &&
+        getValue(requestDef.sort[0]) === 'desc') {
+      rows = rows.reverse();
+    }
+  }
 
-              case 46:
-                _context3.prev = 46;
+  if ('limit' in requestDef || 'skip' in requestDef) {
+    // have to do the limit in-memory
+    var skip = requestDef.skip || 0;
+    var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip;
+    rows = rows.slice(skip, limit);
+  }
+  return rows;
+}
 
-                _iterator3.f();
+function rowFilter(doc, selector, inMemoryFields) {
+  return inMemoryFields.every(function (field) {
+    var matcher = selector[field];
+    var parsedField = parseField(field);
+    var docFieldValue = getFieldFromDoc(doc, parsedField);
+    if (isCombinationalField(field)) {
+      return matchCominationalSelector(field, matcher, doc);
+    }
 
-                return _context3.finish(46);
+    return matchSelector(matcher, doc, parsedField, docFieldValue);
+  });
+}
 
-              case 49:
-                if (this.store) {
-                  this.dispatch((0, _store.resetState)());
-                }
+function matchSelector(matcher, doc, parsedField, docFieldValue) {
+  if (!matcher) {
+    // no filtering necessary; this field is just needed for sorting
+    return true;
+  }
 
-                this.emit('logout');
+  return Object.keys(matcher).every(function (userOperator) {
+    var userValue = matcher[userOperator];
+    return match(userOperator, doc, userValue, parsedField, docFieldValue);
+  });
+}
 
-              case 51:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this, [[6, 12], [17, 22], [26, 43, 46, 49], [31, 36]]);
-      }));
+function matchCominationalSelector(field, matcher, doc) {
 
-      function logout() {
-        return _logout.apply(this, arguments);
-      }
+  if (field === '$or') {
+    return matcher.some(function (orMatchers) {
+      return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+    });
+  }
 
-      return logout;
-    }()
-    /**
-     * Forwards to a stack client instance and returns
-     * a [DocumentCollection]{@link https://docs.cozy.io/en/cozy-client/api/cozy-stack-client/#DocumentCollection} instance.
-     *
-     * @param  {string} doctype The collection doctype.
-     * @returns {DocumentCollection} Collection corresponding to the doctype
-     */
+  if (field === '$not') {
+    return !rowFilter(doc, matcher, Object.keys(matcher));
+  }
 
-  }, {
-    key: "collection",
-    value: function collection(doctype) {
-      return this.getStackClient().collection(doctype);
-    }
-  }, {
-    key: "fetch",
-    value: function fetch(method, path, body) {
-      var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-      return this.getStackClient().fetch(method, path, body, options);
-    }
-  }, {
-    key: "all",
-    value: function all(doctype) {
-      _logger.default.warn("\nclient.all is deprecated, prefer to use the Q helper to build a new QueryDefinition.\n\nimport { Q } from 'cozy-client'\nclient.query(Q('io.cozy.bills'))");
+  //`$nor`
+  return !matcher.find(function (orMatchers) {
+    return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+  });
 
-      return (0, _dsl.Q)(doctype);
-    }
-  }, {
-    key: "find",
-    value: function find(doctype) {
-      var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
-      console.warn('client.find(doctype, selector) is deprecated, please use Q(doctype).where(selector) to build the same query.');
-      return new _dsl.QueryDefinition({
-        doctype: doctype,
-        selector: selector
-      });
-    }
-  }, {
-    key: "get",
-    value: function get(doctype, id) {
-      console.warn("client.get(".concat(doctype, ", id) is deprecated, please use Q(").concat(doctype, ").getById(id) to build the same query."));
-      return new _dsl.QueryDefinition({
-        doctype: doctype,
-        id: id
-      });
-    }
-    /**
-     * Creates a document and saves it on the server
-     *
-     * @param  {string} type - Doctype of the document
-     * @param  {object} doc - Document to save
-     * @param  {ReferenceMap} [references] - References are a special kind of relationship
-     * that is not stored inside the referencer document, they are used for example between a photo
-     * and its album. You should not need to use it normally.
-     * @param  {object} options - Mutation options
-     *
-     * @example
-     * ```js
-     * await client.create('io.cozy.todos', {
-     *   label: 'My todo',
-     *   relationships: {
-     *     authors: {
-     *       data: [{_id: 1, _type: 'io.cozy.persons'}]
-     *     }
-     *   }
-     * })
-     * ```
-     *
-     * @returns {Promise}
-     */
+}
 
-  }, {
-    key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(type, doc, references) {
-        var options,
-            _type,
-            attributes,
-            normalizedDoc,
-            ret,
-            _args4 = arguments;
+function match(userOperator, doc, userValue, parsedField, docFieldValue) {
+  if (!matchers[userOperator]) {
+    throw new Error('unknown operator "' + userOperator +
+      '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' +
+      '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all');
+  }
+  return matchers[userOperator](doc, userValue, parsedField, docFieldValue);
+}
 
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {};
-                _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]);
-                normalizedDoc = _objectSpread({
-                  _type: type
-                }, attributes);
-                _context4.next = 5;
-                return this.schema.validate(normalizedDoc);
+function fieldExists(docFieldValue) {
+  return typeof docFieldValue !== 'undefined' && docFieldValue !== null;
+}
 
-              case 5:
-                ret = _context4.sent;
+function fieldIsNotUndefined(docFieldValue) {
+  return typeof docFieldValue !== 'undefined';
+}
 
-                if (!(ret !== true)) {
-                  _context4.next = 8;
-                  break;
-                }
+function modField(docFieldValue, userValue) {
+  var divisor = userValue[0];
+  var mod = userValue[1];
+  if (divisor === 0) {
+    throw new Error('Bad divisor, cannot divide by zero');
+  }
 
-                throw new Error('Validation failed');
+  if (parseInt(divisor, 10) !== divisor ) {
+    throw new Error('Divisor is not an integer');
+  }
 
-              case 8:
-                return _context4.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc, references), options));
+  if (parseInt(mod, 10) !== mod ) {
+    throw new Error('Modulus is not an integer');
+  }
 
-              case 9:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4, this);
-      }));
+  if (parseInt(docFieldValue, 10) !== docFieldValue) {
+    return false;
+  }
 
-      function create(_x3, _x4, _x5) {
-        return _create.apply(this, arguments);
-      }
+  return docFieldValue % divisor === mod;
+}
 
-      return create;
-    }()
-  }, {
-    key: "validate",
-    value: function validate(document) {
-      return this.schema.validate(document);
+function arrayContainsValue(docFieldValue, userValue) {
+  return userValue.some(function (val) {
+    if (docFieldValue instanceof Array) {
+      return docFieldValue.indexOf(val) > -1;
     }
-    /**
-     * Create or update a document on the server
-     *
-     * @param  {object} doc - Document to save
-     * @param  {object} mutationOptions - Mutation options
-     * @returns {Promise}
-     */
 
-  }, {
-    key: "save",
-    value: function () {
-      var _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(doc) {
-        var mutationOptions,
-            _type,
-            attributes,
-            normalizedDoc,
-            ret,
-            _args5 = arguments;
+    return docFieldValue === val;
+  });
+}
 
-        return _regenerator.default.wrap(function _callee5$(_context5) {
-          while (1) {
-            switch (_context5.prev = _context5.next) {
-              case 0:
-                mutationOptions = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
-                _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]);
+function arrayContainsAllValues(docFieldValue, userValue) {
+  return userValue.every(function (val) {
+    return docFieldValue.indexOf(val) > -1;
+  });
+}
 
-                if (_type) {
-                  _context5.next = 4;
-                  break;
-                }
+function arraySize(docFieldValue, userValue) {
+  return docFieldValue.length === userValue;
+}
 
-                throw new Error('The document must have a `_type` property');
+function regexMatch(docFieldValue, userValue) {
+  var re = new RegExp(userValue);
 
-              case 4:
-                normalizedDoc = _objectSpread({
-                  _type: _type
-                }, attributes);
-                _context5.next = 7;
-                return this.schema.validate(normalizedDoc);
+  return re.test(docFieldValue);
+}
 
-              case 7:
-                ret = _context5.sent;
+function typeMatch(docFieldValue, userValue) {
 
-                if (!(ret !== true)) {
-                  _context5.next = 10;
-                  break;
-                }
+  switch (userValue) {
+    case 'null':
+      return docFieldValue === null;
+    case 'boolean':
+      return typeof (docFieldValue) === 'boolean';
+    case 'number':
+      return typeof (docFieldValue) === 'number';
+    case 'string':
+      return typeof (docFieldValue) === 'string';
+    case 'array':
+      return docFieldValue instanceof Array;
+    case 'object':
+      return ({}).toString.call(docFieldValue) === '[object Object]';
+  }
 
-                throw new Error('Validation failed');
+  throw new Error(userValue + ' not supported as a type.' +
+                  'Please use one of object, string, array, number, boolean or null.');
 
-              case 10:
-                return _context5.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc), mutationOptions));
+}
 
-              case 11:
-              case "end":
-                return _context5.stop();
-            }
-          }
-        }, _callee5, this);
-      }));
+var matchers = {
 
-      function save(_x6) {
-        return _save.apply(this, arguments);
-      }
+  '$elemMatch': function (doc, userValue, parsedField, docFieldValue) {
+    if (!Array.isArray(docFieldValue)) {
+      return false;
+    }
 
-      return save;
-    }()
-    /**
-     * Saves multiple documents in one batch
-     * - Can only be called with documents from the same doctype
-     * - Does not support automatic creation of references
-     *
-     * @param  {CozyClientDocument[]} docs
-     * @param  {Object} mutationOptions
-     * @returns {Promise<void>}
-     */
+    if (docFieldValue.length === 0) {
+      return false;
+    }
 
-  }, {
-    key: "saveAll",
-    value: function () {
-      var _saveAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(docs) {
-        var _this2 = this;
+    if (typeof docFieldValue[0] === 'object') {
+      return docFieldValue.some(function (val) {
+        return rowFilter(val, userValue, Object.keys(userValue));
+      });
+    }
 
-        var mutationOptions,
-            doctypes,
-            validations,
-            errors,
-            toSaveDocs,
-            mutation,
-            _args6 = arguments;
-        return _regenerator.default.wrap(function _callee6$(_context6) {
-          while (1) {
-            switch (_context6.prev = _context6.next) {
-              case 0:
-                mutationOptions = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
-                doctypes = Array.from(new Set(docs.map(function (x) {
-                  return x._type;
-                })));
+    return docFieldValue.some(function (val) {
+      return matchSelector(userValue, doc, parsedField, val);
+    });
+  },
 
-                if (!(doctypes.length !== 1)) {
-                  _context6.next = 4;
-                  break;
-                }
+  '$allMatch': function (doc, userValue, parsedField, docFieldValue) {
+    if (!Array.isArray(docFieldValue)) {
+      return false;
+    }
 
-                throw new Error('saveAll can only save documents with the same doctype');
+    /* istanbul ignore next */
+    if (docFieldValue.length === 0) {
+      return false;
+    }
 
-              case 4:
-                _context6.next = 6;
-                return Promise.all(docs.map(function (d) {
-                  return _this2.schema.validate(d);
-                }));
+    if (typeof docFieldValue[0] === 'object') {
+      return docFieldValue.every(function (val) {
+        return rowFilter(val, userValue, Object.keys(userValue));
+      });
+    }
 
-              case 6:
-                validations = _context6.sent;
-                errors = validations.filter(function (validation) {
-                  return validation !== true;
-                });
+    return docFieldValue.every(function (val) {
+      return matchSelector(userValue, doc, parsedField, val);
+    });
+  },
 
-                if (!(errors.length > 0)) {
-                  _context6.next = 11;
-                  break;
-                }
+  '$eq': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) === 0;
+  },
 
-                console.warn('There has been some validation errors while bulk saving', errors);
-                throw new Error('Validation failed for at least one doc');
+  '$gte': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) >= 0;
+  },
 
-              case 11:
-                toSaveDocs = docs.map(function (d) {
-                  return _this2.prepareDocumentForSave(d);
-                });
-                mutation = _dsl.Mutations.updateDocuments(toSaveDocs);
-                return _context6.abrupt("return", this.mutate(mutation, mutationOptions));
+  '$gt': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) > 0;
+  },
 
-              case 14:
-              case "end":
-                return _context6.stop();
-            }
-          }
-        }, _callee6, this);
-      }));
+  '$lte': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) <= 0;
+  },
 
-      function saveAll(_x7) {
-        return _saveAll.apply(this, arguments);
-      }
+  '$lt': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) < 0;
+  },
 
-      return saveAll;
-    }()
-  }, {
-    key: "ensureCozyMetadata",
-    value: function ensureCozyMetadata(document) {
-      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
-        event: DOC_CREATION
-      };
-      var METADATA_VERSION = 1;
-      if (this.appMetadata === undefined) return document;
-      var doctypeVersion;
+  '$exists': function (doc, userValue, parsedField, docFieldValue) {
+    //a field that is null is still considered to exist
+    if (userValue) {
+      return fieldIsNotUndefined(docFieldValue);
+    }
 
-      if (document._type) {
-        var schema = this.schema.getDoctypeSchema(document._type);
-        doctypeVersion = (0, _get.default)(schema, 'doctypeVersion');
-      }
+    return !fieldIsNotUndefined(docFieldValue);
+  },
 
-      var _this$appMetadata = this.appMetadata,
-          slug = _this$appMetadata.slug,
-          sourceAccount = _this$appMetadata.sourceAccount,
-          version = _this$appMetadata.version;
-      var now = new Date().toISOString();
-      var cozyMetadata = (0, _get.default)(document, 'cozyMetadata', {});
+  '$mod': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && modField(docFieldValue, userValue);
+  },
 
-      if (options.event === DOC_CREATION) {
-        cozyMetadata = _objectSpread({
-          metadataVersion: METADATA_VERSION,
-          doctypeVersion: doctypeVersion,
-          createdByApp: slug,
-          sourceAccount: sourceAccount,
-          createdAt: now,
-          createdByAppVersion: version,
-          updatedAt: now,
-          updatedByApps: slug ? [{
-            date: now,
-            slug: slug,
-            version: version
-          }] : []
-        }, cozyMetadata);
-      } else if (options.event === DOC_UPDATE) {
-        cozyMetadata = _objectSpread(_objectSpread({}, cozyMetadata), {}, {
-          updatedAt: now,
-          updatedByApps: [{
-            date: now,
-            slug: slug,
-            version: version
-          }].concat((0, _toConsumableArray2.default)((0, _get.default)(document, 'cozyMetadata.updatedByApps', []).filter(function (info) {
-            return info.slug !== slug;
-          })))
-        });
-      }
+  '$ne': function (doc, userValue, parsedField, docFieldValue) {
+    return userValue.every(function (neValue) {
+      return (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, neValue) !== 0;
+    });
+  },
+  '$in': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue);
+  },
 
-      return _objectSpread(_objectSpread({}, document), {}, {
-        cozyMetadata: cozyMetadata
-      });
-    }
-    /**
-     * Dehydrates and adds metadata before saving a document
-     *
-     * @param  {CozyClientDocument} doc - Document that will be saved
-     * @returns {CozyClientDocument}
-     */
+  '$nin': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue);
+  },
 
-  }, {
-    key: "prepareDocumentForSave",
-    value: function prepareDocumentForSave(doc) {
-      var isNewDoc = !doc._rev;
-      var dehydratedDoc = this.ensureCozyMetadata((0, _helpers2.dehydrate)(doc), {
-        event: isNewDoc ? DOC_CREATION : DOC_UPDATE
-      });
-      return dehydratedDoc;
-    }
-    /**
-     * Creates a list of mutations to execute to create a document and its relationships.
-     *
-     * ```js
-     * const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' }
-     * // relations can be arrays or single objects
-     * const relationships = {
-     *   attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }],
-     *   bills: { _id: 9999, _type: 'io.cozy.bills' }
-     * }
-     * client.getDocumentSavePlan(baseDoc, relationships)
-     * ```
-     *
-     *
-     * @param  {object} document - Document to create
-     * @param  {ReferenceMap} [referencesByName] - References to the created document. The
-     * relationship class associated to each reference list should support references, otherwise this
-     * method will throw.
-     *
-     * @returns {Mutation[]|Mutation}  One or more mutation to execute
-     */
+  '$size': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue);
+  },
 
-  }, {
-    key: "getDocumentSavePlan",
-    value: function getDocumentSavePlan(document, referencesByName) {
-      var _this3 = this;
+  '$all': function (doc, userValue, parsedField, docFieldValue) {
+    return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue);
+  },
 
-      var isNewDoc = !document._rev;
-      var docToSave = this.prepareDocumentForSave(document);
-      var saveMutation = isNewDoc ? _dsl.Mutations.createDocument(docToSave) : _dsl.Mutations.updateDocument(docToSave);
-      var hasReferences = referencesByName && Object.values(referencesByName).filter(function (references) {
-        return Array.isArray(references) ? references.length > 0 : references;
-      }).length > 0;
+  '$regex': function (doc, userValue, parsedField, docFieldValue) {
+    return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue);
+  },
+
+  '$type': function (doc, userValue, parsedField, docFieldValue) {
+    return typeMatch(docFieldValue, userValue);
+  }
+};
+
+// return true if the given doc matches the supplied selector
+function matchesSelector(doc, selector) {
+  /* istanbul ignore if */
+  if (typeof selector !== 'object') {
+    // match the CouchDB error message
+    throw new Error('Selector error: expected a JSON object');
+  }
 
-      if (!hasReferences) {
-        return saveMutation;
-      } else {
-        for (var _i = 0, _Object$keys = Object.keys(referencesByName); _i < _Object$keys.length; _i++) {
-          var relName = _Object$keys[_i];
-          var doctype = document._type;
-          var doctypeRelationship = this.schema.getRelationship(doctype, relName);
-          var relationshipClass = doctypeRelationship.type;
+  selector = massageSelector(selector);
+  var row = {
+    'doc': doc
+  };
 
-          if (!supportsReferences(relationshipClass)) {
-            throw referencesUnsupportedError(doctypeRelationship.name);
-          }
-        }
-      }
+  var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector));
+  return rowsMatched && rowsMatched.length === 1;
+}
 
-      if (referencesByName && !isNewDoc) {
-        throw new Error('Unable to save external relationships on a not-new document');
-      }
 
-      return [saveMutation, function (response) {
-        var doc = _this3.hydrateDocument(response.data);
 
-        return Object.entries(referencesByName).map(function (_ref2) {
-          var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
-              relName = _ref3[0],
-              references = _ref3[1];
 
-          var relationship = doc[relName];
-          return relationship.addReferences(references);
-        });
-      }];
-    }
-    /**
-     * Hooks are an observable system for events on documents.
-     * There are at the moment only 2 hooks available.
-     *
-     * - before:destroy, called just before a document is destroyed via CozyClient::destroy
-     * - after:destroy, called after a document is destroyed via CozyClient::destroy
-     *
-     * @example
-     * ```
-     * CozyClient.registerHook('io.cozy.bank.accounts', 'before:destroy', () => {
-     *   console.log('A io.cozy.bank.accounts is being destroyed')
-     * })
-     * ```
-     *
-     * @param  {string}   doctype - Doctype on which the hook will be registered
-     * @param  {string}   name    - Name of the hook
-     * @param  {Function} fn      - Callback to be executed
-     */
+/***/ }),
+/* 516 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-  }, {
-    key: "triggerHook",
-    value: function triggerHook(name, document) {
-      if (!CozyClient.hooks) return;
-      var allHooks = CozyClient.hooks[document._type] || {};
-      var hooks = allHooks[name] || [];
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "collate": () => (/* binding */ collate),
+/* harmony export */   "normalizeKey": () => (/* binding */ normalizeKey),
+/* harmony export */   "toIndexableString": () => (/* binding */ toIndexableString),
+/* harmony export */   "parseIndexableString": () => (/* binding */ parseIndexableString)
+/* harmony export */ });
+function pad(str, padWith, upToLength) {
+  var padding = '';
+  var targetLength = upToLength - str.length;
+  /* istanbul ignore next */
+  while (padding.length < targetLength) {
+    padding += padWith;
+  }
+  return padding;
+}
 
-      var _iterator4 = _createForOfIteratorHelper(hooks),
-          _step4;
+function padLeft(str, padWith, upToLength) {
+  var padding = pad(str, padWith, upToLength);
+  return padding + str;
+}
 
-      try {
-        for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
-          var h = _step4.value;
-          h(this, document);
-        }
-      } catch (err) {
-        _iterator4.e(err);
-      } finally {
-        _iterator4.f();
-      }
-    }
-    /**
-     * Destroys a document. {before,after}:destroy hooks will be fired.
-     *
-     * @param  {CozyClientDocument} document - Document to be deleted
-     * @returns {Promise<CozyClientDocument>} The document that has been deleted
-     */
+var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
+var MAGNITUDE_DIGITS = 3; // ditto
+var SEP = ''; // set to '_' for easier debugging 
 
-  }, {
-    key: "destroy",
-    value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document) {
-        var mutationOptions,
-            res,
-            _args7 = arguments;
-        return _regenerator.default.wrap(function _callee7$(_context7) {
-          while (1) {
-            switch (_context7.prev = _context7.next) {
-              case 0:
-                mutationOptions = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};
-                _context7.next = 3;
-                return this.triggerHook('before:destroy', document);
+function collate(a, b) {
 
-              case 3:
-                _context7.next = 5;
-                return this.mutate(_dsl.Mutations.deleteDocument(document), mutationOptions);
+  if (a === b) {
+    return 0;
+  }
 
-              case 5:
-                res = _context7.sent;
-                _context7.next = 8;
-                return this.triggerHook('after:destroy', document);
+  a = normalizeKey(a);
+  b = normalizeKey(b);
 
-              case 8:
-                return _context7.abrupt("return", res);
+  var ai = collationIndex(a);
+  var bi = collationIndex(b);
+  if ((ai - bi) !== 0) {
+    return ai - bi;
+  }
+  switch (typeof a) {
+    case 'number':
+      return a - b;
+    case 'boolean':
+      return a < b ? -1 : 1;
+    case 'string':
+      return stringCollate(a, b);
+  }
+  return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
+}
 
-              case 9:
-              case "end":
-                return _context7.stop();
+// couch considers null/NaN/Infinity/-Infinity === undefined,
+// for the purposes of mapreduce indexes. also, dates get stringified.
+function normalizeKey(key) {
+  switch (typeof key) {
+    case 'undefined':
+      return null;
+    case 'number':
+      if (key === Infinity || key === -Infinity || isNaN(key)) {
+        return null;
+      }
+      return key;
+    case 'object':
+      var origKey = key;
+      if (Array.isArray(key)) {
+        var len = key.length;
+        key = new Array(len);
+        for (var i = 0; i < len; i++) {
+          key[i] = normalizeKey(origKey[i]);
+        }
+      /* istanbul ignore next */
+      } else if (key instanceof Date) {
+        return key.toJSON();
+      } else if (key !== null) { // generic object
+        key = {};
+        for (var k in origKey) {
+          if (origKey.hasOwnProperty(k)) {
+            var val = origKey[k];
+            if (typeof val !== 'undefined') {
+              key[k] = normalizeKey(val);
             }
           }
-        }, _callee7, this);
-      }));
-
-      function destroy(_x8) {
-        return _destroy.apply(this, arguments);
+        }
       }
+  }
+  return key;
+}
 
-      return destroy;
-    }()
-  }, {
-    key: "upload",
-    value: function upload(file, dirPath) {
-      var mutationOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-      return this.mutate(_dsl.Mutations.uploadFile(file, dirPath), mutationOptions);
+function indexify(key) {
+  if (key !== null) {
+    switch (typeof key) {
+      case 'boolean':
+        return key ? 1 : 0;
+      case 'number':
+        return numToIndexableString(key);
+      case 'string':
+        // We've to be sure that key does not contain \u0000
+        // Do order-preserving replacements:
+        // 0 -> 1, 1
+        // 1 -> 1, 2
+        // 2 -> 2, 2
+        /* eslint-disable no-control-regex */
+        return key
+          .replace(/\u0002/g, '\u0002\u0002')
+          .replace(/\u0001/g, '\u0001\u0002')
+          .replace(/\u0000/g, '\u0001\u0001');
+        /* eslint-enable no-control-regex */
+      case 'object':
+        var isArray = Array.isArray(key);
+        var arr = isArray ? key : Object.keys(key);
+        var i = -1;
+        var len = arr.length;
+        var result = '';
+        if (isArray) {
+          while (++i < len) {
+            result += toIndexableString(arr[i]);
+          }
+        } else {
+          while (++i < len) {
+            var objKey = arr[i];
+            result += toIndexableString(objKey) +
+                toIndexableString(key[objKey]);
+          }
+        }
+        return result;
     }
-    /**
-     * Makes sure that the query exists in the store
-     *
-     * @param  {string} queryId - Id of the query
-     * @param  {QueryDefinition} queryDefinition - Definition of the query
-     * @param  {QueryOptions} [options] - Additional options
-     */
+  }
+  return '';
+}
 
-  }, {
-    key: "ensureQueryExists",
-    value: function ensureQueryExists(queryId, queryDefinition, options) {
-      this.ensureStore();
-      var existingQuery = (0, _store.getQueryFromState)(this.store.getState(), queryId); // Don't trigger the INIT_QUERY for fetchMore() calls
+// convert the given key to a string that would be appropriate
+// for lexical sorting, e.g. within a database, where the
+// sorting is the same given by the collate() function.
+function toIndexableString(key) {
+  var zero = '\u0000';
+  key = normalizeKey(key);
+  return collationIndex(key) + SEP + indexify(key) + zero;
+}
 
-      if (existingQuery.fetchStatus !== 'loaded' || !queryDefinition.skip && !queryDefinition.bookmark) {
-        this.dispatch((0, _store.initQuery)(queryId, queryDefinition, options));
+function parseNumber(str, i) {
+  var originalIdx = i;
+  var num;
+  var zero = str[i] === '1';
+  if (zero) {
+    num = 0;
+    i++;
+  } else {
+    var neg = str[i] === '0';
+    i++;
+    var numAsString = '';
+    var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
+    var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
+    /* istanbul ignore next */
+    if (neg) {
+      magnitude = -magnitude;
+    }
+    i += MAGNITUDE_DIGITS;
+    while (true) {
+      var ch = str[i];
+      if (ch === '\u0000') {
+        break;
+      } else {
+        numAsString += ch;
       }
+      i++;
     }
-    /**
-     * Executes a query and returns its results.
-     *
-     * Results from the query will be saved internally and can be retrieved via
-     * `getQueryFromState` or directly using `<Query />`. `<Query />` automatically
-     * executes its query when mounted if no fetch policy has been indicated.
-     *
-     * @param  {QueryDefinition} queryDefinition - Definition that will be executed
-     * @param  {QueryOptions} [options] - Options
-     * @returns {Promise<QueryResult>}
-     */
-
-  }, {
-    key: "query",
-    value: function () {
-      var _query = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(queryDefinition) {
-        var _this4 = this;
-
-        var _ref4,
-            update,
-            options,
-            queryId,
-            existingQuery,
-            shouldFetch,
-            response,
-            _args8 = arguments;
+    numAsString = numAsString.split('.');
+    if (numAsString.length === 1) {
+      num = parseInt(numAsString, 10);
+    } else {
+      /* istanbul ignore next */
+      num = parseFloat(numAsString[0] + '.' + numAsString[1]);
+    }
+    /* istanbul ignore next */
+    if (neg) {
+      num = num - 10;
+    }
+    /* istanbul ignore next */
+    if (magnitude !== 0) {
+      // parseFloat is more reliable than pow due to rounding errors
+      // e.g. Number.MAX_VALUE would return Infinity if we did
+      // num * Math.pow(10, magnitude);
+      num = parseFloat(num + 'e' + magnitude);
+    }
+  }
+  return {num: num, length : i - originalIdx};
+}
 
-        return _regenerator.default.wrap(function _callee8$(_context8) {
-          while (1) {
-            switch (_context8.prev = _context8.next) {
-              case 0:
-                _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
-                update = _ref4.update, options = (0, _objectWithoutProperties2.default)(_ref4, ["update"]);
-                this.ensureStore();
-                queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
-                existingQuery = this.getQueryFromState(queryId);
+// move up the stack while parsing
+// this function moved outside of parseIndexableString for performance
+function pop(stack, metaStack) {
+  var obj = stack.pop();
 
-                if (!options.fetchPolicy) {
-                  _context8.next = 11;
-                  break;
-                }
+  if (metaStack.length) {
+    var lastMetaElement = metaStack[metaStack.length - 1];
+    if (obj === lastMetaElement.element) {
+      // popping a meta-element, e.g. an object whose value is another object
+      metaStack.pop();
+      lastMetaElement = metaStack[metaStack.length - 1];
+    }
+    var element = lastMetaElement.element;
+    var lastElementIndex = lastMetaElement.index;
+    if (Array.isArray(element)) {
+      element.push(obj);
+    } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+      var key = stack.pop();
+      element[key] = obj;
+    } else {
+      stack.push(obj); // obj with key only
+    }
+  }
+}
 
-                if (options.as) {
-                  _context8.next = 8;
-                  break;
-                }
+function parseIndexableString(str) {
+  var stack = [];
+  var metaStack = []; // stack for arrays and objects
+  var i = 0;
 
-                throw new Error('Cannot use `fetchPolicy` without naming the query, please use `as` to name the query');
+  /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+  while (true) {
+    var collationIndex = str[i++];
+    if (collationIndex === '\u0000') {
+      if (stack.length === 1) {
+        return stack.pop();
+      } else {
+        pop(stack, metaStack);
+        continue;
+      }
+    }
+    switch (collationIndex) {
+      case '1':
+        stack.push(null);
+        break;
+      case '2':
+        stack.push(str[i] === '1');
+        i++;
+        break;
+      case '3':
+        var parsedNum = parseNumber(str, i);
+        stack.push(parsedNum.num);
+        i += parsedNum.length;
+        break;
+      case '4':
+        var parsedStr = '';
+        /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+        while (true) {
+          var ch = str[i];
+          if (ch === '\u0000') {
+            break;
+          }
+          parsedStr += ch;
+          i++;
+        }
+        // perform the reverse of the order-preserving replacement
+        // algorithm (see above)
+        /* eslint-disable no-control-regex */
+        parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
+          .replace(/\u0001\u0002/g, '\u0001')
+          .replace(/\u0002\u0002/g, '\u0002');
+        /* eslint-enable no-control-regex */
+        stack.push(parsedStr);
+        break;
+      case '5':
+        var arrayElement = { element: [], index: stack.length };
+        stack.push(arrayElement.element);
+        metaStack.push(arrayElement);
+        break;
+      case '6':
+        var objElement = { element: {}, index: stack.length };
+        stack.push(objElement.element);
+        metaStack.push(objElement);
+        break;
+      /* istanbul ignore next */
+      default:
+        throw new Error(
+          'bad collationIndex or unexpectedly reached end of input: ' +
+            collationIndex);
+    }
+  }
+}
 
-              case 8:
-                shouldFetch = options.fetchPolicy(existingQuery);
+function arrayCollate(a, b) {
+  var len = Math.min(a.length, b.length);
+  for (var i = 0; i < len; i++) {
+    var sort = collate(a[i], b[i]);
+    if (sort !== 0) {
+      return sort;
+    }
+  }
+  return (a.length === b.length) ? 0 :
+    (a.length > b.length) ? 1 : -1;
+}
+function stringCollate(a, b) {
+  // See: https://github.com/daleharvey/pouchdb/issues/40
+  // This is incompatible with the CouchDB implementation, but its the
+  // best we can do for now
+  return (a === b) ? 0 : ((a > b) ? 1 : -1);
+}
+function objectCollate(a, b) {
+  var ak = Object.keys(a), bk = Object.keys(b);
+  var len = Math.min(ak.length, bk.length);
+  for (var i = 0; i < len; i++) {
+    // First sort the keys
+    var sort = collate(ak[i], bk[i]);
+    if (sort !== 0) {
+      return sort;
+    }
+    // if the keys are equal sort the values
+    sort = collate(a[ak[i]], b[bk[i]]);
+    if (sort !== 0) {
+      return sort;
+    }
 
-                if (shouldFetch) {
-                  _context8.next = 11;
-                  break;
-                }
+  }
+  return (ak.length === bk.length) ? 0 :
+    (ak.length > bk.length) ? 1 : -1;
+}
+// The collation is defined by erlangs ordered terms
+// the atoms null, true, false come first, then numbers, strings,
+// arrays, then objects
+// null/undefined/NaN/Infinity/-Infinity are all considered null
+function collationIndex(x) {
+  var id = ['boolean', 'number', 'string', 'object'];
+  var idx = id.indexOf(typeof x);
+  //false if -1 otherwise true, but fast!!!!1
+  if (~idx) {
+    if (x === null) {
+      return 1;
+    }
+    if (Array.isArray(x)) {
+      return 5;
+    }
+    return idx < 3 ? (idx + 2) : (idx + 3);
+  }
+  /* istanbul ignore next */
+  if (Array.isArray(x)) {
+    return 5;
+  }
+}
 
-                return _context8.abrupt("return");
+// conversion:
+// x yyy zz...zz
+// x = 0 for negative, 1 for 0, 2 for positive
+// y = exponent (for negative numbers negated) moved so that it's >= 0
+// z = mantisse
+function numToIndexableString(num) {
 
-              case 11:
-                if (!(existingQuery && Object.keys(existingQuery).length > 0)) {
-                  _context8.next = 14;
-                  break;
-                }
+  if (num === 0) {
+    return '1';
+  }
 
-                if (!(existingQuery.fetchStatus === 'loading')) {
-                  _context8.next = 14;
-                  break;
-                }
+  // convert number to exponential format for easier and
+  // more succinct string sorting
+  var expFormat = num.toExponential().split(/e\+?/);
+  var magnitude = parseInt(expFormat[1], 10);
 
-                return _context8.abrupt("return", this._promiseCache.get(function () {
-                  return (0, _jsonStableStringify.default)(queryDefinition);
-                }));
+  var neg = num < 0;
 
-              case 14:
-                this.ensureQueryExists(queryId, queryDefinition, options);
-                _context8.prev = 15;
-                this.dispatch((0, _store.loadQuery)(queryId));
-                _context8.next = 19;
-                return this._promiseCache.exec(function () {
-                  return _this4.requestQuery(queryDefinition);
-                }, function () {
-                  return (0, _jsonStableStringify.default)(queryDefinition);
-                });
+  var result = neg ? '0' : '2';
 
-              case 19:
-                response = _context8.sent;
-                this.dispatch((0, _store.receiveQueryResult)(queryId, response, {
-                  update: update
-                }));
-                return _context8.abrupt("return", response);
+  // first sort by magnitude
+  // it's easier if all magnitudes are positive
+  var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
+  var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
 
-              case 24:
-                _context8.prev = 24;
-                _context8.t0 = _context8["catch"](15);
-                this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0)); // specific onError
+  result += SEP + magString;
 
-                if (!options.onError) {
-                  _context8.next = 31;
-                  break;
-                }
+  // then sort by the factor
+  var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
+  /* istanbul ignore next */
+  if (neg) { // for negative reverse ordering
+    factor = 10 - factor;
+  }
 
-                options.onError(_context8.t0); // defaulted onError
+  var factorStr = factor.toFixed(20);
 
-                _context8.next = 36;
-                break;
+  // strip zeros from the end
+  factorStr = factorStr.replace(/\.?0+$/, '');
 
-              case 31:
-                if (!this.options.onError) {
-                  _context8.next = 35;
-                  break;
-                }
+  result += SEP + factorStr;
 
-                this.options.onError(_context8.t0);
-                _context8.next = 36;
-                break;
+  return result;
+}
 
-              case 35:
-                throw _context8.t0;
 
-              case 36:
-              case "end":
-                return _context8.stop();
-            }
-          }
-        }, _callee8, this, [[15, 24]]);
-      }));
 
-      function query(_x9) {
-        return _query.apply(this, arguments);
-      }
 
-      return query;
-    }()
-    /**
-     * Will fetch all documents for a `queryDefinition`, automatically fetching more
-     * documents if the total of documents is superior to the pagination limit. Can
-     * result in a lot of network requests.
-     *
-     * @param  {QueryDefinition} queryDefinition - Definition to be executed
-     * @param {QueryOptions} [options] - Options
-     * @returns {Promise<QueryResult>} All documents matching the query
-     */
+/***/ }),
+/* 517 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-  }, {
-    key: "queryAll",
-    value: function () {
-      var _queryAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(queryDefinition) {
-        var options,
-            queryId,
-            mergedOptions,
-            resp,
-            documents,
-            currentResult,
-            _args9 = arguments;
-        return _regenerator.default.wrap(function _callee9$(_context9) {
-          while (1) {
-            switch (_context9.prev = _context9.next) {
-              case 0:
-                options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
-                queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
-                mergedOptions = _objectSpread(_objectSpread({}, options), {}, {
-                  as: queryId
-                });
-                _context9.next = 5;
-                return this.query(queryDefinition, mergedOptions);
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507);
+/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(511);
+/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(509);
+/* harmony import */ var pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(518);
+/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(516);
+/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(510);
+/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(512);
+/* harmony import */ var pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(520);
 
-              case 5:
-                resp = _context9.sent;
-                documents = resp.data;
 
-              case 7:
-                if (!(resp && resp.next)) {
-                  _context9.next = 21;
-                  break;
-                }
 
-                if (!resp.bookmark) {
-                  _context9.next = 14;
-                  break;
-                }
 
-                _context9.next = 11;
-                return this.query(queryDefinition.offsetBookmark(resp.bookmark), mergedOptions);
 
-              case 11:
-                resp = _context9.sent;
-                _context9.next = 18;
-                break;
 
-              case 14:
-                currentResult = (0, _store.getRawQueryFromState)(this.store.getState(), queryId);
-                _context9.next = 17;
-                return this.query(queryDefinition.offset(currentResult.data.length), mergedOptions);
 
-              case 17:
-                resp = _context9.sent;
 
-              case 18:
-                documents.push.apply(documents, (0, _toConsumableArray2.default)(resp.data));
-                _context9.next = 7;
-                break;
 
-              case 21:
-                return _context9.abrupt("return", documents);
+/*
+ * Simple task queue to sequentialize actions. Assumes
+ * callbacks will eventually fire (once).
+ */
 
-              case 22:
-              case "end":
-                return _context9.stop();
-            }
-          }
-        }, _callee9, this);
-      }));
 
-      function queryAll(_x10) {
-        return _queryAll.apply(this, arguments);
-      }
+function TaskQueue() {
+  this.promise = new Promise(function (fulfill) {fulfill(); });
+}
+TaskQueue.prototype.add = function (promiseFactory) {
+  this.promise = this.promise.catch(function () {
+    // just recover
+  }).then(function () {
+    return promiseFactory();
+  });
+  return this.promise;
+};
+TaskQueue.prototype.finish = function () {
+  return this.promise;
+};
 
-      return queryAll;
-    }()
-  }, {
-    key: "watchQuery",
-    value: function watchQuery() {
-      console.warn('client.watchQuery is deprecated, please use client.makeObservableQuery.');
-      return this.makeObservableQuery.apply(this, arguments);
-    }
-  }, {
-    key: "makeObservableQuery",
-    value: function makeObservableQuery(queryDefinition) {
-      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-      this.ensureStore();
-      var queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
-      this.ensureQueryExists(queryId, queryDefinition);
-      return new _ObservableQuery.default(queryId, queryDefinition, this, options);
-    }
-    /**
-     * Mutate a document
-     *
-     * @param  {object}    mutationDefinition - Describe the mutation
-     * @param {object} [options] - Options
-     * @param  {string}    [options.as] - Mutation id
-     * @param  {Function}    [options.update] - Function to update the document
-     * @param  {Function}    [options.updateQueries] - Function to update queries
-     * @returns {Promise}
-     */
+function stringify(input) {
+  if (!input) {
+    return 'undefined'; // backwards compat for empty reduce
+  }
+  // for backwards compat with mapreduce, functions/strings are stringified
+  // as-is. everything else is JSON-stringified.
+  switch (typeof input) {
+    case 'function':
+      // e.g. a mapreduce map
+      return input.toString();
+    case 'string':
+      // e.g. a mapreduce built-in _reduce function
+      return input.toString();
+    default:
+      // e.g. a JSON object in the case of mango queries
+      return JSON.stringify(input);
+  }
+}
 
-  }, {
-    key: "mutate",
-    value: function () {
-      var _mutate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(mutationDefinition) {
-        var _ref5,
-            update,
-            updateQueries,
-            options,
-            mutationId,
-            response,
-            _args10 = arguments;
+/* create a string signature for a view so we can cache it and uniq it */
+function createViewSignature(mapFun, reduceFun) {
+  // the "undefined" part is for backwards compatibility
+  return stringify(mapFun) + stringify(reduceFun) + 'undefined';
+}
 
-        return _regenerator.default.wrap(function _callee10$(_context10) {
-          while (1) {
-            switch (_context10.prev = _context10.next) {
-              case 0:
-                _ref5 = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {};
-                update = _ref5.update, updateQueries = _ref5.updateQueries, options = (0, _objectWithoutProperties2.default)(_ref5, ["update", "updateQueries"]);
-                this.ensureStore();
-                mutationId = options.as || this.queryIdGenerator.generateId(mutationDefinition);
-                this.dispatch((0, _store.initMutation)(mutationId, mutationDefinition));
-                _context10.prev = 5;
-                _context10.next = 8;
-                return this.requestMutation(mutationDefinition);
+function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) {
+  var viewSignature = createViewSignature(mapFun, reduceFun);
 
-              case 8:
-                response = _context10.sent;
-                this.dispatch((0, _store.receiveMutationResult)(mutationId, response, {
-                  update: update,
-                  updateQueries: updateQueries
-                }, mutationDefinition));
-                return _context10.abrupt("return", response);
+  var cachedViews;
+  if (!temporary) {
+    // cache this to ensure we don't try to update the same view twice
+    cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {};
+    if (cachedViews[viewSignature]) {
+      return cachedViews[viewSignature];
+    }
+  }
 
-              case 13:
-                _context10.prev = 13;
-                _context10.t0 = _context10["catch"](5);
-                this.dispatch((0, _store.receiveMutationError)(mutationId, _context10.t0, mutationDefinition));
-                throw _context10.t0;
+  var promiseForView = sourceDB.info().then(function (info) {
 
-              case 17:
-              case "end":
-                return _context10.stop();
-            }
-          }
-        }, _callee10, this, [[5, 13]]);
-      }));
+    var depDbName = info.db_name + '-mrview-' +
+      (temporary ? 'temp' : (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__.stringMd5)(viewSignature));
 
-      function mutate(_x11) {
-        return _mutate.apply(this, arguments);
+    // save the view name in the source db so it can be cleaned up if necessary
+    // (e.g. when the _design doc is deleted, remove all associated view data)
+    function diffFunction(doc) {
+      doc.views = doc.views || {};
+      var fullViewName = viewName;
+      if (fullViewName.indexOf('/') === -1) {
+        fullViewName = viewName + '/' + viewName;
       }
-
-      return mutate;
-    }()
-    /**
-     * Executes a query through links and fetches relationships
-     *
-     * @private
-     * @param  {QueryDefinition} definition QueryDefinition to be executed
-     * @returns {Promise<ClientResponse>}
-     */
-
-  }, {
-    key: "requestQuery",
-    value: function () {
-      var _requestQuery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(definition) {
-        var mainResponse, withIncluded;
-        return _regenerator.default.wrap(function _callee11$(_context11) {
-          while (1) {
-            switch (_context11.prev = _context11.next) {
-              case 0:
-                _context11.next = 2;
-                return this.chain.request(definition);
-
-              case 2:
-                mainResponse = _context11.sent;
-
-                if (definition.includes) {
-                  _context11.next = 5;
-                  break;
-                }
-
-                return _context11.abrupt("return", mainResponse);
-
-              case 5:
-                _context11.next = 7;
-                return this.fetchRelationships(mainResponse, this.getIncludesRelationships(definition));
-
-              case 7:
-                withIncluded = _context11.sent;
-                return _context11.abrupt("return", withIncluded);
-
-              case 9:
-              case "end":
-                return _context11.stop();
-            }
-          }
-        }, _callee11, this);
-      }));
-
-      function requestQuery(_x12) {
-        return _requestQuery.apply(this, arguments);
+      var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
+      /* istanbul ignore if */
+      if (depDbs[depDbName]) {
+        return; // no update necessary
       }
+      depDbs[depDbName] = true;
+      return doc;
+    }
+    return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(sourceDB, '_local/' + localDocName, diffFunction).then(function () {
+      return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
+        var db = res.db;
+        db.auto_compaction = true;
+        var view = {
+          name: depDbName,
+          db: db,
+          sourceDB: sourceDB,
+          adapter: sourceDB.adapter,
+          mapFun: mapFun,
+          reduceFun: reduceFun
+        };
+        return view.db.get('_local/lastSeq').catch(function (err) {
+          /* istanbul ignore if */
+          if (err.status !== 404) {
+            throw err;
+          }
+        }).then(function (lastSeqDoc) {
+          view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
+          if (cachedViews) {
+            view.db.once('destroyed', function () {
+              delete cachedViews[viewSignature];
+            });
+          }
+          return view;
+        });
+      });
+    });
+  });
 
-      return requestQuery;
-    }()
-    /**
-     * Fetch relationships for a response (can be several docs).
-     * Fills the `relationships` attribute of each documents.
-     *
-     * Can potentially result in several fetch requests.
-     * Queries are optimized before being sent (multiple single documents queries can be packed into
-     * one multiple document query) for example.
-     *
-     * @private
-     */
-
-  }, {
-    key: "fetchRelationships",
-    value: function () {
-      var _fetchRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(response, relationshipsByName) {
-        var _this5 = this;
+  if (cachedViews) {
+    cachedViews[viewSignature] = promiseForView;
+  }
+  return promiseForView;
+}
 
-        var isSingleDoc, responseDocs, queryDefToDocIdAndRel, documents, definitions, optimizedDefinitions, responses, uniqueDocuments, included, relationshipsByDocId, _iterator5, _step5, _step5$value, def, resp, docIdAndRel, _docIdAndRel, docId, relName;
+var persistentQueues = {};
+var tempViewQueue = new TaskQueue();
+var CHANGES_BATCH_SIZE = 50;
 
-        return _regenerator.default.wrap(function _callee12$(_context12) {
-          while (1) {
-            switch (_context12.prev = _context12.next) {
-              case 0:
-                isSingleDoc = !Array.isArray(response.data);
+function parseViewName(name) {
+  // can be either 'ddocname/viewname' or just 'viewname'
+  // (where the ddoc name is the same)
+  return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+}
 
-                if (!(!isSingleDoc && response.data.length === 0)) {
-                  _context12.next = 3;
-                  break;
-                }
+function isGenOne(changes) {
+  // only return true if the current change is 1-
+  // and there are no other leafs
+  return changes.length === 1 && /^1-/.test(changes[0].rev);
+}
 
-                return _context12.abrupt("return", response);
+function emitError(db, e) {
+  try {
+    db.emit('error', e);
+  } catch (err) {
+    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error',
+      'The user\'s map/reduce function threw an uncaught error.\n' +
+      'You can debug this error by doing:\n' +
+      'myDatabase.on(\'error\', function (err) { debugger; });\n' +
+      'Please double-check your map/reduce function.');
+    (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error', e);
+  }
+}
 
-              case 3:
-                responseDocs = isSingleDoc ? [response.data] : response.data;
-                queryDefToDocIdAndRel = new Map();
-                documents = [];
-                definitions = [];
-                responseDocs.forEach(function (doc) {
-                  return (0, _forEach.default)(relationshipsByName, function (relationship, relName) {
-                    try {
-                      var queryDef = relationship.type.query(doc, _this5, relationship);
-                      var docId = doc._id; // Used to reattach responses into the relationships attribute of
-                      // each document
+/**
+ * Returns an "abstract" mapreduce object of the form:
+ *
+ *   {
+ *     query: queryFun,
+ *     viewCleanup: viewCleanupFun
+ *   }
+ *
+ * Arguments are:
+ *
+ * localDoc: string
+ *   This is for the local doc that gets saved in order to track the
+ *   "dependent" DBs and clean them up for viewCleanup. It should be
+ *   unique, so that indexer plugins don't collide with each other.
+ * mapper: function (mapFunDef, emit)
+ *   Returns a map function based on the mapFunDef, which in the case of
+ *   normal map/reduce is just the de-stringified function, but may be
+ *   something else, such as an object in the case of pouchdb-find.
+ * reducer: function (reduceFunDef)
+ *   Ditto, but for reducing. Modules don't have to support reducing
+ *   (e.g. pouchdb-find).
+ * ddocValidator: function (ddoc, viewName)
+ *   Throws an error if the ddoc or viewName is not valid.
+ *   This could be a way to communicate to the user that the configuration for the
+ *   indexer is invalid.
+ */
+function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) {
 
-                      queryDefToDocIdAndRel.set(queryDef, [docId, relName]); // Relationships can yield "queries" that are already resolved documents.
-                      // These do not need to go through the usual link request mechanism.
+  function tryMap(db, fun, doc) {
+    // emit an event if there was an error thrown by a map function.
+    // putting try/catches in a single function also avoids deoptimizations.
+    try {
+      fun(doc);
+    } catch (e) {
+      emitError(db, e);
+    }
+  }
 
-                      if (queryDef instanceof _dsl.QueryDefinition) {
-                        definitions.push(queryDef);
-                      } else {
-                        documents.push(queryDef);
-                      }
-                    } catch (_unused) {// eslint-disable-next-line
-                      // We do not crash completely if one the relationship behaves badly and
-                      // throws
-                    }
-                  });
-                }); // Definitions can be in optimized/regrouped in case of HasMany relationships.
+  function tryReduce(db, fun, keys, values, rereduce) {
+    // same as above, but returning the result or an error. there are two separate
+    // functions to avoid extra memory allocations since the tryCode() case is used
+    // for custom map functions (common) vs this function, which is only used for
+    // custom reduce functions (rare)
+    try {
+      return {output : fun(keys, values, rereduce)};
+    } catch (e) {
+      emitError(db, e);
+      return {error: e};
+    }
+  }
 
-                optimizedDefinitions = (0, _optimize.default)(definitions);
-                _context12.next = 11;
-                return Promise.all(optimizedDefinitions.map(function (req) {
-                  return _this5.chain.request(req);
-                }));
+  function sortByKeyThenValue(x, y) {
+    var keyCompare = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.key, y.key);
+    return keyCompare !== 0 ? keyCompare : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.value, y.value);
+  }
 
-              case 11:
-                responses = _context12.sent;
-                // "Included" documents will be stored in the `documents` store
-                uniqueDocuments = (0, _uniqBy.default)((0, _flatten.default)(documents), '_id');
-                included = (0, _flatten.default)(responses.map(function (r) {
-                  return r.included || r.data;
-                })).concat(uniqueDocuments).filter(Boolean); // Some relationships have the relationship data on the other side of the
-                // relationship (ex: io.cozy.photos.albums do not have photo inclusion information,
-                // it is on the io.cozy.files side).
-                // Here we take the data received from the relationship queries, and group
-                // it so that we can fill the `relationships` attribute of each doc before
-                // storing the document. This makes the data easier to manipulate for the front-end.
+  function sliceResults(results, limit, skip) {
+    skip = skip || 0;
+    if (typeof limit === 'number') {
+      return results.slice(skip, limit + skip);
+    } else if (skip > 0) {
+      return results.slice(skip);
+    }
+    return results;
+  }
 
-                relationshipsByDocId = {};
-                _iterator5 = _createForOfIteratorHelper((0, _zip.default)(optimizedDefinitions, responses));
+  function rowToDocId(row) {
+    var val = row.value;
+    // Users can explicitly specify a joined doc _id, or it
+    // defaults to the doc _id that emitted the key/value.
+    var docId = (val && typeof val === 'object' && val._id) || row.id;
+    return docId;
+  }
 
-                try {
-                  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
-                    _step5$value = (0, _slicedToArray2.default)(_step5.value, 2), def = _step5$value[0], resp = _step5$value[1];
-                    docIdAndRel = queryDefToDocIdAndRel.get(def);
+  function readAttachmentsAsBlobOrBuffer(res) {
+    res.rows.forEach(function (row) {
+      var atts = row.doc && row.doc._attachments;
+      if (!atts) {
+        return;
+      }
+      Object.keys(atts).forEach(function (filename) {
+        var att = atts[filename];
+        atts[filename].data = (0,pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__.base64StringToBlobOrBuffer)(att.data, att.content_type);
+      });
+    });
+  }
 
-                    if (docIdAndRel) {
-                      _docIdAndRel = (0, _slicedToArray2.default)(docIdAndRel, 2), docId = _docIdAndRel[0], relName = _docIdAndRel[1];
-                      relationshipsByDocId[docId] = relationshipsByDocId[docId] || {};
-                      relationshipsByDocId[docId][relName] = (0, _helpers.responseToRelationship)(resp);
-                    }
-                  }
-                } catch (err) {
-                  _iterator5.e(err);
-                } finally {
-                  _iterator5.f();
-                }
+  function postprocessAttachments(opts) {
+    return function (res) {
+      if (opts.include_docs && opts.attachments && opts.binary) {
+        readAttachmentsAsBlobOrBuffer(res);
+      }
+      return res;
+    };
+  }
 
-                return _context12.abrupt("return", _objectSpread(_objectSpread({}, (0, _helpers.attachRelationships)(response, relationshipsByDocId)), {}, {
-                  included: included
-                }));
+  function addHttpParam(paramName, opts, params, asJson) {
+    // add an http param from opts to params, optionally json-encoded
+    var val = opts[paramName];
+    if (typeof val !== 'undefined') {
+      if (asJson) {
+        val = encodeURIComponent(JSON.stringify(val));
+      }
+      params.push(paramName + '=' + val);
+    }
+  }
 
-              case 18:
-              case "end":
-                return _context12.stop();
-            }
-          }
-        }, _callee12);
-      }));
+  function coerceInteger(integerCandidate) {
+    if (typeof integerCandidate !== 'undefined') {
+      var asNumber = Number(integerCandidate);
+      // prevents e.g. '1foo' or '1.1' being coerced to 1
+      if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
+        return asNumber;
+      } else {
+        return integerCandidate;
+      }
+    }
+  }
 
-      function fetchRelationships(_x13, _x14) {
-        return _fetchRelationships.apply(this, arguments);
+  function coerceOptions(opts) {
+    opts.group_level = coerceInteger(opts.group_level);
+    opts.limit = coerceInteger(opts.limit);
+    opts.skip = coerceInteger(opts.skip);
+    return opts;
+  }
+
+  function checkPositiveInteger(number) {
+    if (number) {
+      if (typeof number !== 'number') {
+        return  new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for integer: "' +
+          number + '"');
+      }
+      if (number < 0) {
+        return new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for positive integer: ' +
+          '"' + number + '"');
       }
+    }
+  }
 
-      return fetchRelationships;
-    }()
-  }, {
-    key: "requestMutation",
-    value: function () {
-      var _requestMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(definition) {
-        var _this6 = this;
+  function checkQueryParseError(options, fun) {
+    var startkeyName = options.descending ? 'endkey' : 'startkey';
+    var endkeyName = options.descending ? 'startkey' : 'endkey';
 
-        var _definition, first, rest, firstResponse;
+    if (typeof options[startkeyName] !== 'undefined' &&
+      typeof options[endkeyName] !== 'undefined' &&
+      (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(options[startkeyName], options[endkeyName]) > 0) {
+      throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('No rows can match your key range, ' +
+        'reverse your start_key and end_key or set {descending : true}');
+    } else if (fun.reduce && options.reduce !== false) {
+      if (options.include_docs) {
+        throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('{include_docs:true} is invalid for reduce');
+      } else if (options.keys && options.keys.length > 1 &&
+        !options.group && !options.group_level) {
+        throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Multi-key fetches for reduce views must use ' +
+          '{group: true}');
+      }
+    }
+    ['group_level', 'limit', 'skip'].forEach(function (optionName) {
+      var error = checkPositiveInteger(options[optionName]);
+      if (error) {
+        throw error;
+      }
+    });
+  }
 
-        return _regenerator.default.wrap(function _callee13$(_context13) {
-          while (1) {
-            switch (_context13.prev = _context13.next) {
-              case 0:
-                if (!Array.isArray(definition)) {
-                  _context13.next = 8;
-                  break;
-                }
+  function httpQuery(db, fun, opts) {
+    // List of parameters to add to the PUT request
+    var params = [];
+    var body;
+    var method = 'GET';
+    var ok, status;
 
-                _definition = (0, _toArray2.default)(definition), first = _definition[0], rest = _definition.slice(1);
-                _context13.next = 4;
-                return this.requestMutation(first);
+    // If opts.reduce exists and is defined, then add it to the list
+    // of parameters.
+    // If reduce=false then the results are that of only the map function
+    // not the final result of map and reduce.
+    addHttpParam('reduce', opts, params);
+    addHttpParam('include_docs', opts, params);
+    addHttpParam('attachments', opts, params);
+    addHttpParam('limit', opts, params);
+    addHttpParam('descending', opts, params);
+    addHttpParam('group', opts, params);
+    addHttpParam('group_level', opts, params);
+    addHttpParam('skip', opts, params);
+    addHttpParam('stale', opts, params);
+    addHttpParam('conflicts', opts, params);
+    addHttpParam('startkey', opts, params, true);
+    addHttpParam('start_key', opts, params, true);
+    addHttpParam('endkey', opts, params, true);
+    addHttpParam('end_key', opts, params, true);
+    addHttpParam('inclusive_end', opts, params);
+    addHttpParam('key', opts, params, true);
+    addHttpParam('update_seq', opts, params);
 
-              case 4:
-                firstResponse = _context13.sent;
-                _context13.next = 7;
-                return Promise.all(rest.map(function (def) {
-                  var mutationDef = typeof def === 'function' ? def(firstResponse) : def;
-                  return _this6.requestMutation(mutationDef);
-                }));
+    // Format the list of parameters into a valid URI query string
+    params = params.join('&');
+    params = params === '' ? '' : '?' + params;
 
-              case 7:
-                return _context13.abrupt("return", firstResponse);
+    // If keys are supplied, issue a POST to circumvent GET query string limits
+    // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+    if (typeof opts.keys !== 'undefined') {
+      var MAX_URL_LENGTH = 2000;
+      // according to http://stackoverflow.com/a/417184/680742,
+      // the de facto URL length limit is 2000 characters
 
-              case 8:
-                return _context13.abrupt("return", this.chain.request(definition));
+      var keysAsString =
+        'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
+      if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
+        // If the keys are short enough, do a GET. we do this to work around
+        // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
+        params += (params[0] === '?' ? '&' : '?') + keysAsString;
+      } else {
+        method = 'POST';
+        if (typeof fun === 'string') {
+          body = {keys: opts.keys};
+        } else { // fun is {map : mapfun}, so append to this
+          fun.keys = opts.keys;
+        }
+      }
+    }
 
-              case 9:
-              case "end":
-                return _context13.stop();
-            }
+    // We are referencing a query defined in the design doc
+    if (typeof fun === 'string') {
+      var parts = parseViewName(fun);
+      return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
+        headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}),
+        method: method,
+        body: JSON.stringify(body)
+      }).then(function (response) {
+        ok = response.ok;
+        status = response.status;
+        return response.json();
+      }).then(function (result) {
+        if (!ok) {
+          result.status = status;
+          throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result);
+        }
+        // fail the entire request if the result contains an error
+        result.rows.forEach(function (row) {
+          /* istanbul ignore if */
+          if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
+            throw new Error(row.reason);
           }
-        }, _callee13, this);
-      }));
+        });
+        return result;
+      }).then(postprocessAttachments(opts));
+    }
 
-      function requestMutation(_x15) {
-        return _requestMutation.apply(this, arguments);
+    // We are using a temporary view, terrible for performance, good for testing
+    body = body || {};
+    Object.keys(fun).forEach(function (key) {
+      if (Array.isArray(fun[key])) {
+        body[key] = fun[key];
+      } else {
+        body[key] = fun[key].toString();
       }
+    });
 
-      return requestMutation;
-    }()
-  }, {
-    key: "getIncludesRelationships",
-    value: function getIncludesRelationships(queryDefinition) {
-      var _this7 = this;
+    return db.fetch('_temp_view' + params, {
+      headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}),
+      method: 'POST',
+      body: JSON.stringify(body)
+    }).then(function (response) {
+        ok = response.ok;
+        status = response.status;
+      return response.json();
+    }).then(function (result) {
+      if (!ok) {
+        result.status = status;
+        throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result);
+      }
+      return result;
+    }).then(postprocessAttachments(opts));
+  }
 
-      var includes = queryDefinition.includes,
-          doctype = queryDefinition.doctype;
-      if (!includes) return {};
-      return (0, _fromPairs.default)(includes.map(function (relName) {
-        return [relName, _this7.schema.getRelationship(doctype, relName)];
-      }));
-    }
-    /**
-     * Returns documents with their relationships resolved according to their schema.
-     * If related documents are not in the store, they will not be fetched automatically.
-     * Instead, the relationships will have null documents.
-     *
-     * @param  {string} doctype - Doctype of the documents being hydrated
-     * @param  {Array<CozyClientDocument>} documents - Documents to be hydrated
-     * @returns {Array<HydratedDocument>}
-     */
+  // custom adapters can define their own api._query
+  // and override the default behavior
+  /* istanbul ignore next */
+  function customQuery(db, fun, opts) {
+    return new Promise(function (resolve, reject) {
+      db._query(fun, opts, function (err, res) {
+        if (err) {
+          return reject(err);
+        }
+        resolve(res);
+      });
+    });
+  }
 
-  }, {
-    key: "hydrateDocuments",
-    value: function hydrateDocuments(doctype, documents) {
-      var _this8 = this;
+  // custom adapters can define their own api._viewCleanup
+  // and override the default behavior
+  /* istanbul ignore next */
+  function customViewCleanup(db) {
+    return new Promise(function (resolve, reject) {
+      db._viewCleanup(function (err, res) {
+        if (err) {
+          return reject(err);
+        }
+        resolve(res);
+      });
+    });
+  }
 
-      if (this.options.autoHydrate === false) {
-        return documents;
+  function defaultsTo(value) {
+    return function (reason) {
+      /* istanbul ignore else */
+      if (reason.status === 404) {
+        return value;
+      } else {
+        throw reason;
       }
+    };
+  }
 
-      var schema = this.schema.getDoctypeSchema(doctype);
-      var relationships = schema.relationships;
+  // returns a promise for a list of docs to update, based on the input docId.
+  // the order doesn't matter, because post-3.2.0, bulkDocs
+  // is an atomic operation in all three adapters.
+  function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
+    var metaDocId = '_local/doc_' + docId;
+    var defaultMetaDoc = {_id: metaDocId, keys: []};
+    var docData = docIdsToChangesAndEmits.get(docId);
+    var indexableKeysToKeyValues = docData[0];
+    var changes = docData[1];
 
-      if (relationships) {
-        return documents.map(function (doc) {
-          return _this8.hydrateDocument(doc, schema);
-        });
-      } else {
-        return documents;
+    function getMetaDoc() {
+      if (isGenOne(changes)) {
+        // generation 1, so we can safely assume initial state
+        // for performance reasons (avoids unnecessary GETs)
+        return Promise.resolve(defaultMetaDoc);
       }
+      return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc));
     }
-    /**
-     * Resolves relationships on a document.
-     *
-     * The original document is kept in the target attribute of
-     * the relationship
-     *
-     * @param  {CozyClientDocument} document - for which relationships must be resolved
-     * @param  {Schema} [schemaArg] - Optional
-     * @returns {HydratedDocument}
-     */
 
-  }, {
-    key: "hydrateDocument",
-    value: function hydrateDocument(document, schemaArg) {
-      if (!document) {
-        return document;
+    function getKeyValueDocs(metaDoc) {
+      if (!metaDoc.keys.length) {
+        // no keys, no need for a lookup
+        return Promise.resolve({rows: []});
       }
-
-      var schema = schemaArg || this.schema.getDoctypeSchema(document._type);
-      return _objectSpread(_objectSpread({}, document), this.hydrateRelationships(document, schema.relationships));
-    }
-  }, {
-    key: "hydrateRelationships",
-    value: function hydrateRelationships(document, schemaRelationships) {
-      var methods = this.getRelationshipStoreAccessors();
-      return (0, _mapValues.default)(schemaRelationships, function (assoc, name) {
-        return (0, _associations.create)(document, assoc, methods);
+      return view.db.allDocs({
+        keys: metaDoc.keys,
+        include_docs: true
       });
     }
-    /**
-     * Creates (locally) a new document for the given doctype.
-     * This document is hydrated : its relationships are there
-     * and working.
-     */
 
-  }, {
-    key: "makeNewDocument",
-    value: function makeNewDocument(doctype) {
-      var obj = {
-        _type: doctype
-      };
-      return this.hydrateDocument(obj);
-    }
-  }, {
-    key: "generateRandomId",
-    value: function generateRandomId() {
-      return this.queryIdGenerator.generateRandomId();
-    }
-    /**
-     * Creates an association that is linked to the store.
-     */
+    function processKeyValueDocs(metaDoc, kvDocsRes) {
+      var kvDocs = [];
+      var oldKeys = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set();
 
-  }, {
-    key: "getAssociation",
-    value: function getAssociation(document, associationName) {
-      return (0, _associations.create)(document, this.schema.getRelationship(document._type, associationName), this.getRelationshipStoreAccessors());
+      for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
+        var row = kvDocsRes.rows[i];
+        var doc = row.doc;
+        if (!doc) { // deleted
+          continue;
+        }
+        kvDocs.push(doc);
+        oldKeys.add(doc._id);
+        doc._deleted = !indexableKeysToKeyValues.has(doc._id);
+        if (!doc._deleted) {
+          var keyValue = indexableKeysToKeyValues.get(doc._id);
+          if ('value' in keyValue) {
+            doc.value = keyValue.value;
+          }
+        }
+      }
+      var newKeys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(indexableKeysToKeyValues);
+      newKeys.forEach(function (key) {
+        if (!oldKeys.has(key)) {
+          // new doc
+          var kvDoc = {
+            _id: key
+          };
+          var keyValue = indexableKeysToKeyValues.get(key);
+          if ('value' in keyValue) {
+            kvDoc.value = keyValue.value;
+          }
+          kvDocs.push(kvDoc);
+        }
+      });
+      metaDoc.keys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(newKeys.concat(metaDoc.keys));
+      kvDocs.push(metaDoc);
+
+      return kvDocs;
     }
-    /**
-     * Returns the accessors that are given to the relationships for them
-     * to deal with the stores.
-     *
-     * Relationships need to have access to the store to ping it when
-     * a modification (addById/removeById etc...) has been done. This wakes
-     * the store up, which in turn will update the `<Query>`s and re-render the data.
-     */
 
-  }, {
-    key: "getRelationshipStoreAccessors",
-    value: function getRelationshipStoreAccessors() {
-      var _this9 = this;
+    return getMetaDoc().then(function (metaDoc) {
+      return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
+        return processKeyValueDocs(metaDoc, kvDocsRes);
+      });
+    });
+  }
 
-      if (!this.storeAccesors) {
-        this.storeAccessors = {
-          get: this.getDocumentFromState.bind(this),
-          save: function save(document, opts) {
-            return _this9.save.call(_this9, document, opts);
-          },
-          dispatch: this.dispatch.bind(this),
-          query: function query(def, opts) {
-            return _this9.query.call(_this9, def, opts);
-          },
-          mutate: function mutate(def, opts) {
-            return _this9.mutate.call(_this9, def, opts);
-          }
-        };
-      }
+  // updates all emitted key/value docs and metaDocs in the mrview database
+  // for the given batch of documents from the source database
+  function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
+    var seqDocId = '_local/lastSeq';
+    return view.db.get(seqDocId)
+      .catch(defaultsTo({_id: seqDocId, seq: 0}))
+      .then(function (lastSeqDoc) {
+        var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docIdsToChangesAndEmits);
+        return Promise.all(docIds.map(function (docId) {
+          return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
+        })).then(function (listOfDocsToPersist) {
+          var docsToPersist = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten)(listOfDocsToPersist);
+          lastSeqDoc.seq = seq;
+          docsToPersist.push(lastSeqDoc);
+          // write all docs in a single operation, update the seq once
+          return view.db.bulkDocs({docs : docsToPersist});
+        });
+      });
+  }
 
-      return this.storeAccessors;
+  function getQueue(view) {
+    var viewName = typeof view === 'string' ? view : view.name;
+    var queue = persistentQueues[viewName];
+    if (!queue) {
+      queue = persistentQueues[viewName] = new TaskQueue();
     }
-    /**
-     * Get a collection of documents from the internal store.
-     *
-     * @param {string} type - Doctype of the collection
-     *
-     * @returns {CozyClientDocument[]} Array of documents or null if the collection does not exist.
-     */
+    return queue;
+  }
 
-  }, {
-    key: "getCollectionFromState",
-    value: function getCollectionFromState(type) {
-      try {
-        return (0, _store.getCollectionFromState)(this.store.getState(), type);
-      } catch (e) {
-        _logger.default.warn('Could not getCollectionFromState', type, e.message);
+  function updateView(view) {
+    return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () {
+      return updateViewInQueue(view);
+    })();
+  }
 
-        return null;
+  function updateViewInQueue(view) {
+    // bind the emit function once
+    var mapResults;
+    var doc;
+
+    function emit(key, value) {
+      var output = {id: doc._id, key: (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(key)};
+      // Don't explicitly store the value unless it's defined and non-null.
+      // This saves on storage space, because often people don't use it.
+      if (typeof value !== 'undefined' && value !== null) {
+        output.value = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(value);
       }
+      mapResults.push(output);
     }
-    /**
-     * Get a document from the internal store.
-     *
-     * @param {string} type - Doctype of the document
-     * @param {string} id   - Id of the document
-     *
-     * @returns {CozyClientDocument} Document or null if the object does not exist.
-     */
 
-  }, {
-    key: "getDocumentFromState",
-    value: function getDocumentFromState(type, id) {
-      try {
-        return (0, _store.getDocumentFromState)(this.store.getState(), type, id);
-      } catch (e) {
-        _logger.default.warn('Could not getDocumentFromState', type, id, e.message);
+    var mapFun = mapper(view.mapFun, emit);
 
-        return null;
+    var currentSeq = view.seq || 0;
+
+    function processChange(docIdsToChangesAndEmits, seq) {
+      return function () {
+        return saveKeyValues(view, docIdsToChangesAndEmits, seq);
+      };
+    }
+
+    var queue = new TaskQueue();
+
+    function processNextBatch() {
+      return view.sourceDB.changes({
+        return_docs: true,
+        conflicts: true,
+        include_docs: true,
+        style: 'all_docs',
+        since: currentSeq,
+        limit: CHANGES_BATCH_SIZE
+      }).then(processBatch);
+    }
+
+    function processBatch(response) {
+      var results = response.results;
+      if (!results.length) {
+        return;
+      }
+      var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results);
+      queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
+      if (results.length < CHANGES_BATCH_SIZE) {
+        return;
       }
+      return processNextBatch();
     }
-    /**
-     * Get a query from the internal store.
-     *
-     * @param {string} id - Id of the query (set via Query.props.as)
-     * @param {object} options - Options
-     * @param {boolean} [options.hydrated] - Whether documents should be returned already hydrated (default: false)
-     * @param  {object} [options.singleDocData] - If true, the "data" returned will be
-     * a single doc instead of an array for single doc queries. Defaults to false for backward
-     * compatibility but will be set to true in the future.
-     *
-     * @returns {QueryState} - Query state or null if it does not exist.
-     */
 
-  }, {
-    key: "getQueryFromState",
-    value: function getQueryFromState(id) {
-      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-      var hydrated = options.hydrated || false;
-      var singleDocData = options.singleDocData || false;
+    function createDocIdsToChangesAndEmits(results) {
+      var docIdsToChangesAndEmits = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
+      for (var i = 0, len = results.length; i < len; i++) {
+        var change = results[i];
+        if (change.doc._id[0] !== '_') {
+          mapResults = [];
+          doc = change.doc;
 
-      try {
-        var queryResults = (0, _store.getQueryFromState)(this.store.getState(), id);
-        var doctype = queryResults.definition && queryResults.definition.doctype;
-        var isSingleDocQuery = queryResults.definition && queryResults.definition.id;
+          if (!doc._deleted) {
+            tryMap(view.sourceDB, mapFun, doc);
+          }
+          mapResults.sort(sortByKeyThenValue);
 
-        if (!hydrated && !singleDocData) {
-          // Early return let's us preserve reference equality in the simple case
-          return queryResults;
+          var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults);
+          docIdsToChangesAndEmits.set(change.doc._id, [
+            indexableKeysToKeyValues,
+            change.changes
+          ]);
         }
+        currentSeq = change.seq;
+      }
+      return docIdsToChangesAndEmits;
+    }
 
-        var data = hydrated && doctype ? this.hydrateDocuments(doctype, queryResults.data) : queryResults.data;
-        return _objectSpread(_objectSpread({}, queryResults), {}, {
-          data: isSingleDocQuery && singleDocData ? data[0] : data
-        });
-      } catch (e) {
-        console.warn("Could not get query from state. queryId: ".concat(id, ", error: ").concat(e.message));
-        return null;
+    function createIndexableKeysToKeyValues(mapResults) {
+      var indexableKeysToKeyValues = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
+      var lastKey;
+      for (var i = 0, len = mapResults.length; i < len; i++) {
+        var emittedKeyValue = mapResults[i];
+        var complexKey = [emittedKeyValue.key, emittedKeyValue.id];
+        if (i > 0 && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(emittedKeyValue.key, lastKey) === 0) {
+          complexKey.push(i); // dup key+id, so make it unique
+        }
+        indexableKeysToKeyValues.set((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)(complexKey), emittedKeyValue);
+        lastKey = emittedKeyValue.key;
       }
+      return indexableKeysToKeyValues;
     }
-    /**
-     * Executes a query and returns the results from internal store.
-     *
-     * Can be useful in pure JS context (without React)
-     * Has a behavior close to <Query /> or useQuery
-     *
-     * @param {object} query - Query with definition and options
-     * @returns {Promise<QueryState>} Query state
-     */
 
-  }, {
-    key: "register",
+    return processNextBatch().then(function () {
+      return queue.finish();
+    }).then(function () {
+      view.seq = currentSeq;
+    });
+  }
 
-    /**
-     * Performs a complete OAuth flow using a Cordova webview
-     * or React Native WebView for auth.
-     * The `register` method's name has been chosen for compat reasons with the Authentication compo.
-     *
-     * @param   {string} cozyURL Receives the URL of the cozy instance.
-     * @returns {object}   Contains the fetched token and the client information.
-     */
-    value: function register(cozyURL) {
-      var stackClient = this.getStackClient();
-      stackClient.setUri(cozyURL);
-      return this.startOAuthFlow(_mobile.authFunction);
-    }
-  }, {
-    key: "isReactNative",
-    value: function isReactNative() {
-      return typeof navigator != 'undefined' && navigator.product == 'ReactNative';
+  function reduceView(view, results, options) {
+    if (options.group_level === 0) {
+      delete options.group_level;
     }
-    /**
-     * Performs a complete OAuth flow, including updating the internal token at the end.
-     *
-     * @param   {OpenURLCallback} openURLCallback Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.
-     * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client.
-     */
-
-  }, {
-    key: "startOAuthFlow",
-    value: function () {
-      var _startOAuthFlow = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(openURLCallback) {
-        var stackClient;
-        return _regenerator.default.wrap(function _callee14$(_context14) {
-          while (1) {
-            switch (_context14.prev = _context14.next) {
-              case 0:
-                stackClient = this.getStackClient();
-                _context14.next = 3;
-                return stackClient.register();
 
-              case 3:
-                _context14.next = 5;
-                return this.certifyFlagship();
+    var shouldGroup = options.group || options.group_level;
 
-              case 5:
-                return _context14.abrupt("return", this.authorize({
-                  openURLCallback: openURLCallback
-                }));
+    var reduceFun = reducer(view.reduceFun);
 
-              case 6:
-              case "end":
-                return _context14.stop();
-            }
-          }
-        }, _callee14, this);
-      }));
+    var groups = [];
+    var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
+      options.group_level;
+    results.forEach(function (e) {
+      var last = groups[groups.length - 1];
+      var groupKey = shouldGroup ? e.key : null;
 
-      function startOAuthFlow(_x16) {
-        return _startOAuthFlow.apply(this, arguments);
+      // only set group_level for array keys
+      if (shouldGroup && Array.isArray(groupKey)) {
+        groupKey = groupKey.slice(0, lvl);
       }
 
-      return startOAuthFlow;
-    }()
-    /**
-     * Perform the Flagship certification process for verifying that the current running app is a genuine Cozy application
-     *
-     * This mechanism is described in https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/flagship-certification/README.md
-     */
+      if (last && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(last.groupKey, groupKey) === 0) {
+        last.keys.push([e.key, e.id]);
+        last.values.push(e.value);
+        return;
+      }
+      groups.push({
+        keys: [[e.key, e.id]],
+        values: [e.value],
+        groupKey: groupKey
+      });
+    });
+    results = [];
+    for (var i = 0, len = groups.length; i < len; i++) {
+      var e = groups[i];
+      var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false);
+      if (reduceTry.error && reduceTry.error instanceof pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.BuiltInError) {
+        // CouchDB returns an error if a built-in errors out
+        throw reduceTry.error;
+      }
+      results.push({
+        // CouchDB just sets the value to null if a non-built-in errors out
+        value: reduceTry.error ? null : reduceTry.output,
+        key: e.groupKey
+      });
+    }
+    // no total_rows/offset when reducing
+    return {rows: sliceResults(results, options.limit, options.skip)};
+  }
 
-  }, {
-    key: "certifyFlagship",
-    value: function () {
-      var _certifyFlagship2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15() {
-        var stackClient;
-        return _regenerator.default.wrap(function _callee15$(_context15) {
-          while (1) {
-            switch (_context15.prev = _context15.next) {
-              case 0:
-                stackClient = this.getStackClient();
+  function queryView(view, opts) {
+    return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () {
+      return queryViewInQueue(view, opts);
+    })();
+  }
 
-                if (!stackClient.oauthOptions.shouldRequireFlagshipPermissions) {
-                  _context15.next = 4;
-                  break;
-                }
+  function queryViewInQueue(view, opts) {
+    var totalRows;
+    var shouldReduce = view.reduceFun && opts.reduce !== false;
+    var skip = opts.skip || 0;
+    if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
+      // equivalent query
+      opts.limit = 0;
+      delete opts.keys;
+    }
 
-                _context15.next = 4;
-                return (0, _flagshipCertification.certifyFlagship)(stackClient.oauthOptions.certificationConfig, this);
+    function fetchFromView(viewOpts) {
+      viewOpts.include_docs = true;
+      return view.db.allDocs(viewOpts).then(function (res) {
+        totalRows = res.total_rows;
+        return res.rows.map(function (result) {
 
-              case 4:
-              case "end":
-                return _context15.stop();
+          // implicit migration - in older versions of PouchDB,
+          // we explicitly stored the doc as {id: ..., key: ..., value: ...}
+          // this is tested in a migration test
+          /* istanbul ignore next */
+          if ('value' in result.doc && typeof result.doc.value === 'object' &&
+            result.doc.value !== null) {
+            var keys = Object.keys(result.doc.value).sort();
+            // this detection method is not perfect, but it's unlikely the user
+            // emitted a value which was an object with these 3 exact keys
+            var expectedKeys = ['id', 'key', 'value'];
+            if (!(keys < expectedKeys || keys > expectedKeys)) {
+              return result.doc.value;
             }
           }
-        }, _callee15, this);
-      }));
 
-      function certifyFlagship() {
-        return _certifyFlagship2.apply(this, arguments);
+          var parsedKeyAndDocId = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.parseIndexableString)(result.doc._id);
+          return {
+            key: parsedKeyAndDocId[0],
+            id: parsedKeyAndDocId[1],
+            value: ('value' in result.doc ? result.doc.value : null)
+          };
+        });
+      });
+    }
+
+    function onMapResultsReady(rows) {
+      var finalResults;
+      if (shouldReduce) {
+        finalResults = reduceView(view, rows, opts);
+      } else {
+        finalResults = {
+          total_rows: totalRows,
+          offset: skip,
+          rows: rows
+        };
+      }
+      /* istanbul ignore if */
+      if (opts.update_seq) {
+        finalResults.update_seq = view.seq;
       }
+      if (opts.include_docs) {
+        var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(rows.map(rowToDocId));
 
-      return certifyFlagship;
-    }()
-    /**
-     * Creates an OAuth token with needed permissions for the current client.
-     * The authorization page URL generation can be overriding by passing a function pointer as `openURLCallback` parameter
-     * It is possible to skip the session creation process (when using an in-app browser) by passing a sessionCode (see https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code)
-     *
-     * @param {object} [options] - Authorization options
-     * @param {OpenURLCallback} [options.openURLCallback] - Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.
-     * @param {SessionCode} [options.sessionCode] - session code than can be added to the authorization URL to automatically create the session.
-     * @param {PKCECodes} [options.pkceCodes] - code verifier and a code challenge that should be used in the PKCE verification process.
-     * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client.
-     */
+        return view.sourceDB.allDocs({
+          keys: docIds,
+          include_docs: true,
+          conflicts: opts.conflicts,
+          attachments: opts.attachments,
+          binary: opts.binary
+        }).then(function (allDocsRes) {
+          var docIdsToDocs = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
+          allDocsRes.rows.forEach(function (row) {
+            docIdsToDocs.set(row.id, row.doc);
+          });
+          rows.forEach(function (row) {
+            var docId = rowToDocId(row);
+            var doc = docIdsToDocs.get(docId);
+            if (doc) {
+              row.doc = doc;
+            }
+          });
+          return finalResults;
+        });
+      } else {
+        return finalResults;
+      }
+    }
 
-  }, {
-    key: "authorize",
-    value: function () {
-      var _authorize = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() {
-        var _ref6,
-            _ref6$openURLCallback,
-            openURLCallback,
-            _ref6$sessionCode,
-            sessionCode,
-            _ref6$pkceCodes,
-            pkceCodes,
-            codeVerifier,
-            codeChallenge,
-            stackClient,
-            stateCode,
-            url,
-            redirectedURL,
-            code,
-            token,
-            _stackClient,
-            _args16 = arguments;
+    if (typeof opts.keys !== 'undefined') {
+      var keys = opts.keys;
+      var fetchPromises = keys.map(function (key) {
+        var viewOpts = {
+          startkey : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key]),
+          endkey   : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key, {}])
+        };
+        /* istanbul ignore if */
+        if (opts.update_seq) {
+          viewOpts.update_seq = true;
+        }
+        return fetchFromView(viewOpts);
+      });
+      return Promise.all(fetchPromises).then(pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten).then(onMapResultsReady);
+    } else { // normal query, no 'keys'
+      var viewOpts = {
+        descending : opts.descending
+      };
+      /* istanbul ignore if */
+      if (opts.update_seq) {
+        viewOpts.update_seq = true;
+      }
+      var startkey;
+      var endkey;
+      if ('start_key' in opts) {
+        startkey = opts.start_key;
+      }
+      if ('startkey' in opts) {
+        startkey = opts.startkey;
+      }
+      if ('end_key' in opts) {
+        endkey = opts.end_key;
+      }
+      if ('endkey' in opts) {
+        endkey = opts.endkey;
+      }
+      if (typeof startkey !== 'undefined') {
+        viewOpts.startkey = opts.descending ?
+          (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey, {}]) :
+          (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey]);
+      }
+      if (typeof endkey !== 'undefined') {
+        var inclusiveEnd = opts.inclusive_end !== false;
+        if (opts.descending) {
+          inclusiveEnd = !inclusiveEnd;
+        }
 
-        return _regenerator.default.wrap(function _callee16$(_context16) {
-          while (1) {
-            switch (_context16.prev = _context16.next) {
-              case 0:
-                _ref6 = _args16.length > 0 && _args16[0] !== undefined ? _args16[0] : {}, _ref6$openURLCallback = _ref6.openURLCallback, openURLCallback = _ref6$openURLCallback === void 0 ? _mobile.authFunction : _ref6$openURLCallback, _ref6$sessionCode = _ref6.sessionCode, sessionCode = _ref6$sessionCode === void 0 ? undefined : _ref6$sessionCode, _ref6$pkceCodes = _ref6.pkceCodes, pkceCodes = _ref6$pkceCodes === void 0 ? {} : _ref6$pkceCodes;
-                _context16.prev = 1;
-                codeVerifier = pkceCodes.codeVerifier, codeChallenge = pkceCodes.codeChallenge;
-                stackClient = this.getStackClient();
-                stateCode = stackClient.generateStateCode();
-                url = stackClient.getAuthCodeURL({
-                  stateCode: stateCode,
-                  scopes: undefined,
-                  sessionCode: sessionCode,
-                  codeChallenge: codeChallenge
-                });
-                _context16.next = 8;
-                return openURLCallback(url);
+        viewOpts.endkey = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)(
+          inclusiveEnd ? [endkey, {}] : [endkey]);
+      }
+      if (typeof opts.key !== 'undefined') {
+        var keyStart = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key]);
+        var keyEnd = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key, {}]);
+        if (viewOpts.descending) {
+          viewOpts.endkey = keyStart;
+          viewOpts.startkey = keyEnd;
+        } else {
+          viewOpts.startkey = keyStart;
+          viewOpts.endkey = keyEnd;
+        }
+      }
+      if (!shouldReduce) {
+        if (typeof opts.limit === 'number') {
+          viewOpts.limit = opts.limit;
+        }
+        viewOpts.skip = skip;
+      }
+      return fetchFromView(viewOpts).then(onMapResultsReady);
+    }
+  }
 
-              case 8:
-                redirectedURL = _context16.sent;
-                code = stackClient.getAccessCodeFromURL(redirectedURL, stateCode);
-                _context16.next = 12;
-                return stackClient.fetchAccessToken(code, undefined, undefined, codeVerifier);
+  function httpViewCleanup(db) {
+    return db.fetch('_view_cleanup', {
+      headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}),
+      method: 'POST'
+    }).then(function (response) {
+      return response.json();
+    });
+  }
 
-              case 12:
-                token = _context16.sent;
-                stackClient.setToken(token);
-                return _context16.abrupt("return", {
-                  token: token,
-                  infos: stackClient.oauthOptions,
-                  client: stackClient.oauthOptions // for compat with Authentication comp reasons
+  function localViewCleanup(db) {
+    return db.get('_local/' + localDocName).then(function (metaDoc) {
+      var docsToViews = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map();
+      Object.keys(metaDoc.views).forEach(function (fullViewName) {
+        var parts = parseViewName(fullViewName);
+        var designDocName = '_design/' + parts[0];
+        var viewName = parts[1];
+        var views = docsToViews.get(designDocName);
+        if (!views) {
+          views = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set();
+          docsToViews.set(designDocName, views);
+        }
+        views.add(viewName);
+      });
+      var opts = {
+        keys : (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docsToViews),
+        include_docs : true
+      };
+      return db.allDocs(opts).then(function (res) {
+        var viewsToStatus = {};
+        res.rows.forEach(function (row) {
+          var ddocName = row.key.substring(8); // cuts off '_design/'
+          docsToViews.get(row.key).forEach(function (viewName) {
+            var fullViewName = ddocName + '/' + viewName;
+            /* istanbul ignore if */
+            if (!metaDoc.views[fullViewName]) {
+              // new format, without slashes, to support PouchDB 2.2.0
+              // migration test in pouchdb's browser.migration.js verifies this
+              fullViewName = viewName;
+            }
+            var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
+            // design doc deleted, or view function nonexistent
+            var statusIsGood = row.doc && row.doc.views &&
+              row.doc.views[viewName];
+            viewDBNames.forEach(function (viewDBName) {
+              viewsToStatus[viewDBName] =
+                viewsToStatus[viewDBName] || statusIsGood;
+            });
+          });
+        });
+        var dbsToDelete = Object.keys(viewsToStatus).filter(
+          function (viewDBName) { return !viewsToStatus[viewDBName]; });
+        var destroyPromises = dbsToDelete.map(function (viewDBName) {
+          return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(viewDBName), function () {
+            return new db.constructor(viewDBName, db.__opts).destroy();
+          })();
+        });
+        return Promise.all(destroyPromises).then(function () {
+          return {ok: true};
+        });
+      });
+    }, defaultsTo({ok: true}));
+  }
 
-                });
+  function queryPromised(db, fun, opts) {
+    /* istanbul ignore next */
+    if (typeof db._query === 'function') {
+      return customQuery(db, fun, opts);
+    }
+    if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) {
+      return httpQuery(db, fun, opts);
+    }
 
-              case 17:
-                _context16.prev = 17;
-                _context16.t0 = _context16["catch"](1);
+    if (typeof fun !== 'string') {
+      // temp_view
+      checkQueryParseError(opts, fun);
 
-                /* if REGISTRATION_ABORT is emited, we have to unregister the client. */
-                if (_context16.t0.message === _const.REGISTRATION_ABORT) {
-                  _stackClient = this.getStackClient();
+      tempViewQueue.add(function () {
+        var createViewPromise = createView(
+          /* sourceDB */ db,
+          /* viewName */ 'temp_view/temp_view',
+          /* mapFun */ fun.map,
+          /* reduceFun */ fun.reduce,
+          /* temporary */ true,
+          /* localDocName */ localDocName);
+        return createViewPromise.then(function (view) {
+          return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.fin)(updateView(view).then(function () {
+            return queryView(view, opts);
+          }), function () {
+            return view.db.destroy();
+          });
+        });
+      });
+      return tempViewQueue.finish();
+    } else {
+      // persistent view
+      var fullViewName = fun;
+      var parts = parseViewName(fullViewName);
+      var designDocName = parts[0];
+      var viewName = parts[1];
+      return db.get('_design/' + designDocName).then(function (doc) {
+        var fun = doc.views && doc.views[viewName];
 
-                  _stackClient.unregister();
-                }
+        if (!fun) {
+          // basic validator; it's assumed that every subclass would want this
+          throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.NotFoundError('ddoc ' + doc._id + ' has no view named ' +
+            viewName);
+        }
 
-                throw _context16.t0;
+        ddocValidator(doc, viewName);
+        checkQueryParseError(opts, fun);
 
-              case 21:
-              case "end":
-                return _context16.stop();
+        var createViewPromise = createView(
+          /* sourceDB */ db,
+          /* viewName */ fullViewName,
+          /* mapFun */ fun.map,
+          /* reduceFun */ fun.reduce,
+          /* temporary */ false,
+          /* localDocName */ localDocName);
+        return createViewPromise.then(function (view) {
+          if (opts.stale === 'ok' || opts.stale === 'update_after') {
+            if (opts.stale === 'update_after') {
+              (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () {
+                updateView(view);
+              });
             }
+            return queryView(view, opts);
+          } else { // stale not ok
+            return updateView(view).then(function () {
+              return queryView(view, opts);
+            });
           }
-        }, _callee16, this, [[1, 17]]);
-      }));
-
-      function authorize() {
-        return _authorize.apply(this, arguments);
-      }
-
-      return authorize;
-    }()
-    /**
-     * Renews the token if, for instance, new permissions are required or token
-     * has expired.
-     *
-     * @returns {object}   Contains the fetched token and the client information.
-     */
-
-  }, {
-    key: "renewAuthorization",
-    value: function renewAuthorization() {
-      return this.authorize({
-        openURLCallback: _mobile.authFunction
+        });
       });
     }
-    /**
-     * Sets the internal store of the client. Use this when you want to have cozy-client's
-     * internal store colocated with your existing Redux store.
-     *
-     * Typically, you would need to do this only once in your application, this is why
-     * setStore throws if you do it twice. If you really need to set the store again,
-     * use options.force = true.
-     *
-     * @example
-     * ```
-     * const client = new CozyClient()
-     * const store = createStore(combineReducers({
-     *   todos: todoReducer,
-     *   cozy: client.reducer()
-     * })
-     * client.setStore(store)
-     * ```
-     *
-     * @param {ReduxStore} store - A redux store
-     * @param {object} [options] - Options
-     * @param {boolean} [options.force] - Will deactivate throwing when client's store already exists
-     */
+  }
 
-  }, {
-    key: "setStore",
-    value: function setStore(store) {
-      var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
-          _ref7$force = _ref7.force,
-          force = _ref7$force === void 0 ? false : _ref7$force;
+  function abstractQuery(fun, opts, callback) {
+    var db = this;
+    if (typeof opts === 'function') {
+      callback = opts;
+      opts = {};
+    }
+    opts = opts ? coerceOptions(opts) : {};
 
-      if (store === undefined) {
-        throw new Error('Store is undefined');
-      } else if (this.store && !force) {
-        throw new Error("Client already has a store, it is forbidden to change store.\nsetStore must be called before any query is executed. Try to\ncall setStore earlier in your code, preferably just after the\ninstantiation of the client.");
-      }
+    if (typeof fun === 'function') {
+      fun = {map : fun};
+    }
 
-      this.store = store;
+    var promise = Promise.resolve().then(function () {
+      return queryPromised(db, fun, opts);
+    });
+    (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.promisedCallback)(promise, callback);
+    return promise;
+  }
+
+  var abstractViewCleanup = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.callbackify)(function () {
+    var db = this;
+    /* istanbul ignore next */
+    if (typeof db._viewCleanup === 'function') {
+      return customViewCleanup(db);
     }
-  }, {
-    key: "ensureStore",
-    value: function ensureStore() {
-      if (!this.store) {
-        this.setStore((0, _store.createStore)());
-      }
+    if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) {
+      return httpViewCleanup(db);
     }
-    /**
-     * Returns whether the client has been revoked on the server
-     */
+    return localViewCleanup(db);
+  });
 
-  }, {
-    key: "checkForRevocation",
-    value: function () {
-      var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17() {
-        return _regenerator.default.wrap(function _callee17$(_context17) {
-          while (1) {
-            switch (_context17.prev = _context17.next) {
-              case 0:
-                return _context17.abrupt("return", this.stackClient.checkForRevocation());
+  return {
+    query: abstractQuery,
+    viewCleanup: abstractViewCleanup
+  };
+}
 
-              case 1:
-              case "end":
-                return _context17.stop();
-            }
-          }
-        }, _callee17, this);
-      }));
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createAbstractMapReduce);
 
-      function checkForRevocation() {
-        return _checkForRevocation.apply(this, arguments);
-      }
 
-      return checkForRevocation;
-    }()
-    /** Sets public attribute and emits event related to revocation */
+/***/ }),
+/* 518 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-  }, {
-    key: "handleRevocationChange",
-    value: function handleRevocationChange(state) {
-      if (state) {
-        this.isRevoked = true;
-        this.emit('revoked');
-      } else {
-        this.isRevoked = false;
-        this.emit('unrevoked');
-      }
-    }
-    /** Emits event when token is refreshed */
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "atob": () => (/* binding */ thisAtob),
+/* harmony export */   "btoa": () => (/* binding */ thisBtoa),
+/* harmony export */   "base64StringToBlobOrBuffer": () => (/* binding */ b64ToBluffer),
+/* harmony export */   "binaryStringToArrayBuffer": () => (/* binding */ binaryStringToArrayBuffer),
+/* harmony export */   "binaryStringToBlobOrBuffer": () => (/* binding */ binStringToBluffer),
+/* harmony export */   "blob": () => (/* binding */ createBlob),
+/* harmony export */   "blobOrBufferToBase64": () => (/* binding */ blobToBase64),
+/* harmony export */   "blobOrBufferToBinaryString": () => (/* binding */ blobToBase64$1),
+/* harmony export */   "readAsArrayBuffer": () => (/* binding */ readAsArrayBuffer),
+/* harmony export */   "readAsBinaryString": () => (/* binding */ readAsBinaryString),
+/* harmony export */   "typedBuffer": () => (/* binding */ typedBuffer)
+/* harmony export */ });
+/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(519);
+/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer_from__WEBPACK_IMPORTED_MODULE_0__);
 
-  }, {
-    key: "handleTokenRefresh",
-    value: function handleTokenRefresh(token) {
-      this.emit('tokenRefreshed');
 
-      if (this.options.onTokenRefresh) {
-        deprecatedHandler("Using onTokenRefresh is deprecated, please use events like this: cozyClient.on('tokenRefreshed', token => console.log('Token has been refreshed', token)). https://git.io/fj3M3");
-        this.options.onTokenRefresh(token);
-      }
-    }
-    /**
-     * If no stack client has been passed in options, creates a default stack
-     * client and attaches handlers for revocation and token refresh.
-     * If a stackClient has been passed in options, ensure it has handlers for
-     * revocation and token refresh.
-     *
-     * If `oauth` options are passed, stackClient is an OAuthStackClient.
-     */
+function thisAtob(str) {
+  var base64 = new Buffer(str, 'base64');
+  // Node.js will just skip the characters it can't decode instead of
+  // throwing an exception
+  if (base64.toString('base64') !== str) {
+    throw new Error("attachment is not a valid base64 string");
+  }
+  return base64.toString('binary');
+}
 
-  }, {
-    key: "createClient",
-    value: function createClient() {
-      if (this.options.client) {
-        console.warn('CozyClient: Using options.client is deprecated, please use options.stackClient.');
-      }
+function thisBtoa(str) {
+  return buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(str, 'binary').toString('base64');
+}
 
-      var warningForCustomHandlers = this.options.warningForCustomHandlers !== undefined ? this.options.warningForCustomHandlers : true;
-      var stackClient = this.options.client || this.options.stackClient;
-      var handlers = {
-        onRevocationChange: this.handleRevocationChange,
-        onTokenRefresh: this.handleTokenRefresh
-      };
+function typedBuffer(binString, buffType, type) {
+  // buffType is either 'binary' or 'base64'
+  var buff = buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(binString, buffType);
+  buff.type = type; // non-standard, but used for consistency with the browser
+  return buff;
+}
 
-      if (stackClient) {
-        this.stackClient = stackClient;
+function b64ToBluffer(b64, type) {
+  return typedBuffer(b64, 'base64', type);
+}
 
-        if (!stackClient.options) {
-          stackClient.options = {};
-        }
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+  var length = bin.length;
+  var buf = new ArrayBuffer(length);
+  var arr = new Uint8Array(buf);
+  for (var i = 0; i < length; i++) {
+    arr[i] = bin.charCodeAt(i);
+  }
+  return buf;
+}
 
-        for (var _i2 = 0, _Object$keys2 = Object.keys(handlers); _i2 < _Object$keys2.length; _i2++) {
-          var handlerName = _Object$keys2[_i2];
+function binStringToBluffer(binString, type) {
+  return typedBuffer(binString, 'binary', type);
+}
 
-          if (!stackClient.options[handlerName]) {
-            stackClient.options[handlerName] = handlers[handlerName];
-          } else {
-            if (warningForCustomHandlers) {
-              console.warn("You passed a stackClient with its own ".concat(handlerName, ". It is not supported, unexpected things might happen."));
-            }
-          }
-        }
-      } else {
-        var options = _objectSpread(_objectSpread({}, this.options), handlers);
+// This function is unused in Node
+/* istanbul ignore next */
+function createBlob() {
+}
 
-        this.stackClient = this.options.oauth ? new _cozyStackClient.OAuthClient(options) : new _cozyStackClient.default(options);
-      }
+function blobToBase64(blobOrBuffer, callback) {
+  callback(blobOrBuffer.toString('base64'));
+}
 
-      this.client = new Proxy(this.stackClient, deprecatedHandler('Using cozyClient.client is deprecated, please use cozyClient.stackClient.'));
-    }
-  }, {
-    key: "getClient",
-    value: function getClient() {
-      console.warn('CozyClient: getClient() is deprecated, please use getStackClient().');
-      return this.getStackClient();
-    }
-  }, {
-    key: "getStackClient",
-    value: function getStackClient() {
-      if (!this.stackClient) {
-        this.createClient();
-      }
+// not used in Node, but here for completeness
+function blobToBase64$1(blobOrBuffer, callback) {
+  callback(blobOrBuffer.toString('binary'));
+}
 
-      return this.stackClient;
-    }
-  }, {
-    key: "reducer",
-    value: function reducer() {
-      return _store.default;
-    }
-  }, {
-    key: "dispatch",
-    value: function dispatch(action) {
-      return this.store.dispatch(action);
-    }
-    /**
-     * getInstanceOptions - Returns current instance options, such as domain or app slug
-     *
-     * @returns {object}
-     */
+// simplified API. universal browser support is assumed
+function readAsArrayBuffer(blob, callback) {
+  var reader = new FileReader();
+  reader.onloadend = function (e) {
+    var result = e.target.result || new ArrayBuffer(0);
+    callback(result);
+  };
+  reader.readAsArrayBuffer(blob);
+}
 
-  }, {
-    key: "getInstanceOptions",
-    value: function getInstanceOptions() {
-      return this.instanceOptions;
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+  var binary = '';
+  var bytes = new Uint8Array(buffer);
+  var length = bytes.byteLength;
+  for (var i = 0; i < length; i++) {
+    binary += String.fromCharCode(bytes[i]);
+  }
+  return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+  var reader = new FileReader();
+  var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+  reader.onloadend = function (e) {
+    var result = e.target.result || '';
+    if (hasBinaryString) {
+      return callback(result);
     }
-    /**
-     * loadInstanceOptionsFromDOM - Loads the dataset injected by the Stack in web pages and exposes it through getInstanceOptions
-     *
-     * @param {string} [selector=[role=application]] A selector for the node that holds the dataset to load
-     *
-     * @returns {void}
-     */
+    callback(arrayBufferToBinaryString(result));
+  };
+  if (hasBinaryString) {
+    reader.readAsBinaryString(blob);
+  } else {
+    reader.readAsArrayBuffer(blob);
+  }
+}
 
-  }, {
-    key: "loadInstanceOptionsFromDOM",
-    value: function loadInstanceOptionsFromDOM() {
-      var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '[role=application]';
-      var root = document.querySelector(selector);
 
-      if (!(root instanceof HTMLElement)) {
-        throw new Error('The selector that is passed does not return an HTMLElement');
-      }
 
-      var _root$dataset = root.dataset,
-          _root$dataset$cozy = _root$dataset.cozy,
-          cozy = _root$dataset$cozy === void 0 ? '{}' : _root$dataset$cozy,
-          dataset = (0, _objectWithoutProperties2.default)(_root$dataset, ["cozy"]);
-      this.instanceOptions = _objectSpread(_objectSpread({}, JSON.parse(cozy)), dataset);
-      this.capabilities = this.instanceOptions.capabilities || null;
-    }
-    /**
-     * Directly set the data in the store, without using a query
-     * This is useful for cases like Pouch replication, which wants to
-     * set some data in the store.
-     *
-     * @param {object} data - Data that is inserted in the store. Shape: { doctype: [data] }
-     */
 
-  }, {
-    key: "setData",
-    value: function setData(data) {
-      var _this10 = this;
+/***/ }),
+/* 519 */
+/***/ ((module) => {
 
-      this.ensureStore();
-      Object.entries(data).forEach(function (_ref8) {
-        var _ref9 = (0, _slicedToArray2.default)(_ref8, 2),
-            doctype = _ref9[0],
-            data = _ref9[1];
+var toString = Object.prototype.toString
 
-        _this10.dispatch((0, _store.receiveQueryResult)(null, {
-          data: data
-        }));
-      });
-    }
-    /**
-     * At any time put an error function
-     *
-     * @param {Function} [onError] - Set a callback for queries which are errored
-     * @throws {Error} onError should not have been defined yet
-     */
+var isModern = (
+  typeof Buffer.alloc === 'function' &&
+  typeof Buffer.allocUnsafe === 'function' &&
+  typeof Buffer.from === 'function'
+)
 
-  }, {
-    key: "setOnError",
-    value: function setOnError(onError) {
-      if (this.options && this.options.onError) {
-        throw new Error('On Error is already defined');
-      }
+function isArrayBuffer (input) {
+  return toString.call(input).slice(8, -1) === 'ArrayBuffer'
+}
 
-      this.options.onError = onError;
-    }
-  }, {
-    key: "toJSON",
-    value: function toJSON() {
-      return new _snapshots.CozyClient({
-        uri: this.options.uri
-      });
-    }
-  }], [{
-    key: "fromOldClient",
-    value: function fromOldClient(oldClient, options) {
-      return new CozyClient(_objectSpread({
-        uri: oldClient._url,
-        token: oldClient._token.token
-      }, options));
-    }
-    /**
-     * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate
-     * a client with an OAuth-based instance of cozy-client-js.
-     *
-     * Warning: unlike other instantiators, this one needs to be awaited.
-     *
-     * @param {OldCozyClient} oldClient - An OAuth instance of the deprecated cozy-client
-     * @param {object} options - CozyStackClient options
-     * @returns {Promise<CozyClient>} An instance of a client, configured from the old client
-     */
+function fromArrayBuffer (obj, byteOffset, length) {
+  byteOffset >>>= 0
 
-  }, {
-    key: "fromOldOAuthClient",
-    value: function () {
-      var _fromOldOAuthClient = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(oldClient, options) {
-        var credentials, oauthOptions;
-        return _regenerator.default.wrap(function _callee18$(_context18) {
-          while (1) {
-            switch (_context18.prev = _context18.next) {
-              case 0:
-                if (!oldClient._oauth) {
-                  _context18.next = 8;
-                  break;
-                }
+  var maxLength = obj.byteLength - byteOffset
 
-                _context18.next = 3;
-                return oldClient.authorize();
+  if (maxLength < 0) {
+    throw new RangeError("'offset' is out of bounds")
+  }
 
-              case 3:
-                credentials = _context18.sent;
-                oauthOptions = {
-                  oauth: credentials.client,
-                  token: credentials.token,
-                  scope: credentials.token.scope
-                };
-                return _context18.abrupt("return", new CozyClient(_objectSpread(_objectSpread({
-                  uri: oldClient._url
-                }, oauthOptions), options)));
+  if (length === undefined) {
+    length = maxLength
+  } else {
+    length >>>= 0
 
-              case 8:
-                throw new Error('Cannot instantiate a new client: old client is not an OAuth client. CozyClient.fromOldClient might be more suitable.');
+    if (length > maxLength) {
+      throw new RangeError("'length' is out of bounds")
+    }
+  }
 
-              case 9:
-              case "end":
-                return _context18.stop();
-            }
-          }
-        }, _callee18);
-      }));
+  return isModern
+    ? Buffer.from(obj.slice(byteOffset, byteOffset + length))
+    : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)))
+}
 
-      function fromOldOAuthClient(_x17, _x18) {
-        return _fromOldOAuthClient.apply(this, arguments);
-      }
+function fromString (string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') {
+    encoding = 'utf8'
+  }
 
-      return fromOldOAuthClient;
-    }()
-    /**
-     * In konnector/service context, CozyClient can be instantiated from
-     * environment variables
-     *
-     * @param  {NodeEnvironment} [envArg]  - The environment
-     * @param  {object} options - Options
-     * @returns {CozyClient}
-     */
+  if (!Buffer.isEncoding(encoding)) {
+    throw new TypeError('"encoding" must be a valid string encoding')
+  }
 
-  }, {
-    key: "fromEnv",
-    value: function fromEnv(envArg) {
-      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-      var env = envArg || (typeof process !== 'undefined' ? process.env : {});
-      var COZY_URL = env.COZY_URL,
-          COZY_CREDENTIALS = env.COZY_CREDENTIALS,
-          NODE_ENV = env.NODE_ENV;
+  return isModern
+    ? Buffer.from(string, encoding)
+    : new Buffer(string, encoding)
+}
 
-      if (!COZY_URL || !COZY_CREDENTIALS) {
-        throw new Error('Env used to instantiate CozyClient must have COZY_URL and COZY_CREDENTIALS');
-      }
+function bufferFrom (value, encodingOrOffset, length) {
+  if (typeof value === 'number') {
+    throw new TypeError('"value" argument must not be a number')
+  }
 
-      if (NODE_ENV === 'development') {
-        options.oauth = JSON.parse(COZY_CREDENTIALS);
-      } else {
-        options.token = COZY_CREDENTIALS.trim();
-      }
+  if (isArrayBuffer(value)) {
+    return fromArrayBuffer(value, encodingOrOffset, length)
+  }
 
-      options.uri = COZY_URL.trim();
-      return new CozyClient(_objectSpread({}, options));
-    }
-    /**
-     * When used from an app, CozyClient can be instantiated from the data injected by the stack in
-     * the DOM.
-     *
-     * @param  {object}   options  - CozyClient constructor options
-     * @param  {string}   selector - Options
-     * @returns {CozyClient} - CozyClient instance
-     */
+  if (typeof value === 'string') {
+    return fromString(value, encodingOrOffset)
+  }
 
-  }, {
-    key: "fromDOM",
-    value: function fromDOM() {
-      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-      var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '[role=application]';
-      var root = document.querySelector(selector);
+  return isModern
+    ? Buffer.from(value)
+    : new Buffer(value)
+}
 
-      if (!(root instanceof HTMLElement)) {
-        throw new Error("Cannot find an HTMLElement corresponding to ".concat(selector));
-      }
+module.exports = bufferFrom
 
-      if (!root || !root.dataset) {
-        throw new Error("Found no data in ".concat(selector, " to instantiate cozyClient"));
-      }
 
-      var data = root.dataset.cozy ? JSON.parse(root.dataset.cozy) : _objectSpread({}, root.dataset);
-      var domain = data.domain,
-          token = data.token;
+/***/ }),
+/* 520 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-      if (!domain || !token) {
-        domain = domain || data.cozyDomain;
-        token = token || data.cozyToken;
-      }
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "uniq": () => (/* binding */ uniq),
+/* harmony export */   "sequentialize": () => (/* binding */ sequentialize),
+/* harmony export */   "fin": () => (/* binding */ fin),
+/* harmony export */   "callbackify": () => (/* binding */ callbackify),
+/* harmony export */   "promisedCallback": () => (/* binding */ promisedCallback),
+/* harmony export */   "mapToKeysArray": () => (/* binding */ mapToKeysArray),
+/* harmony export */   "QueryParseError": () => (/* binding */ QueryParseError),
+/* harmony export */   "NotFoundError": () => (/* binding */ NotFoundError),
+/* harmony export */   "BuiltInError": () => (/* binding */ BuiltInError)
+/* harmony export */ });
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(497);
+/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(509);
+/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(495);
+/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(507);
 
-      if (!domain || !token) {
-        throw new Error("Found no data in ".concat(root.dataset, " to instantiate cozyClient"));
-      }
 
-      return new CozyClient(_objectSpread({
-        uri: "".concat(window.location.protocol, "//").concat(domain),
-        token: token,
-        capabilities: data.capabilities
-      }, options));
-    }
-  }, {
-    key: "registerHook",
-    value: function registerHook(doctype, name, fn) {
-      var hooks = CozyClient.hooks[doctype] = CozyClient.hooks[doctype] || {};
-      hooks[name] = hooks[name] || [];
-      hooks[name].push(fn);
-    }
-  }]);
-  return CozyClient;
-}();
 
-CozyClient.hooks = CozyClient.hooks || {};
-CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
 
-CozyClient.version = "27.26.4";
 
-_microee.default.mixin(CozyClient);
+function QueryParseError(message) {
+  this.status = 400;
+  this.name = 'query_parse_error';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, QueryParseError);
+  } catch (e) {}
+}
 
-var _default = CozyClient;
-exports["default"] = _default;
+inherits__WEBPACK_IMPORTED_MODULE_0___default()(QueryParseError, Error);
 
-/***/ }),
-/* 514 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function NotFoundError(message) {
+  this.status = 404;
+  this.name = 'not_found';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, NotFoundError);
+  } catch (e) {}
+}
 
-var arrayWithHoles = __webpack_require__(515);
+inherits__WEBPACK_IMPORTED_MODULE_0___default()(NotFoundError, Error);
+
+function BuiltInError(message) {
+  this.status = 500;
+  this.name = 'invalid_value';
+  this.message = message;
+  this.error = true;
+  try {
+    Error.captureStackTrace(this, BuiltInError);
+  } catch (e) {}
+}
 
-var iterableToArray = __webpack_require__(516);
+inherits__WEBPACK_IMPORTED_MODULE_0___default()(BuiltInError, Error);
 
-var unsupportedIterableToArray = __webpack_require__(517);
+function promisedCallback(promise, callback) {
+  if (callback) {
+    promise.then(function (res) {
+      (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () {
+        callback(null, res);
+      });
+    }, function (reason) {
+      (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () {
+        callback(reason);
+      });
+    });
+  }
+  return promise;
+}
 
-var nonIterableRest = __webpack_require__(519);
+function callbackify(fun) {
+  return argsarray__WEBPACK_IMPORTED_MODULE_2___default()(function (args) {
+    var cb = args.pop();
+    var promise = fun.apply(this, args);
+    if (typeof cb === 'function') {
+      promisedCallback(promise, cb);
+    }
+    return promise;
+  });
+}
 
-function _toArray(arr) {
-  return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest();
+// Promise finally util similar to Q.finally
+function fin(promise, finalPromiseFactory) {
+  return promise.then(function (res) {
+    return finalPromiseFactory().then(function () {
+      return res;
+    });
+  }, function (reason) {
+    return finalPromiseFactory().then(function () {
+      throw reason;
+    });
+  });
 }
 
-module.exports = _toArray;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+function sequentialize(queue, promiseFactory) {
+  return function () {
+    var args = arguments;
+    var that = this;
+    return queue.add(function () {
+      return promiseFactory.apply(that, args);
+    });
+  };
+}
 
-/***/ }),
-/* 515 */
-/***/ ((module) => {
+// uniq an array of strings, order not guaranteed
+// similar to underscore/lodash _.uniq
+function uniq(arr) {
+  var theSet = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__.Set(arr);
+  var result = new Array(theSet.size);
+  var index = -1;
+  theSet.forEach(function (value) {
+    result[++index] = value;
+  });
+  return result;
+}
 
-function _arrayWithHoles(arr) {
-  if (Array.isArray(arr)) return arr;
+function mapToKeysArray(map) {
+  var result = new Array(map.size);
+  var index = -1;
+  map.forEach(function (value, key) {
+    result[++index] = key;
+  });
+  return result;
 }
 
-module.exports = _arrayWithHoles;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+
+
 
 /***/ }),
-/* 516 */
-/***/ ((module) => {
+/* 521 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-function _iterableToArray(iter) {
-  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
-}
+"use strict";
 
-module.exports = _iterableToArray;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-/***/ }),
-/* 517 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _interopRequireWildcard = __webpack_require__(522);
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+var _exportNames = {
+  CozyLink: true,
+  StackLink: true,
+  compose: true,
+  QueryDefinition: true,
+  Mutations: true,
+  MutationTypes: true,
+  getDoctypeFromOperation: true,
+  Q: true,
+  Association: true,
+  HasMany: true,
+  HasOne: true,
+  HasOneInPlace: true,
+  HasManyInPlace: true,
+  HasManyTriggers: true,
+  dehydrate: true,
+  generateWebLink: true,
+  rootCozyUrl: true,
+  InvalidCozyUrlError: true,
+  InvalidProtocolError: true,
+  cancelable: true,
+  getQueryFromState: true,
+  Registry: true,
+  manifest: true,
+  BulkEditError: true,
+  models: true
+};
+Object.defineProperty(exports, "default", ({
+  enumerable: true,
+  get: function get() {
+    return _CozyClient.default;
+  }
+}));
+Object.defineProperty(exports, "CozyLink", ({
+  enumerable: true,
+  get: function get() {
+    return _CozyLink.default;
+  }
+}));
+Object.defineProperty(exports, "StackLink", ({
+  enumerable: true,
+  get: function get() {
+    return _StackLink.default;
+  }
+}));
+Object.defineProperty(exports, "compose", ({
+  enumerable: true,
+  get: function get() {
+    return _flow.default;
+  }
+}));
+Object.defineProperty(exports, "QueryDefinition", ({
+  enumerable: true,
+  get: function get() {
+    return _dsl.QueryDefinition;
+  }
+}));
+Object.defineProperty(exports, "Mutations", ({
+  enumerable: true,
+  get: function get() {
+    return _dsl.Mutations;
+  }
+}));
+Object.defineProperty(exports, "MutationTypes", ({
+  enumerable: true,
+  get: function get() {
+    return _dsl.MutationTypes;
+  }
+}));
+Object.defineProperty(exports, "getDoctypeFromOperation", ({
+  enumerable: true,
+  get: function get() {
+    return _dsl.getDoctypeFromOperation;
+  }
+}));
+Object.defineProperty(exports, "Q", ({
+  enumerable: true,
+  get: function get() {
+    return _dsl.Q;
+  }
+}));
+Object.defineProperty(exports, "Association", ({
+  enumerable: true,
+  get: function get() {
+    return _associations.Association;
+  }
+}));
+Object.defineProperty(exports, "HasMany", ({
+  enumerable: true,
+  get: function get() {
+    return _associations.HasMany;
+  }
+}));
+Object.defineProperty(exports, "HasOne", ({
+  enumerable: true,
+  get: function get() {
+    return _associations.HasOne;
+  }
+}));
+Object.defineProperty(exports, "HasOneInPlace", ({
+  enumerable: true,
+  get: function get() {
+    return _associations.HasOneInPlace;
+  }
+}));
+Object.defineProperty(exports, "HasManyInPlace", ({
+  enumerable: true,
+  get: function get() {
+    return _associations.HasManyInPlace;
+  }
+}));
+Object.defineProperty(exports, "HasManyTriggers", ({
+  enumerable: true,
+  get: function get() {
+    return _associations.HasManyTriggers;
+  }
+}));
+Object.defineProperty(exports, "dehydrate", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.dehydrate;
+  }
+}));
+Object.defineProperty(exports, "generateWebLink", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.generateWebLink;
+  }
+}));
+Object.defineProperty(exports, "rootCozyUrl", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.rootCozyUrl;
+  }
+}));
+Object.defineProperty(exports, "InvalidCozyUrlError", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.InvalidCozyUrlError;
+  }
+}));
+Object.defineProperty(exports, "InvalidProtocolError", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.InvalidProtocolError;
+  }
+}));
+Object.defineProperty(exports, "cancelable", ({
+  enumerable: true,
+  get: function get() {
+    return _utils.cancelable;
+  }
+}));
+Object.defineProperty(exports, "getQueryFromState", ({
+  enumerable: true,
+  get: function get() {
+    return _store.getQueryFromState;
+  }
+}));
+Object.defineProperty(exports, "Registry", ({
+  enumerable: true,
+  get: function get() {
+    return _registry.default;
+  }
+}));
+Object.defineProperty(exports, "BulkEditError", ({
+  enumerable: true,
+  get: function get() {
+    return _errors.BulkEditError;
+  }
+}));
+exports.models = exports.manifest = void 0;
+
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
-var arrayLikeToArray = __webpack_require__(518);
+var _CozyLink = _interopRequireDefault(__webpack_require__(699));
 
-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);
-}
+var _StackLink = _interopRequireDefault(__webpack_require__(698));
 
-module.exports = _unsupportedIterableToArray;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+var _flow = _interopRequireDefault(__webpack_require__(805));
 
-/***/ }),
-/* 518 */
-/***/ ((module) => {
+var _dsl = __webpack_require__(619);
 
-function _arrayLikeToArray(arr, len) {
-  if (len == null || len > arr.length) len = arr.length;
+var _associations = __webpack_require__(703);
 
-  for (var i = 0, arr2 = new Array(len); i < len; i++) {
-    arr2[i] = arr[i];
-  }
+var _helpers = __webpack_require__(768);
 
-  return arr2;
-}
+var _utils = __webpack_require__(817);
 
-module.exports = _arrayLikeToArray;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+var _store = __webpack_require__(705);
 
-/***/ }),
-/* 519 */
-/***/ ((module) => {
+var _registry = _interopRequireDefault(__webpack_require__(608));
 
-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.");
-}
+var manifest = _interopRequireWildcard(__webpack_require__(818));
 
-module.exports = _nonIterableRest;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+exports.manifest = manifest;
 
-/***/ }),
-/* 520 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _mock = __webpack_require__(819);
 
-var arrayWithHoles = __webpack_require__(515);
+Object.keys(_mock).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+  if (key in exports && exports[key] === _mock[key]) return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function get() {
+      return _mock[key];
+    }
+  });
+});
 
-var iterableToArrayLimit = __webpack_require__(521);
+var _errors = __webpack_require__(700);
 
-var unsupportedIterableToArray = __webpack_require__(517);
+var _cli = __webpack_require__(820);
 
-var nonIterableRest = __webpack_require__(519);
+Object.keys(_cli).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+  if (key in exports && exports[key] === _cli[key]) return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function get() {
+      return _cli[key];
+    }
+  });
+});
 
-function _slicedToArray(arr, i) {
-  return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
-}
+var models = _interopRequireWildcard(__webpack_require__(826));
 
-module.exports = _slicedToArray;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+exports.models = models;
 
 /***/ }),
-/* 521 */
-/***/ ((module) => {
-
-function _iterableToArrayLimit(arr, i) {
-  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
+/* 522 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  if (_i == null) return;
-  var _arr = [];
-  var _n = true;
-  var _d = false;
+var _typeof = (__webpack_require__(523)["default"]);
 
-  var _s, _e;
+function _getRequireWildcardCache(nodeInterop) {
+  if (typeof WeakMap !== "function") return null;
+  var cacheBabelInterop = new WeakMap();
+  var cacheNodeInterop = new WeakMap();
+  return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) {
+    return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
+  })(nodeInterop);
+}
 
-  try {
-    for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
-      _arr.push(_s.value);
+function _interopRequireWildcard(obj, nodeInterop) {
+  if (!nodeInterop && obj && obj.__esModule) {
+    return obj;
+  }
 
-      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;
-    }
+  if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") {
+    return {
+      "default": obj
+    };
   }
 
-  return _arr;
-}
+  var cache = _getRequireWildcardCache(nodeInterop);
 
-module.exports = _iterableToArrayLimit;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+  if (cache && cache.has(obj)) {
+    return cache.get(obj);
+  }
 
-/***/ }),
-/* 522 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  var newObj = {};
+  var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
 
-var arrayWithoutHoles = __webpack_require__(523);
+  for (var key in obj) {
+    if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
+      var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
 
-var iterableToArray = __webpack_require__(516);
+      if (desc && (desc.get || desc.set)) {
+        Object.defineProperty(newObj, key, desc);
+      } else {
+        newObj[key] = obj[key];
+      }
+    }
+  }
 
-var unsupportedIterableToArray = __webpack_require__(517);
+  newObj["default"] = obj;
 
-var nonIterableSpread = __webpack_require__(524);
+  if (cache) {
+    cache.set(obj, newObj);
+  }
 
-function _toConsumableArray(arr) {
-  return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
+  return newObj;
 }
 
-module.exports = _toConsumableArray;
+module.exports = _interopRequireWildcard;
 module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
 /* 523 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/***/ ((module) => {
 
-var arrayLikeToArray = __webpack_require__(518);
+function _typeof(obj) {
+  "@babel/helpers - typeof";
 
-function _arrayWithoutHoles(arr) {
-  if (Array.isArray(arr)) return arrayLikeToArray(arr);
+  if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
+    module.exports = _typeof = function _typeof(obj) {
+      return typeof obj;
+    };
+
+    module.exports["default"] = module.exports, module.exports.__esModule = true;
+  } else {
+    module.exports = _typeof = function _typeof(obj) {
+      return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+    };
+
+    module.exports["default"] = module.exports, module.exports.__esModule = true;
+  }
+
+  return _typeof(obj);
 }
 
-module.exports = _arrayWithoutHoles;
+module.exports = _typeof;
 module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
 /* 524 */
 /***/ ((module) => {
 
-function _nonIterableSpread() {
-  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+function _interopRequireDefault(obj) {
+  return obj && obj.__esModule ? obj : {
+    "default": obj
+  };
 }
 
-module.exports = _nonIterableSpread;
+module.exports = _interopRequireDefault;
 module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
 /* 525 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var objectWithoutPropertiesLoose = __webpack_require__(526);
-
-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];
-    }
-  }
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  return target;
-}
+"use strict";
 
-module.exports = _objectWithoutProperties;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-/***/ }),
-/* 526 */
-/***/ ((module) => {
+var _interopRequireWildcard = __webpack_require__(522);
 
-function _objectWithoutPropertiesLoose(source, excluded) {
-  if (source == null) return {};
-  var target = {};
-  var sourceKeys = Object.keys(source);
-  var key, i;
+var _interopRequireDefault = __webpack_require__(524);
 
-  for (i = 0; i < sourceKeys.length; i++) {
-    key = sourceKeys[i];
-    if (excluded.indexOf(key) >= 0) continue;
-    target[key] = source[key];
-  }
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-  return target;
-}
+var _toArray2 = _interopRequireDefault(__webpack_require__(526));
 
-module.exports = _objectWithoutPropertiesLoose;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
 
-/***/ }),
-/* 527 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-module.exports = __webpack_require__(528);
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-/***/ }),
-/* 528 */
-/***/ ((module) => {
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var runtime = (function (exports) {
-  "use strict";
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-  var Op = Object.prototype;
-  var hasOwn = Op.hasOwnProperty;
-  var undefined; // More compressible than void 0.
-  var $Symbol = typeof Symbol === "function" ? Symbol : {};
-  var iteratorSymbol = $Symbol.iterator || "@@iterator";
-  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
-  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-  function define(obj, key, value) {
-    Object.defineProperty(obj, key, {
-      value: value,
-      enumerable: true,
-      configurable: true,
-      writable: true
-    });
-    return obj[key];
-  }
-  try {
-    // IE 8 has a broken Object.defineProperty that only works on DOM objects.
-    define({}, "");
-  } catch (err) {
-    define = function(obj, key, value) {
-      return obj[key] = value;
-    };
-  }
+var _mapValues = _interopRequireDefault(__webpack_require__(545));
 
-  function wrap(innerFn, outerFn, self, tryLocsList) {
-    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
-    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
-    var generator = Object.create(protoGenerator.prototype);
-    var context = new Context(tryLocsList || []);
+var _fromPairs = _interopRequireDefault(__webpack_require__(551));
 
-    // The ._invoke method unifies the implementations of the .next,
-    // .throw, and .return methods.
-    generator._invoke = makeInvokeMethod(innerFn, self, context);
+var _flatten = _interopRequireDefault(__webpack_require__(552));
 
-    return generator;
-  }
-  exports.wrap = wrap;
+var _uniqBy = _interopRequireDefault(__webpack_require__(412));
 
-  // Try/catch helper to minimize deoptimizations. Returns a completion
-  // record like context.tryEntries[i].completion. This interface could
-  // have been (and was previously) designed to take a closure to be
-  // invoked without arguments, but in all the cases we care about we
-  // already have an existing method we want to call, so there's no need
-  // to create a new function object. We can even get away with assuming
-  // the method takes exactly one argument, since that happens to be true
-  // in every case, so we don't have to touch the arguments object. The
-  // only additional allocation required is the completion record, which
-  // has a stable shape and so hopefully should be cheap to allocate.
-  function tryCatch(fn, obj, arg) {
-    try {
-      return { type: "normal", arg: fn.call(obj, arg) };
-    } catch (err) {
-      return { type: "throw", arg: err };
-    }
-  }
+var _zip = _interopRequireDefault(__webpack_require__(555));
 
-  var GenStateSuspendedStart = "suspendedStart";
-  var GenStateSuspendedYield = "suspendedYield";
-  var GenStateExecuting = "executing";
-  var GenStateCompleted = "completed";
+var _forEach = _interopRequireDefault(__webpack_require__(565));
 
-  // Returning this object from the innerFn has the same effect as
-  // breaking out of the dispatch switch statement.
-  var ContinueSentinel = {};
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-  // Dummy constructor functions that we use as the .constructor and
-  // .constructor.prototype properties for functions that return Generator
-  // objects. For full spec compliance, you may wish to configure your
-  // minifier not to mangle the names of these two functions.
-  function Generator() {}
-  function GeneratorFunction() {}
-  function GeneratorFunctionPrototype() {}
+var _microee = _interopRequireDefault(__webpack_require__(570));
 
-  // This is a polyfill for %IteratorPrototype% for environments that
-  // don't natively support it.
-  var IteratorPrototype = {};
-  define(IteratorPrototype, iteratorSymbol, function () {
-    return this;
-  });
+var _cozyStackClient = _interopRequireWildcard(__webpack_require__(571));
 
-  var getProto = Object.getPrototypeOf;
-  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
-  if (NativeIteratorPrototype &&
-      NativeIteratorPrototype !== Op &&
-      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
-    // This environment has a native %IteratorPrototype%; use it instead
-    // of the polyfill.
-    IteratorPrototype = NativeIteratorPrototype;
-  }
+var _const = __webpack_require__(697);
 
-  var Gp = GeneratorFunctionPrototype.prototype =
-    Generator.prototype = Object.create(IteratorPrototype);
-  GeneratorFunction.prototype = GeneratorFunctionPrototype;
-  define(Gp, "constructor", GeneratorFunctionPrototype);
-  define(GeneratorFunctionPrototype, "constructor", GeneratorFunction);
-  GeneratorFunction.displayName = define(
-    GeneratorFunctionPrototype,
-    toStringTagSymbol,
-    "GeneratorFunction"
-  );
+var _StackLink = _interopRequireDefault(__webpack_require__(698));
 
-  // Helper for defining the .next, .throw, and .return methods of the
-  // Iterator interface in terms of a single ._invoke method.
-  function defineIteratorMethods(prototype) {
-    ["next", "throw", "return"].forEach(function(method) {
-      define(prototype, method, function(arg) {
-        return this._invoke(method, arg);
-      });
-    });
-  }
+var _associations = __webpack_require__(703);
 
-  exports.isGeneratorFunction = function(genFun) {
-    var ctor = typeof genFun === "function" && genFun.constructor;
-    return ctor
-      ? ctor === GeneratorFunction ||
-        // For the native GeneratorFunction constructor, the best we can
-        // do is to check its .name property.
-        (ctor.displayName || ctor.name) === "GeneratorFunction"
-      : false;
-  };
+var _helpers = __webpack_require__(767);
 
-  exports.mark = function(genFun) {
-    if (Object.setPrototypeOf) {
-      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
-    } else {
-      genFun.__proto__ = GeneratorFunctionPrototype;
-      define(genFun, toStringTagSymbol, "GeneratorFunction");
-    }
-    genFun.prototype = Object.create(Gp);
-    return genFun;
-  };
+var _helpers2 = __webpack_require__(768);
 
-  // Within the body of any async function, `await x` is transformed to
-  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
-  // `hasOwn.call(value, "__await")` to determine if the yielded value is
-  // meant to be awaited.
-  exports.awrap = function(arg) {
-    return { __await: arg };
-  };
+var _dsl = __webpack_require__(619);
 
-  function AsyncIterator(generator, PromiseImpl) {
-    function invoke(method, arg, resolve, reject) {
-      var record = tryCatch(generator[method], generator, arg);
-      if (record.type === "throw") {
-        reject(record.arg);
-      } else {
-        var result = record.arg;
-        var value = result.value;
-        if (value &&
-            typeof value === "object" &&
-            hasOwn.call(value, "__await")) {
-          return PromiseImpl.resolve(value.__await).then(function(value) {
-            invoke("next", value, resolve, reject);
-          }, function(err) {
-            invoke("throw", err, resolve, reject);
-          });
-        }
+var _mobile = __webpack_require__(769);
 
-        return PromiseImpl.resolve(value).then(function(unwrapped) {
-          // When a yielded Promise is resolved, its final value becomes
-          // the .value of the Promise<{value,done}> result for the
-          // current iteration.
-          result.value = unwrapped;
-          resolve(result);
-        }, function(error) {
-          // If a rejected Promise was yielded, throw the rejection back
-          // into the async generator function so it can be handled there.
-          return invoke("throw", error, resolve, reject);
-        });
-      }
-    }
+var _optimize = _interopRequireDefault(__webpack_require__(787));
 
-    var previousPromise;
+var _store = _interopRequireWildcard(__webpack_require__(705));
 
-    function enqueue(method, arg) {
-      function callInvokeWithMethodAndArg() {
-        return new PromiseImpl(function(resolve, reject) {
-          invoke(method, arg, resolve, reject);
-        });
-      }
+var _policies = _interopRequireDefault(__webpack_require__(789));
 
-      return previousPromise =
-        // If enqueue has been called before, then we want to wait until
-        // all previous Promises have been resolved before calling invoke,
-        // so that results are always delivered in the correct order. If
-        // enqueue has not been called before, then it is important to
-        // call invoke immediately, without waiting on a callback to fire,
-        // so that the async generator function has the opportunity to do
-        // any necessary setup in a predictable way. This predictability
-        // is why the Promise constructor synchronously invokes its
-        // executor callback, and why async functions synchronously
-        // execute code before the first await. Since we implement simple
-        // async functions in terms of async generators, it is especially
-        // important to get this right, even though it requires care.
-        previousPromise ? previousPromise.then(
-          callInvokeWithMethodAndArg,
-          // Avoid propagating failures to Promises returned by later
-          // invocations of the iterator.
-          callInvokeWithMethodAndArg
-        ) : callInvokeWithMethodAndArg();
-    }
+var _Schema = _interopRequireDefault(__webpack_require__(790));
 
-    // Define the unified helper method that is used to implement .next,
-    // .throw, and .return (see defineIteratorMethods).
-    this._invoke = enqueue;
-  }
+var _CozyLink = __webpack_require__(699);
 
-  defineIteratorMethods(AsyncIterator.prototype);
-  define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
-    return this;
-  });
-  exports.AsyncIterator = AsyncIterator;
+var _ObservableQuery = _interopRequireDefault(__webpack_require__(796));
 
-  // Note that simple async functions are implemented on top of
-  // AsyncIterator objects; they just return a Promise for the value of
-  // the final result produced by the iterator.
-  exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
-    if (PromiseImpl === void 0) PromiseImpl = Promise;
+var _snapshots = __webpack_require__(797);
 
-    var iter = new AsyncIterator(
-      wrap(innerFn, outerFn, self, tryLocsList),
-      PromiseImpl
-    );
+var _logger = _interopRequireDefault(__webpack_require__(715));
 
-    return exports.isGeneratorFunction(outerFn)
-      ? iter // If outerFn is a generator, return the full iterator.
-      : iter.next().then(function(result) {
-          return result.done ? result.value : iter.next();
-        });
-  };
+var _types = __webpack_require__(622);
 
-  function makeInvokeMethod(innerFn, self, context) {
-    var state = GenStateSuspendedStart;
+var _queries = __webpack_require__(735);
 
-    return function invoke(method, arg) {
-      if (state === GenStateExecuting) {
-        throw new Error("Generator is already running");
-      }
+var _jsonStableStringify = _interopRequireDefault(__webpack_require__(798));
 
-      if (state === GenStateCompleted) {
-        if (method === "throw") {
-          throw arg;
-        }
+var _promiseCache = _interopRequireDefault(__webpack_require__(802));
 
-        // Be forgiving, per 25.3.3.3.3 of the spec:
-        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
-        return doneResult();
-      }
+var _flagshipCertification = __webpack_require__(803);
 
-      context.method = method;
-      context.arg = arg;
+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; }
 
-      while (true) {
-        var delegate = context.delegate;
-        if (delegate) {
-          var delegateResult = maybeInvokeDelegate(delegate, context);
-          if (delegateResult) {
-            if (delegateResult === ContinueSentinel) continue;
-            return delegateResult;
-          }
-        }
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-        if (context.method === "next") {
-          // Setting context._sent for legacy support of Babel's
-          // function.sent implementation.
-          context.sent = context._sent = context.arg;
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-        } else if (context.method === "throw") {
-          if (state === GenStateSuspendedStart) {
-            state = GenStateCompleted;
-            throw context.arg;
-          }
+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); }
 
-          context.dispatchException(context.arg);
+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; }
 
-        } else if (context.method === "return") {
-          context.abrupt("return", context.arg);
-        }
+var ensureArray = function ensureArray(arr) {
+  return Array.isArray(arr) ? arr : [arr];
+};
 
-        state = GenStateExecuting;
+var deprecatedHandler = function deprecatedHandler(msg) {
+  return {
+    get: function get(target, prop) {
+      console.warn(msg);
+      return target[prop];
+    }
+  };
+};
 
-        var record = tryCatch(innerFn, self, context);
-        if (record.type === "normal") {
-          // If an exception is thrown from innerFn, we leave state ===
-          // GenStateExecuting and loop back for another invocation.
-          state = context.done
-            ? GenStateCompleted
-            : GenStateSuspendedYield;
+var supportsReferences = function supportsReferences(relationshipClass) {
+  return relationshipClass.prototype.addReferences && relationshipClass.prototype.removeReferences;
+};
 
-          if (record.arg === ContinueSentinel) {
-            continue;
-          }
+var referencesUnsupportedError = function referencesUnsupportedError(relationshipClassName) {
+  return new Error("The \"".concat(relationshipClassName, "\" relationship does not support references. If you need to add references to a document, its relationship class must have the methods {add,remove}References"));
+};
 
-          return {
-            value: record.arg,
-            done: context.done
-          };
+var securiseUri = function securiseUri(uri) {
+  var _window$cozy;
 
-        } else if (record.type === "throw") {
-          state = GenStateCompleted;
-          // Dispatch the exception by looping back around to the
-          // context.dispatchException(context.arg) call above.
-          context.method = "throw";
-          context.arg = record.arg;
-        }
-      }
-    };
+  if (uri && typeof window !== 'undefined' && (_window$cozy = window['cozy']) !== null && _window$cozy !== void 0 && _window$cozy.isSecureProtocol) {
+    var secureUrl = new URL(uri);
+    secureUrl.protocol = 'https:';
+    return secureUrl.toString();
   }
 
-  // Call delegate.iterator[context.method](context.arg) and handle the
-  // result, either by returning a { value, done } result from the
-  // delegate iterator, or by modifying context.method and context.arg,
-  // setting context.delegate to null, and returning the ContinueSentinel.
-  function maybeInvokeDelegate(delegate, context) {
-    var method = delegate.iterator[context.method];
-    if (method === undefined) {
-      // A .throw or .return when the delegate iterator has no .throw
-      // method always terminates the yield* loop.
-      context.delegate = null;
+  return uri;
+};
 
-      if (context.method === "throw") {
-        // Note: ["return"] must be used for ES3 parsing compatibility.
-        if (delegate.iterator["return"]) {
-          // If the delegate iterator has a return method, give it a
-          // chance to clean up.
-          context.method = "return";
-          context.arg = undefined;
-          maybeInvokeDelegate(delegate, context);
+var DOC_CREATION = 'creation';
+var DOC_UPDATE = 'update';
+/**
+ * @typedef {object} ClientOptions
+ * @property {object} [client]
+ * @property {object} [link]
+ * @property {object} [links]
+ * @property {Token} [token]
+ * @property {string} [uri]
+ * @property {object} [stackClient]
+ * @property {boolean} [warningForCustomHandlers]
+ * @property {boolean} [autoHydrate]
+ * @property {object} [oauth]
+ * @property {Function} [onTokenRefresh]
+ * @property {Function} [onError] - Default callback if a query is errored
+ * @property  {Link}         [link]   - Backward compatibility
+ * @property  {Array<Link>}  [links]  - List of links
+ * @property  {object}       [schema] - Schema description for each doctypes
+ * @property  {AppMetadata}  [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata
+ * @property  {ClientCapabilities} [capabilities] - Capabilities sent by the stack
+ * @property  {boolean} [store] - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information.
+ */
 
-          if (context.method === "throw") {
-            // If maybeInvokeDelegate(context) changed context.method from
-            // "return" to "throw", let that override the TypeError below.
-            return ContinueSentinel;
-          }
-        }
+/**
+ * Responsible for
+ *
+ * - Creating observable queries
+ * - Hydration
+ * - Creating plan for saving documents
+ * - Associations
+ */
 
-        context.method = "throw";
-        context.arg = new TypeError(
-          "The iterator does not provide a 'throw' method");
-      }
+var CozyClient = /*#__PURE__*/function () {
+  /**
+   * @param  {ClientOptions} rawOptions - Options
+   *
+   * @example
+   * ```js
+   * const client = new CozyClient({
+   *   schema: {
+   *     todos: {
+   *       doctype: 'io.cozy.todos',
+   *       relationships: {
+   *         authors: {
+   *           type: 'has-many',
+   *           doctype: 'io.cozy.persons'
+   *         }
+   *       }
+   *     }
+   *   }
+   * })
+   * ```
+   *
+   * Cozy-Client will automatically call `this.login()` if provided with a token and an uri
+   */
+  function CozyClient() {
+    var _this = this;
 
-      return ContinueSentinel;
-    }
+    var rawOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+    (0, _classCallCheck2.default)(this, CozyClient);
+    (0, _defineProperty2.default)(this, "fetchQueryAndGetFromState", /*#__PURE__*/function () {
+      var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query) {
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.prev = 0;
+                _context.next = 3;
+                return _this.query(query.definition, query.options);
 
-    var record = tryCatch(method, delegate.iterator, context.arg);
+              case 3:
+                return _context.abrupt("return", _this.getQueryFromState(query.options.as));
 
-    if (record.type === "throw") {
-      context.method = "throw";
-      context.arg = record.arg;
-      context.delegate = null;
-      return ContinueSentinel;
-    }
+              case 6:
+                _context.prev = 6;
+                _context.t0 = _context["catch"](0);
+                throw _context.t0;
 
-    var info = record.arg;
+              case 9:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, null, [[0, 6]]);
+      }));
 
-    if (! info) {
-      context.method = "throw";
-      context.arg = new TypeError("iterator result is not an object");
-      context.delegate = null;
-      return ContinueSentinel;
-    }
+      return function (_x) {
+        return _ref.apply(this, arguments);
+      };
+    }());
+    var link = rawOptions.link,
+        links = rawOptions.links,
+        _rawOptions$schema = rawOptions.schema,
+        schema = _rawOptions$schema === void 0 ? {} : _rawOptions$schema,
+        _rawOptions$appMetada = rawOptions.appMetadata,
+        appMetadata = _rawOptions$appMetada === void 0 ? {} : _rawOptions$appMetada,
+        capabilities = rawOptions.capabilities,
+        options = (0, _objectWithoutProperties2.default)(rawOptions, ["link", "links", "schema", "appMetadata", "capabilities"]);
 
-    if (info.done) {
-      // Assign the result of the finished delegate to the temporary
-      // variable specified by delegate.resultName (see delegateYield).
-      context[delegate.resultName] = info.value;
+    if (link) {
+      console.warn('`link` is deprecated, use `links`');
+    }
 
-      // Resume execution at the desired location (see delegateYield).
-      context.next = delegate.nextLoc;
+    this.appMetadata = appMetadata;
+    options.uri = securiseUri(options.uri);
+    this.options = options;
+    this.queryIdGenerator = new _queries.QueryIDGenerator();
+    this.isLogged = false;
+    this.instanceOptions = {}; // Bind handlers
 
-      // If context.method was "throw" but the delegate handled the
-      // exception, let the outer generator proceed normally. If
-      // context.method was "next", forget context.arg since it has been
-      // "consumed" by the delegate iterator. If context.method was
-      // "return", allow the original .return call to continue in the
-      // outer generator.
-      if (context.method !== "return") {
-        context.method = "next";
-        context.arg = undefined;
+    this.handleRevocationChange = this.handleRevocationChange.bind(this);
+    this.handleTokenRefresh = this.handleTokenRefresh.bind(this);
+    this.createClient();
+    var stackClient = this.getStackClient();
+    stackClient.on('error', function () {
+      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+        args[_key] = arguments[_key];
       }
 
-    } else {
-      // Re-yield the result returned by the delegate method.
-      return info;
-    }
-
-    // The delegate iterator is finished, so forget it and continue with
-    // the outer generator.
-    context.delegate = null;
-    return ContinueSentinel;
-  }
+      return _this.emit.apply(_this, ['error'].concat(args));
+    });
+    this.links = ensureArray(link || links || new _StackLink.default());
+    this.registerClientOnLinks();
+    this.chain = (0, _CozyLink.chain)(this.links);
+    this.schema = new _Schema.default(schema, stackClient);
+    /**
+     * @type {ClientCapabilities}
+     */
 
-  // Define Generator.prototype.{next,throw,return} in terms of the
-  // unified ._invoke helper method.
-  defineIteratorMethods(Gp);
+    this.capabilities = capabilities || null; // Instances of plugins registered with registerPlugin
 
-  define(Gp, toStringTagSymbol, "Generator");
+    this.plugins = {};
 
-  // A Generator should always return itself as the iterator object when the
-  // @@iterator function is called on it. Some browsers' implementations of the
-  // iterator prototype chain incorrectly implement this, causing the Generator
-  // object to not be returned from this call. This ensures that doesn't happen.
-  // See https://github.com/facebook/regenerator/issues/274 for more details.
-  define(Gp, iteratorSymbol, function() {
-    return this;
-  });
+    try {
+      this.loadInstanceOptionsFromDOM();
+    } catch (err) {// not a critical error, we may be in node or the instance options are not on the default HTML element
+    }
 
-  define(Gp, "toString", function() {
-    return "[object Generator]";
-  });
+    if (options.uri && options.token) {
+      this.login();
+    }
+    /**
+     * @type {object}
+     */
 
-  function pushTryEntry(locs) {
-    var entry = { tryLoc: locs[0] };
 
-    if (1 in locs) {
-      entry.catchLoc = locs[1];
-    }
+    this.storeAccesors = null;
 
-    if (2 in locs) {
-      entry.finallyLoc = locs[2];
-      entry.afterLoc = locs[3];
+    if (options.store !== false) {
+      this.ensureStore();
     }
+    /**
+     * Holds in-flight promises for deduplication purpose
+     *
+     * @private
+     * @type {PromiseCache}
+     */
 
-    this.tryEntries.push(entry);
-  }
-
-  function resetTryEntry(entry) {
-    var record = entry.completion || {};
-    record.type = "normal";
-    delete record.arg;
-    entry.completion = record;
-  }
 
-  function Context(tryLocsList) {
-    // The root entry object (effectively a try statement without a catch
-    // or a finally block) gives us a place to store values thrown from
-    // locations where there is no enclosing try statement.
-    this.tryEntries = [{ tryLoc: "root" }];
-    tryLocsList.forEach(pushTryEntry, this);
-    this.reset(true);
+    this._promiseCache = new _promiseCache.default();
   }
+  /**
+   * Gets overrided by MicroEE.mixin
+   * This is here just so typescript does not scream
+   *
+   * TODO Find a better way to make TS understand that emit is
+   * a method from cozy-client
+   */
 
-  exports.keys = function(object) {
-    var keys = [];
-    for (var key in object) {
-      keys.push(key);
-    }
-    keys.reverse();
-
-    // Rather than returning an object with a next method, we keep
-    // things simple and return the next function itself.
-    return function next() {
-      while (keys.length) {
-        var key = keys.pop();
-        if (key in object) {
-          next.value = key;
-          next.done = false;
-          return next;
-        }
-      }
 
-      // To avoid creating an additional object, we just hang the .value
-      // and .done properties off the next function object itself. This
-      // also ensures that the minifier will not anonymize the function.
-      next.done = true;
-      return next;
-    };
-  };
+  (0, _createClass2.default)(CozyClient, [{
+    key: "emit",
+    value: function emit() {}
+  }, {
+    key: "on",
+    value: function on() {}
+  }, {
+    key: "removeListener",
+    value: function removeListener() {}
+    /**
+     * A plugin is a class whose constructor receives the client as first argument.
+     * The main mean of interaction with the client should be with events
+     * like "login"/"logout".
+     *
+     * The plugin system is meant to encourage separation of concerns, modularity
+     * and testability : instead of registering events at module level, please
+     * create a plugin that subscribes to events.
+     *
+     * Plugin instances are stored internally in the `plugins` attribute of the client
+     * and can be accessed via this mean. A plugin class must have the attribute
+     * `pluginName` that will be use as the key in the `plugins` object.
+     *
+     * Two plugins with the same `pluginName` cannot co-exist.
+     *
+     * @example
+     * ```js
+     * class AlertPlugin {
+     *   constructor(client, options) {
+     *     this.client = client
+     *     this.options = options
+     *     this.handleLogin = this.handleLogin.bind(this)
+     *     this.handleLogout = this.handleLogout.bind(this)
+     *     this.client.on("login", this.handleLogin)
+     *     this.client.on("logout", this.handleLogout)
+     *   }
+     *
+     *   handleLogin() {
+     *     alert(this.options.onLoginAlert)
+     *   }
+     *
+     *   handleLogout() {
+     *     alert(this.options.onLogoutAlert)
+     *   }
+     * }
+     *
+     * AlertPlugin.pluginName = 'alerts'
+     *
+     * client.registerPlugin(AlertPlugin, {
+     *   onLoginAlert: 'client has logged in !',
+     *   onLogoutAlert: 'client has logged out !'
+     * })
+     *
+     * // the instance of the plugin is accessible via
+     * client.plugins.alerts
+     * ```
+     */
 
-  function values(iterable) {
-    if (iterable) {
-      var iteratorMethod = iterable[iteratorSymbol];
-      if (iteratorMethod) {
-        return iteratorMethod.call(iterable);
+  }, {
+    key: "registerPlugin",
+    value: function registerPlugin(Plugin, options) {
+      if (!Plugin.pluginName) {
+        throw new Error('Cannot register a plugin whose class does not have `pluginName` attribute.');
       }
 
-      if (typeof iterable.next === "function") {
-        return iterable;
+      if (this.plugins[Plugin.pluginName]) {
+        throw new Error("Cannot register plugin ".concat(Plugin.pluginName, ". A plugin with the same name has already been registered."));
       }
 
-      if (!isNaN(iterable.length)) {
-        var i = -1, next = function next() {
-          while (++i < iterable.length) {
-            if (hasOwn.call(iterable, i)) {
-              next.value = iterable[i];
-              next.done = false;
-              return next;
-            }
-          }
-
-          next.value = undefined;
-          next.done = true;
-
-          return next;
-        };
-
-        return next.next = next;
-      }
+      var instance = new Plugin(this, options);
+      this.plugins[Plugin.pluginName] = instance;
+      return instance;
     }
+    /**
+     * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate
+     * a client with a cookie-based instance of cozy-client-js.
+     *
+     * @param {OldCozyClient} oldClient - An instance of the deprecated cozy-client
+     * @param {object} options - CozyStackClient options
+     * @returns {CozyClient}
+     */
 
-    // Return an iterator with no values.
-    return { next: doneResult };
-  }
-  exports.values = values;
-
-  function doneResult() {
-    return { value: undefined, done: true };
-  }
-
-  Context.prototype = {
-    constructor: Context,
-
-    reset: function(skipTempReset) {
-      this.prev = 0;
-      this.next = 0;
-      // Resetting context._sent for legacy support of Babel's
-      // function.sent implementation.
-      this.sent = this._sent = undefined;
-      this.done = false;
-      this.delegate = null;
-
-      this.method = "next";
-      this.arg = undefined;
+  }, {
+    key: "addSchema",
+    value: function addSchema(schemaDefinition) {
+      this.schema.add(schemaDefinition);
+    }
+  }, {
+    key: "registerClientOnLinks",
+    value: function registerClientOnLinks() {
+      var _iterator = _createForOfIteratorHelper(this.links),
+          _step;
 
-      this.tryEntries.forEach(resetTryEntry);
+      try {
+        for (_iterator.s(); !(_step = _iterator.n()).done;) {
+          var link = _step.value;
 
-      if (!skipTempReset) {
-        for (var name in this) {
-          // Not sure about the optimal order of these conditions:
-          if (name.charAt(0) === "t" &&
-              hasOwn.call(this, name) &&
-              !isNaN(+name.slice(1))) {
-            this[name] = undefined;
+          if (link.registerClient) {
+            try {
+              link.registerClient(this);
+            } catch (e) {
+              console.warn(e);
+            }
           }
         }
+      } catch (err) {
+        _iterator.e(err);
+      } finally {
+        _iterator.f();
       }
-    },
-
-    stop: function() {
-      this.done = true;
+    }
+    /**
+     * Notify the links that they can start and set isLogged to true.
+     *
+     * On mobile, where url/token are set after instantiation, use this method
+     * to set the token and uri via options.
+     *
+     * Emits
+     *
+     * - "beforeLogin" at the beginning, before links have been set up
+     * - "login" when the client is fully logged in and links have been set up
+     *
+     * @param  {object}   [options] - Options
+     * @param  {string}   options.token  - If passed, the token is set on the client
+     * @param  {string}   options.uri  - If passed, the uri is set on the client
+     * @returns {Promise} - Resolves when all links have been setup and client is fully logged in
+     *
+     */
 
-      var rootEntry = this.tryEntries[0];
-      var rootRecord = rootEntry.completion;
-      if (rootRecord.type === "throw") {
-        throw rootRecord.arg;
+  }, {
+    key: "login",
+    value: function login(options) {
+      // Keep the promise to be able to return it in future calls.
+      // This allows us to autoLogin in constructor without breaking any compatibility
+      // with codes that uses an explicit login.
+      if (this.isLogged && !this.isRevoked) {
+        console.warn("CozyClient is already logged.");
+        return this.loginPromise;
       }
 
-      return this.rval;
-    },
-
-    dispatchException: function(exception) {
-      if (this.done) {
-        throw exception;
-      }
+      return this.loginPromise = this._login(options);
+    }
+  }, {
+    key: "_login",
+    value: function () {
+      var _login2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(options) {
+        var _iterator2, _step2, link;
 
-      var context = this;
-      function handle(loc, caught) {
-        record.type = "throw";
-        record.arg = exception;
-        context.next = loc;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                this.emit('beforeLogin');
+                this.registerClientOnLinks();
 
-        if (caught) {
-          // If the dispatched exception was caught by a catch block,
-          // then let that catch block handle the exception normally.
-          context.method = "next";
-          context.arg = undefined;
-        }
+                if (options) {
+                  if (options.uri) {
+                    this.stackClient.setUri(options.uri);
+                  }
 
-        return !! caught;
-      }
+                  if (options.token) {
+                    this.stackClient.setToken(options.token);
+                  }
+                }
 
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        var record = entry.completion;
+                _iterator2 = _createForOfIteratorHelper(this.links);
+                _context2.prev = 4;
 
-        if (entry.tryLoc === "root") {
-          // Exception thrown outside of any try block that could handle
-          // it, so set the completion value of the entire function to
-          // throw the exception.
-          return handle("end");
-        }
+                _iterator2.s();
 
-        if (entry.tryLoc <= this.prev) {
-          var hasCatch = hasOwn.call(entry, "catchLoc");
-          var hasFinally = hasOwn.call(entry, "finallyLoc");
+              case 6:
+                if ((_step2 = _iterator2.n()).done) {
+                  _context2.next = 13;
+                  break;
+                }
 
-          if (hasCatch && hasFinally) {
-            if (this.prev < entry.catchLoc) {
-              return handle(entry.catchLoc, true);
-            } else if (this.prev < entry.finallyLoc) {
-              return handle(entry.finallyLoc);
-            }
+                link = _step2.value;
 
-          } else if (hasCatch) {
-            if (this.prev < entry.catchLoc) {
-              return handle(entry.catchLoc, true);
-            }
+                if (!link.onLogin) {
+                  _context2.next = 11;
+                  break;
+                }
 
-          } else if (hasFinally) {
-            if (this.prev < entry.finallyLoc) {
-              return handle(entry.finallyLoc);
-            }
+                _context2.next = 11;
+                return link.onLogin();
 
-          } else {
-            throw new Error("try statement without catch or finally");
-          }
-        }
-      }
-    },
+              case 11:
+                _context2.next = 6;
+                break;
 
-    abrupt: function(type, arg) {
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        if (entry.tryLoc <= this.prev &&
-            hasOwn.call(entry, "finallyLoc") &&
-            this.prev < entry.finallyLoc) {
-          var finallyEntry = entry;
-          break;
-        }
-      }
+              case 13:
+                _context2.next = 18;
+                break;
 
-      if (finallyEntry &&
-          (type === "break" ||
-           type === "continue") &&
-          finallyEntry.tryLoc <= arg &&
-          arg <= finallyEntry.finallyLoc) {
-        // Ignore the finally entry if control is not jumping to a
-        // location outside the try/catch block.
-        finallyEntry = null;
-      }
+              case 15:
+                _context2.prev = 15;
+                _context2.t0 = _context2["catch"](4);
 
-      var record = finallyEntry ? finallyEntry.completion : {};
-      record.type = type;
-      record.arg = arg;
+                _iterator2.e(_context2.t0);
 
-      if (finallyEntry) {
-        this.method = "next";
-        this.next = finallyEntry.finallyLoc;
-        return ContinueSentinel;
-      }
+              case 18:
+                _context2.prev = 18;
 
-      return this.complete(record);
-    },
+                _iterator2.f();
 
-    complete: function(record, afterLoc) {
-      if (record.type === "throw") {
-        throw record.arg;
-      }
+                return _context2.finish(18);
 
-      if (record.type === "break" ||
-          record.type === "continue") {
-        this.next = record.arg;
-      } else if (record.type === "return") {
-        this.rval = this.arg = record.arg;
-        this.method = "return";
-        this.next = "end";
-      } else if (record.type === "normal" && afterLoc) {
-        this.next = afterLoc;
-      }
+              case 21:
+                this.isLogged = true;
+                this.isRevoked = false;
+                this.emit('login');
 
-      return ContinueSentinel;
-    },
+              case 24:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this, [[4, 15, 18, 21]]);
+      }));
 
-    finish: function(finallyLoc) {
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        if (entry.finallyLoc === finallyLoc) {
-          this.complete(entry.completion, entry.afterLoc);
-          resetTryEntry(entry);
-          return ContinueSentinel;
-        }
+      function _login(_x2) {
+        return _login2.apply(this, arguments);
       }
-    },
 
-    "catch": function(tryLoc) {
-      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-        var entry = this.tryEntries[i];
-        if (entry.tryLoc === tryLoc) {
-          var record = entry.completion;
-          if (record.type === "throw") {
-            var thrown = record.arg;
-            resetTryEntry(entry);
-          }
-          return thrown;
-        }
-      }
+      return _login;
+    }()
+    /**
+     * Logs out the client and reset all the links
+     *
+     * Emits
+     *
+     * - "beforeLogout" at the beginning, before links have been reset
+     * - "login" when the client is fully logged out and links have been reset
+     *
+     * @returns {Promise} - Resolves when all links have been reset and client is fully logged out
+     */
 
-      // The context.catch method must only be called with a location
-      // argument that corresponds to a known catch block.
-      throw new Error("illegal catch attempt");
-    },
+  }, {
+    key: "logout",
+    value: function () {
+      var _logout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
+        var _iterator3, _step3, link;
 
-    delegateYield: function(iterable, resultName, nextLoc) {
-      this.delegate = {
-        iterator: values(iterable),
-        resultName: resultName,
-        nextLoc: nextLoc
-      };
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                if (this.isLogged) {
+                  _context3.next = 3;
+                  break;
+                }
 
-      if (this.method === "next") {
-        // Deliberately forget the last sent value so that we don't
-        // accidentally pass it on to the delegate.
-        this.arg = undefined;
-      }
+                _logger.default.warn("CozyClient isn't logged.");
 
-      return ContinueSentinel;
-    }
-  };
+                return _context3.abrupt("return");
 
-  // Regardless of whether this script is executing as a CommonJS module
-  // or not, return the runtime object so that we can declare the variable
-  // regeneratorRuntime in the outer scope, which allows this module to be
-  // injected easily by `bin/regenerator --include-runtime script.js`.
-  return exports;
+              case 3:
+                this.emit('beforeLogout');
+                this.isLogged = false;
 
-}(
-  // If this script is executing as a CommonJS module, use module.exports
-  // as the regeneratorRuntime namespace. Otherwise create a new empty
-  // object. Either way, the resulting object will be used to initialize
-  // the regeneratorRuntime variable at the top of this file.
-   true ? module.exports : 0
-));
+                if (!(this.stackClient instanceof _cozyStackClient.OAuthClient)) {
+                  _context3.next = 17;
+                  break;
+                }
 
-try {
-  regeneratorRuntime = runtime;
-} catch (accidentalStrictMode) {
-  // This module should not be running in strict mode, so the above
-  // assignment should always work unless something is misconfigured. Just
-  // in case runtime.js accidentally runs in strict mode, in modern engines
-  // we can explicitly access globalThis. In older engines we can escape
-  // strict mode using a global Function call. This could conceivably fail
-  // if a Content Security Policy forbids using Function, but in that case
-  // the proper solution is to fix the accidental strict mode problem. If
-  // you've misconfigured your bundler to force strict mode and applied a
-  // CSP to forbid Function, and you're not willing to fix either of those
-  // problems, please detail your unique predicament in a GitHub issue.
-  if (typeof globalThis === "object") {
-    globalThis.regeneratorRuntime = runtime;
-  } else {
-    Function("r", "regeneratorRuntime = r")(runtime);
-  }
-}
+                _context3.prev = 6;
 
+                if (!(this.stackClient.unregister && (!this.stackClient.isRegistered || this.stackClient.isRegistered()))) {
+                  _context3.next = 10;
+                  break;
+                }
 
-/***/ }),
-/* 529 */
-/***/ ((module) => {
+                _context3.next = 10;
+                return this.stackClient.unregister();
 
-function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
-  try {
-    var info = gen[key](arg);
-    var value = info.value;
-  } catch (error) {
-    reject(error);
-    return;
-  }
+              case 10:
+                _context3.next = 15;
+                break;
 
-  if (info.done) {
-    resolve(value);
-  } else {
-    Promise.resolve(value).then(_next, _throw);
-  }
-}
+              case 12:
+                _context3.prev = 12;
+                _context3.t0 = _context3["catch"](6);
 
-function _asyncToGenerator(fn) {
-  return function () {
-    var self = this,
-        args = arguments;
-    return new Promise(function (resolve, reject) {
-      var gen = fn.apply(self, args);
+                _logger.default.warn("Impossible to unregister client on stack: ".concat(_context3.t0));
 
-      function _next(value) {
-        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
-      }
+              case 15:
+                _context3.next = 25;
+                break;
 
-      function _throw(err) {
-        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
-      }
+              case 17:
+                _context3.prev = 17;
+                _context3.next = 20;
+                return this.stackClient.fetch('DELETE', '/auth/login');
 
-      _next(undefined);
-    });
-  };
-}
+              case 20:
+                _context3.next = 25;
+                break;
 
-module.exports = _asyncToGenerator;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+              case 22:
+                _context3.prev = 22;
+                _context3.t1 = _context3["catch"](17);
 
-/***/ }),
-/* 530 */
-/***/ ((module) => {
+                _logger.default.warn("Impossible to log out: ".concat(_context3.t1));
 
-function _classCallCheck(instance, Constructor) {
-  if (!(instance instanceof Constructor)) {
-    throw new TypeError("Cannot call a class as a function");
-  }
-}
+              case 25:
+                // clean information on links
+                _iterator3 = _createForOfIteratorHelper(this.links);
+                _context3.prev = 26;
 
-module.exports = _classCallCheck;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+                _iterator3.s();
 
-/***/ }),
-/* 531 */
-/***/ ((module) => {
+              case 28:
+                if ((_step3 = _iterator3.n()).done) {
+                  _context3.next = 41;
+                  break;
+                }
 
-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);
-  }
-}
+                link = _step3.value;
 
-function _createClass(Constructor, protoProps, staticProps) {
-  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
-  if (staticProps) _defineProperties(Constructor, staticProps);
-  return Constructor;
-}
+                if (!link.reset) {
+                  _context3.next = 39;
+                  break;
+                }
 
-module.exports = _createClass;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+                _context3.prev = 31;
+                _context3.next = 34;
+                return link.reset();
 
-/***/ }),
-/* 532 */
-/***/ ((module) => {
+              case 34:
+                _context3.next = 39;
+                break;
 
-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;
-  }
+              case 36:
+                _context3.prev = 36;
+                _context3.t2 = _context3["catch"](31);
+                console.warn(_context3.t2);
 
-  return obj;
-}
+              case 39:
+                _context3.next = 28;
+                break;
 
-module.exports = _defineProperty;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+              case 41:
+                _context3.next = 46;
+                break;
 
-/***/ }),
-/* 533 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 43:
+                _context3.prev = 43;
+                _context3.t3 = _context3["catch"](26);
 
-var baseAssignValue = __webpack_require__(534),
-    baseForOwn = __webpack_require__(536),
-    baseIteratee = __webpack_require__(401);
+                _iterator3.e(_context3.t3);
 
-/**
- * Creates an object with the same keys as `object` and values generated
- * by running each own enumerable string keyed property of `object` thru
- * `iteratee`. The iteratee is invoked with three arguments:
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @since 2.4.0
- * @category Object
- * @param {Object} object The object to iterate over.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @returns {Object} Returns the new mapped object.
- * @see _.mapKeys
- * @example
- *
- * var users = {
- *   'fred':    { 'user': 'fred',    'age': 40 },
- *   'pebbles': { 'user': 'pebbles', 'age': 1 }
- * };
- *
- * _.mapValues(users, function(o) { return o.age; });
- * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
- *
- * // The `_.property` iteratee shorthand.
- * _.mapValues(users, 'age');
- * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
- */
-function mapValues(object, iteratee) {
-  var result = {};
-  iteratee = baseIteratee(iteratee, 3);
+              case 46:
+                _context3.prev = 46;
 
-  baseForOwn(object, function(value, key, object) {
-    baseAssignValue(result, key, iteratee(value, key, object));
-  });
-  return result;
-}
+                _iterator3.f();
 
-module.exports = mapValues;
+                return _context3.finish(46);
 
+              case 49:
+                if (this.store) {
+                  this.dispatch((0, _store.resetState)());
+                }
 
-/***/ }),
-/* 534 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                this.emit('logout');
 
-var defineProperty = __webpack_require__(535);
+              case 51:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this, [[6, 12], [17, 22], [26, 43, 46, 49], [31, 36]]);
+      }));
 
-/**
- * The base implementation of `assignValue` and `assignMergeValue` without
- * value checks.
- *
- * @private
- * @param {Object} object The object to modify.
- * @param {string} key The key of the property to assign.
- * @param {*} value The value to assign.
- */
-function baseAssignValue(object, key, value) {
-  if (key == '__proto__' && defineProperty) {
-    defineProperty(object, key, {
-      'configurable': true,
-      'enumerable': true,
-      'value': value,
-      'writable': true
-    });
-  } else {
-    object[key] = value;
-  }
-}
+      function logout() {
+        return _logout.apply(this, arguments);
+      }
 
-module.exports = baseAssignValue;
+      return logout;
+    }()
+    /**
+     * Forwards to a stack client instance and returns
+     * a [DocumentCollection]{@link https://docs.cozy.io/en/cozy-client/api/cozy-stack-client/#DocumentCollection} instance.
+     *
+     * @param  {string} doctype The collection doctype.
+     * @returns {DocumentCollection} Collection corresponding to the doctype
+     */
 
+  }, {
+    key: "collection",
+    value: function collection(doctype) {
+      return this.getStackClient().collection(doctype);
+    }
+  }, {
+    key: "fetch",
+    value: function fetch(method, path, body) {
+      var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+      return this.getStackClient().fetch(method, path, body, options);
+    }
+  }, {
+    key: "all",
+    value: function all(doctype) {
+      _logger.default.warn("\nclient.all is deprecated, prefer to use the Q helper to build a new QueryDefinition.\n\nimport { Q } from 'cozy-client'\nclient.query(Q('io.cozy.bills'))");
 
-/***/ }),
-/* 535 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      return (0, _dsl.Q)(doctype);
+    }
+  }, {
+    key: "find",
+    value: function find(doctype) {
+      var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
+      console.warn('client.find(doctype, selector) is deprecated, please use Q(doctype).where(selector) to build the same query.');
+      return new _dsl.QueryDefinition({
+        doctype: doctype,
+        selector: selector
+      });
+    }
+  }, {
+    key: "get",
+    value: function get(doctype, id) {
+      console.warn("client.get(".concat(doctype, ", id) is deprecated, please use Q(").concat(doctype, ").getById(id) to build the same query."));
+      return new _dsl.QueryDefinition({
+        doctype: doctype,
+        id: id
+      });
+    }
+    /**
+     * Creates a document and saves it on the server
+     *
+     * @param  {string} type - Doctype of the document
+     * @param  {object} doc - Document to save
+     * @param  {ReferenceMap} [references] - References are a special kind of relationship
+     * that is not stored inside the referencer document, they are used for example between a photo
+     * and its album. You should not need to use it normally.
+     * @param  {object} options - Mutation options
+     *
+     * @example
+     * ```js
+     * await client.create('io.cozy.todos', {
+     *   label: 'My todo',
+     *   relationships: {
+     *     authors: {
+     *       data: [{_id: 1, _type: 'io.cozy.persons'}]
+     *     }
+     *   }
+     * })
+     * ```
+     *
+     * @returns {Promise}
+     */
 
-var getNative = __webpack_require__(371);
+  }, {
+    key: "create",
+    value: function () {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(type, doc, references) {
+        var options,
+            _type,
+            attributes,
+            normalizedDoc,
+            ret,
+            _args4 = arguments;
 
-var defineProperty = (function() {
-  try {
-    var func = getNative(Object, 'defineProperty');
-    func({}, '', {});
-    return func;
-  } catch (e) {}
-}());
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {};
+                _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]);
+                normalizedDoc = _objectSpread({
+                  _type: type
+                }, attributes);
+                _context4.next = 5;
+                return this.schema.validate(normalizedDoc);
 
-module.exports = defineProperty;
+              case 5:
+                ret = _context4.sent;
 
+                if (!(ret !== true)) {
+                  _context4.next = 8;
+                  break;
+                }
 
-/***/ }),
-/* 536 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                throw new Error('Validation failed');
 
-var baseFor = __webpack_require__(537),
-    keys = __webpack_require__(429);
+              case 8:
+                return _context4.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc, references), options));
 
-/**
- * The base implementation of `_.forOwn` without support for iteratee shorthands.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Object} Returns `object`.
- */
-function baseForOwn(object, iteratee) {
-  return object && baseFor(object, iteratee, keys);
-}
+              case 9:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
 
-module.exports = baseForOwn;
+      function create(_x3, _x4, _x5) {
+        return _create.apply(this, arguments);
+      }
 
+      return create;
+    }()
+  }, {
+    key: "validate",
+    value: function validate(document) {
+      return this.schema.validate(document);
+    }
+    /**
+     * Create or update a document on the server
+     *
+     * @param  {object} doc - Document to save
+     * @param  {object} mutationOptions - Mutation options
+     * @returns {Promise}
+     */
 
-/***/ }),
-/* 537 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  }, {
+    key: "save",
+    value: function () {
+      var _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(doc) {
+        var mutationOptions,
+            _type,
+            attributes,
+            normalizedDoc,
+            ret,
+            _args5 = arguments;
 
-var createBaseFor = __webpack_require__(538);
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                mutationOptions = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
+                _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]);
 
-/**
- * The base implementation of `baseForOwn` which iterates over `object`
- * properties returned by `keysFunc` and invokes `iteratee` for each property.
- * Iteratee functions may exit iteration early by explicitly returning `false`.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} keysFunc The function to get the keys of `object`.
- * @returns {Object} Returns `object`.
- */
-var baseFor = createBaseFor();
+                if (_type) {
+                  _context5.next = 4;
+                  break;
+                }
 
-module.exports = baseFor;
+                throw new Error('The document must have a `_type` property');
 
+              case 4:
+                normalizedDoc = _objectSpread({
+                  _type: _type
+                }, attributes);
+                _context5.next = 7;
+                return this.schema.validate(normalizedDoc);
 
-/***/ }),
-/* 538 */
-/***/ ((module) => {
+              case 7:
+                ret = _context5.sent;
 
-/**
- * Creates a base function for methods like `_.forIn` and `_.forOwn`.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
-function createBaseFor(fromRight) {
-  return function(object, iteratee, keysFunc) {
-    var index = -1,
-        iterable = Object(object),
-        props = keysFunc(object),
-        length = props.length;
+                if (!(ret !== true)) {
+                  _context5.next = 10;
+                  break;
+                }
 
-    while (length--) {
-      var key = props[fromRight ? length : ++index];
-      if (iteratee(iterable[key], key, iterable) === false) {
-        break;
-      }
-    }
-    return object;
-  };
-}
+                throw new Error('Validation failed');
 
-module.exports = createBaseFor;
+              case 10:
+                return _context5.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc), mutationOptions));
 
+              case 11:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this);
+      }));
 
-/***/ }),
-/* 539 */
-/***/ ((module) => {
+      function save(_x6) {
+        return _save.apply(this, arguments);
+      }
 
-/**
- * The inverse of `_.toPairs`; this method returns an object composed
- * from key-value `pairs`.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Array
- * @param {Array} pairs The key-value pairs.
- * @returns {Object} Returns the new object.
- * @example
- *
- * _.fromPairs([['a', 1], ['b', 2]]);
- * // => { 'a': 1, 'b': 2 }
- */
-function fromPairs(pairs) {
-  var index = -1,
-      length = pairs == null ? 0 : pairs.length,
-      result = {};
+      return save;
+    }()
+    /**
+     * Saves multiple documents in one batch
+     * - Can only be called with documents from the same doctype
+     * - Does not support automatic creation of references
+     *
+     * @param  {CozyClientDocument[]} docs
+     * @param  {Object} mutationOptions
+     * @returns {Promise<void>}
+     */
 
-  while (++index < length) {
-    var pair = pairs[index];
-    result[pair[0]] = pair[1];
-  }
-  return result;
-}
+  }, {
+    key: "saveAll",
+    value: function () {
+      var _saveAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(docs) {
+        var _this2 = this;
 
-module.exports = fromPairs;
+        var mutationOptions,
+            doctypes,
+            validations,
+            errors,
+            toSaveDocs,
+            mutation,
+            _args6 = arguments;
+        return _regenerator.default.wrap(function _callee6$(_context6) {
+          while (1) {
+            switch (_context6.prev = _context6.next) {
+              case 0:
+                mutationOptions = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
+                doctypes = Array.from(new Set(docs.map(function (x) {
+                  return x._type;
+                })));
 
+                if (!(doctypes.length !== 1)) {
+                  _context6.next = 4;
+                  break;
+                }
 
-/***/ }),
-/* 540 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                throw new Error('saveAll can only save documents with the same doctype');
 
-var baseFlatten = __webpack_require__(541);
+              case 4:
+                _context6.next = 6;
+                return Promise.all(docs.map(function (d) {
+                  return _this2.schema.validate(d);
+                }));
 
-/**
- * Flattens `array` a single level deep.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {Array} array The array to flatten.
- * @returns {Array} Returns the new flattened array.
- * @example
- *
- * _.flatten([1, [2, [3, [4]], 5]]);
- * // => [1, 2, [3, [4]], 5]
- */
-function flatten(array) {
-  var length = array == null ? 0 : array.length;
-  return length ? baseFlatten(array, 1) : [];
-}
+              case 6:
+                validations = _context6.sent;
+                errors = validations.filter(function (validation) {
+                  return validation !== true;
+                });
 
-module.exports = flatten;
+                if (!(errors.length > 0)) {
+                  _context6.next = 11;
+                  break;
+                }
 
+                console.warn('There has been some validation errors while bulk saving', errors);
+                throw new Error('Validation failed for at least one doc');
 
-/***/ }),
-/* 541 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 11:
+                toSaveDocs = docs.map(function (d) {
+                  return _this2.prepareDocumentForSave(d);
+                });
+                mutation = _dsl.Mutations.updateDocuments(toSaveDocs);
+                return _context6.abrupt("return", this.mutate(mutation, mutationOptions));
 
-var arrayPush = __webpack_require__(425),
-    isFlattenable = __webpack_require__(542);
+              case 14:
+              case "end":
+                return _context6.stop();
+            }
+          }
+        }, _callee6, this);
+      }));
 
-/**
- * The base implementation of `_.flatten` with support for restricting flattening.
- *
- * @private
- * @param {Array} array The array to flatten.
- * @param {number} depth The maximum recursion depth.
- * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
- * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
- * @param {Array} [result=[]] The initial result value.
- * @returns {Array} Returns the new flattened array.
- */
-function baseFlatten(array, depth, predicate, isStrict, result) {
-  var index = -1,
-      length = array.length;
+      function saveAll(_x7) {
+        return _saveAll.apply(this, arguments);
+      }
 
-  predicate || (predicate = isFlattenable);
-  result || (result = []);
+      return saveAll;
+    }()
+  }, {
+    key: "ensureCozyMetadata",
+    value: function ensureCozyMetadata(document) {
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
+        event: DOC_CREATION
+      };
+      var METADATA_VERSION = 1;
+      if (this.appMetadata === undefined) return document;
+      var doctypeVersion;
 
-  while (++index < length) {
-    var value = array[index];
-    if (depth > 0 && predicate(value)) {
-      if (depth > 1) {
-        // Recursively flatten arrays (susceptible to call stack limits).
-        baseFlatten(value, depth - 1, predicate, isStrict, result);
-      } else {
-        arrayPush(result, value);
+      if (document._type) {
+        var schema = this.schema.getDoctypeSchema(document._type);
+        doctypeVersion = (0, _get.default)(schema, 'doctypeVersion');
       }
-    } else if (!isStrict) {
-      result[result.length] = value;
-    }
-  }
-  return result;
-}
 
-module.exports = baseFlatten;
+      var _this$appMetadata = this.appMetadata,
+          slug = _this$appMetadata.slug,
+          sourceAccount = _this$appMetadata.sourceAccount,
+          version = _this$appMetadata.version;
+      var now = new Date().toISOString();
+      var cozyMetadata = (0, _get.default)(document, 'cozyMetadata', {});
+
+      if (options.event === DOC_CREATION) {
+        cozyMetadata = _objectSpread({
+          metadataVersion: METADATA_VERSION,
+          doctypeVersion: doctypeVersion,
+          createdByApp: slug,
+          sourceAccount: sourceAccount,
+          createdAt: now,
+          createdByAppVersion: version,
+          updatedAt: now,
+          updatedByApps: slug ? [{
+            date: now,
+            slug: slug,
+            version: version
+          }] : []
+        }, cozyMetadata);
+      } else if (options.event === DOC_UPDATE) {
+        cozyMetadata = _objectSpread(_objectSpread({}, cozyMetadata), {}, {
+          updatedAt: now,
+          updatedByApps: [{
+            date: now,
+            slug: slug,
+            version: version
+          }].concat((0, _toConsumableArray2.default)((0, _get.default)(document, 'cozyMetadata.updatedByApps', []).filter(function (info) {
+            return info.slug !== slug;
+          })))
+        });
+      }
 
+      return _objectSpread(_objectSpread({}, document), {}, {
+        cozyMetadata: cozyMetadata
+      });
+    }
+    /**
+     * Dehydrates and adds metadata before saving a document
+     *
+     * @param  {CozyClientDocument} doc - Document that will be saved
+     * @returns {CozyClientDocument}
+     */
 
-/***/ }),
-/* 542 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  }, {
+    key: "prepareDocumentForSave",
+    value: function prepareDocumentForSave(doc) {
+      var isNewDoc = !doc._rev;
+      var dehydratedDoc = this.ensureCozyMetadata((0, _helpers2.dehydrate)(doc), {
+        event: isNewDoc ? DOC_CREATION : DOC_UPDATE
+      });
+      return dehydratedDoc;
+    }
+    /**
+     * Creates a list of mutations to execute to create a document and its relationships.
+     *
+     * ```js
+     * const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' }
+     * // relations can be arrays or single objects
+     * const relationships = {
+     *   attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }],
+     *   bills: { _id: 9999, _type: 'io.cozy.bills' }
+     * }
+     * client.getDocumentSavePlan(baseDoc, relationships)
+     * ```
+     *
+     *
+     * @param  {object} document - Document to create
+     * @param  {ReferenceMap} [referencesByName] - References to the created document. The
+     * relationship class associated to each reference list should support references, otherwise this
+     * method will throw.
+     *
+     * @returns {Mutation[]|Mutation}  One or more mutation to execute
+     */
 
-var Symbol = __webpack_require__(47),
-    isArguments = __webpack_require__(432),
-    isArray = __webpack_require__(55);
+  }, {
+    key: "getDocumentSavePlan",
+    value: function getDocumentSavePlan(document, referencesByName) {
+      var _this3 = this;
 
-/** Built-in value references. */
-var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
+      var isNewDoc = !document._rev;
+      var docToSave = this.prepareDocumentForSave(document);
+      var saveMutation = isNewDoc ? _dsl.Mutations.createDocument(docToSave) : _dsl.Mutations.updateDocument(docToSave);
+      var hasReferences = referencesByName && Object.values(referencesByName).filter(function (references) {
+        return Array.isArray(references) ? references.length > 0 : references;
+      }).length > 0;
 
-/**
- * Checks if `value` is a flattenable `arguments` object or array.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
- */
-function isFlattenable(value) {
-  return isArray(value) || isArguments(value) ||
-    !!(spreadableSymbol && value && value[spreadableSymbol]);
-}
+      if (!hasReferences) {
+        return saveMutation;
+      } else {
+        for (var _i = 0, _Object$keys = Object.keys(referencesByName); _i < _Object$keys.length; _i++) {
+          var relName = _Object$keys[_i];
+          var doctype = document._type;
+          var doctypeRelationship = this.schema.getRelationship(doctype, relName);
+          var relationshipClass = doctypeRelationship.type;
 
-module.exports = isFlattenable;
+          if (!supportsReferences(relationshipClass)) {
+            throw referencesUnsupportedError(doctypeRelationship.name);
+          }
+        }
+      }
 
+      if (referencesByName && !isNewDoc) {
+        throw new Error('Unable to save external relationships on a not-new document');
+      }
 
-/***/ }),
-/* 543 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      return [saveMutation, function (response) {
+        var doc = _this3.hydrateDocument(response.data);
 
-var baseRest = __webpack_require__(544),
-    unzip = __webpack_require__(551);
+        return Object.entries(referencesByName).map(function (_ref2) {
+          var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
+              relName = _ref3[0],
+              references = _ref3[1];
 
-/**
- * Creates an array of grouped elements, the first of which contains the
- * first elements of the given arrays, the second of which contains the
- * second elements of the given arrays, and so on.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {...Array} [arrays] The arrays to process.
- * @returns {Array} Returns the new array of grouped elements.
- * @example
- *
- * _.zip(['a', 'b'], [1, 2], [true, false]);
- * // => [['a', 1, true], ['b', 2, false]]
- */
-var zip = baseRest(unzip);
+          var relationship = doc[relName];
+          return relationship.addReferences(references);
+        });
+      }];
+    }
+    /**
+     * Hooks are an observable system for events on documents.
+     * There are at the moment only 2 hooks available.
+     *
+     * - before:destroy, called just before a document is destroyed via CozyClient::destroy
+     * - after:destroy, called after a document is destroyed via CozyClient::destroy
+     *
+     * @example
+     * ```
+     * CozyClient.registerHook('io.cozy.bank.accounts', 'before:destroy', () => {
+     *   console.log('A io.cozy.bank.accounts is being destroyed')
+     * })
+     * ```
+     *
+     * @param  {string}   doctype - Doctype on which the hook will be registered
+     * @param  {string}   name    - Name of the hook
+     * @param  {Function} fn      - Callback to be executed
+     */
 
-module.exports = zip;
+  }, {
+    key: "triggerHook",
+    value: function triggerHook(name, document) {
+      if (!CozyClient.hooks) return;
+      var allHooks = CozyClient.hooks[document._type] || {};
+      var hooks = allHooks[name] || [];
 
+      var _iterator4 = _createForOfIteratorHelper(hooks),
+          _step4;
 
-/***/ }),
-/* 544 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      try {
+        for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
+          var h = _step4.value;
+          h(this, document);
+        }
+      } catch (err) {
+        _iterator4.e(err);
+      } finally {
+        _iterator4.f();
+      }
+    }
+    /**
+     * Destroys a document. {before,after}:destroy hooks will be fired.
+     *
+     * @param  {CozyClientDocument} document - Document to be deleted
+     * @returns {Promise<CozyClientDocument>} The document that has been deleted
+     */
 
-var identity = __webpack_require__(459),
-    overRest = __webpack_require__(545),
-    setToString = __webpack_require__(547);
+  }, {
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document) {
+        var mutationOptions,
+            res,
+            _args7 = arguments;
+        return _regenerator.default.wrap(function _callee7$(_context7) {
+          while (1) {
+            switch (_context7.prev = _context7.next) {
+              case 0:
+                mutationOptions = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};
+                _context7.next = 3;
+                return this.triggerHook('before:destroy', document);
 
-/**
- * The base implementation of `_.rest` which doesn't validate or coerce arguments.
- *
- * @private
- * @param {Function} func The function to apply a rest parameter to.
- * @param {number} [start=func.length-1] The start position of the rest parameter.
- * @returns {Function} Returns the new function.
- */
-function baseRest(func, start) {
-  return setToString(overRest(func, start, identity), func + '');
-}
+              case 3:
+                _context7.next = 5;
+                return this.mutate(_dsl.Mutations.deleteDocument(document), mutationOptions);
 
-module.exports = baseRest;
+              case 5:
+                res = _context7.sent;
+                _context7.next = 8;
+                return this.triggerHook('after:destroy', document);
 
+              case 8:
+                return _context7.abrupt("return", res);
 
-/***/ }),
-/* 545 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 9:
+              case "end":
+                return _context7.stop();
+            }
+          }
+        }, _callee7, this);
+      }));
 
-var apply = __webpack_require__(546);
+      function destroy(_x8) {
+        return _destroy.apply(this, arguments);
+      }
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeMax = Math.max;
+      return destroy;
+    }()
+  }, {
+    key: "upload",
+    value: function upload(file, dirPath) {
+      var mutationOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+      return this.mutate(_dsl.Mutations.uploadFile(file, dirPath), mutationOptions);
+    }
+    /**
+     * Makes sure that the query exists in the store
+     *
+     * @param  {string} queryId - Id of the query
+     * @param  {QueryDefinition} queryDefinition - Definition of the query
+     * @param  {QueryOptions} [options] - Additional options
+     */
 
-/**
- * A specialized version of `baseRest` which transforms the rest array.
- *
- * @private
- * @param {Function} func The function to apply a rest parameter to.
- * @param {number} [start=func.length-1] The start position of the rest parameter.
- * @param {Function} transform The rest array transform.
- * @returns {Function} Returns the new function.
- */
-function overRest(func, start, transform) {
-  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
-  return function() {
-    var args = arguments,
-        index = -1,
-        length = nativeMax(args.length - start, 0),
-        array = Array(length);
+  }, {
+    key: "ensureQueryExists",
+    value: function ensureQueryExists(queryId, queryDefinition, options) {
+      this.ensureStore();
+      var existingQuery = (0, _store.getQueryFromState)(this.store.getState(), queryId); // Don't trigger the INIT_QUERY for fetchMore() calls
 
-    while (++index < length) {
-      array[index] = args[start + index];
-    }
-    index = -1;
-    var otherArgs = Array(start + 1);
-    while (++index < start) {
-      otherArgs[index] = args[index];
+      if (existingQuery.fetchStatus !== 'loaded' || !queryDefinition.skip && !queryDefinition.bookmark) {
+        this.dispatch((0, _store.initQuery)(queryId, queryDefinition, options));
+      }
     }
-    otherArgs[start] = transform(array);
-    return apply(func, this, otherArgs);
-  };
-}
+    /**
+     * Executes a query and returns its results.
+     *
+     * Results from the query will be saved internally and can be retrieved via
+     * `getQueryFromState` or directly using `<Query />`. `<Query />` automatically
+     * executes its query when mounted if no fetch policy has been indicated.
+     *
+     * @param  {QueryDefinition} queryDefinition - Definition that will be executed
+     * @param  {QueryOptions} [options] - Options
+     * @returns {Promise<QueryResult>}
+     */
 
-module.exports = overRest;
+  }, {
+    key: "query",
+    value: function () {
+      var _query = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(queryDefinition) {
+        var _this4 = this;
 
+        var _ref4,
+            update,
+            options,
+            queryId,
+            existingQuery,
+            shouldFetch,
+            response,
+            _args8 = arguments;
 
-/***/ }),
-/* 546 */
-/***/ ((module) => {
+        return _regenerator.default.wrap(function _callee8$(_context8) {
+          while (1) {
+            switch (_context8.prev = _context8.next) {
+              case 0:
+                _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
+                update = _ref4.update, options = (0, _objectWithoutProperties2.default)(_ref4, ["update"]);
+                this.ensureStore();
+                queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
+                existingQuery = this.getQueryFromState(queryId);
 
-/**
- * A faster alternative to `Function#apply`, this function invokes `func`
- * with the `this` binding of `thisArg` and the arguments of `args`.
- *
- * @private
- * @param {Function} func The function to invoke.
- * @param {*} thisArg The `this` binding of `func`.
- * @param {Array} args The arguments to invoke `func` with.
- * @returns {*} Returns the result of `func`.
- */
-function apply(func, thisArg, args) {
-  switch (args.length) {
-    case 0: return func.call(thisArg);
-    case 1: return func.call(thisArg, args[0]);
-    case 2: return func.call(thisArg, args[0], args[1]);
-    case 3: return func.call(thisArg, args[0], args[1], args[2]);
-  }
-  return func.apply(thisArg, args);
-}
+                if (!options.fetchPolicy) {
+                  _context8.next = 11;
+                  break;
+                }
 
-module.exports = apply;
+                if (options.as) {
+                  _context8.next = 8;
+                  break;
+                }
 
+                throw new Error('Cannot use `fetchPolicy` without naming the query, please use `as` to name the query');
 
-/***/ }),
-/* 547 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 8:
+                shouldFetch = options.fetchPolicy(existingQuery);
 
-var baseSetToString = __webpack_require__(548),
-    shortOut = __webpack_require__(550);
+                if (shouldFetch) {
+                  _context8.next = 11;
+                  break;
+                }
 
-/**
- * Sets the `toString` method of `func` to return `string`.
- *
- * @private
- * @param {Function} func The function to modify.
- * @param {Function} string The `toString` result.
- * @returns {Function} Returns `func`.
- */
-var setToString = shortOut(baseSetToString);
+                return _context8.abrupt("return");
 
-module.exports = setToString;
+              case 11:
+                if (!(existingQuery && Object.keys(existingQuery).length > 0)) {
+                  _context8.next = 14;
+                  break;
+                }
 
+                if (!(existingQuery.fetchStatus === 'loading')) {
+                  _context8.next = 14;
+                  break;
+                }
 
-/***/ }),
-/* 548 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                return _context8.abrupt("return", this._promiseCache.get(function () {
+                  return (0, _jsonStableStringify.default)(queryDefinition);
+                }));
 
-var constant = __webpack_require__(549),
-    defineProperty = __webpack_require__(535),
-    identity = __webpack_require__(459);
+              case 14:
+                this.ensureQueryExists(queryId, queryDefinition, options);
+                _context8.prev = 15;
+                this.dispatch((0, _store.loadQuery)(queryId));
+                _context8.next = 19;
+                return this._promiseCache.exec(function () {
+                  return _this4.requestQuery(queryDefinition);
+                }, function () {
+                  return (0, _jsonStableStringify.default)(queryDefinition);
+                });
 
-/**
- * The base implementation of `setToString` without support for hot loop shorting.
- *
- * @private
- * @param {Function} func The function to modify.
- * @param {Function} string The `toString` result.
- * @returns {Function} Returns `func`.
- */
-var baseSetToString = !defineProperty ? identity : function(func, string) {
-  return defineProperty(func, 'toString', {
-    'configurable': true,
-    'enumerable': false,
-    'value': constant(string),
-    'writable': true
-  });
-};
+              case 19:
+                response = _context8.sent;
+                this.dispatch((0, _store.receiveQueryResult)(queryId, response, {
+                  update: update
+                }));
+                return _context8.abrupt("return", response);
 
-module.exports = baseSetToString;
+              case 24:
+                _context8.prev = 24;
+                _context8.t0 = _context8["catch"](15);
+                this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0)); // specific onError
 
+                if (!options.onError) {
+                  _context8.next = 31;
+                  break;
+                }
 
-/***/ }),
-/* 549 */
-/***/ ((module) => {
+                options.onError(_context8.t0); // defaulted onError
 
-/**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @since 2.4.0
- * @category Util
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new constant function.
- * @example
- *
- * var objects = _.times(2, _.constant({ 'a': 1 }));
- *
- * console.log(objects);
- * // => [{ 'a': 1 }, { 'a': 1 }]
- *
- * console.log(objects[0] === objects[1]);
- * // => true
- */
-function constant(value) {
-  return function() {
-    return value;
-  };
-}
+                _context8.next = 36;
+                break;
 
-module.exports = constant;
+              case 31:
+                if (!this.options.onError) {
+                  _context8.next = 35;
+                  break;
+                }
 
+                this.options.onError(_context8.t0);
+                _context8.next = 36;
+                break;
 
-/***/ }),
-/* 550 */
-/***/ ((module) => {
+              case 35:
+                throw _context8.t0;
 
-/** Used to detect hot functions by number of calls within a span of milliseconds. */
-var HOT_COUNT = 800,
-    HOT_SPAN = 16;
+              case 36:
+              case "end":
+                return _context8.stop();
+            }
+          }
+        }, _callee8, this, [[15, 24]]);
+      }));
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeNow = Date.now;
+      function query(_x9) {
+        return _query.apply(this, arguments);
+      }
 
-/**
- * Creates a function that'll short out and invoke `identity` instead
- * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
- * milliseconds.
- *
- * @private
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new shortable function.
- */
-function shortOut(func) {
-  var count = 0,
-      lastCalled = 0;
+      return query;
+    }()
+    /**
+     * Will fetch all documents for a `queryDefinition`, automatically fetching more
+     * documents if the total of documents is superior to the pagination limit. Can
+     * result in a lot of network requests.
+     *
+     * @param  {QueryDefinition} queryDefinition - Definition to be executed
+     * @param {QueryOptions} [options] - Options
+     * @returns {Promise<QueryResult>} All documents matching the query
+     */
 
-  return function() {
-    var stamp = nativeNow(),
-        remaining = HOT_SPAN - (stamp - lastCalled);
+  }, {
+    key: "queryAll",
+    value: function () {
+      var _queryAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(queryDefinition) {
+        var options,
+            queryId,
+            mergedOptions,
+            resp,
+            documents,
+            currentResult,
+            _args9 = arguments;
+        return _regenerator.default.wrap(function _callee9$(_context9) {
+          while (1) {
+            switch (_context9.prev = _context9.next) {
+              case 0:
+                options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
+                queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
+                mergedOptions = _objectSpread(_objectSpread({}, options), {}, {
+                  as: queryId
+                });
+                _context9.next = 5;
+                return this.query(queryDefinition, mergedOptions);
 
-    lastCalled = stamp;
-    if (remaining > 0) {
-      if (++count >= HOT_COUNT) {
-        return arguments[0];
-      }
-    } else {
-      count = 0;
-    }
-    return func.apply(undefined, arguments);
-  };
-}
+              case 5:
+                resp = _context9.sent;
+                documents = resp.data;
 
-module.exports = shortOut;
+              case 7:
+                if (!(resp && resp.next)) {
+                  _context9.next = 21;
+                  break;
+                }
 
+                if (!resp.bookmark) {
+                  _context9.next = 14;
+                  break;
+                }
 
-/***/ }),
-/* 551 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                _context9.next = 11;
+                return this.query(queryDefinition.offsetBookmark(resp.bookmark), mergedOptions);
 
-var arrayFilter = __webpack_require__(427),
-    arrayMap = __webpack_require__(398),
-    baseProperty = __webpack_require__(461),
-    baseTimes = __webpack_require__(431),
-    isArrayLikeObject = __webpack_require__(552);
+              case 11:
+                resp = _context9.sent;
+                _context9.next = 18;
+                break;
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeMax = Math.max;
+              case 14:
+                currentResult = (0, _store.getRawQueryFromState)(this.store.getState(), queryId);
+                _context9.next = 17;
+                return this.query(queryDefinition.offset(currentResult.data.length), mergedOptions);
 
-/**
- * This method is like `_.zip` except that it accepts an array of grouped
- * elements and creates an array regrouping the elements to their pre-zip
- * configuration.
- *
- * @static
- * @memberOf _
- * @since 1.2.0
- * @category Array
- * @param {Array} array The array of grouped elements to process.
- * @returns {Array} Returns the new array of regrouped elements.
- * @example
- *
- * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
- * // => [['a', 1, true], ['b', 2, false]]
- *
- * _.unzip(zipped);
- * // => [['a', 'b'], [1, 2], [true, false]]
- */
-function unzip(array) {
-  if (!(array && array.length)) {
-    return [];
-  }
-  var length = 0;
-  array = arrayFilter(array, function(group) {
-    if (isArrayLikeObject(group)) {
-      length = nativeMax(group.length, length);
-      return true;
-    }
-  });
-  return baseTimes(length, function(index) {
-    return arrayMap(array, baseProperty(index));
-  });
-}
+              case 17:
+                resp = _context9.sent;
 
-module.exports = unzip;
+              case 18:
+                documents.push.apply(documents, (0, _toConsumableArray2.default)(resp.data));
+                _context9.next = 7;
+                break;
 
+              case 21:
+                return _context9.abrupt("return", documents);
 
-/***/ }),
-/* 552 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 22:
+              case "end":
+                return _context9.stop();
+            }
+          }
+        }, _callee9, this);
+      }));
 
-var isArrayLike = __webpack_require__(446),
-    isObjectLike = __webpack_require__(53);
+      function queryAll(_x10) {
+        return _queryAll.apply(this, arguments);
+      }
 
-/**
- * This method is like `_.isArrayLike` except that it also checks if `value`
- * is an object.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an array-like object,
- *  else `false`.
- * @example
- *
- * _.isArrayLikeObject([1, 2, 3]);
- * // => true
- *
- * _.isArrayLikeObject(document.body.children);
- * // => true
- *
- * _.isArrayLikeObject('abc');
- * // => false
- *
- * _.isArrayLikeObject(_.noop);
- * // => false
- */
-function isArrayLikeObject(value) {
-  return isObjectLike(value) && isArrayLike(value);
-}
+      return queryAll;
+    }()
+  }, {
+    key: "watchQuery",
+    value: function watchQuery() {
+      console.warn('client.watchQuery is deprecated, please use client.makeObservableQuery.');
+      return this.makeObservableQuery.apply(this, arguments);
+    }
+  }, {
+    key: "makeObservableQuery",
+    value: function makeObservableQuery(queryDefinition) {
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+      this.ensureStore();
+      var queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
+      this.ensureQueryExists(queryId, queryDefinition);
+      return new _ObservableQuery.default(queryId, queryDefinition, this, options);
+    }
+    /**
+     * Mutate a document
+     *
+     * @param  {object}    mutationDefinition - Describe the mutation
+     * @param {object} [options] - Options
+     * @param  {string}    [options.as] - Mutation id
+     * @param  {Function}    [options.update] - Function to update the document
+     * @param  {Function}    [options.updateQueries] - Function to update queries
+     * @returns {Promise}
+     */
 
-module.exports = isArrayLikeObject;
+  }, {
+    key: "mutate",
+    value: function () {
+      var _mutate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(mutationDefinition) {
+        var _ref5,
+            update,
+            updateQueries,
+            options,
+            mutationId,
+            response,
+            _args10 = arguments;
 
+        return _regenerator.default.wrap(function _callee10$(_context10) {
+          while (1) {
+            switch (_context10.prev = _context10.next) {
+              case 0:
+                _ref5 = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {};
+                update = _ref5.update, updateQueries = _ref5.updateQueries, options = (0, _objectWithoutProperties2.default)(_ref5, ["update", "updateQueries"]);
+                this.ensureStore();
+                mutationId = options.as || this.queryIdGenerator.generateId(mutationDefinition);
+                this.dispatch((0, _store.initMutation)(mutationId, mutationDefinition));
+                _context10.prev = 5;
+                _context10.next = 8;
+                return this.requestMutation(mutationDefinition);
 
-/***/ }),
-/* 553 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 8:
+                response = _context10.sent;
+                this.dispatch((0, _store.receiveMutationResult)(mutationId, response, {
+                  update: update,
+                  updateQueries: updateQueries
+                }, mutationDefinition));
+                return _context10.abrupt("return", response);
 
-var arrayEach = __webpack_require__(554),
-    baseEach = __webpack_require__(555),
-    castFunction = __webpack_require__(557),
-    isArray = __webpack_require__(55);
+              case 13:
+                _context10.prev = 13;
+                _context10.t0 = _context10["catch"](5);
+                this.dispatch((0, _store.receiveMutationError)(mutationId, _context10.t0, mutationDefinition));
+                throw _context10.t0;
 
-/**
- * Iterates over elements of `collection` and invokes `iteratee` for each element.
- * The iteratee is invoked with three arguments: (value, index|key, collection).
- * Iteratee functions may exit iteration early by explicitly returning `false`.
- *
- * **Note:** As with other "Collections" methods, objects with a "length"
- * property are iterated like arrays. To avoid this behavior use `_.forIn`
- * or `_.forOwn` for object iteration.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @alias each
- * @category Collection
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @returns {Array|Object} Returns `collection`.
- * @see _.forEachRight
- * @example
- *
- * _.forEach([1, 2], function(value) {
- *   console.log(value);
- * });
- * // => Logs `1` then `2`.
- *
- * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
- *   console.log(key);
- * });
- * // => Logs 'a' then 'b' (iteration order is not guaranteed).
- */
-function forEach(collection, iteratee) {
-  var func = isArray(collection) ? arrayEach : baseEach;
-  return func(collection, castFunction(iteratee));
-}
+              case 17:
+              case "end":
+                return _context10.stop();
+            }
+          }
+        }, _callee10, this, [[5, 13]]);
+      }));
 
-module.exports = forEach;
+      function mutate(_x11) {
+        return _mutate.apply(this, arguments);
+      }
 
+      return mutate;
+    }()
+    /**
+     * Executes a query through links and fetches relationships
+     *
+     * @private
+     * @param  {QueryDefinition} definition QueryDefinition to be executed
+     * @returns {Promise<ClientResponse>}
+     */
 
-/***/ }),
-/* 554 */
-/***/ ((module) => {
+  }, {
+    key: "requestQuery",
+    value: function () {
+      var _requestQuery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(definition) {
+        var mainResponse, withIncluded;
+        return _regenerator.default.wrap(function _callee11$(_context11) {
+          while (1) {
+            switch (_context11.prev = _context11.next) {
+              case 0:
+                _context11.next = 2;
+                return this.chain.request(definition);
 
-/**
- * A specialized version of `_.forEach` for arrays without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns `array`.
- */
-function arrayEach(array, iteratee) {
-  var index = -1,
-      length = array == null ? 0 : array.length;
+              case 2:
+                mainResponse = _context11.sent;
 
-  while (++index < length) {
-    if (iteratee(array[index], index, array) === false) {
-      break;
-    }
-  }
-  return array;
-}
+                if (definition.includes) {
+                  _context11.next = 5;
+                  break;
+                }
 
-module.exports = arrayEach;
+                return _context11.abrupt("return", mainResponse);
 
+              case 5:
+                _context11.next = 7;
+                return this.fetchRelationships(mainResponse, this.getIncludesRelationships(definition));
 
-/***/ }),
-/* 555 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 7:
+                withIncluded = _context11.sent;
+                return _context11.abrupt("return", withIncluded);
 
-var baseForOwn = __webpack_require__(536),
-    createBaseEach = __webpack_require__(556);
+              case 9:
+              case "end":
+                return _context11.stop();
+            }
+          }
+        }, _callee11, this);
+      }));
 
-/**
- * The base implementation of `_.forEach` without support for iteratee shorthands.
- *
- * @private
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array|Object} Returns `collection`.
- */
-var baseEach = createBaseEach(baseForOwn);
+      function requestQuery(_x12) {
+        return _requestQuery.apply(this, arguments);
+      }
 
-module.exports = baseEach;
+      return requestQuery;
+    }()
+    /**
+     * Fetch relationships for a response (can be several docs).
+     * Fills the `relationships` attribute of each documents.
+     *
+     * Can potentially result in several fetch requests.
+     * Queries are optimized before being sent (multiple single documents queries can be packed into
+     * one multiple document query) for example.
+     *
+     * @private
+     */
 
+  }, {
+    key: "fetchRelationships",
+    value: function () {
+      var _fetchRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(response, relationshipsByName) {
+        var _this5 = this;
 
-/***/ }),
-/* 556 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+        var isSingleDoc, responseDocs, queryDefToDocIdAndRel, documents, definitions, optimizedDefinitions, responses, uniqueDocuments, included, relationshipsByDocId, _iterator5, _step5, _step5$value, def, resp, docIdAndRel, _docIdAndRel, docId, relName;
 
-var isArrayLike = __webpack_require__(446);
+        return _regenerator.default.wrap(function _callee12$(_context12) {
+          while (1) {
+            switch (_context12.prev = _context12.next) {
+              case 0:
+                isSingleDoc = !Array.isArray(response.data);
 
-/**
- * Creates a `baseEach` or `baseEachRight` function.
- *
- * @private
- * @param {Function} eachFunc The function to iterate over a collection.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
-function createBaseEach(eachFunc, fromRight) {
-  return function(collection, iteratee) {
-    if (collection == null) {
-      return collection;
-    }
-    if (!isArrayLike(collection)) {
-      return eachFunc(collection, iteratee);
-    }
-    var length = collection.length,
-        index = fromRight ? length : -1,
-        iterable = Object(collection);
+                if (!(!isSingleDoc && response.data.length === 0)) {
+                  _context12.next = 3;
+                  break;
+                }
 
-    while ((fromRight ? index-- : ++index < length)) {
-      if (iteratee(iterable[index], index, iterable) === false) {
-        break;
-      }
-    }
-    return collection;
-  };
-}
+                return _context12.abrupt("return", response);
 
-module.exports = createBaseEach;
+              case 3:
+                responseDocs = isSingleDoc ? [response.data] : response.data;
+                queryDefToDocIdAndRel = new Map();
+                documents = [];
+                definitions = [];
+                responseDocs.forEach(function (doc) {
+                  return (0, _forEach.default)(relationshipsByName, function (relationship, relName) {
+                    try {
+                      var queryDef = relationship.type.query(doc, _this5, relationship);
+                      var docId = doc._id; // Used to reattach responses into the relationships attribute of
+                      // each document
 
+                      queryDefToDocIdAndRel.set(queryDef, [docId, relName]); // Relationships can yield "queries" that are already resolved documents.
+                      // These do not need to go through the usual link request mechanism.
 
-/***/ }),
-/* 557 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                      if (queryDef instanceof _dsl.QueryDefinition) {
+                        definitions.push(queryDef);
+                      } else {
+                        documents.push(queryDef);
+                      }
+                    } catch (_unused) {// eslint-disable-next-line
+                      // We do not crash completely if one the relationship behaves badly and
+                      // throws
+                    }
+                  });
+                }); // Definitions can be in optimized/regrouped in case of HasMany relationships.
 
-var identity = __webpack_require__(459);
+                optimizedDefinitions = (0, _optimize.default)(definitions);
+                _context12.next = 11;
+                return Promise.all(optimizedDefinitions.map(function (req) {
+                  return _this5.chain.request(req);
+                }));
 
-/**
- * Casts `value` to `identity` if it's not a function.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {Function} Returns cast function.
- */
-function castFunction(value) {
-  return typeof value == 'function' ? value : identity;
-}
+              case 11:
+                responses = _context12.sent;
+                // "Included" documents will be stored in the `documents` store
+                uniqueDocuments = (0, _uniqBy.default)((0, _flatten.default)(documents), '_id');
+                included = (0, _flatten.default)(responses.map(function (r) {
+                  return r.included || r.data;
+                })).concat(uniqueDocuments).filter(Boolean); // Some relationships have the relationship data on the other side of the
+                // relationship (ex: io.cozy.photos.albums do not have photo inclusion information,
+                // it is on the io.cozy.files side).
+                // Here we take the data received from the relationship queries, and group
+                // it so that we can fill the `relationships` attribute of each doc before
+                // storing the document. This makes the data easier to manipulate for the front-end.
 
-module.exports = castFunction;
+                relationshipsByDocId = {};
+                _iterator5 = _createForOfIteratorHelper((0, _zip.default)(optimizedDefinitions, responses));
 
+                try {
+                  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
+                    _step5$value = (0, _slicedToArray2.default)(_step5.value, 2), def = _step5$value[0], resp = _step5$value[1];
+                    docIdAndRel = queryDefToDocIdAndRel.get(def);
 
-/***/ }),
-/* 558 */
-/***/ ((module) => {
+                    if (docIdAndRel) {
+                      _docIdAndRel = (0, _slicedToArray2.default)(docIdAndRel, 2), docId = _docIdAndRel[0], relName = _docIdAndRel[1];
+                      relationshipsByDocId[docId] = relationshipsByDocId[docId] || {};
+                      relationshipsByDocId[docId][relName] = (0, _helpers.responseToRelationship)(resp);
+                    }
+                  }
+                } catch (err) {
+                  _iterator5.e(err);
+                } finally {
+                  _iterator5.f();
+                }
 
-function M() { this._events = {}; }
-M.prototype = {
-  on: function(ev, cb) {
-    this._events || (this._events = {});
-    var e = this._events;
-    (e[ev] || (e[ev] = [])).push(cb);
-    return this;
-  },
-  removeListener: function(ev, cb) {
-    var e = this._events[ev] || [], i;
-    for(i = e.length-1; i >= 0 && e[i]; i--){
-      if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); }
-    }
-  },
-  removeAllListeners: function(ev) {
-    if(!ev) { this._events = {}; }
-    else { this._events[ev] && (this._events[ev] = []); }
-  },
-  listeners: function(ev) {
-    return (this._events ? this._events[ev] || [] : []);
-  },
-  emit: function(ev) {
-    this._events || (this._events = {});
-    var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || [];
-    for(i = e.length-1; i >= 0 && e[i]; i--){
-      e[i].apply(this, args);
-    }
-    return this;
-  },
-  when: function(ev, cb) {
-    return this.once(ev, cb, true);
-  },
-  once: function(ev, cb, when) {
-    if(!cb) return this;
-    function c() {
-      if(!when) this.removeListener(ev, c);
-      if(cb.apply(this, arguments) && when) this.removeListener(ev, c);
-    }
-    c.cb = cb;
-    this.on(ev, c);
-    return this;
-  }
-};
-M.mixin = function(dest) {
-  var o = M.prototype, k;
-  for (k in o) {
-    o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
-  }
-};
-module.exports = M;
+                return _context12.abrupt("return", _objectSpread(_objectSpread({}, (0, _helpers.attachRelationships)(response, relationshipsByDocId)), {}, {
+                  included: included
+                }));
 
+              case 18:
+              case "end":
+                return _context12.stop();
+            }
+          }
+        }, _callee12);
+      }));
 
-/***/ }),
-/* 559 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+      function fetchRelationships(_x13, _x14) {
+        return _fetchRelationships.apply(this, arguments);
+      }
 
-"use strict";
+      return fetchRelationships;
+    }()
+  }, {
+    key: "requestMutation",
+    value: function () {
+      var _requestMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(definition) {
+        var _this6 = this;
 
+        var _definition, first, rest, firstResponse;
 
-var _interopRequireWildcard = __webpack_require__(510);
+        return _regenerator.default.wrap(function _callee13$(_context13) {
+          while (1) {
+            switch (_context13.prev = _context13.next) {
+              case 0:
+                if (!Array.isArray(definition)) {
+                  _context13.next = 8;
+                  break;
+                }
 
-var _interopRequireDefault = __webpack_require__(512);
+                _definition = (0, _toArray2.default)(definition), first = _definition[0], rest = _definition.slice(1);
+                _context13.next = 4;
+                return this.requestMutation(first);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-Object.defineProperty(exports, "default", ({
-  enumerable: true,
-  get: function get() {
-    return _CozyStackClient.default;
-  }
-}));
-Object.defineProperty(exports, "OAuthClient", ({
-  enumerable: true,
-  get: function get() {
-    return _OAuthClient.default;
-  }
-}));
-Object.defineProperty(exports, "errors", ({
-  enumerable: true,
-  get: function get() {
-    return _errors.default;
-  }
-}));
-Object.defineProperty(exports, "FetchError", ({
-  enumerable: true,
-  get: function get() {
-    return _errors.FetchError;
-  }
-}));
-Object.defineProperty(exports, "normalizeDoc", ({
-  enumerable: true,
-  get: function get() {
-    return _DocumentCollection.normalizeDoc;
-  }
-}));
+              case 4:
+                firstResponse = _context13.sent;
+                _context13.next = 7;
+                return Promise.all(rest.map(function (def) {
+                  var mutationDef = typeof def === 'function' ? def(firstResponse) : def;
+                  return _this6.requestMutation(mutationDef);
+                }));
 
-var _CozyStackClient = _interopRequireDefault(__webpack_require__(560));
+              case 7:
+                return _context13.abrupt("return", firstResponse);
 
-var _OAuthClient = _interopRequireDefault(__webpack_require__(684));
+              case 8:
+                return _context13.abrupt("return", this.chain.request(definition));
 
-var _errors = _interopRequireWildcard(__webpack_require__(651));
+              case 9:
+              case "end":
+                return _context13.stop();
+            }
+          }
+        }, _callee13, this);
+      }));
 
-var _DocumentCollection = __webpack_require__(601);
+      function requestMutation(_x15) {
+        return _requestMutation.apply(this, arguments);
+      }
 
-/***/ }),
-/* 560 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+      return requestMutation;
+    }()
+  }, {
+    key: "getIncludesRelationships",
+    value: function getIncludesRelationships(queryDefinition) {
+      var _this7 = this;
 
-"use strict";
+      var includes = queryDefinition.includes,
+          doctype = queryDefinition.doctype;
+      if (!includes) return {};
+      return (0, _fromPairs.default)(includes.map(function (relName) {
+        return [relName, _this7.schema.getRelationship(doctype, relName)];
+      }));
+    }
+    /**
+     * Returns documents with their relationships resolved according to their schema.
+     * If related documents are not in the store, they will not be fetched automatically.
+     * Instead, the relationships will have null documents.
+     *
+     * @param  {string} doctype - Doctype of the documents being hydrated
+     * @param  {Array<CozyClientDocument>} documents - Documents to be hydrated
+     * @returns {Array<HydratedDocument>}
+     */
+
+  }, {
+    key: "hydrateDocuments",
+    value: function hydrateDocuments(doctype, documents) {
+      var _this8 = this;
+
+      if (this.options.autoHydrate === false) {
+        return documents;
+      }
 
+      var schema = this.schema.getDoctypeSchema(doctype);
+      var relationships = schema.relationships;
 
-var _interopRequireWildcard = __webpack_require__(510);
+      if (relationships) {
+        return documents.map(function (doc) {
+          return _this8.hydrateDocument(doc, schema);
+        });
+      } else {
+        return documents;
+      }
+    }
+    /**
+     * Resolves relationships on a document.
+     *
+     * The original document is kept in the target attribute of
+     * the relationship
+     *
+     * @param  {CozyClientDocument} document - for which relationships must be resolved
+     * @param  {Schema} [schemaArg] - Optional
+     * @returns {HydratedDocument}
+     */
 
-var _interopRequireDefault = __webpack_require__(512);
+  }, {
+    key: "hydrateDocument",
+    value: function hydrateDocument(document, schemaArg) {
+      if (!document) {
+        return document;
+      }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+      var schema = schemaArg || this.schema.getDoctypeSchema(document._type);
+      return _objectSpread(_objectSpread({}, document), this.hydrateRelationships(document, schema.relationships));
+    }
+  }, {
+    key: "hydrateRelationships",
+    value: function hydrateRelationships(document, schemaRelationships) {
+      var methods = this.getRelationshipStoreAccessors();
+      return (0, _mapValues.default)(schemaRelationships, function (assoc, name) {
+        return (0, _associations.create)(document, assoc, methods);
+      });
+    }
+    /**
+     * Creates (locally) a new document for the given doctype.
+     * This document is hydrated : its relationships are there
+     * and working.
+     */
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+  }, {
+    key: "makeNewDocument",
+    value: function makeNewDocument(doctype) {
+      var obj = {
+        _type: doctype
+      };
+      return this.hydrateDocument(obj);
+    }
+  }, {
+    key: "generateRandomId",
+    value: function generateRandomId() {
+      return this.queryIdGenerator.generateRandomId();
+    }
+    /**
+     * Creates an association that is linked to the store.
+     */
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+  }, {
+    key: "getAssociation",
+    value: function getAssociation(document, associationName) {
+      return (0, _associations.create)(document, this.schema.getRelationship(document._type, associationName), this.getRelationshipStoreAccessors());
+    }
+    /**
+     * Returns the accessors that are given to the relationships for them
+     * to deal with the stores.
+     *
+     * Relationships need to have access to the store to ping it when
+     * a modification (addById/removeById etc...) has been done. This wakes
+     * the store up, which in turn will update the `<Query>`s and re-render the data.
+     */
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+  }, {
+    key: "getRelationshipStoreAccessors",
+    value: function getRelationshipStoreAccessors() {
+      var _this9 = this;
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+      if (!this.storeAccesors) {
+        this.storeAccessors = {
+          get: this.getDocumentFromState.bind(this),
+          save: function save(document, opts) {
+            return _this9.save.call(_this9, document, opts);
+          },
+          dispatch: this.dispatch.bind(this),
+          query: function query(def, opts) {
+            return _this9.query.call(_this9, def, opts);
+          },
+          mutate: function mutate(def, opts) {
+            return _this9.mutate.call(_this9, def, opts);
+          }
+        };
+      }
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+      return this.storeAccessors;
+    }
+    /**
+     * Get a collection of documents from the internal store.
+     *
+     * @param {string} type - Doctype of the collection
+     *
+     * @returns {CozyClientDocument[]} Array of documents or null if the collection does not exist.
+     */
 
-var _cloneDeep = _interopRequireDefault(__webpack_require__(561));
+  }, {
+    key: "getCollectionFromState",
+    value: function getCollectionFromState(type) {
+      try {
+        return (0, _store.getCollectionFromState)(this.store.getState(), type);
+      } catch (e) {
+        _logger.default.warn('Could not getCollectionFromState', type, e.message);
 
-var _AppCollection = _interopRequireWildcard(__webpack_require__(590));
+        return null;
+      }
+    }
+    /**
+     * Get a document from the internal store.
+     *
+     * @param {string} type - Doctype of the document
+     * @param {string} id   - Id of the document
+     *
+     * @returns {CozyClientDocument} Document or null if the object does not exist.
+     */
 
-var _AppToken = _interopRequireDefault(__webpack_require__(656));
+  }, {
+    key: "getDocumentFromState",
+    value: function getDocumentFromState(type, id) {
+      try {
+        return (0, _store.getDocumentFromState)(this.store.getState(), type, id);
+      } catch (e) {
+        _logger.default.warn('Could not getDocumentFromState', type, id, e.message);
 
-var _AccessToken = _interopRequireDefault(__webpack_require__(657));
+        return null;
+      }
+    }
+    /**
+     * Get a query from the internal store.
+     *
+     * @param {string} id - Id of the query (set via Query.props.as)
+     * @param {object} options - Options
+     * @param {boolean} [options.hydrated] - Whether documents should be returned already hydrated (default: false)
+     * @param  {object} [options.singleDocData] - If true, the "data" returned will be
+     * a single doc instead of an array for single doc queries. Defaults to false for backward
+     * compatibility but will be set to true in the future.
+     *
+     * @returns {QueryState} - Query state or null if it does not exist.
+     */
 
-var _DocumentCollection = _interopRequireDefault(__webpack_require__(601));
+  }, {
+    key: "getQueryFromState",
+    value: function getQueryFromState(id) {
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+      var hydrated = options.hydrated || false;
+      var singleDocData = options.singleDocData || false;
 
-var _FileCollection = _interopRequireDefault(__webpack_require__(658));
+      try {
+        var queryResults = (0, _store.getQueryFromState)(this.store.getState(), id);
+        var doctype = queryResults.definition && queryResults.definition.doctype;
+        var isSingleDocQuery = queryResults.definition && queryResults.definition.id;
 
-var _JobCollection = _interopRequireWildcard(__webpack_require__(667));
+        if (!hydrated && !singleDocData) {
+          // Early return let's us preserve reference equality in the simple case
+          return queryResults;
+        }
 
-var _KonnectorCollection = _interopRequireWildcard(__webpack_require__(668));
+        var data = hydrated && doctype ? this.hydrateDocuments(doctype, queryResults.data) : queryResults.data;
+        return _objectSpread(_objectSpread({}, queryResults), {}, {
+          data: isSingleDocQuery && singleDocData ? data[0] : data
+        });
+      } catch (e) {
+        console.warn("Could not get query from state. queryId: ".concat(id, ", error: ").concat(e.message));
+        return null;
+      }
+    }
+    /**
+     * Executes a query and returns the results from internal store.
+     *
+     * Can be useful in pure JS context (without React)
+     * Has a behavior close to <Query /> or useQuery
+     *
+     * @param {object} query - Query with definition and options
+     * @returns {Promise<QueryState>} Query state
+     */
 
-var _SharingCollection = _interopRequireDefault(__webpack_require__(672));
+  }, {
+    key: "register",
 
-var _PermissionCollection = _interopRequireDefault(__webpack_require__(673));
+    /**
+     * Performs a complete OAuth flow using a Cordova webview
+     * or React Native WebView for auth.
+     * The `register` method's name has been chosen for compat reasons with the Authentication compo.
+     *
+     * @param   {string} cozyURL Receives the URL of the cozy instance.
+     * @returns {object}   Contains the fetched token and the client information.
+     */
+    value: function register(cozyURL) {
+      var stackClient = this.getStackClient();
+      stackClient.setUri(cozyURL);
+      return this.startOAuthFlow(_mobile.authFunction);
+    }
+  }, {
+    key: "isReactNative",
+    value: function isReactNative() {
+      return typeof navigator != 'undefined' && navigator.product == 'ReactNative';
+    }
+    /**
+     * Performs a complete OAuth flow, including updating the internal token at the end.
+     *
+     * @param   {OpenURLCallback} openURLCallback Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.
+     * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client.
+     */
 
-var _TriggerCollection = _interopRequireWildcard(__webpack_require__(669));
+  }, {
+    key: "startOAuthFlow",
+    value: function () {
+      var _startOAuthFlow = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(openURLCallback) {
+        var stackClient;
+        return _regenerator.default.wrap(function _callee14$(_context14) {
+          while (1) {
+            switch (_context14.prev = _context14.next) {
+              case 0:
+                stackClient = this.getStackClient();
+                _context14.next = 3;
+                return stackClient.register();
 
-var _SettingsCollection = _interopRequireWildcard(__webpack_require__(674));
+              case 3:
+                _context14.next = 5;
+                return this.certifyFlagship();
 
-var _NotesCollection = _interopRequireWildcard(__webpack_require__(675));
+              case 5:
+                return _context14.abrupt("return", this.authorize({
+                  openURLCallback: openURLCallback
+                }));
 
-var _OAuthClientsCollection = _interopRequireWildcard(__webpack_require__(677));
+              case 6:
+              case "end":
+                return _context14.stop();
+            }
+          }
+        }, _callee14, this);
+      }));
 
-var _ShortcutsCollection = _interopRequireWildcard(__webpack_require__(678));
+      function startOAuthFlow(_x16) {
+        return _startOAuthFlow.apply(this, arguments);
+      }
 
-var _ContactsCollection = _interopRequireWildcard(__webpack_require__(679));
+      return startOAuthFlow;
+    }()
+    /**
+     * Perform the Flagship certification process for verifying that the current running app is a genuine Cozy application
+     *
+     * This mechanism is described in https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/flagship-certification/README.md
+     */
 
-var _getIconURL2 = _interopRequireDefault(__webpack_require__(680));
+  }, {
+    key: "certifyFlagship",
+    value: function () {
+      var _certifyFlagship2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15() {
+        var stackClient;
+        return _regenerator.default.wrap(function _callee15$(_context15) {
+          while (1) {
+            switch (_context15.prev = _context15.next) {
+              case 0:
+                stackClient = this.getStackClient();
 
-var _logDeprecate = _interopRequireDefault(__webpack_require__(682));
+                if (!stackClient.oauthOptions.shouldRequireFlagshipPermissions) {
+                  _context15.next = 4;
+                  break;
+                }
 
-var _errors = _interopRequireWildcard(__webpack_require__(651));
+                _context15.next = 4;
+                return (0, _flagshipCertification.certifyFlagship)(stackClient.oauthOptions.certificationConfig, this);
 
-var _xhrFetch = __webpack_require__(683);
+              case 4:
+              case "end":
+                return _context15.stop();
+            }
+          }
+        }, _callee15, this);
+      }));
 
-var _microee = _interopRequireDefault(__webpack_require__(558));
+      function certifyFlagship() {
+        return _certifyFlagship2.apply(this, arguments);
+      }
 
-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; }
+      return certifyFlagship;
+    }()
+    /**
+     * Creates an OAuth token with needed permissions for the current client.
+     * The authorization page URL generation can be overriding by passing a function pointer as `openURLCallback` parameter
+     * It is possible to skip the session creation process (when using an in-app browser) by passing a sessionCode (see https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code)
+     *
+     * @param {object} [options] - Authorization options
+     * @param {OpenURLCallback} [options.openURLCallback] - Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.
+     * @param {SessionCode} [options.sessionCode] - session code than can be added to the authorization URL to automatically create the session.
+     * @param {PKCECodes} [options.pkceCodes] - code verifier and a code challenge that should be used in the PKCE verification process.
+     * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client.
+     */
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  }, {
+    key: "authorize",
+    value: function () {
+      var _authorize = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() {
+        var _ref6,
+            _ref6$openURLCallback,
+            openURLCallback,
+            _ref6$sessionCode,
+            sessionCode,
+            _ref6$pkceCodes,
+            pkceCodes,
+            codeVerifier,
+            codeChallenge,
+            stackClient,
+            stateCode,
+            url,
+            redirectedURL,
+            code,
+            token,
+            _stackClient,
+            _args16 = arguments;
 
-var normalizeUri = function normalizeUri(uriArg) {
-  var uri = uriArg;
-  if (uri === null) return null;
+        return _regenerator.default.wrap(function _callee16$(_context16) {
+          while (1) {
+            switch (_context16.prev = _context16.next) {
+              case 0:
+                _ref6 = _args16.length > 0 && _args16[0] !== undefined ? _args16[0] : {}, _ref6$openURLCallback = _ref6.openURLCallback, openURLCallback = _ref6$openURLCallback === void 0 ? _mobile.authFunction : _ref6$openURLCallback, _ref6$sessionCode = _ref6.sessionCode, sessionCode = _ref6$sessionCode === void 0 ? undefined : _ref6$sessionCode, _ref6$pkceCodes = _ref6.pkceCodes, pkceCodes = _ref6$pkceCodes === void 0 ? {} : _ref6$pkceCodes;
+                _context16.prev = 1;
+                codeVerifier = pkceCodes.codeVerifier, codeChallenge = pkceCodes.codeChallenge;
+                stackClient = this.getStackClient();
+                stateCode = stackClient.generateStateCode();
+                url = stackClient.getAuthCodeURL({
+                  stateCode: stateCode,
+                  scopes: undefined,
+                  sessionCode: sessionCode,
+                  codeChallenge: codeChallenge
+                });
+                _context16.next = 8;
+                return openURLCallback(url);
 
-  while (uri[uri.length - 1] === '/') {
-    uri = uri.slice(0, -1);
-  }
+              case 8:
+                redirectedURL = _context16.sent;
+                code = stackClient.getAccessCodeFromURL(redirectedURL, stateCode);
+                _context16.next = 12;
+                return stackClient.fetchAccessToken(code, undefined, undefined, codeVerifier);
 
-  return uri;
-};
+              case 12:
+                token = _context16.sent;
+                stackClient.setToken(token);
+                return _context16.abrupt("return", {
+                  token: token,
+                  infos: stackClient.oauthOptions,
+                  client: stackClient.oauthOptions // for compat with Authentication comp reasons
 
-var isRevocationError = function isRevocationError(err) {
-  return err.message && _errors.default.CLIENT_NOT_FOUND.test(err.message);
-};
-/**
- * Main API against the `cozy-stack` server.
- */
+                });
 
+              case 17:
+                _context16.prev = 17;
+                _context16.t0 = _context16["catch"](1);
 
-var CozyStackClient = /*#__PURE__*/function () {
-  function CozyStackClient(options) {
-    (0, _classCallCheck2.default)(this, CozyStackClient);
+                /* if REGISTRATION_ABORT is emited, we have to unregister the client. */
+                if (_context16.t0.message === _const.REGISTRATION_ABORT) {
+                  _stackClient = this.getStackClient();
 
-    var opts = _objectSpread({}, options);
+                  _stackClient.unregister();
+                }
 
-    var token = opts.token,
-        _opts$uri = opts.uri,
-        uri = _opts$uri === void 0 ? '' : _opts$uri;
-    this.options = opts;
-    this.setUri(uri);
-    this.setToken(token);
-    this.konnectors = new _KonnectorCollection.default(this);
-    this.jobs = new _JobCollection.default(this);
-  }
-  /**
-   * Creates a {@link DocumentCollection} instance.
-   *
-   * @param  {string} doctype The collection doctype.
-   * @returns {DocumentCollection}
-   */
+                throw _context16.t0;
 
+              case 21:
+              case "end":
+                return _context16.stop();
+            }
+          }
+        }, _callee16, this, [[1, 17]]);
+      }));
 
-  (0, _createClass2.default)(CozyStackClient, [{
-    key: "collection",
-    value: function collection(doctype) {
-      if (!doctype) {
-        throw new Error('CozyStackClient.collection() called without a doctype');
+      function authorize() {
+        return _authorize.apply(this, arguments);
       }
 
-      switch (doctype) {
-        case _AppCollection.APPS_DOCTYPE:
-          return new _AppCollection.default(this);
-
-        case _KonnectorCollection.KONNECTORS_DOCTYPE:
-          return new _KonnectorCollection.default(this);
+      return authorize;
+    }()
+    /**
+     * Renews the token if, for instance, new permissions are required or token
+     * has expired.
+     *
+     * @returns {object}   Contains the fetched token and the client information.
+     */
 
-        case 'io.cozy.files':
-          return new _FileCollection.default(doctype, this);
+  }, {
+    key: "renewAuthorization",
+    value: function renewAuthorization() {
+      return this.authorize({
+        openURLCallback: _mobile.authFunction
+      });
+    }
+    /**
+     * Sets the internal store of the client. Use this when you want to have cozy-client's
+     * internal store colocated with your existing Redux store.
+     *
+     * Typically, you would need to do this only once in your application, this is why
+     * setStore throws if you do it twice. If you really need to set the store again,
+     * use options.force = true.
+     *
+     * @example
+     * ```
+     * const client = new CozyClient()
+     * const store = createStore(combineReducers({
+     *   todos: todoReducer,
+     *   cozy: client.reducer()
+     * })
+     * client.setStore(store)
+     * ```
+     *
+     * @param {ReduxStore} store - A redux store
+     * @param {object} [options] - Options
+     * @param {boolean} [options.force] - Will deactivate throwing when client's store already exists
+     */
 
-        case 'io.cozy.sharings':
-          return new _SharingCollection.default(doctype, this);
+  }, {
+    key: "setStore",
+    value: function setStore(store) {
+      var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
+          _ref7$force = _ref7.force,
+          force = _ref7$force === void 0 ? false : _ref7$force;
 
-        case 'io.cozy.permissions':
-          return new _PermissionCollection.default(doctype, this);
+      if (store === undefined) {
+        throw new Error('Store is undefined');
+      } else if (this.store && !force) {
+        throw new Error("Client already has a store, it is forbidden to change store.\nsetStore must be called before any query is executed. Try to\ncall setStore earlier in your code, preferably just after the\ninstantiation of the client.");
+      }
 
-        case _ContactsCollection.CONTACTS_DOCTYPE:
-          return new _ContactsCollection.default(doctype, this);
+      this.store = store;
+    }
+  }, {
+    key: "ensureStore",
+    value: function ensureStore() {
+      if (!this.store) {
+        this.setStore((0, _store.createStore)());
+      }
+    }
+    /**
+     * Returns whether the client has been revoked on the server
+     */
 
-        case _TriggerCollection.TRIGGERS_DOCTYPE:
-          return new _TriggerCollection.default(this);
+  }, {
+    key: "checkForRevocation",
+    value: function () {
+      var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17() {
+        return _regenerator.default.wrap(function _callee17$(_context17) {
+          while (1) {
+            switch (_context17.prev = _context17.next) {
+              case 0:
+                return _context17.abrupt("return", this.stackClient.checkForRevocation());
 
-        case _JobCollection.JOBS_DOCTYPE:
-          return new _JobCollection.default(this);
+              case 1:
+              case "end":
+                return _context17.stop();
+            }
+          }
+        }, _callee17, this);
+      }));
 
-        case _SettingsCollection.SETTINGS_DOCTYPE:
-          return new _SettingsCollection.default(this);
+      function checkForRevocation() {
+        return _checkForRevocation.apply(this, arguments);
+      }
 
-        case _NotesCollection.NOTES_DOCTYPE:
-          return new _NotesCollection.default(this);
+      return checkForRevocation;
+    }()
+    /** Sets public attribute and emits event related to revocation */
 
-        case _OAuthClientsCollection.OAUTH_CLIENTS_DOCTYPE:
-          return new _OAuthClientsCollection.default(this);
+  }, {
+    key: "handleRevocationChange",
+    value: function handleRevocationChange(state) {
+      if (state) {
+        this.isRevoked = true;
+        this.emit('revoked');
+      } else {
+        this.isRevoked = false;
+        this.emit('unrevoked');
+      }
+    }
+    /** Emits event when token is refreshed */
 
-        case _ShortcutsCollection.SHORTCUTS_DOCTYPE:
-          return new _ShortcutsCollection.default(this);
+  }, {
+    key: "handleTokenRefresh",
+    value: function handleTokenRefresh(token) {
+      this.emit('tokenRefreshed');
 
-        default:
-          return new _DocumentCollection.default(doctype, this);
+      if (this.options.onTokenRefresh) {
+        deprecatedHandler("Using onTokenRefresh is deprecated, please use events like this: cozyClient.on('tokenRefreshed', token => console.log('Token has been refreshed', token)). https://git.io/fj3M3");
+        this.options.onTokenRefresh(token);
       }
     }
     /**
-     * Fetches an endpoint in an authorized way.
+     * If no stack client has been passed in options, creates a default stack
+     * client and attaches handlers for revocation and token refresh.
+     * If a stackClient has been passed in options, ensure it has handlers for
+     * revocation and token refresh.
      *
-     * @param  {string} method The HTTP method.
-     * @param  {string} path The URI.
-     * @param  {object} [body] The payload.
-     * @param  {object} [opts={}] Options for fetch
-     * @returns {object}
-     * @throws {FetchError}
+     * If `oauth` options are passed, stackClient is an OAuthStackClient.
      */
 
   }, {
-    key: "fetch",
-    value: function (_fetch) {
-      function fetch(_x, _x2, _x3) {
-        return _fetch.apply(this, arguments);
+    key: "createClient",
+    value: function createClient() {
+      if (this.options.client) {
+        console.warn('CozyClient: Using options.client is deprecated, please use options.stackClient.');
       }
 
-      fetch.toString = function () {
-        return _fetch.toString();
+      var warningForCustomHandlers = this.options.warningForCustomHandlers !== undefined ? this.options.warningForCustomHandlers : true;
+      var stackClient = this.options.client || this.options.stackClient;
+      var handlers = {
+        onRevocationChange: this.handleRevocationChange,
+        onTokenRefresh: this.handleTokenRefresh
       };
 
-      return fetch;
-    }( /*#__PURE__*/function () {
-      var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(method, path, body) {
-        var opts,
-            options,
-            headers,
-            fullPath,
-            fetcher,
-            response,
-            _args = arguments;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                opts = _args.length > 3 && _args[3] !== undefined ? _args[3] : {};
-                options = _objectSpread({}, opts);
-                options.method = method;
-                headers = options.headers = _objectSpread({}, opts.headers);
+      if (stackClient) {
+        this.stackClient = stackClient;
 
-                if (method !== 'GET' && method !== 'HEAD' && body !== undefined) {
-                  if (headers['Content-Type']) {
-                    options.body = body;
-                  }
-                }
+        if (!stackClient.options) {
+          stackClient.options = {};
+        }
 
-                if (!headers.Authorization) {
-                  headers.Authorization = this.getAuthorizationHeader();
-                } // the option credentials:include tells fetch to include the cookies in the
-                // request even for cross-origin requests
+        for (var _i2 = 0, _Object$keys2 = Object.keys(handlers); _i2 < _Object$keys2.length; _i2++) {
+          var handlerName = _Object$keys2[_i2];
 
+          if (!stackClient.options[handlerName]) {
+            stackClient.options[handlerName] = handlers[handlerName];
+          } else {
+            if (warningForCustomHandlers) {
+              console.warn("You passed a stackClient with its own ".concat(handlerName, ". It is not supported, unexpected things might happen."));
+            }
+          }
+        }
+      } else {
+        var options = _objectSpread(_objectSpread({}, this.options), handlers);
 
-                options.credentials = 'include';
-                fullPath = this.fullpath(path);
-                fetcher = (0, _xhrFetch.shouldXMLHTTPRequestBeUsed)(method, path, options) ? _xhrFetch.fetchWithXMLHttpRequest : fetch;
-                _context.prev = 9;
-                _context.next = 12;
-                return fetcher(fullPath, options);
+        this.stackClient = this.options.oauth ? new _cozyStackClient.OAuthClient(options) : new _cozyStackClient.default(options);
+      }
 
-              case 12:
-                response = _context.sent;
+      this.client = new Proxy(this.stackClient, deprecatedHandler('Using cozyClient.client is deprecated, please use cozyClient.stackClient.'));
+    }
+  }, {
+    key: "getClient",
+    value: function getClient() {
+      console.warn('CozyClient: getClient() is deprecated, please use getStackClient().');
+      return this.getStackClient();
+    }
+  }, {
+    key: "getStackClient",
+    value: function getStackClient() {
+      if (!this.stackClient) {
+        this.createClient();
+      }
 
-                if (!response.ok) {
-                  this.emit('error', new _errors.FetchError(response, "".concat(response.status, " ").concat(response.statusText)));
-                }
+      return this.stackClient;
+    }
+  }, {
+    key: "reducer",
+    value: function reducer() {
+      return _store.default;
+    }
+  }, {
+    key: "dispatch",
+    value: function dispatch(action) {
+      return this.store.dispatch(action);
+    }
+    /**
+     * getInstanceOptions - Returns current instance options, such as domain or app slug
+     *
+     * @returns {object}
+     */
 
-                return _context.abrupt("return", response);
+  }, {
+    key: "getInstanceOptions",
+    value: function getInstanceOptions() {
+      return this.instanceOptions;
+    }
+    /**
+     * loadInstanceOptionsFromDOM - Loads the dataset injected by the Stack in web pages and exposes it through getInstanceOptions
+     *
+     * @param {string} [selector=[role=application]] A selector for the node that holds the dataset to load
+     *
+     * @returns {void}
+     */
 
-              case 17:
-                _context.prev = 17;
-                _context.t0 = _context["catch"](9);
+  }, {
+    key: "loadInstanceOptionsFromDOM",
+    value: function loadInstanceOptionsFromDOM() {
+      var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '[role=application]';
+      var root = document.querySelector(selector);
 
-                if (isRevocationError(_context.t0)) {
-                  this.onRevocationChange(true);
-                }
+      if (!(root instanceof HTMLElement)) {
+        throw new Error('The selector that is passed does not return an HTMLElement');
+      }
 
-                throw _context.t0;
+      var _root$dataset = root.dataset,
+          _root$dataset$cozy = _root$dataset.cozy,
+          cozy = _root$dataset$cozy === void 0 ? '{}' : _root$dataset$cozy,
+          dataset = (0, _objectWithoutProperties2.default)(_root$dataset, ["cozy"]);
+      this.instanceOptions = _objectSpread(_objectSpread({}, JSON.parse(cozy)), dataset);
+      this.capabilities = this.instanceOptions.capabilities || null;
+    }
+    /**
+     * Directly set the data in the store, without using a query
+     * This is useful for cases like Pouch replication, which wants to
+     * set some data in the store.
+     *
+     * @param {object} data - Data that is inserted in the store. Shape: { doctype: [data] }
+     */
 
-              case 21:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this, [[9, 17]]);
-      }));
+  }, {
+    key: "setData",
+    value: function setData(data) {
+      var _this10 = this;
+
+      this.ensureStore();
+      Object.entries(data).forEach(function (_ref8) {
+        var _ref9 = (0, _slicedToArray2.default)(_ref8, 2),
+            doctype = _ref9[0],
+            data = _ref9[1];
+
+        _this10.dispatch((0, _store.receiveQueryResult)(null, {
+          data: data
+        }));
+      });
+    }
+    /**
+     * At any time put an error function
+     *
+     * @param {Function} [onError] - Set a callback for queries which are errored
+     * @throws {Error} onError should not have been defined yet
+     */
 
-      return function (_x4, _x5, _x6) {
-        return _ref.apply(this, arguments);
-      };
-    }())
   }, {
-    key: "onTokenRefresh",
-    value: function onTokenRefresh(token) {
-      if (this.options && this.options.onTokenRefresh) {
-        this.options.onTokenRefresh(token);
+    key: "setOnError",
+    value: function setOnError(onError) {
+      if (this.options && this.options.onError) {
+        throw new Error('On Error is already defined');
       }
+
+      this.options.onError = onError;
     }
   }, {
-    key: "onRevocationChange",
-    value: function onRevocationChange(state) {
-      if (this.options && this.options.onRevocationChange) {
-        this.options.onRevocationChange(state);
-      }
+    key: "toJSON",
+    value: function toJSON() {
+      return new _snapshots.CozyClient({
+        uri: this.options.uri
+      });
+    }
+  }], [{
+    key: "fromOldClient",
+    value: function fromOldClient(oldClient, options) {
+      return new CozyClient(_objectSpread({
+        uri: oldClient._url,
+        token: oldClient._token.token
+      }, options));
     }
     /**
-     * Returns whether the client has been revoked on the server
+     * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate
+     * a client with an OAuth-based instance of cozy-client-js.
+     *
+     * Warning: unlike other instantiators, this one needs to be awaited.
+     *
+     * @param {OldCozyClient} oldClient - An OAuth instance of the deprecated cozy-client
+     * @param {object} options - CozyStackClient options
+     * @returns {Promise<CozyClient>} An instance of a client, configured from the old client
      */
 
   }, {
-    key: "checkForRevocation",
+    key: "fromOldOAuthClient",
     value: function () {
-      var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-        return _regenerator.default.wrap(function _callee2$(_context2) {
+      var _fromOldOAuthClient = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(oldClient, options) {
+        var credentials, oauthOptions;
+        return _regenerator.default.wrap(function _callee18$(_context18) {
           while (1) {
-            switch (_context2.prev = _context2.next) {
+            switch (_context18.prev = _context18.next) {
               case 0:
-                _context2.prev = 0;
-                _context2.next = 3;
-                return this.fetchInformation();
+                if (!oldClient._oauth) {
+                  _context18.next = 8;
+                  break;
+                }
+
+                _context18.next = 3;
+                return oldClient.authorize();
 
               case 3:
-                return _context2.abrupt("return", false);
+                credentials = _context18.sent;
+                oauthOptions = {
+                  oauth: credentials.client,
+                  token: credentials.token,
+                  scope: credentials.token.scope
+                };
+                return _context18.abrupt("return", new CozyClient(_objectSpread(_objectSpread({
+                  uri: oldClient._url
+                }, oauthOptions), options)));
 
-              case 6:
-                _context2.prev = 6;
-                _context2.t0 = _context2["catch"](0);
-                return _context2.abrupt("return", isRevocationError(_context2.t0));
+              case 8:
+                throw new Error('Cannot instantiate a new client: old client is not an OAuth client. CozyClient.fromOldClient might be more suitable.');
 
               case 9:
               case "end":
-                return _context2.stop();
+                return _context18.stop();
             }
           }
-        }, _callee2, this, [[0, 6]]);
+        }, _callee18);
       }));
 
-      function checkForRevocation() {
-        return _checkForRevocation.apply(this, arguments);
+      function fromOldOAuthClient(_x17, _x18) {
+        return _fromOldOAuthClient.apply(this, arguments);
       }
 
-      return checkForRevocation;
+      return fromOldOAuthClient;
     }()
     /**
-     * Retrieves a new app token by refreshing the currently used token.
+     * In konnector/service context, CozyClient can be instantiated from
+     * environment variables
      *
-     * @throws {Error} The client should already have an access token to use this function
-     * @throws {Error} The client couldn't fetch a new token
-     * @returns {Promise} A promise that resolves with a new AccessToken object
+     * @param  {NodeEnvironment} [envArg]  - The environment
+     * @param  {object} options - Options
+     * @returns {CozyClient}
      */
 
   }, {
-    key: "refreshToken",
-    value: function () {
-      var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
-        var options, response, html, parser, doc, appNode, data, token, newToken;
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                if (this.token) {
-                  _context3.next = 2;
-                  break;
-                }
+    key: "fromEnv",
+    value: function fromEnv(envArg) {
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+      var env = envArg || (typeof process !== 'undefined' ? process.env : {});
+      var COZY_URL = env.COZY_URL,
+          COZY_CREDENTIALS = env.COZY_CREDENTIALS,
+          NODE_ENV = env.NODE_ENV;
 
-                throw new Error('Cannot refresh an empty token');
+      if (!COZY_URL || !COZY_CREDENTIALS) {
+        throw new Error('Env used to instantiate CozyClient must have COZY_URL and COZY_CREDENTIALS');
+      }
 
-              case 2:
-                options = {
-                  method: 'GET',
-                  credentials: 'include'
-                };
+      if (NODE_ENV === 'development') {
+        options.oauth = JSON.parse(COZY_CREDENTIALS);
+      } else {
+        options.token = COZY_CREDENTIALS.trim();
+      }
 
-                if (global.document) {
-                  _context3.next = 5;
-                  break;
-                }
+      options.uri = COZY_URL.trim();
+      return new CozyClient(_objectSpread({}, options));
+    }
+    /**
+     * When used from an app, CozyClient can be instantiated from the data injected by the stack in
+     * the DOM.
+     *
+     * @param  {object}   options  - CozyClient constructor options
+     * @param  {string}   selector - Options
+     * @returns {CozyClient} - CozyClient instance
+     */
 
-                throw new Error('Not in a web context, cannot refresh token');
+  }, {
+    key: "fromDOM",
+    value: function fromDOM() {
+      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+      var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '[role=application]';
+      var root = document.querySelector(selector);
 
-              case 5:
-                _context3.next = 7;
-                return fetch('/?refreshToken', options);
+      if (!(root instanceof HTMLElement)) {
+        throw new Error("Cannot find an HTMLElement corresponding to ".concat(selector));
+      }
 
-              case 7:
-                response = _context3.sent;
+      if (!root || !root.dataset) {
+        throw new Error("Found no data in ".concat(selector, " to instantiate cozyClient"));
+      }
 
-                if (response.ok) {
-                  _context3.next = 10;
-                  break;
-                }
+      var data = root.dataset.cozy ? JSON.parse(root.dataset.cozy) : _objectSpread({}, root.dataset);
+      var domain = data.domain,
+          token = data.token;
 
-                throw new Error("couldn't fetch a new token - response " + response.statusCode);
+      if (!domain || !token) {
+        domain = domain || data.cozyDomain;
+        token = token || data.cozyToken;
+      }
 
-              case 10:
-                _context3.next = 12;
-                return response.text();
+      if (!domain || !token) {
+        throw new Error("Found no data in ".concat(root.dataset, " to instantiate cozyClient"));
+      }
 
-              case 12:
-                html = _context3.sent;
-                parser = new DOMParser();
-                doc = parser.parseFromString(html, 'text/html');
+      return new CozyClient(_objectSpread({
+        uri: "".concat(window.location.protocol, "//").concat(domain),
+        token: token,
+        capabilities: data.capabilities
+      }, options));
+    }
+  }, {
+    key: "registerHook",
+    value: function registerHook(doctype, name, fn) {
+      var hooks = CozyClient.hooks[doctype] = CozyClient.hooks[doctype] || {};
+      hooks[name] = hooks[name] || [];
+      hooks[name].push(fn);
+    }
+  }]);
+  return CozyClient;
+}();
 
-                if (doc) {
-                  _context3.next = 17;
-                  break;
-                }
+CozyClient.hooks = CozyClient.hooks || {};
+CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
 
-                throw Error("couldn't fetch a new token - doc is not html");
+CozyClient.version = "29.2.0";
 
-              case 17:
-                appNode = doc.querySelector('div[role="application"]');
+_microee.default.mixin(CozyClient);
 
-                if (appNode) {
-                  _context3.next = 20;
-                  break;
-                }
+var _default = CozyClient;
+exports["default"] = _default;
 
-                throw Error("couldn't fetch a new token - no div[role=application]");
+/***/ }),
+/* 526 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 20:
-                data = appNode.dataset.cozy ? JSON.parse(appNode.dataset.cozy) : _objectSpread({}, appNode.dataset);
-                token = data.token;
+var arrayWithHoles = __webpack_require__(527);
 
-                if (token) {
-                  token = token || data.cozyToken;
-                }
+var iterableToArray = __webpack_require__(528);
 
-                if (token) {
-                  _context3.next = 25;
-                  break;
-                }
+var unsupportedIterableToArray = __webpack_require__(529);
 
-                throw Error("couldn't fetch a new token -- missing data-cozy or data-cozy-token attribute");
+var nonIterableRest = __webpack_require__(531);
 
-              case 25:
-                newToken = new _AppToken.default(token);
-                this.onTokenRefresh(newToken);
-                return _context3.abrupt("return", newToken);
+function _toArray(arr) {
+  return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest();
+}
 
-              case 28:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this);
-      }));
+module.exports = _toArray;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-      function refreshToken() {
-        return _refreshToken.apply(this, arguments);
-      }
+/***/ }),
+/* 527 */
+/***/ ((module) => {
 
-      return refreshToken;
-    }()
-    /**
-     * Fetches JSON in an authorized way.
-     *
-     * @param  {string} method The HTTP method.
-     * @param  {string} path The URI.
-     * @param  {object} body The payload.
-     * @param  {object} options Options
-     * @returns {object}
-     * @throws {FetchError}
-     */
+function _arrayWithHoles(arr) {
+  if (Array.isArray(arr)) return arr;
+}
 
-  }, {
-    key: "fetchJSON",
-    value: function () {
-      var _fetchJSON = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(method, path, body) {
-        var options,
-            token,
-            _args4 = arguments;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {};
-                _context4.prev = 1;
-                _context4.next = 4;
-                return this.fetchJSONWithCurrentToken(method, path, body, options);
+module.exports = _arrayWithHoles;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
+
+/***/ }),
+/* 528 */
+/***/ ((module) => {
+
+function _iterableToArray(iter) {
+  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
+}
+
+module.exports = _iterableToArray;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
+
+/***/ }),
+/* 529 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var arrayLikeToArray = __webpack_require__(530);
+
+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);
+}
+
+module.exports = _unsupportedIterableToArray;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
+
+/***/ }),
+/* 530 */
+/***/ ((module) => {
+
+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;
+}
+
+module.exports = _arrayLikeToArray;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
+
+/***/ }),
+/* 531 */
+/***/ ((module) => {
+
+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.");
+}
+
+module.exports = _nonIterableRest;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-              case 4:
-                return _context4.abrupt("return", _context4.sent);
+/***/ }),
+/* 532 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 7:
-                _context4.prev = 7;
-                _context4.t0 = _context4["catch"](1);
+var arrayWithHoles = __webpack_require__(527);
 
-                if (!(_errors.default.EXPIRED_TOKEN.test(_context4.t0.message) || _errors.default.INVALID_TOKEN.test(_context4.t0.message))) {
-                  _context4.next = 25;
-                  break;
-                }
+var iterableToArrayLimit = __webpack_require__(533);
 
-                _context4.prev = 10;
-                _context4.next = 13;
-                return this.refreshToken();
+var unsupportedIterableToArray = __webpack_require__(529);
 
-              case 13:
-                token = _context4.sent;
-                _context4.next = 19;
-                break;
+var nonIterableRest = __webpack_require__(531);
 
-              case 16:
-                _context4.prev = 16;
-                _context4.t1 = _context4["catch"](10);
-                throw _context4.t0;
+function _slicedToArray(arr, i) {
+  return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
+}
 
-              case 19:
-                this.setToken(token);
-                _context4.next = 22;
-                return this.fetchJSONWithCurrentToken(method, path, body, options);
+module.exports = _slicedToArray;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-              case 22:
-                return _context4.abrupt("return", _context4.sent);
+/***/ }),
+/* 533 */
+/***/ ((module) => {
 
-              case 25:
-                throw _context4.t0;
+function _iterableToArrayLimit(arr, i) {
+  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
 
-              case 26:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4, this, [[1, 7], [10, 16]]);
-      }));
+  if (_i == null) return;
+  var _arr = [];
+  var _n = true;
+  var _d = false;
 
-      function fetchJSON(_x7, _x8, _x9) {
-        return _fetchJSON.apply(this, arguments);
-      }
+  var _s, _e;
 
-      return fetchJSON;
-    }()
-  }, {
-    key: "fetchJSONWithCurrentToken",
-    value: function () {
-      var _fetchJSONWithCurrentToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(method, path, bodyArg) {
-        var options,
-            clonedOptions,
-            headers,
-            body,
-            resp,
-            contentType,
-            isJson,
-            data,
-            _args5 = arguments;
-        return _regenerator.default.wrap(function _callee5$(_context5) {
-          while (1) {
-            switch (_context5.prev = _context5.next) {
-              case 0:
-                options = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : {};
-                //Since we modify the object later by adding in some case a
-                //content-type, let's clone this object to scope the modification
-                clonedOptions = (0, _cloneDeep.default)(options);
-                headers = clonedOptions.headers = clonedOptions.headers || {};
-                headers['Accept'] = 'application/json';
-                body = bodyArg;
+  try {
+    for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
+      _arr.push(_s.value);
 
-                if (method !== 'GET' && method !== 'HEAD' && body !== undefined) {
-                  if (!headers['Content-Type']) {
-                    headers['Content-Type'] = 'application/json';
-                    body = JSON.stringify(body);
-                  }
-                }
+      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;
+    }
+  }
 
-                _context5.next = 8;
-                return this.fetch(method, path, body, clonedOptions);
+  return _arr;
+}
 
-              case 8:
-                resp = _context5.sent;
-                contentType = resp.headers.get('content-type');
-                isJson = contentType && contentType.indexOf('json') >= 0;
-                _context5.next = 13;
-                return isJson ? resp.json() : resp.text();
+module.exports = _iterableToArrayLimit;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-              case 13:
-                data = _context5.sent;
+/***/ }),
+/* 534 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                if (!resp.ok) {
-                  _context5.next = 16;
-                  break;
-                }
+var arrayWithoutHoles = __webpack_require__(535);
 
-                return _context5.abrupt("return", data);
+var iterableToArray = __webpack_require__(528);
 
-              case 16:
-                throw new _errors.FetchError(resp, data);
+var unsupportedIterableToArray = __webpack_require__(529);
 
-              case 17:
-              case "end":
-                return _context5.stop();
-            }
-          }
-        }, _callee5, this);
-      }));
+var nonIterableSpread = __webpack_require__(536);
 
-      function fetchJSONWithCurrentToken(_x10, _x11, _x12) {
-        return _fetchJSONWithCurrentToken.apply(this, arguments);
-      }
+function _toConsumableArray(arr) {
+  return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
+}
 
-      return fetchJSONWithCurrentToken;
-    }()
-  }, {
-    key: "fullpath",
-    value: function fullpath(path) {
-      if (path.startsWith('http')) {
-        return path;
-      } else {
-        return this.uri + path;
-      }
-    }
-  }, {
-    key: "getAuthorizationHeader",
-    value: function getAuthorizationHeader() {
-      return this.token ? this.token.toAuthHeader() : null;
-    }
-  }, {
-    key: "setCredentials",
-    value: function setCredentials(token) {
-      (0, _logDeprecate.default)('CozyStackClient::setCredentials is deprecated, use CozyStackClient::setToken');
-      return this.setToken(token);
-    }
-  }, {
-    key: "getCredentials",
-    value: function getCredentials() {
-      (0, _logDeprecate.default)('CozyStackClient::getCredentials is deprecated, use CozyStackClient::getAuthorizationHeader');
-      return this.getAuthorizationHeader();
-    }
-    /**
-     * Change or set the API token
-     *
-     * @param {string|AppToken|AccessToken} token - Stack API token
-     */
+module.exports = _toConsumableArray;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-  }, {
-    key: "setToken",
-    value: function setToken(token) {
-      if (!token) {
-        this.token = null;
-      } else {
-        if (token.toAuthHeader) {
-          // AppToken or AccessToken
-          this.token = token;
-        } else if (typeof token === 'string') {
-          // jwt string
-          this.token = new _AppToken.default(token);
-        } else {
-          console.warn('Cozy-Client: Unknown token format', token);
-          throw new Error('Cozy-Client: Unknown token format');
-        }
+/***/ }),
+/* 535 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-        this.onRevocationChange(false);
-      }
-    }
-    /**
-     * Get the access token string, being an oauth token or an app token
-     *
-     * @returns {string} token
-     */
+var arrayLikeToArray = __webpack_require__(530);
 
-  }, {
-    key: "getAccessToken",
-    value: function getAccessToken() {
-      return this.token && this.token.getAccessToken();
-    }
-  }, {
-    key: "setUri",
-    value: function setUri(uri) {
-      this.uri = normalizeUri(uri);
-    }
-  }, {
-    key: "getIconURL",
-    value: function getIconURL(opts) {
-      return (0, _getIconURL2.default)(this, opts);
-    }
-  }]);
-  return CozyStackClient;
-}();
+function _arrayWithoutHoles(arr) {
+  if (Array.isArray(arr)) return arrayLikeToArray(arr);
+}
 
-_microee.default.mixin(CozyStackClient);
+module.exports = _arrayWithoutHoles;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-var _default = CozyStackClient;
-exports["default"] = _default;
+/***/ }),
+/* 536 */
+/***/ ((module) => {
+
+function _nonIterableSpread() {
+  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+}
+
+module.exports = _nonIterableSpread;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 561 */
+/* 537 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseClone = __webpack_require__(562);
+var objectWithoutPropertiesLoose = __webpack_require__(538);
 
-/** Used to compose bitmasks for cloning. */
-var CLONE_DEEP_FLAG = 1,
-    CLONE_SYMBOLS_FLAG = 4;
+function _objectWithoutProperties(source, excluded) {
+  if (source == null) return {};
+  var target = objectWithoutPropertiesLoose(source, excluded);
+  var key, i;
 
-/**
- * This method is like `_.clone` except that it recursively clones `value`.
- *
- * @static
- * @memberOf _
- * @since 1.0.0
- * @category Lang
- * @param {*} value The value to recursively clone.
- * @returns {*} Returns the deep cloned value.
- * @see _.clone
- * @example
- *
- * var objects = [{ 'a': 1 }, { 'b': 2 }];
- *
- * var deep = _.cloneDeep(objects);
- * console.log(deep[0] === objects[0]);
- * // => false
- */
-function cloneDeep(value) {
-  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
-}
+  if (Object.getOwnPropertySymbols) {
+    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
 
-module.exports = cloneDeep;
+    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;
+}
 
+module.exports = _objectWithoutProperties;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 562 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 538 */
+/***/ ((module) => {
 
-var Stack = __webpack_require__(404),
-    arrayEach = __webpack_require__(554),
-    assignValue = __webpack_require__(563),
-    baseAssign = __webpack_require__(564),
-    baseAssignIn = __webpack_require__(566),
-    cloneBuffer = __webpack_require__(570),
-    copyArray = __webpack_require__(571),
-    copySymbols = __webpack_require__(572),
-    copySymbolsIn = __webpack_require__(573),
-    getAllKeys = __webpack_require__(423),
-    getAllKeysIn = __webpack_require__(576),
-    getTag = __webpack_require__(447),
-    initCloneArray = __webpack_require__(577),
-    initCloneByTag = __webpack_require__(578),
-    initCloneObject = __webpack_require__(584),
-    isArray = __webpack_require__(55),
-    isBuffer = __webpack_require__(434),
-    isMap = __webpack_require__(586),
-    isObject = __webpack_require__(52),
-    isSet = __webpack_require__(588),
-    keys = __webpack_require__(429),
-    keysIn = __webpack_require__(567);
+function _objectWithoutPropertiesLoose(source, excluded) {
+  if (source == null) return {};
+  var target = {};
+  var sourceKeys = Object.keys(source);
+  var key, i;
 
-/** Used to compose bitmasks for cloning. */
-var CLONE_DEEP_FLAG = 1,
-    CLONE_FLAT_FLAG = 2,
-    CLONE_SYMBOLS_FLAG = 4;
+  for (i = 0; i < sourceKeys.length; i++) {
+    key = sourceKeys[i];
+    if (excluded.indexOf(key) >= 0) continue;
+    target[key] = source[key];
+  }
 
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]',
-    arrayTag = '[object Array]',
-    boolTag = '[object Boolean]',
-    dateTag = '[object Date]',
-    errorTag = '[object Error]',
-    funcTag = '[object Function]',
-    genTag = '[object GeneratorFunction]',
-    mapTag = '[object Map]',
-    numberTag = '[object Number]',
-    objectTag = '[object Object]',
-    regexpTag = '[object RegExp]',
-    setTag = '[object Set]',
-    stringTag = '[object String]',
-    symbolTag = '[object Symbol]',
-    weakMapTag = '[object WeakMap]';
+  return target;
+}
 
-var arrayBufferTag = '[object ArrayBuffer]',
-    dataViewTag = '[object DataView]',
-    float32Tag = '[object Float32Array]',
-    float64Tag = '[object Float64Array]',
-    int8Tag = '[object Int8Array]',
-    int16Tag = '[object Int16Array]',
-    int32Tag = '[object Int32Array]',
-    uint8Tag = '[object Uint8Array]',
-    uint8ClampedTag = '[object Uint8ClampedArray]',
-    uint16Tag = '[object Uint16Array]',
-    uint32Tag = '[object Uint32Array]';
+module.exports = _objectWithoutPropertiesLoose;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-/** Used to identify `toStringTag` values supported by `_.clone`. */
-var cloneableTags = {};
-cloneableTags[argsTag] = cloneableTags[arrayTag] =
-cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
-cloneableTags[boolTag] = cloneableTags[dateTag] =
-cloneableTags[float32Tag] = cloneableTags[float64Tag] =
-cloneableTags[int8Tag] = cloneableTags[int16Tag] =
-cloneableTags[int32Tag] = cloneableTags[mapTag] =
-cloneableTags[numberTag] = cloneableTags[objectTag] =
-cloneableTags[regexpTag] = cloneableTags[setTag] =
-cloneableTags[stringTag] = cloneableTags[symbolTag] =
-cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
-cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
-cloneableTags[errorTag] = cloneableTags[funcTag] =
-cloneableTags[weakMapTag] = false;
+/***/ }),
+/* 539 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+module.exports = __webpack_require__(540);
+
+
+/***/ }),
+/* 540 */
+/***/ ((module) => {
 
 /**
- * The base implementation of `_.clone` and `_.cloneDeep` which tracks
- * traversed objects.
+ * Copyright (c) 2014-present, Facebook, Inc.
  *
- * @private
- * @param {*} value The value to clone.
- * @param {boolean} bitmask The bitmask flags.
- *  1 - Deep clone
- *  2 - Flatten inherited properties
- *  4 - Clone symbols
- * @param {Function} [customizer] The function to customize cloning.
- * @param {string} [key] The key of `value`.
- * @param {Object} [object] The parent object of `value`.
- * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
- * @returns {*} Returns the cloned value.
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
  */
-function baseClone(value, bitmask, customizer, key, object, stack) {
-  var result,
-      isDeep = bitmask & CLONE_DEEP_FLAG,
-      isFlat = bitmask & CLONE_FLAT_FLAG,
-      isFull = bitmask & CLONE_SYMBOLS_FLAG;
 
-  if (customizer) {
-    result = object ? customizer(value, key, object, stack) : customizer(value);
+var runtime = (function (exports) {
+  "use strict";
+
+  var Op = Object.prototype;
+  var hasOwn = Op.hasOwnProperty;
+  var undefined; // More compressible than void 0.
+  var $Symbol = typeof Symbol === "function" ? Symbol : {};
+  var iteratorSymbol = $Symbol.iterator || "@@iterator";
+  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
+  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+
+  function define(obj, key, value) {
+    Object.defineProperty(obj, key, {
+      value: value,
+      enumerable: true,
+      configurable: true,
+      writable: true
+    });
+    return obj[key];
   }
-  if (result !== undefined) {
-    return result;
+  try {
+    // IE 8 has a broken Object.defineProperty that only works on DOM objects.
+    define({}, "");
+  } catch (err) {
+    define = function(obj, key, value) {
+      return obj[key] = value;
+    };
   }
-  if (!isObject(value)) {
-    return value;
+
+  function wrap(innerFn, outerFn, self, tryLocsList) {
+    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
+    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
+    var generator = Object.create(protoGenerator.prototype);
+    var context = new Context(tryLocsList || []);
+
+    // The ._invoke method unifies the implementations of the .next,
+    // .throw, and .return methods.
+    generator._invoke = makeInvokeMethod(innerFn, self, context);
+
+    return generator;
   }
-  var isArr = isArray(value);
-  if (isArr) {
-    result = initCloneArray(value);
-    if (!isDeep) {
-      return copyArray(value, result);
-    }
-  } else {
-    var tag = getTag(value),
-        isFunc = tag == funcTag || tag == genTag;
+  exports.wrap = wrap;
 
-    if (isBuffer(value)) {
-      return cloneBuffer(value, isDeep);
-    }
-    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
-      result = (isFlat || isFunc) ? {} : initCloneObject(value);
-      if (!isDeep) {
-        return isFlat
-          ? copySymbolsIn(value, baseAssignIn(result, value))
-          : copySymbols(value, baseAssign(result, value));
-      }
-    } else {
-      if (!cloneableTags[tag]) {
-        return object ? value : {};
-      }
-      result = initCloneByTag(value, tag, isDeep);
+  // Try/catch helper to minimize deoptimizations. Returns a completion
+  // record like context.tryEntries[i].completion. This interface could
+  // have been (and was previously) designed to take a closure to be
+  // invoked without arguments, but in all the cases we care about we
+  // already have an existing method we want to call, so there's no need
+  // to create a new function object. We can even get away with assuming
+  // the method takes exactly one argument, since that happens to be true
+  // in every case, so we don't have to touch the arguments object. The
+  // only additional allocation required is the completion record, which
+  // has a stable shape and so hopefully should be cheap to allocate.
+  function tryCatch(fn, obj, arg) {
+    try {
+      return { type: "normal", arg: fn.call(obj, arg) };
+    } catch (err) {
+      return { type: "throw", arg: err };
     }
   }
-  // Check for circular references and return its corresponding clone.
-  stack || (stack = new Stack);
-  var stacked = stack.get(value);
-  if (stacked) {
-    return stacked;
+
+  var GenStateSuspendedStart = "suspendedStart";
+  var GenStateSuspendedYield = "suspendedYield";
+  var GenStateExecuting = "executing";
+  var GenStateCompleted = "completed";
+
+  // Returning this object from the innerFn has the same effect as
+  // breaking out of the dispatch switch statement.
+  var ContinueSentinel = {};
+
+  // Dummy constructor functions that we use as the .constructor and
+  // .constructor.prototype properties for functions that return Generator
+  // objects. For full spec compliance, you may wish to configure your
+  // minifier not to mangle the names of these two functions.
+  function Generator() {}
+  function GeneratorFunction() {}
+  function GeneratorFunctionPrototype() {}
+
+  // This is a polyfill for %IteratorPrototype% for environments that
+  // don't natively support it.
+  var IteratorPrototype = {};
+  define(IteratorPrototype, iteratorSymbol, function () {
+    return this;
+  });
+
+  var getProto = Object.getPrototypeOf;
+  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+  if (NativeIteratorPrototype &&
+      NativeIteratorPrototype !== Op &&
+      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
+    // This environment has a native %IteratorPrototype%; use it instead
+    // of the polyfill.
+    IteratorPrototype = NativeIteratorPrototype;
   }
-  stack.set(value, result);
 
-  if (isSet(value)) {
-    value.forEach(function(subValue) {
-      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
-    });
-  } else if (isMap(value)) {
-    value.forEach(function(subValue, key) {
-      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
+  var Gp = GeneratorFunctionPrototype.prototype =
+    Generator.prototype = Object.create(IteratorPrototype);
+  GeneratorFunction.prototype = GeneratorFunctionPrototype;
+  define(Gp, "constructor", GeneratorFunctionPrototype);
+  define(GeneratorFunctionPrototype, "constructor", GeneratorFunction);
+  GeneratorFunction.displayName = define(
+    GeneratorFunctionPrototype,
+    toStringTagSymbol,
+    "GeneratorFunction"
+  );
+
+  // Helper for defining the .next, .throw, and .return methods of the
+  // Iterator interface in terms of a single ._invoke method.
+  function defineIteratorMethods(prototype) {
+    ["next", "throw", "return"].forEach(function(method) {
+      define(prototype, method, function(arg) {
+        return this._invoke(method, arg);
+      });
     });
   }
 
-  var keysFunc = isFull
-    ? (isFlat ? getAllKeysIn : getAllKeys)
-    : (isFlat ? keysIn : keys);
+  exports.isGeneratorFunction = function(genFun) {
+    var ctor = typeof genFun === "function" && genFun.constructor;
+    return ctor
+      ? ctor === GeneratorFunction ||
+        // For the native GeneratorFunction constructor, the best we can
+        // do is to check its .name property.
+        (ctor.displayName || ctor.name) === "GeneratorFunction"
+      : false;
+  };
 
-  var props = isArr ? undefined : keysFunc(value);
-  arrayEach(props || value, function(subValue, key) {
-    if (props) {
-      key = subValue;
-      subValue = value[key];
+  exports.mark = function(genFun) {
+    if (Object.setPrototypeOf) {
+      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
+    } else {
+      genFun.__proto__ = GeneratorFunctionPrototype;
+      define(genFun, toStringTagSymbol, "GeneratorFunction");
     }
-    // Recursively populate clone (susceptible to call stack limits).
-    assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
-  });
-  return result;
-}
+    genFun.prototype = Object.create(Gp);
+    return genFun;
+  };
 
-module.exports = baseClone;
+  // Within the body of any async function, `await x` is transformed to
+  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
+  // `hasOwn.call(value, "__await")` to determine if the yielded value is
+  // meant to be awaited.
+  exports.awrap = function(arg) {
+    return { __await: arg };
+  };
 
+  function AsyncIterator(generator, PromiseImpl) {
+    function invoke(method, arg, resolve, reject) {
+      var record = tryCatch(generator[method], generator, arg);
+      if (record.type === "throw") {
+        reject(record.arg);
+      } else {
+        var result = record.arg;
+        var value = result.value;
+        if (value &&
+            typeof value === "object" &&
+            hasOwn.call(value, "__await")) {
+          return PromiseImpl.resolve(value.__await).then(function(value) {
+            invoke("next", value, resolve, reject);
+          }, function(err) {
+            invoke("throw", err, resolve, reject);
+          });
+        }
 
-/***/ }),
-/* 563 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+        return PromiseImpl.resolve(value).then(function(unwrapped) {
+          // When a yielded Promise is resolved, its final value becomes
+          // the .value of the Promise<{value,done}> result for the
+          // current iteration.
+          result.value = unwrapped;
+          resolve(result);
+        }, function(error) {
+          // If a rejected Promise was yielded, throw the rejection back
+          // into the async generator function so it can be handled there.
+          return invoke("throw", error, resolve, reject);
+        });
+      }
+    }
 
-var baseAssignValue = __webpack_require__(534),
-    eq = __webpack_require__(385);
+    var previousPromise;
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+    function enqueue(method, arg) {
+      function callInvokeWithMethodAndArg() {
+        return new PromiseImpl(function(resolve, reject) {
+          invoke(method, arg, resolve, reject);
+        });
+      }
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+      return previousPromise =
+        // If enqueue has been called before, then we want to wait until
+        // all previous Promises have been resolved before calling invoke,
+        // so that results are always delivered in the correct order. If
+        // enqueue has not been called before, then it is important to
+        // call invoke immediately, without waiting on a callback to fire,
+        // so that the async generator function has the opportunity to do
+        // any necessary setup in a predictable way. This predictability
+        // is why the Promise constructor synchronously invokes its
+        // executor callback, and why async functions synchronously
+        // execute code before the first await. Since we implement simple
+        // async functions in terms of async generators, it is especially
+        // important to get this right, even though it requires care.
+        previousPromise ? previousPromise.then(
+          callInvokeWithMethodAndArg,
+          // Avoid propagating failures to Promises returned by later
+          // invocations of the iterator.
+          callInvokeWithMethodAndArg
+        ) : callInvokeWithMethodAndArg();
+    }
 
-/**
- * Assigns `value` to `key` of `object` if the existing value is not equivalent
- * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * for equality comparisons.
- *
- * @private
- * @param {Object} object The object to modify.
- * @param {string} key The key of the property to assign.
- * @param {*} value The value to assign.
- */
-function assignValue(object, key, value) {
-  var objValue = object[key];
-  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
-      (value === undefined && !(key in object))) {
-    baseAssignValue(object, key, value);
+    // Define the unified helper method that is used to implement .next,
+    // .throw, and .return (see defineIteratorMethods).
+    this._invoke = enqueue;
   }
-}
 
-module.exports = assignValue;
+  defineIteratorMethods(AsyncIterator.prototype);
+  define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
+    return this;
+  });
+  exports.AsyncIterator = AsyncIterator;
 
+  // Note that simple async functions are implemented on top of
+  // AsyncIterator objects; they just return a Promise for the value of
+  // the final result produced by the iterator.
+  exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
+    if (PromiseImpl === void 0) PromiseImpl = Promise;
 
-/***/ }),
-/* 564 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    var iter = new AsyncIterator(
+      wrap(innerFn, outerFn, self, tryLocsList),
+      PromiseImpl
+    );
 
-var copyObject = __webpack_require__(565),
-    keys = __webpack_require__(429);
+    return exports.isGeneratorFunction(outerFn)
+      ? iter // If outerFn is a generator, return the full iterator.
+      : iter.next().then(function(result) {
+          return result.done ? result.value : iter.next();
+        });
+  };
 
-/**
- * The base implementation of `_.assign` without support for multiple sources
- * or `customizer` functions.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @returns {Object} Returns `object`.
- */
-function baseAssign(object, source) {
-  return object && copyObject(source, keys(source), object);
-}
+  function makeInvokeMethod(innerFn, self, context) {
+    var state = GenStateSuspendedStart;
 
-module.exports = baseAssign;
+    return function invoke(method, arg) {
+      if (state === GenStateExecuting) {
+        throw new Error("Generator is already running");
+      }
 
+      if (state === GenStateCompleted) {
+        if (method === "throw") {
+          throw arg;
+        }
 
-/***/ }),
-/* 565 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+        // Be forgiving, per 25.3.3.3.3 of the spec:
+        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
+        return doneResult();
+      }
 
-var assignValue = __webpack_require__(563),
-    baseAssignValue = __webpack_require__(534);
+      context.method = method;
+      context.arg = arg;
 
-/**
- * Copies properties of `source` to `object`.
- *
- * @private
- * @param {Object} source The object to copy properties from.
- * @param {Array} props The property identifiers to copy.
- * @param {Object} [object={}] The object to copy properties to.
- * @param {Function} [customizer] The function to customize copied values.
- * @returns {Object} Returns `object`.
- */
-function copyObject(source, props, object, customizer) {
-  var isNew = !object;
-  object || (object = {});
+      while (true) {
+        var delegate = context.delegate;
+        if (delegate) {
+          var delegateResult = maybeInvokeDelegate(delegate, context);
+          if (delegateResult) {
+            if (delegateResult === ContinueSentinel) continue;
+            return delegateResult;
+          }
+        }
 
-  var index = -1,
-      length = props.length;
+        if (context.method === "next") {
+          // Setting context._sent for legacy support of Babel's
+          // function.sent implementation.
+          context.sent = context._sent = context.arg;
 
-  while (++index < length) {
-    var key = props[index];
+        } else if (context.method === "throw") {
+          if (state === GenStateSuspendedStart) {
+            state = GenStateCompleted;
+            throw context.arg;
+          }
 
-    var newValue = customizer
-      ? customizer(object[key], source[key], key, object, source)
-      : undefined;
+          context.dispatchException(context.arg);
 
-    if (newValue === undefined) {
-      newValue = source[key];
-    }
-    if (isNew) {
-      baseAssignValue(object, key, newValue);
-    } else {
-      assignValue(object, key, newValue);
-    }
-  }
-  return object;
-}
+        } else if (context.method === "return") {
+          context.abrupt("return", context.arg);
+        }
 
-module.exports = copyObject;
+        state = GenStateExecuting;
 
+        var record = tryCatch(innerFn, self, context);
+        if (record.type === "normal") {
+          // If an exception is thrown from innerFn, we leave state ===
+          // GenStateExecuting and loop back for another invocation.
+          state = context.done
+            ? GenStateCompleted
+            : GenStateSuspendedYield;
 
-/***/ }),
-/* 566 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+          if (record.arg === ContinueSentinel) {
+            continue;
+          }
 
-var copyObject = __webpack_require__(565),
-    keysIn = __webpack_require__(567);
+          return {
+            value: record.arg,
+            done: context.done
+          };
 
-/**
- * The base implementation of `_.assignIn` without support for multiple sources
- * or `customizer` functions.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @returns {Object} Returns `object`.
- */
-function baseAssignIn(object, source) {
-  return object && copyObject(source, keysIn(source), object);
-}
+        } else if (record.type === "throw") {
+          state = GenStateCompleted;
+          // Dispatch the exception by looping back around to the
+          // context.dispatchException(context.arg) call above.
+          context.method = "throw";
+          context.arg = record.arg;
+        }
+      }
+    };
+  }
 
-module.exports = baseAssignIn;
+  // Call delegate.iterator[context.method](context.arg) and handle the
+  // result, either by returning a { value, done } result from the
+  // delegate iterator, or by modifying context.method and context.arg,
+  // setting context.delegate to null, and returning the ContinueSentinel.
+  function maybeInvokeDelegate(delegate, context) {
+    var method = delegate.iterator[context.method];
+    if (method === undefined) {
+      // A .throw or .return when the delegate iterator has no .throw
+      // method always terminates the yield* loop.
+      context.delegate = null;
 
+      if (context.method === "throw") {
+        // Note: ["return"] must be used for ES3 parsing compatibility.
+        if (delegate.iterator["return"]) {
+          // If the delegate iterator has a return method, give it a
+          // chance to clean up.
+          context.method = "return";
+          context.arg = undefined;
+          maybeInvokeDelegate(delegate, context);
 
-/***/ }),
-/* 567 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+          if (context.method === "throw") {
+            // If maybeInvokeDelegate(context) changed context.method from
+            // "return" to "throw", let that override the TypeError below.
+            return ContinueSentinel;
+          }
+        }
 
-var arrayLikeKeys = __webpack_require__(430),
-    baseKeysIn = __webpack_require__(568),
-    isArrayLike = __webpack_require__(446);
+        context.method = "throw";
+        context.arg = new TypeError(
+          "The iterator does not provide a 'throw' method");
+      }
 
-/**
- * Creates an array of the own and inherited enumerable property names of `object`.
- *
- * **Note:** Non-object values are coerced to objects.
- *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- * @example
- *
- * function Foo() {
- *   this.a = 1;
- *   this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.keysIn(new Foo);
- * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
- */
-function keysIn(object) {
-  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
-}
+      return ContinueSentinel;
+    }
 
-module.exports = keysIn;
+    var record = tryCatch(method, delegate.iterator, context.arg);
 
+    if (record.type === "throw") {
+      context.method = "throw";
+      context.arg = record.arg;
+      context.delegate = null;
+      return ContinueSentinel;
+    }
 
-/***/ }),
-/* 568 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    var info = record.arg;
 
-var isObject = __webpack_require__(52),
-    isPrototype = __webpack_require__(443),
-    nativeKeysIn = __webpack_require__(569);
+    if (! info) {
+      context.method = "throw";
+      context.arg = new TypeError("iterator result is not an object");
+      context.delegate = null;
+      return ContinueSentinel;
+    }
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+    if (info.done) {
+      // Assign the result of the finished delegate to the temporary
+      // variable specified by delegate.resultName (see delegateYield).
+      context[delegate.resultName] = info.value;
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+      // Resume execution at the desired location (see delegateYield).
+      context.next = delegate.nextLoc;
 
-/**
- * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- */
-function baseKeysIn(object) {
-  if (!isObject(object)) {
-    return nativeKeysIn(object);
-  }
-  var isProto = isPrototype(object),
-      result = [];
+      // If context.method was "throw" but the delegate handled the
+      // exception, let the outer generator proceed normally. If
+      // context.method was "next", forget context.arg since it has been
+      // "consumed" by the delegate iterator. If context.method was
+      // "return", allow the original .return call to continue in the
+      // outer generator.
+      if (context.method !== "return") {
+        context.method = "next";
+        context.arg = undefined;
+      }
 
-  for (var key in object) {
-    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
-      result.push(key);
+    } else {
+      // Re-yield the result returned by the delegate method.
+      return info;
     }
+
+    // The delegate iterator is finished, so forget it and continue with
+    // the outer generator.
+    context.delegate = null;
+    return ContinueSentinel;
   }
-  return result;
-}
 
-module.exports = baseKeysIn;
+  // Define Generator.prototype.{next,throw,return} in terms of the
+  // unified ._invoke helper method.
+  defineIteratorMethods(Gp);
 
+  define(Gp, toStringTagSymbol, "Generator");
 
-/***/ }),
-/* 569 */
-/***/ ((module) => {
+  // A Generator should always return itself as the iterator object when the
+  // @@iterator function is called on it. Some browsers' implementations of the
+  // iterator prototype chain incorrectly implement this, causing the Generator
+  // object to not be returned from this call. This ensures that doesn't happen.
+  // See https://github.com/facebook/regenerator/issues/274 for more details.
+  define(Gp, iteratorSymbol, function() {
+    return this;
+  });
 
-/**
- * This function is like
- * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
- * except that it includes inherited enumerable properties.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- */
-function nativeKeysIn(object) {
-  var result = [];
-  if (object != null) {
-    for (var key in Object(object)) {
-      result.push(key);
+  define(Gp, "toString", function() {
+    return "[object Generator]";
+  });
+
+  function pushTryEntry(locs) {
+    var entry = { tryLoc: locs[0] };
+
+    if (1 in locs) {
+      entry.catchLoc = locs[1];
+    }
+
+    if (2 in locs) {
+      entry.finallyLoc = locs[2];
+      entry.afterLoc = locs[3];
     }
+
+    this.tryEntries.push(entry);
   }
-  return result;
-}
 
-module.exports = nativeKeysIn;
+  function resetTryEntry(entry) {
+    var record = entry.completion || {};
+    record.type = "normal";
+    delete record.arg;
+    entry.completion = record;
+  }
 
+  function Context(tryLocsList) {
+    // The root entry object (effectively a try statement without a catch
+    // or a finally block) gives us a place to store values thrown from
+    // locations where there is no enclosing try statement.
+    this.tryEntries = [{ tryLoc: "root" }];
+    tryLocsList.forEach(pushTryEntry, this);
+    this.reset(true);
+  }
 
-/***/ }),
-/* 570 */
-/***/ ((module, exports, __webpack_require__) => {
+  exports.keys = function(object) {
+    var keys = [];
+    for (var key in object) {
+      keys.push(key);
+    }
+    keys.reverse();
+
+    // Rather than returning an object with a next method, we keep
+    // things simple and return the next function itself.
+    return function next() {
+      while (keys.length) {
+        var key = keys.pop();
+        if (key in object) {
+          next.value = key;
+          next.done = false;
+          return next;
+        }
+      }
+
+      // To avoid creating an additional object, we just hang the .value
+      // and .done properties off the next function object itself. This
+      // also ensures that the minifier will not anonymize the function.
+      next.done = true;
+      return next;
+    };
+  };
+
+  function values(iterable) {
+    if (iterable) {
+      var iteratorMethod = iterable[iteratorSymbol];
+      if (iteratorMethod) {
+        return iteratorMethod.call(iterable);
+      }
 
-/* module decorator */ module = __webpack_require__.nmd(module);
-var root = __webpack_require__(48);
+      if (typeof iterable.next === "function") {
+        return iterable;
+      }
 
-/** Detect free variable `exports`. */
-var freeExports =  true && exports && !exports.nodeType && exports;
+      if (!isNaN(iterable.length)) {
+        var i = -1, next = function next() {
+          while (++i < iterable.length) {
+            if (hasOwn.call(iterable, i)) {
+              next.value = iterable[i];
+              next.done = false;
+              return next;
+            }
+          }
 
-/** Detect free variable `module`. */
-var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
+          next.value = undefined;
+          next.done = true;
 
-/** Detect the popular CommonJS extension `module.exports`. */
-var moduleExports = freeModule && freeModule.exports === freeExports;
+          return next;
+        };
 
-/** Built-in value references. */
-var Buffer = moduleExports ? root.Buffer : undefined,
-    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
+        return next.next = next;
+      }
+    }
 
-/**
- * Creates a clone of  `buffer`.
- *
- * @private
- * @param {Buffer} buffer The buffer to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @returns {Buffer} Returns the cloned buffer.
- */
-function cloneBuffer(buffer, isDeep) {
-  if (isDeep) {
-    return buffer.slice();
+    // Return an iterator with no values.
+    return { next: doneResult };
   }
-  var length = buffer.length,
-      result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
-
-  buffer.copy(result);
-  return result;
-}
-
-module.exports = cloneBuffer;
+  exports.values = values;
 
+  function doneResult() {
+    return { value: undefined, done: true };
+  }
 
-/***/ }),
-/* 571 */
-/***/ ((module) => {
+  Context.prototype = {
+    constructor: Context,
 
-/**
- * Copies the values of `source` to `array`.
- *
- * @private
- * @param {Array} source The array to copy values from.
- * @param {Array} [array=[]] The array to copy values to.
- * @returns {Array} Returns `array`.
- */
-function copyArray(source, array) {
-  var index = -1,
-      length = source.length;
+    reset: function(skipTempReset) {
+      this.prev = 0;
+      this.next = 0;
+      // Resetting context._sent for legacy support of Babel's
+      // function.sent implementation.
+      this.sent = this._sent = undefined;
+      this.done = false;
+      this.delegate = null;
 
-  array || (array = Array(length));
-  while (++index < length) {
-    array[index] = source[index];
-  }
-  return array;
-}
+      this.method = "next";
+      this.arg = undefined;
 
-module.exports = copyArray;
+      this.tryEntries.forEach(resetTryEntry);
 
+      if (!skipTempReset) {
+        for (var name in this) {
+          // Not sure about the optimal order of these conditions:
+          if (name.charAt(0) === "t" &&
+              hasOwn.call(this, name) &&
+              !isNaN(+name.slice(1))) {
+            this[name] = undefined;
+          }
+        }
+      }
+    },
 
-/***/ }),
-/* 572 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    stop: function() {
+      this.done = true;
 
-var copyObject = __webpack_require__(565),
-    getSymbols = __webpack_require__(426);
+      var rootEntry = this.tryEntries[0];
+      var rootRecord = rootEntry.completion;
+      if (rootRecord.type === "throw") {
+        throw rootRecord.arg;
+      }
 
-/**
- * Copies own symbols of `source` to `object`.
- *
- * @private
- * @param {Object} source The object to copy symbols from.
- * @param {Object} [object={}] The object to copy symbols to.
- * @returns {Object} Returns `object`.
- */
-function copySymbols(source, object) {
-  return copyObject(source, getSymbols(source), object);
-}
+      return this.rval;
+    },
 
-module.exports = copySymbols;
+    dispatchException: function(exception) {
+      if (this.done) {
+        throw exception;
+      }
 
+      var context = this;
+      function handle(loc, caught) {
+        record.type = "throw";
+        record.arg = exception;
+        context.next = loc;
 
-/***/ }),
-/* 573 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+        if (caught) {
+          // If the dispatched exception was caught by a catch block,
+          // then let that catch block handle the exception normally.
+          context.method = "next";
+          context.arg = undefined;
+        }
 
-var copyObject = __webpack_require__(565),
-    getSymbolsIn = __webpack_require__(574);
+        return !! caught;
+      }
 
-/**
- * Copies own and inherited symbols of `source` to `object`.
- *
- * @private
- * @param {Object} source The object to copy symbols from.
- * @param {Object} [object={}] The object to copy symbols to.
- * @returns {Object} Returns `object`.
- */
-function copySymbolsIn(source, object) {
-  return copyObject(source, getSymbolsIn(source), object);
-}
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        var record = entry.completion;
 
-module.exports = copySymbolsIn;
+        if (entry.tryLoc === "root") {
+          // Exception thrown outside of any try block that could handle
+          // it, so set the completion value of the entire function to
+          // throw the exception.
+          return handle("end");
+        }
 
+        if (entry.tryLoc <= this.prev) {
+          var hasCatch = hasOwn.call(entry, "catchLoc");
+          var hasFinally = hasOwn.call(entry, "finallyLoc");
 
-/***/ }),
-/* 574 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+          if (hasCatch && hasFinally) {
+            if (this.prev < entry.catchLoc) {
+              return handle(entry.catchLoc, true);
+            } else if (this.prev < entry.finallyLoc) {
+              return handle(entry.finallyLoc);
+            }
 
-var arrayPush = __webpack_require__(425),
-    getPrototype = __webpack_require__(575),
-    getSymbols = __webpack_require__(426),
-    stubArray = __webpack_require__(428);
+          } else if (hasCatch) {
+            if (this.prev < entry.catchLoc) {
+              return handle(entry.catchLoc, true);
+            }
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeGetSymbols = Object.getOwnPropertySymbols;
+          } else if (hasFinally) {
+            if (this.prev < entry.finallyLoc) {
+              return handle(entry.finallyLoc);
+            }
 
-/**
- * Creates an array of the own and inherited enumerable symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of symbols.
- */
-var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
-  var result = [];
-  while (object) {
-    arrayPush(result, getSymbols(object));
-    object = getPrototype(object);
-  }
-  return result;
-};
+          } else {
+            throw new Error("try statement without catch or finally");
+          }
+        }
+      }
+    },
 
-module.exports = getSymbolsIn;
+    abrupt: function(type, arg) {
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        if (entry.tryLoc <= this.prev &&
+            hasOwn.call(entry, "finallyLoc") &&
+            this.prev < entry.finallyLoc) {
+          var finallyEntry = entry;
+          break;
+        }
+      }
 
+      if (finallyEntry &&
+          (type === "break" ||
+           type === "continue") &&
+          finallyEntry.tryLoc <= arg &&
+          arg <= finallyEntry.finallyLoc) {
+        // Ignore the finally entry if control is not jumping to a
+        // location outside the try/catch block.
+        finallyEntry = null;
+      }
 
-/***/ }),
-/* 575 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      var record = finallyEntry ? finallyEntry.completion : {};
+      record.type = type;
+      record.arg = arg;
 
-var overArg = __webpack_require__(445);
+      if (finallyEntry) {
+        this.method = "next";
+        this.next = finallyEntry.finallyLoc;
+        return ContinueSentinel;
+      }
 
-/** Built-in value references. */
-var getPrototype = overArg(Object.getPrototypeOf, Object);
+      return this.complete(record);
+    },
 
-module.exports = getPrototype;
+    complete: function(record, afterLoc) {
+      if (record.type === "throw") {
+        throw record.arg;
+      }
 
+      if (record.type === "break" ||
+          record.type === "continue") {
+        this.next = record.arg;
+      } else if (record.type === "return") {
+        this.rval = this.arg = record.arg;
+        this.method = "return";
+        this.next = "end";
+      } else if (record.type === "normal" && afterLoc) {
+        this.next = afterLoc;
+      }
 
-/***/ }),
-/* 576 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      return ContinueSentinel;
+    },
 
-var baseGetAllKeys = __webpack_require__(424),
-    getSymbolsIn = __webpack_require__(574),
-    keysIn = __webpack_require__(567);
+    finish: function(finallyLoc) {
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        if (entry.finallyLoc === finallyLoc) {
+          this.complete(entry.completion, entry.afterLoc);
+          resetTryEntry(entry);
+          return ContinueSentinel;
+        }
+      }
+    },
 
-/**
- * Creates an array of own and inherited enumerable property names and
- * symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names and symbols.
- */
-function getAllKeysIn(object) {
-  return baseGetAllKeys(object, keysIn, getSymbolsIn);
-}
+    "catch": function(tryLoc) {
+      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+        var entry = this.tryEntries[i];
+        if (entry.tryLoc === tryLoc) {
+          var record = entry.completion;
+          if (record.type === "throw") {
+            var thrown = record.arg;
+            resetTryEntry(entry);
+          }
+          return thrown;
+        }
+      }
 
-module.exports = getAllKeysIn;
+      // The context.catch method must only be called with a location
+      // argument that corresponds to a known catch block.
+      throw new Error("illegal catch attempt");
+    },
 
+    delegateYield: function(iterable, resultName, nextLoc) {
+      this.delegate = {
+        iterator: values(iterable),
+        resultName: resultName,
+        nextLoc: nextLoc
+      };
 
-/***/ }),
-/* 577 */
-/***/ ((module) => {
+      if (this.method === "next") {
+        // Deliberately forget the last sent value so that we don't
+        // accidentally pass it on to the delegate.
+        this.arg = undefined;
+      }
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+      return ContinueSentinel;
+    }
+  };
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+  // Regardless of whether this script is executing as a CommonJS module
+  // or not, return the runtime object so that we can declare the variable
+  // regeneratorRuntime in the outer scope, which allows this module to be
+  // injected easily by `bin/regenerator --include-runtime script.js`.
+  return exports;
 
-/**
- * Initializes an array clone.
- *
- * @private
- * @param {Array} array The array to clone.
- * @returns {Array} Returns the initialized clone.
- */
-function initCloneArray(array) {
-  var length = array.length,
-      result = new array.constructor(length);
+}(
+  // If this script is executing as a CommonJS module, use module.exports
+  // as the regeneratorRuntime namespace. Otherwise create a new empty
+  // object. Either way, the resulting object will be used to initialize
+  // the regeneratorRuntime variable at the top of this file.
+   true ? module.exports : 0
+));
 
-  // Add properties assigned by `RegExp#exec`.
-  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
-    result.index = array.index;
-    result.input = array.input;
+try {
+  regeneratorRuntime = runtime;
+} catch (accidentalStrictMode) {
+  // This module should not be running in strict mode, so the above
+  // assignment should always work unless something is misconfigured. Just
+  // in case runtime.js accidentally runs in strict mode, in modern engines
+  // we can explicitly access globalThis. In older engines we can escape
+  // strict mode using a global Function call. This could conceivably fail
+  // if a Content Security Policy forbids using Function, but in that case
+  // the proper solution is to fix the accidental strict mode problem. If
+  // you've misconfigured your bundler to force strict mode and applied a
+  // CSP to forbid Function, and you're not willing to fix either of those
+  // problems, please detail your unique predicament in a GitHub issue.
+  if (typeof globalThis === "object") {
+    globalThis.regeneratorRuntime = runtime;
+  } else {
+    Function("r", "regeneratorRuntime = r")(runtime);
   }
-  return result;
 }
 
-module.exports = initCloneArray;
-
 
 /***/ }),
-/* 578 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 541 */
+/***/ ((module) => {
 
-var cloneArrayBuffer = __webpack_require__(579),
-    cloneDataView = __webpack_require__(580),
-    cloneRegExp = __webpack_require__(581),
-    cloneSymbol = __webpack_require__(582),
-    cloneTypedArray = __webpack_require__(583);
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+  try {
+    var info = gen[key](arg);
+    var value = info.value;
+  } catch (error) {
+    reject(error);
+    return;
+  }
 
-/** `Object#toString` result references. */
-var boolTag = '[object Boolean]',
-    dateTag = '[object Date]',
-    mapTag = '[object Map]',
-    numberTag = '[object Number]',
-    regexpTag = '[object RegExp]',
-    setTag = '[object Set]',
-    stringTag = '[object String]',
-    symbolTag = '[object Symbol]';
+  if (info.done) {
+    resolve(value);
+  } else {
+    Promise.resolve(value).then(_next, _throw);
+  }
+}
 
-var arrayBufferTag = '[object ArrayBuffer]',
-    dataViewTag = '[object DataView]',
-    float32Tag = '[object Float32Array]',
-    float64Tag = '[object Float64Array]',
-    int8Tag = '[object Int8Array]',
-    int16Tag = '[object Int16Array]',
-    int32Tag = '[object Int32Array]',
-    uint8Tag = '[object Uint8Array]',
-    uint8ClampedTag = '[object Uint8ClampedArray]',
-    uint16Tag = '[object Uint16Array]',
-    uint32Tag = '[object Uint32Array]';
+function _asyncToGenerator(fn) {
+  return function () {
+    var self = this,
+        args = arguments;
+    return new Promise(function (resolve, reject) {
+      var gen = fn.apply(self, args);
 
-/**
- * Initializes an object clone based on its `toStringTag`.
- *
- * **Note:** This function only supports cloning values with tags of
- * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
- *
- * @private
- * @param {Object} object The object to clone.
- * @param {string} tag The `toStringTag` of the object to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @returns {Object} Returns the initialized clone.
- */
-function initCloneByTag(object, tag, isDeep) {
-  var Ctor = object.constructor;
-  switch (tag) {
-    case arrayBufferTag:
-      return cloneArrayBuffer(object);
+      function _next(value) {
+        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+      }
 
-    case boolTag:
-    case dateTag:
-      return new Ctor(+object);
+      function _throw(err) {
+        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+      }
 
-    case dataViewTag:
-      return cloneDataView(object, isDeep);
+      _next(undefined);
+    });
+  };
+}
 
-    case float32Tag: case float64Tag:
-    case int8Tag: case int16Tag: case int32Tag:
-    case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
-      return cloneTypedArray(object, isDeep);
+module.exports = _asyncToGenerator;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-    case mapTag:
-      return new Ctor;
+/***/ }),
+/* 542 */
+/***/ ((module) => {
 
-    case numberTag:
-    case stringTag:
-      return new Ctor(object);
+function _classCallCheck(instance, Constructor) {
+  if (!(instance instanceof Constructor)) {
+    throw new TypeError("Cannot call a class as a function");
+  }
+}
 
-    case regexpTag:
-      return cloneRegExp(object);
+module.exports = _classCallCheck;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-    case setTag:
-      return new Ctor;
+/***/ }),
+/* 543 */
+/***/ ((module) => {
 
-    case symbolTag:
-      return cloneSymbol(object);
+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);
   }
 }
 
-module.exports = initCloneByTag;
+function _createClass(Constructor, protoProps, staticProps) {
+  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+  if (staticProps) _defineProperties(Constructor, staticProps);
+  return Constructor;
+}
 
+module.exports = _createClass;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 579 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 544 */
+/***/ ((module) => {
 
-var Uint8Array = __webpack_require__(419);
+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;
+  }
 
-/**
- * Creates a clone of `arrayBuffer`.
- *
- * @private
- * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
- * @returns {ArrayBuffer} Returns the cloned array buffer.
- */
-function cloneArrayBuffer(arrayBuffer) {
-  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
-  new Uint8Array(result).set(new Uint8Array(arrayBuffer));
-  return result;
+  return obj;
 }
 
-module.exports = cloneArrayBuffer;
-
+module.exports = _defineProperty;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 580 */
+/* 545 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var cloneArrayBuffer = __webpack_require__(579);
+var baseAssignValue = __webpack_require__(546),
+    baseForOwn = __webpack_require__(548),
+    baseIteratee = __webpack_require__(413);
 
 /**
- * Creates a clone of `dataView`.
+ * Creates an object with the same keys as `object` and values generated
+ * by running each own enumerable string keyed property of `object` thru
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, key, object).
  *
- * @private
- * @param {Object} dataView The data view to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @returns {Object} Returns the cloned data view.
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new mapped object.
+ * @see _.mapKeys
+ * @example
+ *
+ * var users = {
+ *   'fred':    { 'user': 'fred',    'age': 40 },
+ *   'pebbles': { 'user': 'pebbles', 'age': 1 }
+ * };
+ *
+ * _.mapValues(users, function(o) { return o.age; });
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.mapValues(users, 'age');
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
  */
-function cloneDataView(dataView, isDeep) {
-  var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
-  return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
+function mapValues(object, iteratee) {
+  var result = {};
+  iteratee = baseIteratee(iteratee, 3);
+
+  baseForOwn(object, function(value, key, object) {
+    baseAssignValue(result, key, iteratee(value, key, object));
+  });
+  return result;
 }
 
-module.exports = cloneDataView;
+module.exports = mapValues;
 
 
 /***/ }),
-/* 581 */
-/***/ ((module) => {
+/* 546 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/** Used to match `RegExp` flags from their coerced string values. */
-var reFlags = /\w*$/;
+var defineProperty = __webpack_require__(547);
 
 /**
- * Creates a clone of `regexp`.
+ * The base implementation of `assignValue` and `assignMergeValue` without
+ * value checks.
  *
  * @private
- * @param {Object} regexp The regexp to clone.
- * @returns {Object} Returns the cloned regexp.
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
  */
-function cloneRegExp(regexp) {
-  var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
-  result.lastIndex = regexp.lastIndex;
-  return result;
+function baseAssignValue(object, key, value) {
+  if (key == '__proto__' && defineProperty) {
+    defineProperty(object, key, {
+      'configurable': true,
+      'enumerable': true,
+      'value': value,
+      'writable': true
+    });
+  } else {
+    object[key] = value;
+  }
 }
 
-module.exports = cloneRegExp;
+module.exports = baseAssignValue;
 
 
 /***/ }),
-/* 582 */
+/* 547 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var Symbol = __webpack_require__(47);
-
-/** Used to convert symbols to primitives and strings. */
-var symbolProto = Symbol ? Symbol.prototype : undefined,
-    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
+var getNative = __webpack_require__(383);
 
-/**
- * Creates a clone of the `symbol` object.
- *
- * @private
- * @param {Object} symbol The symbol object to clone.
- * @returns {Object} Returns the cloned symbol object.
- */
-function cloneSymbol(symbol) {
-  return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
-}
+var defineProperty = (function() {
+  try {
+    var func = getNative(Object, 'defineProperty');
+    func({}, '', {});
+    return func;
+  } catch (e) {}
+}());
 
-module.exports = cloneSymbol;
+module.exports = defineProperty;
 
 
 /***/ }),
-/* 583 */
+/* 548 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var cloneArrayBuffer = __webpack_require__(579);
+var baseFor = __webpack_require__(549),
+    keys = __webpack_require__(441);
 
 /**
- * Creates a clone of `typedArray`.
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
  *
  * @private
- * @param {Object} typedArray The typed array to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @returns {Object} Returns the cloned typed array.
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
  */
-function cloneTypedArray(typedArray, isDeep) {
-  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
-  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
+function baseForOwn(object, iteratee) {
+  return object && baseFor(object, iteratee, keys);
 }
 
-module.exports = cloneTypedArray;
+module.exports = baseForOwn;
 
 
 /***/ }),
-/* 584 */
+/* 549 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseCreate = __webpack_require__(585),
-    getPrototype = __webpack_require__(575),
-    isPrototype = __webpack_require__(443);
+var createBaseFor = __webpack_require__(550);
 
 /**
- * Initializes an object clone.
+ * The base implementation of `baseForOwn` which iterates over `object`
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
  *
  * @private
- * @param {Object} object The object to clone.
- * @returns {Object} Returns the initialized clone.
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
  */
-function initCloneObject(object) {
-  return (typeof object.constructor == 'function' && !isPrototype(object))
-    ? baseCreate(getPrototype(object))
-    : {};
-}
+var baseFor = createBaseFor();
 
-module.exports = initCloneObject;
+module.exports = baseFor;
 
 
 /***/ }),
-/* 585 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var isObject = __webpack_require__(52);
-
-/** Built-in value references. */
-var objectCreate = Object.create;
+/* 550 */
+/***/ ((module) => {
 
 /**
- * The base implementation of `_.create` without support for assigning
- * properties to the created object.
+ * Creates a base function for methods like `_.forIn` and `_.forOwn`.
  *
  * @private
- * @param {Object} proto The object to inherit from.
- * @returns {Object} Returns the new object.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
  */
-var baseCreate = (function() {
-  function object() {}
-  return function(proto) {
-    if (!isObject(proto)) {
-      return {};
-    }
-    if (objectCreate) {
-      return objectCreate(proto);
+function createBaseFor(fromRight) {
+  return function(object, iteratee, keysFunc) {
+    var index = -1,
+        iterable = Object(object),
+        props = keysFunc(object),
+        length = props.length;
+
+    while (length--) {
+      var key = props[fromRight ? length : ++index];
+      if (iteratee(iterable[key], key, iterable) === false) {
+        break;
+      }
     }
-    object.prototype = proto;
-    var result = new object;
-    object.prototype = undefined;
-    return result;
+    return object;
   };
-}());
+}
 
-module.exports = baseCreate;
+module.exports = createBaseFor;
 
 
 /***/ }),
-/* 586 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseIsMap = __webpack_require__(587),
-    baseUnary = __webpack_require__(440),
-    nodeUtil = __webpack_require__(441);
-
-/* Node.js helper references. */
-var nodeIsMap = nodeUtil && nodeUtil.isMap;
+/* 551 */
+/***/ ((module) => {
 
 /**
- * Checks if `value` is classified as a `Map` object.
+ * The inverse of `_.toPairs`; this method returns an object composed
+ * from key-value `pairs`.
  *
  * @static
  * @memberOf _
- * @since 4.3.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} pairs The key-value pairs.
+ * @returns {Object} Returns the new object.
  * @example
  *
- * _.isMap(new Map);
- * // => true
- *
- * _.isMap(new WeakMap);
- * // => false
+ * _.fromPairs([['a', 1], ['b', 2]]);
+ * // => { 'a': 1, 'b': 2 }
  */
-var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
-
-module.exports = isMap;
-
-
-/***/ }),
-/* 587 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var getTag = __webpack_require__(447),
-    isObjectLike = __webpack_require__(53);
-
-/** `Object#toString` result references. */
-var mapTag = '[object Map]';
+function fromPairs(pairs) {
+  var index = -1,
+      length = pairs == null ? 0 : pairs.length,
+      result = {};
 
-/**
- * The base implementation of `_.isMap` without Node.js optimizations.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a map, else `false`.
- */
-function baseIsMap(value) {
-  return isObjectLike(value) && getTag(value) == mapTag;
+  while (++index < length) {
+    var pair = pairs[index];
+    result[pair[0]] = pair[1];
+  }
+  return result;
 }
 
-module.exports = baseIsMap;
+module.exports = fromPairs;
 
 
 /***/ }),
-/* 588 */
+/* 552 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIsSet = __webpack_require__(589),
-    baseUnary = __webpack_require__(440),
-    nodeUtil = __webpack_require__(441);
-
-/* Node.js helper references. */
-var nodeIsSet = nodeUtil && nodeUtil.isSet;
+var baseFlatten = __webpack_require__(553);
 
 /**
- * Checks if `value` is classified as a `Set` object.
+ * Flattens `array` a single level deep.
  *
  * @static
  * @memberOf _
- * @since 4.3.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
  * @example
  *
- * _.isSet(new Set);
- * // => true
- *
- * _.isSet(new WeakSet);
- * // => false
- */
-var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
-
-module.exports = isSet;
-
-
-/***/ }),
-/* 589 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var getTag = __webpack_require__(447),
-    isObjectLike = __webpack_require__(53);
-
-/** `Object#toString` result references. */
-var setTag = '[object Set]';
-
-/**
- * The base implementation of `_.isSet` without Node.js optimizations.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ * _.flatten([1, [2, [3, [4]], 5]]);
+ * // => [1, 2, [3, [4]], 5]
  */
-function baseIsSet(value) {
-  return isObjectLike(value) && getTag(value) == setTag;
+function flatten(array) {
+  var length = array == null ? 0 : array.length;
+  return length ? baseFlatten(array, 1) : [];
 }
 
-module.exports = baseIsSet;
-
-
-/***/ }),
-/* 590 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireWildcard = __webpack_require__(510);
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.normalizeApp = exports.APPS_DOCTYPE = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
-
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
-
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
-
-var _get3 = _interopRequireDefault(__webpack_require__(358));
-
-var _registry = __webpack_require__(596);
-
-var _Collection = _interopRequireDefault(__webpack_require__(600));
-
-var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601));
-
-var _errors = __webpack_require__(651);
-
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
-
-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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
-
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
-
-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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
-
-var APPS_DOCTYPE = 'io.cozy.apps';
-exports.APPS_DOCTYPE = APPS_DOCTYPE;
-
-var normalizeApp = function normalizeApp(app, doctype) {
-  return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, app.attributes), app), (0, _DocumentCollection2.normalizeDoc)(app, doctype)), {}, {
-    id: app.id // ignores any 'id' attribute in the manifest
-
-  });
-};
-/**
- * Extends `DocumentCollection` API along with specific methods for `io.cozy.apps`.
- */
-
-
-exports.normalizeApp = normalizeApp;
-
-var AppCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(AppCollection, _DocumentCollection);
-
-  var _super = _createSuper(AppCollection);
-
-  function AppCollection(stackClient) {
-    var _this;
-
-    (0, _classCallCheck2.default)(this, AppCollection);
-    _this = _super.call(this, APPS_DOCTYPE, stackClient);
-    _this.endpoint = '/apps/';
-    return _this;
-  }
-
-  (0, _createClass2.default)(AppCollection, [{
-    key: "get",
-    value: function () {
-      var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(idArg, query) {
-        var _this2 = this;
-
-        var id, sources, dataFetchers, _iterator, _step, source, res, data, normalizedDoc;
-
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                if (idArg.indexOf('/') > -1) {
-                  id = idArg.split('/')[1];
-                } else {
-                  console.warn("Deprecated: in next versions of cozy-client, it will not be possible to query apps/konnectors only with id, please use the form ".concat(this.doctype, "/").concat(idArg, "\n\n- Q('io.cozy.apps').getById('banks')\n+ Q('io.cozy.apps').getById('io.cozy.apps/banks')"));
-                  id = idArg;
-                }
-
-                if (!(query && query.sources && (!Array.isArray(query.sources) || query.sources.length === 0))) {
-                  _context.next = 3;
-                  break;
-                }
-
-                throw new Error('Invalid "sources" attribute passed in query, please use an array with at least one element.');
-
-              case 3:
-                sources = (0, _get3.default)(query, 'sources', ['stack']);
-                dataFetchers = {
-                  stack: function stack() {
-                    return _Collection.default.get(_this2.stackClient, "".concat(_this2.endpoint).concat(encodeURIComponent(id)), {
-                      normalize: _this2.constructor.normalizeDoctype(_this2.doctype)
-                    });
-                  },
-                  registry: function registry() {
-                    return _this2.stackClient.fetchJSON('GET', _registry.registryEndpoint + id);
-                  }
-                };
-                _iterator = _createForOfIteratorHelper(sources);
-                _context.prev = 6;
-
-                _iterator.s();
-
-              case 8:
-                if ((_step = _iterator.n()).done) {
-                  _context.next = 27;
-                  break;
-                }
-
-                source = _step.value;
-                _context.prev = 10;
-                _context.next = 13;
-                return dataFetchers[source]();
-
-              case 13:
-                res = _context.sent;
-
-                if (!(source !== 'registry')) {
-                  _context.next = 16;
-                  break;
-                }
-
-                return _context.abrupt("return", res);
-
-              case 16:
-                data = (0, _registry.transformRegistryFormatToStackFormat)(res);
-                normalizedDoc = (0, _DocumentCollection2.normalizeDoc)(data, this.doctype);
-                return _context.abrupt("return", {
-                  data: normalizedDoc
-                });
-
-              case 21:
-                _context.prev = 21;
-                _context.t0 = _context["catch"](10);
-
-                if (!(source === sources[sources.length - 1])) {
-                  _context.next = 25;
-                  break;
-                }
-
-                throw _context.t0;
-
-              case 25:
-                _context.next = 8;
-                break;
-
-              case 27:
-                _context.next = 32;
-                break;
-
-              case 29:
-                _context.prev = 29;
-                _context.t1 = _context["catch"](6);
-
-                _iterator.e(_context.t1);
-
-              case 32:
-                _context.prev = 32;
-
-                _iterator.f();
-
-                return _context.finish(32);
-
-              case 35:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this, [[6, 29, 32, 35], [10, 21]]);
-      }));
-
-      function get(_x, _x2) {
-        return _get2.apply(this, arguments);
-      }
-
-      return get;
-    }()
-    /**
-     * Lists all apps, without filters.
-     *
-     * The returned documents are not paginated by the stack.
-     *
-     * @returns {{data, meta, skip, next}} The JSON API conformant response.
-     * @throws {FetchError}
-     */
-
-  }, {
-    key: "all",
-    value: function () {
-      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-        var _this3 = this;
-
-        var resp;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                _context2.next = 2;
-                return this.stackClient.fetchJSON('GET', this.endpoint);
+module.exports = flatten;
 
-              case 2:
-                resp = _context2.sent;
-                return _context2.abrupt("return", {
-                  data: resp.data.map(function (app) {
-                    return normalizeApp(app, _this3.doctype);
-                  }),
-                  meta: {
-                    count: resp.meta.count
-                  },
-                  skip: 0,
-                  next: false
-                });
 
-              case 4:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this);
-      }));
+/***/ }),
+/* 553 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function all() {
-        return _all.apply(this, arguments);
-      }
+var arrayPush = __webpack_require__(437),
+    isFlattenable = __webpack_require__(554);
 
-      return all;
-    }()
-  }, {
-    key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                throw new Error('create() method is not available for applications');
+/**
+ * The base implementation of `_.flatten` with support for restricting flattening.
+ *
+ * @private
+ * @param {Array} array The array to flatten.
+ * @param {number} depth The maximum recursion depth.
+ * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
+ * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
+ * @param {Array} [result=[]] The initial result value.
+ * @returns {Array} Returns the new flattened array.
+ */
+function baseFlatten(array, depth, predicate, isStrict, result) {
+  var index = -1,
+      length = array.length;
 
-              case 1:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3);
-      }));
+  predicate || (predicate = isFlattenable);
+  result || (result = []);
 
-      function create() {
-        return _create.apply(this, arguments);
+  while (++index < length) {
+    var value = array[index];
+    if (depth > 0 && predicate(value)) {
+      if (depth > 1) {
+        // Recursively flatten arrays (susceptible to call stack limits).
+        baseFlatten(value, depth - 1, predicate, isStrict, result);
+      } else {
+        arrayPush(result, value);
       }
+    } else if (!isStrict) {
+      result[result.length] = value;
+    }
+  }
+  return result;
+}
 
-      return create;
-    }()
-  }, {
-    key: "update",
-    value: function () {
-      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                throw new Error('update() method is not available for applications');
+module.exports = baseFlatten;
 
-              case 1:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4);
-      }));
 
-      function update() {
-        return _update.apply(this, arguments);
-      }
+/***/ }),
+/* 554 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return update;
-    }()
-  }, {
-    key: "destroy",
-    value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
-        return _regenerator.default.wrap(function _callee5$(_context5) {
-          while (1) {
-            switch (_context5.prev = _context5.next) {
-              case 0:
-                throw new Error('destroy() method is not available for applications');
+var Symbol = __webpack_require__(47),
+    isArguments = __webpack_require__(444),
+    isArray = __webpack_require__(55);
 
-              case 1:
-              case "end":
-                return _context5.stop();
-            }
-          }
-        }, _callee5);
-      }));
+/** Built-in value references. */
+var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
 
-      function destroy() {
-        return _destroy.apply(this, arguments);
-      }
+/**
+ * Checks if `value` is a flattenable `arguments` object or array.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+ */
+function isFlattenable(value) {
+  return isArray(value) || isArguments(value) ||
+    !!(spreadableSymbol && value && value[spreadableSymbol]);
+}
 
-      return destroy;
-    }()
-  }]);
-  return AppCollection;
-}(_DocumentCollection2.default);
+module.exports = isFlattenable;
 
-AppCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
-var _default = AppCollection;
-exports["default"] = _default;
 
 /***/ }),
-/* 591 */
+/* 555 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var setPrototypeOf = __webpack_require__(592);
+var baseRest = __webpack_require__(556),
+    unzip = __webpack_require__(563);
 
-function _inherits(subClass, superClass) {
-  if (typeof superClass !== "function" && superClass !== null) {
-    throw new TypeError("Super expression must either be null or a function");
-  }
+/**
+ * Creates an array of grouped elements, the first of which contains the
+ * first elements of the given arrays, the second of which contains the
+ * second elements of the given arrays, and so on.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zip(['a', 'b'], [1, 2], [true, false]);
+ * // => [['a', 1, true], ['b', 2, false]]
+ */
+var zip = baseRest(unzip);
 
-  subClass.prototype = Object.create(superClass && superClass.prototype, {
-    constructor: {
-      value: subClass,
-      writable: true,
-      configurable: true
-    }
-  });
-  if (superClass) setPrototypeOf(subClass, superClass);
-}
+module.exports = zip;
 
-module.exports = _inherits;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 592 */
-/***/ ((module) => {
+/* 556 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _setPrototypeOf(o, p) {
-  module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
-    o.__proto__ = p;
-    return o;
-  };
+var identity = __webpack_require__(471),
+    overRest = __webpack_require__(557),
+    setToString = __webpack_require__(559);
 
-  module.exports["default"] = module.exports, module.exports.__esModule = true;
-  return _setPrototypeOf(o, p);
+/**
+ * The base implementation of `_.rest` which doesn't validate or coerce arguments.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ */
+function baseRest(func, start) {
+  return setToString(overRest(func, start, identity), func + '');
 }
 
-module.exports = _setPrototypeOf;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+module.exports = baseRest;
+
 
 /***/ }),
-/* 593 */
+/* 557 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _typeof = (__webpack_require__(511)["default"]);
+var apply = __webpack_require__(558);
 
-var assertThisInitialized = __webpack_require__(594);
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
 
-function _possibleConstructorReturn(self, call) {
-  if (call && (_typeof(call) === "object" || typeof call === "function")) {
-    return call;
-  } else if (call !== void 0) {
-    throw new TypeError("Derived constructors may only return object or undefined");
-  }
+/**
+ * A specialized version of `baseRest` which transforms the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @param {Function} transform The rest array transform.
+ * @returns {Function} Returns the new function.
+ */
+function overRest(func, start, transform) {
+  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
+  return function() {
+    var args = arguments,
+        index = -1,
+        length = nativeMax(args.length - start, 0),
+        array = Array(length);
 
-  return assertThisInitialized(self);
+    while (++index < length) {
+      array[index] = args[start + index];
+    }
+    index = -1;
+    var otherArgs = Array(start + 1);
+    while (++index < start) {
+      otherArgs[index] = args[index];
+    }
+    otherArgs[start] = transform(array);
+    return apply(func, this, otherArgs);
+  };
 }
 
-module.exports = _possibleConstructorReturn;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+module.exports = overRest;
+
 
 /***/ }),
-/* 594 */
+/* 558 */
 /***/ ((module) => {
 
-function _assertThisInitialized(self) {
-  if (self === void 0) {
-    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+/**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} args The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+function apply(func, thisArg, args) {
+  switch (args.length) {
+    case 0: return func.call(thisArg);
+    case 1: return func.call(thisArg, args[0]);
+    case 2: return func.call(thisArg, args[0], args[1]);
+    case 3: return func.call(thisArg, args[0], args[1], args[2]);
   }
-
-  return self;
+  return func.apply(thisArg, args);
 }
 
-module.exports = _assertThisInitialized;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+module.exports = apply;
+
 
 /***/ }),
-/* 595 */
-/***/ ((module) => {
+/* 559 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _getPrototypeOf(o) {
-  module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
-    return o.__proto__ || Object.getPrototypeOf(o);
-  };
-  module.exports["default"] = module.exports, module.exports.__esModule = true;
-  return _getPrototypeOf(o);
-}
+var baseSetToString = __webpack_require__(560),
+    shortOut = __webpack_require__(562);
 
-module.exports = _getPrototypeOf;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+/**
+ * Sets the `toString` method of `func` to return `string`.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */
+var setToString = shortOut(baseSetToString);
 
-/***/ }),
-/* 596 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+module.exports = setToString;
 
-"use strict";
 
+/***/ }),
+/* 560 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _interopRequireDefault = __webpack_require__(512);
+var constant = __webpack_require__(561),
+    defineProperty = __webpack_require__(547),
+    identity = __webpack_require__(471);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.registryEndpoint = exports.transformRegistryFormatToStackFormat = void 0;
+/**
+ * The base implementation of `setToString` without support for hot loop shorting.
+ *
+ * @private
+ * @param {Function} func The function to modify.
+ * @param {Function} string The `toString` result.
+ * @returns {Function} Returns `func`.
+ */
+var baseSetToString = !defineProperty ? identity : function(func, string) {
+  return defineProperty(func, 'toString', {
+    'configurable': true,
+    'enumerable': false,
+    'value': constant(string),
+    'writable': true
+  });
+};
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+module.exports = baseSetToString;
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+/***/ }),
+/* 561 */
+/***/ ((module) => {
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+/**
+ * Creates a function that returns `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 2.4.0
+ * @category Util
+ * @param {*} value The value to return from the new function.
+ * @returns {Function} Returns the new constant function.
+ * @example
+ *
+ * var objects = _.times(2, _.constant({ 'a': 1 }));
+ *
+ * console.log(objects);
+ * // => [{ 'a': 1 }, { 'a': 1 }]
+ *
+ * console.log(objects[0] === objects[1]);
+ * // => true
+ */
+function constant(value) {
+  return function() {
+    return value;
+  };
+}
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+module.exports = constant;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
 
-__webpack_require__(597);
+/***/ }),
+/* 562 */
+/***/ ((module) => {
 
-var _terms = _interopRequireDefault(__webpack_require__(598));
+/** Used to detect hot functions by number of calls within a span of milliseconds. */
+var HOT_COUNT = 800,
+    HOT_SPAN = 16;
 
-var _constants = __webpack_require__(599);
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeNow = Date.now;
 
-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; }
+/**
+ * Creates a function that'll short out and invoke `identity` instead
+ * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
+ * milliseconds.
+ *
+ * @private
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new shortable function.
+ */
+function shortOut(func) {
+  var count = 0,
+      lastCalled = 0;
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  return function() {
+    var stamp = nativeNow(),
+        remaining = HOT_SPAN - (stamp - lastCalled);
 
-var transformRegistryFormatToStackFormat = function transformRegistryFormatToStackFormat(doc) {
-  return _objectSpread({
-    id: (0, _get.default)(doc, 'latest_version.manifest.source'),
-    attributes: (0, _get.default)(doc, 'latest_version.manifest')
-  }, doc);
-};
+    lastCalled = stamp;
+    if (remaining > 0) {
+      if (++count >= HOT_COUNT) {
+        return arguments[0];
+      }
+    } else {
+      count = 0;
+    }
+    return func.apply(undefined, arguments);
+  };
+}
 
-exports.transformRegistryFormatToStackFormat = transformRegistryFormatToStackFormat;
-var registryEndpoint = '/registry/';
-exports.registryEndpoint = registryEndpoint;
+module.exports = shortOut;
 
-var queryPartFromOptions = function queryPartFromOptions(options) {
-  var query = new URLSearchParams(options).toString();
-  return query ? "?".concat(query) : '';
-};
 
-var getBaseRoute = function getBaseRoute(app) {
-  var type = app.type; // TODO node is an historic type, it should be `konnector`, check with the back
+/***/ }),
+/* 563 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var route = type === _constants.APP_TYPE.KONNECTOR || type === 'node' ? 'konnectors' : 'apps';
-  return "/".concat(route);
-};
-/**
- * @typedef {object} RegistryApp
- * @property {string} slug
- * @property {object} terms
- * @property {boolean} installed
- */
+var arrayFilter = __webpack_require__(439),
+    arrayMap = __webpack_require__(410),
+    baseProperty = __webpack_require__(473),
+    baseTimes = __webpack_require__(443),
+    isArrayLikeObject = __webpack_require__(564);
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
 
 /**
- * @typedef {"dev"|"beta"|"stable"} RegistryAppChannel
+ * This method is like `_.zip` except that it accepts an array of grouped
+ * elements and creates an array regrouping the elements to their pre-zip
+ * configuration.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.2.0
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
+ * // => [['a', 1, true], ['b', 2, false]]
+ *
+ * _.unzip(zipped);
+ * // => [['a', 'b'], [1, 2], [true, false]]
  */
+function unzip(array) {
+  if (!(array && array.length)) {
+    return [];
+  }
+  var length = 0;
+  array = arrayFilter(array, function(group) {
+    if (isArrayLikeObject(group)) {
+      length = nativeMax(group.length, length);
+      return true;
+    }
+  });
+  return baseTimes(length, function(index) {
+    return arrayMap(array, baseProperty(index));
+  });
+}
 
+module.exports = unzip;
 
-var Registry = /*#__PURE__*/function () {
-  function Registry(options) {
-    (0, _classCallCheck2.default)(this, Registry);
 
-    if (!options.client) {
-      throw new Error('Need to pass a client to instantiate a Registry API.');
-    }
+/***/ }),
+/* 564 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    this.client = options.client;
-  }
-  /**
-   * Installs or updates an app from a source.
-   *
-   * Accepts the terms if the app has them.
-   *
-   * @param  {RegistryApp} app - App to be installed
-   * @param  {string} source - String (ex: registry://drive/stable)
-   * @returns {Promise}
-   */
+var isArrayLike = __webpack_require__(458),
+    isObjectLike = __webpack_require__(53);
 
+/**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object,
+ *  else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+function isArrayLikeObject(value) {
+  return isObjectLike(value) && isArrayLike(value);
+}
 
-  (0, _createClass2.default)(Registry, [{
-    key: "installApp",
-    value: function () {
-      var _installApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, source) {
-        var slug, terms, searchParams, isUpdate, querypart, verb, baseRoute;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                slug = app.slug, terms = app.terms;
-                searchParams = {};
-                isUpdate = app.installed;
-                if (isUpdate) searchParams.PermissionsAcked = isUpdate;
-                if (source) searchParams.Source = source;
-                querypart = queryPartFromOptions(searchParams);
+module.exports = isArrayLikeObject;
 
-                if (!terms) {
-                  _context.next = 9;
-                  break;
-                }
 
-                _context.next = 9;
-                return _terms.default.save(this.client, terms);
+/***/ }),
+/* 565 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 9:
-                verb = app.installed ? 'PUT' : 'POST';
-                baseRoute = getBaseRoute(app);
-                return _context.abrupt("return", this.client.stackClient.fetchJSON(verb, "".concat(baseRoute, "/").concat(slug).concat(querypart)));
+var arrayEach = __webpack_require__(566),
+    baseEach = __webpack_require__(567),
+    castFunction = __webpack_require__(569),
+    isArray = __webpack_require__(55);
 
-              case 12:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
+/**
+ * Iterates over elements of `collection` and invokes `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length"
+ * property are iterated like arrays. To avoid this behavior use `_.forIn`
+ * or `_.forOwn` for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @see _.forEachRight
+ * @example
+ *
+ * _.forEach([1, 2], function(value) {
+ *   console.log(value);
+ * });
+ * // => Logs `1` then `2`.
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ *   console.log(key);
+ * });
+ * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ */
+function forEach(collection, iteratee) {
+  var func = isArray(collection) ? arrayEach : baseEach;
+  return func(collection, castFunction(iteratee));
+}
 
-      function installApp(_x, _x2) {
-        return _installApp.apply(this, arguments);
-      }
+module.exports = forEach;
 
-      return installApp;
-    }()
-    /**
-     * Uninstalls an app.
-     */
 
-  }, {
-    key: "uninstallApp",
-    value: function () {
-      var _uninstallApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(app) {
-        var slug, baseRoute;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                slug = app.slug;
-                baseRoute = getBaseRoute(app);
-                return _context2.abrupt("return", this.client.stackClient.fetchJSON('DELETE', "".concat(baseRoute, "/").concat(slug)));
+/***/ }),
+/* 566 */
+/***/ ((module) => {
 
-              case 3:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this);
-      }));
+/**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+function arrayEach(array, iteratee) {
+  var index = -1,
+      length = array == null ? 0 : array.length;
 
-      function uninstallApp(_x3) {
-        return _uninstallApp.apply(this, arguments);
-      }
+  while (++index < length) {
+    if (iteratee(array[index], index, array) === false) {
+      break;
+    }
+  }
+  return array;
+}
 
-      return uninstallApp;
-    }()
-    /**
-     * Fetch at most 200 apps from the channel
-     *
-     * @param  {object} params - Fetching parameters
-     * @param  {string} params.type - "webapp" or "konnector"
-     * @param  {RegistryAppChannel} params.channel - The channel of the apps to fetch
-     * @param  {string} params.limit - maximum number of fetched apps - defaults to 200
-     *
-     * @returns {Promise<Array<RegistryApp>>}
-     */
+module.exports = arrayEach;
 
-  }, {
-    key: "fetchApps",
-    value: function () {
-      var _fetchApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(params) {
-        var channel, type, _params$limit, limit, searchParams, querypart, _yield$this$client$st, apps;
 
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                channel = params.channel, type = params.type, _params$limit = params.limit, limit = _params$limit === void 0 ? '200' : _params$limit;
-                searchParams = {
-                  limit: limit,
-                  versionsChannel: channel,
-                  latestChannelVersion: channel
-                };
-                querypart = new URLSearchParams(searchParams).toString();
+/***/ }),
+/* 567 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                if (type) {
-                  // Unfortunately, URLSearchParams encodes brackets so we have to do
-                  // the querypart handling manually
-                  querypart = querypart + "&filter[type]=".concat(type);
-                }
+var baseForOwn = __webpack_require__(548),
+    createBaseEach = __webpack_require__(568);
 
-                _context3.next = 6;
-                return this.client.stackClient.fetchJSON('GET', "/registry?".concat(querypart));
+/**
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */
+var baseEach = createBaseEach(baseForOwn);
 
-              case 6:
-                _yield$this$client$st = _context3.sent;
-                apps = _yield$this$client$st.data;
-                return _context3.abrupt("return", apps);
+module.exports = baseEach;
 
-              case 9:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this);
-      }));
 
-      function fetchApps(_x4) {
-        return _fetchApps.apply(this, arguments);
-      }
+/***/ }),
+/* 568 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return fetchApps;
-    }()
-    /**
-     * Fetch the list of apps that are in maintenance mode
-     *
-     * @returns {Array<RegistryApp>}
-     */
+var isArrayLike = __webpack_require__(458);
 
-  }, {
-    key: "fetchAppsInMaintenance",
-    value: function fetchAppsInMaintenance() {
-      return this.client.stackClient.fetchJSON('GET', '/registry/maintenance');
+/**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseEach(eachFunc, fromRight) {
+  return function(collection, iteratee) {
+    if (collection == null) {
+      return collection;
     }
-    /**
-     * Fetch the status of a single app on the registry
-     *
-     * @param  {string} slug - The slug of the app to fetch
-     *
-     * @returns {RegistryApp}
-     */
-
-  }, {
-    key: "fetchApp",
-    value: function fetchApp(slug) {
-      return this.client.stackClient.fetchJSON('GET', "/registry/".concat(slug));
+    if (!isArrayLike(collection)) {
+      return eachFunc(collection, iteratee);
     }
-    /**
-     * Fetch the latest version of an app for the given channel and slug
-     *
-     * @param  {object} params - Fetching parameters
-     * @param  {string} params.slug - The slug of the app to fetch
-     * @param  {RegistryAppChannel} params.channel - The channel of the app to fetch
-     * @param  {string} params.version - The version of the app to fetch. Can also be "latest"
-     *
-     * @returns {RegistryApp}
-     */
-
-  }, {
-    key: "fetchAppVersion",
-    value: function fetchAppVersion(params) {
-      if (!params.slug) {
-        throw new Error('Need to pass a slug to use fetchAppVersion');
-      }
-
-      var slug = params.slug,
-          channel = params.channel,
-          version = params.version;
-      var finalChannel = !channel && (!version || version === 'latest') ? 'stable' : channel;
-      var url = "/registry/".concat(slug, "/");
+    var length = collection.length,
+        index = fromRight ? length : -1,
+        iterable = Object(collection);
 
-      if (finalChannel) {
-        url += "".concat(finalChannel, "/").concat(version || 'latest');
-      } else {
-        url += "".concat(version);
+    while ((fromRight ? index-- : ++index < length)) {
+      if (iteratee(iterable[index], index, iterable) === false) {
+        break;
       }
-
-      return this.client.stackClient.fetchJSON('GET', url);
     }
-  }]);
-  return Registry;
-}();
+    return collection;
+  };
+}
+
+module.exports = createBaseEach;
 
-var _default = Registry;
-exports["default"] = _default;
 
 /***/ }),
-/* 597 */
-/***/ (function() {
+/* 569 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var identity = __webpack_require__(471);
 
 /**
+ * Casts `value` to `identity` if it's not a function.
  *
- *
- * @author Jerry Bendy <jerry@icewingcc.com>
- * @licence MIT
- *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Function} Returns cast function.
  */
+function castFunction(value) {
+  return typeof value == 'function' ? value : identity;
+}
 
-(function(self) {
-    'use strict';
+module.exports = castFunction;
 
-    var nativeURLSearchParams = (function() {
-            // #41 Fix issue in RN
-            try {
-                if (self.URLSearchParams && (new self.URLSearchParams('foo=bar')).get('foo') === 'bar') {
-                    return self.URLSearchParams;
-                }
-            } catch (e) {}
-            return null;
-        })(),
-        isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1',
-        // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus.
-        decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'),
-        __URLSearchParams__ = "__URLSearchParams__",
-        // Fix bug in Edge which cannot encode ' &' correctly
-        encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() {
-            var ampersandTest = new nativeURLSearchParams();
-            ampersandTest.append('s', ' &');
-            return ampersandTest.toString() === 's=+%26';
-        })() : true,
-        prototype = URLSearchParamsPolyfill.prototype,
-        iterable = !!(self.Symbol && self.Symbol.iterator);
 
-    if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) {
-        return;
+/***/ }),
+/* 570 */
+/***/ ((module) => {
+
+function M() { this._events = {}; }
+M.prototype = {
+  on: function(ev, cb) {
+    this._events || (this._events = {});
+    var e = this._events;
+    (e[ev] || (e[ev] = [])).push(cb);
+    return this;
+  },
+  removeListener: function(ev, cb) {
+    var e = this._events[ev] || [], i;
+    for(i = e.length-1; i >= 0 && e[i]; i--){
+      if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); }
+    }
+  },
+  removeAllListeners: function(ev) {
+    if(!ev) { this._events = {}; }
+    else { this._events[ev] && (this._events[ev] = []); }
+  },
+  listeners: function(ev) {
+    return (this._events ? this._events[ev] || [] : []);
+  },
+  emit: function(ev) {
+    this._events || (this._events = {});
+    var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || [];
+    for(i = e.length-1; i >= 0 && e[i]; i--){
+      e[i].apply(this, args);
+    }
+    return this;
+  },
+  when: function(ev, cb) {
+    return this.once(ev, cb, true);
+  },
+  once: function(ev, cb, when) {
+    if(!cb) return this;
+    function c() {
+      if(!when) this.removeListener(ev, c);
+      if(cb.apply(this, arguments) && when) this.removeListener(ev, c);
     }
+    c.cb = cb;
+    this.on(ev, c);
+    return this;
+  }
+};
+M.mixin = function(dest) {
+  var o = M.prototype, k;
+  for (k in o) {
+    o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
+  }
+};
+module.exports = M;
 
 
-    /**
-     * Make a URLSearchParams instance
-     *
-     * @param {object|string|URLSearchParams} search
-     * @constructor
-     */
-    function URLSearchParamsPolyfill(search) {
-        search = search || "";
+/***/ }),
+/* 571 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-        // support construct object with another URLSearchParams instance
-        if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) {
-            search = search.toString();
-        }
-        this [__URLSearchParams__] = parseToDict(search);
-    }
+"use strict";
 
 
-    /**
-     * Appends a specified key/value pair as a new search parameter.
-     *
-     * @param {string} name
-     * @param {string} value
-     */
-    prototype.append = function(name, value) {
-        appendTo(this [__URLSearchParams__], name, value);
-    };
+var _interopRequireWildcard = __webpack_require__(522);
 
-    /**
-     * Deletes the given search parameter, and its associated value,
-     * from the list of all search parameters.
-     *
-     * @param {string} name
-     */
-    prototype['delete'] = function(name) {
-        delete this [__URLSearchParams__] [name];
-    };
+var _interopRequireDefault = __webpack_require__(524);
 
-    /**
-     * Returns the first value associated to the given search parameter.
-     *
-     * @param {string} name
-     * @returns {string|null}
-     */
-    prototype.get = function(name) {
-        var dict = this [__URLSearchParams__];
-        return this.has(name) ? dict[name][0] : null;
-    };
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+Object.defineProperty(exports, "default", ({
+  enumerable: true,
+  get: function get() {
+    return _CozyStackClient.default;
+  }
+}));
+Object.defineProperty(exports, "OAuthClient", ({
+  enumerable: true,
+  get: function get() {
+    return _OAuthClient.default;
+  }
+}));
+Object.defineProperty(exports, "errors", ({
+  enumerable: true,
+  get: function get() {
+    return _errors.default;
+  }
+}));
+Object.defineProperty(exports, "FetchError", ({
+  enumerable: true,
+  get: function get() {
+    return _errors.FetchError;
+  }
+}));
+Object.defineProperty(exports, "normalizeDoc", ({
+  enumerable: true,
+  get: function get() {
+    return _DocumentCollection.normalizeDoc;
+  }
+}));
 
-    /**
-     * Returns all the values association with a given search parameter.
-     *
-     * @param {string} name
-     * @returns {Array}
-     */
-    prototype.getAll = function(name) {
-        var dict = this [__URLSearchParams__];
-        return this.has(name) ? dict [name].slice(0) : [];
-    };
+var _CozyStackClient = _interopRequireDefault(__webpack_require__(572));
 
-    /**
-     * Returns a Boolean indicating if such a search parameter exists.
-     *
-     * @param {string} name
-     * @returns {boolean}
-     */
-    prototype.has = function(name) {
-        return hasOwnProperty(this [__URLSearchParams__], name);
-    };
+var _OAuthClient = _interopRequireDefault(__webpack_require__(696));
 
-    /**
-     * Sets the value associated to a given search parameter to
-     * the given value. If there were several values, delete the
-     * others.
-     *
-     * @param {string} name
-     * @param {string} value
-     */
-    prototype.set = function set(name, value) {
-        this [__URLSearchParams__][name] = ['' + value];
-    };
+var _errors = _interopRequireWildcard(__webpack_require__(663));
 
-    /**
-     * Returns a string containg a query string suitable for use in a URL.
-     *
-     * @returns {string}
-     */
-    prototype.toString = function() {
-        var dict = this[__URLSearchParams__], query = [], i, key, name, value;
-        for (key in dict) {
-            name = encode(key);
-            for (i = 0, value = dict[key]; i < value.length; i++) {
-                query.push(name + '=' + encode(value[i]));
-            }
-        }
-        return query.join('&');
-    };
+var _DocumentCollection = __webpack_require__(613);
+
+/***/ }),
+/* 572 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
 
-    // There is a bug in Safari 10.1 and `Proxy`ing it is not enough.
-    var forSureUsePolyfill = !decodesPlusesCorrectly;
-    var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy);
-    var propValue; 
-    if (useProxy) {
-        // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0
-        propValue = new Proxy(nativeURLSearchParams, {
-            construct: function (target, args) {
-                return new target((new URLSearchParamsPolyfill(args[0]).toString()));
-            }
-        })
-        // Chrome <=60 .toString() on a function proxy got error "Function.prototype.toString is not generic"
-        propValue.toString = Function.prototype.toString.bind(URLSearchParamsPolyfill);
-    } else {
-        propValue = URLSearchParamsPolyfill;
-    }
-    /*
-     * Apply polifill to global object and append other prototype into it
-     */
-    Object.defineProperty(self, 'URLSearchParams', {
-        value: propValue
-    });
 
-    var USPProto = self.URLSearchParams.prototype;
+var _interopRequireWildcard = __webpack_require__(522);
 
-    USPProto.polyfill = true;
+var _interopRequireDefault = __webpack_require__(524);
 
-    /**
-     *
-     * @param {function} callback
-     * @param {object} thisArg
-     */
-    USPProto.forEach = USPProto.forEach || function(callback, thisArg) {
-        var dict = parseToDict(this.toString());
-        Object.getOwnPropertyNames(dict).forEach(function(name) {
-            dict[name].forEach(function(value) {
-                callback.call(thisArg, value, name, this);
-            }, this);
-        }, this);
-    };
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-    /**
-     * Sort all name-value pairs
-     */
-    USPProto.sort = USPProto.sort || function() {
-        var dict = parseToDict(this.toString()), keys = [], k, i, j;
-        for (k in dict) {
-            keys.push(k);
-        }
-        keys.sort();
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-        for (i = 0; i < keys.length; i++) {
-            this['delete'](keys[i]);
-        }
-        for (i = 0; i < keys.length; i++) {
-            var key = keys[i], values = dict[key];
-            for (j = 0; j < values.length; j++) {
-                this.append(key, values[j]);
-            }
-        }
-    };
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-    /**
-     * Returns an iterator allowing to go through all keys of
-     * the key/value pairs contained in this object.
-     *
-     * @returns {function}
-     */
-    USPProto.keys = USPProto.keys || function() {
-        var items = [];
-        this.forEach(function(item, name) {
-            items.push(name);
-        });
-        return makeIterator(items);
-    };
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-    /**
-     * Returns an iterator allowing to go through all values of
-     * the key/value pairs contained in this object.
-     *
-     * @returns {function}
-     */
-    USPProto.values = USPProto.values || function() {
-        var items = [];
-        this.forEach(function(item) {
-            items.push(item);
-        });
-        return makeIterator(items);
-    };
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-    /**
-     * Returns an iterator allowing to go through all key/value
-     * pairs contained in this object.
-     *
-     * @returns {function}
-     */
-    USPProto.entries = USPProto.entries || function() {
-        var items = [];
-        this.forEach(function(item, name) {
-            items.push([name, item]);
-        });
-        return makeIterator(items);
-    };
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
+var _cloneDeep = _interopRequireDefault(__webpack_require__(573));
 
-    if (iterable) {
-        USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries;
-    }
+var _AppCollection = _interopRequireWildcard(__webpack_require__(602));
 
+var _AppToken = _interopRequireDefault(__webpack_require__(668));
 
-    function encode(str) {
-        var replace = {
-            '!': '%21',
-            "'": '%27',
-            '(': '%28',
-            ')': '%29',
-            '~': '%7E',
-            '%20': '+',
-            '%00': '\x00'
-        };
-        return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) {
-            return replace[match];
-        });
-    }
+var _AccessToken = _interopRequireDefault(__webpack_require__(669));
 
-    function decode(str) {
-        return str
-            .replace(/[ +]/g, '%20')
-            .replace(/(%[a-f0-9]{2})+/ig, function(match) {
-                return decodeURIComponent(match);
-            });
-    }
+var _DocumentCollection = _interopRequireDefault(__webpack_require__(613));
 
-    function makeIterator(arr) {
-        var iterator = {
-            next: function() {
-                var value = arr.shift();
-                return {done: value === undefined, value: value};
-            }
-        };
+var _FileCollection = _interopRequireDefault(__webpack_require__(670));
 
-        if (iterable) {
-            iterator[self.Symbol.iterator] = function() {
-                return iterator;
-            };
-        }
+var _JobCollection = _interopRequireWildcard(__webpack_require__(679));
 
-        return iterator;
-    }
+var _KonnectorCollection = _interopRequireWildcard(__webpack_require__(680));
 
-    function parseToDict(search) {
-        var dict = {};
+var _SharingCollection = _interopRequireDefault(__webpack_require__(684));
 
-        if (typeof search === "object") {
-            // if `search` is an array, treat it as a sequence
-            if (isArray(search)) {
-                for (var i = 0; i < search.length; i++) {
-                    var item = search[i];
-                    if (isArray(item) && item.length === 2) {
-                        appendTo(dict, item[0], item[1]);
-                    } else {
-                        throw new TypeError("Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements");
-                    }
-                }
+var _PermissionCollection = _interopRequireDefault(__webpack_require__(685));
 
-            } else {
-                for (var key in search) {
-                    if (search.hasOwnProperty(key)) {
-                        appendTo(dict, key, search[key]);
-                    }
-                }
-            }
+var _TriggerCollection = _interopRequireWildcard(__webpack_require__(681));
 
-        } else {
-            // remove first '?'
-            if (search.indexOf("?") === 0) {
-                search = search.slice(1);
-            }
+var _SettingsCollection = _interopRequireWildcard(__webpack_require__(686));
 
-            var pairs = search.split("&");
-            for (var j = 0; j < pairs.length; j++) {
-                var value = pairs [j],
-                    index = value.indexOf('=');
+var _NotesCollection = _interopRequireWildcard(__webpack_require__(687));
 
-                if (-1 < index) {
-                    appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));
+var _OAuthClientsCollection = _interopRequireWildcard(__webpack_require__(689));
 
-                } else {
-                    if (value) {
-                        appendTo(dict, decode(value), '');
-                    }
-                }
-            }
-        }
+var _ShortcutsCollection = _interopRequireWildcard(__webpack_require__(690));
 
-        return dict;
-    }
+var _ContactsCollection = _interopRequireWildcard(__webpack_require__(691));
 
-    function appendTo(dict, name, value) {
-        var val = typeof value === 'string' ? value : (
-            value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value)
-        );
+var _getIconURL2 = _interopRequireDefault(__webpack_require__(692));
 
-        // #47 Prevent using `hasOwnProperty` as a property name
-        if (hasOwnProperty(dict, name)) {
-            dict[name].push(val);
-        } else {
-            dict[name] = [val];
-        }
-    }
+var _logDeprecate = _interopRequireDefault(__webpack_require__(694));
 
-    function isArray(val) {
-        return !!val && '[object Array]' === Object.prototype.toString.call(val);
-    }
+var _errors = _interopRequireWildcard(__webpack_require__(663));
 
-    function hasOwnProperty(obj, prop) {
-        return Object.prototype.hasOwnProperty.call(obj, prop);
-    }
+var _xhrFetch = __webpack_require__(695);
 
-})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this));
+var _microee = _interopRequireDefault(__webpack_require__(570));
 
+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; }
 
-/***/ }),
-/* 598 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-"use strict";
+var normalizeUri = function normalizeUri(uriArg) {
+  var uri = uriArg;
+  if (uri === null) return null;
 
+  while (uri[uri.length - 1] === '/') {
+    uri = uri.slice(0, -1);
+  }
 
-var _interopRequireDefault = __webpack_require__(512);
+  return uri;
+};
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+var isRevocationError = function isRevocationError(err) {
+  return err.message && _errors.default.CLIENT_NOT_FOUND.test(err.message);
+};
+/**
+ * Main API against the `cozy-stack` server.
+ */
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var CozyStackClient = /*#__PURE__*/function () {
+  function CozyStackClient(options) {
+    (0, _classCallCheck2.default)(this, CozyStackClient);
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
+    var opts = _objectSpread({}, options);
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+    var token = opts.token,
+        _opts$uri = opts.uri,
+        uri = _opts$uri === void 0 ? '' : _opts$uri;
+    this.options = opts;
+    this.setUri(uri);
+    this.setToken(token);
+    this.konnectors = new _KonnectorCollection.default(this);
+    this.jobs = new _JobCollection.default(this);
+  }
+  /**
+   * Creates a {@link DocumentCollection} instance.
+   *
+   * @param  {string} doctype The collection doctype.
+   * @returns {DocumentCollection}
+   */
 
-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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  (0, _createClass2.default)(CozyStackClient, [{
+    key: "collection",
+    value: function collection(doctype) {
+      if (!doctype) {
+        throw new Error('CozyStackClient.collection() called without a doctype');
+      }
 
-var TERMS_DOCTYPE = 'io.cozy.terms';
-/* TODO Use collection terms */
+      switch (doctype) {
+        case _AppCollection.APPS_DOCTYPE:
+          return new _AppCollection.default(this);
 
-function save(_x, _x2) {
-  return _save.apply(this, arguments);
-}
+        case _KonnectorCollection.KONNECTORS_DOCTYPE:
+          return new _KonnectorCollection.default(this);
 
-function _save() {
-  _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, terms) {
-    var id, termsAttributes, _yield$client$query, savedTermsDocs, savedTerms, termsToSave, _termsToSave;
+        case 'io.cozy.files':
+          return new _FileCollection.default(doctype, this);
 
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            id = terms.id, termsAttributes = (0, _objectWithoutProperties2.default)(terms, ["id"]);
-            _context.next = 3;
-            return client.query({
-              doctype: TERMS_DOCTYPE,
-              selector: {
-                termsId: id,
-                version: termsAttributes.version
-              },
-              limit: 1
-            });
+        case 'io.cozy.sharings':
+          return new _SharingCollection.default(doctype, this);
 
-          case 3:
-            _yield$client$query = _context.sent;
-            savedTermsDocs = _yield$client$query.data;
+        case 'io.cozy.permissions':
+          return new _PermissionCollection.default(doctype, this);
 
-            if (!(savedTermsDocs && savedTermsDocs.length)) {
-              _context.next = 13;
-              break;
-            }
+        case _ContactsCollection.CONTACTS_DOCTYPE:
+          return new _ContactsCollection.default(doctype, this);
 
-            // we just update the url if this is the same id and same version
-            // but the url changed
-            savedTerms = savedTermsDocs[0];
+        case _TriggerCollection.TRIGGERS_DOCTYPE:
+          return new _TriggerCollection.default(this);
 
-            if (!(savedTerms.termsId == id && savedTerms.version == termsAttributes.version && savedTerms.url != termsAttributes.url)) {
-              _context.next = 11;
-              break;
-            }
+        case _JobCollection.JOBS_DOCTYPE:
+          return new _JobCollection.default(this);
 
-            termsToSave = _objectSpread(_objectSpread({
-              _type: TERMS_DOCTYPE
-            }, savedTerms), {}, {
-              url: termsAttributes.url
-            });
-            _context.next = 11;
-            return client.save(termsToSave);
+        case _SettingsCollection.SETTINGS_DOCTYPE:
+          return new _SettingsCollection.default(this);
 
-          case 11:
-            _context.next = 16;
-            break;
+        case _NotesCollection.NOTES_DOCTYPE:
+          return new _NotesCollection.default(this);
 
-          case 13:
-            _termsToSave = _objectSpread(_objectSpread({
-              _type: TERMS_DOCTYPE
-            }, termsAttributes), {}, {
-              termsId: id,
-              accepted: true,
-              acceptedAt: new Date()
-            });
-            _context.next = 16;
-            return client.save(_termsToSave);
+        case _OAuthClientsCollection.OAUTH_CLIENTS_DOCTYPE:
+          return new _OAuthClientsCollection.default(this);
 
-          case 16:
-          case "end":
-            return _context.stop();
-        }
+        case _ShortcutsCollection.SHORTCUTS_DOCTYPE:
+          return new _ShortcutsCollection.default(this);
+
+        default:
+          return new _DocumentCollection.default(doctype, this);
       }
-    }, _callee);
-  }));
-  return _save.apply(this, arguments);
-}
+    }
+    /**
+     * Fetches an endpoint in an authorized way.
+     *
+     * @param  {string} method The HTTP method.
+     * @param  {string} path The URI.
+     * @param  {object} [body] The payload.
+     * @param  {object} [opts={}] Options for fetch
+     * @returns {object}
+     * @throws {FetchError}
+     */
 
-var _default = {
-  save: save
-};
-exports["default"] = _default;
+  }, {
+    key: "fetch",
+    value: function (_fetch) {
+      function fetch(_x, _x2, _x3) {
+        return _fetch.apply(this, arguments);
+      }
 
-/***/ }),
-/* 599 */
-/***/ ((__unused_webpack_module, exports) => {
+      fetch.toString = function () {
+        return _fetch.toString();
+      };
 
-"use strict";
+      return fetch;
+    }( /*#__PURE__*/function () {
+      var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(method, path, body) {
+        var opts,
+            options,
+            headers,
+            fullPath,
+            fetcher,
+            response,
+            _args = arguments;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                opts = _args.length > 3 && _args[3] !== undefined ? _args[3] : {};
+                options = _objectSpread({}, opts);
+                options.method = method;
+                headers = options.headers = _objectSpread({}, opts.headers);
 
+                if (method !== 'GET' && method !== 'HEAD' && body !== undefined) {
+                  if (headers['Content-Type']) {
+                    options.body = body;
+                  }
+                }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.APP_TYPE = void 0;
-var APP_TYPE = {
-  KONNECTOR: 'konnector',
-  WEBAPP: 'webapp'
-};
-exports.APP_TYPE = APP_TYPE;
+                if (!headers.Authorization) {
+                  headers.Authorization = this.getAuthorizationHeader();
+                } // the option credentials:include tells fetch to include the cookies in the
+                // request even for cross-origin requests
 
-/***/ }),
-/* 600 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-"use strict";
+                options.credentials = 'include';
+                fullPath = this.fullpath(path);
+                fetcher = (0, _xhrFetch.shouldXMLHTTPRequestBeUsed)(method, path, options) ? _xhrFetch.fetchWithXMLHttpRequest : fetch;
+                _context.prev = 9;
+                _context.next = 12;
+                return fetcher(fullPath, options);
 
+              case 12:
+                response = _context.sent;
 
-var _interopRequireDefault = __webpack_require__(512);
+                if (!response.ok) {
+                  this.emit('error', new _errors.FetchError(response, "".concat(response.status, " ").concat(response.statusText)));
+                }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.Collection = exports.isDocumentUpdateConflict = exports.isNoUsableIndexError = exports.isIndexConflictError = exports.isIndexNotFoundError = exports.dontThrowNotFoundError = void 0;
+                return _context.abrupt("return", response);
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+              case 17:
+                _context.prev = 17;
+                _context.t0 = _context["catch"](9);
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+                if (isRevocationError(_context.t0)) {
+                  this.onRevocationChange(true);
+                }
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+                throw _context.t0;
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+              case 21:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this, [[9, 17]]);
+      }));
 
-/**
- * Handler for error response which return a empty value for "not found" error
- *
- * @param  {Error}         error - An error
- * @param  {Array|object}  data Data to return in case of "not found" error
- * @returns {object}        JsonAPI response with empty data in case of "not
- * found" error.
- */
-var dontThrowNotFoundError = function dontThrowNotFoundError(error) {
-  var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
+      return function (_x4, _x5, _x6) {
+        return _ref.apply(this, arguments);
+      };
+    }())
+  }, {
+    key: "onTokenRefresh",
+    value: function onTokenRefresh(token) {
+      if (this.options && this.options.onTokenRefresh) {
+        this.options.onTokenRefresh(token);
+      }
+    }
+  }, {
+    key: "onRevocationChange",
+    value: function onRevocationChange(state) {
+      if (this.options && this.options.onRevocationChange) {
+        this.options.onRevocationChange(state);
+      }
+    }
+    /**
+     * Returns whether the client has been revoked on the server
+     */
 
-  if (error.message.match(/not_found/)) {
-    var expectsCollection = Array.isArray(data); // Return expected JsonAPI attributes : collections are expecting
-    // meta, skip and next attribute
+  }, {
+    key: "checkForRevocation",
+    value: function () {
+      var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                _context2.prev = 0;
+                _context2.next = 3;
+                return this.fetchInformation();
 
-    return expectsCollection ? {
-      data: data,
-      meta: {
-        count: 0
-      },
-      skip: 0,
-      next: false
-    } : {
-      data: data
-    };
-  }
+              case 3:
+                return _context2.abrupt("return", false);
 
-  throw error;
-};
-/**
- * Helper to identify an index not found error
- *
- * @param {Error} error - An error
- * @returns {boolean} - Whether or not the error is an index not found error
- */
+              case 6:
+                _context2.prev = 6;
+                _context2.t0 = _context2["catch"](0);
+                return _context2.abrupt("return", isRevocationError(_context2.t0));
 
+              case 9:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this, [[0, 6]]);
+      }));
 
-exports.dontThrowNotFoundError = dontThrowNotFoundError;
+      function checkForRevocation() {
+        return _checkForRevocation.apply(this, arguments);
+      }
 
-var isIndexNotFoundError = function isIndexNotFoundError(error) {
-  return error.message.match(/no_index/);
-};
-/**
- * Helper to identify an index conflict
- *
- * @param {Error} error - An error
- * @returns {boolean} - Whether or not the error is an index conflict error
- */
+      return checkForRevocation;
+    }()
+    /**
+     * Retrieves a new app token by refreshing the currently used token.
+     *
+     * @throws {Error} The client should already have an access token to use this function
+     * @throws {Error} The client couldn't fetch a new token
+     * @returns {Promise} A promise that resolves with a new AccessToken object
+     */
 
+  }, {
+    key: "refreshToken",
+    value: function () {
+      var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
+        var options, response, html, parser, doc, appNode, data, token, newToken;
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                if (this.token) {
+                  _context3.next = 2;
+                  break;
+                }
 
-exports.isIndexNotFoundError = isIndexNotFoundError;
+                throw new Error('Cannot refresh an empty token');
 
-var isIndexConflictError = function isIndexConflictError(error) {
-  return error.message.match(/error_saving_ddoc/);
-};
-/**
- * Helper to identify a no usable index error
- *
- * @param {Error} error - An error
- * @returns {boolean} - Whether or not the error is a no usable index error
- */
+              case 2:
+                options = {
+                  method: 'GET',
+                  credentials: 'include'
+                };
+
+                if (global.document) {
+                  _context3.next = 5;
+                  break;
+                }
 
+                throw new Error('Not in a web context, cannot refresh token');
 
-exports.isIndexConflictError = isIndexConflictError;
+              case 5:
+                _context3.next = 7;
+                return fetch('/?refreshToken', options);
 
-var isNoUsableIndexError = function isNoUsableIndexError(error) {
-  return error.message.match(/no_usable_index/);
-};
-/**
- * Helper to identify a document conflict
- *
- * @param {Error} error - An error
- * @returns {boolean} - Whether or not the error is a document conflict error
- */
+              case 7:
+                response = _context3.sent;
 
+                if (response.ok) {
+                  _context3.next = 10;
+                  break;
+                }
 
-exports.isNoUsableIndexError = isNoUsableIndexError;
+                throw new Error("couldn't fetch a new token - response " + response.statusCode);
 
-var isDocumentUpdateConflict = function isDocumentUpdateConflict(error) {
-  return error.message.match(/Document update conflict/);
-};
-/**
- * Utility class to abstract an regroup identical methods and logics for
- * specific collections.
- */
+              case 10:
+                _context3.next = 12;
+                return response.text();
 
+              case 12:
+                html = _context3.sent;
+                parser = new DOMParser();
+                doc = parser.parseFromString(html, 'text/html');
 
-exports.isDocumentUpdateConflict = isDocumentUpdateConflict;
+                if (doc) {
+                  _context3.next = 17;
+                  break;
+                }
 
-var Collection = /*#__PURE__*/function () {
-  function Collection() {
-    (0, _classCallCheck2.default)(this, Collection);
-  }
+                throw Error("couldn't fetch a new token - doc is not html");
 
-  (0, _createClass2.default)(Collection, null, [{
-    key: "get",
+              case 17:
+                appNode = doc.querySelector('div[role="application"]');
+
+                if (appNode) {
+                  _context3.next = 20;
+                  break;
+                }
+
+                throw Error("couldn't fetch a new token - no div[role=application]");
+
+              case 20:
+                data = appNode.dataset.cozy ? JSON.parse(appNode.dataset.cozy) : _objectSpread({}, appNode.dataset);
+                token = data.token;
 
+                if (token) {
+                  token = token || data.cozyToken;
+                }
+
+                if (token) {
+                  _context3.next = 25;
+                  break;
+                }
+
+                throw Error("couldn't fetch a new token -- missing data-cozy or data-cozy-token attribute");
+
+              case 25:
+                newToken = new _AppToken.default(token);
+                this.onTokenRefresh(newToken);
+                return _context3.abrupt("return", newToken);
+
+              case 28:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
+
+      function refreshToken() {
+        return _refreshToken.apply(this, arguments);
+      }
+
+      return refreshToken;
+    }()
     /**
-     * Utility method aimed to return only one document.
+     * Fetches JSON in an authorized way.
      *
-     * @param  {CozyStackClient}  stackClient - CozyStackClient
-     * @param  {string}  endpoint - Stack endpoint
-     * @param  {object}  options - Options of the collection
-     * @param  {Function}    options.normalize Callback to normalize response data
-     * (default `data => data`)
-     * @param  {string}  options.method    HTTP method (default `GET`)
-     * @returns {object}  JsonAPI response containing normalized
-     * document as data attribute
+     * @param  {string} method The HTTP method.
+     * @param  {string} path The URI.
+     * @param  {object} body The payload.
+     * @param  {object} options Options
+     * @returns {object}
+     * @throws {FetchError}
      */
-    value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(stackClient, endpoint, _ref) {
-        var _ref$normalize, normalize, _ref$method, method, resp;
 
-        return _regenerator.default.wrap(function _callee$(_context) {
+  }, {
+    key: "fetchJSON",
+    value: function () {
+      var _fetchJSON = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(method, path, body) {
+        var options,
+            token,
+            _args4 = arguments;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
           while (1) {
-            switch (_context.prev = _context.next) {
+            switch (_context4.prev = _context4.next) {
               case 0:
-                _ref$normalize = _ref.normalize, normalize = _ref$normalize === void 0 ? function (data, response) {
-                  return data;
-                } : _ref$normalize, _ref$method = _ref.method, method = _ref$method === void 0 ? 'GET' : _ref$method;
-                _context.prev = 1;
-                _context.next = 4;
-                return stackClient.fetchJSON(method, endpoint);
+                options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {};
+                _context4.prev = 1;
+                _context4.next = 4;
+                return this.fetchJSONWithCurrentToken(method, path, body, options);
 
               case 4:
-                resp = _context.sent;
-                return _context.abrupt("return", {
-                  data: normalize(resp.data, resp)
-                });
+                return _context4.abrupt("return", _context4.sent);
 
-              case 8:
-                _context.prev = 8;
-                _context.t0 = _context["catch"](1);
-                return _context.abrupt("return", dontThrowNotFoundError(_context.t0, null));
+              case 7:
+                _context4.prev = 7;
+                _context4.t0 = _context4["catch"](1);
 
-              case 11:
+                if (!(_errors.default.EXPIRED_TOKEN.test(_context4.t0.message) || _errors.default.INVALID_TOKEN.test(_context4.t0.message))) {
+                  _context4.next = 25;
+                  break;
+                }
+
+                _context4.prev = 10;
+                _context4.next = 13;
+                return this.refreshToken();
+
+              case 13:
+                token = _context4.sent;
+                _context4.next = 19;
+                break;
+
+              case 16:
+                _context4.prev = 16;
+                _context4.t1 = _context4["catch"](10);
+                throw _context4.t0;
+
+              case 19:
+                this.setToken(token);
+                _context4.next = 22;
+                return this.fetchJSONWithCurrentToken(method, path, body, options);
+
+              case 22:
+                return _context4.abrupt("return", _context4.sent);
+
+              case 25:
+                throw _context4.t0;
+
+              case 26:
               case "end":
-                return _context.stop();
+                return _context4.stop();
             }
           }
-        }, _callee, null, [[1, 8]]);
+        }, _callee4, this, [[1, 7], [10, 16]]);
       }));
 
-      function get(_x, _x2, _x3) {
-        return _get.apply(this, arguments);
+      function fetchJSON(_x7, _x8, _x9) {
+        return _fetchJSON.apply(this, arguments);
       }
 
-      return get;
+      return fetchJSON;
     }()
-  }]);
-  return Collection;
-}();
-
-exports.Collection = Collection;
-var _default = Collection;
-exports["default"] = _default;
-
-/***/ }),
-/* 601 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+  }, {
+    key: "fetchJSONWithCurrentToken",
+    value: function () {
+      var _fetchJSONWithCurrentToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(method, path, bodyArg) {
+        var options,
+            clonedOptions,
+            headers,
+            body,
+            resp,
+            contentType,
+            isJson,
+            data,
+            _args5 = arguments;
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                options = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : {};
+                //Since we modify the object later by adding in some case a
+                //content-type, let's clone this object to scope the modification
+                clonedOptions = (0, _cloneDeep.default)(options);
+                headers = clonedOptions.headers = clonedOptions.headers || {};
+                headers['Accept'] = 'application/json';
+                body = bodyArg;
 
-"use strict";
+                if (method !== 'GET' && method !== 'HEAD' && body !== undefined) {
+                  if (!headers['Content-Type']) {
+                    headers['Content-Type'] = 'application/json';
+                    body = JSON.stringify(body);
+                  }
+                }
 
+                _context5.next = 8;
+                return this.fetch(method, path, body, clonedOptions);
 
-var _interopRequireWildcard = __webpack_require__(510);
+              case 8:
+                resp = _context5.sent;
+                contentType = resp.headers.get('content-type');
+                isJson = contentType && contentType.indexOf('json') >= 0;
+                _context5.next = 13;
+                return isJson ? resp.json() : resp.text();
 
-var _interopRequireDefault = __webpack_require__(512);
+              case 13:
+                data = _context5.sent;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.normalizeDoc = normalizeDoc;
-exports.normalizeDoctype = exports["default"] = void 0;
+                if (!resp.ok) {
+                  _context5.next = 16;
+                  break;
+                }
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+                return _context5.abrupt("return", data);
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
+              case 16:
+                throw new _errors.FetchError(resp, data);
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+              case 17:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this);
+      }));
 
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
+      function fetchJSONWithCurrentToken(_x10, _x11, _x12) {
+        return _fetchJSONWithCurrentToken.apply(this, arguments);
+      }
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+      return fetchJSONWithCurrentToken;
+    }()
+  }, {
+    key: "fullpath",
+    value: function fullpath(path) {
+      if (path.startsWith('http')) {
+        return path;
+      } else {
+        return this.uri + path;
+      }
+    }
+  }, {
+    key: "getAuthorizationHeader",
+    value: function getAuthorizationHeader() {
+      return this.token ? this.token.toAuthHeader() : null;
+    }
+  }, {
+    key: "setCredentials",
+    value: function setCredentials(token) {
+      (0, _logDeprecate.default)('CozyStackClient::setCredentials is deprecated, use CozyStackClient::setToken');
+      return this.setToken(token);
+    }
+  }, {
+    key: "getCredentials",
+    value: function getCredentials() {
+      (0, _logDeprecate.default)('CozyStackClient::getCredentials is deprecated, use CozyStackClient::getAuthorizationHeader');
+      return this.getAuthorizationHeader();
+    }
+    /**
+     * Change or set the API token
+     *
+     * @param {string|AppToken|AccessToken} token - Stack API token
+     */
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+  }, {
+    key: "setToken",
+    value: function setToken(token) {
+      if (!token) {
+        this.token = null;
+      } else {
+        if (token.toAuthHeader) {
+          // AppToken or AccessToken
+          this.token = token;
+        } else if (typeof token === 'string') {
+          // jwt string
+          this.token = new _AppToken.default(token);
+        } else {
+          console.warn('Cozy-Client: Unknown token format', token);
+          throw new Error('Cozy-Client: Unknown token format');
+        }
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+        this.onRevocationChange(false);
+      }
+    }
+    /**
+     * Get the access token string, being an oauth token or an app token
+     *
+     * @returns {string} token
+     */
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+  }, {
+    key: "getAccessToken",
+    value: function getAccessToken() {
+      return this.token && this.token.getAccessToken();
+    }
+  }, {
+    key: "setUri",
+    value: function setUri(uri) {
+      this.uri = normalizeUri(uri);
+    }
+  }, {
+    key: "getIconURL",
+    value: function getIconURL(opts) {
+      return (0, _getIconURL2.default)(this, opts);
+    }
+  }]);
+  return CozyStackClient;
+}();
 
-var _cozyFlags = _interopRequireDefault(__webpack_require__(603));
+_microee.default.mixin(CozyStackClient);
 
-var _utils = __webpack_require__(611);
+var _default = CozyStackClient;
+exports["default"] = _default;
 
-var _uniq = _interopRequireDefault(__webpack_require__(612));
+/***/ }),
+/* 573 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _omit = _interopRequireDefault(__webpack_require__(613));
+var baseClone = __webpack_require__(574);
 
-var _head = _interopRequireDefault(__webpack_require__(621));
+/** Used to compose bitmasks for cloning. */
+var CLONE_DEEP_FLAG = 1,
+    CLONE_SYMBOLS_FLAG = 4;
 
-var _startsWith = _interopRequireDefault(__webpack_require__(622));
+/**
+ * This method is like `_.clone` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.0.0
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @returns {*} Returns the deep cloned value.
+ * @see _.clone
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var deep = _.cloneDeep(objects);
+ * console.log(deep[0] === objects[0]);
+ * // => false
+ */
+function cloneDeep(value) {
+  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
+}
 
-var _qs = _interopRequireDefault(__webpack_require__(629));
+module.exports = cloneDeep;
 
-var _mangoIndex = __webpack_require__(645);
 
-var _Collection = _interopRequireWildcard(__webpack_require__(600));
+/***/ }),
+/* 574 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var querystring = _interopRequireWildcard(__webpack_require__(647));
+var Stack = __webpack_require__(416),
+    arrayEach = __webpack_require__(566),
+    assignValue = __webpack_require__(575),
+    baseAssign = __webpack_require__(576),
+    baseAssignIn = __webpack_require__(578),
+    cloneBuffer = __webpack_require__(582),
+    copyArray = __webpack_require__(583),
+    copySymbols = __webpack_require__(584),
+    copySymbolsIn = __webpack_require__(585),
+    getAllKeys = __webpack_require__(435),
+    getAllKeysIn = __webpack_require__(588),
+    getTag = __webpack_require__(459),
+    initCloneArray = __webpack_require__(589),
+    initCloneByTag = __webpack_require__(590),
+    initCloneObject = __webpack_require__(596),
+    isArray = __webpack_require__(55),
+    isBuffer = __webpack_require__(446),
+    isMap = __webpack_require__(598),
+    isObject = __webpack_require__(52),
+    isSet = __webpack_require__(600),
+    keys = __webpack_require__(441),
+    keysIn = __webpack_require__(579);
 
-var _errors = __webpack_require__(651);
+/** Used to compose bitmasks for cloning. */
+var CLONE_DEEP_FLAG = 1,
+    CLONE_FLAT_FLAG = 2,
+    CLONE_SYMBOLS_FLAG = 4;
 
-function _templateObject10() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "/copy?rev=", ""]);
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    genTag = '[object GeneratorFunction]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    symbolTag = '[object Symbol]',
+    weakMapTag = '[object WeakMap]';
 
-  _templateObject10 = function _templateObject10() {
-    return data;
-  };
+var arrayBufferTag = '[object ArrayBuffer]',
+    dataViewTag = '[object DataView]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
 
-  return data;
-}
+/** Used to identify `toStringTag` values supported by `_.clone`. */
+var cloneableTags = {};
+cloneableTags[argsTag] = cloneableTags[arrayTag] =
+cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
+cloneableTags[boolTag] = cloneableTags[dateTag] =
+cloneableTags[float32Tag] = cloneableTags[float64Tag] =
+cloneableTags[int8Tag] = cloneableTags[int16Tag] =
+cloneableTags[int32Tag] = cloneableTags[mapTag] =
+cloneableTags[numberTag] = cloneableTags[objectTag] =
+cloneableTags[regexpTag] = cloneableTags[setTag] =
+cloneableTags[stringTag] = cloneableTags[symbolTag] =
+cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+cloneableTags[errorTag] = cloneableTags[funcTag] =
+cloneableTags[weakMapTag] = false;
 
-function _templateObject9() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "?rev=", ""]);
+/**
+ * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+ * traversed objects.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} bitmask The bitmask flags.
+ *  1 - Deep clone
+ *  2 - Flatten inherited properties
+ *  4 - Clone symbols
+ * @param {Function} [customizer] The function to customize cloning.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The parent object of `value`.
+ * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
+ * @returns {*} Returns the cloned value.
+ */
+function baseClone(value, bitmask, customizer, key, object, stack) {
+  var result,
+      isDeep = bitmask & CLONE_DEEP_FLAG,
+      isFlat = bitmask & CLONE_FLAT_FLAG,
+      isFull = bitmask & CLONE_SYMBOLS_FLAG;
 
-  _templateObject9 = function _templateObject9() {
-    return data;
-  };
+  if (customizer) {
+    result = object ? customizer(value, key, object, stack) : customizer(value);
+  }
+  if (result !== undefined) {
+    return result;
+  }
+  if (!isObject(value)) {
+    return value;
+  }
+  var isArr = isArray(value);
+  if (isArr) {
+    result = initCloneArray(value);
+    if (!isDeep) {
+      return copyArray(value, result);
+    }
+  } else {
+    var tag = getTag(value),
+        isFunc = tag == funcTag || tag == genTag;
 
-  return data;
-}
+    if (isBuffer(value)) {
+      return cloneBuffer(value, isDeep);
+    }
+    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+      result = (isFlat || isFunc) ? {} : initCloneObject(value);
+      if (!isDeep) {
+        return isFlat
+          ? copySymbolsIn(value, baseAssignIn(result, value))
+          : copySymbols(value, baseAssign(result, value));
+      }
+    } else {
+      if (!cloneableTags[tag]) {
+        return object ? value : {};
+      }
+      result = initCloneByTag(value, tag, isDeep);
+    }
+  }
+  // Check for circular references and return its corresponding clone.
+  stack || (stack = new Stack);
+  var stacked = stack.get(value);
+  if (stacked) {
+    return stacked;
+  }
+  stack.set(value, result);
 
-function _templateObject8() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design_docs?include_docs=true"]);
+  if (isSet(value)) {
+    value.forEach(function(subValue) {
+      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
+    });
+  } else if (isMap(value)) {
+    value.forEach(function(subValue, key) {
+      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
+    });
+  }
 
-  _templateObject8 = function _templateObject8() {
-    return data;
-  };
+  var keysFunc = isFull
+    ? (isFlat ? getAllKeysIn : getAllKeys)
+    : (isFlat ? keysIn : keys);
 
-  return data;
+  var props = isArr ? undefined : keysFunc(value);
+  arrayEach(props || value, function(subValue, key) {
+    if (props) {
+      key = subValue;
+      subValue = value[key];
+    }
+    // Recursively populate clone (susceptible to call stack limits).
+    assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
+  });
+  return result;
 }
 
-function _templateObject7() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_index"]);
+module.exports = baseClone;
 
-  _templateObject7 = function _templateObject7() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 575 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+var baseAssignValue = __webpack_require__(546),
+    eq = __webpack_require__(397);
 
-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); }
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-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; }
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-function _templateObject6() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "?rev=", ""]);
+/**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+function assignValue(object, key, value) {
+  var objValue = object[key];
+  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
+      (value === undefined && !(key in object))) {
+    baseAssignValue(object, key, value);
+  }
+}
 
-  _templateObject6 = function _templateObject6() {
-    return data;
-  };
+module.exports = assignValue;
 
-  return data;
-}
 
-function _templateObject5() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]);
+/***/ }),
+/* 576 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  _templateObject5 = function _templateObject5() {
-    return data;
-  };
+var copyObject = __webpack_require__(577),
+    keys = __webpack_require__(441);
 
-  return data;
+/**
+ * The base implementation of `_.assign` without support for multiple sources
+ * or `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+function baseAssign(object, source) {
+  return object && copyObject(source, keys(source), object);
 }
 
-function _templateObject4() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]);
+module.exports = baseAssign;
 
-  _templateObject4 = function _templateObject4() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 577 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _templateObject3() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_all_docs?include_docs=true"]);
+var assignValue = __webpack_require__(575),
+    baseAssignValue = __webpack_require__(546);
 
-  _templateObject3 = function _templateObject3() {
-    return data;
-  };
+/**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property identifiers to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+function copyObject(source, props, object, customizer) {
+  var isNew = !object;
+  object || (object = {});
 
-  return data;
-}
+  var index = -1,
+      length = props.length;
 
-function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_find"]);
+  while (++index < length) {
+    var key = props[index];
 
-  _templateObject2 = function _templateObject2() {
-    return data;
-  };
+    var newValue = customizer
+      ? customizer(object[key], source[key], key, object, source)
+      : undefined;
 
-  return data;
+    if (newValue === undefined) {
+      newValue = source[key];
+    }
+    if (isNew) {
+      baseAssignValue(object, key, newValue);
+    } else {
+      assignValue(object, key, newValue);
+    }
+  }
+  return object;
 }
 
-function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]);
-
-  _templateObject = function _templateObject() {
-    return data;
-  };
+module.exports = copyObject;
 
-  return data;
-}
 
-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; }
+/***/ }),
+/* 578 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+var copyObject = __webpack_require__(577),
+    keysIn = __webpack_require__(579);
 
-var DATABASE_DOES_NOT_EXIST = 'Database does not exist.';
 /**
- * Normalize a document, adding its doctype if needed
+ * The base implementation of `_.assignIn` without support for multiple sources
+ * or `customizer` functions.
  *
- * @param {object} doc - Document to normalize
- * @param {string} doctype - Document doctype
- * @returns {object} normalized document
  * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
  */
-
-function normalizeDoc() {
-  var doc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  var doctype = arguments.length > 1 ? arguments[1] : undefined;
-  var id = doc._id || doc.id;
-  return _objectSpread({
-    id: id,
-    _id: id,
-    _type: doctype
-  }, doc);
+function baseAssignIn(object, source) {
+  return object && copyObject(source, keysIn(source), object);
 }
 
-var prepareForDeletion = function prepareForDeletion(x) {
-  return Object.assign({}, (0, _omit.default)(x, '_type'), {
-    _deleted: true
-  });
-};
-/**
- * Abstracts a collection of documents of the same doctype, providing CRUD methods and other helpers.
- */
+module.exports = baseAssignIn;
 
 
-var DocumentCollection = /*#__PURE__*/function () {
-  function DocumentCollection(doctype, stackClient) {
-    (0, _classCallCheck2.default)(this, DocumentCollection);
-    this.doctype = doctype;
-    this.stackClient = stackClient;
-    this.indexes = {};
-    this.endpoint = "/data/".concat(this.doctype, "/");
-  }
-  /**
-   * Provides a callback for `Collection.get`
-   *
-   * @private
-   * @param {string} doctype - Document doctype
-   * @returns {Function} (data, response) => normalizedDocument
-   *                                        using `normalizeDoc`
-   */
+/***/ }),
+/* 579 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var arrayLikeKeys = __webpack_require__(442),
+    baseKeysIn = __webpack_require__(580),
+    isArrayLike = __webpack_require__(458);
 
-  (0, _createClass2.default)(DocumentCollection, [{
-    key: "all",
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
+}
 
-    /**
-     * Lists all documents of the collection, without filters.
-     *
-     * The returned documents are paginated by the stack.
-     *
-     * @param  {{limit, skip, bookmark, keys}} options The fetch options: pagination & fetch of specific docs.
-     * @returns {{data, meta, skip, bookmark, next}} The JSON API conformant response.
-     * @throws {FetchError}
-     */
-    value: function () {
-      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-        var _this = this;
+module.exports = keysIn;
 
-        var options,
-            _options$limit,
-            limit,
-            _options$skip,
-            skip,
-            bookmark,
-            keys,
-            isUsingAllDocsRoute,
-            route,
-            url,
-            params,
-            path,
-            resp,
-            data,
-            next,
-            _args = arguments;
 
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
-                _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip, bookmark = options.bookmark, keys = options.keys; // If the limit is intentionnally null, we need to use _all_docs, since
-                // _normal_docs uses _find and has a hard limit of 1000
+/***/ }),
+/* 580 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                isUsingAllDocsRoute = !!keys || limit === null;
-                route = isUsingAllDocsRoute ? '_all_docs' : '_normal_docs';
-                url = (0, _utils.uri)(_templateObject(), this.doctype, route);
-                params = {
-                  include_docs: true,
-                  limit: limit,
-                  skip: skip,
-                  keys: keys,
-                  bookmark: bookmark
-                };
-                path = querystring.buildURL(url, params); // If no document of this doctype exist, this route will return a 404,
-                // so we need to try/catch and return an empty response object in case of a 404
+var isObject = __webpack_require__(52),
+    isPrototype = __webpack_require__(455),
+    nativeKeysIn = __webpack_require__(581);
 
-                _context.prev = 7;
-                _context.next = 10;
-                return this.stackClient.fetchJSON('GET', path);
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-              case 10:
-                resp = _context.sent;
-                _context.next = 16;
-                break;
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-              case 13:
-                _context.prev = 13;
-                _context.t0 = _context["catch"](7);
-                return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0));
+/**
+ * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function baseKeysIn(object) {
+  if (!isObject(object)) {
+    return nativeKeysIn(object);
+  }
+  var isProto = isPrototype(object),
+      result = [];
 
-              case 16:
-                /* If using `all_docs` we need to filter our design documents and check if
-                the document is not null. If we use `normal_doc` we can't have any design doc
-                 */
-                if (isUsingAllDocsRoute) {
-                  data = resp.rows.filter(function (doc) {
-                    return doc && doc.doc !== null && !doc.error && !(0, _startsWith.default)(doc.id, '_design');
-                  }).map(function (row) {
-                    return normalizeDoc(row.doc, _this.doctype);
-                  });
-                } else {
-                  data = resp.rows.map(function (row) {
-                    return normalizeDoc(row, _this.doctype);
-                  });
-                } // The presence of a bookmark doesn’t guarantee that there are more results.
-                // See https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination
+  for (var key in object) {
+    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+      result.push(key);
+    }
+  }
+  return result;
+}
 
+module.exports = baseKeysIn;
 
-                next = bookmark ? resp.rows.length >= limit : skip + resp.rows.length < resp.total_rows;
-                return _context.abrupt("return", {
-                  data: data,
-                  meta: {
-                    count: isUsingAllDocsRoute ? data.length : resp.total_rows
-                  },
-                  skip: skip,
-                  bookmark: resp.bookmark,
-                  next: next
-                });
 
-              case 19:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this, [[7, 13]]);
-      }));
+/***/ }),
+/* 581 */
+/***/ ((module) => {
 
-      function all() {
-        return _all.apply(this, arguments);
-      }
+/**
+ * This function is like
+ * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+ * except that it includes inherited enumerable properties.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function nativeKeysIn(object) {
+  var result = [];
+  if (object != null) {
+    for (var key in Object(object)) {
+      result.push(key);
+    }
+  }
+  return result;
+}
 
-      return all;
-    }()
-  }, {
-    key: "fetchDocumentsWithMango",
-    value: function () {
-      var _fetchDocumentsWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(path, selector) {
-        var options,
-            _args2 = arguments;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {};
-                return _context2.abrupt("return", this.stackClient.fetchJSON('POST', path, this.toMangoOptions(selector, options)));
+module.exports = nativeKeysIn;
 
-              case 2:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this);
-      }));
 
-      function fetchDocumentsWithMango(_x, _x2) {
-        return _fetchDocumentsWithMango.apply(this, arguments);
-      }
+/***/ }),
+/* 582 */
+/***/ ((module, exports, __webpack_require__) => {
 
-      return fetchDocumentsWithMango;
-    }()
-    /**
-     * Migrate an existing unamed index to a named one.
-     *
-     * Index migration became necessary for optimistic index, because
-     * we started to use named index while we used to have unamed index,
-     * i.e. indexes with CouchDB-generated ID.
-     *
-     * @param {object} sourceIndex - The index to migrate
-     * @param {string} targetIndexName - The new index name
-     * @private
-     */
+/* module decorator */ module = __webpack_require__.nmd(module);
+var root = __webpack_require__(48);
 
-  }, {
-    key: "migrateUnamedIndex",
-    value: function () {
-      var _migrateUnamedIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sourceIndex, targetIndexName) {
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                _context3.prev = 0;
-                _context3.next = 3;
-                return this.copyIndex(sourceIndex, targetIndexName);
+/** Detect free variable `exports`. */
+var freeExports =  true && exports && !exports.nodeType && exports;
 
-              case 3:
-                _context3.next = 5;
-                return this.destroyIndex(sourceIndex);
+/** Detect free variable `module`. */
+var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
 
-              case 5:
-                _context3.next = 16;
-                break;
+/** Detect the popular CommonJS extension `module.exports`. */
+var moduleExports = freeModule && freeModule.exports === freeExports;
 
-              case 7:
-                _context3.prev = 7;
-                _context3.t0 = _context3["catch"](0);
+/** Built-in value references. */
+var Buffer = moduleExports ? root.Buffer : undefined,
+    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
 
-                if ((0, _Collection.isDocumentUpdateConflict)(_context3.t0)) {
-                  _context3.next = 11;
-                  break;
-                }
+/**
+ * Creates a clone of  `buffer`.
+ *
+ * @private
+ * @param {Buffer} buffer The buffer to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Buffer} Returns the cloned buffer.
+ */
+function cloneBuffer(buffer, isDeep) {
+  if (isDeep) {
+    return buffer.slice();
+  }
+  var length = buffer.length,
+      result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
 
-                throw _context3.t0;
+  buffer.copy(result);
+  return result;
+}
 
-              case 11:
-                (0, _utils.sleep)(1000);
-                _context3.next = 14;
-                return this.copyIndex(sourceIndex, targetIndexName);
+module.exports = cloneBuffer;
 
-              case 14:
-                _context3.next = 16;
-                return this.destroyIndex(sourceIndex);
 
-              case 16:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this, [[0, 7]]);
-      }));
+/***/ }),
+/* 583 */
+/***/ ((module) => {
 
-      function migrateUnamedIndex(_x3, _x4) {
-        return _migrateUnamedIndex.apply(this, arguments);
-      }
+/**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+function copyArray(source, array) {
+  var index = -1,
+      length = source.length;
 
-      return migrateUnamedIndex;
-    }()
-    /**
-     * Handle index creation if it is missing.
-     *
-     * When an index is missing, we first check if there is one with a different
-     * name but the same definition. If yes, it means we found an old unamed
-     * index, so we migrate it. If there is none, we create the new index.
-     *
-     * @param {object} selector The mango selector
-     * @param {MangoQueryOptions} options The find options
-     * @private
-     */
+  array || (array = Array(length));
+  while (++index < length) {
+    array[index] = source[index];
+  }
+  return array;
+}
 
-  }, {
-    key: "handleMissingIndex",
-    value: function () {
-      var _handleMissingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(selector, options) {
-        var indexedFields, partialFilter, existingIndex, indexName;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                indexedFields = options.indexedFields, partialFilter = options.partialFilter;
+module.exports = copyArray;
 
-                if (!indexedFields) {
-                  indexedFields = (0, _mangoIndex.getIndexFields)({
-                    sort: options.sort,
-                    selector: selector
-                  });
-                }
 
-                _context4.next = 4;
-                return this.findExistingIndex(selector, options);
+/***/ }),
+/* 584 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 4:
-                existingIndex = _context4.sent;
-                indexName = (0, _mangoIndex.getIndexNameFromFields)(indexedFields);
+var copyObject = __webpack_require__(577),
+    getSymbols = __webpack_require__(438);
 
-                if (existingIndex) {
-                  _context4.next = 11;
-                  break;
-                }
+/**
+ * Copies own symbols of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+function copySymbols(source, object) {
+  return copyObject(source, getSymbols(source), object);
+}
 
-                _context4.next = 9;
-                return this.createIndex(indexedFields, {
-                  partialFilter: partialFilter,
-                  indexName: indexName
-                });
+module.exports = copySymbols;
 
-              case 9:
-                _context4.next = 17;
-                break;
 
-              case 11:
-                if (!(existingIndex._id !== "_design/".concat(indexName))) {
-                  _context4.next = 16;
-                  break;
-                }
+/***/ }),
+/* 585 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                _context4.next = 14;
-                return this.migrateUnamedIndex(existingIndex, indexName);
+var copyObject = __webpack_require__(577),
+    getSymbolsIn = __webpack_require__(586);
 
-              case 14:
-                _context4.next = 17;
-                break;
+/**
+ * Copies own and inherited symbols of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+function copySymbolsIn(source, object) {
+  return copyObject(source, getSymbolsIn(source), object);
+}
 
-              case 16:
-                throw new Error("Index unusable for query, index used: ".concat(indexName));
+module.exports = copySymbolsIn;
 
-              case 17:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4, this);
-      }));
 
-      function handleMissingIndex(_x5, _x6) {
-        return _handleMissingIndex.apply(this, arguments);
-      }
+/***/ }),
+/* 586 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return handleMissingIndex;
-    }()
-    /**
-     * Find documents with the mango selector and create index
-     * if missing.
-     *
-     * We adopt an optimistic approach for index creation:
-     * we run the query first, and only if an index missing
-     * error is returned, the index is created and
-     * the query run again.
-     *
-     * @param {string} path The route path
-     * @param {object} selector The mango selector
-     * @param {MangoQueryOptions} options The find options
-     *
-     * @returns {object} - The find response
-     * @private
-     */
+var arrayPush = __webpack_require__(437),
+    getPrototype = __webpack_require__(587),
+    getSymbols = __webpack_require__(438),
+    stubArray = __webpack_require__(440);
 
-  }, {
-    key: "findWithMango",
-    value: function () {
-      var _findWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(path, selector) {
-        var options,
-            resp,
-            _args5 = arguments;
-        return _regenerator.default.wrap(function _callee5$(_context5) {
-          while (1) {
-            switch (_context5.prev = _context5.next) {
-              case 0:
-                options = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : {};
-                _context5.prev = 1;
-                _context5.next = 4;
-                return this.fetchDocumentsWithMango(path, selector, options);
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeGetSymbols = Object.getOwnPropertySymbols;
 
-              case 4:
-                resp = _context5.sent;
-                _context5.next = 18;
-                break;
+/**
+ * Creates an array of the own and inherited enumerable symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
+  var result = [];
+  while (object) {
+    arrayPush(result, getSymbols(object));
+    object = getPrototype(object);
+  }
+  return result;
+};
 
-              case 7:
-                _context5.prev = 7;
-                _context5.t0 = _context5["catch"](1);
+module.exports = getSymbolsIn;
 
-                if (!(!(0, _Collection.isIndexNotFoundError)(_context5.t0) && !(0, _Collection.isNoUsableIndexError)(_context5.t0))) {
-                  _context5.next = 13;
-                  break;
-                }
 
-                throw _context5.t0;
+/***/ }),
+/* 587 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 13:
-                _context5.next = 15;
-                return this.handleMissingIndex(selector, options);
+var overArg = __webpack_require__(457);
 
-              case 15:
-                _context5.next = 17;
-                return this.fetchDocumentsWithMango(path, selector, options);
+/** Built-in value references. */
+var getPrototype = overArg(Object.getPrototypeOf, Object);
 
-              case 17:
-                resp = _context5.sent;
+module.exports = getPrototype;
 
-              case 18:
-                return _context5.abrupt("return", resp);
 
-              case 19:
-              case "end":
-                return _context5.stop();
-            }
-          }
-        }, _callee5, this, [[1, 7]]);
-      }));
+/***/ }),
+/* 588 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function findWithMango(_x7, _x8) {
-        return _findWithMango.apply(this, arguments);
-      }
+var baseGetAllKeys = __webpack_require__(436),
+    getSymbolsIn = __webpack_require__(586),
+    keysIn = __webpack_require__(579);
 
-      return findWithMango;
-    }()
-    /**
-     * Returns a filtered list of documents using a Mango selector.
-     *
-     * The returned documents are paginated by the stack.
-     *
-     * @param  {object} selector The Mango selector.
-     * @param  {{sort, fields, limit, skip, bookmark, indexId}} options The query options.
-     * @returns {{data, skip, bookmark, next}} The JSON API conformant response.
-     * @throws {FetchError}
-     */
+/**
+ * Creates an array of own and inherited enumerable property names and
+ * symbols of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names and symbols.
+ */
+function getAllKeysIn(object) {
+  return baseGetAllKeys(object, keysIn, getSymbolsIn);
+}
 
-  }, {
-    key: "find",
-    value: function () {
-      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(selector) {
-        var _this2 = this;
+module.exports = getAllKeysIn;
 
-        var options,
-            _options$skip2,
-            skip,
-            resp,
-            path,
-            _args6 = arguments;
 
-        return _regenerator.default.wrap(function _callee6$(_context6) {
-          while (1) {
-            switch (_context6.prev = _context6.next) {
-              case 0:
-                options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
-                _options$skip2 = options.skip, skip = _options$skip2 === void 0 ? 0 : _options$skip2;
-                _context6.prev = 2;
-                path = (0, _utils.uri)(_templateObject2(), this.doctype);
-                _context6.next = 6;
-                return this.findWithMango(path, selector, options);
+/***/ }),
+/* 589 */
+/***/ ((module) => {
 
-              case 6:
-                resp = _context6.sent;
-                _context6.next = 12;
-                break;
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-              case 9:
-                _context6.prev = 9;
-                _context6.t0 = _context6["catch"](2);
-                return _context6.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context6.t0));
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-              case 12:
-                return _context6.abrupt("return", {
-                  data: resp.docs.map(function (doc) {
-                    return normalizeDoc(doc, _this2.doctype);
-                  }),
-                  next: resp.next,
-                  skip: skip,
-                  bookmark: resp.bookmark,
-                  execution_stats: resp.execution_stats
-                });
+/**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */
+function initCloneArray(array) {
+  var length = array.length,
+      result = new array.constructor(length);
 
-              case 13:
-              case "end":
-                return _context6.stop();
-            }
-          }
-        }, _callee6, this, [[2, 9]]);
-      }));
+  // Add properties assigned by `RegExp#exec`.
+  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+    result.index = array.index;
+    result.input = array.input;
+  }
+  return result;
+}
 
-      function find(_x9) {
-        return _find.apply(this, arguments);
-      }
+module.exports = initCloneArray;
 
-      return find;
-    }()
-    /**
-     * Get a document by id
-     *
-     * @param  {string} id The document id.
-     * @returns {object}  JsonAPI response containing normalized document as data attribute
-     */
 
-  }, {
-    key: "get",
-    value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(id) {
-        return _regenerator.default.wrap(function _callee7$(_context7) {
-          while (1) {
-            switch (_context7.prev = _context7.next) {
-              case 0:
-                return _context7.abrupt("return", _Collection.default.get(this.stackClient, "".concat(this.endpoint).concat(encodeURIComponent(id)), {
-                  normalize: this.constructor.normalizeDoctype(this.doctype)
-                }));
+/***/ }),
+/* 590 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 1:
-              case "end":
-                return _context7.stop();
-            }
-          }
-        }, _callee7, this);
-      }));
+var cloneArrayBuffer = __webpack_require__(591),
+    cloneDataView = __webpack_require__(592),
+    cloneRegExp = __webpack_require__(593),
+    cloneSymbol = __webpack_require__(594),
+    cloneTypedArray = __webpack_require__(595);
 
-      function get(_x10) {
-        return _get.apply(this, arguments);
-      }
+/** `Object#toString` result references. */
+var boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    symbolTag = '[object Symbol]';
 
-      return get;
-    }()
-    /**
-     * Get many documents by id
-     */
+var arrayBufferTag = '[object ArrayBuffer]',
+    dataViewTag = '[object DataView]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
 
-  }, {
-    key: "getAll",
-    value: function () {
-      var _getAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(ids) {
-        var _this3 = this;
+/**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneByTag(object, tag, isDeep) {
+  var Ctor = object.constructor;
+  switch (tag) {
+    case arrayBufferTag:
+      return cloneArrayBuffer(object);
 
-        var resp, rows;
-        return _regenerator.default.wrap(function _callee8$(_context8) {
-          while (1) {
-            switch (_context8.prev = _context8.next) {
-              case 0:
-                _context8.prev = 0;
-                _context8.next = 3;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), this.doctype), {
-                  keys: ids
-                });
+    case boolTag:
+    case dateTag:
+      return new Ctor(+object);
 
-              case 3:
-                resp = _context8.sent;
-                _context8.next = 9;
-                break;
+    case dataViewTag:
+      return cloneDataView(object, isDeep);
 
-              case 6:
-                _context8.prev = 6;
-                _context8.t0 = _context8["catch"](0);
-                return _context8.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context8.t0));
+    case float32Tag: case float64Tag:
+    case int8Tag: case int16Tag: case int32Tag:
+    case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
+      return cloneTypedArray(object, isDeep);
 
-              case 9:
-                rows = resp.rows.filter(function (row) {
-                  return row.doc;
-                });
-                return _context8.abrupt("return", {
-                  data: rows.map(function (row) {
-                    return normalizeDoc(row.doc, _this3.doctype);
-                  }),
-                  meta: {
-                    count: rows.length
-                  }
-                });
+    case mapTag:
+      return new Ctor;
 
-              case 11:
-              case "end":
-                return _context8.stop();
-            }
-          }
-        }, _callee8, this, [[0, 6]]);
-      }));
+    case numberTag:
+    case stringTag:
+      return new Ctor(object);
 
-      function getAll(_x11) {
-        return _getAll.apply(this, arguments);
-      }
+    case regexpTag:
+      return cloneRegExp(object);
 
-      return getAll;
-    }()
-    /**
-     * Creates a document
-     *
-     * @param {object} doc - Document to create. Optional: you can force the id with the _id attribute
-     */
+    case setTag:
+      return new Ctor;
 
-  }, {
-    key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(_ref) {
-        var _id, _type, document, hasFixedId, method, endpoint, resp;
+    case symbolTag:
+      return cloneSymbol(object);
+  }
+}
 
-        return _regenerator.default.wrap(function _callee9$(_context9) {
-          while (1) {
-            switch (_context9.prev = _context9.next) {
-              case 0:
-                _id = _ref._id, _type = _ref._type, document = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type"]);
-                // In case of a fixed id, let's use the dedicated creation endpoint
-                // https://github.com/cozy/cozy-stack/blob/master/docs/data-system.md#create-a-document-with-a-fixed-id
-                hasFixedId = !!_id;
-                method = hasFixedId ? 'PUT' : 'POST';
-                endpoint = (0, _utils.uri)(_templateObject4(), this.doctype, hasFixedId ? _id : '');
-                _context9.next = 6;
-                return this.stackClient.fetchJSON(method, endpoint, document);
+module.exports = initCloneByTag;
 
-              case 6:
-                resp = _context9.sent;
-                return _context9.abrupt("return", {
-                  data: normalizeDoc(resp.data, this.doctype)
-                });
 
-              case 8:
-              case "end":
-                return _context9.stop();
-            }
-          }
-        }, _callee9, this);
-      }));
+/***/ }),
+/* 591 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function create(_x12) {
-        return _create.apply(this, arguments);
-      }
+var Uint8Array = __webpack_require__(431);
 
-      return create;
-    }()
-    /**
-     * Updates a document
-     *
-     * @param {object} document - Document to update. Do not forget the _id attribute
-     */
+/**
+ * Creates a clone of `arrayBuffer`.
+ *
+ * @private
+ * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+function cloneArrayBuffer(arrayBuffer) {
+  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
+  new Uint8Array(result).set(new Uint8Array(arrayBuffer));
+  return result;
+}
 
-  }, {
-    key: "update",
-    value: function () {
-      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(document) {
-        var resp;
-        return _regenerator.default.wrap(function _callee10$(_context10) {
-          while (1) {
-            switch (_context10.prev = _context10.next) {
-              case 0:
-                _context10.next = 2;
-                return this.stackClient.fetchJSON('PUT', (0, _utils.uri)(_templateObject5(), this.doctype, document._id), document);
+module.exports = cloneArrayBuffer;
 
-              case 2:
-                resp = _context10.sent;
-                return _context10.abrupt("return", {
-                  data: normalizeDoc(resp.data, this.doctype)
-                });
 
-              case 4:
-              case "end":
-                return _context10.stop();
-            }
-          }
-        }, _callee10, this);
-      }));
+/***/ }),
+/* 592 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function update(_x13) {
-        return _update.apply(this, arguments);
-      }
+var cloneArrayBuffer = __webpack_require__(591);
 
-      return update;
-    }()
-    /**
-     * Destroys a document
-     *
-     * @param {object} doc - Document to destroy. Do not forget _id and _rev attributes
-     */
+/**
+ * Creates a clone of `dataView`.
+ *
+ * @private
+ * @param {Object} dataView The data view to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned data view.
+ */
+function cloneDataView(dataView, isDeep) {
+  var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
+  return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
+}
 
-  }, {
-    key: "destroy",
-    value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(_ref2) {
-        var _id, _rev, document, resp;
+module.exports = cloneDataView;
 
-        return _regenerator.default.wrap(function _callee11$(_context11) {
-          while (1) {
-            switch (_context11.prev = _context11.next) {
-              case 0:
-                _id = _ref2._id, _rev = _ref2._rev, document = (0, _objectWithoutProperties2.default)(_ref2, ["_id", "_rev"]);
-                _context11.next = 3;
-                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), this.doctype, _id, _rev));
 
-              case 3:
-                resp = _context11.sent;
-                return _context11.abrupt("return", {
-                  data: normalizeDoc(_objectSpread(_objectSpread({}, document), {}, {
-                    _id: _id,
-                    _rev: resp.rev,
-                    _deleted: true
-                  }), this.doctype)
-                });
+/***/ }),
+/* 593 */
+/***/ ((module) => {
 
-              case 5:
-              case "end":
-                return _context11.stop();
-            }
-          }
-        }, _callee11, this);
-      }));
+/** Used to match `RegExp` flags from their coerced string values. */
+var reFlags = /\w*$/;
 
-      function destroy(_x14) {
-        return _destroy.apply(this, arguments);
-      }
+/**
+ * Creates a clone of `regexp`.
+ *
+ * @private
+ * @param {Object} regexp The regexp to clone.
+ * @returns {Object} Returns the cloned regexp.
+ */
+function cloneRegExp(regexp) {
+  var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
+  result.lastIndex = regexp.lastIndex;
+  return result;
+}
 
-      return destroy;
-    }()
-    /**
-     * Updates several documents in one batch
-     *
-     * @param  {Document[]} rawDocs Documents to be updated
-     */
+module.exports = cloneRegExp;
 
-  }, {
-    key: "updateAll",
-    value: function () {
-      var _updateAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(rawDocs) {
-        var stackClient, docs, update, firstDoc, resp;
-        return _regenerator.default.wrap(function _callee12$(_context12) {
-          while (1) {
-            switch (_context12.prev = _context12.next) {
-              case 0:
-                stackClient = this.stackClient;
-                docs = rawDocs ? rawDocs.map(function (d) {
-                  return (0, _omit.default)(d, '_type');
-                }) : rawDocs;
 
-                if (!(!docs || !docs.length)) {
-                  _context12.next = 4;
-                  break;
-                }
+/***/ }),
+/* 594 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                return _context12.abrupt("return", Promise.resolve([]));
+var Symbol = __webpack_require__(47);
 
-              case 4:
-                _context12.prev = 4;
-                _context12.next = 7;
-                return stackClient.fetchJSON('POST', "/data/".concat(this.doctype, "/_bulk_docs"), {
-                  docs: docs
-                });
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
 
-              case 7:
-                update = _context12.sent;
-                return _context12.abrupt("return", update);
+/**
+ * Creates a clone of the `symbol` object.
+ *
+ * @private
+ * @param {Object} symbol The symbol object to clone.
+ * @returns {Object} Returns the cloned symbol object.
+ */
+function cloneSymbol(symbol) {
+  return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
+}
 
-              case 11:
-                _context12.prev = 11;
-                _context12.t0 = _context12["catch"](4);
+module.exports = cloneSymbol;
 
-                if (!(_context12.t0.reason && _context12.t0.reason.reason && _context12.t0.reason.reason === DATABASE_DOES_NOT_EXIST)) {
-                  _context12.next = 24;
-                  break;
-                }
 
-                _context12.next = 16;
-                return this.create(docs[0]);
+/***/ }),
+/* 595 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 16:
-                firstDoc = _context12.sent;
-                _context12.next = 19;
-                return this.updateAll(docs.slice(1));
+var cloneArrayBuffer = __webpack_require__(591);
 
-              case 19:
-                resp = _context12.sent;
-                resp.unshift({
-                  ok: true,
-                  id: firstDoc._id,
-                  rev: firstDoc._rev
-                });
-                return _context12.abrupt("return", resp);
+/**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */
+function cloneTypedArray(typedArray, isDeep) {
+  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
+  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
+}
 
-              case 24:
-                throw _context12.t0;
+module.exports = cloneTypedArray;
 
-              case 25:
-              case "end":
-                return _context12.stop();
-            }
-          }
-        }, _callee12, this, [[4, 11]]);
-      }));
 
-      function updateAll(_x15) {
-        return _updateAll.apply(this, arguments);
-      }
+/***/ }),
+/* 596 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return updateAll;
-    }()
-    /**
-     * Deletes several documents in one batch
-     *
-     * @param  {Document[]} docs - Documents to delete
-     */
+var baseCreate = __webpack_require__(597),
+    getPrototype = __webpack_require__(587),
+    isPrototype = __webpack_require__(455);
 
-  }, {
-    key: "destroyAll",
-    value: function destroyAll(docs) {
-      return this.updateAll(docs.map(prepareForDeletion));
-    }
-  }, {
-    key: "toMangoOptions",
-    value: function toMangoOptions(selector) {
-      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-      var sort = options.sort,
-          indexedFields = options.indexedFields;
-      var fields = options.fields,
-          _options$skip3 = options.skip,
-          skip = _options$skip3 === void 0 ? 0 : _options$skip3,
-          limit = options.limit,
-          bookmark = options.bookmark;
-      sort = (0, _mangoIndex.transformSort)(sort);
-      indexedFields = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({
-        sort: sort,
-        selector: selector
-      });
-      var indexName = options.indexId || "_design/".concat((0, _mangoIndex.getIndexNameFromFields)(indexedFields));
+/**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneObject(object) {
+  return (typeof object.constructor == 'function' && !isPrototype(object))
+    ? baseCreate(getPrototype(object))
+    : {};
+}
 
-      if (sort) {
-        var sortOrders = (0, _uniq.default)(sort.map(function (sortOption) {
-          return (0, _head.default)(Object.values(sortOption));
-        }));
-        if (sortOrders.length > 1) throw new Error('Mango sort can only use a single order (asc or desc).');
-        var sortOrder = sortOrders.length > 0 ? (0, _head.default)(sortOrders) : 'asc';
+module.exports = initCloneObject;
 
-        var _iterator = _createForOfIteratorHelper(indexedFields),
-            _step;
 
-        try {
-          var _loop = function _loop() {
-            var field = _step.value;
-            if (!sort.find(function (sortOption) {
-              return (0, _head.default)(Object.keys(sortOption)) === field;
-            })) sort.push((0, _defineProperty2.default)({}, field, sortOrder));
-          };
+/***/ }),
+/* 597 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-          for (_iterator.s(); !(_step = _iterator.n()).done;) {
-            _loop();
-          }
-        } catch (err) {
-          _iterator.e(err);
-        } finally {
-          _iterator.f();
-        }
-      }
+var isObject = __webpack_require__(52);
 
-      var opts = {
-        selector: selector,
-        use_index: indexName,
-        // TODO: type and class should not be necessary, it's just a temp fix for a stack bug
-        fields: fields ? [].concat((0, _toConsumableArray2.default)(fields), ['_id', '_type', 'class']) : undefined,
-        limit: limit,
-        skip: skip,
-        bookmark: options.bookmark || bookmark,
-        sort: sort,
-        execution_stats: (0, _cozyFlags.default)('debug') ? true : undefined
-      };
-      return opts;
+/** Built-in value references. */
+var objectCreate = Object.create;
+
+/**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} proto The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+var baseCreate = (function() {
+  function object() {}
+  return function(proto) {
+    if (!isObject(proto)) {
+      return {};
     }
-  }, {
-    key: "checkUniquenessOf",
-    value: function () {
-      var _checkUniquenessOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(property, value) {
-        var indexId, existingDocs;
-        return _regenerator.default.wrap(function _callee13$(_context13) {
-          while (1) {
-            switch (_context13.prev = _context13.next) {
-              case 0:
-                _context13.next = 2;
-                return this.getUniqueIndexId(property);
+    if (objectCreate) {
+      return objectCreate(proto);
+    }
+    object.prototype = proto;
+    var result = new object;
+    object.prototype = undefined;
+    return result;
+  };
+}());
 
-              case 2:
-                indexId = _context13.sent;
-                _context13.next = 5;
-                return this.find((0, _defineProperty2.default)({}, property, value), {
-                  indexId: indexId,
-                  fields: ['_id']
-                });
+module.exports = baseCreate;
 
-              case 5:
-                existingDocs = _context13.sent;
-                return _context13.abrupt("return", existingDocs.data.length === 0);
 
-              case 7:
-              case "end":
-                return _context13.stop();
-            }
-          }
-        }, _callee13, this);
-      }));
+/***/ }),
+/* 598 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function checkUniquenessOf(_x16, _x17) {
-        return _checkUniquenessOf.apply(this, arguments);
-      }
+var baseIsMap = __webpack_require__(599),
+    baseUnary = __webpack_require__(452),
+    nodeUtil = __webpack_require__(453);
 
-      return checkUniquenessOf;
-    }()
-  }, {
-    key: "getUniqueIndexId",
-    value: function getUniqueIndexId(property) {
-      return this.getIndexId([property], {
-        indexName: "".concat(this.doctype, "/").concat(property)
-      });
-    }
-  }, {
-    key: "getIndexId",
-    value: function () {
-      var _getIndexId = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(fields, _ref3) {
-        var partialFilter, _ref3$indexName, indexName, index;
+/* Node.js helper references. */
+var nodeIsMap = nodeUtil && nodeUtil.isMap;
 
-        return _regenerator.default.wrap(function _callee14$(_context14) {
-          while (1) {
-            switch (_context14.prev = _context14.next) {
-              case 0:
-                partialFilter = _ref3.partialFilter, _ref3$indexName = _ref3.indexName, indexName = _ref3$indexName === void 0 ? this.getIndexNameFromFields(fields) : _ref3$indexName;
+/**
+ * Checks if `value` is classified as a `Map` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ * @example
+ *
+ * _.isMap(new Map);
+ * // => true
+ *
+ * _.isMap(new WeakMap);
+ * // => false
+ */
+var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
 
-                if (this.indexes[indexName]) {
-                  _context14.next = 20;
-                  break;
-                }
+module.exports = isMap;
 
-                _context14.prev = 2;
-                _context14.next = 5;
-                return this.createIndex(fields, {
-                  partialFilter: partialFilter
-                });
 
-              case 5:
-                index = _context14.sent;
-                _context14.next = 19;
-                break;
+/***/ }),
+/* 599 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 8:
-                _context14.prev = 8;
-                _context14.t0 = _context14["catch"](2);
+var getTag = __webpack_require__(459),
+    isObjectLike = __webpack_require__(53);
 
-                if ((0, _Collection.isIndexConflictError)(_context14.t0)) {
-                  _context14.next = 14;
-                  break;
-                }
+/** `Object#toString` result references. */
+var mapTag = '[object Map]';
 
-                throw _context14.t0;
+/**
+ * The base implementation of `_.isMap` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+ */
+function baseIsMap(value) {
+  return isObjectLike(value) && getTag(value) == mapTag;
+}
 
-              case 14:
-                _context14.next = 16;
-                return (0, _utils.sleep)(1000);
+module.exports = baseIsMap;
 
-              case 16:
-                _context14.next = 18;
-                return this.createIndex(fields, {
-                  partialFilter: partialFilter
-                });
 
-              case 18:
-                index = _context14.sent;
+/***/ }),
+/* 600 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 19:
-                this.indexes[indexName] = index;
+var baseIsSet = __webpack_require__(601),
+    baseUnary = __webpack_require__(452),
+    nodeUtil = __webpack_require__(453);
 
-              case 20:
-                return _context14.abrupt("return", this.indexes[indexName].id);
+/* Node.js helper references. */
+var nodeIsSet = nodeUtil && nodeUtil.isSet;
 
-              case 21:
-              case "end":
-                return _context14.stop();
-            }
-          }
-        }, _callee14, this, [[2, 8]]);
-      }));
+/**
+ * Checks if `value` is classified as a `Set` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.3.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ * @example
+ *
+ * _.isSet(new Set);
+ * // => true
+ *
+ * _.isSet(new WeakSet);
+ * // => false
+ */
+var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
 
-      function getIndexId(_x18, _x19) {
-        return _getIndexId.apply(this, arguments);
-      }
+module.exports = isSet;
 
-      return getIndexId;
-    }()
-  }, {
-    key: "createIndex",
-    value: function () {
-      var _createIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(fields) {
-        var _ref4,
-            partialFilter,
-            indexName,
-            indexDef,
-            resp,
-            indexResp,
-            selector,
-            options,
-            _args15 = arguments;
 
-        return _regenerator.default.wrap(function _callee15$(_context15) {
-          while (1) {
-            switch (_context15.prev = _context15.next) {
-              case 0:
-                _ref4 = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : {}, partialFilter = _ref4.partialFilter, indexName = _ref4.indexName;
-                indexDef = {
-                  index: {
-                    fields: fields
-                  }
-                };
+/***/ }),
+/* 601 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                if (indexName) {
-                  indexDef.ddoc = indexName;
-                }
+var getTag = __webpack_require__(459),
+    isObjectLike = __webpack_require__(53);
 
-                if (partialFilter) {
-                  indexDef.index.partial_filter_selector = partialFilter;
-                }
+/** `Object#toString` result references. */
+var setTag = '[object Set]';
 
-                _context15.prev = 4;
-                _context15.next = 7;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), this.doctype), indexDef);
+/**
+ * The base implementation of `_.isSet` without Node.js optimizations.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+ */
+function baseIsSet(value) {
+  return isObjectLike(value) && getTag(value) == setTag;
+}
 
-              case 7:
-                resp = _context15.sent;
-                _context15.next = 17;
-                break;
+module.exports = baseIsSet;
 
-              case 10:
-                _context15.prev = 10;
-                _context15.t0 = _context15["catch"](4);
 
-                if ((0, _Collection.isIndexConflictError)(_context15.t0)) {
-                  _context15.next = 16;
-                  break;
-                }
+/***/ }),
+/* 602 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-                throw _context15.t0;
+"use strict";
 
-              case 16:
-                return _context15.abrupt("return");
 
-              case 17:
-                indexResp = {
-                  id: resp.id,
-                  fields: fields
-                };
+var _interopRequireWildcard = __webpack_require__(522);
 
-                if (!(resp.result === 'exists')) {
-                  _context15.next = 20;
-                  break;
-                }
+var _interopRequireDefault = __webpack_require__(524);
 
-                return _context15.abrupt("return", indexResp);
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = exports.normalizeApp = exports.APPS_DOCTYPE = void 0;
 
-              case 20:
-                // indexes might not be usable right after being created; so we delay the resolving until they are
-                selector = {};
-                fields.forEach(function (f) {
-                  return selector[f] = {
-                    $gt: null
-                  };
-                });
-                options = {
-                  indexId: indexResp.id,
-                  limit: 1
-                };
-                _context15.next = 25;
-                return (0, _utils.attempt)(this.find(selector, options));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-              case 25:
-                if (!_context15.sent) {
-                  _context15.next = 27;
-                  break;
-                }
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-                return _context15.abrupt("return", indexResp);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-              case 27:
-                _context15.next = 29;
-                return (0, _utils.sleep)(1000);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-              case 29:
-                _context15.next = 31;
-                return (0, _utils.attempt)(this.find(selector, options));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-              case 31:
-                if (!_context15.sent) {
-                  _context15.next = 33;
-                  break;
-                }
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-                return _context15.abrupt("return", indexResp);
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-              case 33:
-                _context15.next = 35;
-                return (0, _utils.sleep)(500);
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-              case 35:
-                return _context15.abrupt("return", indexResp);
+var _get3 = _interopRequireDefault(__webpack_require__(370));
 
-              case 36:
-              case "end":
-                return _context15.stop();
-            }
-          }
-        }, _callee15, this, [[4, 10]]);
-      }));
+var _registry = __webpack_require__(608);
 
-      function createIndex(_x20) {
-        return _createIndex.apply(this, arguments);
-      }
+var _Collection = _interopRequireDefault(__webpack_require__(612));
 
-      return createIndex;
-    }()
-    /**
-     * Retrieve all design docs of mango indexes
-     *
-     * @returns {Array} The design docs
-     */
+var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613));
 
-  }, {
-    key: "fetchAllMangoIndexes",
-    value: function () {
-      var _fetchAllMangoIndexes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() {
-        var path, indexes;
-        return _regenerator.default.wrap(function _callee16$(_context16) {
-          while (1) {
-            switch (_context16.prev = _context16.next) {
-              case 0:
-                path = (0, _utils.uri)(_templateObject8(), this.doctype);
-                _context16.next = 3;
-                return this.stackClient.fetchJSON('GET', path);
+var _errors = __webpack_require__(663);
 
-              case 3:
-                indexes = _context16.sent;
-                return _context16.abrupt("return", indexes.rows.filter(function (index) {
-                  return index.doc.language === 'query';
-                }).map(function (doc) {
-                  return (0, _mangoIndex.normalizeDesignDoc)(doc);
-                }));
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-              case 5:
-              case "end":
-                return _context16.stop();
-            }
-          }
-        }, _callee16, this);
-      }));
+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 fetchAllMangoIndexes() {
-        return _fetchAllMangoIndexes.apply(this, arguments);
-      }
+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; }
 
-      return fetchAllMangoIndexes;
-    }()
-    /**
-     * Delete the specified design doc
-     *
-     * @param {object} index - The design doc to remove
-     * @returns {object} The delete response
-     */
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-  }, {
-    key: "destroyIndex",
-    value: function () {
-      var _destroyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(index) {
-        var ddoc, rev, path;
-        return _regenerator.default.wrap(function _callee17$(_context17) {
-          while (1) {
-            switch (_context17.prev = _context17.next) {
-              case 0:
-                ddoc = index._id.split('/')[1];
-                rev = index._rev;
-                path = (0, _utils.uri)(_templateObject9(), this.doctype, ddoc, rev);
-                return _context17.abrupt("return", this.stackClient.fetchJSON('DELETE', path));
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-              case 4:
-              case "end":
-                return _context17.stop();
-            }
-          }
-        }, _callee17, this);
-      }));
+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 destroyIndex(_x21) {
-        return _destroyIndex.apply(this, arguments);
-      }
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-      return destroyIndex;
-    }()
-    /**
-     * Copy an existing design doc.
-     *
-     * This is useful to create a new design doc without
-     * having to recompute the existing index.
-     *
-     * @param {object} existingIndex - The design doc to copy
-     * @param {string} newIndexName - The name of the copy
-     * @returns {object} The copy response
-     */
+var APPS_DOCTYPE = 'io.cozy.apps';
+exports.APPS_DOCTYPE = APPS_DOCTYPE;
 
-  }, {
-    key: "copyIndex",
-    value: function () {
-      var _copyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(existingIndex, newIndexName) {
-        var ddoc, rev, path, options;
-        return _regenerator.default.wrap(function _callee18$(_context18) {
-          while (1) {
-            switch (_context18.prev = _context18.next) {
-              case 0:
-                ddoc = existingIndex._id.split('/')[1];
-                rev = existingIndex._rev;
-                path = (0, _utils.uri)(_templateObject10(), this.doctype, ddoc, rev);
-                options = {
-                  headers: {
-                    Destination: "_design/".concat(newIndexName)
-                  }
-                };
-                return _context18.abrupt("return", this.stackClient.fetchJSON('POST', path, null, options));
+var normalizeApp = function normalizeApp(app, doctype) {
+  return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, app.attributes), app), (0, _DocumentCollection2.normalizeDoc)(app, doctype)), {}, {
+    id: app.id // ignores any 'id' attribute in the manifest
 
-              case 5:
-              case "end":
-                return _context18.stop();
-            }
-          }
-        }, _callee18, this);
-      }));
+  });
+};
+/**
+ * Extends `DocumentCollection` API along with specific methods for `io.cozy.apps`.
+ */
 
-      function copyIndex(_x22, _x23) {
-        return _copyIndex.apply(this, arguments);
-      }
 
-      return copyIndex;
-    }()
-    /**
-     * Find an existing mango index based on the query definition
-     *
-     * This is useful to avoid creating new indexes having the
-     * same definition of an existing one.
-     *
-     * @param {object}            selector  The query selector
-     * @param {MangoQueryOptions} options   The find options
-     *
-     * @returns {object} A matching index if it exists
-     * @private
-     */
+exports.normalizeApp = normalizeApp;
 
-  }, {
-    key: "findExistingIndex",
+var AppCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(AppCollection, _DocumentCollection);
+
+  var _super = _createSuper(AppCollection);
+
+  function AppCollection(stackClient) {
+    var _this;
+
+    (0, _classCallCheck2.default)(this, AppCollection);
+    _this = _super.call(this, APPS_DOCTYPE, stackClient);
+    _this.endpoint = '/apps/';
+    return _this;
+  }
+
+  (0, _createClass2.default)(AppCollection, [{
+    key: "get",
     value: function () {
-      var _findExistingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(selector, options) {
-        var sort, indexedFields, partialFilter, indexes, fieldsToIndex, existingIndex, _iterator2, _step2, index;
+      var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(idArg, query) {
+        var _this2 = this;
 
-        return _regenerator.default.wrap(function _callee19$(_context19) {
+        var id, sources, dataFetchers, _iterator, _step, source, res, data, normalizedDoc;
+
+        return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
-            switch (_context19.prev = _context19.next) {
+            switch (_context.prev = _context.next) {
               case 0:
-                sort = options.sort, indexedFields = options.indexedFields, partialFilter = options.partialFilter;
-                _context19.next = 3;
-                return this.fetchAllMangoIndexes();
+                if (idArg.indexOf('/') > -1) {
+                  id = idArg.split('/')[1];
+                } else {
+                  console.warn("Deprecated: in next versions of cozy-client, it will not be possible to query apps/konnectors only with id, please use the form ".concat(this.doctype, "/").concat(idArg, "\n\n- Q('io.cozy.apps').getById('banks')\n+ Q('io.cozy.apps').getById('io.cozy.apps/banks')"));
+                  id = idArg;
+                }
+
+                if (!(query && query.sources && (!Array.isArray(query.sources) || query.sources.length === 0))) {
+                  _context.next = 3;
+                  break;
+                }
+
+                throw new Error('Invalid "sources" attribute passed in query, please use an array with at least one element.');
 
               case 3:
-                indexes = _context19.sent;
+                sources = (0, _get3.default)(query, 'sources', ['stack']);
+                dataFetchers = {
+                  stack: function stack() {
+                    return _Collection.default.get(_this2.stackClient, "".concat(_this2.endpoint).concat(encodeURIComponent(id)), {
+                      normalize: _this2.constructor.normalizeDoctype(_this2.doctype)
+                    });
+                  },
+                  registry: function registry() {
+                    return _this2.stackClient.fetchJSON('GET', _registry.registryEndpoint + id);
+                  }
+                };
+                _iterator = _createForOfIteratorHelper(sources);
+                _context.prev = 6;
 
-                if (!(indexes.length < 1)) {
-                  _context19.next = 6;
+                _iterator.s();
+
+              case 8:
+                if ((_step = _iterator.n()).done) {
+                  _context.next = 27;
                   break;
                 }
 
-                return _context19.abrupt("return", null);
-
-              case 6:
-                sort = (0, _mangoIndex.transformSort)(sort);
-                fieldsToIndex = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({
-                  sort: sort,
-                  selector: selector
-                });
-                existingIndex = indexes.find(function (index) {
-                  return (0, _mangoIndex.isMatchingIndex)(index, fieldsToIndex, partialFilter);
-                });
-                _iterator2 = _createForOfIteratorHelper(indexes);
-                _context19.prev = 10;
+                source = _step.value;
+                _context.prev = 10;
+                _context.next = 13;
+                return dataFetchers[source]();
 
-                _iterator2.s();
+              case 13:
+                res = _context.sent;
 
-              case 12:
-                if ((_step2 = _iterator2.n()).done) {
-                  _context19.next = 19;
+                if (!(source !== 'registry')) {
+                  _context.next = 16;
                   break;
                 }
 
-                index = _step2.value;
+                return _context.abrupt("return", res);
 
-                if (!(0, _mangoIndex.isInconsistentIndex)(index)) {
-                  _context19.next = 17;
+              case 16:
+                data = (0, _registry.transformRegistryFormatToStackFormat)(res);
+                normalizedDoc = (0, _DocumentCollection2.normalizeDoc)(data, this.doctype);
+                return _context.abrupt("return", {
+                  data: normalizedDoc
+                });
+
+              case 21:
+                _context.prev = 21;
+                _context.t0 = _context["catch"](10);
+
+                if (!(source === sources[sources.length - 1])) {
+                  _context.next = 25;
                   break;
                 }
 
-                _context19.next = 17;
-                return this.destroyIndex(index);
+                throw _context.t0;
 
-              case 17:
-                _context19.next = 12;
+              case 25:
+                _context.next = 8;
                 break;
 
-              case 19:
-                _context19.next = 24;
+              case 27:
+                _context.next = 32;
                 break;
 
-              case 21:
-                _context19.prev = 21;
-                _context19.t0 = _context19["catch"](10);
-
-                _iterator2.e(_context19.t0);
+              case 29:
+                _context.prev = 29;
+                _context.t1 = _context["catch"](6);
 
-              case 24:
-                _context19.prev = 24;
+                _iterator.e(_context.t1);
 
-                _iterator2.f();
+              case 32:
+                _context.prev = 32;
 
-                return _context19.finish(24);
+                _iterator.f();
 
-              case 27:
-                return _context19.abrupt("return", existingIndex);
+                return _context.finish(32);
 
-              case 28:
+              case 35:
               case "end":
-                return _context19.stop();
+                return _context.stop();
             }
           }
-        }, _callee19, this, [[10, 21, 24, 27]]);
+        }, _callee, this, [[6, 29, 32, 35], [10, 21]]);
       }));
 
-      function findExistingIndex(_x24, _x25) {
-        return _findExistingIndex.apply(this, arguments);
+      function get(_x, _x2) {
+        return _get2.apply(this, arguments);
       }
 
-      return findExistingIndex;
+      return get;
     }()
     /**
-     * Calls _changes route from CouchDB
-     * No further treatment is done contrary to fetchchanges
+     * Lists all apps, without filters.
      *
-     * @param {object} couchOptions - Couch options for changes https://kutt.it/5r7MNQ
-     * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned
-     * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents
-     * @param {boolean} [couchOptions.includeDocs] - Includes full documents as part of results
+     * The returned documents are not paginated by the stack.
      *
-     * @see https://docs.couchdb.org/en/stable/api/database/changes.html
+     * @returns {{data, meta, skip, next}} The JSON API conformant response.
+     * @throws {FetchError}
      */
 
   }, {
-    key: "fetchChangesRaw",
+    key: "all",
     value: function () {
-      var _fetchChangesRaw = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(couchOptions) {
-        var hasDocIds, urlParams, method, endpoint, params, result;
-        return _regenerator.default.wrap(function _callee20$(_context20) {
+      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+        var _this3 = this;
+
+        var resp;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
-            switch (_context20.prev = _context20.next) {
+            switch (_context2.prev = _context2.next) {
               case 0:
-                hasDocIds = couchOptions.doc_ids && couchOptions.doc_ids.length > 0;
-                urlParams = "?".concat([_qs.default.stringify(_objectSpread(_objectSpread({}, (0, _omit.default)(couchOptions, ['doc_ids', 'includeDocs'])), {}, {
-                  include_docs: couchOptions.includeDocs
-                })), hasDocIds && couchOptions.filter === undefined ? 'filter=_doc_ids' : undefined].filter(Boolean).join('&'));
-                method = hasDocIds ? 'POST' : 'GET';
-                endpoint = "/data/".concat(this.doctype, "/_changes").concat(urlParams);
-                params = hasDocIds ? {
-                  doc_ids: couchOptions.doc_ids
-                } : undefined;
-                _context20.next = 7;
-                return this.stackClient.fetchJSON(method, endpoint, params);
+                _context2.next = 2;
+                return this.stackClient.fetchJSON('GET', this.endpoint);
 
-              case 7:
-                result = _context20.sent;
-                return _context20.abrupt("return", result);
+              case 2:
+                resp = _context2.sent;
+                return _context2.abrupt("return", {
+                  data: resp.data.map(function (app) {
+                    return normalizeApp(app, _this3.doctype);
+                  }),
+                  meta: {
+                    count: resp.meta.count
+                  },
+                  skip: 0,
+                  next: false
+                });
 
-              case 9:
+              case 4:
               case "end":
-                return _context20.stop();
+                return _context2.stop();
             }
           }
-        }, _callee20, this);
+        }, _callee2, this);
       }));
 
-      function fetchChangesRaw(_x26) {
-        return _fetchChangesRaw.apply(this, arguments);
+      function all() {
+        return _all.apply(this, arguments);
       }
 
-      return fetchChangesRaw;
+      return all;
     }()
-    /**
-     * Use Couch _changes API
-     * Deleted and design docs are filtered by default, thus documents are retrieved in the response
-     * (include_docs is set to true in the parameters of _changes).
-     *
-     * You should use fetchChangesRaw to have low level control on _changes parameters.
-     *
-     * @param {object} couchOptions - Couch options for changes
-     * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned
-     * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents
-     *
-     * @param {object} options - Further options on the returned documents. By default, it is set to { includeDesign: false, includeDeleted: false }
-     * @param {boolean} [options.includeDesign] - Whether to include changes from design docs (needs include_docs to be true)
-     * @param {boolean} [options.includeDeleted] - Whether to include changes for deleted documents (needs include_docs to be true)
-     *
-     * @typedef {object} FetchChangesReturnValue
-     * @property {string} newLastSeq
-     * @property {Array<object>} documents
-     * @returns {FetchChangesReturnValue}
-     */
-
   }, {
-    key: "fetchChanges",
+    key: "create",
     value: function () {
-      var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() {
-        var couchOptions,
-            options,
-            opts,
-            result,
-            newLastSeq,
-            docs,
-            _args21 = arguments;
-        return _regenerator.default.wrap(function _callee21$(_context21) {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
+        return _regenerator.default.wrap(function _callee3$(_context3) {
           while (1) {
-            switch (_context21.prev = _context21.next) {
+            switch (_context3.prev = _context3.next) {
               case 0:
-                couchOptions = _args21.length > 0 && _args21[0] !== undefined ? _args21[0] : {};
-                options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {};
-                opts = {
-                  // Necessary since we deal with deleted and design docs later
-                  includeDocs: true
-                };
-
-                if (typeof couchOptions !== 'object') {
-                  opts.since = couchOptions;
-                  console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"})."));
-                } else if (Object.keys(couchOptions).length > 0) {
-                  Object.assign(opts, couchOptions);
-                }
-
-                _context21.next = 6;
-                return this.fetchChangesRaw(opts);
-
-              case 6:
-                result = _context21.sent;
-                newLastSeq = result.last_seq;
-                docs = result.results.map(function (x) {
-                  return x.doc;
-                }).filter(Boolean);
+                throw new Error('create() method is not available for applications');
 
-                if (!options.includeDesign) {
-                  docs = docs.filter(function (doc) {
-                    return doc._id.indexOf('_design') !== 0;
-                  });
-                }
+              case 1:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3);
+      }));
 
-                if (!options.includeDeleted) {
-                  docs = docs.filter(function (doc) {
-                    return !doc._deleted;
-                  });
-                }
+      function create() {
+        return _create.apply(this, arguments);
+      }
 
-                return _context21.abrupt("return", {
-                  newLastSeq: newLastSeq,
-                  documents: docs
-                });
+      return create;
+    }()
+  }, {
+    key: "update",
+    value: function () {
+      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                throw new Error('update() method is not available for applications');
 
-              case 12:
+              case 1:
               case "end":
-                return _context21.stop();
+                return _context4.stop();
             }
           }
-        }, _callee21, this);
+        }, _callee4);
       }));
 
-      function fetchChanges() {
-        return _fetchChanges.apply(this, arguments);
+      function update() {
+        return _update.apply(this, arguments);
       }
 
-      return fetchChanges;
+      return update;
     }()
-  }], [{
-    key: "normalizeDoctype",
-    value: function normalizeDoctype(doctype) {
-      return this.normalizeDoctypeRawApi(doctype);
-    }
-    /**
-     * `normalizeDoctype` for api end points returning json api responses
-     *
-     * @private
-     * @param {string} doctype - Document doctype
-     * @returns {Function} (data, response) => normalizedDocument
-     *                                        using `normalizeDoc`
-     */
-
   }, {
-    key: "normalizeDoctypeJsonApi",
-    value: function normalizeDoctypeJsonApi(doctype) {
-      return function (data, response) {
-        // use the "data" attribute of the response
-        return normalizeDoc(data, doctype);
-      };
-    }
-    /**
-     * `normalizeDoctype` for api end points returning raw documents
-     *
-     * @private
-     * @param {string} doctype - Document doctype
-     * @returns {Function} (data, response) => normalizedDocument
-     *                                        using `normalizeDoc`
-     */
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                throw new Error('destroy() method is not available for applications');
 
-  }, {
-    key: "normalizeDoctypeRawApi",
-    value: function normalizeDoctypeRawApi(doctype) {
-      return function (data, response) {
-        // use the response directly
-        return normalizeDoc(response, doctype);
-      };
-    }
+              case 1:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5);
+      }));
+
+      function destroy() {
+        return _destroy.apply(this, arguments);
+      }
+
+      return destroy;
+    }()
   }]);
-  return DocumentCollection;
-}();
+  return AppCollection;
+}(_DocumentCollection2.default);
 
-var _default = DocumentCollection;
+AppCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+var _default = AppCollection;
 exports["default"] = _default;
-var normalizeDoctype = DocumentCollection.normalizeDoctype;
-exports.normalizeDoctype = normalizeDoctype;
 
 /***/ }),
-/* 602 */
-/***/ ((module) => {
+/* 603 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _taggedTemplateLiteral(strings, raw) {
-  if (!raw) {
-    raw = strings.slice(0);
+var setPrototypeOf = __webpack_require__(604);
+
+function _inherits(subClass, superClass) {
+  if (typeof superClass !== "function" && superClass !== null) {
+    throw new TypeError("Super expression must either be null or a function");
   }
 
-  return Object.freeze(Object.defineProperties(strings, {
-    raw: {
-      value: Object.freeze(raw)
+  subClass.prototype = Object.create(superClass && superClass.prototype, {
+    constructor: {
+      value: subClass,
+      writable: true,
+      configurable: true
     }
-  }));
+  });
+  if (superClass) setPrototypeOf(subClass, superClass);
 }
 
-module.exports = _taggedTemplateLiteral;
+module.exports = _inherits;
 module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 603 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+/* 604 */
+/***/ ((module) => {
 
-var _flag = _interopRequireDefault(__webpack_require__(604));
+function _setPrototypeOf(o, p) {
+  module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
+    o.__proto__ = p;
+    return o;
+  };
 
-/* global __ENABLED_FLAGS__ */
-if (typeof __ENABLED_FLAGS__ !== 'undefined') {
-  _flag.default.enable(__ENABLED_FLAGS__);
+  module.exports["default"] = module.exports, module.exports.__esModule = true;
+  return _setPrototypeOf(o, p);
 }
 
-var _default = _flag.default;
-exports["default"] = _default;
+module.exports = _setPrototypeOf;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 604 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
+/* 605 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var _typeof = (__webpack_require__(523)["default"]);
 
-var _interopRequireDefault = __webpack_require__(512);
+var assertThisInitialized = __webpack_require__(606);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.initialize = exports.initializeFromDOM = exports.getTemplateData = exports.initializeFromRemote = exports.enable = exports.resetFlags = exports.listFlags = void 0;
+function _possibleConstructorReturn(self, call) {
+  if (call && (_typeof(call) === "object" || typeof call === "function")) {
+    return call;
+  } else if (call !== void 0) {
+    throw new TypeError("Derived constructors may only return object or undefined");
+  }
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+  return assertThisInitialized(self);
+}
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+module.exports = _possibleConstructorReturn;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+/***/ }),
+/* 606 */
+/***/ ((module) => {
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+function _assertThisInitialized(self) {
+  if (self === void 0) {
+    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+  }
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+  return self;
+}
 
-var _store = _interopRequireDefault(__webpack_require__(605));
+module.exports = _assertThisInitialized;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-var _dsl = __webpack_require__(607);
+/***/ }),
+/* 607 */
+/***/ ((module) => {
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+function _getPrototypeOf(o) {
+  module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
+    return o.__proto__ || Object.getPrototypeOf(o);
+  };
+  module.exports["default"] = module.exports, module.exports.__esModule = true;
+  return _getPrototypeOf(o);
+}
 
-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); }
+module.exports = _getPrototypeOf;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-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; }
+/***/ }),
+/* 608 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var store = new _store.default();
-/**
- * Public API to use flags
- */
+"use strict";
 
-var flag = function flag() {
-  var args = [].slice.call(arguments);
 
-  if (args.length === 1) {
-    return store.get(args[0]);
-  } else {
-    store.set(args[0], args[1]);
-    return args[1];
-  }
-};
-/** List all flags from the store */
+var _interopRequireDefault = __webpack_require__(524);
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = exports.registryEndpoint = exports.transformRegistryFormatToStackFormat = void 0;
 
-var listFlags = function listFlags() {
-  return store.keys().sort();
-};
-/** Resets all the flags */
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-exports.listFlags = listFlags;
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var resetFlags = function resetFlags() {
-  listFlags().forEach(function (name) {
-    return store.remove(name);
-  });
-};
-/**
- * Enables several flags
- *
- * Supports passing either  object flagName -> flagValue
- *
- * @param {string[]|Object} flagsToEnable
- */
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-exports.resetFlags = resetFlags;
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-var enable = function enable(flagsToEnable) {
-  var flagNameToValue;
+__webpack_require__(609);
 
-  if (Array.isArray(flagsToEnable)) {
-    // eslint-disable-next-line no-console
-    console.log('flags.enable: Deprecation warning: prefer to use an object { flag1: true, flag2: true } instead of an array when using flags.enable');
-    flagNameToValue = flagsToEnable.map(function (flagName) {
-      return [flagName, true];
-    });
-  } else if (typeof flagsToEnable === 'object') {
-    flagNameToValue = Object.entries(flagsToEnable);
-  }
+var _terms = _interopRequireDefault(__webpack_require__(610));
 
-  if (!flagNameToValue) {
-    return;
-  }
+var _constants = __webpack_require__(611);
 
-  var _iterator = _createForOfIteratorHelper(flagNameToValue),
-      _step;
+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; }
 
-  try {
-    for (_iterator.s(); !(_step = _iterator.n()).done;) {
-      var _step$value = (0, _slicedToArray2.default)(_step.value, 2),
-          flagName = _step$value[0],
-          flagValue = _step$value[1];
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-      flag(flagName, flagValue);
-    }
-  } catch (err) {
-    _iterator.e(err);
-  } finally {
-    _iterator.f();
-  }
+var transformRegistryFormatToStackFormat = function transformRegistryFormatToStackFormat(doc) {
+  return _objectSpread({
+    id: (0, _get.default)(doc, 'latest_version.manifest.source'),
+    attributes: (0, _get.default)(doc, 'latest_version.manifest')
+  }, doc);
 };
-/**
- * Initializes flags from the remote endpoint serving instance flags
- *
- * @private
- * @see  https://docs.cozy.io/en/cozy-stack/settings/#get-settingsflags
- * @param  {CozyClient} client
- */
-
-
-exports.enable = enable;
-
-var initializeFromRemote = /*#__PURE__*/function () {
-  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) {
-    var _yield$client$query, attributes;
-
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            _context.next = 2;
-            return client.query((0, _dsl.Q)('io.cozy.settings').getById('flags'));
-
-          case 2:
-            _yield$client$query = _context.sent;
-            attributes = _yield$client$query.data.attributes;
-            enable(attributes);
-
-          case 5:
-          case "end":
-            return _context.stop();
-        }
-      }
-    }, _callee);
-  }));
-
-  return function initializeFromRemote(_x) {
-    return _ref.apply(this, arguments);
-  };
-}();
 
-exports.initializeFromRemote = initializeFromRemote;
+exports.transformRegistryFormatToStackFormat = transformRegistryFormatToStackFormat;
+var registryEndpoint = '/registry/';
+exports.registryEndpoint = registryEndpoint;
 
-var capitalize = function capitalize(str) {
-  return str[0].toUpperCase() + str.slice(1);
+var queryPartFromOptions = function queryPartFromOptions(options) {
+  var query = new URLSearchParams(options).toString();
+  return query ? "?".concat(query) : '';
 };
 
-var getTemplateData = function getTemplateData(attr) {
-  if (typeof document === 'undefined') {
-    return null;
-  }
-
-  var allDataNode = document.querySelector('[data-cozy]');
-  var attrNode = document.querySelector("[data-cozy-".concat(attr, "]"));
+var getBaseRoute = function getBaseRoute(app) {
+  var type = app.type; // TODO node is an historic type, it should be `konnector`, check with the back
 
-  try {
-    if (allDataNode) {
-      return JSON.parse(allDataNode.dataset.cozy)[attr];
-    } else if (attrNode) {
-      // eslint-disable-next-line no-console
-      console.warn('Prefer to use [data-cozy] to store template data. <div data-cozy="{{.CozyData}}></div>. "');
-      return JSON.parse(attrNode.dataset["cozy".concat(capitalize(attr))]);
-    } else {
-      return null;
-    }
-  } catch (e) {
-    return null;
-  }
+  var route = type === _constants.APP_TYPE.KONNECTOR || type === 'node' ? 'konnectors' : 'apps';
+  return "/".concat(route);
 };
 /**
- * Initialize from the template data injected by cozy-stack into the DOM
- *
- * @private
- * @see https://docs.cozy.io/en/cozy-stack/client-app-dev/#good-practices-for-your-application
- *
- * @returns {Boolean} - False is DOM initialization could not be completed, true otherwise
+ * @typedef {object} RegistryApp
+ * @property {string} slug
+ * @property {object} terms
+ * @property {boolean} installed
  */
 
-
-exports.getTemplateData = getTemplateData;
-
-var initializeFromDOM = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-    var domData;
-    return _regenerator.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            domData = getTemplateData('flags');
-
-            if (domData) {
-              _context2.next = 3;
-              break;
-            }
-
-            return _context2.abrupt("return", false);
-
-          case 3:
-            enable(domData);
-            return _context2.abrupt("return", true);
-
-          case 5:
-          case "end":
-            return _context2.stop();
-        }
-      }
-    }, _callee2);
-  }));
-
-  return function initializeFromDOM() {
-    return _ref2.apply(this, arguments);
-  };
-}();
 /**
- * Initialize flags from DOM if possible, otherwise from remote endpoint
- *
- * @example
- *
- * Flags can be taken from the flags injected by the stack
- * ```
- * <div data-cozy="{{ .CozyData }}"></div>
- *
- * // not recommended but possible
- * <div data-flags="{{ .Flags }}"></div>
- * ````
- *
- * @param  {CozyClient} client - A CozyClient
- * @return {Promise} Resolves when flags have been initialized
+ * @typedef {"dev"|"beta"|"stable"} RegistryAppChannel
  */
 
 
-exports.initializeFromDOM = initializeFromDOM;
-
-var initialize = /*#__PURE__*/function () {
-  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(client) {
-    var domRes;
-    return _regenerator.default.wrap(function _callee3$(_context3) {
-      while (1) {
-        switch (_context3.prev = _context3.next) {
-          case 0:
-            _context3.next = 2;
-            return initializeFromDOM();
-
-          case 2:
-            domRes = _context3.sent;
-
-            if (!(domRes == false)) {
-              _context3.next = 6;
-              break;
-            }
-
-            _context3.next = 6;
-            return initializeFromRemote(client);
-
-          case 6:
-          case "end":
-            return _context3.stop();
-        }
-      }
-    }, _callee3);
-  }));
-
-  return function initialize(_x2) {
-    return _ref3.apply(this, arguments);
-  };
-}();
+var Registry = /*#__PURE__*/function () {
+  function Registry(options) {
+    (0, _classCallCheck2.default)(this, Registry);
 
-exports.initialize = initialize;
+    if (!options.client) {
+      throw new Error('Need to pass a client to instantiate a Registry API.');
+    }
 
-var FlagClientPlugin = /*#__PURE__*/function () {
-  function FlagClientPlugin(client) {
-    (0, _classCallCheck2.default)(this, FlagClientPlugin);
-    this.client = client;
-    this.handleLogin = this.handleLogin.bind(this);
-    this.handleLogout = this.handleLogout.bind(this);
-    this.client.on('login', this.handleLogin);
-    this.client.on('logout', this.handleLogout);
-    this.setupInitializing();
-    if (client.isLogged) this.handleLogin();
+    this.client = options.client;
   }
   /**
-   * Fetches and sets flags from remote
+   * Installs or updates an app from a source.
+   *
+   * Accepts the terms if the app has them.
+   *
+   * @param  {RegistryApp} app - App to be installed
+   * @param  {string} source - String (ex: registry://drive/stable)
+   * @returns {Promise}
    */
 
 
-  (0, _createClass2.default)(FlagClientPlugin, [{
-    key: "refresh",
+  (0, _createClass2.default)(Registry, [{
+    key: "installApp",
     value: function () {
-      var _refresh = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
-        return _regenerator.default.wrap(function _callee4$(_context4) {
+      var _installApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, source) {
+        var slug, terms, searchParams, isUpdate, querypart, verb, baseRoute;
+        return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
-            switch (_context4.prev = _context4.next) {
+            switch (_context.prev = _context.next) {
               case 0:
-                _context4.next = 2;
-                return flag.initializeFromRemote(this.client);
+                slug = app.slug, terms = app.terms;
+                searchParams = {};
+                isUpdate = app.installed;
+                if (isUpdate) searchParams.PermissionsAcked = isUpdate;
+                if (source) searchParams.Source = source;
+                querypart = queryPartFromOptions(searchParams);
 
-              case 2:
+                if (!terms) {
+                  _context.next = 9;
+                  break;
+                }
+
+                _context.next = 9;
+                return _terms.default.save(this.client, terms);
+
+              case 9:
+                verb = app.installed ? 'PUT' : 'POST';
+                baseRoute = getBaseRoute(app);
+                return _context.abrupt("return", this.client.stackClient.fetchJSON(verb, "".concat(baseRoute, "/").concat(slug).concat(querypart)));
+
+              case 12:
               case "end":
-                return _context4.stop();
+                return _context.stop();
             }
           }
-        }, _callee4, this);
+        }, _callee, this);
       }));
 
-      function refresh() {
-        return _refresh.apply(this, arguments);
+      function installApp(_x, _x2) {
+        return _installApp.apply(this, arguments);
       }
 
-      return refresh;
+      return installApp;
     }()
     /**
-     * Sets up a promise that can be awaited to wait for flag complete
-     * initialization
+     * Uninstalls an app.
      */
 
   }, {
-    key: "setupInitializing",
-    value: function setupInitializing() {
-      var _this = this;
-
-      this.initializing = new Promise(function (resolve) {
-        _this.resolveInitializing = resolve;
-      });
-    }
-  }, {
-    key: "handleLogin",
+    key: "uninstallApp",
     value: function () {
-      var _handleLogin = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
-        return _regenerator.default.wrap(function _callee5$(_context5) {
+      var _uninstallApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(app) {
+        var slug, baseRoute;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
-            switch (_context5.prev = _context5.next) {
+            switch (_context2.prev = _context2.next) {
               case 0:
-                _context5.next = 2;
-                return flag.initialize(this.client);
-
-              case 2:
-                this.resolveInitializing();
-                this.client.emit('plugin:flag:login');
+                slug = app.slug;
+                baseRoute = getBaseRoute(app);
+                return _context2.abrupt("return", this.client.stackClient.fetchJSON('DELETE', "".concat(baseRoute, "/").concat(slug)));
 
-              case 4:
+              case 3:
               case "end":
-                return _context5.stop();
+                return _context2.stop();
             }
           }
-        }, _callee5, this);
+        }, _callee2, this);
       }));
 
-      function handleLogin() {
-        return _handleLogin.apply(this, arguments);
+      function uninstallApp(_x3) {
+        return _uninstallApp.apply(this, arguments);
       }
 
-      return handleLogin;
+      return uninstallApp;
     }()
+    /**
+     * Fetch at most 200 apps from the channel
+     *
+     * @param  {object} params - Fetching parameters
+     * @param  {string} params.type - "webapp" or "konnector"
+     * @param  {RegistryAppChannel} params.channel - The channel of the apps to fetch
+     * @param  {string} params.limit - maximum number of fetched apps - defaults to 200
+     *
+     * @returns {Promise<Array<RegistryApp>>}
+     */
+
   }, {
-    key: "handleLogout",
+    key: "fetchApps",
     value: function () {
-      var _handleLogout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
-        return _regenerator.default.wrap(function _callee6$(_context6) {
+      var _fetchApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(params) {
+        var channel, type, _params$limit, limit, searchParams, querypart, _yield$this$client$st, apps;
+
+        return _regenerator.default.wrap(function _callee3$(_context3) {
           while (1) {
-            switch (_context6.prev = _context6.next) {
+            switch (_context3.prev = _context3.next) {
               case 0:
-                flag.reset();
-                this.setupInitializing();
-                this.client.emit('plugin:flag:logout');
+                channel = params.channel, type = params.type, _params$limit = params.limit, limit = _params$limit === void 0 ? '200' : _params$limit;
+                searchParams = {
+                  limit: limit,
+                  versionsChannel: channel,
+                  latestChannelVersion: channel
+                };
+                querypart = new URLSearchParams(searchParams).toString();
 
-              case 3:
+                if (type) {
+                  // Unfortunately, URLSearchParams encodes brackets so we have to do
+                  // the querypart handling manually
+                  querypart = querypart + "&filter[type]=".concat(type);
+                }
+
+                _context3.next = 6;
+                return this.client.stackClient.fetchJSON('GET', "/registry?".concat(querypart));
+
+              case 6:
+                _yield$this$client$st = _context3.sent;
+                apps = _yield$this$client$st.data;
+                return _context3.abrupt("return", apps);
+
+              case 9:
               case "end":
-                return _context6.stop();
+                return _context3.stop();
             }
           }
-        }, _callee6, this);
+        }, _callee3, this);
       }));
 
-      function handleLogout() {
-        return _handleLogout.apply(this, arguments);
+      function fetchApps(_x4) {
+        return _fetchApps.apply(this, arguments);
       }
 
-      return handleLogout;
+      return fetchApps;
     }()
+    /**
+     * Fetch the list of apps that are in maintenance mode
+     *
+     * @returns {Array<RegistryApp>}
+     */
+
+  }, {
+    key: "fetchAppsInMaintenance",
+    value: function fetchAppsInMaintenance() {
+      return this.client.stackClient.fetchJSON('GET', '/registry/maintenance');
+    }
+    /**
+     * Fetch the status of a single app on the registry
+     *
+     * @param  {string} slug - The slug of the app to fetch
+     *
+     * @returns {RegistryApp}
+     */
+
+  }, {
+    key: "fetchApp",
+    value: function fetchApp(slug) {
+      return this.client.stackClient.fetchJSON('GET', "/registry/".concat(slug));
+    }
+    /**
+     * Fetch the latest version of an app for the given channel and slug
+     *
+     * @param  {object} params - Fetching parameters
+     * @param  {string} params.slug - The slug of the app to fetch
+     * @param  {RegistryAppChannel} params.channel - The channel of the app to fetch
+     * @param  {string} params.version - The version of the app to fetch. Can also be "latest"
+     *
+     * @returns {RegistryApp}
+     */
+
+  }, {
+    key: "fetchAppVersion",
+    value: function fetchAppVersion(params) {
+      if (!params.slug) {
+        throw new Error('Need to pass a slug to use fetchAppVersion');
+      }
+
+      var slug = params.slug,
+          channel = params.channel,
+          version = params.version;
+      var finalChannel = !channel && (!version || version === 'latest') ? 'stable' : channel;
+      var url = "/registry/".concat(slug, "/");
+
+      if (finalChannel) {
+        url += "".concat(finalChannel, "/").concat(version || 'latest');
+      } else {
+        url += "".concat(version);
+      }
+
+      return this.client.stackClient.fetchJSON('GET', url);
+    }
   }]);
-  return FlagClientPlugin;
+  return Registry;
 }();
 
-FlagClientPlugin.pluginName = 'flags';
-flag.store = store;
-flag.list = listFlags;
-flag.reset = resetFlags;
-flag.enable = enable;
-flag.initializeFromRemote = initializeFromRemote;
-flag.initializeFromDOM = initializeFromDOM;
-flag.initialize = initialize;
-flag.plugin = FlagClientPlugin;
-var _default = flag;
+var _default = Registry;
 exports["default"] = _default;
 
 /***/ }),
-/* 605 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 609 */
+/***/ (function() {
 
-"use strict";
+/**
+ *
+ *
+ * @author Jerry Bendy <jerry@icewingcc.com>
+ * @licence MIT
+ *
+ */
 
+(function(self) {
+    'use strict';
 
-var _interopRequireDefault = __webpack_require__(512);
+    var nativeURLSearchParams = (function() {
+            // #41 Fix issue in RN
+            try {
+                if (self.URLSearchParams && (new self.URLSearchParams('foo=bar')).get('foo') === 'bar') {
+                    return self.URLSearchParams;
+                }
+            } catch (e) {}
+            return null;
+        })(),
+        isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1',
+        // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus.
+        decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'),
+        __URLSearchParams__ = "__URLSearchParams__",
+        // Fix bug in Edge which cannot encode ' &' correctly
+        encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() {
+            var ampersandTest = new nativeURLSearchParams();
+            ampersandTest.append('s', ' &');
+            return ampersandTest.toString() === 's=+%26';
+        })() : true,
+        prototype = URLSearchParamsPolyfill.prototype,
+        iterable = !!(self.Symbol && self.Symbol.iterator);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+    if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) {
+        return;
+    }
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+    /**
+     * Make a URLSearchParams instance
+     *
+     * @param {object|string|URLSearchParams} search
+     * @constructor
+     */
+    function URLSearchParamsPolyfill(search) {
+        search = search || "";
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+        // support construct object with another URLSearchParams instance
+        if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) {
+            search = search.toString();
+        }
+        this [__URLSearchParams__] = parseToDict(search);
+    }
 
-var _microee = _interopRequireDefault(__webpack_require__(558));
 
-var _lsAdapter = _interopRequireDefault(__webpack_require__(606));
+    /**
+     * Appends a specified key/value pair as a new search parameter.
+     *
+     * @param {string} name
+     * @param {string} value
+     */
+    prototype.append = function(name, value) {
+        appendTo(this [__URLSearchParams__], name, value);
+    };
 
-/**
- * In memory key value storage.
- *
- * Can potentially be backed by localStorage if present
+    /**
+     * Deletes the given search parameter, and its associated value,
+     * from the list of all search parameters.
+     *
+     * @param {string} name
+     */
+    prototype['delete'] = function(name) {
+        delete this [__URLSearchParams__] [name];
+    };
 
- * Emits `change` when a key is set (eventEmitter)
- */
-var FlagStore = /*#__PURE__*/function () {
-  function FlagStore() {
-    (0, _classCallCheck2.default)(this, FlagStore);
-    this.store = {};
+    /**
+     * Returns the first value associated to the given search parameter.
+     *
+     * @param {string} name
+     * @returns {string|null}
+     */
+    prototype.get = function(name) {
+        var dict = this [__URLSearchParams__];
+        return this.has(name) ? dict[name][0] : null;
+    };
 
-    if (typeof localStorage !== 'undefined') {
-      this.longtermStore = _lsAdapter.default;
+    /**
+     * Returns all the values association with a given search parameter.
+     *
+     * @param {string} name
+     * @returns {Array}
+     */
+    prototype.getAll = function(name) {
+        var dict = this [__URLSearchParams__];
+        return this.has(name) ? dict [name].slice(0) : [];
+    };
+
+    /**
+     * Returns a Boolean indicating if such a search parameter exists.
+     *
+     * @param {string} name
+     * @returns {boolean}
+     */
+    prototype.has = function(name) {
+        return hasOwnProperty(this [__URLSearchParams__], name);
+    };
+
+    /**
+     * Sets the value associated to a given search parameter to
+     * the given value. If there were several values, delete the
+     * others.
+     *
+     * @param {string} name
+     * @param {string} value
+     */
+    prototype.set = function set(name, value) {
+        this [__URLSearchParams__][name] = ['' + value];
+    };
+
+    /**
+     * Returns a string containg a query string suitable for use in a URL.
+     *
+     * @returns {string}
+     */
+    prototype.toString = function() {
+        var dict = this[__URLSearchParams__], query = [], i, key, name, value;
+        for (key in dict) {
+            name = encode(key);
+            for (i = 0, value = dict[key]; i < value.length; i++) {
+                query.push(name + '=' + encode(value[i]));
+            }
+        }
+        return query.join('&');
+    };
+
+    // There is a bug in Safari 10.1 and `Proxy`ing it is not enough.
+    var forSureUsePolyfill = !decodesPlusesCorrectly;
+    var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy);
+    var propValue; 
+    if (useProxy) {
+        // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0
+        propValue = new Proxy(nativeURLSearchParams, {
+            construct: function (target, args) {
+                return new target((new URLSearchParamsPolyfill(args[0]).toString()));
+            }
+        })
+        // Chrome <=60 .toString() on a function proxy got error "Function.prototype.toString is not generic"
+        propValue.toString = Function.prototype.toString.bind(URLSearchParamsPolyfill);
+    } else {
+        propValue = URLSearchParamsPolyfill;
     }
+    /*
+     * Apply polifill to global object and append other prototype into it
+     */
+    Object.defineProperty(self, 'URLSearchParams', {
+        value: propValue
+    });
 
-    this.restore();
-  }
+    var USPProto = self.URLSearchParams.prototype;
 
-  (0, _createClass2.default)(FlagStore, [{
-    key: "restore",
-    value: function restore() {
-      if (!this.longtermStore) {
-        return;
-      }
+    USPProto.polyfill = true;
 
-      var allValues = this.longtermStore.getAll();
+    /**
+     *
+     * @param {function} callback
+     * @param {object} thisArg
+     */
+    USPProto.forEach = USPProto.forEach || function(callback, thisArg) {
+        var dict = parseToDict(this.toString());
+        Object.getOwnPropertyNames(dict).forEach(function(name) {
+            dict[name].forEach(function(value) {
+                callback.call(thisArg, value, name, this);
+            }, this);
+        }, this);
+    };
 
-      for (var _i = 0, _Object$entries = Object.entries(allValues); _i < _Object$entries.length; _i++) {
-        var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
-            flag = _Object$entries$_i[0],
-            val = _Object$entries$_i[1];
+    /**
+     * Sort all name-value pairs
+     */
+    USPProto.sort = USPProto.sort || function() {
+        var dict = parseToDict(this.toString()), keys = [], k, i, j;
+        for (k in dict) {
+            keys.push(k);
+        }
+        keys.sort();
+
+        for (i = 0; i < keys.length; i++) {
+            this['delete'](keys[i]);
+        }
+        for (i = 0; i < keys.length; i++) {
+            var key = keys[i], values = dict[key];
+            for (j = 0; j < values.length; j++) {
+                this.append(key, values[j]);
+            }
+        }
+    };
+
+    /**
+     * Returns an iterator allowing to go through all keys of
+     * the key/value pairs contained in this object.
+     *
+     * @returns {function}
+     */
+    USPProto.keys = USPProto.keys || function() {
+        var items = [];
+        this.forEach(function(item, name) {
+            items.push(name);
+        });
+        return makeIterator(items);
+    };
+
+    /**
+     * Returns an iterator allowing to go through all values of
+     * the key/value pairs contained in this object.
+     *
+     * @returns {function}
+     */
+    USPProto.values = USPProto.values || function() {
+        var items = [];
+        this.forEach(function(item) {
+            items.push(item);
+        });
+        return makeIterator(items);
+    };
+
+    /**
+     * Returns an iterator allowing to go through all key/value
+     * pairs contained in this object.
+     *
+     * @returns {function}
+     */
+    USPProto.entries = USPProto.entries || function() {
+        var items = [];
+        this.forEach(function(item, name) {
+            items.push([name, item]);
+        });
+        return makeIterator(items);
+    };
+
+
+    if (iterable) {
+        USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries;
+    }
+
+
+    function encode(str) {
+        var replace = {
+            '!': '%21',
+            "'": '%27',
+            '(': '%28',
+            ')': '%29',
+            '~': '%7E',
+            '%20': '+',
+            '%00': '\x00'
+        };
+        return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) {
+            return replace[match];
+        });
+    }
+
+    function decode(str) {
+        return str
+            .replace(/[ +]/g, '%20')
+            .replace(/(%[a-f0-9]{2})+/ig, function(match) {
+                return decodeURIComponent(match);
+            });
+    }
+
+    function makeIterator(arr) {
+        var iterator = {
+            next: function() {
+                var value = arr.shift();
+                return {done: value === undefined, value: value};
+            }
+        };
+
+        if (iterable) {
+            iterator[self.Symbol.iterator] = function() {
+                return iterator;
+            };
+        }
+
+        return iterator;
+    }
+
+    function parseToDict(search) {
+        var dict = {};
+
+        if (typeof search === "object") {
+            // if `search` is an array, treat it as a sequence
+            if (isArray(search)) {
+                for (var i = 0; i < search.length; i++) {
+                    var item = search[i];
+                    if (isArray(item) && item.length === 2) {
+                        appendTo(dict, item[0], item[1]);
+                    } else {
+                        throw new TypeError("Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements");
+                    }
+                }
+
+            } else {
+                for (var key in search) {
+                    if (search.hasOwnProperty(key)) {
+                        appendTo(dict, key, search[key]);
+                    }
+                }
+            }
+
+        } else {
+            // remove first '?'
+            if (search.indexOf("?") === 0) {
+                search = search.slice(1);
+            }
+
+            var pairs = search.split("&");
+            for (var j = 0; j < pairs.length; j++) {
+                var value = pairs [j],
+                    index = value.indexOf('=');
+
+                if (-1 < index) {
+                    appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));
+
+                } else {
+                    if (value) {
+                        appendTo(dict, decode(value), '');
+                    }
+                }
+            }
+        }
 
-        this.store[flag] = val;
-        this.emit('change', flag);
-      }
-    }
-  }, {
-    key: "keys",
-    value: function keys() {
-      return Object.keys(this.store);
+        return dict;
     }
-  }, {
-    key: "get",
-    value: function get(name) {
-      if (!this.store.hasOwnProperty(name)) {
-        this.store[name] = null;
-      }
 
-      return this.store[name];
-    }
-  }, {
-    key: "set",
-    value: function set(name, value) {
-      if (this.longtermStore) {
-        this.longtermStore.setItem(name, value);
-      }
+    function appendTo(dict, name, value) {
+        var val = typeof value === 'string' ? value : (
+            value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value)
+        );
 
-      this.store[name] = value;
-      this.emit('change', name);
+        // #47 Prevent using `hasOwnProperty` as a property name
+        if (hasOwnProperty(dict, name)) {
+            dict[name].push(val);
+        } else {
+            dict[name] = [val];
+        }
     }
-  }, {
-    key: "remove",
-    value: function remove(name) {
-      delete this.store[name];
 
-      if (this.longtermStore) {
-        this.longtermStore.removeItem(name);
-      }
+    function isArray(val) {
+        return !!val && '[object Array]' === Object.prototype.toString.call(val);
+    }
 
-      this.emit('change', name);
+    function hasOwnProperty(obj, prop) {
+        return Object.prototype.hasOwnProperty.call(obj, prop);
     }
-  }]);
-  return FlagStore;
-}();
 
-_microee.default.mixin(FlagStore);
+})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this));
 
-var _default = FlagStore;
-exports["default"] = _default;
 
 /***/ }),
-/* 606 */
-/***/ ((__unused_webpack_module, exports) => {
+/* 610 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
+var _interopRequireDefault = __webpack_require__(524);
+
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.getKey = exports.prefix = void 0;
+exports["default"] = void 0;
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-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); }
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-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; }
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-/* global localStorage */
-var prefix = 'flag__';
-exports.prefix = prefix;
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var getKey = function getKey(name) {
-  return prefix + name;
-};
+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; }
 
-exports.getKey = getKey;
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var listFlagLocalStorage = function listFlagLocalStorage() {
-  return Object.keys(localStorage).filter(function (x) {
-    return x.indexOf(prefix) === 0;
-  }).map(function (x) {
-    return x.replace(prefix, '');
-  });
-};
-/**
- * Gets a flag from localStorage, parses value from JSON
- *
- * @param  {String} flag
- */
+var TERMS_DOCTYPE = 'io.cozy.terms';
+/* TODO Use collection terms */
 
+function save(_x, _x2) {
+  return _save.apply(this, arguments);
+}
 
-var getItem = function getItem(flag) {
-  var val = localStorage.getItem(getKey(flag));
-  var parsed = val ? JSON.parse(val) : val;
-  return parsed;
-};
-/**
- * Stores a flag in localStorage, stringifies the value for storage
- *
- * @param  {String} flag
- * @param  {String} value
- */
+function _save() {
+  _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, terms) {
+    var id, termsAttributes, _yield$client$query, savedTermsDocs, savedTerms, termsToSave, _termsToSave;
 
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            id = terms.id, termsAttributes = (0, _objectWithoutProperties2.default)(terms, ["id"]);
+            _context.next = 3;
+            return client.query({
+              doctype: TERMS_DOCTYPE,
+              selector: {
+                termsId: id,
+                version: termsAttributes.version
+              },
+              limit: 1
+            });
 
-var setItem = function setItem(flag, value) {
-  var str = JSON.stringify(value);
-  return localStorage.setItem(getKey(flag), str);
-};
-/**
- * Removes a flag from localStorage
- *
- * @param  {String} flag
- */
+          case 3:
+            _yield$client$query = _context.sent;
+            savedTermsDocs = _yield$client$query.data;
 
+            if (!(savedTermsDocs && savedTermsDocs.length)) {
+              _context.next = 13;
+              break;
+            }
 
-var removeItem = function removeItem(flag) {
-  return localStorage.removeItem(getKey(flag));
-};
-/**
- * Returns all stored flags as an object
- */
+            // we just update the url if this is the same id and same version
+            // but the url changed
+            savedTerms = savedTermsDocs[0];
 
+            if (!(savedTerms.termsId == id && savedTerms.version == termsAttributes.version && savedTerms.url != termsAttributes.url)) {
+              _context.next = 11;
+              break;
+            }
 
-var getAll = function getAll() {
-  var res = {};
+            termsToSave = _objectSpread(_objectSpread({
+              _type: TERMS_DOCTYPE
+            }, savedTerms), {}, {
+              url: termsAttributes.url
+            });
+            _context.next = 11;
+            return client.save(termsToSave);
 
-  var _iterator = _createForOfIteratorHelper(listFlagLocalStorage()),
-      _step;
+          case 11:
+            _context.next = 16;
+            break;
 
-  try {
-    for (_iterator.s(); !(_step = _iterator.n()).done;) {
-      var flag = _step.value;
-      res[flag] = getItem(flag);
-    }
-  } catch (err) {
-    _iterator.e(err);
-  } finally {
-    _iterator.f();
-  }
+          case 13:
+            _termsToSave = _objectSpread(_objectSpread({
+              _type: TERMS_DOCTYPE
+            }, termsAttributes), {}, {
+              termsId: id,
+              accepted: true,
+              acceptedAt: new Date()
+            });
+            _context.next = 16;
+            return client.save(_termsToSave);
 
-  return res;
+          case 16:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
+  return _save.apply(this, arguments);
+}
+
+var _default = {
+  save: save
 };
-/**
- * Clears all the flags from localstorage
- */
+exports["default"] = _default;
 
+/***/ }),
+/* 611 */
+/***/ ((__unused_webpack_module, exports) => {
 
-var clearAll = function clearAll() {
-  var _iterator2 = _createForOfIteratorHelper(listFlagLocalStorage()),
-      _step2;
+"use strict";
 
-  try {
-    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
-      var flag = _step2.value;
-      removeItem(flag);
-    }
-  } catch (err) {
-    _iterator2.e(err);
-  } finally {
-    _iterator2.f();
-  }
-};
 
-var _default = {
-  getAll: getAll,
-  getItem: getItem,
-  setItem: setItem,
-  clearAll: clearAll,
-  removeItem: removeItem
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.APP_TYPE = void 0;
+var APP_TYPE = {
+  KONNECTOR: 'konnector',
+  WEBAPP: 'webapp'
 };
-exports["default"] = _default;
+exports.APP_TYPE = APP_TYPE;
 
 /***/ }),
-/* 607 */
+/* 612 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.QueryDefinition = exports.MutationTypes = exports.Mutations = exports.getDoctypeFromOperation = exports.uploadFile = exports.removeReferencedBy = exports.addReferencedBy = exports.removeReferencesTo = exports.addReferencesTo = exports.deleteDocument = exports.updateDocuments = exports.updateDocument = exports.createDocument = exports.isAGetByIdQuery = exports.Q = void 0;
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+exports["default"] = exports.Collection = exports.isDocumentUpdateConflict = exports.isNoUsableIndexError = exports.isIndexConflictError = exports.isIndexNotFoundError = exports.dontThrowNotFoundError = void 0;
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _isArray = _interopRequireDefault(__webpack_require__(55));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _findKey = _interopRequireDefault(__webpack_require__(608));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _types = __webpack_require__(610);
+/**
+ * Handler for error response which return a empty value for "not found" error
+ *
+ * @param  {Error}         error - An error
+ * @param  {Array|object}  data Data to return in case of "not found" error
+ * @returns {object}        JsonAPI response with empty data in case of "not
+ * found" error.
+ */
+var dontThrowNotFoundError = function dontThrowNotFoundError(error) {
+  var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
 
-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; }
+  if (error.message.match(/not_found/)) {
+    var expectsCollection = Array.isArray(data); // Return expected JsonAPI attributes : collections are expecting
+    // meta, skip and next attribute
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+    return expectsCollection ? {
+      data: data,
+      meta: {
+        count: 0
+      },
+      skip: 0,
+      next: false
+    } : {
+      data: data
+    };
+  }
 
+  throw error;
+};
 /**
- * @typedef PartialQueryDefinition
+ * Helper to identify an index not found error
  *
- * @property {Array} [indexedFields]
- * @property {Array} [sort]
- * @property {object} [selector]
+ * @param {Error} error - An error
+ * @returns {boolean} - Whether or not the error is an index not found error
  */
 
-/**
- * @typedef {object} MangoSelector
- */
 
+exports.dontThrowNotFoundError = dontThrowNotFoundError;
+
+var isIndexNotFoundError = function isIndexNotFoundError(error) {
+  return error.message.match(/no_index/);
+};
 /**
- * @typedef {object} MangoPartialFilter
+ * Helper to identify an index conflict
+ *
+ * @param {Error} error - An error
+ * @returns {boolean} - Whether or not the error is an index conflict error
  */
 
+
+exports.isIndexNotFoundError = isIndexNotFoundError;
+
+var isIndexConflictError = function isIndexConflictError(error) {
+  return error.message.match(/error_saving_ddoc/);
+};
 /**
- * Chainable API to create query definitions to retrieve documents
- * from a Cozy. `QueryDefinition`s are sent to links.
+ * Helper to identify a no usable index error
  *
- * @augments {object}
+ * @param {Error} error - An error
+ * @returns {boolean} - Whether or not the error is a no usable index error
  */
-var QueryDefinition = /*#__PURE__*/function () {
-  /**
-   * @class
-   *
-   * @param {object} options Initial options for the query definition
-   * @param {Doctype} [options.doctype] - The doctype of the doc.
-   * @param {DocId|null} [options.id] - The id of the doc.
-   * @param {Array<DocId>} [options.ids] - The ids of the docs.
-   * @param {MangoSelector} [options.selector] - The selector to query the docs.
-   * @param {Array<string>} [options.fields] - The fields to return.
-   * @param {Array<string>} [options.indexedFields] - The fields to index.
-   * @param {MangoPartialFilter} [options.partialFilter] - The partial index definition to filter docs.
-   * @param {Array<object>} [options.sort] - The sorting params.
-   * @param {Array<string>} [options.includes] - The docs to include.
-   * @param {string|null} [options.referenced] - The referenced document.
-   * @param {number|null} [options.limit] - The document's limit to return.
-   * @param {number|null} [options.skip] - The number of docs to skip.
-   * @param {CouchDBViewCursor} [options.cursor] - The cursor to paginate views.
-   * @param {string} [options.bookmark] - The bookmark to paginate mango queries.
-   */
-  function QueryDefinition() {
-    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-    (0, _classCallCheck2.default)(this, QueryDefinition);
-    this.doctype = options.doctype;
-    this.id = options.id;
-    this.ids = options.ids;
-    this.selector = options.selector;
-    this.fields = options.fields;
-    this.indexedFields = options.indexedFields;
-    this.partialFilter = options.partialFilter;
-    this.sort = options.sort;
-    this.includes = options.includes;
-    this.referenced = options.referenced;
-    this.limit = options.limit;
-    this.skip = options.skip;
-    this.cursor = options.cursor;
-    this.bookmark = options.bookmark;
-  }
-  /**
-   * Checks if the sort order matches the index' fields order.
-   *
-   * When sorting with CouchDB, it is required to:
-   * - use indexed fields
-   * - keep the same order than the indexed fields.
-   *
-   * See https://docs.cozy.io/en/tutorials/data/queries/#sort-data-with-mango
-   *
-   * @param {PartialQueryDefinition} obj - A partial QueryDefinition to check
-   */
 
 
-  (0, _createClass2.default)(QueryDefinition, [{
-    key: "checkSortOrder",
-    value: function checkSortOrder(_ref) {
-      var sort = _ref.sort,
-          selector = _ref.selector,
-          indexedFields = _ref.indexedFields;
+exports.isIndexConflictError = isIndexConflictError;
 
-      var _sort = this.sort || sort;
+var isNoUsableIndexError = function isNoUsableIndexError(error) {
+  return error.message.match(/no_usable_index/);
+};
+/**
+ * Helper to identify a document conflict
+ *
+ * @param {Error} error - An error
+ * @returns {boolean} - Whether or not the error is a document conflict error
+ */
 
-      var _selector = this.selector || selector || {};
 
-      var _indexedFields = this.indexedFields || indexedFields;
+exports.isNoUsableIndexError = isNoUsableIndexError;
 
-      if (!_sort) {
-        return;
-      }
+var isDocumentUpdateConflict = function isDocumentUpdateConflict(error) {
+  return error.message.match(/Document update conflict/);
+};
+/**
+ * Utility class to abstract an regroup identical methods and logics for
+ * specific collections.
+ */
 
-      var fieldsToIndex = _indexedFields || Object.keys(_selector);
 
-      if (!fieldsToIndex || fieldsToIndex.length < 1) {
-        return;
-      }
+exports.isDocumentUpdateConflict = isDocumentUpdateConflict;
 
-      if (_sort.length > fieldsToIndex.length) {
-        console.warn("You should not sort on non-indexed fields.\n\n        Sort: ".concat(JSON.stringify(_sort), "\n\n        Indexed fields: ").concat(fieldsToIndex));
-        return;
-      }
+var Collection = /*#__PURE__*/function () {
+  function Collection() {
+    (0, _classCallCheck2.default)(this, Collection);
+  }
+
+  (0, _createClass2.default)(Collection, null, [{
+    key: "get",
 
-      for (var i = 0; i < _sort.length; i++) {
-        if (Object.keys(_sort[i])[0] !== fieldsToIndex[i]) {
-          console.warn("The sort order should be the same than the indexed fields.\n\n          Sort: ".concat(JSON.stringify(_sort), "\n\n          Indexed fields: ").concat(fieldsToIndex, "\n"));
-          return;
-        }
-      }
-    }
     /**
-     * Checks the selector predicates.
-     *
-     * It is useful to warn the developer when a partial index might be used.
+     * Utility method aimed to return only one document.
      *
-     * @param {MangoSelector} selector - The selector definition
-     * @returns {void}
+     * @param  {CozyStackClient}  stackClient - CozyStackClient
+     * @param  {string}  endpoint - Stack endpoint
+     * @param  {object}  options - Options of the collection
+     * @param  {Function}    options.normalize Callback to normalize response data
+     * (default `data => data`)
+     * @param  {string}  options.method    HTTP method (default `GET`)
+     * @returns {object}  JsonAPI response containing normalized
+     * document as data attribute
      */
+    value: function () {
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(stackClient, endpoint, _ref) {
+        var _ref$normalize, normalize, _ref$method, method, resp;
 
-  }, {
-    key: "checkSelector",
-    value: function checkSelector(selector) {
-      var hasExistsFalse = (0, _findKey.default)(selector, ['$exists', false]);
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _ref$normalize = _ref.normalize, normalize = _ref$normalize === void 0 ? function (data, response) {
+                  return data;
+                } : _ref$normalize, _ref$method = _ref.method, method = _ref$method === void 0 ? 'GET' : _ref$method;
+                _context.prev = 1;
+                _context.next = 4;
+                return stackClient.fetchJSON(method, endpoint);
 
-      if (hasExistsFalse) {
-        console.warn("The \"$exists: false\" predicate should be defined as a partial index for better performance.\n\n        Selector: ".concat(selector));
-      }
+              case 4:
+                resp = _context.sent;
+                return _context.abrupt("return", {
+                  data: normalize(resp.data, resp)
+                });
 
-      var hasNe = (0, _findKey.default)(selector, '$ne');
+              case 8:
+                _context.prev = 8;
+                _context.t0 = _context["catch"](1);
+                return _context.abrupt("return", dontThrowNotFoundError(_context.t0, null));
 
-      if (hasNe) {
-        console.info("The use of the $ne operator is more efficient with a partial index.\n\n        Selector: ".concat(selector));
-      }
-    }
-    /**
-     * Query a single document on its id.
-     *
-     * @param {string} id   The document id.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+              case 11:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, null, [[1, 8]]);
+      }));
 
-  }, {
-    key: "getById",
-    value: function getById(id) {
-      if (!id) {
-        throw new Error('getById called with undefined id');
+      function get(_x, _x2, _x3) {
+        return _get.apply(this, arguments);
       }
 
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        id: id
-      }));
-    }
-    /**
-     * Query several documents on their ids.
-     *
-     * @param {Array} ids   The documents ids.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+      return get;
+    }()
+  }]);
+  return Collection;
+}();
 
-  }, {
-    key: "getByIds",
-    value: function getByIds(ids) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        ids: ids
-      }));
-    }
-    /**
-     * Query documents with a [mango selector](http://docs.couchdb.org/en/latest/api/database/find.html#find-selectors).
-     * Each field passed in the selector will be indexed, except if the indexField option is used.
-     *
-     * @param {MangoSelector} selector   The Mango selector.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+exports.Collection = Collection;
+var _default = Collection;
+exports["default"] = _default;
 
-  }, {
-    key: "where",
-    value: function where(selector) {
-      this.checkSortOrder({
-        selector: selector
-      });
-      this.checkSelector(selector);
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        selector: selector
-      }));
-    }
-    /**
-     * Specify which fields of each object should be returned. If it is omitted, the entire object is returned.
-     *
-     * @param {Array} fields The fields to return.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+/***/ }),
+/* 613 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  }, {
-    key: "select",
-    value: function select(fields) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        fields: fields
-      }));
-    }
-    /**
-     * Specify which fields should be indexed. This prevent the automatic indexing of the mango fields.
-     *
-     * @param {Array} indexedFields The fields to index.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+"use strict";
 
-  }, {
-    key: "indexFields",
-    value: function indexFields(indexedFields) {
-      this.checkSortOrder({
-        indexedFields: indexedFields
-      });
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        indexedFields: indexedFields
-      }));
-    }
-    /**
-     * Specify a [partial index](https://docs.couchdb.org/en/stable/api/database/find.html#find-partial-indexes).
-     * The filter must follow the same syntax than the selector.
-     *
-     * A partial index includes a filter, used to select documents before the indexing.
-     * You can find more information about partial indexes [here](https://docs.cozy.io/en/tutorials/data/advanced/#partial-indexes)
-     *
-     * @param {object} partialFilter - The filter definition.
-     */
 
-  }, {
-    key: "partialIndex",
-    value: function partialIndex(partialFilter) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        partialFilter: partialFilter
-      }));
-    }
-    /**
-     * Specify how to sort documents, following the [sort syntax](http://docs.couchdb.org/en/latest/api/database/find.html#find-sort)
-     *
-     * @param {Array} sort The list of field name and direction pairs.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+var _interopRequireWildcard = __webpack_require__(522);
 
-  }, {
-    key: "sortBy",
-    value: function sortBy(sort) {
-      if (!(0, _isArray.default)(sort)) {
-        throw new Error("Invalid sort, should be an array ([{ label: \"desc\"}, { name: \"asc\"}]), you passed ".concat(JSON.stringify(sort), "."));
-      }
+var _interopRequireDefault = __webpack_require__(524);
 
-      this.checkSortOrder({
-        sort: sort
-      });
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        sort: sort
-      }));
-    }
-    /**
-     * Includes documents having a relationships with the ones queried.
-     * For example, query albums including the photos.
-     *
-     * @param {Array} includes The documents to include.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.normalizeDoc = normalizeDoc;
+exports.normalizeDoctype = exports["default"] = void 0;
 
-  }, {
-    key: "include",
-    value: function include(includes) {
-      if (!Array.isArray(includes)) {
-        throw new Error('include() takes an array of relationship names');
-      }
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        includes: includes
-      }));
-    }
-    /**
-     * Maximum number of documents returned, useful for pagination. Default is 100.
-     *
-     * @param {number} limit The document's limit.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-  }, {
-    key: "limitBy",
-    value: function limitBy(limit) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        limit: limit
-      }));
-    }
-  }, {
-    key: "UNSAFE_noLimit",
-    value: function UNSAFE_noLimit() {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        limit: null
-      }));
-    }
-    /**
-     * Skip the first ‘n’ documents, where ‘n’ is the value specified.
-     *
-     * Beware, this [performs badly](http://docs.couchdb.org/en/stable/ddocs/views/pagination.html#paging-alternate-method) on view's index.
-     *  Prefer cursor-based pagination in such situation.
-     *
-     * @param {number} skip The number of documents to skip.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-  }, {
-    key: "offset",
-    value: function offset(skip) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        bookmark: undefined,
-        cursor: undefined,
-        skip: skip
-      }));
-    }
-    /**
-     * Use [cursor-based](https://docs.cozy.io/en/cozy-stack/jsonapi/#pagination) pagination.
-     * *Warning*: this is only useful for views.
-     * The cursor is a [startkey, startkey_docid] array, where startkey is the view's key,
-     * e.g. ["io.cozy.photos.albums", "album-id"] and startkey_docid is the id of
-     * the starting document of the query, e.g. "file-id".
-     * Use the last docid of each query as startkey_docid to paginate or leave blank for the first query.
-     *
-     * @param {CouchDBViewCursor} cursor The cursor for pagination.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-  }, {
-    key: "offsetCursor",
-    value: function offsetCursor(cursor) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        bookmark: undefined,
-        skip: undefined,
-        cursor: cursor
-      }));
-    }
-    /**
-     * Use [bookmark](https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination) pagination.
-     * Note this only applies for mango-queries (not views) and is way more efficient than skip pagination.
-     * The bookmark is a string returned by the _find response and can be seen as a pointer in
-     * the index for the next query.
-     *
-     * @param {string} bookmark The bookmark to continue a previous paginated query.
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-  }, {
-    key: "offsetBookmark",
-    value: function offsetBookmark(bookmark) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        skip: undefined,
-        cursor: undefined,
-        bookmark: bookmark
-      }));
-    }
-    /**
-     * Use the [file reference system](https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/)
-     *
-     * @param {object} document The reference document
-     * @returns {QueryDefinition}  The QueryDefinition object.
-     */
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-  }, {
-    key: "referencedBy",
-    value: function referencedBy(document) {
-      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
-        referenced: document
-      }));
-    }
-  }, {
-    key: "toDefinition",
-    value: function toDefinition() {
-      return {
-        doctype: this.doctype,
-        id: this.id,
-        ids: this.ids,
-        selector: this.selector,
-        fields: this.fields,
-        indexedFields: this.indexedFields,
-        partialFilter: this.partialFilter,
-        sort: this.sort,
-        includes: this.includes,
-        referenced: this.referenced,
-        limit: this.limit,
-        skip: this.skip,
-        cursor: this.cursor,
-        bookmark: this.bookmark
-      };
-    }
-  }]);
-  return QueryDefinition;
-}();
-/**
- * Helper to create a QueryDefinition. Recommended way to create
- * query definitions.
- *
- * @param {Doctype} doctype - Doctype of the query definition
- *
- * @example
- * ```
- * import { Q } from 'cozy-client'
- *
- * const qDef = Q('io.cozy.todos').where({ _id: '1234' })
- * ```
- */
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-exports.QueryDefinition = QueryDefinition;
+var _cozyFlags = _interopRequireDefault(__webpack_require__(615));
 
-var Q = function Q(doctype) {
-  return new QueryDefinition({
-    doctype: doctype
-  });
-};
-/**
- * Check if the query is a getById() query
- *
- * @param {QueryDefinition} queryDefinition The query definition
- *
- * @returns {boolean}
- */
+var _utils = __webpack_require__(623);
 
+var _uniq = _interopRequireDefault(__webpack_require__(624));
 
-exports.Q = Q;
+var _omit = _interopRequireDefault(__webpack_require__(625));
 
-var isAGetByIdQuery = function isAGetByIdQuery(queryDefinition) {
-  if (!queryDefinition) return false;
-  var attributes = Object.values(queryDefinition);
-  if (attributes.length === 0) return false; // 2 attrs because we check if id and doctype are not undefined
+var _head = _interopRequireDefault(__webpack_require__(633));
 
-  return attributes.filter(function (attr) {
-    return attr !== undefined;
-  }).length === 2 && queryDefinition.id !== undefined;
-}; // Mutations
+var _startsWith = _interopRequireDefault(__webpack_require__(634));
 
+var _qs = _interopRequireDefault(__webpack_require__(641));
 
-exports.isAGetByIdQuery = isAGetByIdQuery;
-var CREATE_DOCUMENT = 'CREATE_DOCUMENT';
-var UPDATE_DOCUMENT = 'UPDATE_DOCUMENT';
-var UPDATE_DOCUMENTS = 'UPDATE_DOCUMENTS';
-var DELETE_DOCUMENT = 'DELETE_DOCUMENT';
-var ADD_REFERENCES_TO = 'ADD_REFERENCES_TO';
-var REMOVE_REFERENCES_TO = 'REMOVE_REFERENCES_TO';
-var ADD_REFERENCED_BY = 'ADD_REFERENCED_BY';
-var REMOVE_REFERENCED_BY = 'REMOVE_REFERENCED_BY';
-var UPLOAD_FILE = 'UPLOAD_FILE';
+var _mangoIndex = __webpack_require__(657);
 
-var createDocument = function createDocument(document) {
-  return {
-    mutationType: MutationTypes.CREATE_DOCUMENT,
-    document: document
-  };
-};
+var _Collection = _interopRequireWildcard(__webpack_require__(612));
 
-exports.createDocument = createDocument;
+var querystring = _interopRequireWildcard(__webpack_require__(659));
 
-var updateDocument = function updateDocument(document) {
-  return {
-    mutationType: MutationTypes.UPDATE_DOCUMENT,
-    document: document
-  };
-};
+var _errors = __webpack_require__(663);
 
-exports.updateDocument = updateDocument;
+function _templateObject10() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "/copy?rev=", ""]);
 
-var updateDocuments = function updateDocuments(documents) {
-  return {
-    mutationType: MutationTypes.UPDATE_DOCUMENTS,
-    documents: documents
+  _templateObject10 = function _templateObject10() {
+    return data;
   };
-};
 
-exports.updateDocuments = updateDocuments;
+  return data;
+}
 
-var deleteDocument = function deleteDocument(document) {
-  return {
-    mutationType: MutationTypes.DELETE_DOCUMENT,
-    document: document
+function _templateObject9() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "?rev=", ""]);
+
+  _templateObject9 = function _templateObject9() {
+    return data;
   };
-};
 
-exports.deleteDocument = deleteDocument;
+  return data;
+}
 
-var addReferencesTo = function addReferencesTo(document, referencedDocuments) {
-  return {
-    mutationType: MutationTypes.ADD_REFERENCES_TO,
-    referencedDocuments: referencedDocuments,
-    document: document
+function _templateObject8() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design_docs?include_docs=true"]);
+
+  _templateObject8 = function _templateObject8() {
+    return data;
   };
-};
 
-exports.addReferencesTo = addReferencesTo;
+  return data;
+}
 
-var removeReferencesTo = function removeReferencesTo(document, referencedDocuments) {
-  return {
-    mutationType: MutationTypes.REMOVE_REFERENCES_TO,
-    referencedDocuments: referencedDocuments,
-    document: document
+function _templateObject7() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_index"]);
+
+  _templateObject7 = function _templateObject7() {
+    return data;
   };
-};
 
-exports.removeReferencesTo = removeReferencesTo;
+  return data;
+}
 
-var addReferencedBy = function addReferencedBy(document, referencedDocuments) {
-  return {
-    mutationType: MutationTypes.ADD_REFERENCED_BY,
-    referencedDocuments: referencedDocuments,
-    document: document
-  };
-};
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-exports.addReferencedBy = addReferencedBy;
+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); }
 
-var removeReferencedBy = function removeReferencedBy(document, referencedDocuments) {
-  return {
-    mutationType: MutationTypes.REMOVE_REFERENCED_BY,
-    referencedDocuments: referencedDocuments,
-    document: document
-  };
-};
+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; }
 
-exports.removeReferencedBy = removeReferencedBy;
+function _templateObject6() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "?rev=", ""]);
 
-var uploadFile = function uploadFile(file, dirPath) {
-  return {
-    mutationType: MutationTypes.UPLOAD_FILE,
-    file: file,
-    dirPath: dirPath
+  _templateObject6 = function _templateObject6() {
+    return data;
   };
-};
 
-exports.uploadFile = uploadFile;
+  return data;
+}
 
-var getDoctypeFromOperation = function getDoctypeFromOperation(operation) {
-  if (operation.mutationType) {
-    var type = operation.mutationType;
+function _templateObject5() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]);
 
-    switch (type) {
-      case CREATE_DOCUMENT:
-        return operation.document._type;
+  _templateObject5 = function _templateObject5() {
+    return data;
+  };
 
-      case UPDATE_DOCUMENT:
-        return operation.document._type;
+  return data;
+}
 
-      case UPDATE_DOCUMENTS:
-        return operation.documents[0]._type;
+function _templateObject4() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]);
 
-      case DELETE_DOCUMENT:
-        return operation.document._type;
+  _templateObject4 = function _templateObject4() {
+    return data;
+  };
 
-      case ADD_REFERENCES_TO:
-        throw new Error('Not implemented');
+  return data;
+}
 
-      case UPLOAD_FILE:
-        throw new Error('Not implemented');
+function _templateObject3() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_all_docs?include_docs=true"]);
 
-      default:
-        throw new Error("Unknown mutationType ".concat(type));
-    }
-  } else {
-    return operation.doctype;
-  }
-};
+  _templateObject3 = function _templateObject3() {
+    return data;
+  };
 
-exports.getDoctypeFromOperation = getDoctypeFromOperation;
-var Mutations = {
-  createDocument: createDocument,
-  updateDocument: updateDocument,
-  updateDocuments: updateDocuments,
-  deleteDocument: deleteDocument,
-  addReferencesTo: addReferencesTo,
-  removeReferencesTo: removeReferencesTo,
-  addReferencedBy: addReferencedBy,
-  removeReferencedBy: removeReferencedBy,
-  uploadFile: uploadFile
-};
-exports.Mutations = Mutations;
-var MutationTypes = {
-  CREATE_DOCUMENT: CREATE_DOCUMENT,
-  UPDATE_DOCUMENT: UPDATE_DOCUMENT,
-  UPDATE_DOCUMENTS: UPDATE_DOCUMENTS,
-  DELETE_DOCUMENT: DELETE_DOCUMENT,
-  ADD_REFERENCES_TO: ADD_REFERENCES_TO,
-  REMOVE_REFERENCES_TO: REMOVE_REFERENCES_TO,
-  ADD_REFERENCED_BY: ADD_REFERENCED_BY,
-  REMOVE_REFERENCED_BY: REMOVE_REFERENCED_BY,
-  UPLOAD_FILE: UPLOAD_FILE
-};
-exports.MutationTypes = MutationTypes;
+  return data;
+}
 
-/***/ }),
-/* 608 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function _templateObject2() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_find"]);
 
-var baseFindKey = __webpack_require__(609),
-    baseForOwn = __webpack_require__(536),
-    baseIteratee = __webpack_require__(401);
+  _templateObject2 = function _templateObject2() {
+    return data;
+  };
 
-/**
- * This method is like `_.find` except that it returns the key of the first
- * element `predicate` returns truthy for instead of the element itself.
- *
- * @static
- * @memberOf _
- * @since 1.1.0
- * @category Object
- * @param {Object} object The object to inspect.
- * @param {Function} [predicate=_.identity] The function invoked per iteration.
- * @returns {string|undefined} Returns the key of the matched element,
- *  else `undefined`.
- * @example
- *
- * var users = {
- *   'barney':  { 'age': 36, 'active': true },
- *   'fred':    { 'age': 40, 'active': false },
- *   'pebbles': { 'age': 1,  'active': true }
- * };
- *
- * _.findKey(users, function(o) { return o.age < 40; });
- * // => 'barney' (iteration order is not guaranteed)
- *
- * // The `_.matches` iteratee shorthand.
- * _.findKey(users, { 'age': 1, 'active': true });
- * // => 'pebbles'
- *
- * // The `_.matchesProperty` iteratee shorthand.
- * _.findKey(users, ['active', false]);
- * // => 'fred'
- *
- * // The `_.property` iteratee shorthand.
- * _.findKey(users, 'active');
- * // => 'barney'
- */
-function findKey(object, predicate) {
-  return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn);
+  return data;
 }
 
-module.exports = findKey;
+function _templateObject() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]);
 
+  _templateObject = function _templateObject() {
+    return data;
+  };
 
-/***/ }),
-/* 609 */
-/***/ ((module) => {
+  return data;
+}
+
+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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
+var DATABASE_DOES_NOT_EXIST = 'Database does not exist.';
 /**
- * The base implementation of methods like `_.findKey` and `_.findLastKey`,
- * without support for iteratee shorthands, which iterates over `collection`
- * using `eachFunc`.
+ * Normalize a document, adding its doctype if needed
  *
+ * @param {object} doc - Document to normalize
+ * @param {string} doctype - Document doctype
+ * @returns {object} normalized document
  * @private
- * @param {Array|Object} collection The collection to inspect.
- * @param {Function} predicate The function invoked per iteration.
- * @param {Function} eachFunc The function to iterate over `collection`.
- * @returns {*} Returns the found element or its key, else `undefined`.
  */
-function baseFindKey(collection, predicate, eachFunc) {
-  var result;
-  eachFunc(collection, function(value, key, collection) {
-    if (predicate(value, key, collection)) {
-      result = key;
-      return false;
-    }
-  });
-  return result;
+
+function normalizeDoc() {
+  var doc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  var doctype = arguments.length > 1 ? arguments[1] : undefined;
+  var id = doc._id || doc.id;
+  return _objectSpread({
+    id: id,
+    _id: id,
+    _type: doctype
+  }, doc);
 }
 
-module.exports = baseFindKey;
+var prepareForDeletion = function prepareForDeletion(x) {
+  return Object.assign({}, (0, _omit.default)(x, '_type'), {
+    _deleted: true
+  });
+};
+/**
+ * Abstracts a collection of documents of the same doctype, providing CRUD methods and other helpers.
+ */
+
 
+var DocumentCollection = /*#__PURE__*/function () {
+  function DocumentCollection(doctype, stackClient) {
+    (0, _classCallCheck2.default)(this, DocumentCollection);
+    this.doctype = doctype;
+    this.stackClient = stackClient;
+    this.indexes = {};
+    this.endpoint = "/data/".concat(this.doctype, "/");
+  }
+  /**
+   * Provides a callback for `Collection.get`
+   *
+   * @private
+   * @param {string} doctype - Document doctype
+   * @returns {Function} (data, response) => normalizedDocument
+   *                                        using `normalizeDoc`
+   */
 
-/***/ }),
-/* 610 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-"use strict";
+  (0, _createClass2.default)(DocumentCollection, [{
+    key: "all",
 
+    /**
+     * Lists all documents of the collection, without filters.
+     *
+     * The returned documents are paginated by the stack.
+     *
+     * @param  {{limit, skip, bookmark, keys}} options The fetch options: pagination & fetch of specific docs.
+     * @returns {{data, meta, skip, bookmark, next}} The JSON API conformant response.
+     * @throws {FetchError}
+     */
+    value: function () {
+      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var _this = this;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+        var options,
+            _options$limit,
+            limit,
+            _options$skip,
+            skip,
+            bookmark,
+            keys,
+            isUsingAllDocsRoute,
+            route,
+            url,
+            params,
+            path,
+            resp,
+            data,
+            next,
+            _args = arguments;
 
-var _dsl = __webpack_require__(607);
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
+                _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip, bookmark = options.bookmark, keys = options.keys; // If the limit is intentionnally null, we need to use _all_docs, since
+                // _normal_docs uses _find and has a hard limit of 1000
 
-/**
- * @typedef {"io.cozy.accounts"} AccountsDoctype
- * @typedef {"io.cozy.triggers"} TriggersDoctype
- * @typedef {"io.cozy.konnectors"} KonnectorsDoctype
- * @typedef {"io.cozy.notes"} NotesDoctype
- * @typedef {"io.cozy.apps"} AppsDoctype
- * @typedef {"io.cozy.settings"} SettingsDoctype
- * @typedef {"io.cozy-oauth.clients"} OAuthClientsDoctype
- * @typedef {"io.cozy.files"} FilesDoctype
- * @typedef {AccountsDoctype|TriggersDoctype|KonnectorsDoctype|NotesDoctype|AppsDoctype|SettingsDoctype|OAuthClientsDoctype|FilesDoctype} KnownDoctype
- * @typedef {KnownDoctype|string} Doctype
- */
+                isUsingAllDocsRoute = !!keys || limit === null;
+                route = isUsingAllDocsRoute ? '_all_docs' : '_normal_docs';
+                url = (0, _utils.uri)(_templateObject(), this.doctype, route);
+                params = {
+                  include_docs: true,
+                  limit: limit,
+                  skip: skip,
+                  keys: keys,
+                  bookmark: bookmark
+                };
+                path = querystring.buildURL(url, params); // If no document of this doctype exist, this route will return a 404,
+                // so we need to try/catch and return an empty response object in case of a 404
 
-/**
- * @typedef {object} Link
- * @typedef {object} Mutation
- * @typedef {object} DocumentCollection
- * @typedef {object} QueryResult
- * @typedef {object} HydratedDocument
- * @typedef {object} ReduxStore
- * @typedef {object} Token
- * @typedef {object} ClientResponse
- * @typedef {object} Manifest
- */
+                _context.prev = 7;
+                _context.next = 10;
+                return this.stackClient.fetchJSON('GET', path);
 
-/**
- * @typedef {object} OldCozyClient
- */
+              case 10:
+                resp = _context.sent;
+                _context.next = 16;
+                break;
 
-/**
- * @typedef {object} NodeEnvironment
- */
+              case 13:
+                _context.prev = 13;
+                _context.t0 = _context["catch"](7);
+                return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0));
 
-/**
- * @typedef {"loading"|"loaded"|"pending"|"failed"} QueryFetchStatus
- */
+              case 16:
+                /* If using `all_docs` we need to filter our design documents and check if
+                the document is not null. If we use `normal_doc` we can't have any design doc
+                 */
+                if (isUsingAllDocsRoute) {
+                  data = resp.rows.filter(function (doc) {
+                    return doc && doc.doc !== null && !doc.error && !(0, _startsWith.default)(doc.id, '_design');
+                  }).map(function (row) {
+                    return normalizeDoc(row.doc, _this.doctype);
+                  });
+                } else {
+                  data = resp.rows.map(function (row) {
+                    return normalizeDoc(row, _this.doctype);
+                  });
+                } // The presence of a bookmark doesn’t guarantee that there are more results.
+                // See https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination
 
-/**
- * @typedef {Record<Doctype, QueryState>} QueriesStateSlice
- */
 
-/**
- * @typedef {Record<string, CozyClientDocument>} IndexedDocuments
- */
+                next = bookmark ? resp.rows.length >= limit : skip + resp.rows.length < resp.total_rows;
+                return _context.abrupt("return", {
+                  data: data,
+                  meta: {
+                    count: isUsingAllDocsRoute ? data.length : resp.total_rows
+                  },
+                  skip: skip,
+                  bookmark: resp.bookmark,
+                  next: next
+                });
 
-/**
- * @typedef {Record<Doctype, IndexedDocuments>} DocumentsStateSlice
- */
+              case 19:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this, [[7, 13]]);
+      }));
 
-/**
- * @typedef {object} QueryState
- * @property {string} id
- * @property {QueryDefinition} definition
- * @property {QueryFetchStatus} fetchStatus
- * @property {number} lastFetch
- * @property {number} lastUpdate
- * @property {number} lastErrorUpdate
- * @property {Error} lastError
- * @property {boolean} hasMore
- * @property {number} count
- * @property {object|Array} data
- * @property {string} bookmark
- * @property {object} [execution_stats]
- * @property {QueryOptions} [options]
- */
+      function all() {
+        return _all.apply(this, arguments);
+      }
 
-/**
- * @typedef {object} AutoUpdateOptions
- * @param {boolean} update - Should documents be updated in the query (default: true)
- * @param {boolean} add - Should documents be added to the query (default: true)
- * @param {boolean} remove - Should documents be removed from the query (default: true)
- */
+      return all;
+    }()
+  }, {
+    key: "fetchDocumentsWithMango",
+    value: function () {
+      var _fetchDocumentsWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(path, selector) {
+        var options,
+            _args2 = arguments;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {};
+                return _context2.abrupt("return", this.stackClient.fetchJSON('POST', path, this.toMangoOptions(selector, options)));
 
-/**
- * @typedef {object} QueryOptions
- * @property {string} [as] - Name of the query
- * @property {Function} [fetchPolicy] - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies"
- * @property {AutoUpdateOptions} [autoUpdate] - Options for the query auto update
- * @property {string} [update] - Does not seem to be used
- * @property {Function} [onError] - Callback when the query is errored
- * @property {boolean} [enabled=true] - If set to false, the query won't be executed
- * @property {object} [hydrated=true] - Whether documents should be returned already hydrated
- * @property {object} [singleDocData] - If true, the "data" returned will be
- * a single doc instead of an array for single doc queries. Defaults to false for backward
- * compatibility but will be set to true in the future.
- */
+              case 2:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
 
-/**
- * @typedef {object} FetchMoreAble
- * @property {Function} fetchMore
- */
+      function fetchDocumentsWithMango(_x, _x2) {
+        return _fetchDocumentsWithMango.apply(this, arguments);
+      }
 
-/**
- * @typedef {object} FetchAble
- * @property {Function} fetch
- */
+      return fetchDocumentsWithMango;
+    }()
+    /**
+     * Migrate an existing unamed index to a named one.
+     *
+     * Index migration became necessary for optimistic index, because
+     * we started to use named index while we used to have unamed index,
+     * i.e. indexes with CouchDB-generated ID.
+     *
+     * @param {object} sourceIndex - The index to migrate
+     * @param {string} targetIndexName - The new index name
+     * @private
+     */
 
-/**
- * @typedef {QueryState & FetchMoreAble & FetchAble} UseQueryReturnValue
- */
+  }, {
+    key: "migrateUnamedIndex",
+    value: function () {
+      var _migrateUnamedIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sourceIndex, targetIndexName) {
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                _context3.prev = 0;
+                _context3.next = 3;
+                return this.copyIndex(sourceIndex, targetIndexName);
 
-/**
- * A reference to a document
- *
- * @typedef {object} ReferencedByRelationship
- * @property {RelationshipParent} [parent]
- * @property {ReferencedBy} [referenced_by]
- */
+              case 3:
+                _context3.next = 5;
+                return this.destroyIndex(sourceIndex);
 
-/**
- * @typedef {object} RelationshipParent
- * @property {{related: string}} links
- * @property {Reference} [data]
- */
+              case 5:
+                _context3.next = 16;
+                break;
 
-/**
- * @typedef {object} ReferencedBy
- * @property {{self: string}} links
- * @property {Reference[]|null} data
- */
+              case 7:
+                _context3.prev = 7;
+                _context3.t0 = _context3["catch"](0);
 
-/**
- * A reference to a document
- * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#references
- *
- * @typedef {object} Reference
- * @property {string} id - id of the document
- * @property {string} type - doctype of the document
- */
+                if ((0, _Collection.isDocumentUpdateConflict)(_context3.t0)) {
+                  _context3.next = 11;
+                  break;
+                }
 
-/**
- * @typedef {Object.<string, Array<Reference>>} ReferenceMap
- */
+                throw _context3.t0;
 
-/**
- * @typedef {object} MutationOptions
- * @property {string} [as]
- * @property {Function} [update]
- * @property {Function} [updateQueries]
- */
+              case 11:
+                (0, _utils.sleep)(1000);
+                _context3.next = 14;
+                return this.copyIndex(sourceIndex, targetIndexName);
 
-/**
- * @typedef {object} CozyClientDocument - A document
- * @property {string} [_id] - Id of the document
- * @property {string} [id] - Id of the document
- * @property {string} [_type] - Type of the document
- * @property {string} [_rev] - Current revision of the document
- * @property {boolean} [_deleted] - When the document has been deleted
- * @property {ReferencedByRelationship} [relationships] - Relationships of the document
- * @property {Reference[]} [referenced_by] - referenced by of another document
- */
+              case 14:
+                _context3.next = 16;
+                return this.destroyIndex(sourceIndex);
 
-/**
- * @typedef {object} FileDocument - An io.cozy.files document
- * @property {string} _id - Id of the file
- * @property {FilesDoctype} _type - Doctype of the file
- * @property {string} name - Name of the file
- * @property {object} metadata - Metadata of the file
- * @property {object} type - Type of the file
- * @property {object} class - Class of the file
- * @typedef {CozyClientDocument & FileDocument} IOCozyFile - An io.cozy.files document
- */
+              case 16:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this, [[0, 7]]);
+      }));
 
-/**
- * @typedef {object} FolderDocument - An io.cozy.files document
- * @property {string} _id - Id of the folder
- * @property {FilesDoctype} _type - Doctype of the folder
- * @property {string} name - Name of the folder
- * @property {object} metadata - Metadata of the folder
- * @property {object} type - Type of the folder
- * @typedef {CozyClientDocument & FolderDocument} IOCozyFolder - An io.cozy.files document
- */
+      function migrateUnamedIndex(_x3, _x4) {
+        return _migrateUnamedIndex.apply(this, arguments);
+      }
 
-/**
- * @typedef {object} OAuthClientDocument - An io.cozy.oauth.clients document
- * @property {string} _id - Id of the client
- * @property {OAuthClientsDoctype} _type - Doctype of the client
- * @property {string} software_id
- * @property {string} software_version
- * @property {string} client_id
- * @property {string} client_name
- * @property {string} client_kind
- * @property {string} client_uri
- * @property {string} logo_uri
- * @property {string} policy_uri
- * @property {string} notification_platform
- * @property {string} notification_device_token
- * @property {Array<String>} redirect_uris
- * @typedef {CozyClientDocument & OAuthClientDocument} IOCozyOAuthClient - An io.cozy.oauth.clients document
- */
+      return migrateUnamedIndex;
+    }()
+    /**
+     * Handle index creation if it is missing.
+     *
+     * When an index is missing, we first check if there is one with a different
+     * name but the same definition. If yes, it means we found an old unamed
+     * index, so we migrate it. If there is none, we create the new index.
+     *
+     * @param {object} selector The mango selector
+     * @param {MangoQueryOptions} options The find options
+     * @private
+     */
 
-/**
- * @typedef {object} ClientError
- * @property {string} [status]
- */
+  }, {
+    key: "handleMissingIndex",
+    value: function () {
+      var _handleMissingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(selector, options) {
+        var indexedFields, partialFilter, existingIndex, indexName;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                indexedFields = options.indexedFields, partialFilter = options.partialFilter;
 
-/**
- * @typedef FilePlugin
- * @property {object} [externalDataDirectory]
- * @property {object} [cacheDirectory]
- * @property {object} [externalCacheDirectory]
- * @property {object} [dataDirectory]
- */
+                if (!indexedFields) {
+                  indexedFields = (0, _mangoIndex.getIndexFields)({
+                    sort: options.sort,
+                    selector: selector
+                  });
+                }
 
-/**
- * @typedef InAppBrowser
- * @property {Function} open
- */
+                _context4.next = 4;
+                return this.findExistingIndex(selector, options);
 
-/**
- * @typedef {object} AppMetadata
- */
+              case 4:
+                existingIndex = _context4.sent;
+                indexName = (0, _mangoIndex.getIndexNameFromFields)(indexedFields);
 
-/**
- * @typedef {object} ClientCapabilities
- *
- * @description Read more about client capabilities here https://docs.cozy.io/en/cozy-stack/settings/#get-settingscapabilities.
- *
- * @property {boolean} can_auth_with_oidc - Whether OIDC login is possible with this Cozy
- * @property {boolean} can_auth_with_password - Whether  password login is possible with this Cozy
- * @property {boolean} file_versioning - Whether file versioning is active on this Cozy
- * @property {boolean} flat_subdomains - Whether the stack has been configured to use flat subdomains
- */
+                if (existingIndex) {
+                  _context4.next = 11;
+                  break;
+                }
 
-/**
- * @typedef Cordova
- * @property {FilePlugin} file
- * @property {InAppBrowser} InAppBrowser
- * @property {object} plugins
- */
+                _context4.next = 9;
+                return this.createIndex(indexedFields, {
+                  partialFilter: partialFilter,
+                  indexName: indexName
+                });
 
-/**
- * @typedef  CordovaWindow
- * @property {Cordova} cordova
- * @property {object} SafariViewController
- * @property {Function} resolveLocalFileSystemURL
- * @property {Function} handleOpenURL
- */
+              case 9:
+                _context4.next = 17;
+                break;
 
-/**
- * @typedef {object} CouchDBDocument - A document
- * @property {string} _id - Id of the document
- * @property {string} _rev - Current revision of the document
- * @property {boolean} [_deleted] - When the document has been deleted
- * @property {object} [relationships] - Relationships of the document
- */
+              case 11:
+                if (!(existingIndex._id !== "_design/".concat(indexName))) {
+                  _context4.next = 16;
+                  break;
+                }
 
-/**
- * @typedef {object} CouchDBBulkResult - An item of the CouchDB bulk docs response
- * @property {boolean} ok
- * @property {string} id
- * @property {string} rev
- * @property {string?} error?
- * @property {string?} reason?
- */
+                _context4.next = 14;
+                return this.migrateUnamedIndex(existingIndex, indexName);
 
-/**
- * @typedef {Array<string>|string} ViewKey
- * @typedef {string} DocId
- * @typedef {[ViewKey, DocId]} CouchDBViewCursor
- */
+              case 14:
+                _context4.next = 17;
+                break;
 
-/**
- * @typedef {object} Theme
- * @property {string} id
- * @property {string} label
- * @property {string} icon
- * @property {Array<QualificationAttributes>} items
- * @property {Array<string>} [defaultItems]
- *
- * @typedef {Array<Theme>} ThemesList
- *
- * @typedef {'identity'|'family'|'work_study'|'health'|'home'|'transport'|'finance'|'invoice'} ThemesLabels
- */
+              case 16:
+                throw new Error("Index unusable for query, index used: ".concat(indexName));
 
-/**
- * @typedef {object} QualificationAttributes
- * @property {string} label
- * @property {string} [purpose]
- * @property {string} [sourceCategory]
- * @property {string} [sourceSubCategory]
- * @property {Array<string>} [subjects]
- */
+              case 17:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
 
-/**
- * @typedef {'identity_photo'|'national_id_card'|'passport'|'residence_permit'|'family_record_book'|'birth_certificate'|'driver_license'|'other_identity_document'|'citizen_registration_certificate'|'personal_sporting_licence'} IdentityLabel
- *
- * @typedef {'family_record_book'|'birth_certificate'|'wedding'|'pacs'|'divorce'|'large_family_card'|'caf'|'other_family_document'|'payment_proof_family_allowance'} FamilyLabel
- *
- * @typedef {'diploma'|'work_contract'|'pay_sheet'|'unemployment_benefit'|'pension'|'gradebook'|'student_card'|'resume'|'motivation_letter'|'other_work_document'|'work_disability_recognition'|'school_attendance_certificate'} WorkStudyLabels
- *
- * @typedef {'health_certificate'|'health_book'|'national_health_insurance_card'|'health_insurance_card'|'prescription'|'health_invoice'|'national_health_insurance_right_certificate'|'work_disability_recognition'|'pregnancy_medical_certificate'|'other_health_document'} HealthLabels
- *
- * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'house_sale_agreeement'|'building_permit'|'technical_diagnostic_record'|'lease'|'rent_receipt'|'house_insurance'|'work_quote'|'work_invoice'|'other_house_document'|'unfit_for_habitation_declaration'|'accommodation_proof'|'house_insurance'} HomeLabels
- *
- * @typedef {'driver_license'|'vehicle_registration'|'car_insurance'|'mechanic_invoice'|'transport_invoice'|'other_transport_document'} TransportLabels
- *
- * @typedef {'tax_return'|'tax_notice'|'tax_timetable'|'pay_sheet'|'receipt'|'other_tax_document'|'bank_details'|'bank_statement'|'loan_agreement'|'other_bank_document'|'payment_proof_family_allowance'|'other_revenue'} FinanceLabels
- *
- * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'appliance_invoice'|'web_service_invoice'|'restaurant_invoice'|'work_invoice'|'transport_invoice'|'health_invoice'|'other_invoice'} InvoiceLabels
- *
- * @typedef {'personal_sporting_licence'|'other_activity_document'} ActivityLabels
- *
- * @typedef {IdentityLabel|FamilyLabel|WorkStudyLabels|HealthLabels|HomeLabels|TransportLabels|FinanceLabels|InvoiceLabels|ActivityLabels} ItemsLabels
- */
+      function handleMissingIndex(_x5, _x6) {
+        return _handleMissingIndex.apply(this, arguments);
+      }
 
-/**
- * @typedef {object} DACCMeasure
- * See https://github.com/cozy/DACC
- *
- * @property {string} measureName - It must match an existing measure name on the DACC server
- * @property {string} startDate - Start of the aggregation period. Should be in YYYY-MM-DD format
- * @property {number} value - The measured value on the aggregation period
- * @property {string} createdBy - The slug of the app creating the measure
- * @property {object} group1 - Should be a {key: value} where the key is set in the measure definition.
- * @property {object} group2 - Should be a {key: value} where the key is set in the measure definition.
- * @property {object} group3 - Should be a {key: value} where the key is set in the measure definition.
- */
+      return handleMissingIndex;
+    }()
+    /**
+     * Find documents with the mango selector and create index
+     * if missing.
+     *
+     * We adopt an optimistic approach for index creation:
+     * we run the query first, and only if an index missing
+     * error is returned, the index is created and
+     * the query run again.
+     *
+     * @param {string} path The route path
+     * @param {object} selector The mango selector
+     * @param {MangoQueryOptions} options The find options
+     *
+     * @returns {object} - The find response
+     * @private
+     */
 
-/**
- * Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.
- *
- * @callback OpenURLCallback
- * @param {string} url - URL to present to the user
- */
+  }, {
+    key: "findWithMango",
+    value: function () {
+      var _findWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(path, selector) {
+        var options,
+            resp,
+            _args5 = arguments;
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                options = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : {};
+                _context5.prev = 1;
+                _context5.next = 4;
+                return this.fetchDocumentsWithMango(path, selector, options);
 
-/**
- * A session code generated by the cozy-stack that can be used to create a session
- *
- * More information: https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code
- *
- * @typedef {string} SessionCode
- */
+              case 4:
+                resp = _context5.sent;
+                _context5.next = 18;
+                break;
 
-/**
- * An object containing a code verifier and a code challenge that can be used in a
- * PKCE verification process
- *
- * More information: https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension
- *
- * @typedef {object} PKCECodes
- * @property {string} [codeVerifier]
- * @property {string} [codeChallenge]
- */
-var _default = {};
-exports["default"] = _default;
+              case 7:
+                _context5.prev = 7;
+                _context5.t0 = _context5["catch"](1);
 
-/***/ }),
-/* 611 */
-/***/ ((__unused_webpack_module, exports) => {
+                if (!(!(0, _Collection.isIndexNotFoundError)(_context5.t0) && !(0, _Collection.isNoUsableIndexError)(_context5.t0))) {
+                  _context5.next = 13;
+                  break;
+                }
 
-"use strict";
+                throw _context5.t0;
 
+              case 13:
+                _context5.next = 15;
+                return this.handleMissingIndex(selector, options);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.formatBytes = exports.slugify = exports.sleep = exports.attempt = exports.uri = void 0;
+              case 15:
+                _context5.next = 17;
+                return this.fetchDocumentsWithMango(path, selector, options);
 
-/**
- * @function
- * @description Template tag function for URIs encoding
- *
- * Will automatically apply `encodeURIComponent` to template literal placeholders
- *
- * @example
- * ```
- * const safe = uri`/data/${doctype}/_all_docs?limit=${limit}`
- * ```
- *
- * @private
- */
-var uri = function uri(strings) {
-  var parts = [strings[0]];
+              case 17:
+                resp = _context5.sent;
 
-  for (var i = 0; i < (arguments.length <= 1 ? 0 : arguments.length - 1); i++) {
-    parts.push(encodeURIComponent(i + 1 < 1 || arguments.length <= i + 1 ? undefined : arguments[i + 1]) + strings[i + 1]);
-  }
+              case 18:
+                return _context5.abrupt("return", resp);
 
-  return parts.join('');
-};
-/**
- * @function
- * @description Helps to avoid nested try/catch when using async/await
- *
- * Inspired by a Go pattern: http://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/
- *
- * @example
- * ```
- * if (await attempt(collection.all()) return
- * await sleep(1000)
- * if (await attempt(collection.all()) return
- * await sleep(1000)
- * return
- * ```
- *
- * @private
- */
+              case 19:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this, [[1, 7]]);
+      }));
 
+      function findWithMango(_x7, _x8) {
+        return _findWithMango.apply(this, arguments);
+      }
 
-exports.uri = uri;
+      return findWithMango;
+    }()
+    /**
+     * Returns a filtered list of documents using a Mango selector.
+     *
+     * The returned documents are paginated by the stack.
+     *
+     * @param  {object} selector The Mango selector.
+     * @param  {{sort, fields, limit, skip, bookmark, indexId}} options The query options.
+     * @returns {{data, skip, bookmark, next}} The JSON API conformant response.
+     * @throws {FetchError}
+     */
 
-var attempt = function attempt(promise) {
-  return promise.then(function () {
-    return true;
-  }).catch(function () {
-    return false;
-  });
-};
-/**
- * @function
- * @description Helps to avoid nested try/catch when using async/await — see documentation for attempt
- * @private
- */
+  }, {
+    key: "find",
+    value: function () {
+      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(selector) {
+        var _this2 = this;
 
+        var options,
+            _options$skip2,
+            skip,
+            resp,
+            path,
+            _args6 = arguments;
 
-exports.attempt = attempt;
+        return _regenerator.default.wrap(function _callee6$(_context6) {
+          while (1) {
+            switch (_context6.prev = _context6.next) {
+              case 0:
+                options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
+                _options$skip2 = options.skip, skip = _options$skip2 === void 0 ? 0 : _options$skip2;
+                _context6.prev = 2;
+                path = (0, _utils.uri)(_templateObject2(), this.doctype);
+                _context6.next = 6;
+                return this.findWithMango(path, selector, options);
 
-var sleep = function sleep(time, args) {
-  return new Promise(function (resolve) {
-    setTimeout(resolve, time, args);
-  });
-};
+              case 6:
+                resp = _context6.sent;
+                _context6.next = 12;
+                break;
 
-exports.sleep = sleep;
+              case 9:
+                _context6.prev = 9;
+                _context6.t0 = _context6["catch"](2);
+                return _context6.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context6.t0));
 
-var slugify = function slugify(text) {
-  return text.toString().toLowerCase().replace(/\s+/g, '-') // Replace spaces with -
-  .replace(/[^\w-]+/g, '') // Remove all non-word chars
-  .replace(/--+/g, '-') // Replace multiple - with single -
-  .replace(/^-+/, '') // Trim - from start of text
-  .replace(/-+$/, '');
-}; // Trim - from end of text
+              case 12:
+                return _context6.abrupt("return", {
+                  data: resp.docs.map(function (doc) {
+                    return normalizeDoc(doc, _this2.doctype);
+                  }),
+                  next: resp.next,
+                  skip: skip,
+                  bookmark: resp.bookmark,
+                  execution_stats: resp.execution_stats
+                });
 
+              case 13:
+              case "end":
+                return _context6.stop();
+            }
+          }
+        }, _callee6, this, [[2, 9]]);
+      }));
 
-exports.slugify = slugify;
+      function find(_x9) {
+        return _find.apply(this, arguments);
+      }
 
-var formatBytes = function formatBytes(bytes) {
-  var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
-  if (bytes === 0) return '0 Bytes';
-  var k = 1024;
-  var dm = decimals < 0 ? 0 : decimals;
-  var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
-  var i = Math.floor(Math.log(bytes) / Math.log(k));
-  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
-};
+      return find;
+    }()
+    /**
+     * Get a document by id
+     *
+     * @param  {string} id The document id.
+     * @returns {object}  JsonAPI response containing normalized document as data attribute
+     */
 
-exports.formatBytes = formatBytes;
+  }, {
+    key: "get",
+    value: function () {
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(id) {
+        return _regenerator.default.wrap(function _callee7$(_context7) {
+          while (1) {
+            switch (_context7.prev = _context7.next) {
+              case 0:
+                return _context7.abrupt("return", _Collection.default.get(this.stackClient, "".concat(this.endpoint).concat(encodeURIComponent(id)), {
+                  normalize: this.constructor.normalizeDoctype(this.doctype)
+                }));
 
-/***/ }),
-/* 612 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 1:
+              case "end":
+                return _context7.stop();
+            }
+          }
+        }, _callee7, this);
+      }));
 
-var baseUniq = __webpack_require__(463);
+      function get(_x10) {
+        return _get.apply(this, arguments);
+      }
 
-/**
- * Creates a duplicate-free version of an array, using
- * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * for equality comparisons, in which only the first occurrence of each element
- * is kept. The order of result values is determined by the order they occur
- * in the array.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {Array} array The array to inspect.
- * @returns {Array} Returns the new duplicate free array.
- * @example
- *
- * _.uniq([2, 1, 2]);
- * // => [2, 1]
- */
-function uniq(array) {
-  return (array && array.length) ? baseUniq(array) : [];
-}
+      return get;
+    }()
+    /**
+     * Get many documents by id
+     */
 
-module.exports = uniq;
+  }, {
+    key: "getAll",
+    value: function () {
+      var _getAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(ids) {
+        var _this3 = this;
 
+        var resp, rows;
+        return _regenerator.default.wrap(function _callee8$(_context8) {
+          while (1) {
+            switch (_context8.prev = _context8.next) {
+              case 0:
+                _context8.prev = 0;
+                _context8.next = 3;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), this.doctype), {
+                  keys: ids
+                });
 
-/***/ }),
-/* 613 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 3:
+                resp = _context8.sent;
+                _context8.next = 9;
+                break;
 
-var arrayMap = __webpack_require__(398),
-    baseClone = __webpack_require__(562),
-    baseUnset = __webpack_require__(614),
-    castPath = __webpack_require__(360),
-    copyObject = __webpack_require__(565),
-    customOmitClone = __webpack_require__(618),
-    flatRest = __webpack_require__(620),
-    getAllKeysIn = __webpack_require__(576);
+              case 6:
+                _context8.prev = 6;
+                _context8.t0 = _context8["catch"](0);
+                return _context8.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context8.t0));
 
-/** Used to compose bitmasks for cloning. */
-var CLONE_DEEP_FLAG = 1,
-    CLONE_FLAT_FLAG = 2,
-    CLONE_SYMBOLS_FLAG = 4;
+              case 9:
+                rows = resp.rows.filter(function (row) {
+                  return row.doc;
+                });
+                return _context8.abrupt("return", {
+                  data: rows.map(function (row) {
+                    return normalizeDoc(row.doc, _this3.doctype);
+                  }),
+                  meta: {
+                    count: rows.length
+                  }
+                });
 
-/**
- * The opposite of `_.pick`; this method creates an object composed of the
- * own and inherited enumerable property paths of `object` that are not omitted.
- *
- * **Note:** This method is considerably slower than `_.pick`.
- *
- * @static
- * @since 0.1.0
- * @memberOf _
- * @category Object
- * @param {Object} object The source object.
- * @param {...(string|string[])} [paths] The property paths to omit.
- * @returns {Object} Returns the new object.
- * @example
- *
- * var object = { 'a': 1, 'b': '2', 'c': 3 };
- *
- * _.omit(object, ['a', 'c']);
- * // => { 'b': '2' }
- */
-var omit = flatRest(function(object, paths) {
-  var result = {};
-  if (object == null) {
-    return result;
-  }
-  var isDeep = false;
-  paths = arrayMap(paths, function(path) {
-    path = castPath(path, object);
-    isDeep || (isDeep = path.length > 1);
-    return path;
-  });
-  copyObject(object, getAllKeysIn(object), result);
-  if (isDeep) {
-    result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
-  }
-  var length = paths.length;
-  while (length--) {
-    baseUnset(result, paths[length]);
-  }
-  return result;
-});
+              case 11:
+              case "end":
+                return _context8.stop();
+            }
+          }
+        }, _callee8, this, [[0, 6]]);
+      }));
 
-module.exports = omit;
+      function getAll(_x11) {
+        return _getAll.apply(this, arguments);
+      }
 
+      return getAll;
+    }()
+    /**
+     * Creates a document
+     *
+     * @param {object} doc - Document to create. Optional: you can force the id with the _id attribute
+     */
 
-/***/ }),
-/* 614 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  }, {
+    key: "create",
+    value: function () {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(_ref) {
+        var _id, _type, document, hasFixedId, method, endpoint, resp;
 
-var castPath = __webpack_require__(360),
-    last = __webpack_require__(615),
-    parent = __webpack_require__(616),
-    toKey = __webpack_require__(399);
+        return _regenerator.default.wrap(function _callee9$(_context9) {
+          while (1) {
+            switch (_context9.prev = _context9.next) {
+              case 0:
+                _id = _ref._id, _type = _ref._type, document = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type"]);
+                // In case of a fixed id, let's use the dedicated creation endpoint
+                // https://github.com/cozy/cozy-stack/blob/master/docs/data-system.md#create-a-document-with-a-fixed-id
+                hasFixedId = !!_id;
+                method = hasFixedId ? 'PUT' : 'POST';
+                endpoint = (0, _utils.uri)(_templateObject4(), this.doctype, hasFixedId ? _id : '');
+                _context9.next = 6;
+                return this.stackClient.fetchJSON(method, endpoint, document);
 
-/**
- * The base implementation of `_.unset`.
- *
- * @private
- * @param {Object} object The object to modify.
- * @param {Array|string} path The property path to unset.
- * @returns {boolean} Returns `true` if the property is deleted, else `false`.
- */
-function baseUnset(object, path) {
-  path = castPath(path, object);
-  object = parent(object, path);
-  return object == null || delete object[toKey(last(path))];
-}
+              case 6:
+                resp = _context9.sent;
+                return _context9.abrupt("return", {
+                  data: normalizeDoc(resp.data, this.doctype)
+                });
 
-module.exports = baseUnset;
+              case 8:
+              case "end":
+                return _context9.stop();
+            }
+          }
+        }, _callee9, this);
+      }));
 
+      function create(_x12) {
+        return _create.apply(this, arguments);
+      }
 
-/***/ }),
-/* 615 */
-/***/ ((module) => {
+      return create;
+    }()
+    /**
+     * Updates a document
+     *
+     * @param {object} document - Document to update. Do not forget the _id attribute
+     */
 
-/**
- * Gets the last element of `array`.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {Array} array The array to query.
- * @returns {*} Returns the last element of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- */
-function last(array) {
-  var length = array == null ? 0 : array.length;
-  return length ? array[length - 1] : undefined;
-}
+  }, {
+    key: "update",
+    value: function () {
+      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(document) {
+        var resp;
+        return _regenerator.default.wrap(function _callee10$(_context10) {
+          while (1) {
+            switch (_context10.prev = _context10.next) {
+              case 0:
+                _context10.next = 2;
+                return this.stackClient.fetchJSON('PUT', (0, _utils.uri)(_templateObject5(), this.doctype, document._id), document);
 
-module.exports = last;
+              case 2:
+                resp = _context10.sent;
+                return _context10.abrupt("return", {
+                  data: normalizeDoc(resp.data, this.doctype)
+                });
 
+              case 4:
+              case "end":
+                return _context10.stop();
+            }
+          }
+        }, _callee10, this);
+      }));
 
-/***/ }),
-/* 616 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      function update(_x13) {
+        return _update.apply(this, arguments);
+      }
 
-var baseGet = __webpack_require__(359),
-    baseSlice = __webpack_require__(617);
+      return update;
+    }()
+    /**
+     * Destroys a document
+     *
+     * @param {object} doc - Document to destroy. Do not forget _id and _rev attributes
+     */
 
-/**
- * Gets the parent value at `path` of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array} path The path to get the parent value of.
- * @returns {*} Returns the parent value.
- */
-function parent(object, path) {
-  return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
-}
+  }, {
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(_ref2) {
+        var _id, _rev, document, resp;
 
-module.exports = parent;
+        return _regenerator.default.wrap(function _callee11$(_context11) {
+          while (1) {
+            switch (_context11.prev = _context11.next) {
+              case 0:
+                _id = _ref2._id, _rev = _ref2._rev, document = (0, _objectWithoutProperties2.default)(_ref2, ["_id", "_rev"]);
+                _context11.next = 3;
+                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), this.doctype, _id, _rev));
 
+              case 3:
+                resp = _context11.sent;
+                return _context11.abrupt("return", {
+                  data: normalizeDoc(_objectSpread(_objectSpread({}, document), {}, {
+                    _id: _id,
+                    _rev: resp.rev,
+                    _deleted: true
+                  }), this.doctype)
+                });
 
-/***/ }),
-/* 617 */
-/***/ ((module) => {
+              case 5:
+              case "end":
+                return _context11.stop();
+            }
+          }
+        }, _callee11, this);
+      }));
 
-/**
- * The base implementation of `_.slice` without an iteratee call guard.
- *
- * @private
- * @param {Array} array The array to slice.
- * @param {number} [start=0] The start position.
- * @param {number} [end=array.length] The end position.
- * @returns {Array} Returns the slice of `array`.
- */
-function baseSlice(array, start, end) {
-  var index = -1,
-      length = array.length;
+      function destroy(_x14) {
+        return _destroy.apply(this, arguments);
+      }
 
-  if (start < 0) {
-    start = -start > length ? 0 : (length + start);
-  }
-  end = end > length ? length : end;
-  if (end < 0) {
-    end += length;
-  }
-  length = start > end ? 0 : ((end - start) >>> 0);
-  start >>>= 0;
+      return destroy;
+    }()
+    /**
+     * Updates several documents in one batch
+     *
+     * @param  {Document[]} rawDocs Documents to be updated
+     */
 
-  var result = Array(length);
-  while (++index < length) {
-    result[index] = array[index + start];
-  }
-  return result;
-}
+  }, {
+    key: "updateAll",
+    value: function () {
+      var _updateAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(rawDocs) {
+        var stackClient, docs, update, firstDoc, resp;
+        return _regenerator.default.wrap(function _callee12$(_context12) {
+          while (1) {
+            switch (_context12.prev = _context12.next) {
+              case 0:
+                stackClient = this.stackClient;
+                docs = rawDocs ? rawDocs.map(function (d) {
+                  return (0, _omit.default)(d, '_type');
+                }) : rawDocs;
 
-module.exports = baseSlice;
+                if (!(!docs || !docs.length)) {
+                  _context12.next = 4;
+                  break;
+                }
 
+                return _context12.abrupt("return", Promise.resolve([]));
 
-/***/ }),
-/* 618 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 4:
+                _context12.prev = 4;
+                _context12.next = 7;
+                return stackClient.fetchJSON('POST', "/data/".concat(this.doctype, "/_bulk_docs"), {
+                  docs: docs
+                });
 
-var isPlainObject = __webpack_require__(619);
+              case 7:
+                update = _context12.sent;
+                return _context12.abrupt("return", update);
 
-/**
- * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
- * objects.
- *
- * @private
- * @param {*} value The value to inspect.
- * @param {string} key The key of the property to inspect.
- * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
- */
-function customOmitClone(value) {
-  return isPlainObject(value) ? undefined : value;
-}
+              case 11:
+                _context12.prev = 11;
+                _context12.t0 = _context12["catch"](4);
 
-module.exports = customOmitClone;
+                if (!(_context12.t0.reason && _context12.t0.reason.reason && _context12.t0.reason.reason === DATABASE_DOES_NOT_EXIST)) {
+                  _context12.next = 24;
+                  break;
+                }
 
+                _context12.next = 16;
+                return this.create(docs[0]);
 
-/***/ }),
-/* 619 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 16:
+                firstDoc = _context12.sent;
+                _context12.next = 19;
+                return this.updateAll(docs.slice(1));
 
-var baseGetTag = __webpack_require__(46),
-    getPrototype = __webpack_require__(575),
-    isObjectLike = __webpack_require__(53);
+              case 19:
+                resp = _context12.sent;
+                resp.unshift({
+                  ok: true,
+                  id: firstDoc._id,
+                  rev: firstDoc._rev
+                });
+                return _context12.abrupt("return", resp);
 
-/** `Object#toString` result references. */
-var objectTag = '[object Object]';
+              case 24:
+                throw _context12.t0;
 
-/** Used for built-in method references. */
-var funcProto = Function.prototype,
-    objectProto = Object.prototype;
+              case 25:
+              case "end":
+                return _context12.stop();
+            }
+          }
+        }, _callee12, this, [[4, 11]]);
+      }));
 
-/** Used to resolve the decompiled source of functions. */
-var funcToString = funcProto.toString;
+      function updateAll(_x15) {
+        return _updateAll.apply(this, arguments);
+      }
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+      return updateAll;
+    }()
+    /**
+     * Deletes several documents in one batch
+     *
+     * @param  {Document[]} docs - Documents to delete
+     */
 
-/** Used to infer the `Object` constructor. */
-var objectCtorString = funcToString.call(Object);
+  }, {
+    key: "destroyAll",
+    value: function destroyAll(docs) {
+      return this.updateAll(docs.map(prepareForDeletion));
+    }
+  }, {
+    key: "toMangoOptions",
+    value: function toMangoOptions(selector) {
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+      var sort = options.sort,
+          indexedFields = options.indexedFields;
+      var fields = options.fields,
+          _options$skip3 = options.skip,
+          skip = _options$skip3 === void 0 ? 0 : _options$skip3,
+          limit = options.limit,
+          bookmark = options.bookmark;
+      sort = (0, _mangoIndex.transformSort)(sort);
+      indexedFields = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({
+        sort: sort,
+        selector: selector
+      });
+      var indexName = options.indexId || "_design/".concat((0, _mangoIndex.getIndexNameFromFields)(indexedFields));
 
-/**
- * Checks if `value` is a plain object, that is, an object created by the
- * `Object` constructor or one with a `[[Prototype]]` of `null`.
- *
- * @static
- * @memberOf _
- * @since 0.8.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- * @example
- *
- * function Foo() {
- *   this.a = 1;
- * }
- *
- * _.isPlainObject(new Foo);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- *
- * _.isPlainObject(Object.create(null));
- * // => true
- */
-function isPlainObject(value) {
-  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
-    return false;
-  }
-  var proto = getPrototype(value);
-  if (proto === null) {
-    return true;
-  }
-  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
-  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
-    funcToString.call(Ctor) == objectCtorString;
-}
+      if (sort) {
+        var sortOrders = (0, _uniq.default)(sort.map(function (sortOption) {
+          return (0, _head.default)(Object.values(sortOption));
+        }));
+        if (sortOrders.length > 1) throw new Error('Mango sort can only use a single order (asc or desc).');
+        var sortOrder = sortOrders.length > 0 ? (0, _head.default)(sortOrders) : 'asc';
 
-module.exports = isPlainObject;
+        var _iterator = _createForOfIteratorHelper(indexedFields),
+            _step;
 
+        try {
+          var _loop = function _loop() {
+            var field = _step.value;
+            if (!sort.find(function (sortOption) {
+              return (0, _head.default)(Object.keys(sortOption)) === field;
+            })) sort.push((0, _defineProperty2.default)({}, field, sortOrder));
+          };
 
-/***/ }),
-/* 620 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+          for (_iterator.s(); !(_step = _iterator.n()).done;) {
+            _loop();
+          }
+        } catch (err) {
+          _iterator.e(err);
+        } finally {
+          _iterator.f();
+        }
+      }
 
-var flatten = __webpack_require__(540),
-    overRest = __webpack_require__(545),
-    setToString = __webpack_require__(547);
+      var opts = {
+        selector: selector,
+        use_index: indexName,
+        // TODO: type and class should not be necessary, it's just a temp fix for a stack bug
+        fields: fields ? [].concat((0, _toConsumableArray2.default)(fields), ['_id', '_type', 'class']) : undefined,
+        limit: limit,
+        skip: skip,
+        bookmark: options.bookmark || bookmark,
+        sort: sort,
+        execution_stats: (0, _cozyFlags.default)('debug') ? true : undefined
+      };
+      return opts;
+    }
+  }, {
+    key: "checkUniquenessOf",
+    value: function () {
+      var _checkUniquenessOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(property, value) {
+        var indexId, existingDocs;
+        return _regenerator.default.wrap(function _callee13$(_context13) {
+          while (1) {
+            switch (_context13.prev = _context13.next) {
+              case 0:
+                _context13.next = 2;
+                return this.getUniqueIndexId(property);
 
-/**
- * A specialized version of `baseRest` which flattens the rest array.
- *
- * @private
- * @param {Function} func The function to apply a rest parameter to.
- * @returns {Function} Returns the new function.
- */
-function flatRest(func) {
-  return setToString(overRest(func, undefined, flatten), func + '');
-}
+              case 2:
+                indexId = _context13.sent;
+                _context13.next = 5;
+                return this.find((0, _defineProperty2.default)({}, property, value), {
+                  indexId: indexId,
+                  fields: ['_id']
+                });
 
-module.exports = flatRest;
+              case 5:
+                existingDocs = _context13.sent;
+                return _context13.abrupt("return", existingDocs.data.length === 0);
 
+              case 7:
+              case "end":
+                return _context13.stop();
+            }
+          }
+        }, _callee13, this);
+      }));
 
-/***/ }),
-/* 621 */
-/***/ ((module) => {
+      function checkUniquenessOf(_x16, _x17) {
+        return _checkUniquenessOf.apply(this, arguments);
+      }
 
-/**
- * Gets the first element of `array`.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @alias first
- * @category Array
- * @param {Array} array The array to query.
- * @returns {*} Returns the first element of `array`.
- * @example
- *
- * _.head([1, 2, 3]);
- * // => 1
- *
- * _.head([]);
- * // => undefined
- */
-function head(array) {
-  return (array && array.length) ? array[0] : undefined;
-}
+      return checkUniquenessOf;
+    }()
+  }, {
+    key: "getUniqueIndexId",
+    value: function getUniqueIndexId(property) {
+      return this.getIndexId([property], {
+        indexName: "".concat(this.doctype, "/").concat(property)
+      });
+    }
+  }, {
+    key: "getIndexId",
+    value: function () {
+      var _getIndexId = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(fields, _ref3) {
+        var partialFilter, _ref3$indexName, indexName, index;
 
-module.exports = head;
+        return _regenerator.default.wrap(function _callee14$(_context14) {
+          while (1) {
+            switch (_context14.prev = _context14.next) {
+              case 0:
+                partialFilter = _ref3.partialFilter, _ref3$indexName = _ref3.indexName, indexName = _ref3$indexName === void 0 ? this.getIndexNameFromFields(fields) : _ref3$indexName;
 
+                if (this.indexes[indexName]) {
+                  _context14.next = 20;
+                  break;
+                }
 
-/***/ }),
-/* 622 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                _context14.prev = 2;
+                _context14.next = 5;
+                return this.createIndex(fields, {
+                  partialFilter: partialFilter
+                });
 
-var baseClamp = __webpack_require__(623),
-    baseToString = __webpack_require__(397),
-    toInteger = __webpack_require__(624),
-    toString = __webpack_require__(396);
+              case 5:
+                index = _context14.sent;
+                _context14.next = 19;
+                break;
 
-/**
- * Checks if `string` starts with the given target string.
- *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category String
- * @param {string} [string=''] The string to inspect.
- * @param {string} [target] The string to search for.
- * @param {number} [position=0] The position to search from.
- * @returns {boolean} Returns `true` if `string` starts with `target`,
- *  else `false`.
- * @example
- *
- * _.startsWith('abc', 'a');
- * // => true
- *
- * _.startsWith('abc', 'b');
- * // => false
- *
- * _.startsWith('abc', 'b', 1);
- * // => true
- */
-function startsWith(string, target, position) {
-  string = toString(string);
-  position = position == null
-    ? 0
-    : baseClamp(toInteger(position), 0, string.length);
+              case 8:
+                _context14.prev = 8;
+                _context14.t0 = _context14["catch"](2);
 
-  target = baseToString(target);
-  return string.slice(position, position + target.length) == target;
-}
+                if ((0, _Collection.isIndexConflictError)(_context14.t0)) {
+                  _context14.next = 14;
+                  break;
+                }
 
-module.exports = startsWith;
+                throw _context14.t0;
 
+              case 14:
+                _context14.next = 16;
+                return (0, _utils.sleep)(1000);
 
-/***/ }),
-/* 623 */
-/***/ ((module) => {
+              case 16:
+                _context14.next = 18;
+                return this.createIndex(fields, {
+                  partialFilter: partialFilter
+                });
 
-/**
- * The base implementation of `_.clamp` which doesn't coerce arguments.
- *
- * @private
- * @param {number} number The number to clamp.
- * @param {number} [lower] The lower bound.
- * @param {number} upper The upper bound.
- * @returns {number} Returns the clamped number.
- */
-function baseClamp(number, lower, upper) {
-  if (number === number) {
-    if (upper !== undefined) {
-      number = number <= upper ? number : upper;
-    }
-    if (lower !== undefined) {
-      number = number >= lower ? number : lower;
-    }
-  }
-  return number;
-}
+              case 18:
+                index = _context14.sent;
 
-module.exports = baseClamp;
+              case 19:
+                this.indexes[indexName] = index;
 
+              case 20:
+                return _context14.abrupt("return", this.indexes[indexName].id);
 
-/***/ }),
-/* 624 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 21:
+              case "end":
+                return _context14.stop();
+            }
+          }
+        }, _callee14, this, [[2, 8]]);
+      }));
 
-var toFinite = __webpack_require__(625);
+      function getIndexId(_x18, _x19) {
+        return _getIndexId.apply(this, arguments);
+      }
 
-/**
- * Converts `value` to an integer.
- *
- * **Note:** This method is loosely based on
- * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {number} Returns the converted integer.
- * @example
- *
- * _.toInteger(3.2);
- * // => 3
- *
- * _.toInteger(Number.MIN_VALUE);
- * // => 0
- *
- * _.toInteger(Infinity);
- * // => 1.7976931348623157e+308
- *
- * _.toInteger('3.2');
- * // => 3
- */
-function toInteger(value) {
-  var result = toFinite(value),
-      remainder = result % 1;
+      return getIndexId;
+    }()
+  }, {
+    key: "createIndex",
+    value: function () {
+      var _createIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(fields) {
+        var _ref4,
+            partialFilter,
+            indexName,
+            indexDef,
+            resp,
+            indexResp,
+            selector,
+            options,
+            _args15 = arguments;
 
-  return result === result ? (remainder ? result - remainder : result) : 0;
-}
+        return _regenerator.default.wrap(function _callee15$(_context15) {
+          while (1) {
+            switch (_context15.prev = _context15.next) {
+              case 0:
+                _ref4 = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : {}, partialFilter = _ref4.partialFilter, indexName = _ref4.indexName;
+                indexDef = {
+                  index: {
+                    fields: fields
+                  }
+                };
 
-module.exports = toInteger;
+                if (indexName) {
+                  indexDef.ddoc = indexName;
+                }
 
+                if (partialFilter) {
+                  indexDef.index.partial_filter_selector = partialFilter;
+                }
 
-/***/ }),
-/* 625 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+                _context15.prev = 4;
+                _context15.next = 7;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), this.doctype), indexDef);
 
-var toNumber = __webpack_require__(626);
+              case 7:
+                resp = _context15.sent;
+                _context15.next = 17;
+                break;
 
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0,
-    MAX_INTEGER = 1.7976931348623157e+308;
+              case 10:
+                _context15.prev = 10;
+                _context15.t0 = _context15["catch"](4);
 
-/**
- * Converts `value` to a finite number.
- *
- * @static
- * @memberOf _
- * @since 4.12.0
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {number} Returns the converted number.
- * @example
- *
- * _.toFinite(3.2);
- * // => 3.2
- *
- * _.toFinite(Number.MIN_VALUE);
- * // => 5e-324
- *
- * _.toFinite(Infinity);
- * // => 1.7976931348623157e+308
- *
- * _.toFinite('3.2');
- * // => 3.2
- */
-function toFinite(value) {
-  if (!value) {
-    return value === 0 ? value : 0;
-  }
-  value = toNumber(value);
-  if (value === INFINITY || value === -INFINITY) {
-    var sign = (value < 0 ? -1 : 1);
-    return sign * MAX_INTEGER;
-  }
-  return value === value ? value : 0;
-}
+                if ((0, _Collection.isIndexConflictError)(_context15.t0)) {
+                  _context15.next = 16;
+                  break;
+                }
 
-module.exports = toFinite;
+                throw _context15.t0;
 
+              case 16:
+                return _context15.abrupt("return");
 
-/***/ }),
-/* 626 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 17:
+                indexResp = {
+                  id: resp.id,
+                  fields: fields
+                };
 
-var baseTrim = __webpack_require__(627),
-    isObject = __webpack_require__(52),
-    isSymbol = __webpack_require__(362);
+                if (!(resp.result === 'exists')) {
+                  _context15.next = 20;
+                  break;
+                }
 
-/** Used as references for various `Number` constants. */
-var NAN = 0 / 0;
+                return _context15.abrupt("return", indexResp);
 
-/** Used to detect bad signed hexadecimal string values. */
-var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+              case 20:
+                // indexes might not be usable right after being created; so we delay the resolving until they are
+                selector = {};
+                fields.forEach(function (f) {
+                  return selector[f] = {
+                    $gt: null
+                  };
+                });
+                options = {
+                  indexId: indexResp.id,
+                  limit: 1
+                };
+                _context15.next = 25;
+                return (0, _utils.attempt)(this.find(selector, options));
 
-/** Used to detect binary string values. */
-var reIsBinary = /^0b[01]+$/i;
+              case 25:
+                if (!_context15.sent) {
+                  _context15.next = 27;
+                  break;
+                }
 
-/** Used to detect octal string values. */
-var reIsOctal = /^0o[0-7]+$/i;
+                return _context15.abrupt("return", indexResp);
 
-/** Built-in method references without a dependency on `root`. */
-var freeParseInt = parseInt;
+              case 27:
+                _context15.next = 29;
+                return (0, _utils.sleep)(1000);
 
-/**
- * Converts `value` to a number.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to process.
- * @returns {number} Returns the number.
- * @example
- *
- * _.toNumber(3.2);
- * // => 3.2
- *
- * _.toNumber(Number.MIN_VALUE);
- * // => 5e-324
- *
- * _.toNumber(Infinity);
- * // => Infinity
- *
- * _.toNumber('3.2');
- * // => 3.2
- */
-function toNumber(value) {
-  if (typeof value == 'number') {
-    return value;
-  }
-  if (isSymbol(value)) {
-    return NAN;
-  }
-  if (isObject(value)) {
-    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
-    value = isObject(other) ? (other + '') : other;
-  }
-  if (typeof value != 'string') {
-    return value === 0 ? value : +value;
-  }
-  value = baseTrim(value);
-  var isBinary = reIsBinary.test(value);
-  return (isBinary || reIsOctal.test(value))
-    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
-    : (reIsBadHex.test(value) ? NAN : +value);
-}
+              case 29:
+                _context15.next = 31;
+                return (0, _utils.attempt)(this.find(selector, options));
 
-module.exports = toNumber;
+              case 31:
+                if (!_context15.sent) {
+                  _context15.next = 33;
+                  break;
+                }
 
+                return _context15.abrupt("return", indexResp);
 
-/***/ }),
-/* 627 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 33:
+                _context15.next = 35;
+                return (0, _utils.sleep)(500);
 
-var trimmedEndIndex = __webpack_require__(628);
+              case 35:
+                return _context15.abrupt("return", indexResp);
 
-/** Used to match leading whitespace. */
-var reTrimStart = /^\s+/;
+              case 36:
+              case "end":
+                return _context15.stop();
+            }
+          }
+        }, _callee15, this, [[4, 10]]);
+      }));
 
-/**
- * The base implementation of `_.trim`.
- *
- * @private
- * @param {string} string The string to trim.
- * @returns {string} Returns the trimmed string.
- */
-function baseTrim(string) {
-  return string
-    ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
-    : string;
-}
+      function createIndex(_x20) {
+        return _createIndex.apply(this, arguments);
+      }
 
-module.exports = baseTrim;
+      return createIndex;
+    }()
+    /**
+     * Retrieve all design docs of mango indexes
+     *
+     * @returns {Array} The design docs
+     */
 
+  }, {
+    key: "fetchAllMangoIndexes",
+    value: function () {
+      var _fetchAllMangoIndexes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() {
+        var path, indexes;
+        return _regenerator.default.wrap(function _callee16$(_context16) {
+          while (1) {
+            switch (_context16.prev = _context16.next) {
+              case 0:
+                path = (0, _utils.uri)(_templateObject8(), this.doctype);
+                _context16.next = 3;
+                return this.stackClient.fetchJSON('GET', path);
 
-/***/ }),
-/* 628 */
-/***/ ((module) => {
+              case 3:
+                indexes = _context16.sent;
+                return _context16.abrupt("return", indexes.rows.filter(function (index) {
+                  return index.doc.language === 'query';
+                }).map(function (doc) {
+                  return (0, _mangoIndex.normalizeDesignDoc)(doc);
+                }));
 
-/** Used to match a single whitespace character. */
-var reWhitespace = /\s/;
+              case 5:
+              case "end":
+                return _context16.stop();
+            }
+          }
+        }, _callee16, this);
+      }));
 
-/**
- * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
- * character of `string`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @returns {number} Returns the index of the last non-whitespace character.
- */
-function trimmedEndIndex(string) {
-  var index = string.length;
+      function fetchAllMangoIndexes() {
+        return _fetchAllMangoIndexes.apply(this, arguments);
+      }
 
-  while (index-- && reWhitespace.test(string.charAt(index))) {}
-  return index;
-}
+      return fetchAllMangoIndexes;
+    }()
+    /**
+     * Delete the specified design doc
+     *
+     * @param {object} index - The design doc to remove
+     * @returns {object} The delete response
+     */
 
-module.exports = trimmedEndIndex;
+  }, {
+    key: "destroyIndex",
+    value: function () {
+      var _destroyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(index) {
+        var ddoc, rev, path;
+        return _regenerator.default.wrap(function _callee17$(_context17) {
+          while (1) {
+            switch (_context17.prev = _context17.next) {
+              case 0:
+                ddoc = index._id.split('/')[1];
+                rev = index._rev;
+                path = (0, _utils.uri)(_templateObject9(), this.doctype, ddoc, rev);
+                return _context17.abrupt("return", this.stackClient.fetchJSON('DELETE', path));
 
+              case 4:
+              case "end":
+                return _context17.stop();
+            }
+          }
+        }, _callee17, this);
+      }));
 
-/***/ }),
-/* 629 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      function destroyIndex(_x21) {
+        return _destroyIndex.apply(this, arguments);
+      }
 
-"use strict";
+      return destroyIndex;
+    }()
+    /**
+     * Copy an existing design doc.
+     *
+     * This is useful to create a new design doc without
+     * having to recompute the existing index.
+     *
+     * @param {object} existingIndex - The design doc to copy
+     * @param {string} newIndexName - The name of the copy
+     * @returns {object} The copy response
+     */
 
+  }, {
+    key: "copyIndex",
+    value: function () {
+      var _copyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(existingIndex, newIndexName) {
+        var ddoc, rev, path, options;
+        return _regenerator.default.wrap(function _callee18$(_context18) {
+          while (1) {
+            switch (_context18.prev = _context18.next) {
+              case 0:
+                ddoc = existingIndex._id.split('/')[1];
+                rev = existingIndex._rev;
+                path = (0, _utils.uri)(_templateObject10(), this.doctype, ddoc, rev);
+                options = {
+                  headers: {
+                    Destination: "_design/".concat(newIndexName)
+                  }
+                };
+                return _context18.abrupt("return", this.stackClient.fetchJSON('POST', path, null, options));
 
-var stringify = __webpack_require__(630);
-var parse = __webpack_require__(644);
-var formats = __webpack_require__(643);
+              case 5:
+              case "end":
+                return _context18.stop();
+            }
+          }
+        }, _callee18, this);
+      }));
 
-module.exports = {
-    formats: formats,
-    parse: parse,
-    stringify: stringify
-};
+      function copyIndex(_x22, _x23) {
+        return _copyIndex.apply(this, arguments);
+      }
 
+      return copyIndex;
+    }()
+    /**
+     * Find an existing mango index based on the query definition
+     *
+     * This is useful to avoid creating new indexes having the
+     * same definition of an existing one.
+     *
+     * @param {object}            selector  The query selector
+     * @param {MangoQueryOptions} options   The find options
+     *
+     * @returns {object} A matching index if it exists
+     * @private
+     */
 
-/***/ }),
-/* 630 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  }, {
+    key: "findExistingIndex",
+    value: function () {
+      var _findExistingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(selector, options) {
+        var sort, indexedFields, partialFilter, indexes, fieldsToIndex, existingIndex, _iterator2, _step2, index;
 
-"use strict";
+        return _regenerator.default.wrap(function _callee19$(_context19) {
+          while (1) {
+            switch (_context19.prev = _context19.next) {
+              case 0:
+                sort = options.sort, indexedFields = options.indexedFields, partialFilter = options.partialFilter;
+                _context19.next = 3;
+                return this.fetchAllMangoIndexes();
 
+              case 3:
+                indexes = _context19.sent;
 
-var getSideChannel = __webpack_require__(631);
-var utils = __webpack_require__(642);
-var formats = __webpack_require__(643);
-var has = Object.prototype.hasOwnProperty;
+                if (!(indexes.length < 1)) {
+                  _context19.next = 6;
+                  break;
+                }
 
-var arrayPrefixGenerators = {
-    brackets: function brackets(prefix) {
-        return prefix + '[]';
-    },
-    comma: 'comma',
-    indices: function indices(prefix, key) {
-        return prefix + '[' + key + ']';
-    },
-    repeat: function repeat(prefix) {
-        return prefix;
-    }
-};
+                return _context19.abrupt("return", null);
 
-var isArray = Array.isArray;
-var push = Array.prototype.push;
-var pushToArray = function (arr, valueOrArray) {
-    push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
-};
+              case 6:
+                sort = (0, _mangoIndex.transformSort)(sort);
+                fieldsToIndex = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({
+                  sort: sort,
+                  selector: selector
+                });
+                existingIndex = indexes.find(function (index) {
+                  return (0, _mangoIndex.isMatchingIndex)(index, fieldsToIndex, partialFilter);
+                });
+                _iterator2 = _createForOfIteratorHelper(indexes);
+                _context19.prev = 10;
 
-var toISO = Date.prototype.toISOString;
+                _iterator2.s();
 
-var defaultFormat = formats['default'];
-var defaults = {
-    addQueryPrefix: false,
-    allowDots: false,
-    charset: 'utf-8',
-    charsetSentinel: false,
-    delimiter: '&',
-    encode: true,
-    encoder: utils.encode,
-    encodeValuesOnly: false,
-    format: defaultFormat,
-    formatter: formats.formatters[defaultFormat],
-    // deprecated
-    indices: false,
-    serializeDate: function serializeDate(date) {
-        return toISO.call(date);
-    },
-    skipNulls: false,
-    strictNullHandling: false
-};
+              case 12:
+                if ((_step2 = _iterator2.n()).done) {
+                  _context19.next = 19;
+                  break;
+                }
 
-var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
-    return typeof v === 'string'
-        || typeof v === 'number'
-        || typeof v === 'boolean'
-        || typeof v === 'symbol'
-        || typeof v === 'bigint';
-};
+                index = _step2.value;
 
-var stringify = function stringify(
-    object,
-    prefix,
-    generateArrayPrefix,
-    strictNullHandling,
-    skipNulls,
-    encoder,
-    filter,
-    sort,
-    allowDots,
-    serializeDate,
-    format,
-    formatter,
-    encodeValuesOnly,
-    charset,
-    sideChannel
-) {
-    var obj = object;
+                if (!(0, _mangoIndex.isInconsistentIndex)(index)) {
+                  _context19.next = 17;
+                  break;
+                }
 
-    if (sideChannel.has(object)) {
-        throw new RangeError('Cyclic object value');
-    }
+                _context19.next = 17;
+                return this.destroyIndex(index);
 
-    if (typeof filter === 'function') {
-        obj = filter(prefix, obj);
-    } else if (obj instanceof Date) {
-        obj = serializeDate(obj);
-    } else if (generateArrayPrefix === 'comma' && isArray(obj)) {
-        obj = utils.maybeMap(obj, function (value) {
-            if (value instanceof Date) {
-                return serializeDate(value);
-            }
-            return value;
-        });
-    }
+              case 17:
+                _context19.next = 12;
+                break;
 
-    if (obj === null) {
-        if (strictNullHandling) {
-            return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;
-        }
+              case 19:
+                _context19.next = 24;
+                break;
 
-        obj = '';
-    }
+              case 21:
+                _context19.prev = 21;
+                _context19.t0 = _context19["catch"](10);
 
-    if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
-        if (encoder) {
-            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
-            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
-        }
-        return [formatter(prefix) + '=' + formatter(String(obj))];
-    }
+                _iterator2.e(_context19.t0);
 
-    var values = [];
+              case 24:
+                _context19.prev = 24;
 
-    if (typeof obj === 'undefined') {
-        return values;
-    }
+                _iterator2.f();
 
-    var objKeys;
-    if (generateArrayPrefix === 'comma' && isArray(obj)) {
-        // we need to join elements in
-        objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
-    } else if (isArray(filter)) {
-        objKeys = filter;
-    } else {
-        var keys = Object.keys(obj);
-        objKeys = sort ? keys.sort(sort) : keys;
-    }
+                return _context19.finish(24);
 
-    for (var i = 0; i < objKeys.length; ++i) {
-        var key = objKeys[i];
-        var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
+              case 27:
+                return _context19.abrupt("return", existingIndex);
 
-        if (skipNulls && value === null) {
-            continue;
-        }
+              case 28:
+              case "end":
+                return _context19.stop();
+            }
+          }
+        }, _callee19, this, [[10, 21, 24, 27]]);
+      }));
 
-        var keyPrefix = isArray(obj)
-            ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
-            : prefix + (allowDots ? '.' + key : '[' + key + ']');
+      function findExistingIndex(_x24, _x25) {
+        return _findExistingIndex.apply(this, arguments);
+      }
 
-        sideChannel.set(object, true);
-        var valueSideChannel = getSideChannel();
-        pushToArray(values, stringify(
-            value,
-            keyPrefix,
-            generateArrayPrefix,
-            strictNullHandling,
-            skipNulls,
-            encoder,
-            filter,
-            sort,
-            allowDots,
-            serializeDate,
-            format,
-            formatter,
-            encodeValuesOnly,
-            charset,
-            valueSideChannel
-        ));
-    }
+      return findExistingIndex;
+    }()
+    /**
+     * Calls _changes route from CouchDB
+     * No further treatment is done contrary to fetchchanges
+     *
+     * @param {object} couchOptions - Couch options for changes https://kutt.it/5r7MNQ
+     * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned
+     * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents
+     * @param {boolean} [couchOptions.includeDocs] - Includes full documents as part of results
+     *
+     * @see https://docs.couchdb.org/en/stable/api/database/changes.html
+     */
 
-    return values;
-};
+  }, {
+    key: "fetchChangesRaw",
+    value: function () {
+      var _fetchChangesRaw = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(couchOptions) {
+        var hasDocIds, urlParams, method, endpoint, params, result;
+        return _regenerator.default.wrap(function _callee20$(_context20) {
+          while (1) {
+            switch (_context20.prev = _context20.next) {
+              case 0:
+                hasDocIds = couchOptions.doc_ids && couchOptions.doc_ids.length > 0;
+                urlParams = "?".concat([_qs.default.stringify(_objectSpread(_objectSpread({}, (0, _omit.default)(couchOptions, ['doc_ids', 'includeDocs'])), {}, {
+                  include_docs: couchOptions.includeDocs
+                })), hasDocIds && couchOptions.filter === undefined ? 'filter=_doc_ids' : undefined].filter(Boolean).join('&'));
+                method = hasDocIds ? 'POST' : 'GET';
+                endpoint = "/data/".concat(this.doctype, "/_changes").concat(urlParams);
+                params = hasDocIds ? {
+                  doc_ids: couchOptions.doc_ids
+                } : undefined;
+                _context20.next = 7;
+                return this.stackClient.fetchJSON(method, endpoint, params);
 
-var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
-    if (!opts) {
-        return defaults;
-    }
+              case 7:
+                result = _context20.sent;
+                return _context20.abrupt("return", result);
 
-    if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
-        throw new TypeError('Encoder has to be a function.');
-    }
+              case 9:
+              case "end":
+                return _context20.stop();
+            }
+          }
+        }, _callee20, this);
+      }));
 
-    var charset = opts.charset || defaults.charset;
-    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
-        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
-    }
+      function fetchChangesRaw(_x26) {
+        return _fetchChangesRaw.apply(this, arguments);
+      }
 
-    var format = formats['default'];
-    if (typeof opts.format !== 'undefined') {
-        if (!has.call(formats.formatters, opts.format)) {
-            throw new TypeError('Unknown format option provided.');
-        }
-        format = opts.format;
-    }
-    var formatter = formats.formatters[format];
+      return fetchChangesRaw;
+    }()
+    /**
+     * Use Couch _changes API
+     * Deleted and design docs are filtered by default, thus documents are retrieved in the response
+     * (include_docs is set to true in the parameters of _changes).
+     *
+     * You should use fetchChangesRaw to have low level control on _changes parameters.
+     *
+     * @param {object} couchOptions - Couch options for changes
+     * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned
+     * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents
+     *
+     * @param {object} options - Further options on the returned documents. By default, it is set to { includeDesign: false, includeDeleted: false }
+     * @param {boolean} [options.includeDesign] - Whether to include changes from design docs (needs include_docs to be true)
+     * @param {boolean} [options.includeDeleted] - Whether to include changes for deleted documents (needs include_docs to be true)
+     *
+     * @typedef {object} FetchChangesReturnValue
+     * @property {string} newLastSeq
+     * @property {Array<object>} documents
+     * @returns {FetchChangesReturnValue}
+     */
 
-    var filter = defaults.filter;
-    if (typeof opts.filter === 'function' || isArray(opts.filter)) {
-        filter = opts.filter;
-    }
+  }, {
+    key: "fetchChanges",
+    value: function () {
+      var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() {
+        var couchOptions,
+            options,
+            opts,
+            result,
+            newLastSeq,
+            docs,
+            _args21 = arguments;
+        return _regenerator.default.wrap(function _callee21$(_context21) {
+          while (1) {
+            switch (_context21.prev = _context21.next) {
+              case 0:
+                couchOptions = _args21.length > 0 && _args21[0] !== undefined ? _args21[0] : {};
+                options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {};
+                opts = {
+                  // Necessary since we deal with deleted and design docs later
+                  includeDocs: true
+                };
 
-    return {
-        addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
-        allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
-        charset: charset,
-        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
-        delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
-        encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
-        encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
-        encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
-        filter: filter,
-        format: format,
-        formatter: formatter,
-        serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
-        skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
-        sort: typeof opts.sort === 'function' ? opts.sort : null,
-        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
-    };
-};
+                if (typeof couchOptions !== 'object') {
+                  opts.since = couchOptions;
+                  console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"})."));
+                } else if (Object.keys(couchOptions).length > 0) {
+                  Object.assign(opts, couchOptions);
+                }
 
-module.exports = function (object, opts) {
-    var obj = object;
-    var options = normalizeStringifyOptions(opts);
+                _context21.next = 6;
+                return this.fetchChangesRaw(opts);
 
-    var objKeys;
-    var filter;
+              case 6:
+                result = _context21.sent;
+                newLastSeq = result.last_seq;
+                docs = result.results.map(function (x) {
+                  return x.doc;
+                }).filter(Boolean);
 
-    if (typeof options.filter === 'function') {
-        filter = options.filter;
-        obj = filter('', obj);
-    } else if (isArray(options.filter)) {
-        filter = options.filter;
-        objKeys = filter;
-    }
+                if (!options.includeDesign) {
+                  docs = docs.filter(function (doc) {
+                    return doc._id.indexOf('_design') !== 0;
+                  });
+                }
 
-    var keys = [];
+                if (!options.includeDeleted) {
+                  docs = docs.filter(function (doc) {
+                    return !doc._deleted;
+                  });
+                }
 
-    if (typeof obj !== 'object' || obj === null) {
-        return '';
-    }
+                return _context21.abrupt("return", {
+                  newLastSeq: newLastSeq,
+                  documents: docs
+                });
 
-    var arrayFormat;
-    if (opts && opts.arrayFormat in arrayPrefixGenerators) {
-        arrayFormat = opts.arrayFormat;
-    } else if (opts && 'indices' in opts) {
-        arrayFormat = opts.indices ? 'indices' : 'repeat';
-    } else {
-        arrayFormat = 'indices';
-    }
+              case 12:
+              case "end":
+                return _context21.stop();
+            }
+          }
+        }, _callee21, this);
+      }));
 
-    var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
+      function fetchChanges() {
+        return _fetchChanges.apply(this, arguments);
+      }
 
-    if (!objKeys) {
-        objKeys = Object.keys(obj);
+      return fetchChanges;
+    }()
+  }], [{
+    key: "normalizeDoctype",
+    value: function normalizeDoctype(doctype) {
+      return this.normalizeDoctypeRawApi(doctype);
     }
+    /**
+     * `normalizeDoctype` for api end points returning json api responses
+     *
+     * @private
+     * @param {string} doctype - Document doctype
+     * @returns {Function} (data, response) => normalizedDocument
+     *                                        using `normalizeDoc`
+     */
 
-    if (options.sort) {
-        objKeys.sort(options.sort);
+  }, {
+    key: "normalizeDoctypeJsonApi",
+    value: function normalizeDoctypeJsonApi(doctype) {
+      return function (data, response) {
+        // use the "data" attribute of the response
+        return normalizeDoc(data, doctype);
+      };
     }
+    /**
+     * `normalizeDoctype` for api end points returning raw documents
+     *
+     * @private
+     * @param {string} doctype - Document doctype
+     * @returns {Function} (data, response) => normalizedDocument
+     *                                        using `normalizeDoc`
+     */
 
-    var sideChannel = getSideChannel();
-    for (var i = 0; i < objKeys.length; ++i) {
-        var key = objKeys[i];
-
-        if (options.skipNulls && obj[key] === null) {
-            continue;
-        }
-        pushToArray(keys, stringify(
-            obj[key],
-            key,
-            generateArrayPrefix,
-            options.strictNullHandling,
-            options.skipNulls,
-            options.encode ? options.encoder : null,
-            options.filter,
-            options.sort,
-            options.allowDots,
-            options.serializeDate,
-            options.format,
-            options.formatter,
-            options.encodeValuesOnly,
-            options.charset,
-            sideChannel
-        ));
+  }, {
+    key: "normalizeDoctypeRawApi",
+    value: function normalizeDoctypeRawApi(doctype) {
+      return function (data, response) {
+        // use the response directly
+        return normalizeDoc(response, doctype);
+      };
     }
+  }]);
+  return DocumentCollection;
+}();
 
-    var joined = keys.join(options.delimiter);
-    var prefix = options.addQueryPrefix === true ? '?' : '';
+var _default = DocumentCollection;
+exports["default"] = _default;
+var normalizeDoctype = DocumentCollection.normalizeDoctype;
+exports.normalizeDoctype = normalizeDoctype;
 
-    if (options.charsetSentinel) {
-        if (options.charset === 'iso-8859-1') {
-            // encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
-            prefix += 'utf8=%26%2310003%3B&';
-        } else {
-            // encodeURIComponent('✓')
-            prefix += 'utf8=%E2%9C%93&';
-        }
-    }
+/***/ }),
+/* 614 */
+/***/ ((module) => {
 
-    return joined.length > 0 ? prefix + joined : '';
-};
+function _taggedTemplateLiteral(strings, raw) {
+  if (!raw) {
+    raw = strings.slice(0);
+  }
+
+  return Object.freeze(Object.defineProperties(strings, {
+    raw: {
+      value: Object.freeze(raw)
+    }
+  }));
+}
 
+module.exports = _taggedTemplateLiteral;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 631 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 615 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
-var callBound = __webpack_require__(638);
-var inspect = __webpack_require__(640);
-
-var $TypeError = GetIntrinsic('%TypeError%');
-var $WeakMap = GetIntrinsic('%WeakMap%', true);
-var $Map = GetIntrinsic('%Map%', true);
-
-var $weakMapGet = callBound('WeakMap.prototype.get', true);
-var $weakMapSet = callBound('WeakMap.prototype.set', true);
-var $weakMapHas = callBound('WeakMap.prototype.has', true);
-var $mapGet = callBound('Map.prototype.get', true);
-var $mapSet = callBound('Map.prototype.set', true);
-var $mapHas = callBound('Map.prototype.has', true);
+var _interopRequireDefault = __webpack_require__(524);
 
-/*
- * This function traverses the list returning the node corresponding to the
- * given key.
- *
- * That node is also moved to the head of the list, so that if it's accessed
- * again we don't need to traverse the whole list. By doing so, all the recently
- * used nodes can be accessed relatively quickly.
- */
-var listGetNode = function (list, key) { // eslint-disable-line consistent-return
-	for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {
-		if (curr.key === key) {
-			prev.next = curr.next;
-			curr.next = list.next;
-			list.next = curr; // eslint-disable-line no-param-reassign
-			return curr;
-		}
-	}
-};
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-var listGet = function (objects, key) {
-	var node = listGetNode(objects, key);
-	return node && node.value;
-};
-var listSet = function (objects, key, value) {
-	var node = listGetNode(objects, key);
-	if (node) {
-		node.value = value;
-	} else {
-		// Prepend the new node to the beginning of the list
-		objects.next = { // eslint-disable-line no-param-reassign
-			key: key,
-			next: objects.next,
-			value: value
-		};
-	}
-};
-var listHas = function (objects, key) {
-	return !!listGetNode(objects, key);
-};
+var _flag = _interopRequireDefault(__webpack_require__(616));
 
-module.exports = function getSideChannel() {
-	var $wm;
-	var $m;
-	var $o;
-	var channel = {
-		assert: function (key) {
-			if (!channel.has(key)) {
-				throw new $TypeError('Side channel does not contain ' + inspect(key));
-			}
-		},
-		get: function (key) { // eslint-disable-line consistent-return
-			if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
-				if ($wm) {
-					return $weakMapGet($wm, key);
-				}
-			} else if ($Map) {
-				if ($m) {
-					return $mapGet($m, key);
-				}
-			} else {
-				if ($o) { // eslint-disable-line no-lonely-if
-					return listGet($o, key);
-				}
-			}
-		},
-		has: function (key) {
-			if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
-				if ($wm) {
-					return $weakMapHas($wm, key);
-				}
-			} else if ($Map) {
-				if ($m) {
-					return $mapHas($m, key);
-				}
-			} else {
-				if ($o) { // eslint-disable-line no-lonely-if
-					return listHas($o, key);
-				}
-			}
-			return false;
-		},
-		set: function (key, value) {
-			if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
-				if (!$wm) {
-					$wm = new $WeakMap();
-				}
-				$weakMapSet($wm, key, value);
-			} else if ($Map) {
-				if (!$m) {
-					$m = new $Map();
-				}
-				$mapSet($m, key, value);
-			} else {
-				if (!$o) {
-					/*
-					 * Initialize the linked list as an empty node, so that we don't have
-					 * to special-case handling of the first node: we can always refer to
-					 * it as (previous node).next, instead of something like (list).head
-					 */
-					$o = { key: {}, next: null };
-				}
-				listSet($o, key, value);
-			}
-		}
-	};
-	return channel;
-};
+/* global __ENABLED_FLAGS__ */
+if (typeof __ENABLED_FLAGS__ !== 'undefined') {
+  _flag.default.enable(__ENABLED_FLAGS__);
+}
 
+var _default = _flag.default;
+exports["default"] = _default;
 
 /***/ }),
-/* 632 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 616 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var undefined;
+var _interopRequireDefault = __webpack_require__(524);
 
-var $SyntaxError = SyntaxError;
-var $Function = Function;
-var $TypeError = TypeError;
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.resetFlags = exports.listFlags = exports.initializeFromRemote = exports.initializeFromDOM = exports.initialize = exports.getTemplateData = exports.enable = exports["default"] = void 0;
 
-// eslint-disable-next-line consistent-return
-var getEvalledConstructor = function (expressionSyntax) {
-	try {
-		return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
-	} catch (e) {}
-};
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var $gOPD = Object.getOwnPropertyDescriptor;
-if ($gOPD) {
-	try {
-		$gOPD({}, '');
-	} catch (e) {
-		$gOPD = null; // this is IE 8, which has a broken gOPD
-	}
-}
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var throwTypeError = function () {
-	throw new $TypeError();
-};
-var ThrowTypeError = $gOPD
-	? (function () {
-		try {
-			// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
-			arguments.callee; // IE 8 does not throw here
-			return throwTypeError;
-		} catch (calleeThrows) {
-			try {
-				// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
-				return $gOPD(arguments, 'callee').get;
-			} catch (gOPDthrows) {
-				return throwTypeError;
-			}
-		}
-	}())
-	: throwTypeError;
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var hasSymbols = __webpack_require__(633)();
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
 
-var needsEval = {};
+var _store = _interopRequireDefault(__webpack_require__(617));
 
-var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);
+var _dsl = __webpack_require__(619);
 
-var INTRINSICS = {
-	'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
-	'%Array%': Array,
-	'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
-	'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,
-	'%AsyncFromSyncIteratorPrototype%': undefined,
-	'%AsyncFunction%': needsEval,
-	'%AsyncGenerator%': needsEval,
-	'%AsyncGeneratorFunction%': needsEval,
-	'%AsyncIteratorPrototype%': needsEval,
-	'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
-	'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
-	'%Boolean%': Boolean,
-	'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
-	'%Date%': Date,
-	'%decodeURI%': decodeURI,
-	'%decodeURIComponent%': decodeURIComponent,
-	'%encodeURI%': encodeURI,
-	'%encodeURIComponent%': encodeURIComponent,
-	'%Error%': Error,
-	'%eval%': eval, // eslint-disable-line no-eval
-	'%EvalError%': EvalError,
-	'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
-	'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
-	'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
-	'%Function%': $Function,
-	'%GeneratorFunction%': needsEval,
-	'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
-	'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
-	'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
-	'%isFinite%': isFinite,
-	'%isNaN%': isNaN,
-	'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,
-	'%JSON%': typeof JSON === 'object' ? JSON : undefined,
-	'%Map%': typeof Map === 'undefined' ? undefined : Map,
-	'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),
-	'%Math%': Math,
-	'%Number%': Number,
-	'%Object%': Object,
-	'%parseFloat%': parseFloat,
-	'%parseInt%': parseInt,
-	'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
-	'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
-	'%RangeError%': RangeError,
-	'%ReferenceError%': ReferenceError,
-	'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
-	'%RegExp%': RegExp,
-	'%Set%': typeof Set === 'undefined' ? undefined : Set,
-	'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),
-	'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
-	'%String%': String,
-	'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,
-	'%Symbol%': hasSymbols ? Symbol : undefined,
-	'%SyntaxError%': $SyntaxError,
-	'%ThrowTypeError%': ThrowTypeError,
-	'%TypedArray%': TypedArray,
-	'%TypeError%': $TypeError,
-	'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
-	'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
-	'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
-	'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
-	'%URIError%': URIError,
-	'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
-	'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
-	'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
-};
+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 F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-var doEval = function doEval(name) {
-	var value;
-	if (name === '%AsyncFunction%') {
-		value = getEvalledConstructor('async function () {}');
-	} else if (name === '%GeneratorFunction%') {
-		value = getEvalledConstructor('function* () {}');
-	} else if (name === '%AsyncGeneratorFunction%') {
-		value = getEvalledConstructor('async function* () {}');
-	} else if (name === '%AsyncGenerator%') {
-		var fn = doEval('%AsyncGeneratorFunction%');
-		if (fn) {
-			value = fn.prototype;
-		}
-	} else if (name === '%AsyncIteratorPrototype%') {
-		var gen = doEval('%AsyncGenerator%');
-		if (gen) {
-			value = getProto(gen.prototype);
-		}
-	}
+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); }
 
-	INTRINSICS[name] = value;
+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; }
 
-	return value;
-};
+var store = new _store.default();
+/**
+ * Public API to use flags
+ */
 
-var LEGACY_ALIASES = {
-	'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
-	'%ArrayPrototype%': ['Array', 'prototype'],
-	'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
-	'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
-	'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
-	'%ArrayProto_values%': ['Array', 'prototype', 'values'],
-	'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
-	'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
-	'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
-	'%BooleanPrototype%': ['Boolean', 'prototype'],
-	'%DataViewPrototype%': ['DataView', 'prototype'],
-	'%DatePrototype%': ['Date', 'prototype'],
-	'%ErrorPrototype%': ['Error', 'prototype'],
-	'%EvalErrorPrototype%': ['EvalError', 'prototype'],
-	'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
-	'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
-	'%FunctionPrototype%': ['Function', 'prototype'],
-	'%Generator%': ['GeneratorFunction', 'prototype'],
-	'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
-	'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
-	'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
-	'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
-	'%JSONParse%': ['JSON', 'parse'],
-	'%JSONStringify%': ['JSON', 'stringify'],
-	'%MapPrototype%': ['Map', 'prototype'],
-	'%NumberPrototype%': ['Number', 'prototype'],
-	'%ObjectPrototype%': ['Object', 'prototype'],
-	'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
-	'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
-	'%PromisePrototype%': ['Promise', 'prototype'],
-	'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
-	'%Promise_all%': ['Promise', 'all'],
-	'%Promise_reject%': ['Promise', 'reject'],
-	'%Promise_resolve%': ['Promise', 'resolve'],
-	'%RangeErrorPrototype%': ['RangeError', 'prototype'],
-	'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
-	'%RegExpPrototype%': ['RegExp', 'prototype'],
-	'%SetPrototype%': ['Set', 'prototype'],
-	'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
-	'%StringPrototype%': ['String', 'prototype'],
-	'%SymbolPrototype%': ['Symbol', 'prototype'],
-	'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
-	'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
-	'%TypeErrorPrototype%': ['TypeError', 'prototype'],
-	'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
-	'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
-	'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
-	'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
-	'%URIErrorPrototype%': ['URIError', 'prototype'],
-	'%WeakMapPrototype%': ['WeakMap', 'prototype'],
-	'%WeakSetPrototype%': ['WeakSet', 'prototype']
+var flag = function flag() {
+  var args = [].slice.call(arguments);
+
+  if (args.length === 1) {
+    return store.get(args[0]);
+  } else {
+    store.set(args[0], args[1]);
+    return args[1];
+  }
 };
+/** List all flags from the store */
 
-var bind = __webpack_require__(635);
-var hasOwn = __webpack_require__(637);
-var $concat = bind.call(Function.call, Array.prototype.concat);
-var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
-var $replace = bind.call(Function.call, String.prototype.replace);
-var $strSlice = bind.call(Function.call, String.prototype.slice);
 
-/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
-var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
-var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
-var stringToPath = function stringToPath(string) {
-	var first = $strSlice(string, 0, 1);
-	var last = $strSlice(string, -1);
-	if (first === '%' && last !== '%') {
-		throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
-	} else if (last === '%' && first !== '%') {
-		throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
-	}
-	var result = [];
-	$replace(string, rePropName, function (match, number, quote, subString) {
-		result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
-	});
-	return result;
+var listFlags = function listFlags() {
+  return store.keys().sort();
 };
-/* end adaptation */
-
-var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
-	var intrinsicName = name;
-	var alias;
-	if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
-		alias = LEGACY_ALIASES[intrinsicName];
-		intrinsicName = '%' + alias[0] + '%';
-	}
+/** Resets all the flags */
 
-	if (hasOwn(INTRINSICS, intrinsicName)) {
-		var value = INTRINSICS[intrinsicName];
-		if (value === needsEval) {
-			value = doEval(intrinsicName);
-		}
-		if (typeof value === 'undefined' && !allowMissing) {
-			throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
-		}
 
-		return {
-			alias: alias,
-			name: intrinsicName,
-			value: value
-		};
-	}
+exports.listFlags = listFlags;
 
-	throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
+var resetFlags = function resetFlags() {
+  listFlags().forEach(function (name) {
+    return store.remove(name);
+  });
 };
+/**
+ * Enables several flags
+ *
+ * Supports passing either  object flagName -> flagValue
+ *
+ * @param {string[]|Object} flagsToEnable
+ */
 
-module.exports = function GetIntrinsic(name, allowMissing) {
-	if (typeof name !== 'string' || name.length === 0) {
-		throw new $TypeError('intrinsic name must be a non-empty string');
-	}
-	if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
-		throw new $TypeError('"allowMissing" argument must be a boolean');
-	}
 
-	var parts = stringToPath(name);
-	var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
+exports.resetFlags = resetFlags;
 
-	var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
-	var intrinsicRealName = intrinsic.name;
-	var value = intrinsic.value;
-	var skipFurtherCaching = false;
+var enable = function enable(flagsToEnable) {
+  var flagNameToValue;
 
-	var alias = intrinsic.alias;
-	if (alias) {
-		intrinsicBaseName = alias[0];
-		$spliceApply(parts, $concat([0, 1], alias));
-	}
+  if (Array.isArray(flagsToEnable)) {
+    if (flagsToEnable.length === 0) {
+      return;
+    } // eslint-disable-next-line no-console
 
-	for (var i = 1, isOwn = true; i < parts.length; i += 1) {
-		var part = parts[i];
-		var first = $strSlice(part, 0, 1);
-		var last = $strSlice(part, -1);
-		if (
-			(
-				(first === '"' || first === "'" || first === '`')
-				|| (last === '"' || last === "'" || last === '`')
-			)
-			&& first !== last
-		) {
-			throw new $SyntaxError('property names with quotes must have matching quotes');
-		}
-		if (part === 'constructor' || !isOwn) {
-			skipFurtherCaching = true;
-		}
 
-		intrinsicBaseName += '.' + part;
-		intrinsicRealName = '%' + intrinsicBaseName + '%';
+    console.log('flags.enable: Deprecation warning: prefer to use an object { flag1: true, flag2: true } instead of an array when using flags.enable');
+    flagNameToValue = flagsToEnable.map(function (flagName) {
+      return [flagName, true];
+    });
+  } else if (typeof flagsToEnable === 'object') {
+    flagNameToValue = Object.entries(flagsToEnable);
+  }
 
-		if (hasOwn(INTRINSICS, intrinsicRealName)) {
-			value = INTRINSICS[intrinsicRealName];
-		} else if (value != null) {
-			if (!(part in value)) {
-				if (!allowMissing) {
-					throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
-				}
-				return void undefined;
-			}
-			if ($gOPD && (i + 1) >= parts.length) {
-				var desc = $gOPD(value, part);
-				isOwn = !!desc;
+  if (!flagNameToValue) {
+    return;
+  }
 
-				// By convention, when a data property is converted to an accessor
-				// property to emulate a data property that does not suffer from
-				// the override mistake, that accessor's getter is marked with
-				// an `originalValue` property. Here, when we detect this, we
-				// uphold the illusion by pretending to see that original data
-				// property, i.e., returning the value rather than the getter
-				// itself.
-				if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
-					value = desc.get;
-				} else {
-					value = value[part];
-				}
-			} else {
-				isOwn = hasOwn(value, part);
-				value = value[part];
-			}
+  var _iterator = _createForOfIteratorHelper(flagNameToValue),
+      _step;
 
-			if (isOwn && !skipFurtherCaching) {
-				INTRINSICS[intrinsicRealName] = value;
-			}
-		}
-	}
-	return value;
+  try {
+    for (_iterator.s(); !(_step = _iterator.n()).done;) {
+      var _step$value = (0, _slicedToArray2.default)(_step.value, 2),
+          flagName = _step$value[0],
+          flagValue = _step$value[1];
+
+      flag(flagName, flagValue);
+    }
+  } catch (err) {
+    _iterator.e(err);
+  } finally {
+    _iterator.f();
+  }
 };
+/**
+ * Initializes flags from the remote endpoint serving instance flags
+ *
+ * @private
+ * @see  https://docs.cozy.io/en/cozy-stack/settings/#get-settingsflags
+ * @param  {CozyClient} client
+ */
 
 
-/***/ }),
-/* 633 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+exports.enable = enable;
 
-"use strict";
+var initializeFromRemote = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) {
+    var _yield$client$query, attributes;
 
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            _context.next = 2;
+            return client.query((0, _dsl.Q)('io.cozy.settings').getById('flags'));
 
-var origSymbol = typeof Symbol !== 'undefined' && Symbol;
-var hasSymbolSham = __webpack_require__(634);
+          case 2:
+            _yield$client$query = _context.sent;
+            attributes = _yield$client$query.data.attributes;
+            enable(attributes);
 
-module.exports = function hasNativeSymbols() {
-	if (typeof origSymbol !== 'function') { return false; }
-	if (typeof Symbol !== 'function') { return false; }
-	if (typeof origSymbol('foo') !== 'symbol') { return false; }
-	if (typeof Symbol('bar') !== 'symbol') { return false; }
+          case 5:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
 
-	return hasSymbolSham();
+  return function initializeFromRemote(_x) {
+    return _ref.apply(this, arguments);
+  };
+}();
+
+exports.initializeFromRemote = initializeFromRemote;
+
+var capitalize = function capitalize(str) {
+  return str[0].toUpperCase() + str.slice(1);
 };
 
+var getTemplateData = function getTemplateData(attr) {
+  if (typeof document === 'undefined') {
+    return null;
+  }
 
-/***/ }),
-/* 634 */
-/***/ ((module) => {
+  var allDataNode = document.querySelector('[data-cozy]');
+  var attrNode = document.querySelector("[data-cozy-".concat(attr, "]"));
 
-"use strict";
+  try {
+    if (allDataNode) {
+      return JSON.parse(allDataNode.dataset.cozy)[attr];
+    } else if (attrNode) {
+      // eslint-disable-next-line no-console
+      console.warn('Prefer to use [data-cozy] to store template data. <div data-cozy="{{.CozyData}}></div>. "');
+      return JSON.parse(attrNode.dataset["cozy".concat(capitalize(attr))]);
+    } else {
+      return null;
+    }
+  } catch (e) {
+    return null;
+  }
+};
+/**
+ * Initialize from the template data injected by cozy-stack into the DOM
+ *
+ * @private
+ * @see https://docs.cozy.io/en/cozy-stack/client-app-dev/#good-practices-for-your-application
+ *
+ * @returns {Boolean} - False is DOM initialization could not be completed, true otherwise
+ */
 
 
-/* eslint complexity: [2, 18], max-statements: [2, 33] */
-module.exports = function hasSymbols() {
-	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
-	if (typeof Symbol.iterator === 'symbol') { return true; }
+exports.getTemplateData = getTemplateData;
 
-	var obj = {};
-	var sym = Symbol('test');
-	var symObj = Object(sym);
-	if (typeof sym === 'string') { return false; }
+var initializeFromDOM = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+    var domData;
+    return _regenerator.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            domData = getTemplateData('flags');
 
-	if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }
-	if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }
+            if (domData) {
+              _context2.next = 3;
+              break;
+            }
+
+            return _context2.abrupt("return", false);
+
+          case 3:
+            enable(domData);
+            return _context2.abrupt("return", true);
+
+          case 5:
+          case "end":
+            return _context2.stop();
+        }
+      }
+    }, _callee2);
+  }));
+
+  return function initializeFromDOM() {
+    return _ref2.apply(this, arguments);
+  };
+}();
+/**
+ * Initialize flags from DOM if possible, otherwise from remote endpoint
+ *
+ * @example
+ *
+ * Flags can be taken from the flags injected by the stack
+ * ```
+ * <div data-cozy="{{ .CozyData }}"></div>
+ *
+ * // not recommended but possible
+ * <div data-flags="{{ .Flags }}"></div>
+ * ````
+ *
+ * @param  {CozyClient} client - A CozyClient
+ * @return {Promise} Resolves when flags have been initialized
+ */
 
-	// temp disabled per https://github.com/ljharb/object.assign/issues/17
-	// if (sym instanceof Symbol) { return false; }
-	// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
-	// if (!(symObj instanceof Symbol)) { return false; }
 
-	// if (typeof Symbol.prototype.toString !== 'function') { return false; }
-	// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }
+exports.initializeFromDOM = initializeFromDOM;
 
-	var symVal = 42;
-	obj[sym] = symVal;
-	for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop
-	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }
+var initialize = /*#__PURE__*/function () {
+  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(client) {
+    var domRes;
+    return _regenerator.default.wrap(function _callee3$(_context3) {
+      while (1) {
+        switch (_context3.prev = _context3.next) {
+          case 0:
+            _context3.next = 2;
+            return initializeFromDOM();
 
-	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }
+          case 2:
+            domRes = _context3.sent;
 
-	var syms = Object.getOwnPropertySymbols(obj);
-	if (syms.length !== 1 || syms[0] !== sym) { return false; }
+            if (!(domRes == false)) {
+              _context3.next = 6;
+              break;
+            }
 
-	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }
+            _context3.next = 6;
+            return initializeFromRemote(client);
 
-	if (typeof Object.getOwnPropertyDescriptor === 'function') {
-		var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
-		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
-	}
+          case 6:
+          case "end":
+            return _context3.stop();
+        }
+      }
+    }, _callee3);
+  }));
 
-	return true;
-};
+  return function initialize(_x2) {
+    return _ref3.apply(this, arguments);
+  };
+}();
 
+exports.initialize = initialize;
 
-/***/ }),
-/* 635 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var FlagClientPlugin = /*#__PURE__*/function () {
+  function FlagClientPlugin(client) {
+    (0, _classCallCheck2.default)(this, FlagClientPlugin);
+    this.client = client;
+    this.handleLogin = this.handleLogin.bind(this);
+    this.handleLogout = this.handleLogout.bind(this);
+    this.client.on('login', this.handleLogin);
+    this.client.on('logout', this.handleLogout);
+    this.setupInitializing();
+    if (client.isLogged) this.handleLogin();
+  }
+  /**
+   * Fetches and sets flags from remote
+   */
 
-"use strict";
 
+  (0, _createClass2.default)(FlagClientPlugin, [{
+    key: "refresh",
+    value: function () {
+      var _refresh = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                _context4.next = 2;
+                return flag.initializeFromRemote(this.client);
 
-var implementation = __webpack_require__(636);
+              case 2:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
 
-module.exports = Function.prototype.bind || implementation;
+      function refresh() {
+        return _refresh.apply(this, arguments);
+      }
 
+      return refresh;
+    }()
+    /**
+     * Sets up a promise that can be awaited to wait for flag complete
+     * initialization
+     */
 
-/***/ }),
-/* 636 */
-/***/ ((module) => {
+  }, {
+    key: "setupInitializing",
+    value: function setupInitializing() {
+      var _this = this;
 
-"use strict";
+      this.initializing = new Promise(function (resolve) {
+        _this.resolveInitializing = resolve;
+      });
+    }
+  }, {
+    key: "handleLogin",
+    value: function () {
+      var _handleLogin = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                _context5.next = 2;
+                return flag.initialize(this.client);
 
+              case 2:
+                this.resolveInitializing();
+                this.client.emit('plugin:flag:login');
 
-/* eslint no-invalid-this: 1 */
+              case 4:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this);
+      }));
 
-var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
-var slice = Array.prototype.slice;
-var toStr = Object.prototype.toString;
-var funcType = '[object Function]';
+      function handleLogin() {
+        return _handleLogin.apply(this, arguments);
+      }
 
-module.exports = function bind(that) {
-    var target = this;
-    if (typeof target !== 'function' || toStr.call(target) !== funcType) {
-        throw new TypeError(ERROR_MESSAGE + target);
-    }
-    var args = slice.call(arguments, 1);
+      return handleLogin;
+    }()
+  }, {
+    key: "handleLogout",
+    value: function () {
+      var _handleLogout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
+        return _regenerator.default.wrap(function _callee6$(_context6) {
+          while (1) {
+            switch (_context6.prev = _context6.next) {
+              case 0:
+                flag.reset();
+                this.setupInitializing();
+                this.client.emit('plugin:flag:logout');
 
-    var bound;
-    var binder = function () {
-        if (this instanceof bound) {
-            var result = target.apply(
-                this,
-                args.concat(slice.call(arguments))
-            );
-            if (Object(result) === result) {
-                return result;
+              case 3:
+              case "end":
+                return _context6.stop();
             }
-            return this;
-        } else {
-            return target.apply(
-                that,
-                args.concat(slice.call(arguments))
-            );
-        }
-    };
-
-    var boundLength = Math.max(0, target.length - args.length);
-    var boundArgs = [];
-    for (var i = 0; i < boundLength; i++) {
-        boundArgs.push('$' + i);
-    }
-
-    bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
+          }
+        }, _callee6, this);
+      }));
 
-    if (target.prototype) {
-        var Empty = function Empty() {};
-        Empty.prototype = target.prototype;
-        bound.prototype = new Empty();
-        Empty.prototype = null;
-    }
+      function handleLogout() {
+        return _handleLogout.apply(this, arguments);
+      }
 
-    return bound;
-};
+      return handleLogout;
+    }()
+  }]);
+  return FlagClientPlugin;
+}();
 
+FlagClientPlugin.pluginName = 'flags';
+flag.store = store;
+flag.list = listFlags;
+flag.reset = resetFlags;
+flag.enable = enable;
+flag.initializeFromRemote = initializeFromRemote;
+flag.initializeFromDOM = initializeFromDOM;
+flag.initialize = initialize;
+flag.plugin = FlagClientPlugin;
+var _default = flag;
+exports["default"] = _default;
 
 /***/ }),
-/* 637 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 617 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var bind = __webpack_require__(635);
-
-module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);
+var _interopRequireDefault = __webpack_require__(524);
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-/***/ }),
-/* 638 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
 
-"use strict";
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var GetIntrinsic = __webpack_require__(632);
+var _microee = _interopRequireDefault(__webpack_require__(570));
 
-var callBind = __webpack_require__(639);
+var _lsAdapter = _interopRequireDefault(__webpack_require__(618));
 
-var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));
+/**
+ * In memory key value storage.
+ *
+ * Can potentially be backed by localStorage if present
 
-module.exports = function callBoundIntrinsic(name, allowMissing) {
-	var intrinsic = GetIntrinsic(name, !!allowMissing);
-	if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
-		return callBind(intrinsic);
-	}
-	return intrinsic;
-};
+ * Emits `change` when a key is set (eventEmitter)
+ */
+var FlagStore = /*#__PURE__*/function () {
+  function FlagStore() {
+    (0, _classCallCheck2.default)(this, FlagStore);
+    this.store = {};
 
+    if (typeof localStorage !== 'undefined') {
+      this.longtermStore = _lsAdapter.default;
+    }
 
-/***/ }),
-/* 639 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    this.restore();
+  }
 
-"use strict";
+  (0, _createClass2.default)(FlagStore, [{
+    key: "restore",
+    value: function restore() {
+      if (!this.longtermStore) {
+        return;
+      }
 
+      var allValues = this.longtermStore.getAll();
 
-var bind = __webpack_require__(635);
-var GetIntrinsic = __webpack_require__(632);
+      for (var _i = 0, _Object$entries = Object.entries(allValues); _i < _Object$entries.length; _i++) {
+        var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
+            flag = _Object$entries$_i[0],
+            val = _Object$entries$_i[1];
 
-var $apply = GetIntrinsic('%Function.prototype.apply%');
-var $call = GetIntrinsic('%Function.prototype.call%');
-var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);
+        this.store[flag] = val;
+        this.emit('change', flag);
+      }
+    }
+  }, {
+    key: "keys",
+    value: function keys() {
+      return Object.keys(this.store);
+    }
+  }, {
+    key: "get",
+    value: function get(name) {
+      // eslint-disable-next-line no-prototype-builtins
+      if (!this.store.hasOwnProperty(name)) {
+        this.store[name] = null;
+      }
 
-var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
-var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
-var $max = GetIntrinsic('%Math.max%');
+      return this.store[name];
+    }
+  }, {
+    key: "set",
+    value: function set(name, value) {
+      if (this.longtermStore) {
+        this.longtermStore.setItem(name, value);
+      }
 
-if ($defineProperty) {
-	try {
-		$defineProperty({}, 'a', { value: 1 });
-	} catch (e) {
-		// IE 8 has a broken defineProperty
-		$defineProperty = null;
-	}
-}
+      this.store[name] = value;
+      this.emit('change', name);
+    }
+  }, {
+    key: "remove",
+    value: function remove(name) {
+      delete this.store[name];
 
-module.exports = function callBind(originalFunction) {
-	var func = $reflectApply(bind, $call, arguments);
-	if ($gOPD && $defineProperty) {
-		var desc = $gOPD(func, 'length');
-		if (desc.configurable) {
-			// original length, plus the receiver, minus any additional arguments (after the receiver)
-			$defineProperty(
-				func,
-				'length',
-				{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }
-			);
-		}
-	}
-	return func;
-};
+      if (this.longtermStore) {
+        this.longtermStore.removeItem(name);
+      }
 
-var applyBind = function applyBind() {
-	return $reflectApply(bind, $apply, arguments);
-};
+      this.emit('change', name);
+    }
+  }]);
+  return FlagStore;
+}();
 
-if ($defineProperty) {
-	$defineProperty(module.exports, 'apply', { value: applyBind });
-} else {
-	module.exports.apply = applyBind;
-}
+_microee.default.mixin(FlagStore);
 
+var _default = FlagStore;
+exports["default"] = _default;
 
 /***/ }),
-/* 640 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 618 */
+/***/ ((__unused_webpack_module, exports) => {
 
-var hasMap = typeof Map === 'function' && Map.prototype;
-var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
-var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
-var mapForEach = hasMap && Map.prototype.forEach;
-var hasSet = typeof Set === 'function' && Set.prototype;
-var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
-var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
-var setForEach = hasSet && Set.prototype.forEach;
-var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
-var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
-var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
-var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
-var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
-var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
-var booleanValueOf = Boolean.prototype.valueOf;
-var objectToString = Object.prototype.toString;
-var functionToString = Function.prototype.toString;
-var match = String.prototype.match;
-var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
-var gOPS = Object.getOwnPropertySymbols;
-var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
-var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
-var isEnumerable = Object.prototype.propertyIsEnumerable;
+"use strict";
 
-var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
-    [].__proto__ === Array.prototype // eslint-disable-line no-proto
-        ? function (O) {
-            return O.__proto__; // eslint-disable-line no-proto
-        }
-        : null
-);
 
-var inspectCustom = (__webpack_require__(641).custom);
-var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;
-var toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.prefix = exports.getKey = exports["default"] = void 0;
 
-module.exports = function inspect_(obj, options, depth, seen) {
-    var opts = options || {};
+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 F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-    if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {
-        throw new TypeError('option "quoteStyle" must be "single" or "double"');
-    }
-    if (
-        has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
-            ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
-            : opts.maxStringLength !== null
-        )
-    ) {
-        throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
-    }
-    var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
-    if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
-        throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
-    }
+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); }
 
-    if (
-        has(opts, 'indent')
-        && opts.indent !== null
-        && opts.indent !== '\t'
-        && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
-    ) {
-        throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');
-    }
+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; }
 
-    if (typeof obj === 'undefined') {
-        return 'undefined';
-    }
-    if (obj === null) {
-        return 'null';
-    }
-    if (typeof obj === 'boolean') {
-        return obj ? 'true' : 'false';
-    }
+// eslint-disable-next-line no-redeclare
 
-    if (typeof obj === 'string') {
-        return inspectString(obj, opts);
-    }
-    if (typeof obj === 'number') {
-        if (obj === 0) {
-            return Infinity / obj > 0 ? '0' : '-0';
-        }
-        return String(obj);
-    }
-    if (typeof obj === 'bigint') {
-        return String(obj) + 'n';
-    }
+/* global localStorage */
+var prefix = 'flag__';
+exports.prefix = prefix;
 
-    var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
-    if (typeof depth === 'undefined') { depth = 0; }
-    if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
-        return isArray(obj) ? '[Array]' : '[Object]';
-    }
+var getKey = function getKey(name) {
+  return prefix + name;
+};
 
-    var indent = getIndent(opts, depth);
+exports.getKey = getKey;
 
-    if (typeof seen === 'undefined') {
-        seen = [];
-    } else if (indexOf(seen, obj) >= 0) {
-        return '[Circular]';
-    }
+var listFlagLocalStorage = function listFlagLocalStorage() {
+  return Object.keys(localStorage).filter(function (x) {
+    return x.indexOf(prefix) === 0;
+  }).map(function (x) {
+    return x.replace(prefix, '');
+  });
+};
+/**
+ * Gets a flag from localStorage, parses value from JSON
+ *
+ * @param  {String} flag
+ */
 
-    function inspect(value, from, noIndent) {
-        if (from) {
-            seen = seen.slice();
-            seen.push(from);
-        }
-        if (noIndent) {
-            var newOpts = {
-                depth: opts.depth
-            };
-            if (has(opts, 'quoteStyle')) {
-                newOpts.quoteStyle = opts.quoteStyle;
-            }
-            return inspect_(value, newOpts, depth + 1, seen);
-        }
-        return inspect_(value, opts, depth + 1, seen);
-    }
 
-    if (typeof obj === 'function') {
-        var name = nameOf(obj);
-        var keys = arrObjKeys(obj, inspect);
-        return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');
-    }
-    if (isSymbol(obj)) {
-        var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
-        return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
-    }
-    if (isElement(obj)) {
-        var s = '<' + String(obj.nodeName).toLowerCase();
-        var attrs = obj.attributes || [];
-        for (var i = 0; i < attrs.length; i++) {
-            s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
-        }
-        s += '>';
-        if (obj.childNodes && obj.childNodes.length) { s += '...'; }
-        s += '</' + String(obj.nodeName).toLowerCase() + '>';
-        return s;
-    }
-    if (isArray(obj)) {
-        if (obj.length === 0) { return '[]'; }
-        var xs = arrObjKeys(obj, inspect);
-        if (indent && !singleLineValues(xs)) {
-            return '[' + indentedJoin(xs, indent) + ']';
-        }
-        return '[ ' + xs.join(', ') + ' ]';
-    }
-    if (isError(obj)) {
-        var parts = arrObjKeys(obj, inspect);
-        if (parts.length === 0) { return '[' + String(obj) + ']'; }
-        return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';
-    }
-    if (typeof obj === 'object' && customInspect) {
-        if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {
-            return obj[inspectSymbol]();
-        } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
-            return obj.inspect();
-        }
-    }
-    if (isMap(obj)) {
-        var mapParts = [];
-        mapForEach.call(obj, function (value, key) {
-            mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
-        });
-        return collectionOf('Map', mapSize.call(obj), mapParts, indent);
-    }
-    if (isSet(obj)) {
-        var setParts = [];
-        setForEach.call(obj, function (value) {
-            setParts.push(inspect(value, obj));
-        });
-        return collectionOf('Set', setSize.call(obj), setParts, indent);
-    }
-    if (isWeakMap(obj)) {
-        return weakCollectionOf('WeakMap');
-    }
-    if (isWeakSet(obj)) {
-        return weakCollectionOf('WeakSet');
-    }
-    if (isWeakRef(obj)) {
-        return weakCollectionOf('WeakRef');
-    }
-    if (isNumber(obj)) {
-        return markBoxed(inspect(Number(obj)));
-    }
-    if (isBigInt(obj)) {
-        return markBoxed(inspect(bigIntValueOf.call(obj)));
-    }
-    if (isBoolean(obj)) {
-        return markBoxed(booleanValueOf.call(obj));
-    }
-    if (isString(obj)) {
-        return markBoxed(inspect(String(obj)));
-    }
-    if (!isDate(obj) && !isRegExp(obj)) {
-        var ys = arrObjKeys(obj, inspect);
-        var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
-        var protoTag = obj instanceof Object ? '' : 'null prototype';
-        var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';
-        var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
-        var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');
-        if (ys.length === 0) { return tag + '{}'; }
-        if (indent) {
-            return tag + '{' + indentedJoin(ys, indent) + '}';
-        }
-        return tag + '{ ' + ys.join(', ') + ' }';
-    }
-    return String(obj);
+var getItem = function getItem(flag) {
+  var val = localStorage.getItem(getKey(flag));
+  var parsed = val ? JSON.parse(val) : val;
+  return parsed;
 };
+/**
+ * Stores a flag in localStorage, stringifies the value for storage
+ *
+ * @param  {String} flag
+ * @param  {String} value
+ */
 
-function wrapQuotes(s, defaultStyle, opts) {
-    var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'";
-    return quoteChar + s + quoteChar;
-}
-
-function quote(s) {
-    return String(s).replace(/"/g, '&quot;');
-}
 
-function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
-function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
-function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
-function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
-function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
-function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
-function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+var setItem = function setItem(flag, value) {
+  var str = JSON.stringify(value);
+  return localStorage.setItem(getKey(flag), str);
+};
+/**
+ * Removes a flag from localStorage
+ *
+ * @param  {String} flag
+ */
 
-// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
-function isSymbol(obj) {
-    if (hasShammedSymbols) {
-        return obj && typeof obj === 'object' && obj instanceof Symbol;
-    }
-    if (typeof obj === 'symbol') {
-        return true;
-    }
-    if (!obj || typeof obj !== 'object' || !symToString) {
-        return false;
-    }
-    try {
-        symToString.call(obj);
-        return true;
-    } catch (e) {}
-    return false;
-}
 
-function isBigInt(obj) {
-    if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
-        return false;
-    }
-    try {
-        bigIntValueOf.call(obj);
-        return true;
-    } catch (e) {}
-    return false;
-}
+var removeItem = function removeItem(flag) {
+  return localStorage.removeItem(getKey(flag));
+};
+/**
+ * Returns all stored flags as an object
+ */
 
-var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
-function has(obj, key) {
-    return hasOwn.call(obj, key);
-}
 
-function toStr(obj) {
-    return objectToString.call(obj);
-}
+var getAll = function getAll() {
+  var res = {};
 
-function nameOf(f) {
-    if (f.name) { return f.name; }
-    var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/);
-    if (m) { return m[1]; }
-    return null;
-}
+  var _iterator = _createForOfIteratorHelper(listFlagLocalStorage()),
+      _step;
 
-function indexOf(xs, x) {
-    if (xs.indexOf) { return xs.indexOf(x); }
-    for (var i = 0, l = xs.length; i < l; i++) {
-        if (xs[i] === x) { return i; }
+  try {
+    for (_iterator.s(); !(_step = _iterator.n()).done;) {
+      var flag = _step.value;
+      res[flag] = getItem(flag);
     }
-    return -1;
-}
+  } catch (err) {
+    _iterator.e(err);
+  } finally {
+    _iterator.f();
+  }
 
-function isMap(x) {
-    if (!mapSize || !x || typeof x !== 'object') {
-        return false;
-    }
-    try {
-        mapSize.call(x);
-        try {
-            setSize.call(x);
-        } catch (s) {
-            return true;
-        }
-        return x instanceof Map; // core-js workaround, pre-v2.5.0
-    } catch (e) {}
-    return false;
-}
+  return res;
+};
+/**
+ * Clears all the flags from localstorage
+ */
 
-function isWeakMap(x) {
-    if (!weakMapHas || !x || typeof x !== 'object') {
-        return false;
-    }
-    try {
-        weakMapHas.call(x, weakMapHas);
-        try {
-            weakSetHas.call(x, weakSetHas);
-        } catch (s) {
-            return true;
-        }
-        return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
-    } catch (e) {}
-    return false;
-}
 
-function isWeakRef(x) {
-    if (!weakRefDeref || !x || typeof x !== 'object') {
-        return false;
-    }
-    try {
-        weakRefDeref.call(x);
-        return true;
-    } catch (e) {}
-    return false;
-}
+var clearAll = function clearAll() {
+  var _iterator2 = _createForOfIteratorHelper(listFlagLocalStorage()),
+      _step2;
 
-function isSet(x) {
-    if (!setSize || !x || typeof x !== 'object') {
-        return false;
+  try {
+    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+      var flag = _step2.value;
+      removeItem(flag);
     }
-    try {
-        setSize.call(x);
-        try {
-            mapSize.call(x);
-        } catch (m) {
-            return true;
-        }
-        return x instanceof Set; // core-js workaround, pre-v2.5.0
-    } catch (e) {}
-    return false;
-}
+  } catch (err) {
+    _iterator2.e(err);
+  } finally {
+    _iterator2.f();
+  }
+};
 
-function isWeakSet(x) {
-    if (!weakSetHas || !x || typeof x !== 'object') {
-        return false;
-    }
-    try {
-        weakSetHas.call(x, weakSetHas);
-        try {
-            weakMapHas.call(x, weakMapHas);
-        } catch (s) {
-            return true;
-        }
-        return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
-    } catch (e) {}
-    return false;
-}
+var _default = {
+  getAll: getAll,
+  getItem: getItem,
+  setItem: setItem,
+  clearAll: clearAll,
+  removeItem: removeItem
+};
+exports["default"] = _default;
 
-function isElement(x) {
-    if (!x || typeof x !== 'object') { return false; }
-    if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
-        return true;
-    }
-    return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
-}
+/***/ }),
+/* 619 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-function inspectString(str, opts) {
-    if (str.length > opts.maxStringLength) {
-        var remaining = str.length - opts.maxStringLength;
-        var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
-        return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;
-    }
-    // eslint-disable-next-line no-control-regex
-    var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte);
-    return wrapQuotes(s, 'single', opts);
-}
+"use strict";
 
-function lowbyte(c) {
-    var n = c.charCodeAt(0);
-    var x = {
-        8: 'b',
-        9: 't',
-        10: 'n',
-        12: 'f',
-        13: 'r'
-    }[n];
-    if (x) { return '\\' + x; }
-    return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();
-}
 
-function markBoxed(str) {
-    return 'Object(' + str + ')';
-}
+var _interopRequireDefault = __webpack_require__(524);
 
-function weakCollectionOf(type) {
-    return type + ' { ? }';
-}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.QueryDefinition = exports.MutationTypes = exports.Mutations = exports.getDoctypeFromOperation = exports.uploadFile = exports.removeReferencedBy = exports.addReferencedBy = exports.removeReferencesTo = exports.addReferencesTo = exports.deleteDocument = exports.updateDocuments = exports.updateDocument = exports.createDocument = exports.isAGetByIdQuery = exports.Q = void 0;
 
-function collectionOf(type, size, entries, indent) {
-    var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');
-    return type + ' (' + size + ') {' + joinedEntries + '}';
-}
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-function singleLineValues(xs) {
-    for (var i = 0; i < xs.length; i++) {
-        if (indexOf(xs[i], '\n') >= 0) {
-            return false;
-        }
-    }
-    return true;
-}
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-function getIndent(opts, depth) {
-    var baseIndent;
-    if (opts.indent === '\t') {
-        baseIndent = '\t';
-    } else if (typeof opts.indent === 'number' && opts.indent > 0) {
-        baseIndent = Array(opts.indent + 1).join(' ');
-    } else {
-        return null;
-    }
-    return {
-        base: baseIndent,
-        prev: Array(depth + 1).join(baseIndent)
-    };
-}
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-function indentedJoin(xs, indent) {
-    if (xs.length === 0) { return ''; }
-    var lineJoiner = '\n' + indent.prev + indent.base;
-    return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev;
-}
+var _isArray = _interopRequireDefault(__webpack_require__(55));
 
-function arrObjKeys(obj, inspect) {
-    var isArr = isArray(obj);
-    var xs = [];
-    if (isArr) {
-        xs.length = obj.length;
-        for (var i = 0; i < obj.length; i++) {
-            xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
-        }
-    }
-    var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
-    var symMap;
-    if (hasShammedSymbols) {
-        symMap = {};
-        for (var k = 0; k < syms.length; k++) {
-            symMap['$' + syms[k]] = syms[k];
-        }
-    }
+var _findKey = _interopRequireDefault(__webpack_require__(620));
 
-    for (var key in obj) { // eslint-disable-line no-restricted-syntax
-        if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
-        if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
-        if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
-            // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
-            continue; // eslint-disable-line no-restricted-syntax, no-continue
-        } else if ((/[^\w$]/).test(key)) {
-            xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
-        } else {
-            xs.push(key + ': ' + inspect(obj[key], obj));
-        }
-    }
-    if (typeof gOPS === 'function') {
-        for (var j = 0; j < syms.length; j++) {
-            if (isEnumerable.call(obj, syms[j])) {
-                xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
-            }
-        }
-    }
-    return xs;
-}
+var _types = __webpack_require__(622);
 
+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; }
 
-/***/ }),
-/* 641 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-module.exports = __webpack_require__(64).inspect;
+/**
+ * @typedef PartialQueryDefinition
+ *
+ * @property {Array} [indexedFields]
+ * @property {Array} [sort]
+ * @property {object} [selector]
+ */
 
+/**
+ * @typedef {object} MangoSelector
+ */
 
-/***/ }),
-/* 642 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/**
+ * @typedef {object} MangoPartialFilter
+ */
 
-"use strict";
+/**
+ * Chainable API to create query definitions to retrieve documents
+ * from a Cozy. `QueryDefinition`s are sent to links.
+ *
+ * @augments {object}
+ */
+var QueryDefinition = /*#__PURE__*/function () {
+  /**
+   * @class
+   *
+   * @param {object} options Initial options for the query definition
+   * @param {Doctype} [options.doctype] - The doctype of the doc.
+   * @param {DocId|null} [options.id] - The id of the doc.
+   * @param {Array<DocId>} [options.ids] - The ids of the docs.
+   * @param {MangoSelector} [options.selector] - The selector to query the docs.
+   * @param {Array<string>} [options.fields] - The fields to return.
+   * @param {Array<string>} [options.indexedFields] - The fields to index.
+   * @param {MangoPartialFilter} [options.partialFilter] - The partial index definition to filter docs.
+   * @param {Array<object>} [options.sort] - The sorting params.
+   * @param {Array<string>} [options.includes] - The docs to include.
+   * @param {string|null} [options.referenced] - The referenced document.
+   * @param {number|null} [options.limit] - The document's limit to return.
+   * @param {number|null} [options.skip] - The number of docs to skip.
+   * @param {CouchDBViewCursor} [options.cursor] - The cursor to paginate views.
+   * @param {string} [options.bookmark] - The bookmark to paginate mango queries.
+   */
+  function QueryDefinition() {
+    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+    (0, _classCallCheck2.default)(this, QueryDefinition);
+    this.doctype = options.doctype;
+    this.id = options.id;
+    this.ids = options.ids;
+    this.selector = options.selector;
+    this.fields = options.fields;
+    this.indexedFields = options.indexedFields;
+    this.partialFilter = options.partialFilter;
+    this.sort = options.sort;
+    this.includes = options.includes;
+    this.referenced = options.referenced;
+    this.limit = options.limit;
+    this.skip = options.skip;
+    this.cursor = options.cursor;
+    this.bookmark = options.bookmark;
+  }
+  /**
+   * Checks if the sort order matches the index' fields order.
+   *
+   * When sorting with CouchDB, it is required to:
+   * - use indexed fields
+   * - keep the same order than the indexed fields.
+   *
+   * See https://docs.cozy.io/en/tutorials/data/queries/#sort-data-with-mango
+   *
+   * @param {PartialQueryDefinition} obj - A partial QueryDefinition to check
+   */
 
 
-var formats = __webpack_require__(643);
+  (0, _createClass2.default)(QueryDefinition, [{
+    key: "checkSortOrder",
+    value: function checkSortOrder(_ref) {
+      var sort = _ref.sort,
+          selector = _ref.selector,
+          indexedFields = _ref.indexedFields;
 
-var has = Object.prototype.hasOwnProperty;
-var isArray = Array.isArray;
+      var _sort = this.sort || sort;
 
-var hexTable = (function () {
-    var array = [];
-    for (var i = 0; i < 256; ++i) {
-        array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
-    }
+      var _selector = this.selector || selector || {};
 
-    return array;
-}());
+      var _indexedFields = this.indexedFields || indexedFields;
 
-var compactQueue = function compactQueue(queue) {
-    while (queue.length > 1) {
-        var item = queue.pop();
-        var obj = item.obj[item.prop];
+      if (!_sort) {
+        return;
+      }
 
-        if (isArray(obj)) {
-            var compacted = [];
+      var fieldsToIndex = _indexedFields || Object.keys(_selector);
 
-            for (var j = 0; j < obj.length; ++j) {
-                if (typeof obj[j] !== 'undefined') {
-                    compacted.push(obj[j]);
-                }
-            }
+      if (!fieldsToIndex || fieldsToIndex.length < 1) {
+        return;
+      }
 
-            item.obj[item.prop] = compacted;
+      if (_sort.length > fieldsToIndex.length) {
+        console.warn("You should not sort on non-indexed fields.\n\n        Sort: ".concat(JSON.stringify(_sort), "\n\n        Indexed fields: ").concat(fieldsToIndex));
+        return;
+      }
+
+      for (var i = 0; i < _sort.length; i++) {
+        if (Object.keys(_sort[i])[0] !== fieldsToIndex[i]) {
+          console.warn("The sort order should be the same than the indexed fields.\n\n          Sort: ".concat(JSON.stringify(_sort), "\n\n          Indexed fields: ").concat(fieldsToIndex, "\n"));
+          return;
         }
+      }
     }
-};
+    /**
+     * Checks the selector predicates.
+     *
+     * It is useful to warn the developer when a partial index might be used.
+     *
+     * @param {MangoSelector} selector - The selector definition
+     * @returns {void}
+     */
 
-var arrayToObject = function arrayToObject(source, options) {
-    var obj = options && options.plainObjects ? Object.create(null) : {};
-    for (var i = 0; i < source.length; ++i) {
-        if (typeof source[i] !== 'undefined') {
-            obj[i] = source[i];
-        }
+  }, {
+    key: "checkSelector",
+    value: function checkSelector(selector) {
+      var hasExistsFalse = (0, _findKey.default)(selector, ['$exists', false]);
+
+      if (hasExistsFalse) {
+        console.warn("The \"$exists: false\" predicate should be defined as a partial index for better performance.\n\n        Selector: ".concat(selector));
+      }
+
+      var hasNe = (0, _findKey.default)(selector, '$ne');
+
+      if (hasNe) {
+        console.info("The use of the $ne operator is more efficient with a partial index.\n\n        Selector: ".concat(selector));
+      }
     }
+    /**
+     * Query a single document on its id.
+     *
+     * @param {string} id   The document id.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    return obj;
-};
+  }, {
+    key: "getById",
+    value: function getById(id) {
+      if (!id) {
+        throw new Error('getById called with undefined id');
+      }
 
-var merge = function merge(target, source, options) {
-    /* eslint no-param-reassign: 0 */
-    if (!source) {
-        return target;
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        id: id
+      }));
     }
+    /**
+     * Query several documents on their ids.
+     *
+     * @param {Array} ids   The documents ids.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    if (typeof source !== 'object') {
-        if (isArray(target)) {
-            target.push(source);
-        } else if (target && typeof target === 'object') {
-            if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
-                target[source] = true;
-            }
-        } else {
-            return [target, source];
-        }
+  }, {
+    key: "getByIds",
+    value: function getByIds(ids) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        ids: ids
+      }));
+    }
+    /**
+     * Query documents with a [mango selector](http://docs.couchdb.org/en/latest/api/database/find.html#find-selectors).
+     * Each field passed in the selector will be indexed, except if the indexField option is used.
+     *
+     * @param {MangoSelector} selector   The Mango selector.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-        return target;
+  }, {
+    key: "where",
+    value: function where(selector) {
+      this.checkSortOrder({
+        selector: selector
+      });
+      this.checkSelector(selector);
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        selector: selector
+      }));
     }
+    /**
+     * Specify which fields of each object should be returned. If it is omitted, the entire object is returned.
+     *
+     * @param {Array} fields The fields to return.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    if (!target || typeof target !== 'object') {
-        return [target].concat(source);
+  }, {
+    key: "select",
+    value: function select(fields) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        fields: fields
+      }));
     }
+    /**
+     * Specify which fields should be indexed. This prevent the automatic indexing of the mango fields.
+     *
+     * @param {Array} indexedFields The fields to index.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    var mergeTarget = target;
-    if (isArray(target) && !isArray(source)) {
-        mergeTarget = arrayToObject(target, options);
+  }, {
+    key: "indexFields",
+    value: function indexFields(indexedFields) {
+      this.checkSortOrder({
+        indexedFields: indexedFields
+      });
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        indexedFields: indexedFields
+      }));
     }
+    /**
+     * Specify a [partial index](https://docs.couchdb.org/en/stable/api/database/find.html#find-partial-indexes).
+     * The filter must follow the same syntax than the selector.
+     *
+     * A partial index includes a filter, used to select documents before the indexing.
+     * You can find more information about partial indexes [here](https://docs.cozy.io/en/tutorials/data/advanced/#partial-indexes)
+     *
+     * @param {object} partialFilter - The filter definition.
+     */
 
-    if (isArray(target) && isArray(source)) {
-        source.forEach(function (item, i) {
-            if (has.call(target, i)) {
-                var targetItem = target[i];
-                if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
-                    target[i] = merge(targetItem, item, options);
-                } else {
-                    target.push(item);
-                }
-            } else {
-                target[i] = item;
-            }
-        });
-        return target;
+  }, {
+    key: "partialIndex",
+    value: function partialIndex(partialFilter) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        partialFilter: partialFilter
+      }));
     }
+    /**
+     * Specify how to sort documents, following the [sort syntax](http://docs.couchdb.org/en/latest/api/database/find.html#find-sort)
+     *
+     * @param {Array} sort The list of field name and direction pairs.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    return Object.keys(source).reduce(function (acc, key) {
-        var value = source[key];
+  }, {
+    key: "sortBy",
+    value: function sortBy(sort) {
+      if (!(0, _isArray.default)(sort)) {
+        throw new Error("Invalid sort, should be an array ([{ label: \"desc\"}, { name: \"asc\"}]), you passed ".concat(JSON.stringify(sort), "."));
+      }
 
-        if (has.call(acc, key)) {
-            acc[key] = merge(acc[key], value, options);
-        } else {
-            acc[key] = value;
-        }
-        return acc;
-    }, mergeTarget);
-};
+      this.checkSortOrder({
+        sort: sort
+      });
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        sort: sort
+      }));
+    }
+    /**
+     * Includes documents having a relationships with the ones queried.
+     * For example, query albums including the photos.
+     *
+     * @param {Array} includes The documents to include.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-var assign = function assignSingleSource(target, source) {
-    return Object.keys(source).reduce(function (acc, key) {
-        acc[key] = source[key];
-        return acc;
-    }, target);
-};
+  }, {
+    key: "include",
+    value: function include(includes) {
+      if (!Array.isArray(includes)) {
+        throw new Error('include() takes an array of relationship names');
+      }
 
-var decode = function (str, decoder, charset) {
-    var strWithoutPlus = str.replace(/\+/g, ' ');
-    if (charset === 'iso-8859-1') {
-        // unescape never throws, no try...catch needed:
-        return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
-    }
-    // utf-8
-    try {
-        return decodeURIComponent(strWithoutPlus);
-    } catch (e) {
-        return strWithoutPlus;
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        includes: includes
+      }));
     }
-};
+    /**
+     * Maximum number of documents returned, useful for pagination. Default is 100.
+     *
+     * @param {number} limit The document's limit.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-var encode = function encode(str, defaultEncoder, charset, kind, format) {
-    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
-    // It has been adapted here for stricter adherence to RFC 3986
-    if (str.length === 0) {
-        return str;
+  }, {
+    key: "limitBy",
+    value: function limitBy(limit) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        limit: limit
+      }));
     }
-
-    var string = str;
-    if (typeof str === 'symbol') {
-        string = Symbol.prototype.toString.call(str);
-    } else if (typeof str !== 'string') {
-        string = String(str);
+  }, {
+    key: "UNSAFE_noLimit",
+    value: function UNSAFE_noLimit() {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        limit: null
+      }));
     }
+    /**
+     * Skip the first ‘n’ documents, where ‘n’ is the value specified.
+     *
+     * Beware, this [performs badly](http://docs.couchdb.org/en/stable/ddocs/views/pagination.html#paging-alternate-method) on view's index.
+     *  Prefer cursor-based pagination in such situation.
+     *
+     * @param {number} skip The number of documents to skip.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    if (charset === 'iso-8859-1') {
-        return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
-            return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
-        });
+  }, {
+    key: "offset",
+    value: function offset(skip) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        bookmark: undefined,
+        cursor: undefined,
+        skip: skip
+      }));
     }
+    /**
+     * Use [cursor-based](https://docs.cozy.io/en/cozy-stack/jsonapi/#pagination) pagination.
+     * *Warning*: this is only useful for views.
+     * The cursor is a [startkey, startkey_docid] array, where startkey is the view's key,
+     * e.g. ["io.cozy.photos.albums", "album-id"] and startkey_docid is the id of
+     * the starting document of the query, e.g. "file-id".
+     * Use the last docid of each query as startkey_docid to paginate or leave blank for the first query.
+     *
+     * @param {CouchDBViewCursor} cursor The cursor for pagination.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    var out = '';
-    for (var i = 0; i < string.length; ++i) {
-        var c = string.charCodeAt(i);
-
-        if (
-            c === 0x2D // -
-            || c === 0x2E // .
-            || c === 0x5F // _
-            || c === 0x7E // ~
-            || (c >= 0x30 && c <= 0x39) // 0-9
-            || (c >= 0x41 && c <= 0x5A) // a-z
-            || (c >= 0x61 && c <= 0x7A) // A-Z
-            || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
-        ) {
-            out += string.charAt(i);
-            continue;
-        }
-
-        if (c < 0x80) {
-            out = out + hexTable[c];
-            continue;
-        }
-
-        if (c < 0x800) {
-            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
-            continue;
-        }
-
-        if (c < 0xD800 || c >= 0xE000) {
-            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
-            continue;
-        }
-
-        i += 1;
-        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
-        out += hexTable[0xF0 | (c >> 18)]
-            + hexTable[0x80 | ((c >> 12) & 0x3F)]
-            + hexTable[0x80 | ((c >> 6) & 0x3F)]
-            + hexTable[0x80 | (c & 0x3F)];
+  }, {
+    key: "offsetCursor",
+    value: function offsetCursor(cursor) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        bookmark: undefined,
+        skip: undefined,
+        cursor: cursor
+      }));
     }
+    /**
+     * Use [bookmark](https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination) pagination.
+     * Note this only applies for mango-queries (not views) and is way more efficient than skip pagination.
+     * The bookmark is a string returned by the _find response and can be seen as a pointer in
+     * the index for the next query.
+     *
+     * @param {string} bookmark The bookmark to continue a previous paginated query.
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    return out;
-};
-
-var compact = function compact(value) {
-    var queue = [{ obj: { o: value }, prop: 'o' }];
-    var refs = [];
-
-    for (var i = 0; i < queue.length; ++i) {
-        var item = queue[i];
-        var obj = item.obj[item.prop];
-
-        var keys = Object.keys(obj);
-        for (var j = 0; j < keys.length; ++j) {
-            var key = keys[j];
-            var val = obj[key];
-            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
-                queue.push({ obj: obj, prop: key });
-                refs.push(val);
-            }
-        }
+  }, {
+    key: "offsetBookmark",
+    value: function offsetBookmark(bookmark) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        skip: undefined,
+        cursor: undefined,
+        bookmark: bookmark
+      }));
     }
+    /**
+     * Use the [file reference system](https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/)
+     *
+     * @param {object} document The reference document
+     * @returns {QueryDefinition}  The QueryDefinition object.
+     */
 
-    compactQueue(queue);
-
-    return value;
-};
-
-var isRegExp = function isRegExp(obj) {
-    return Object.prototype.toString.call(obj) === '[object RegExp]';
-};
-
-var isBuffer = function isBuffer(obj) {
-    if (!obj || typeof obj !== 'object') {
-        return false;
+  }, {
+    key: "referencedBy",
+    value: function referencedBy(document) {
+      return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
+        referenced: document
+      }));
     }
+  }, {
+    key: "toDefinition",
+    value: function toDefinition() {
+      return {
+        doctype: this.doctype,
+        id: this.id,
+        ids: this.ids,
+        selector: this.selector,
+        fields: this.fields,
+        indexedFields: this.indexedFields,
+        partialFilter: this.partialFilter,
+        sort: this.sort,
+        includes: this.includes,
+        referenced: this.referenced,
+        limit: this.limit,
+        skip: this.skip,
+        cursor: this.cursor,
+        bookmark: this.bookmark
+      };
+    }
+  }]);
+  return QueryDefinition;
+}();
+/**
+ * Helper to create a QueryDefinition. Recommended way to create
+ * query definitions.
+ *
+ * @param {Doctype} doctype - Doctype of the query definition
+ *
+ * @example
+ * ```
+ * import { Q } from 'cozy-client'
+ *
+ * const qDef = Q('io.cozy.todos').where({ _id: '1234' })
+ * ```
+ */
 
-    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
-};
-
-var combine = function combine(a, b) {
-    return [].concat(a, b);
-};
 
-var maybeMap = function maybeMap(val, fn) {
-    if (isArray(val)) {
-        var mapped = [];
-        for (var i = 0; i < val.length; i += 1) {
-            mapped.push(fn(val[i]));
-        }
-        return mapped;
-    }
-    return fn(val);
-};
+exports.QueryDefinition = QueryDefinition;
 
-module.exports = {
-    arrayToObject: arrayToObject,
-    assign: assign,
-    combine: combine,
-    compact: compact,
-    decode: decode,
-    encode: encode,
-    isBuffer: isBuffer,
-    isRegExp: isRegExp,
-    maybeMap: maybeMap,
-    merge: merge
+var Q = function Q(doctype) {
+  return new QueryDefinition({
+    doctype: doctype
+  });
 };
+/**
+ * Check if the query is a getById() query
+ *
+ * @param {QueryDefinition} queryDefinition The query definition
+ *
+ * @returns {boolean}
+ */
 
 
-/***/ }),
-/* 643 */
-/***/ ((module) => {
+exports.Q = Q;
 
-"use strict";
+var isAGetByIdQuery = function isAGetByIdQuery(queryDefinition) {
+  if (!queryDefinition) return false;
+  var attributes = Object.values(queryDefinition);
+  if (attributes.length === 0) return false; // 2 attrs because we check if id and doctype are not undefined
 
+  return attributes.filter(function (attr) {
+    return attr !== undefined;
+  }).length === 2 && queryDefinition.id !== undefined;
+}; // Mutations
 
-var replace = String.prototype.replace;
-var percentTwenties = /%20/g;
 
-var Format = {
-    RFC1738: 'RFC1738',
-    RFC3986: 'RFC3986'
-};
+exports.isAGetByIdQuery = isAGetByIdQuery;
+var CREATE_DOCUMENT = 'CREATE_DOCUMENT';
+var UPDATE_DOCUMENT = 'UPDATE_DOCUMENT';
+var UPDATE_DOCUMENTS = 'UPDATE_DOCUMENTS';
+var DELETE_DOCUMENT = 'DELETE_DOCUMENT';
+var ADD_REFERENCES_TO = 'ADD_REFERENCES_TO';
+var REMOVE_REFERENCES_TO = 'REMOVE_REFERENCES_TO';
+var ADD_REFERENCED_BY = 'ADD_REFERENCED_BY';
+var REMOVE_REFERENCED_BY = 'REMOVE_REFERENCED_BY';
+var UPLOAD_FILE = 'UPLOAD_FILE';
 
-module.exports = {
-    'default': Format.RFC3986,
-    formatters: {
-        RFC1738: function (value) {
-            return replace.call(value, percentTwenties, '+');
-        },
-        RFC3986: function (value) {
-            return String(value);
-        }
-    },
-    RFC1738: Format.RFC1738,
-    RFC3986: Format.RFC3986
+var createDocument = function createDocument(document) {
+  return {
+    mutationType: MutationTypes.CREATE_DOCUMENT,
+    document: document
+  };
 };
 
+exports.createDocument = createDocument;
 
-/***/ }),
-/* 644 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-"use strict";
+var updateDocument = function updateDocument(document) {
+  return {
+    mutationType: MutationTypes.UPDATE_DOCUMENT,
+    document: document
+  };
+};
 
+exports.updateDocument = updateDocument;
 
-var utils = __webpack_require__(642);
+var updateDocuments = function updateDocuments(documents) {
+  return {
+    mutationType: MutationTypes.UPDATE_DOCUMENTS,
+    documents: documents
+  };
+};
 
-var has = Object.prototype.hasOwnProperty;
-var isArray = Array.isArray;
+exports.updateDocuments = updateDocuments;
 
-var defaults = {
-    allowDots: false,
-    allowPrototypes: false,
-    allowSparse: false,
-    arrayLimit: 20,
-    charset: 'utf-8',
-    charsetSentinel: false,
-    comma: false,
-    decoder: utils.decode,
-    delimiter: '&',
-    depth: 5,
-    ignoreQueryPrefix: false,
-    interpretNumericEntities: false,
-    parameterLimit: 1000,
-    parseArrays: true,
-    plainObjects: false,
-    strictNullHandling: false
+var deleteDocument = function deleteDocument(document) {
+  return {
+    mutationType: MutationTypes.DELETE_DOCUMENT,
+    document: document
+  };
 };
 
-var interpretNumericEntities = function (str) {
-    return str.replace(/&#(\d+);/g, function ($0, numberStr) {
-        return String.fromCharCode(parseInt(numberStr, 10));
-    });
+exports.deleteDocument = deleteDocument;
+
+var addReferencesTo = function addReferencesTo(document, referencedDocuments) {
+  return {
+    mutationType: MutationTypes.ADD_REFERENCES_TO,
+    referencedDocuments: referencedDocuments,
+    document: document
+  };
 };
 
-var parseArrayValue = function (val, options) {
-    if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
-        return val.split(',');
-    }
+exports.addReferencesTo = addReferencesTo;
 
-    return val;
+var removeReferencesTo = function removeReferencesTo(document, referencedDocuments) {
+  return {
+    mutationType: MutationTypes.REMOVE_REFERENCES_TO,
+    referencedDocuments: referencedDocuments,
+    document: document
+  };
 };
 
-// This is what browsers will submit when the ✓ character occurs in an
-// application/x-www-form-urlencoded body and the encoding of the page containing
-// the form is iso-8859-1, or when the submitted form has an accept-charset
-// attribute of iso-8859-1. Presumably also with other charsets that do not contain
-// the ✓ character, such as us-ascii.
-var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')
+exports.removeReferencesTo = removeReferencesTo;
 
-// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
-var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
+var addReferencedBy = function addReferencedBy(document, referencedDocuments) {
+  return {
+    mutationType: MutationTypes.ADD_REFERENCED_BY,
+    referencedDocuments: referencedDocuments,
+    document: document
+  };
+};
 
-var parseValues = function parseQueryStringValues(str, options) {
-    var obj = {};
-    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
-    var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
-    var parts = cleanStr.split(options.delimiter, limit);
-    var skipIndex = -1; // Keep track of where the utf8 sentinel was found
-    var i;
+exports.addReferencedBy = addReferencedBy;
 
-    var charset = options.charset;
-    if (options.charsetSentinel) {
-        for (i = 0; i < parts.length; ++i) {
-            if (parts[i].indexOf('utf8=') === 0) {
-                if (parts[i] === charsetSentinel) {
-                    charset = 'utf-8';
-                } else if (parts[i] === isoSentinel) {
-                    charset = 'iso-8859-1';
-                }
-                skipIndex = i;
-                i = parts.length; // The eslint settings do not allow break;
-            }
-        }
-    }
+var removeReferencedBy = function removeReferencedBy(document, referencedDocuments) {
+  return {
+    mutationType: MutationTypes.REMOVE_REFERENCED_BY,
+    referencedDocuments: referencedDocuments,
+    document: document
+  };
+};
 
-    for (i = 0; i < parts.length; ++i) {
-        if (i === skipIndex) {
-            continue;
-        }
-        var part = parts[i];
+exports.removeReferencedBy = removeReferencedBy;
 
-        var bracketEqualsPos = part.indexOf(']=');
-        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
+var uploadFile = function uploadFile(file, dirPath) {
+  return {
+    mutationType: MutationTypes.UPLOAD_FILE,
+    file: file,
+    dirPath: dirPath
+  };
+};
 
-        var key, val;
-        if (pos === -1) {
-            key = options.decoder(part, defaults.decoder, charset, 'key');
-            val = options.strictNullHandling ? null : '';
-        } else {
-            key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
-            val = utils.maybeMap(
-                parseArrayValue(part.slice(pos + 1), options),
-                function (encodedVal) {
-                    return options.decoder(encodedVal, defaults.decoder, charset, 'value');
-                }
-            );
-        }
+exports.uploadFile = uploadFile;
 
-        if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
-            val = interpretNumericEntities(val);
-        }
+var getDoctypeFromOperation = function getDoctypeFromOperation(operation) {
+  if (operation.mutationType) {
+    var type = operation.mutationType;
 
-        if (part.indexOf('[]=') > -1) {
-            val = isArray(val) ? [val] : val;
-        }
+    switch (type) {
+      case CREATE_DOCUMENT:
+        return operation.document._type;
 
-        if (has.call(obj, key)) {
-            obj[key] = utils.combine(obj[key], val);
-        } else {
-            obj[key] = val;
-        }
-    }
+      case UPDATE_DOCUMENT:
+        return operation.document._type;
 
-    return obj;
-};
+      case UPDATE_DOCUMENTS:
+        return operation.documents[0]._type;
 
-var parseObject = function (chain, val, options, valuesParsed) {
-    var leaf = valuesParsed ? val : parseArrayValue(val, options);
+      case DELETE_DOCUMENT:
+        return operation.document._type;
 
-    for (var i = chain.length - 1; i >= 0; --i) {
-        var obj;
-        var root = chain[i];
+      case ADD_REFERENCES_TO:
+        throw new Error('Not implemented');
 
-        if (root === '[]' && options.parseArrays) {
-            obj = [].concat(leaf);
-        } else {
-            obj = options.plainObjects ? Object.create(null) : {};
-            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
-            var index = parseInt(cleanRoot, 10);
-            if (!options.parseArrays && cleanRoot === '') {
-                obj = { 0: leaf };
-            } else if (
-                !isNaN(index)
-                && root !== cleanRoot
-                && String(index) === cleanRoot
-                && index >= 0
-                && (options.parseArrays && index <= options.arrayLimit)
-            ) {
-                obj = [];
-                obj[index] = leaf;
-            } else {
-                obj[cleanRoot] = leaf;
-            }
-        }
+      case UPLOAD_FILE:
+        throw new Error('Not implemented');
 
-        leaf = obj;
+      default:
+        throw new Error("Unknown mutationType ".concat(type));
     }
+  } else {
+    return operation.doctype;
+  }
+};
 
-    return leaf;
+exports.getDoctypeFromOperation = getDoctypeFromOperation;
+var Mutations = {
+  createDocument: createDocument,
+  updateDocument: updateDocument,
+  updateDocuments: updateDocuments,
+  deleteDocument: deleteDocument,
+  addReferencesTo: addReferencesTo,
+  removeReferencesTo: removeReferencesTo,
+  addReferencedBy: addReferencedBy,
+  removeReferencedBy: removeReferencedBy,
+  uploadFile: uploadFile
+};
+exports.Mutations = Mutations;
+var MutationTypes = {
+  CREATE_DOCUMENT: CREATE_DOCUMENT,
+  UPDATE_DOCUMENT: UPDATE_DOCUMENT,
+  UPDATE_DOCUMENTS: UPDATE_DOCUMENTS,
+  DELETE_DOCUMENT: DELETE_DOCUMENT,
+  ADD_REFERENCES_TO: ADD_REFERENCES_TO,
+  REMOVE_REFERENCES_TO: REMOVE_REFERENCES_TO,
+  ADD_REFERENCED_BY: ADD_REFERENCED_BY,
+  REMOVE_REFERENCED_BY: REMOVE_REFERENCED_BY,
+  UPLOAD_FILE: UPLOAD_FILE
 };
+exports.MutationTypes = MutationTypes;
 
-var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
-    if (!givenKey) {
-        return;
-    }
+/***/ }),
+/* 620 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    // Transform dot notation to bracket notation
-    var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
+var baseFindKey = __webpack_require__(621),
+    baseForOwn = __webpack_require__(548),
+    baseIteratee = __webpack_require__(413);
 
-    // The regex chunks
+/**
+ * This method is like `_.find` except that it returns the key of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element,
+ *  else `undefined`.
+ * @example
+ *
+ * var users = {
+ *   'barney':  { 'age': 36, 'active': true },
+ *   'fred':    { 'age': 40, 'active': false },
+ *   'pebbles': { 'age': 1,  'active': true }
+ * };
+ *
+ * _.findKey(users, function(o) { return o.age < 40; });
+ * // => 'barney' (iteration order is not guaranteed)
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findKey(users, { 'age': 1, 'active': true });
+ * // => 'pebbles'
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findKey(users, 'active');
+ * // => 'barney'
+ */
+function findKey(object, predicate) {
+  return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn);
+}
 
-    var brackets = /(\[[^[\]]*])/;
-    var child = /(\[[^[\]]*])/g;
+module.exports = findKey;
 
-    // Get the parent
 
-    var segment = options.depth > 0 && brackets.exec(key);
-    var parent = segment ? key.slice(0, segment.index) : key;
+/***/ }),
+/* 621 */
+/***/ ((module) => {
 
-    // Stash the parent if it exists
+/**
+ * The base implementation of methods like `_.findKey` and `_.findLastKey`,
+ * without support for iteratee shorthands, which iterates over `collection`
+ * using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to inspect.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */
+function baseFindKey(collection, predicate, eachFunc) {
+  var result;
+  eachFunc(collection, function(value, key, collection) {
+    if (predicate(value, key, collection)) {
+      result = key;
+      return false;
+    }
+  });
+  return result;
+}
 
-    var keys = [];
-    if (parent) {
-        // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
-        if (!options.plainObjects && has.call(Object.prototype, parent)) {
-            if (!options.allowPrototypes) {
-                return;
-            }
-        }
+module.exports = baseFindKey;
 
-        keys.push(parent);
-    }
 
-    // Loop through children appending to the array until we hit depth
+/***/ }),
+/* 622 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-    var i = 0;
-    while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
-        i += 1;
-        if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
-            if (!options.allowPrototypes) {
-                return;
-            }
-        }
-        keys.push(segment[1]);
-    }
+"use strict";
 
-    // If there's a remainder, just add whatever is left
 
-    if (segment) {
-        keys.push('[' + key.slice(segment.index) + ']');
-    }
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-    return parseObject(keys, val, options, valuesParsed);
-};
+var _dsl = __webpack_require__(619);
 
-var normalizeParseOptions = function normalizeParseOptions(opts) {
-    if (!opts) {
-        return defaults;
-    }
+/**
+ * @typedef {"io.cozy.accounts"} AccountsDoctype
+ * @typedef {"io.cozy.triggers"} TriggersDoctype
+ * @typedef {"io.cozy.konnectors"} KonnectorsDoctype
+ * @typedef {"io.cozy.notes"} NotesDoctype
+ * @typedef {"io.cozy.apps"} AppsDoctype
+ * @typedef {"io.cozy.settings"} SettingsDoctype
+ * @typedef {"io.cozy-oauth.clients"} OAuthClientsDoctype
+ * @typedef {"io.cozy.files"} FilesDoctype
+ * @typedef {AccountsDoctype|TriggersDoctype|KonnectorsDoctype|NotesDoctype|AppsDoctype|SettingsDoctype|OAuthClientsDoctype|FilesDoctype} KnownDoctype
+ * @typedef {KnownDoctype|string} Doctype
+ */
 
-    if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
-        throw new TypeError('Decoder has to be a function.');
-    }
+/**
+ * @typedef {object} Link
+ * @typedef {object} Mutation
+ * @typedef {object} DocumentCollection
+ * @typedef {object} QueryResult
+ * @typedef {object} HydratedDocument
+ * @typedef {object} ReduxStore
+ * @typedef {object} Token
+ * @typedef {object} ClientResponse
+ * @typedef {object} Manifest
+ */
 
-    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
-        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
-    }
-    var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
+/**
+ * @typedef {object} OldCozyClient
+ */
 
-    return {
-        allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
-        allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
-        allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
-        arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
-        charset: charset,
-        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
-        comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
-        decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
-        delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
-        // eslint-disable-next-line no-implicit-coercion, no-extra-parens
-        depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
-        ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
-        interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
-        parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
-        parseArrays: opts.parseArrays !== false,
-        plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
-        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
-    };
-};
+/**
+ * @typedef {object} NodeEnvironment
+ */
 
-module.exports = function (str, opts) {
-    var options = normalizeParseOptions(opts);
+/**
+ * @typedef {"loading"|"loaded"|"pending"|"failed"} QueryFetchStatus
+ */
 
-    if (str === '' || str === null || typeof str === 'undefined') {
-        return options.plainObjects ? Object.create(null) : {};
-    }
+/**
+ * @typedef {Record<Doctype, QueryState>} QueriesStateSlice
+ */
 
-    var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
-    var obj = options.plainObjects ? Object.create(null) : {};
+/**
+ * @typedef {Record<string, CozyClientDocument>} IndexedDocuments
+ */
 
-    // Iterate over the keys and setup the new object
+/**
+ * @typedef {Record<Doctype, IndexedDocuments>} DocumentsStateSlice
+ */
 
-    var keys = Object.keys(tempObj);
-    for (var i = 0; i < keys.length; ++i) {
-        var key = keys[i];
-        var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');
-        obj = utils.merge(obj, newObj, options);
-    }
+/**
+ * @typedef {object} QueryState
+ * @property {string} id
+ * @property {QueryDefinition} definition
+ * @property {QueryFetchStatus} fetchStatus
+ * @property {number} lastFetch
+ * @property {number} lastUpdate
+ * @property {number} lastErrorUpdate
+ * @property {Error} lastError
+ * @property {boolean} hasMore
+ * @property {number} count
+ * @property {object|Array} data
+ * @property {string} bookmark
+ * @property {object} [execution_stats]
+ * @property {QueryOptions} [options]
+ */
 
-    if (options.allowSparse === true) {
-        return obj;
-    }
+/**
+ * @typedef {object} AutoUpdateOptions
+ * @param {boolean} update - Should documents be updated in the query (default: true)
+ * @param {boolean} add - Should documents be added to the query (default: true)
+ * @param {boolean} remove - Should documents be removed from the query (default: true)
+ */
 
-    return utils.compact(obj);
-};
+/**
+ * @typedef {object} QueryOptions
+ * @property {string} [as] - Name of the query
+ * @property {Function} [fetchPolicy] - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies"
+ * @property {AutoUpdateOptions} [autoUpdate] - Options for the query auto update
+ * @property {string} [update] - Does not seem to be used
+ * @property {Function} [onError] - Callback when the query is errored
+ * @property {boolean} [enabled=true] - If set to false, the query won't be executed
+ * @property {object} [hydrated=true] - Whether documents should be returned already hydrated
+ * @property {object} [singleDocData] - If true, the "data" returned will be
+ * a single doc instead of an array for single doc queries. Defaults to false for backward
+ * compatibility but will be set to true in the future.
+ */
 
+/**
+ * @typedef {object} FetchMoreAble
+ * @property {Function} fetchMore
+ */
 
-/***/ }),
-/* 645 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/**
+ * @typedef {object} FetchAble
+ * @property {Function} fetch
+ */
 
-"use strict";
+/**
+ * @typedef {QueryState & FetchMoreAble & FetchAble} UseQueryReturnValue
+ */
+
+/**
+ * A reference to a document
+ *
+ * @typedef {object} ReferencedByRelationship
+ * @property {RelationshipParent} [parent]
+ * @property {ReferencedBy} [referenced_by]
+ */
 
+/**
+ * @typedef {object} RelationshipParent
+ * @property {{related: string}} links
+ * @property {Reference} [data]
+ */
 
-var _interopRequireDefault = __webpack_require__(512);
+/**
+ * @typedef {object} ReferencedBy
+ * @property {{self: string}} links
+ * @property {Reference[]|null} data
+ */
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.isMatchingIndex = exports.isInconsistentIndex = exports.getIndexFields = exports.transformSort = exports.getIndexNameFromFields = exports.normalizeDesignDoc = void 0;
+/**
+ * A reference to a document
+ * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#references
+ *
+ * @typedef {object} Reference
+ * @property {string} id - id of the document
+ * @property {string} type - doctype of the document
+ */
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+/**
+ * @typedef {Object.<string, Array<Reference>>} ReferenceMap
+ */
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+/**
+ * @typedef {object} MutationOptions
+ * @property {string} [as]
+ * @property {Function} [update]
+ * @property {Function} [updateQueries]
+ */
 
-var _utils = __webpack_require__(611);
+/**
+ * @typedef {object} CozyClientDocument - A document
+ * @property {string} [_id] - Id of the document
+ * @property {string} [id] - Id of the document
+ * @property {string} [_type] - Type of the document
+ * @property {string} [_rev] - Current revision of the document
+ * @property {boolean} [_deleted] - When the document has been deleted
+ * @property {ReferencedByRelationship} [relationships] - Relationships of the document
+ * @property {Reference[]} [referenced_by] - referenced by of another document
+ */
 
-var _head = _interopRequireDefault(__webpack_require__(621));
+/**
+ * @typedef {object} FileDocument - An io.cozy.files document
+ * @property {string} _id - Id of the file
+ * @property {FilesDoctype} _type - Doctype of the file
+ * @property {string} name - Name of the file
+ * @property {object} metadata - Metadata of the file
+ * @property {string} type - Type of the file
+ * @property {string} class - Class of the file
+ * @property {string} mime - Mime of the file
+ * @property {boolean} executable - Whether or not the file is executable
+ * @property {boolean} encrypted - Whether or not the file is client-side encrypted
+ * @typedef {CozyClientDocument & FileDocument} IOCozyFile - An io.cozy.files document
+ */
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+/**
+ * @typedef {object} FolderDocument - An io.cozy.files document
+ * @property {string} _id - Id of the folder
+ * @property {FilesDoctype} _type - Doctype of the folder
+ * @property {string} name - Name of the folder
+ * @property {object} metadata - Metadata of the folder
+ * @property {object} type - Type of the folder
+ * @typedef {CozyClientDocument & FolderDocument} IOCozyFolder - An io.cozy.files document
+ */
 
-var _isEqual = _interopRequireDefault(__webpack_require__(646));
+/**
+ * @typedef {object} OAuthClientDocument - An io.cozy.oauth.clients document
+ * @property {string} _id - Id of the client
+ * @property {OAuthClientsDoctype} _type - Doctype of the client
+ * @property {string} software_id
+ * @property {string} software_version
+ * @property {string} client_id
+ * @property {string} client_name
+ * @property {string} client_kind
+ * @property {string} client_uri
+ * @property {string} logo_uri
+ * @property {string} policy_uri
+ * @property {string} notification_platform
+ * @property {string} notification_device_token
+ * @property {Array<String>} redirect_uris
+ * @typedef {CozyClientDocument & OAuthClientDocument} IOCozyOAuthClient - An io.cozy.oauth.clients document
+ */
 
-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; }
+/**
+ * @typedef {object} ClientError
+ * @property {string} [status]
+ */
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+/**
+ * @typedef FilePlugin
+ * @property {object} [externalDataDirectory]
+ * @property {object} [cacheDirectory]
+ * @property {object} [externalCacheDirectory]
+ * @property {object} [dataDirectory]
+ */
 
 /**
- * @typedef {object} MangoPartialFilter
+ * @typedef InAppBrowser
+ * @property {Function} open
  */
 
 /**
- * @typedef {object} MangoQueryOptions
- *
- * @property {Array<object>} [sort] The sorting parameters
- * @property {Array<string>} [fields] The fields to return
- * @property {number|null} [limit] For pagination, the number of results to return
- * @property {number|null} [skip] For skip-based pagination, the number of referenced files to skip
- * @property {string|null} [indexId] The _id of the CouchDB index to use for this request
- * @property {string|null} [bookmark] For bookmark-based pagination, the document _id to start from
- * @property {Array<string>} [indexedFields]
- * @property {MangoPartialFilter|null} [partialFilter] An optional partial filter
+ * @typedef {object} AppMetadata
  */
 
 /**
- * Attributes representing a design doc
+ * @typedef {object} ClientCapabilities
  *
- * @typedef {object} DesignDoc
+ * @description Read more about client capabilities here https://docs.cozy.io/en/cozy-stack/settings/#get-settingscapabilities.
  *
- * @property {string} _id - Id of the design doc. Can be named, e.g. '_design/by_indexed_attribute' or not, e.g. '_design/12345'
- * @property {string} language - The index language. Can be 'query' for mango index or 'javascript' for views.
- * @property {object} views - Views definition, i.e. the index.
+ * @property {boolean} can_auth_with_oidc - Whether OIDC login is possible with this Cozy
+ * @property {boolean} can_auth_with_password - Whether  password login is possible with this Cozy
+ * @property {boolean} file_versioning - Whether file versioning is active on this Cozy
+ * @property {boolean} flat_subdomains - Whether the stack has been configured to use flat subdomains
  */
-var normalizeDesignDoc = function normalizeDesignDoc(designDoc) {
-  var id = designDoc._id || designDoc.id;
-  return _objectSpread({
-    id: id,
-    _id: id
-  }, designDoc.doc);
-};
 
-exports.normalizeDesignDoc = normalizeDesignDoc;
+/**
+ * @typedef Cordova
+ * @property {FilePlugin} file
+ * @property {InAppBrowser} InAppBrowser
+ * @property {object} plugins
+ */
 
-var getIndexNameFromFields = function getIndexNameFromFields(fields) {
-  return "by_".concat(fields.join('_and_'));
-};
+/**
+ * @typedef  CordovaWindow
+ * @property {Cordova} cordova
+ * @property {object} SafariViewController
+ * @property {Function} resolveLocalFileSystemURL
+ * @property {Function} handleOpenURL
+ */
 
-exports.getIndexNameFromFields = getIndexNameFromFields;
+/**
+ * @typedef {object} CouchDBDocument - A document
+ * @property {string} _id - Id of the document
+ * @property {string} _rev - Current revision of the document
+ * @property {boolean} [_deleted] - When the document has been deleted
+ * @property {object} [relationships] - Relationships of the document
+ */
 
-var transformSort = function transformSort(sort) {
-  if (!sort || Array.isArray(sort)) {
-    return sort;
-  }
+/**
+ * @typedef {object} CouchDBBulkResult - An item of the CouchDB bulk docs response
+ * @property {boolean} ok
+ * @property {string} id
+ * @property {string} rev
+ * @property {string?} error?
+ * @property {string?} reason?
+ */
 
-  console.warn('Passing an object to the "sort" is deprecated, please use an array instead.');
-  return (0, _utils.transform)(sort, function (acc, order, field) {
-    return acc.push((0, _defineProperty2.default)({}, field, order));
-  }, []);
-};
 /**
- * Compute fields that should be indexed for a mango
- * query to work
+ * @typedef {Array<string>|string} ViewKey
+ * @typedef {string} DocId
+ * @typedef {[ViewKey, DocId]} CouchDBViewCursor
+ */
+
+/**
+ * @typedef {object} Theme
+ * @property {string} id
+ * @property {string} label
+ * @property {string} icon
+ * @property {Array<QualificationAttributes>} items
+ * @property {Array<string>} [defaultItems]
  *
- * @param {MangoQueryOptions} options - Mango query options
+ * @typedef {Array<Theme>} ThemesList
  *
- * @returns {Array} - Fields to index
+ * @typedef {'identity'|'family'|'work_study'|'health'|'home'|'transport'|'finance'|'invoice'} ThemesLabels
  */
 
+/**
+ * @typedef {object} QualificationAttributes
+ * @property {string} label
+ * @property {string} [purpose]
+ * @property {string} [sourceCategory]
+ * @property {string} [sourceSubCategory]
+ * @property {Array<string>} [subjects]
+ */
 
-exports.transformSort = transformSort;
-
-var getIndexFields = function getIndexFields(_ref) {
-  var selector = _ref.selector,
-      _ref$sort = _ref.sort,
-      sort = _ref$sort === void 0 ? [] : _ref$sort;
-  return Array.from(new Set([].concat((0, _toConsumableArray2.default)(sort.map(function (sortOption) {
-    return (0, _head.default)(Object.keys(sortOption));
-  })), (0, _toConsumableArray2.default)(selector ? Object.keys(selector) : []))));
-};
 /**
- * Check if an index is in an inconsistent state, i.e. its name
- * contains the indexed attributes which are not in correct order.
+ * @typedef {'identity_photo'|'national_id_card'|'passport'|'residence_permit'|'family_record_book'|'birth_certificate'|'driver_license'|'other_identity_document'|'citizen_registration_certificate'|'personal_sporting_licence'} IdentityLabel
  *
- * @param {DesignDoc} index - The index to check
- * @returns {boolean} True if the index is inconsistent
+ * @typedef {'family_record_book'|'birth_certificate'|'wedding'|'pacs'|'divorce'|'large_family_card'|'caf'|'other_family_document'|'payment_proof_family_allowance'} FamilyLabel
+ *
+ * @typedef {'diploma'|'work_contract'|'pay_sheet'|'unemployment_benefit'|'pension'|'gradebook'|'student_card'|'resume'|'motivation_letter'|'other_work_document'|'work_disability_recognition'|'school_attendance_certificate'} WorkStudyLabels
+ *
+ * @typedef {'health_certificate'|'health_book'|'national_health_insurance_card'|'health_insurance_card'|'prescription'|'health_invoice'|'national_health_insurance_right_certificate'|'work_disability_recognition'|'pregnancy_medical_certificate'|'other_health_document'} HealthLabels
+ *
+ * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'house_sale_agreeement'|'building_permit'|'technical_diagnostic_record'|'lease'|'rent_receipt'|'house_insurance'|'work_quote'|'work_invoice'|'other_house_document'|'unfit_for_habitation_declaration'|'accommodation_proof'|'house_insurance'} HomeLabels
+ *
+ * @typedef {'driver_license'|'vehicle_registration'|'car_insurance'|'mechanic_invoice'|'transport_invoice'|'other_transport_document'} TransportLabels
+ *
+ * @typedef {'tax_return'|'tax_notice'|'tax_timetable'|'pay_sheet'|'receipt'|'other_tax_document'|'bank_details'|'bank_statement'|'loan_agreement'|'other_bank_document'|'payment_proof_family_allowance'|'other_revenue'} FinanceLabels
+ *
+ * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'appliance_invoice'|'web_service_invoice'|'restaurant_invoice'|'work_invoice'|'transport_invoice'|'health_invoice'|'other_invoice'} InvoiceLabels
+ *
+ * @typedef {'personal_sporting_licence'|'other_activity_document'} ActivityLabels
+ *
+ * @typedef {IdentityLabel|FamilyLabel|WorkStudyLabels|HealthLabels|HomeLabels|TransportLabels|FinanceLabels|InvoiceLabels|ActivityLabels} ItemsLabels
  */
 
-
-exports.getIndexFields = getIndexFields;
-
-var isInconsistentIndex = function isInconsistentIndex(index) {
-  var indexId = index._id;
-
-  if (!indexId.startsWith('_design/by_')) {
-    return false;
-  }
-
-  var fieldsInName = indexId.split('_design/by_')[1].split('_and_');
-  var viewId = Object.keys((0, _get.default)(index, "views"))[0];
-  var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields")));
-  return !(0, _isEqual.default)(fieldsInName, fieldsInIndex);
-};
 /**
- * Check if an index is matching the given fields
+ * @typedef {object} DACCMeasure
+ * See https://github.com/cozy/DACC
  *
- * @param {DesignDoc} index - The index to check
- * @param {Array} fields - The fields that the index must have
- * @param {object} partialFilter - An optional partial filter
- * @returns {boolean} True if the index is matches the given fields
+ * @property {string} measureName - It must match an existing measure name on the DACC server
+ * @property {string} startDate - Start of the aggregation period. Should be in YYYY-MM-DD format
+ * @property {number} value - The measured value on the aggregation period
+ * @property {string} createdBy - The slug of the app creating the measure
+ * @property {object} group1 - Should be a {key: value} where the key is set in the measure definition.
+ * @property {object} group2 - Should be a {key: value} where the key is set in the measure definition.
+ * @property {object} group3 - Should be a {key: value} where the key is set in the measure definition.
  */
 
-
-exports.isInconsistentIndex = isInconsistentIndex;
-
-var isMatchingIndex = function isMatchingIndex(index, fields, partialFilter) {
-  var viewId = Object.keys((0, _get.default)(index, "views"))[0];
-  var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields")));
-
-  if ((0, _isEqual.default)(fieldsInIndex, fields)) {
-    if (!partialFilter) {
-      return true;
-    }
-
-    var partialFilterInIndex = (0, _get.default)(index, "views.".concat(viewId, ".map.partial_filter_selector"));
-
-    if ((0, _isEqual.default)(partialFilter, partialFilterInIndex)) {
-      return true;
-    }
-  }
-
-  return false;
-};
-
-exports.isMatchingIndex = isMatchingIndex;
-
-/***/ }),
-/* 646 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseIsEqual = __webpack_require__(410);
-
 /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent.
+ * Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.
  *
- * **Note:** This method supports comparing arrays, array buffers, booleans,
- * date objects, error objects, maps, numbers, `Object` objects, regexes,
- * sets, strings, symbols, and typed arrays. `Object` objects are compared
- * by their own, not inherited, enumerable properties. Functions and DOM
- * nodes are compared by strict equality, i.e. `===`.
+ * @callback OpenURLCallback
+ * @param {string} url - URL to present to the user
+ */
+
+/**
+ * A session code generated by the cozy-stack that can be used to create a session
  *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
+ * More information: https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code
  *
- * var object = { 'a': 1 };
- * var other = { 'a': 1 };
+ * @typedef {string} SessionCode
+ */
+
+/**
+ * An object containing a code verifier and a code challenge that can be used in a
+ * PKCE verification process
  *
- * _.isEqual(object, other);
- * // => true
+ * More information: https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension
  *
- * object === other;
- * // => false
+ * @typedef {object} PKCECodes
+ * @property {string} [codeVerifier]
+ * @property {string} [codeChallenge]
  */
-function isEqual(value, other) {
-  return baseIsEqual(value, other);
-}
-
-module.exports = isEqual;
-
+var _default = {};
+exports["default"] = _default;
 
 /***/ }),
-/* 647 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 623 */
+/***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
-
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.buildURL = exports.encode = void 0;
-
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
-
-var _pickBy = _interopRequireDefault(__webpack_require__(648));
+exports.formatBytes = exports.slugify = exports.sleep = exports.attempt = exports.uri = void 0;
 
 /**
- * Encode a value of any type into a URI search param compatible string with a specific treatment for arrays which will keep their brackets (they do not with standard `toString()` method).
- *
- * Examples:
- *
- *   encodeValues([['io.cozy.files', 'abcd1234'], '12345'])
- *   // → '[[%22io.cozy.files%22,%22abcd1234%22],%2212345%22]'
- *
- *   encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), true)
- *   // → '%22io.cozy.files%2Cabcd1234%2C12345%22'
+ * @function
+ * @description Template tag function for URIs encoding
  *
- *   encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), false)
- *   // → 'io.cozy.files%2Cabcd1234%2C12345'
+ * Will automatically apply `encodeURIComponent` to template literal placeholders
  *
- *   encodeValues('[1234]')
- *   // → %5B1234%5D
+ * @example
+ * ```
+ * const safe = uri`/data/${doctype}/_all_docs?limit=${limit}`
+ * ```
  *
- * @function
  * @private
  */
-var encodeValues = function encodeValues(values) {
-  var fromArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+var uri = function uri(strings) {
+  var parts = [strings[0]];
 
-  if (Array.isArray(values)) {
-    return '[' + values.map(function (v) {
-      return encodeValues(v, true);
-    }).join(',') + ']';
+  for (var i = 0; i < (arguments.length <= 1 ? 0 : arguments.length - 1); i++) {
+    parts.push(encodeURIComponent(i + 1 < 1 || arguments.length <= i + 1 ? undefined : arguments[i + 1]) + strings[i + 1]);
   }
 
-  return fromArray ? encodeURIComponent("\"".concat(values, "\"")) : encodeURIComponent(values);
+  return parts.join('');
 };
 /**
- * Encode an object as querystring, values are encoded as
- * URI components, keys are not.
- *
  * @function
+ * @description Helps to avoid nested try/catch when using async/await
+ *
+ * Inspired by a Go pattern: http://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/
+ *
+ * @example
+ * ```
+ * if (await attempt(collection.all()) return
+ * await sleep(1000)
+ * if (await attempt(collection.all()) return
+ * await sleep(1000)
+ * return
+ * ```
+ *
  * @private
  */
 
 
-var encode = function encode(data) {
-  return Object.entries(data).map(function (_ref) {
-    var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
-        k = _ref2[0],
-        v = _ref2[1];
+exports.uri = uri;
 
-    var encodedValue = encodeValues(v);
-    return "".concat(k, "=").concat(encodedValue);
-  }).join('&');
+var attempt = function attempt(promise) {
+  return promise.then(function () {
+    return true;
+  }).catch(function () {
+    return false;
+  });
 };
 /**
- * Returns a URL from base url and a query parameter object.
- * Any undefined parameter is removed.
- *
  * @function
+ * @description Helps to avoid nested try/catch when using async/await — see documentation for attempt
  * @private
  */
 
 
-exports.encode = encode;
+exports.attempt = attempt;
 
-var buildURL = function buildURL(url, params) {
-  var qs = encode((0, _pickBy.default)(params));
+var sleep = function sleep(time, args) {
+  return new Promise(function (resolve) {
+    setTimeout(resolve, time, args);
+  });
+};
 
-  if (qs) {
-    return "".concat(url, "?").concat(qs);
-  } else {
-    return url;
-  }
+exports.sleep = sleep;
+
+var slugify = function slugify(text) {
+  return text.toString().toLowerCase().replace(/\s+/g, '-') // Replace spaces with -
+  .replace(/[^\w-]+/g, '') // Remove all non-word chars
+  .replace(/--+/g, '-') // Replace multiple - with single -
+  .replace(/^-+/, '') // Trim - from start of text
+  .replace(/-+$/, '');
+}; // Trim - from end of text
+
+
+exports.slugify = slugify;
+
+var formatBytes = function formatBytes(bytes) {
+  var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
+  if (bytes === 0) return '0 Bytes';
+  var k = 1024;
+  var dm = decimals < 0 ? 0 : decimals;
+  var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+  var i = Math.floor(Math.log(bytes) / Math.log(k));
+  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
 };
 
-exports.buildURL = buildURL;
+exports.formatBytes = formatBytes;
 
 /***/ }),
-/* 648 */
+/* 624 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var arrayMap = __webpack_require__(398),
-    baseIteratee = __webpack_require__(401),
-    basePickBy = __webpack_require__(649),
-    getAllKeysIn = __webpack_require__(576);
+var baseUniq = __webpack_require__(475);
 
 /**
- * Creates an object composed of the `object` properties `predicate` returns
- * truthy for. The predicate is invoked with two arguments: (value, key).
+ * Creates a duplicate-free version of an array, using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons, in which only the first occurrence of each element
+ * is kept. The order of result values is determined by the order they occur
+ * in the array.
  *
  * @static
  * @memberOf _
- * @since 4.0.0
- * @category Object
- * @param {Object} object The source object.
- * @param {Function} [predicate=_.identity] The function invoked per property.
- * @returns {Object} Returns the new object.
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
  * @example
  *
- * var object = { 'a': 1, 'b': '2', 'c': 3 };
- *
- * _.pickBy(object, _.isNumber);
- * // => { 'a': 1, 'c': 3 }
+ * _.uniq([2, 1, 2]);
+ * // => [2, 1]
  */
-function pickBy(object, predicate) {
-  if (object == null) {
-    return {};
-  }
-  var props = arrayMap(getAllKeysIn(object), function(prop) {
-    return [prop];
-  });
-  predicate = baseIteratee(predicate);
-  return basePickBy(object, props, function(value, path) {
-    return predicate(value, path[0]);
-  });
+function uniq(array) {
+  return (array && array.length) ? baseUniq(array) : [];
 }
 
-module.exports = pickBy;
+module.exports = uniq;
 
 
 /***/ }),
-/* 649 */
+/* 625 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseGet = __webpack_require__(359),
-    baseSet = __webpack_require__(650),
-    castPath = __webpack_require__(360);
+var arrayMap = __webpack_require__(410),
+    baseClone = __webpack_require__(574),
+    baseUnset = __webpack_require__(626),
+    castPath = __webpack_require__(372),
+    copyObject = __webpack_require__(577),
+    customOmitClone = __webpack_require__(630),
+    flatRest = __webpack_require__(632),
+    getAllKeysIn = __webpack_require__(588);
+
+/** Used to compose bitmasks for cloning. */
+var CLONE_DEEP_FLAG = 1,
+    CLONE_FLAT_FLAG = 2,
+    CLONE_SYMBOLS_FLAG = 4;
 
 /**
- * The base implementation of  `_.pickBy` without support for iteratee shorthands.
+ * The opposite of `_.pick`; this method creates an object composed of the
+ * own and inherited enumerable property paths of `object` that are not omitted.
  *
- * @private
+ * **Note:** This method is considerably slower than `_.pick`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
  * @param {Object} object The source object.
- * @param {string[]} paths The property paths to pick.
- * @param {Function} predicate The function invoked per property.
+ * @param {...(string|string[])} [paths] The property paths to omit.
  * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omit(object, ['a', 'c']);
+ * // => { 'b': '2' }
  */
-function basePickBy(object, paths, predicate) {
-  var index = -1,
-      length = paths.length,
-      result = {};
-
-  while (++index < length) {
-    var path = paths[index],
-        value = baseGet(object, path);
-
-    if (predicate(value, path)) {
-      baseSet(result, castPath(path, object), value);
-    }
+var omit = flatRest(function(object, paths) {
+  var result = {};
+  if (object == null) {
+    return result;
+  }
+  var isDeep = false;
+  paths = arrayMap(paths, function(path) {
+    path = castPath(path, object);
+    isDeep || (isDeep = path.length > 1);
+    return path;
+  });
+  copyObject(object, getAllKeysIn(object), result);
+  if (isDeep) {
+    result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
+  }
+  var length = paths.length;
+  while (length--) {
+    baseUnset(result, paths[length]);
   }
   return result;
-}
+});
 
-module.exports = basePickBy;
+module.exports = omit;
 
 
 /***/ }),
-/* 650 */
+/* 626 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var assignValue = __webpack_require__(563),
-    castPath = __webpack_require__(360),
-    isIndex = __webpack_require__(436),
-    isObject = __webpack_require__(52),
-    toKey = __webpack_require__(399);
+var castPath = __webpack_require__(372),
+    last = __webpack_require__(627),
+    parent = __webpack_require__(628),
+    toKey = __webpack_require__(411);
 
 /**
- * The base implementation of `_.set`.
+ * The base implementation of `_.unset`.
  *
  * @private
  * @param {Object} object The object to modify.
- * @param {Array|string} path The path of the property to set.
- * @param {*} value The value to set.
- * @param {Function} [customizer] The function to customize path creation.
- * @returns {Object} Returns `object`.
+ * @param {Array|string} path The property path to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
  */
-function baseSet(object, path, value, customizer) {
-  if (!isObject(object)) {
-    return object;
-  }
+function baseUnset(object, path) {
   path = castPath(path, object);
-
-  var index = -1,
-      length = path.length,
-      lastIndex = length - 1,
-      nested = object;
-
-  while (nested != null && ++index < length) {
-    var key = toKey(path[index]),
-        newValue = value;
-
-    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
-      return object;
-    }
-
-    if (index != lastIndex) {
-      var objValue = nested[key];
-      newValue = customizer ? customizer(objValue, key, nested) : undefined;
-      if (newValue === undefined) {
-        newValue = isObject(objValue)
-          ? objValue
-          : (isIndex(path[index + 1]) ? [] : {});
-      }
-    }
-    assignValue(nested, key, newValue);
-    nested = nested[key];
-  }
-  return object;
+  object = parent(object, path);
+  return object == null || delete object[toKey(last(path))];
 }
 
-module.exports = baseSet;
+module.exports = baseUnset;
 
 
 /***/ }),
-/* 651 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.FetchError = exports["default"] = void 0;
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+/* 627 */
+/***/ ((module) => {
 
-var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(594));
+/**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+function last(array) {
+  var length = array == null ? 0 : array.length;
+  return length ? array[length - 1] : undefined;
+}
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+module.exports = last;
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+/***/ }),
+/* 628 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652));
+var baseGet = __webpack_require__(371),
+    baseSlice = __webpack_require__(629);
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+/**
+ * Gets the parent value at `path` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
+ */
+function parent(object, path) {
+  return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
+}
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+module.exports = parent;
 
-var EXPIRED_TOKEN = /Expired token/;
-var CLIENT_NOT_FOUND = /Client not found/;
-var INVALID_TOKEN = /Invalid JWT token/;
-var _default = {
-  EXPIRED_TOKEN: EXPIRED_TOKEN,
-  CLIENT_NOT_FOUND: CLIENT_NOT_FOUND,
-  INVALID_TOKEN: INVALID_TOKEN
-};
-exports["default"] = _default;
 
-var getWwwAuthenticateErrorMessage = function getWwwAuthenticateErrorMessage(response) {
-  var invalidTokenRegex = /invalid_token/;
-  var expiredTokenRegex = /access token expired/;
-  var wwwAuthenticateHeader = response.headers && response.headers.get('www-authenticate');
+/***/ }),
+/* 629 */
+/***/ ((module) => {
 
-  if (!wwwAuthenticateHeader) {
-    return undefined;
-  }
+/**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+function baseSlice(array, start, end) {
+  var index = -1,
+      length = array.length;
 
-  if (expiredTokenRegex.test(wwwAuthenticateHeader)) {
-    return 'Expired token';
+  if (start < 0) {
+    start = -start > length ? 0 : (length + start);
   }
-
-  if (invalidTokenRegex.test(wwwAuthenticateHeader)) {
-    return 'Invalid token';
+  end = end > length ? length : end;
+  if (end < 0) {
+    end += length;
   }
+  length = start > end ? 0 : ((end - start) >>> 0);
+  start >>>= 0;
 
-  return undefined;
-};
-
-var FetchError = /*#__PURE__*/function (_Error) {
-  (0, _inherits2.default)(FetchError, _Error);
-
-  var _super = _createSuper(FetchError);
-
-  function FetchError(response, reason) {
-    var _this;
-
-    (0, _classCallCheck2.default)(this, FetchError);
-    _this = _super.call(this);
-
-    if (Error.captureStackTrace) {
-      Error.captureStackTrace((0, _assertThisInitialized2.default)(_this), _this.constructor);
-    } // WARN We have to hardcode this because babel doesn't play nice when extending Error
-
-
-    _this.name = 'FetchError';
-    _this.response = response;
-    _this.url = response.url;
-    _this.status = response.status;
-    _this.reason = reason;
-    var wwwAuthenticateErrorMessage = getWwwAuthenticateErrorMessage(response);
-    Object.defineProperty((0, _assertThisInitialized2.default)(_this), 'message', {
-      value: reason.message || wwwAuthenticateErrorMessage || (typeof reason === 'string' ? reason : JSON.stringify(reason))
-    });
-    return _this;
+  var result = Array(length);
+  while (++index < length) {
+    result[index] = array[index + start];
   }
+  return result;
+}
 
-  return FetchError;
-}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
+module.exports = baseSlice;
 
-exports.FetchError = FetchError;
 
 /***/ }),
-/* 652 */
+/* 630 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var getPrototypeOf = __webpack_require__(595);
-
-var setPrototypeOf = __webpack_require__(592);
-
-var isNativeFunction = __webpack_require__(653);
-
-var construct = __webpack_require__(654);
-
-function _wrapNativeSuper(Class) {
-  var _cache = typeof Map === "function" ? new Map() : undefined;
-
-  module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
-    if (Class === null || !isNativeFunction(Class)) return Class;
-
-    if (typeof Class !== "function") {
-      throw new TypeError("Super expression must either be null or a function");
-    }
-
-    if (typeof _cache !== "undefined") {
-      if (_cache.has(Class)) return _cache.get(Class);
-
-      _cache.set(Class, Wrapper);
-    }
-
-    function Wrapper() {
-      return construct(Class, arguments, getPrototypeOf(this).constructor);
-    }
-
-    Wrapper.prototype = Object.create(Class.prototype, {
-      constructor: {
-        value: Wrapper,
-        enumerable: false,
-        writable: true,
-        configurable: true
-      }
-    });
-    return setPrototypeOf(Wrapper, Class);
-  };
+var isPlainObject = __webpack_require__(631);
 
-  module.exports["default"] = module.exports, module.exports.__esModule = true;
-  return _wrapNativeSuper(Class);
+/**
+ * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
+ * objects.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @param {string} key The key of the property to inspect.
+ * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
+ */
+function customOmitClone(value) {
+  return isPlainObject(value) ? undefined : value;
 }
 
-module.exports = _wrapNativeSuper;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
-
-/***/ }),
-/* 653 */
-/***/ ((module) => {
-
-function _isNativeFunction(fn) {
-  return Function.toString.call(fn).indexOf("[native code]") !== -1;
-}
+module.exports = customOmitClone;
 
-module.exports = _isNativeFunction;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
 
 /***/ }),
-/* 654 */
+/* 631 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var setPrototypeOf = __webpack_require__(592);
-
-var isNativeReflectConstruct = __webpack_require__(655);
-
-function _construct(Parent, args, Class) {
-  if (isNativeReflectConstruct()) {
-    module.exports = _construct = Reflect.construct;
-    module.exports["default"] = module.exports, module.exports.__esModule = true;
-  } else {
-    module.exports = _construct = function _construct(Parent, args, Class) {
-      var a = [null];
-      a.push.apply(a, args);
-      var Constructor = Function.bind.apply(Parent, a);
-      var instance = new Constructor();
-      if (Class) setPrototypeOf(instance, Class.prototype);
-      return instance;
-    };
+var baseGetTag = __webpack_require__(46),
+    getPrototype = __webpack_require__(587),
+    isObjectLike = __webpack_require__(53);
 
-    module.exports["default"] = module.exports, module.exports.__esModule = true;
-  }
+/** `Object#toString` result references. */
+var objectTag = '[object Object]';
 
-  return _construct.apply(null, arguments);
-}
+/** Used for built-in method references. */
+var funcProto = Function.prototype,
+    objectProto = Object.prototype;
 
-module.exports = _construct;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
+/** Used to resolve the decompiled source of functions. */
+var funcToString = funcProto.toString;
 
-/***/ }),
-/* 655 */
-/***/ ((module) => {
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-function _isNativeReflectConstruct() {
-  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
-  if (Reflect.construct.sham) return false;
-  if (typeof Proxy === "function") return true;
+/** Used to infer the `Object` constructor. */
+var objectCtorString = funcToString.call(Object);
 
-  try {
-    Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
-    return true;
-  } catch (e) {
+/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.8.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+function isPlainObject(value) {
+  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
     return false;
   }
-}
-
-module.exports = _isNativeReflectConstruct;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
-
-/***/ }),
-/* 656 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var AppToken = /*#__PURE__*/function () {
-  function AppToken(token) {
-    (0, _classCallCheck2.default)(this, AppToken);
-    this.token = token || '';
-  }
-
-  (0, _createClass2.default)(AppToken, [{
-    key: "toAuthHeader",
-    value: function toAuthHeader() {
-      return 'Bearer ' + this.token;
-    }
-  }, {
-    key: "toBasicAuth",
-    value: function toBasicAuth() {
-      return "user:".concat(this.token, "@");
-    }
-    /**
-     * Get the app token string
-     *
-     * @see CozyStackClient.getAccessToken
-     * @returns {string} token
-     */
-
-  }, {
-    key: "getAccessToken",
-    value: function getAccessToken() {
-      return this.token;
-    }
-  }]);
-  return AppToken;
-}();
-
-exports["default"] = AppToken;
-
-/***/ }),
-/* 657 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var AccessToken = /*#__PURE__*/function () {
-  function AccessToken(dataArg) {
-    (0, _classCallCheck2.default)(this, AccessToken);
-    var data = dataArg;
-    if (typeof data === 'string') data = JSON.parse(data);
-    this.tokenType = data.token_type || data.tokenType;
-    this.accessToken = data.access_token || data.accessToken;
-    this.refreshToken = data.refresh_token || data.refreshToken;
-    this.scope = data.scope;
+  var proto = getPrototype(value);
+  if (proto === null) {
+    return true;
   }
-
-  (0, _createClass2.default)(AccessToken, [{
-    key: "toAuthHeader",
-    value: function toAuthHeader() {
-      return 'Bearer ' + this.accessToken;
-    }
-  }, {
-    key: "toBasicAuth",
-    value: function toBasicAuth() {
-      return "user:".concat(this.accessToken, "@");
-    }
-  }, {
-    key: "toJSON",
-    value: function toJSON() {
-      return {
-        tokenType: this.tokenType,
-        accessToken: this.accessToken,
-        refreshToken: this.refreshToken,
-        scope: this.scope
-      };
-    }
-  }, {
-    key: "toString",
-    value: function toString() {
-      return JSON.stringify(this.toJSON());
-    }
-    /**
-     * Get the access token string
-     *
-     * @see CozyStackClient.getAccessToken
-     * @returns {string} token
-     */
-
-  }, {
-    key: "getAccessToken",
-    value: function getAccessToken() {
-      return this.accessToken;
-    }
-  }]);
-  return AccessToken;
-}();
-
-exports["default"] = AccessToken;
-
-/***/ }),
-/* 658 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireWildcard = __webpack_require__(510);
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.isDirectory = exports.isFile = void 0;
-
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
-
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(594));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
-
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
-
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
-
-var _lite = _interopRequireDefault(__webpack_require__(659));
-
-var _has = _interopRequireDefault(__webpack_require__(662));
-
-var _get = _interopRequireDefault(__webpack_require__(358));
-
-var _omit = _interopRequireDefault(__webpack_require__(613));
-
-var _pick = _interopRequireDefault(__webpack_require__(664));
-
-var _mangoIndex = __webpack_require__(645);
-
-var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601));
-
-var _utils = __webpack_require__(611);
-
-var _errors = __webpack_require__(651);
-
-var _Collection = __webpack_require__(600);
-
-var _getIllegalCharacter = __webpack_require__(666);
-
-var querystring = _interopRequireWildcard(__webpack_require__(647));
-
-function _templateObject23() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/_changes"]);
-
-  _templateObject23 = function _templateObject23() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject22() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]);
-
-  _templateObject22 = function _templateObject22() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject21() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]);
-
-  _templateObject21 = function _templateObject21() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject20() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]);
-
-  _templateObject20 = function _templateObject20() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject19() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/versions"]);
-
-  _templateObject19 = function _templateObject19() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject18() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/upload/metadata"]);
-
-  _templateObject18 = function _templateObject18() {
-    return data;
-  };
-
-  return data;
+  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
+  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
+    funcToString.call(Ctor) == objectCtorString;
 }
 
-function _templateObject17() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
-
-  _templateObject17 = function _templateObject17() {
-    return data;
-  };
+module.exports = isPlainObject;
 
-  return data;
-}
 
-function _templateObject16() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=directory"]);
+/***/ }),
+/* 632 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  _templateObject16 = function _templateObject16() {
-    return data;
-  };
+var flatten = __webpack_require__(552),
+    overRest = __webpack_require__(557),
+    setToString = __webpack_require__(559);
 
-  return data;
+/**
+ * A specialized version of `baseRest` which flattens the rest array.
+ *
+ * @private
+ * @param {Function} func The function to apply a rest parameter to.
+ * @returns {Function} Returns the new function.
+ */
+function flatRest(func) {
+  return setToString(overRest(func, undefined, flatten), func + '');
 }
 
-function _templateObject15() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/metadata?Path=", ""]);
+module.exports = flatRest;
 
-  _templateObject15 = function _templateObject15() {
-    return data;
-  };
 
-  return data;
+/***/ }),
+/* 633 */
+/***/ ((module) => {
+
+/**
+ * Gets the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @alias first
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the first element of `array`.
+ * @example
+ *
+ * _.head([1, 2, 3]);
+ * // => 1
+ *
+ * _.head([]);
+ * // => undefined
+ */
+function head(array) {
+  return (array && array.length) ? array[0] : undefined;
 }
 
-function _templateObject14() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
+module.exports = head;
 
-  _templateObject14 = function _templateObject14() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 634 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _templateObject13() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Path=", ""]);
+var baseClamp = __webpack_require__(635),
+    baseToString = __webpack_require__(409),
+    toInteger = __webpack_require__(636),
+    toString = __webpack_require__(408);
 
-  _templateObject13 = function _templateObject13() {
-    return data;
-  };
+/**
+ * Checks if `string` starts with the given target string.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {string} [target] The string to search for.
+ * @param {number} [position=0] The position to search from.
+ * @returns {boolean} Returns `true` if `string` starts with `target`,
+ *  else `false`.
+ * @example
+ *
+ * _.startsWith('abc', 'a');
+ * // => true
+ *
+ * _.startsWith('abc', 'b');
+ * // => false
+ *
+ * _.startsWith('abc', 'b', 1);
+ * // => true
+ */
+function startsWith(string, target, position) {
+  string = toString(string);
+  position = position == null
+    ? 0
+    : baseClamp(toInteger(position), 0, string.length);
 
-  return data;
+  target = baseToString(target);
+  return string.slice(position, position + target.length) == target;
 }
 
-function _templateObject12() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?VersionId=", "&Filename=", ""]);
+module.exports = startsWith;
 
-  _templateObject12 = function _templateObject12() {
-    return data;
-  };
 
-  return data;
+/***/ }),
+/* 635 */
+/***/ ((module) => {
+
+/**
+ * The base implementation of `_.clamp` which doesn't coerce arguments.
+ *
+ * @private
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ */
+function baseClamp(number, lower, upper) {
+  if (number === number) {
+    if (upper !== undefined) {
+      number = number <= upper ? number : upper;
+    }
+    if (lower !== undefined) {
+      number = number >= lower ? number : lower;
+    }
+  }
+  return number;
 }
 
-function _templateObject11() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Id=", "&Filename=", ""]);
+module.exports = baseClamp;
 
-  _templateObject11 = function _templateObject11() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 636 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _templateObject10() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", ""]);
+var toFinite = __webpack_require__(637);
 
-  _templateObject10 = function _templateObject10() {
-    return data;
-  };
+/**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This method is loosely based on
+ * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3.2);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3.2');
+ * // => 3
+ */
+function toInteger(value) {
+  var result = toFinite(value),
+      remainder = result % 1;
 
-  return data;
+  return result === result ? (remainder ? result - remainder : result) : 0;
 }
 
-function _templateObject9() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", "&MetadataID=", "&Size=", ""]);
+module.exports = toInteger;
 
-  _templateObject9 = function _templateObject9() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 637 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _templateObject8() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
+var toNumber = __webpack_require__(638);
 
-  _templateObject8 = function _templateObject8() {
-    return data;
-  };
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0,
+    MAX_INTEGER = 1.7976931348623157e+308;
 
-  return data;
+/**
+ * Converts `value` to a finite number.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.12.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted number.
+ * @example
+ *
+ * _.toFinite(3.2);
+ * // => 3.2
+ *
+ * _.toFinite(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toFinite(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toFinite('3.2');
+ * // => 3.2
+ */
+function toFinite(value) {
+  if (!value) {
+    return value === 0 ? value : 0;
+  }
+  value = toNumber(value);
+  if (value === INFINITY || value === -INFINITY) {
+    var sign = (value < 0 ? -1 : 1);
+    return sign * MAX_INTEGER;
+  }
+  return value === value ? value : 0;
 }
 
-function _templateObject7() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/trash/", ""]);
+module.exports = toFinite;
 
-  _templateObject7 = function _templateObject7() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 638 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _templateObject6() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
+var baseTrim = __webpack_require__(639),
+    isObject = __webpack_require__(52),
+    isSymbol = __webpack_require__(374);
 
-  _templateObject6 = function _templateObject6() {
-    return data;
-  };
+/** Used as references for various `Number` constants. */
+var NAN = 0 / 0;
 
-  return data;
-}
+/** Used to detect bad signed hexadecimal string values. */
+var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+/** Used to detect binary string values. */
+var reIsBinary = /^0b[01]+$/i;
 
-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); }
+/** Used to detect octal string values. */
+var reIsOctal = /^0o[0-7]+$/i;
 
-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; }
+/** Built-in method references without a dependency on `root`. */
+var freeParseInt = parseInt;
 
-function _templateObject5() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]);
+/**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3.2);
+ * // => 3.2
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3.2');
+ * // => 3.2
+ */
+function toNumber(value) {
+  if (typeof value == 'number') {
+    return value;
+  }
+  if (isSymbol(value)) {
+    return NAN;
+  }
+  if (isObject(value)) {
+    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
+    value = isObject(other) ? (other + '') : other;
+  }
+  if (typeof value != 'string') {
+    return value === 0 ? value : +value;
+  }
+  value = baseTrim(value);
+  var isBinary = reIsBinary.test(value);
+  return (isBinary || reIsOctal.test(value))
+    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+    : (reIsBadHex.test(value) ? NAN : +value);
+}
 
-  _templateObject5 = function _templateObject5() {
-    return data;
-  };
+module.exports = toNumber;
 
-  return data;
-}
 
-function _templateObject4() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]);
+/***/ }),
+/* 639 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  _templateObject4 = function _templateObject4() {
-    return data;
-  };
+var trimmedEndIndex = __webpack_require__(640);
 
-  return data;
+/** Used to match leading whitespace. */
+var reTrimStart = /^\s+/;
+
+/**
+ * The base implementation of `_.trim`.
+ *
+ * @private
+ * @param {string} string The string to trim.
+ * @returns {string} Returns the trimmed string.
+ */
+function baseTrim(string) {
+  return string
+    ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
+    : string;
 }
 
-function _templateObject3() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]);
+module.exports = baseTrim;
 
-  _templateObject3 = function _templateObject3() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 640 */
+/***/ ((module) => {
 
-function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]);
+/** Used to match a single whitespace character. */
+var reWhitespace = /\s/;
 
-  _templateObject2 = function _templateObject2() {
-    return data;
-  };
+/**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
+ * character of `string`.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the index of the last non-whitespace character.
+ */
+function trimmedEndIndex(string) {
+  var index = string.length;
 
-  return data;
+  while (index-- && reWhitespace.test(string.charAt(index))) {}
+  return index;
 }
 
-function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]);
+module.exports = trimmedEndIndex;
 
-  _templateObject = function _templateObject() {
-    return data;
-  };
 
-  return data;
-}
+/***/ }),
+/* 641 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+"use strict";
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-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; }
+var stringify = __webpack_require__(642);
+var parse = __webpack_require__(656);
+var formats = __webpack_require__(655);
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+module.exports = {
+    formats: formats,
+    parse: parse,
+    stringify: stringify
+};
 
-/**
- * Cursor used for Mango queries pagination
- *
- * @typedef {Array<string>|string} ViewKey
- * @typedef {string} DocId
- * @typedef {Array<*> & {0: ViewKey, 1: DocId}} CouchDBViewCursor
- */
 
-/**
- * Attributes used for directory creation
- *
- * @typedef {object} DirectoryAttributes
- * @property {string} dirId - Id of the parent directory.
- * @property {boolean} name - Name of the created directory.
- * @property {boolean} executable - Indicates whether the file will be executable.
- */
+/***/ }),
+/* 642 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/**
- * Attributes used for file creation
- *
- * @typedef {object} FileAttributes
- * @property {string} dirId - Id of the parent directory.
- * @property {string} name - Name of the created file.
- * @property {Date} lastModifiedDate - Can be used to set the last modified date of a file.
- * @property {boolean} executable - Whether or not the file is executable
- * @property {object} metadata io.cozy.files.metadata to attach to the file
- */
+"use strict";
 
-/**
- * Document representing a io.cozy.files
- *
- * @typedef {object} FileDocument
- * @property {string} _id - Id of the file
- * @property {FileAttributes} attributes - Attributes of the file
- */
 
-/**
- * Stream is not defined in a browser, but is on NodeJS environment
- *
- * @typedef {object} Stream
- */
+var getSideChannel = __webpack_require__(643);
+var utils = __webpack_require__(654);
+var formats = __webpack_require__(655);
+var has = Object.prototype.hasOwnProperty;
 
-/**
- * Document representing a io.cozy.oauth.clients
- *
- * @typedef {object} OAuthClient
- * @property {string} _id - Id of the client
- * @property {string} _type - Doctype of the client (i.e. io.cozy.oauth.clients)
- */
-var ROOT_DIR_ID = 'io.cozy.files.root-dir';
-var CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream';
-/**
- * Normalize a file, adding document's doctype if needed
- *
- * @param  {FileDocument} file - File to normalize
- * @returns {FileDocument} normalized file
- * @private
- */
+var arrayPrefixGenerators = {
+    brackets: function brackets(prefix) {
+        return prefix + '[]';
+    },
+    comma: 'comma',
+    indices: function indices(prefix, key) {
+        return prefix + '[' + key + ']';
+    },
+    repeat: function repeat(prefix) {
+        return prefix;
+    }
+};
 
-var normalizeFile = function normalizeFile(file) {
-  return _objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(file, 'io.cozy.files')), file.attributes);
+var isArray = Array.isArray;
+var push = Array.prototype.push;
+var pushToArray = function (arr, valueOrArray) {
+    push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
 };
-/**
- * Normalize references, expliciting _type and _id — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/
- *
- * @param  {Array<object>} references - The list of files referenced by a document to normalize
- * @returns {Array<object>} the data attribute of the normalized references
- * @private
- */
 
+var toISO = Date.prototype.toISOString;
 
-var normalizeReferences = function normalizeReferences(references) {
-  return references ? references.map(function (ref) {
-    return {
-      _type: ref.type,
-      _id: ref.id
-    };
-  }) : [];
+var defaultFormat = formats['default'];
+var defaults = {
+    addQueryPrefix: false,
+    allowDots: false,
+    charset: 'utf-8',
+    charsetSentinel: false,
+    delimiter: '&',
+    encode: true,
+    encoder: utils.encode,
+    encodeValuesOnly: false,
+    format: defaultFormat,
+    formatter: formats.formatters[defaultFormat],
+    // deprecated
+    indices: false,
+    serializeDate: function serializeDate(date) {
+        return toISO.call(date);
+    },
+    skipNulls: false,
+    strictNullHandling: false
 };
-/**
- * Sanitize the file name by trimming spaces
- *
- * @param {string} name - The file name to trim
- * @returns {string} the trimmed file name
- * @private
- */
 
-
-var sanitizeFileName = function sanitizeFileName(name) {
-  return name && name.trim();
+var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
+    return typeof v === 'string'
+        || typeof v === 'number'
+        || typeof v === 'boolean'
+        || typeof v === 'symbol'
+        || typeof v === 'bigint';
 };
-/**
- * Sanitize and validate the file name - throw errors according to case
- *
- * @param {string} name - The file name
- * @returns {string} the trimmed safe file name
- * @throws {Error} - explaining reason why file name is not valid
- * @private
- */
 
+var stringify = function stringify(
+    object,
+    prefix,
+    generateArrayPrefix,
+    strictNullHandling,
+    skipNulls,
+    encoder,
+    filter,
+    sort,
+    allowDots,
+    serializeDate,
+    format,
+    formatter,
+    encodeValuesOnly,
+    charset,
+    sideChannel
+) {
+    var obj = object;
 
-var sanitizeAndValidateFileName = function sanitizeAndValidateFileName(name) {
-  var safeName = sanitizeFileName(name);
+    if (sideChannel.has(object)) {
+        throw new RangeError('Cyclic object value');
+    }
 
-  if (typeof safeName !== 'string' || safeName === '') {
-    throw new Error('Missing name argument');
-  }
+    if (typeof filter === 'function') {
+        obj = filter(prefix, obj);
+    } else if (obj instanceof Date) {
+        obj = serializeDate(obj);
+    } else if (generateArrayPrefix === 'comma' && isArray(obj)) {
+        obj = utils.maybeMap(obj, function (value) {
+            if (value instanceof Date) {
+                return serializeDate(value);
+            }
+            return value;
+        });
+    }
 
-  if (name === '.' || name === '..') {
-    throw new Error("Invalid filename: ".concat(name));
-  }
+    if (obj === null) {
+        if (strictNullHandling) {
+            return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;
+        }
 
-  var illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(safeName);
+        obj = '';
+    }
 
-  if (illegalCharacters.length) {
-    throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters));
-  }
+    if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
+        if (encoder) {
+            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
+            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
+        }
+        return [formatter(prefix) + '=' + formatter(String(obj))];
+    }
 
-  return safeName;
-};
-/**
- * Returns true when parameter has type directory, file or has _type io.cozy.files
- *
- * @param {object} doc - The document whose type is checked
- * @param {string} [doc._type] - The document's doctype
- * @param {'directory'|'file'} [doc.type] - The io.cozy-files document type
- *
- * @returns {boolean} true when objects has type directory, file or has _type io.cozy.files or false
- */
+    var values = [];
 
+    if (typeof obj === 'undefined') {
+        return values;
+    }
 
-var isFile = function isFile(_ref) {
-  var _type = _ref._type,
-      type = _ref.type;
-  return _type === 'io.cozy.files' || type === 'directory' || type === 'file';
-};
-/**
- * Returns true when parameters has type directory
- *
- * @param {string} type - The type of the file
- * @returns {boolean} true when parameters has type directory or false
- */
+    var objKeys;
+    if (generateArrayPrefix === 'comma' && isArray(obj)) {
+        // we need to join elements in
+        objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
+    } else if (isArray(filter)) {
+        objKeys = filter;
+    } else {
+        var keys = Object.keys(obj);
+        objKeys = sort ? keys.sort(sort) : keys;
+    }
 
+    for (var i = 0; i < objKeys.length; ++i) {
+        var key = objKeys[i];
+        var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
 
-exports.isFile = isFile;
+        if (skipNulls && value === null) {
+            continue;
+        }
 
-var isDirectory = function isDirectory(_ref2) {
-  var type = _ref2.type;
-  return type === 'directory';
-};
+        var keyPrefix = isArray(obj)
+            ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
+            : prefix + (allowDots ? '.' + key : '[' + key + ']');
 
-exports.isDirectory = isDirectory;
+        sideChannel.set(object, true);
+        var valueSideChannel = getSideChannel();
+        pushToArray(values, stringify(
+            value,
+            keyPrefix,
+            generateArrayPrefix,
+            strictNullHandling,
+            skipNulls,
+            encoder,
+            filter,
+            sort,
+            allowDots,
+            serializeDate,
+            format,
+            formatter,
+            encodeValuesOnly,
+            charset,
+            valueSideChannel
+        ));
+    }
 
-var raceWithCondition = function raceWithCondition(promises, predicate) {
-  return new Promise(function (resolve) {
-    promises.forEach(function (p) {
-      return p.then(function (res) {
-        if (predicate(res)) {
-          resolve(true);
-        }
-      });
-    });
-    Promise.all(promises).then(function () {
-      return resolve(false);
-    });
-  });
+    return values;
 };
 
-var dirName = function dirName(path) {
-  var lastIndex = path.lastIndexOf('/');
-  return path.substring(0, lastIndex);
-};
-/**
- * Implements `DocumentCollection` API along with specific methods for
- * `io.cozy.files`.
- *
- * Files are a special type of documents and are handled differently by the stack:
- * special routes are to be used, and there is a notion of referenced files, aka
- * files associated to a specific document
- */
+var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
+    if (!opts) {
+        return defaults;
+    }
 
+    if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
+        throw new TypeError('Encoder has to be a function.');
+    }
 
-var FileCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(FileCollection, _DocumentCollection);
+    var charset = opts.charset || defaults.charset;
+    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
+        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
+    }
 
-  var _super = _createSuper(FileCollection);
+    var format = formats['default'];
+    if (typeof opts.format !== 'undefined') {
+        if (!has.call(formats.formatters, opts.format)) {
+            throw new TypeError('Unknown format option provided.');
+        }
+        format = opts.format;
+    }
+    var formatter = formats.formatters[format];
 
-  function FileCollection(doctype, stackClient) {
-    var _this;
+    var filter = defaults.filter;
+    if (typeof opts.filter === 'function' || isArray(opts.filter)) {
+        filter = opts.filter;
+    }
 
-    (0, _classCallCheck2.default)(this, FileCollection);
-    _this = _super.call(this, doctype, stackClient);
-    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "extractResponseLinkRelated", function (res) {
-      var href = res.links && res.links.related;
-      if (!href) throw new Error('No related link in server response');
-      return _this.stackClient.fullpath(href);
-    });
-    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "forceFileDownload", function (href, filename) {
-      var element = document.createElement('a');
-      element.setAttribute('href', href);
-      element.setAttribute('download', filename);
-      element.style.display = 'none';
-      document.body.appendChild(element);
-      element.click();
-      document.body.removeChild(element);
-    });
-    _this.specialDirectories = {};
-    return _this;
-  }
-  /**
-   * Fetches the file's data
-   *
-   * @param {string} id File id
-   * @returns {{data, included}} Information about the file or folder and it's descendents
-   */
+    return {
+        addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
+        allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
+        charset: charset,
+        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
+        delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
+        encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
+        encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
+        encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
+        filter: filter,
+        format: format,
+        formatter: formatter,
+        serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
+        skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
+        sort: typeof opts.sort === 'function' ? opts.sort : null,
+        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
+    };
+};
 
+module.exports = function (object, opts) {
+    var obj = object;
+    var options = normalizeStringifyOptions(opts);
 
-  (0, _createClass2.default)(FileCollection, [{
-    key: "get",
-    value: function get(id) {
-      return this.statById(id);
+    var objKeys;
+    var filter;
+
+    if (typeof options.filter === 'function') {
+        filter = options.filter;
+        obj = filter('', obj);
+    } else if (isArray(options.filter)) {
+        filter = options.filter;
+        objKeys = filter;
     }
-  }, {
-    key: "fetchFindFiles",
-    value: function () {
-      var _fetchFindFiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) {
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                return _context.abrupt("return", this.stackClient.fetchJSON('POST', '/files/_find', this.toMangoOptions(selector, options)));
 
-              case 1:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
+    var keys = [];
 
-      function fetchFindFiles(_x, _x2) {
-        return _fetchFindFiles.apply(this, arguments);
-      }
+    if (typeof obj !== 'object' || obj === null) {
+        return '';
+    }
 
-      return fetchFindFiles;
-    }()
-    /**
-     * Returns a filtered list of documents using a Mango selector.
-     *
-     * The returned documents are paginated by the stack.
-     *
-     * @param {object}            selector  The Mango selector.
-     * @param {MangoQueryOptions} options   The query options
-     *
-     * @returns {{data, meta, skip, next, bookmark}} The JSON API conformant response.
-     * @throws {FetchError}
-     */
+    var arrayFormat;
+    if (opts && opts.arrayFormat in arrayPrefixGenerators) {
+        arrayFormat = opts.arrayFormat;
+    } else if (opts && 'indices' in opts) {
+        arrayFormat = opts.indices ? 'indices' : 'repeat';
+    } else {
+        arrayFormat = 'indices';
+    }
 
-  }, {
-    key: "find",
-    value: function () {
-      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(selector) {
-        var options,
-            _options$skip,
-            skip,
-            resp,
-            path,
-            nextLink,
-            nextLinkURL,
-            nextBookmark,
-            _args2 = arguments;
+    var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
 
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                options = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {};
-                _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip;
-                _context2.prev = 2;
-                path = '/files/_find';
-                _context2.next = 6;
-                return this.findWithMango(path, selector, options);
+    if (!objKeys) {
+        objKeys = Object.keys(obj);
+    }
 
-              case 6:
-                resp = _context2.sent;
-                _context2.next = 12;
-                break;
+    if (options.sort) {
+        objKeys.sort(options.sort);
+    }
 
-              case 9:
-                _context2.prev = 9;
-                _context2.t0 = _context2["catch"](2);
-                return _context2.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context2.t0));
+    var sideChannel = getSideChannel();
+    for (var i = 0; i < objKeys.length; ++i) {
+        var key = objKeys[i];
 
-              case 12:
-                nextLink = (0, _get.default)(resp, 'links.next', '');
-                nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink));
-                nextBookmark = nextLinkURL.searchParams.get('page[cursor]');
-                return _context2.abrupt("return", {
-                  data: resp.data.map(function (f) {
-                    return normalizeFile(f);
-                  }),
-                  meta: resp.meta,
-                  next: resp.meta.count > skip + resp.data.length,
-                  skip: skip,
-                  bookmark: nextBookmark || undefined,
-                  execution_stats: resp.meta.execution_stats
-                });
+        if (options.skipNulls && obj[key] === null) {
+            continue;
+        }
+        pushToArray(keys, stringify(
+            obj[key],
+            key,
+            generateArrayPrefix,
+            options.strictNullHandling,
+            options.skipNulls,
+            options.encode ? options.encoder : null,
+            options.filter,
+            options.sort,
+            options.allowDots,
+            options.serializeDate,
+            options.format,
+            options.formatter,
+            options.encodeValuesOnly,
+            options.charset,
+            sideChannel
+        ));
+    }
 
-              case 16:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this, [[2, 9]]);
-      }));
+    var joined = keys.join(options.delimiter);
+    var prefix = options.addQueryPrefix === true ? '?' : '';
 
-      function find(_x3) {
-        return _find.apply(this, arguments);
-      }
+    if (options.charsetSentinel) {
+        if (options.charset === 'iso-8859-1') {
+            // encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
+            prefix += 'utf8=%26%2310003%3B&';
+        } else {
+            // encodeURIComponent('✓')
+            prefix += 'utf8=%E2%9C%93&';
+        }
+    }
 
-      return find;
-    }()
-    /**
-     * async findReferencedBy - Returns the list of files referenced by a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/
-     *
-     * @param  {object}       document          A JSON representing a document, with at least a `_type` and `_id` field.
-     * @param  {object}       options           Additional options
-     * @param  {number|null}  [options.skip]    For skip-based pagination, the number of referenced files to skip.
-     * @param  {number|null}  [options.limit]   For pagination, the number of results to return.
-     * @param  {CouchDBViewCursor|null}  [options.cursor]  For cursor-based pagination, the index cursor.
-     * @returns {{data, included, meta, skip, next, bookmark}} The JSON API conformant response.
-     */
+    return joined.length > 0 ? prefix + joined : '';
+};
 
-  }, {
-    key: "findReferencedBy",
-    value: function () {
-      var _findReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) {
-        var _ref3,
-            _ref3$skip,
-            skip,
-            limit,
-            cursor,
-            params,
-            path,
-            url,
-            resp,
-            _args3 = arguments;
 
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                _ref3 = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref3$skip = _ref3.skip, skip = _ref3$skip === void 0 ? 0 : _ref3$skip, limit = _ref3.limit, cursor = _ref3.cursor;
-                params = {
-                  include: 'files',
-                  'page[limit]': limit,
-                  'page[cursor]': cursor,
-                  sort: 'datetime'
-                };
-                path = (0, _utils.uri)(_templateObject(), document._type, document._id);
-                url = querystring.buildURL(path, params);
-                _context3.next = 6;
-                return this.stackClient.fetchJSON('GET', url);
+/***/ }),
+/* 643 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 6:
-                resp = _context3.sent;
-                return _context3.abrupt("return", {
-                  data: normalizeReferences(resp.data),
-                  included: resp.included ? resp.included.map(function (f) {
-                    return normalizeFile(f);
-                  }) : [],
-                  next: (0, _has.default)(resp, 'links.next'),
-                  meta: resp.meta,
-                  skip: skip
-                });
+"use strict";
 
-              case 8:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this);
-      }));
 
-      function findReferencedBy(_x4) {
-        return _findReferencedBy.apply(this, arguments);
-      }
+var GetIntrinsic = __webpack_require__(644);
+var callBound = __webpack_require__(650);
+var inspect = __webpack_require__(652);
 
-      return findReferencedBy;
-    }()
-    /**
-     *  Add referenced_by documents to a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-filesfile-idrelationshipsreferenced_by
-     *
-     *  For example, to have an album referenced by a file:
-     * ```
-     * addReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}])
-     * ```
-     *
-     * @param  {FileDocument} document  A JSON representing the file
-     * @param  {Array}  documents       An array of JSON documents having a `_type` and `_id` field.
-     * @returns {{data, meta}}          The JSON API conformant response.
-     */
+var $TypeError = GetIntrinsic('%TypeError%');
+var $WeakMap = GetIntrinsic('%WeakMap%', true);
+var $Map = GetIntrinsic('%Map%', true);
 
-  }, {
-    key: "addReferencedBy",
-    value: function () {
-      var _addReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, documents) {
-        var refs, resp;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                refs = documents.map(function (d) {
-                  return {
-                    id: d._id,
-                    type: d._type
-                  };
-                });
-                _context4.next = 3;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject2(), document._id), {
-                  data: refs
-                });
+var $weakMapGet = callBound('WeakMap.prototype.get', true);
+var $weakMapSet = callBound('WeakMap.prototype.set', true);
+var $weakMapHas = callBound('WeakMap.prototype.has', true);
+var $mapGet = callBound('Map.prototype.get', true);
+var $mapSet = callBound('Map.prototype.set', true);
+var $mapHas = callBound('Map.prototype.has', true);
+
+/*
+ * This function traverses the list returning the node corresponding to the
+ * given key.
+ *
+ * That node is also moved to the head of the list, so that if it's accessed
+ * again we don't need to traverse the whole list. By doing so, all the recently
+ * used nodes can be accessed relatively quickly.
+ */
+var listGetNode = function (list, key) { // eslint-disable-line consistent-return
+	for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {
+		if (curr.key === key) {
+			prev.next = curr.next;
+			curr.next = list.next;
+			list.next = curr; // eslint-disable-line no-param-reassign
+			return curr;
+		}
+	}
+};
 
-              case 3:
-                resp = _context4.sent;
-                return _context4.abrupt("return", {
-                  data: normalizeReferences(resp.data),
-                  meta: resp.meta
-                });
+var listGet = function (objects, key) {
+	var node = listGetNode(objects, key);
+	return node && node.value;
+};
+var listSet = function (objects, key, value) {
+	var node = listGetNode(objects, key);
+	if (node) {
+		node.value = value;
+	} else {
+		// Prepend the new node to the beginning of the list
+		objects.next = { // eslint-disable-line no-param-reassign
+			key: key,
+			next: objects.next,
+			value: value
+		};
+	}
+};
+var listHas = function (objects, key) {
+	return !!listGetNode(objects, key);
+};
 
-              case 5:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4, this);
-      }));
+module.exports = function getSideChannel() {
+	var $wm;
+	var $m;
+	var $o;
+	var channel = {
+		assert: function (key) {
+			if (!channel.has(key)) {
+				throw new $TypeError('Side channel does not contain ' + inspect(key));
+			}
+		},
+		get: function (key) { // eslint-disable-line consistent-return
+			if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
+				if ($wm) {
+					return $weakMapGet($wm, key);
+				}
+			} else if ($Map) {
+				if ($m) {
+					return $mapGet($m, key);
+				}
+			} else {
+				if ($o) { // eslint-disable-line no-lonely-if
+					return listGet($o, key);
+				}
+			}
+		},
+		has: function (key) {
+			if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
+				if ($wm) {
+					return $weakMapHas($wm, key);
+				}
+			} else if ($Map) {
+				if ($m) {
+					return $mapHas($m, key);
+				}
+			} else {
+				if ($o) { // eslint-disable-line no-lonely-if
+					return listHas($o, key);
+				}
+			}
+			return false;
+		},
+		set: function (key, value) {
+			if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
+				if (!$wm) {
+					$wm = new $WeakMap();
+				}
+				$weakMapSet($wm, key, value);
+			} else if ($Map) {
+				if (!$m) {
+					$m = new $Map();
+				}
+				$mapSet($m, key, value);
+			} else {
+				if (!$o) {
+					/*
+					 * Initialize the linked list as an empty node, so that we don't have
+					 * to special-case handling of the first node: we can always refer to
+					 * it as (previous node).next, instead of something like (list).head
+					 */
+					$o = { key: {}, next: null };
+				}
+				listSet($o, key, value);
+			}
+		}
+	};
+	return channel;
+};
 
-      function addReferencedBy(_x5, _x6) {
-        return _addReferencedBy.apply(this, arguments);
-      }
 
-      return addReferencedBy;
-    }()
-    /**
-     *  Remove referenced_by documents from a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-filesfile-idrelationshipsreferenced_by
-     *
-     *  For example, to remove an album reference from a file:
-     * ```
-     *  removeReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}])
-     * ```
-     *
-     * @param  {object} document        A JSON representing the file
-     * @param  {Array}  documents       An array of JSON documents having a `_type` and `_id` field.
-     * @returns {{data, meta}}          The JSON API conformant response.
-     */
+/***/ }),
+/* 644 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  }, {
-    key: "removeReferencedBy",
-    value: function () {
-      var _removeReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(document, documents) {
-        var refs, resp;
-        return _regenerator.default.wrap(function _callee5$(_context5) {
-          while (1) {
-            switch (_context5.prev = _context5.next) {
-              case 0:
-                refs = documents.map(function (d) {
-                  return {
-                    id: d._id,
-                    type: d._type
-                  };
-                });
-                _context5.next = 3;
-                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), document._id), {
-                  data: refs
-                });
+"use strict";
 
-              case 3:
-                resp = _context5.sent;
-                return _context5.abrupt("return", {
-                  data: normalizeReferences(resp.data),
-                  meta: resp.meta
-                });
 
-              case 5:
-              case "end":
-                return _context5.stop();
-            }
-          }
-        }, _callee5, this);
-      }));
+var undefined;
 
-      function removeReferencedBy(_x7, _x8) {
-        return _removeReferencedBy.apply(this, arguments);
-      }
+var $SyntaxError = SyntaxError;
+var $Function = Function;
+var $TypeError = TypeError;
 
-      return removeReferencedBy;
-    }()
-    /**
-     *  Add files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-datatypedoc-idrelationshipsreferences
-     *
-     *  For example, to add a photo to an album:
-     * ```
-     *  addReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}])
-     * ```
-     *
-     * @param  {object} document        A JSON representing a document, with at least a `_type` and `_id` field.
-     * @param  {Array}  documents       An array of JSON files having an `_id` field.
-     *
-     * Returns 204 No Content
-     */
+// eslint-disable-next-line consistent-return
+var getEvalledConstructor = function (expressionSyntax) {
+	try {
+		return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
+	} catch (e) {}
+};
 
-  }, {
-    key: "addReferencesTo",
-    value: function () {
-      var _addReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document, documents) {
-        var refs;
-        return _regenerator.default.wrap(function _callee6$(_context6) {
-          while (1) {
-            switch (_context6.prev = _context6.next) {
-              case 0:
-                refs = documents.map(function (d) {
-                  return {
-                    id: d._id,
-                    type: 'io.cozy.files'
-                  };
-                });
-                return _context6.abrupt("return", this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject4(), document._type, document._id), {
-                  data: refs
-                }));
+var $gOPD = Object.getOwnPropertyDescriptor;
+if ($gOPD) {
+	try {
+		$gOPD({}, '');
+	} catch (e) {
+		$gOPD = null; // this is IE 8, which has a broken gOPD
+	}
+}
 
-              case 2:
-              case "end":
-                return _context6.stop();
-            }
-          }
-        }, _callee6, this);
-      }));
+var throwTypeError = function () {
+	throw new $TypeError();
+};
+var ThrowTypeError = $gOPD
+	? (function () {
+		try {
+			// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
+			arguments.callee; // IE 8 does not throw here
+			return throwTypeError;
+		} catch (calleeThrows) {
+			try {
+				// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
+				return $gOPD(arguments, 'callee').get;
+			} catch (gOPDthrows) {
+				return throwTypeError;
+			}
+		}
+	}())
+	: throwTypeError;
 
-      function addReferencesTo(_x9, _x10) {
-        return _addReferencesTo.apply(this, arguments);
-      }
+var hasSymbols = __webpack_require__(645)();
 
-      return addReferencesTo;
-    }()
-    /**
-     *  Remove files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-datatypedoc-idrelationshipsreferences
-     *
-     *  For example, to remove a photo from an album:
-     * ```
-     *  removeReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}])
-     * ```
-     *
-     * @param  {object} document        A JSON representing a document, with at least a `_type` and `_id` field.
-     * @param  {Array}  documents       An array of JSON files having an `_id` field.
-     *
-     * Returns 204 No Content
-     */
+var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto
 
-  }, {
-    key: "removeReferencesTo",
-    value: function () {
-      var _removeReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document, documents) {
-        var refs;
-        return _regenerator.default.wrap(function _callee7$(_context7) {
-          while (1) {
-            switch (_context7.prev = _context7.next) {
-              case 0:
-                refs = documents.map(function (d) {
-                  return {
-                    id: d._id,
-                    type: 'io.cozy.files'
-                  };
-                });
-                return _context7.abrupt("return", this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), document._type, document._id), {
-                  data: refs
-                }));
+var needsEval = {};
 
-              case 2:
-              case "end":
-                return _context7.stop();
-            }
-          }
-        }, _callee7, this);
-      }));
+var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);
 
-      function removeReferencesTo(_x11, _x12) {
-        return _removeReferencesTo.apply(this, arguments);
-      }
+var INTRINSICS = {
+	'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
+	'%Array%': Array,
+	'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
+	'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,
+	'%AsyncFromSyncIteratorPrototype%': undefined,
+	'%AsyncFunction%': needsEval,
+	'%AsyncGenerator%': needsEval,
+	'%AsyncGeneratorFunction%': needsEval,
+	'%AsyncIteratorPrototype%': needsEval,
+	'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
+	'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
+	'%Boolean%': Boolean,
+	'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
+	'%Date%': Date,
+	'%decodeURI%': decodeURI,
+	'%decodeURIComponent%': decodeURIComponent,
+	'%encodeURI%': encodeURI,
+	'%encodeURIComponent%': encodeURIComponent,
+	'%Error%': Error,
+	'%eval%': eval, // eslint-disable-line no-eval
+	'%EvalError%': EvalError,
+	'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
+	'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
+	'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
+	'%Function%': $Function,
+	'%GeneratorFunction%': needsEval,
+	'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
+	'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
+	'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
+	'%isFinite%': isFinite,
+	'%isNaN%': isNaN,
+	'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,
+	'%JSON%': typeof JSON === 'object' ? JSON : undefined,
+	'%Map%': typeof Map === 'undefined' ? undefined : Map,
+	'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),
+	'%Math%': Math,
+	'%Number%': Number,
+	'%Object%': Object,
+	'%parseFloat%': parseFloat,
+	'%parseInt%': parseInt,
+	'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
+	'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
+	'%RangeError%': RangeError,
+	'%ReferenceError%': ReferenceError,
+	'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
+	'%RegExp%': RegExp,
+	'%Set%': typeof Set === 'undefined' ? undefined : Set,
+	'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),
+	'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
+	'%String%': String,
+	'%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,
+	'%Symbol%': hasSymbols ? Symbol : undefined,
+	'%SyntaxError%': $SyntaxError,
+	'%ThrowTypeError%': ThrowTypeError,
+	'%TypedArray%': TypedArray,
+	'%TypeError%': $TypeError,
+	'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
+	'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
+	'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
+	'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
+	'%URIError%': URIError,
+	'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
+	'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
+	'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
+};
 
-      return removeReferencesTo;
-    }()
-    /**
-     * Sends file to trash and removes references to it
-     *
-     * @param  {FileDocument} file - File that will be sent to trash
-     * @returns {Promise} - Resolves when references have been removed
-     * and file has been sent to trash
-     */
+var doEval = function doEval(name) {
+	var value;
+	if (name === '%AsyncFunction%') {
+		value = getEvalledConstructor('async function () {}');
+	} else if (name === '%GeneratorFunction%') {
+		value = getEvalledConstructor('function* () {}');
+	} else if (name === '%AsyncGeneratorFunction%') {
+		value = getEvalledConstructor('async function* () {}');
+	} else if (name === '%AsyncGenerator%') {
+		var fn = doEval('%AsyncGeneratorFunction%');
+		if (fn) {
+			value = fn.prototype;
+		}
+	} else if (name === '%AsyncIteratorPrototype%') {
+		var gen = doEval('%AsyncGenerator%');
+		if (gen) {
+			value = getProto(gen.prototype);
+		}
+	}
 
-  }, {
-    key: "destroy",
-    value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(file) {
-        var _ref4,
-            _ref4$ifMatch,
-            ifMatch,
-            _id,
-            relationships,
-            _iterator,
-            _step,
-            ref,
-            resp,
-            _args8 = arguments;
+	INTRINSICS[name] = value;
 
-        return _regenerator.default.wrap(function _callee8$(_context8) {
-          while (1) {
-            switch (_context8.prev = _context8.next) {
-              case 0:
-                _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {}, _ref4$ifMatch = _ref4.ifMatch, ifMatch = _ref4$ifMatch === void 0 ? '' : _ref4$ifMatch;
-                _id = file._id, relationships = file.relationships;
+	return value;
+};
 
-                if (!(relationships && relationships.referenced_by && Array.isArray(relationships.referenced_by.data))) {
-                  _context8.next = 20;
-                  break;
-                }
+var LEGACY_ALIASES = {
+	'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
+	'%ArrayPrototype%': ['Array', 'prototype'],
+	'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
+	'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
+	'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
+	'%ArrayProto_values%': ['Array', 'prototype', 'values'],
+	'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
+	'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
+	'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
+	'%BooleanPrototype%': ['Boolean', 'prototype'],
+	'%DataViewPrototype%': ['DataView', 'prototype'],
+	'%DatePrototype%': ['Date', 'prototype'],
+	'%ErrorPrototype%': ['Error', 'prototype'],
+	'%EvalErrorPrototype%': ['EvalError', 'prototype'],
+	'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
+	'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
+	'%FunctionPrototype%': ['Function', 'prototype'],
+	'%Generator%': ['GeneratorFunction', 'prototype'],
+	'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
+	'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
+	'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
+	'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
+	'%JSONParse%': ['JSON', 'parse'],
+	'%JSONStringify%': ['JSON', 'stringify'],
+	'%MapPrototype%': ['Map', 'prototype'],
+	'%NumberPrototype%': ['Number', 'prototype'],
+	'%ObjectPrototype%': ['Object', 'prototype'],
+	'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
+	'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
+	'%PromisePrototype%': ['Promise', 'prototype'],
+	'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
+	'%Promise_all%': ['Promise', 'all'],
+	'%Promise_reject%': ['Promise', 'reject'],
+	'%Promise_resolve%': ['Promise', 'resolve'],
+	'%RangeErrorPrototype%': ['RangeError', 'prototype'],
+	'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
+	'%RegExpPrototype%': ['RegExp', 'prototype'],
+	'%SetPrototype%': ['Set', 'prototype'],
+	'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
+	'%StringPrototype%': ['String', 'prototype'],
+	'%SymbolPrototype%': ['Symbol', 'prototype'],
+	'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
+	'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
+	'%TypeErrorPrototype%': ['TypeError', 'prototype'],
+	'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
+	'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
+	'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
+	'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
+	'%URIErrorPrototype%': ['URIError', 'prototype'],
+	'%WeakMapPrototype%': ['WeakMap', 'prototype'],
+	'%WeakSetPrototype%': ['WeakSet', 'prototype']
+};
 
-                _iterator = _createForOfIteratorHelper(relationships.referenced_by.data);
-                _context8.prev = 4;
+var bind = __webpack_require__(647);
+var hasOwn = __webpack_require__(649);
+var $concat = bind.call(Function.call, Array.prototype.concat);
+var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
+var $replace = bind.call(Function.call, String.prototype.replace);
+var $strSlice = bind.call(Function.call, String.prototype.slice);
 
-                _iterator.s();
+/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
+var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
+var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
+var stringToPath = function stringToPath(string) {
+	var first = $strSlice(string, 0, 1);
+	var last = $strSlice(string, -1);
+	if (first === '%' && last !== '%') {
+		throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
+	} else if (last === '%' && first !== '%') {
+		throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
+	}
+	var result = [];
+	$replace(string, rePropName, function (match, number, quote, subString) {
+		result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
+	});
+	return result;
+};
+/* end adaptation */
 
-              case 6:
-                if ((_step = _iterator.n()).done) {
-                  _context8.next = 12;
-                  break;
-                }
+var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
+	var intrinsicName = name;
+	var alias;
+	if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
+		alias = LEGACY_ALIASES[intrinsicName];
+		intrinsicName = '%' + alias[0] + '%';
+	}
 
-                ref = _step.value;
-                _context8.next = 10;
-                return this.removeReferencesTo({
-                  _id: ref.id,
-                  _type: ref.type
-                }, [{
-                  _id: _id
-                }]);
+	if (hasOwn(INTRINSICS, intrinsicName)) {
+		var value = INTRINSICS[intrinsicName];
+		if (value === needsEval) {
+			value = doEval(intrinsicName);
+		}
+		if (typeof value === 'undefined' && !allowMissing) {
+			throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
+		}
 
-              case 10:
-                _context8.next = 6;
-                break;
+		return {
+			alias: alias,
+			name: intrinsicName,
+			value: value
+		};
+	}
 
-              case 12:
-                _context8.next = 17;
-                break;
+	throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
+};
 
-              case 14:
-                _context8.prev = 14;
-                _context8.t0 = _context8["catch"](4);
+module.exports = function GetIntrinsic(name, allowMissing) {
+	if (typeof name !== 'string' || name.length === 0) {
+		throw new $TypeError('intrinsic name must be a non-empty string');
+	}
+	if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
+		throw new $TypeError('"allowMissing" argument must be a boolean');
+	}
 
-                _iterator.e(_context8.t0);
+	var parts = stringToPath(name);
+	var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
 
-              case 17:
-                _context8.prev = 17;
+	var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
+	var intrinsicRealName = intrinsic.name;
+	var value = intrinsic.value;
+	var skipFurtherCaching = false;
 
-                _iterator.f();
+	var alias = intrinsic.alias;
+	if (alias) {
+		intrinsicBaseName = alias[0];
+		$spliceApply(parts, $concat([0, 1], alias));
+	}
 
-                return _context8.finish(17);
+	for (var i = 1, isOwn = true; i < parts.length; i += 1) {
+		var part = parts[i];
+		var first = $strSlice(part, 0, 1);
+		var last = $strSlice(part, -1);
+		if (
+			(
+				(first === '"' || first === "'" || first === '`')
+				|| (last === '"' || last === "'" || last === '`')
+			)
+			&& first !== last
+		) {
+			throw new $SyntaxError('property names with quotes must have matching quotes');
+		}
+		if (part === 'constructor' || !isOwn) {
+			skipFurtherCaching = true;
+		}
 
-              case 20:
-                _context8.next = 22;
-                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), _id), undefined, {
-                  headers: {
-                    'If-Match': ifMatch
-                  }
-                });
+		intrinsicBaseName += '.' + part;
+		intrinsicRealName = '%' + intrinsicBaseName + '%';
 
-              case 22:
-                resp = _context8.sent;
-                return _context8.abrupt("return", {
-                  data: normalizeFile(resp.data)
-                });
+		if (hasOwn(INTRINSICS, intrinsicRealName)) {
+			value = INTRINSICS[intrinsicRealName];
+		} else if (value != null) {
+			if (!(part in value)) {
+				if (!allowMissing) {
+					throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
+				}
+				return void undefined;
+			}
+			if ($gOPD && (i + 1) >= parts.length) {
+				var desc = $gOPD(value, part);
+				isOwn = !!desc;
 
-              case 24:
-              case "end":
-                return _context8.stop();
-            }
-          }
-        }, _callee8, this, [[4, 14, 17, 20]]);
-      }));
+				// By convention, when a data property is converted to an accessor
+				// property to emulate a data property that does not suffer from
+				// the override mistake, that accessor's getter is marked with
+				// an `originalValue` property. Here, when we detect this, we
+				// uphold the illusion by pretending to see that original data
+				// property, i.e., returning the value rather than the getter
+				// itself.
+				if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
+					value = desc.get;
+				} else {
+					value = value[part];
+				}
+			} else {
+				isOwn = hasOwn(value, part);
+				value = value[part];
+			}
 
-      function destroy(_x13) {
-        return _destroy.apply(this, arguments);
-      }
+			if (isOwn && !skipFurtherCaching) {
+				INTRINSICS[intrinsicRealName] = value;
+			}
+		}
+	}
+	return value;
+};
 
-      return destroy;
-    }()
-    /**
-     * Empty the Trash
-     */
 
-  }, {
-    key: "emptyTrash",
-    value: function emptyTrash() {
-      return this.stackClient.fetchJSON('DELETE', '/files/trash');
-    }
-    /**
-     * Restores a trashed file.
-     *
-     * @param {string} id   - The file's id
-     * @returns {Promise}   - A promise that returns the restored file if resolved.
-     * @throws {FetchError}
-     *
-     */
+/***/ }),
+/* 645 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  }, {
-    key: "restore",
-    value: function restore(id) {
-      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), id));
-    }
-    /**
-     * async deleteFilePermanently - Definitely delete a file
-     *
-     * @param  {string} id - The id of the file to delete
-     * @returns {object} The deleted file object
-     */
+"use strict";
 
-  }, {
-    key: "deleteFilePermanently",
-    value: function () {
-      var _deleteFilePermanently = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(id) {
-        var resp;
-        return _regenerator.default.wrap(function _callee9$(_context9) {
-          while (1) {
-            switch (_context9.prev = _context9.next) {
-              case 0:
-                _context9.next = 2;
-                return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject8(), id), {
-                  data: {
-                    type: 'io.cozy.files',
-                    id: id,
-                    attributes: {
-                      permanent_delete: true
-                    }
-                  }
-                });
 
-              case 2:
-                resp = _context9.sent;
-                return _context9.abrupt("return", resp.data);
+var origSymbol = typeof Symbol !== 'undefined' && Symbol;
+var hasSymbolSham = __webpack_require__(646);
 
-              case 4:
-              case "end":
-                return _context9.stop();
-            }
-          }
-        }, _callee9, this);
-      }));
+module.exports = function hasNativeSymbols() {
+	if (typeof origSymbol !== 'function') { return false; }
+	if (typeof Symbol !== 'function') { return false; }
+	if (typeof origSymbol('foo') !== 'symbol') { return false; }
+	if (typeof Symbol('bar') !== 'symbol') { return false; }
 
-      function deleteFilePermanently(_x14) {
-        return _deleteFilePermanently.apply(this, arguments);
-      }
+	return hasSymbolSham();
+};
 
-      return deleteFilePermanently;
-    }()
-    /**
-     * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded
-     * @param {string} dirPath Path to upload the file to. ie : /Administative/XXX/
-     * @returns {object} Created io.cozy.files
-     */
 
-  }, {
-    key: "upload",
-    value: function () {
-      var _upload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data, dirPath) {
-        var dirId;
-        return _regenerator.default.wrap(function _callee10$(_context10) {
-          while (1) {
-            switch (_context10.prev = _context10.next) {
-              case 0:
-                _context10.next = 2;
-                return this.ensureDirectoryExists(dirPath);
+/***/ }),
+/* 646 */
+/***/ ((module) => {
 
-              case 2:
-                dirId = _context10.sent;
-                return _context10.abrupt("return", this.createFile(data, {
-                  dirId: dirId
-                }));
+"use strict";
 
-              case 4:
-              case "end":
-                return _context10.stop();
-            }
-          }
-        }, _callee10, this);
-      }));
 
-      function upload(_x15, _x16) {
-        return _upload.apply(this, arguments);
-      }
+/* eslint complexity: [2, 18], max-statements: [2, 33] */
+module.exports = function hasSymbols() {
+	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
+	if (typeof Symbol.iterator === 'symbol') { return true; }
 
-      return upload;
-    }()
-    /**
-     * Creates directory or file.
-     * - Used by StackLink to support CozyClient.create('io.cozy.files', options)
-     *
-     * @param {FileAttributes|DirectoryAttributes} attributes - Attributes of the created file/directory
-     * @param {File|Blob|string|ArrayBuffer} attributes.data Will be used as content of the created file
-     * @throws {Error} - explaining reason why creation failed
-     */
+	var obj = {};
+	var sym = Symbol('test');
+	var symObj = Object(sym);
+	if (typeof sym === 'string') { return false; }
 
-  }, {
-    key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(attributes) {
-        var data, createFileOptions;
-        return _regenerator.default.wrap(function _callee11$(_context11) {
-          while (1) {
-            switch (_context11.prev = _context11.next) {
-              case 0:
-                if (!(attributes.type === 'directory')) {
-                  _context11.next = 4;
-                  break;
-                }
+	if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }
+	if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }
 
-                return _context11.abrupt("return", this.createDirectory(attributes));
+	// temp disabled per https://github.com/ljharb/object.assign/issues/17
+	// if (sym instanceof Symbol) { return false; }
+	// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
+	// if (!(symObj instanceof Symbol)) { return false; }
 
-              case 4:
-                data = attributes.data, createFileOptions = (0, _objectWithoutProperties2.default)(attributes, ["data"]);
-                return _context11.abrupt("return", this.createFile(data, createFileOptions));
+	// if (typeof Symbol.prototype.toString !== 'function') { return false; }
+	// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }
 
-              case 6:
-              case "end":
-                return _context11.stop();
-            }
-          }
-        }, _callee11, this);
-      }));
+	var symVal = 42;
+	obj[sym] = symVal;
+	for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop
+	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }
 
-      function create(_x17) {
-        return _create.apply(this, arguments);
-      }
+	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }
 
-      return create;
-    }()
-    /***
-     * Update the io.cozy.files
-     * Used by StackLink to support CozyClient.save({file})
-     * @param {FileAttributes} file - The file with its new content
-     * @returns {FileAttributes} Updated document
-     * @throws {Error} - explaining reason why update failed
-     */
+	var syms = Object.getOwnPropertySymbols(obj);
+	if (syms.length !== 1 || syms[0] !== sym) { return false; }
 
-  }, {
-    key: "update",
-    value: function () {
-      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(file) {
-        return _regenerator.default.wrap(function _callee12$(_context12) {
-          while (1) {
-            switch (_context12.prev = _context12.next) {
-              case 0:
-                return _context12.abrupt("return", this.updateAttributes(file.id, file));
+	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }
 
-              case 1:
-              case "end":
-                return _context12.stop();
-            }
-          }
-        }, _callee12, this);
-      }));
+	if (typeof Object.getOwnPropertyDescriptor === 'function') {
+		var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
+		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
+	}
 
-      function update(_x18) {
-        return _update.apply(this, arguments);
-      }
+	return true;
+};
 
-      return update;
-    }()
-    /**
-     * Creates a file
-     *
-     * @private
-     * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded
-     * @param {FileAttributes} params Additional parameters
-     * @param  {object}  params.options     Options to pass to doUpload method (additional headers)
-     * @throws {Error} - explaining reason why creation failed
-     */
 
-  }, {
-    key: "createFile",
-    value: function () {
-      var _createFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(data) {
-        var _ref5,
-            nameOption,
-            _ref5$dirId,
-            dirId,
-            executableOption,
-            metadata,
-            options,
-            name,
-            executable,
-            metadataId,
-            meta,
-            size,
-            path,
-            _args13 = arguments;
+/***/ }),
+/* 647 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-        return _regenerator.default.wrap(function _callee13$(_context13) {
-          while (1) {
-            switch (_context13.prev = _context13.next) {
-              case 0:
-                _ref5 = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {};
-                nameOption = _ref5.name, _ref5$dirId = _ref5.dirId, dirId = _ref5$dirId === void 0 ? '' : _ref5$dirId, executableOption = _ref5.executable, metadata = _ref5.metadata, options = (0, _objectWithoutProperties2.default)(_ref5, ["name", "dirId", "executable", "metadata"]);
-                name = nameOption;
-                executable = executableOption; // handle case where data is a file and contains the name
+"use strict";
 
-                if (!name && typeof data.name === 'string') {
-                  name = data.name;
-                }
 
-                name = sanitizeAndValidateFileName(name);
+var implementation = __webpack_require__(648);
 
-                if (executable === undefined) {
-                  executable = false;
-                }
+module.exports = Function.prototype.bind || implementation;
 
-                metadataId = '';
 
-                if (!metadata) {
-                  _context13.next = 13;
-                  break;
-                }
+/***/ }),
+/* 648 */
+/***/ ((module) => {
 
-                _context13.next = 11;
-                return this.createFileMetadata(metadata);
+"use strict";
 
-              case 11:
-                meta = _context13.sent;
-                metadataId = meta.data.id;
 
-              case 13:
-                size = '';
+/* eslint no-invalid-this: 1 */
 
-                if (options.contentLength) {
-                  size = String(options.contentLength);
-                }
+var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
+var slice = Array.prototype.slice;
+var toStr = Object.prototype.toString;
+var funcType = '[object Function]';
 
-                path = (0, _utils.uri)(_templateObject9(), dirId, name, executable, metadataId, size);
-                return _context13.abrupt("return", this.doUpload(data, path, options));
+module.exports = function bind(that) {
+    var target = this;
+    if (typeof target !== 'function' || toStr.call(target) !== funcType) {
+        throw new TypeError(ERROR_MESSAGE + target);
+    }
+    var args = slice.call(arguments, 1);
 
-              case 17:
-              case "end":
-                return _context13.stop();
+    var bound;
+    var binder = function () {
+        if (this instanceof bound) {
+            var result = target.apply(
+                this,
+                args.concat(slice.call(arguments))
+            );
+            if (Object(result) === result) {
+                return result;
             }
-          }
-        }, _callee13, this);
-      }));
-
-      function createFile(_x19) {
-        return _createFile.apply(this, arguments);
-      }
+            return this;
+        } else {
+            return target.apply(
+                that,
+                args.concat(slice.call(arguments))
+            );
+        }
+    };
 
-      return createFile;
-    }()
-    /**
-     * updateFile - Updates a file's data
-     *
-     * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded
-     * @param {FileAttributes} params       Additional parameters
-     * @param  {object}  params.options     Options to pass to doUpload method (additional headers)
-     * @returns {object}                    Updated document
-     * @throws {Error} - explaining reason why update failed
-     */
+    var boundLength = Math.max(0, target.length - args.length);
+    var boundArgs = [];
+    for (var i = 0; i < boundLength; i++) {
+        boundArgs.push('$' + i);
+    }
 
-  }, {
-    key: "updateFile",
-    value: function () {
-      var _updateFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(data) {
-        var _ref6,
-            _ref6$executable,
-            executable,
-            fileId,
-            _ref6$name,
-            name,
-            metadata,
-            options,
-            fileName,
-            sanitizedName,
-            metadataId,
-            path,
-            meta,
-            size,
-            _args14 = arguments;
+    bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
 
-        return _regenerator.default.wrap(function _callee14$(_context14) {
-          while (1) {
-            switch (_context14.prev = _context14.next) {
-              case 0:
-                _ref6 = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {};
-                _ref6$executable = _ref6.executable, executable = _ref6$executable === void 0 ? false : _ref6$executable, fileId = _ref6.fileId, _ref6$name = _ref6.name, name = _ref6$name === void 0 ? '' : _ref6$name, metadata = _ref6.metadata, options = (0, _objectWithoutProperties2.default)(_ref6, ["executable", "fileId", "name", "metadata"]);
+    if (target.prototype) {
+        var Empty = function Empty() {};
+        Empty.prototype = target.prototype;
+        bound.prototype = new Empty();
+        Empty.prototype = null;
+    }
 
-                if (!(!fileId || typeof fileId !== 'string')) {
-                  _context14.next = 4;
-                  break;
-                }
+    return bound;
+};
 
-                throw new Error('missing fileId argument');
 
-              case 4:
-                // name might be set in a File object
-                fileName = name || data.name;
+/***/ }),
+/* 649 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                if (!(!fileName || typeof fileName !== 'string')) {
-                  _context14.next = 7;
-                  break;
-                }
+"use strict";
 
-                throw new Error('missing name in data argument');
 
-              case 7:
-                sanitizedName = sanitizeAndValidateFileName(fileName);
-                /**
-                 * We already use the body to send the content of the file. So we have 2 choices :
-                 * Use an object in a query string to send the metadata
-                 * create a new header http
-                 * In both case, we have a size limitation depending of the browser.
-                 *
-                 * So we had this current workaround where we create the metadata before
-                 * (no size limit since we can use the body for that) and after we use the ID.
-                 */
+var bind = __webpack_require__(647);
 
-                path = (0, _utils.uri)(_templateObject10(), fileId, sanitizedName, executable);
+module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);
 
-                if (!metadata) {
-                  _context14.next = 15;
-                  break;
-                }
 
-                _context14.next = 12;
-                return this.createFileMetadata(metadata);
+/***/ }),
+/* 650 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-              case 12:
-                meta = _context14.sent;
-                metadataId = meta.data.id;
-                path = path + "&MetadataID=".concat(metadataId);
+"use strict";
 
-              case 15:
-                size = '';
 
-                if (options.contentLength) {
-                  size = String(options.contentLength);
-                  path = path + "&Size=".concat(size);
-                }
+var GetIntrinsic = __webpack_require__(644);
 
-                return _context14.abrupt("return", this.doUpload(data, path, options, 'PUT'));
+var callBind = __webpack_require__(651);
 
-              case 18:
-              case "end":
-                return _context14.stop();
-            }
-          }
-        }, _callee14, this);
-      }));
+var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));
 
-      function updateFile(_x20) {
-        return _updateFile.apply(this, arguments);
-      }
+module.exports = function callBoundIntrinsic(name, allowMissing) {
+	var intrinsic = GetIntrinsic(name, !!allowMissing);
+	if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
+		return callBind(intrinsic);
+	}
+	return intrinsic;
+};
 
-      return updateFile;
-    }()
-  }, {
-    key: "getDownloadLinkById",
-    value: function getDownloadLinkById(id, filename) {
-      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject11(), id, filename)).then(this.extractResponseLinkRelated);
-    }
-  }, {
-    key: "getDownloadLinkByRevision",
-    value: function getDownloadLinkByRevision(versionId, filename) {
-      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject12(), versionId, filename)).then(this.extractResponseLinkRelated);
-    }
-  }, {
-    key: "getDownloadLinkByPath",
-    value: function getDownloadLinkByPath(path) {
-      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject13(), path)).then(this.extractResponseLinkRelated);
-    }
-  }, {
-    key: "download",
 
-    /**
-     * Download a file or a specific version of the file
-     *
-     * @param {object} file io.cozy.files object
-     * @param {string} versionId Id of the io.cozy.files.version
-     * @param {string} filename The name you want for the downloaded file
-     *                            (by default the same as the file)
-     */
-    value: function () {
-      var _download = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(file) {
-        var versionId,
-            filename,
-            href,
-            filenameToUse,
-            _args15 = arguments;
-        return _regenerator.default.wrap(function _callee15$(_context15) {
-          while (1) {
-            switch (_context15.prev = _context15.next) {
-              case 0:
-                versionId = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : null;
-                filename = _args15.length > 2 && _args15[2] !== undefined ? _args15[2] : undefined;
-                filenameToUse = filename ? filename : file.name;
-                /**
-                 * Passing a filename to forceFileDownload is not enough
-                 * for a few browsers since the stack's response header will
-                 * not contain that name. Passing the filename to
-                 * getDownloadLinkBy{Id,Revision} will ask the stack to
-                 * return this filename in its content-disposition
-                 * header response
-                 */
+/***/ }),
+/* 651 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-                if (versionId) {
-                  _context15.next = 9;
-                  break;
-                }
+"use strict";
 
-                _context15.next = 6;
-                return this.getDownloadLinkById(file._id, filenameToUse);
 
-              case 6:
-                href = _context15.sent;
-                _context15.next = 12;
-                break;
+var bind = __webpack_require__(647);
+var GetIntrinsic = __webpack_require__(644);
 
-              case 9:
-                _context15.next = 11;
-                return this.getDownloadLinkByRevision(versionId, filenameToUse);
+var $apply = GetIntrinsic('%Function.prototype.apply%');
+var $call = GetIntrinsic('%Function.prototype.call%');
+var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);
 
-              case 11:
-                href = _context15.sent;
+var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
+var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
+var $max = GetIntrinsic('%Math.max%');
 
-              case 12:
-                this.forceFileDownload("".concat(href, "?Dl=1"), filenameToUse);
+if ($defineProperty) {
+	try {
+		$defineProperty({}, 'a', { value: 1 });
+	} catch (e) {
+		// IE 8 has a broken defineProperty
+		$defineProperty = null;
+	}
+}
 
-              case 13:
-              case "end":
-                return _context15.stop();
-            }
-          }
-        }, _callee15, this);
-      }));
+module.exports = function callBind(originalFunction) {
+	var func = $reflectApply(bind, $call, arguments);
+	if ($gOPD && $defineProperty) {
+		var desc = $gOPD(func, 'length');
+		if (desc.configurable) {
+			// original length, plus the receiver, minus any additional arguments (after the receiver)
+			$defineProperty(
+				func,
+				'length',
+				{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }
+			);
+		}
+	}
+	return func;
+};
 
-      function download(_x21) {
-        return _download.apply(this, arguments);
-      }
+var applyBind = function applyBind() {
+	return $reflectApply(bind, $apply, arguments);
+};
 
-      return download;
-    }()
-  }, {
-    key: "fetchFileContent",
-    value: function () {
-      var _fetchFileContent = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16(id) {
-        return _regenerator.default.wrap(function _callee16$(_context16) {
-          while (1) {
-            switch (_context16.prev = _context16.next) {
-              case 0:
-                console.warn('FileCollection.fetchFileContent() is deprecated. Use FileCollection.fetchFileContentById() instead');
-                return _context16.abrupt("return", this.fetchFileContentById(id));
+if ($defineProperty) {
+	$defineProperty(module.exports, 'apply', { value: applyBind });
+} else {
+	module.exports.apply = applyBind;
+}
 
-              case 2:
-              case "end":
-                return _context16.stop();
-            }
-          }
-        }, _callee16, this);
-      }));
 
-      function fetchFileContent(_x22) {
-        return _fetchFileContent.apply(this, arguments);
-      }
+/***/ }),
+/* 652 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return fetchFileContent;
-    }()
-    /**
-     * Fetch the binary of a file or a specific version of a file
-     * Useful for instance when you can't download the file directly
-     * (via a content-disposition attachement header) and need to store
-     * it before doing an operation.
-     *
-     * @param {string} id Id of the io.cozy.files or io.cozy.files.version
-     *
-     */
+var hasMap = typeof Map === 'function' && Map.prototype;
+var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
+var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
+var mapForEach = hasMap && Map.prototype.forEach;
+var hasSet = typeof Set === 'function' && Set.prototype;
+var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
+var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
+var setForEach = hasSet && Set.prototype.forEach;
+var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
+var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
+var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
+var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
+var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
+var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
+var booleanValueOf = Boolean.prototype.valueOf;
+var objectToString = Object.prototype.toString;
+var functionToString = Function.prototype.toString;
+var match = String.prototype.match;
+var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
+var gOPS = Object.getOwnPropertySymbols;
+var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
+var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
+var isEnumerable = Object.prototype.propertyIsEnumerable;
 
-  }, {
-    key: "fetchFileContentById",
-    value: function () {
-      var _fetchFileContentById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(id) {
-        return _regenerator.default.wrap(function _callee17$(_context17) {
-          while (1) {
-            switch (_context17.prev = _context17.next) {
-              case 0:
-                return _context17.abrupt("return", this.stackClient.fetch('GET', "/files/download/".concat(id)));
+var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
+    [].__proto__ === Array.prototype // eslint-disable-line no-proto
+        ? function (O) {
+            return O.__proto__; // eslint-disable-line no-proto
+        }
+        : null
+);
 
-              case 1:
-              case "end":
-                return _context17.stop();
-            }
-          }
-        }, _callee17, this);
-      }));
+var inspectCustom = (__webpack_require__(653).custom);
+var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;
+var toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;
 
-      function fetchFileContentById(_x23) {
-        return _fetchFileContentById.apply(this, arguments);
-      }
+module.exports = function inspect_(obj, options, depth, seen) {
+    var opts = options || {};
 
-      return fetchFileContentById;
-    }()
-    /**
-     * Get a beautified size for a given file
-     * 1024B => 1KB
-     * 102404500404B => 95.37 GB
-     *
-     * @param {object} file io.cozy.files object
-     * @param {number} decimal number of decimal
-     */
+    if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {
+        throw new TypeError('option "quoteStyle" must be "single" or "double"');
+    }
+    if (
+        has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
+            ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
+            : opts.maxStringLength !== null
+        )
+    ) {
+        throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
+    }
+    var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
+    if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
+        throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
+    }
 
-  }, {
-    key: "getBeautifulSize",
-    value: function getBeautifulSize(file, decimal) {
-      return (0, _utils.formatBytes)(parseInt(file.size), decimal);
+    if (
+        has(opts, 'indent')
+        && opts.indent !== null
+        && opts.indent !== '\t'
+        && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
+    ) {
+        throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');
     }
-  }, {
-    key: "downloadArchive",
-    value: function () {
-      var _downloadArchive = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(fileIds) {
-        var notSecureFilename,
-            filename,
-            href,
-            fullpath,
-            _args18 = arguments;
-        return _regenerator.default.wrap(function _callee18$(_context18) {
-          while (1) {
-            switch (_context18.prev = _context18.next) {
-              case 0:
-                notSecureFilename = _args18.length > 1 && _args18[1] !== undefined ? _args18[1] : 'files';
-                filename = (0, _utils.slugify)(notSecureFilename);
-                _context18.next = 4;
-                return this.getArchiveLinkByIds(fileIds, filename);
 
-              case 4:
-                href = _context18.sent;
-                fullpath = this.stackClient.fullpath(href);
-                this.forceFileDownload(fullpath, filename + '.zip');
+    if (typeof obj === 'undefined') {
+        return 'undefined';
+    }
+    if (obj === null) {
+        return 'null';
+    }
+    if (typeof obj === 'boolean') {
+        return obj ? 'true' : 'false';
+    }
 
-              case 7:
-              case "end":
-                return _context18.stop();
-            }
-          }
-        }, _callee18, this);
-      }));
+    if (typeof obj === 'string') {
+        return inspectString(obj, opts);
+    }
+    if (typeof obj === 'number') {
+        if (obj === 0) {
+            return Infinity / obj > 0 ? '0' : '-0';
+        }
+        return String(obj);
+    }
+    if (typeof obj === 'bigint') {
+        return String(obj) + 'n';
+    }
 
-      function downloadArchive(_x24) {
-        return _downloadArchive.apply(this, arguments);
-      }
+    var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
+    if (typeof depth === 'undefined') { depth = 0; }
+    if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
+        return isArray(obj) ? '[Array]' : '[Object]';
+    }
 
-      return downloadArchive;
-    }()
-  }, {
-    key: "getArchiveLinkByIds",
-    value: function () {
-      var _getArchiveLinkByIds = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(ids) {
-        var name,
-            resp,
-            _args19 = arguments;
-        return _regenerator.default.wrap(function _callee19$(_context19) {
-          while (1) {
-            switch (_context19.prev = _context19.next) {
-              case 0:
-                name = _args19.length > 1 && _args19[1] !== undefined ? _args19[1] : 'files';
-                _context19.next = 3;
-                return this.stackClient.fetchJSON('POST', '/files/archive', {
-                  data: {
-                    type: 'io.cozy.archives',
-                    attributes: {
-                      name: name,
-                      ids: ids
-                    }
-                  }
-                });
+    var indent = getIndent(opts, depth);
 
-              case 3:
-                resp = _context19.sent;
-                return _context19.abrupt("return", resp.links.related);
+    if (typeof seen === 'undefined') {
+        seen = [];
+    } else if (indexOf(seen, obj) >= 0) {
+        return '[Circular]';
+    }
 
-              case 5:
-              case "end":
-                return _context19.stop();
+    function inspect(value, from, noIndent) {
+        if (from) {
+            seen = seen.slice();
+            seen.push(from);
+        }
+        if (noIndent) {
+            var newOpts = {
+                depth: opts.depth
+            };
+            if (has(opts, 'quoteStyle')) {
+                newOpts.quoteStyle = opts.quoteStyle;
             }
-          }
-        }, _callee19, this);
-      }));
+            return inspect_(value, newOpts, depth + 1, seen);
+        }
+        return inspect_(value, opts, depth + 1, seen);
+    }
 
-      function getArchiveLinkByIds(_x25) {
-        return _getArchiveLinkByIds.apply(this, arguments);
-      }
+    if (typeof obj === 'function') {
+        var name = nameOf(obj);
+        var keys = arrObjKeys(obj, inspect);
+        return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');
+    }
+    if (isSymbol(obj)) {
+        var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
+        return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
+    }
+    if (isElement(obj)) {
+        var s = '<' + String(obj.nodeName).toLowerCase();
+        var attrs = obj.attributes || [];
+        for (var i = 0; i < attrs.length; i++) {
+            s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
+        }
+        s += '>';
+        if (obj.childNodes && obj.childNodes.length) { s += '...'; }
+        s += '</' + String(obj.nodeName).toLowerCase() + '>';
+        return s;
+    }
+    if (isArray(obj)) {
+        if (obj.length === 0) { return '[]'; }
+        var xs = arrObjKeys(obj, inspect);
+        if (indent && !singleLineValues(xs)) {
+            return '[' + indentedJoin(xs, indent) + ']';
+        }
+        return '[ ' + xs.join(', ') + ' ]';
+    }
+    if (isError(obj)) {
+        var parts = arrObjKeys(obj, inspect);
+        if (parts.length === 0) { return '[' + String(obj) + ']'; }
+        return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';
+    }
+    if (typeof obj === 'object' && customInspect) {
+        if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {
+            return obj[inspectSymbol]();
+        } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
+            return obj.inspect();
+        }
+    }
+    if (isMap(obj)) {
+        var mapParts = [];
+        mapForEach.call(obj, function (value, key) {
+            mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
+        });
+        return collectionOf('Map', mapSize.call(obj), mapParts, indent);
+    }
+    if (isSet(obj)) {
+        var setParts = [];
+        setForEach.call(obj, function (value) {
+            setParts.push(inspect(value, obj));
+        });
+        return collectionOf('Set', setSize.call(obj), setParts, indent);
+    }
+    if (isWeakMap(obj)) {
+        return weakCollectionOf('WeakMap');
+    }
+    if (isWeakSet(obj)) {
+        return weakCollectionOf('WeakSet');
+    }
+    if (isWeakRef(obj)) {
+        return weakCollectionOf('WeakRef');
+    }
+    if (isNumber(obj)) {
+        return markBoxed(inspect(Number(obj)));
+    }
+    if (isBigInt(obj)) {
+        return markBoxed(inspect(bigIntValueOf.call(obj)));
+    }
+    if (isBoolean(obj)) {
+        return markBoxed(booleanValueOf.call(obj));
+    }
+    if (isString(obj)) {
+        return markBoxed(inspect(String(obj)));
+    }
+    if (!isDate(obj) && !isRegExp(obj)) {
+        var ys = arrObjKeys(obj, inspect);
+        var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
+        var protoTag = obj instanceof Object ? '' : 'null prototype';
+        var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';
+        var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
+        var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');
+        if (ys.length === 0) { return tag + '{}'; }
+        if (indent) {
+            return tag + '{' + indentedJoin(ys, indent) + '}';
+        }
+        return tag + '{ ' + ys.join(', ') + ' }';
+    }
+    return String(obj);
+};
 
-      return getArchiveLinkByIds;
-    }()
-    /**
-     * Checks if the file belongs to the parent's hierarchy.
-     *
-     * @param  {string|object}  child    The file which can either be an id or an object
-     * @param  {string|object}  parent   The parent target which can either be an id or an object
-     * @returns {boolean}                 Whether the file is a parent's child
-     */
+function wrapQuotes(s, defaultStyle, opts) {
+    var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'";
+    return quoteChar + s + quoteChar;
+}
 
-  }, {
-    key: "isChildOf",
-    value: function () {
-      var _isChildOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(child, parent) {
-        var _this2 = this;
+function quote(s) {
+    return String(s).replace(/"/g, '&quot;');
+}
 
-        var _ref7, childID, childDirID, childPath, _ref8, parentID, childDoc, currPath, targetsPath, newPath;
+function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
+function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
 
-        return _regenerator.default.wrap(function _callee20$(_context20) {
-          while (1) {
-            switch (_context20.prev = _context20.next) {
-              case 0:
-                _ref7 = typeof child === 'object' ? child : {
-                  _id: child
-                }, childID = _ref7._id, childDirID = _ref7.dirID, childPath = _ref7.path;
-                _ref8 = typeof parent === 'object' ? parent : {
-                  _id: parent
-                }, parentID = _ref8._id;
+// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
+function isSymbol(obj) {
+    if (hasShammedSymbols) {
+        return obj && typeof obj === 'object' && obj instanceof Symbol;
+    }
+    if (typeof obj === 'symbol') {
+        return true;
+    }
+    if (!obj || typeof obj !== 'object' || !symToString) {
+        return false;
+    }
+    try {
+        symToString.call(obj);
+        return true;
+    } catch (e) {}
+    return false;
+}
 
-                if (!(childID === parentID || childDirID === parentID)) {
-                  _context20.next = 4;
-                  break;
-                }
+function isBigInt(obj) {
+    if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
+        return false;
+    }
+    try {
+        bigIntValueOf.call(obj);
+        return true;
+    } catch (e) {}
+    return false;
+}
 
-                return _context20.abrupt("return", true);
+var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
+function has(obj, key) {
+    return hasOwn.call(obj, key);
+}
 
-              case 4:
-                if (childPath) {
-                  _context20.next = 10;
-                  break;
-                }
+function toStr(obj) {
+    return objectToString.call(obj);
+}
 
-                _context20.next = 7;
-                return this.statById(childID);
+function nameOf(f) {
+    if (f.name) { return f.name; }
+    var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/);
+    if (m) { return m[1]; }
+    return null;
+}
 
-              case 7:
-                childDoc = _context20.sent;
-                childPath = childDoc.data.path;
-                childDirID = childDoc.data.dirID;
+function indexOf(xs, x) {
+    if (xs.indexOf) { return xs.indexOf(x); }
+    for (var i = 0, l = xs.length; i < l; i++) {
+        if (xs[i] === x) { return i; }
+    }
+    return -1;
+}
 
-              case 10:
-                // Build hierarchy paths
-                currPath = childPath;
-                targetsPath = [childPath];
+function isMap(x) {
+    if (!mapSize || !x || typeof x !== 'object') {
+        return false;
+    }
+    try {
+        mapSize.call(x);
+        try {
+            setSize.call(x);
+        } catch (s) {
+            return true;
+        }
+        return x instanceof Map; // core-js workaround, pre-v2.5.0
+    } catch (e) {}
+    return false;
+}
 
-                while (currPath != '') {
-                  newPath = dirName(currPath);
+function isWeakMap(x) {
+    if (!weakMapHas || !x || typeof x !== 'object') {
+        return false;
+    }
+    try {
+        weakMapHas.call(x, weakMapHas);
+        try {
+            weakSetHas.call(x, weakSetHas);
+        } catch (s) {
+            return true;
+        }
+        return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
+    } catch (e) {}
+    return false;
+}
 
-                  if (newPath != '') {
-                    targetsPath.push(newPath);
-                  }
+function isWeakRef(x) {
+    if (!weakRefDeref || !x || typeof x !== 'object') {
+        return false;
+    }
+    try {
+        weakRefDeref.call(x);
+        return true;
+    } catch (e) {}
+    return false;
+}
 
-                  currPath = newPath;
-                }
+function isSet(x) {
+    if (!setSize || !x || typeof x !== 'object') {
+        return false;
+    }
+    try {
+        setSize.call(x);
+        try {
+            mapSize.call(x);
+        } catch (m) {
+            return true;
+        }
+        return x instanceof Set; // core-js workaround, pre-v2.5.0
+    } catch (e) {}
+    return false;
+}
 
-                targetsPath.reverse(); // Look for all hierarchy in parallel and return true as soon as a dir is the searched parent
+function isWeakSet(x) {
+    if (!weakSetHas || !x || typeof x !== 'object') {
+        return false;
+    }
+    try {
+        weakSetHas.call(x, weakSetHas);
+        try {
+            weakMapHas.call(x, weakMapHas);
+        } catch (s) {
+            return true;
+        }
+        return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
+    } catch (e) {}
+    return false;
+}
 
-                return _context20.abrupt("return", raceWithCondition(targetsPath.map(function (path) {
-                  return _this2.statByPath(path);
-                }), function (stat) {
-                  return stat.data._id == parentID;
-                }));
+function isElement(x) {
+    if (!x || typeof x !== 'object') { return false; }
+    if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
+        return true;
+    }
+    return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
+}
 
-              case 15:
-              case "end":
-                return _context20.stop();
-            }
-          }
-        }, _callee20, this);
-      }));
+function inspectString(str, opts) {
+    if (str.length > opts.maxStringLength) {
+        var remaining = str.length - opts.maxStringLength;
+        var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
+        return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;
+    }
+    // eslint-disable-next-line no-control-regex
+    var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte);
+    return wrapQuotes(s, 'single', opts);
+}
 
-      function isChildOf(_x26, _x27) {
-        return _isChildOf.apply(this, arguments);
-      }
+function lowbyte(c) {
+    var n = c.charCodeAt(0);
+    var x = {
+        8: 'b',
+        9: 't',
+        10: 'n',
+        12: 'f',
+        13: 'r'
+    }[n];
+    if (x) { return '\\' + x; }
+    return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();
+}
 
-      return isChildOf;
-    }()
-    /**
-     * statById - Fetches the metadata about a document. For folders, the results include the list of child files and folders.
-     *
-     * @param {string}      id                      ID of the document
-     * @param {object|null} options                 Pagination options
-     * @param {number|null} [options.page[limit]]   For pagination, the number of results to return.
-     * @param {number|null} [options.page[skip]]    For skip-based pagination, the number of referenced files to skip.
-     * @param {CouchDBViewCursor|null} [options.page[cursor]]  For cursor-based pagination, the index cursor.
-     *
-     * @returns {object} A promise resolving to an object containing "data" (the document metadata), "included" (the child documents) and "links" (pagination informations)
-     */
+function markBoxed(str) {
+    return 'Object(' + str + ')';
+}
 
-  }, {
-    key: "statById",
-    value: function () {
-      var _statById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(id) {
-        var options,
-            params,
-            path,
-            url,
-            resp,
-            _args21 = arguments;
-        return _regenerator.default.wrap(function _callee21$(_context21) {
-          while (1) {
-            switch (_context21.prev = _context21.next) {
-              case 0:
-                options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {};
-                params = (0, _pick.default)(options, ['page[limit]', 'page[skip]', 'page[cursor]']);
-                path = (0, _utils.uri)(_templateObject14(), id);
-                url = querystring.buildURL(path, params);
-                _context21.next = 6;
-                return this.stackClient.fetchJSON('GET', url);
+function weakCollectionOf(type) {
+    return type + ' { ? }';
+}
 
-              case 6:
-                resp = _context21.sent;
-                return _context21.abrupt("return", {
-                  data: normalizeFile(resp.data),
-                  included: resp.included && resp.included.map(function (f) {
-                    return normalizeFile(f);
-                  }),
-                  links: resp.links
-                });
+function collectionOf(type, size, entries, indent) {
+    var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');
+    return type + ' (' + size + ') {' + joinedEntries + '}';
+}
 
-              case 8:
-              case "end":
-                return _context21.stop();
-            }
-          }
-        }, _callee21, this);
-      }));
+function singleLineValues(xs) {
+    for (var i = 0; i < xs.length; i++) {
+        if (indexOf(xs[i], '\n') >= 0) {
+            return false;
+        }
+    }
+    return true;
+}
 
-      function statById(_x28) {
-        return _statById.apply(this, arguments);
-      }
+function getIndent(opts, depth) {
+    var baseIndent;
+    if (opts.indent === '\t') {
+        baseIndent = '\t';
+    } else if (typeof opts.indent === 'number' && opts.indent > 0) {
+        baseIndent = Array(opts.indent + 1).join(' ');
+    } else {
+        return null;
+    }
+    return {
+        base: baseIndent,
+        prev: Array(depth + 1).join(baseIndent)
+    };
+}
 
-      return statById;
-    }()
-  }, {
-    key: "statByPath",
-    value: function () {
-      var _statByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22(path) {
-        var resp;
-        return _regenerator.default.wrap(function _callee22$(_context22) {
-          while (1) {
-            switch (_context22.prev = _context22.next) {
-              case 0:
-                _context22.next = 2;
-                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject15(), path));
+function indentedJoin(xs, indent) {
+    if (xs.length === 0) { return ''; }
+    var lineJoiner = '\n' + indent.prev + indent.base;
+    return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev;
+}
 
-              case 2:
-                resp = _context22.sent;
-                return _context22.abrupt("return", {
-                  data: normalizeFile(resp.data),
-                  included: resp.included && resp.included.map(function (f) {
-                    return normalizeFile(f);
-                  })
-                });
+function arrObjKeys(obj, inspect) {
+    var isArr = isArray(obj);
+    var xs = [];
+    if (isArr) {
+        xs.length = obj.length;
+        for (var i = 0; i < obj.length; i++) {
+            xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
+        }
+    }
+    var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
+    var symMap;
+    if (hasShammedSymbols) {
+        symMap = {};
+        for (var k = 0; k < syms.length; k++) {
+            symMap['$' + syms[k]] = syms[k];
+        }
+    }
 
-              case 4:
-              case "end":
-                return _context22.stop();
+    for (var key in obj) { // eslint-disable-line no-restricted-syntax
+        if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
+        if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
+        if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
+            // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
+            continue; // eslint-disable-line no-restricted-syntax, no-continue
+        } else if ((/[^\w$]/).test(key)) {
+            xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
+        } else {
+            xs.push(key + ': ' + inspect(obj[key], obj));
+        }
+    }
+    if (typeof gOPS === 'function') {
+        for (var j = 0; j < syms.length; j++) {
+            if (isEnumerable.call(obj, syms[j])) {
+                xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
             }
-          }
-        }, _callee22, this);
-      }));
+        }
+    }
+    return xs;
+}
 
-      function statByPath(_x29) {
-        return _statByPath.apply(this, arguments);
-      }
 
-      return statByPath;
-    }()
-    /**
-     * Create directory
-     *
-     * @private
-     * @param  {DirectoryAttributes} attributes - Attributes of the directory
-     * @returns {Promise}
-     * @throws {Error} - explaining reason why creation failed
-     */
+/***/ }),
+/* 653 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  }, {
-    key: "createDirectory",
-    value: function () {
-      var _createDirectory = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() {
-        var attributes,
-            name,
-            dirId,
-            lastModifiedDate,
-            safeName,
-            lastModified,
-            resp,
-            _args23 = arguments;
-        return _regenerator.default.wrap(function _callee23$(_context23) {
-          while (1) {
-            switch (_context23.prev = _context23.next) {
-              case 0:
-                attributes = _args23.length > 0 && _args23[0] !== undefined ? _args23[0] : {};
-                name = attributes.name, dirId = attributes.dirId, lastModifiedDate = attributes.lastModifiedDate;
-                safeName = sanitizeAndValidateFileName(name);
-                lastModified = lastModifiedDate && (typeof lastModifiedDate === 'string' ? new Date(lastModifiedDate) : lastModifiedDate);
-                _context23.next = 6;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject16(), dirId, safeName), undefined, {
-                  headers: {
-                    Date: lastModified ? lastModified.toGMTString() : ''
-                  }
-                });
+module.exports = __webpack_require__(64).inspect;
 
-              case 6:
-                resp = _context23.sent;
-                return _context23.abrupt("return", {
-                  data: normalizeFile(resp.data)
-                });
 
-              case 8:
-              case "end":
-                return _context23.stop();
-            }
-          }
-        }, _callee23, this);
-      }));
+/***/ }),
+/* 654 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function createDirectory() {
-        return _createDirectory.apply(this, arguments);
-      }
+"use strict";
 
-      return createDirectory;
-    }()
-  }, {
-    key: "ensureDirectoryExists",
-    value: function () {
-      var _ensureDirectoryExists = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24(path) {
-        var resp;
-        return _regenerator.default.wrap(function _callee24$(_context24) {
-          while (1) {
-            switch (_context24.prev = _context24.next) {
-              case 0:
-                if (this.specialDirectories[path]) {
-                  _context24.next = 5;
-                  break;
-                }
 
-                _context24.next = 3;
-                return this.createDirectoryByPath(path);
+var formats = __webpack_require__(655);
 
-              case 3:
-                resp = _context24.sent;
-                this.specialDirectories[path] = resp.data._id;
+var has = Object.prototype.hasOwnProperty;
+var isArray = Array.isArray;
 
-              case 5:
-                return _context24.abrupt("return", this.specialDirectories[path]);
+var hexTable = (function () {
+    var array = [];
+    for (var i = 0; i < 256; ++i) {
+        array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
+    }
 
-              case 6:
-              case "end":
-                return _context24.stop();
-            }
-          }
-        }, _callee24, this);
-      }));
+    return array;
+}());
 
-      function ensureDirectoryExists(_x30) {
-        return _ensureDirectoryExists.apply(this, arguments);
-      }
+var compactQueue = function compactQueue(queue) {
+    while (queue.length > 1) {
+        var item = queue.pop();
+        var obj = item.obj[item.prop];
 
-      return ensureDirectoryExists;
-    }()
-  }, {
-    key: "getDirectoryOrCreate",
-    value: function () {
-      var _getDirectoryOrCreate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25(name, parentDirectory) {
-        var safeName, path, stat, parsedError, errors;
-        return _regenerator.default.wrap(function _callee25$(_context25) {
-          while (1) {
-            switch (_context25.prev = _context25.next) {
-              case 0:
-                if (!(parentDirectory && !parentDirectory.attributes)) {
-                  _context25.next = 2;
-                  break;
+        if (isArray(obj)) {
+            var compacted = [];
+
+            for (var j = 0; j < obj.length; ++j) {
+                if (typeof obj[j] !== 'undefined') {
+                    compacted.push(obj[j]);
                 }
+            }
 
-                throw new Error('Malformed parent directory');
+            item.obj[item.prop] = compacted;
+        }
+    }
+};
 
-              case 2:
-                safeName = sanitizeFileName(name);
-                path = "".concat(parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path, "/").concat(safeName);
-                _context25.prev = 4;
-                _context25.next = 7;
-                return this.statByPath(path || '/');
+var arrayToObject = function arrayToObject(source, options) {
+    var obj = options && options.plainObjects ? Object.create(null) : {};
+    for (var i = 0; i < source.length; ++i) {
+        if (typeof source[i] !== 'undefined') {
+            obj[i] = source[i];
+        }
+    }
+
+    return obj;
+};
+
+var merge = function merge(target, source, options) {
+    /* eslint no-param-reassign: 0 */
+    if (!source) {
+        return target;
+    }
+
+    if (typeof source !== 'object') {
+        if (isArray(target)) {
+            target.push(source);
+        } else if (target && typeof target === 'object') {
+            if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
+                target[source] = true;
+            }
+        } else {
+            return [target, source];
+        }
 
-              case 7:
-                stat = _context25.sent;
-                return _context25.abrupt("return", stat);
+        return target;
+    }
 
-              case 11:
-                _context25.prev = 11;
-                _context25.t0 = _context25["catch"](4);
-                parsedError = JSON.parse(_context25.t0.message);
-                errors = parsedError.errors;
+    if (!target || typeof target !== 'object') {
+        return [target].concat(source);
+    }
 
-                if (!(errors && errors.length && errors[0].status === '404')) {
-                  _context25.next = 17;
-                  break;
-                }
+    var mergeTarget = target;
+    if (isArray(target) && !isArray(source)) {
+        mergeTarget = arrayToObject(target, options);
+    }
 
-                return _context25.abrupt("return", this.createDirectory({
-                  name: safeName,
-                  dirId: parentDirectory && parentDirectory._id
-                }));
+    if (isArray(target) && isArray(source)) {
+        source.forEach(function (item, i) {
+            if (has.call(target, i)) {
+                var targetItem = target[i];
+                if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
+                    target[i] = merge(targetItem, item, options);
+                } else {
+                    target.push(item);
+                }
+            } else {
+                target[i] = item;
+            }
+        });
+        return target;
+    }
 
-              case 17:
-                throw errors;
+    return Object.keys(source).reduce(function (acc, key) {
+        var value = source[key];
 
-              case 18:
-              case "end":
-                return _context25.stop();
-            }
-          }
-        }, _callee25, this, [[4, 11]]);
-      }));
+        if (has.call(acc, key)) {
+            acc[key] = merge(acc[key], value, options);
+        } else {
+            acc[key] = value;
+        }
+        return acc;
+    }, mergeTarget);
+};
 
-      function getDirectoryOrCreate(_x31, _x32) {
-        return _getDirectoryOrCreate.apply(this, arguments);
-      }
+var assign = function assignSingleSource(target, source) {
+    return Object.keys(source).reduce(function (acc, key) {
+        acc[key] = source[key];
+        return acc;
+    }, target);
+};
 
-      return getDirectoryOrCreate;
-    }()
-    /**
-     * async createDirectoryByPath - Creates one or more folders until the given path exists
-     *
-     * @param  {string} path - Path of the created directory
-     * @returns {object} The document corresponding to the last segment of the path
-     */
+var decode = function (str, decoder, charset) {
+    var strWithoutPlus = str.replace(/\+/g, ' ');
+    if (charset === 'iso-8859-1') {
+        // unescape never throws, no try...catch needed:
+        return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
+    }
+    // utf-8
+    try {
+        return decodeURIComponent(strWithoutPlus);
+    } catch (e) {
+        return strWithoutPlus;
+    }
+};
 
-  }, {
-    key: "createDirectoryByPath",
-    value: function () {
-      var _createDirectoryByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26(path) {
-        var parts, root, parentDir, _iterator2, _step2, part;
+var encode = function encode(str, defaultEncoder, charset, kind, format) {
+    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
+    // It has been adapted here for stricter adherence to RFC 3986
+    if (str.length === 0) {
+        return str;
+    }
 
-        return _regenerator.default.wrap(function _callee26$(_context26) {
-          while (1) {
-            switch (_context26.prev = _context26.next) {
-              case 0:
-                parts = path.split('/').filter(function (part) {
-                  return part !== '';
-                });
-                _context26.next = 3;
-                return this.statById(ROOT_DIR_ID);
+    var string = str;
+    if (typeof str === 'symbol') {
+        string = Symbol.prototype.toString.call(str);
+    } else if (typeof str !== 'string') {
+        string = String(str);
+    }
 
-              case 3:
-                root = _context26.sent;
+    if (charset === 'iso-8859-1') {
+        return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
+            return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
+        });
+    }
 
-                if (parts.length) {
-                  _context26.next = 6;
-                  break;
-                }
+    var out = '';
+    for (var i = 0; i < string.length; ++i) {
+        var c = string.charCodeAt(i);
 
-                return _context26.abrupt("return", root);
+        if (
+            c === 0x2D // -
+            || c === 0x2E // .
+            || c === 0x5F // _
+            || c === 0x7E // ~
+            || (c >= 0x30 && c <= 0x39) // 0-9
+            || (c >= 0x41 && c <= 0x5A) // a-z
+            || (c >= 0x61 && c <= 0x7A) // A-Z
+            || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
+        ) {
+            out += string.charAt(i);
+            continue;
+        }
 
-              case 6:
-                parentDir = root;
-                _iterator2 = _createForOfIteratorHelper(parts);
-                _context26.prev = 8;
+        if (c < 0x80) {
+            out = out + hexTable[c];
+            continue;
+        }
 
-                _iterator2.s();
+        if (c < 0x800) {
+            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
+            continue;
+        }
 
-              case 10:
-                if ((_step2 = _iterator2.n()).done) {
-                  _context26.next = 17;
-                  break;
-                }
+        if (c < 0xD800 || c >= 0xE000) {
+            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
+            continue;
+        }
 
-                part = _step2.value;
-                _context26.next = 14;
-                return this.getDirectoryOrCreate(part, parentDir.data);
+        i += 1;
+        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
+        out += hexTable[0xF0 | (c >> 18)]
+            + hexTable[0x80 | ((c >> 12) & 0x3F)]
+            + hexTable[0x80 | ((c >> 6) & 0x3F)]
+            + hexTable[0x80 | (c & 0x3F)];
+    }
 
-              case 14:
-                parentDir = _context26.sent;
+    return out;
+};
 
-              case 15:
-                _context26.next = 10;
-                break;
+var compact = function compact(value) {
+    var queue = [{ obj: { o: value }, prop: 'o' }];
+    var refs = [];
 
-              case 17:
-                _context26.next = 22;
-                break;
+    for (var i = 0; i < queue.length; ++i) {
+        var item = queue[i];
+        var obj = item.obj[item.prop];
 
-              case 19:
-                _context26.prev = 19;
-                _context26.t0 = _context26["catch"](8);
+        var keys = Object.keys(obj);
+        for (var j = 0; j < keys.length; ++j) {
+            var key = keys[j];
+            var val = obj[key];
+            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
+                queue.push({ obj: obj, prop: key });
+                refs.push(val);
+            }
+        }
+    }
 
-                _iterator2.e(_context26.t0);
+    compactQueue(queue);
 
-              case 22:
-                _context26.prev = 22;
+    return value;
+};
 
-                _iterator2.f();
+var isRegExp = function isRegExp(obj) {
+    return Object.prototype.toString.call(obj) === '[object RegExp]';
+};
 
-                return _context26.finish(22);
+var isBuffer = function isBuffer(obj) {
+    if (!obj || typeof obj !== 'object') {
+        return false;
+    }
 
-              case 25:
-                return _context26.abrupt("return", parentDir);
+    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
+};
 
-              case 26:
-              case "end":
-                return _context26.stop();
-            }
-          }
-        }, _callee26, this, [[8, 19, 22, 25]]);
-      }));
+var combine = function combine(a, b) {
+    return [].concat(a, b);
+};
 
-      function createDirectoryByPath(_x33) {
-        return _createDirectoryByPath.apply(this, arguments);
-      }
+var maybeMap = function maybeMap(val, fn) {
+    if (isArray(val)) {
+        var mapped = [];
+        for (var i = 0; i < val.length; i += 1) {
+            mapped.push(fn(val[i]));
+        }
+        return mapped;
+    }
+    return fn(val);
+};
 
-      return createDirectoryByPath;
-    }()
-    /**
-     *
-     * async updateAttributes - Updates a file / folder's attributes except
-     * the metadata attribute. If you want to update its metadata attribute,
-     * then use `updateFileMetadataAttribute` since `metadata` is a specific
-     * doctype.
-     *
-     * For instance, if you want to update the name of a file, you can pass
-     * attributes = { name: 'newName'}
-     *
-     * You can see the attributes for both Folder and File (as they share the
-     * same doctype they have a few in common) here :
-     * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#iocozyfiles
-     *
-     * @private You shoud use update() directly.
-     * @param  {string} id         File id
-     * @param  {object} attributes New file attributes
-     * @returns {object}            Updated document
-     * @throws {Error} - explaining reason why update failed
-     */
+module.exports = {
+    arrayToObject: arrayToObject,
+    assign: assign,
+    combine: combine,
+    compact: compact,
+    decode: decode,
+    encode: encode,
+    isBuffer: isBuffer,
+    isRegExp: isRegExp,
+    maybeMap: maybeMap,
+    merge: merge
+};
 
-  }, {
-    key: "updateAttributes",
-    value: function () {
-      var _updateAttributes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27(id, attributes) {
-        var sanitizedAttributes, resp;
-        return _regenerator.default.wrap(function _callee27$(_context27) {
-          while (1) {
-            switch (_context27.prev = _context27.next) {
-              case 0:
-                sanitizedAttributes = _objectSpread({}, attributes);
 
-                if (attributes.name) {
-                  sanitizedAttributes.name = sanitizeAndValidateFileName(attributes.name);
-                }
+/***/ }),
+/* 655 */
+/***/ ((module) => {
 
-                _context27.next = 4;
-                return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject17(), id), {
-                  data: {
-                    type: 'io.cozy.files',
-                    id: id,
-                    attributes: sanitizedAttributes
-                  }
-                });
+"use strict";
 
-              case 4:
-                resp = _context27.sent;
-                return _context27.abrupt("return", {
-                  data: normalizeFile(resp.data)
-                });
 
-              case 6:
-              case "end":
-                return _context27.stop();
-            }
-          }
-        }, _callee27, this);
-      }));
+var replace = String.prototype.replace;
+var percentTwenties = /%20/g;
 
-      function updateAttributes(_x34, _x35) {
-        return _updateAttributes.apply(this, arguments);
-      }
+var Format = {
+    RFC1738: 'RFC1738',
+    RFC3986: 'RFC3986'
+};
 
-      return updateAttributes;
-    }()
-  }, {
-    key: "updateFileMetadata",
-    value: function () {
-      var _updateFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28(id, attributes) {
-        return _regenerator.default.wrap(function _callee28$(_context28) {
-          while (1) {
-            switch (_context28.prev = _context28.next) {
-              case 0:
-                console.warn('CozyClient FileCollection updateFileMetadata method is deprecated. Use updateAttributes instead');
-                return _context28.abrupt("return", this.updateAttributes(id, attributes));
+module.exports = {
+    'default': Format.RFC3986,
+    formatters: {
+        RFC1738: function (value) {
+            return replace.call(value, percentTwenties, '+');
+        },
+        RFC3986: function (value) {
+            return String(value);
+        }
+    },
+    RFC1738: Format.RFC1738,
+    RFC3986: Format.RFC3986
+};
 
-              case 2:
-              case "end":
-                return _context28.stop();
-            }
-          }
-        }, _callee28, this);
-      }));
 
-      function updateFileMetadata(_x36, _x37) {
-        return _updateFileMetadata.apply(this, arguments);
-      }
+/***/ }),
+/* 656 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return updateFileMetadata;
-    }()
-    /**
-     * Send a metadata object that can be associated to a file uploaded after that,
-     * via the MetadataID query parameter.
-     * See https://github.com/cozy/cozy-stack/blob/master/docs/files.md#post-filesuploadmetadata
-     *
-     * @param {object} attributes The file's metadata
-     * @returns {object}          The Metadata object
-     */
+"use strict";
 
-  }, {
-    key: "createFileMetadata",
-    value: function () {
-      var _createFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee29(attributes) {
-        var resp;
-        return _regenerator.default.wrap(function _callee29$(_context29) {
-          while (1) {
-            switch (_context29.prev = _context29.next) {
-              case 0:
-                _context29.next = 2;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject18()), {
-                  data: {
-                    type: 'io.cozy.files.metadata',
-                    attributes: attributes
-                  }
-                });
 
-              case 2:
-                resp = _context29.sent;
-                return _context29.abrupt("return", {
-                  data: resp.data
-                });
+var utils = __webpack_require__(654);
 
-              case 4:
-              case "end":
-                return _context29.stop();
-            }
-          }
-        }, _callee29, this);
-      }));
+var has = Object.prototype.hasOwnProperty;
+var isArray = Array.isArray;
 
-      function createFileMetadata(_x38) {
-        return _createFileMetadata.apply(this, arguments);
-      }
+var defaults = {
+    allowDots: false,
+    allowPrototypes: false,
+    allowSparse: false,
+    arrayLimit: 20,
+    charset: 'utf-8',
+    charsetSentinel: false,
+    comma: false,
+    decoder: utils.decode,
+    delimiter: '&',
+    depth: 5,
+    ignoreQueryPrefix: false,
+    interpretNumericEntities: false,
+    parameterLimit: 1000,
+    parseArrays: true,
+    plainObjects: false,
+    strictNullHandling: false
+};
 
-      return createFileMetadata;
-    }()
-    /**
-     *
-     * Updates the metadata attribute of a io.cozy.files
-     * Creates a new version of the file without having
-     * to upload again the file's content
-     *
-     * To see available content of the metadata attribute
-     * see : https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files_metadata/
-     *
-     * @param {string} id File id
-     * @param {object} metadata io.cozy.files.metadata attributes
-     * @returns {object} io.cozy.files updated
-     */
+var interpretNumericEntities = function (str) {
+    return str.replace(/&#(\d+);/g, function ($0, numberStr) {
+        return String.fromCharCode(parseInt(numberStr, 10));
+    });
+};
 
-  }, {
-    key: "updateMetadataAttribute",
-    value: function () {
-      var _updateMetadataAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee30(id, metadata) {
-        var resp;
-        return _regenerator.default.wrap(function _callee30$(_context30) {
-          while (1) {
-            switch (_context30.prev = _context30.next) {
-              case 0:
-                _context30.next = 2;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject19(), id), {
-                  data: {
-                    type: 'io.cozy.files.metadata',
-                    attributes: metadata
-                  }
-                });
+var parseArrayValue = function (val, options) {
+    if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
+        return val.split(',');
+    }
 
-              case 2:
-                resp = _context30.sent;
-                return _context30.abrupt("return", {
-                  data: resp.data
-                });
+    return val;
+};
 
-              case 4:
-              case "end":
-                return _context30.stop();
-            }
-          }
-        }, _callee30, this);
-      }));
+// This is what browsers will submit when the ✓ character occurs in an
+// application/x-www-form-urlencoded body and the encoding of the page containing
+// the form is iso-8859-1, or when the submitted form has an accept-charset
+// attribute of iso-8859-1. Presumably also with other charsets that do not contain
+// the ✓ character, such as us-ascii.
+var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')
 
-      function updateMetadataAttribute(_x39, _x40) {
-        return _updateMetadataAttribute.apply(this, arguments);
-      }
+// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
+var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
 
-      return updateMetadataAttribute;
-    }()
-    /**
-     * Get the file mime-type based on its name
-     *
-     * @param {string} name - The file name
-     * @returns {string} the inferred file mime-type
-     */
+var parseValues = function parseQueryStringValues(str, options) {
+    var obj = {};
+    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
+    var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
+    var parts = cleanStr.split(options.delimiter, limit);
+    var skipIndex = -1; // Keep track of where the utf8 sentinel was found
+    var i;
 
-  }, {
-    key: "getFileTypeFromName",
-    value: function getFileTypeFromName(name) {
-      return _lite.default.getType(name) || CONTENT_TYPE_OCTET_STREAM;
+    var charset = options.charset;
+    if (options.charsetSentinel) {
+        for (i = 0; i < parts.length; ++i) {
+            if (parts[i].indexOf('utf8=') === 0) {
+                if (parts[i] === charsetSentinel) {
+                    charset = 'utf-8';
+                } else if (parts[i] === isoSentinel) {
+                    charset = 'iso-8859-1';
+                }
+                skipIndex = i;
+                i = parts.length; // The eslint settings do not allow break;
+            }
+        }
     }
-    /**
-     *
-     * This method should not be called directly to upload a file.
-     * You should use `createFile`
-     *
-     * @param {File|Blob|Stream|string|ArrayBuffer} dataArg file to be uploaded
-     * @param {string} path Uri to call the stack from. Something like
-     * `/files/${dirId}?Name=${name}&Type=file&Executable=${executable}&MetadataID=${metadataId}`
-     * @param {object} options Additional headers
-     * @param {string} method POST / PUT / PATCH
-     */
 
-  }, {
-    key: "doUpload",
-    value: function () {
-      var _doUpload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee31(dataArg, path, options) {
-        var method,
-            correctPath,
-            data,
-            isBuffer,
-            isFile,
-            isBlob,
-            isStream,
-            isString,
-            _ref9,
-            contentType,
-            contentLength,
-            checksum,
-            lastModifiedDate,
-            ifMatch,
-            sPath,
-            params,
-            name,
-            headers,
-            date,
-            resp,
-            _args31 = arguments;
+    for (i = 0; i < parts.length; ++i) {
+        if (i === skipIndex) {
+            continue;
+        }
+        var part = parts[i];
 
-        return _regenerator.default.wrap(function _callee31$(_context31) {
-          while (1) {
-            switch (_context31.prev = _context31.next) {
-              case 0:
-                method = _args31.length > 3 && _args31[3] !== undefined ? _args31[3] : 'POST';
-                correctPath = path;
-                data = dataArg;
+        var bracketEqualsPos = part.indexOf(']=');
+        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
 
-                if (data) {
-                  _context31.next = 5;
-                  break;
+        var key, val;
+        if (pos === -1) {
+            key = options.decoder(part, defaults.decoder, charset, 'key');
+            val = options.strictNullHandling ? null : '';
+        } else {
+            key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
+            val = utils.maybeMap(
+                parseArrayValue(part.slice(pos + 1), options),
+                function (encodedVal) {
+                    return options.decoder(encodedVal, defaults.decoder, charset, 'value');
                 }
+            );
+        }
 
-                throw new Error('missing data argument');
+        if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
+            val = interpretNumericEntities(val);
+        }
 
-              case 5:
-                // transform any ArrayBufferView to ArrayBuffer
-                if (data.buffer && data.buffer instanceof ArrayBuffer) {
-                  data = data.buffer;
-                }
+        if (part.indexOf('[]=') > -1) {
+            val = isArray(val) ? [val] : val;
+        }
 
-                isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer;
-                isFile = typeof File !== 'undefined' && data instanceof File;
-                isBlob = typeof Blob !== 'undefined' && data instanceof Blob;
-                isStream = data.readable === true && typeof data.pipe === 'function';
-                isString = typeof data === 'string';
+        if (has.call(obj, key)) {
+            obj[key] = utils.combine(obj[key], val);
+        } else {
+            obj[key] = val;
+        }
+    }
 
-                if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) {
-                  _context31.next = 13;
-                  break;
-                }
+    return obj;
+};
 
-                throw new Error('invalid data type');
+var parseObject = function (chain, val, options, valuesParsed) {
+    var leaf = valuesParsed ? val : parseArrayValue(val, options);
 
-              case 13:
-                _ref9 = options || {}, contentType = _ref9.contentType, contentLength = _ref9.contentLength, checksum = _ref9.checksum, lastModifiedDate = _ref9.lastModifiedDate, ifMatch = _ref9.ifMatch;
+    for (var i = chain.length - 1; i >= 0; --i) {
+        var obj;
+        var root = chain[i];
 
-                if (!contentType) {
-                  if (typeof data === 'string') {
-                    contentType = 'text/plain';
-                  } else {
-                    if (data.type) {
-                      // The type is specified in the file object
-                      contentType = data.type;
-                    } else {
-                      // Extract the name from the correctPath and infer the type
-                      sPath = correctPath.split('?');
-                      params = sPath.length > 1 ? sPath[1] : '';
-                      name = new URLSearchParams(params).get('Name');
-                      contentType = this.getFileTypeFromName(name.toLowerCase());
-                    }
-                  }
-                }
+        if (root === '[]' && options.parseArrays) {
+            obj = [].concat(leaf);
+        } else {
+            obj = options.plainObjects ? Object.create(null) : {};
+            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
+            var index = parseInt(cleanRoot, 10);
+            if (!options.parseArrays && cleanRoot === '') {
+                obj = { 0: leaf };
+            } else if (
+                !isNaN(index)
+                && root !== cleanRoot
+                && String(index) === cleanRoot
+                && index >= 0
+                && (options.parseArrays && index <= options.arrayLimit)
+            ) {
+                obj = [];
+                obj[index] = leaf;
+            } else {
+                obj[cleanRoot] = leaf;
+            }
+        }
 
-                lastModifiedDate = lastModifiedDate || data.lastModified;
+        leaf = obj;
+    }
 
-                if (lastModifiedDate) {
-                  lastModifiedDate = new Date(lastModifiedDate);
-                }
+    return leaf;
+};
 
-                headers = {
-                  'Content-Type': contentType
-                };
-                if (contentLength) headers['Content-Length'] = String(contentLength);
-                if (checksum) headers['Content-MD5'] = checksum;
+var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
+    if (!givenKey) {
+        return;
+    }
 
-                if (lastModifiedDate) {
-                  date = lastModifiedDate.toISOString();
-                  correctPath = "".concat(correctPath, "&UpdatedAt=").concat(date, "&CreatedAt=").concat(date);
-                }
+    // Transform dot notation to bracket notation
+    var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
 
-                if (ifMatch) headers['If-Match'] = ifMatch;
-                _context31.next = 24;
-                return this.stackClient.fetchJSON(method, correctPath, data, {
-                  headers: headers,
-                  onUploadProgress: options.onUploadProgress
-                });
+    // The regex chunks
 
-              case 24:
-                resp = _context31.sent;
-                return _context31.abrupt("return", {
-                  data: normalizeFile(resp.data)
-                });
+    var brackets = /(\[[^[\]]*])/;
+    var child = /(\[[^[\]]*])/g;
 
-              case 26:
-              case "end":
-                return _context31.stop();
-            }
-          }
-        }, _callee31, this);
-      }));
+    // Get the parent
 
-      function doUpload(_x41, _x42, _x43) {
-        return _doUpload.apply(this, arguments);
-      }
+    var segment = options.depth > 0 && brackets.exec(key);
+    var parent = segment ? key.slice(0, segment.index) : key;
 
-      return doUpload;
-    }()
-    /**
-     * async findNotSynchronizedDirectories - Returns the list of directories not synchronized on the given OAuth client (mainly Cozy Desktop clients) — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#get-datatypedoc-idrelationshipsnot_synchronizing
-     *
-     * @param  {OAuthClient}  oauthClient           A JSON representing an OAuth client, with at least a `_type` and `_id` field.
-     * @param  {object|null}  options               Pagination options
-     * @param  {number|null}  options.skip          For skip-based pagination, the number of referenced files to skip.
-     * @param  {number|null}  options.limit         For pagination, the number of results to return.
-     * @param  {CouchDBViewCursor|null}  options.cursor        For cursor-based pagination, the index cursor.
-     * @param  {boolean}      options.includeFiles  Include the whole file documents in the results list
-     *
-     * @returns {Array<object|IOCozyFolder>}    The JSON API conformant response.
-     */
+    // Stash the parent if it exists
 
-  }, {
-    key: "findNotSynchronizedDirectories",
-    value: function () {
-      var _findNotSynchronizedDirectories = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee32(oauthClient) {
-        var _ref10,
-            _ref10$skip,
-            skip,
-            limit,
-            cursor,
-            _ref10$includeFiles,
-            includeFiles,
-            params,
-            path,
-            url,
-            resp,
-            _args32 = arguments;
+    var keys = [];
+    if (parent) {
+        // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
+        if (!options.plainObjects && has.call(Object.prototype, parent)) {
+            if (!options.allowPrototypes) {
+                return;
+            }
+        }
 
-        return _regenerator.default.wrap(function _callee32$(_context32) {
-          while (1) {
-            switch (_context32.prev = _context32.next) {
-              case 0:
-                _ref10 = _args32.length > 1 && _args32[1] !== undefined ? _args32[1] : {}, _ref10$skip = _ref10.skip, skip = _ref10$skip === void 0 ? 0 : _ref10$skip, limit = _ref10.limit, cursor = _ref10.cursor, _ref10$includeFiles = _ref10.includeFiles, includeFiles = _ref10$includeFiles === void 0 ? false : _ref10$includeFiles;
-                params = {
-                  include: includeFiles ? 'files' : undefined,
-                  'page[limit]': limit,
-                  'page[cursor]': cursor,
-                  sort: 'id'
-                };
-                path = (0, _utils.uri)(_templateObject20(), oauthClient._type, oauthClient._id);
-                url = querystring.buildURL(path, params);
-                _context32.next = 6;
-                return this.stackClient.fetchJSON('GET', url);
+        keys.push(parent);
+    }
 
-              case 6:
-                resp = _context32.sent;
-                return _context32.abrupt("return", {
-                  data: resp.data.map(function (f) {
-                    return normalizeFile(f);
-                  }),
-                  included: resp.included ? resp.included.map(function (f) {
-                    return normalizeFile(f);
-                  }) : [],
-                  next: (0, _has.default)(resp, 'links.next'),
-                  meta: resp.meta,
-                  skip: skip
-                });
+    // Loop through children appending to the array until we hit depth
 
-              case 8:
-              case "end":
-                return _context32.stop();
+    var i = 0;
+    while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
+        i += 1;
+        if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
+            if (!options.allowPrototypes) {
+                return;
             }
-          }
-        }, _callee32, this);
-      }));
+        }
+        keys.push(segment[1]);
+    }
 
-      function findNotSynchronizedDirectories(_x44) {
-        return _findNotSynchronizedDirectories.apply(this, arguments);
-      }
+    // If there's a remainder, just add whatever is left
 
-      return findNotSynchronizedDirectories;
-    }()
-    /**
-     *  Add directory synchronization exclusions to an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#post-datatypedoc-idrelationshipsnot_synchronizing
-     *
-     *  For example, to exclude directory `/Photos` from `My Computer`'s desktop synchronization:
-     * ```
-     * addNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}])
-     * ```
-     *
-     * @param  {OAuthClient} oauthClient  A JSON representing the OAuth client
-     * @param  {Array}  directories       An array of JSON documents having a `_type` and `_id` fields and representing directories.
-     *
-     * Returns 204 No Content
-     */
+    if (segment) {
+        keys.push('[' + key.slice(segment.index) + ']');
+    }
 
-  }, {
-    key: "addNotSynchronizedDirectories",
-    value: function addNotSynchronizedDirectories(oauthClient, directories) {
-      var refs = directories.map(function (d) {
-        return {
-          id: d._id,
-          type: d._type
-        };
-      });
-      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject21(), oauthClient._type, oauthClient._id), {
-        data: refs
-      });
+    return parseObject(keys, val, options, valuesParsed);
+};
+
+var normalizeParseOptions = function normalizeParseOptions(opts) {
+    if (!opts) {
+        return defaults;
     }
-    /**
-     *  Remove directory synchronization exclusions from an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#delete-datatypedoc-idrelationshipsnot_synchronizing
-     *
-     *  For example, to re-include directory `/Photos` into `My Computer`'s desktop synchronization:
-     * ```
-     *  removeNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}])
-     * ```
-     *
-     * @param  {OAuthClient} oauthClient  A JSON representing the OAuth client
-     * @param  {Array}  directories       An array of JSON documents having a `_type` and `_id` field and representing directories.
-     *
-     * Returns 204 No Content
-     */
 
-  }, {
-    key: "removeNotSynchronizedDirectories",
-    value: function removeNotSynchronizedDirectories(oauthClient, directories) {
-      var refs = directories.map(function (d) {
-        return {
-          id: d._id,
-          type: d._type
-        };
-      });
-      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject22(), oauthClient._type, oauthClient._id), {
-        data: refs
-      });
+    if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
+        throw new TypeError('Decoder has to be a function.');
     }
-    /**
-     * Use cozy-stack's _changes API for io.cozy.files
-     * Design docs are filtered by default, thus documents are retrieved in the
-     * response (includeDocs is set to true in the parameters of _changes).
-     * Deleted and trashed documents can be filtered on demand and files' paths
-     * can be requested as well.
-     *
-     * Since deleted and trashed documents are skipped by cozy-stack rather than
-     * CouchDB, when either option is set to true, the response can contain less
-     * documents than the defined limit. Thus one should rely solely on the
-     * `pending` result attribute to determine if more documents can be fetched or
-     * not.
-     *
-     * You should use fetchChangesRaw to call CouchDB's _changes API.
-     *
-     * @typedef {object} CouchOptions
-     * @property {string} since - Bookmark telling CouchDB from which point in time should changes be returned
-     * @property {number} limit - The maximum number of returned documents for one call
-     * @property {boolean} includeDocs - Whether or not complete documents should be returned
-     *
-     * @typedef {object} FetchChangesOptions
-     * @property {Array<string>} fields - The list of fields that should be returned for each document
-     * @property {boolean} includeFilePath - Whether to include the path of file changes (needs includeDocs to be true)
-     * @property {boolean} skipDeleted - Whether to skip changes for deleted documents
-     * @property {boolean} skipTrashed - Whether to skip changes for trashed documents (needs includeDocs to be true)
-     *
-     * @param  {CouchOptions} couchOptions - Couch options for changes
-     * @param  {FetchChangesOptions} options - Further options on the returned documents. By default, it is set to
-     *                                        { includeFilePath: false, skipDeleted: false, skipTrashed: false }
-     *
-     * @typedef {object} FetchChangesReturnValue
-     * @property {string} newLastSeq
-     * @property {boolean} pending
-     * @property {Array<object>} documents
-     * @returns {FetchChangesReturnValue}
-     */
 
-  }, {
-    key: "fetchChanges",
-    value: function () {
-      var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee33() {
-        var couchOptions,
-            options,
-            opts,
-            params,
-            path,
-            url,
-            _yield$this$stackClie,
-            newLastSeq,
-            pending,
-            results,
-            _args33 = arguments;
+    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
+        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
+    }
+    var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
 
-        return _regenerator.default.wrap(function _callee33$(_context33) {
-          while (1) {
-            switch (_context33.prev = _context33.next) {
-              case 0:
-                couchOptions = _args33.length > 0 && _args33[0] !== undefined ? _args33[0] : {};
-                options = _args33.length > 1 && _args33[1] !== undefined ? _args33[1] : {};
-                opts = {};
+    return {
+        allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
+        allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
+        allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
+        arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
+        charset: charset,
+        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
+        comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
+        decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
+        delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
+        // eslint-disable-next-line no-implicit-coercion, no-extra-parens
+        depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
+        ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
+        interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
+        parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
+        parseArrays: opts.parseArrays !== false,
+        plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
+        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
+    };
+};
 
-                if (typeof couchOptions !== 'object') {
-                  opts.since = couchOptions;
-                  console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"})."));
-                } else if (Object.keys(couchOptions).length > 0) {
-                  Object.assign(opts, couchOptions);
-                }
+module.exports = function (str, opts) {
+    var options = normalizeParseOptions(opts);
 
-                if (Object.keys(options).length > 0) {
-                  Object.assign(opts, options);
+    if (str === '' || str === null || typeof str === 'undefined') {
+        return options.plainObjects ? Object.create(null) : {};
+    }
 
-                  if (options.skipTrashed || options.includeFilePath) {
-                    opts.includeDocs = true;
-                  }
-                }
+    var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
+    var obj = options.plainObjects ? Object.create(null) : {};
 
-                params = _objectSpread(_objectSpread({}, (0, _omit.default)(opts, ['fields', 'includeDocs', 'includeFilePath', 'skipDeleted', 'skipTrashed'])), {}, {
-                  fields: opts.fields ? opts.fields.join(',') : null,
-                  include_docs: opts.includeDocs,
-                  include_file_path: opts.includeFilePath,
-                  skip_deleted: opts.skipDeleted,
-                  skip_trashed: opts.skipTrashed
-                });
-                path = (0, _utils.uri)(_templateObject23());
-                url = querystring.buildURL(path, params);
-                _context33.next = 10;
-                return this.stackClient.fetchJSON('GET', url);
+    // Iterate over the keys and setup the new object
 
-              case 10:
-                _yield$this$stackClie = _context33.sent;
-                newLastSeq = _yield$this$stackClie.last_seq;
-                pending = _yield$this$stackClie.pending;
-                results = _yield$this$stackClie.results;
-                return _context33.abrupt("return", {
-                  newLastSeq: newLastSeq,
-                  pending: pending,
-                  results: results
-                });
+    var keys = Object.keys(tempObj);
+    for (var i = 0; i < keys.length; ++i) {
+        var key = keys[i];
+        var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');
+        obj = utils.merge(obj, newObj, options);
+    }
 
-              case 15:
-              case "end":
-                return _context33.stop();
-            }
-          }
-        }, _callee33, this);
-      }));
+    if (options.allowSparse === true) {
+        return obj;
+    }
 
-      function fetchChanges() {
-        return _fetchChanges.apply(this, arguments);
-      }
+    return utils.compact(obj);
+};
 
-      return fetchChanges;
-    }()
-  }]);
-  return FileCollection;
-}(_DocumentCollection2.default);
 
-var _default = FileCollection;
-exports["default"] = _default;
+/***/ }),
+/* 657 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.isMatchingIndex = exports.isInconsistentIndex = exports.getIndexFields = exports.transformSort = exports.getIndexNameFromFields = exports.normalizeDesignDoc = void 0;
 
-/***/ }),
-/* 659 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-"use strict";
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
+var _utils = __webpack_require__(623);
 
-let Mime = __webpack_require__(660);
-module.exports = new Mime(__webpack_require__(661));
+var _head = _interopRequireDefault(__webpack_require__(633));
 
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-/***/ }),
-/* 660 */
-/***/ ((module) => {
+var _isEqual = _interopRequireDefault(__webpack_require__(658));
 
-"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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
 /**
- * @param typeMap [Object] Map of MIME type -> Array[extensions]
- * @param ...
+ * @typedef {object} MangoPartialFilter
  */
-function Mime() {
-  this._types = Object.create(null);
-  this._extensions = Object.create(null);
-
-  for (let i = 0; i < arguments.length; i++) {
-    this.define(arguments[i]);
-  }
-
-  this.define = this.define.bind(this);
-  this.getType = this.getType.bind(this);
-  this.getExtension = this.getExtension.bind(this);
-}
 
 /**
- * Define mimetype -> extension mappings.  Each key is a mime-type that maps
- * to an array of extensions associated with the type.  The first extension is
- * used as the default extension for the type.
- *
- * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
- *
- * If a type declares an extension that has already been defined, an error will
- * be thrown.  To suppress this error and force the extension to be associated
- * with the new type, pass `force`=true.  Alternatively, you may prefix the
- * extension with "*" to map the type to extension, without mapping the
- * extension to the type.
+ * @typedef {object} MangoQueryOptions
  *
- * e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
+ * @property {Array<object>} [sort] The sorting parameters
+ * @property {Array<string>} [fields] The fields to return
+ * @property {number|null} [limit] For pagination, the number of results to return
+ * @property {number|null} [skip] For skip-based pagination, the number of referenced files to skip
+ * @property {string|null} [indexId] The _id of the CouchDB index to use for this request
+ * @property {string|null} [bookmark] For bookmark-based pagination, the document _id to start from
+ * @property {Array<string>} [indexedFields]
+ * @property {MangoPartialFilter|null} [partialFilter] An optional partial filter
+ */
+
+/**
+ * Attributes representing a design doc
  *
+ * @typedef {object} DesignDoc
  *
- * @param map (Object) type definitions
- * @param force (Boolean) if true, force overriding of existing definitions
+ * @property {string} _id - Id of the design doc. Can be named, e.g. '_design/by_indexed_attribute' or not, e.g. '_design/12345'
+ * @property {string} language - The index language. Can be 'query' for mango index or 'javascript' for views.
+ * @property {object} views - Views definition, i.e. the index.
  */
-Mime.prototype.define = function(typeMap, force) {
-  for (let type in typeMap) {
-    let extensions = typeMap[type].map(function(t) {
-      return t.toLowerCase();
-    });
-    type = type.toLowerCase();
-
-    for (let i = 0; i < extensions.length; i++) {
-      const ext = extensions[i];
+var normalizeDesignDoc = function normalizeDesignDoc(designDoc) {
+  var id = designDoc._id || designDoc.id;
+  return _objectSpread({
+    id: id,
+    _id: id
+  }, designDoc.doc);
+};
 
-      // '*' prefix = not the preferred type for this extension.  So fixup the
-      // extension, and skip it.
-      if (ext[0] === '*') {
-        continue;
-      }
+exports.normalizeDesignDoc = normalizeDesignDoc;
 
-      if (!force && (ext in this._types)) {
-        throw new Error(
-          'Attempt to change mapping for "' + ext +
-          '" extension from "' + this._types[ext] + '" to "' + type +
-          '". Pass `force=true` to allow this, otherwise remove "' + ext +
-          '" from the list of extensions for "' + type + '".'
-        );
-      }
+var getIndexNameFromFields = function getIndexNameFromFields(fields) {
+  return "by_".concat(fields.join('_and_'));
+};
 
-      this._types[ext] = type;
-    }
+exports.getIndexNameFromFields = getIndexNameFromFields;
 
-    // Use first extension as default
-    if (force || !this._extensions[type]) {
-      const ext = extensions[0];
-      this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1);
-    }
+var transformSort = function transformSort(sort) {
+  if (!sort || Array.isArray(sort)) {
+    return sort;
   }
-};
 
+  console.warn('Passing an object to the "sort" is deprecated, please use an array instead.');
+  return (0, _utils.transform)(sort, function (acc, order, field) {
+    return acc.push((0, _defineProperty2.default)({}, field, order));
+  }, []);
+};
 /**
- * Lookup a mime type based on extension
+ * Compute fields that should be indexed for a mango
+ * query to work
+ *
+ * @param {MangoQueryOptions} options - Mango query options
+ *
+ * @returns {Array} - Fields to index
  */
-Mime.prototype.getType = function(path) {
-  path = String(path);
-  let last = path.replace(/^.*[/\\]/, '').toLowerCase();
-  let ext = last.replace(/^.*\./, '').toLowerCase();
 
-  let hasPath = last.length < path.length;
-  let hasDot = ext.length < last.length - 1;
 
-  return (hasDot || !hasPath) && this._types[ext] || null;
-};
+exports.transformSort = transformSort;
 
+var getIndexFields = function getIndexFields(_ref) {
+  var selector = _ref.selector,
+      _ref$sort = _ref.sort,
+      sort = _ref$sort === void 0 ? [] : _ref$sort;
+  return Array.from(new Set([].concat((0, _toConsumableArray2.default)(sort.map(function (sortOption) {
+    return (0, _head.default)(Object.keys(sortOption));
+  })), (0, _toConsumableArray2.default)(selector ? Object.keys(selector) : []))));
+};
 /**
- * Return file extension associated with a mime type
+ * Check if an index is in an inconsistent state, i.e. its name
+ * contains the indexed attributes which are not in correct order.
+ *
+ * @param {DesignDoc} index - The index to check
+ * @returns {boolean} True if the index is inconsistent
  */
-Mime.prototype.getExtension = function(type) {
-  type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
-  return type && this._extensions[type.toLowerCase()] || null;
+
+
+exports.getIndexFields = getIndexFields;
+
+var isInconsistentIndex = function isInconsistentIndex(index) {
+  var indexId = index._id;
+
+  if (!indexId.startsWith('_design/by_')) {
+    return false;
+  }
+
+  var fieldsInName = indexId.split('_design/by_')[1].split('_and_');
+  var viewId = Object.keys((0, _get.default)(index, "views"))[0];
+  var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields")));
+  return !(0, _isEqual.default)(fieldsInName, fieldsInIndex);
 };
+/**
+ * Check if an index is matching the given fields
+ *
+ * @param {DesignDoc} index - The index to check
+ * @param {Array} fields - The fields that the index must have
+ * @param {object} partialFilter - An optional partial filter
+ * @returns {boolean} True if the index is matches the given fields
+ */
 
-module.exports = Mime;
 
+exports.isInconsistentIndex = isInconsistentIndex;
 
-/***/ }),
-/* 661 */
-/***/ ((module) => {
+var isMatchingIndex = function isMatchingIndex(index, fields, partialFilter) {
+  var viewId = Object.keys((0, _get.default)(index, "views"))[0];
+  var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields")));
 
-module.exports = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma","es"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/mrb-consumer+xml":["*xdf"],"application/mrb-publish+xml":["*xdf"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["*xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-error+xml":["xer"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]};
+  if ((0, _isEqual.default)(fieldsInIndex, fields)) {
+    if (!partialFilter) {
+      return true;
+    }
+
+    var partialFilterInIndex = (0, _get.default)(index, "views.".concat(viewId, ".map.partial_filter_selector"));
+
+    if ((0, _isEqual.default)(partialFilter, partialFilterInIndex)) {
+      return true;
+    }
+  }
+
+  return false;
+};
+
+exports.isMatchingIndex = isMatchingIndex;
 
 /***/ }),
-/* 662 */
+/* 658 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseHas = __webpack_require__(663),
-    hasPath = __webpack_require__(458);
+var baseIsEqual = __webpack_require__(422);
 
 /**
- * Checks if `path` is a direct property of `object`.
+ * Performs a deep comparison between two values to determine if they are
+ * equivalent.
+ *
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
+ * by their own, not inherited, enumerable properties. Functions and DOM
+ * nodes are compared by strict equality, i.e. `===`.
  *
  * @static
- * @since 0.1.0
  * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  * @example
  *
- * var object = { 'a': { 'b': 2 } };
- * var other = _.create({ 'a': _.create({ 'b': 2 }) });
- *
- * _.has(object, 'a');
- * // => true
- *
- * _.has(object, 'a.b');
- * // => true
+ * var object = { 'a': 1 };
+ * var other = { 'a': 1 };
  *
- * _.has(object, ['a', 'b']);
+ * _.isEqual(object, other);
  * // => true
  *
- * _.has(other, 'a');
+ * object === other;
  * // => false
  */
-function has(object, path) {
-  return object != null && hasPath(object, path, baseHas);
+function isEqual(value, other) {
+  return baseIsEqual(value, other);
 }
 
-module.exports = has;
+module.exports = isEqual;
 
 
 /***/ }),
-/* 663 */
-/***/ ((module) => {
+/* 659 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+"use strict";
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.buildURL = exports.encode = void 0;
+
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
+
+var _pickBy = _interopRequireDefault(__webpack_require__(660));
 
 /**
- * The base implementation of `_.has` without support for deep paths.
+ * Encode a value of any type into a URI search param compatible string with a specific treatment for arrays which will keep their brackets (they do not with standard `toString()` method).
+ *
+ * Examples:
+ *
+ *   encodeValues([['io.cozy.files', 'abcd1234'], '12345'])
+ *   // → '[[%22io.cozy.files%22,%22abcd1234%22],%2212345%22]'
  *
+ *   encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), true)
+ *   // → '%22io.cozy.files%2Cabcd1234%2C12345%22'
+ *
+ *   encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), false)
+ *   // → 'io.cozy.files%2Cabcd1234%2C12345'
+ *
+ *   encodeValues('[1234]')
+ *   // → %5B1234%5D
+ *
+ * @function
  * @private
- * @param {Object} [object] The object to query.
- * @param {Array|string} key The key to check.
- * @returns {boolean} Returns `true` if `key` exists, else `false`.
  */
-function baseHas(object, key) {
-  return object != null && hasOwnProperty.call(object, key);
-}
+var encodeValues = function encodeValues(values) {
+  var fromArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
 
-module.exports = baseHas;
+  if (Array.isArray(values)) {
+    return '[' + values.map(function (v) {
+      return encodeValues(v, true);
+    }).join(',') + ']';
+  }
+
+  return fromArray ? encodeURIComponent("\"".concat(values, "\"")) : encodeURIComponent(values);
+};
+/**
+ * Encode an object as querystring, values are encoded as
+ * URI components, keys are not.
+ *
+ * @function
+ * @private
+ */
+
+
+var encode = function encode(data) {
+  return Object.entries(data).map(function (_ref) {
+    var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
+        k = _ref2[0],
+        v = _ref2[1];
+
+    var encodedValue = encodeValues(v);
+    return "".concat(k, "=").concat(encodedValue);
+  }).join('&');
+};
+/**
+ * Returns a URL from base url and a query parameter object.
+ * Any undefined parameter is removed.
+ *
+ * @function
+ * @private
+ */
+
+
+exports.encode = encode;
+
+var buildURL = function buildURL(url, params) {
+  var qs = encode((0, _pickBy.default)(params));
+
+  if (qs) {
+    return "".concat(url, "?").concat(qs);
+  } else {
+    return url;
+  }
+};
 
+exports.buildURL = buildURL;
 
 /***/ }),
-/* 664 */
+/* 660 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var basePick = __webpack_require__(665),
-    flatRest = __webpack_require__(620);
+var arrayMap = __webpack_require__(410),
+    baseIteratee = __webpack_require__(413),
+    basePickBy = __webpack_require__(661),
+    getAllKeysIn = __webpack_require__(588);
 
 /**
- * Creates an object composed of the picked `object` properties.
+ * Creates an object composed of the `object` properties `predicate` returns
+ * truthy for. The predicate is invoked with two arguments: (value, key).
  *
  * @static
- * @since 0.1.0
  * @memberOf _
+ * @since 4.0.0
  * @category Object
  * @param {Object} object The source object.
- * @param {...(string|string[])} [paths] The property paths to pick.
+ * @param {Function} [predicate=_.identity] The function invoked per property.
  * @returns {Object} Returns the new object.
  * @example
  *
  * var object = { 'a': 1, 'b': '2', 'c': 3 };
  *
- * _.pick(object, ['a', 'c']);
+ * _.pickBy(object, _.isNumber);
  * // => { 'a': 1, 'c': 3 }
  */
-var pick = flatRest(function(object, paths) {
-  return object == null ? {} : basePick(object, paths);
-});
+function pickBy(object, predicate) {
+  if (object == null) {
+    return {};
+  }
+  var props = arrayMap(getAllKeysIn(object), function(prop) {
+    return [prop];
+  });
+  predicate = baseIteratee(predicate);
+  return basePickBy(object, props, function(value, path) {
+    return predicate(value, path[0]);
+  });
+}
 
-module.exports = pick;
+module.exports = pickBy;
 
 
 /***/ }),
-/* 665 */
+/* 661 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var basePickBy = __webpack_require__(649),
-    hasIn = __webpack_require__(456);
+var baseGet = __webpack_require__(371),
+    baseSet = __webpack_require__(662),
+    castPath = __webpack_require__(372);
 
 /**
- * The base implementation of `_.pick` without support for individual
- * property identifiers.
+ * The base implementation of  `_.pickBy` without support for iteratee shorthands.
  *
  * @private
  * @param {Object} object The source object.
  * @param {string[]} paths The property paths to pick.
+ * @param {Function} predicate The function invoked per property.
  * @returns {Object} Returns the new object.
  */
-function basePick(object, paths) {
-  return basePickBy(object, paths, function(value, path) {
-    return hasIn(object, path);
-  });
-}
+function basePickBy(object, paths, predicate) {
+  var index = -1,
+      length = paths.length,
+      result = {};
 
-module.exports = basePick;
+  while (++index < length) {
+    var path = paths[index],
+        value = baseGet(object, path);
 
+    if (predicate(value, path)) {
+      baseSet(result, castPath(path, object), value);
+    }
+  }
+  return result;
+}
 
-/***/ }),
-/* 666 */
-/***/ ((__unused_webpack_module, exports) => {
+module.exports = basePickBy;
 
-"use strict";
 
+/***/ }),
+/* 662 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.getIllegalCharacters = void 0;
+var assignValue = __webpack_require__(575),
+    castPath = __webpack_require__(372),
+    isIndex = __webpack_require__(448),
+    isObject = __webpack_require__(52),
+    toKey = __webpack_require__(411);
 
 /**
- * Get the list of illegal characters in the file name
+ * The base implementation of `_.set`.
  *
- * @public
- * @param {string} name - the file name
- * @returns {string} illegal characters separated by spaces
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
  */
-var getIllegalCharacters = function getIllegalCharacters(name) {
-  var FILENAME_ILLEGAL_CHARACTERS = /\/|\x00|\n|\r/g; // eslint-disable-line no-control-regex
+function baseSet(object, path, value, customizer) {
+  if (!isObject(object)) {
+    return object;
+  }
+  path = castPath(path, object);
 
-  var match = name.match(FILENAME_ILLEGAL_CHARACTERS);
-  return match ? match.join(' ') : '';
-};
+  var index = -1,
+      length = path.length,
+      lastIndex = length - 1,
+      nested = object;
+
+  while (nested != null && ++index < length) {
+    var key = toKey(path[index]),
+        newValue = value;
+
+    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
+      return object;
+    }
+
+    if (index != lastIndex) {
+      var objValue = nested[key];
+      newValue = customizer ? customizer(objValue, key, nested) : undefined;
+      if (newValue === undefined) {
+        newValue = isObject(objValue)
+          ? objValue
+          : (isIndex(path[index + 1]) ? [] : {});
+      }
+    }
+    assignValue(nested, key, newValue);
+    nested = nested[key];
+  }
+  return object;
+}
+
+module.exports = baseSet;
 
-exports.getIllegalCharacters = getIllegalCharacters;
 
 /***/ }),
-/* 667 */
+/* 663 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.hasJobFinished = exports.normalizeJob = exports.JOBS_DOCTYPE = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
+exports.FetchError = exports["default"] = void 0;
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(606));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _Collection = _interopRequireDefault(__webpack_require__(600));
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _DocumentCollection = __webpack_require__(601);
+var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664));
 
-var _utils = __webpack_require__(611);
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/", ""]);
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-  _templateObject = function _templateObject() {
-    return data;
-  };
+var EXPIRED_TOKEN = /Expired token/;
+var CLIENT_NOT_FOUND = /Client not found/;
+var INVALID_TOKEN = /Invalid JWT token/;
+var _default = {
+  EXPIRED_TOKEN: EXPIRED_TOKEN,
+  CLIENT_NOT_FOUND: CLIENT_NOT_FOUND,
+  INVALID_TOKEN: INVALID_TOKEN
+};
+exports["default"] = _default;
 
-  return data;
-}
+var getWwwAuthenticateErrorMessage = function getWwwAuthenticateErrorMessage(response) {
+  var invalidTokenRegex = /invalid_token/;
+  var expiredTokenRegex = /access token expired/;
+  var wwwAuthenticateHeader = response.headers && response.headers.get('www-authenticate');
 
-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; }
+  if (!wwwAuthenticateHeader) {
+    return undefined;
+  }
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  if (expiredTokenRegex.test(wwwAuthenticateHeader)) {
+    return 'Expired token';
+  }
 
-var JOBS_DOCTYPE = 'io.cozy.jobs';
-exports.JOBS_DOCTYPE = JOBS_DOCTYPE;
+  if (invalidTokenRegex.test(wwwAuthenticateHeader)) {
+    return 'Invalid token';
+  }
 
-var sleep = function sleep(delay) {
-  return new Promise(function (resolve) {
-    return setTimeout(resolve, delay);
-  });
+  return undefined;
 };
 
-var normalizeJob = function normalizeJob(job) {
-  return _objectSpread(_objectSpread(_objectSpread({}, job), (0, _DocumentCollection.normalizeDoc)(job, JOBS_DOCTYPE)), job.attributes);
-};
+var FetchError = /*#__PURE__*/function (_Error) {
+  (0, _inherits2.default)(FetchError, _Error);
 
-exports.normalizeJob = normalizeJob;
+  var _super = _createSuper(FetchError);
 
-var hasJobFinished = function hasJobFinished(job) {
-  return job.state === 'done' || job.state === 'errored';
-};
-/**
- * Document representing a io.cozy.jobs
- *
- * @typedef {object} JobDocument
- * @property {string} _id - Id of the job
- * @property {string} attributes.state - state of the job. Can be 'errored', 'running', 'queued', 'done'
- * @property {string} attributes.error - Error message of the job if any
- */
+  function FetchError(response, reason) {
+    var _this;
 
+    (0, _classCallCheck2.default)(this, FetchError);
+    _this = _super.call(this);
 
-exports.hasJobFinished = hasJobFinished;
+    if (Error.captureStackTrace) {
+      Error.captureStackTrace((0, _assertThisInitialized2.default)(_this), _this.constructor);
+    } // WARN We have to hardcode this because babel doesn't play nice when extending Error
 
-var JobCollection = /*#__PURE__*/function () {
-  function JobCollection(stackClient) {
-    (0, _classCallCheck2.default)(this, JobCollection);
-    this.stackClient = stackClient;
+
+    _this.name = 'FetchError';
+    _this.response = response;
+    _this.url = response.url;
+    _this.status = response.status;
+    _this.reason = reason;
+    var wwwAuthenticateErrorMessage = getWwwAuthenticateErrorMessage(response);
+    Object.defineProperty((0, _assertThisInitialized2.default)(_this), 'message', {
+      value: reason.message || wwwAuthenticateErrorMessage || (typeof reason === 'string' ? reason : JSON.stringify(reason))
+    });
+    return _this;
   }
 
-  (0, _createClass2.default)(JobCollection, [{
-    key: "queued",
-    value: function queued(workerType) {
-      return this.stackClient.fetchJSON('GET', "/jobs/queue/".concat(workerType));
-    }
-    /**
-     * Creates a job
-     *
-     * @param  {string} workerType - Ex: "konnector"
-     * @param  {object} [args={}] - Ex: {"slug": "my-konnector", "trigger": "trigger-id"}
-     * @param  {object} [options={}] - creation options
-     * @param  {boolean} [manual=false] -  Manual execution
-     * @returns {object} createdJob
-     */
+  return FetchError;
+}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
 
-  }, {
-    key: "create",
-    value: function create(workerType) {
-      var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-      var manual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
-      return this.stackClient.fetchJSON('POST', "/jobs/queue/".concat(workerType), {
-        data: {
-          type: JOBS_DOCTYPE,
-          attributes: {
-            arguments: args,
-            options: options,
-            manual: manual
-          }
-        }
-      });
+exports.FetchError = FetchError;
+
+/***/ }),
+/* 664 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var getPrototypeOf = __webpack_require__(607);
+
+var setPrototypeOf = __webpack_require__(604);
+
+var isNativeFunction = __webpack_require__(665);
+
+var construct = __webpack_require__(666);
+
+function _wrapNativeSuper(Class) {
+  var _cache = typeof Map === "function" ? new Map() : undefined;
+
+  module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
+    if (Class === null || !isNativeFunction(Class)) return Class;
+
+    if (typeof Class !== "function") {
+      throw new TypeError("Super expression must either be null or a function");
     }
-    /**
-     * Return a normalized job, given its id
-     *
-     * @param {string} id - id of the job
-     * @returns {JobDocument}
-     */
 
-  }, {
-    key: "get",
-    value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) {
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                return _context.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject(), id), {
-                  normalize: normalizeJob
-                }));
+    if (typeof _cache !== "undefined") {
+      if (_cache.has(Class)) return _cache.get(Class);
 
-              case 1:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
+      _cache.set(Class, Wrapper);
+    }
 
-      function get(_x) {
-        return _get.apply(this, arguments);
+    function Wrapper() {
+      return construct(Class, arguments, getPrototypeOf(this).constructor);
+    }
+
+    Wrapper.prototype = Object.create(Class.prototype, {
+      constructor: {
+        value: Wrapper,
+        enumerable: false,
+        writable: true,
+        configurable: true
       }
+    });
+    return setPrototypeOf(Wrapper, Class);
+  };
 
-      return get;
-    }()
-    /**
-     * Update the job's state
-     * This does work only for jobs comming from @client triggers
-     *
-     * @param {JobDocument} job - io.cozy.jobs document
-     */
+  module.exports["default"] = module.exports, module.exports.__esModule = true;
+  return _wrapNativeSuper(Class);
+}
 
-  }, {
-    key: "update",
-    value: function () {
-      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(job) {
-        var jobResult;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                if (!(job.worker !== 'client')) {
-                  _context2.next = 2;
-                  break;
-                }
+module.exports = _wrapNativeSuper;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-                throw new Error("JobCollection.update only works for client workers. ".concat(job.worker, " given"));
+/***/ }),
+/* 665 */
+/***/ ((module) => {
 
-              case 2:
-                _context2.next = 4;
-                return this.stackClient.fetchJSON('PATCH', "/jobs/".concat(job._id), {
-                  data: {
-                    type: JOBS_DOCTYPE,
-                    id: job._id,
-                    attributes: {
-                      state: job.attributes.state,
-                      error: job.attributes.error
-                    }
-                  }
-                });
+function _isNativeFunction(fn) {
+  return Function.toString.call(fn).indexOf("[native code]") !== -1;
+}
 
-              case 4:
-                jobResult = _context2.sent;
-                return _context2.abrupt("return", normalizeJob(jobResult.data));
+module.exports = _isNativeFunction;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-              case 6:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this);
-      }));
+/***/ }),
+/* 666 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      function update(_x2) {
-        return _update.apply(this, arguments);
-      }
+var setPrototypeOf = __webpack_require__(604);
 
-      return update;
-    }()
-    /**
-     * Polls a job state until it is finished
-     *
-     * `options.until` can be used to tweak when to stop waiting. It will be
-     * given the current job state. If true is returned, the awaiting is
-     * stopped.
-     */
+var isNativeReflectConstruct = __webpack_require__(667);
 
-  }, {
-    key: "waitFor",
-    value: function () {
-      var _waitFor = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(id) {
-        var _ref,
-            _ref$onUpdate,
-            onUpdate,
-            _ref$until,
-            until,
-            _ref$delay,
-            delay,
-            _ref$timeout,
-            timeout,
-            start,
-            jobData,
-            now,
-            _args3 = arguments;
+function _construct(Parent, args, Class) {
+  if (isNativeReflectConstruct()) {
+    module.exports = _construct = Reflect.construct;
+    module.exports["default"] = module.exports, module.exports.__esModule = true;
+  } else {
+    module.exports = _construct = function _construct(Parent, args, Class) {
+      var a = [null];
+      a.push.apply(a, args);
+      var Constructor = Function.bind.apply(Parent, a);
+      var instance = new Constructor();
+      if (Class) setPrototypeOf(instance, Class.prototype);
+      return instance;
+    };
 
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                _ref = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref$onUpdate = _ref.onUpdate, onUpdate = _ref$onUpdate === void 0 ? null : _ref$onUpdate, _ref$until = _ref.until, until = _ref$until === void 0 ? hasJobFinished : _ref$until, _ref$delay = _ref.delay, delay = _ref$delay === void 0 ? 5 * 1000 : _ref$delay, _ref$timeout = _ref.timeout, timeout = _ref$timeout === void 0 ? 60 * 5 * 1000 : _ref$timeout;
-                start = Date.now();
-                _context3.next = 4;
-                return this.get(id);
+    module.exports["default"] = module.exports, module.exports.__esModule = true;
+  }
 
-              case 4:
-                jobData = _context3.sent.data.attributes;
+  return _construct.apply(null, arguments);
+}
 
-              case 5:
-                if (!(!jobData || !until(jobData))) {
-                  _context3.next = 17;
-                  break;
-                }
+module.exports = _construct;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-                _context3.next = 8;
-                return sleep(delay);
+/***/ }),
+/* 667 */
+/***/ ((module) => {
 
-              case 8:
-                _context3.next = 10;
-                return this.get(id);
+function _isNativeReflectConstruct() {
+  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
+  if (Reflect.construct.sham) return false;
+  if (typeof Proxy === "function") return true;
 
-              case 10:
-                jobData = _context3.sent.data.attributes;
+  try {
+    Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
+    return true;
+  } catch (e) {
+    return false;
+  }
+}
 
-                if (onUpdate) {
-                  onUpdate(jobData);
-                }
+module.exports = _isNativeReflectConstruct;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-                now = Date.now();
+/***/ }),
+/* 668 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-                if (!(start - now > timeout)) {
-                  _context3.next = 15;
-                  break;
-                }
+"use strict";
 
-                throw new Error('Timeout for JobCollection::waitFor');
 
-              case 15:
-                _context3.next = 5;
-                break;
+var _interopRequireDefault = __webpack_require__(524);
 
-              case 17:
-                return _context3.abrupt("return", jobData);
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-              case 18:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this);
-      }));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-      function waitFor(_x3) {
-        return _waitFor.apply(this, arguments);
-      }
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-      return waitFor;
-    }()
+var AppToken = /*#__PURE__*/function () {
+  function AppToken(token) {
+    (0, _classCallCheck2.default)(this, AppToken);
+    this.token = token || '';
+  }
+
+  (0, _createClass2.default)(AppToken, [{
+    key: "toAuthHeader",
+    value: function toAuthHeader() {
+      return 'Bearer ' + this.token;
+    }
+  }, {
+    key: "toBasicAuth",
+    value: function toBasicAuth() {
+      return "user:".concat(this.token, "@");
+    }
+    /**
+     * Get the app token string
+     *
+     * @see CozyStackClient.getAccessToken
+     * @returns {string} token
+     */
+
+  }, {
+    key: "getAccessToken",
+    value: function getAccessToken() {
+      return this.token;
+    }
   }]);
-  return JobCollection;
+  return AppToken;
 }();
 
-var _default = JobCollection;
-exports["default"] = _default;
+exports["default"] = AppToken;
 
 /***/ }),
-/* 668 */
+/* 669 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
+
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
+
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
+
+var AccessToken = /*#__PURE__*/function () {
+  function AccessToken(dataArg) {
+    (0, _classCallCheck2.default)(this, AccessToken);
+    var data = dataArg;
+    if (typeof data === 'string') data = JSON.parse(data);
+    this.tokenType = data.token_type || data.tokenType;
+    this.accessToken = data.access_token || data.accessToken;
+    this.refreshToken = data.refresh_token || data.refreshToken;
+    this.scope = data.scope;
+  }
+
+  (0, _createClass2.default)(AccessToken, [{
+    key: "toAuthHeader",
+    value: function toAuthHeader() {
+      return 'Bearer ' + this.accessToken;
+    }
+  }, {
+    key: "toBasicAuth",
+    value: function toBasicAuth() {
+      return "user:".concat(this.accessToken, "@");
+    }
+  }, {
+    key: "toJSON",
+    value: function toJSON() {
+      return {
+        tokenType: this.tokenType,
+        accessToken: this.accessToken,
+        refreshToken: this.refreshToken,
+        scope: this.scope
+      };
+    }
+  }, {
+    key: "toString",
+    value: function toString() {
+      return JSON.stringify(this.toJSON());
+    }
+    /**
+     * Get the access token string
+     *
+     * @see CozyStackClient.getAccessToken
+     * @returns {string} token
+     */
+
+  }, {
+    key: "getAccessToken",
+    value: function getAccessToken() {
+      return this.accessToken;
+    }
+  }]);
+  return AccessToken;
+}();
+
+exports["default"] = AccessToken;
+
+/***/ }),
+/* 670 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireWildcard = __webpack_require__(510);
+var _interopRequireWildcard = __webpack_require__(522);
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.KONNECTORS_DOCTYPE = void 0;
+exports["default"] = exports.isDirectory = exports.isFile = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(606));
 
-var _pick = _interopRequireDefault(__webpack_require__(664));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _AppCollection2 = _interopRequireDefault(__webpack_require__(590));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _TriggerCollection = _interopRequireWildcard(__webpack_require__(669));
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _DocumentCollection = __webpack_require__(601);
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+var _lite = _interopRequireDefault(__webpack_require__(671));
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var _has = _interopRequireDefault(__webpack_require__(674));
 
-var KONNECTORS_DOCTYPE = 'io.cozy.konnectors';
-exports.KONNECTORS_DOCTYPE = KONNECTORS_DOCTYPE;
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-var KonnectorCollection = /*#__PURE__*/function (_AppCollection) {
-  (0, _inherits2.default)(KonnectorCollection, _AppCollection);
+var _omit = _interopRequireDefault(__webpack_require__(625));
 
-  var _super = _createSuper(KonnectorCollection);
+var _pick = _interopRequireDefault(__webpack_require__(676));
 
-  function KonnectorCollection(stackClient) {
-    var _this;
+var _mangoIndex = __webpack_require__(657);
 
-    (0, _classCallCheck2.default)(this, KonnectorCollection);
-    _this = _super.call(this, stackClient);
-    _this.doctype = KONNECTORS_DOCTYPE;
-    _this.endpoint = '/konnectors/';
-    return _this;
-  }
+var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613));
 
-  (0, _createClass2.default)(KonnectorCollection, [{
-    key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                throw new Error('create() method is not available for konnectors');
+var _utils = __webpack_require__(623);
 
-              case 1:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee);
-      }));
+var _errors = __webpack_require__(663);
 
-      function create() {
-        return _create.apply(this, arguments);
-      }
+var _Collection = __webpack_require__(612);
 
-      return create;
-    }()
-  }, {
-    key: "destroy",
-    value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                throw new Error('destroy() method is not available for konnectors');
+var _getIllegalCharacter = __webpack_require__(678);
 
-              case 1:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2);
-      }));
+var querystring = _interopRequireWildcard(__webpack_require__(659));
 
-      function destroy() {
-        return _destroy.apply(this, arguments);
-      }
+function _templateObject23() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/_changes"]);
 
-      return destroy;
-    }()
-    /**
-     * Find triggers for a particular konnector
-     *
-     * @param  {string} slug of the konnector
-     */
+  _templateObject23 = function _templateObject23() {
+    return data;
+  };
 
-  }, {
-    key: "findTriggersBySlug",
-    value: function () {
-      var _findTriggersBySlug = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(slug) {
-        var triggerCol, _yield$triggerCol$all, rawTriggers;
+  return data;
+}
 
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                triggerCol = new _TriggerCollection.default(this.stackClient);
-                _context3.next = 3;
-                return triggerCol.all({
-                  limit: null
-                });
+function _templateObject22() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]);
 
-              case 3:
-                _yield$triggerCol$all = _context3.sent;
-                rawTriggers = _yield$triggerCol$all.data;
-                return _context3.abrupt("return", rawTriggers.map(function (x) {
-                  return x.attributes;
-                }).filter(function (triggerAttrs) {
-                  return (0, _TriggerCollection.isForKonnector)(triggerAttrs, slug);
-                }));
+  _templateObject22 = function _templateObject22() {
+    return data;
+  };
+
+  return data;
+}
+
+function _templateObject21() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]);
+
+  _templateObject21 = function _templateObject21() {
+    return data;
+  };
+
+  return data;
+}
+
+function _templateObject20() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]);
+
+  _templateObject20 = function _templateObject20() {
+    return data;
+  };
+
+  return data;
+}
 
-              case 6:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this);
-      }));
+function _templateObject19() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/versions"]);
 
-      function findTriggersBySlug(_x) {
-        return _findTriggersBySlug.apply(this, arguments);
-      }
+  _templateObject19 = function _templateObject19() {
+    return data;
+  };
 
-      return findTriggersBySlug;
-    }()
-    /**
-     * Launch a trigger for a given konnector.
-     *
-     * @param  {string} slug
-     * @param  {object} options
-     * @param  {object} options.accountId - Pinpoint the account that should be used, useful if the user
-     * has more than 1 account for 1 konnector
-     */
+  return data;
+}
 
-  }, {
-    key: "launch",
-    value: function () {
-      var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(slug) {
-        var options,
-            triggerCol,
-            konnTriggers,
-            filteredTriggers,
-            filterAttrs,
-            _args4 = arguments;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {};
-                triggerCol = new _TriggerCollection.default(this.stackClient);
-                _context4.next = 4;
-                return this.findTriggersBySlug(slug);
+function _templateObject18() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/upload/metadata"]);
 
-              case 4:
-                konnTriggers = _context4.sent;
-                filteredTriggers = options.accountId ? konnTriggers.filter(function (triggerAttrs) {
-                  return (0, _TriggerCollection.isForAccount)(triggerAttrs, options.accountId);
-                }) : konnTriggers;
+  _templateObject18 = function _templateObject18() {
+    return data;
+  };
 
-                if (!(filteredTriggers.length === 1)) {
-                  _context4.next = 10;
-                  break;
-                }
+  return data;
+}
 
-                return _context4.abrupt("return", triggerCol.launch(konnTriggers[0]));
+function _templateObject17() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
 
-              case 10:
-                filterAttrs = JSON.stringify((0, _pick.default)({
-                  slug: slug,
-                  accountId: options.accountId
-                }));
+  _templateObject17 = function _templateObject17() {
+    return data;
+  };
 
-                if (!(filteredTriggers.length === 0)) {
-                  _context4.next = 15;
-                  break;
-                }
+  return data;
+}
 
-                throw new Error("No trigger found for ".concat(filterAttrs));
+function _templateObject16() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=directory"]);
 
-              case 15:
-                if (!(filteredTriggers.length > 1)) {
-                  _context4.next = 17;
-                  break;
-                }
+  _templateObject16 = function _templateObject16() {
+    return data;
+  };
 
-                throw new Error("More than 1 trigger found for ".concat(filterAttrs));
+  return data;
+}
 
-              case 17:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4, this);
-      }));
+function _templateObject15() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/metadata?Path=", ""]);
 
-      function launch(_x2) {
-        return _launch.apply(this, arguments);
-      }
+  _templateObject15 = function _templateObject15() {
+    return data;
+  };
 
-      return launch;
-    }()
-    /**
-     * Updates a konnector
-     *
-     * @param  {string} slug
-     * @param  {object} options
-     * @param  {object} options.source - Specify the source (ex: registry://slug/stable)
-     * @param  {boolean} options.sync - Wait for konnector to be updated, otherwise the job
-     * is just scheduled
-     */
+  return data;
+}
 
-  }, {
-    key: "update",
-    value: function () {
-      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(slug) {
-        var options,
-            source,
-            sync,
-            reqOptions,
-            rawKonnector,
-            _args5 = arguments;
-        return _regenerator.default.wrap(function _callee5$(_context5) {
-          while (1) {
-            switch (_context5.prev = _context5.next) {
-              case 0:
-                options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
+function _templateObject14() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
 
-                if (slug) {
-                  _context5.next = 3;
-                  break;
-                }
+  _templateObject14 = function _templateObject14() {
+    return data;
+  };
 
-                throw new Error('Cannot call update with no slug');
+  return data;
+}
 
-              case 3:
-                source = options.source || null;
-                sync = options.sync || false;
-                reqOptions = sync ? {
-                  headers: {
-                    Accept: 'text/event-stream'
-                  }
-                } : {};
-                _context5.next = 8;
-                return this.stackClient.fetchJSON('PUT', "/konnectors/".concat(slug) + (source ? "?Source=".concat(source) : ''), reqOptions);
+function _templateObject13() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Path=", ""]);
 
-              case 8:
-                rawKonnector = _context5.sent;
-                return _context5.abrupt("return", (0, _DocumentCollection.normalizeDoc)(rawKonnector));
+  _templateObject13 = function _templateObject13() {
+    return data;
+  };
 
-              case 10:
-              case "end":
-                return _context5.stop();
-            }
-          }
-        }, _callee5, this);
-      }));
+  return data;
+}
 
-      function update(_x3) {
-        return _update.apply(this, arguments);
-      }
+function _templateObject12() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?VersionId=", "&Filename=", ""]);
 
-      return update;
-    }()
-  }]);
-  return KonnectorCollection;
-}(_AppCollection2.default);
+  _templateObject12 = function _templateObject12() {
+    return data;
+  };
 
-var _default = KonnectorCollection;
-exports["default"] = _default;
+  return data;
+}
 
-/***/ }),
-/* 669 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+function _templateObject11() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Id=", "&Filename=", ""]);
 
-"use strict";
+  _templateObject11 = function _templateObject11() {
+    return data;
+  };
 
+  return data;
+}
 
-var _interopRequireWildcard = __webpack_require__(510);
+function _templateObject10() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", "&Encrypted=", ""]);
 
-var _interopRequireDefault = __webpack_require__(512);
+  _templateObject10 = function _templateObject10() {
+    return data;
+  };
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.isForAccount = exports.isForKonnector = exports.normalizeTrigger = exports.TRIGGERS_DOCTYPE = exports.JOBS_DOCTYPE = void 0;
+  return data;
+}
+
+function _templateObject9() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", "&Encrypted=", "&MetadataID=", "&Size=", ""]);
+
+  _templateObject9 = function _templateObject9() {
+    return data;
+  };
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
+  return data;
+}
 
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
+function _templateObject8() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+  _templateObject8 = function _templateObject8() {
+    return data;
+  };
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+  return data;
+}
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+function _templateObject7() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/trash/", ""]);
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+  _templateObject7 = function _templateObject7() {
+    return data;
+  };
 
-var _get3 = _interopRequireDefault(__webpack_require__(670));
+  return data;
+}
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+function _templateObject6() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+  _templateObject6 = function _templateObject6() {
+    return data;
+  };
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+  return data;
+}
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-var _Collection = _interopRequireWildcard(__webpack_require__(600));
+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); }
 
-var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601));
+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; }
 
-var _JobCollection = __webpack_require__(667);
+function _templateObject5() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]);
 
-var _utils = __webpack_require__(611);
+  _templateObject5 = function _templateObject5() {
+    return data;
+  };
 
-var _errors = __webpack_require__(651);
+  return data;
+}
 
 function _templateObject4() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", "/launch"]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]);
 
   _templateObject4 = function _templateObject4() {
     return data;
@@ -106503,7 +105256,7 @@ function _templateObject4() {
 }
 
 function _templateObject3() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]);
 
   _templateObject3 = function _templateObject3() {
     return data;
@@ -106513,7 +105266,7 @@ function _templateObject3() {
 }
 
 function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]);
 
   _templateObject2 = function _templateObject2() {
     return data;
@@ -106523,7 +105276,7 @@ function _templateObject2() {
 }
 
 function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers"]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]);
 
   _templateObject = function _templateObject() {
     return data;
@@ -106540,206 +105293,389 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
 
 function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var JOBS_DOCTYPE = 'io.cozy.jobs';
-exports.JOBS_DOCTYPE = JOBS_DOCTYPE;
-var TRIGGERS_DOCTYPE = 'io.cozy.triggers';
-exports.TRIGGERS_DOCTYPE = TRIGGERS_DOCTYPE;
+/**
+ * Cursor used for Mango queries pagination
+ *
+ * @typedef {Array<string>|string} ViewKey
+ * @typedef {string} DocId
+ * @typedef {Array<*> & {0: ViewKey, 1: DocId}} CouchDBViewCursor
+ */
 
-var normalizeTrigger = function normalizeTrigger(trigger) {
-  return _objectSpread(_objectSpread(_objectSpread({}, trigger), (0, _DocumentCollection2.normalizeDoc)(trigger, TRIGGERS_DOCTYPE)), trigger.attributes);
+/**
+ * Attributes used for directory creation
+ *
+ * @typedef {object} DirectoryAttributes
+ * @property {string} dirId - Id of the parent directory.
+ * @property {boolean} name - Name of the created directory.
+ * @property {boolean} executable - Indicates whether the file will be executable.
+ */
+
+/**
+ * Attributes used for file creation
+ *
+ * @typedef {object} FileAttributes
+ * @property {string} dirId - Id of the parent directory.
+ * @property {string} name - Name of the created file.
+ * @property {Date} lastModifiedDate - Can be used to set the last modified date of a file.
+ * @property {boolean} executable - Whether or not the file is executable
+ * @property {boolean} encrypted - Whether or not the file is client-side encrypted
+ * @property {object} metadata io.cozy.files.metadata to attach to the file
+ */
+
+/**
+ * Document representing a io.cozy.files
+ *
+ * @typedef {object} FileDocument
+ * @property {string} _id - Id of the file
+ * @property {FileAttributes} attributes - Attributes of the file
+ */
+
+/**
+ * Stream is not defined in a browser, but is on NodeJS environment
+ *
+ * @typedef {object} Stream
+ */
+
+/**
+ * Document representing a io.cozy.oauth.clients
+ *
+ * @typedef {object} OAuthClient
+ * @property {string} _id - Id of the client
+ * @property {string} _type - Doctype of the client (i.e. io.cozy.oauth.clients)
+ */
+var ROOT_DIR_ID = 'io.cozy.files.root-dir';
+var CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream';
+/**
+ * Normalize a file, adding document's doctype if needed
+ *
+ * @param  {FileDocument} file - File to normalize
+ * @returns {FileDocument} normalized file
+ * @private
+ */
+
+var normalizeFile = function normalizeFile(file) {
+  var _file$meta;
+
+  return _objectSpread(_objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(file, 'io.cozy.files')), file.attributes), {}, {
+    _rev: file === null || file === void 0 ? void 0 : (_file$meta = file.meta) === null || _file$meta === void 0 ? void 0 : _file$meta.rev // Beware of JSON-API
+
+  });
 };
+/**
+ * Normalize references, expliciting _type and _id — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/
+ *
+ * @param  {Array<object>} references - The list of files referenced by a document to normalize
+ * @returns {Array<object>} the data attribute of the normalized references
+ * @private
+ */
 
-exports.normalizeTrigger = normalizeTrigger;
 
-var isForKonnector = function isForKonnector(triggerAttrs, slug) {
-  return triggerAttrs.worker === 'konnector' && triggerAttrs.message.konnector == slug;
+var normalizeReferences = function normalizeReferences(references) {
+  return references ? references.map(function (ref) {
+    return {
+      _type: ref.type,
+      _id: ref.id
+    };
+  }) : [];
 };
+/**
+ * Sanitize the file name by trimming spaces
+ *
+ * @param {string} name - The file name to trim
+ * @returns {string} the trimmed file name
+ * @private
+ */
 
-exports.isForKonnector = isForKonnector;
 
-var isForAccount = function isForAccount(triggerAttrs, accountId) {
-  return triggerAttrs.message.account == accountId;
+var sanitizeFileName = function sanitizeFileName(name) {
+  return name && name.trim();
 };
+/**
+ * Sanitize and validate the file name - throw errors according to case
+ *
+ * @param {string} name - The file name
+ * @returns {string} the trimmed safe file name
+ * @throws {Error} - explaining reason why file name is not valid
+ * @private
+ */
 
-exports.isForAccount = isForAccount;
 
-var buildParamsUrl = function buildParamsUrl(worker, type) {
-  var urlParams = new URLSearchParams();
+var sanitizeAndValidateFileName = function sanitizeAndValidateFileName(name) {
+  var safeName = sanitizeFileName(name);
 
-  if (worker) {
-    if (Array.isArray(worker.$in)) {
-      urlParams.set('Worker', worker.$in.join(','));
-    } else {
-      urlParams.set('Worker', worker);
-    }
+  if (typeof safeName !== 'string' || safeName === '') {
+    throw new Error('Missing name argument');
   }
 
-  if (type) {
-    if (Array.isArray(type.$in)) {
-      urlParams.set('Type', type.$in.join(','));
-    } else {
-      urlParams.set('Type', type);
-    }
+  if (name === '.' || name === '..') {
+    throw new Error("Invalid filename: ".concat(name));
   }
 
-  return urlParams.toString();
+  var illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(safeName);
+
+  if (illegalCharacters.length) {
+    throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters));
+  }
+
+  return safeName;
 };
 /**
- * Implements `DocumentCollection` API along with specific methods for `io.cozy.triggers`.
+ * Returns true when parameter has type directory, file or has _type io.cozy.files
+ *
+ * @param {object} doc - The document whose type is checked
+ * @param {string} [doc._type] - The document's doctype
+ * @param {'directory'|'file'} [doc.type] - The io.cozy-files document type
+ *
+ * @returns {boolean} true when objects has type directory, file or has _type io.cozy.files or false
  */
 
 
-var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(TriggerCollection, _DocumentCollection);
+var isFile = function isFile(_ref) {
+  var _type = _ref._type,
+      type = _ref.type;
+  return _type === 'io.cozy.files' || type === 'directory' || type === 'file';
+};
+/**
+ * Returns true when parameters has type directory
+ *
+ * @param {string} type - The type of the file
+ * @returns {boolean} true when parameters has type directory or false
+ */
 
-  var _super = _createSuper(TriggerCollection);
 
-  function TriggerCollection(stackClient) {
-    (0, _classCallCheck2.default)(this, TriggerCollection);
-    return _super.call(this, TRIGGERS_DOCTYPE, stackClient);
+exports.isFile = isFile;
+
+var isDirectory = function isDirectory(_ref2) {
+  var type = _ref2.type;
+  return type === 'directory';
+};
+
+exports.isDirectory = isDirectory;
+
+var raceWithCondition = function raceWithCondition(promises, predicate) {
+  return new Promise(function (resolve) {
+    promises.forEach(function (p) {
+      return p.then(function (res) {
+        if (predicate(res)) {
+          resolve(true);
+        }
+      });
+    });
+    Promise.all(promises).then(function () {
+      return resolve(false);
+    });
+  });
+};
+
+var dirName = function dirName(path) {
+  var lastIndex = path.lastIndexOf('/');
+  return path.substring(0, lastIndex);
+};
+/**
+ * Implements `DocumentCollection` API along with specific methods for
+ * `io.cozy.files`.
+ *
+ * Files are a special type of documents and are handled differently by the stack:
+ * special routes are to be used, and there is a notion of referenced files, aka
+ * files associated to a specific document
+ */
+
+
+var FileCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(FileCollection, _DocumentCollection);
+
+  var _super = _createSuper(FileCollection);
+
+  function FileCollection(doctype, stackClient) {
+    var _this;
+
+    (0, _classCallCheck2.default)(this, FileCollection);
+    _this = _super.call(this, doctype, stackClient);
+    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "extractResponseLinkRelated", function (res) {
+      var href = res.links && res.links.related;
+      if (!href) throw new Error('No related link in server response');
+      return _this.stackClient.fullpath(href);
+    });
+    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "forceFileDownload", function (href, filename) {
+      var element = document.createElement('a');
+      element.setAttribute('href', href);
+      element.setAttribute('download', filename);
+      element.style.display = 'none';
+      document.body.appendChild(element);
+      element.click();
+      document.body.removeChild(element);
+    });
+    _this.specialDirectories = {};
+    return _this;
   }
   /**
-   * Get the list of triggers.
+   * Fetches the file's data
    *
-   * @see https://docs.cozy.io/en/cozy-stack/jobs/#get-jobstriggers
-   * @param  {{Worker}} options The fetch options: Worker allow to filter only triggers associated with a specific worker.
-   * @returns {{data}} The JSON API conformant response.
-   * @throws {FetchError}
+   * @param {string} id File id
+   * @returns {{data, included}} Information about the file or folder and it's descendents
    */
 
 
-  (0, _createClass2.default)(TriggerCollection, [{
-    key: "all",
+  (0, _createClass2.default)(FileCollection, [{
+    key: "get",
+    value: function get(id) {
+      return this.statById(id);
+    }
+  }, {
+    key: "fetchFindFiles",
     value: function () {
-      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-        var options,
-            resp,
-            _args = arguments;
+      var _fetchFindFiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) {
         return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
               case 0:
-                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
-                _context.prev = 1;
-                _context.next = 4;
-                return this.stackClient.fetchJSON('GET', "/jobs/triggers");
-
-              case 4:
-                resp = _context.sent;
-                return _context.abrupt("return", {
-                  data: resp.data.map(function (row) {
-                    return normalizeTrigger(row, TRIGGERS_DOCTYPE);
-                  }),
-                  meta: {
-                    count: resp.data.length
-                  },
-                  next: false,
-                  skip: 0
-                });
-
-              case 8:
-                _context.prev = 8;
-                _context.t0 = _context["catch"](1);
-                return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0));
+                return _context.abrupt("return", this.stackClient.fetchJSON('POST', '/files/_find', this.toMangoOptions(selector, options)));
 
-              case 11:
+              case 1:
               case "end":
                 return _context.stop();
             }
           }
-        }, _callee, this, [[1, 8]]);
+        }, _callee, this);
       }));
 
-      function all() {
-        return _all.apply(this, arguments);
+      function fetchFindFiles(_x, _x2) {
+        return _fetchFindFiles.apply(this, arguments);
       }
 
-      return all;
+      return fetchFindFiles;
     }()
     /**
-     * Creates a Trigger document
+     * Returns a filtered list of documents using a Mango selector.
      *
-     * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggers
-     * @param  {object}  attributes Trigger's attributes
-     * @returns {object}  Stack response, containing trigger document under `data` attribute.
+     * The returned documents are paginated by the stack.
+     *
+     * @param {object}            selector  The Mango selector.
+     * @param {MangoQueryOptions} options   The query options
+     *
+     * @returns {{data, meta, skip, next, bookmark}} The JSON API conformant response.
+     * @throws {FetchError}
      */
 
   }, {
-    key: "create",
+    key: "find",
     value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(attributes) {
-        var path, resp;
+      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(selector) {
+        var options,
+            _options$skip,
+            skip,
+            resp,
+            path,
+            nextLink,
+            nextLinkURL,
+            nextBookmark,
+            _args2 = arguments;
+
         return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
-                path = (0, _utils.uri)(_templateObject());
-                _context2.next = 3;
-                return this.stackClient.fetchJSON('POST', path, {
-                  data: {
-                    attributes: attributes
-                  }
-                });
+                options = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {};
+                _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip;
+                _context2.prev = 2;
+                path = '/files/_find';
+                _context2.next = 6;
+                return this.findWithMango(path, selector, options);
 
-              case 3:
+              case 6:
                 resp = _context2.sent;
+                _context2.next = 12;
+                break;
+
+              case 9:
+                _context2.prev = 9;
+                _context2.t0 = _context2["catch"](2);
+                return _context2.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context2.t0));
+
+              case 12:
+                nextLink = (0, _get.default)(resp, 'links.next', '');
+                nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink));
+                nextBookmark = nextLinkURL.searchParams.get('page[cursor]');
                 return _context2.abrupt("return", {
-                  data: normalizeTrigger(resp.data)
+                  data: resp.data.map(function (f) {
+                    return normalizeFile(f);
+                  }),
+                  meta: resp.meta,
+                  next: resp.meta.count > skip + resp.data.length,
+                  skip: skip,
+                  bookmark: nextBookmark || undefined,
+                  execution_stats: resp.meta.execution_stats
                 });
 
-              case 5:
+              case 16:
               case "end":
                 return _context2.stop();
             }
           }
-        }, _callee2, this);
+        }, _callee2, this, [[2, 9]]);
       }));
 
-      function create(_x) {
-        return _create.apply(this, arguments);
+      function find(_x3) {
+        return _find.apply(this, arguments);
       }
 
-      return create;
+      return find;
     }()
     /**
-     * Deletes a trigger
+     * async findReferencedBy - Returns the list of files referenced by a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/
      *
-     * @see https://docs.cozy.io/en/cozy-stack/jobs/#delete-jobstriggerstrigger-id
-     * @param  {object} document The trigger to delete — must have an _id field
-     * @returns {object} The deleted document
+     * @param  {object}       document          A JSON representing a document, with at least a `_type` and `_id` field.
+     * @param  {object}       options           Additional options
+     * @param  {number|null}  [options.skip]    For skip-based pagination, the number of referenced files to skip.
+     * @param  {number|null}  [options.limit]   For pagination, the number of results to return.
+     * @param  {CouchDBViewCursor|null}  [options.cursor]  For cursor-based pagination, the index cursor.
+     * @returns {{data, included, meta, skip, next, bookmark}} The JSON API conformant response.
      */
 
   }, {
-    key: "destroy",
+    key: "findReferencedBy",
     value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) {
-        var _id;
+      var _findReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) {
+        var _ref3,
+            _ref3$skip,
+            skip,
+            limit,
+            cursor,
+            params,
+            path,
+            url,
+            resp,
+            _args3 = arguments;
 
         return _regenerator.default.wrap(function _callee3$(_context3) {
           while (1) {
             switch (_context3.prev = _context3.next) {
               case 0:
-                _id = document._id;
-
-                if (_id) {
-                  _context3.next = 3;
-                  break;
-                }
-
-                throw new Error('TriggerCollection.destroy needs a document with an _id');
-
-              case 3:
-                _context3.next = 5;
-                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), _id));
+                _ref3 = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref3$skip = _ref3.skip, skip = _ref3$skip === void 0 ? 0 : _ref3$skip, limit = _ref3.limit, cursor = _ref3.cursor;
+                params = {
+                  include: 'files',
+                  'page[limit]': limit,
+                  'page[cursor]': cursor,
+                  sort: 'datetime'
+                };
+                path = (0, _utils.uri)(_templateObject(), document._type, document._id);
+                url = querystring.buildURL(path, params);
+                _context3.next = 6;
+                return this.stackClient.fetchJSON('GET', url);
 
-              case 5:
+              case 6:
+                resp = _context3.sent;
                 return _context3.abrupt("return", {
-                  data: normalizeTrigger(_objectSpread(_objectSpread({}, document), {}, {
-                    _deleted: true
-                  }))
+                  data: normalizeReferences(resp.data),
+                  included: resp.included ? resp.included.map(function (f) {
+                    return normalizeFile(f);
+                  }) : [],
+                  next: (0, _has.default)(resp, 'links.next'),
+                  meta: resp.meta,
+                  skip: skip
                 });
 
-              case 6:
+              case 8:
               case "end":
                 return _context3.stop();
             }
@@ -106747,110 +105683,107 @@ var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) {
         }, _callee3, this);
       }));
 
-      function destroy(_x2) {
-        return _destroy.apply(this, arguments);
+      function findReferencedBy(_x4) {
+        return _findReferencedBy.apply(this, arguments);
       }
 
-      return destroy;
+      return findReferencedBy;
     }()
     /**
+     *  Add referenced_by documents to a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-filesfile-idrelationshipsreferenced_by
      *
-     * Be warned, ATM /jobs/triggers does not return the same informations
-     * than /data/io.cozy.triggers (used by the super.find method).
-     *
-     * See https://github.com/cozy/cozy-stack/pull/2010
+     *  For example, to have an album referenced by a file:
+     * ```
+     * addReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}])
+     * ```
      *
-     * @param {object} selector - Which kind of worker {konnector,service}
-     * @param {object} options - Options
-     * @returns {{data, meta, skip, next}} The JSON API conformant response.
-     * @throws {FetchError}
+     * @param  {FileDocument} document  A JSON representing the file
+     * @param  {Array}  documents       An array of JSON documents having a `_type` and `_id` field.
+     * @returns {{data, meta}}          The JSON API conformant response.
      */
 
   }, {
-    key: "find",
+    key: "addReferencedBy",
     value: function () {
-      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
-        var selector,
-            options,
-            worker,
-            type,
-            rest,
-            hasOnlyWorkerAndType,
-            url,
-            resp,
-            _args4 = arguments;
+      var _addReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, documents) {
+        var refs, resp;
         return _regenerator.default.wrap(function _callee4$(_context4) {
           while (1) {
             switch (_context4.prev = _context4.next) {
               case 0:
-                selector = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
-                options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {};
-                worker = selector.worker, type = selector.type, rest = (0, _objectWithoutProperties2.default)(selector, ["worker", "type"]);
-                hasOnlyWorkerAndType = Object.keys(rest).length === 0;
-
-                if (!hasOnlyWorkerAndType) {
-                  _context4.next = 18;
-                  break;
-                }
-
-                // @see https://github.com/cozy/cozy-stack/blob/master/docs/jobs.md#get-jobstriggers
-                url = "/jobs/triggers?".concat(buildParamsUrl(worker, type));
-                _context4.prev = 6;
-                _context4.next = 9;
-                return this.stackClient.fetchJSON('GET', url);
+                refs = documents.map(function (d) {
+                  return {
+                    id: d._id,
+                    type: d._type
+                  };
+                });
+                _context4.next = 3;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject2(), document._id), {
+                  data: refs
+                });
 
-              case 9:
+              case 3:
                 resp = _context4.sent;
                 return _context4.abrupt("return", {
-                  data: resp.data.map(function (row) {
-                    return normalizeTrigger(row, TRIGGERS_DOCTYPE);
-                  }),
-                  meta: {
-                    count: resp.data.length
-                  },
-                  next: false,
-                  skip: 0
+                  data: normalizeReferences(resp.data),
+                  meta: resp.meta
                 });
 
-              case 13:
-                _context4.prev = 13;
-                _context4.t0 = _context4["catch"](6);
-                return _context4.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context4.t0));
-
-              case 16:
-                _context4.next = 19;
-                break;
-
-              case 18:
-                return _context4.abrupt("return", (0, _get3.default)((0, _getPrototypeOf2.default)(TriggerCollection.prototype), "find", this).call(this, selector, options));
-
-              case 19:
+              case 5:
               case "end":
                 return _context4.stop();
             }
           }
-        }, _callee4, this, [[6, 13]]);
+        }, _callee4, this);
       }));
 
-      function find() {
-        return _find.apply(this, arguments);
+      function addReferencedBy(_x5, _x6) {
+        return _addReferencedBy.apply(this, arguments);
       }
 
-      return find;
+      return addReferencedBy;
     }()
+    /**
+     *  Remove referenced_by documents from a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-filesfile-idrelationshipsreferenced_by
+     *
+     *  For example, to remove an album reference from a file:
+     * ```
+     *  removeReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}])
+     * ```
+     *
+     * @param  {object} document        A JSON representing the file
+     * @param  {Array}  documents       An array of JSON documents having a `_type` and `_id` field.
+     * @returns {{data, meta}}          The JSON API conformant response.
+     */
+
   }, {
-    key: "get",
+    key: "removeReferencedBy",
     value: function () {
-      var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(id) {
+      var _removeReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(document, documents) {
+        var refs, resp;
         return _regenerator.default.wrap(function _callee5$(_context5) {
           while (1) {
             switch (_context5.prev = _context5.next) {
               case 0:
-                return _context5.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject3(), id), {
-                  normalize: normalizeTrigger
-                }));
+                refs = documents.map(function (d) {
+                  return {
+                    id: d._id,
+                    type: d._type
+                  };
+                });
+                _context5.next = 3;
+                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), document._id), {
+                  data: refs
+                });
 
-              case 1:
+              case 3:
+                resp = _context5.sent;
+                return _context5.abrupt("return", {
+                  data: normalizeReferences(resp.data),
+                  meta: resp.meta
+                });
+
+              case 5:
               case "end":
                 return _context5.stop();
             }
@@ -106858,40 +105791,46 @@ var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) {
         }, _callee5, this);
       }));
 
-      function get(_x3) {
-        return _get2.apply(this, arguments);
+      function removeReferencedBy(_x7, _x8) {
+        return _removeReferencedBy.apply(this, arguments);
       }
 
-      return get;
+      return removeReferencedBy;
     }()
     /**
-     * Force given trigger execution.
+     *  Add files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-datatypedoc-idrelationshipsreferences
      *
-     * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggerstrigger-idlaunch
-     * @param {object} trigger Trigger to launch
-     * @returns {object} Stack response, containing job launched by trigger, under `data` attribute.
+     *  For example, to add a photo to an album:
+     * ```
+     *  addReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}])
+     * ```
+     *
+     * @param  {object} document        A JSON representing a document, with at least a `_type` and `_id` field.
+     * @param  {Array}  documents       An array of JSON files having an `_id` field.
+     *
+     * Returns 204 No Content
      */
 
   }, {
-    key: "launch",
+    key: "addReferencesTo",
     value: function () {
-      var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(trigger) {
-        var path, resp;
+      var _addReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document, documents) {
+        var refs;
         return _regenerator.default.wrap(function _callee6$(_context6) {
           while (1) {
             switch (_context6.prev = _context6.next) {
               case 0:
-                path = (0, _utils.uri)(_templateObject4(), trigger._id);
-                _context6.next = 3;
-                return this.stackClient.fetchJSON('POST', path);
-
-              case 3:
-                resp = _context6.sent;
-                return _context6.abrupt("return", {
-                  data: (0, _JobCollection.normalizeJob)(resp.data)
+                refs = documents.map(function (d) {
+                  return {
+                    id: d._id,
+                    type: 'io.cozy.files'
+                  };
                 });
+                return _context6.abrupt("return", this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject4(), document._type, document._id), {
+                  data: refs
+                }));
 
-              case 5:
+              case 2:
               case "end":
                 return _context6.stop();
             }
@@ -106899,1640 +105838,2107 @@ var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) {
         }, _callee6, this);
       }));
 
-      function launch(_x4) {
-        return _launch.apply(this, arguments);
+      function addReferencesTo(_x9, _x10) {
+        return _addReferencesTo.apply(this, arguments);
       }
 
-      return launch;
+      return addReferencesTo;
     }()
+    /**
+     *  Remove files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-datatypedoc-idrelationshipsreferences
+     *
+     *  For example, to remove a photo from an album:
+     * ```
+     *  removeReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}])
+     * ```
+     *
+     * @param  {object} document        A JSON representing a document, with at least a `_type` and `_id` field.
+     * @param  {Array}  documents       An array of JSON files having an `_id` field.
+     *
+     * Returns 204 No Content
+     */
+
   }, {
-    key: "update",
+    key: "removeReferencesTo",
     value: function () {
-      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() {
+      var _removeReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document, documents) {
+        var refs;
         return _regenerator.default.wrap(function _callee7$(_context7) {
           while (1) {
             switch (_context7.prev = _context7.next) {
               case 0:
-                throw new Error('update() method is not available for triggers');
+                refs = documents.map(function (d) {
+                  return {
+                    id: d._id,
+                    type: 'io.cozy.files'
+                  };
+                });
+                return _context7.abrupt("return", this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), document._type, document._id), {
+                  data: refs
+                }));
 
-              case 1:
+              case 2:
               case "end":
                 return _context7.stop();
             }
           }
-        }, _callee7);
+        }, _callee7, this);
       }));
 
-      function update() {
-        return _update.apply(this, arguments);
+      function removeReferencesTo(_x11, _x12) {
+        return _removeReferencesTo.apply(this, arguments);
       }
 
-      return update;
+      return removeReferencesTo;
     }()
-  }]);
-  return TriggerCollection;
-}(_DocumentCollection2.default);
-
-TriggerCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
-var _default = TriggerCollection;
-exports["default"] = _default;
-
-/***/ }),
-/* 670 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var superPropBase = __webpack_require__(671);
-
-function _get(target, property, receiver) {
-  if (typeof Reflect !== "undefined" && Reflect.get) {
-    module.exports = _get = Reflect.get;
-    module.exports["default"] = module.exports, module.exports.__esModule = true;
-  } else {
-    module.exports = _get = function _get(target, property, receiver) {
-      var base = superPropBase(target, property);
-      if (!base) return;
-      var desc = Object.getOwnPropertyDescriptor(base, property);
-
-      if (desc.get) {
-        return desc.get.call(receiver);
-      }
-
-      return desc.value;
-    };
-
-    module.exports["default"] = module.exports, module.exports.__esModule = true;
-  }
-
-  return _get(target, property, receiver || target);
-}
-
-module.exports = _get;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
-
-/***/ }),
-/* 671 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var getPrototypeOf = __webpack_require__(595);
-
-function _superPropBase(object, property) {
-  while (!Object.prototype.hasOwnProperty.call(object, property)) {
-    object = getPrototypeOf(object);
-    if (object === null) break;
-  }
-
-  return object;
-}
-
-module.exports = _superPropBase;
-module.exports["default"] = module.exports, module.exports.__esModule = true;
-
-/***/ }),
-/* 672 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireWildcard = __webpack_require__(510);
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.getSharingRules = exports.BITWARDEN_CIPHERS_DOCTYPE = exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = exports.SHARING_DOCTYPE = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
-
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
-
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
-
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
-
-var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601));
-
-var _FileCollection = __webpack_require__(658);
-
-var _utils = __webpack_require__(611);
-
-function _templateObject6() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]);
-
-  _templateObject6 = function _templateObject6() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject5() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/self"]);
-
-  _templateObject5 = function _templateObject5() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject4() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/", ""]);
-
-  _templateObject4 = function _templateObject4() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject3() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]);
-
-  _templateObject3 = function _templateObject3() {
-    return data;
-  };
-
-  return data;
-}
-
-function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", ""]);
+    /**
+     * Sends file to trash and removes references to it
+     *
+     * @param  {FileDocument} file - File that will be sent to trash
+     * @returns {Promise} - Resolves when references have been removed
+     * and file has been sent to trash
+     */
 
-  _templateObject2 = function _templateObject2() {
-    return data;
-  };
+  }, {
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(file) {
+        var _ref4,
+            _ref4$ifMatch,
+            ifMatch,
+            _id,
+            relationships,
+            _iterator,
+            _step,
+            ref,
+            resp,
+            _args8 = arguments;
 
-  return data;
-}
+        return _regenerator.default.wrap(function _callee8$(_context8) {
+          while (1) {
+            switch (_context8.prev = _context8.next) {
+              case 0:
+                _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {}, _ref4$ifMatch = _ref4.ifMatch, ifMatch = _ref4$ifMatch === void 0 ? '' : _ref4$ifMatch;
+                _id = file._id, relationships = file.relationships;
 
-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; }
+                if (!(relationships && relationships.referenced_by && Array.isArray(relationships.referenced_by.data))) {
+                  _context8.next = 20;
+                  break;
+                }
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+                _iterator = _createForOfIteratorHelper(relationships.referenced_by.data);
+                _context8.prev = 4;
 
-function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/doctype/", ""]);
+                _iterator.s();
 
-  _templateObject = function _templateObject() {
-    return data;
-  };
+              case 6:
+                if ((_step = _iterator.n()).done) {
+                  _context8.next = 12;
+                  break;
+                }
 
-  return data;
-}
+                ref = _step.value;
+                _context8.next = 10;
+                return this.removeReferencesTo({
+                  _id: ref.id,
+                  _type: ref.type
+                }, [{
+                  _id: _id
+                }]);
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+              case 10:
+                _context8.next = 6;
+                break;
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+              case 12:
+                _context8.next = 17;
+                break;
 
-var SHARING_DOCTYPE = 'io.cozy.sharings';
-exports.SHARING_DOCTYPE = SHARING_DOCTYPE;
-var BITWARDEN_ORGANIZATIONS_DOCTYPE = 'com.bitwarden.organizations';
-exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = BITWARDEN_ORGANIZATIONS_DOCTYPE;
-var BITWARDEN_CIPHERS_DOCTYPE = 'com.bitwarden.ciphers';
-exports.BITWARDEN_CIPHERS_DOCTYPE = BITWARDEN_CIPHERS_DOCTYPE;
+              case 14:
+                _context8.prev = 14;
+                _context8.t0 = _context8["catch"](4);
 
-var normalizeSharing = function normalizeSharing(sharing) {
-  return (0, _DocumentCollection2.normalizeDoc)(sharing, SHARING_DOCTYPE);
-};
-/**
- * @typedef {object} Rule A sharing rule
- * @property {string} title
- * @property {string} doctype
- * @property {Array} values
- * @property {string=} add
- * @property {string=} update
- * @property {string=} remove
- */
+                _iterator.e(_context8.t0);
 
-/**
- * @typedef {object} Recipient An io.cozy.contact
- */
+              case 17:
+                _context8.prev = 17;
 
-/**
- * @typedef {object} Sharing An io.cozy.sharings document
- */
+                _iterator.f();
 
-/**
- * @typedef {object} SharingPolicy Define the add/update/remove policies for a sharing
- * @property {string} add
- * @property {string} update
- * @property {string} remove
- */
+                return _context8.finish(17);
 
-/**
- * @typedef {(undefined|'one-way'|'two-way')} SharingType Define how a document is synced between sharing's owner and receivers.
- */
+              case 20:
+                _context8.next = 22;
+                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), _id), undefined, {
+                  headers: {
+                    'If-Match': ifMatch
+                  }
+                });
 
-/**
- * @typedef {object} RelationshipItem Define a recipient that can be used as target of a sharing
- * @property {string} id - Recipient's ID
- * @property {string} type - Reciptient's type (should be 'io.cozy.contacts')
- */
+              case 22:
+                resp = _context8.sent;
+                return _context8.abrupt("return", {
+                  data: normalizeFile(resp.data)
+                });
 
-/**
- * Implements the `DocumentCollection` API along with specific methods for
- * `io.cozy.sharings`.
- */
+              case 24:
+              case "end":
+                return _context8.stop();
+            }
+          }
+        }, _callee8, this, [[4, 14, 17, 20]]);
+      }));
 
+      function destroy(_x13) {
+        return _destroy.apply(this, arguments);
+      }
 
-var SharingCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(SharingCollection, _DocumentCollection);
+      return destroy;
+    }()
+    /**
+     * Empty the Trash
+     */
 
-  var _super = _createSuper(SharingCollection);
+  }, {
+    key: "emptyTrash",
+    value: function emptyTrash() {
+      return this.stackClient.fetchJSON('DELETE', '/files/trash');
+    }
+    /**
+     * Restores a trashed file.
+     *
+     * @param {string} id   - The file's id
+     * @returns {Promise}   - A promise that returns the restored file if resolved.
+     * @throws {FetchError}
+     *
+     */
 
-  function SharingCollection() {
-    (0, _classCallCheck2.default)(this, SharingCollection);
-    return _super.apply(this, arguments);
-  }
+  }, {
+    key: "restore",
+    value: function restore(id) {
+      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), id));
+    }
+    /**
+     * async deleteFilePermanently - Definitely delete a file
+     *
+     * @param  {string} id - The id of the file to delete
+     * @returns {object} The deleted file object
+     */
 
-  (0, _createClass2.default)(SharingCollection, [{
-    key: "findByDoctype",
+  }, {
+    key: "deleteFilePermanently",
     value: function () {
-      var _findByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(doctype) {
+      var _deleteFilePermanently = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(id) {
         var resp;
-        return _regenerator.default.wrap(function _callee$(_context) {
+        return _regenerator.default.wrap(function _callee9$(_context9) {
           while (1) {
-            switch (_context.prev = _context.next) {
+            switch (_context9.prev = _context9.next) {
               case 0:
-                _context.next = 2;
-                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), doctype));
+                _context9.next = 2;
+                return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject8(), id), {
+                  data: {
+                    type: 'io.cozy.files',
+                    id: id,
+                    attributes: {
+                      permanent_delete: true
+                    }
+                  }
+                });
 
               case 2:
-                resp = _context.sent;
-                return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
-                  data: resp.data.map(normalizeSharing)
-                }));
+                resp = _context9.sent;
+                return _context9.abrupt("return", resp.data);
 
               case 4:
               case "end":
-                return _context.stop();
+                return _context9.stop();
             }
           }
-        }, _callee, this);
+        }, _callee9, this);
       }));
 
-      function findByDoctype(_x) {
-        return _findByDoctype.apply(this, arguments);
+      function deleteFilePermanently(_x14) {
+        return _deleteFilePermanently.apply(this, arguments);
       }
 
-      return findByDoctype;
+      return deleteFilePermanently;
     }()
     /**
-     * Fetches a sharing by id
-     *
-     * @param {string} id Sharing's id
-     * @returns {Sharing} sharing
+     * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded
+     * @param {string} dirPath Path to upload the file to. ie : /Administative/XXX/
+     * @returns {object} Created io.cozy.files
      */
 
   }, {
-    key: "get",
+    key: "upload",
     value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
-        var path, resp;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
+      var _upload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data, dirPath) {
+        var dirId;
+        return _regenerator.default.wrap(function _callee10$(_context10) {
           while (1) {
-            switch (_context2.prev = _context2.next) {
+            switch (_context10.prev = _context10.next) {
               case 0:
-                path = (0, _utils.uri)(_templateObject2(), id);
-                _context2.next = 3;
-                return this.stackClient.fetchJSON('GET', path);
+                _context10.next = 2;
+                return this.ensureDirectoryExists(dirPath);
 
-              case 3:
-                resp = _context2.sent;
-                return _context2.abrupt("return", {
-                  data: normalizeSharing(resp.data)
-                });
+              case 2:
+                dirId = _context10.sent;
+                return _context10.abrupt("return", this.createFile(data, {
+                  dirId: dirId
+                }));
 
-              case 5:
+              case 4:
               case "end":
-                return _context2.stop();
+                return _context10.stop();
             }
           }
-        }, _callee2, this);
+        }, _callee10, this);
       }));
 
-      function get(_x2) {
-        return _get.apply(this, arguments);
+      function upload(_x15, _x16) {
+        return _upload.apply(this, arguments);
       }
 
-      return get;
+      return upload;
     }()
     /**
+     * Creates directory or file.
+     * - Used by StackLink to support CozyClient.create('io.cozy.files', options)
      *
-     * Creates a new Sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings
-     *
-     * @param {object} params Sharing  params
-     * @param {Sharing} params.document The document to share
-     * @param {string} params.description Description of the sharing
-     * @param {string=} params.previewPath The preview path
-     * @param {Array<Rule>=} params.rules The rules defined to the sharing. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
-     * @param {Array<Recipient>=} params.recipients Recipients to add to the sharings (will have the same permissions given by the rules defined by the sharing )
-     * @param {Array<Recipient>=} params.readOnlyRecipients Recipients to add to the sharings with only read only access
-     * @param {boolean=} params.openSharing If someone else than the owner can add a recipient to the sharing
-     * @param {string=} params.appSlug Slug of the targeted app
+     * @param {FileAttributes|DirectoryAttributes} attributes - Attributes of the created file/directory
+     * @param {File|Blob|string|ArrayBuffer} attributes.data Will be used as content of the created file
+     * @throws {Error} - explaining reason why creation failed
      */
 
   }, {
     key: "create",
     value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref) {
-        var document, description, previewPath, rules, _ref$recipients, recipients, _ref$readOnlyRecipien, readOnlyRecipients, openSharing, appSlug, attributes, optionalAttributes, resp;
-
-        return _regenerator.default.wrap(function _callee3$(_context3) {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(attributes) {
+        var data, createFileOptions;
+        return _regenerator.default.wrap(function _callee11$(_context11) {
           while (1) {
-            switch (_context3.prev = _context3.next) {
+            switch (_context11.prev = _context11.next) {
               case 0:
-                document = _ref.document, description = _ref.description, previewPath = _ref.previewPath, rules = _ref.rules, _ref$recipients = _ref.recipients, recipients = _ref$recipients === void 0 ? [] : _ref$recipients, _ref$readOnlyRecipien = _ref.readOnlyRecipients, readOnlyRecipients = _ref$readOnlyRecipien === void 0 ? [] : _ref$readOnlyRecipien, openSharing = _ref.openSharing, appSlug = _ref.appSlug;
-                attributes = {
-                  description: description,
-                  preview_path: previewPath,
-                  open_sharing: openSharing,
-                  rules: rules ? rules : getSharingRules(document)
-                };
-                optionalAttributes = {};
-
-                if (appSlug) {
-                  optionalAttributes = {
-                    app_slug: appSlug
-                  };
+                if (!(attributes.type === 'directory')) {
+                  _context11.next = 4;
+                  break;
                 }
 
-                _context3.next = 6;
-                return this.stackClient.fetchJSON('POST', '/sharings/', {
-                  data: {
-                    type: 'io.cozy.sharings',
-                    attributes: _objectSpread(_objectSpread({}, attributes), optionalAttributes),
-                    relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && {
-                      recipients: {
-                        data: recipients.map(toRelationshipItem)
-                      }
-                    }), readOnlyRecipients.length > 0 && {
-                      read_only_recipients: {
-                        data: readOnlyRecipients.map(toRelationshipItem)
-                      }
-                    })
-                  }
-                });
+                return _context11.abrupt("return", this.createDirectory(attributes));
 
-              case 6:
-                resp = _context3.sent;
-                return _context3.abrupt("return", {
-                  data: normalizeSharing(resp.data)
-                });
+              case 4:
+                data = attributes.data, createFileOptions = (0, _objectWithoutProperties2.default)(attributes, ["data"]);
+                return _context11.abrupt("return", this.createFile(data, createFileOptions));
 
-              case 8:
+              case 6:
               case "end":
-                return _context3.stop();
+                return _context11.stop();
             }
           }
-        }, _callee3, this);
+        }, _callee11, this);
       }));
 
-      function create(_x3) {
+      function create(_x17) {
         return _create.apply(this, arguments);
       }
 
       return create;
     }()
-    /**
-     * @deprecated Use create() instead
-     * share - Creates a new sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings
+    /***
+     * Updates an existing file or directory
      *
-     * @param  {Sharing} document The document to share. Should have and _id and a name.
-     * @param  {Array} recipients A list of io.cozy.contacts
-     * @param  {string} sharingType - If "two-way", will set the open_sharing attribute to true
-     * @param  {string} description - Describes the sharing
-     * @param  {string=} previewPath Relative URL of the sharings preview page
+     * Used by StackLink to support CozyClient.save({file}).
+     * Update the binary file if a `data` param is passed. Only updates
+     * attributes otherwise.
+     *
+     * @param {FileAttributes} file - The file with its new content
+     * @param {File|Blob|string|ArrayBuffer} attributes.data Will be used as content of the updated file
+     * @returns {FileAttributes} Updated document
+     * @throws {Error} - explaining reason why update failed
      */
 
   }, {
-    key: "share",
+    key: "update",
     value: function () {
-      var _share = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, recipients, sharingType, description) {
-        var previewPath,
-            recipientsToUse,
-            _args4 = arguments;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
+      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(attributes) {
+        var data, updateFileOptions, fileId;
+        return _regenerator.default.wrap(function _callee12$(_context12) {
           while (1) {
-            switch (_context4.prev = _context4.next) {
+            switch (_context12.prev = _context12.next) {
               case 0:
-                previewPath = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : null;
-                console.warn('SharingCollection.share is deprecated, use SharingCollection.create instead');
-                recipientsToUse = sharingType === 'two-way' ? {
-                  recipients: recipients
-                } : {
-                  readOnlyRecipients: recipients
-                };
-                return _context4.abrupt("return", this.create(_objectSpread(_objectSpread({
-                  document: document
-                }, recipientsToUse), {}, {
-                  description: description,
-                  previewPath: previewPath,
-                  openSharing: sharingType === 'two-way',
-                  rules: getSharingRules(document, sharingType)
-                })));
+                data = attributes.data, updateFileOptions = (0, _objectWithoutProperties2.default)(attributes, ["data"]);
+                fileId = attributes.id || attributes._id;
 
-              case 4:
+                if (!data) {
+                  _context12.next = 7;
+                  break;
+                }
+
+                if (!(attributes.type === 'directory')) {
+                  _context12.next = 5;
+                  break;
+                }
+
+                throw new Error('You cannot pass a data object for a directory');
+
+              case 5:
+                updateFileOptions.fileId = fileId;
+                return _context12.abrupt("return", this.updateFile(data, updateFileOptions));
+
+              case 7:
+                return _context12.abrupt("return", this.updateAttributes(fileId, attributes));
+
+              case 8:
               case "end":
-                return _context4.stop();
+                return _context12.stop();
             }
           }
-        }, _callee4, this);
+        }, _callee12, this);
       }));
 
-      function share(_x4, _x5, _x6, _x7) {
-        return _share.apply(this, arguments);
+      function update(_x18) {
+        return _update.apply(this, arguments);
       }
 
-      return share;
+      return update;
     }()
     /**
-     * getDiscoveryLink - Returns the URL of the page that can be used to accept a sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#get-sharingssharing-iddiscovery
-     *
-     * @param  {string} sharingId - Id of the sharing
-     * @param  {string} sharecode - Code of the sharing
-     * @returns {string}
-     */
-
-  }, {
-    key: "getDiscoveryLink",
-    value: function getDiscoveryLink(sharingId, sharecode) {
-      return this.stackClient.fullpath("/sharings/".concat(sharingId, "/discovery?sharecode=").concat(sharecode));
-    }
-    /**
-     * Add an array of contacts to the Sharing
+     * Creates a file
      *
-     * @param {object} options Object
-     * @param {Sharing} options.document Sharing Object
-     * @param {Array<Recipient>=} options.recipients Recipients to add to the sharing
-     * @param {Array<Recipient>=} options.readOnlyRecipients Recipients to add to the sharings with only read only access
+     * @private
+     * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded
+     * @param {FileAttributes} params Additional parameters
+     * @param  {object}  params.options     Options to pass to doUpload method (additional headers)
+     * @throws {Error} - explaining reason why creation failed
      */
 
   }, {
-    key: "addRecipients",
+    key: "createFile",
     value: function () {
-      var _addRecipients = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(_ref2) {
-        var document, _ref2$recipients, recipients, _ref2$readOnlyRecipie, readOnlyRecipients, resp;
+      var _createFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(data) {
+        var _ref5,
+            nameOption,
+            _ref5$dirId,
+            dirId,
+            _ref5$executable,
+            executable,
+            _ref5$encrypted,
+            encrypted,
+            metadata,
+            options,
+            name,
+            metadataId,
+            meta,
+            size,
+            path,
+            _args13 = arguments;
 
-        return _regenerator.default.wrap(function _callee5$(_context5) {
+        return _regenerator.default.wrap(function _callee13$(_context13) {
           while (1) {
-            switch (_context5.prev = _context5.next) {
+            switch (_context13.prev = _context13.next) {
               case 0:
-                document = _ref2.document, _ref2$recipients = _ref2.recipients, recipients = _ref2$recipients === void 0 ? [] : _ref2$recipients, _ref2$readOnlyRecipie = _ref2.readOnlyRecipients, readOnlyRecipients = _ref2$readOnlyRecipie === void 0 ? [] : _ref2$readOnlyRecipie;
-                _context5.next = 3;
-                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), document._id), {
-                  data: {
-                    type: 'io.cozy.sharings',
-                    id: document._id,
-                    relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && {
-                      recipients: {
-                        data: recipients.map(toRelationshipItem)
-                      }
-                    }), readOnlyRecipients.length > 0 && {
-                      read_only_recipients: {
-                        data: readOnlyRecipients.map(toRelationshipItem)
-                      }
-                    })
-                  }
-                });
+                _ref5 = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {};
+                nameOption = _ref5.name, _ref5$dirId = _ref5.dirId, dirId = _ref5$dirId === void 0 ? '' : _ref5$dirId, _ref5$executable = _ref5.executable, executable = _ref5$executable === void 0 ? false : _ref5$executable, _ref5$encrypted = _ref5.encrypted, encrypted = _ref5$encrypted === void 0 ? false : _ref5$encrypted, metadata = _ref5.metadata, options = (0, _objectWithoutProperties2.default)(_ref5, ["name", "dirId", "executable", "encrypted", "metadata"]);
+                name = nameOption; // handle case where data is a file and contains the name
 
-              case 3:
-                resp = _context5.sent;
-                return _context5.abrupt("return", {
-                  data: normalizeSharing(resp.data)
-                });
+                if (!name && typeof data.name === 'string') {
+                  name = data.name;
+                }
 
-              case 5:
+                name = sanitizeAndValidateFileName(name);
+                metadataId = '';
+
+                if (!metadata) {
+                  _context13.next = 11;
+                  break;
+                }
+
+                _context13.next = 9;
+                return this.createFileMetadata(metadata);
+
+              case 9:
+                meta = _context13.sent;
+                metadataId = meta.data.id;
+
+              case 11:
+                size = '';
+
+                if (options.contentLength) {
+                  size = String(options.contentLength);
+                }
+
+                path = (0, _utils.uri)(_templateObject9(), dirId, name, executable, encrypted, metadataId, size);
+                return _context13.abrupt("return", this.doUpload(data, path, options));
+
+              case 15:
               case "end":
-                return _context5.stop();
+                return _context13.stop();
             }
           }
-        }, _callee5, this);
+        }, _callee13, this);
       }));
 
-      function addRecipients(_x8) {
-        return _addRecipients.apply(this, arguments);
+      function createFile(_x19) {
+        return _createFile.apply(this, arguments);
       }
 
-      return addRecipients;
+      return createFile;
     }()
     /**
-     * Revoke only one recipient of the sharing.
-     *
-     * @param {object} sharing Sharing Object
-     * @param {number} recipientIndex Index of this recipient in the members array of the sharing
-     */
-
-  }, {
-    key: "revokeRecipient",
-    value: function revokeRecipient(sharing, recipientIndex) {
-      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject4(), sharing._id, recipientIndex));
-    }
-    /**
-     * Remove self from the sharing.
-     *
-     * @param {object} sharing Sharing Object
-     */
-
-  }, {
-    key: "revokeSelf",
-    value: function revokeSelf(sharing) {
-      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), sharing._id));
-    }
-    /**
-     * Revoke the sharing for all the members. Must be called
-     * from the owner's cozy
+     * updateFile - Updates a file's data
      *
-     * @param {object} sharing Sharing Objects
+     * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded
+     * @param {FileAttributes} params       Additional parameters
+     * @param  {object}  params.options     Options to pass to doUpload method (additional headers)
+     * @returns {object}                    Updated document
+     * @throws {Error} - explaining reason why update failed
      */
 
   }, {
-    key: "revokeAllRecipients",
-    value: function revokeAllRecipients(sharing) {
-      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), sharing._id));
-    }
-  }]);
-  return SharingCollection;
-}(_DocumentCollection2.default);
-
-SharingCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+    key: "updateFile",
+    value: function () {
+      var _updateFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(data) {
+        var _ref6,
+            _ref6$executable,
+            executable,
+            _ref6$encrypted,
+            encrypted,
+            fileId,
+            _ref6$name,
+            name,
+            metadata,
+            options,
+            fileName,
+            sanitizedName,
+            metadataId,
+            path,
+            meta,
+            size,
+            _args14 = arguments;
 
-var getSharingRulesWithoutWarning = function getSharingRulesWithoutWarning(document, sharingType) {
-  if ((0, _FileCollection.isFile)(document)) {
-    return getSharingRulesForFile(document, sharingType);
-  }
+        return _regenerator.default.wrap(function _callee14$(_context14) {
+          while (1) {
+            switch (_context14.prev = _context14.next) {
+              case 0:
+                _ref6 = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {};
+                _ref6$executable = _ref6.executable, executable = _ref6$executable === void 0 ? false : _ref6$executable, _ref6$encrypted = _ref6.encrypted, encrypted = _ref6$encrypted === void 0 ? false : _ref6$encrypted, fileId = _ref6.fileId, _ref6$name = _ref6.name, name = _ref6$name === void 0 ? '' : _ref6$name, metadata = _ref6.metadata, options = (0, _objectWithoutProperties2.default)(_ref6, ["executable", "encrypted", "fileId", "name", "metadata"]);
 
-  if (document._type === BITWARDEN_ORGANIZATIONS_DOCTYPE) {
-    return getSharingRulesForOrganizations(document);
-  }
+                if (!(!fileId || typeof fileId !== 'string')) {
+                  _context14.next = 4;
+                  break;
+                }
 
-  return getSharingRulesForPhotosAlbum(document, sharingType);
-};
-/**
- * Rules determine the behavior of the sharing when changes are made to the shared document
- * See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
- *
- * @param {Sharing} document - The document to share. Should have and _id and a name
- * @param  {SharingType} sharingType - The type of the sharing
- *
- * @returns {Array<Rule>=} The rules that define how to share the document
- */
+                throw new Error('missing fileId argument');
 
+              case 4:
+                // name might be set in a File object
+                fileName = name || data.name;
 
-var getSharingRules = function getSharingRules(document, sharingType) {
-  if (sharingType) {
-    console.warn("sharingType is deprecated and will be removed. We now set this default rules: ".concat(getSharingRulesWithoutWarning(document), "} \n      \n      If this default rules do not fill your need, please set custom rules \n      by using the 'rules' object of the SharingCollection.create() method"));
-  }
+                if (!(!fileName || typeof fileName !== 'string')) {
+                  _context14.next = 7;
+                  break;
+                }
 
-  return getSharingRulesWithoutWarning(document, sharingType);
-};
-/**
- * Compute the rules that define how to share a Photo Album. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
- *
- * @param {Sharing} document - The document to share. Should have and _id and a name
- * @param  {SharingType} sharingType - The type of the sharing
- *
- * @returns {Array<Rule>=} The rules that define how to share a Photo Album
- */
+                throw new Error('missing name in data argument');
 
+              case 7:
+                sanitizedName = sanitizeAndValidateFileName(fileName);
+                /**
+                 * We already use the body to send the content of the file. So we have 2 choices :
+                 * Use an object in a query string to send the metadata
+                 * create a new header http
+                 * In both case, we have a size limitation depending of the browser.
+                 *
+                 * So we had this current workaround where we create the metadata before
+                 * (no size limit since we can use the body for that) and after we use the ID.
+                 */
 
-exports.getSharingRules = getSharingRules;
+                path = (0, _utils.uri)(_templateObject10(), fileId, sanitizedName, executable, encrypted);
 
-var getSharingRulesForPhotosAlbum = function getSharingRulesForPhotosAlbum(document, sharingType) {
-  var _id = document._id,
-      _type = document._type;
-  return [_objectSpread({
-    title: 'collection',
-    doctype: _type,
-    values: [_id]
-  }, getSharingPolicyForAlbum(sharingType)), _objectSpread({
-    title: 'items',
-    doctype: 'io.cozy.files',
-    values: ["".concat(_type, "/").concat(_id)],
-    selector: 'referenced_by'
-  }, getSharingPolicyForReferencedFiles(sharingType))];
-};
-/**
- * Compute the sharing policy for a ReferencedFile based on its sharing type
- *
- * @param  {SharingType} sharingType - The type of the sharing
- *
- * @returns {SharingPolicy} The sharing policy for the ReferencedFile
- */
+                if (!metadata) {
+                  _context14.next = 15;
+                  break;
+                }
 
+                _context14.next = 12;
+                return this.createFileMetadata(metadata);
 
-var getSharingPolicyForReferencedFiles = function getSharingPolicyForReferencedFiles(sharingType) {
-  return sharingType === 'two-way' ? {
-    add: 'sync',
-    update: 'sync',
-    remove: 'sync'
-  } : {
-    add: 'push',
-    update: 'none',
-    remove: 'push'
-  };
-};
-/**
- * Compute the sharing policy for an Album based on its sharing type
- *
- * @param  {SharingType} sharingType - The type of the sharing
- *
- * @returns {Array<Rule>=} The sharing policy for the Album
- */
+              case 12:
+                meta = _context14.sent;
+                metadataId = meta.data.id;
+                path = path + "&MetadataID=".concat(metadataId);
 
+              case 15:
+                size = '';
 
-var getSharingPolicyForAlbum = function getSharingPolicyForAlbum(sharingType) {
-  if (!sharingType) return {
-    update: 'sync',
-    remove: 'revoke'
-  };
-  return sharingType === 'two-way' ? {
-    update: 'sync',
-    remove: 'revoke'
-  } : {
-    update: 'push',
-    remove: 'revoke'
-  };
-};
-/**
- * Compute the rules that define how to share a File. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
- *
- * @param {Sharing} document - The document to share. Should have and _id and a name
- * @param  {SharingType} sharingType - The type of the sharing
- *
- * @returns {Array<Rule>=} The rules that define how to share a File
- */
+                if (options.contentLength) {
+                  size = String(options.contentLength);
+                  path = path + "&Size=".concat(size);
+                }
 
+                return _context14.abrupt("return", this.doUpload(data, path, options, 'PUT'));
 
-var getSharingRulesForFile = function getSharingRulesForFile(document, sharingType) {
-  var _id = document._id,
-      name = document.name;
-  return [_objectSpread({
-    title: name,
-    doctype: 'io.cozy.files',
-    values: [_id]
-  }, getSharingPolicyForFile(document, sharingType))];
-};
-/**
- * Compute the sharing policy for a File based on its sharing type
- *
- * @param {Sharing} document - The document to share. Should have and _id and a name
- * @param {SharingType} sharingType - The type of the sharing
- *
- * @returns {SharingPolicy} The sharing policy for the File
- */
+              case 18:
+              case "end":
+                return _context14.stop();
+            }
+          }
+        }, _callee14, this);
+      }));
 
+      function updateFile(_x20) {
+        return _updateFile.apply(this, arguments);
+      }
 
-var getSharingPolicyForFile = function getSharingPolicyForFile(document, sharingType) {
-  if ((0, _FileCollection.isDirectory)(document)) {
-    if (!sharingType) return {
-      add: 'sync',
-      update: 'sync',
-      remove: 'sync'
-    };
-    return sharingType === 'two-way' ? {
-      add: 'sync',
-      update: 'sync',
-      remove: 'sync'
-    } : {
-      add: 'push',
-      update: 'push',
-      remove: 'push'
-    };
-  }
+      return updateFile;
+    }()
+  }, {
+    key: "getDownloadLinkById",
+    value: function getDownloadLinkById(id, filename) {
+      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject11(), id, filename)).then(this.extractResponseLinkRelated);
+    }
+  }, {
+    key: "getDownloadLinkByRevision",
+    value: function getDownloadLinkByRevision(versionId, filename) {
+      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject12(), versionId, filename)).then(this.extractResponseLinkRelated);
+    }
+  }, {
+    key: "getDownloadLinkByPath",
+    value: function getDownloadLinkByPath(path) {
+      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject13(), path)).then(this.extractResponseLinkRelated);
+    }
+  }, {
+    key: "download",
 
-  if (!sharingType) return {
-    update: 'sync',
-    remove: 'revoke'
-  };
-  return sharingType === 'two-way' ? {
-    update: 'sync',
-    remove: 'revoke'
-  } : {
-    update: 'push',
-    remove: 'revoke'
-  };
-};
-/**
- * Compute the rules that define how to share an Organization. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
- *
- * @param {Sharing} document The document to share. Should have and _id and a name
- *
- * @returns {Array<Rule>=} The rules that define how to share an Organization
- */
+    /**
+     * Download a file or a specific version of the file
+     *
+     * @param {object} file io.cozy.files object
+     * @param {string} versionId Id of the io.cozy.files.version
+     * @param {string} filename The name you want for the downloaded file
+     *                            (by default the same as the file)
+     */
+    value: function () {
+      var _download = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(file) {
+        var versionId,
+            filename,
+            href,
+            filenameToUse,
+            _args15 = arguments;
+        return _regenerator.default.wrap(function _callee15$(_context15) {
+          while (1) {
+            switch (_context15.prev = _context15.next) {
+              case 0:
+                versionId = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : null;
+                filename = _args15.length > 2 && _args15[2] !== undefined ? _args15[2] : undefined;
+                filenameToUse = filename ? filename : file.name;
+                /**
+                 * Passing a filename to forceFileDownload is not enough
+                 * for a few browsers since the stack's response header will
+                 * not contain that name. Passing the filename to
+                 * getDownloadLinkBy{Id,Revision} will ask the stack to
+                 * return this filename in its content-disposition
+                 * header response
+                 */
 
+                if (versionId) {
+                  _context15.next = 9;
+                  break;
+                }
 
-var getSharingRulesForOrganizations = function getSharingRulesForOrganizations(document) {
-  var _id = document._id,
-      name = document.name;
-  var sharingRules = [{
-    title: name,
-    doctype: BITWARDEN_ORGANIZATIONS_DOCTYPE,
-    values: [_id],
-    add: 'sync',
-    update: 'sync',
-    remove: 'revoke'
-  }, {
-    title: 'Ciphers',
-    doctype: BITWARDEN_CIPHERS_DOCTYPE,
-    values: [_id],
-    add: 'sync',
-    update: 'sync',
-    remove: 'sync',
-    selector: 'organization_id'
-  }];
-  return sharingRules;
-};
-/**
- * Compute the RelationshipItem that can be referenced as a sharing recipient
- *
- * @param {Recipient} item The recipient of a sharing
- *
- * @returns {RelationshipItem} The RelationshipItem that can be referenced as a sharing recipient
- */
+                _context15.next = 6;
+                return this.getDownloadLinkById(file._id, filenameToUse);
 
+              case 6:
+                href = _context15.sent;
+                _context15.next = 12;
+                break;
 
-var toRelationshipItem = function toRelationshipItem(item) {
-  return {
-    id: item._id,
-    type: item._type
-  };
-};
+              case 9:
+                _context15.next = 11;
+                return this.getDownloadLinkByRevision(versionId, filenameToUse);
 
-var _default = SharingCollection;
-exports["default"] = _default;
+              case 11:
+                href = _context15.sent;
 
-/***/ }),
-/* 673 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+              case 12:
+                this.forceFileDownload("".concat(href, "?Dl=1"), filenameToUse);
 
-"use strict";
+              case 13:
+              case "end":
+                return _context15.stop();
+            }
+          }
+        }, _callee15, this);
+      }));
 
+      function download(_x21) {
+        return _download.apply(this, arguments);
+      }
 
-var _interopRequireWildcard = __webpack_require__(510);
+      return download;
+    }()
+  }, {
+    key: "fetchFileContent",
+    value: function () {
+      var _fetchFileContent = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16(id) {
+        return _regenerator.default.wrap(function _callee16$(_context16) {
+          while (1) {
+            switch (_context16.prev = _context16.next) {
+              case 0:
+                console.warn('FileCollection.fetchFileContent() is deprecated. Use FileCollection.fetchFileContentById() instead');
+                return _context16.abrupt("return", this.fetchFileContentById(id));
 
-var _interopRequireDefault = __webpack_require__(512);
+              case 2:
+              case "end":
+                return _context16.stop();
+            }
+          }
+        }, _callee16, this);
+      }));
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.getPermissionsFor = void 0;
+      function fetchFileContent(_x22) {
+        return _fetchFileContent.apply(this, arguments);
+      }
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+      return fetchFileContent;
+    }()
+    /**
+     * Fetch the binary of a file or a specific version of a file
+     * Useful for instance when you can't download the file directly
+     * (via a content-disposition attachement header) and need to store
+     * it before doing an operation.
+     *
+     * @param {string} id Id of the io.cozy.files or io.cozy.files.version
+     *
+     */
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+  }, {
+    key: "fetchFileContentById",
+    value: function () {
+      var _fetchFileContentById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(id) {
+        return _regenerator.default.wrap(function _callee17$(_context17) {
+          while (1) {
+            switch (_context17.prev = _context17.next) {
+              case 0:
+                return _context17.abrupt("return", this.stackClient.fetch('GET', "/files/download/".concat(id)));
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
+              case 1:
+              case "end":
+                return _context17.stop();
+            }
+          }
+        }, _callee17, this);
+      }));
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+      function fetchFileContentById(_x23) {
+        return _fetchFileContentById.apply(this, arguments);
+      }
 
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
+      return fetchFileContentById;
+    }()
+    /**
+     * Get a beautified size for a given file
+     * 1024B => 1KB
+     * 102404500404B => 95.37 GB
+     *
+     * @param {object} file io.cozy.files object
+     * @param {number} decimal number of decimal
+     */
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+  }, {
+    key: "getBeautifulSize",
+    value: function getBeautifulSize(file, decimal) {
+      return (0, _utils.formatBytes)(parseInt(file.size), decimal);
+    }
+  }, {
+    key: "downloadArchive",
+    value: function () {
+      var _downloadArchive = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(fileIds) {
+        var notSecureFilename,
+            filename,
+            href,
+            fullpath,
+            _args18 = arguments;
+        return _regenerator.default.wrap(function _callee18$(_context18) {
+          while (1) {
+            switch (_context18.prev = _context18.next) {
+              case 0:
+                notSecureFilename = _args18.length > 1 && _args18[1] !== undefined ? _args18[1] : 'files';
+                filename = (0, _utils.slugify)(notSecureFilename);
+                _context18.next = 4;
+                return this.getArchiveLinkByIds(fileIds, filename);
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+              case 4:
+                href = _context18.sent;
+                fullpath = this.stackClient.fullpath(href);
+                this.forceFileDownload(fullpath, filename + '.zip');
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+              case 7:
+              case "end":
+                return _context18.stop();
+            }
+          }
+        }, _callee18, this);
+      }));
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+      function downloadArchive(_x24) {
+        return _downloadArchive.apply(this, arguments);
+      }
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+      return downloadArchive;
+    }()
+  }, {
+    key: "getArchiveLinkByIds",
+    value: function () {
+      var _getArchiveLinkByIds = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(ids) {
+        var name,
+            resp,
+            _args19 = arguments;
+        return _regenerator.default.wrap(function _callee19$(_context19) {
+          while (1) {
+            switch (_context19.prev = _context19.next) {
+              case 0:
+                name = _args19.length > 1 && _args19[1] !== undefined ? _args19[1] : 'files';
+                _context19.next = 3;
+                return this.stackClient.fetchJSON('POST', '/files/archive', {
+                  data: {
+                    type: 'io.cozy.archives',
+                    attributes: {
+                      name: name,
+                      ids: ids
+                    }
+                  }
+                });
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+              case 3:
+                resp = _context19.sent;
+                return _context19.abrupt("return", resp.links.related);
 
-var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601));
+              case 5:
+              case "end":
+                return _context19.stop();
+            }
+          }
+        }, _callee19, this);
+      }));
 
-var _FileCollection = __webpack_require__(658);
+      function getArchiveLinkByIds(_x25) {
+        return _getArchiveLinkByIds.apply(this, arguments);
+      }
 
-var _utils = __webpack_require__(611);
+      return getArchiveLinkByIds;
+    }()
+    /**
+     * Checks if the file belongs to the parent's hierarchy.
+     *
+     * @param  {string|object}  child    The file which can either be an id or an object
+     * @param  {string|object}  parent   The parent target which can either be an id or an object
+     * @returns {boolean}                 Whether the file is a parent's child
+     */
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+  }, {
+    key: "isChildOf",
+    value: function () {
+      var _isChildOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(child, parent) {
+        var _this2 = this;
 
-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); }
+        var _ref7, childID, childDirID, childPath, _ref8, parentID, childDoc, currPath, targetsPath, newPath;
 
-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; }
+        return _regenerator.default.wrap(function _callee20$(_context20) {
+          while (1) {
+            switch (_context20.prev = _context20.next) {
+              case 0:
+                _ref7 = typeof child === 'object' ? child : {
+                  _id: child
+                }, childID = _ref7._id, childDirID = _ref7.dirID, childPath = _ref7.path;
+                _ref8 = typeof parent === 'object' ? parent : {
+                  _id: parent
+                }, parentID = _ref8._id;
 
-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; }
+                if (!(childID === parentID || childDirID === parentID)) {
+                  _context20.next = 4;
+                  break;
+                }
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+                return _context20.abrupt("return", true);
 
-function _templateObject3() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/permissions/doctype/", "/shared-by-link"]);
+              case 4:
+                if (childPath) {
+                  _context20.next = 10;
+                  break;
+                }
 
-  _templateObject3 = function _templateObject3() {
-    return data;
-  };
+                _context20.next = 7;
+                return this.statById(childID);
 
-  return data;
-}
+              case 7:
+                childDoc = _context20.sent;
+                childPath = childDoc.data.path;
+                childDirID = childDoc.data.dirID;
 
-function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]);
+              case 10:
+                // Build hierarchy paths
+                currPath = childPath;
+                targetsPath = [childPath];
 
-  _templateObject2 = function _templateObject2() {
-    return data;
-  };
+                while (currPath != '') {
+                  newPath = dirName(currPath);
 
-  return data;
-}
+                  if (newPath != '') {
+                    targetsPath.push(newPath);
+                  }
 
-function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]);
+                  currPath = newPath;
+                }
 
-  _templateObject = function _templateObject() {
-    return data;
-  };
+                targetsPath.reverse(); // Look for all hierarchy in parallel and return true as soon as a dir is the searched parent
 
-  return data;
-}
+                return _context20.abrupt("return", raceWithCondition(targetsPath.map(function (path) {
+                  return _this2.statByPath(path);
+                }), function (stat) {
+                  return stat.data._id == parentID;
+                }));
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+              case 15:
+              case "end":
+                return _context20.stop();
+            }
+          }
+        }, _callee20, this);
+      }));
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+      function isChildOf(_x26, _x27) {
+        return _isChildOf.apply(this, arguments);
+      }
 
-var normalizePermission = function normalizePermission(perm) {
-  return (0, _DocumentCollection2.normalizeDoc)(perm, 'io.cozy.permissions');
-};
-/**
- * Implements `DocumentCollection` API along with specific methods for `io.cozy.permissions`.
- */
+      return isChildOf;
+    }()
+    /**
+     * statById - Fetches the metadata about a document. For folders, the results include the list of child files and folders.
+     *
+     * @param {string}      id                      ID of the document
+     * @param {object|null} options                 Pagination options
+     * @param {number|null} [options.page[limit]]   For pagination, the number of results to return.
+     * @param {number|null} [options.page[skip]]    For skip-based pagination, the number of referenced files to skip.
+     * @param {CouchDBViewCursor|null} [options.page[cursor]]  For cursor-based pagination, the index cursor.
+     *
+     * @returns {object} A promise resolving to an object containing "data" (the document metadata), "included" (the child documents) and "links" (pagination informations)
+     */
 
+  }, {
+    key: "statById",
+    value: function () {
+      var _statById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(id) {
+        var options,
+            params,
+            path,
+            url,
+            resp,
+            _args21 = arguments;
+        return _regenerator.default.wrap(function _callee21$(_context21) {
+          while (1) {
+            switch (_context21.prev = _context21.next) {
+              case 0:
+                options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {};
+                params = (0, _pick.default)(options, ['page[limit]', 'page[skip]', 'page[cursor]']);
+                path = (0, _utils.uri)(_templateObject14(), id);
+                url = querystring.buildURL(path, params);
+                _context21.next = 6;
+                return this.stackClient.fetchJSON('GET', url);
 
-var PermissionCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(PermissionCollection, _DocumentCollection);
+              case 6:
+                resp = _context21.sent;
+                return _context21.abrupt("return", {
+                  data: normalizeFile(resp.data),
+                  included: resp.included && resp.included.map(function (f) {
+                    return normalizeFile(f);
+                  }),
+                  links: resp.links
+                });
 
-  var _super = _createSuper(PermissionCollection);
+              case 8:
+              case "end":
+                return _context21.stop();
+            }
+          }
+        }, _callee21, this);
+      }));
 
-  function PermissionCollection() {
-    (0, _classCallCheck2.default)(this, PermissionCollection);
-    return _super.apply(this, arguments);
-  }
+      function statById(_x28) {
+        return _statById.apply(this, arguments);
+      }
 
-  (0, _createClass2.default)(PermissionCollection, [{
-    key: "get",
+      return statById;
+    }()
+  }, {
+    key: "statByPath",
     value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) {
+      var _statByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22(path) {
         var resp;
-        return _regenerator.default.wrap(function _callee$(_context) {
+        return _regenerator.default.wrap(function _callee22$(_context22) {
           while (1) {
-            switch (_context.prev = _context.next) {
+            switch (_context22.prev = _context22.next) {
               case 0:
-                _context.next = 2;
-                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), id));
+                _context22.next = 2;
+                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject15(), path));
 
               case 2:
-                resp = _context.sent;
-                return _context.abrupt("return", {
-                  data: normalizePermission(resp.data)
+                resp = _context22.sent;
+                return _context22.abrupt("return", {
+                  data: normalizeFile(resp.data),
+                  included: resp.included && resp.included.map(function (f) {
+                    return normalizeFile(f);
+                  })
                 });
 
               case 4:
               case "end":
-                return _context.stop();
+                return _context22.stop();
             }
           }
-        }, _callee, this);
+        }, _callee22, this);
       }));
 
-      function get(_x) {
-        return _get.apply(this, arguments);
+      function statByPath(_x29) {
+        return _statByPath.apply(this, arguments);
       }
 
-      return get;
+      return statByPath;
     }()
     /**
-     * Create a new set of permissions
-     * It can also associates one or more codes to it, via the codes parameter
-     *
-     * @param {object} permission
-     * @param {string} permission.codes A comma separed list of values (defaulted to code)
-     * @param {string} permission.ttl Make the codes expire after a delay (bigduration format)
-     * @param {boolean} permission.tiny If set to true then the generated shortcode will be 6 digits
-     * Cozy-Stack has a few conditions to be able to use this tiny shortcode ATM you have to specifiy
-     * a ttl < 1h, but it can change.
-     * see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions for exact informations
-     *
-     * bigduration format: https://github.com/justincampbell/bigduration/blob/master/README.md
-     * @see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions
+     * Create directory
      *
+     * @private
+     * @param  {DirectoryAttributes} attributes - Attributes of the directory
+     * @returns {Promise}
+     * @throws {Error} - explaining reason why creation failed
      */
 
   }, {
-    key: "create",
+    key: "createDirectory",
     value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) {
-        var _id, _type, _ref$codes, codes, ttl, tiny, attributes, searchParams, resp;
-
-        return _regenerator.default.wrap(function _callee2$(_context2) {
+      var _createDirectory = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() {
+        var attributes,
+            name,
+            dirId,
+            lastModifiedDate,
+            safeName,
+            lastModified,
+            resp,
+            _args23 = arguments;
+        return _regenerator.default.wrap(function _callee23$(_context23) {
           while (1) {
-            switch (_context2.prev = _context2.next) {
+            switch (_context23.prev = _context23.next) {
               case 0:
-                _id = _ref._id, _type = _ref._type, _ref$codes = _ref.codes, codes = _ref$codes === void 0 ? 'code' : _ref$codes, ttl = _ref.ttl, tiny = _ref.tiny, attributes = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type", "codes", "ttl", "tiny"]);
-                searchParams = new URLSearchParams();
-                searchParams.append('codes', codes);
-                if (ttl) searchParams.append('ttl', ttl);
-                if (tiny) searchParams.append('tiny', true);
-                _context2.next = 7;
-                return this.stackClient.fetchJSON('POST', "/permissions?".concat(searchParams), {
-                  data: {
-                    type: 'io.cozy.permissions',
-                    attributes: attributes
+                attributes = _args23.length > 0 && _args23[0] !== undefined ? _args23[0] : {};
+                name = attributes.name, dirId = attributes.dirId, lastModifiedDate = attributes.lastModifiedDate;
+                safeName = sanitizeAndValidateFileName(name);
+                lastModified = lastModifiedDate && (typeof lastModifiedDate === 'string' ? new Date(lastModifiedDate) : lastModifiedDate);
+                _context23.next = 6;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject16(), dirId, safeName), undefined, {
+                  headers: {
+                    Date: lastModified ? lastModified.toGMTString() : ''
                   }
                 });
 
-              case 7:
-                resp = _context2.sent;
-                return _context2.abrupt("return", {
-                  data: normalizePermission(resp.data)
+              case 6:
+                resp = _context23.sent;
+                return _context23.abrupt("return", {
+                  data: normalizeFile(resp.data)
                 });
 
-              case 9:
+              case 8:
               case "end":
-                return _context2.stop();
+                return _context23.stop();
             }
           }
-        }, _callee2, this);
+        }, _callee23, this);
       }));
 
-      function create(_x2) {
-        return _create.apply(this, arguments);
+      function createDirectory() {
+        return _createDirectory.apply(this, arguments);
       }
 
-      return create;
+      return createDirectory;
     }()
-    /**
-     * Adds a permission to the given document. Document type must be
-     * `io.cozy.apps`, `io.cozy.konnectors` or `io.cozy.permissions`
-     *
-     * @param  {object}  document - Document which receives the permission
-     * @param  {object}  permission - Describes the permission
-     * @returns {Promise}
-     *
-     * @example
-     * ```
-     * const permissions = await client
-     *   .collection('io.cozy.permissions')
-     *   .add(konnector, {
-     *     folder: {
-     *       type: 'io.cozy.files',
-     *       verbs: ['GET', 'PUT'],
-     *       values: [`io.cozy.files.bc57b60eb2954537b0dcdc6ebd8e9d23`]
-     *     }
-     *  })
-     * ```
-     */
-
   }, {
-    key: "add",
+    key: "ensureDirectoryExists",
     value: function () {
-      var _add = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document, permission) {
-        var endpoint, resp;
-        return _regenerator.default.wrap(function _callee3$(_context3) {
+      var _ensureDirectoryExists = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24(path) {
+        var resp;
+        return _regenerator.default.wrap(function _callee24$(_context24) {
           while (1) {
-            switch (_context3.prev = _context3.next) {
+            switch (_context24.prev = _context24.next) {
               case 0:
-                _context3.t0 = document._type;
-                _context3.next = _context3.t0 === 'io.cozy.apps' ? 3 : _context3.t0 === 'io.cozy.konnectors' ? 5 : _context3.t0 === 'io.cozy.permissions' ? 7 : 9;
-                break;
+                if (this.specialDirectories[path]) {
+                  _context24.next = 5;
+                  break;
+                }
+
+                _context24.next = 3;
+                return this.createDirectoryByPath(path);
 
               case 3:
-                endpoint = "/permissions/apps/".concat(document.slug);
-                return _context3.abrupt("break", 10);
+                resp = _context24.sent;
+                this.specialDirectories[path] = resp.data._id;
 
               case 5:
-                endpoint = "/permissions/konnectors/".concat(document.slug);
-                return _context3.abrupt("break", 10);
-
-              case 7:
-                endpoint = "/permissions/".concat(document._id);
-                return _context3.abrupt("break", 10);
-
-              case 9:
-                throw new Error('Permissions can only be added on existing permissions, apps and konnectors.');
-
-              case 10:
-                _context3.next = 12;
-                return this.stackClient.fetchJSON('PATCH', endpoint, {
-                  data: {
-                    type: 'io.cozy.permissions',
-                    attributes: {
-                      permissions: permission
-                    }
-                  }
-                });
-
-              case 12:
-                resp = _context3.sent;
-                return _context3.abrupt("return", {
-                  data: normalizePermission(resp.data)
-                });
+                return _context24.abrupt("return", this.specialDirectories[path]);
 
-              case 14:
+              case 6:
               case "end":
-                return _context3.stop();
+                return _context24.stop();
             }
           }
-        }, _callee3, this);
+        }, _callee24, this);
       }));
 
-      function add(_x3, _x4) {
-        return _add.apply(this, arguments);
+      function ensureDirectoryExists(_x30) {
+        return _ensureDirectoryExists.apply(this, arguments);
       }
 
-      return add;
+      return ensureDirectoryExists;
     }()
   }, {
-    key: "destroy",
-    value: function destroy(permission) {
-      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), permission.id));
-    }
-  }, {
-    key: "findLinksByDoctype",
+    key: "getDirectoryOrCreate",
     value: function () {
-      var _findLinksByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(doctype) {
-        var resp;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
+      var _getDirectoryOrCreate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25(name, parentDirectory) {
+        var safeName, path, stat, parsedError, errors;
+        return _regenerator.default.wrap(function _callee25$(_context25) {
           while (1) {
-            switch (_context4.prev = _context4.next) {
+            switch (_context25.prev = _context25.next) {
               case 0:
-                _context4.next = 2;
-                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject3(), doctype));
+                if (!(parentDirectory && !parentDirectory.attributes)) {
+                  _context25.next = 2;
+                  break;
+                }
+
+                throw new Error('Malformed parent directory');
 
               case 2:
-                resp = _context4.sent;
-                return _context4.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
-                  data: resp.data.map(normalizePermission)
+                safeName = sanitizeFileName(name);
+                path = "".concat(parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path, "/").concat(safeName);
+                _context25.prev = 4;
+                _context25.next = 7;
+                return this.statByPath(path || '/');
+
+              case 7:
+                stat = _context25.sent;
+                return _context25.abrupt("return", stat);
+
+              case 11:
+                _context25.prev = 11;
+                _context25.t0 = _context25["catch"](4);
+                parsedError = JSON.parse(_context25.t0.message);
+                errors = parsedError.errors;
+
+                if (!(errors && errors.length && errors[0].status === '404')) {
+                  _context25.next = 17;
+                  break;
+                }
+
+                return _context25.abrupt("return", this.createDirectory({
+                  name: safeName,
+                  dirId: parentDirectory && parentDirectory._id
                 }));
 
-              case 4:
+              case 17:
+                throw errors;
+
+              case 18:
               case "end":
-                return _context4.stop();
+                return _context25.stop();
             }
           }
-        }, _callee4, this);
+        }, _callee25, this, [[4, 11]]);
       }));
 
-      function findLinksByDoctype(_x5) {
-        return _findLinksByDoctype.apply(this, arguments);
+      function getDirectoryOrCreate(_x31, _x32) {
+        return _getDirectoryOrCreate.apply(this, arguments);
       }
 
-      return findLinksByDoctype;
+      return getDirectoryOrCreate;
     }()
+    /**
+     * async createDirectoryByPath - Creates one or more folders until the given path exists
+     *
+     * @param  {string} path - Path of the created directory
+     * @returns {object} The document corresponding to the last segment of the path
+     */
+
   }, {
-    key: "findApps",
+    key: "createDirectoryByPath",
     value: function () {
-      var _findApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
-        var resp;
-        return _regenerator.default.wrap(function _callee5$(_context5) {
+      var _createDirectoryByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26(path) {
+        var parts, root, parentDir, _iterator2, _step2, part;
+
+        return _regenerator.default.wrap(function _callee26$(_context26) {
           while (1) {
-            switch (_context5.prev = _context5.next) {
+            switch (_context26.prev = _context26.next) {
               case 0:
-                _context5.next = 2;
-                return this.stackClient.fetchJSON('GET', '/apps/');
+                parts = path.split('/').filter(function (part) {
+                  return part !== '';
+                });
+                _context26.next = 3;
+                return this.statById(ROOT_DIR_ID);
 
-              case 2:
-                resp = _context5.sent;
-                return _context5.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
-                  data: resp.data.map(function (a) {
-                    return _objectSpread({
-                      _id: a.id
-                    }, a);
-                  })
-                }));
+              case 3:
+                root = _context26.sent;
 
-              case 4:
+                if (parts.length) {
+                  _context26.next = 6;
+                  break;
+                }
+
+                return _context26.abrupt("return", root);
+
+              case 6:
+                parentDir = root;
+                _iterator2 = _createForOfIteratorHelper(parts);
+                _context26.prev = 8;
+
+                _iterator2.s();
+
+              case 10:
+                if ((_step2 = _iterator2.n()).done) {
+                  _context26.next = 17;
+                  break;
+                }
+
+                part = _step2.value;
+                _context26.next = 14;
+                return this.getDirectoryOrCreate(part, parentDir.data);
+
+              case 14:
+                parentDir = _context26.sent;
+
+              case 15:
+                _context26.next = 10;
+                break;
+
+              case 17:
+                _context26.next = 22;
+                break;
+
+              case 19:
+                _context26.prev = 19;
+                _context26.t0 = _context26["catch"](8);
+
+                _iterator2.e(_context26.t0);
+
+              case 22:
+                _context26.prev = 22;
+
+                _iterator2.f();
+
+                return _context26.finish(22);
+
+              case 25:
+                return _context26.abrupt("return", parentDir);
+
+              case 26:
               case "end":
-                return _context5.stop();
+                return _context26.stop();
             }
           }
-        }, _callee5, this);
+        }, _callee26, this, [[8, 19, 22, 25]]);
       }));
 
-      function findApps() {
-        return _findApps.apply(this, arguments);
+      function createDirectoryByPath(_x33) {
+        return _createDirectoryByPath.apply(this, arguments);
       }
 
-      return findApps;
+      return createDirectoryByPath;
     }()
     /**
-     * Create a share link
      *
-     * @param {{_id, _type}} document - cozy document
-     * @param {object} options - options
-     * @param {string[]} options.verbs - explicit permissions to use
+     * async updateAttributes - Updates a file / folder's attributes except
+     * the metadata attribute. If you want to update its metadata attribute,
+     * then use `updateFileMetadataAttribute` since `metadata` is a specific
+     * doctype.
+     *
+     * For instance, if you want to update the name of a file, you can pass
+     * attributes = { name: 'newName'}
+     *
+     * You can see the attributes for both Folder and File (as they share the
+     * same doctype they have a few in common) here :
+     * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#iocozyfiles
+     *
+     * @private You shoud use update() directly.
+     * @param  {string} id         File id
+     * @param  {object} attributes New file attributes
+     * @returns {object}            Updated document
+     * @throws {Error} - explaining reason why update failed
      */
 
   }, {
-    key: "createSharingLink",
+    key: "updateAttributes",
     value: function () {
-      var _createSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document) {
-        var options,
-            verbs,
-            resp,
-            _args6 = arguments;
-        return _regenerator.default.wrap(function _callee6$(_context6) {
+      var _updateAttributes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27(id, attributes) {
+        var sanitizedAttributes, resp;
+        return _regenerator.default.wrap(function _callee27$(_context27) {
           while (1) {
-            switch (_context6.prev = _context6.next) {
+            switch (_context27.prev = _context27.next) {
               case 0:
-                options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
-                verbs = options.verbs;
-                _context6.next = 4;
-                return this.stackClient.fetchJSON('POST', "/permissions?codes=email", {
+                sanitizedAttributes = _objectSpread({}, attributes);
+
+                if (attributes.name) {
+                  sanitizedAttributes.name = sanitizeAndValidateFileName(attributes.name);
+                }
+
+                _context27.next = 4;
+                return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject17(), id), {
                   data: {
-                    type: 'io.cozy.permissions',
-                    attributes: {
-                      permissions: getPermissionsFor(document, true, verbs ? {
-                        verbs: verbs
-                      } : {})
-                    }
+                    type: 'io.cozy.files',
+                    id: id,
+                    attributes: sanitizedAttributes
                   }
                 });
 
               case 4:
-                resp = _context6.sent;
-                return _context6.abrupt("return", {
-                  data: normalizePermission(resp.data)
+                resp = _context27.sent;
+                return _context27.abrupt("return", {
+                  data: normalizeFile(resp.data)
                 });
 
               case 6:
               case "end":
-                return _context6.stop();
+                return _context27.stop();
             }
           }
-        }, _callee6, this);
+        }, _callee27, this);
       }));
 
-      function createSharingLink(_x6) {
-        return _createSharingLink.apply(this, arguments);
+      function updateAttributes(_x34, _x35) {
+        return _updateAttributes.apply(this, arguments);
       }
 
-      return createSharingLink;
+      return updateAttributes;
+    }()
+  }, {
+    key: "updateFileMetadata",
+    value: function () {
+      var _updateFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28(id, attributes) {
+        return _regenerator.default.wrap(function _callee28$(_context28) {
+          while (1) {
+            switch (_context28.prev = _context28.next) {
+              case 0:
+                console.warn('CozyClient FileCollection updateFileMetadata method is deprecated. Use updateAttributes instead');
+                return _context28.abrupt("return", this.updateAttributes(id, attributes));
+
+              case 2:
+              case "end":
+                return _context28.stop();
+            }
+          }
+        }, _callee28, this);
+      }));
+
+      function updateFileMetadata(_x36, _x37) {
+        return _updateFileMetadata.apply(this, arguments);
+      }
+
+      return updateFileMetadata;
     }()
     /**
-     * Follow the next link to fetch the next permissions
+     * Send a metadata object that can be associated to a file uploaded after that,
+     * via the MetadataID query parameter.
+     * See https://github.com/cozy/cozy-stack/blob/master/docs/files.md#post-filesuploadmetadata
      *
-     * @param {object} permissions JSON-API based permissions document
+     * @param {object} attributes The file's metadata
+     * @returns {object}          The Metadata object
      */
 
   }, {
-    key: "fetchPermissionsByLink",
+    key: "createFileMetadata",
     value: function () {
-      var _fetchPermissionsByLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(permissions) {
-        return _regenerator.default.wrap(function _callee7$(_context7) {
+      var _createFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee29(attributes) {
+        var resp;
+        return _regenerator.default.wrap(function _callee29$(_context29) {
           while (1) {
-            switch (_context7.prev = _context7.next) {
+            switch (_context29.prev = _context29.next) {
               case 0:
-                if (!(permissions.links && permissions.links.next)) {
-                  _context7.next = 4;
-                  break;
-                }
-
-                _context7.next = 3;
-                return this.stackClient.fetchJSON('GET', permissions.links.next);
+                _context29.next = 2;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject18()), {
+                  data: {
+                    type: 'io.cozy.files.metadata',
+                    attributes: attributes
+                  }
+                });
 
-              case 3:
-                return _context7.abrupt("return", _context7.sent);
+              case 2:
+                resp = _context29.sent;
+                return _context29.abrupt("return", {
+                  data: resp.data
+                });
 
               case 4:
               case "end":
-                return _context7.stop();
+                return _context29.stop();
             }
           }
-        }, _callee7, this);
+        }, _callee29, this);
       }));
 
-      function fetchPermissionsByLink(_x7) {
-        return _fetchPermissionsByLink.apply(this, arguments);
+      function createFileMetadata(_x38) {
+        return _createFileMetadata.apply(this, arguments);
       }
 
-      return fetchPermissionsByLink;
+      return createFileMetadata;
     }()
     /**
      *
-     * @param {object} document Cozy doc
-     * @returns {object} with all the permissions
+     * Updates the metadata attribute of a io.cozy.files
+     * Creates a new version of the file without having
+     * to upload again the file's content
+     *
+     * To see available content of the metadata attribute
+     * see : https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files_metadata/
+     *
+     * @param {string} id File id
+     * @param {object} metadata io.cozy.files.metadata attributes
+     * @returns {object} io.cozy.files updated
      */
 
   }, {
-    key: "fetchAllLinks",
+    key: "updateMetadataAttribute",
     value: function () {
-      var _fetchAllLinks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(document) {
-        var allLinks, resp, _allLinks$data;
-
-        return _regenerator.default.wrap(function _callee8$(_context8) {
+      var _updateMetadataAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee30(id, metadata) {
+        var resp;
+        return _regenerator.default.wrap(function _callee30$(_context30) {
           while (1) {
-            switch (_context8.prev = _context8.next) {
+            switch (_context30.prev = _context30.next) {
               case 0:
-                _context8.next = 2;
-                return this.findLinksByDoctype(document._type);
+                _context30.next = 2;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject19(), id), {
+                  data: {
+                    type: 'io.cozy.files.metadata',
+                    attributes: metadata
+                  }
+                });
 
               case 2:
-                allLinks = _context8.sent;
-                resp = allLinks;
+                resp = _context30.sent;
+                return _context30.abrupt("return", {
+                  data: resp.data
+                });
 
               case 4:
-                if (!(resp.links && resp.links.next)) {
-                  _context8.next = 11;
-                  break;
-                }
-
-                _context8.next = 7;
-                return this.fetchPermissionsByLink(resp);
-
-              case 7:
-                resp = _context8.sent;
-
-                (_allLinks$data = allLinks.data).push.apply(_allLinks$data, (0, _toConsumableArray2.default)(resp.data.map(normalizePermission)));
-
-                _context8.next = 4;
-                break;
-
-              case 11:
-                return _context8.abrupt("return", allLinks);
-
-              case 12:
               case "end":
-                return _context8.stop();
+                return _context30.stop();
             }
           }
-        }, _callee8, this);
+        }, _callee30, this);
       }));
 
-      function fetchAllLinks(_x8) {
-        return _fetchAllLinks.apply(this, arguments);
+      function updateMetadataAttribute(_x39, _x40) {
+        return _updateMetadataAttribute.apply(this, arguments);
       }
 
-      return fetchAllLinks;
+      return updateMetadataAttribute;
     }()
     /**
-     * Destroy a sharing link and the related permissions
+     * Get the file mime-type based on its name
      *
-     * @param {object} document
+     * @param {string} name - The file name
+     * @returns {string} the inferred file mime-type
      */
 
   }, {
-    key: "revokeSharingLink",
+    key: "getFileTypeFromName",
+    value: function getFileTypeFromName(name) {
+      return _lite.default.getType(name) || CONTENT_TYPE_OCTET_STREAM;
+    }
+    /**
+     *
+     * This method should not be called directly to upload a file.
+     * You should use `createFile`
+     *
+     * @param {File|Blob|Stream|string|ArrayBuffer} dataArg file to be uploaded
+     * @param {string} path Uri to call the stack from. Something like
+     * `/files/${dirId}?Name=${name}&Type=file&Executable=${executable}&MetadataID=${metadataId}`
+     * @param {object} options Additional headers
+     * @param {string} method POST / PUT / PATCH
+     */
+
+  }, {
+    key: "doUpload",
     value: function () {
-      var _revokeSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(document) {
-        var allLinks, links, _iterator, _step, perm;
+      var _doUpload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee31(dataArg, path, options) {
+        var method,
+            correctPath,
+            data,
+            isBuffer,
+            isFile,
+            isBlob,
+            isStream,
+            isString,
+            _ref9,
+            contentType,
+            contentLength,
+            checksum,
+            lastModifiedDate,
+            ifMatch,
+            sPath,
+            params,
+            name,
+            headers,
+            date,
+            resp,
+            _args31 = arguments;
 
-        return _regenerator.default.wrap(function _callee9$(_context9) {
+        return _regenerator.default.wrap(function _callee31$(_context31) {
           while (1) {
-            switch (_context9.prev = _context9.next) {
+            switch (_context31.prev = _context31.next) {
               case 0:
-                _context9.next = 2;
-                return this.fetchAllLinks(document);
+                method = _args31.length > 3 && _args31[3] !== undefined ? _args31[3] : 'POST';
+                correctPath = path;
+                data = dataArg;
 
-              case 2:
-                allLinks = _context9.sent;
-                links = allLinks.data.filter(function (perm) {
-                  return isPermissionRelatedTo(perm, document);
-                });
-                _iterator = _createForOfIteratorHelper(links);
-                _context9.prev = 5;
+                if (data) {
+                  _context31.next = 5;
+                  break;
+                }
 
-                _iterator.s();
+                throw new Error('missing data argument');
 
-              case 7:
-                if ((_step = _iterator.n()).done) {
-                  _context9.next = 13;
-                  break;
+              case 5:
+                // transform any ArrayBufferView to ArrayBuffer
+                if (data.buffer && data.buffer instanceof ArrayBuffer) {
+                  data = data.buffer;
                 }
 
-                perm = _step.value;
-                _context9.next = 11;
-                return this.destroy(perm);
+                isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer;
+                isFile = typeof File !== 'undefined' && data instanceof File;
+                isBlob = typeof Blob !== 'undefined' && data instanceof Blob;
+                isStream = data.readable === true && typeof data.pipe === 'function';
+                isString = typeof data === 'string';
 
-              case 11:
-                _context9.next = 7;
-                break;
+                if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) {
+                  _context31.next = 13;
+                  break;
+                }
+
+                throw new Error('invalid data type');
 
               case 13:
-                _context9.next = 18;
-                break;
+                _ref9 = options || {}, contentType = _ref9.contentType, contentLength = _ref9.contentLength, checksum = _ref9.checksum, lastModifiedDate = _ref9.lastModifiedDate, ifMatch = _ref9.ifMatch;
 
-              case 15:
-                _context9.prev = 15;
-                _context9.t0 = _context9["catch"](5);
+                if (!contentType) {
+                  if (typeof data === 'string') {
+                    contentType = 'text/plain';
+                  } else {
+                    if (data.type) {
+                      // The type is specified in the file object
+                      contentType = data.type;
+                    } else {
+                      // Extract the name from the correctPath and infer the type
+                      sPath = correctPath.split('?');
+                      params = sPath.length > 1 ? sPath[1] : '';
+                      name = new URLSearchParams(params).get('Name');
+                      contentType = this.getFileTypeFromName(name.toLowerCase());
+                    }
+                  }
+                }
 
-                _iterator.e(_context9.t0);
+                lastModifiedDate = lastModifiedDate || data.lastModified;
 
-              case 18:
-                _context9.prev = 18;
+                if (lastModifiedDate) {
+                  lastModifiedDate = new Date(lastModifiedDate);
+                }
 
-                _iterator.f();
+                headers = {
+                  'Content-Type': contentType
+                };
+                if (contentLength) headers['Content-Length'] = String(contentLength);
+                if (checksum) headers['Content-MD5'] = checksum;
 
-                return _context9.finish(18);
+                if (lastModifiedDate) {
+                  date = lastModifiedDate.toISOString();
+                  correctPath = "".concat(correctPath, "&UpdatedAt=").concat(date, "&CreatedAt=").concat(date);
+                }
 
-              case 21:
+                if (ifMatch) headers['If-Match'] = ifMatch;
+                _context31.next = 24;
+                return this.stackClient.fetchJSON(method, correctPath, data, {
+                  headers: headers,
+                  onUploadProgress: options.onUploadProgress
+                });
+
+              case 24:
+                resp = _context31.sent;
+                return _context31.abrupt("return", {
+                  data: normalizeFile(resp.data)
+                });
+
+              case 26:
               case "end":
-                return _context9.stop();
+                return _context31.stop();
             }
           }
-        }, _callee9, this, [[5, 15, 18, 21]]);
+        }, _callee31, this);
       }));
 
-      function revokeSharingLink(_x9) {
-        return _revokeSharingLink.apply(this, arguments);
+      function doUpload(_x41, _x42, _x43) {
+        return _doUpload.apply(this, arguments);
       }
 
-      return revokeSharingLink;
+      return doUpload;
     }()
     /**
-     * async getOwnPermissions - deprecated: please use fetchOwnPermissions instead
+     * async findNotSynchronizedDirectories - Returns the list of directories not synchronized on the given OAuth client (mainly Cozy Desktop clients) — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#get-datatypedoc-idrelationshipsnot_synchronizing
      *
-     * @typedef {object} Permission
+     * @param  {OAuthClient}  oauthClient           A JSON representing an OAuth client, with at least a `_type` and `_id` field.
+     * @param  {object|null}  options               Pagination options
+     * @param  {number|null}  options.skip          For skip-based pagination, the number of referenced files to skip.
+     * @param  {number|null}  options.limit         For pagination, the number of results to return.
+     * @param  {CouchDBViewCursor|null}  options.cursor        For cursor-based pagination, the index cursor.
+     * @param  {boolean}      options.includeFiles  Include the whole file documents in the results list
      *
-     * @returns {Permission} permission
+     * @returns {Array<object|IOCozyFolder>}    The JSON API conformant response.
      */
 
   }, {
-    key: "getOwnPermissions",
+    key: "findNotSynchronizedDirectories",
     value: function () {
-      var _getOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10() {
-        return _regenerator.default.wrap(function _callee10$(_context10) {
+      var _findNotSynchronizedDirectories = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee32(oauthClient) {
+        var _ref10,
+            _ref10$skip,
+            skip,
+            limit,
+            cursor,
+            _ref10$includeFiles,
+            includeFiles,
+            params,
+            path,
+            url,
+            resp,
+            _args32 = arguments;
+
+        return _regenerator.default.wrap(function _callee32$(_context32) {
           while (1) {
-            switch (_context10.prev = _context10.next) {
+            switch (_context32.prev = _context32.next) {
               case 0:
-                console.warn('getOwnPermissions is deprecated, please use fetchOwnPermissions instead');
-                return _context10.abrupt("return", this.fetchOwnPermissions());
+                _ref10 = _args32.length > 1 && _args32[1] !== undefined ? _args32[1] : {}, _ref10$skip = _ref10.skip, skip = _ref10$skip === void 0 ? 0 : _ref10$skip, limit = _ref10.limit, cursor = _ref10.cursor, _ref10$includeFiles = _ref10.includeFiles, includeFiles = _ref10$includeFiles === void 0 ? false : _ref10$includeFiles;
+                params = {
+                  include: includeFiles ? 'files' : undefined,
+                  'page[limit]': limit,
+                  'page[cursor]': cursor,
+                  sort: 'id'
+                };
+                path = (0, _utils.uri)(_templateObject20(), oauthClient._type, oauthClient._id);
+                url = querystring.buildURL(path, params);
+                _context32.next = 6;
+                return this.stackClient.fetchJSON('GET', url);
 
-              case 2:
+              case 6:
+                resp = _context32.sent;
+                return _context32.abrupt("return", {
+                  data: resp.data.map(function (f) {
+                    return normalizeFile(f);
+                  }),
+                  included: resp.included ? resp.included.map(function (f) {
+                    return normalizeFile(f);
+                  }) : [],
+                  next: (0, _has.default)(resp, 'links.next'),
+                  meta: resp.meta,
+                  skip: skip
+                });
+
+              case 8:
               case "end":
-                return _context10.stop();
+                return _context32.stop();
             }
           }
-        }, _callee10, this);
+        }, _callee32, this);
       }));
 
-      function getOwnPermissions() {
-        return _getOwnPermissions.apply(this, arguments);
+      function findNotSynchronizedDirectories(_x44) {
+        return _findNotSynchronizedDirectories.apply(this, arguments);
       }
 
-      return getOwnPermissions;
+      return findNotSynchronizedDirectories;
     }()
     /**
-     * async fetchOwnPermissions - Fetches permissions
+     *  Add directory synchronization exclusions to an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#post-datatypedoc-idrelationshipsnot_synchronizing
+     *
+     *  For example, to exclude directory `/Photos` from `My Computer`'s desktop synchronization:
+     * ```
+     * addNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}])
+     * ```
+     *
+     * @param  {OAuthClient} oauthClient  A JSON representing the OAuth client
+     * @param  {Array}  directories       An array of JSON documents having a `_type` and `_id` fields and representing directories.
+     *
+     * Returns 204 No Content
+     */
+
+  }, {
+    key: "addNotSynchronizedDirectories",
+    value: function addNotSynchronizedDirectories(oauthClient, directories) {
+      var refs = directories.map(function (d) {
+        return {
+          id: d._id,
+          type: d._type
+        };
+      });
+      return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject21(), oauthClient._type, oauthClient._id), {
+        data: refs
+      });
+    }
+    /**
+     *  Remove directory synchronization exclusions from an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#delete-datatypedoc-idrelationshipsnot_synchronizing
+     *
+     *  For example, to re-include directory `/Photos` into `My Computer`'s desktop synchronization:
+     * ```
+     *  removeNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}])
+     * ```
+     *
+     * @param  {OAuthClient} oauthClient  A JSON representing the OAuth client
+     * @param  {Array}  directories       An array of JSON documents having a `_type` and `_id` field and representing directories.
+     *
+     * Returns 204 No Content
+     */
+
+  }, {
+    key: "removeNotSynchronizedDirectories",
+    value: function removeNotSynchronizedDirectories(oauthClient, directories) {
+      var refs = directories.map(function (d) {
+        return {
+          id: d._id,
+          type: d._type
+        };
+      });
+      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject22(), oauthClient._type, oauthClient._id), {
+        data: refs
+      });
+    }
+    /**
+     * Use cozy-stack's _changes API for io.cozy.files
+     * Design docs are filtered by default, thus documents are retrieved in the
+     * response (includeDocs is set to true in the parameters of _changes).
+     * Deleted and trashed documents can be filtered on demand and files' paths
+     * can be requested as well.
+     *
+     * Since deleted and trashed documents are skipped by cozy-stack rather than
+     * CouchDB, when either option is set to true, the response can contain less
+     * documents than the defined limit. Thus one should rely solely on the
+     * `pending` result attribute to determine if more documents can be fetched or
+     * not.
+     *
+     * You should use fetchChangesRaw to call CouchDB's _changes API.
+     *
+     * @typedef {object} CouchOptions
+     * @property {string} since - Bookmark telling CouchDB from which point in time should changes be returned
+     * @property {number} limit - The maximum number of returned documents for one call
+     * @property {boolean} includeDocs - Whether or not complete documents should be returned
      *
-     * @typedef {object} Permission
+     * @typedef {object} FetchChangesOptions
+     * @property {Array<string>} fields - The list of fields that should be returned for each document
+     * @property {boolean} includeFilePath - Whether to include the path of file changes (needs includeDocs to be true)
+     * @property {boolean} skipDeleted - Whether to skip changes for deleted documents
+     * @property {boolean} skipTrashed - Whether to skip changes for trashed documents (needs includeDocs to be true)
      *
-     * @returns {Permission} permission
+     * @param  {CouchOptions} couchOptions - Couch options for changes
+     * @param  {FetchChangesOptions} options - Further options on the returned documents. By default, it is set to
+     *                                        { includeFilePath: false, skipDeleted: false, skipTrashed: false }
+     *
+     * @typedef {object} FetchChangesReturnValue
+     * @property {string} newLastSeq
+     * @property {boolean} pending
+     * @property {Array<object>} documents
+     * @returns {FetchChangesReturnValue}
      */
 
   }, {
-    key: "fetchOwnPermissions",
+    key: "fetchChanges",
     value: function () {
-      var _fetchOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() {
-        var resp;
-        return _regenerator.default.wrap(function _callee11$(_context11) {
+      var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee33() {
+        var couchOptions,
+            options,
+            opts,
+            params,
+            path,
+            url,
+            _yield$this$stackClie,
+            newLastSeq,
+            pending,
+            results,
+            _args33 = arguments;
+
+        return _regenerator.default.wrap(function _callee33$(_context33) {
           while (1) {
-            switch (_context11.prev = _context11.next) {
+            switch (_context33.prev = _context33.next) {
               case 0:
-                _context11.next = 2;
-                return this.stackClient.fetchJSON('GET', '/permissions/self');
+                couchOptions = _args33.length > 0 && _args33[0] !== undefined ? _args33[0] : {};
+                options = _args33.length > 1 && _args33[1] !== undefined ? _args33[1] : {};
+                opts = {};
 
-              case 2:
-                resp = _context11.sent;
-                return _context11.abrupt("return", {
-                  data: normalizePermission(resp.data),
-                  included: resp.included ? resp.included.map(normalizePermission) : []
+                if (typeof couchOptions !== 'object') {
+                  opts.since = couchOptions;
+                  console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"})."));
+                } else if (Object.keys(couchOptions).length > 0) {
+                  Object.assign(opts, couchOptions);
+                }
+
+                if (Object.keys(options).length > 0) {
+                  Object.assign(opts, options);
+
+                  if (options.skipTrashed || options.includeFilePath) {
+                    opts.includeDocs = true;
+                  }
+                }
+
+                params = _objectSpread(_objectSpread({}, (0, _omit.default)(opts, ['fields', 'includeDocs', 'includeFilePath', 'skipDeleted', 'skipTrashed'])), {}, {
+                  fields: opts.fields ? opts.fields.join(',') : null,
+                  include_docs: opts.includeDocs,
+                  include_file_path: opts.includeFilePath,
+                  skip_deleted: opts.skipDeleted,
+                  skip_trashed: opts.skipTrashed
                 });
+                path = (0, _utils.uri)(_templateObject23());
+                url = querystring.buildURL(path, params);
+                _context33.next = 10;
+                return this.stackClient.fetchJSON('GET', url);
 
-              case 4:
+              case 10:
+                _yield$this$stackClie = _context33.sent;
+                newLastSeq = _yield$this$stackClie.last_seq;
+                pending = _yield$this$stackClie.pending;
+                results = _yield$this$stackClie.results;
+                return _context33.abrupt("return", {
+                  newLastSeq: newLastSeq,
+                  pending: pending,
+                  results: results
+                });
+
+              case 15:
               case "end":
-                return _context11.stop();
+                return _context33.stop();
             }
           }
-        }, _callee11, this);
+        }, _callee33, this);
       }));
 
-      function fetchOwnPermissions() {
-        return _fetchOwnPermissions.apply(this, arguments);
+      function fetchChanges() {
+        return _fetchChanges.apply(this, arguments);
       }
 
-      return fetchOwnPermissions;
+      return fetchChanges;
     }()
   }]);
-  return PermissionCollection;
+  return FileCollection;
 }(_DocumentCollection2.default);
+
+var _default = FileCollection;
+exports["default"] = _default;
+
+/***/ }),
+/* 671 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+"use strict";
+
+
+let Mime = __webpack_require__(672);
+module.exports = new Mime(__webpack_require__(673));
+
+
+/***/ }),
+/* 672 */
+/***/ ((module) => {
+
+"use strict";
+
+
 /**
- * Build a permission set
+ * @param typeMap [Object] Map of MIME type -> Array[extensions]
+ * @param ...
+ */
+function Mime() {
+  this._types = Object.create(null);
+  this._extensions = Object.create(null);
+
+  for (let i = 0; i < arguments.length; i++) {
+    this.define(arguments[i]);
+  }
+
+  this.define = this.define.bind(this);
+  this.getType = this.getType.bind(this);
+  this.getExtension = this.getExtension.bind(this);
+}
+
+/**
+ * Define mimetype -> extension mappings.  Each key is a mime-type that maps
+ * to an array of extensions associated with the type.  The first extension is
+ * used as the default extension for the type.
  *
- * @param {{_id, _type}} document - cozy document
- * @param {boolean} publicLink - are the permissions for a public link ?
- * @param {object} options - options
- * @param {string[]} options.verbs - explicit permissions to use
- * @returns {object} permissions object that can be sent through /permissions/*
+ * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
+ *
+ * If a type declares an extension that has already been defined, an error will
+ * be thrown.  To suppress this error and force the extension to be associated
+ * with the new type, pass `force`=true.  Alternatively, you may prefix the
+ * extension with "*" to map the type to extension, without mapping the
+ * extension to the type.
+ *
+ * e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
+ *
+ *
+ * @param map (Object) type definitions
+ * @param force (Boolean) if true, force overriding of existing definitions
  */
+Mime.prototype.define = function(typeMap, force) {
+  for (let type in typeMap) {
+    let extensions = typeMap[type].map(function(t) {
+      return t.toLowerCase();
+    });
+    type = type.toLowerCase();
 
+    for (let i = 0; i < extensions.length; i++) {
+      const ext = extensions[i];
 
-var getPermissionsFor = function getPermissionsFor(document) {
-  var publicLink = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-  var _id = document._id,
-      _type = document._type;
-  var verbs = options.verbs ? options.verbs : publicLink ? ['GET'] : ['ALL']; // TODO: this works for albums, but it needs to be generalized and integrated
-  // with cozy-client ; some sort of doctype "schema" will be needed here
+      // '*' prefix = not the preferred type for this extension.  So fixup the
+      // extension, and skip it.
+      if (ext[0] === '*') {
+        continue;
+      }
 
-  return (0, _FileCollection.isFile)(document) ? {
-    files: {
-      type: 'io.cozy.files',
-      verbs: verbs,
-      values: [_id]
+      if (!force && (ext in this._types)) {
+        throw new Error(
+          'Attempt to change mapping for "' + ext +
+          '" extension from "' + this._types[ext] + '" to "' + type +
+          '". Pass `force=true` to allow this, otherwise remove "' + ext +
+          '" from the list of extensions for "' + type + '".'
+        );
+      }
+
+      this._types[ext] = type;
     }
-  } : {
-    collection: {
-      type: _type,
-      verbs: verbs,
-      values: [_id]
-    },
-    files: {
-      type: 'io.cozy.files',
-      verbs: verbs,
-      values: ["".concat(_type, "/").concat(_id)],
-      selector: 'referenced_by'
+
+    // Use first extension as default
+    if (force || !this._extensions[type]) {
+      const ext = extensions[0];
+      this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1);
     }
-  };
+  }
 };
 
-exports.getPermissionsFor = getPermissionsFor;
-PermissionCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+/**
+ * Lookup a mime type based on extension
+ */
+Mime.prototype.getType = function(path) {
+  path = String(path);
+  let last = path.replace(/^.*[/\\]/, '').toLowerCase();
+  let ext = last.replace(/^.*\./, '').toLowerCase();
 
-var isPermissionRelatedTo = function isPermissionRelatedTo(perm, document) {
-  var _id = document._id;
-  return (0, _FileCollection.isFile)(document) ? perm.attributes.permissions.files.values.indexOf(_id) !== -1 : perm.attributes.permissions.collection.values.indexOf(_id) !== -1;
+  let hasPath = last.length < path.length;
+  let hasDot = ext.length < last.length - 1;
+
+  return (hasDot || !hasPath) && this._types[ext] || null;
 };
 
-var _default = PermissionCollection;
-exports["default"] = _default;
+/**
+ * Return file extension associated with a mime type
+ */
+Mime.prototype.getExtension = function(type) {
+  type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
+  return type && this._extensions[type.toLowerCase()] || null;
+};
+
+module.exports = Mime;
+
+
+/***/ }),
+/* 673 */
+/***/ ((module) => {
+
+module.exports = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma","es"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/mrb-consumer+xml":["*xdf"],"application/mrb-publish+xml":["*xdf"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["*xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-error+xml":["xer"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]};
 
 /***/ }),
 /* 674 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var baseHas = __webpack_require__(675),
+    hasPath = __webpack_require__(470);
 
+/**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': 2 } };
+ * var other = _.create({ 'a': _.create({ 'b': 2 }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b');
+ * // => true
+ *
+ * _.has(object, ['a', 'b']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */
+function has(object, path) {
+  return object != null && hasPath(object, path, baseHas);
+}
 
-var _interopRequireDefault = __webpack_require__(512);
+module.exports = has;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.SETTINGS_DOCTYPE = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+/***/ }),
+/* 675 */
+/***/ ((module) => {
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+/**
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} [object] The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+function baseHas(object, key) {
+  return object != null && hasOwnProperty.call(object, key);
+}
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+module.exports = baseHas;
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+/***/ }),
+/* 676 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+var basePick = __webpack_require__(677),
+    flatRest = __webpack_require__(632);
 
-var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601));
+/**
+ * Creates an object composed of the picked `object` properties.
+ *
+ * @static
+ * @since 0.1.0
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [paths] The property paths to pick.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pick(object, ['a', 'c']);
+ * // => { 'a': 1, 'c': 3 }
+ */
+var pick = flatRest(function(object, paths) {
+  return object == null ? {} : basePick(object, paths);
+});
 
-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; }
+module.exports = pick;
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+/***/ }),
+/* 677 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var basePickBy = __webpack_require__(661),
+    hasIn = __webpack_require__(468);
 
-var SETTINGS_DOCTYPE = 'io.cozy.settings';
 /**
- * Implements `DocumentCollection` API to interact with the /settings endpoint of the stack
+ * The base implementation of `_.pick` without support for individual
+ * property identifiers.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} paths The property paths to pick.
+ * @returns {Object} Returns the new object.
  */
+function basePick(object, paths) {
+  return basePickBy(object, paths, function(value, path) {
+    return hasIn(object, path);
+  });
+}
 
-exports.SETTINGS_DOCTYPE = SETTINGS_DOCTYPE;
-
-var SettingsCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(SettingsCollection, _DocumentCollection);
-
-  var _super = _createSuper(SettingsCollection);
+module.exports = basePick;
 
-  function SettingsCollection(stackClient) {
-    (0, _classCallCheck2.default)(this, SettingsCollection);
-    return _super.call(this, SETTINGS_DOCTYPE, stackClient);
-  }
-  /**
-   * async get - Calls a route on the /settings API
-   *
-   * @param  {string} path The setting route to call, eg `instance` or `context`
-   * @returns {object} The response from the route
-   */
 
+/***/ }),
+/* 678 */
+/***/ ((__unused_webpack_module, exports) => {
 
-  (0, _createClass2.default)(SettingsCollection, [{
-    key: "get",
-    value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(path) {
-        var resp;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                _context.next = 2;
-                return this.stackClient.fetchJSON('GET', "/settings/".concat(path));
+"use strict";
 
-              case 2:
-                resp = _context.sent;
-                return _context.abrupt("return", {
-                  data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SETTINGS_DOCTYPE)(_objectSpread({
-                    id: "/settings/".concat(path)
-                  }, resp.data), resp)
-                });
 
-              case 4:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getIllegalCharacters = void 0;
 
-      function get(_x) {
-        return _get.apply(this, arguments);
-      }
+/**
+ * Get the list of illegal characters in the file name
+ *
+ * @public
+ * @param {string} name - the file name
+ * @returns {string} illegal characters separated by spaces
+ */
+var getIllegalCharacters = function getIllegalCharacters(name) {
+  var FILENAME_ILLEGAL_CHARACTERS = /\/|\x00|\n|\r/g; // eslint-disable-line no-control-regex
 
-      return get;
-    }()
-  }]);
-  return SettingsCollection;
-}(_DocumentCollection2.default);
+  var match = name.match(FILENAME_ILLEGAL_CHARACTERS);
+  return match ? match.join(' ') : '';
+};
 
-SettingsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
-var _default = SettingsCollection;
-exports["default"] = _default;
+exports.getIllegalCharacters = getIllegalCharacters;
 
 /***/ }),
-/* 675 */
+/* 679 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.NOTES_URL_DOCTYPE = exports.NOTES_DOCTYPE = void 0;
-
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+exports["default"] = exports.hasJobFinished = exports.normalizeJob = exports.JOBS_DOCTYPE = void 0;
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _utils = __webpack_require__(611);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _NotesSchema = __webpack_require__(676);
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/notes/", "/open"]);
+var _Collection = _interopRequireDefault(__webpack_require__(612));
 
-  _templateObject2 = function _templateObject2() {
-    return data;
-  };
+var _DocumentCollection = __webpack_require__(613);
 
-  return data;
-}
+var _utils = __webpack_require__(623);
 
 function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/", ""]);
 
   _templateObject = function _templateObject() {
     return data;
@@ -108541,975 +107947,628 @@ function _templateObject() {
   return data;
 }
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
-
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
-
 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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var NOTES_DOCTYPE = 'io.cozy.notes';
-exports.NOTES_DOCTYPE = NOTES_DOCTYPE;
-var NOTES_URL_DOCTYPE = 'io.cozy.notes.url';
-exports.NOTES_URL_DOCTYPE = NOTES_URL_DOCTYPE;
+var JOBS_DOCTYPE = 'io.cozy.jobs';
+exports.JOBS_DOCTYPE = JOBS_DOCTYPE;
 
-var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_DOCTYPE);
+var sleep = function sleep(delay) {
+  return new Promise(function (resolve) {
+    return setTimeout(resolve, delay);
+  });
+};
 
-var normalizeNote = function normalizeNote(note) {
-  return _objectSpread(_objectSpread({}, normalizeDoc(note, NOTES_DOCTYPE)), note.attributes);
+var normalizeJob = function normalizeJob(job) {
+  return _objectSpread(_objectSpread(_objectSpread({}, job), (0, _DocumentCollection.normalizeDoc)(job, JOBS_DOCTYPE)), job.attributes);
 };
 
-var normalizeNoteUrl = function normalizeNoteUrl(noteUrl) {
-  return _objectSpread(_objectSpread({}, _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_URL_DOCTYPE)(noteUrl)), noteUrl.attributes);
+exports.normalizeJob = normalizeJob;
+
+var hasJobFinished = function hasJobFinished(job) {
+  return job.state === 'done' || job.state === 'errored';
 };
 /**
- * Implements `DocumentCollection` API to interact with the /notes endpoint of the stack
+ * Document representing a io.cozy.jobs
+ *
+ * @typedef {object} JobDocument
+ * @property {string} _id - Id of the job
+ * @property {string} attributes.state - state of the job. Can be 'errored', 'running', 'queued', 'done'
+ * @property {string} attributes.error - Error message of the job if any
  */
 
 
-var NotesCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(NotesCollection, _DocumentCollection);
-
-  var _super = _createSuper(NotesCollection);
+exports.hasJobFinished = hasJobFinished;
 
-  function NotesCollection(stackClient) {
-    (0, _classCallCheck2.default)(this, NotesCollection);
-    return _super.call(this, NOTES_DOCTYPE, stackClient);
+var JobCollection = /*#__PURE__*/function () {
+  function JobCollection(stackClient) {
+    (0, _classCallCheck2.default)(this, JobCollection);
+    this.stackClient = stackClient;
   }
-  /**
-   * Fetches all notes
-   *
-   * @returns {{data, links, meta}} The JSON API conformant response.
-   */
-
-
-  (0, _createClass2.default)(NotesCollection, [{
-    key: "all",
-    value: function () {
-      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-        var resp;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                _context.next = 2;
-                return this.stackClient.fetchJSON('GET', '/notes');
-
-              case 2:
-                resp = _context.sent;
-                return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
-                  data: resp.data.map(normalizeNote)
-                }));
-
-              case 4:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
-
-      function all() {
-        return _all.apply(this, arguments);
-      }
-
-      return all;
-    }()
-    /**
-     * Destroys the note on the server
-     *
-     * @param {object} note       The io.cozy.notes document to destroy
-     * @param {string} [note._id] The note's id
-     *
-     * @returns {{ data }} The deleted note
-     */
-
-  }, {
-    key: "destroy",
-    value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) {
-        var _id, resp;
-
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                _id = _ref._id;
-                _context2.next = 3;
-                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject(), _id));
-
-              case 3:
-                resp = _context2.sent;
-                return _context2.abrupt("return", {
-                  data: _objectSpread(_objectSpread({}, normalizeNote(resp.data)), {}, {
-                    _deleted: true
-                  })
-                });
-
-              case 5:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this);
-      }));
-
-      function destroy(_x) {
-        return _destroy.apply(this, arguments);
-      }
 
-      return destroy;
-    }()
+  (0, _createClass2.default)(JobCollection, [{
+    key: "queued",
+    value: function queued(workerType) {
+      return this.stackClient.fetchJSON('GET', "/jobs/queue/".concat(workerType));
+    }
     /**
-     * Create a note
-     *
-     * @param {object} options
-     * @param {string} [options.dir_id] dir_id where to create the note
+     * Creates a job
      *
-     * @returns {{data, links, meta}} The JSON API conformant response.
+     * @param  {string} workerType - Ex: "konnector"
+     * @param  {object} [args={}] - Ex: {"slug": "my-konnector", "trigger": "trigger-id"}
+     * @param  {object} [options={}] - creation options
+     * @param  {boolean} [manual=false] -  Manual execution
+     * @returns {object} createdJob
      */
 
   }, {
     key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref2) {
-        var dir_id, resp;
-        return _regenerator.default.wrap(function _callee3$(_context3) {
-          while (1) {
-            switch (_context3.prev = _context3.next) {
-              case 0:
-                dir_id = _ref2.dir_id;
-                _context3.next = 3;
-                return this.stackClient.fetchJSON('POST', '/notes', {
-                  data: {
-                    type: 'io.cozy.notes.documents',
-                    attributes: {
-                      title: '',
-                      schema: (0, _NotesSchema.getDefaultSchema)(),
-                      dir_id: dir_id
-                    }
-                  }
-                });
-
-              case 3:
-                resp = _context3.sent;
-                return _context3.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
-                  data: normalizeNote(resp.data)
-                }));
-
-              case 5:
-              case "end":
-                return _context3.stop();
-            }
-          }
-        }, _callee3, this);
-      }));
-
-      function create(_x2) {
-        return _create.apply(this, arguments);
-      }
-
-      return create;
-    }()
-    /**
-     * Returns the details to build the note's url
-     *
-     * @see https://github.com/cozy/cozy-stack/blob/master/docs/notes.md#get-notesidopen
-     *
-     * @param {object} note       The io.cozy.notes document to open
-     * @param {string} [note._id] The note's id
-     *
-     * @returns {{ data }} The note's url details
-     */
-
-  }, {
-    key: "fetchURL",
-    value: function () {
-      var _fetchURL = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(_ref3) {
-        var _id, resp;
-
-        return _regenerator.default.wrap(function _callee4$(_context4) {
-          while (1) {
-            switch (_context4.prev = _context4.next) {
-              case 0:
-                _id = _ref3._id;
-                _context4.next = 3;
-                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject2(), _id));
-
-              case 3:
-                resp = _context4.sent;
-                return _context4.abrupt("return", {
-                  data: normalizeNoteUrl(resp.data)
-                });
-
-              case 5:
-              case "end":
-                return _context4.stop();
-            }
-          }
-        }, _callee4, this);
-      }));
-
-      function fetchURL(_x3) {
-        return _fetchURL.apply(this, arguments);
-      }
-
-      return fetchURL;
-    }()
-    /**
-     * Returns promise mirror schema for a note
-     *
-     * @returns {object} schema
-     */
-
-  }, {
-    key: "getDefaultSchema",
-    value: function getDefaultSchema() {
-      return (0, _NotesSchema.getDefaultSchema)();
-    }
-  }]);
-  return NotesCollection;
-}(_DocumentCollection2.default);
-
-NotesCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
-var _default = NotesCollection;
-exports["default"] = _default;
-
-/***/ }),
-/* 676 */
-/***/ ((__unused_webpack_module, exports) => {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.getDefaultSchema = exports.marks = exports.nodes = void 0;
-// taken from a debug of @atlakit/editor/editor-core/create-editor/create-editor
-// L139 (new Schema({nodes ,marks}))
-// static because the @atlaskit code base requires a real navigator
-// TODO: either find and exclude plugins requiring interaction
-//       or running a JSDOM faking a navigator
-var nodes = [['doc', {
-  content: '(block)+',
-  marks: 'link'
-}], ['paragraph', {
-  content: 'inline*',
-  group: 'block',
-  marks: 'strong code em link strike subsup textColor typeAheadQuery underline',
-  parseDOM: [{
-    tag: 'p'
-  }]
-}], ['text', {
-  group: 'inline'
-}], ['bulletList', {
-  group: 'block',
-  content: 'listItem+',
-  parseDOM: [{
-    tag: 'ul'
-  }]
-}], ['orderedList', {
-  group: 'block',
-  content: 'listItem+',
-  parseDOM: [{
-    tag: 'ol'
-  }]
-}], ['listItem', {
-  content: '(paragraph ) (paragraph | bulletList | orderedList )*',
-  defining: true,
-  parseDOM: [{
-    tag: 'li'
-  }]
-}], ['heading', {
-  attrs: {
-    level: {
-      default: 1
-    }
-  },
-  content: 'inline*',
-  group: 'block',
-  defining: true,
-  parseDOM: [{
-    tag: 'h1',
-    attrs: {
-      level: 1
-    }
-  }, {
-    tag: 'h2',
-    attrs: {
-      level: 2
-    }
-  }, {
-    tag: 'h3',
-    attrs: {
-      level: 3
-    }
-  }, {
-    tag: 'h4',
-    attrs: {
-      level: 4
-    }
-  }, {
-    tag: 'h5',
-    attrs: {
-      level: 5
-    }
-  }, {
-    tag: 'h6',
-    attrs: {
-      level: 6
-    }
-  }]
-}], ['blockquote', {
-  content: 'paragraph+',
-  group: 'block',
-  defining: true,
-  selectable: false,
-  parseDOM: [{
-    tag: 'blockquote'
-  }]
-}], ['rule', {
-  group: 'block',
-  parseDOM: [{
-    tag: 'hr'
-  }]
-}], ['panel', {
-  group: 'block',
-  content: '(paragraph | heading | bulletList | orderedList)+',
-  attrs: {
-    panelType: {
-      default: 'info'
-    }
-  },
-  parseDOM: [{
-    tag: 'div[data-panel-type]'
-  }]
-}], ['confluenceUnsupportedBlock', {
-  group: 'block',
-  attrs: {
-    cxhtml: {
-      default: null
-    }
-  },
-  parseDOM: [{
-    tag: 'div[data-node-type="confluenceUnsupportedBlock"]'
-  }]
-}], ['confluenceUnsupportedInline', {
-  group: 'inline',
-  inline: true,
-  atom: true,
-  attrs: {
-    cxhtml: {
-      default: null
-    }
-  },
-  parseDOM: [{
-    tag: 'div[data-node-type="confluenceUnsupportedInline"]'
-  }]
-}], ['unsupportedBlock', {
-  inline: false,
-  group: 'block',
-  atom: true,
-  selectable: true,
-  attrs: {
-    originalValue: {
-      default: {}
-    }
-  },
-  parseDOM: [{
-    tag: '[data-node-type="unsupportedBlock"]'
-  }]
-}], ['unsupportedInline', {
-  inline: true,
-  group: 'inline',
-  selectable: true,
-  attrs: {
-    originalValue: {
-      default: {}
-    }
-  },
-  parseDOM: [{
-    tag: '[data-node-type="unsupportedInline"]'
-  }]
-}], ['hardBreak', {
-  inline: true,
-  group: 'inline',
-  selectable: false,
-  parseDOM: [{
-    tag: 'br'
-  }]
-}], ['table', {
-  content: 'tableRow+',
-  attrs: {
-    isNumberColumnEnabled: {
-      default: false
-    },
-    layout: {
-      default: 'default'
-    },
-    __autoSize: {
-      default: false
-    }
-  },
-  tableRole: 'table',
-  isolating: true,
-  selectable: false,
-  group: 'block',
-  parseDOM: [{
-    tag: 'table'
-  }]
-}], ['tableHeader', {
-  content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading )+',
-  attrs: {
-    colspan: {
-      default: 1
-    },
-    rowspan: {
-      default: 1
-    },
-    colwidth: {
-      default: null
-    },
-    background: {
-      default: null
-    }
-  },
-  tableRole: 'header_cell',
-  isolating: true,
-  marks: '',
-  parseDOM: [{
-    tag: 'th'
-  }]
-}], ['tableRow', {
-  content: '(tableCell | tableHeader)+',
-  tableRole: 'row',
-  parseDOM: [{
-    tag: 'tr'
-  }]
-}], ['tableCell', {
-  content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | unsupportedBlock)+',
-  attrs: {
-    colspan: {
-      default: 1
-    },
-    rowspan: {
-      default: 1
-    },
-    colwidth: {
-      default: null
-    },
-    background: {
-      default: null
-    }
-  },
-  tableRole: 'cell',
-  marks: '',
-  isolating: true,
-  parseDOM: [{
-    tag: '.ak-renderer-table-number-column',
-    ignore: true
-  }, {
-    tag: 'td'
-  }]
-}]];
-exports.nodes = nodes;
-var marks = [['link', {
-  excludes: 'color',
-  group: 'link',
-  attrs: {
-    href: {},
-    __confluenceMetadata: {
-      default: null
-    }
-  },
-  inclusive: false,
-  parseDOM: [{
-    tag: 'a[href]'
-  }]
-}], ['em', {
-  inclusive: true,
-  group: 'fontStyle',
-  parseDOM: [{
-    tag: 'i'
-  }, {
-    tag: 'em'
-  }, {
-    style: 'font-style=italic'
-  }]
-}], ['strong', {
-  inclusive: true,
-  group: 'fontStyle',
-  parseDOM: [{
-    tag: 'strong'
-  }, {
-    tag: 'b'
-  }, {
-    style: 'font-weight'
-  }]
-}], ['textColor', {
-  attrs: {
-    color: {}
-  },
-  inclusive: true,
-  group: 'color',
-  parseDOM: [{
-    style: 'color'
-  }]
-}], ['strike', {
-  inclusive: true,
-  group: 'fontStyle',
-  parseDOM: [{
-    tag: 'strike'
-  }, {
-    tag: 's'
-  }, {
-    tag: 'del'
-  }, {
-    style: 'text-decoration'
-  }]
-}], ['subsup', {
-  inclusive: true,
-  group: 'fontStyle',
-  attrs: {
-    type: {
-      default: 'sub'
-    }
-  },
-  parseDOM: [{
-    tag: 'sub',
-    attrs: {
-      type: 'sub'
-    }
-  }, {
-    tag: 'sup',
-    attrs: {
-      type: 'sup'
-    }
-  }]
-}], ['underline', {
-  inclusive: true,
-  group: 'fontStyle',
-  parseDOM: [{
-    tag: 'u'
-  }, {
-    style: 'text-decoration'
-  }]
-}], ['code', {
-  excludes: 'fontStyle link searchQuery color',
-  inclusive: true,
-  parseDOM: [{
-    tag: 'span.code',
-    preserveWhitespace: true
-  }, {
-    tag: 'code',
-    preserveWhitespace: true
+    value: function create(workerType) {
+      var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+      var manual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
+      return this.stackClient.fetchJSON('POST', "/jobs/queue/".concat(workerType), {
+        data: {
+          type: JOBS_DOCTYPE,
+          attributes: {
+            arguments: args,
+            options: options,
+            manual: manual
+          }
+        }
+      });
+    }
+    /**
+     * Return a normalized job, given its id
+     *
+     * @param {string} id - id of the job
+     * @returns {JobDocument}
+     */
+
   }, {
-    tag: 'tt',
-    preserveWhitespace: true
+    key: "get",
+    value: function () {
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) {
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                return _context.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject(), id), {
+                  normalize: normalizeJob
+                }));
+
+              case 1:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
+
+      function get(_x) {
+        return _get.apply(this, arguments);
+      }
+
+      return get;
+    }()
+    /**
+     * Update the job's state
+     * This does work only for jobs comming from @client triggers
+     *
+     * @param {JobDocument} job - io.cozy.jobs document
+     */
+
   }, {
-    tag: 'span',
-    preserveWhitespace: true
-  }]
-}], ['typeAheadQuery', {
-  excludes: 'searchQuery',
-  inclusive: true,
-  group: 'searchQuery',
-  parseDOM: [{
-    tag: 'span[data-type-ahead-query]'
-  }],
-  attrs: {
-    trigger: {
-      default: ''
-    }
-  }
-}]];
-exports.marks = marks;
+    key: "update",
+    value: function () {
+      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(job) {
+        var jobResult;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                if (!(job.worker !== 'client')) {
+                  _context2.next = 2;
+                  break;
+                }
 
-var getDefaultSchema = function getDefaultSchema() {
-  return {
-    nodes: nodes,
-    marks: marks
-  };
-};
+                throw new Error("JobCollection.update only works for client workers. ".concat(job.worker, " given"));
 
-exports.getDefaultSchema = getDefaultSchema;
+              case 2:
+                _context2.next = 4;
+                return this.stackClient.fetchJSON('PATCH', "/jobs/".concat(job._id), {
+                  data: {
+                    type: JOBS_DOCTYPE,
+                    id: job._id,
+                    attributes: {
+                      state: job.attributes.state,
+                      error: job.attributes.error
+                    }
+                  }
+                });
 
-/***/ }),
-/* 677 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+              case 4:
+                jobResult = _context2.sent;
+                return _context2.abrupt("return", normalizeJob(jobResult.data));
 
-"use strict";
+              case 6:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
 
+      function update(_x2) {
+        return _update.apply(this, arguments);
+      }
 
-var _interopRequireWildcard = __webpack_require__(510);
+      return update;
+    }()
+    /**
+     * Polls a job state until it is finished
+     *
+     * `options.until` can be used to tweak when to stop waiting. It will be
+     * given the current job state. If true is returned, the awaiting is
+     * stopped.
+     */
 
-var _interopRequireDefault = __webpack_require__(512);
+  }, {
+    key: "waitFor",
+    value: function () {
+      var _waitFor = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(id) {
+        var _ref,
+            _ref$onUpdate,
+            onUpdate,
+            _ref$until,
+            until,
+            _ref$delay,
+            delay,
+            _ref$timeout,
+            timeout,
+            start,
+            jobData,
+            now,
+            _args3 = arguments;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.OAUTH_CLIENTS_DOCTYPE = void 0;
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                _ref = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref$onUpdate = _ref.onUpdate, onUpdate = _ref$onUpdate === void 0 ? null : _ref$onUpdate, _ref$until = _ref.until, until = _ref$until === void 0 ? hasJobFinished : _ref$until, _ref$delay = _ref.delay, delay = _ref$delay === void 0 ? 5 * 1000 : _ref$delay, _ref$timeout = _ref.timeout, timeout = _ref$timeout === void 0 ? 60 * 5 * 1000 : _ref$timeout;
+                start = Date.now();
+                _context3.next = 4;
+                return this.get(id);
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+              case 4:
+                jobData = _context3.sent.data.attributes;
 
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
+              case 5:
+                if (!(!jobData || !until(jobData))) {
+                  _context3.next = 17;
+                  break;
+                }
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+                _context3.next = 8;
+                return sleep(delay);
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+              case 8:
+                _context3.next = 10;
+                return this.get(id);
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+              case 10:
+                jobData = _context3.sent.data.attributes;
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+                if (onUpdate) {
+                  onUpdate(jobData);
+                }
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+                now = Date.now();
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+                if (!(start - now > timeout)) {
+                  _context3.next = 15;
+                  break;
+                }
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+                throw new Error('Timeout for JobCollection::waitFor');
 
-var _get2 = _interopRequireDefault(__webpack_require__(358));
+              case 15:
+                _context3.next = 5;
+                break;
 
-var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601));
+              case 17:
+                return _context3.abrupt("return", jobData);
 
-var _utils = __webpack_require__(611);
+              case 18:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
 
-var querystring = _interopRequireWildcard(__webpack_require__(647));
+      function waitFor(_x3) {
+        return _waitFor.apply(this, arguments);
+      }
 
-var _Collection = __webpack_require__(600);
+      return waitFor;
+    }()
+  }]);
+  return JobCollection;
+}();
 
-var _errors = __webpack_require__(651);
+var _default = JobCollection;
+exports["default"] = _default;
 
-function _templateObject3() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]);
+/***/ }),
+/* 680 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  _templateObject3 = function _templateObject3() {
-    return data;
-  };
+"use strict";
 
-  return data;
-}
 
-function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]);
+var _interopRequireWildcard = __webpack_require__(522);
 
-  _templateObject2 = function _templateObject2() {
-    return data;
-  };
+var _interopRequireDefault = __webpack_require__(524);
 
-  return data;
-}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = exports.KONNECTORS_DOCTYPE = void 0;
 
-function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients"]);
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-  _templateObject = function _templateObject() {
-    return data;
-  };
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-  return data;
-}
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-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; }
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var OAUTH_CLIENTS_DOCTYPE = 'io.cozy.oauth.clients';
-exports.OAUTH_CLIENTS_DOCTYPE = OAUTH_CLIENTS_DOCTYPE;
+var _pick = _interopRequireDefault(__webpack_require__(676));
 
-var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(OAUTH_CLIENTS_DOCTYPE);
+var _AppCollection2 = _interopRequireDefault(__webpack_require__(602));
 
-var normalizeOAuthClient = function normalizeOAuthClient(client) {
-  return _objectSpread(_objectSpread({}, normalizeDoc(client, OAUTH_CLIENTS_DOCTYPE)), client.attributes);
-};
-/**
- * Implements `DocumentCollection` API to interact with the /settings/clients endpoint of the stack
- */
+var _TriggerCollection = _interopRequireWildcard(__webpack_require__(681));
 
+var _DocumentCollection = __webpack_require__(613);
 
-var OAuthClientsCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(OAuthClientsCollection, _DocumentCollection);
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-  var _super = _createSuper(OAuthClientsCollection);
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-  function OAuthClientsCollection(stackClient) {
-    (0, _classCallCheck2.default)(this, OAuthClientsCollection);
-    return _super.call(this, OAUTH_CLIENTS_DOCTYPE, stackClient);
-  }
-  /**
-   * Fetches all OAuth clients
-   *
-   * @param  {object}         options             Query options
-   * @param  {number}         [options.limit]     For pagination, the number of results to return.
-   * @param  {string}         [options.bookmark]  For bookmark-based pagination, the document _id to start from
-   * @param  {Array<string>}  [options.keys]      Ids of specific clients to return (within the current page),
-   *
-   * @returns {object} The JSON API conformant response.
-   */
+var KONNECTORS_DOCTYPE = 'io.cozy.konnectors';
+exports.KONNECTORS_DOCTYPE = KONNECTORS_DOCTYPE;
 
+var KonnectorCollection = /*#__PURE__*/function (_AppCollection) {
+  (0, _inherits2.default)(KonnectorCollection, _AppCollection);
 
-  (0, _createClass2.default)(OAuthClientsCollection, [{
-    key: "all",
-    value: function () {
-      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-        var options,
-            _options$limit,
-            limit,
-            bookmark,
-            keys,
-            params,
-            url,
-            path,
-            resp,
-            nextLink,
-            nextLinkURL,
-            nextBookmark,
-            hasBookmark,
-            data,
-            meta,
-            _args = arguments;
+  var _super = _createSuper(KonnectorCollection);
+
+  function KonnectorCollection(stackClient) {
+    var _this;
+
+    (0, _classCallCheck2.default)(this, KonnectorCollection);
+    _this = _super.call(this, stackClient);
+    _this.doctype = KONNECTORS_DOCTYPE;
+    _this.endpoint = '/konnectors/';
+    return _this;
+  }
 
+  (0, _createClass2.default)(KonnectorCollection, [{
+    key: "create",
+    value: function () {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
         return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
               case 0:
-                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
-                _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, bookmark = options.bookmark, keys = options.keys;
-                params = {
-                  'page[limit]': limit,
-                  'page[cursor]': bookmark
-                };
-                url = (0, _utils.uri)(_templateObject());
-                path = querystring.buildURL(url, params);
-                _context.prev = 5;
-                _context.next = 8;
-                return this.stackClient.fetchJSON('GET', path);
+                throw new Error('create() method is not available for konnectors');
 
-              case 8:
-                resp = _context.sent;
-                _context.next = 14;
-                break;
+              case 1:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee);
+      }));
 
-              case 11:
-                _context.prev = 11;
-                _context.t0 = _context["catch"](5);
-                return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0));
+      function create() {
+        return _create.apply(this, arguments);
+      }
 
-              case 14:
-                nextLink = (0, _get2.default)(resp, 'links.next', '');
-                nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink));
-                nextBookmark = nextLinkURL.searchParams.get('page[cursor]') || undefined;
-                hasBookmark = nextBookmark !== undefined;
+      return create;
+    }()
+  }, {
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                throw new Error('destroy() method is not available for konnectors');
 
-                if (!keys) {
-                  _context.next = 24;
-                  break;
-                }
+              case 1:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2);
+      }));
 
-                data = resp.data.filter(function (c) {
-                  return keys.includes(c.id);
-                }).map(function (c) {
-                  return normalizeOAuthClient(c);
-                });
-                meta = _objectSpread(_objectSpread({}, resp.meta), {}, {
-                  count: data.length
-                });
-                return _context.abrupt("return", {
-                  data: data,
-                  meta: meta,
-                  next: keys.length > data.length && hasBookmark,
-                  bookmark: nextBookmark
-                });
+      function destroy() {
+        return _destroy.apply(this, arguments);
+      }
 
-              case 24:
-                return _context.abrupt("return", {
-                  data: resp.data.map(function (c) {
-                    return normalizeOAuthClient(c);
-                  }),
-                  meta: resp.meta,
-                  next: hasBookmark,
-                  bookmark: nextBookmark
+      return destroy;
+    }()
+    /**
+     * Find triggers for a particular konnector
+     *
+     * @param  {string} slug of the konnector
+     */
+
+  }, {
+    key: "findTriggersBySlug",
+    value: function () {
+      var _findTriggersBySlug = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(slug) {
+        var triggerCol, _yield$triggerCol$all, rawTriggers;
+
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                triggerCol = new _TriggerCollection.default(this.stackClient);
+                _context3.next = 3;
+                return triggerCol.all({
+                  limit: null
                 });
 
-              case 25:
+              case 3:
+                _yield$triggerCol$all = _context3.sent;
+                rawTriggers = _yield$triggerCol$all.data;
+                return _context3.abrupt("return", rawTriggers.map(function (x) {
+                  return x.attributes;
+                }).filter(function (triggerAttrs) {
+                  return (0, _TriggerCollection.isForKonnector)(triggerAttrs, slug);
+                }));
+
+              case 6:
               case "end":
-                return _context.stop();
+                return _context3.stop();
             }
           }
-        }, _callee, this, [[5, 11]]);
+        }, _callee3, this);
       }));
 
-      function all() {
-        return _all.apply(this, arguments);
+      function findTriggersBySlug(_x) {
+        return _findTriggersBySlug.apply(this, arguments);
       }
 
-      return all;
+      return findTriggersBySlug;
     }()
     /**
-     * Get an OAuth client by id
+     * Launch a trigger for a given konnector.
      *
-     * @param  {string} id The client id.
-     * @returns {object}  JsonAPI response containing normalized client as data attribute
+     * @param  {string} slug
+     * @param  {object} options
+     * @param  {object} options.accountId - Pinpoint the account that should be used, useful if the user
+     * has more than 1 account for 1 konnector
      */
 
   }, {
-    key: "get",
+    key: "launch",
     value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
-        var resp;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
+      var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(slug) {
+        var options,
+            triggerCol,
+            konnTriggers,
+            filteredTriggers,
+            filterAttrs,
+            _args4 = arguments;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
           while (1) {
-            switch (_context2.prev = _context2.next) {
+            switch (_context4.prev = _context4.next) {
               case 0:
-                _context2.next = 2;
-                return this.all({
-                  keys: [id]
-                });
+                options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {};
+                triggerCol = new _TriggerCollection.default(this.stackClient);
+                _context4.next = 4;
+                return this.findTriggersBySlug(slug);
 
-              case 2:
-                resp = _context2.sent;
+              case 4:
+                konnTriggers = _context4.sent;
+                filteredTriggers = options.accountId ? konnTriggers.filter(function (triggerAttrs) {
+                  return (0, _TriggerCollection.isForAccount)(triggerAttrs, options.accountId);
+                }) : konnTriggers;
 
-              case 3:
-                if (!resp.next) {
-                  _context2.next = 9;
+                if (!(filteredTriggers.length === 1)) {
+                  _context4.next = 10;
                   break;
                 }
 
-                _context2.next = 6;
-                return this.all({
-                  keys: [id],
-                  bookmark: resp.bookmark
-                });
+                return _context4.abrupt("return", triggerCol.launch(konnTriggers[0]));
 
-              case 6:
-                resp = _context2.sent;
-                _context2.next = 3;
-                break;
+              case 10:
+                filterAttrs = JSON.stringify((0, _pick.default)({
+                  slug: slug,
+                  accountId: options.accountId
+                }));
 
-              case 9:
-                if (!resp.data.length) {
-                  _context2.next = 13;
+                if (!(filteredTriggers.length === 0)) {
+                  _context4.next = 15;
                   break;
                 }
 
-                return _context2.abrupt("return", {
-                  data: normalizeOAuthClient(resp.data[0])
-                });
+                throw new Error("No trigger found for ".concat(filterAttrs));
 
-              case 13:
-                resp.url = (0, _utils.uri)(_templateObject2(), id);
-                resp.status = '404';
-                throw new _errors.FetchError(resp, 'Not Found');
+              case 15:
+                if (!(filteredTriggers.length > 1)) {
+                  _context4.next = 17;
+                  break;
+                }
 
-              case 16:
+                throw new Error("More than 1 trigger found for ".concat(filterAttrs));
+
+              case 17:
               case "end":
-                return _context2.stop();
+                return _context4.stop();
             }
           }
-        }, _callee2, this);
+        }, _callee4, this);
       }));
 
-      function get(_x) {
-        return _get.apply(this, arguments);
+      function launch(_x2) {
+        return _launch.apply(this, arguments);
       }
 
-      return get;
+      return launch;
     }()
     /**
-     * Destroys the OAuth client on the server
-     *
-     * @param {object} oauthClient The io.cozy.oauth.clients document to destroy
+     * Updates a konnector
      *
-     * @returns {{ data }} The deleted client
+     * @param  {string} slug
+     * @param  {object} options
+     * @param  {object} options.source - Specify the source (ex: registry://slug/stable)
+     * @param  {boolean} options.sync - Wait for konnector to be updated, otherwise the job
+     * is just scheduled
      */
 
   }, {
-    key: "destroy",
+    key: "update",
     value: function () {
-      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(oauthClient) {
-        var _id;
-
-        return _regenerator.default.wrap(function _callee3$(_context3) {
+      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(slug) {
+        var options,
+            source,
+            sync,
+            reqOptions,
+            rawKonnector,
+            _args5 = arguments;
+        return _regenerator.default.wrap(function _callee5$(_context5) {
           while (1) {
-            switch (_context3.prev = _context3.next) {
+            switch (_context5.prev = _context5.next) {
               case 0:
-                _id = oauthClient._id;
-                _context3.next = 3;
-                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), _id));
+                options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
+
+                if (slug) {
+                  _context5.next = 3;
+                  break;
+                }
+
+                throw new Error('Cannot call update with no slug');
 
               case 3:
-                return _context3.abrupt("return", {
-                  data: _objectSpread(_objectSpread({}, normalizeOAuthClient(oauthClient)), {}, {
-                    _deleted: true
-                  })
-                });
+                source = options.source || null;
+                sync = options.sync || false;
+                reqOptions = sync ? {
+                  headers: {
+                    Accept: 'text/event-stream'
+                  }
+                } : {};
+                _context5.next = 8;
+                return this.stackClient.fetchJSON('PUT', "/konnectors/".concat(slug) + (source ? "?Source=".concat(source) : ''), reqOptions);
 
-              case 4:
+              case 8:
+                rawKonnector = _context5.sent;
+                return _context5.abrupt("return", (0, _DocumentCollection.normalizeDoc)(rawKonnector));
+
+              case 10:
               case "end":
-                return _context3.stop();
+                return _context5.stop();
             }
           }
-        }, _callee3, this);
+        }, _callee5, this);
       }));
 
-      function destroy(_x2) {
-        return _destroy.apply(this, arguments);
+      function update(_x3) {
+        return _update.apply(this, arguments);
       }
 
-      return destroy;
+      return update;
     }()
   }]);
-  return OAuthClientsCollection;
-}(_DocumentCollection2.default);
+  return KonnectorCollection;
+}(_AppCollection2.default);
 
-OAuthClientsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
-var _default = OAuthClientsCollection;
+var _default = KonnectorCollection;
 exports["default"] = _default;
 
 /***/ }),
-/* 678 */
+/* 681 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireWildcard = __webpack_require__(522);
+
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.SHORTCUTS_DOCTYPE = void 0;
+exports["default"] = exports.isForAccount = exports.isForKonnector = exports.normalizeTrigger = exports.TRIGGERS_DOCTYPE = exports.JOBS_DOCTYPE = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602));
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var _get3 = _interopRequireDefault(__webpack_require__(682));
+
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
+
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
+
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
+
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
+
+var _Collection = _interopRequireWildcard(__webpack_require__(612));
+
+var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613));
+
+var _JobCollection = __webpack_require__(679);
+
+var _utils = __webpack_require__(623);
+
+var _errors = __webpack_require__(663);
+
+function _templateObject4() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", "/launch"]);
+
+  _templateObject4 = function _templateObject4() {
+    return data;
+  };
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+  return data;
+}
 
-var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601));
+function _templateObject3() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]);
 
-var _utils = __webpack_require__(611);
+  _templateObject3 = function _templateObject3() {
+    return data;
+  };
 
-var _getIllegalCharacter = __webpack_require__(666);
+  return data;
+}
 
 function _templateObject2() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts/", ""]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]);
 
   _templateObject2 = function _templateObject2() {
     return data;
@@ -109519,7 +108578,7 @@ function _templateObject2() {
 }
 
 function _templateObject() {
-  var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts"]);
+  var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers"]);
 
   _templateObject = function _templateObject() {
     return data;
@@ -109532,116 +108591,155 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
 
 function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var SHORTCUTS_DOCTYPE = 'io.cozy.files.shortcuts';
-exports.SHORTCUTS_DOCTYPE = SHORTCUTS_DOCTYPE;
+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; }
 
-var ShortcutsCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(ShortcutsCollection, _DocumentCollection);
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-  var _super = _createSuper(ShortcutsCollection);
+var JOBS_DOCTYPE = 'io.cozy.jobs';
+exports.JOBS_DOCTYPE = JOBS_DOCTYPE;
+var TRIGGERS_DOCTYPE = 'io.cozy.triggers';
+exports.TRIGGERS_DOCTYPE = TRIGGERS_DOCTYPE;
 
-  function ShortcutsCollection(stackClient) {
-    (0, _classCallCheck2.default)(this, ShortcutsCollection);
-    return _super.call(this, SHORTCUTS_DOCTYPE, stackClient);
-  }
-  /**
-   * Create a shortcut
-   *
-   * @param {object} attributes shortcut's attributes
-   * @param {string} attributes.name Filename
-   * @param {string} attributes.url Shortcut's URL
-   * @param {string} attributes.dir_id dir_id where to create the shortcut
-   * @throws {Error} - explaining reason why creation failed
-   */
+var normalizeTrigger = function normalizeTrigger(trigger) {
+  return _objectSpread(_objectSpread(_objectSpread({}, trigger), (0, _DocumentCollection2.normalizeDoc)(trigger, TRIGGERS_DOCTYPE)), trigger.attributes);
+};
 
+exports.normalizeTrigger = normalizeTrigger;
 
-  (0, _createClass2.default)(ShortcutsCollection, [{
-    key: "create",
-    value: function () {
-      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(attributes) {
-        var name, illegalCharacters, path, resp;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                if (!attributes.type) {
-                  attributes.type = SHORTCUTS_DOCTYPE;
-                }
+var isForKonnector = function isForKonnector(triggerAttrs, slug) {
+  return triggerAttrs.worker === 'konnector' && triggerAttrs.message.konnector == slug;
+};
 
-                if (!(!attributes.name || !attributes.name.trim() || !attributes.url || !attributes.dir_id)) {
-                  _context.next = 3;
-                  break;
-                }
+exports.isForKonnector = isForKonnector;
 
-                throw new Error('you need at least a name, an url and a dir_id attributes to create a shortcut');
+var isForAccount = function isForAccount(triggerAttrs, accountId) {
+  return triggerAttrs.message.account == accountId;
+};
 
-              case 3:
-                name = attributes.name.trim();
+exports.isForAccount = isForAccount;
 
-                if (!(name === '.' || name === '..')) {
-                  _context.next = 6;
-                  break;
-                }
+var buildParamsUrl = function buildParamsUrl(worker, type) {
+  var urlParams = new URLSearchParams();
 
-                throw new Error("Invalid filename: ".concat(name));
+  if (worker) {
+    if (Array.isArray(worker.$in)) {
+      urlParams.set('Worker', worker.$in.join(','));
+    } else {
+      urlParams.set('Worker', worker);
+    }
+  }
 
-              case 6:
-                illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(name);
+  if (type) {
+    if (Array.isArray(type.$in)) {
+      urlParams.set('Type', type.$in.join(','));
+    } else {
+      urlParams.set('Type', type);
+    }
+  }
 
-                if (!illegalCharacters.length) {
-                  _context.next = 9;
-                  break;
-                }
+  return urlParams.toString();
+};
+/**
+ * Implements `DocumentCollection` API along with specific methods for `io.cozy.triggers`.
+ */
 
-                throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters));
 
-              case 9:
-                path = (0, _utils.uri)(_templateObject());
-                _context.next = 12;
-                return this.stackClient.fetchJSON('POST', path, {
-                  data: {
-                    attributes: attributes,
-                    type: 'io.cozy.files.shortcuts'
-                  }
-                });
+var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(TriggerCollection, _DocumentCollection);
 
-              case 12:
+  var _super = _createSuper(TriggerCollection);
+
+  function TriggerCollection(stackClient) {
+    (0, _classCallCheck2.default)(this, TriggerCollection);
+    return _super.call(this, TRIGGERS_DOCTYPE, stackClient);
+  }
+  /**
+   * Get the list of triggers.
+   *
+   * @see https://docs.cozy.io/en/cozy-stack/jobs/#get-jobstriggers
+   * @param  {{Worker}} options The fetch options: Worker allow to filter only triggers associated with a specific worker.
+   * @returns {{data}} The JSON API conformant response.
+   * @throws {FetchError}
+   */
+
+
+  (0, _createClass2.default)(TriggerCollection, [{
+    key: "all",
+    value: function () {
+      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var options,
+            resp,
+            _args = arguments;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
+                _context.prev = 1;
+                _context.next = 4;
+                return this.stackClient.fetchJSON('GET', "/jobs/triggers");
+
+              case 4:
                 resp = _context.sent;
                 return _context.abrupt("return", {
-                  data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp)
+                  data: resp.data.map(function (row) {
+                    return normalizeTrigger(row, TRIGGERS_DOCTYPE);
+                  }),
+                  meta: {
+                    count: resp.data.length
+                  },
+                  next: false,
+                  skip: 0
                 });
 
-              case 14:
+              case 8:
+                _context.prev = 8;
+                _context.t0 = _context["catch"](1);
+                return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0));
+
+              case 11:
               case "end":
                 return _context.stop();
             }
           }
-        }, _callee, this);
+        }, _callee, this, [[1, 8]]);
       }));
 
-      function create(_x) {
-        return _create.apply(this, arguments);
+      function all() {
+        return _all.apply(this, arguments);
       }
 
-      return create;
+      return all;
     }()
+    /**
+     * Creates a Trigger document
+     *
+     * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggers
+     * @param  {object}  attributes Trigger's attributes
+     * @returns {object}  Stack response, containing trigger document under `data` attribute.
+     */
+
   }, {
-    key: "get",
+    key: "create",
     value: function () {
-      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(attributes) {
         var path, resp;
         return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
-                path = (0, _utils.uri)(_templateObject2(), id);
+                path = (0, _utils.uri)(_templateObject());
                 _context2.next = 3;
-                return this.stackClient.fetchJSON('GET', path);
+                return this.stackClient.fetchJSON('POST', path, {
+                  data: {
+                    attributes: attributes
+                  }
+                });
 
               case 3:
                 resp = _context2.sent;
                 return _context2.abrupt("return", {
-                  data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp)
+                  data: normalizeTrigger(resp.data)
                 });
 
               case 5:
@@ -109652,1112 +108750,1109 @@ var ShortcutsCollection = /*#__PURE__*/function (_DocumentCollection) {
         }, _callee2, this);
       }));
 
-      function get(_x2) {
-        return _get.apply(this, arguments);
+      function create(_x) {
+        return _create.apply(this, arguments);
       }
 
-      return get;
+      return create;
     }()
-  }]);
-  return ShortcutsCollection;
-}(_DocumentCollection2.default);
-
-ShortcutsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
-var _default = ShortcutsCollection;
-exports["default"] = _default;
-
-/***/ }),
-/* 679 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
+    /**
+     * Deletes a trigger
+     *
+     * @see https://docs.cozy.io/en/cozy-stack/jobs/#delete-jobstriggerstrigger-id
+     * @param  {object} document The trigger to delete — must have an _id field
+     * @returns {object} The deleted document
+     */
 
+  }, {
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) {
+        var _id;
 
-var _interopRequireWildcard = __webpack_require__(510);
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                _id = document._id;
 
-var _interopRequireDefault = __webpack_require__(512);
+                if (_id) {
+                  _context3.next = 3;
+                  break;
+                }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.CONTACTS_DOCTYPE = void 0;
+                throw new Error('TriggerCollection.destroy needs a document with an _id');
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+              case 3:
+                _context3.next = 5;
+                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), _id));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+              case 5:
+                return _context3.abrupt("return", {
+                  data: normalizeTrigger(_objectSpread(_objectSpread({}, document), {}, {
+                    _deleted: true
+                  }))
+                });
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+              case 6:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+      function destroy(_x2) {
+        return _destroy.apply(this, arguments);
+      }
 
-var _get2 = _interopRequireDefault(__webpack_require__(670));
+      return destroy;
+    }()
+    /**
+     *
+     * Be warned, ATM /jobs/triggers does not return the same informations
+     * than /data/io.cozy.triggers (used by the super.find method).
+     *
+     * See https://github.com/cozy/cozy-stack/pull/2010
+     *
+     * @param {object} selector - Which kind of worker {konnector,service}
+     * @param {object} options - Options
+     * @returns {{data, meta, skip, next}} The JSON API conformant response.
+     * @throws {FetchError}
+     */
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+  }, {
+    key: "find",
+    value: function () {
+      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
+        var selector,
+            options,
+            worker,
+            type,
+            rest,
+            hasOnlyWorkerAndType,
+            url,
+            resp,
+            _args4 = arguments;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                selector = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
+                options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {};
+                worker = selector.worker, type = selector.type, rest = (0, _objectWithoutProperties2.default)(selector, ["worker", "type"]);
+                hasOnlyWorkerAndType = Object.keys(rest).length === 0;
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+                if (!hasOnlyWorkerAndType) {
+                  _context4.next = 18;
+                  break;
+                }
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+                // @see https://github.com/cozy/cozy-stack/blob/master/docs/jobs.md#get-jobstriggers
+                url = "/jobs/triggers?".concat(buildParamsUrl(worker, type));
+                _context4.prev = 6;
+                _context4.next = 9;
+                return this.stackClient.fetchJSON('GET', url);
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+              case 9:
+                resp = _context4.sent;
+                return _context4.abrupt("return", {
+                  data: resp.data.map(function (row) {
+                    return normalizeTrigger(row, TRIGGERS_DOCTYPE);
+                  }),
+                  meta: {
+                    count: resp.data.length
+                  },
+                  next: false,
+                  skip: 0
+                });
 
-var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601));
+              case 13:
+                _context4.prev = 13;
+                _context4.t0 = _context4["catch"](6);
+                return _context4.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context4.t0));
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+              case 16:
+                _context4.next = 19;
+                break;
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+              case 18:
+                return _context4.abrupt("return", (0, _get3.default)((0, _getPrototypeOf2.default)(TriggerCollection.prototype), "find", this).call(this, selector, options));
 
-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; }
+              case 19:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this, [[6, 13]]);
+      }));
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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 find() {
+        return _find.apply(this, arguments);
+      }
 
-var normalizeMyselfResp = function normalizeMyselfResp(resp) {
-  return _objectSpread(_objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(resp.data, CONTACTS_DOCTYPE)), resp.data.attributes), {}, {
-    _rev: resp.data.meta.rev
-  });
-};
+      return find;
+    }()
+  }, {
+    key: "get",
+    value: function () {
+      var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(id) {
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                return _context5.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject3(), id), {
+                  normalize: normalizeTrigger
+                }));
 
-var ContactsCollection = /*#__PURE__*/function (_DocumentCollection) {
-  (0, _inherits2.default)(ContactsCollection, _DocumentCollection);
+              case 1:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this);
+      }));
 
-  var _super = _createSuper(ContactsCollection);
+      function get(_x3) {
+        return _get2.apply(this, arguments);
+      }
 
-  function ContactsCollection() {
-    (0, _classCallCheck2.default)(this, ContactsCollection);
-    return _super.apply(this, arguments);
-  }
+      return get;
+    }()
+    /**
+     * Force given trigger execution.
+     *
+     * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggerstrigger-idlaunch
+     * @param {object} trigger Trigger to launch
+     * @returns {object} Stack response, containing job launched by trigger, under `data` attribute.
+     */
 
-  (0, _createClass2.default)(ContactsCollection, [{
-    key: "find",
+  }, {
+    key: "launch",
     value: function () {
-      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) {
-        return _regenerator.default.wrap(function _callee$(_context) {
+      var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(trigger) {
+        var path, resp;
+        return _regenerator.default.wrap(function _callee6$(_context6) {
           while (1) {
-            switch (_context.prev = _context.next) {
+            switch (_context6.prev = _context6.next) {
               case 0:
-                if (!(Object.values(selector).length === 1 && selector['me'] == true)) {
-                  _context.next = 4;
-                  break;
-                }
-
-                return _context.abrupt("return", this.findMyself());
+                path = (0, _utils.uri)(_templateObject4(), trigger._id);
+                _context6.next = 3;
+                return this.stackClient.fetchJSON('POST', path);
 
-              case 4:
-                return _context.abrupt("return", (0, _get2.default)((0, _getPrototypeOf2.default)(ContactsCollection.prototype), "find", this).call(this, selector, options));
+              case 3:
+                resp = _context6.sent;
+                return _context6.abrupt("return", {
+                  data: (0, _JobCollection.normalizeJob)(resp.data)
+                });
 
               case 5:
               case "end":
-                return _context.stop();
+                return _context6.stop();
             }
           }
-        }, _callee, this);
+        }, _callee6, this);
       }));
 
-      function find(_x, _x2) {
-        return _find.apply(this, arguments);
+      function launch(_x4) {
+        return _launch.apply(this, arguments);
       }
 
-      return find;
+      return launch;
     }()
   }, {
-    key: "findMyself",
+    key: "update",
     value: function () {
-      var _findMyself = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-        var resp, col;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
+      var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() {
+        return _regenerator.default.wrap(function _callee7$(_context7) {
           while (1) {
-            switch (_context2.prev = _context2.next) {
+            switch (_context7.prev = _context7.next) {
               case 0:
-                _context2.next = 2;
-                return this.stackClient.fetchJSON('POST', '/contacts/myself');
-
-              case 2:
-                resp = _context2.sent;
-                col = {
-                  data: [normalizeMyselfResp(resp)],
-                  next: false,
-                  meta: null,
-                  bookmark: false
-                };
-                return _context2.abrupt("return", col);
+                throw new Error('update() method is not available for triggers');
 
-              case 5:
+              case 1:
               case "end":
-                return _context2.stop();
+                return _context7.stop();
             }
           }
-        }, _callee2, this);
+        }, _callee7);
       }));
 
-      function findMyself() {
-        return _findMyself.apply(this, arguments);
+      function update() {
+        return _update.apply(this, arguments);
       }
 
-      return findMyself;
+      return update;
     }()
   }]);
-  return ContactsCollection;
+  return TriggerCollection;
 }(_DocumentCollection2.default);
 
-var CONTACTS_DOCTYPE = 'io.cozy.contacts';
-exports.CONTACTS_DOCTYPE = CONTACTS_DOCTYPE;
-var _default = ContactsCollection;
+TriggerCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+var _default = TriggerCollection;
 exports["default"] = _default;
 
 /***/ }),
-/* 680 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 682 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var superPropBase = __webpack_require__(683);
 
+function _get(target, property, receiver) {
+  if (typeof Reflect !== "undefined" && Reflect.get) {
+    module.exports = _get = Reflect.get;
+    module.exports["default"] = module.exports, module.exports.__esModule = true;
+  } else {
+    module.exports = _get = function _get(target, property, receiver) {
+      var base = superPropBase(target, property);
+      if (!base) return;
+      var desc = Object.getOwnPropertyDescriptor(base, property);
 
-var _interopRequireWildcard = __webpack_require__(510);
+      if (desc.get) {
+        return desc.get.call(receiver);
+      }
 
-var _interopRequireDefault = __webpack_require__(512);
+      return desc.value;
+    };
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.getIconURL = exports["default"] = exports._getIconURL = void 0;
+    module.exports["default"] = module.exports, module.exports.__esModule = true;
+  }
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+  return _get(target, property, receiver || target);
+}
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+module.exports = _get;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-var _memoize = _interopRequireWildcard(__webpack_require__(681));
+/***/ }),
+/* 683 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+var getPrototypeOf = __webpack_require__(607);
 
-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 _superPropBase(object, property) {
+  while (!Object.prototype.hasOwnProperty.call(object, property)) {
+    object = getPrototypeOf(object);
+    if (object === null) break;
+  }
 
-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; }
+  return object;
+}
 
-/**
- * Get Icon source Url
- *
- * @param  {object}  app - Apps data - io.cozy.apps
- * @param  {string}  slug - Slug - string
- * @param  {string|undefined} domain - Host to use in the origin (e.g. cozy.tools)
- * @param  {string} protocol - Url protocol (e.g. http / https)
- * @returns {string}  Source Url of icon
- * @private
- * @throws {Error} When cannot fetch or get icon source
- */
-var loadIcon = /*#__PURE__*/function () {
-  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, slug, domain, protocol) {
-    var source;
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            if (domain) {
-              _context.next = 2;
-              break;
-            }
+module.exports = _superPropBase;
+module.exports["default"] = module.exports, module.exports.__esModule = true;
 
-            throw new Error('Cannot fetch icon: missing domain');
+/***/ }),
+/* 684 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-          case 2:
-            source = _getAppIconURL(app, slug, domain, protocol);
+"use strict";
 
-            if (source) {
-              _context.next = 5;
-              break;
-            }
 
-            throw new Error("Cannot get icon source for app ".concat(app.name));
+var _interopRequireWildcard = __webpack_require__(522);
 
-          case 5:
-            return _context.abrupt("return", source);
+var _interopRequireDefault = __webpack_require__(524);
 
-          case 6:
-          case "end":
-            return _context.stop();
-        }
-      }
-    }, _callee);
-  }));
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = exports.getSharingRules = exports.BITWARDEN_CIPHERS_DOCTYPE = exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = exports.SHARING_DOCTYPE = void 0;
 
-  return function loadIcon(_x, _x2, _x3, _x4) {
-    return _ref.apply(this, arguments);
-  };
-}();
-/**
- * Get App Icon URL
- *
- * @param  {object}  app - Apps data - io.cozy.apps or Slug - string
- * @param  {string}  slug - Slug - string
- * @param  {string|undefined} domain - Host to use in the origin (e.g. cozy.tools)
- * @param  {string} protocol - Url protocol (e.g. http / https)
- * @private
- * @returns {string|null}  App Icon URL
- */
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _getAppIconURL = function _getAppIconURL(app, slug, domain, protocol) {
-  var path = app && app.links && app.links.icon || _getRegistryIconPath(app, slug);
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-  return path ? "".concat(protocol, "//").concat(domain).concat(path) : null;
-};
-/**
- * Get Registry Icon Path
- *
- * @param  {object}  app - Apps data - io.cozy.apps or Slug - string
- * @param  {string}  slug - Slug - string
- * @returns {string|undefined}  Registry icon path
- * @private
- */
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _getRegistryIconPath = function _getRegistryIconPath(app, slug) {
-  if (slug) {
-    return "/registry/".concat(slug, "/icon");
-  }
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-  return app && app.latest_version && app.latest_version.version && "/registry/".concat(app.slug, "/").concat(app.latest_version.version, "/icon");
-};
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var mimeTypes = {
-  gif: 'image/gif',
-  ico: 'image/vnd.microsoft.icon',
-  jpeg: 'image/jpeg',
-  jpg: 'image/jpeg',
-  png: 'image/png',
-  svg: 'image/svg+xml'
-};
-/**
- * Get icon extension
- *
- * @param {object} app io.cozy.apps or io.cozy.konnectors document
- * @param  {string} app.icon - App Icon
- * @param  {string} app.name - App Name
- * @returns {string}  icon extension
- * @private
- * @throws {Error} When problem while detecting icon mime type
- */
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var getIconExtensionFromApp = function getIconExtensionFromApp(app) {
-  if (!app.icon) {
-    throw new Error("".concat(app.name, ": Cannot detect icon mime type since app has no icon"));
-  }
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-  var extension = app.icon.split('.').pop();
+var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613));
 
-  if (!extension) {
-    throw new Error("".concat(app.name, ": Unable to detect icon mime type from extension (").concat(app.icon, ")"));
-  }
+var _FileCollection = __webpack_require__(670);
 
-  return extension;
-};
+var _utils = __webpack_require__(623);
 
-var fallbacks = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(tries, check) {
-    var err, _iterator, _step, _try, res;
+function _templateObject6() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]);
 
-    return _regenerator.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            _iterator = _createForOfIteratorHelper(tries);
-            _context2.prev = 1;
+  _templateObject6 = function _templateObject6() {
+    return data;
+  };
 
-            _iterator.s();
+  return data;
+}
 
-          case 3:
-            if ((_step = _iterator.n()).done) {
-              _context2.next = 18;
-              break;
-            }
+function _templateObject5() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/self"]);
 
-            _try = _step.value;
-            _context2.prev = 5;
-            _context2.next = 8;
-            return _try();
+  _templateObject5 = function _templateObject5() {
+    return data;
+  };
 
-          case 8:
-            res = _context2.sent;
-            check && check(res);
-            return _context2.abrupt("return", res);
+  return data;
+}
 
-          case 13:
-            _context2.prev = 13;
-            _context2.t0 = _context2["catch"](5);
-            err = _context2.t0;
+function _templateObject4() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/", ""]);
 
-          case 16:
-            _context2.next = 3;
-            break;
+  _templateObject4 = function _templateObject4() {
+    return data;
+  };
 
-          case 18:
-            _context2.next = 23;
-            break;
+  return data;
+}
 
-          case 20:
-            _context2.prev = 20;
-            _context2.t1 = _context2["catch"](1);
+function _templateObject3() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]);
 
-            _iterator.e(_context2.t1);
+  _templateObject3 = function _templateObject3() {
+    return data;
+  };
 
-          case 23:
-            _context2.prev = 23;
+  return data;
+}
 
-            _iterator.f();
+function _templateObject2() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", ""]);
 
-            return _context2.finish(23);
+  _templateObject2 = function _templateObject2() {
+    return data;
+  };
 
-          case 26:
-            throw err;
+  return data;
+}
 
-          case 27:
-          case "end":
-            return _context2.stop();
-        }
-      }
-    }, _callee2, null, [[1, 20, 23, 26], [5, 13]]);
-  }));
+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; }
 
-  return function fallbacks(_x5, _x6) {
-    return _ref2.apply(this, arguments);
+function _objectSpread(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) { (0, _defineProperty2.default)(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 _templateObject() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/sharings/doctype/", ""]);
+
+  _templateObject = function _templateObject() {
+    return data;
   };
-}();
-/**
- * Fetch application/konnector that is installed
- *
- * @private
- */
 
+  return data;
+}
 
-var fetchAppOrKonnector = function fetchAppOrKonnector(stackClient, type, slug) {
-  return stackClient.fetchJSON('GET', "/".concat(type, "s/").concat(slug)).then(function (x) {
-    return x.data.attributes;
-  });
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+
+var SHARING_DOCTYPE = 'io.cozy.sharings';
+exports.SHARING_DOCTYPE = SHARING_DOCTYPE;
+var BITWARDEN_ORGANIZATIONS_DOCTYPE = 'com.bitwarden.organizations';
+exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = BITWARDEN_ORGANIZATIONS_DOCTYPE;
+var BITWARDEN_CIPHERS_DOCTYPE = 'com.bitwarden.ciphers';
+exports.BITWARDEN_CIPHERS_DOCTYPE = BITWARDEN_CIPHERS_DOCTYPE;
+
+var normalizeSharing = function normalizeSharing(sharing) {
+  return (0, _DocumentCollection2.normalizeDoc)(sharing, SHARING_DOCTYPE);
 };
 /**
- * Fetch application/konnector from the registry
- *
- * @private
+ * @typedef {object} Rule A sharing rule
+ * @property {string} title
+ * @property {string} doctype
+ * @property {Array} values
+ * @property {string=} add
+ * @property {string=} update
+ * @property {string=} remove
  */
 
-
-var fetchAppOrKonnectorViaRegistry = function fetchAppOrKonnectorViaRegistry(stackClient, type, slug) {
-  return stackClient.fetchJSON('GET', "/registry/".concat(slug)).then(function (x) {
-    return x.latest_version.manifest;
-  });
-};
 /**
- * Get Icon URL using blob mechanism if OAuth connected
- * or using preloaded url when blob not needed
- *
- * @param  {CozyStackClient}  stackClient - CozyStackClient
- * @param  {object}  stackClient.oauthOptions - oauthOptions used to detect fetching mechanism
- * @param  {object} opts - Options
- * @param  {string} opts.type - Options type
- * @param  {string|undefined} opts.slug - Options slug
- * @param  {object|string|undefined}  opts.appData - Apps data - io.cozy.apps
- * @param  {string} [opts.priority='stack'] - Options priority
- * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob .
- * @private
- * @throws {Error} while fetching icon, or unknown image extension
+ * @typedef {object} Recipient An io.cozy.contact
  */
 
+/**
+ * @typedef {object} Sharing An io.cozy.sharings document
+ */
 
-var _getIconURL = /*#__PURE__*/function () {
-  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(stackClient, opts) {
-    var type, slug, appData, _opts$priority, priority, iconDataFetchers, resp, icon, app, appDataFetchers, ext, _URL, domain, protocol;
+/**
+ * @typedef {object} SharingPolicy Define the add/update/remove policies for a sharing
+ * @property {string} add
+ * @property {string} update
+ * @property {string} remove
+ */
 
-    return _regenerator.default.wrap(function _callee3$(_context3) {
-      while (1) {
-        switch (_context3.prev = _context3.next) {
-          case 0:
-            type = opts.type, slug = opts.slug, appData = opts.appData, _opts$priority = opts.priority, priority = _opts$priority === void 0 ? 'stack' : _opts$priority;
+/**
+ * @typedef {(undefined|'one-way'|'two-way')} SharingType Define how a document is synced between sharing's owner and receivers.
+ */
 
-            if (!stackClient.oauthOptions) {
-              _context3.next = 29;
-              break;
-            }
+/**
+ * @typedef {object} RelationshipItem Define a recipient that can be used as target of a sharing
+ * @property {string} id - Recipient's ID
+ * @property {string} type - Reciptient's type (should be 'io.cozy.contacts')
+ */
 
-            iconDataFetchers = [function () {
-              return stackClient.fetch('GET', "/".concat(type, "s/").concat(slug, "/icon"));
-            }, function () {
-              return stackClient.fetch('GET', "/registry/".concat(slug, "/icon"));
-            }];
+/**
+ * Implements the `DocumentCollection` API along with specific methods for
+ * `io.cozy.sharings`.
+ */
 
-            if (priority === 'registry') {
-              iconDataFetchers.reverse();
-            }
 
-            _context3.next = 6;
-            return fallbacks(iconDataFetchers, function (resp) {
-              if (!resp.ok) {
-                throw new Error("Error while fetching icon ".concat(resp.statusText));
-              }
-            });
+var SharingCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(SharingCollection, _DocumentCollection);
 
-          case 6:
-            resp = _context3.sent;
-            _context3.next = 9;
-            return resp.blob();
+  var _super = _createSuper(SharingCollection);
 
-          case 9:
-            icon = _context3.sent;
+  function SharingCollection() {
+    (0, _classCallCheck2.default)(this, SharingCollection);
+    return _super.apply(this, arguments);
+  }
 
-            if (icon.type) {
-              _context3.next = 26;
-              break;
-            }
+  (0, _createClass2.default)(SharingCollection, [{
+    key: "findByDoctype",
+    value: function () {
+      var _findByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(doctype) {
+        var resp;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.next = 2;
+                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), doctype));
 
-            // iOS10 does not set correctly mime type for images, so we assume
-            // that an empty mime type could mean that the app is running on iOS10.
-            // For regular images like jpeg, png or gif it still works well in the
-            // Safari browser but not for SVG.
-            // So let's set a mime type manually. We cannot always set it to
-            // image/svg+xml and must guess the mime type based on the icon attribute
-            // from app/manifest
-            // See https://stackoverflow.com/questions/38318411/uiwebview-on-ios-10-beta-not-loading-any-svg-images
-            appDataFetchers = [function () {
-              return fetchAppOrKonnector(stackClient, type, slug);
-            }, function () {
-              return fetchAppOrKonnectorViaRegistry(stackClient, type, slug);
-            }];
+              case 2:
+                resp = _context.sent;
+                return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
+                  data: resp.data.map(normalizeSharing)
+                }));
 
-            if (priority === 'registry') {
-              appDataFetchers.reverse();
+              case 4:
+              case "end":
+                return _context.stop();
             }
+          }
+        }, _callee, this);
+      }));
 
-            _context3.t1 = appData;
-
-            if (_context3.t1) {
-              _context3.next = 18;
-              break;
-            }
+      function findByDoctype(_x) {
+        return _findByDoctype.apply(this, arguments);
+      }
 
-            _context3.next = 17;
-            return fallbacks(appDataFetchers);
+      return findByDoctype;
+    }()
+    /**
+     * Fetches a sharing by id
+     *
+     * @param {string} id Sharing's id
+     * @returns {Sharing} sharing
+     */
 
-          case 17:
-            _context3.t1 = _context3.sent;
+  }, {
+    key: "get",
+    value: function () {
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
+        var path, resp;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                path = (0, _utils.uri)(_templateObject2(), id);
+                _context2.next = 3;
+                return this.stackClient.fetchJSON('GET', path);
 
-          case 18:
-            _context3.t0 = _context3.t1;
+              case 3:
+                resp = _context2.sent;
+                return _context2.abrupt("return", {
+                  data: normalizeSharing(resp.data)
+                });
 
-            if (_context3.t0) {
-              _context3.next = 21;
-              break;
+              case 5:
+              case "end":
+                return _context2.stop();
             }
+          }
+        }, _callee2, this);
+      }));
 
-            _context3.t0 = {};
+      function get(_x2) {
+        return _get.apply(this, arguments);
+      }
 
-          case 21:
-            app = _context3.t0;
-            ext = getIconExtensionFromApp(app);
+      return get;
+    }()
+    /**
+     *
+     * Creates a new Sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings
+     *
+     * @param {object} params Sharing  params
+     * @param {Sharing} params.document The document to share
+     * @param {string} params.description Description of the sharing
+     * @param {string=} params.previewPath The preview path
+     * @param {Array<Rule>=} params.rules The rules defined to the sharing. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
+     * @param {Array<Recipient>=} params.recipients Recipients to add to the sharings (will have the same permissions given by the rules defined by the sharing )
+     * @param {Array<Recipient>=} params.readOnlyRecipients Recipients to add to the sharings with only read only access
+     * @param {boolean=} params.openSharing If someone else than the owner can add a recipient to the sharing
+     * @param {string=} params.appSlug Slug of the targeted app
+     */
 
-            if (mimeTypes[ext]) {
-              _context3.next = 25;
-              break;
-            }
+  }, {
+    key: "create",
+    value: function () {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref) {
+        var document, description, previewPath, rules, _ref$recipients, recipients, _ref$readOnlyRecipien, readOnlyRecipients, openSharing, appSlug, attributes, optionalAttributes, resp;
 
-            throw new Error("Unknown image extension \"".concat(ext, "\" for app ").concat(app.name));
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                document = _ref.document, description = _ref.description, previewPath = _ref.previewPath, rules = _ref.rules, _ref$recipients = _ref.recipients, recipients = _ref$recipients === void 0 ? [] : _ref$recipients, _ref$readOnlyRecipien = _ref.readOnlyRecipients, readOnlyRecipients = _ref$readOnlyRecipien === void 0 ? [] : _ref$readOnlyRecipien, openSharing = _ref.openSharing, appSlug = _ref.appSlug;
+                attributes = {
+                  description: description,
+                  preview_path: previewPath,
+                  open_sharing: openSharing,
+                  rules: rules ? rules : getSharingRules(document)
+                };
+                optionalAttributes = {};
 
-          case 25:
-            icon = new Blob([icon], {
-              type: mimeTypes[ext]
-            });
+                if (appSlug) {
+                  optionalAttributes = {
+                    app_slug: appSlug
+                  };
+                }
 
-          case 26:
-            return _context3.abrupt("return", URL.createObjectURL(icon));
+                _context3.next = 6;
+                return this.stackClient.fetchJSON('POST', '/sharings/', {
+                  data: {
+                    type: 'io.cozy.sharings',
+                    attributes: _objectSpread(_objectSpread({}, attributes), optionalAttributes),
+                    relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && {
+                      recipients: {
+                        data: recipients.map(toRelationshipItem)
+                      }
+                    }), readOnlyRecipients.length > 0 && {
+                      read_only_recipients: {
+                        data: readOnlyRecipients.map(toRelationshipItem)
+                      }
+                    })
+                  }
+                });
 
-          case 29:
-            _context3.prev = 29;
-            _URL = new URL(stackClient.uri), domain = _URL.host, protocol = _URL.protocol;
-            return _context3.abrupt("return", loadIcon(appData, slug, domain, protocol));
+              case 6:
+                resp = _context3.sent;
+                return _context3.abrupt("return", {
+                  data: normalizeSharing(resp.data)
+                });
 
-          case 34:
-            _context3.prev = 34;
-            _context3.t2 = _context3["catch"](29);
-            throw new Error("Cannot fetch icon: invalid stackClient.uri: ".concat(_context3.t2.message));
+              case 8:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
 
-          case 37:
-          case "end":
-            return _context3.stop();
-        }
+      function create(_x3) {
+        return _create.apply(this, arguments);
       }
-    }, _callee3, null, [[29, 34]]);
-  }));
-
-  return function _getIconURL(_x7, _x8) {
-    return _ref3.apply(this, arguments);
-  };
-}();
-/**
- * Get Icon URL using blob mechanism if OAuth connected
- * or using preloaded url when blob not needed
- *
- * @param  {CozyStackClient}  stackClient - CozyStackClient
- * @param  {object}  stackClient.oauthOptions - oauthOptions used to detect fetching mechanism
- * @param  {object} opts - Options
- * @param  {string} opts.type - Options type
- * @param  {string|undefined} opts.slug - Options slug
- * @param  {object|string|undefined}  opts.appData - Apps data - io.cozy.apps or Slug - string
- * @param  {string} [opts.priority='stack'] - Options priority
- * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob or ErrorReturned
- */
-
-
-exports._getIconURL = _getIconURL;
-
-var getIconURL = function getIconURL() {
-  return _getIconURL.apply(this, arguments).catch(function () {
-    return new _memoize.ErrorReturned();
-  });
-};
 
-exports.getIconURL = getIconURL;
+      return create;
+    }()
+    /**
+     * @deprecated Use create() instead
+     * share - Creates a new sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings
+     *
+     * @param  {Sharing} document The document to share. Should have and _id and a name.
+     * @param  {Array} recipients A list of io.cozy.contacts
+     * @param  {string} sharingType - If "two-way", will set the open_sharing attribute to true
+     * @param  {string} description - Describes the sharing
+     * @param  {string=} previewPath Relative URL of the sharings preview page
+     */
 
-var _default = (0, _memoize.default)(getIconURL, {
-  maxDuration: 300 * 1000,
-  key: function key(stackClient, opts) {
-    var type = opts.type,
-        slug = opts.slug,
-        priority = opts.priority;
-    return stackClient.uri + +':' + type + ':' + slug + ':' + priority;
-  }
-});
+  }, {
+    key: "share",
+    value: function () {
+      var _share = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, recipients, sharingType, description) {
+        var previewPath,
+            recipientsToUse,
+            _args4 = arguments;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                previewPath = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : null;
+                console.warn('SharingCollection.share is deprecated, use SharingCollection.create instead');
+                recipientsToUse = sharingType === 'two-way' ? {
+                  recipients: recipients
+                } : {
+                  readOnlyRecipients: recipients
+                };
+                return _context4.abrupt("return", this.create(_objectSpread(_objectSpread({
+                  document: document
+                }, recipientsToUse), {}, {
+                  description: description,
+                  previewPath: previewPath,
+                  openSharing: sharingType === 'two-way',
+                  rules: getSharingRules(document, sharingType)
+                })));
 
-exports["default"] = _default;
+              case 4:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
 
-/***/ }),
-/* 681 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+      function share(_x4, _x5, _x6, _x7) {
+        return _share.apply(this, arguments);
+      }
 
-"use strict";
+      return share;
+    }()
+    /**
+     * getDiscoveryLink - Returns the URL of the page that can be used to accept a sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#get-sharingssharing-iddiscovery
+     *
+     * @param  {string} sharingId - Id of the sharing
+     * @param  {string} sharecode - Code of the sharing
+     * @returns {string}
+     */
 
+  }, {
+    key: "getDiscoveryLink",
+    value: function getDiscoveryLink(sharingId, sharecode) {
+      return this.stackClient.fullpath("/sharings/".concat(sharingId, "/discovery?sharecode=").concat(sharecode));
+    }
+    /**
+     * Add an array of contacts to the Sharing
+     *
+     * @param {object} options Object
+     * @param {Sharing} options.document Sharing Object
+     * @param {Array<Recipient>=} options.recipients Recipients to add to the sharing
+     * @param {Array<Recipient>=} options.readOnlyRecipients Recipients to add to the sharings with only read only access
+     */
 
-var _interopRequireDefault = __webpack_require__(512);
+  }, {
+    key: "addRecipients",
+    value: function () {
+      var _addRecipients = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(_ref2) {
+        var document, _ref2$recipients, recipients, _ref2$readOnlyRecipie, readOnlyRecipients, resp;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.ErrorReturned = exports["default"] = void 0;
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                document = _ref2.document, _ref2$recipients = _ref2.recipients, recipients = _ref2$recipients === void 0 ? [] : _ref2$recipients, _ref2$readOnlyRecipie = _ref2.readOnlyRecipients, readOnlyRecipients = _ref2$readOnlyRecipie === void 0 ? [] : _ref2$readOnlyRecipie;
+                _context5.next = 3;
+                return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), document._id), {
+                  data: {
+                    type: 'io.cozy.sharings',
+                    id: document._id,
+                    relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && {
+                      recipients: {
+                        data: recipients.map(toRelationshipItem)
+                      }
+                    }), readOnlyRecipients.length > 0 && {
+                      read_only_recipients: {
+                        data: readOnlyRecipients.map(toRelationshipItem)
+                      }
+                    })
+                  }
+                });
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+              case 3:
+                resp = _context5.sent;
+                return _context5.abrupt("return", {
+                  data: normalizeSharing(resp.data)
+                });
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+              case 5:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this);
+      }));
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+      function addRecipients(_x8) {
+        return _addRecipients.apply(this, arguments);
+      }
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+      return addRecipients;
+    }()
+    /**
+     * Revoke only one recipient of the sharing.
+     *
+     * @param {object} sharing Sharing Object
+     * @param {number} recipientIndex Index of this recipient in the members array of the sharing
+     */
 
-var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652));
+  }, {
+    key: "revokeRecipient",
+    value: function revokeRecipient(sharing, recipientIndex) {
+      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject4(), sharing._id, recipientIndex));
+    }
+    /**
+     * Remove self from the sharing.
+     *
+     * @param {object} sharing Sharing Object
+     */
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+  }, {
+    key: "revokeSelf",
+    value: function revokeSelf(sharing) {
+      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), sharing._id));
+    }
+    /**
+     * Revoke the sharing for all the members. Must be called
+     * from the owner's cozy
+     *
+     * @param {object} sharing Sharing Objects
+     */
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+  }, {
+    key: "revokeAllRecipients",
+    value: function revokeAllRecipients(sharing) {
+      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), sharing._id));
+    }
+  }]);
+  return SharingCollection;
+}(_DocumentCollection2.default);
 
-var ErrorReturned = /*#__PURE__*/function (_String) {
-  (0, _inherits2.default)(ErrorReturned, _String);
+SharingCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
 
-  var _super = _createSuper(ErrorReturned);
+var getSharingRulesWithoutWarning = function getSharingRulesWithoutWarning(document, sharingType) {
+  if ((0, _FileCollection.isFile)(document)) {
+    return getSharingRulesForFile(document, sharingType);
+  }
 
-  function ErrorReturned() {
-    (0, _classCallCheck2.default)(this, ErrorReturned);
-    return _super.apply(this, arguments);
+  if (document._type === BITWARDEN_ORGANIZATIONS_DOCTYPE) {
+    return getSharingRulesForOrganizations(document);
   }
 
-  return ErrorReturned;
-}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(String));
+  return getSharingRulesForPhotosAlbum(document, sharingType);
+};
 /**
- * Delete outdated results from cache
+ * Rules determine the behavior of the sharing when changes are made to the shared document
+ * See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
+ *
+ * @param {Sharing} document - The document to share. Should have and _id and a name
+ * @param  {SharingType} sharingType - The type of the sharing
+ *
+ * @returns {Array<Rule>=} The rules that define how to share the document
  */
 
 
-exports.ErrorReturned = ErrorReturned;
+var getSharingRules = function getSharingRules(document, sharingType) {
+  if (sharingType) {
+    console.warn("sharingType is deprecated and will be removed. We now set this default rules: ".concat(getSharingRulesWithoutWarning(document), "} \n      \n      If this default rules do not fill your need, please set custom rules \n      by using the 'rules' object of the SharingCollection.create() method"));
+  }
 
-var garbageCollect = function garbageCollect(cache, maxDuration) {
-  var now = Date.now();
+  return getSharingRulesWithoutWarning(document, sharingType);
+};
+/**
+ * Compute the rules that define how to share a Photo Album. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
+ *
+ * @param {Sharing} document - The document to share. Should have and _id and a name
+ * @param  {SharingType} sharingType - The type of the sharing
+ *
+ * @returns {Array<Rule>=} The rules that define how to share a Photo Album
+ */
 
-  for (var _i = 0, _Object$keys = Object.keys(cache); _i < _Object$keys.length; _i++) {
-    var key = _Object$keys[_i];
-    var delta = now - cache[key].date;
 
-    if (delta > maxDuration) {
-      delete cache[key];
-    }
-  }
-};
+exports.getSharingRules = getSharingRules;
 
-var isPromise = function isPromise(maybePromise) {
-  return typeof maybePromise === 'object' && typeof maybePromise.then === 'function';
+var getSharingRulesForPhotosAlbum = function getSharingRulesForPhotosAlbum(document, sharingType) {
+  var _id = document._id,
+      _type = document._type;
+  return [_objectSpread({
+    title: 'collection',
+    doctype: _type,
+    values: [_id]
+  }, getSharingPolicyForAlbum(sharingType)), _objectSpread({
+    title: 'items',
+    doctype: 'io.cozy.files',
+    values: ["".concat(_type, "/").concat(_id)],
+    selector: 'referenced_by'
+  }, getSharingPolicyForReferencedFiles(sharingType))];
 };
 /**
- * Memoize with maxDuration and custom key
+ * Compute the sharing policy for a ReferencedFile based on its sharing type
+ *
+ * @param  {SharingType} sharingType - The type of the sharing
+ *
+ * @returns {SharingPolicy} The sharing policy for the ReferencedFile
  */
 
 
-var memoize = function memoize(fn, options) {
-  var cache = {};
-  return function () {
-    var key = options.key.apply(null, arguments);
-    garbageCollect(cache, options.maxDuration);
-    var existing = cache[key];
-
-    if (existing) {
-      return existing.result;
-    } else {
-      var result = fn.apply(this, arguments);
-      cache[key] = {
-        result: result,
-        date: Date.now()
-      };
-      /**
-       * If the result is a promise and this promise
-       * failed or resolved with a specific error (aka ErrorReturned),
-       * let's remove the result from the cache since we don't want to
-       * memoize error
-       */
+var getSharingPolicyForReferencedFiles = function getSharingPolicyForReferencedFiles(sharingType) {
+  return sharingType === 'two-way' ? {
+    add: 'sync',
+    update: 'sync',
+    remove: 'sync'
+  } : {
+    add: 'push',
+    update: 'none',
+    remove: 'push'
+  };
+};
+/**
+ * Compute the sharing policy for an Album based on its sharing type
+ *
+ * @param  {SharingType} sharingType - The type of the sharing
+ *
+ * @returns {Array<Rule>=} The sharing policy for the Album
+ */
 
-      if (isPromise(result)) {
-        result.then(function (v) {
-          if (v instanceof ErrorReturned) {
-            delete cache[key];
-          }
-        }).catch(function (e) {
-          delete cache[key];
-        });
-      }
 
-      return result;
-    }
+var getSharingPolicyForAlbum = function getSharingPolicyForAlbum(sharingType) {
+  if (!sharingType) return {
+    update: 'sync',
+    remove: 'revoke'
+  };
+  return sharingType === 'two-way' ? {
+    update: 'sync',
+    remove: 'revoke'
+  } : {
+    update: 'push',
+    remove: 'revoke'
   };
 };
+/**
+ * Compute the rules that define how to share a File. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
+ *
+ * @param {Sharing} document - The document to share. Should have and _id and a name
+ * @param  {SharingType} sharingType - The type of the sharing
+ *
+ * @returns {Array<Rule>=} The rules that define how to share a File
+ */
 
-var _default = memoize;
-exports["default"] = _default;
 
-/***/ }),
-/* 682 */
-/***/ ((__unused_webpack_module, exports) => {
+var getSharingRulesForFile = function getSharingRulesForFile(document, sharingType) {
+  var _id = document._id,
+      name = document.name;
+  return [_objectSpread({
+    title: name,
+    doctype: 'io.cozy.files',
+    values: [_id]
+  }, getSharingPolicyForFile(document, sharingType))];
+};
+/**
+ * Compute the sharing policy for a File based on its sharing type
+ *
+ * @param {Sharing} document - The document to share. Should have and _id and a name
+ * @param {SharingType} sharingType - The type of the sharing
+ *
+ * @returns {SharingPolicy} The sharing policy for the File
+ */
 
-"use strict";
 
+var getSharingPolicyForFile = function getSharingPolicyForFile(document, sharingType) {
+  if ((0, _FileCollection.isDirectory)(document)) {
+    if (!sharingType) return {
+      add: 'sync',
+      update: 'sync',
+      remove: 'sync'
+    };
+    return sharingType === 'two-way' ? {
+      add: 'sync',
+      update: 'sync',
+      remove: 'sync'
+    } : {
+      add: 'push',
+      update: 'push',
+      remove: 'push'
+    };
+  }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+  if (!sharingType) return {
+    update: 'sync',
+    remove: 'revoke'
+  };
+  return sharingType === 'two-way' ? {
+    update: 'sync',
+    remove: 'revoke'
+  } : {
+    update: 'push',
+    remove: 'revoke'
+  };
+};
+/**
+ * Compute the rules that define how to share an Organization. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing
+ *
+ * @param {Sharing} document The document to share. Should have and _id and a name
+ *
+ * @returns {Array<Rule>=} The rules that define how to share an Organization
+ */
 
-var logDeprecate = function logDeprecate() {
-  var _console;
 
-  if (process.env.NODE_ENV === 'test') {
-    throw new Error('Deprecation error: ' + (arguments.length <= 0 ? undefined : arguments[0]));
-  }
+var getSharingRulesForOrganizations = function getSharingRulesForOrganizations(document) {
+  var _id = document._id,
+      name = document.name;
+  var sharingRules = [{
+    title: name,
+    doctype: BITWARDEN_ORGANIZATIONS_DOCTYPE,
+    values: [_id],
+    add: 'sync',
+    update: 'sync',
+    remove: 'revoke'
+  }, {
+    title: 'Ciphers',
+    doctype: BITWARDEN_CIPHERS_DOCTYPE,
+    values: [_id],
+    add: 'sync',
+    update: 'sync',
+    remove: 'sync',
+    selector: 'organization_id'
+  }];
+  return sharingRules;
+};
+/**
+ * Compute the RelationshipItem that can be referenced as a sharing recipient
+ *
+ * @param {Recipient} item The recipient of a sharing
+ *
+ * @returns {RelationshipItem} The RelationshipItem that can be referenced as a sharing recipient
+ */
 
-  (_console = console).warn.apply(_console, arguments);
+
+var toRelationshipItem = function toRelationshipItem(item) {
+  return {
+    id: item._id,
+    type: item._type
+  };
 };
 
-var _default = logDeprecate;
+var _default = SharingCollection;
 exports["default"] = _default;
 
 /***/ }),
-/* 683 */
+/* 685 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireWildcard = __webpack_require__(522);
+
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.shouldXMLHTTPRequestBeUsed = exports.fetchWithXMLHttpRequest = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+exports["default"] = exports.getPermissionsFor = void 0;
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-var _memoize = _interopRequireDefault(__webpack_require__(365));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var headersFromString = function headersFromString(headerString) {
-  return new Headers(headerString.split('\r\n').map(function (x) {
-    return x.split(':', 2);
-  }).filter(function (x) {
-    return x.length == 2;
-  }));
-};
-/**
- * Returns a `fetch()` like response but uses XHR.
- * XMLHTTPRequest provides upload progress events unlike fetch.
- *
- * @private
- * @param {string} fullpath - Route path
- * @param {object} options - Fetch options
- * @param {Function} options.onUploadProgress - Callback to receive upload progress events
- */
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var fetchWithXMLHttpRequest = /*#__PURE__*/function () {
-  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(fullpath, options) {
-    var response;
-    return _regenerator.default.wrap(function _callee3$(_context3) {
-      while (1) {
-        switch (_context3.prev = _context3.next) {
-          case 0:
-            _context3.next = 2;
-            return new Promise(function (resolve, reject) {
-              var xhr = new XMLHttpRequest();
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-              if (options.onUploadProgress && xhr.upload) {
-                xhr.upload.addEventListener('progress', options.onUploadProgress, false);
-              }
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-              xhr.onload = function () {
-                if (this.readyState == 4) {
-                  resolve(this);
-                } else {
-                  reject(this);
-                }
-              };
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-              xhr.onerror = function (err) {
-                reject(err);
-              };
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-              xhr.open(options.method, fullpath, true);
-              xhr.withCredentials = true;
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-              for (var _i = 0, _Object$entries = Object.entries(options.headers); _i < _Object$entries.length; _i++) {
-                var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
-                    headerName = _Object$entries$_i[0],
-                    headerValue = _Object$entries$_i[1];
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-                xhr.setRequestHeader(headerName, headerValue);
-              }
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-              xhr.send(options.body);
-            });
+var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613));
 
-          case 2:
-            response = _context3.sent;
-            return _context3.abrupt("return", {
-              headers: headersFromString(response.getAllResponseHeaders()),
-              ok: response.status >= 200 && response.status < 300,
-              text: function () {
-                var _text = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-                  return _regenerator.default.wrap(function _callee$(_context) {
-                    while (1) {
-                      switch (_context.prev = _context.next) {
-                        case 0:
-                          return _context.abrupt("return", response.responseText);
+var _FileCollection = __webpack_require__(670);
 
-                        case 1:
-                        case "end":
-                          return _context.stop();
-                      }
-                    }
-                  }, _callee);
-                }));
+var _utils = __webpack_require__(623);
 
-                function text() {
-                  return _text.apply(this, arguments);
-                }
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-                return text;
-              }(),
-              json: function () {
-                var _json = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-                  return _regenerator.default.wrap(function _callee2$(_context2) {
-                    while (1) {
-                      switch (_context2.prev = _context2.next) {
-                        case 0:
-                          return _context2.abrupt("return", JSON.parse(response.responseText));
+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); }
 
-                        case 1:
-                        case "end":
-                          return _context2.stop();
-                      }
-                    }
-                  }, _callee2);
-                }));
+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 json() {
-                  return _json.apply(this, arguments);
-                }
+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; }
 
-                return json;
-              }(),
-              status: response.status,
-              statusText: response.statusText
-            });
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-          case 4:
-          case "end":
-            return _context3.stop();
-        }
-      }
-    }, _callee3);
-  }));
+function _templateObject3() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/permissions/doctype/", "/shared-by-link"]);
 
-  return function fetchWithXMLHttpRequest(_x, _x2) {
-    return _ref.apply(this, arguments);
+  _templateObject3 = function _templateObject3() {
+    return data;
   };
-}();
-
-exports.fetchWithXMLHttpRequest = fetchWithXMLHttpRequest;
-var doesXHRSupportLoadAndProgress = (0, _memoize.default)(function () {
-  var xhr = new XMLHttpRequest();
-  return 'onload' in xhr && 'onprogress' in xhr;
-});
-
-var shouldXMLHTTPRequestBeUsed = function shouldXMLHTTPRequestBeUsed(method, path, options) {
-  return Boolean(options.onUploadProgress) && doesXHRSupportLoadAndProgress();
-};
-
-exports.shouldXMLHTTPRequestBeUsed = shouldXMLHTTPRequestBeUsed;
-
-/***/ }),
-/* 684 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
-
-var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652));
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _get2 = _interopRequireDefault(__webpack_require__(670));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
-
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+  return data;
+}
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+function _templateObject2() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]);
 
-var _CozyStackClient2 = _interopRequireDefault(__webpack_require__(560));
+  _templateObject2 = function _templateObject2() {
+    return data;
+  };
 
-var _AccessToken = _interopRequireDefault(__webpack_require__(657));
+  return data;
+}
 
-var _logDeprecate = _interopRequireDefault(__webpack_require__(682));
+function _templateObject() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]);
 
-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; }
+  _templateObject = function _templateObject() {
+    return data;
+  };
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  return data;
+}
 
 function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
 function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var defaultoauthOptions = {
-  clientID: '',
-  clientName: '',
-  clientKind: '',
-  clientSecret: '',
-  clientURI: '',
-  registrationAccessToken: '',
-  redirectURI: '',
-  softwareID: '',
-  softwareVersion: '',
-  logoURI: '',
-  policyURI: '',
-  notificationPlatform: '',
-  notificationDeviceToken: ''
+var normalizePermission = function normalizePermission(perm) {
+  return (0, _DocumentCollection2.normalizeDoc)(perm, 'io.cozy.permissions');
 };
 /**
- * Specialized `CozyStackClient` for mobile, implementing stack registration
- * through OAuth.
+ * Implements `DocumentCollection` API along with specific methods for `io.cozy.permissions`.
  */
 
-var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
-  (0, _inherits2.default)(OAuthClient, _CozyStackClient);
-
-  var _super = _createSuper(OAuthClient);
-
-  function OAuthClient(_ref) {
-    var _this;
-
-    var oauth = _ref.oauth,
-        _ref$scope = _ref.scope,
-        scope = _ref$scope === void 0 ? [] : _ref$scope,
-        onTokenRefresh = _ref.onTokenRefresh,
-        options = (0, _objectWithoutProperties2.default)(_ref, ["oauth", "scope", "onTokenRefresh"]);
-    (0, _classCallCheck2.default)(this, OAuthClient);
-    _this = _super.call(this, options);
 
-    _this.setOAuthOptions(_objectSpread(_objectSpread({}, defaultoauthOptions), oauth));
+var PermissionCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(PermissionCollection, _DocumentCollection);
 
-    if (oauth.token) {
-      _this.setToken(oauth.token);
-    }
+  var _super = _createSuper(PermissionCollection);
 
-    _this.scope = scope;
-    _this.onTokenRefresh = onTokenRefresh;
-    return _this;
+  function PermissionCollection() {
+    (0, _classCallCheck2.default)(this, PermissionCollection);
+    return _super.apply(this, arguments);
   }
-  /**
-   * Checks if the client has his registration information from the server
-   *
-   * @returns {boolean} true if registered, false otherwise
-   * @private
-   */
-
-
-  (0, _createClass2.default)(OAuthClient, [{
-    key: "isRegistered",
-    value: function isRegistered() {
-      return this.oauthOptions.clientID !== '';
-    }
-    /**
-     * Converts a camel-cased data set to snake case, suitable for sending to the OAuth server
-     *
-     * @param   {object} data Initial data
-     * @returns {object} Formatted data
-     * @private
-     */
-
-  }, {
-    key: "snakeCaseOAuthData",
-    value: function snakeCaseOAuthData(data) {
-      var mappedFields = {
-        softwareID: 'software_id',
-        softwareVersion: 'software_version',
-        clientID: 'client_id',
-        clientName: 'client_name',
-        clientKind: 'client_kind',
-        clientURI: 'client_uri',
-        logoURI: 'logo_uri',
-        policyURI: 'policy_uri',
-        notificationPlatform: 'notification_platform',
-        notificationDeviceToken: 'notification_device_token',
-        redirectURI: 'redirect_uris'
-      };
-      var result = {};
-      Object.keys(data).forEach(function (fieldName) {
-        var key = mappedFields[fieldName] || fieldName;
-        var value = data[fieldName];
-        result[key] = value;
-      }); // special case: turn redirect_uris into an array
-
-      if (result['redirect_uris'] && result['redirect_uris'] instanceof Array === false) result['redirect_uris'] = [result['redirect_uris']];
-      return result;
-    }
-    /**
-     * Converts a snake-cased data set to camel case, suitable for internal use
-     *
-     * @param   {object} data Initial data
-     * @returns {object} Formatted data
-     * @private
-     */
-
-  }, {
-    key: "camelCaseOAuthData",
-    value: function camelCaseOAuthData(data) {
-      var mappedFields = {
-        client_id: 'clientID',
-        client_name: 'clientName',
-        client_secret: 'clientSecret',
-        registration_access_token: 'registrationAccessToken',
-        software_id: 'softwareID',
-        redirect_uris: 'redirectURI'
-      };
-      var result = {};
-      Object.keys(data).forEach(function (fieldName) {
-        var key = mappedFields[fieldName] || fieldName;
-        var value = data[fieldName];
-        result[key] = value;
-      });
-      return result;
-    }
-    /** Performs the HTTP call to register the client to the server */
-
-  }, {
-    key: "doRegistration",
-    value: function doRegistration() {
-      return this.fetchJSON('POST', '/auth/register', this.snakeCaseOAuthData({
-        redirectURI: this.oauthOptions.redirectURI,
-        clientName: this.oauthOptions.clientName,
-        softwareID: this.oauthOptions.softwareID,
-        clientKind: this.oauthOptions.clientKind,
-        clientURI: this.oauthOptions.clientURI,
-        logoURI: this.oauthOptions.logoURI,
-        policyURI: this.oauthOptions.policyURI,
-        softwareVersion: this.oauthOptions.softwareVersion,
-        notificationPlatform: this.oauthOptions.notificationPlatform,
-        notificationDeviceToken: this.oauthOptions.notificationDeviceToken
-      }));
-    }
-    /**
-     * Registers the currenly configured client with the OAuth server and
-     * sets internal information from the server response
-     *
-     * @throws {Error} When the client is already registered
-     * @returns {Promise} A promise that resolves with a complete list of client information, including client ID and client secret.
-     */
 
-  }, {
-    key: "register",
+  (0, _createClass2.default)(PermissionCollection, [{
+    key: "get",
     value: function () {
-      var _register = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
-        var mandatoryFields, fields, missingMandatoryFields, data;
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) {
+        var resp;
         return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
               case 0:
-                if (!this.isRegistered()) {
-                  _context.next = 2;
-                  break;
-                }
-
-                throw new Error('Client already registered');
+                _context.next = 2;
+                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), id));
 
               case 2:
-                mandatoryFields = ['redirectURI'];
-                fields = Object.keys(this.oauthOptions);
-                missingMandatoryFields = mandatoryFields.filter(function (fieldName) {
-                  return fields[fieldName];
+                resp = _context.sent;
+                return _context.abrupt("return", {
+                  data: normalizePermission(resp.data)
                 });
 
-                if (!(missingMandatoryFields.length > 0)) {
-                  _context.next = 7;
-                  break;
-                }
-
-                throw new Error("Can't register client : missing ".concat(missingMandatoryFields, " fields"));
-
-              case 7:
-                _context.next = 9;
-                return this.doRegistration();
-
-              case 9:
-                data = _context.sent;
-                this.setOAuthOptions(_objectSpread(_objectSpread({}, this.oauthOptions), {}, {
-                  client_id: data.client_id,
-                  client_name: data.client_name,
-                  client_secret: data.client_secret,
-                  registration_access_token: data.registration_access_token,
-                  software_id: data.software_id
-                }));
-                return _context.abrupt("return", this.oauthOptions);
-
-              case 12:
+              case 4:
               case "end":
                 return _context.stop();
             }
@@ -110765,45 +109860,59 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee, this);
       }));
 
-      function register() {
-        return _register.apply(this, arguments);
+      function get(_x) {
+        return _get.apply(this, arguments);
       }
 
-      return register;
+      return get;
     }()
     /**
-     * Unregisters the currenly configured client with the OAuth server.
+     * Create a new set of permissions
+     * It can also associates one or more codes to it, via the codes parameter
+     *
+     * @param {object} permission
+     * @param {string} permission.codes A comma separed list of values (defaulted to code)
+     * @param {string} permission.ttl Make the codes expire after a delay (bigduration format)
+     * @param {boolean} permission.tiny If set to true then the generated shortcode will be 6 digits
+     * Cozy-Stack has a few conditions to be able to use this tiny shortcode ATM you have to specifiy
+     * a ttl < 1h, but it can change.
+     * see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions for exact informations
+     *
+     * bigduration format: https://github.com/justincampbell/bigduration/blob/master/README.md
+     * @see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions
      *
-     * @throws {NotRegisteredException} When the client doesn't have it's registration information
-     * @returns {Promise}
      */
 
   }, {
-    key: "unregister",
+    key: "create",
     value: function () {
-      var _unregister = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-        var clientID;
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) {
+        var _id, _type, _ref$codes, codes, ttl, tiny, attributes, searchParams, resp;
+
         return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
-                if (this.isRegistered()) {
-                  _context2.next = 2;
-                  break;
-                }
-
-                throw new NotRegisteredException();
-
-              case 2:
-                clientID = this.oauthOptions.clientID;
-                this.oauthOptions.clientID = '';
-                return _context2.abrupt("return", this.fetchJSON('DELETE', "/auth/register/".concat(clientID), null, {
-                  headers: {
-                    Authorization: this.registrationAccessTokenToAuthHeader()
+                _id = _ref._id, _type = _ref._type, _ref$codes = _ref.codes, codes = _ref$codes === void 0 ? 'code' : _ref$codes, ttl = _ref.ttl, tiny = _ref.tiny, attributes = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type", "codes", "ttl", "tiny"]);
+                searchParams = new URLSearchParams();
+                searchParams.append('codes', codes);
+                if (ttl) searchParams.append('ttl', ttl);
+                if (tiny) searchParams.append('tiny', true);
+                _context2.next = 7;
+                return this.stackClient.fetchJSON('POST', "/permissions?".concat(searchParams), {
+                  data: {
+                    type: 'io.cozy.permissions',
+                    attributes: attributes
                   }
-                }));
+                });
 
-              case 5:
+              case 7:
+                resp = _context2.sent;
+                return _context2.abrupt("return", {
+                  data: normalizePermission(resp.data)
+                });
+
+              case 9:
               case "end":
                 return _context2.stop();
             }
@@ -110811,42 +109920,80 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee2, this);
       }));
 
-      function unregister() {
-        return _unregister.apply(this, arguments);
+      function create(_x2) {
+        return _create.apply(this, arguments);
       }
 
-      return unregister;
+      return create;
     }()
     /**
-     * Fetches the complete set of client information from the server after it has been registered.
+     * Adds a permission to the given document. Document type must be
+     * `io.cozy.apps`, `io.cozy.konnectors` or `io.cozy.permissions`
      *
-     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @param  {object}  document - Document which receives the permission
+     * @param  {object}  permission - Describes the permission
      * @returns {Promise}
+     *
+     * @example
+     * ```
+     * const permissions = await client
+     *   .collection('io.cozy.permissions')
+     *   .add(konnector, {
+     *     folder: {
+     *       type: 'io.cozy.files',
+     *       verbs: ['GET', 'PUT'],
+     *       values: [`io.cozy.files.bc57b60eb2954537b0dcdc6ebd8e9d23`]
+     *     }
+     *  })
+     * ```
      */
 
   }, {
-    key: "fetchInformation",
+    key: "add",
     value: function () {
-      var _fetchInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
+      var _add = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document, permission) {
+        var endpoint, resp;
         return _regenerator.default.wrap(function _callee3$(_context3) {
           while (1) {
             switch (_context3.prev = _context3.next) {
               case 0:
-                if (this.isRegistered()) {
-                  _context3.next = 2;
-                  break;
-                }
+                _context3.t0 = document._type;
+                _context3.next = _context3.t0 === 'io.cozy.apps' ? 3 : _context3.t0 === 'io.cozy.konnectors' ? 5 : _context3.t0 === 'io.cozy.permissions' ? 7 : 9;
+                break;
 
-                throw new NotRegisteredException();
+              case 3:
+                endpoint = "/permissions/apps/".concat(document.slug);
+                return _context3.abrupt("break", 10);
 
-              case 2:
-                return _context3.abrupt("return", this.fetchJSON('GET', "/auth/register/".concat(this.oauthOptions.clientID), null, {
-                  headers: {
-                    Authorization: this.registrationAccessTokenToAuthHeader()
+              case 5:
+                endpoint = "/permissions/konnectors/".concat(document.slug);
+                return _context3.abrupt("break", 10);
+
+              case 7:
+                endpoint = "/permissions/".concat(document._id);
+                return _context3.abrupt("break", 10);
+
+              case 9:
+                throw new Error('Permissions can only be added on existing permissions, apps and konnectors.');
+
+              case 10:
+                _context3.next = 12;
+                return this.stackClient.fetchJSON('PATCH', endpoint, {
+                  data: {
+                    type: 'io.cozy.permissions',
+                    attributes: {
+                      permissions: permission
+                    }
                   }
-                }));
+                });
 
-              case 3:
+              case 12:
+                resp = _context3.sent;
+                return _context3.abrupt("return", {
+                  data: normalizePermission(resp.data)
+                });
+
+              case 14:
               case "end":
                 return _context3.stop();
             }
@@ -110854,65 +110001,36 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee3, this);
       }));
 
-      function fetchInformation() {
-        return _fetchInformation.apply(this, arguments);
+      function add(_x3, _x4) {
+        return _add.apply(this, arguments);
       }
 
-      return fetchInformation;
+      return add;
     }()
-    /**
-     * Overwrites the client own information. This method will update both the local information and the remote information on the OAuth server.
-     *
-     * @throws {NotRegisteredException} When the client doesn't have it's registration information
-     * @param   {object} information Set of information to update. Note that some fields such as `clientID` can't be updated.
-     * @param   {boolean} resetSecret = false Optionnal, whether to reset the client secret or not
-     * @returns {Promise} Resolves to a complete, updated list of client information
-     */
-
   }, {
-    key: "updateInformation",
+    key: "destroy",
+    value: function destroy(permission) {
+      return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), permission.id));
+    }
+  }, {
+    key: "findLinksByDoctype",
     value: function () {
-      var _updateInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(information) {
-        var resetSecret,
-            mandatoryFields,
-            data,
-            result,
-            _args4 = arguments;
+      var _findLinksByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(doctype) {
+        var resp;
         return _regenerator.default.wrap(function _callee4$(_context4) {
           while (1) {
             switch (_context4.prev = _context4.next) {
               case 0:
-                resetSecret = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : false;
-
-                if (this.isRegistered()) {
-                  _context4.next = 3;
-                  break;
-                }
-
-                throw new NotRegisteredException();
-
-              case 3:
-                mandatoryFields = {
-                  clientID: this.oauthOptions.clientID,
-                  clientName: this.oauthOptions.clientName,
-                  redirectURI: this.oauthOptions.redirectURI,
-                  softwareID: this.oauthOptions.softwareID
-                };
-                data = this.snakeCaseOAuthData(_objectSpread(_objectSpread({}, mandatoryFields), information));
-                if (resetSecret) data['client_secret'] = this.oauthOptions.clientSecret;
-                _context4.next = 8;
-                return this.fetchJSON('PUT', "/auth/register/".concat(this.oauthOptions.clientID), data, {
-                  headers: {
-                    Authorization: this.registrationAccessTokenToAuthHeader()
-                  }
-                });
+                _context4.next = 2;
+                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject3(), doctype));
 
-              case 8:
-                result = _context4.sent;
-                this.setOAuthOptions(_objectSpread(_objectSpread({}, data), result));
-                return _context4.abrupt("return", this.oauthOptions);
+              case 2:
+                resp = _context4.sent;
+                return _context4.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
+                  data: resp.data.map(normalizePermission)
+                }));
 
-              case 11:
+              case 4:
               case "end":
                 return _context4.stop();
             }
@@ -110920,170 +110038,35 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee4, this);
       }));
 
-      function updateInformation(_x) {
-        return _updateInformation.apply(this, arguments);
+      function findLinksByDoctype(_x5) {
+        return _findLinksByDoctype.apply(this, arguments);
       }
 
-      return updateInformation;
+      return findLinksByDoctype;
     }()
-    /**
-     * Generates a random state code to be used during the OAuth process
-     *
-     * @returns {string}
-     */
-
-  }, {
-    key: "generateStateCode",
-    value: function generateStateCode() {
-      var STATE_SIZE = 16;
-      var hasCrypto = typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function';
-      var buffer;
-
-      if (hasCrypto) {
-        buffer = new Uint8Array(STATE_SIZE);
-        window.crypto.getRandomValues(buffer);
-      } else {
-        buffer = new Array(STATE_SIZE);
-
-        for (var i = 0; i < buffer.length; i++) {
-          buffer[i] = Math.floor(Math.random() * 255);
-        }
-      }
-
-      return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-');
-    }
-    /**
-     * Generates the URL that the user should be sent to in order to accept the app's permissions.
-     *
-     * @throws {NotRegisteredException} When the client doesn't have it's registration information
-     * @param {object} options - URL generation options
-     * @param {string} options.stateCode - A random code to be included in the URl for security. Can be generated with `client.generateStateCode()`
-     * @param {Array} [options.scopes] - An array of permission scopes for the token.
-     * @param {SessionCode} [options.sessionCode] - A session code that can be used to create a session.
-     * @param {string} [options.codeChallenge] - A code challenge that can be used in a PKCE verification process.
-     * @returns {string} The URL
-     */
-
-  }, {
-    key: "getAuthCodeURL",
-    value: function getAuthCodeURL(_ref2) {
-      var stateCode = _ref2.stateCode,
-          _ref2$scopes = _ref2.scopes,
-          scopes = _ref2$scopes === void 0 ? this.scope : _ref2$scopes,
-          _ref2$sessionCode = _ref2.sessionCode,
-          sessionCode = _ref2$sessionCode === void 0 ? undefined : _ref2$sessionCode,
-          _ref2$codeChallenge = _ref2.codeChallenge,
-          codeChallenge = _ref2$codeChallenge === void 0 ? undefined : _ref2$codeChallenge;
-      if (!this.isRegistered()) throw new NotRegisteredException();
-      var query = {
-        client_id: this.oauthOptions.clientID,
-        redirect_uri: this.oauthOptions.redirectURI,
-        state: stateCode,
-        response_type: 'code',
-        scope: scopes.join(' ')
-      };
-
-      if (this.oauthOptions.registerToken) {
-        query = _objectSpread(_objectSpread({}, query), {}, {
-          registerToken: this.oauthOptions.registerToken
-        });
-      }
-
-      if (sessionCode) {
-        query = _objectSpread(_objectSpread({}, query), {}, {
-          session_code: sessionCode
-        });
-      }
-
-      if (codeChallenge) {
-        query = _objectSpread(_objectSpread({}, query), {}, {
-          code_challenge: codeChallenge,
-          code_challenge_method: 'S256'
-        });
-      }
-
-      return "".concat(this.uri, "/auth/authorize?").concat(this.dataToQueryString(query));
-    }
-  }, {
-    key: "dataToQueryString",
-    value: function dataToQueryString(data) {
-      return Object.keys(data).map(function (param) {
-        return "".concat(param, "=").concat(encodeURIComponent(data[param]));
-      }).join('&');
-    }
-    /**
-     * Retrieves the access code contained in the URL to which the user is redirected after accepting the app's permissions (the `redirectURI`).
-     *
-     * @throws {Error} The URL should contain the same state code as the one generated with `client.getAuthCodeURL()`. If not, it will throw an error
-     * @param   {string} pageURL The redirected page URL, containing the state code and the access code
-     * @param   {string} stateCode The state code that was contained in the original URL the user was sent to (see `client.getAuthCodeURL()`)
-     * @returns {string} The access code
-     */
-
-  }, {
-    key: "getAccessCodeFromURL",
-    value: function getAccessCodeFromURL(pageURL, stateCode) {
-      if (!stateCode) throw new Error('Missing state code');
-      var params = new URL(pageURL).searchParams;
-      var urlStateCode = params.get('state');
-      var urlAccessCode = params.get('access_code');
-      if (stateCode !== urlStateCode) throw new Error('Given state does not match url query state');
-      return urlAccessCode;
-    }
-    /**
-     * Exchanges an access code for an access token. This function does **not** update the client's token.
-     *
-     * @throws {NotRegisteredException} When the client doesn't have it's registration information
-     * @param   {string} accessCode - The access code contained in the redirection URL — see `client.getAccessCodeFromURL()`
-     * @param   {object} oauthOptionsArg — To use when OAuthClient is not yet registered (during login process)
-     * @param   {string} uri — To use when OAuthClient is not yet registered (during login process)
-     * @param   {string} codeVerifier — The PKCE code verifier (see https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension)
-     * @returns {Promise} A promise that resolves with an AccessToken object.
-     */
-
   }, {
-    key: "fetchAccessToken",
+    key: "findApps",
     value: function () {
-      var _fetchAccessToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(accessCode, oauthOptionsArg, uri, codeVerifier) {
-        var oauthOptions, data, result;
+      var _findApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
+        var resp;
         return _regenerator.default.wrap(function _callee5$(_context5) {
           while (1) {
             switch (_context5.prev = _context5.next) {
               case 0:
-                if (!(!this.isRegistered() && !oauthOptionsArg)) {
-                  _context5.next = 2;
-                  break;
-                }
-
-                throw new NotRegisteredException();
+                _context5.next = 2;
+                return this.stackClient.fetchJSON('GET', '/apps/');
 
               case 2:
-                oauthOptions = oauthOptionsArg || this.oauthOptions;
-                data = {
-                  grant_type: 'authorization_code',
-                  code: accessCode,
-                  client_id: oauthOptions.clientID,
-                  client_secret: oauthOptions.clientSecret
-                };
-
-                if (codeVerifier) {
-                  data = _objectSpread(_objectSpread({}, data), {}, {
-                    code_verifier: codeVerifier
-                  });
-                }
-
-                _context5.next = 7;
-                return this.fetchJSON('POST', (uri || '') + '/auth/access_token', this.dataToQueryString(data), {
-                  headers: {
-                    'Content-Type': 'application/x-www-form-urlencoded'
-                  }
-                });
-
-              case 7:
-                result = _context5.sent;
-                return _context5.abrupt("return", new _AccessToken.default(result));
+                resp = _context5.sent;
+                return _context5.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
+                  data: resp.data.map(function (a) {
+                    return _objectSpread({
+                      _id: a.id
+                    }, a);
+                  })
+                }));
 
-              case 9:
+              case 4:
               case "end":
                 return _context5.stop();
             }
@@ -111091,35 +110074,53 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee5, this);
       }));
 
-      function fetchAccessToken(_x2, _x3, _x4, _x5) {
-        return _fetchAccessToken.apply(this, arguments);
+      function findApps() {
+        return _findApps.apply(this, arguments);
       }
 
-      return fetchAccessToken;
+      return findApps;
     }()
     /**
-     * @typedef SessionCodeRes
-     * @property {string} session_code The value of the session code
-     */
-
-    /**
-     * Fetches a new session code. Only usable by the Flagship application
+     * Create a share link
      *
-     * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application
-     * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code
+     * @param {{_id, _type}} document - cozy document
+     * @param {object} options - options
+     * @param {string[]} options.verbs - explicit permissions to use
      */
 
   }, {
-    key: "fetchSessionCode",
+    key: "createSharingLink",
     value: function () {
-      var _fetchSessionCode = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
+      var _createSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document) {
+        var options,
+            verbs,
+            resp,
+            _args6 = arguments;
         return _regenerator.default.wrap(function _callee6$(_context6) {
           while (1) {
             switch (_context6.prev = _context6.next) {
               case 0:
-                return _context6.abrupt("return", this.fetchJSON('POST', '/auth/session_code'));
+                options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
+                verbs = options.verbs;
+                _context6.next = 4;
+                return this.stackClient.fetchJSON('POST', "/permissions?codes=email", {
+                  data: {
+                    type: 'io.cozy.permissions',
+                    attributes: {
+                      permissions: getPermissionsFor(document, true, verbs ? {
+                        verbs: verbs
+                      } : {})
+                    }
+                  }
+                });
 
-              case 1:
+              case 4:
+                resp = _context6.sent;
+                return _context6.abrupt("return", {
+                  data: normalizePermission(resp.data)
+                });
+
+              case 6:
               case "end":
                 return _context6.stop();
             }
@@ -111127,37 +110128,38 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee6, this);
       }));
 
-      function fetchSessionCode() {
-        return _fetchSessionCode.apply(this, arguments);
+      function createSharingLink(_x6) {
+        return _createSharingLink.apply(this, arguments);
       }
 
-      return fetchSessionCode;
+      return createSharingLink;
     }()
     /**
-     * Fetches a new session code. Only usable by the Flagship application
+     * Follow the next link to fetch the next permissions
      *
-     * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application
-     * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code
+     * @param {object} permissions JSON-API based permissions document
      */
 
   }, {
-    key: "fetchSessionCodeWithPassword",
+    key: "fetchPermissionsByLink",
     value: function () {
-      var _fetchSessionCodeWithPassword = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(_ref3) {
-        var passwordHash, _ref3$twoFactorToken, twoFactorToken, _ref3$twoFactorPassco, twoFactorPasscode;
-
+      var _fetchPermissionsByLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(permissions) {
         return _regenerator.default.wrap(function _callee7$(_context7) {
           while (1) {
             switch (_context7.prev = _context7.next) {
               case 0:
-                passwordHash = _ref3.passwordHash, _ref3$twoFactorToken = _ref3.twoFactorToken, twoFactorToken = _ref3$twoFactorToken === void 0 ? undefined : _ref3$twoFactorToken, _ref3$twoFactorPassco = _ref3.twoFactorPasscode, twoFactorPasscode = _ref3$twoFactorPassco === void 0 ? undefined : _ref3$twoFactorPassco;
-                return _context7.abrupt("return", this.fetchJSON('POST', '/auth/session_code', {
-                  passphrase: passwordHash,
-                  two_factor_token: twoFactorToken,
-                  two_factor_passcode: twoFactorPasscode
-                }));
+                if (!(permissions.links && permissions.links.next)) {
+                  _context7.next = 4;
+                  break;
+                }
 
-              case 2:
+                _context7.next = 3;
+                return this.stackClient.fetchJSON('GET', permissions.links.next);
+
+              case 3:
+                return _context7.abrupt("return", _context7.sent);
+
+              case 4:
               case "end":
                 return _context7.stop();
             }
@@ -111165,71 +110167,56 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee7, this);
       }));
 
-      function fetchSessionCodeWithPassword(_x6) {
-        return _fetchSessionCodeWithPassword.apply(this, arguments);
+      function fetchPermissionsByLink(_x7) {
+        return _fetchPermissionsByLink.apply(this, arguments);
       }
 
-      return fetchSessionCodeWithPassword;
+      return fetchPermissionsByLink;
     }()
     /**
-     * Retrieves a new access token by refreshing the currently used token.
      *
-     * @throws {NotRegisteredException} When the client doesn't have it's registration information
-     * @throws {Error} The client should already have an access token to use this function
-     * @returns {Promise} A promise that resolves with a new AccessToken object
+     * @param {object} document Cozy doc
+     * @returns {object} with all the permissions
      */
 
   }, {
-    key: "refreshToken",
+    key: "fetchAllLinks",
     value: function () {
-      var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8() {
-        var data, result, newToken;
+      var _fetchAllLinks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(document) {
+        var allLinks, resp, _allLinks$data;
+
         return _regenerator.default.wrap(function _callee8$(_context8) {
           while (1) {
             switch (_context8.prev = _context8.next) {
               case 0:
-                if (this.isRegistered()) {
-                  _context8.next = 2;
-                  break;
-                }
-
-                throw new NotRegisteredException();
+                _context8.next = 2;
+                return this.findLinksByDoctype(document._type);
 
               case 2:
-                if (this.token) {
-                  _context8.next = 4;
+                allLinks = _context8.sent;
+                resp = allLinks;
+
+              case 4:
+                if (!(resp.links && resp.links.next)) {
+                  _context8.next = 11;
                   break;
                 }
 
-                throw new Error('No token to refresh');
-
-              case 4:
-                data = {
-                  grant_type: 'refresh_token',
-                  refresh_token: this.token.refreshToken,
-                  client_id: this.oauthOptions.clientID,
-                  client_secret: this.oauthOptions.clientSecret
-                };
                 _context8.next = 7;
-                return (0, _get2.default)((0, _getPrototypeOf2.default)(OAuthClient.prototype), "fetchJSON", this).call(this, 'POST', '/auth/access_token', this.dataToQueryString(data), {
-                  headers: {
-                    'Content-Type': 'application/x-www-form-urlencoded'
-                  }
-                });
+                return this.fetchPermissionsByLink(resp);
 
               case 7:
-                result = _context8.sent;
-                newToken = new _AccessToken.default(_objectSpread({
-                  refresh_token: this.token.refreshToken
-                }, result));
+                resp = _context8.sent;
 
-                if (this.onTokenRefresh && typeof this.onTokenRefresh === 'function') {
-                  this.onTokenRefresh(newToken);
-                }
+                (_allLinks$data = allLinks.data).push.apply(_allLinks$data, (0, _toConsumableArray2.default)(resp.data.map(normalizePermission)));
 
-                return _context8.abrupt("return", newToken);
+                _context8.next = 4;
+                break;
 
               case 11:
+                return _context8.abrupt("return", allLinks);
+
+              case 12:
               case "end":
                 return _context8.stop();
             }
@@ -111237,168 +110224,213 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
         }, _callee8, this);
       }));
 
-      function refreshToken() {
-        return _refreshToken.apply(this, arguments);
+      function fetchAllLinks(_x8) {
+        return _fetchAllLinks.apply(this, arguments);
       }
 
-      return refreshToken;
+      return fetchAllLinks;
     }()
-  }, {
-    key: "exchangeOAuthSecret",
-    value: function exchangeOAuthSecret(uri, secret) {
-      return this.fetchJSON('POST', uri + '/auth/secret_exchange', {
-        secret: secret
-      });
-    }
     /**
-     * Updates the client's stored token
+     * Destroy a sharing link and the related permissions
      *
-     * @param {string} token = null The new token to use — can be a string, a json object or an AccessToken instance.
+     * @param {object} document
      */
 
   }, {
-    key: "setToken",
-    value: function setToken(token) {
-      if (token) {
-        this.token = token instanceof _AccessToken.default ? token : new _AccessToken.default(token);
-      } else {
-        this.token = null;
+    key: "revokeSharingLink",
+    value: function () {
+      var _revokeSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(document) {
+        var allLinks, links, _iterator, _step, perm;
+
+        return _regenerator.default.wrap(function _callee9$(_context9) {
+          while (1) {
+            switch (_context9.prev = _context9.next) {
+              case 0:
+                _context9.next = 2;
+                return this.fetchAllLinks(document);
+
+              case 2:
+                allLinks = _context9.sent;
+                links = allLinks.data.filter(function (perm) {
+                  return isPermissionRelatedTo(perm, document);
+                });
+                _iterator = _createForOfIteratorHelper(links);
+                _context9.prev = 5;
+
+                _iterator.s();
+
+              case 7:
+                if ((_step = _iterator.n()).done) {
+                  _context9.next = 13;
+                  break;
+                }
+
+                perm = _step.value;
+                _context9.next = 11;
+                return this.destroy(perm);
+
+              case 11:
+                _context9.next = 7;
+                break;
+
+              case 13:
+                _context9.next = 18;
+                break;
+
+              case 15:
+                _context9.prev = 15;
+                _context9.t0 = _context9["catch"](5);
+
+                _iterator.e(_context9.t0);
+
+              case 18:
+                _context9.prev = 18;
+
+                _iterator.f();
+
+                return _context9.finish(18);
+
+              case 21:
+              case "end":
+                return _context9.stop();
+            }
+          }
+        }, _callee9, this, [[5, 15, 18, 21]]);
+      }));
+
+      function revokeSharingLink(_x9) {
+        return _revokeSharingLink.apply(this, arguments);
       }
-    }
-  }, {
-    key: "setCredentials",
-    value: function setCredentials(token) {
-      (0, _logDeprecate.default)('setCredentials is deprecated, please replace by setToken');
-      return this.setToken(token);
-    }
-    /**
-     * Updates the OAuth informations
-     *
-     * @param {object} options Map of OAuth options
-     */
 
-  }, {
-    key: "setOAuthOptions",
-    value: function setOAuthOptions(options) {
-      this.oauthOptions = this.camelCaseOAuthData(options);
-    }
-  }, {
-    key: "resetClientId",
-    value: function resetClientId() {
-      this.oauthOptions.clientID = '';
-    }
+      return revokeSharingLink;
+    }()
     /**
-     * Reset the current OAuth client
+     * async getOwnPermissions - deprecated: please use fetchOwnPermissions instead
+     *
+     * @typedef {object} Permission
+     *
+     * @returns {Permission} permission
      */
 
   }, {
-    key: "resetClient",
-    value: function resetClient() {
-      this.resetClientId();
-      this.setUri(null);
-      this.setToken(null);
-    }
-    /**
-     * Turns the client's registration access token into a header suitable for HTTP requests. Used in some queries to manipulate the client on the server side.
-     *
-     * @returns {string}
-     * @private
-     */
+    key: "getOwnPermissions",
+    value: function () {
+      var _getOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10() {
+        return _regenerator.default.wrap(function _callee10$(_context10) {
+          while (1) {
+            switch (_context10.prev = _context10.next) {
+              case 0:
+                console.warn('getOwnPermissions is deprecated, please use fetchOwnPermissions instead');
+                return _context10.abrupt("return", this.fetchOwnPermissions());
 
-  }, {
-    key: "registrationAccessTokenToAuthHeader",
-    value: function registrationAccessTokenToAuthHeader() {
-      if (!this.oauthOptions.registrationAccessToken) {
-        throw new Error('No registration access token');
+              case 2:
+              case "end":
+                return _context10.stop();
+            }
+          }
+        }, _callee10, this);
+      }));
+
+      function getOwnPermissions() {
+        return _getOwnPermissions.apply(this, arguments);
       }
 
-      return 'Bearer ' + this.oauthOptions.registrationAccessToken;
-    }
+      return getOwnPermissions;
+    }()
     /**
-     * This method should be used in flagship app onboarding process to finalize the
-     * cozy creation by setting the user password into the cozy-stack
+     * async fetchOwnPermissions - Fetches permissions
      *
-     * More info: https://docs.cozy.io/en/cozy-stack/settings/#post-settingspassphraseflagship
+     * @typedef {object} Permission
      *
-     * @param {object} params
-     * @param {string} params.registerToken - registration token provided by the onboarding link
-     * @param {string} params.passwordHash - hash of the master password
-     * @param {string} params.hint - hint for the master password
-     * @param {string} params.key - key (crypted) used for the vault encryption
-     * @param {string} params.publicKey - public key used for sharing ciphers from the vault
-     * @param {string} params.privateKey - private key (crypted) used for sharing ciphers from the vault
-     * @param {string} params.iterations - number of KDF iterations applied when hashing the master password
-     * @returns {object} token - The OAauth token
+     * @returns {Permission} permission
      */
 
   }, {
-    key: "setPassphraseFlagship",
-    value: function setPassphraseFlagship(_ref4) {
-      var registerToken = _ref4.registerToken,
-          passwordHash = _ref4.passwordHash,
-          hint = _ref4.hint,
-          key = _ref4.key,
-          publicKey = _ref4.publicKey,
-          privateKey = _ref4.privateKey,
-          iterations = _ref4.iterations;
-      return this.fetchJSON('POST', '/settings/passphrase/flagship', {
-        register_token: registerToken,
-        passphrase: passwordHash,
-        hint: hint,
-        key: key,
-        public_key: publicKey,
-        private_key: privateKey,
-        iterations: iterations,
-        client_id: this.oauthOptions.clientID,
-        client_secret: this.oauthOptions.clientSecret
-      }, {
-        // TODO: faut il mettre le header?
-        headers: {
-          Authorization: this.registrationAccessTokenToAuthHeader()
-        }
-      });
-    }
-  }]);
-  return OAuthClient;
-}(_CozyStackClient2.default);
+    key: "fetchOwnPermissions",
+    value: function () {
+      var _fetchOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() {
+        var resp;
+        return _regenerator.default.wrap(function _callee11$(_context11) {
+          while (1) {
+            switch (_context11.prev = _context11.next) {
+              case 0:
+                _context11.next = 2;
+                return this.stackClient.fetchJSON('GET', '/permissions/self');
 
-var NotRegisteredException = /*#__PURE__*/function (_Error) {
-  (0, _inherits2.default)(NotRegisteredException, _Error);
+              case 2:
+                resp = _context11.sent;
+                return _context11.abrupt("return", {
+                  data: normalizePermission(resp.data),
+                  included: resp.included ? resp.included.map(normalizePermission) : []
+                });
 
-  var _super2 = _createSuper(NotRegisteredException);
+              case 4:
+              case "end":
+                return _context11.stop();
+            }
+          }
+        }, _callee11, this);
+      }));
 
-  function NotRegisteredException() {
-    var _this2;
+      function fetchOwnPermissions() {
+        return _fetchOwnPermissions.apply(this, arguments);
+      }
 
-    var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Client not registered or missing OAuth information';
-    (0, _classCallCheck2.default)(this, NotRegisteredException);
-    _this2 = _super2.call(this, message);
-    _this2.message = message;
-    _this2.name = 'NotRegisteredException';
-    return _this2;
-  }
+      return fetchOwnPermissions;
+    }()
+  }]);
+  return PermissionCollection;
+}(_DocumentCollection2.default);
+/**
+ * Build a permission set
+ *
+ * @param {{_id, _type}} document - cozy document
+ * @param {boolean} publicLink - are the permissions for a public link ?
+ * @param {object} options - options
+ * @param {string[]} options.verbs - explicit permissions to use
+ * @returns {object} permissions object that can be sent through /permissions/*
+ */
 
-  return NotRegisteredException;
-}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
 
-var _default = OAuthClient;
-exports["default"] = _default;
+var getPermissionsFor = function getPermissionsFor(document) {
+  var publicLink = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+  var _id = document._id,
+      _type = document._type;
+  var verbs = options.verbs ? options.verbs : publicLink ? ['GET'] : ['ALL']; // TODO: this works for albums, but it needs to be generalized and integrated
+  // with cozy-client ; some sort of doctype "schema" will be needed here
 
-/***/ }),
-/* 685 */
-/***/ ((__unused_webpack_module, exports) => {
+  return (0, _FileCollection.isFile)(document) ? {
+    files: {
+      type: 'io.cozy.files',
+      verbs: verbs,
+      values: [_id]
+    }
+  } : {
+    collection: {
+      type: _type,
+      verbs: verbs,
+      values: [_id]
+    },
+    files: {
+      type: 'io.cozy.files',
+      verbs: verbs,
+      values: ["".concat(_type, "/").concat(_id)],
+      selector: 'referenced_by'
+    }
+  };
+};
 
-"use strict";
+exports.getPermissionsFor = getPermissionsFor;
+PermissionCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
 
+var isPermissionRelatedTo = function isPermissionRelatedTo(perm, document) {
+  var _id = document._id;
+  return (0, _FileCollection.isFile)(document) ? perm.attributes.permissions.files.values.indexOf(_id) !== -1 : perm.attributes.permissions.collection.values.indexOf(_id) !== -1;
+};
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.DOCTYPE_FILES = exports.REGISTRATION_ABORT = void 0;
-var REGISTRATION_ABORT = 'REGISTRATION_ABORT';
-exports.REGISTRATION_ABORT = REGISTRATION_ABORT;
-var DOCTYPE_FILES = 'io.cozy.files';
-exports.DOCTYPE_FILES = DOCTYPE_FILES;
+var _default = PermissionCollection;
+exports["default"] = _default;
 
 /***/ }),
 /* 686 */
@@ -111407,229 +110439,84 @@ exports.DOCTYPE_FILES = DOCTYPE_FILES;
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.transformBulkDocsResponse = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
-
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
-
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+exports["default"] = exports.SETTINGS_DOCTYPE = void 0;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _dsl = __webpack_require__(607);
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _CozyLink2 = _interopRequireDefault(__webpack_require__(687));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _types = __webpack_require__(610);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _const = __webpack_require__(685);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _errors = __webpack_require__(688);
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _zipWith = _interopRequireDefault(__webpack_require__(689));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613));
 
 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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-/**
- * Returns full documents after a bulk update
- *
- * @private
- *
- * @param  {CouchDBBulkResult[]} bulkResponse - Response from bulk docs
- * @param  {CozyClientDocument[]} originalDocuments - Documents that were updated
- * @returns {{ data: CozyClientDocument[] }} - Full documents with updated _id and _rev
- */
-var transformBulkDocsResponse = function transformBulkDocsResponse(bulkResponse, originalDocuments) {
-  var updatedDocs = (0, _zipWith.default)(bulkResponse, originalDocuments, function (result, od) {
-    return result.ok ? _objectSpread(_objectSpread({}, od), {}, {
-      _id: result.id,
-      _rev: result.rev
-    }) : od;
-  });
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-  if (bulkResponse.find(function (x) {
-    return !x.ok;
-  })) {
-    throw new _errors.BulkEditError(bulkResponse, updatedDocs);
-  }
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-  return {
-    data: updatedDocs
-  };
-};
+var SETTINGS_DOCTYPE = 'io.cozy.settings';
 /**
- * Transfers queries and mutations to a remote stack
+ * Implements `DocumentCollection` API to interact with the /settings endpoint of the stack
  */
 
+exports.SETTINGS_DOCTYPE = SETTINGS_DOCTYPE;
 
-exports.transformBulkDocsResponse = transformBulkDocsResponse;
-
-var StackLink = /*#__PURE__*/function (_CozyLink) {
-  (0, _inherits2.default)(StackLink, _CozyLink);
+var SettingsCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(SettingsCollection, _DocumentCollection);
 
-  var _super = _createSuper(StackLink);
+  var _super = _createSuper(SettingsCollection);
 
+  function SettingsCollection(stackClient) {
+    (0, _classCallCheck2.default)(this, SettingsCollection);
+    return _super.call(this, SETTINGS_DOCTYPE, stackClient);
+  }
   /**
-   * @param {object} [options] - Options
-   * @param  {object} [options.stackClient] - A StackClient
-   * @param  {object} [options.client] - A StackClient (deprecated)
+   * async get - Calls a route on the /settings API
+   *
+   * @param  {string} path The setting route to call, eg `instance` or `context`
+   * @returns {object} The response from the route
    */
-  function StackLink() {
-    var _this;
-
-    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
-        client = _ref.client,
-        stackClient = _ref.stackClient;
-
-    (0, _classCallCheck2.default)(this, StackLink);
-    _this = _super.call(this);
-
-    if (client) {
-      console.warn('Using options.client is deprecated, prefer options.stackClient');
-    }
-
-    _this.stackClient = stackClient || client;
-    return _this;
-  }
-
-  (0, _createClass2.default)(StackLink, [{
-    key: "registerClient",
-    value: function registerClient(client) {
-      this.stackClient = client.stackClient || client.client;
-    }
-  }, {
-    key: "reset",
-    value: function reset() {
-      this.stackClient = null;
-    }
-  }, {
-    key: "request",
-    value: function request(operation, result, forward) {
-      if (operation.mutationType) {
-        return this.executeMutation(operation, result, forward);
-      }
-
-      return this.executeQuery(operation);
-    }
-  }, {
-    key: "executeQuery",
-    value: function executeQuery(query) {
-      var doctype = query.doctype,
-          selector = query.selector,
-          id = query.id,
-          ids = query.ids,
-          referenced = query.referenced,
-          options = (0, _objectWithoutProperties2.default)(query, ["doctype", "selector", "id", "ids", "referenced"]);
-
-      if (!doctype) {
-        console.warn('Bad query', query);
-        throw new Error('No doctype found in a query definition');
-      }
-
-      var collection = this.stackClient.collection(doctype);
-
-      if (id) {
-        return collection.get(id, query);
-      }
 
-      if (ids) {
-        return collection.getAll(ids);
-      }
-
-      if (referenced) {
-        return collection.findReferencedBy(referenced, options);
-      }
 
-      return !selector && !options.sort ? collection.all(options) : collection.find(selector, options);
-    }
-  }, {
-    key: "executeMutation",
+  (0, _createClass2.default)(SettingsCollection, [{
+    key: "get",
     value: function () {
-      var _executeMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mutation, result, forward) {
-        var mutationType, doc, docs, props, updateAllResp;
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(path) {
+        var resp;
         return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
               case 0:
-                mutationType = mutation.mutationType, doc = mutation.document, docs = mutation.documents, props = (0, _objectWithoutProperties2.default)(mutation, ["mutationType", "document", "documents"]);
-                _context.t0 = mutationType;
-                _context.next = _context.t0 === _dsl.MutationTypes.CREATE_DOCUMENT ? 4 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENTS ? 5 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENT ? 9 : _context.t0 === _dsl.MutationTypes.DELETE_DOCUMENT ? 10 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCES_TO ? 11 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCES_TO ? 12 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCED_BY ? 13 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCED_BY ? 18 : _context.t0 === _dsl.MutationTypes.UPLOAD_FILE ? 23 : 24;
-                break;
-
-              case 4:
-                return _context.abrupt("return", this.stackClient.collection(doc._type).create(doc));
-
-              case 5:
-                _context.next = 7;
-                return this.stackClient.collection(docs[0]._type).updateAll(docs);
-
-              case 7:
-                updateAllResp = _context.sent;
-                return _context.abrupt("return", transformBulkDocsResponse(updateAllResp, docs));
-
-              case 9:
-                return _context.abrupt("return", this.stackClient.collection(doc._type).update(doc));
-
-              case 10:
-                return _context.abrupt("return", this.stackClient.collection(doc._type).destroy(doc));
-
-              case 11:
-                return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).addReferencesTo(doc, props.referencedDocuments));
-
-              case 12:
-                return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).removeReferencesTo(doc, props.referencedDocuments));
-
-              case 13:
-                if (!(doc._type === _const.DOCTYPE_FILES)) {
-                  _context.next = 17;
-                  break;
-                }
-
-                return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).addReferencedBy(doc, props.referencedDocuments));
-
-              case 17:
-                throw new Error('The document type should be io.cozy.files');
-
-              case 18:
-                if (!(doc._type === _const.DOCTYPE_FILES)) {
-                  _context.next = 22;
-                  break;
-                }
-
-                return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).removeReferencedBy(doc, props.referencedDocuments));
-
-              case 22:
-                throw new Error('The document type should be io.cozy.files');
-
-              case 23:
-                return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).upload(props.file, props.dirPath));
+                _context.next = 2;
+                return this.stackClient.fetchJSON('GET', "/settings/".concat(path));
 
-              case 24:
-                return _context.abrupt("return", forward(mutation, result));
+              case 2:
+                resp = _context.sent;
+                return _context.abrupt("return", {
+                  data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SETTINGS_DOCTYPE)(_objectSpread({
+                    id: "/settings/".concat(path)
+                  }, resp.data), resp)
+                });
 
-              case 25:
+              case 4:
               case "end":
                 return _context.stop();
             }
@@ -111637,17 +110524,19 @@ var StackLink = /*#__PURE__*/function (_CozyLink) {
         }, _callee, this);
       }));
 
-      function executeMutation(_x, _x2, _x3) {
-        return _executeMutation.apply(this, arguments);
+      function get(_x) {
+        return _get.apply(this, arguments);
       }
 
-      return executeMutation;
+      return get;
     }()
   }]);
-  return StackLink;
-}(_CozyLink2.default);
+  return SettingsCollection;
+}(_DocumentCollection2.default);
 
-exports["default"] = StackLink;
+SettingsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+var _default = SettingsCollection;
+exports["default"] = _default;
 
 /***/ }),
 /* 687 */
@@ -111656,13476 +110545,14618 @@ exports["default"] = StackLink;
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.chain = exports["default"] = void 0;
+exports["default"] = exports.NOTES_URL_DOCTYPE = exports.NOTES_DOCTYPE = void 0;
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var CozyLink = /*#__PURE__*/function () {
-  function CozyLink(requestHandler) {
-    (0, _classCallCheck2.default)(this, CozyLink);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-    if (typeof requestHandler === 'function') {
-      this.request = requestHandler;
-    }
-  }
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-  (0, _createClass2.default)(CozyLink, [{
-    key: "request",
-    value: function request(operation, result, forward) {
-      throw new Error('request is not implemented');
-    }
-  }]);
-  return CozyLink;
-}();
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-exports["default"] = CozyLink;
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var toLink = function toLink(handler) {
-  return typeof handler === 'function' ? new CozyLink(handler) : handler;
-};
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var defaultLinkHandler = function defaultLinkHandler(operation, result) {
-  if (result) return result;else if (operation.execute) return operation.execute();else throw new Error("No link could handle operation ".concat(JSON.stringify(operation)));
-};
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var chain = function chain(links) {
-  return [].concat((0, _toConsumableArray2.default)(links), [defaultLinkHandler]).map(toLink).reduce(concat);
-};
+var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613));
 
-exports.chain = chain;
+var _utils = __webpack_require__(623);
 
-var concat = function concat(firstLink, nextLink) {
-  return new CozyLink(function (operation, result, forward) {
-    var nextForward = function nextForward(op, res) {
-      return nextLink.request(op, res, forward);
-    };
+var _NotesSchema = __webpack_require__(688);
 
-    return firstLink.request(operation, result, nextForward);
-  });
-};
+function _templateObject2() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/notes/", "/open"]);
 
-/***/ }),
-/* 688 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+  _templateObject2 = function _templateObject2() {
+    return data;
+  };
 
-"use strict";
+  return data;
+}
 
+function _templateObject() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]);
 
-var _interopRequireDefault = __webpack_require__(512);
+  _templateObject = function _templateObject() {
+    return data;
+  };
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.BulkEditError = void 0;
+  return data;
+}
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+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; }
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var NOTES_DOCTYPE = 'io.cozy.notes';
+exports.NOTES_DOCTYPE = NOTES_DOCTYPE;
+var NOTES_URL_DOCTYPE = 'io.cozy.notes.url';
+exports.NOTES_URL_DOCTYPE = NOTES_URL_DOCTYPE;
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_DOCTYPE);
 
-var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652));
+var normalizeNote = function normalizeNote(note) {
+  return _objectSpread(_objectSpread({}, normalizeDoc(note, NOTES_DOCTYPE)), note.attributes);
+};
 
-var _zipWith = _interopRequireDefault(__webpack_require__(689));
+var normalizeNoteUrl = function normalizeNoteUrl(noteUrl) {
+  return _objectSpread(_objectSpread({}, _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_URL_DOCTYPE)(noteUrl)), noteUrl.attributes);
+};
+/**
+ * Implements `DocumentCollection` API to interact with the /notes endpoint of the stack
+ */
 
-var _types = __webpack_require__(610);
 
-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; }
+var NotesCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(NotesCollection, _DocumentCollection);
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  var _super = _createSuper(NotesCollection);
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+  function NotesCollection(stackClient) {
+    (0, _classCallCheck2.default)(this, NotesCollection);
+    return _super.call(this, NOTES_DOCTYPE, stackClient);
+  }
+  /**
+   * Fetches all notes
+   *
+   * @returns {{data, links, meta}} The JSON API conformant response.
+   */
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var BulkEditError = /*#__PURE__*/function (_Error) {
-  (0, _inherits2.default)(BulkEditError, _Error);
+  (0, _createClass2.default)(NotesCollection, [{
+    key: "all",
+    value: function () {
+      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var resp;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.next = 2;
+                return this.stackClient.fetchJSON('GET', '/notes');
 
-  var _super = _createSuper(BulkEditError);
+              case 2:
+                resp = _context.sent;
+                return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
+                  data: resp.data.map(normalizeNote)
+                }));
 
-  /**
-   * Indicates that a bulk edit has (potentially partially) failed
-   *
-   * @param  {CouchDBBulkResult[]} bulkResponse - CouchDB Bulk response
-   * @param  {CozyClientDocument[]} updatedDocs - Docs with updated _id and _rev
-   */
-  function BulkEditError(bulkResponse, updatedDocs) {
-    var _this;
+              case 4:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
 
-    (0, _classCallCheck2.default)(this, BulkEditError);
-    _this = _super.call(this, 'Error while bulk saving');
-    _this.name = 'BulkEditError';
-    _this.results = (0, _zipWith.default)(bulkResponse, updatedDocs, function (result, doc) {
-      return _objectSpread(_objectSpread({}, result), {}, {
-        doc: doc
-      });
-    });
-    return _this;
-  }
-  /**
-   * Get documents that have been correctly updated
-   *
-   * @returns {CozyClientDocument[]}
-   */
+      function all() {
+        return _all.apply(this, arguments);
+      }
 
+      return all;
+    }()
+    /**
+     * Destroys the note on the server
+     *
+     * @param {object} note       The io.cozy.notes document to destroy
+     * @param {string} [note._id] The note's id
+     *
+     * @returns {{ data }} The deleted note
+     */
 
-  (0, _createClass2.default)(BulkEditError, [{
-    key: "getUpdatedDocuments",
-    value: function getUpdatedDocuments() {
-      return this.results.filter(function (r) {
-        return r.ok;
-      }).map(function (r) {
-        return r.doc;
-      });
-    }
+  }, {
+    key: "destroy",
+    value: function () {
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) {
+        var _id, resp;
+
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                _id = _ref._id;
+                _context2.next = 3;
+                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject(), _id));
+
+              case 3:
+                resp = _context2.sent;
+                return _context2.abrupt("return", {
+                  data: _objectSpread(_objectSpread({}, normalizeNote(resp.data)), {}, {
+                    _deleted: true
+                  })
+                });
+
+              case 5:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
+
+      function destroy(_x) {
+        return _destroy.apply(this, arguments);
+      }
+
+      return destroy;
+    }()
     /**
-     * Get bulk errors results
+     * Create a note
      *
-     * @returns {Array<CouchDBBulkResult & { doc: CozyClientDocument }>}
+     * @param {object} options
+     * @param {string} [options.dir_id] dir_id where to create the note
+     *
+     * @returns {{data, links, meta}} The JSON API conformant response.
      */
 
   }, {
-    key: "getErrors",
-    value: function getErrors() {
-      return this.results.filter(function (r) {
-        return !r.ok;
-      });
-    }
-  }]);
-  return BulkEditError;
-}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
+    key: "create",
+    value: function () {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref2) {
+        var dir_id, resp;
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                dir_id = _ref2.dir_id;
+                _context3.next = 3;
+                return this.stackClient.fetchJSON('POST', '/notes', {
+                  data: {
+                    type: 'io.cozy.notes.documents',
+                    attributes: {
+                      title: '',
+                      schema: (0, _NotesSchema.getDefaultSchema)(),
+                      dir_id: dir_id
+                    }
+                  }
+                });
 
-exports.BulkEditError = BulkEditError;
+              case 3:
+                resp = _context3.sent;
+                return _context3.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, {
+                  data: normalizeNote(resp.data)
+                }));
 
-/***/ }),
-/* 689 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 5:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
 
-var baseRest = __webpack_require__(544),
-    unzipWith = __webpack_require__(690);
+      function create(_x2) {
+        return _create.apply(this, arguments);
+      }
 
-/**
- * This method is like `_.zip` except that it accepts `iteratee` to specify
- * how grouped values should be combined. The iteratee is invoked with the
- * elements of each group: (...group).
- *
- * @static
- * @memberOf _
- * @since 3.8.0
- * @category Array
- * @param {...Array} [arrays] The arrays to process.
- * @param {Function} [iteratee=_.identity] The function to combine
- *  grouped values.
- * @returns {Array} Returns the new array of grouped elements.
- * @example
- *
- * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
- *   return a + b + c;
- * });
- * // => [111, 222]
- */
-var zipWith = baseRest(function(arrays) {
-  var length = arrays.length,
-      iteratee = length > 1 ? arrays[length - 1] : undefined;
+      return create;
+    }()
+    /**
+     * Returns the details to build the note's url
+     *
+     * @see https://github.com/cozy/cozy-stack/blob/master/docs/notes.md#get-notesidopen
+     *
+     * @param {object} note       The io.cozy.notes document to open
+     * @param {string} [note._id] The note's id
+     *
+     * @returns {{ data }} The note's url details
+     */
 
-  iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
-  return unzipWith(arrays, iteratee);
-});
+  }, {
+    key: "fetchURL",
+    value: function () {
+      var _fetchURL = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(_ref3) {
+        var _id, resp;
 
-module.exports = zipWith;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                _id = _ref3._id;
+                _context4.next = 3;
+                return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject2(), _id));
+
+              case 3:
+                resp = _context4.sent;
+                return _context4.abrupt("return", {
+                  data: normalizeNoteUrl(resp.data)
+                });
+
+              case 5:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
+
+      function fetchURL(_x3) {
+        return _fetchURL.apply(this, arguments);
+      }
+
+      return fetchURL;
+    }()
+    /**
+     * Returns promise mirror schema for a note
+     *
+     * @returns {object} schema
+     */
+
+  }, {
+    key: "getDefaultSchema",
+    value: function getDefaultSchema() {
+      return (0, _NotesSchema.getDefaultSchema)();
+    }
+  }]);
+  return NotesCollection;
+}(_DocumentCollection2.default);
 
+NotesCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+var _default = NotesCollection;
+exports["default"] = _default;
 
 /***/ }),
-/* 690 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 688 */
+/***/ ((__unused_webpack_module, exports) => {
 
-var apply = __webpack_require__(546),
-    arrayMap = __webpack_require__(398),
-    unzip = __webpack_require__(551);
+"use strict";
 
-/**
- * This method is like `_.unzip` except that it accepts `iteratee` to specify
- * how regrouped values should be combined. The iteratee is invoked with the
- * elements of each group: (...group).
- *
- * @static
- * @memberOf _
- * @since 3.8.0
- * @category Array
- * @param {Array} array The array of grouped elements to process.
- * @param {Function} [iteratee=_.identity] The function to combine
- *  regrouped values.
- * @returns {Array} Returns the new array of regrouped elements.
- * @example
- *
- * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
- * // => [[1, 10, 100], [2, 20, 200]]
- *
- * _.unzipWith(zipped, _.add);
- * // => [3, 30, 300]
- */
-function unzipWith(array, iteratee) {
-  if (!(array && array.length)) {
-    return [];
-  }
-  var result = unzip(array);
-  if (iteratee == null) {
-    return result;
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getDefaultSchema = exports.marks = exports.nodes = void 0;
+// taken from a debug of @atlakit/editor/editor-core/create-editor/create-editor
+// L139 (new Schema({nodes ,marks}))
+// static because the @atlaskit code base requires a real navigator
+// TODO: either find and exclude plugins requiring interaction
+//       or running a JSDOM faking a navigator
+var nodes = [['doc', {
+  content: '(block)+',
+  marks: 'link'
+}], ['paragraph', {
+  content: 'inline*',
+  group: 'block',
+  marks: 'strong code em link strike subsup textColor typeAheadQuery underline',
+  parseDOM: [{
+    tag: 'p'
+  }]
+}], ['text', {
+  group: 'inline'
+}], ['bulletList', {
+  group: 'block',
+  content: 'listItem+',
+  parseDOM: [{
+    tag: 'ul'
+  }]
+}], ['orderedList', {
+  group: 'block',
+  content: 'listItem+',
+  parseDOM: [{
+    tag: 'ol'
+  }]
+}], ['listItem', {
+  content: '(paragraph ) (paragraph | bulletList | orderedList )*',
+  defining: true,
+  parseDOM: [{
+    tag: 'li'
+  }]
+}], ['heading', {
+  attrs: {
+    level: {
+      default: 1
+    }
+  },
+  content: 'inline*',
+  group: 'block',
+  defining: true,
+  parseDOM: [{
+    tag: 'h1',
+    attrs: {
+      level: 1
+    }
+  }, {
+    tag: 'h2',
+    attrs: {
+      level: 2
+    }
+  }, {
+    tag: 'h3',
+    attrs: {
+      level: 3
+    }
+  }, {
+    tag: 'h4',
+    attrs: {
+      level: 4
+    }
+  }, {
+    tag: 'h5',
+    attrs: {
+      level: 5
+    }
+  }, {
+    tag: 'h6',
+    attrs: {
+      level: 6
+    }
+  }]
+}], ['blockquote', {
+  content: 'paragraph+',
+  group: 'block',
+  defining: true,
+  selectable: false,
+  parseDOM: [{
+    tag: 'blockquote'
+  }]
+}], ['rule', {
+  group: 'block',
+  parseDOM: [{
+    tag: 'hr'
+  }]
+}], ['panel', {
+  group: 'block',
+  content: '(paragraph | heading | bulletList | orderedList)+',
+  attrs: {
+    panelType: {
+      default: 'info'
+    }
+  },
+  parseDOM: [{
+    tag: 'div[data-panel-type]'
+  }]
+}], ['confluenceUnsupportedBlock', {
+  group: 'block',
+  attrs: {
+    cxhtml: {
+      default: null
+    }
+  },
+  parseDOM: [{
+    tag: 'div[data-node-type="confluenceUnsupportedBlock"]'
+  }]
+}], ['confluenceUnsupportedInline', {
+  group: 'inline',
+  inline: true,
+  atom: true,
+  attrs: {
+    cxhtml: {
+      default: null
+    }
+  },
+  parseDOM: [{
+    tag: 'div[data-node-type="confluenceUnsupportedInline"]'
+  }]
+}], ['unsupportedBlock', {
+  inline: false,
+  group: 'block',
+  atom: true,
+  selectable: true,
+  attrs: {
+    originalValue: {
+      default: {}
+    }
+  },
+  parseDOM: [{
+    tag: '[data-node-type="unsupportedBlock"]'
+  }]
+}], ['unsupportedInline', {
+  inline: true,
+  group: 'inline',
+  selectable: true,
+  attrs: {
+    originalValue: {
+      default: {}
+    }
+  },
+  parseDOM: [{
+    tag: '[data-node-type="unsupportedInline"]'
+  }]
+}], ['hardBreak', {
+  inline: true,
+  group: 'inline',
+  selectable: false,
+  parseDOM: [{
+    tag: 'br'
+  }]
+}], ['table', {
+  content: 'tableRow+',
+  attrs: {
+    isNumberColumnEnabled: {
+      default: false
+    },
+    layout: {
+      default: 'default'
+    },
+    __autoSize: {
+      default: false
+    }
+  },
+  tableRole: 'table',
+  isolating: true,
+  selectable: false,
+  group: 'block',
+  parseDOM: [{
+    tag: 'table'
+  }]
+}], ['tableHeader', {
+  content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading )+',
+  attrs: {
+    colspan: {
+      default: 1
+    },
+    rowspan: {
+      default: 1
+    },
+    colwidth: {
+      default: null
+    },
+    background: {
+      default: null
+    }
+  },
+  tableRole: 'header_cell',
+  isolating: true,
+  marks: '',
+  parseDOM: [{
+    tag: 'th'
+  }]
+}], ['tableRow', {
+  content: '(tableCell | tableHeader)+',
+  tableRole: 'row',
+  parseDOM: [{
+    tag: 'tr'
+  }]
+}], ['tableCell', {
+  content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | unsupportedBlock)+',
+  attrs: {
+    colspan: {
+      default: 1
+    },
+    rowspan: {
+      default: 1
+    },
+    colwidth: {
+      default: null
+    },
+    background: {
+      default: null
+    }
+  },
+  tableRole: 'cell',
+  marks: '',
+  isolating: true,
+  parseDOM: [{
+    tag: '.ak-renderer-table-number-column',
+    ignore: true
+  }, {
+    tag: 'td'
+  }]
+}]];
+exports.nodes = nodes;
+var marks = [['link', {
+  excludes: 'color',
+  group: 'link',
+  attrs: {
+    href: {},
+    __confluenceMetadata: {
+      default: null
+    }
+  },
+  inclusive: false,
+  parseDOM: [{
+    tag: 'a[href]'
+  }]
+}], ['em', {
+  inclusive: true,
+  group: 'fontStyle',
+  parseDOM: [{
+    tag: 'i'
+  }, {
+    tag: 'em'
+  }, {
+    style: 'font-style=italic'
+  }]
+}], ['strong', {
+  inclusive: true,
+  group: 'fontStyle',
+  parseDOM: [{
+    tag: 'strong'
+  }, {
+    tag: 'b'
+  }, {
+    style: 'font-weight'
+  }]
+}], ['textColor', {
+  attrs: {
+    color: {}
+  },
+  inclusive: true,
+  group: 'color',
+  parseDOM: [{
+    style: 'color'
+  }]
+}], ['strike', {
+  inclusive: true,
+  group: 'fontStyle',
+  parseDOM: [{
+    tag: 'strike'
+  }, {
+    tag: 's'
+  }, {
+    tag: 'del'
+  }, {
+    style: 'text-decoration'
+  }]
+}], ['subsup', {
+  inclusive: true,
+  group: 'fontStyle',
+  attrs: {
+    type: {
+      default: 'sub'
+    }
+  },
+  parseDOM: [{
+    tag: 'sub',
+    attrs: {
+      type: 'sub'
+    }
+  }, {
+    tag: 'sup',
+    attrs: {
+      type: 'sup'
+    }
+  }]
+}], ['underline', {
+  inclusive: true,
+  group: 'fontStyle',
+  parseDOM: [{
+    tag: 'u'
+  }, {
+    style: 'text-decoration'
+  }]
+}], ['code', {
+  excludes: 'fontStyle link searchQuery color',
+  inclusive: true,
+  parseDOM: [{
+    tag: 'span.code',
+    preserveWhitespace: true
+  }, {
+    tag: 'code',
+    preserveWhitespace: true
+  }, {
+    tag: 'tt',
+    preserveWhitespace: true
+  }, {
+    tag: 'span',
+    preserveWhitespace: true
+  }]
+}], ['typeAheadQuery', {
+  excludes: 'searchQuery',
+  inclusive: true,
+  group: 'searchQuery',
+  parseDOM: [{
+    tag: 'span[data-type-ahead-query]'
+  }],
+  attrs: {
+    trigger: {
+      default: ''
+    }
   }
-  return arrayMap(result, function(group) {
-    return apply(iteratee, undefined, group);
-  });
-}
+}]];
+exports.marks = marks;
 
-module.exports = unzipWith;
+var getDefaultSchema = function getDefaultSchema() {
+  return {
+    nodes: nodes,
+    marks: marks
+  };
+};
 
+exports.getDefaultSchema = getDefaultSchema;
 
 /***/ }),
-/* 691 */
+/* 689 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireWildcard = __webpack_require__(522);
+
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-Object.defineProperty(exports, "HasManyFiles", ({
-  enumerable: true,
-  get: function get() {
-    return _HasManyFiles.default;
-  }
-}));
-Object.defineProperty(exports, "HasMany", ({
-  enumerable: true,
-  get: function get() {
-    return _HasMany.default;
-  }
-}));
-Object.defineProperty(exports, "HasOne", ({
-  enumerable: true,
-  get: function get() {
-    return _HasOne.default;
-  }
-}));
-Object.defineProperty(exports, "HasOneInPlace", ({
-  enumerable: true,
-  get: function get() {
-    return _HasOneInPlace.default;
-  }
-}));
-Object.defineProperty(exports, "HasManyInPlace", ({
-  enumerable: true,
-  get: function get() {
-    return _HasManyInPlace.default;
-  }
-}));
-Object.defineProperty(exports, "HasManyTriggers", ({
-  enumerable: true,
-  get: function get() {
-    return _HasManyTriggers.default;
-  }
-}));
-Object.defineProperty(exports, "Association", ({
-  enumerable: true,
-  get: function get() {
-    return _Association.default;
-  }
-}));
-Object.defineProperty(exports, "resolveClass", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.resolveClass;
-  }
-}));
-Object.defineProperty(exports, "create", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.create;
-  }
-}));
-Object.defineProperty(exports, "isReferencedBy", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.isReferencedBy;
-  }
-}));
-Object.defineProperty(exports, "isReferencedById", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.isReferencedById;
-  }
-}));
-Object.defineProperty(exports, "getReferencedBy", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.getReferencedBy;
-  }
-}));
-Object.defineProperty(exports, "getReferencedById", ({
-  enumerable: true,
-  get: function get() {
-    return _helpers.getReferencedById;
-  }
-}));
-
-var _HasManyFiles = _interopRequireDefault(__webpack_require__(692));
-
-var _HasMany = _interopRequireDefault(__webpack_require__(741));
-
-var _HasOne = _interopRequireDefault(__webpack_require__(750));
-
-var _HasOneInPlace = _interopRequireDefault(__webpack_require__(752));
-
-var _HasManyInPlace = _interopRequireDefault(__webpack_require__(753));
-
-var _HasManyTriggers = _interopRequireDefault(__webpack_require__(754));
-
-var _Association = _interopRequireDefault(__webpack_require__(740));
+exports["default"] = exports.OAUTH_CLIENTS_DOCTYPE = void 0;
 
-var _helpers = __webpack_require__(755);
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-/***/ }),
-/* 692 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-"use strict";
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _interopRequireDefault = __webpack_require__(512);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _get2 = _interopRequireDefault(__webpack_require__(370));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _utils = __webpack_require__(623);
 
-var _get3 = _interopRequireDefault(__webpack_require__(670));
+var querystring = _interopRequireWildcard(__webpack_require__(659));
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+var _Collection = __webpack_require__(612);
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var _errors = __webpack_require__(663);
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+function _templateObject3() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]);
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+  _templateObject3 = function _templateObject3() {
+    return data;
+  };
 
-var _get4 = _interopRequireDefault(__webpack_require__(358));
+  return data;
+}
 
-var _omit = _interopRequireDefault(__webpack_require__(613));
+function _templateObject2() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]);
 
-var _uniq = _interopRequireDefault(__webpack_require__(612));
+  _templateObject2 = function _templateObject2() {
+    return data;
+  };
 
-var _dsl = __webpack_require__(607);
+  return data;
+}
 
-var _store = __webpack_require__(693);
+function _templateObject() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients"]);
 
-var _types = __webpack_require__(610);
+  _templateObject = function _templateObject() {
+    return data;
+  };
 
-var _const = __webpack_require__(685);
+  return data;
+}
 
-var _Association = _interopRequireDefault(__webpack_require__(740));
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-var _HasMany2 = _interopRequireDefault(__webpack_require__(741));
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
 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 _objectSpread(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) { (0, _defineProperty2.default)(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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
-
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var OAUTH_CLIENTS_DOCTYPE = 'io.cozy.oauth.clients';
+exports.OAUTH_CLIENTS_DOCTYPE = OAUTH_CLIENTS_DOCTYPE;
 
-/**
- * newCursor - Returns a CouchDB view Cursor for cursor-based pagination
- *
- * @param {ViewKey} key - The CouchDB key of the view which will be requested
- * @param {DocId} startDocId - The first doc _id to return from the view
- *
- * @returns {CouchDBViewCursor}
- */
-var newCursor = function newCursor(_ref, startDocId) {
-  var _ref2 = (0, _slicedToArray2.default)(_ref, 3),
-      doctype = _ref2[0],
-      id = _ref2[1],
-      lastDatetime = _ref2[2];
+var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(OAUTH_CLIENTS_DOCTYPE);
 
-  var cursorKey = lastDatetime ? [doctype, id, lastDatetime] : [doctype, id];
-  return [cursorKey, startDocId];
+var normalizeOAuthClient = function normalizeOAuthClient(client) {
+  return _objectSpread(_objectSpread({}, normalizeDoc(client, OAUTH_CLIENTS_DOCTYPE)), client.attributes);
 };
 /**
- *  This class is only used for photos albums relationships.
- *  Behind the hood, the queries uses a view returning the files sorted
- *  by datetime, with a cursor-based pagination.
+ * Implements `DocumentCollection` API to interact with the /settings/clients endpoint of the stack
  */
 
 
-var HasManyFiles = /*#__PURE__*/function (_HasMany) {
-  (0, _inherits2.default)(HasManyFiles, _HasMany);
+var OAuthClientsCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(OAuthClientsCollection, _DocumentCollection);
 
-  var _super = _createSuper(HasManyFiles);
+  var _super = _createSuper(OAuthClientsCollection);
 
-  function HasManyFiles() {
-    (0, _classCallCheck2.default)(this, HasManyFiles);
-    return _super.apply(this, arguments);
+  function OAuthClientsCollection(stackClient) {
+    (0, _classCallCheck2.default)(this, OAuthClientsCollection);
+    return _super.call(this, OAUTH_CLIENTS_DOCTYPE, stackClient);
   }
+  /**
+   * Fetches all OAuth clients
+   *
+   * @param  {object}         options             Query options
+   * @param  {number}         [options.limit]     For pagination, the number of results to return.
+   * @param  {string}         [options.bookmark]  For bookmark-based pagination, the document _id to start from
+   * @param  {Array<string>}  [options.keys]      Ids of specific clients to return (within the current page),
+   *
+   * @returns {object} The JSON API conformant response.
+   */
 
-  (0, _createClass2.default)(HasManyFiles, [{
-    key: "fetchMore",
+
+  (0, _createClass2.default)(OAuthClientsCollection, [{
+    key: "all",
     value: function () {
-      var _fetchMore = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-        var _this = this;
+      var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var options,
+            _options$limit,
+            limit,
+            bookmark,
+            keys,
+            params,
+            url,
+            path,
+            resp,
+            nextLink,
+            nextLinkURL,
+            nextBookmark,
+            hasBookmark,
+            data,
+            meta,
+            _args = arguments;
 
-        var queryDef, relationships, lastRelationship;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
+        return _regenerator.default.wrap(function _callee$(_context) {
           while (1) {
-            switch (_context2.prev = _context2.next) {
+            switch (_context.prev = _context.next) {
               case 0:
-                queryDef = new _dsl.QueryDefinition({
-                  doctype: _const.DOCTYPE_FILES
-                });
-                relationships = this.getRelationship().data; // Get last datetime for cursor
+                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
+                _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, bookmark = options.bookmark, keys = options.keys;
+                params = {
+                  'page[limit]': limit,
+                  'page[cursor]': bookmark
+                };
+                url = (0, _utils.uri)(_templateObject());
+                path = querystring.buildURL(url, params);
+                _context.prev = 5;
+                _context.next = 8;
+                return this.stackClient.fetchJSON('GET', path);
 
-                lastRelationship = relationships[relationships.length - 1];
-                _context2.next = 5;
-                return this.dispatch( /*#__PURE__*/function () {
-                  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(dispatch, getState) {
-                    var lastRelDoc, lastDatetime, cursor, response;
-                    return _regenerator.default.wrap(function _callee$(_context) {
-                      while (1) {
-                        switch (_context.prev = _context.next) {
-                          case 0:
-                            lastRelDoc = (0, _store.getDocumentFromState)(getState(), lastRelationship._type, lastRelationship._id); // Photos always have a datetime field in metadata
+              case 8:
+                resp = _context.sent;
+                _context.next = 14;
+                break;
 
-                            lastDatetime = lastRelDoc.attributes.metadata.datetime; // cursor-based pagination
+              case 11:
+                _context.prev = 11;
+                _context.t0 = _context["catch"](5);
+                return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0));
 
-                            cursor = newCursor([_this.target._type, _this.target._id, lastDatetime], relationships[relationships.length - 1]._id);
-                            _context.next = 5;
-                            return _this.query(queryDef.referencedBy(_this.target).offsetCursor(cursor));
+              case 14:
+                nextLink = (0, _get2.default)(resp, 'links.next', '');
+                nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink));
+                nextBookmark = nextLinkURL.searchParams.get('page[cursor]') || undefined;
+                hasBookmark = nextBookmark !== undefined;
 
-                          case 5:
-                            response = _context.sent;
-                            // Remove first returned element, used as starting point for the query
-                            response.data.shift();
-                            _context.next = 9;
-                            return _this.dispatch(_this.updateRelationshipData(function (previousRelationshipData) {
-                              return _objectSpread(_objectSpread({}, previousRelationshipData), {}, {
-                                data: [].concat((0, _toConsumableArray2.default)(previousRelationshipData.data), (0, _toConsumableArray2.default)(response.data)),
-                                next: response.next
-                              });
-                            }));
+                if (!keys) {
+                  _context.next = 24;
+                  break;
+                }
 
-                          case 9:
-                          case "end":
-                            return _context.stop();
-                        }
-                      }
-                    }, _callee);
-                  }));
+                data = resp.data.filter(function (c) {
+                  return keys.includes(c.id);
+                }).map(function (c) {
+                  return normalizeOAuthClient(c);
+                });
+                meta = _objectSpread(_objectSpread({}, resp.meta), {}, {
+                  count: data.length
+                });
+                return _context.abrupt("return", {
+                  data: data,
+                  meta: meta,
+                  next: keys.length > data.length && hasBookmark,
+                  bookmark: nextBookmark
+                });
 
-                  return function (_x, _x2) {
-                    return _ref3.apply(this, arguments);
-                  };
-                }());
+              case 24:
+                return _context.abrupt("return", {
+                  data: resp.data.map(function (c) {
+                    return normalizeOAuthClient(c);
+                  }),
+                  meta: resp.meta,
+                  next: hasBookmark,
+                  bookmark: nextBookmark
+                });
 
-              case 5:
+              case 25:
               case "end":
-                return _context2.stop();
+                return _context.stop();
             }
           }
-        }, _callee2, this);
+        }, _callee, this, [[5, 11]]);
       }));
 
-      function fetchMore() {
-        return _fetchMore.apply(this, arguments);
+      function all() {
+        return _all.apply(this, arguments);
       }
 
-      return fetchMore;
+      return all;
     }()
+    /**
+     * Get an OAuth client by id
+     *
+     * @param  {string} id The client id.
+     * @returns {object}  JsonAPI response containing normalized client as data attribute
+     */
+
   }, {
-    key: "addById",
+    key: "get",
     value: function () {
-      var _addById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(idsArg) {
-        var _this2 = this;
-
-        var ids, relations;
-        return _regenerator.default.wrap(function _callee3$(_context3) {
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
+        var resp;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
-            switch (_context3.prev = _context3.next) {
+            switch (_context2.prev = _context2.next) {
               case 0:
-                ids = Array.isArray(idsArg) ? idsArg : [idsArg];
-                relations = ids.map(function (id) {
-                  return {
-                    _id: id,
-                    _type: _this2.doctype
-                  };
+                _context2.next = 2;
+                return this.all({
+                  keys: [id]
                 });
-                _context3.next = 4;
-                return this.mutate(this.addReferences(relations));
 
-              case 4:
-                this.addTargetRelationships(ids);
+              case 2:
+                resp = _context2.sent;
 
-              case 5:
+              case 3:
+                if (!resp.next) {
+                  _context2.next = 9;
+                  break;
+                }
+
+                _context2.next = 6;
+                return this.all({
+                  keys: [id],
+                  bookmark: resp.bookmark
+                });
+
+              case 6:
+                resp = _context2.sent;
+                _context2.next = 3;
+                break;
+
+              case 9:
+                if (!resp.data.length) {
+                  _context2.next = 13;
+                  break;
+                }
+
+                return _context2.abrupt("return", {
+                  data: normalizeOAuthClient(resp.data[0])
+                });
+
+              case 13:
+                resp.url = (0, _utils.uri)(_templateObject2(), id);
+                resp.status = '404';
+                throw new _errors.FetchError(resp, 'Not Found');
+
+              case 16:
               case "end":
-                return _context3.stop();
+                return _context2.stop();
             }
           }
-        }, _callee3, this);
+        }, _callee2, this);
       }));
 
-      function addById(_x3) {
-        return _addById.apply(this, arguments);
+      function get(_x) {
+        return _get.apply(this, arguments);
       }
 
-      return addById;
+      return get;
     }()
+    /**
+     * Destroys the OAuth client on the server
+     *
+     * @param {object} oauthClient The io.cozy.oauth.clients document to destroy
+     *
+     * @returns {{ data }} The deleted client
+     */
+
   }, {
-    key: "removeById",
+    key: "destroy",
     value: function () {
-      var _removeById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(idsArg) {
-        var _this3 = this;
+      var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(oauthClient) {
+        var _id;
 
-        var ids, references;
-        return _regenerator.default.wrap(function _callee4$(_context4) {
+        return _regenerator.default.wrap(function _callee3$(_context3) {
           while (1) {
-            switch (_context4.prev = _context4.next) {
+            switch (_context3.prev = _context3.next) {
               case 0:
-                ids = Array.isArray(idsArg) ? idsArg : [idsArg];
-                references = ids.map(function (id) {
-                  return {
-                    _id: id,
-                    _type: _this3.doctype
-                  };
+                _id = oauthClient._id;
+                _context3.next = 3;
+                return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), _id));
+
+              case 3:
+                return _context3.abrupt("return", {
+                  data: _objectSpread(_objectSpread({}, normalizeOAuthClient(oauthClient)), {}, {
+                    _deleted: true
+                  })
                 });
-                _context4.next = 4;
-                return this.mutate(this.removeReferences(references));
 
               case 4:
-                this.removeTargetRelationships(ids);
-
-              case 5:
               case "end":
-                return _context4.stop();
+                return _context3.stop();
             }
           }
-        }, _callee4, this);
+        }, _callee3, this);
       }));
 
-      function removeById(_x4) {
-        return _removeById.apply(this, arguments);
+      function destroy(_x2) {
+        return _destroy.apply(this, arguments);
       }
 
-      return removeById;
+      return destroy;
     }()
-  }, {
-    key: "addReferences",
-    value: function addReferences(referencedDocs) {
-      if (this.target._type === _const.DOCTYPE_FILES) {
-        return _dsl.Mutations.addReferencedBy(this.target, referencedDocs);
-      } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) {
-        return _dsl.Mutations.addReferencesTo(this.target, referencedDocs);
-      } else {
-        throw new Error('Either the document or the references should be io.cozy.files');
-      }
-    }
-  }, {
-    key: "removeReferences",
-    value: function removeReferences(referencedDocs) {
-      if (this.target._type === _const.DOCTYPE_FILES) {
-        return _dsl.Mutations.removeReferencedBy(this.target, referencedDocs);
-      } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) {
-        return _dsl.Mutations.removeReferencesTo(this.target, referencedDocs);
-      } else {
-        throw new Error('Either the document or the references should be io.cozy.files');
-      }
-    }
-  }, {
-    key: "dehydrate",
-    value: function dehydrate(doc) {
-      // HasManyFiles relationships are stored on the file doctype, not the document the files are related to
-      return (0, _omit.default)(doc, [this.name, "relationships.".concat(this.name)]);
-    }
-    /**
-     * @param {CozyClientDocument} document - Document to query
-     * @param {object} client - The CozyClient instance
-     * @param {Association} assoc - The query params
-     *
-     * @returns {CozyClientDocument | QueryDefinition}
-     */
-
-  }, {
-    key: "data",
-    get: function get() {
-      var _this4 = this;
-
-      if (this.target._type === _const.DOCTYPE_FILES) {
-        var refs = (0, _get4.default)(this.target, 'referenced_by', []);
-        return refs.map(function (_ref4) {
-          var id = _ref4.id,
-              type = _ref4.type;
-          return _this4.get(type, id);
-        }).filter(Boolean);
-      } else {
-        return (0, _get3.default)((0, _getPrototypeOf2.default)(HasManyFiles.prototype), "data", this);
-      }
-    }
-  }], [{
-    key: "query",
-    value: function query(document, client, assoc) {
-      if (document._type === _const.DOCTYPE_FILES) {
-        var refs = (0, _get4.default)(document, "relationships.referenced_by.data", []);
-        var ids = (0, _uniq.default)(refs.filter(function (ref) {
-          return ref.type === assoc.doctype;
-        }).map(function (ref) {
-          return ref.id;
-        }));
-        return ids.length > 0 ? (0, _dsl.Q)(assoc.doctype).getByIds(ids) : null;
-      } else {
-        var cursor = newCursor([document._type, document._id], '');
-        return (0, _dsl.Q)(assoc.doctype).referencedBy(document).offsetCursor(cursor);
-      }
-    }
   }]);
-  return HasManyFiles;
-}(_HasMany2.default);
+  return OAuthClientsCollection;
+}(_DocumentCollection2.default);
 
-exports["default"] = HasManyFiles;
+OAuthClientsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+var _default = OAuthClientsCollection;
+exports["default"] = _default;
 
 /***/ }),
-/* 693 */
+/* 690 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireWildcard = __webpack_require__(510);
-
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-Object.defineProperty(exports, "initQuery", ({
-  enumerable: true,
-  get: function get() {
-    return _queries.initQuery;
-  }
-}));
-Object.defineProperty(exports, "loadQuery", ({
-  enumerable: true,
-  get: function get() {
-    return _queries.loadQuery;
-  }
-}));
-Object.defineProperty(exports, "receiveQueryResult", ({
-  enumerable: true,
-  get: function get() {
-    return _queries.receiveQueryResult;
-  }
-}));
-Object.defineProperty(exports, "receiveQueryError", ({
-  enumerable: true,
-  get: function get() {
-    return _queries.receiveQueryError;
-  }
-}));
-Object.defineProperty(exports, "initMutation", ({
-  enumerable: true,
-  get: function get() {
-    return _mutations.initMutation;
-  }
-}));
-Object.defineProperty(exports, "receiveMutationResult", ({
-  enumerable: true,
-  get: function get() {
-    return _mutations.receiveMutationResult;
-  }
-}));
-Object.defineProperty(exports, "receiveMutationError", ({
-  enumerable: true,
-  get: function get() {
-    return _mutations.receiveMutationError;
-  }
-}));
-exports.resetState = exports.getRawQueryFromState = exports.getQueryFromState = exports.getQueryFromStore = exports.getDocumentFromState = exports.getCollectionFromState = exports.getStateRoot = exports.createStore = exports["default"] = exports.StoreProxy = void 0;
+exports["default"] = exports.SHORTCUTS_DOCTYPE = void 0;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _cozyFlags = _interopRequireDefault(__webpack_require__(603));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _redux = __webpack_require__(694);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _reduxThunk = _interopRequireDefault(__webpack_require__(697));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _documents = _interopRequireWildcard(__webpack_require__(698));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _queries = _interopRequireWildcard(__webpack_require__(723));
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _mutations = __webpack_require__(738);
+var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613));
 
-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; }
+var _utils = __webpack_require__(623);
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+var _getIllegalCharacter = __webpack_require__(678);
 
-var RESET_ACTION_TYPE = 'COZY_CLIENT.RESET_STATE';
+function _templateObject2() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts/", ""]);
 
-var resetState = function resetState() {
-  return {
-    type: RESET_ACTION_TYPE
+  _templateObject2 = function _templateObject2() {
+    return data;
   };
-};
 
-exports.resetState = resetState;
+  return data;
+}
 
-var StoreProxy = /*#__PURE__*/function () {
-  function StoreProxy(state) {
-    (0, _classCallCheck2.default)(this, StoreProxy);
-    this.state = state;
-  }
+function _templateObject() {
+  var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts"]);
 
-  (0, _createClass2.default)(StoreProxy, [{
-    key: "readDocument",
-    value: function readDocument(doctype, id) {
-      return this.state.documents[doctype][id];
-    }
-  }, {
-    key: "writeDocument",
-    value: function writeDocument(document) {
-      this.setState(function (state) {
-        return _objectSpread(_objectSpread({}, state), {}, {
-          documents: _objectSpread(_objectSpread({}, state.documents), {}, (0, _defineProperty2.default)({}, document._type, _objectSpread(_objectSpread({}, state.documents[document._type]), {}, (0, _defineProperty2.default)({}, document._id, document))))
-        });
-      });
-    }
-  }, {
-    key: "setState",
-    value: function setState(updaterFn) {
-      this.state = updaterFn(this.state);
-    }
-  }, {
-    key: "getState",
-    value: function getState() {
-      return this.state;
-    }
-  }]);
-  return StoreProxy;
-}();
+  _templateObject = function _templateObject() {
+    return data;
+  };
 
-exports.StoreProxy = StoreProxy;
-var initialState = {
-  documents: {},
-  queries: {}
-};
+  return data;
+}
 
-var combinedReducer = function combinedReducer() {
-  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
-  var action = arguments.length > 1 ? arguments[1] : undefined;
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-  if (action.type == RESET_ACTION_TYPE) {
-    return initialState;
-  }
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-  if (!(0, _queries.isQueryAction)(action) && !(0, _mutations.isMutationAction)(action)) {
-    return state;
-  }
+var SHORTCUTS_DOCTYPE = 'io.cozy.files.shortcuts';
+exports.SHORTCUTS_DOCTYPE = SHORTCUTS_DOCTYPE;
 
-  if (action.update) {
-    var proxy = new StoreProxy(state);
-    action.update(proxy, action.response);
-    return {
-      documents: proxy.getState().documents,
-      queries: (0, _queries.default)(proxy.getState().queries, action, proxy.getState().documents)
-    };
+var ShortcutsCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(ShortcutsCollection, _DocumentCollection);
+
+  var _super = _createSuper(ShortcutsCollection);
+
+  function ShortcutsCollection(stackClient) {
+    (0, _classCallCheck2.default)(this, ShortcutsCollection);
+    return _super.call(this, SHORTCUTS_DOCTYPE, stackClient);
   }
+  /**
+   * Create a shortcut
+   *
+   * @param {object} attributes shortcut's attributes
+   * @param {string} attributes.name Filename
+   * @param {string} attributes.url Shortcut's URL
+   * @param {string} attributes.dir_id dir_id where to create the shortcut
+   * @throws {Error} - explaining reason why creation failed
+   */
 
-  var nextDocuments = (0, _documents.default)(state.documents, action);
-  var haveDocumentsChanged = nextDocuments !== state.documents;
-  return {
-    documents: nextDocuments,
-    queries: (0, _queries.default)(state.queries, action, nextDocuments, haveDocumentsChanged)
-  };
-};
 
-var _default = combinedReducer;
-exports["default"] = _default;
+  (0, _createClass2.default)(ShortcutsCollection, [{
+    key: "create",
+    value: function () {
+      var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(attributes) {
+        var name, illegalCharacters, path, resp;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                if (!attributes.type) {
+                  attributes.type = SHORTCUTS_DOCTYPE;
+                }
 
-var composedEnhancer = // @ts-ignore '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__' doesn't exist 'Window & typeof globalThis'.ts(2339)
-// should be (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ in ts file
-// see https://github.com/reduxjs/redux-devtools/tree/main/extension#11-basic-store
-(0, _cozyFlags.default)('debug') && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose;
+                if (!(!attributes.name || !attributes.name.trim() || !attributes.url || !attributes.dir_id)) {
+                  _context.next = 3;
+                  break;
+                }
 
-var createStore = function createStore() {
-  return (0, _redux.createStore)((0, _redux.combineReducers)({
-    cozy: combinedReducer
-  }), composedEnhancer((0, _redux.applyMiddleware)(_reduxThunk.default)));
-};
+                throw new Error('you need at least a name, an url and a dir_id attributes to create a shortcut');
 
-exports.createStore = createStore;
+              case 3:
+                name = attributes.name.trim();
 
-var getStateRoot = function getStateRoot(state) {
-  return state.cozy || {};
-};
+                if (!(name === '.' || name === '..')) {
+                  _context.next = 6;
+                  break;
+                }
 
-exports.getStateRoot = getStateRoot;
+                throw new Error("Invalid filename: ".concat(name));
 
-var getCollectionFromState = function getCollectionFromState(state, doctype) {
-  return (0, _documents.getCollectionFromSlice)(getStateRoot(state).documents, doctype);
-};
+              case 6:
+                illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(name);
 
-exports.getCollectionFromState = getCollectionFromState;
+                if (!illegalCharacters.length) {
+                  _context.next = 9;
+                  break;
+                }
 
-var getDocumentFromState = function getDocumentFromState(state, doctype, id) {
-  return (0, _documents.getDocumentFromSlice)(getStateRoot(state).documents, doctype, id);
-};
+                throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters));
 
-exports.getDocumentFromState = getDocumentFromState;
+              case 9:
+                path = (0, _utils.uri)(_templateObject());
+                _context.next = 12;
+                return this.stackClient.fetchJSON('POST', path, {
+                  data: {
+                    attributes: attributes,
+                    type: 'io.cozy.files.shortcuts'
+                  }
+                });
 
-var getQueryFromStore = function getQueryFromStore(store, queryId) {
-  return getQueryFromState(store.getState(), queryId);
-};
+              case 12:
+                resp = _context.sent;
+                return _context.abrupt("return", {
+                  data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp)
+                });
 
-exports.getQueryFromStore = getQueryFromStore;
+              case 14:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
 
-var getQueryFromState = function getQueryFromState(state, queryId) {
-  return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId, getStateRoot(state).documents);
-};
+      function create(_x) {
+        return _create.apply(this, arguments);
+      }
 
-exports.getQueryFromState = getQueryFromState;
+      return create;
+    }()
+  }, {
+    key: "get",
+    value: function () {
+      var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
+        var path, resp;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                path = (0, _utils.uri)(_templateObject2(), id);
+                _context2.next = 3;
+                return this.stackClient.fetchJSON('GET', path);
 
-var getRawQueryFromState = function getRawQueryFromState(state, queryId) {
-  return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId);
-};
+              case 3:
+                resp = _context2.sent;
+                return _context2.abrupt("return", {
+                  data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp)
+                });
 
-exports.getRawQueryFromState = getRawQueryFromState;
+              case 5:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
+
+      function get(_x2) {
+        return _get.apply(this, arguments);
+      }
+
+      return get;
+    }()
+  }]);
+  return ShortcutsCollection;
+}(_DocumentCollection2.default);
+
+ShortcutsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi;
+var _default = ShortcutsCollection;
+exports["default"] = _default;
 
 /***/ }),
-/* 694 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+/* 691 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "__DO_NOT_USE__ActionTypes": () => (/* binding */ ActionTypes),
-/* harmony export */   "applyMiddleware": () => (/* binding */ applyMiddleware),
-/* harmony export */   "bindActionCreators": () => (/* binding */ bindActionCreators),
-/* harmony export */   "combineReducers": () => (/* binding */ combineReducers),
-/* harmony export */   "compose": () => (/* binding */ compose),
-/* harmony export */   "createStore": () => (/* binding */ createStore)
-/* harmony export */ });
-/* harmony import */ var _babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(695);
 
 
-/**
- * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js
- *
- * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes
- * during build.
- * @param {number} code
- */
-function formatProdErrorMessage(code) {
-  return "Minified Redux error #" + code + "; visit https://redux.js.org/Errors?code=" + code + " for the full message or " + 'use the non-minified dev environment for full errors. ';
-}
+var _interopRequireWildcard = __webpack_require__(522);
 
-// Inlined version of the `symbol-observable` polyfill
-var $$observable = (function () {
-  return typeof Symbol === 'function' && Symbol.observable || '@@observable';
-})();
+var _interopRequireDefault = __webpack_require__(524);
 
-/**
- * These are private action types reserved by Redux.
- * For any unknown actions, you must return the current state.
- * If the current state is undefined, you must return the initial state.
- * Do not reference these action types directly in your code.
- */
-var randomString = function randomString() {
-  return Math.random().toString(36).substring(7).split('').join('.');
-};
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = exports.CONTACTS_DOCTYPE = void 0;
 
-var ActionTypes = {
-  INIT: "@@redux/INIT" + randomString(),
-  REPLACE: "@@redux/REPLACE" + randomString(),
-  PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {
-    return "@@redux/PROBE_UNKNOWN_ACTION" + randomString();
-  }
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
+
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
+
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
+
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
+
+var _get2 = _interopRequireDefault(__webpack_require__(682));
+
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
+
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
+
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
+
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
+
+var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613));
+
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+
+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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
+
+var normalizeMyselfResp = function normalizeMyselfResp(resp) {
+  return _objectSpread(_objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(resp.data, CONTACTS_DOCTYPE)), resp.data.attributes), {}, {
+    _rev: resp.data.meta.rev
+  });
 };
 
-/**
- * @param {any} obj The object to inspect.
- * @returns {boolean} True if the argument appears to be a plain object.
- */
-function isPlainObject(obj) {
-  if (typeof obj !== 'object' || obj === null) return false;
-  var proto = obj;
+var ContactsCollection = /*#__PURE__*/function (_DocumentCollection) {
+  (0, _inherits2.default)(ContactsCollection, _DocumentCollection);
 
-  while (Object.getPrototypeOf(proto) !== null) {
-    proto = Object.getPrototypeOf(proto);
+  var _super = _createSuper(ContactsCollection);
+
+  function ContactsCollection() {
+    (0, _classCallCheck2.default)(this, ContactsCollection);
+    return _super.apply(this, arguments);
   }
 
-  return Object.getPrototypeOf(obj) === proto;
-}
+  (0, _createClass2.default)(ContactsCollection, [{
+    key: "find",
+    value: function () {
+      var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) {
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                if (!(Object.values(selector).length === 1 && selector['me'] == true)) {
+                  _context.next = 4;
+                  break;
+                }
+
+                return _context.abrupt("return", this.findMyself());
+
+              case 4:
+                return _context.abrupt("return", (0, _get2.default)((0, _getPrototypeOf2.default)(ContactsCollection.prototype), "find", this).call(this, selector, options));
+
+              case 5:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
+
+      function find(_x, _x2) {
+        return _find.apply(this, arguments);
+      }
+
+      return find;
+    }()
+  }, {
+    key: "findMyself",
+    value: function () {
+      var _findMyself = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+        var resp, col;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                _context2.next = 2;
+                return this.stackClient.fetchJSON('POST', '/contacts/myself');
+
+              case 2:
+                resp = _context2.sent;
+                col = {
+                  data: [normalizeMyselfResp(resp)],
+                  next: false,
+                  meta: null,
+                  bookmark: false
+                };
+                return _context2.abrupt("return", col);
+
+              case 5:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
+
+      function findMyself() {
+        return _findMyself.apply(this, arguments);
+      }
+
+      return findMyself;
+    }()
+  }]);
+  return ContactsCollection;
+}(_DocumentCollection2.default);
 
-// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of
-function miniKindOf(val) {
-  if (val === void 0) return 'undefined';
-  if (val === null) return 'null';
-  var type = typeof val;
+var CONTACTS_DOCTYPE = 'io.cozy.contacts';
+exports.CONTACTS_DOCTYPE = CONTACTS_DOCTYPE;
+var _default = ContactsCollection;
+exports["default"] = _default;
 
-  switch (type) {
-    case 'boolean':
-    case 'string':
-    case 'number':
-    case 'symbol':
-    case 'function':
-      {
-        return type;
-      }
-  }
+/***/ }),
+/* 692 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  if (Array.isArray(val)) return 'array';
-  if (isDate(val)) return 'date';
-  if (isError(val)) return 'error';
-  var constructorName = ctorName(val);
+"use strict";
 
-  switch (constructorName) {
-    case 'Symbol':
-    case 'Promise':
-    case 'WeakMap':
-    case 'WeakSet':
-    case 'Map':
-    case 'Set':
-      return constructorName;
-  } // other
 
+var _interopRequireWildcard = __webpack_require__(522);
 
-  return type.slice(8, -1).toLowerCase().replace(/\s/g, '');
-}
+var _interopRequireDefault = __webpack_require__(524);
 
-function ctorName(val) {
-  return typeof val.constructor === 'function' ? val.constructor.name : null;
-}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getIconURL = exports["default"] = exports._getIconURL = void 0;
 
-function isError(val) {
-  return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';
-}
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-function isDate(val) {
-  if (val instanceof Date) return true;
-  return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';
-}
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-function kindOf(val) {
-  var typeOfVal = typeof val;
+var _memoize = _interopRequireWildcard(__webpack_require__(693));
 
-  if (process.env.NODE_ENV !== 'production') {
-    typeOfVal = miniKindOf(val);
-  }
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
-  return typeOfVal;
-}
+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; }
 
 /**
- * Creates a Redux store that holds the state tree.
- * The only way to change the data in the store is to call `dispatch()` on it.
- *
- * There should only be a single store in your app. To specify how different
- * parts of the state tree respond to actions, you may combine several reducers
- * into a single reducer function by using `combineReducers`.
- *
- * @param {Function} reducer A function that returns the next state tree, given
- * the current state tree and the action to handle.
- *
- * @param {any} [preloadedState] The initial state. You may optionally specify it
- * to hydrate the state from the server in universal apps, or to restore a
- * previously serialized user session.
- * If you use `combineReducers` to produce the root reducer function, this must be
- * an object with the same shape as `combineReducers` keys.
- *
- * @param {Function} [enhancer] The store enhancer. You may optionally specify it
- * to enhance the store with third-party capabilities such as middleware,
- * time travel, persistence, etc. The only store enhancer that ships with Redux
- * is `applyMiddleware()`.
+ * Get Icon source Url
  *
- * @returns {Store} A Redux store that lets you read the state, dispatch actions
- * and subscribe to changes.
+ * @param  {object}  app - Apps data - io.cozy.apps
+ * @param  {string}  slug - Slug - string
+ * @param  {string|undefined} domain - Host to use in the origin (e.g. cozy.tools)
+ * @param  {string} protocol - Url protocol (e.g. http / https)
+ * @returns {string}  Source Url of icon
+ * @private
+ * @throws {Error} When cannot fetch or get icon source
  */
+var loadIcon = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, slug, domain, protocol) {
+    var source;
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            if (domain) {
+              _context.next = 2;
+              break;
+            }
 
-function createStore(reducer, preloadedState, enhancer) {
-  var _ref2;
+            throw new Error('Cannot fetch icon: missing domain');
 
-  if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {
-    throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');
-  }
+          case 2:
+            source = _getAppIconURL(app, slug, domain, protocol);
 
-  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
-    enhancer = preloadedState;
-    preloadedState = undefined;
-  }
+            if (source) {
+              _context.next = 5;
+              break;
+            }
 
-  if (typeof enhancer !== 'undefined') {
-    if (typeof enhancer !== 'function') {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(1) : "Expected the enhancer to be a function. Instead, received: '" + kindOf(enhancer) + "'");
-    }
+            throw new Error("Cannot get icon source for app ".concat(app.name));
 
-    return enhancer(createStore)(reducer, preloadedState);
-  }
+          case 5:
+            return _context.abrupt("return", source);
 
-  if (typeof reducer !== 'function') {
-    throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : "Expected the root reducer to be a function. Instead, received: '" + kindOf(reducer) + "'");
-  }
+          case 6:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
 
-  var currentReducer = reducer;
-  var currentState = preloadedState;
-  var currentListeners = [];
-  var nextListeners = currentListeners;
-  var isDispatching = false;
-  /**
-   * This makes a shallow copy of currentListeners so we can use
-   * nextListeners as a temporary list while dispatching.
-   *
-   * This prevents any bugs around consumers calling
-   * subscribe/unsubscribe in the middle of a dispatch.
-   */
+  return function loadIcon(_x, _x2, _x3, _x4) {
+    return _ref.apply(this, arguments);
+  };
+}();
+/**
+ * Get App Icon URL
+ *
+ * @param  {object}  app - Apps data - io.cozy.apps or Slug - string
+ * @param  {string}  slug - Slug - string
+ * @param  {string|undefined} domain - Host to use in the origin (e.g. cozy.tools)
+ * @param  {string} protocol - Url protocol (e.g. http / https)
+ * @private
+ * @returns {string|null}  App Icon URL
+ */
 
-  function ensureCanMutateNextListeners() {
-    if (nextListeners === currentListeners) {
-      nextListeners = currentListeners.slice();
-    }
-  }
-  /**
-   * Reads the state tree managed by the store.
-   *
-   * @returns {any} The current state tree of your application.
-   */
 
+var _getAppIconURL = function _getAppIconURL(app, slug, domain, protocol) {
+  var path = app && app.links && app.links.icon || _getRegistryIconPath(app, slug);
 
-  function getState() {
-    if (isDispatching) {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');
-    }
+  return path ? "".concat(protocol, "//").concat(domain).concat(path) : null;
+};
+/**
+ * Get Registry Icon Path
+ *
+ * @param  {object}  app - Apps data - io.cozy.apps or Slug - string
+ * @param  {string}  slug - Slug - string
+ * @returns {string|undefined}  Registry icon path
+ * @private
+ */
 
-    return currentState;
-  }
-  /**
-   * Adds a change listener. It will be called any time an action is dispatched,
-   * and some part of the state tree may potentially have changed. You may then
-   * call `getState()` to read the current state tree inside the callback.
-   *
-   * You may call `dispatch()` from a change listener, with the following
-   * caveats:
-   *
-   * 1. The subscriptions are snapshotted just before every `dispatch()` call.
-   * If you subscribe or unsubscribe while the listeners are being invoked, this
-   * will not have any effect on the `dispatch()` that is currently in progress.
-   * However, the next `dispatch()` call, whether nested or not, will use a more
-   * recent snapshot of the subscription list.
-   *
-   * 2. The listener should not expect to see all state changes, as the state
-   * might have been updated multiple times during a nested `dispatch()` before
-   * the listener is called. It is, however, guaranteed that all subscribers
-   * registered before the `dispatch()` started will be called with the latest
-   * state by the time it exits.
-   *
-   * @param {Function} listener A callback to be invoked on every dispatch.
-   * @returns {Function} A function to remove this change listener.
-   */
 
+var _getRegistryIconPath = function _getRegistryIconPath(app, slug) {
+  if (slug) {
+    return "/registry/".concat(slug, "/icon");
+  }
 
-  function subscribe(listener) {
-    if (typeof listener !== 'function') {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(4) : "Expected the listener to be a function. Instead, received: '" + kindOf(listener) + "'");
-    }
+  return app && app.latest_version && app.latest_version.version && "/registry/".concat(app.slug, "/").concat(app.latest_version.version, "/icon");
+};
 
-    if (isDispatching) {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');
-    }
+var mimeTypes = {
+  gif: 'image/gif',
+  ico: 'image/vnd.microsoft.icon',
+  jpeg: 'image/jpeg',
+  jpg: 'image/jpeg',
+  png: 'image/png',
+  svg: 'image/svg+xml'
+};
+/**
+ * Get icon extension
+ *
+ * @param {object} app io.cozy.apps or io.cozy.konnectors document
+ * @param  {string} app.icon - App Icon
+ * @param  {string} app.name - App Name
+ * @returns {string}  icon extension
+ * @private
+ * @throws {Error} When problem while detecting icon mime type
+ */
 
-    var isSubscribed = true;
-    ensureCanMutateNextListeners();
-    nextListeners.push(listener);
-    return function unsubscribe() {
-      if (!isSubscribed) {
-        return;
-      }
+var getIconExtensionFromApp = function getIconExtensionFromApp(app) {
+  if (!app.icon) {
+    throw new Error("".concat(app.name, ": Cannot detect icon mime type since app has no icon"));
+  }
 
-      if (isDispatching) {
-        throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');
-      }
+  var extension = app.icon.split('.').pop();
 
-      isSubscribed = false;
-      ensureCanMutateNextListeners();
-      var index = nextListeners.indexOf(listener);
-      nextListeners.splice(index, 1);
-      currentListeners = null;
-    };
+  if (!extension) {
+    throw new Error("".concat(app.name, ": Unable to detect icon mime type from extension (").concat(app.icon, ")"));
   }
-  /**
-   * Dispatches an action. It is the only way to trigger a state change.
-   *
-   * The `reducer` function, used to create the store, will be called with the
-   * current state tree and the given `action`. Its return value will
-   * be considered the **next** state of the tree, and the change listeners
-   * will be notified.
-   *
-   * The base implementation only supports plain object actions. If you want to
-   * dispatch a Promise, an Observable, a thunk, or something else, you need to
-   * wrap your store creating function into the corresponding middleware. For
-   * example, see the documentation for the `redux-thunk` package. Even the
-   * middleware will eventually dispatch plain object actions using this method.
-   *
-   * @param {Object} action A plain object representing “what changed”. It is
-   * a good idea to keep actions serializable so you can record and replay user
-   * sessions, or use the time travelling `redux-devtools`. An action must have
-   * a `type` property which may not be `undefined`. It is a good idea to use
-   * string constants for action types.
-   *
-   * @returns {Object} For convenience, the same action object you dispatched.
-   *
-   * Note that, if you use a custom middleware, it may wrap `dispatch()` to
-   * return something else (for example, a Promise you can await).
-   */
 
+  return extension;
+};
 
-  function dispatch(action) {
-    if (!isPlainObject(action)) {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(7) : "Actions must be plain objects. Instead, the actual type was: '" + kindOf(action) + "'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.");
-    }
+var fallbacks = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(tries, check) {
+    var err, _iterator, _step, _try, res;
 
-    if (typeof action.type === 'undefined') {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(8) : 'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.');
-    }
+    return _regenerator.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            _iterator = _createForOfIteratorHelper(tries);
+            _context2.prev = 1;
 
-    if (isDispatching) {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');
-    }
+            _iterator.s();
 
-    try {
-      isDispatching = true;
-      currentState = currentReducer(currentState, action);
-    } finally {
-      isDispatching = false;
-    }
+          case 3:
+            if ((_step = _iterator.n()).done) {
+              _context2.next = 18;
+              break;
+            }
 
-    var listeners = currentListeners = nextListeners;
+            _try = _step.value;
+            _context2.prev = 5;
+            _context2.next = 8;
+            return _try();
 
-    for (var i = 0; i < listeners.length; i++) {
-      var listener = listeners[i];
-      listener();
-    }
+          case 8:
+            res = _context2.sent;
+            check && check(res);
+            return _context2.abrupt("return", res);
 
-    return action;
-  }
-  /**
-   * Replaces the reducer currently used by the store to calculate the state.
-   *
-   * You might need this if your app implements code splitting and you want to
-   * load some of the reducers dynamically. You might also need this if you
-   * implement a hot reloading mechanism for Redux.
-   *
-   * @param {Function} nextReducer The reducer for the store to use instead.
-   * @returns {void}
-   */
+          case 13:
+            _context2.prev = 13;
+            _context2.t0 = _context2["catch"](5);
+            err = _context2.t0;
 
+          case 16:
+            _context2.next = 3;
+            break;
 
-  function replaceReducer(nextReducer) {
-    if (typeof nextReducer !== 'function') {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(10) : "Expected the nextReducer to be a function. Instead, received: '" + kindOf(nextReducer));
-    }
+          case 18:
+            _context2.next = 23;
+            break;
 
-    currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.
-    // Any reducers that existed in both the new and old rootReducer
-    // will receive the previous state. This effectively populates
-    // the new state tree with any relevant data from the old one.
+          case 20:
+            _context2.prev = 20;
+            _context2.t1 = _context2["catch"](1);
 
-    dispatch({
-      type: ActionTypes.REPLACE
-    });
-  }
-  /**
-   * Interoperability point for observable/reactive libraries.
-   * @returns {observable} A minimal observable of state changes.
-   * For more information, see the observable proposal:
-   * https://github.com/tc39/proposal-observable
-   */
+            _iterator.e(_context2.t1);
 
+          case 23:
+            _context2.prev = 23;
 
-  function observable() {
-    var _ref;
+            _iterator.f();
 
-    var outerSubscribe = subscribe;
-    return _ref = {
-      /**
-       * The minimal observable subscription method.
-       * @param {Object} observer Any object that can be used as an observer.
-       * The observer object should have a `next` method.
-       * @returns {subscription} An object with an `unsubscribe` method that can
-       * be used to unsubscribe the observable from the store, and prevent further
-       * emission of values from the observable.
-       */
-      subscribe: function subscribe(observer) {
-        if (typeof observer !== 'object' || observer === null) {
-          throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(11) : "Expected the observer to be an object. Instead, received: '" + kindOf(observer) + "'");
-        }
+            return _context2.finish(23);
 
-        function observeState() {
-          if (observer.next) {
-            observer.next(getState());
-          }
-        }
+          case 26:
+            throw err;
 
-        observeState();
-        var unsubscribe = outerSubscribe(observeState);
-        return {
-          unsubscribe: unsubscribe
-        };
+          case 27:
+          case "end":
+            return _context2.stop();
+        }
       }
-    }, _ref[$$observable] = function () {
-      return this;
-    }, _ref;
-  } // When a store is created, an "INIT" action is dispatched so that every
-  // reducer returns their initial state. This effectively populates
-  // the initial state tree.
-
-
-  dispatch({
-    type: ActionTypes.INIT
-  });
-  return _ref2 = {
-    dispatch: dispatch,
-    subscribe: subscribe,
-    getState: getState,
-    replaceReducer: replaceReducer
-  }, _ref2[$$observable] = observable, _ref2;
-}
+    }, _callee2, null, [[1, 20, 23, 26], [5, 13]]);
+  }));
 
+  return function fallbacks(_x5, _x6) {
+    return _ref2.apply(this, arguments);
+  };
+}();
 /**
- * Prints a warning in the console if it exists.
+ * Fetch application/konnector that is installed
  *
- * @param {String} message The warning message.
- * @returns {void}
+ * @private
  */
-function warning(message) {
-  /* eslint-disable no-console */
-  if (typeof console !== 'undefined' && typeof console.error === 'function') {
-    console.error(message);
-  }
-  /* eslint-enable no-console */
-
-
-  try {
-    // This error was thrown as a convenience so that if you enable
-    // "break on all exceptions" in your console,
-    // it would pause the execution at this line.
-    throw new Error(message);
-  } catch (e) {} // eslint-disable-line no-empty
 
-}
-
-function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
-  var reducerKeys = Object.keys(reducers);
-  var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';
-
-  if (reducerKeys.length === 0) {
-    return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';
-  }
-
-  if (!isPlainObject(inputState)) {
-    return "The " + argumentName + " has unexpected type of \"" + kindOf(inputState) + "\". Expected argument to be an object with the following " + ("keys: \"" + reducerKeys.join('", "') + "\"");
-  }
 
-  var unexpectedKeys = Object.keys(inputState).filter(function (key) {
-    return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];
-  });
-  unexpectedKeys.forEach(function (key) {
-    unexpectedKeyCache[key] = true;
+var fetchAppOrKonnector = function fetchAppOrKonnector(stackClient, type, slug) {
+  return stackClient.fetchJSON('GET', "/".concat(type, "s/").concat(slug)).then(function (x) {
+    return x.data.attributes;
   });
-  if (action && action.type === ActionTypes.REPLACE) return;
-
-  if (unexpectedKeys.length > 0) {
-    return "Unexpected " + (unexpectedKeys.length > 1 ? 'keys' : 'key') + " " + ("\"" + unexpectedKeys.join('", "') + "\" found in " + argumentName + ". ") + "Expected to find one of the known reducer keys instead: " + ("\"" + reducerKeys.join('", "') + "\". Unexpected keys will be ignored.");
-  }
-}
-
-function assertReducerShape(reducers) {
-  Object.keys(reducers).forEach(function (key) {
-    var reducer = reducers[key];
-    var initialState = reducer(undefined, {
-      type: ActionTypes.INIT
-    });
+};
+/**
+ * Fetch application/konnector from the registry
+ *
+ * @private
+ */
 
-    if (typeof initialState === 'undefined') {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(12) : "The slice reducer for key \"" + key + "\" returned undefined during initialization. " + "If the state passed to the reducer is undefined, you must " + "explicitly return the initial state. The initial state may " + "not be undefined. If you don't want to set a value for this reducer, " + "you can use null instead of undefined.");
-    }
 
-    if (typeof reducer(undefined, {
-      type: ActionTypes.PROBE_UNKNOWN_ACTION()
-    }) === 'undefined') {
-      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(13) : "The slice reducer for key \"" + key + "\" returned undefined when probed with a random type. " + ("Don't try to handle '" + ActionTypes.INIT + "' or other actions in \"redux/*\" ") + "namespace. They are considered private. Instead, you must return the " + "current state for any unknown actions, unless it is undefined, " + "in which case you must return the initial state, regardless of the " + "action type. The initial state may not be undefined, but can be null.");
-    }
+var fetchAppOrKonnectorViaRegistry = function fetchAppOrKonnectorViaRegistry(stackClient, type, slug) {
+  return stackClient.fetchJSON('GET', "/registry/".concat(slug)).then(function (x) {
+    return x.latest_version.manifest;
   });
-}
+};
 /**
- * Turns an object whose values are different reducer functions, into a single
- * reducer function. It will call every child reducer, and gather their results
- * into a single state object, whose keys correspond to the keys of the passed
- * reducer functions.
- *
- * @param {Object} reducers An object whose values correspond to different
- * reducer functions that need to be combined into one. One handy way to obtain
- * it is to use ES6 `import * as reducers` syntax. The reducers may never return
- * undefined for any action. Instead, they should return their initial state
- * if the state passed to them was undefined, and the current state for any
- * unrecognized action.
+ * Get Icon URL using blob mechanism if OAuth connected
+ * or using preloaded url when blob not needed
  *
- * @returns {Function} A reducer function that invokes every reducer inside the
- * passed object, and builds a state object with the same shape.
+ * @param  {CozyStackClient}  stackClient - CozyStackClient
+ * @param  {object}  stackClient.oauthOptions - oauthOptions used to detect fetching mechanism
+ * @param  {object} opts - Options
+ * @param  {string} opts.type - Options type
+ * @param  {string|undefined} opts.slug - Options slug
+ * @param  {object|string|undefined}  opts.appData - Apps data - io.cozy.apps
+ * @param  {string} [opts.priority='stack'] - Options priority
+ * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob .
+ * @private
+ * @throws {Error} while fetching icon, or unknown image extension
  */
 
 
-function combineReducers(reducers) {
-  var reducerKeys = Object.keys(reducers);
-  var finalReducers = {};
+var _getIconURL = /*#__PURE__*/function () {
+  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(stackClient, opts) {
+    var type, slug, appData, _opts$priority, priority, iconDataFetchers, resp, icon, app, appDataFetchers, ext, _URL, domain, protocol;
 
-  for (var i = 0; i < reducerKeys.length; i++) {
-    var key = reducerKeys[i];
+    return _regenerator.default.wrap(function _callee3$(_context3) {
+      while (1) {
+        switch (_context3.prev = _context3.next) {
+          case 0:
+            type = opts.type, slug = opts.slug, appData = opts.appData, _opts$priority = opts.priority, priority = _opts$priority === void 0 ? 'stack' : _opts$priority;
 
-    if (process.env.NODE_ENV !== 'production') {
-      if (typeof reducers[key] === 'undefined') {
-        warning("No reducer provided for key \"" + key + "\"");
-      }
-    }
+            if (!stackClient.oauthOptions) {
+              _context3.next = 29;
+              break;
+            }
 
-    if (typeof reducers[key] === 'function') {
-      finalReducers[key] = reducers[key];
-    }
-  }
+            iconDataFetchers = [function () {
+              return stackClient.fetch('GET', "/".concat(type, "s/").concat(slug, "/icon"));
+            }, function () {
+              return stackClient.fetch('GET', "/registry/".concat(slug, "/icon"));
+            }];
 
-  var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same
-  // keys multiple times.
+            if (priority === 'registry') {
+              iconDataFetchers.reverse();
+            }
 
-  var unexpectedKeyCache;
+            _context3.next = 6;
+            return fallbacks(iconDataFetchers, function (resp) {
+              if (!resp.ok) {
+                throw new Error("Error while fetching icon ".concat(resp.statusText));
+              }
+            });
 
-  if (process.env.NODE_ENV !== 'production') {
-    unexpectedKeyCache = {};
-  }
+          case 6:
+            resp = _context3.sent;
+            _context3.next = 9;
+            return resp.blob();
 
-  var shapeAssertionError;
+          case 9:
+            icon = _context3.sent;
 
-  try {
-    assertReducerShape(finalReducers);
-  } catch (e) {
-    shapeAssertionError = e;
-  }
+            if (icon.type) {
+              _context3.next = 26;
+              break;
+            }
 
-  return function combination(state, action) {
-    if (state === void 0) {
-      state = {};
-    }
+            // iOS10 does not set correctly mime type for images, so we assume
+            // that an empty mime type could mean that the app is running on iOS10.
+            // For regular images like jpeg, png or gif it still works well in the
+            // Safari browser but not for SVG.
+            // So let's set a mime type manually. We cannot always set it to
+            // image/svg+xml and must guess the mime type based on the icon attribute
+            // from app/manifest
+            // See https://stackoverflow.com/questions/38318411/uiwebview-on-ios-10-beta-not-loading-any-svg-images
+            appDataFetchers = [function () {
+              return fetchAppOrKonnector(stackClient, type, slug);
+            }, function () {
+              return fetchAppOrKonnectorViaRegistry(stackClient, type, slug);
+            }];
 
-    if (shapeAssertionError) {
-      throw shapeAssertionError;
-    }
+            if (priority === 'registry') {
+              appDataFetchers.reverse();
+            }
 
-    if (process.env.NODE_ENV !== 'production') {
-      var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);
+            _context3.t1 = appData;
 
-      if (warningMessage) {
-        warning(warningMessage);
-      }
-    }
+            if (_context3.t1) {
+              _context3.next = 18;
+              break;
+            }
 
-    var hasChanged = false;
-    var nextState = {};
+            _context3.next = 17;
+            return fallbacks(appDataFetchers);
 
-    for (var _i = 0; _i < finalReducerKeys.length; _i++) {
-      var _key = finalReducerKeys[_i];
-      var reducer = finalReducers[_key];
-      var previousStateForKey = state[_key];
-      var nextStateForKey = reducer(previousStateForKey, action);
+          case 17:
+            _context3.t1 = _context3.sent;
 
-      if (typeof nextStateForKey === 'undefined') {
-        var actionType = action && action.type;
-        throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(14) : "When called with an action of type " + (actionType ? "\"" + String(actionType) + "\"" : '(unknown type)') + ", the slice reducer for key \"" + _key + "\" returned undefined. " + "To ignore an action, you must explicitly return the previous state. " + "If you want this reducer to hold no value, you can return null instead of undefined.");
-      }
+          case 18:
+            _context3.t0 = _context3.t1;
 
-      nextState[_key] = nextStateForKey;
-      hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
-    }
+            if (_context3.t0) {
+              _context3.next = 21;
+              break;
+            }
 
-    hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;
-    return hasChanged ? nextState : state;
-  };
-}
+            _context3.t0 = {};
 
-function bindActionCreator(actionCreator, dispatch) {
-  return function () {
-    return dispatch(actionCreator.apply(this, arguments));
-  };
-}
-/**
- * Turns an object whose values are action creators, into an object with the
- * same keys, but with every function wrapped into a `dispatch` call so they
- * may be invoked directly. This is just a convenience method, as you can call
- * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
- *
- * For convenience, you can also pass an action creator as the first argument,
- * and get a dispatch wrapped function in return.
- *
- * @param {Function|Object} actionCreators An object whose values are action
- * creator functions. One handy way to obtain it is to use ES6 `import * as`
- * syntax. You may also pass a single function.
- *
- * @param {Function} dispatch The `dispatch` function available on your Redux
- * store.
- *
- * @returns {Function|Object} The object mimicking the original object, but with
- * every action creator wrapped into the `dispatch` call. If you passed a
- * function as `actionCreators`, the return value will also be a single
- * function.
- */
+          case 21:
+            app = _context3.t0;
+            ext = getIconExtensionFromApp(app);
 
+            if (mimeTypes[ext]) {
+              _context3.next = 25;
+              break;
+            }
 
-function bindActionCreators(actionCreators, dispatch) {
-  if (typeof actionCreators === 'function') {
-    return bindActionCreator(actionCreators, dispatch);
-  }
+            throw new Error("Unknown image extension \"".concat(ext, "\" for app ").concat(app.name));
 
-  if (typeof actionCreators !== 'object' || actionCreators === null) {
-    throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(16) : "bindActionCreators expected an object or a function, but instead received: '" + kindOf(actionCreators) + "'. " + "Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?");
-  }
+          case 25:
+            icon = new Blob([icon], {
+              type: mimeTypes[ext]
+            });
 
-  var boundActionCreators = {};
+          case 26:
+            return _context3.abrupt("return", URL.createObjectURL(icon));
 
-  for (var key in actionCreators) {
-    var actionCreator = actionCreators[key];
+          case 29:
+            _context3.prev = 29;
+            _URL = new URL(stackClient.uri), domain = _URL.host, protocol = _URL.protocol;
+            return _context3.abrupt("return", loadIcon(appData, slug, domain, protocol));
 
-    if (typeof actionCreator === 'function') {
-      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
-    }
-  }
+          case 34:
+            _context3.prev = 34;
+            _context3.t2 = _context3["catch"](29);
+            throw new Error("Cannot fetch icon: invalid stackClient.uri: ".concat(_context3.t2.message));
 
-  return boundActionCreators;
-}
+          case 37:
+          case "end":
+            return _context3.stop();
+        }
+      }
+    }, _callee3, null, [[29, 34]]);
+  }));
 
+  return function _getIconURL(_x7, _x8) {
+    return _ref3.apply(this, arguments);
+  };
+}();
 /**
- * Composes single-argument functions from right to left. The rightmost
- * function can take multiple arguments as it provides the signature for
- * the resulting composite function.
+ * Get Icon URL using blob mechanism if OAuth connected
+ * or using preloaded url when blob not needed
  *
- * @param {...Function} funcs The functions to compose.
- * @returns {Function} A function obtained by composing the argument functions
- * from right to left. For example, compose(f, g, h) is identical to doing
- * (...args) => f(g(h(...args))).
+ * @param  {CozyStackClient}  stackClient - CozyStackClient
+ * @param  {object}  stackClient.oauthOptions - oauthOptions used to detect fetching mechanism
+ * @param  {object} opts - Options
+ * @param  {string} opts.type - Options type
+ * @param  {string|undefined} opts.slug - Options slug
+ * @param  {object|string|undefined}  opts.appData - Apps data - io.cozy.apps or Slug - string
+ * @param  {string} [opts.priority='stack'] - Options priority
+ * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob or ErrorReturned
  */
-function compose() {
-  for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {
-    funcs[_key] = arguments[_key];
-  }
 
-  if (funcs.length === 0) {
-    return function (arg) {
-      return arg;
-    };
-  }
 
-  if (funcs.length === 1) {
-    return funcs[0];
-  }
+exports._getIconURL = _getIconURL;
 
-  return funcs.reduce(function (a, b) {
-    return function () {
-      return a(b.apply(void 0, arguments));
-    };
+var getIconURL = function getIconURL() {
+  return _getIconURL.apply(this, arguments).catch(function () {
+    return new _memoize.ErrorReturned();
   });
-}
+};
 
-/**
- * Creates a store enhancer that applies middleware to the dispatch method
- * of the Redux store. This is handy for a variety of tasks, such as expressing
- * asynchronous actions in a concise manner, or logging every action payload.
- *
- * See `redux-thunk` package as an example of the Redux middleware.
- *
- * Because middleware is potentially asynchronous, this should be the first
- * store enhancer in the composition chain.
- *
- * Note that each middleware will be given the `dispatch` and `getState` functions
- * as named arguments.
- *
- * @param {...Function} middlewares The middleware chain to be applied.
- * @returns {Function} A store enhancer applying the middleware.
- */
+exports.getIconURL = getIconURL;
 
-function applyMiddleware() {
-  for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {
-    middlewares[_key] = arguments[_key];
+var _default = (0, _memoize.default)(getIconURL, {
+  maxDuration: 300 * 1000,
+  key: function key(stackClient, opts) {
+    var type = opts.type,
+        slug = opts.slug,
+        priority = opts.priority;
+    return stackClient.uri + +':' + type + ':' + slug + ':' + priority;
   }
+});
 
-  return function (createStore) {
-    return function () {
-      var store = createStore.apply(void 0, arguments);
+exports["default"] = _default;
 
-      var _dispatch = function dispatch() {
-        throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');
-      };
+/***/ }),
+/* 693 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-      var middlewareAPI = {
-        getState: store.getState,
-        dispatch: function dispatch() {
-          return _dispatch.apply(void 0, arguments);
-        }
-      };
-      var chain = middlewares.map(function (middleware) {
-        return middleware(middlewareAPI);
-      });
-      _dispatch = compose.apply(void 0, chain)(store.dispatch);
-      return (0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, store), {}, {
-        dispatch: _dispatch
-      });
-    };
-  };
-}
+"use strict";
 
-/*
- * This is a dummy function to check if the function name has been altered by minification.
- * If the function has been minified and NODE_ENV !== 'production', warn the user.
- */
 
-function isCrushed() {}
+var _interopRequireDefault = __webpack_require__(524);
 
-if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
-  warning('You are currently using minified code outside of NODE_ENV === "production". ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.');
-}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.ErrorReturned = exports["default"] = void 0;
 
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-/***/ }),
-/* 695 */
-/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (/* binding */ _objectSpread2)
-/* harmony export */ });
-/* harmony import */ var _defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(696);
+var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664));
 
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-function ownKeys(object, enumerableOnly) {
-  var keys = Object.keys(object);
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-  if (Object.getOwnPropertySymbols) {
-    var symbols = Object.getOwnPropertySymbols(object);
+var ErrorReturned = /*#__PURE__*/function (_String) {
+  (0, _inherits2.default)(ErrorReturned, _String);
 
-    if (enumerableOnly) {
-      symbols = symbols.filter(function (sym) {
-        return Object.getOwnPropertyDescriptor(object, sym).enumerable;
-      });
-    }
+  var _super = _createSuper(ErrorReturned);
 
-    keys.push.apply(keys, symbols);
+  function ErrorReturned() {
+    (0, _classCallCheck2.default)(this, ErrorReturned);
+    return _super.apply(this, arguments);
   }
 
-  return keys;
-}
+  return ErrorReturned;
+}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(String));
+/**
+ * Delete outdated results from cache
+ */
 
-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) {
-        (0,_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__["default"])(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));
-      });
-    }
-  }
+exports.ErrorReturned = ErrorReturned;
 
-  return target;
-}
+var garbageCollect = function garbageCollect(cache, maxDuration) {
+  var now = Date.now();
 
-/***/ }),
-/* 696 */
-/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+  for (var _i = 0, _Object$keys = Object.keys(cache); _i < _Object$keys.length; _i++) {
+    var key = _Object$keys[_i];
+    var delta = now - cache[key].date;
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (/* binding */ _defineProperty)
-/* harmony export */ });
-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;
+    if (delta > maxDuration) {
+      delete cache[key];
+    }
   }
+};
 
-  return obj;
-}
+var isPromise = function isPromise(maybePromise) {
+  return typeof maybePromise === 'object' && typeof maybePromise.then === 'function';
+};
+/**
+ * Memoize with maxDuration and custom key
+ */
 
-/***/ }),
-/* 697 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-function createThunkMiddleware(extraArgument) {
-  return function (_ref) {
-    var dispatch = _ref.dispatch,
-        getState = _ref.getState;
-    return function (next) {
-      return function (action) {
-        if (typeof action === 'function') {
-          return action(dispatch, getState, extraArgument);
-        }
+var memoize = function memoize(fn, options) {
+  var cache = {};
+  return function () {
+    var key = options.key.apply(null, arguments);
+    garbageCollect(cache, options.maxDuration);
+    var existing = cache[key];
 
-        return next(action);
+    if (existing) {
+      return existing.result;
+    } else {
+      var result = fn.apply(this, arguments);
+      cache[key] = {
+        result: result,
+        date: Date.now()
       };
-    };
-  };
-}
+      /**
+       * If the result is a promise and this promise
+       * failed or resolved with a specific error (aka ErrorReturned),
+       * let's remove the result from the cache since we don't want to
+       * memoize error
+       */
 
-var thunk = createThunkMiddleware();
-thunk.withExtraArgument = createThunkMiddleware;
+      if (isPromise(result)) {
+        result.then(function (v) {
+          if (v instanceof ErrorReturned) {
+            delete cache[key];
+          }
+        }).catch(function (e) {
+          delete cache[key];
+        });
+      }
 
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (thunk);
+      return result;
+    }
+  };
+};
+
+var _default = memoize;
+exports["default"] = _default;
 
 /***/ }),
-/* 698 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 694 */
+/***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
-
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.extractAndMergeDocument = exports.getCollectionFromSlice = exports.getDocumentFromSlice = exports["default"] = exports.mergeDocumentsWithRelationships = void 0;
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
-
-var _keyBy = _interopRequireDefault(__webpack_require__(699));
-
-var _get = _interopRequireDefault(__webpack_require__(358));
-
-var _isEqual = _interopRequireDefault(__webpack_require__(646));
-
-var _omit = _interopRequireDefault(__webpack_require__(613));
-
-var _logger = _interopRequireDefault(__webpack_require__(703));
-
-var _queries = __webpack_require__(723);
+exports["default"] = void 0;
 
-var _dsl = __webpack_require__(607);
+var logDeprecate = function logDeprecate() {
+  var _console;
 
-var _mutations = __webpack_require__(738);
+  if (process.env.NODE_ENV === 'test') {
+    throw new Error('Deprecation error: ' + (arguments.length <= 0 ? undefined : arguments[0]));
+  }
 
-var _types = __webpack_require__(610);
+  (_console = console).warn.apply(_console, arguments);
+};
 
-var _helpers = __webpack_require__(739);
+var _default = logDeprecate;
+exports["default"] = _default;
 
-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; }
+/***/ }),
+/* 695 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+"use strict";
 
-var storeDocument = function storeDocument(state, document) {
-  var type = document._type;
 
-  if (!type) {
-    if (process.env.NODE_ENV !== 'production') {
-      _logger.default.info('Document without _type', document);
-    }
+var _interopRequireDefault = __webpack_require__(524);
 
-    throw new Error('Document without _type');
-  }
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.shouldXMLHTTPRequestBeUsed = exports.fetchWithXMLHttpRequest = void 0;
 
-  if (!(0, _helpers.properId)(document)) {
-    if (process.env.NODE_ENV !== 'production') {
-      _logger.default.info('Document without id', document);
-    }
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-    throw new Error('Document without id');
-  }
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
 
-  var existingDoc = (0, _get.default)(state, [type, (0, _helpers.properId)(document)]);
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-  if ((0, _isEqual.default)(existingDoc, document)) {
-    return state;
-  } else {
-    return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, type, _objectSpread(_objectSpread({}, state[type]), {}, (0, _defineProperty2.default)({}, (0, _helpers.properId)(document), mergeDocumentsWithRelationships(existingDoc, document)))));
-  }
+var _memoize = _interopRequireDefault(__webpack_require__(377));
+
+var headersFromString = function headersFromString(headerString) {
+  return new Headers(headerString.split('\r\n').map(function (x) {
+    return x.split(':', 2);
+  }).filter(function (x) {
+    return x.length == 2;
+  }));
 };
+/**
+ * Returns a `fetch()` like response but uses XHR.
+ * XMLHTTPRequest provides upload progress events unlike fetch.
+ *
+ * @private
+ * @param {string} fullpath - Route path
+ * @param {object} options - Fetch options
+ * @param {Function} options.onUploadProgress - Callback to receive upload progress events
+ */
 
-var mergeDocumentsWithRelationships = function mergeDocumentsWithRelationships() {
-  var prevDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  var nextDocument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 
-  /**
-   * @type {CozyClientDocument}
-   */
-  var merged = _objectSpread(_objectSpread({}, prevDocument), nextDocument);
+var fetchWithXMLHttpRequest = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(fullpath, options) {
+    var response;
+    return _regenerator.default.wrap(function _callee3$(_context3) {
+      while (1) {
+        switch (_context3.prev = _context3.next) {
+          case 0:
+            _context3.next = 2;
+            return new Promise(function (resolve, reject) {
+              var xhr = new XMLHttpRequest();
 
-  if (prevDocument.relationships || nextDocument.relationships) merged.relationships = _objectSpread(_objectSpread({}, prevDocument.relationships), nextDocument.relationships);
-  return merged;
-}; // reducer
+              if (options.onUploadProgress && xhr.upload) {
+                xhr.upload.addEventListener('progress', options.onUploadProgress, false);
+              }
 
+              xhr.onload = function () {
+                if (this.readyState == 4) {
+                  resolve(this);
+                } else {
+                  reject(this);
+                }
+              };
 
-exports.mergeDocumentsWithRelationships = mergeDocumentsWithRelationships;
+              xhr.onerror = function (err) {
+                reject(err);
+              };
 
-var documents = function documents() {
-  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  var action = arguments.length > 1 ? arguments[1] : undefined;
+              xhr.open(options.method, fullpath, true);
+              xhr.withCredentials = true;
 
-  if (!(0, _queries.isReceivingData)(action) && !(0, _mutations.isReceivingMutationResult)(action)) {
-    return state;
-  }
+              for (var _i = 0, _Object$entries = Object.entries(options.headers); _i < _Object$entries.length; _i++) {
+                var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
+                    headerName = _Object$entries$_i[0],
+                    headerValue = _Object$entries$_i[1];
 
-  if (action && action.definition && action.definition.mutationType === _dsl.MutationTypes.DELETE_DOCUMENT) {
-    var docId = action.definition.document._id;
-    var _type = action.definition.document._type;
-    return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, _type, (0, _omit.default)(state[_type], docId)));
-  }
+                xhr.setRequestHeader(headerName, headerValue);
+              }
 
-  var _action$response = action.response,
-      data = _action$response.data,
-      included = _action$response.included;
-  if (!data || Array.isArray(data) && data.length === 0) return state;
-  var updatedStateWithIncluded = included ? included.reduce(storeDocument, state) : state;
+              xhr.send(options.body);
+            });
 
-  if (!Array.isArray(data)) {
-    return storeDocument(updatedStateWithIncluded, data);
-  }
+          case 2:
+            response = _context3.sent;
+            return _context3.abrupt("return", {
+              headers: headersFromString(response.getAllResponseHeaders()),
+              ok: response.status >= 200 && response.status < 300,
+              text: function () {
+                var _text = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+                  return _regenerator.default.wrap(function _callee$(_context) {
+                    while (1) {
+                      switch (_context.prev = _context.next) {
+                        case 0:
+                          return _context.abrupt("return", response.responseText);
 
-  return extractAndMergeDocument(data, updatedStateWithIncluded);
-};
+                        case 1:
+                        case "end":
+                          return _context.stop();
+                      }
+                    }
+                  }, _callee);
+                }));
 
-var _default = documents; // selector
+                function text() {
+                  return _text.apply(this, arguments);
+                }
 
-exports["default"] = _default;
+                return text;
+              }(),
+              json: function () {
+                var _json = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+                  return _regenerator.default.wrap(function _callee2$(_context2) {
+                    while (1) {
+                      switch (_context2.prev = _context2.next) {
+                        case 0:
+                          return _context2.abrupt("return", JSON.parse(response.responseText));
 
-var getDocumentFromSlice = function getDocumentFromSlice() {
-  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  var doctype = arguments.length > 1 ? arguments[1] : undefined;
-  var id = arguments.length > 2 ? arguments[2] : undefined;
+                        case 1:
+                        case "end":
+                          return _context2.stop();
+                      }
+                    }
+                  }, _callee2);
+                }));
 
-  if (!doctype) {
-    throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype');
-  }
+                function json() {
+                  return _json.apply(this, arguments);
+                }
 
-  if (!id) {
-    throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined id');
-  }
+                return json;
+              }(),
+              status: response.status,
+              statusText: response.statusText
+            });
 
-  if (!state[doctype]) {
-    if (process.env.NODE_ENV !== 'production') {
-      _logger.default.info("getDocumentFromSlice: ".concat(doctype, " is absent from the store's documents. State is"), state);
-    }
+          case 4:
+          case "end":
+            return _context3.stop();
+        }
+      }
+    }, _callee3);
+  }));
 
-    return null;
-  } else if (!state[doctype][id]) {
-    if (process.env.NODE_ENV !== 'production') {
-      _logger.default.info("getDocumentFromSlice: ".concat(doctype, ":").concat(id, " is absent from the store documents. State is"), state);
-    }
+  return function fetchWithXMLHttpRequest(_x, _x2) {
+    return _ref.apply(this, arguments);
+  };
+}();
 
-    return null;
-  }
+exports.fetchWithXMLHttpRequest = fetchWithXMLHttpRequest;
+var doesXHRSupportLoadAndProgress = (0, _memoize.default)(function () {
+  var xhr = new XMLHttpRequest();
+  return 'onload' in xhr && 'onprogress' in xhr;
+});
 
-  return state[doctype][id];
+var shouldXMLHTTPRequestBeUsed = function shouldXMLHTTPRequestBeUsed(method, path, options) {
+  return Boolean(options.onUploadProgress) && doesXHRSupportLoadAndProgress();
 };
 
-exports.getDocumentFromSlice = getDocumentFromSlice;
+exports.shouldXMLHTTPRequestBeUsed = shouldXMLHTTPRequestBeUsed;
 
-var getCollectionFromSlice = function getCollectionFromSlice() {
-  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  var doctype = arguments.length > 1 ? arguments[1] : undefined;
+/***/ }),
+/* 696 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  if (!doctype) {
-    throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype');
-  }
+"use strict";
 
-  if (!state[doctype]) {
-    if (process.env.NODE_ENV !== 'production') {
-      _logger.default.info("getCollectionFromSlice: ".concat(doctype, " is absent from the store documents. State is"), state);
-    }
 
-    return null;
-  }
+var _interopRequireDefault = __webpack_require__(524);
 
-  return Object.values(state[doctype]);
-};
-/*
-  This method has been created in order to get a returned object
-  in `data` with the full set on information coming potentially from
-  `included`
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-  This method should be somewhere else. The `document` shall not be
-  dealt with included / data and so on.
+var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664));
 
-  This method takes `data` and `included` and merge both sources
-  together. It should be always up-to-date. The returned object
-  will be as full of information as it can be.
-*/
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-exports.getCollectionFromSlice = getCollectionFromSlice;
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var extractAndMergeDocument = function extractAndMergeDocument(data, updatedStateWithIncluded) {
-  var doctype = data[0]._type;
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-  if (!doctype) {
-    _logger.default.info('Document without _type', data[0]);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-    throw new Error('Document without _type');
-  }
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-  var sortedData = (0, _keyBy.default)(data, _helpers.properId);
-  var mergedData = Object.assign({}, updatedStateWithIncluded);
-  mergedData[doctype] = Object.assign({}, updatedStateWithIncluded[doctype]);
-  Object.values(sortedData).map(function (data) {
-    var id = (0, _helpers.properId)(data);
+var _get2 = _interopRequireDefault(__webpack_require__(682));
 
-    if (mergedData[doctype][id]) {
-      mergedData[doctype][id] = _objectSpread(_objectSpread({}, mergedData[doctype][id]), data);
-    } else {
-      mergedData[doctype][id] = data;
-    }
-  });
-  return mergedData;
-};
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-exports.extractAndMergeDocument = extractAndMergeDocument;
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-/***/ }),
-/* 699 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var baseAssignValue = __webpack_require__(534),
-    createAggregator = __webpack_require__(700);
+var _CozyStackClient2 = _interopRequireDefault(__webpack_require__(572));
 
-/**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` thru `iteratee`. The corresponding value of
- * each key is the last element responsible for generating the key. The
- * iteratee is invoked with one argument: (value).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Collection
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var array = [
- *   { 'dir': 'left', 'code': 97 },
- *   { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.keyBy(array, function(o) {
- *   return String.fromCharCode(o.code);
- * });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.keyBy(array, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- */
-var keyBy = createAggregator(function(result, value, key) {
-  baseAssignValue(result, key, value);
-});
+var _AccessToken = _interopRequireDefault(__webpack_require__(669));
 
-module.exports = keyBy;
+var _logDeprecate = _interopRequireDefault(__webpack_require__(694));
 
+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; }
 
-/***/ }),
-/* 700 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var arrayAggregator = __webpack_require__(701),
-    baseAggregator = __webpack_require__(702),
-    baseIteratee = __webpack_require__(401),
-    isArray = __webpack_require__(55);
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+
+var defaultoauthOptions = {
+  clientID: '',
+  clientName: '',
+  clientKind: '',
+  clientSecret: '',
+  clientURI: '',
+  registrationAccessToken: '',
+  redirectURI: '',
+  softwareID: '',
+  softwareVersion: '',
+  logoURI: '',
+  policyURI: '',
+  notificationPlatform: '',
+  notificationDeviceToken: ''
+};
 /**
- * Creates a function like `_.groupBy`.
- *
- * @private
- * @param {Function} setter The function to set accumulator values.
- * @param {Function} [initializer] The accumulator object initializer.
- * @returns {Function} Returns the new aggregator function.
+ * Specialized `CozyStackClient` for mobile, implementing stack registration
+ * through OAuth.
  */
-function createAggregator(setter, initializer) {
-  return function(collection, iteratee) {
-    var func = isArray(collection) ? arrayAggregator : baseAggregator,
-        accumulator = initializer ? initializer() : {};
 
-    return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
-  };
-}
+var OAuthClient = /*#__PURE__*/function (_CozyStackClient) {
+  (0, _inherits2.default)(OAuthClient, _CozyStackClient);
 
-module.exports = createAggregator;
+  var _super = _createSuper(OAuthClient);
 
+  function OAuthClient(_ref) {
+    var _this;
 
-/***/ }),
-/* 701 */
-/***/ ((module) => {
+    var oauth = _ref.oauth,
+        _ref$scope = _ref.scope,
+        scope = _ref$scope === void 0 ? [] : _ref$scope,
+        onTokenRefresh = _ref.onTokenRefresh,
+        options = (0, _objectWithoutProperties2.default)(_ref, ["oauth", "scope", "onTokenRefresh"]);
+    (0, _classCallCheck2.default)(this, OAuthClient);
+    _this = _super.call(this, options);
 
-/**
- * A specialized version of `baseAggregator` for arrays.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} setter The function to set `accumulator` values.
- * @param {Function} iteratee The iteratee to transform keys.
- * @param {Object} accumulator The initial aggregated object.
- * @returns {Function} Returns `accumulator`.
- */
-function arrayAggregator(array, setter, iteratee, accumulator) {
-  var index = -1,
-      length = array == null ? 0 : array.length;
+    _this.setOAuthOptions(_objectSpread(_objectSpread({}, defaultoauthOptions), oauth));
 
-  while (++index < length) {
-    var value = array[index];
-    setter(accumulator, value, iteratee(value), array);
-  }
-  return accumulator;
-}
+    if (oauth.token) {
+      _this.setToken(oauth.token);
+    }
 
-module.exports = arrayAggregator;
+    _this.scope = scope;
+    _this.onTokenRefresh = onTokenRefresh;
+    return _this;
+  }
+  /**
+   * Checks if the client has his registration information from the server
+   *
+   * @returns {boolean} true if registered, false otherwise
+   * @private
+   */
 
 
-/***/ }),
-/* 702 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  (0, _createClass2.default)(OAuthClient, [{
+    key: "isRegistered",
+    value: function isRegistered() {
+      return this.oauthOptions.clientID !== '';
+    }
+    /**
+     * Converts a camel-cased data set to snake case, suitable for sending to the OAuth server
+     *
+     * @param   {object} data Initial data
+     * @returns {object} Formatted data
+     * @private
+     */
 
-var baseEach = __webpack_require__(555);
+  }, {
+    key: "snakeCaseOAuthData",
+    value: function snakeCaseOAuthData(data) {
+      var mappedFields = {
+        softwareID: 'software_id',
+        softwareVersion: 'software_version',
+        clientID: 'client_id',
+        clientName: 'client_name',
+        clientKind: 'client_kind',
+        clientURI: 'client_uri',
+        logoURI: 'logo_uri',
+        policyURI: 'policy_uri',
+        notificationPlatform: 'notification_platform',
+        notificationDeviceToken: 'notification_device_token',
+        redirectURI: 'redirect_uris'
+      };
+      var result = {};
+      Object.keys(data).forEach(function (fieldName) {
+        var key = mappedFields[fieldName] || fieldName;
+        var value = data[fieldName];
+        result[key] = value;
+      }); // special case: turn redirect_uris into an array
 
-/**
- * Aggregates elements of `collection` on `accumulator` with keys transformed
- * by `iteratee` and values set by `setter`.
- *
- * @private
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function} setter The function to set `accumulator` values.
- * @param {Function} iteratee The iteratee to transform keys.
- * @param {Object} accumulator The initial aggregated object.
- * @returns {Function} Returns `accumulator`.
- */
-function baseAggregator(collection, setter, iteratee, accumulator) {
-  baseEach(collection, function(value, key, collection) {
-    setter(accumulator, value, iteratee(value), collection);
-  });
-  return accumulator;
-}
+      if (result['redirect_uris'] && result['redirect_uris'] instanceof Array === false) result['redirect_uris'] = [result['redirect_uris']];
+      return result;
+    }
+    /**
+     * Converts a snake-cased data set to camel case, suitable for internal use
+     *
+     * @param   {object} data Initial data
+     * @returns {object} Formatted data
+     * @private
+     */
 
-module.exports = baseAggregator;
+  }, {
+    key: "camelCaseOAuthData",
+    value: function camelCaseOAuthData(data) {
+      var mappedFields = {
+        client_id: 'clientID',
+        client_name: 'clientName',
+        client_secret: 'clientSecret',
+        registration_access_token: 'registrationAccessToken',
+        software_id: 'softwareID',
+        redirect_uris: 'redirectURI'
+      };
+      var result = {};
+      Object.keys(data).forEach(function (fieldName) {
+        var key = mappedFields[fieldName] || fieldName;
+        var value = data[fieldName];
+        result[key] = value;
+      });
+      return result;
+    }
+    /** Performs the HTTP call to register the client to the server */
 
+  }, {
+    key: "doRegistration",
+    value: function doRegistration() {
+      return this.fetchJSON('POST', '/auth/register', this.snakeCaseOAuthData({
+        redirectURI: this.oauthOptions.redirectURI,
+        clientName: this.oauthOptions.clientName,
+        softwareID: this.oauthOptions.softwareID,
+        clientKind: this.oauthOptions.clientKind,
+        clientURI: this.oauthOptions.clientURI,
+        logoURI: this.oauthOptions.logoURI,
+        policyURI: this.oauthOptions.policyURI,
+        softwareVersion: this.oauthOptions.softwareVersion,
+        notificationPlatform: this.oauthOptions.notificationPlatform,
+        notificationDeviceToken: this.oauthOptions.notificationDeviceToken
+      }));
+    }
+    /**
+     * Registers the currenly configured client with the OAuth server and
+     * sets internal information from the server response
+     *
+     * @throws {Error} When the client is already registered
+     * @returns {Promise} A promise that resolves with a complete list of client information, including client ID and client secret.
+     */
 
-/***/ }),
-/* 703 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+  }, {
+    key: "register",
+    value: function () {
+      var _register = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var mandatoryFields, fields, missingMandatoryFields, data;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                if (!this.isRegistered()) {
+                  _context.next = 2;
+                  break;
+                }
 
-"use strict";
+                throw new Error('Client already registered');
 
+              case 2:
+                mandatoryFields = ['redirectURI'];
+                fields = Object.keys(this.oauthOptions);
+                missingMandatoryFields = mandatoryFields.filter(function (fieldName) {
+                  return fields[fieldName];
+                });
 
-var _interopRequireDefault = __webpack_require__(512);
+                if (!(missingMandatoryFields.length > 0)) {
+                  _context.next = 7;
+                  break;
+                }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+                throw new Error("Can't register client : missing ".concat(missingMandatoryFields, " fields"));
 
-var _minilog = _interopRequireDefault(__webpack_require__(704));
+              case 7:
+                _context.next = 9;
+                return this.doRegistration();
 
-var logger = (0, _minilog.default)('cozy-client');
+              case 9:
+                data = _context.sent;
+                this.setOAuthOptions(_objectSpread(_objectSpread({}, this.oauthOptions), {}, {
+                  client_id: data.client_id,
+                  client_name: data.client_name,
+                  client_secret: data.client_secret,
+                  registration_access_token: data.registration_access_token,
+                  software_id: data.software_id
+                }));
+                return _context.abrupt("return", this.oauthOptions);
 
-_minilog.default.suggest.deny('cozy-client', 'info');
+              case 12:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
 
-var _default = logger;
-exports["default"] = _default;
+      function register() {
+        return _register.apply(this, arguments);
+      }
 
-/***/ }),
-/* 704 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      return register;
+    }()
+    /**
+     * Unregisters the currenly configured client with the OAuth server.
+     *
+     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @returns {Promise}
+     */
 
-module.exports = __webpack_require__(705);
+  }, {
+    key: "unregister",
+    value: function () {
+      var _unregister = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+        var clientID;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                if (this.isRegistered()) {
+                  _context2.next = 2;
+                  break;
+                }
 
-var consoleLogger = __webpack_require__(708);
+                throw new NotRegisteredException();
 
-// if we are running inside Electron then use the web version of console.js
-var isElectron = (typeof window !== 'undefined' && window.process && window.process.type === 'renderer');
-if (isElectron) {
-  consoleLogger = (__webpack_require__(717).minilog);
-}
+              case 2:
+                clientID = this.oauthOptions.clientID;
+                this.oauthOptions.clientID = '';
+                return _context2.abrupt("return", this.fetchJSON('DELETE', "/auth/register/".concat(clientID), null, {
+                  headers: {
+                    Authorization: this.registrationAccessTokenToAuthHeader()
+                  }
+                }));
 
-// intercept the pipe method and transparently wrap the stringifier, if the
-// destination is a Node core stream
+              case 5:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
 
-module.exports.Stringifier = __webpack_require__(721);
+      function unregister() {
+        return _unregister.apply(this, arguments);
+      }
 
-var oldPipe = module.exports.pipe;
-module.exports.pipe = function(dest) {
-  if(dest instanceof __webpack_require__(82)) {
-    return oldPipe.call(module.exports, new (module.exports.Stringifier)).pipe(dest);
-  } else {
-    return oldPipe.call(module.exports, dest);
-  }
-};
+      return unregister;
+    }()
+    /**
+     * Fetches the complete set of client information from the server after it has been registered.
+     *
+     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @returns {Promise}
+     */
 
-module.exports.defaultBackend = consoleLogger;
-module.exports.defaultFormatter = consoleLogger.formatMinilog;
+  }, {
+    key: "fetchInformation",
+    value: function () {
+      var _fetchInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                if (this.isRegistered()) {
+                  _context3.next = 2;
+                  break;
+                }
 
-module.exports.backends = {
-  redis: __webpack_require__(722),
-  nodeConsole: consoleLogger,
-  console: consoleLogger
-};
+                throw new NotRegisteredException();
 
+              case 2:
+                return _context3.abrupt("return", this.fetchJSON('GET', "/auth/register/".concat(this.oauthOptions.clientID), null, {
+                  headers: {
+                    Authorization: this.registrationAccessTokenToAuthHeader()
+                  }
+                }));
 
-/***/ }),
-/* 705 */
-/***/ ((module, exports, __webpack_require__) => {
+              case 3:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
 
-var Transform = __webpack_require__(706),
-    Filter = __webpack_require__(707);
+      function fetchInformation() {
+        return _fetchInformation.apply(this, arguments);
+      }
 
-var log = new Transform(),
-    slice = Array.prototype.slice;
+      return fetchInformation;
+    }()
+    /**
+     * Overwrites the client own information. This method will update both the local information and the remote information on the OAuth server.
+     *
+     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @param   {object} information Set of information to update. Note that some fields such as `clientID` can't be updated.
+     * @param   {boolean} resetSecret = false Optionnal, whether to reset the client secret or not
+     * @returns {Promise} Resolves to a complete, updated list of client information
+     */
 
-exports = module.exports = function create(name) {
-  var o   = function() { log.write(name, undefined, slice.call(arguments)); return o; };
-  o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; };
-  o.info  = function() { log.write(name, 'info',  slice.call(arguments)); return o; };
-  o.warn  = function() { log.write(name, 'warn',  slice.call(arguments)); return o; };
-  o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; };
-  o.group = function() { log.write(name, 'group', slice.call(arguments)); return o; };
-  o.groupEnd = function() { log.write(name, 'groupEnd', slice.call(arguments)); return o; };
-  o.log   = o.debug; // for interface compliance with Node and browser consoles
-  o.suggest = exports.suggest;
-  o.format = log.format;
-  return o;
-};
+  }, {
+    key: "updateInformation",
+    value: function () {
+      var _updateInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(information) {
+        var resetSecret,
+            mandatoryFields,
+            data,
+            result,
+            _args4 = arguments;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                resetSecret = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : false;
 
-// filled in separately
-exports.defaultBackend = exports.defaultFormatter = null;
+                if (this.isRegistered()) {
+                  _context4.next = 3;
+                  break;
+                }
 
-exports.pipe = function(dest) {
-  return log.pipe(dest);
-};
+                throw new NotRegisteredException();
 
-exports.end = exports.unpipe = exports.disable = function(from) {
-  return log.unpipe(from);
-};
+              case 3:
+                mandatoryFields = {
+                  clientID: this.oauthOptions.clientID,
+                  clientName: this.oauthOptions.clientName,
+                  redirectURI: this.oauthOptions.redirectURI,
+                  softwareID: this.oauthOptions.softwareID
+                };
+                data = this.snakeCaseOAuthData(_objectSpread(_objectSpread({}, mandatoryFields), information));
+                if (resetSecret) data['client_secret'] = this.oauthOptions.clientSecret;
+                _context4.next = 8;
+                return this.fetchJSON('PUT', "/auth/register/".concat(this.oauthOptions.clientID), data, {
+                  headers: {
+                    Authorization: this.registrationAccessTokenToAuthHeader()
+                  }
+                });
 
-exports.Transform = Transform;
-exports.Filter = Filter;
-// this is the default filter that's applied when .enable() is called normally
-// you can bypass it completely and set up your own pipes
-exports.suggest = new Filter();
+              case 8:
+                result = _context4.sent;
+                this.setOAuthOptions(_objectSpread(_objectSpread({}, data), result));
+                return _context4.abrupt("return", this.oauthOptions);
 
-exports.enable = function() {
-  if(exports.defaultFormatter) {
-    return log.pipe(exports.suggest) // filter
-              .pipe(exports.defaultFormatter) // formatter
-              .pipe(exports.defaultBackend); // backend
-  }
-  return log.pipe(exports.suggest) // filter
-            .pipe(exports.defaultBackend); // formatter
-};
+              case 11:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
 
+      function updateInformation(_x) {
+        return _updateInformation.apply(this, arguments);
+      }
 
+      return updateInformation;
+    }()
+    /**
+     * Generates a random state code to be used during the OAuth process
+     *
+     * @returns {string}
+     */
 
-/***/ }),
-/* 706 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  }, {
+    key: "generateStateCode",
+    value: function generateStateCode() {
+      var STATE_SIZE = 16;
+      var hasCrypto = typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function';
+      var buffer;
 
-var microee = __webpack_require__(558);
+      if (hasCrypto) {
+        buffer = new Uint8Array(STATE_SIZE);
+        window.crypto.getRandomValues(buffer);
+      } else {
+        buffer = new Array(STATE_SIZE);
 
-// Implements a subset of Node's stream.Transform - in a cross-platform manner.
-function Transform() {}
+        for (var i = 0; i < buffer.length; i++) {
+          buffer[i] = Math.floor(Math.random() * 255);
+        }
+      }
 
-microee.mixin(Transform);
+      return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-');
+    }
+    /**
+     * Generates the URL that the user should be sent to in order to accept the app's permissions.
+     *
+     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @param {object} options - URL generation options
+     * @param {string} options.stateCode - A random code to be included in the URl for security. Can be generated with `client.generateStateCode()`
+     * @param {Array} [options.scopes] - An array of permission scopes for the token.
+     * @param {SessionCode} [options.sessionCode] - A session code that can be used to create a session.
+     * @param {string} [options.codeChallenge] - A code challenge that can be used in a PKCE verification process.
+     * @returns {string} The URL
+     */
 
-// The write() signature is different from Node's
-// --> makes it much easier to work with objects in logs.
-// One of the lessons from v1 was that it's better to target
-// a good browser rather than the lowest common denominator
-// internally.
-// If you want to use external streams, pipe() to ./stringify.js first.
-Transform.prototype.write = function(name, level, args) {
-  this.emit('item', name, level, args);
-};
+  }, {
+    key: "getAuthCodeURL",
+    value: function getAuthCodeURL(_ref2) {
+      var stateCode = _ref2.stateCode,
+          _ref2$scopes = _ref2.scopes,
+          scopes = _ref2$scopes === void 0 ? this.scope : _ref2$scopes,
+          _ref2$sessionCode = _ref2.sessionCode,
+          sessionCode = _ref2$sessionCode === void 0 ? undefined : _ref2$sessionCode,
+          _ref2$codeChallenge = _ref2.codeChallenge,
+          codeChallenge = _ref2$codeChallenge === void 0 ? undefined : _ref2$codeChallenge;
+      if (!this.isRegistered()) throw new NotRegisteredException();
+      var query = {
+        client_id: this.oauthOptions.clientID,
+        redirect_uri: this.oauthOptions.redirectURI,
+        state: stateCode,
+        response_type: 'code',
+        scope: scopes.join(' ')
+      };
 
-Transform.prototype.end = function() {
-  this.emit('end');
-  this.removeAllListeners();
-};
+      if (this.oauthOptions.registerToken) {
+        query = _objectSpread(_objectSpread({}, query), {}, {
+          registerToken: this.oauthOptions.registerToken
+        });
+      }
 
-Transform.prototype.pipe = function(dest) {
-  var s = this;
-  // prevent double piping
-  s.emit('unpipe', dest);
-  // tell the dest that it's being piped to
-  dest.emit('pipe', s);
+      if (sessionCode) {
+        query = _objectSpread(_objectSpread({}, query), {}, {
+          session_code: sessionCode
+        });
+      }
 
-  function onItem() {
-    dest.write.apply(dest, Array.prototype.slice.call(arguments));
-  }
-  function onEnd() { !dest._isStdio && dest.end(); }
+      if (codeChallenge) {
+        query = _objectSpread(_objectSpread({}, query), {}, {
+          code_challenge: codeChallenge,
+          code_challenge_method: 'S256'
+        });
+      }
 
-  s.on('item', onItem);
-  s.on('end', onEnd);
+      return "".concat(this.uri, "/auth/authorize?").concat(this.dataToQueryString(query));
+    }
+  }, {
+    key: "dataToQueryString",
+    value: function dataToQueryString(data) {
+      return Object.keys(data).map(function (param) {
+        return "".concat(param, "=").concat(encodeURIComponent(data[param]));
+      }).join('&');
+    }
+    /**
+     * Retrieves the access code contained in the URL to which the user is redirected after accepting the app's permissions (the `redirectURI`).
+     *
+     * @throws {Error} The URL should contain the same state code as the one generated with `client.getAuthCodeURL()`. If not, it will throw an error
+     * @param   {string} pageURL The redirected page URL, containing the state code and the access code
+     * @param   {string} stateCode The state code that was contained in the original URL the user was sent to (see `client.getAuthCodeURL()`)
+     * @returns {string} The access code
+     */
 
-  s.when('unpipe', function(from) {
-    var match = (from === dest) || typeof from == 'undefined';
-    if(match) {
-      s.removeListener('item', onItem);
-      s.removeListener('end', onEnd);
-      dest.emit('unpipe');
+  }, {
+    key: "getAccessCodeFromURL",
+    value: function getAccessCodeFromURL(pageURL, stateCode) {
+      if (!stateCode) throw new Error('Missing state code');
+      var params = new URL(pageURL).searchParams;
+      var urlStateCode = params.get('state');
+      var urlAccessCode = params.get('access_code');
+      if (stateCode !== urlStateCode) throw new Error('Given state does not match url query state');
+      return urlAccessCode;
     }
-    return match;
-  });
+    /**
+     * Exchanges an access code for an access token. This function does **not** update the client's token.
+     *
+     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @param   {string} accessCode - The access code contained in the redirection URL — see `client.getAccessCodeFromURL()`
+     * @param   {object} oauthOptionsArg — To use when OAuthClient is not yet registered (during login process)
+     * @param   {string} uri — To use when OAuthClient is not yet registered (during login process)
+     * @param   {string} codeVerifier — The PKCE code verifier (see https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension)
+     * @returns {Promise} A promise that resolves with an AccessToken object.
+     */
 
-  return dest;
-};
+  }, {
+    key: "fetchAccessToken",
+    value: function () {
+      var _fetchAccessToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(accessCode, oauthOptionsArg, uri, codeVerifier) {
+        var oauthOptions, data, result;
+        return _regenerator.default.wrap(function _callee5$(_context5) {
+          while (1) {
+            switch (_context5.prev = _context5.next) {
+              case 0:
+                if (!(!this.isRegistered() && !oauthOptionsArg)) {
+                  _context5.next = 2;
+                  break;
+                }
 
-Transform.prototype.unpipe = function(from) {
-  this.emit('unpipe', from);
-  return this;
-};
+                throw new NotRegisteredException();
 
-Transform.prototype.format = function(dest) {
-  throw new Error([
-    'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:',
-    'var Minilog = require(\'minilog\');',
-    'Minilog',
-    '  .pipe(Minilog.backends.console.formatClean)',
-    '  .pipe(Minilog.backends.console);'].join('\n'));
-};
+              case 2:
+                oauthOptions = oauthOptionsArg || this.oauthOptions;
+                data = {
+                  grant_type: 'authorization_code',
+                  code: accessCode,
+                  client_id: oauthOptions.clientID,
+                  client_secret: oauthOptions.clientSecret
+                };
 
-Transform.mixin = function(dest) {
-  var o = Transform.prototype, k;
-  for (k in o) {
-    o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
-  }
-};
+                if (codeVerifier) {
+                  data = _objectSpread(_objectSpread({}, data), {}, {
+                    code_verifier: codeVerifier
+                  });
+                }
 
-module.exports = Transform;
+                _context5.next = 7;
+                return this.fetchJSON('POST', (uri || '') + '/auth/access_token', this.dataToQueryString(data), {
+                  headers: {
+                    'Content-Type': 'application/x-www-form-urlencoded'
+                  }
+                });
 
+              case 7:
+                result = _context5.sent;
+                return _context5.abrupt("return", new _AccessToken.default(result));
 
-/***/ }),
-/* 707 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 9:
+              case "end":
+                return _context5.stop();
+            }
+          }
+        }, _callee5, this);
+      }));
 
-// default filter
-var Transform = __webpack_require__(706);
+      function fetchAccessToken(_x2, _x3, _x4, _x5) {
+        return _fetchAccessToken.apply(this, arguments);
+      }
 
-var levelMap = { debug: 1, info: 2, warn: 3, error: 4 };
+      return fetchAccessToken;
+    }()
+    /**
+     * @typedef SessionCodeRes
+     * @property {string} session_code The value of the session code
+     */
 
-function Filter() {
-  this.enabled = true;
-  this.defaultResult = true;
-  this.clear();
-}
+    /**
+     * Fetches a new session code. Only usable by the Flagship application
+     *
+     * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application
+     * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code
+     */
 
-Transform.mixin(Filter);
+  }, {
+    key: "fetchSessionCode",
+    value: function () {
+      var _fetchSessionCode = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
+        return _regenerator.default.wrap(function _callee6$(_context6) {
+          while (1) {
+            switch (_context6.prev = _context6.next) {
+              case 0:
+                return _context6.abrupt("return", this.fetchJSON('POST', '/auth/session_code'));
 
-// allow all matching, with level >= given level
-Filter.prototype.allow = function(name, level) {
-  this._white.push({ n: name, l: levelMap[level] });
-  return this;
-};
+              case 1:
+              case "end":
+                return _context6.stop();
+            }
+          }
+        }, _callee6, this);
+      }));
 
-// deny all matching, with level <= given level
-Filter.prototype.deny = function(name, level) {
-  this._black.push({ n: name, l: levelMap[level] });
-  return this;
-};
+      function fetchSessionCode() {
+        return _fetchSessionCode.apply(this, arguments);
+      }
+
+      return fetchSessionCode;
+    }()
+    /**
+     * Fetches a new session code. Only usable by the Flagship application
+     *
+     * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application
+     * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code
+     */
+
+  }, {
+    key: "fetchSessionCodeWithPassword",
+    value: function () {
+      var _fetchSessionCodeWithPassword = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(_ref3) {
+        var passwordHash, _ref3$twoFactorToken, twoFactorToken, _ref3$twoFactorPassco, twoFactorPasscode;
+
+        return _regenerator.default.wrap(function _callee7$(_context7) {
+          while (1) {
+            switch (_context7.prev = _context7.next) {
+              case 0:
+                passwordHash = _ref3.passwordHash, _ref3$twoFactorToken = _ref3.twoFactorToken, twoFactorToken = _ref3$twoFactorToken === void 0 ? undefined : _ref3$twoFactorToken, _ref3$twoFactorPassco = _ref3.twoFactorPasscode, twoFactorPasscode = _ref3$twoFactorPassco === void 0 ? undefined : _ref3$twoFactorPassco;
+                return _context7.abrupt("return", this.fetchJSON('POST', '/auth/session_code', {
+                  passphrase: passwordHash,
+                  two_factor_token: twoFactorToken,
+                  two_factor_passcode: twoFactorPasscode
+                }));
 
-Filter.prototype.clear = function() {
-  this._white = [];
-  this._black = [];
-  return this;
-};
+              case 2:
+              case "end":
+                return _context7.stop();
+            }
+          }
+        }, _callee7, this);
+      }));
 
-function test(rule, name) {
-  // use .test for RegExps
-  return (rule.n.test ? rule.n.test(name) : rule.n == name);
-};
+      function fetchSessionCodeWithPassword(_x6) {
+        return _fetchSessionCodeWithPassword.apply(this, arguments);
+      }
 
-Filter.prototype.test = function(name, level) {
-  var i, len = Math.max(this._white.length, this._black.length);
-  for(i = 0; i < len; i++) {
-    if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) {
-      return true;
-    }
-    if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) {
-      return false;
-    }
-  }
-  return this.defaultResult;
-};
+      return fetchSessionCodeWithPassword;
+    }()
+    /**
+     * @typedef AccessTokenRes
+     * @property {string} access_token The OAuth access token
+     * @property {string} refresh_token The OAuth refresh token
+     * @property {string} token_type The OAuth token type
+     * @property {string} scope The OAuth scope
+     */
 
-Filter.prototype.write = function(name, level, args) {
-  if(!this.enabled || this.test(name, level)) {
-    return this.emit('item', name, level, args);
-  }
-};
+    /**
+     * @typedef TwoFactorNeededRes
+     * @property {string} two_factor_token The 2FA token
+     */
 
-module.exports = Filter;
+    /**
+     * Get OAuth access and register tokens without having to make OAuth dance
+     *
+     * This endpoint returns registration tokens only from a Flagship app,
+     * otherwise it returns a session_code that should be used in an OAuth dance
+     *
+     * More info: https://docs.cozy.io/en/cozy-stack/flagship/
+     * More info: https://docs.cozy.io/en/cozy-stack/auth/#post-authloginflagship
+     *
+     * @returns {Promise<AccessTokenRes|TwoFactorNeededRes|SessionCodeRes>} A promise that resolves with an access token, a session_code or a 2FA code
+     */
 
+  }, {
+    key: "loginFlagship",
+    value: function () {
+      var _loginFlagship = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(_ref4) {
+        var passwordHash, _ref4$twoFactorToken, twoFactorToken, _ref4$twoFactorPassco, twoFactorPasscode;
 
-/***/ }),
-/* 708 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+        return _regenerator.default.wrap(function _callee8$(_context8) {
+          while (1) {
+            switch (_context8.prev = _context8.next) {
+              case 0:
+                passwordHash = _ref4.passwordHash, _ref4$twoFactorToken = _ref4.twoFactorToken, twoFactorToken = _ref4$twoFactorToken === void 0 ? undefined : _ref4$twoFactorToken, _ref4$twoFactorPassco = _ref4.twoFactorPasscode, twoFactorPasscode = _ref4$twoFactorPassco === void 0 ? undefined : _ref4$twoFactorPassco;
+                return _context8.abrupt("return", this.fetchJSON('POST', '/auth/login/flagship', {
+                  client_id: this.oauthOptions.clientID,
+                  client_secret: this.oauthOptions.clientSecret,
+                  passphrase: passwordHash,
+                  two_factor_token: twoFactorToken,
+                  two_factor_passcode: twoFactorPasscode
+                }));
 
-var Transform = __webpack_require__(706);
+              case 2:
+              case "end":
+                return _context8.stop();
+            }
+          }
+        }, _callee8, this);
+      }));
 
-function ConsoleBackend() { }
+      function loginFlagship(_x7) {
+        return _loginFlagship.apply(this, arguments);
+      }
 
-Transform.mixin(ConsoleBackend);
+      return loginFlagship;
+    }()
+    /**
+     * Retrieves a new access token by refreshing the currently used token.
+     *
+     * @throws {NotRegisteredException} When the client doesn't have it's registration information
+     * @throws {Error} The client should already have an access token to use this function
+     * @returns {Promise} A promise that resolves with a new AccessToken object
+     */
 
-ConsoleBackend.prototype.write = function() {
-  console.log.apply(console, arguments);
-};
+  }, {
+    key: "refreshToken",
+    value: function () {
+      var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9() {
+        var data, result, newToken;
+        return _regenerator.default.wrap(function _callee9$(_context9) {
+          while (1) {
+            switch (_context9.prev = _context9.next) {
+              case 0:
+                if (this.isRegistered()) {
+                  _context9.next = 2;
+                  break;
+                }
 
-var e = new ConsoleBackend();
+                throw new NotRegisteredException();
 
-var levelMap = (__webpack_require__(709).levelMap);
+              case 2:
+                if (this.token) {
+                  _context9.next = 4;
+                  break;
+                }
 
-e.filterEnv = function() {
-  console.error('Minilog.backends.console.filterEnv is deprecated in Minilog v2.');
-  // return the instance of Minilog
-  return __webpack_require__(705);
-};
+                throw new Error('No token to refresh');
 
-e.formatters = [
-    'formatClean', 'formatColor', 'formatNpm',
-    'formatLearnboost', 'formatMinilog', 'formatWithStack', 'formatTime'
-];
+              case 4:
+                data = {
+                  grant_type: 'refresh_token',
+                  refresh_token: this.token.refreshToken,
+                  client_id: this.oauthOptions.clientID,
+                  client_secret: this.oauthOptions.clientSecret
+                };
+                _context9.next = 7;
+                return (0, _get2.default)((0, _getPrototypeOf2.default)(OAuthClient.prototype), "fetchJSON", this).call(this, 'POST', '/auth/access_token', this.dataToQueryString(data), {
+                  headers: {
+                    'Content-Type': 'application/x-www-form-urlencoded'
+                  }
+                });
 
-e.formatClean = new (__webpack_require__(710));
-e.formatColor = new (__webpack_require__(711));
-e.formatNpm = new (__webpack_require__(712));
-e.formatLearnboost = new (__webpack_require__(713));
-e.formatMinilog = new (__webpack_require__(714));
-e.formatWithStack = new (__webpack_require__(715));
-e.formatTime = new (__webpack_require__(716));
+              case 7:
+                result = _context9.sent;
+                newToken = new _AccessToken.default(_objectSpread({
+                  refresh_token: this.token.refreshToken
+                }, result));
 
-module.exports = e;
+                if (this.onTokenRefresh && typeof this.onTokenRefresh === 'function') {
+                  this.onTokenRefresh(newToken);
+                }
 
+                return _context9.abrupt("return", newToken);
 
-/***/ }),
-/* 709 */
-/***/ ((__unused_webpack_module, exports) => {
+              case 11:
+              case "end":
+                return _context9.stop();
+            }
+          }
+        }, _callee9, this);
+      }));
 
-var styles = {
-  //styles
-  bold: ["\x1B[1m", "\x1B[22m"],
-  italic: ["\x1B[3m", "\x1B[23m"],
-  underline: ["\x1B[4m", "\x1B[24m"],
-  inverse: ["\x1B[7m", "\x1B[27m"],
-  //grayscale
-  white: ["\x1B[37m", "\x1B[39m"],
-  grey: ["\x1B[90m", "\x1B[39m"],
-  black: ["\x1B[30m", "\x1B[39m"],
-  //colors
-  blue: ["\x1B[34m", "\x1B[39m"],
-  cyan: ["\x1B[36m", "\x1B[39m"],
-  green: ["\x1B[32m", "\x1B[39m"],
-  magenta: ["\x1B[35m", "\x1B[39m"],
-  red: ["\x1B[31m", "\x1B[39m"],
-  yellow: ["\x1B[33m", "\x1B[39m"]
-};
+      function refreshToken() {
+        return _refreshToken.apply(this, arguments);
+      }
 
-exports.levelMap = { debug: 1, info: 2, warn: 3, error: 4 };
+      return refreshToken;
+    }()
+  }, {
+    key: "exchangeOAuthSecret",
+    value: function exchangeOAuthSecret(uri, secret) {
+      return this.fetchJSON('POST', uri + '/auth/secret_exchange', {
+        secret: secret
+      });
+    }
+    /**
+     * Updates the client's stored token
+     *
+     * @param {string} token = null The new token to use — can be a string, a json object or an AccessToken instance.
+     */
 
-exports.style = function(str, style) {
-  return styles[style][0] + str + styles[style][1];
-};
+  }, {
+    key: "setToken",
+    value: function setToken(token) {
+      if (token) {
+        this.token = token instanceof _AccessToken.default ? token : new _AccessToken.default(token);
+      } else {
+        this.token = null;
+      }
+    }
+  }, {
+    key: "setCredentials",
+    value: function setCredentials(token) {
+      (0, _logDeprecate.default)('setCredentials is deprecated, please replace by setToken');
+      return this.setToken(token);
+    }
+    /**
+     * Updates the OAuth informations
+     *
+     * @param {object} options Map of OAuth options
+     */
 
+  }, {
+    key: "setOAuthOptions",
+    value: function setOAuthOptions(options) {
+      this.oauthOptions = this.camelCaseOAuthData(options);
+    }
+  }, {
+    key: "resetClientId",
+    value: function resetClientId() {
+      this.oauthOptions.clientID = '';
+    }
+    /**
+     * Reset the current OAuth client
+     */
 
-/***/ }),
-/* 710 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  }, {
+    key: "resetClient",
+    value: function resetClient() {
+      this.resetClientId();
+      this.setUri(null);
+      this.setToken(null);
+    }
+    /**
+     * Turns the client's registration access token into a header suitable for HTTP requests. Used in some queries to manipulate the client on the server side.
+     *
+     * @returns {string}
+     * @private
+     */
 
-var Transform = __webpack_require__(706);
+  }, {
+    key: "registrationAccessTokenToAuthHeader",
+    value: function registrationAccessTokenToAuthHeader() {
+      if (!this.oauthOptions.registrationAccessToken) {
+        throw new Error('No registration access token');
+      }
 
-function FormatClean() {}
+      return 'Bearer ' + this.oauthOptions.registrationAccessToken;
+    }
+    /**
+     * This method should be used in flagship app onboarding process to finalize the
+     * cozy creation by setting the user password into the cozy-stack
+     *
+     * More info: https://docs.cozy.io/en/cozy-stack/settings/#post-settingspassphraseflagship
+     *
+     * @param {object} params
+     * @param {string} params.registerToken - registration token provided by the onboarding link
+     * @param {string} params.passwordHash - hash of the master password
+     * @param {string} params.hint - hint for the master password
+     * @param {string} params.key - key (crypted) used for the vault encryption
+     * @param {string} params.publicKey - public key used for sharing ciphers from the vault
+     * @param {string} params.privateKey - private key (crypted) used for sharing ciphers from the vault
+     * @param {string} params.iterations - number of KDF iterations applied when hashing the master password
+     * @returns {object} token - The OAauth token
+     */
 
-Transform.mixin(FormatClean);
+  }, {
+    key: "setPassphraseFlagship",
+    value: function setPassphraseFlagship(_ref5) {
+      var registerToken = _ref5.registerToken,
+          passwordHash = _ref5.passwordHash,
+          hint = _ref5.hint,
+          key = _ref5.key,
+          publicKey = _ref5.publicKey,
+          privateKey = _ref5.privateKey,
+          iterations = _ref5.iterations;
+      return this.fetchJSON('POST', '/settings/passphrase/flagship', {
+        register_token: registerToken,
+        passphrase: passwordHash,
+        hint: hint,
+        key: key,
+        public_key: publicKey,
+        private_key: privateKey,
+        iterations: iterations,
+        client_id: this.oauthOptions.clientID,
+        client_secret: this.oauthOptions.clientSecret
+      }, {
+        // TODO: faut il mettre le header?
+        headers: {
+          Authorization: this.registrationAccessTokenToAuthHeader()
+        }
+      });
+    }
+  }]);
+  return OAuthClient;
+}(_CozyStackClient2.default);
 
-FormatClean.prototype.write = function(name, level, args) {
-  function pad(s) { return (s.toString().length == 1? '0'+s : s); }
-  this.emit('item', (name ? name + ' ' : '') + (level ? level + ' ' : '') + args.join(' '));
-};
+var NotRegisteredException = /*#__PURE__*/function (_Error) {
+  (0, _inherits2.default)(NotRegisteredException, _Error);
 
-module.exports = FormatClean;
+  var _super2 = _createSuper(NotRegisteredException);
 
+  function NotRegisteredException() {
+    var _this2;
 
-/***/ }),
-/* 711 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Client not registered or missing OAuth information';
+    (0, _classCallCheck2.default)(this, NotRegisteredException);
+    _this2 = _super2.call(this, message);
+    _this2.message = message;
+    _this2.name = 'NotRegisteredException';
+    return _this2;
+  }
 
-var Transform = __webpack_require__(706),
-    style = (__webpack_require__(709).style);
+  return NotRegisteredException;
+}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
 
-function FormatColor() {}
+var _default = OAuthClient;
+exports["default"] = _default;
 
-Transform.mixin(FormatColor);
+/***/ }),
+/* 697 */
+/***/ ((__unused_webpack_module, exports) => {
 
-FormatColor.prototype.write = function(name, level, args) {
-  var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' };
-  function pad(s) { return (s.toString().length == 4? ' '+s : s); }
-  this.emit('item', (name ? name + ' ' : '')
-          + (level ? style('- ' + pad(level.toUpperCase()) + ' -', colors[level]) + ' ' : '')
-          + args.join(' '));
-};
+"use strict";
 
-module.exports = FormatColor;
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.DOCTYPE_PERMISSIONS = exports.DOCTYPE_FILES = exports.REGISTRATION_ABORT = void 0;
+var REGISTRATION_ABORT = 'REGISTRATION_ABORT';
+exports.REGISTRATION_ABORT = REGISTRATION_ABORT;
+var DOCTYPE_FILES = 'io.cozy.files';
+exports.DOCTYPE_FILES = DOCTYPE_FILES;
+var DOCTYPE_PERMISSIONS = 'io.cozy.permissions';
+exports.DOCTYPE_PERMISSIONS = DOCTYPE_PERMISSIONS;
 
 /***/ }),
-/* 712 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 698 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var Transform = __webpack_require__(706);
+"use strict";
 
-function FormatNpm() {}
 
-Transform.mixin(FormatNpm);
+var _interopRequireDefault = __webpack_require__(524);
 
-FormatNpm.prototype.write = function(name, level, args) {
-  var out = {
-    debug: "\x1B[34;40m" + "debug" + "\x1B[39m ",
-    info: "\x1B[32m" + "info" + "\x1B[39m  ",
-    warn: "\x1B[30;41m" + "WARN" + "\x1B[0m  ",
-    error: "\x1B[31;40m" + "ERR!" + "\x1B[0m  "
-  };
-  this.emit(
-    "item",
-    (name ? "\x1B[37;40m" + name + "\x1B[0m " : "") +
-      (level && out[level] ? out[level] : "") +
-      args.join(" ")
-  );
-};
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = exports.transformBulkDocsResponse = void 0;
 
-module.exports = FormatNpm;
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-/***/ }),
-/* 713 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-var Transform = __webpack_require__(706),
-    style = (__webpack_require__(709).style);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-function FormatLearnboost() {}
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-Transform.mixin(FormatLearnboost);
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-FormatLearnboost.prototype.write = function(name, level, args) {
-  var colors = { debug: 'grey', info: 'cyan', warn: 'yellow', error: 'red' };
-  this.emit('item', (name ? style(name +' ', 'grey') : '')
-          + (level ? style(level, colors[level]) + ' ' : '')
-          + args.join(' '));
-};
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-module.exports = FormatLearnboost;
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-/***/ }),
-/* 714 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _dsl = __webpack_require__(619);
 
-var Transform = __webpack_require__(706),
-    style = (__webpack_require__(709).style),
-    util = __webpack_require__(64);
+var _CozyLink2 = _interopRequireDefault(__webpack_require__(699));
 
-function FormatMinilog() {}
+var _types = __webpack_require__(622);
 
-Transform.mixin(FormatMinilog);
+var _const = __webpack_require__(697);
 
-FormatMinilog.prototype.write = function(name, level, args) {
-  var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' };
-  this.emit('item', (name ? style(name +' ', 'grey') : '')
-            + (level ? style(level, colors[level]) + ' ' : '')
-            + args.map(function(item) {
-              return (typeof item == 'string' ? item : util.inspect(item, null, 3, true));
-            }).join(' '));
-};
+var _errors = __webpack_require__(700);
 
-module.exports = FormatMinilog;
+var _zipWith = _interopRequireDefault(__webpack_require__(701));
 
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-/***/ }),
-/* 715 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var Transform = __webpack_require__(706),
-    style = (__webpack_require__(709).style);
+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 FormatNpm() {}
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-Transform.mixin(FormatNpm);
+/**
+ * Returns full documents after a bulk update
+ *
+ * @private
+ *
+ * @param  {CouchDBBulkResult[]} bulkResponse - Response from bulk docs
+ * @param  {CozyClientDocument[]} originalDocuments - Documents that were updated
+ * @returns {{ data: CozyClientDocument[] }} - Full documents with updated _id and _rev
+ */
+var transformBulkDocsResponse = function transformBulkDocsResponse(bulkResponse, originalDocuments) {
+  var updatedDocs = (0, _zipWith.default)(bulkResponse, originalDocuments, function (result, od) {
+    return result.ok ? _objectSpread(_objectSpread({}, od), {}, {
+      _id: result.id,
+      _rev: result.rev
+    }) : od;
+  });
 
-function noop(a){
-  return a;
-}
+  if (bulkResponse.find(function (x) {
+    return !x.ok;
+  })) {
+    throw new _errors.BulkEditError(bulkResponse, updatedDocs);
+  }
 
-var types = {
-  string: noop,
-  number: noop,
-  default: JSON.stringify.bind(JSON)
+  return {
+    data: updatedDocs
+  };
 };
+/**
+ * Transfers queries and mutations to a remote stack
+ */
 
-function stringify(args) {
-  return args.map(function(arg) {
-    return (types[typeof arg] || types.default)(arg);
-  });
-}
 
-FormatNpm.prototype.write = function(name, level, args) {
-  var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' };
-  function pad(s) { return (s.toString().length == 4? ' '+s : s); }
-  function getStack() {
-    var orig = Error.prepareStackTrace;
-    Error.prepareStackTrace = function (err, stack) {
-      return stack;
-    };
-    var err = new Error;
-    Error.captureStackTrace(err, arguments.callee);
-    var stack = err.stack;
-    Error.prepareStackTrace = orig;
-    return stack;
-  }
+exports.transformBulkDocsResponse = transformBulkDocsResponse;
 
-  var frame = getStack()[5],
-      fileName = FormatNpm.fullPath ? frame.getFileName() : frame.getFileName().replace(/^.*\/(.+)$/, '/$1');
+var StackLink = /*#__PURE__*/function (_CozyLink) {
+  (0, _inherits2.default)(StackLink, _CozyLink);
 
-  this.emit('item', (name ? name + ' ' : '')
-          + (level ? style(pad(level), colors[level]) + ' ' : '')
-          + style(fileName + ":" + frame.getLineNumber(), 'grey')
-          + ' '
-          + stringify(args).join(' '));
-};
+  var _super = _createSuper(StackLink);
 
-FormatNpm.fullPath = true;
+  /**
+   * @param {object} [options] - Options
+   * @param  {object} [options.stackClient] - A StackClient
+   * @param  {object} [options.client] - A StackClient (deprecated)
+   */
+  function StackLink() {
+    var _this;
 
-module.exports = FormatNpm;
+    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+        client = _ref.client,
+        stackClient = _ref.stackClient;
 
+    (0, _classCallCheck2.default)(this, StackLink);
+    _this = _super.call(this);
 
+    if (client) {
+      console.warn('Using options.client is deprecated, prefer options.stackClient');
+    }
 
-/***/ }),
-/* 716 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    _this.stackClient = stackClient || client;
+    return _this;
+  }
 
-var Transform = __webpack_require__(706),
-    style = (__webpack_require__(709).style),
-    util = __webpack_require__(64);
+  (0, _createClass2.default)(StackLink, [{
+    key: "registerClient",
+    value: function registerClient(client) {
+      this.stackClient = client.stackClient || client.client;
+    }
+  }, {
+    key: "reset",
+    value: function reset() {
+      this.stackClient = null;
+    }
+  }, {
+    key: "request",
+    value: function request(operation, result, forward) {
+      if (operation.mutationType) {
+        return this.executeMutation(operation, result, forward);
+      }
 
-function FormatTime() {}
+      return this.executeQuery(operation);
+    }
+  }, {
+    key: "executeQuery",
+    value: function executeQuery(query) {
+      var doctype = query.doctype,
+          selector = query.selector,
+          id = query.id,
+          ids = query.ids,
+          referenced = query.referenced,
+          options = (0, _objectWithoutProperties2.default)(query, ["doctype", "selector", "id", "ids", "referenced"]);
 
-function timestamp() {
-  var d = new Date();
-  return ('0' + d.getDate()).slice(-2) + '-' +
-    ('0' + (d.getMonth() + 1)).slice(-2) + '-' +
-    d.getFullYear() + ' ' +
-    ('0' + d.getHours()).slice(-2) + ':' +
-    ('0' + d.getMinutes()).slice(-2) + ':' +
-    ('0' + d.getSeconds()).slice(-2) + '.' +
-    ('00' + d.getMilliseconds()).slice(-3);
-}
+      if (!doctype) {
+        console.warn('Bad query', query);
+        throw new Error('No doctype found in a query definition');
+      }
 
-Transform.mixin(FormatTime);
+      var collection = this.stackClient.collection(doctype);
 
-FormatTime.prototype.write = function(name, level, args) {
-  var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' };
-  this.emit('item', style(timestamp() +' ', 'grey')
-            + (name ? style(name +' ', 'grey') : '')
-            + (level ? style(level, colors[level]) + ' ' : '')
-            + args.map(function(item) {
-              return (typeof item == 'string' ? item : util.inspect(item, null, 3, true));
-            }).join(' '));
-};
+      if (id) {
+        return collection.get(id, query);
+      }
 
-module.exports = FormatTime;
+      if (ids) {
+        return collection.getAll(ids);
+      }
 
+      if (referenced) {
+        return collection.findReferencedBy(referenced, options);
+      }
 
-/***/ }),
-/* 717 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      return !selector && !options.sort ? collection.all(options) : collection.find(selector, options);
+    }
+  }, {
+    key: "executeMutation",
+    value: function () {
+      var _executeMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mutation, result, forward) {
+        var mutationType, doc, docs, props, updateAllResp;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                mutationType = mutation.mutationType, doc = mutation.document, docs = mutation.documents, props = (0, _objectWithoutProperties2.default)(mutation, ["mutationType", "document", "documents"]);
+                _context.t0 = mutationType;
+                _context.next = _context.t0 === _dsl.MutationTypes.CREATE_DOCUMENT ? 4 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENTS ? 5 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENT ? 9 : _context.t0 === _dsl.MutationTypes.DELETE_DOCUMENT ? 10 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCES_TO ? 11 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCES_TO ? 12 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCED_BY ? 13 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCED_BY ? 18 : _context.t0 === _dsl.MutationTypes.UPLOAD_FILE ? 23 : 24;
+                break;
 
-var Transform = __webpack_require__(706);
+              case 4:
+                return _context.abrupt("return", this.stackClient.collection(doc._type).create(doc));
 
-var newlines = /\n+$/,
-    logger = new Transform();
+              case 5:
+                _context.next = 7;
+                return this.stackClient.collection(docs[0]._type).updateAll(docs);
 
-logger.write = function(name, level, args) {
-  var i = args.length-1;
-  if (typeof console === 'undefined' || !console.log) {
-    return;
-  }
-  if(console.log.apply) {
-    return console.log.apply(console, [name, level].concat(args));
-  } else if(JSON && JSON.stringify) {
-    // console.log.apply is undefined in IE8 and IE9
-    // for IE8/9: make console.log at least a bit less awful
-    if(args[i] && typeof args[i] == 'string') {
-      args[i] = args[i].replace(newlines, '');
-    }
-    try {
-      for(i = 0; i < args.length; i++) {
-        args[i] = JSON.stringify(args[i]);
-      }
-    } catch(e) {}
-    console.log(args.join(' '));
-  }
-};
+              case 7:
+                updateAllResp = _context.sent;
+                return _context.abrupt("return", transformBulkDocsResponse(updateAllResp, docs));
 
-logger.formatters = ['color', 'minilog'];
-logger.color = __webpack_require__(718);
-logger.minilog = __webpack_require__(720);
+              case 9:
+                return _context.abrupt("return", this.stackClient.collection(doc._type).update(doc));
 
-module.exports = logger;
+              case 10:
+                return _context.abrupt("return", this.stackClient.collection(doc._type).destroy(doc));
 
+              case 11:
+                return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).addReferencesTo(doc, props.referencedDocuments));
 
-/***/ }),
-/* 718 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+              case 12:
+                return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).removeReferencesTo(doc, props.referencedDocuments));
 
-var Transform = __webpack_require__(706),
-    color = __webpack_require__(719);
+              case 13:
+                if (!(doc._type === _const.DOCTYPE_FILES)) {
+                  _context.next = 17;
+                  break;
+                }
 
-var colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },
-    logger = new Transform();
+                return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).addReferencedBy(doc, props.referencedDocuments));
 
-logger.write = function(name, level, args) {
-  var fn = console.log;
-  if(console[level] && console[level].apply) {
-    fn = console[level];
-    fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args));
-  }
-};
+              case 17:
+                throw new Error('The document type should be io.cozy.files');
 
-// NOP, because piping the formatted logs can only cause trouble.
-logger.pipe = function() { };
+              case 18:
+                if (!(doc._type === _const.DOCTYPE_FILES)) {
+                  _context.next = 22;
+                  break;
+                }
 
-module.exports = logger;
+                return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).removeReferencedBy(doc, props.referencedDocuments));
 
+              case 22:
+                throw new Error('The document type should be io.cozy.files');
 
-/***/ }),
-/* 719 */
-/***/ ((module) => {
+              case 23:
+                return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).upload(props.file, props.dirPath));
 
-var hex = {
-  black: '#000',
-  red: '#c23621',
-  green: '#25bc26',
-  yellow: '#bbbb00',
-  blue:  '#492ee1',
-  magenta: '#d338d3',
-  cyan: '#33bbc8',
-  gray: '#808080',
-  purple: '#708'
-};
-function color(fg, isInverse) {
-  if(isInverse) {
-    return 'color: #fff; background: '+hex[fg]+';';
-  } else {
-    return 'color: '+hex[fg]+';';
-  }
-}
+              case 24:
+                return _context.abrupt("return", forward(mutation, result));
 
-module.exports = color;
+              case 25:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
 
+      function executeMutation(_x, _x2, _x3) {
+        return _executeMutation.apply(this, arguments);
+      }
 
-/***/ }),
-/* 720 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      return executeMutation;
+    }()
+  }]);
+  return StackLink;
+}(_CozyLink2.default);
 
-var Transform = __webpack_require__(706),
-    color = __webpack_require__(719),
-    colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },
-    logger = new Transform();
+exports["default"] = StackLink;
 
-logger.write = function(name, level, args) {
-  var fn = console.log;
-  if(level != 'debug' && console[level]) {
-    fn = console[level];
-  }
+/***/ }),
+/* 699 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  var subset = [], i = 0;
-  if(level != 'info') {
-    for(; i < args.length; i++) {
-      if(typeof args[i] != 'string') break;
-    }
-    fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i)));
-  } else {
-    fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args));
-  }
-};
+"use strict";
 
-// NOP, because piping the formatted logs can only cause trouble.
-logger.pipe = function() { };
 
-module.exports = logger;
+var _interopRequireDefault = __webpack_require__(524);
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.chain = exports["default"] = void 0;
 
-/***/ }),
-/* 721 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-var Transform = __webpack_require__(706);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-function Stringify() {}
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-Transform.mixin(Stringify);
+var CozyLink = /*#__PURE__*/function () {
+  function CozyLink(requestHandler) {
+    (0, _classCallCheck2.default)(this, CozyLink);
 
-Stringify.prototype.write = function(name, level, args) {
-  var result = [];
-  if(name) result.push(name);
-  if(level) result.push(level);
-  result = result.concat(args);
-  for(var i = 0; i < result.length; i++) {
-    if(result[i] && typeof result[i] == 'object') {
-      // Buffers in Node.js look bad when stringified
-      if(result[i].constructor && result[i].constructor.isBuffer) {
-        result[i] = result[i].toString();
-      } else {
-        try {
-          result[i] = JSON.stringify(result[i]);
-        } catch(stringifyError) {
-          // happens when an object has a circular structure
-          // do not throw an error, when printing, the toString() method of the object will be used
-        }
-      }
-    } else {
-      result[i] = result[i];
+    if (typeof requestHandler === 'function') {
+      this.request = requestHandler;
     }
   }
-  this.emit('item',  result.join(' ') + '\n');
-};
-
-module.exports = Stringify;
-
 
-/***/ }),
-/* 722 */
-/***/ ((module) => {
+  (0, _createClass2.default)(CozyLink, [{
+    key: "request",
+    value: function request(operation, result, forward) {
+      throw new Error('request is not implemented');
+    }
+  }]);
+  return CozyLink;
+}();
 
-function RedisBackend(options) {
-  this.client = options.client;
-  this.key = options.key;
-}
+exports["default"] = CozyLink;
 
-RedisBackend.prototype.write = function(str) {
-  this.client.rpush(this.key, str);
+var toLink = function toLink(handler) {
+  return typeof handler === 'function' ? new CozyLink(handler) : handler;
 };
 
-RedisBackend.prototype.end = function() {};
+var defaultLinkHandler = function defaultLinkHandler(operation, result) {
+  if (result) return result;else if (operation.execute) return operation.execute();else throw new Error("No link could handle operation ".concat(JSON.stringify(operation)));
+};
 
-RedisBackend.prototype.clear = function(cb) {
-  this.client.del(this.key, cb);
+var chain = function chain(links) {
+  return [].concat((0, _toConsumableArray2.default)(links), [defaultLinkHandler]).map(toLink).reduce(concat);
 };
 
-module.exports = RedisBackend;
+exports.chain = chain;
+
+var concat = function concat(firstLink, nextLink) {
+  return new CozyLink(function (operation, result, forward) {
+    var nextForward = function nextForward(op, res) {
+      return nextLink.request(op, res, forward);
+    };
 
+    return firstLink.request(operation, result, nextForward);
+  });
+};
 
 /***/ }),
-/* 723 */
+/* 700 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.QueryIDGenerator = exports.getQueryFromSlice = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports["default"] = exports.makeSorterFromDefinition = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.isReceivingData = exports.isQueryAction = void 0;
+exports.BulkEditError = void 0;
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _mapValues = _interopRequireDefault(__webpack_require__(533));
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _groupBy = _interopRequireDefault(__webpack_require__(724));
+var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664));
 
-var _difference = _interopRequireDefault(__webpack_require__(725));
+var _zipWith = _interopRequireDefault(__webpack_require__(701));
 
-var _intersection = _interopRequireDefault(__webpack_require__(727));
+var _types = __webpack_require__(622);
 
-var _concat = _interopRequireDefault(__webpack_require__(730));
+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; }
 
-var _isPlainObject = _interopRequireDefault(__webpack_require__(619));
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var _uniq = _interopRequireDefault(__webpack_require__(612));
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-var _orderBy = _interopRequireDefault(__webpack_require__(731));
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var _isArray = _interopRequireDefault(__webpack_require__(55));
+var BulkEditError = /*#__PURE__*/function (_Error) {
+  (0, _inherits2.default)(BulkEditError, _Error);
 
-var _isString = _interopRequireDefault(__webpack_require__(54));
+  var _super = _createSuper(BulkEditError);
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+  /**
+   * Indicates that a bulk edit has (potentially partially) failed
+   *
+   * @param  {CouchDBBulkResult[]} bulkResponse - CouchDB Bulk response
+   * @param  {CozyClientDocument[]} updatedDocs - Docs with updated _id and _rev
+   */
+  function BulkEditError(bulkResponse, updatedDocs) {
+    var _this;
 
-var _sift = _interopRequireDefault(__webpack_require__(737));
+    (0, _classCallCheck2.default)(this, BulkEditError);
+    _this = _super.call(this, 'Error while bulk saving');
+    _this.name = 'BulkEditError';
+    _this.results = (0, _zipWith.default)(bulkResponse, updatedDocs, function (result, doc) {
+      return _objectSpread(_objectSpread({}, result), {}, {
+        doc: doc
+      });
+    });
+    return _this;
+  }
+  /**
+   * Get documents that have been correctly updated
+   *
+   * @returns {CozyClientDocument[]}
+   */
 
-var _cozyFlags = _interopRequireDefault(__webpack_require__(603));
 
-var _documents = __webpack_require__(698);
+  (0, _createClass2.default)(BulkEditError, [{
+    key: "getUpdatedDocuments",
+    value: function getUpdatedDocuments() {
+      return this.results.filter(function (r) {
+        return r.ok;
+      }).map(function (r) {
+        return r.doc;
+      });
+    }
+    /**
+     * Get bulk errors results
+     *
+     * @returns {Array<CouchDBBulkResult & { doc: CozyClientDocument }>}
+     */
 
-var _mutations = __webpack_require__(738);
+  }, {
+    key: "getErrors",
+    value: function getErrors() {
+      return this.results.filter(function (r) {
+        return !r.ok;
+      });
+    }
+  }]);
+  return BulkEditError;
+}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
 
-var _helpers = __webpack_require__(739);
+exports.BulkEditError = BulkEditError;
 
-var _dsl = __webpack_require__(607);
+/***/ }),
+/* 701 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _types = __webpack_require__(610);
+var baseRest = __webpack_require__(556),
+    unzipWith = __webpack_require__(702);
 
-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; }
+/**
+ * This method is like `_.zip` except that it accepts `iteratee` to specify
+ * how grouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @param {Function} [iteratee=_.identity] The function to combine
+ *  grouped values.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+ *   return a + b + c;
+ * });
+ * // => [111, 222]
+ */
+var zipWith = baseRest(function(arrays) {
+  var length = arrays.length,
+      iteratee = length > 1 ? arrays[length - 1] : undefined;
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+  iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
+  return unzipWith(arrays, iteratee);
+});
 
-var INIT_QUERY = 'INIT_QUERY';
-var LOAD_QUERY = 'LOAD_QUERY';
-var RECEIVE_QUERY_RESULT = 'RECEIVE_QUERY_RESULT';
-var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR'; // Read if the devtools are open to store the execution time
-// This is done at runtime to not read the value everytime
-// we receive a result. So you have to refresh your page
-// in order to get the stats
+module.exports = zipWith;
 
-var executionStatsEnabled = (0, _cozyFlags.default)('debug');
 
-var isQueryAction = function isQueryAction(action) {
-  return [INIT_QUERY, LOAD_QUERY, RECEIVE_QUERY_RESULT, RECEIVE_QUERY_ERROR].indexOf(action.type) !== -1;
-};
+/***/ }),
+/* 702 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-exports.isQueryAction = isQueryAction;
+var apply = __webpack_require__(558),
+    arrayMap = __webpack_require__(410),
+    unzip = __webpack_require__(563);
 
-var isReceivingData = function isReceivingData(action) {
-  return action.type === RECEIVE_QUERY_RESULT;
-};
-/** @type {QueryState} */
+/**
+ * This method is like `_.unzip` except that it accepts `iteratee` to specify
+ * how regrouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @since 3.8.0
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @param {Function} [iteratee=_.identity] The function to combine
+ *  regrouped values.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
+ * // => [[1, 10, 100], [2, 20, 200]]
+ *
+ * _.unzipWith(zipped, _.add);
+ * // => [3, 30, 300]
+ */
+function unzipWith(array, iteratee) {
+  if (!(array && array.length)) {
+    return [];
+  }
+  var result = unzip(array);
+  if (iteratee == null) {
+    return result;
+  }
+  return arrayMap(result, function(group) {
+    return apply(iteratee, undefined, group);
+  });
+}
 
+module.exports = unzipWith;
 
-exports.isReceivingData = isReceivingData;
-var queryInitialState = {
-  id: null,
-  definition: null,
-  fetchStatus: 'pending',
-  lastFetch: null,
-  lastUpdate: null,
-  lastErrorUpdate: null,
-  lastError: null,
-  hasMore: false,
-  count: 0,
-  data: [],
-  bookmark: null
-};
 
-var updateQueryDataFromResponse = function updateQueryDataFromResponse(queryState, response, documents) {
-  var updatedIds = (0, _uniq.default)([].concat((0, _toConsumableArray2.default)(queryState.data), (0, _toConsumableArray2.default)(response.data.map(_helpers.properId))));
+/***/ }),
+/* 703 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+Object.defineProperty(exports, "HasManyFiles", ({
+  enumerable: true,
+  get: function get() {
+    return _HasManyFiles.default;
+  }
+}));
+Object.defineProperty(exports, "HasMany", ({
+  enumerable: true,
+  get: function get() {
+    return _HasMany.default;
+  }
+}));
+Object.defineProperty(exports, "HasOne", ({
+  enumerable: true,
+  get: function get() {
+    return _HasOne.default;
+  }
+}));
+Object.defineProperty(exports, "HasOneInPlace", ({
+  enumerable: true,
+  get: function get() {
+    return _HasOneInPlace.default;
+  }
+}));
+Object.defineProperty(exports, "HasManyInPlace", ({
+  enumerable: true,
+  get: function get() {
+    return _HasManyInPlace.default;
+  }
+}));
+Object.defineProperty(exports, "HasManyTriggers", ({
+  enumerable: true,
+  get: function get() {
+    return _HasManyTriggers.default;
+  }
+}));
+Object.defineProperty(exports, "Association", ({
+  enumerable: true,
+  get: function get() {
+    return _Association.default;
+  }
+}));
+Object.defineProperty(exports, "resolveClass", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.resolveClass;
+  }
+}));
+Object.defineProperty(exports, "create", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.create;
+  }
+}));
+Object.defineProperty(exports, "isReferencedBy", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.isReferencedBy;
+  }
+}));
+Object.defineProperty(exports, "isReferencedById", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.isReferencedById;
+  }
+}));
+Object.defineProperty(exports, "getReferencedBy", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.getReferencedBy;
+  }
+}));
+Object.defineProperty(exports, "getReferencedById", ({
+  enumerable: true,
+  get: function get() {
+    return _helpers.getReferencedById;
+  }
+}));
+
+var _HasManyFiles = _interopRequireDefault(__webpack_require__(704));
+
+var _HasMany = _interopRequireDefault(__webpack_require__(753));
 
-  if (queryState.definition.sort) {
-    var sorter = makeSorterFromDefinition(queryState.definition);
-    var doctype = queryState.definition.doctype;
-    var allDocs = documents[doctype];
-    var docs = allDocs ? updatedIds.map(function (_id) {
-      return allDocs[_id];
-    }).filter(Boolean) : [];
-    var sortedDocs = sorter(docs);
-    updatedIds = sortedDocs.map(_helpers.properId);
-  }
+var _HasOne = _interopRequireDefault(__webpack_require__(762));
 
-  return updatedIds;
-};
-/**
- * Reducer for a query slice
- *
- * @param  {QueryState} state - Current state
- * @param  {any} action - Redux action
- * @param  {DocumentsStateSlice} documents - Reference to the next documents slice
- * @returns {QueryState} - Next state
- */
+var _HasOneInPlace = _interopRequireDefault(__webpack_require__(764));
 
+var _HasManyInPlace = _interopRequireDefault(__webpack_require__(765));
 
-var query = function query() {
-  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : queryInitialState;
-  var action = arguments.length > 1 ? arguments[1] : undefined;
-  var documents = arguments.length > 2 ? arguments[2] : undefined;
+var _HasManyTriggers = _interopRequireDefault(__webpack_require__(766));
 
-  switch (action.type) {
-    case INIT_QUERY:
-      if (state.lastUpdate && state.id === action.queryId && state.definition === action.queryDefinition) {
-        return state;
-      }
+var _Association = _interopRequireDefault(__webpack_require__(752));
 
-      return _objectSpread(_objectSpread({}, state), {}, {
-        id: action.queryId,
-        definition: action.queryDefinition,
-        options: action.options,
-        // When the query is new, we set "fetchStatus" to "loading"
-        // directly since we know it will be loaded right away.
-        // This way, the loadQuery action will have no effect, and
-        // we save an additional render.
-        fetchStatus: state.lastUpdate ? state.fetchStatus : 'pending'
-      });
+var _helpers = __webpack_require__(767);
 
-    case LOAD_QUERY:
-      if (state.fetchStatus === 'loading') {
-        return state;
-      }
+/***/ }),
+/* 704 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-      return _objectSpread(_objectSpread({}, state), {}, {
-        fetchStatus: 'loading'
-      });
+"use strict";
 
-    case RECEIVE_QUERY_RESULT:
-      {
-        var response = action.response;
 
-        if (!response.data) {
-          return state;
-        }
-        /** @type {Partial<QueryState>} */
+var _interopRequireDefault = __webpack_require__(524);
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-        var common = _objectSpread({
-          fetchStatus: 'loaded',
-          lastFetch: Date.now(),
-          lastUpdate: Date.now()
-        }, executionStatsEnabled && {
-          execution_stats: response.execution_stats
-        });
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-        if (!Array.isArray(response.data)) {
-          return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
-            hasMore: false,
-            count: 1,
-            data: [(0, _helpers.properId)(response.data)]
-          });
-        }
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-        return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
-          bookmark: response.bookmark || null,
-          hasMore: response.next !== undefined ? response.next : state.hasMore,
-          count: response.meta && response.meta.count ? response.meta.count : response.data.length,
-          data: updateQueryDataFromResponse(state, response, documents)
-        });
-      }
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-    case RECEIVE_QUERY_ERROR:
-      return _objectSpread(_objectSpread({}, state), {}, {
-        id: action.queryId,
-        fetchStatus: 'failed',
-        lastError: action.error,
-        lastErrorUpdate: Date.now()
-      });
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-    default:
-      return state;
-  }
-};
-/**
- * Normalize sift selector
- *
- * @returns {object}
- */
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var convert$gtNullSelectors = function convert$gtNullSelectors(selector) {
-  var result = {};
+var _get3 = _interopRequireDefault(__webpack_require__(682));
 
-  for (var _i = 0, _Object$entries = Object.entries(selector); _i < _Object$entries.length; _i++) {
-    var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
-        key = _Object$entries$_i[0],
-        value = _Object$entries$_i[1];
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-    var convertedValue = (0, _isPlainObject.default)(value) ? convert$gtNullSelectors(value) : value;
-    var convertedKey = key === '$gt' && convertedValue === null ? '$gtnull' : key;
-    result[convertedKey] = convertedValue;
-  }
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-  return result;
-};
-/**
- * Merges query selectors with query partial indexes
- *
- * @param {object} queryDefinition - A query definition
- * @returns {object} A query definition selector
- */
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
 
-exports.convert$gtNullSelectors = convert$gtNullSelectors;
+var _get4 = _interopRequireDefault(__webpack_require__(370));
 
-var mergeSelectorAndPartialIndex = function mergeSelectorAndPartialIndex(queryDefinition) {
-  return _objectSpread(_objectSpread({}, queryDefinition.selector), (0, _get.default)(queryDefinition, 'partialFilter'));
-};
-/**
- * @param  {QueryDefinition} queryDefinition - A query definition
- * @returns {function(CozyClientDocument): boolean}
- */
+var _omit = _interopRequireDefault(__webpack_require__(625));
 
+var _uniq = _interopRequireDefault(__webpack_require__(624));
 
-exports.mergeSelectorAndPartialIndex = mergeSelectorAndPartialIndex;
+var _dsl = __webpack_require__(619);
 
-var getSelectorFilterFn = function getSelectorFilterFn(queryDefinition) {
-  if (queryDefinition.selector) {
-    var selectors = mergeSelectorAndPartialIndex(queryDefinition); // sift does not work like couchdb when using { $gt: null } as a selector, so we use a custom operator
+var _store = __webpack_require__(705);
 
-    _sift.default.use({
-      $gtnull: function $gtnull(_selectorValue, actualValue) {
-        return !!actualValue;
-      }
-    });
+var _types = __webpack_require__(622);
+
+var _const = __webpack_require__(697);
+
+var _Association = _interopRequireDefault(__webpack_require__(752));
+
+var _HasMany2 = _interopRequireDefault(__webpack_require__(753));
+
+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 _objectSpread(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) { (0, _defineProperty2.default)(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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-    return (0, _sift.default)(convert$gtNullSelectors(selectors));
-  } else if (queryDefinition.id) {
-    /** @type {object} */
-    var siftQuery = {
-      _id: queryDefinition.id
-    };
-    return (0, _sift.default)(siftQuery);
-  } else if (queryDefinition.ids) {
-    /** @type {object} */
-    var _siftQuery = {
-      _id: {
-        $in: queryDefinition.ids
-      }
-    };
-    return (0, _sift.default)(_siftQuery);
-  } else {
-    return null;
-  }
-};
 /**
+ * newCursor - Returns a CouchDB view Cursor for cursor-based pagination
  *
- * Returns a predicate function that checks if a document should be
- * included in the result of the query.
+ * @param {ViewKey} key - The CouchDB key of the view which will be requested
+ * @param {DocId} startDocId - The first doc _id to return from the view
  *
- * @param  {QueryState} query - Definition of the query
- * @returns {function(CozyClientDocument): boolean} Predicate function
+ * @returns {CouchDBViewCursor}
  */
+var newCursor = function newCursor(_ref, startDocId) {
+  var _ref2 = (0, _slicedToArray2.default)(_ref, 3),
+      doctype = _ref2[0],
+      id = _ref2[1],
+      lastDatetime = _ref2[2];
 
-
-var getQueryDocumentsChecker = function getQueryDocumentsChecker(query) {
-  var qdoctype = query.definition.doctype;
-  var selectorFilterFn = getSelectorFilterFn(query.definition);
-  return function (datum) {
-    var ddoctype = datum._type;
-    if (ddoctype !== qdoctype) return false;
-    if (datum._deleted) return false;
-    if (!selectorFilterFn) return true;
-    return !!selectorFilterFn(datum);
-  };
-};
-
-var makeCaseInsensitiveStringSorter = function makeCaseInsensitiveStringSorter(attrName) {
-  return function (item) {
-    var attrValue = (0, _get.default)(item, attrName);
-    return (0, _isString.default)(attrValue) ? attrValue.toLowerCase() : attrValue;
-  };
+  var cursorKey = lastDatetime ? [doctype, id, lastDatetime] : [doctype, id];
+  return [cursorKey, startDocId];
 };
 /**
- * Creates a sort function from a definition.
- *
- * Used to sort query results inside the store when creating a file or
- * receiving updates.
- *
- * @param {QueryDefinition} definition - A query definition
- * @returns {function(Array<CozyClientDocument>): Array<CozyClientDocument>}
- *
- * @private
+ *  This class is only used for photos albums relationships.
+ *  Behind the hood, the queries uses a view returning the files sorted
+ *  by datetime, with a cursor-based pagination.
  */
 
 
-var makeSorterFromDefinition = function makeSorterFromDefinition(definition) {
-  var sort = definition.sort;
+var HasManyFiles = /*#__PURE__*/function (_HasMany) {
+  (0, _inherits2.default)(HasManyFiles, _HasMany);
 
-  if (!sort) {
-    return function (docs) {
-      return docs;
-    };
-  } else if (!(0, _isArray.default)(definition.sort)) {
-    console.warn('Correct update of queries with a sort that is not an array is not supported. Use an array as argument of QueryDefinition::sort');
-    return function (docs) {
-      return docs;
-    };
-  } else {
-    var attributeOrders = sort.map(function (x) {
-      return Object.entries(x)[0];
-    });
-    var attrs = attributeOrders.map(function (x) {
-      return x[0];
-    }).map(makeCaseInsensitiveStringSorter);
-    var orders = attributeOrders.map(function (x) {
-      return x[1];
-    });
-    return function (docs) {
-      return (0, _orderBy.default)(docs, attrs, orders);
-    };
+  var _super = _createSuper(HasManyFiles);
+
+  function HasManyFiles() {
+    (0, _classCallCheck2.default)(this, HasManyFiles);
+    return _super.apply(this, arguments);
   }
-};
-/**
- * Updates query state when new data comes in
- *
- * @param  {QueryState} query - Current query state
- * @param  {Array<CozyClientDocument>} newData - New documents (in most case from the server)
- * @param  {DocumentsStateSlice} documents - A reference to the documents slice
- * @returns {QueryState} - Updated query state
- */
 
+  (0, _createClass2.default)(HasManyFiles, [{
+    key: "fetchMore",
+    value: function () {
+      var _fetchMore = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+        var _this = this;
 
-exports.makeSorterFromDefinition = makeSorterFromDefinition;
+        var queryDef, relationships, lastRelationship;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                queryDef = new _dsl.QueryDefinition({
+                  doctype: _const.DOCTYPE_FILES
+                });
+                relationships = this.getRelationship().data; // Get last datetime for cursor
 
-var updateData = function updateData(query, newData, documents) {
-  var belongsToQuery = getQueryDocumentsChecker(query);
-  var res = (0, _mapValues.default)((0, _groupBy.default)(newData, belongsToQuery), function (docs) {
-    return docs.map(_helpers.properId);
-  });
-  var _res$true = res.true,
-      matchedIds = _res$true === void 0 ? [] : _res$true,
-      _res$false = res.false,
-      unmatchedIds = _res$false === void 0 ? [] : _res$false;
-  var originalIds = query.data;
-  var autoUpdate = query.options && query.options.autoUpdate;
-  var shouldRemove = !autoUpdate || autoUpdate.remove !== false;
-  var shouldAdd = !autoUpdate || autoUpdate.add !== false;
-  var shouldUpdate = !autoUpdate || autoUpdate.update !== false;
-  var toRemove = shouldRemove ? (0, _intersection.default)(originalIds, unmatchedIds) : [];
-  var toAdd = shouldAdd ? (0, _difference.default)(matchedIds, originalIds) : [];
-  var toUpdate = shouldUpdate ? (0, _intersection.default)(originalIds, matchedIds) : [];
-  var changed = toRemove.length || toAdd.length || toUpdate.length; // concat doesn't check duplicates (contrarily to union), which is ok as
-  // toAdd does not contain any id present in originalIds, by construction.
-  // It is also faster than union.
+                lastRelationship = relationships[relationships.length - 1];
+                _context2.next = 5;
+                return this.dispatch( /*#__PURE__*/function () {
+                  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(dispatch, getState) {
+                    var lastRelDoc, lastDatetime, cursor, response;
+                    return _regenerator.default.wrap(function _callee$(_context) {
+                      while (1) {
+                        switch (_context.prev = _context.next) {
+                          case 0:
+                            lastRelDoc = (0, _store.getDocumentFromState)(getState(), lastRelationship._type, lastRelationship._id); // Photos always have a datetime field in metadata
 
-  var updatedData = (0, _difference.default)((0, _concat.default)(originalIds, toAdd), toRemove);
+                            lastDatetime = lastRelDoc.attributes.metadata.datetime; // cursor-based pagination
 
-  if (query.definition.sort && documents) {
-    var sorter = makeSorterFromDefinition(query.definition);
-    var allDocs = documents[query.definition.doctype];
-    var docs = updatedData.map(function (_id) {
-      return allDocs[_id];
-    });
-    var sortedDocs = sorter(docs);
-    updatedData = sortedDocs.map(_helpers.properId);
-  }
+                            cursor = newCursor([_this.target._type, _this.target._id, lastDatetime], relationships[relationships.length - 1]._id);
+                            _context.next = 5;
+                            return _this.query(queryDef.referencedBy(_this.target).offsetCursor(cursor));
 
-  return _objectSpread(_objectSpread({}, query), {}, {
-    data: updatedData,
-    count: updatedData.length,
-    lastUpdate: changed ? Date.now() : query.lastUpdate
-  });
-};
-/**
- * Creates a function that returns an updated query state
- * from an action
- *
- * @param  {object} action - A redux action
- * @param  {DocumentsStateSlice} documents - Reference to documents slice
- * @returns {function(QueryState): QueryState} - Updater query state
- */
+                          case 5:
+                            response = _context.sent;
+                            // Remove first returned element, used as starting point for the query
+                            response.data.shift();
+                            _context.next = 9;
+                            return _this.dispatch(_this.updateRelationshipData(function (previousRelationshipData) {
+                              return _objectSpread(_objectSpread({}, previousRelationshipData), {}, {
+                                data: [].concat((0, _toConsumableArray2.default)(previousRelationshipData.data), (0, _toConsumableArray2.default)(response.data)),
+                                next: response.next
+                              });
+                            }));
 
+                          case 9:
+                          case "end":
+                            return _context.stop();
+                        }
+                      }
+                    }, _callee);
+                  }));
 
-var autoQueryUpdater = function autoQueryUpdater(action, documents) {
-  return function (query) {
-    var data = (0, _get.default)(action, 'response.data') || (0, _get.default)(action, 'definition.document');
-    if (!data) return query;
+                  return function (_x, _x2) {
+                    return _ref3.apply(this, arguments);
+                  };
+                }());
 
-    if (!Array.isArray(data)) {
-      data = [data];
-    }
+              case 5:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
 
-    if (!data.length) {
-      return query;
-    }
+      function fetchMore() {
+        return _fetchMore.apply(this, arguments);
+      }
 
-    if (query.definition.doctype !== data[0]._type) {
-      return query;
-    }
+      return fetchMore;
+    }()
+  }, {
+    key: "addById",
+    value: function () {
+      var _addById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(idsArg) {
+        var _this2 = this;
 
-    return updateData(query, data, documents);
-  };
-};
-/**
- * Creates a function that returns an updated query state
- * from an action
- *
- * @param  {object} action - A redux action
- * @param  {DocumentsStateSlice} documents - Reference to documents slice
- * @returns {function(QueryState): QueryState} - Updater query state
- */
+        var ids, relations;
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                ids = Array.isArray(idsArg) ? idsArg : [idsArg];
+                relations = ids.map(function (id) {
+                  return {
+                    _id: id,
+                    _type: _this2.doctype
+                  };
+                });
+                _context3.next = 4;
+                return this.mutate(this.addReferences(relations));
 
+              case 4:
+                this.addTargetRelationships(ids);
 
-var manualQueryUpdater = function manualQueryUpdater(action, documents) {
-  return function (query) {
-    var updateQueries = action.updateQueries;
-    var response = action.response;
-    var updater = updateQueries[query.id];
+              case 5:
+              case "end":
+                return _context3.stop();
+            }
+          }
+        }, _callee3, this);
+      }));
 
-    if (!updater) {
-      return query;
-    }
+      function addById(_x3) {
+        return _addById.apply(this, arguments);
+      }
 
-    var doctype = query.definition.doctype;
-    var oldData = query.data;
-    var oldDocs = mapIdsToDocuments(documents, doctype, oldData);
-    var newData = updater(oldDocs, response);
-    var newDataIds = newData.map(_helpers.properId);
-    return _objectSpread(_objectSpread({}, query), {}, {
-      data: newDataIds,
-      count: newDataIds.length,
-      lastUpdate: Date.now()
-    });
-  };
-};
-/**
- * @param  {QueriesStateSlice}  state - Redux slice containing all the query states indexed by name
- * @param  {object}  action - Income redux action
- * @param  {DocumentsStateSlice}  documents - Reference to documents slice
- * @param  {boolean} haveDocumentsChanged - Has the document slice changed with current action
- * @returns {QueriesStateSlice}
- */
+      return addById;
+    }()
+  }, {
+    key: "removeById",
+    value: function () {
+      var _removeById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(idsArg) {
+        var _this3 = this;
+
+        var ids, references;
+        return _regenerator.default.wrap(function _callee4$(_context4) {
+          while (1) {
+            switch (_context4.prev = _context4.next) {
+              case 0:
+                ids = Array.isArray(idsArg) ? idsArg : [idsArg];
+                references = ids.map(function (id) {
+                  return {
+                    _id: id,
+                    _type: _this3.doctype
+                  };
+                });
+                _context4.next = 4;
+                return this.mutate(this.removeReferences(references));
 
+              case 4:
+                this.removeTargetRelationships(ids);
 
-var queries = function queries() {
-  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  var action = arguments.length > 1 ? arguments[1] : undefined;
-  var documents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-  var haveDocumentsChanged = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
+              case 5:
+              case "end":
+                return _context4.stop();
+            }
+          }
+        }, _callee4, this);
+      }));
 
-  if (action.type == INIT_QUERY) {
-    var newQueryState = query(state[action.queryId], action, documents); // Do not create new object unnecessarily
+      function removeById(_x4) {
+        return _removeById.apply(this, arguments);
+      }
 
-    if (newQueryState === state[action.queryId]) {
-      return state;
+      return removeById;
+    }()
+  }, {
+    key: "addReferences",
+    value: function addReferences(referencedDocs) {
+      if (this.target._type === _const.DOCTYPE_FILES) {
+        return _dsl.Mutations.addReferencedBy(this.target, referencedDocs);
+      } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) {
+        return _dsl.Mutations.addReferencesTo(this.target, referencedDocs);
+      } else {
+        throw new Error('Either the document or the references should be io.cozy.files');
+      }
+    }
+  }, {
+    key: "removeReferences",
+    value: function removeReferences(referencedDocs) {
+      if (this.target._type === _const.DOCTYPE_FILES) {
+        return _dsl.Mutations.removeReferencedBy(this.target, referencedDocs);
+      } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) {
+        return _dsl.Mutations.removeReferencesTo(this.target, referencedDocs);
+      } else {
+        throw new Error('Either the document or the references should be io.cozy.files');
+      }
+    }
+  }, {
+    key: "dehydrate",
+    value: function dehydrate(doc) {
+      // HasManyFiles relationships are stored on the file doctype, not the document the files are related to
+      return (0, _omit.default)(doc, [this.name, "relationships.".concat(this.name)]);
     }
+    /**
+     * @param {CozyClientDocument} document - Document to query
+     * @param {object} client - The CozyClient instance
+     * @param {Association} assoc - The query params
+     *
+     * @returns {CozyClientDocument | QueryDefinition}
+     */
 
-    return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, action.queryId, newQueryState));
-  }
+  }, {
+    key: "data",
+    get: function get() {
+      var _this4 = this;
 
-  if (isQueryAction(action)) {
-    var updater = autoQueryUpdater(action, documents);
-    return (0, _mapValues.default)(state, function (queryState) {
-      if (queryState.id == action.queryId) {
-        return query(queryState, action, documents);
-      } else if (haveDocumentsChanged) {
-        return updater(queryState);
+      if (this.target._type === _const.DOCTYPE_FILES) {
+        var refs = (0, _get4.default)(this.target, 'referenced_by', []);
+        return refs.map(function (_ref4) {
+          var id = _ref4.id,
+              type = _ref4.type;
+          return _this4.get(type, id);
+        }).filter(Boolean);
       } else {
-        return queryState;
+        return (0, _get3.default)((0, _getPrototypeOf2.default)(HasManyFiles.prototype), "data", this);
       }
-    });
-  }
+    }
+  }], [{
+    key: "query",
+    value: function query(document, client, assoc) {
+      if (document._type === _const.DOCTYPE_FILES) {
+        var refs = (0, _get4.default)(document, "relationships.referenced_by.data", []);
+        var ids = (0, _uniq.default)(refs.filter(function (ref) {
+          return ref.type === assoc.doctype;
+        }).map(function (ref) {
+          return ref.id;
+        }));
+        return ids.length > 0 ? (0, _dsl.Q)(assoc.doctype).getByIds(ids) : null;
+      } else {
+        var cursor = newCursor([document._type, document._id], '');
+        return (0, _dsl.Q)(assoc.doctype).referencedBy(document).offsetCursor(cursor);
+      }
+    }
+  }]);
+  return HasManyFiles;
+}(_HasMany2.default);
 
-  if ((0, _mutations.isReceivingMutationResult)(action)) {
-    var _updater = action.updateQueries ? manualQueryUpdater(action, documents) : autoQueryUpdater(action, documents);
+exports["default"] = HasManyFiles;
 
-    return (0, _mapValues.default)(state, _updater);
-  }
+/***/ }),
+/* 705 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  return state;
-};
+"use strict";
 
-var _default = queries;
-/**
- * Create the query states in the store. Queries are indexed
- * in the store by queryId
- *
- * @param  {string} queryId  Name/id of the query
- * @param  {QueryDefinition} queryDefinition - Definition of the created query
- * @param  {QueryOptions} [options] - Options for the created query
- */
 
-exports["default"] = _default;
+var _interopRequireWildcard = __webpack_require__(522);
 
-var initQuery = function initQuery(queryId, queryDefinition) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
+var _interopRequireDefault = __webpack_require__(524);
 
-  if (!queryDefinition.doctype) {
-    throw new Error('Cannot init query with no doctype');
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+Object.defineProperty(exports, "initQuery", ({
+  enumerable: true,
+  get: function get() {
+    return _queries.initQuery;
+  }
+}));
+Object.defineProperty(exports, "loadQuery", ({
+  enumerable: true,
+  get: function get() {
+    return _queries.loadQuery;
+  }
+}));
+Object.defineProperty(exports, "receiveQueryResult", ({
+  enumerable: true,
+  get: function get() {
+    return _queries.receiveQueryResult;
+  }
+}));
+Object.defineProperty(exports, "receiveQueryError", ({
+  enumerable: true,
+  get: function get() {
+    return _queries.receiveQueryError;
+  }
+}));
+Object.defineProperty(exports, "initMutation", ({
+  enumerable: true,
+  get: function get() {
+    return _mutations.initMutation;
+  }
+}));
+Object.defineProperty(exports, "receiveMutationResult", ({
+  enumerable: true,
+  get: function get() {
+    return _mutations.receiveMutationResult;
   }
+}));
+Object.defineProperty(exports, "receiveMutationError", ({
+  enumerable: true,
+  get: function get() {
+    return _mutations.receiveMutationError;
+  }
+}));
+exports.resetState = exports.getRawQueryFromState = exports.getQueryFromState = exports.getQueryFromStore = exports.getDocumentFromState = exports.getCollectionFromState = exports.getStateRoot = exports.createStore = exports["default"] = exports.StoreProxy = void 0;
 
-  return {
-    type: INIT_QUERY,
-    queryId: queryId,
-    queryDefinition: queryDefinition,
-    options: options
-  };
-};
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-exports.initQuery = initQuery;
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var loadQuery = function loadQuery(queryId) {
-  return {
-    type: LOAD_QUERY,
-    queryId: queryId
-  };
-};
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-exports.loadQuery = loadQuery;
+var _cozyFlags = _interopRequireDefault(__webpack_require__(615));
 
-var receiveQueryResult = function receiveQueryResult(queryId, response) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-  return _objectSpread({
-    type: RECEIVE_QUERY_RESULT,
-    queryId: queryId,
-    response: response
-  }, options);
-};
+var _redux = __webpack_require__(706);
 
-exports.receiveQueryResult = receiveQueryResult;
+var _reduxThunk = _interopRequireDefault(__webpack_require__(709));
 
-var receiveQueryError = function receiveQueryError(queryId, error) {
-  return {
-    type: RECEIVE_QUERY_ERROR,
-    queryId: queryId,
-    error: error
-  };
-}; // selectors
+var _documents = _interopRequireWildcard(__webpack_require__(710));
 
+var _queries = _interopRequireWildcard(__webpack_require__(735));
 
-exports.receiveQueryError = receiveQueryError;
+var _mutations = __webpack_require__(750);
 
-var mapIdsToDocuments = function mapIdsToDocuments(documents, doctype, ids) {
-  return ids.map(function (id) {
-    return (0, _documents.getDocumentFromSlice)(documents, doctype, id);
-  });
-};
+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; }
 
-var getQueryFromSlice = function getQueryFromSlice(state, queryId, documents) {
-  if (!state || !state[queryId]) {
-    return _objectSpread(_objectSpread({}, queryInitialState), {}, {
-      id: queryId,
-      data: null
-    });
-  }
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-  var query = state[queryId];
-  return documents ? _objectSpread(_objectSpread({}, query), {}, {
-    data: mapIdsToDocuments(documents, query.definition.doctype, query.data)
-  }) : query;
+var RESET_ACTION_TYPE = 'COZY_CLIENT.RESET_STATE';
+
+var resetState = function resetState() {
+  return {
+    type: RESET_ACTION_TYPE
+  };
 };
 
-exports.getQueryFromSlice = getQueryFromSlice;
+exports.resetState = resetState;
 
-var QueryIDGenerator = /*#__PURE__*/function () {
-  function QueryIDGenerator() {
-    (0, _classCallCheck2.default)(this, QueryIDGenerator);
-    this.idCounter = 1;
+var StoreProxy = /*#__PURE__*/function () {
+  function StoreProxy(state) {
+    (0, _classCallCheck2.default)(this, StoreProxy);
+    this.state = state;
   }
-  /**
-   * Generates a random id for unamed queries
-   */
-
 
-  (0, _createClass2.default)(QueryIDGenerator, [{
-    key: "generateRandomId",
-    value: function generateRandomId() {
-      var id = this.idCounter;
-      this.idCounter++;
-      return id.toString();
+  (0, _createClass2.default)(StoreProxy, [{
+    key: "readDocument",
+    value: function readDocument(doctype, id) {
+      return this.state.documents[doctype][id];
     }
-    /**
-     * Generates an id for queries
-     * If the query is a getById only query,
-     * we can generate a name for it.
-     *
-     * If not, let's generate a random id
-     *
-     * @param {QueryDefinition} queryDefinition The query definition
-     * @returns {string}
-     */
-
   }, {
-    key: "generateId",
-    value: function generateId(queryDefinition) {
-      if (!(0, _dsl.isAGetByIdQuery)(queryDefinition)) {
-        return this.generateRandomId();
-      } else {
-        var id = queryDefinition.id,
-            doctype = queryDefinition.doctype;
-        return "".concat(doctype, "/").concat(id);
-      }
+    key: "writeDocument",
+    value: function writeDocument(document) {
+      this.setState(function (state) {
+        return _objectSpread(_objectSpread({}, state), {}, {
+          documents: _objectSpread(_objectSpread({}, state.documents), {}, (0, _defineProperty2.default)({}, document._type, _objectSpread(_objectSpread({}, state.documents[document._type]), {}, (0, _defineProperty2.default)({}, document._id, document))))
+        });
+      });
+    }
+  }, {
+    key: "setState",
+    value: function setState(updaterFn) {
+      this.state = updaterFn(this.state);
+    }
+  }, {
+    key: "getState",
+    value: function getState() {
+      return this.state;
     }
   }]);
-  return QueryIDGenerator;
+  return StoreProxy;
 }();
 
-exports.QueryIDGenerator = QueryIDGenerator;
-QueryIDGenerator.UNNAMED = 'unnamed';
-
-/***/ }),
-/* 724 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+exports.StoreProxy = StoreProxy;
+var initialState = {
+  documents: {},
+  queries: {}
+};
 
-var baseAssignValue = __webpack_require__(534),
-    createAggregator = __webpack_require__(700);
+var combinedReducer = function combinedReducer() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
+  var action = arguments.length > 1 ? arguments[1] : undefined;
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+  if (action.type == RESET_ACTION_TYPE) {
+    return initialState;
+  }
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+  if (!(0, _queries.isQueryAction)(action) && !(0, _mutations.isMutationAction)(action)) {
+    return state;
+  }
 
-/**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` thru `iteratee`. The order of grouped values
- * is determined by the order they occur in `collection`. The corresponding
- * value of each key is an array of elements responsible for generating the
- * key. The iteratee is invoked with one argument: (value).
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Collection
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([6.1, 4.2, 6.3], Math.floor);
- * // => { '4': [4.2], '6': [6.1, 6.3] }
- *
- * // The `_.property` iteratee shorthand.
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
-var groupBy = createAggregator(function(result, value, key) {
-  if (hasOwnProperty.call(result, key)) {
-    result[key].push(value);
-  } else {
-    baseAssignValue(result, key, [value]);
+  if (action.update) {
+    var proxy = new StoreProxy(state);
+    action.update(proxy, action.response);
+    return {
+      documents: proxy.getState().documents,
+      queries: (0, _queries.default)(proxy.getState().queries, action, proxy.getState().documents)
+    };
   }
-});
 
-module.exports = groupBy;
+  var nextDocuments = (0, _documents.default)(state.documents, action);
+  var haveDocumentsChanged = nextDocuments !== state.documents;
+  return {
+    documents: nextDocuments,
+    queries: (0, _queries.default)(state.queries, action, nextDocuments, haveDocumentsChanged)
+  };
+};
 
+var _default = combinedReducer;
+exports["default"] = _default;
 
-/***/ }),
-/* 725 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var composedEnhancer = // @ts-ignore '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__' doesn't exist 'Window & typeof globalThis'.ts(2339)
+// should be (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ in ts file
+// see https://github.com/reduxjs/redux-devtools/tree/main/extension#11-basic-store
+(0, _cozyFlags.default)('debug') && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose;
 
-var baseDifference = __webpack_require__(726),
-    baseFlatten = __webpack_require__(541),
-    baseRest = __webpack_require__(544),
-    isArrayLikeObject = __webpack_require__(552);
+var createStore = function createStore() {
+  return (0, _redux.createStore)((0, _redux.combineReducers)({
+    cozy: combinedReducer
+  }), composedEnhancer((0, _redux.applyMiddleware)(_reduxThunk.default)));
+};
 
-/**
- * Creates an array of `array` values not included in the other given arrays
- * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * for equality comparisons. The order and references of result values are
- * determined by the first array.
- *
- * **Note:** Unlike `_.pullAll`, this method returns a new array.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {Array} array The array to inspect.
- * @param {...Array} [values] The values to exclude.
- * @returns {Array} Returns the new array of filtered values.
- * @see _.without, _.xor
- * @example
- *
- * _.difference([2, 1], [2, 3]);
- * // => [1]
- */
-var difference = baseRest(function(array, values) {
-  return isArrayLikeObject(array)
-    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
-    : [];
-});
+exports.createStore = createStore;
 
-module.exports = difference;
+var getStateRoot = function getStateRoot(state) {
+  return state.cozy || {};
+};
 
+exports.getStateRoot = getStateRoot;
 
-/***/ }),
-/* 726 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var getCollectionFromState = function getCollectionFromState(state, doctype) {
+  return (0, _documents.getCollectionFromSlice)(getStateRoot(state).documents, doctype);
+};
 
-var SetCache = __webpack_require__(413),
-    arrayIncludes = __webpack_require__(464),
-    arrayIncludesWith = __webpack_require__(469),
-    arrayMap = __webpack_require__(398),
-    baseUnary = __webpack_require__(440),
-    cacheHas = __webpack_require__(417);
+exports.getCollectionFromState = getCollectionFromState;
 
-/** Used as the size to enable large array optimizations. */
-var LARGE_ARRAY_SIZE = 200;
+var getDocumentFromState = function getDocumentFromState(state, doctype, id) {
+  return (0, _documents.getDocumentFromSlice)(getStateRoot(state).documents, doctype, id);
+};
 
-/**
- * The base implementation of methods like `_.difference` without support
- * for excluding multiple arrays or iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Array} values The values to exclude.
- * @param {Function} [iteratee] The iteratee invoked per element.
- * @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns the new array of filtered values.
- */
-function baseDifference(array, values, iteratee, comparator) {
-  var index = -1,
-      includes = arrayIncludes,
-      isCommon = true,
-      length = array.length,
-      result = [],
-      valuesLength = values.length;
+exports.getDocumentFromState = getDocumentFromState;
 
-  if (!length) {
-    return result;
-  }
-  if (iteratee) {
-    values = arrayMap(values, baseUnary(iteratee));
-  }
-  if (comparator) {
-    includes = arrayIncludesWith;
-    isCommon = false;
-  }
-  else if (values.length >= LARGE_ARRAY_SIZE) {
-    includes = cacheHas;
-    isCommon = false;
-    values = new SetCache(values);
-  }
-  outer:
-  while (++index < length) {
-    var value = array[index],
-        computed = iteratee == null ? value : iteratee(value);
+var getQueryFromStore = function getQueryFromStore(store, queryId) {
+  return getQueryFromState(store.getState(), queryId);
+};
 
-    value = (comparator || value !== 0) ? value : 0;
-    if (isCommon && computed === computed) {
-      var valuesIndex = valuesLength;
-      while (valuesIndex--) {
-        if (values[valuesIndex] === computed) {
-          continue outer;
-        }
-      }
-      result.push(value);
-    }
-    else if (!includes(values, computed, comparator)) {
-      result.push(value);
-    }
-  }
-  return result;
-}
+exports.getQueryFromStore = getQueryFromStore;
 
-module.exports = baseDifference;
+var getQueryFromState = function getQueryFromState(state, queryId) {
+  return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId, getStateRoot(state).documents);
+};
+
+exports.getQueryFromState = getQueryFromState;
+
+var getRawQueryFromState = function getRawQueryFromState(state, queryId) {
+  return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId);
+};
 
+exports.getRawQueryFromState = getRawQueryFromState;
 
 /***/ }),
-/* 727 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 706 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "__DO_NOT_USE__ActionTypes": () => (/* binding */ ActionTypes),
+/* harmony export */   "applyMiddleware": () => (/* binding */ applyMiddleware),
+/* harmony export */   "bindActionCreators": () => (/* binding */ bindActionCreators),
+/* harmony export */   "combineReducers": () => (/* binding */ combineReducers),
+/* harmony export */   "compose": () => (/* binding */ compose),
+/* harmony export */   "createStore": () => (/* binding */ createStore)
+/* harmony export */ });
+/* harmony import */ var _babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(707);
 
-var arrayMap = __webpack_require__(398),
-    baseIntersection = __webpack_require__(728),
-    baseRest = __webpack_require__(544),
-    castArrayLikeObject = __webpack_require__(729);
 
 /**
- * Creates an array of unique values that are included in all given arrays
- * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * for equality comparisons. The order and references of result values are
- * determined by the first array.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {...Array} [arrays] The arrays to inspect.
- * @returns {Array} Returns the new array of intersecting values.
- * @example
+ * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js
  *
- * _.intersection([2, 1], [2, 3]);
- * // => [2]
+ * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes
+ * during build.
+ * @param {number} code
  */
-var intersection = baseRest(function(arrays) {
-  var mapped = arrayMap(arrays, castArrayLikeObject);
-  return (mapped.length && mapped[0] === arrays[0])
-    ? baseIntersection(mapped)
-    : [];
-});
-
-module.exports = intersection;
-
+function formatProdErrorMessage(code) {
+  return "Minified Redux error #" + code + "; visit https://redux.js.org/Errors?code=" + code + " for the full message or " + 'use the non-minified dev environment for full errors. ';
+}
 
-/***/ }),
-/* 728 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+// Inlined version of the `symbol-observable` polyfill
+var $$observable = (function () {
+  return typeof Symbol === 'function' && Symbol.observable || '@@observable';
+})();
 
-var SetCache = __webpack_require__(413),
-    arrayIncludes = __webpack_require__(464),
-    arrayIncludesWith = __webpack_require__(469),
-    arrayMap = __webpack_require__(398),
-    baseUnary = __webpack_require__(440),
-    cacheHas = __webpack_require__(417);
+/**
+ * These are private action types reserved by Redux.
+ * For any unknown actions, you must return the current state.
+ * If the current state is undefined, you must return the initial state.
+ * Do not reference these action types directly in your code.
+ */
+var randomString = function randomString() {
+  return Math.random().toString(36).substring(7).split('').join('.');
+};
 
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeMin = Math.min;
+var ActionTypes = {
+  INIT: "@@redux/INIT" + randomString(),
+  REPLACE: "@@redux/REPLACE" + randomString(),
+  PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {
+    return "@@redux/PROBE_UNKNOWN_ACTION" + randomString();
+  }
+};
 
 /**
- * The base implementation of methods like `_.intersection`, without support
- * for iteratee shorthands, that accepts an array of arrays to inspect.
- *
- * @private
- * @param {Array} arrays The arrays to inspect.
- * @param {Function} [iteratee] The iteratee invoked per element.
- * @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns the new array of shared values.
+ * @param {any} obj The object to inspect.
+ * @returns {boolean} True if the argument appears to be a plain object.
  */
-function baseIntersection(arrays, iteratee, comparator) {
-  var includes = comparator ? arrayIncludesWith : arrayIncludes,
-      length = arrays[0].length,
-      othLength = arrays.length,
-      othIndex = othLength,
-      caches = Array(othLength),
-      maxLength = Infinity,
-      result = [];
+function isPlainObject(obj) {
+  if (typeof obj !== 'object' || obj === null) return false;
+  var proto = obj;
 
-  while (othIndex--) {
-    var array = arrays[othIndex];
-    if (othIndex && iteratee) {
-      array = arrayMap(array, baseUnary(iteratee));
-    }
-    maxLength = nativeMin(array.length, maxLength);
-    caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
-      ? new SetCache(othIndex && array)
-      : undefined;
+  while (Object.getPrototypeOf(proto) !== null) {
+    proto = Object.getPrototypeOf(proto);
   }
-  array = arrays[0];
 
-  var index = -1,
-      seen = caches[0];
+  return Object.getPrototypeOf(obj) === proto;
+}
 
-  outer:
-  while (++index < length && result.length < maxLength) {
-    var value = array[index],
-        computed = iteratee ? iteratee(value) : value;
+// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of
+function miniKindOf(val) {
+  if (val === void 0) return 'undefined';
+  if (val === null) return 'null';
+  var type = typeof val;
 
-    value = (comparator || value !== 0) ? value : 0;
-    if (!(seen
-          ? cacheHas(seen, computed)
-          : includes(result, computed, comparator)
-        )) {
-      othIndex = othLength;
-      while (--othIndex) {
-        var cache = caches[othIndex];
-        if (!(cache
-              ? cacheHas(cache, computed)
-              : includes(arrays[othIndex], computed, comparator))
-            ) {
-          continue outer;
-        }
-      }
-      if (seen) {
-        seen.push(computed);
+  switch (type) {
+    case 'boolean':
+    case 'string':
+    case 'number':
+    case 'symbol':
+    case 'function':
+      {
+        return type;
       }
-      result.push(value);
-    }
   }
-  return result;
-}
 
-module.exports = baseIntersection;
+  if (Array.isArray(val)) return 'array';
+  if (isDate(val)) return 'date';
+  if (isError(val)) return 'error';
+  var constructorName = ctorName(val);
 
+  switch (constructorName) {
+    case 'Symbol':
+    case 'Promise':
+    case 'WeakMap':
+    case 'WeakSet':
+    case 'Map':
+    case 'Set':
+      return constructorName;
+  } // other
 
-/***/ }),
-/* 729 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var isArrayLikeObject = __webpack_require__(552);
+  return type.slice(8, -1).toLowerCase().replace(/\s/g, '');
+}
 
-/**
- * Casts `value` to an empty array if it's not an array like object.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {Array|Object} Returns the cast array-like object.
- */
-function castArrayLikeObject(value) {
-  return isArrayLikeObject(value) ? value : [];
+function ctorName(val) {
+  return typeof val.constructor === 'function' ? val.constructor.name : null;
 }
 
-module.exports = castArrayLikeObject;
+function isError(val) {
+  return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';
+}
 
+function isDate(val) {
+  if (val instanceof Date) return true;
+  return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';
+}
 
-/***/ }),
-/* 730 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function kindOf(val) {
+  var typeOfVal = typeof val;
 
-var arrayPush = __webpack_require__(425),
-    baseFlatten = __webpack_require__(541),
-    copyArray = __webpack_require__(571),
-    isArray = __webpack_require__(55);
+  if (process.env.NODE_ENV !== 'production') {
+    typeOfVal = miniKindOf(val);
+  }
+
+  return typeOfVal;
+}
 
 /**
- * Creates a new array concatenating `array` with any additional arrays
- * and/or values.
+ * Creates a Redux store that holds the state tree.
+ * The only way to change the data in the store is to call `dispatch()` on it.
  *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Array
- * @param {Array} array The array to concatenate.
- * @param {...*} [values] The values to concatenate.
- * @returns {Array} Returns the new concatenated array.
- * @example
+ * There should only be a single store in your app. To specify how different
+ * parts of the state tree respond to actions, you may combine several reducers
+ * into a single reducer function by using `combineReducers`.
  *
- * var array = [1];
- * var other = _.concat(array, 2, [3], [[4]]);
+ * @param {Function} reducer A function that returns the next state tree, given
+ * the current state tree and the action to handle.
  *
- * console.log(other);
- * // => [1, 2, 3, [4]]
+ * @param {any} [preloadedState] The initial state. You may optionally specify it
+ * to hydrate the state from the server in universal apps, or to restore a
+ * previously serialized user session.
+ * If you use `combineReducers` to produce the root reducer function, this must be
+ * an object with the same shape as `combineReducers` keys.
  *
- * console.log(array);
- * // => [1]
+ * @param {Function} [enhancer] The store enhancer. You may optionally specify it
+ * to enhance the store with third-party capabilities such as middleware,
+ * time travel, persistence, etc. The only store enhancer that ships with Redux
+ * is `applyMiddleware()`.
+ *
+ * @returns {Store} A Redux store that lets you read the state, dispatch actions
+ * and subscribe to changes.
  */
-function concat() {
-  var length = arguments.length;
-  if (!length) {
-    return [];
+
+function createStore(reducer, preloadedState, enhancer) {
+  var _ref2;
+
+  if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {
+    throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');
   }
-  var args = Array(length - 1),
-      array = arguments[0],
-      index = length;
 
-  while (index--) {
-    args[index - 1] = arguments[index];
+  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
+    enhancer = preloadedState;
+    preloadedState = undefined;
   }
-  return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
-}
 
-module.exports = concat;
+  if (typeof enhancer !== 'undefined') {
+    if (typeof enhancer !== 'function') {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(1) : "Expected the enhancer to be a function. Instead, received: '" + kindOf(enhancer) + "'");
+    }
 
+    return enhancer(createStore)(reducer, preloadedState);
+  }
 
-/***/ }),
-/* 731 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  if (typeof reducer !== 'function') {
+    throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : "Expected the root reducer to be a function. Instead, received: '" + kindOf(reducer) + "'");
+  }
 
-var baseOrderBy = __webpack_require__(732),
-    isArray = __webpack_require__(55);
+  var currentReducer = reducer;
+  var currentState = preloadedState;
+  var currentListeners = [];
+  var nextListeners = currentListeners;
+  var isDispatching = false;
+  /**
+   * This makes a shallow copy of currentListeners so we can use
+   * nextListeners as a temporary list while dispatching.
+   *
+   * This prevents any bugs around consumers calling
+   * subscribe/unsubscribe in the middle of a dispatch.
+   */
 
-/**
- * This method is like `_.sortBy` except that it allows specifying the sort
- * orders of the iteratees to sort by. If `orders` is unspecified, all values
- * are sorted in ascending order. Otherwise, specify an order of "desc" for
- * descending or "asc" for ascending sort order of corresponding values.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Collection
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
- *  The iteratees to sort by.
- * @param {string[]} [orders] The sort orders of `iteratees`.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
- * @returns {Array} Returns the new sorted array.
- * @example
- *
- * var users = [
- *   { 'user': 'fred',   'age': 48 },
- *   { 'user': 'barney', 'age': 34 },
- *   { 'user': 'fred',   'age': 40 },
- *   { 'user': 'barney', 'age': 36 }
- * ];
- *
- * // Sort by `user` in ascending order and by `age` in descending order.
- * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
- * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
- */
-function orderBy(collection, iteratees, orders, guard) {
-  if (collection == null) {
-    return [];
-  }
-  if (!isArray(iteratees)) {
-    iteratees = iteratees == null ? [] : [iteratees];
+  function ensureCanMutateNextListeners() {
+    if (nextListeners === currentListeners) {
+      nextListeners = currentListeners.slice();
+    }
   }
-  orders = guard ? undefined : orders;
-  if (!isArray(orders)) {
-    orders = orders == null ? [] : [orders];
+  /**
+   * Reads the state tree managed by the store.
+   *
+   * @returns {any} The current state tree of your application.
+   */
+
+
+  function getState() {
+    if (isDispatching) {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');
+    }
+
+    return currentState;
   }
-  return baseOrderBy(collection, iteratees, orders);
-}
+  /**
+   * Adds a change listener. It will be called any time an action is dispatched,
+   * and some part of the state tree may potentially have changed. You may then
+   * call `getState()` to read the current state tree inside the callback.
+   *
+   * You may call `dispatch()` from a change listener, with the following
+   * caveats:
+   *
+   * 1. The subscriptions are snapshotted just before every `dispatch()` call.
+   * If you subscribe or unsubscribe while the listeners are being invoked, this
+   * will not have any effect on the `dispatch()` that is currently in progress.
+   * However, the next `dispatch()` call, whether nested or not, will use a more
+   * recent snapshot of the subscription list.
+   *
+   * 2. The listener should not expect to see all state changes, as the state
+   * might have been updated multiple times during a nested `dispatch()` before
+   * the listener is called. It is, however, guaranteed that all subscribers
+   * registered before the `dispatch()` started will be called with the latest
+   * state by the time it exits.
+   *
+   * @param {Function} listener A callback to be invoked on every dispatch.
+   * @returns {Function} A function to remove this change listener.
+   */
 
-module.exports = orderBy;
 
+  function subscribe(listener) {
+    if (typeof listener !== 'function') {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(4) : "Expected the listener to be a function. Instead, received: '" + kindOf(listener) + "'");
+    }
 
-/***/ }),
-/* 732 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    if (isDispatching) {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');
+    }
 
-var arrayMap = __webpack_require__(398),
-    baseGet = __webpack_require__(359),
-    baseIteratee = __webpack_require__(401),
-    baseMap = __webpack_require__(733),
-    baseSortBy = __webpack_require__(734),
-    baseUnary = __webpack_require__(440),
-    compareMultiple = __webpack_require__(735),
-    identity = __webpack_require__(459),
-    isArray = __webpack_require__(55);
+    var isSubscribed = true;
+    ensureCanMutateNextListeners();
+    nextListeners.push(listener);
+    return function unsubscribe() {
+      if (!isSubscribed) {
+        return;
+      }
 
-/**
- * The base implementation of `_.orderBy` without param guards.
- *
- * @private
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
- * @param {string[]} orders The sort orders of `iteratees`.
- * @returns {Array} Returns the new sorted array.
- */
-function baseOrderBy(collection, iteratees, orders) {
-  if (iteratees.length) {
-    iteratees = arrayMap(iteratees, function(iteratee) {
-      if (isArray(iteratee)) {
-        return function(value) {
-          return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
-        }
+      if (isDispatching) {
+        throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');
       }
-      return iteratee;
-    });
-  } else {
-    iteratees = [identity];
+
+      isSubscribed = false;
+      ensureCanMutateNextListeners();
+      var index = nextListeners.indexOf(listener);
+      nextListeners.splice(index, 1);
+      currentListeners = null;
+    };
   }
+  /**
+   * Dispatches an action. It is the only way to trigger a state change.
+   *
+   * The `reducer` function, used to create the store, will be called with the
+   * current state tree and the given `action`. Its return value will
+   * be considered the **next** state of the tree, and the change listeners
+   * will be notified.
+   *
+   * The base implementation only supports plain object actions. If you want to
+   * dispatch a Promise, an Observable, a thunk, or something else, you need to
+   * wrap your store creating function into the corresponding middleware. For
+   * example, see the documentation for the `redux-thunk` package. Even the
+   * middleware will eventually dispatch plain object actions using this method.
+   *
+   * @param {Object} action A plain object representing “what changed”. It is
+   * a good idea to keep actions serializable so you can record and replay user
+   * sessions, or use the time travelling `redux-devtools`. An action must have
+   * a `type` property which may not be `undefined`. It is a good idea to use
+   * string constants for action types.
+   *
+   * @returns {Object} For convenience, the same action object you dispatched.
+   *
+   * Note that, if you use a custom middleware, it may wrap `dispatch()` to
+   * return something else (for example, a Promise you can await).
+   */
 
-  var index = -1;
-  iteratees = arrayMap(iteratees, baseUnary(baseIteratee));
 
-  var result = baseMap(collection, function(value, key, collection) {
-    var criteria = arrayMap(iteratees, function(iteratee) {
-      return iteratee(value);
-    });
-    return { 'criteria': criteria, 'index': ++index, 'value': value };
-  });
+  function dispatch(action) {
+    if (!isPlainObject(action)) {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(7) : "Actions must be plain objects. Instead, the actual type was: '" + kindOf(action) + "'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.");
+    }
 
-  return baseSortBy(result, function(object, other) {
-    return compareMultiple(object, other, orders);
-  });
-}
+    if (typeof action.type === 'undefined') {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(8) : 'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.');
+    }
 
-module.exports = baseOrderBy;
+    if (isDispatching) {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');
+    }
 
+    try {
+      isDispatching = true;
+      currentState = currentReducer(currentState, action);
+    } finally {
+      isDispatching = false;
+    }
 
-/***/ }),
-/* 733 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    var listeners = currentListeners = nextListeners;
 
-var baseEach = __webpack_require__(555),
-    isArrayLike = __webpack_require__(446);
+    for (var i = 0; i < listeners.length; i++) {
+      var listener = listeners[i];
+      listener();
+    }
 
-/**
- * The base implementation of `_.map` without support for iteratee shorthands.
- *
- * @private
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the new mapped array.
- */
-function baseMap(collection, iteratee) {
-  var index = -1,
-      result = isArrayLike(collection) ? Array(collection.length) : [];
+    return action;
+  }
+  /**
+   * Replaces the reducer currently used by the store to calculate the state.
+   *
+   * You might need this if your app implements code splitting and you want to
+   * load some of the reducers dynamically. You might also need this if you
+   * implement a hot reloading mechanism for Redux.
+   *
+   * @param {Function} nextReducer The reducer for the store to use instead.
+   * @returns {void}
+   */
 
-  baseEach(collection, function(value, key, collection) {
-    result[++index] = iteratee(value, key, collection);
-  });
-  return result;
-}
 
-module.exports = baseMap;
+  function replaceReducer(nextReducer) {
+    if (typeof nextReducer !== 'function') {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(10) : "Expected the nextReducer to be a function. Instead, received: '" + kindOf(nextReducer));
+    }
 
+    currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.
+    // Any reducers that existed in both the new and old rootReducer
+    // will receive the previous state. This effectively populates
+    // the new state tree with any relevant data from the old one.
 
-/***/ }),
-/* 734 */
-/***/ ((module) => {
+    dispatch({
+      type: ActionTypes.REPLACE
+    });
+  }
+  /**
+   * Interoperability point for observable/reactive libraries.
+   * @returns {observable} A minimal observable of state changes.
+   * For more information, see the observable proposal:
+   * https://github.com/tc39/proposal-observable
+   */
 
-/**
- * The base implementation of `_.sortBy` which uses `comparer` to define the
- * sort order of `array` and replaces criteria objects with their corresponding
- * values.
- *
- * @private
- * @param {Array} array The array to sort.
- * @param {Function} comparer The function to define sort order.
- * @returns {Array} Returns `array`.
- */
-function baseSortBy(array, comparer) {
-  var length = array.length;
 
-  array.sort(comparer);
-  while (length--) {
-    array[length] = array[length].value;
-  }
-  return array;
-}
+  function observable() {
+    var _ref;
 
-module.exports = baseSortBy;
+    var outerSubscribe = subscribe;
+    return _ref = {
+      /**
+       * The minimal observable subscription method.
+       * @param {Object} observer Any object that can be used as an observer.
+       * The observer object should have a `next` method.
+       * @returns {subscription} An object with an `unsubscribe` method that can
+       * be used to unsubscribe the observable from the store, and prevent further
+       * emission of values from the observable.
+       */
+      subscribe: function subscribe(observer) {
+        if (typeof observer !== 'object' || observer === null) {
+          throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(11) : "Expected the observer to be an object. Instead, received: '" + kindOf(observer) + "'");
+        }
 
+        function observeState() {
+          if (observer.next) {
+            observer.next(getState());
+          }
+        }
+
+        observeState();
+        var unsubscribe = outerSubscribe(observeState);
+        return {
+          unsubscribe: unsubscribe
+        };
+      }
+    }, _ref[$$observable] = function () {
+      return this;
+    }, _ref;
+  } // When a store is created, an "INIT" action is dispatched so that every
+  // reducer returns their initial state. This effectively populates
+  // the initial state tree.
 
-/***/ }),
-/* 735 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var compareAscending = __webpack_require__(736);
+  dispatch({
+    type: ActionTypes.INIT
+  });
+  return _ref2 = {
+    dispatch: dispatch,
+    subscribe: subscribe,
+    getState: getState,
+    replaceReducer: replaceReducer
+  }, _ref2[$$observable] = observable, _ref2;
+}
 
 /**
- * Used by `_.orderBy` to compare multiple properties of a value to another
- * and stable sort them.
- *
- * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
- * specify an order of "desc" for descending or "asc" for ascending sort order
- * of corresponding values.
+ * Prints a warning in the console if it exists.
  *
- * @private
- * @param {Object} object The object to compare.
- * @param {Object} other The other object to compare.
- * @param {boolean[]|string[]} orders The order to sort by for each property.
- * @returns {number} Returns the sort order indicator for `object`.
+ * @param {String} message The warning message.
+ * @returns {void}
  */
-function compareMultiple(object, other, orders) {
-  var index = -1,
-      objCriteria = object.criteria,
-      othCriteria = other.criteria,
-      length = objCriteria.length,
-      ordersLength = orders.length;
-
-  while (++index < length) {
-    var result = compareAscending(objCriteria[index], othCriteria[index]);
-    if (result) {
-      if (index >= ordersLength) {
-        return result;
-      }
-      var order = orders[index];
-      return result * (order == 'desc' ? -1 : 1);
-    }
+function warning(message) {
+  /* eslint-disable no-console */
+  if (typeof console !== 'undefined' && typeof console.error === 'function') {
+    console.error(message);
   }
-  // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
-  // that causes it, under certain circumstances, to provide the same value for
-  // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
-  // for more details.
-  //
-  // This also ensures a stable sort in V8 and other engines.
-  // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
-  return object.index - other.index;
-}
+  /* eslint-enable no-console */
 
-module.exports = compareMultiple;
 
+  try {
+    // This error was thrown as a convenience so that if you enable
+    // "break on all exceptions" in your console,
+    // it would pause the execution at this line.
+    throw new Error(message);
+  } catch (e) {} // eslint-disable-line no-empty
 
-/***/ }),
-/* 736 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+}
 
-var isSymbol = __webpack_require__(362);
+function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
+  var reducerKeys = Object.keys(reducers);
+  var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';
 
-/**
- * Compares values to sort them in ascending order.
- *
- * @private
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {number} Returns the sort order indicator for `value`.
- */
-function compareAscending(value, other) {
-  if (value !== other) {
-    var valIsDefined = value !== undefined,
-        valIsNull = value === null,
-        valIsReflexive = value === value,
-        valIsSymbol = isSymbol(value);
+  if (reducerKeys.length === 0) {
+    return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';
+  }
 
-    var othIsDefined = other !== undefined,
-        othIsNull = other === null,
-        othIsReflexive = other === other,
-        othIsSymbol = isSymbol(other);
+  if (!isPlainObject(inputState)) {
+    return "The " + argumentName + " has unexpected type of \"" + kindOf(inputState) + "\". Expected argument to be an object with the following " + ("keys: \"" + reducerKeys.join('", "') + "\"");
+  }
 
-    if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
-        (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
-        (valIsNull && othIsDefined && othIsReflexive) ||
-        (!valIsDefined && othIsReflexive) ||
-        !valIsReflexive) {
-      return 1;
-    }
-    if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
-        (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
-        (othIsNull && valIsDefined && valIsReflexive) ||
-        (!othIsDefined && valIsReflexive) ||
-        !othIsReflexive) {
-      return -1;
-    }
+  var unexpectedKeys = Object.keys(inputState).filter(function (key) {
+    return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];
+  });
+  unexpectedKeys.forEach(function (key) {
+    unexpectedKeyCache[key] = true;
+  });
+  if (action && action.type === ActionTypes.REPLACE) return;
+
+  if (unexpectedKeys.length > 0) {
+    return "Unexpected " + (unexpectedKeys.length > 1 ? 'keys' : 'key') + " " + ("\"" + unexpectedKeys.join('", "') + "\" found in " + argumentName + ". ") + "Expected to find one of the known reducer keys instead: " + ("\"" + reducerKeys.join('", "') + "\". Unexpected keys will be ignored.");
   }
-  return 0;
 }
 
-module.exports = compareAscending;
-
+function assertReducerShape(reducers) {
+  Object.keys(reducers).forEach(function (key) {
+    var reducer = reducers[key];
+    var initialState = reducer(undefined, {
+      type: ActionTypes.INIT
+    });
 
-/***/ }),
-/* 737 */
-/***/ ((module, exports) => {
+    if (typeof initialState === 'undefined') {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(12) : "The slice reducer for key \"" + key + "\" returned undefined during initialization. " + "If the state passed to the reducer is undefined, you must " + "explicitly return the initial state. The initial state may " + "not be undefined. If you don't want to set a value for this reducer, " + "you can use null instead of undefined.");
+    }
 
-/*
- * Sift 3.x
+    if (typeof reducer(undefined, {
+      type: ActionTypes.PROBE_UNKNOWN_ACTION()
+    }) === 'undefined') {
+      throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(13) : "The slice reducer for key \"" + key + "\" returned undefined when probed with a random type. " + ("Don't try to handle '" + ActionTypes.INIT + "' or other actions in \"redux/*\" ") + "namespace. They are considered private. Instead, you must return the " + "current state for any unknown actions, unless it is undefined, " + "in which case you must return the initial state, regardless of the " + "action type. The initial state may not be undefined, but can be null.");
+    }
+  });
+}
+/**
+ * Turns an object whose values are different reducer functions, into a single
+ * reducer function. It will call every child reducer, and gather their results
+ * into a single state object, whose keys correspond to the keys of the passed
+ * reducer functions.
  *
- * Copryright 2015, Craig Condon
- * Licensed under MIT
+ * @param {Object} reducers An object whose values correspond to different
+ * reducer functions that need to be combined into one. One handy way to obtain
+ * it is to use ES6 `import * as reducers` syntax. The reducers may never return
+ * undefined for any action. Instead, they should return their initial state
+ * if the state passed to them was undefined, and the current state for any
+ * unrecognized action.
  *
- * Filter JavaScript objects with mongodb queries
+ * @returns {Function} A reducer function that invokes every reducer inside the
+ * passed object, and builds a state object with the same shape.
  */
 
-(function() {
-
-  'use strict';
-
-  /**
-   */
-
-  function isFunction(value) {
-    return typeof value === 'function';
-  }
-
-  /**
-   */
 
-  function isArray(value) {
-    return Object.prototype.toString.call(value) === '[object Array]';
-  }
+function combineReducers(reducers) {
+  var reducerKeys = Object.keys(reducers);
+  var finalReducers = {};
 
-  /**
-   */
+  for (var i = 0; i < reducerKeys.length; i++) {
+    var key = reducerKeys[i];
 
-  function comparable(value) {
-    if (value instanceof Date) {
-      return value.getTime();
-    } else if (isArray(value)) {
-      return value.map(comparable);
-    } else if (value && typeof value.toJSON === 'function') {
-      return value.toJSON();
-    } else {
-      return value;
+    if (process.env.NODE_ENV !== 'production') {
+      if (typeof reducers[key] === 'undefined') {
+        warning("No reducer provided for key \"" + key + "\"");
+      }
     }
-  }
-
-  function get(obj, key) {
-    return isFunction(obj.get) ? obj.get(key) : obj[key];
-  }
-
-  /**
-   */
 
-  function or(validator) {
-    return function(a, b) {
-      if (!isArray(b) || !b.length) {
-        return validator(a, b);
-      }
-      for (var i = 0, n = b.length; i < n; i++) {
-        if (validator(a, get(b,i))) return true;
-      }
-      return false;
+    if (typeof reducers[key] === 'function') {
+      finalReducers[key] = reducers[key];
     }
   }
 
-  /**
-   */
+  var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same
+  // keys multiple times.
 
-  function and(validator) {
-    return function(a, b) {
-      if (!isArray(b) || !b.length) {
-        return validator(a, b);
-      }
-      for (var i = 0, n = b.length; i < n; i++) {
-        if (!validator(a, get(b, i))) return false;
-      }
-      return true;
-    };
-  }
+  var unexpectedKeyCache;
 
-  function validate(validator, b, k, o) {
-    return validator.v(validator.a, b, k, o);
+  if (process.env.NODE_ENV !== 'production') {
+    unexpectedKeyCache = {};
   }
 
-  var OPERATORS = {
-
-    /**
-     */
-
-    $eq: or(function(a, b) {
-      return a(b);
-    }),
+  var shapeAssertionError;
 
-    /**
-     */
+  try {
+    assertReducerShape(finalReducers);
+  } catch (e) {
+    shapeAssertionError = e;
+  }
 
-    $ne: and(function(a, b) {
-      return !a(b);
-    }),
+  return function combination(state, action) {
+    if (state === void 0) {
+      state = {};
+    }
 
-    /**
-     */
+    if (shapeAssertionError) {
+      throw shapeAssertionError;
+    }
 
-    $gt: or(function(a, b) {
-      return sift.compare(comparable(b), a) > 0;
-    }),
+    if (process.env.NODE_ENV !== 'production') {
+      var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);
 
-    /**
-     */
+      if (warningMessage) {
+        warning(warningMessage);
+      }
+    }
 
-    $gte: or(function(a, b) {
-      return sift.compare(comparable(b), a) >= 0;
-    }),
+    var hasChanged = false;
+    var nextState = {};
 
-    /**
-     */
+    for (var _i = 0; _i < finalReducerKeys.length; _i++) {
+      var _key = finalReducerKeys[_i];
+      var reducer = finalReducers[_key];
+      var previousStateForKey = state[_key];
+      var nextStateForKey = reducer(previousStateForKey, action);
 
-    $lt: or(function(a, b) {
-      return sift.compare(comparable(b), a) < 0;
-    }),
+      if (typeof nextStateForKey === 'undefined') {
+        var actionType = action && action.type;
+        throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(14) : "When called with an action of type " + (actionType ? "\"" + String(actionType) + "\"" : '(unknown type)') + ", the slice reducer for key \"" + _key + "\" returned undefined. " + "To ignore an action, you must explicitly return the previous state. " + "If you want this reducer to hold no value, you can return null instead of undefined.");
+      }
 
-    /**
-     */
+      nextState[_key] = nextStateForKey;
+      hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
+    }
 
-    $lte: or(function(a, b) {
-      return sift.compare(comparable(b), a) <= 0;
-    }),
+    hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;
+    return hasChanged ? nextState : state;
+  };
+}
 
-    /**
-     */
+function bindActionCreator(actionCreator, dispatch) {
+  return function () {
+    return dispatch(actionCreator.apply(this, arguments));
+  };
+}
+/**
+ * Turns an object whose values are action creators, into an object with the
+ * same keys, but with every function wrapped into a `dispatch` call so they
+ * may be invoked directly. This is just a convenience method, as you can call
+ * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
+ *
+ * For convenience, you can also pass an action creator as the first argument,
+ * and get a dispatch wrapped function in return.
+ *
+ * @param {Function|Object} actionCreators An object whose values are action
+ * creator functions. One handy way to obtain it is to use ES6 `import * as`
+ * syntax. You may also pass a single function.
+ *
+ * @param {Function} dispatch The `dispatch` function available on your Redux
+ * store.
+ *
+ * @returns {Function|Object} The object mimicking the original object, but with
+ * every action creator wrapped into the `dispatch` call. If you passed a
+ * function as `actionCreators`, the return value will also be a single
+ * function.
+ */
 
-    $mod: or(function(a, b) {
-      return b % a[0] == a[1];
-    }),
 
-    /**
-     */
+function bindActionCreators(actionCreators, dispatch) {
+  if (typeof actionCreators === 'function') {
+    return bindActionCreator(actionCreators, dispatch);
+  }
 
-    $in: function(a, b) {
+  if (typeof actionCreators !== 'object' || actionCreators === null) {
+    throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(16) : "bindActionCreators expected an object or a function, but instead received: '" + kindOf(actionCreators) + "'. " + "Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?");
+  }
 
-      if (b instanceof Array) {
-        for (var i = b.length; i--;) {
-          if (~a.indexOf(comparable(get(b, i)))) {
-            return true;
-          }
-        }
-      } else {
-        var comparableB = comparable(b);
-        if (comparableB === b && typeof b === 'object') {
-          for (var i = a.length; i--;) {
-            if (String(a[i]) === String(b) && String(b) !== '[object Object]') {
-              return true;
-            }
-          }
-        }
+  var boundActionCreators = {};
 
-        /*
-          Handles documents that are undefined, whilst also
-          having a 'null' element in the parameters to $in.
-        */
-        if (typeof comparableB == 'undefined') {
-          for (var i = a.length; i--;) {
-            if (a[i] == null) {
-              return true;
-            }
-          }
-        }
+  for (var key in actionCreators) {
+    var actionCreator = actionCreators[key];
 
-        /*
-          Handles the case of {'field': {$in: [/regexp1/, /regexp2/, ...]}}
-        */
-        for (var i = a.length; i--;) {
-          var validator = createRootValidator(get(a, i), undefined);
-          var result = validate(validator, b, i, a);
-          if ((result) && (String(result) !== '[object Object]') && (String(b) !== '[object Object]')) {
-            return true;
-          }
-        }
+    if (typeof actionCreator === 'function') {
+      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
+    }
+  }
 
-        return !!~a.indexOf(comparableB);
-      }
+  return boundActionCreators;
+}
 
-      return false;
-    },
+/**
+ * Composes single-argument functions from right to left. The rightmost
+ * function can take multiple arguments as it provides the signature for
+ * the resulting composite function.
+ *
+ * @param {...Function} funcs The functions to compose.
+ * @returns {Function} A function obtained by composing the argument functions
+ * from right to left. For example, compose(f, g, h) is identical to doing
+ * (...args) => f(g(h(...args))).
+ */
+function compose() {
+  for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {
+    funcs[_key] = arguments[_key];
+  }
 
-    /**
-     */
+  if (funcs.length === 0) {
+    return function (arg) {
+      return arg;
+    };
+  }
 
-    $nin: function(a, b, k, o) {
-      return !OPERATORS.$in(a, b, k, o);
-    },
+  if (funcs.length === 1) {
+    return funcs[0];
+  }
 
-    /**
-     */
+  return funcs.reduce(function (a, b) {
+    return function () {
+      return a(b.apply(void 0, arguments));
+    };
+  });
+}
 
-    $not: function(a, b, k, o) {
-      return !validate(a, b, k, o);
-    },
+/**
+ * Creates a store enhancer that applies middleware to the dispatch method
+ * of the Redux store. This is handy for a variety of tasks, such as expressing
+ * asynchronous actions in a concise manner, or logging every action payload.
+ *
+ * See `redux-thunk` package as an example of the Redux middleware.
+ *
+ * Because middleware is potentially asynchronous, this should be the first
+ * store enhancer in the composition chain.
+ *
+ * Note that each middleware will be given the `dispatch` and `getState` functions
+ * as named arguments.
+ *
+ * @param {...Function} middlewares The middleware chain to be applied.
+ * @returns {Function} A store enhancer applying the middleware.
+ */
 
-    /**
-     */
+function applyMiddleware() {
+  for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {
+    middlewares[_key] = arguments[_key];
+  }
 
-    $type: function(a, b) {
-      return b != void 0 ? b instanceof a || b.constructor == a : false;
-     },
+  return function (createStore) {
+    return function () {
+      var store = createStore.apply(void 0, arguments);
 
-    /**
-     */
+      var _dispatch = function dispatch() {
+        throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');
+      };
 
-    $all: function(a, b, k, o) {
-      return OPERATORS.$and(a, b, k, o);
-    },
+      var middlewareAPI = {
+        getState: store.getState,
+        dispatch: function dispatch() {
+          return _dispatch.apply(void 0, arguments);
+        }
+      };
+      var chain = middlewares.map(function (middleware) {
+        return middleware(middlewareAPI);
+      });
+      _dispatch = compose.apply(void 0, chain)(store.dispatch);
+      return (0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, store), {}, {
+        dispatch: _dispatch
+      });
+    };
+  };
+}
 
-    /**
-     */
+/*
+ * This is a dummy function to check if the function name has been altered by minification.
+ * If the function has been minified and NODE_ENV !== 'production', warn the user.
+ */
 
-    $size: function(a, b) {
-      return b ? a === b.length : false;
-    },
+function isCrushed() {}
 
-    /**
-     */
+if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
+  warning('You are currently using minified code outside of NODE_ENV === "production". ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.');
+}
 
-    $or: function(a, b, k, o) {
-      for (var i = 0, n = a.length; i < n; i++) if (validate(get(a, i), b, k, o)) return true;
-      return false;
-    },
 
-    /**
-     */
 
-    $nor: function(a, b, k, o) {
-      return !OPERATORS.$or(a, b, k, o);
-    },
 
-    /**
-     */
+/***/ }),
+/* 707 */
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-    $and: function(a, b, k, o) {
-      for (var i = 0, n = a.length; i < n; i++) {
-        if (!validate(get(a, i), b, k, o)) {
-          return false;
-        }
-      }
-      return true;
-    },
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (/* binding */ _objectSpread2)
+/* harmony export */ });
+/* harmony import */ var _defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(708);
 
-    /**
-     */
 
-    $regex: or(function(a, b) {
-      return typeof b === 'string' && a.test(b);
-    }),
+function ownKeys(object, enumerableOnly) {
+  var keys = Object.keys(object);
 
-    /**
-     */
+  if (Object.getOwnPropertySymbols) {
+    var symbols = Object.getOwnPropertySymbols(object);
 
-    $where: function(a, b, k, o) {
-      return a.call(b, b, k, o);
-    },
+    if (enumerableOnly) {
+      symbols = symbols.filter(function (sym) {
+        return Object.getOwnPropertyDescriptor(object, sym).enumerable;
+      });
+    }
 
-    /**
-     */
+    keys.push.apply(keys, symbols);
+  }
 
-    $elemMatch: function(a, b, k, o) {
-      if (isArray(b)) {
-        return !!~search(b, a);
-      }
-      return validate(a, b, k, o);
-    },
+  return keys;
+}
 
-    /**
-     */
+function _objectSpread2(target) {
+  for (var i = 1; i < arguments.length; i++) {
+    var source = arguments[i] != null ? arguments[i] : {};
 
-    $exists: function(a, b, k, o) {
-      return o.hasOwnProperty(k) === a;
+    if (i % 2) {
+      ownKeys(Object(source), true).forEach(function (key) {
+        (0,_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__["default"])(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;
+}
 
-  var prepare = {
+/***/ }),
+/* 708 */
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-    /**
-     */
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (/* binding */ _defineProperty)
+/* harmony export */ });
+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;
+  }
 
-    $eq: function(a) {
+  return obj;
+}
 
-      if (a instanceof RegExp) {
-        return function(b) {
-          return typeof b === 'string' && a.test(b);
-        };
-      } else if (a instanceof Function) {
-        return a;
-      } else if (isArray(a) && !a.length) {
-        // Special case of a == []
-        return function(b) {
-          return (isArray(b) && !b.length);
-        };
-      } else if (a === null){
-        return function(b){
-          //will match both null and undefined
-          return b == null;
+/***/ }),
+/* 709 */
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+function createThunkMiddleware(extraArgument) {
+  return function (_ref) {
+    var dispatch = _ref.dispatch,
+        getState = _ref.getState;
+    return function (next) {
+      return function (action) {
+        if (typeof action === 'function') {
+          return action(dispatch, getState, extraArgument);
         }
-      }
 
-      return function(b) {
-        return sift.compare(comparable(b), a) === 0;
+        return next(action);
       };
-    },
-
-    /**
-     */
+    };
+  };
+}
 
-    $ne: function(a) {
-      return prepare.$eq(a);
-    },
+var thunk = createThunkMiddleware();
+thunk.withExtraArgument = createThunkMiddleware;
 
-    /**
-     */
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (thunk);
 
-    $and: function(a) {
-      return a.map(parse);
-    },
+/***/ }),
+/* 710 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-    /**
-     */
+"use strict";
 
-    $all: function(a) {
-      return prepare.$and(a);
-    },
 
-    /**
-     */
+var _interopRequireDefault = __webpack_require__(524);
 
-    $or: function(a) {
-      return a.map(parse);
-    },
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.extractAndMergeDocument = exports.getCollectionFromSlice = exports.getDocumentFromSlice = exports["default"] = exports.mergeDocumentsWithRelationships = void 0;
 
-    /**
-     */
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-    $nor: function(a) {
-      return a.map(parse);
-    },
+var _keyBy = _interopRequireDefault(__webpack_require__(711));
 
-    /**
-     */
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-    $not: function(a) {
-      return parse(a);
-    },
+var _isEqual = _interopRequireDefault(__webpack_require__(658));
 
-    /**
-     */
+var _omit = _interopRequireDefault(__webpack_require__(625));
 
-    $regex: function(a, query) {
-      return new RegExp(a, query.$options);
-    },
+var _logger = _interopRequireDefault(__webpack_require__(715));
 
-    /**
-     */
+var _queries = __webpack_require__(735);
 
-    $where: function(a) {
-      return typeof a === 'string' ? new Function('obj', 'return ' + a) : a;
-    },
+var _dsl = __webpack_require__(619);
 
-    /**
-     */
+var _mutations = __webpack_require__(750);
 
-    $elemMatch: function(a) {
-      return parse(a);
-    },
+var _types = __webpack_require__(622);
 
-    /**
-     */
+var _helpers = __webpack_require__(751);
 
-    $exists: function(a) {
-      return !!a;
-    }
-  };
+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 _objectSpread(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) { (0, _defineProperty2.default)(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 search(array, validator) {
+var storeDocument = function storeDocument(state, document) {
+  var type = document._type;
 
-    for (var i = 0; i < array.length; i++) {
-      var result = get(array, i);
-      if (validate(validator, get(array, i))) {
-        return i;
-      }
+  if (!type) {
+    if (process.env.NODE_ENV !== 'production') {
+      _logger.default.info('Document without _type', document);
     }
 
-    return -1;
+    throw new Error('Document without _type');
   }
 
-  /**
-   */
+  if (!(0, _helpers.properId)(document)) {
+    if (process.env.NODE_ENV !== 'production') {
+      _logger.default.info('Document without id', document);
+    }
 
-  function createValidator(a, validate) {
-    return { a: a, v: validate };
+    throw new Error('Document without id');
   }
 
-  /**
-   */
-
-  function nestedValidator(a, b) {
-    var values  = [];
-    findValues(b, a.k, 0, b, values);
-
-    if (values.length === 1) {
-      var first = values[0];
-      return validate(a.nv, first[0], first[1], first[2]);
-    }
+  var existingDoc = (0, _get.default)(state, [type, (0, _helpers.properId)(document)]);
 
-    // If the query contains $ne, need to test all elements ANDed together
-    var inclusive = a && a.q && typeof a.q.$ne !== 'undefined';
-    var allValid = inclusive;
-    for (var i = 0; i < values.length; i++) {
-      var result = values[i];
-      var isValid = validate(a.nv, result[0], result[1], result[2]);
-      if (inclusive) {
-        allValid &= isValid;
-      } else {
-        allValid |= isValid;
-      }
-    }
-    return allValid;
+  if ((0, _isEqual.default)(existingDoc, document)) {
+    return state;
+  } else {
+    return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, type, _objectSpread(_objectSpread({}, state[type]), {}, (0, _defineProperty2.default)({}, (0, _helpers.properId)(document), mergeDocumentsWithRelationships(existingDoc, document)))));
   }
+};
+
+var mergeDocumentsWithRelationships = function mergeDocumentsWithRelationships() {
+  var prevDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  var nextDocument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 
   /**
+   * @type {CozyClientDocument}
    */
+  var merged = _objectSpread(_objectSpread({}, prevDocument), nextDocument);
 
-  function findValues(current, keypath, index, object, values) {
+  if (prevDocument.relationships || nextDocument.relationships) merged.relationships = _objectSpread(_objectSpread({}, prevDocument.relationships), nextDocument.relationships);
+  return merged;
+}; // reducer
 
-    if (index === keypath.length || current == void 0) {
 
-      values.push([current, keypath[index - 1], object]);
-      return;
-    }
+exports.mergeDocumentsWithRelationships = mergeDocumentsWithRelationships;
 
-    var k = get(keypath, index);
+var documents = function documents() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  var action = arguments.length > 1 ? arguments[1] : undefined;
 
-    // ensure that if current is an array, that the current key
-    // is NOT an array index. This sort of thing needs to work:
-    // sift({'foo.0':42}, [{foo: [42]}]);
-    if (isArray(current) && isNaN(Number(k))) {
-      for (var i = 0, n = current.length; i < n; i++) {
-        findValues(get(current, i), keypath, index, current, values);
-      }
-    } else {
-      findValues(get(current, k), keypath, index + 1, current, values);
-    }
+  if (!(0, _queries.isReceivingData)(action) && !(0, _mutations.isReceivingMutationResult)(action)) {
+    return state;
   }
 
-  /**
-   */
-
-  function createNestedValidator(keypath, a, q) {
-    return { a: { k: keypath, nv: a, q: q }, v: nestedValidator };
+  if (action && action.definition && action.definition.mutationType === _dsl.MutationTypes.DELETE_DOCUMENT) {
+    var docId = action.definition.document._id;
+    var _type = action.definition.document._type;
+    return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, _type, (0, _omit.default)(state[_type], docId)));
   }
 
-  /**
-   * flatten the query
-   */
+  var _action$response = action.response,
+      data = _action$response.data,
+      included = _action$response.included;
+  if (!data || Array.isArray(data) && data.length === 0) return state;
+  var updatedStateWithIncluded = included ? included.reduce(storeDocument, state) : state;
 
-  function isVanillaObject(value) {
-    return value && value.constructor === Object;
+  if (!Array.isArray(data)) {
+    return storeDocument(updatedStateWithIncluded, data);
   }
 
-  function parse(query) {
-    query = comparable(query);
+  return extractAndMergeDocument(data, updatedStateWithIncluded);
+};
 
-    if (!query || !isVanillaObject(query)) { // cross browser support
-      query = { $eq: query };
-    }
+var _default = documents; // selector
 
-    var validators = [];
+exports["default"] = _default;
 
-    for (var key in query) {
-      var a = query[key];
+var getDocumentFromSlice = function getDocumentFromSlice() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  var doctype = arguments.length > 1 ? arguments[1] : undefined;
+  var id = arguments.length > 2 ? arguments[2] : undefined;
 
-      if (key === '$options') {
-        continue;
-      }
+  if (!doctype) {
+    throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype');
+  }
 
-      if (OPERATORS[key]) {
-        if (prepare[key]) a = prepare[key](a, query);
-        validators.push(createValidator(comparable(a), OPERATORS[key]));
-      } else {
+  if (!id) {
+    throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined id');
+  }
 
-        if (key.charCodeAt(0) === 36) {
-          throw new Error('Unknown operation ' + key);
-        }
-        validators.push(createNestedValidator(key.split('.'), parse(a), a));
-      }
+  if (!state[doctype]) {
+    if (process.env.NODE_ENV !== 'production') {
+      _logger.default.info("getDocumentFromSlice: ".concat(doctype, " is absent from the store's documents. State is"), state);
     }
 
-    return validators.length === 1 ? validators[0] : createValidator(validators, OPERATORS.$and);
+    return null;
+  } else if (!state[doctype][id]) {
+    if (process.env.NODE_ENV !== 'production') {
+      _logger.default.info("getDocumentFromSlice: ".concat(doctype, ":").concat(id, " is absent from the store documents. State is"), state);
+    }
+
+    return null;
   }
 
-  /**
-   */
+  return state[doctype][id];
+};
 
-  function createRootValidator(query, getter) {
-    var validator = parse(query);
-    if (getter) {
-      validator = {
-        a: validator,
-        v: function(a, b, k, o) {
-          return validate(a, getter(b), k, o);
-        }
-      };
+exports.getDocumentFromSlice = getDocumentFromSlice;
+
+var getCollectionFromSlice = function getCollectionFromSlice() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  var doctype = arguments.length > 1 ? arguments[1] : undefined;
+
+  if (!doctype) {
+    throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype');
+  }
+
+  if (!state[doctype]) {
+    if (process.env.NODE_ENV !== 'production') {
+      _logger.default.info("getCollectionFromSlice: ".concat(doctype, " is absent from the store documents. State is"), state);
     }
-    return validator;
+
+    return null;
   }
 
-  /**
-   */
+  return Object.values(state[doctype]);
+};
+/*
+  This method has been created in order to get a returned object
+  in `data` with the full set on information coming potentially from
+  `included`
 
-  function sift(query, array, getter) {
+  This method should be somewhere else. The `document` shall not be
+  dealt with included / data and so on.
 
-    if (isFunction(array)) {
-      getter = array;
-      array  = void 0;
-    }
+  This method takes `data` and `included` and merge both sources
+  together. It should be always up-to-date. The returned object
+  will be as full of information as it can be.
+*/
 
-    var validator = createRootValidator(query, getter);
 
-    function filter(b, k, o) {
-      return validate(validator, b, k, o);
-    }
+exports.getCollectionFromSlice = getCollectionFromSlice;
 
-    if (array) {
-      return array.filter(filter);
-    }
+var extractAndMergeDocument = function extractAndMergeDocument(data, updatedStateWithIncluded) {
+  var doctype = data[0]._type;
 
-    return filter;
+  if (!doctype) {
+    _logger.default.info('Document without _type', data[0]);
+
+    throw new Error('Document without _type');
   }
 
-  /**
-   */
+  var sortedData = (0, _keyBy.default)(data, _helpers.properId);
+  var mergedData = Object.assign({}, updatedStateWithIncluded);
+  mergedData[doctype] = Object.assign({}, updatedStateWithIncluded[doctype]);
+  Object.values(sortedData).map(function (data) {
+    var id = (0, _helpers.properId)(data);
 
-  sift.use = function(plugin) {
-    if (isFunction(plugin)) return plugin(sift);
-    for (var key in plugin) {
-      /* istanbul ignore else */
-      if (key.charCodeAt(0) === 36) {
-        OPERATORS[key] = plugin[key];
-      }
+    if (mergedData[doctype][id]) {
+      mergedData[doctype][id] = _objectSpread(_objectSpread({}, mergedData[doctype][id]), data);
+    } else {
+      mergedData[doctype][id] = data;
     }
-  };
+  });
+  return mergedData;
+};
 
-  /**
-   */
+exports.extractAndMergeDocument = extractAndMergeDocument;
 
-  sift.indexOf = function(query, array, getter) {
-    return search(array, createRootValidator(query, getter));
-  };
+/***/ }),
+/* 711 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  /**
-   */
+var baseAssignValue = __webpack_require__(546),
+    createAggregator = __webpack_require__(712);
 
-  sift.compare = function(a, b) {
-    if(a===b) return 0;
-    if(typeof a === typeof b) {
-      if (a > b) {
-        return 1;
-      }
-      if (a < b) {
-        return -1;
-      }
-    }
+/**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The corresponding value of
+ * each key is the last element responsible for generating the key. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * var array = [
+ *   { 'dir': 'left', 'code': 97 },
+ *   { 'dir': 'right', 'code': 100 }
+ * ];
+ *
+ * _.keyBy(array, function(o) {
+ *   return String.fromCharCode(o.code);
+ * });
+ * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(array, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+ */
+var keyBy = createAggregator(function(result, value, key) {
+  baseAssignValue(result, key, value);
+});
+
+module.exports = keyBy;
+
+
+/***/ }),
+/* 712 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var arrayAggregator = __webpack_require__(713),
+    baseAggregator = __webpack_require__(714),
+    baseIteratee = __webpack_require__(413),
+    isArray = __webpack_require__(55);
+
+/**
+ * Creates a function like `_.groupBy`.
+ *
+ * @private
+ * @param {Function} setter The function to set accumulator values.
+ * @param {Function} [initializer] The accumulator object initializer.
+ * @returns {Function} Returns the new aggregator function.
+ */
+function createAggregator(setter, initializer) {
+  return function(collection, iteratee) {
+    var func = isArray(collection) ? arrayAggregator : baseAggregator,
+        accumulator = initializer ? initializer() : {};
+
+    return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
   };
+}
 
-  /* istanbul ignore next */
-  if ( true && typeof module.exports !== 'undefined') {
-    Object.defineProperty(exports, "__esModule", ({
-      value: true
-    }));
+module.exports = createAggregator;
 
-    module.exports = sift;
-    exports["default"] = module.exports["default"] = sift;
-  }
 
-  /* istanbul ignore next */
-  if (typeof window !== 'undefined') {
-    window.sift = sift;
+/***/ }),
+/* 713 */
+/***/ ((module) => {
+
+/**
+ * A specialized version of `baseAggregator` for arrays.
+ *
+ * @private
+ * @param {Array} [array] The array to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform keys.
+ * @param {Object} accumulator The initial aggregated object.
+ * @returns {Function} Returns `accumulator`.
+ */
+function arrayAggregator(array, setter, iteratee, accumulator) {
+  var index = -1,
+      length = array == null ? 0 : array.length;
+
+  while (++index < length) {
+    var value = array[index];
+    setter(accumulator, value, iteratee(value), array);
   }
-})();
+  return accumulator;
+}
+
+module.exports = arrayAggregator;
 
 
 /***/ }),
-/* 738 */
+/* 714 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var baseEach = __webpack_require__(567);
+
+/**
+ * Aggregates elements of `collection` on `accumulator` with keys transformed
+ * by `iteratee` and values set by `setter`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} setter The function to set `accumulator` values.
+ * @param {Function} iteratee The iteratee to transform keys.
+ * @param {Object} accumulator The initial aggregated object.
+ * @returns {Function} Returns `accumulator`.
+ */
+function baseAggregator(collection, setter, iteratee, accumulator) {
+  baseEach(collection, function(value, key, collection) {
+    setter(accumulator, value, iteratee(value), collection);
+  });
+  return accumulator;
+}
+
+module.exports = baseAggregator;
+
+
+/***/ }),
+/* 715 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.receiveMutationError = exports.receiveMutationResult = exports.initMutation = exports.isReceivingMutationResult = exports.isMutationAction = void 0;
+exports["default"] = void 0;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _minilog = _interopRequireDefault(__webpack_require__(716));
 
-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; }
+var logger = (0, _minilog.default)('cozy-client');
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+_minilog.default.suggest.deny('cozy-client', 'info');
 
-var INIT_MUTATION = 'INIT_MUTATION';
-var RECEIVE_MUTATION_RESULT = 'RECEIVE_MUTATION_RESULT';
-var RECEIVE_MUTATION_ERROR = 'RECEIVE_MUTATION_ERROR';
+var _default = logger;
+exports["default"] = _default;
 
-var isMutationAction = function isMutationAction(action) {
-  return [INIT_MUTATION, RECEIVE_MUTATION_RESULT, RECEIVE_MUTATION_ERROR].indexOf(action.type) !== -1;
+/***/ }),
+/* 716 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+module.exports = __webpack_require__(717);
+
+var consoleLogger = __webpack_require__(720);
+
+// if we are running inside Electron then use the web version of console.js
+var isElectron = (typeof window !== 'undefined' && window.process && window.process.type === 'renderer');
+if (isElectron) {
+  consoleLogger = (__webpack_require__(729).minilog);
+}
+
+// intercept the pipe method and transparently wrap the stringifier, if the
+// destination is a Node core stream
+
+module.exports.Stringifier = __webpack_require__(733);
+
+var oldPipe = module.exports.pipe;
+module.exports.pipe = function(dest) {
+  if(dest instanceof __webpack_require__(82)) {
+    return oldPipe.call(module.exports, new (module.exports.Stringifier)).pipe(dest);
+  } else {
+    return oldPipe.call(module.exports, dest);
+  }
 };
 
-exports.isMutationAction = isMutationAction;
+module.exports.defaultBackend = consoleLogger;
+module.exports.defaultFormatter = consoleLogger.formatMinilog;
 
-var isReceivingMutationResult = function isReceivingMutationResult(action) {
-  return action.type === RECEIVE_MUTATION_RESULT;
-}; // actions
+module.exports.backends = {
+  redis: __webpack_require__(734),
+  nodeConsole: consoleLogger,
+  console: consoleLogger
+};
 
 
-exports.isReceivingMutationResult = isReceivingMutationResult;
+/***/ }),
+/* 717 */
+/***/ ((module, exports, __webpack_require__) => {
 
-var initMutation = function initMutation(mutationId, definition) {
-  return {
-    type: INIT_MUTATION,
-    mutationId: mutationId,
-    definition: definition
-  };
+var Transform = __webpack_require__(718),
+    Filter = __webpack_require__(719);
+
+var log = new Transform(),
+    slice = Array.prototype.slice;
+
+exports = module.exports = function create(name) {
+  var o   = function() { log.write(name, undefined, slice.call(arguments)); return o; };
+  o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; };
+  o.info  = function() { log.write(name, 'info',  slice.call(arguments)); return o; };
+  o.warn  = function() { log.write(name, 'warn',  slice.call(arguments)); return o; };
+  o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; };
+  o.group = function() { log.write(name, 'group', slice.call(arguments)); return o; };
+  o.groupEnd = function() { log.write(name, 'groupEnd', slice.call(arguments)); return o; };
+  o.log   = o.debug; // for interface compliance with Node and browser consoles
+  o.suggest = exports.suggest;
+  o.format = log.format;
+  return o;
 };
 
-exports.initMutation = initMutation;
+// filled in separately
+exports.defaultBackend = exports.defaultFormatter = null;
 
-var receiveMutationResult = function receiveMutationResult(mutationId, response) {
-  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-  var definition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
-  return _objectSpread(_objectSpread({
-    type: RECEIVE_MUTATION_RESULT,
-    mutationId: mutationId,
-    response: response
-  }, options), {}, {
-    definition: definition
-  });
+exports.pipe = function(dest) {
+  return log.pipe(dest);
 };
 
-exports.receiveMutationResult = receiveMutationResult;
+exports.end = exports.unpipe = exports.disable = function(from) {
+  return log.unpipe(from);
+};
 
-var receiveMutationError = function receiveMutationError(mutationId, error) {
-  var definition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-  return {
-    type: RECEIVE_MUTATION_ERROR,
-    mutationId: mutationId,
-    error: error,
-    definition: definition
-  };
+exports.Transform = Transform;
+exports.Filter = Filter;
+// this is the default filter that's applied when .enable() is called normally
+// you can bypass it completely and set up your own pipes
+exports.suggest = new Filter();
+
+exports.enable = function() {
+  if(exports.defaultFormatter) {
+    return log.pipe(exports.suggest) // filter
+              .pipe(exports.defaultFormatter) // formatter
+              .pipe(exports.defaultBackend); // backend
+  }
+  return log.pipe(exports.suggest) // filter
+            .pipe(exports.defaultBackend); // formatter
 };
 
-exports.receiveMutationError = receiveMutationError;
+
 
 /***/ }),
-/* 739 */
-/***/ ((__unused_webpack_module, exports) => {
+/* 718 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var microee = __webpack_require__(570);
 
+// Implements a subset of Node's stream.Transform - in a cross-platform manner.
+function Transform() {}
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.properId = void 0;
+microee.mixin(Transform);
 
-var properId = function properId(doc) {
-  return doc.id || doc._id;
+// The write() signature is different from Node's
+// --> makes it much easier to work with objects in logs.
+// One of the lessons from v1 was that it's better to target
+// a good browser rather than the lowest common denominator
+// internally.
+// If you want to use external streams, pipe() to ./stringify.js first.
+Transform.prototype.write = function(name, level, args) {
+  this.emit('item', name, level, args);
 };
 
-exports.properId = properId;
-
-/***/ }),
-/* 740 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+Transform.prototype.end = function() {
+  this.emit('end');
+  this.removeAllListeners();
+};
 
-"use strict";
+Transform.prototype.pipe = function(dest) {
+  var s = this;
+  // prevent double piping
+  s.emit('unpipe', dest);
+  // tell the dest that it's being piped to
+  dest.emit('pipe', s);
 
+  function onItem() {
+    dest.write.apply(dest, Array.prototype.slice.call(arguments));
+  }
+  function onEnd() { !dest._isStdio && dest.end(); }
 
-var _interopRequireDefault = __webpack_require__(512);
+  s.on('item', onItem);
+  s.on('end', onEnd);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+  s.when('unpipe', function(from) {
+    var match = (from === dest) || typeof from == 'undefined';
+    if(match) {
+      s.removeListener('item', onItem);
+      s.removeListener('end', onEnd);
+      dest.emit('unpipe');
+    }
+    return match;
+  });
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+  return dest;
+};
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+Transform.prototype.unpipe = function(from) {
+  this.emit('unpipe', from);
+  return this;
+};
 
-var _types = __webpack_require__(610);
+Transform.prototype.format = function(dest) {
+  throw new Error([
+    'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:',
+    'var Minilog = require(\'minilog\');',
+    'Minilog',
+    '  .pipe(Minilog.backends.console.formatClean)',
+    '  .pipe(Minilog.backends.console);'].join('\n'));
+};
 
-var _dsl = __webpack_require__(607);
+Transform.mixin = function(dest) {
+  var o = Transform.prototype, k;
+  for (k in o) {
+    o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
+  }
+};
 
-/**
- * Associations are used by components to access related store documents that are
- * linked in a document. They are also responsible for building the `QueryDefinition` that is
- * used by the client to automatically fetch relationship data.
- *
- * Hydrated documents used by components come with Association instances.
- *
- * @interface
- *
- * @description
- * Example: The schema defines an `author` relationship :
- *
- * ```js
- * const BOOK_SCHEMA = {
- *   relationships: {
- *      author: 'has-one'
- *   }
- * }
- * ```
- *
- * Hydrated `books` will have the `author` association instance under the `author` key.
- * Accessing `hydratedBook.author.data` gives you the author from the store, for example :
- *
- * ```json
- * {
- *   "name": "St-Exupery",
- *   "firstName": "Antoine",
- *   "_id": "antoine"
- * }
- * ```
- *
- * It is the responsibility of the relationship to decide how the relationship data is stored.
- * For example, here since we use the default `has-one` relationship, the relationship data
- * is stored in the `relationships` attribute of the original document (in our case here, our book
- * would be
- *
- * ```json
- * {
- *   "title": "Le petit prince",
- *   "relationships": {
- *     "author": {
- *       "data": {
- *         "doctype": "io.cozy.authors",
- *         "_id": "antoine"
- *       }
- *     }
- *   }
- * }
- * ```
- *
- * In the case of an "in-place" relationship, the relationship data is stored directly under the attribute named
- * by the relationship (in our case `author`). Our book would be
- *
- * ```json
- * {
- *     "title": "Le petit prince",
- *     "author": "antoine"
- * }
- * ```
- *
- * ---
- *
- * Each different type of Association may change:
- *
- * - `get raw`: how the relationship data is stored (either as per the JSON API spec or
- *  in a custom way)
- * - `get data`: how the store documents are then fetched from the store to be added to
- * the hydrated document (.data method). View components will access
- * `hydratedDoc[relationshipName].data`.
- * - `get query`: how to build the query to fetch related documents
- *
- */
-var Association = /*#__PURE__*/function () {
-  /**
-   * @param  {object} target - Original object containing raw data
-   * @param  {string} name - Attribute under which the association is stored
-   * @param  {string} doctype - Doctype of the documents managed by the association
-   * @param {object} options - Options passed from the client
-   * @param {Function} options.get - Get a document from the store
-   * @param {Function} options.query - Execute client query
-   * @param {Function} options.mutate - Execute client mutate
-   * @param {Function} options.save - Execute client save
-   * @param  {Function} options.dispatch - Store's dispatch, comes from the client
-   */
-  function Association(target, name, doctype, options) {
-    (0, _classCallCheck2.default)(this, Association);
-    var dispatch = options.dispatch,
-        get = options.get,
-        query = options.query,
-        mutate = options.mutate,
-        save = options.save;
-    /**
-     * The original document declaring the relationship
-     *
-     * @type {object}
-     */
+module.exports = Transform;
 
-    this.target = target;
-    /**
-     * The name of the relationship.
-     *
-     * @type {string}
-     * @example 'author'
-     */
 
-    this.name = name;
-    /**
-     * Doctype of the relationship
-     *
-     * @type {string}
-     * @example 'io.cozy.authors'
-     */
+/***/ }),
+/* 719 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    this.doctype = doctype;
-    /**
-     * Returns the document from the store
-     *
-     * @type {Function}
-     */
+// default filter
+var Transform = __webpack_require__(718);
 
-    this.get = get;
-    /**
-     * Performs a query to retrieve relationship documents.
-     *
-     * @param {QueryDefinition} queryDefinition
-     * @function
-     */
+var levelMap = { debug: 1, info: 2, warn: 3, error: 4 };
 
-    this.query = query;
-    /**
-     * Performs a mutation on the relationship.
-     *
-     * @function
-     */
+function Filter() {
+  this.enabled = true;
+  this.defaultResult = true;
+  this.clear();
+}
 
-    this.mutate = mutate;
-    /**
-     * Saves the relationship in store.
-     *
-     * @type {Function}
-     */
+Transform.mixin(Filter);
 
-    this.save = save;
-    /**
-     * Dispatch an action on the store.
-     *
-     * @type {Function}
-     */
+// allow all matching, with level >= given level
+Filter.prototype.allow = function(name, level) {
+  this._white.push({ n: name, l: levelMap[level] });
+  return this;
+};
 
-    this.dispatch = dispatch;
-  }
-  /**
-   *
-   * Returns the raw relationship data as stored in the original document
-   *
-   * For a document with relationships stored as JSON API spec:
-   *
-   * ```js
-   * const book = {
-   *   title: 'Moby Dick',
-   *   relationships: {
-   *     author: {
-   *       data: {
-   *         doctype: 'io.cozy.authors',
-   *         id: 'herman'
-   *       }
-   *     }
-   *   }
-   *  }
-   * ```
-   *
-   * Raw value will be
-   *
-   * ```json
-   * {
-   *   "doctype": "io.cozy.authors",
-   *   "id": "herman"
-   * }
-   * ```
-   *
-   * Derived `Association`s need to implement this method.
-   *
-   * @returns {object}
-   */
+// deny all matching, with level <= given level
+Filter.prototype.deny = function(name, level) {
+  this._black.push({ n: name, l: levelMap[level] });
+  return this;
+};
 
+Filter.prototype.clear = function() {
+  this._white = [];
+  this._black = [];
+  return this;
+};
 
-  (0, _createClass2.default)(Association, [{
-    key: "raw",
-    get: function get() {
-      throw new Error('A relationship must define its raw getter');
-    }
-    /**
-     * Returns the document(s) from the store
-     *
-     * For document with relationships stored as JSON API spec :
-     *
-     * ```js
-     * const book = {
-     *   title: 'Moby Dick',
-     *   relationships: {
-     *     author: {
-     *       data: {
-     *         doctype: 'io.cozy.authors',
-     *         id: 'herman'
-     *       }
-     *     }
-     *   }
-     *  }
-     * ```
-     *
-     * `data` will be
-     *
-     * ```json
-     * {
-     *   "_id": "herman"
-     *   "_type": "io.cozy.authors",
-     *   "firstName": "herman",
-     *   "name": "Melville"
-     * }
-     * ```
-     *
-     * Derived `Association`s need to implement this method.
-     *
-     * @returns {object}
-     */
+function test(rule, name) {
+  // use .test for RegExps
+  return (rule.n.test ? rule.n.test(name) : rule.n == name);
+};
 
-  }, {
-    key: "data",
-    get: function get() {
-      throw new Error('A relationship must define its data getter');
+Filter.prototype.test = function(name, level) {
+  var i, len = Math.max(this._white.length, this._black.length);
+  for(i = 0; i < len; i++) {
+    if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) {
+      return true;
     }
-    /**
-     * Derived `Association`s need to implement this method.
-     *
-     * @param {CozyClientDocument} document - Document to query
-     * @param {object} client - The CozyClient instance
-     * @param {Association} assoc - Association containing info on how to build the query to fetch related documents
-     *
-     * @returns {CozyClientDocument | QueryDefinition }
-     */
-
-  }], [{
-    key: "query",
-    value: function query(document, client, assoc) {
-      throw new Error('A custom relationship must define its query() function');
+    if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) {
+      return false;
     }
-  }]);
-  return Association;
-}();
-
-var _default = Association;
-exports["default"] = _default;
+  }
+  return this.defaultResult;
+};
 
-/***/ }),
-/* 741 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+Filter.prototype.write = function(name, level, args) {
+  if(!this.enabled || this.test(name, level)) {
+    return this.emit('item', name, level, args);
+  }
+};
 
-"use strict";
+module.exports = Filter;
 
 
-var _interopRequireDefault = __webpack_require__(512);
+/***/ }),
+/* 720 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = exports.updateRelationship = exports.updateHasManyItem = exports.removeHasManyItem = exports.setHasManyItem = exports.getHasManyItems = exports.getHasManyItem = void 0;
+var Transform = __webpack_require__(718);
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+function ConsoleBackend() { }
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+Transform.mixin(ConsoleBackend);
 
-var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(594));
+ConsoleBackend.prototype.write = function() {
+  console.log.apply(console, arguments);
+};
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+var e = new ConsoleBackend();
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var levelMap = (__webpack_require__(721).levelMap);
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+e.filterEnv = function() {
+  console.error('Minilog.backends.console.filterEnv is deprecated in Minilog v2.');
+  // return the instance of Minilog
+  return __webpack_require__(717);
+};
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+e.formatters = [
+    'formatClean', 'formatColor', 'formatNpm',
+    'formatLearnboost', 'formatMinilog', 'formatWithStack', 'formatTime'
+];
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+e.formatClean = new (__webpack_require__(722));
+e.formatColor = new (__webpack_require__(723));
+e.formatNpm = new (__webpack_require__(724));
+e.formatLearnboost = new (__webpack_require__(725));
+e.formatMinilog = new (__webpack_require__(726));
+e.formatWithStack = new (__webpack_require__(727));
+e.formatTime = new (__webpack_require__(728));
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+module.exports = e;
 
-var _merge = _interopRequireDefault(__webpack_require__(742));
 
-var _dsl = __webpack_require__(607);
+/***/ }),
+/* 721 */
+/***/ ((__unused_webpack_module, exports) => {
 
-var _store = __webpack_require__(693);
+var styles = {
+  //styles
+  bold: ["\x1B[1m", "\x1B[22m"],
+  italic: ["\x1B[3m", "\x1B[23m"],
+  underline: ["\x1B[4m", "\x1B[24m"],
+  inverse: ["\x1B[7m", "\x1B[27m"],
+  //grayscale
+  white: ["\x1B[37m", "\x1B[39m"],
+  grey: ["\x1B[90m", "\x1B[39m"],
+  black: ["\x1B[30m", "\x1B[39m"],
+  //colors
+  blue: ["\x1B[34m", "\x1B[39m"],
+  cyan: ["\x1B[36m", "\x1B[39m"],
+  green: ["\x1B[32m", "\x1B[39m"],
+  magenta: ["\x1B[35m", "\x1B[39m"],
+  red: ["\x1B[31m", "\x1B[39m"],
+  yellow: ["\x1B[33m", "\x1B[39m"]
+};
 
-var _types = __webpack_require__(610);
+exports.levelMap = { debug: 1, info: 2, warn: 3, error: 4 };
 
-var _Association2 = _interopRequireDefault(__webpack_require__(740));
+exports.style = function(str, style) {
+  return styles[style][0] + str + styles[style][1];
+};
 
-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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
+/***/ }),
+/* 722 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+var Transform = __webpack_require__(718);
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+function FormatClean() {}
 
-/**
- * @typedef {object} Relationship
- * @property {string} relName - name of the relationship
- * @property {string} relItemId - id of the relation
- * @property {Relation} relItemAttrs - Attributes to be set (at least _id and _type)
- */
+Transform.mixin(FormatClean);
 
-/**
- * @typedef {object} Relation
- * @property {string} _id - id of the relation
- * @property {string} _type - doctype of the relation
- */
-var empty = function empty() {
-  return {
-    data: [],
-    next: true,
-    meta: {
-      count: 0
-    }
-  };
+FormatClean.prototype.write = function(name, level, args) {
+  function pad(s) { return (s.toString().length == 1? '0'+s : s); }
+  this.emit('item', (name ? name + ' ' : '') + (level ? level + ' ' : '') + args.join(' '));
 };
 
-var updateArray = function updateArray(array, indexArg, el) {
-  var index = indexArg === -1 ? array.length : indexArg;
-  return [].concat((0, _toConsumableArray2.default)(array.slice(0, index)), [el], (0, _toConsumableArray2.default)(array.slice(index + 1)));
-};
-/**
- * Related documents are stored in the relationships attribute of the object,
- * following the JSON API spec.
- *
- * Responsible for
- *
- * - Creating relationships
- * - Removing relationships
- *
- * @description
- *
- * ```
- * const schema = {
- *   todos: {
- *      doctype: 'io.cozy.todos',
- *      relationships: {
- *        tasks: {
- *          doctype: 'io.cozy.tasks',
- *          type: 'has-many'
- *        }
- *      }
- *    }
- * }
- *
- * const todo = {
- *   label: "Protect people's privacy",
- *   relationships: {
- *     tasks: {
- *       data: [
- *         {_id: 1, _type: 'io.cozy.tasks'},
- *         {_id: 2, _type: 'io.cozy.tasks'}
- *       ]
- *     }
- *   }
- * }
- * ```
- */
+module.exports = FormatClean;
 
 
-var HasMany = /*#__PURE__*/function (_Association) {
-  (0, _inherits2.default)(HasMany, _Association);
+/***/ }),
+/* 723 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  var _super = _createSuper(HasMany);
+var Transform = __webpack_require__(718),
+    style = (__webpack_require__(721).style);
 
-  function HasMany() {
-    var _this;
+function FormatColor() {}
 
-    (0, _classCallCheck2.default)(this, HasMany);
+Transform.mixin(FormatColor);
 
-    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
-      args[_key] = arguments[_key];
-    }
+FormatColor.prototype.write = function(name, level, args) {
+  var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' };
+  function pad(s) { return (s.toString().length == 4? ' '+s : s); }
+  this.emit('item', (name ? name + ' ' : '')
+          + (level ? style('- ' + pad(level.toUpperCase()) + ' -', colors[level]) + ' ' : '')
+          + args.join(' '));
+};
 
-    _this = _super.call.apply(_super, [this].concat(args));
-    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateRelationshipData", function (getUpdatedRelationshipData) {
-      return function (dispatch, getState) {
-        var previousRelationship = (0, _store.getDocumentFromState)(getState(), _this.target._type, _this.target._id);
-        dispatch((0, _store.receiveQueryResult)(null, {
-          data: _objectSpread(_objectSpread({}, previousRelationship), {}, {
-            relationships: _objectSpread(_objectSpread({}, previousRelationship.relationships), {}, (0, _defineProperty2.default)({}, _this.name, getUpdatedRelationshipData(previousRelationship.relationships[_this.name])))
-          })
-        }));
-      };
-    });
-    return _this;
-  }
+module.exports = FormatColor;
 
-  (0, _createClass2.default)(HasMany, [{
-    key: "fetchMore",
-    value: function fetchMore() {
-      throw 'Not implemented';
-    }
-  }, {
-    key: "exists",
-    value: function exists(document) {
-      return this.existsById(document._id);
-    }
-  }, {
-    key: "containsById",
-    value: function containsById(id) {
-      return this.getRelationship().data.find(function (_ref) {
-        var _id = _ref._id;
-        return id === _id;
-      }) !== undefined;
-    }
-  }, {
-    key: "existsById",
-    value: function existsById(id) {
-      return Boolean(this.containsById(id) && this.get(this.doctype, id));
-    }
-    /**
-     * Add the relationships to the target document
-     *
-     * @param {CozyClientDocument[]} docsArg - Documents to add as relationships
-     * @returns {CozyClientDocument} The saved target document
-     */
 
-  }, {
-    key: "add",
-    value: function add(docsArg) {
-      var docs = Array.isArray(docsArg) ? docsArg : [docsArg];
-      var ids = docs.map(function (doc) {
-        return doc._id;
-      });
-      return this.addById(ids);
-    }
-    /**
-     * Remove the relationships from the target document
-     *
-     * @param {CozyClientDocument[]} docsArg - Documents to remove as relationships
-     * @returns {CozyClientDocument} The saved target document
-     */
+/***/ }),
+/* 724 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  }, {
-    key: "remove",
-    value: function remove(docsArg) {
-      var docs = Array.isArray(docsArg) ? docsArg : [docsArg];
-      var ids = docs.map(function (doc) {
-        return doc._id;
-      });
-      return this.removeById(ids);
-    }
-    /**
-     * Update target document with relationships
-     *
-     * @param {string[]} idsArg - The ids to add as a relationship
-     */
+var Transform = __webpack_require__(718);
 
-  }, {
-    key: "addTargetRelationships",
-    value: function addTargetRelationships(idsArg) {
-      var _this2 = this,
-          _this$target$relation;
+function FormatNpm() {}
 
-      if (!this.target.relationships) this.target.relationships = {};
+Transform.mixin(FormatNpm);
 
-      if (!this.target.relationships[this.name]) {
-        this.target.relationships[this.name] = {
-          data: []
-        };
-      }
+FormatNpm.prototype.write = function(name, level, args) {
+  var out = {
+    debug: "\x1B[34;40m" + "debug" + "\x1B[39m ",
+    info: "\x1B[32m" + "info" + "\x1B[39m  ",
+    warn: "\x1B[30;41m" + "WARN" + "\x1B[0m  ",
+    error: "\x1B[31;40m" + "ERR!" + "\x1B[0m  "
+  };
+  this.emit(
+    "item",
+    (name ? "\x1B[37;40m" + name + "\x1B[0m " : "") +
+      (level && out[level] ? out[level] : "") +
+      args.join(" ")
+  );
+};
 
-      var ids = Array.isArray(idsArg) ? idsArg : [idsArg];
-      var newRelations = ids.filter(function (id) {
-        return !_this2.existsById(id);
-      }).map(function (id) {
-        return {
-          _id: id,
-          _type: _this2.doctype
-        };
-      });
+module.exports = FormatNpm;
 
-      (_this$target$relation = this.target.relationships[this.name].data).push.apply(_this$target$relation, (0, _toConsumableArray2.default)(newRelations));
 
-      this.updateMetaCount();
-    }
-    /**
-     * Add a referenced document by id. You need to call save()
-     * in order to synchronize your document with the store.
-     *
-     * @todo We shouldn't create the array of relationship manually since
-     * it'll not be present in the store as well.
-     * We certainly should use something like `updateRelationship`
-     *
-     */
+/***/ }),
+/* 725 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-  }, {
-    key: "addById",
-    value: function addById(idsArg) {
-      this.addTargetRelationships(idsArg);
-      return this.save(this.target);
-    }
-    /**
-     * Remove relationships from target document
-     *
-     * @param {string[]} idsArg - The ids to remove from the target relationships
-     */
+var Transform = __webpack_require__(718),
+    style = (__webpack_require__(721).style);
 
-  }, {
-    key: "removeTargetRelationships",
-    value: function removeTargetRelationships(idsArg) {
-      var ids = Array.isArray(idsArg) ? idsArg : [idsArg];
-      this.target.relationships[this.name].data = this.target.relationships[this.name].data.filter(function (_ref2) {
-        var _id = _ref2._id;
-        return !ids.includes(_id);
-      });
-      this.updateMetaCount();
-    }
-  }, {
-    key: "removeById",
-    value: function removeById(idsArg) {
-      this.removeTargetRelationships(idsArg);
-      return this.save(this.target);
-    }
-  }, {
-    key: "updateMetaCount",
-    value: function updateMetaCount() {
-      if ((0, _get.default)(this.target.relationships[this.name], 'meta.count') !== undefined) {
-        this.target.relationships[this.name].meta = _objectSpread(_objectSpread({}, this.target.relationships[this.name].meta), {}, {
-          count: this.target.relationships[this.name].data.length
-        });
-      }
-    }
-  }, {
-    key: "getRelationship",
-    value: function getRelationship() {
-      var rawData = this.target[this.name];
-      var relationship = (0, _get.default)(this.target, "relationships.".concat(this.name));
+function FormatLearnboost() {}
 
-      if (!relationship) {
-        if (rawData && rawData.length) {
-          console.warn("You're trying to access data on a relationship that appear to not be loaded yet. You may want to use 'include()' on your query");
-        }
+Transform.mixin(FormatLearnboost);
 
-        return empty();
-      }
+FormatLearnboost.prototype.write = function(name, level, args) {
+  var colors = { debug: 'grey', info: 'cyan', warn: 'yellow', error: 'red' };
+  this.emit('item', (name ? style(name +' ', 'grey') : '')
+          + (level ? style(level, colors[level]) + ' ' : '')
+          + args.join(' '));
+};
 
-      return relationship;
-    }
-  }, {
-    key: "updateTargetRelationship",
-    value: function updateTargetRelationship(store, updateFn) {
-      // TODO See if updateTargetRelationship is still used, removing it would enable us
-      // to remove store.readDocument and store.writeDocument and the StoreProxy
-      var prevTarget = store.readDocument(this.target._type, this.target._id);
-      store.writeDocument(this.updateRelationship(prevTarget, updateFn));
-    }
-  }, {
-    key: "updateRelationship",
-    value: function updateRelationship(target, updateFn) {
-      return HasMany.updateRelationship(target, this.name, updateFn);
-    }
-  }, {
-    key: "dehydrate",
-    value: function dehydrate(doc) {
-      return _objectSpread(_objectSpread({}, doc), {}, {
-        relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, {
-          data: this.raw
-        }))
-      });
-    }
-    /**
-     * @param {CozyClientDocument} document - Document to query
-     * @param {object} client - The CozyClient instance
-     * @param {Association} assoc - The query params
-     *
-     * @returns {CozyClientDocument | QueryDefinition}
-     */
+module.exports = FormatLearnboost;
 
-  }, {
-    key: "raw",
-    get: function get() {
-      return this.getRelationship().data;
-    }
-    /**
-     * Returns store documents
-     */
 
-  }, {
-    key: "data",
-    get: function get() {
-      var _this3 = this;
+/***/ }),
+/* 726 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-      return this.getRelationship().data.map(function (_ref3) {
-        var _id = _ref3._id,
-            _type = _ref3._type;
-        return _this3.get(_type, _id);
-      }).filter(Boolean);
-    }
-  }, {
-    key: "hasMore",
-    get: function get() {
-      return this.getRelationship().next;
-    }
-    /**
-     * Returns the total number of documents in the relationship.
-     * Does not handle documents absent from the store. If you want
-     * to do that, you can use .data.length.
-     *
-     * @returns {number} - Total number of documents in the relationships
-     */
+var Transform = __webpack_require__(718),
+    style = (__webpack_require__(721).style),
+    util = __webpack_require__(64);
 
-  }, {
-    key: "count",
-    get: function get() {
-      var relationship = this.getRelationship();
-      return relationship.meta ? relationship.meta.count : relationship.data.length;
-    }
-  }], [{
-    key: "query",
-    value: function query(document, client, assoc) {
-      var relationships = (0, _get.default)(document, "relationships.".concat(assoc.name, ".data"), []);
-      var ids = relationships.map(function (assoc) {
-        return assoc._id;
-      });
-      return new _dsl.QueryDefinition({
-        doctype: assoc.doctype,
-        ids: ids
-      });
-    }
-  }]);
-  return HasMany;
-}(_Association2.default);
-/**
- * Gets a relationship item with the relationship name and id
- *
- * @param {object} doc - Document to be updated
- * @param {string} relName - Name of the relationship
- * @param {string} relItemId - Id of the relationship item
- */
+function FormatMinilog() {}
 
+Transform.mixin(FormatMinilog);
 
-var getHasManyItem = HasMany.getHasManyItem = function (doc, relName, relItemId) {
-  var relData = (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []);
-  return relData.find(function (rel) {
-    return rel._id == relItemId;
-  });
+FormatMinilog.prototype.write = function(name, level, args) {
+  var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' };
+  this.emit('item', (name ? style(name +' ', 'grey') : '')
+            + (level ? style(level, colors[level]) + ' ' : '')
+            + args.map(function(item) {
+              return (typeof item == 'string' ? item : util.inspect(item, null, 3, true));
+            }).join(' '));
 };
 
-exports.getHasManyItem = getHasManyItem;
+module.exports = FormatMinilog;
 
-var getHasManyItems = HasMany.getHasManyItems = function (doc, relName) {
-  return (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []);
-};
-/**
- * Sets a relationship item with the relationship name and id
- *
- * @param {object} doc - Document to be updated
- * @param {string} relName - Name of the relationship
- * @param {string} relItemId - Id of the relationship item
- * @param {object} relItemAttrs - Attributes to be set (at least _id and _type)
- */
 
+/***/ }),
+/* 727 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-exports.getHasManyItems = getHasManyItems;
+var Transform = __webpack_require__(718),
+    style = (__webpack_require__(721).style);
 
-var setHasManyItem = HasMany.setHasManyItem = function (doc, relName, relItemId, relItemAttrs) {
-  var relData = HasMany.getHasManyItems(doc, relName);
-  var relIndex = relData.findIndex(function (rel) {
-    return rel._id === relItemId;
-  });
-  var updatedRelItem = (0, _merge.default)({}, relData[relIndex], relItemAttrs);
-  var updatedRelData = updateArray(relData, relIndex, updatedRelItem);
-  var updatedDocument = HasMany.updateRelationship(doc, relName, function (relationship) {
-    return (0, _merge.default)({}, relationship, {
-      data: updatedRelData
-    });
-  });
-  return updatedDocument;
-};
-/**
- * Remove one relationship item
- *
- * @param {object} doc - Document to be updated
- * @param {string} relName - Name of the relationship
- * @param {string} relItemId - Id of the relationship item
- */
+function FormatNpm() {}
 
+Transform.mixin(FormatNpm);
 
-exports.setHasManyItem = setHasManyItem;
+function noop(a){
+  return a;
+}
 
-var removeHasManyItem = HasMany.removeHasManyItem = function (doc, relName, relItemId) {
-  var relData = HasMany.getHasManyItems(doc, relName);
-  var updatedRelData = relData.filter(function (rel) {
-    return rel._id !== relItemId;
+var types = {
+  string: noop,
+  number: noop,
+  default: JSON.stringify.bind(JSON)
+};
+
+function stringify(args) {
+  return args.map(function(arg) {
+    return (types[typeof arg] || types.default)(arg);
   });
-  var updatedDocument = HasMany.updateRelationship(doc, relName, function () {
-    return {
-      data: updatedRelData
+}
+
+FormatNpm.prototype.write = function(name, level, args) {
+  var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' };
+  function pad(s) { return (s.toString().length == 4? ' '+s : s); }
+  function getStack() {
+    var orig = Error.prepareStackTrace;
+    Error.prepareStackTrace = function (err, stack) {
+      return stack;
     };
-  });
-  return updatedDocument;
+    var err = new Error;
+    Error.captureStackTrace(err, arguments.callee);
+    var stack = err.stack;
+    Error.prepareStackTrace = orig;
+    return stack;
+  }
+
+  var frame = getStack()[5],
+      fileName = FormatNpm.fullPath ? frame.getFileName() : frame.getFileName().replace(/^.*\/(.+)$/, '/$1');
+
+  this.emit('item', (name ? name + ' ' : '')
+          + (level ? style(pad(level), colors[level]) + ' ' : '')
+          + style(fileName + ":" + frame.getLineNumber(), 'grey')
+          + ' '
+          + stringify(args).join(' '));
 };
-/**
- * Updates a relationship item with the relationship name and id
- *
- * @param {object} doc - Document to be updated
- * @param {string} relName - Name of the relationship
- * @param {string} relItemId - Id of the relationship item
- * @param {Function} updater - receives the current relationship item and should
- * return an updated version. Merge should be used in the updater
- * if previous relationship item fields are to be kept.
- */
 
+FormatNpm.fullPath = true;
 
-exports.removeHasManyItem = removeHasManyItem;
+module.exports = FormatNpm;
 
-var updateHasManyItem = HasMany.updateHasManyItem = function (doc, relName, relItemId, updater) {
-  var relItem = HasMany.getHasManyItem(doc, relName, relItemId);
-  var updatedRelItem = updater(relItem);
-  return HasMany.setHasManyItem(doc, relName, relItemId, updatedRelItem);
+
+
+/***/ }),
+/* 728 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var Transform = __webpack_require__(718),
+    style = (__webpack_require__(721).style),
+    util = __webpack_require__(64);
+
+function FormatTime() {}
+
+function timestamp() {
+  var d = new Date();
+  return ('0' + d.getDate()).slice(-2) + '-' +
+    ('0' + (d.getMonth() + 1)).slice(-2) + '-' +
+    d.getFullYear() + ' ' +
+    ('0' + d.getHours()).slice(-2) + ':' +
+    ('0' + d.getMinutes()).slice(-2) + ':' +
+    ('0' + d.getSeconds()).slice(-2) + '.' +
+    ('00' + d.getMilliseconds()).slice(-3);
+}
+
+Transform.mixin(FormatTime);
+
+FormatTime.prototype.write = function(name, level, args) {
+  var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' };
+  this.emit('item', style(timestamp() +' ', 'grey')
+            + (name ? style(name +' ', 'grey') : '')
+            + (level ? style(level, colors[level]) + ' ' : '')
+            + args.map(function(item) {
+              return (typeof item == 'string' ? item : util.inspect(item, null, 3, true));
+            }).join(' '));
 };
 
-exports.updateHasManyItem = updateHasManyItem;
+module.exports = FormatTime;
 
-var updateRelationship = HasMany.updateRelationship = function (doc, relName, updateFn) {
-  return _objectSpread(_objectSpread({}, doc), {}, {
-    relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, relName, _objectSpread(_objectSpread({}, doc.relationships ? doc.relationships[relName] : {}), updateFn(doc.relationships ? doc.relationships[relName] : {}))))
-  });
+
+/***/ }),
+/* 729 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var Transform = __webpack_require__(718);
+
+var newlines = /\n+$/,
+    logger = new Transform();
+
+logger.write = function(name, level, args) {
+  var i = args.length-1;
+  if (typeof console === 'undefined' || !console.log) {
+    return;
+  }
+  if(console.log.apply) {
+    return console.log.apply(console, [name, level].concat(args));
+  } else if(JSON && JSON.stringify) {
+    // console.log.apply is undefined in IE8 and IE9
+    // for IE8/9: make console.log at least a bit less awful
+    if(args[i] && typeof args[i] == 'string') {
+      args[i] = args[i].replace(newlines, '');
+    }
+    try {
+      for(i = 0; i < args.length; i++) {
+        args[i] = JSON.stringify(args[i]);
+      }
+    } catch(e) {}
+    console.log(args.join(' '));
+  }
 };
 
-exports.updateRelationship = updateRelationship;
-var _default = HasMany;
-exports["default"] = _default;
+logger.formatters = ['color', 'minilog'];
+logger.color = __webpack_require__(730);
+logger.minilog = __webpack_require__(732);
+
+module.exports = logger;
+
 
 /***/ }),
-/* 742 */
+/* 730 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseMerge = __webpack_require__(743),
-    createAssigner = __webpack_require__(748);
+var Transform = __webpack_require__(718),
+    color = __webpack_require__(731);
 
-/**
- * This method is like `_.assign` except that it recursively merges own and
- * inherited enumerable string keyed properties of source objects into the
- * destination object. Source properties that resolve to `undefined` are
- * skipped if a destination value exists. Array and plain object properties
- * are merged recursively. Other objects and value types are overridden by
- * assignment. Source objects are applied from left to right. Subsequent
- * sources overwrite property assignments of previous sources.
- *
- * **Note:** This method mutates `object`.
- *
- * @static
- * @memberOf _
- * @since 0.5.0
- * @category Object
- * @param {Object} object The destination object.
- * @param {...Object} [sources] The source objects.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var object = {
- *   'a': [{ 'b': 2 }, { 'd': 4 }]
- * };
- *
- * var other = {
- *   'a': [{ 'c': 3 }, { 'e': 5 }]
- * };
- *
- * _.merge(object, other);
- * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
- */
-var merge = createAssigner(function(object, source, srcIndex) {
-  baseMerge(object, source, srcIndex);
-});
+var colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },
+    logger = new Transform();
 
-module.exports = merge;
+logger.write = function(name, level, args) {
+  var fn = console.log;
+  if(console[level] && console[level].apply) {
+    fn = console[level];
+    fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args));
+  }
+};
+
+// NOP, because piping the formatted logs can only cause trouble.
+logger.pipe = function() { };
+
+module.exports = logger;
 
 
 /***/ }),
-/* 743 */
+/* 731 */
+/***/ ((module) => {
+
+var hex = {
+  black: '#000',
+  red: '#c23621',
+  green: '#25bc26',
+  yellow: '#bbbb00',
+  blue:  '#492ee1',
+  magenta: '#d338d3',
+  cyan: '#33bbc8',
+  gray: '#808080',
+  purple: '#708'
+};
+function color(fg, isInverse) {
+  if(isInverse) {
+    return 'color: #fff; background: '+hex[fg]+';';
+  } else {
+    return 'color: '+hex[fg]+';';
+  }
+}
+
+module.exports = color;
+
+
+/***/ }),
+/* 732 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var Stack = __webpack_require__(404),
-    assignMergeValue = __webpack_require__(744),
-    baseFor = __webpack_require__(537),
-    baseMergeDeep = __webpack_require__(745),
-    isObject = __webpack_require__(52),
-    keysIn = __webpack_require__(567),
-    safeGet = __webpack_require__(746);
+var Transform = __webpack_require__(718),
+    color = __webpack_require__(731),
+    colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] },
+    logger = new Transform();
 
-/**
- * The base implementation of `_.merge` without support for multiple sources.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {number} srcIndex The index of `source`.
- * @param {Function} [customizer] The function to customize merged values.
- * @param {Object} [stack] Tracks traversed source values and their merged
- *  counterparts.
- */
-function baseMerge(object, source, srcIndex, customizer, stack) {
-  if (object === source) {
-    return;
+logger.write = function(name, level, args) {
+  var fn = console.log;
+  if(level != 'debug' && console[level]) {
+    fn = console[level];
   }
-  baseFor(source, function(srcValue, key) {
-    stack || (stack = new Stack);
-    if (isObject(srcValue)) {
-      baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
-    }
-    else {
-      var newValue = customizer
-        ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
-        : undefined;
 
-      if (newValue === undefined) {
-        newValue = srcValue;
-      }
-      assignMergeValue(object, key, newValue);
+  var subset = [], i = 0;
+  if(level != 'info') {
+    for(; i < args.length; i++) {
+      if(typeof args[i] != 'string') break;
     }
-  }, keysIn);
-}
+    fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i)));
+  } else {
+    fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args));
+  }
+};
 
-module.exports = baseMerge;
+// NOP, because piping the formatted logs can only cause trouble.
+logger.pipe = function() { };
+
+module.exports = logger;
 
 
 /***/ }),
-/* 744 */
+/* 733 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseAssignValue = __webpack_require__(534),
-    eq = __webpack_require__(385);
+var Transform = __webpack_require__(718);
 
-/**
- * This function is like `assignValue` except that it doesn't assign
- * `undefined` values.
- *
- * @private
- * @param {Object} object The object to modify.
- * @param {string} key The key of the property to assign.
- * @param {*} value The value to assign.
- */
-function assignMergeValue(object, key, value) {
-  if ((value !== undefined && !eq(object[key], value)) ||
-      (value === undefined && !(key in object))) {
-    baseAssignValue(object, key, value);
+function Stringify() {}
+
+Transform.mixin(Stringify);
+
+Stringify.prototype.write = function(name, level, args) {
+  var result = [];
+  if(name) result.push(name);
+  if(level) result.push(level);
+  result = result.concat(args);
+  for(var i = 0; i < result.length; i++) {
+    if(result[i] && typeof result[i] == 'object') {
+      // Buffers in Node.js look bad when stringified
+      if(result[i].constructor && result[i].constructor.isBuffer) {
+        result[i] = result[i].toString();
+      } else {
+        try {
+          result[i] = JSON.stringify(result[i]);
+        } catch(stringifyError) {
+          // happens when an object has a circular structure
+          // do not throw an error, when printing, the toString() method of the object will be used
+        }
+      }
+    } else {
+      result[i] = result[i];
+    }
   }
+  this.emit('item',  result.join(' ') + '\n');
+};
+
+module.exports = Stringify;
+
+
+/***/ }),
+/* 734 */
+/***/ ((module) => {
+
+function RedisBackend(options) {
+  this.client = options.client;
+  this.key = options.key;
 }
 
-module.exports = assignMergeValue;
+RedisBackend.prototype.write = function(str) {
+  this.client.rpush(this.key, str);
+};
+
+RedisBackend.prototype.end = function() {};
+
+RedisBackend.prototype.clear = function(cb) {
+  this.client.del(this.key, cb);
+};
+
+module.exports = RedisBackend;
 
 
 /***/ }),
-/* 745 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 735 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var assignMergeValue = __webpack_require__(744),
-    cloneBuffer = __webpack_require__(570),
-    cloneTypedArray = __webpack_require__(583),
-    copyArray = __webpack_require__(571),
-    initCloneObject = __webpack_require__(584),
-    isArguments = __webpack_require__(432),
-    isArray = __webpack_require__(55),
-    isArrayLikeObject = __webpack_require__(552),
-    isBuffer = __webpack_require__(434),
-    isFunction = __webpack_require__(45),
-    isObject = __webpack_require__(52),
-    isPlainObject = __webpack_require__(619),
-    isTypedArray = __webpack_require__(437),
-    safeGet = __webpack_require__(746),
-    toPlainObject = __webpack_require__(747);
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.QueryIDGenerator = exports.getQueryFromSlice = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports["default"] = exports.makeSorterFromDefinition = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.isReceivingData = exports.isQueryAction = void 0;
+
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
+
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
+
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
+
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
+
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
+
+var _mapValues = _interopRequireDefault(__webpack_require__(545));
+
+var _groupBy = _interopRequireDefault(__webpack_require__(736));
+
+var _difference = _interopRequireDefault(__webpack_require__(737));
+
+var _intersection = _interopRequireDefault(__webpack_require__(739));
+
+var _concat = _interopRequireDefault(__webpack_require__(742));
+
+var _isPlainObject = _interopRequireDefault(__webpack_require__(631));
+
+var _uniq = _interopRequireDefault(__webpack_require__(624));
+
+var _orderBy = _interopRequireDefault(__webpack_require__(743));
+
+var _isArray = _interopRequireDefault(__webpack_require__(55));
+
+var _isString = _interopRequireDefault(__webpack_require__(54));
+
+var _get = _interopRequireDefault(__webpack_require__(370));
+
+var _sift = _interopRequireDefault(__webpack_require__(749));
+
+var _cozyFlags = _interopRequireDefault(__webpack_require__(615));
+
+var _documents = __webpack_require__(710);
+
+var _mutations = __webpack_require__(750);
+
+var _helpers = __webpack_require__(751);
+
+var _dsl = __webpack_require__(619);
+
+var _types = __webpack_require__(622);
+
+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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
+
+var INIT_QUERY = 'INIT_QUERY';
+var LOAD_QUERY = 'LOAD_QUERY';
+var RECEIVE_QUERY_RESULT = 'RECEIVE_QUERY_RESULT';
+var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR'; // Read if the devtools are open to store the execution time
+// This is done at runtime to not read the value everytime
+// we receive a result. So you have to refresh your page
+// in order to get the stats
+
+var executionStatsEnabled = (0, _cozyFlags.default)('debug');
+
+var isQueryAction = function isQueryAction(action) {
+  return [INIT_QUERY, LOAD_QUERY, RECEIVE_QUERY_RESULT, RECEIVE_QUERY_ERROR].indexOf(action.type) !== -1;
+};
+
+exports.isQueryAction = isQueryAction;
+
+var isReceivingData = function isReceivingData(action) {
+  return action.type === RECEIVE_QUERY_RESULT;
+};
+/** @type {QueryState} */
+
+
+exports.isReceivingData = isReceivingData;
+var queryInitialState = {
+  id: null,
+  definition: null,
+  fetchStatus: 'pending',
+  lastFetch: null,
+  lastUpdate: null,
+  lastErrorUpdate: null,
+  lastError: null,
+  hasMore: false,
+  count: 0,
+  data: [],
+  bookmark: null
+};
+
+var updateQueryDataFromResponse = function updateQueryDataFromResponse(queryState, response, documents) {
+  var updatedIds = (0, _uniq.default)([].concat((0, _toConsumableArray2.default)(queryState.data), (0, _toConsumableArray2.default)(response.data.map(_helpers.properId))));
+
+  if (queryState.definition.sort) {
+    var sorter = makeSorterFromDefinition(queryState.definition);
+    var doctype = queryState.definition.doctype;
+    var allDocs = documents[doctype];
+    var docs = allDocs ? updatedIds.map(function (_id) {
+      return allDocs[_id];
+    }).filter(Boolean) : [];
+    var sortedDocs = sorter(docs);
+    updatedIds = sortedDocs.map(_helpers.properId);
+  }
 
+  return updatedIds;
+};
 /**
- * A specialized version of `baseMerge` for arrays and objects which performs
- * deep merges and tracks traversed objects enabling objects with circular
- * references to be merged.
+ * Reducer for a query slice
  *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {string} key The key of the value to merge.
- * @param {number} srcIndex The index of `source`.
- * @param {Function} mergeFunc The function to merge values.
- * @param {Function} [customizer] The function to customize assigned values.
- * @param {Object} [stack] Tracks traversed source values and their merged
- *  counterparts.
+ * @param  {QueryState} state - Current state
+ * @param  {any} action - Redux action
+ * @param  {DocumentsStateSlice} documents - Reference to the next documents slice
+ * @returns {QueryState} - Next state
  */
-function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
-  var objValue = safeGet(object, key),
-      srcValue = safeGet(source, key),
-      stacked = stack.get(srcValue);
-
-  if (stacked) {
-    assignMergeValue(object, key, stacked);
-    return;
-  }
-  var newValue = customizer
-    ? customizer(objValue, srcValue, (key + ''), object, source, stack)
-    : undefined;
 
-  var isCommon = newValue === undefined;
 
-  if (isCommon) {
-    var isArr = isArray(srcValue),
-        isBuff = !isArr && isBuffer(srcValue),
-        isTyped = !isArr && !isBuff && isTypedArray(srcValue);
+var query = function query() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : queryInitialState;
+  var action = arguments.length > 1 ? arguments[1] : undefined;
+  var documents = arguments.length > 2 ? arguments[2] : undefined;
 
-    newValue = srcValue;
-    if (isArr || isBuff || isTyped) {
-      if (isArray(objValue)) {
-        newValue = objValue;
-      }
-      else if (isArrayLikeObject(objValue)) {
-        newValue = copyArray(objValue);
-      }
-      else if (isBuff) {
-        isCommon = false;
-        newValue = cloneBuffer(srcValue, true);
-      }
-      else if (isTyped) {
-        isCommon = false;
-        newValue = cloneTypedArray(srcValue, true);
-      }
-      else {
-        newValue = [];
+  switch (action.type) {
+    case INIT_QUERY:
+      if (state.lastUpdate && state.id === action.queryId && state.definition === action.queryDefinition) {
+        return state;
       }
-    }
-    else if (isPlainObject(srcValue) || isArguments(srcValue)) {
-      newValue = objValue;
-      if (isArguments(objValue)) {
-        newValue = toPlainObject(objValue);
+
+      return _objectSpread(_objectSpread({}, state), {}, {
+        id: action.queryId,
+        definition: action.queryDefinition,
+        options: action.options,
+        // When the query is new, we set "fetchStatus" to "loading"
+        // directly since we know it will be loaded right away.
+        // This way, the loadQuery action will have no effect, and
+        // we save an additional render.
+        fetchStatus: state.lastUpdate ? state.fetchStatus : 'pending'
+      });
+
+    case LOAD_QUERY:
+      if (state.fetchStatus === 'loading') {
+        return state;
       }
-      else if (!isObject(objValue) || isFunction(objValue)) {
-        newValue = initCloneObject(srcValue);
+
+      return _objectSpread(_objectSpread({}, state), {}, {
+        fetchStatus: 'loading'
+      });
+
+    case RECEIVE_QUERY_RESULT:
+      {
+        var response = action.response;
+
+        if (!response.data) {
+          return state;
+        }
+        /** @type {Partial<QueryState>} */
+
+
+        var common = _objectSpread({
+          fetchStatus: 'loaded',
+          lastFetch: Date.now(),
+          lastUpdate: Date.now()
+        }, executionStatsEnabled && {
+          execution_stats: response.execution_stats
+        });
+
+        if (!Array.isArray(response.data)) {
+          return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
+            hasMore: false,
+            count: 1,
+            data: [(0, _helpers.properId)(response.data)]
+          });
+        }
+
+        return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
+          bookmark: response.bookmark || null,
+          hasMore: response.next !== undefined ? response.next : state.hasMore,
+          count: response.meta && response.meta.count ? response.meta.count : response.data.length,
+          data: updateQueryDataFromResponse(state, response, documents)
+        });
       }
-    }
-    else {
-      isCommon = false;
-    }
-  }
-  if (isCommon) {
-    // Recursively merge objects and arrays (susceptible to call stack limits).
-    stack.set(srcValue, newValue);
-    mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
-    stack['delete'](srcValue);
+
+    case RECEIVE_QUERY_ERROR:
+      return _objectSpread(_objectSpread({}, state), {}, {
+        id: action.queryId,
+        fetchStatus: 'failed',
+        lastError: action.error,
+        lastErrorUpdate: Date.now()
+      });
+
+    default:
+      return state;
   }
-  assignMergeValue(object, key, newValue);
-}
+};
+/**
+ * Normalize sift selector
+ *
+ * @returns {object}
+ */
 
-module.exports = baseMergeDeep;
 
+var convert$gtNullSelectors = function convert$gtNullSelectors(selector) {
+  var result = {};
 
-/***/ }),
-/* 746 */
-/***/ ((module) => {
+  for (var _i = 0, _Object$entries = Object.entries(selector); _i < _Object$entries.length; _i++) {
+    var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
+        key = _Object$entries$_i[0],
+        value = _Object$entries$_i[1];
+
+    var convertedValue = (0, _isPlainObject.default)(value) ? convert$gtNullSelectors(value) : value;
+    var convertedKey = key === '$gt' && convertedValue === null ? '$gtnull' : key;
+    result[convertedKey] = convertedValue;
+  }
 
+  return result;
+};
 /**
- * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
+ * Merges query selectors with query partial indexes
  *
- * @private
- * @param {Object} object The object to query.
- * @param {string} key The key of the property to get.
- * @returns {*} Returns the property value.
+ * @param {object} queryDefinition - A query definition
+ * @returns {object} A query definition selector
  */
-function safeGet(object, key) {
-  if (key === 'constructor' && typeof object[key] === 'function') {
-    return;
-  }
 
-  if (key == '__proto__') {
-    return;
-  }
 
-  return object[key];
-}
+exports.convert$gtNullSelectors = convert$gtNullSelectors;
 
-module.exports = safeGet;
+var mergeSelectorAndPartialIndex = function mergeSelectorAndPartialIndex(queryDefinition) {
+  return _objectSpread(_objectSpread({}, queryDefinition.selector), (0, _get.default)(queryDefinition, 'partialFilter'));
+};
+/**
+ * @param  {QueryDefinition} queryDefinition - A query definition
+ * @returns {function(CozyClientDocument): boolean}
+ */
 
 
-/***/ }),
-/* 747 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+exports.mergeSelectorAndPartialIndex = mergeSelectorAndPartialIndex;
+
+var getSelectorFilterFn = function getSelectorFilterFn(queryDefinition) {
+  if (queryDefinition.selector) {
+    var selectors = mergeSelectorAndPartialIndex(queryDefinition); // sift does not work like couchdb when using { $gt: null } as a selector, so we use a custom operator
 
-var copyObject = __webpack_require__(565),
-    keysIn = __webpack_require__(567);
+    _sift.default.use({
+      $gtnull: function $gtnull(_selectorValue, actualValue) {
+        return !!actualValue;
+      }
+    });
 
+    return (0, _sift.default)(convert$gtNullSelectors(selectors));
+  } else if (queryDefinition.id) {
+    /** @type {object} */
+    var siftQuery = {
+      _id: queryDefinition.id
+    };
+    return (0, _sift.default)(siftQuery);
+  } else if (queryDefinition.ids) {
+    /** @type {object} */
+    var _siftQuery = {
+      _id: {
+        $in: queryDefinition.ids
+      }
+    };
+    return (0, _sift.default)(_siftQuery);
+  } else {
+    return null;
+  }
+};
 /**
- * Converts `value` to a plain object flattening inherited enumerable string
- * keyed properties of `value` to own properties of the plain object.
  *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {Object} Returns the converted plain object.
- * @example
+ * Returns a predicate function that checks if a document should be
+ * included in the result of the query.
  *
- * function Foo() {
- *   this.b = 2;
- * }
+ * @param  {QueryState} query - Definition of the query
+ * @returns {function(CozyClientDocument): boolean} Predicate function
+ */
+
+
+var getQueryDocumentsChecker = function getQueryDocumentsChecker(query) {
+  var qdoctype = query.definition.doctype;
+  var selectorFilterFn = getSelectorFilterFn(query.definition);
+  return function (datum) {
+    var ddoctype = datum._type;
+    if (ddoctype !== qdoctype) return false;
+    if (datum._deleted) return false;
+    if (!selectorFilterFn) return true;
+    return !!selectorFilterFn(datum);
+  };
+};
+
+var makeCaseInsensitiveStringSorter = function makeCaseInsensitiveStringSorter(attrName) {
+  return function (item) {
+    var attrValue = (0, _get.default)(item, attrName);
+    return (0, _isString.default)(attrValue) ? attrValue.toLowerCase() : attrValue;
+  };
+};
+/**
+ * Creates a sort function from a definition.
  *
- * Foo.prototype.c = 3;
+ * Used to sort query results inside the store when creating a file or
+ * receiving updates.
  *
- * _.assign({ 'a': 1 }, new Foo);
- * // => { 'a': 1, 'b': 2 }
+ * @param {QueryDefinition} definition - A query definition
+ * @returns {function(Array<CozyClientDocument>): Array<CozyClientDocument>}
  *
- * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
- * // => { 'a': 1, 'b': 2, 'c': 3 }
+ * @private
  */
-function toPlainObject(value) {
-  return copyObject(value, keysIn(value));
-}
-
-module.exports = toPlainObject;
 
 
-/***/ }),
-/* 748 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseRest = __webpack_require__(544),
-    isIterateeCall = __webpack_require__(749);
+var makeSorterFromDefinition = function makeSorterFromDefinition(definition) {
+  var sort = definition.sort;
 
+  if (!sort) {
+    return function (docs) {
+      return docs;
+    };
+  } else if (!(0, _isArray.default)(definition.sort)) {
+    console.warn('Correct update of queries with a sort that is not an array is not supported. Use an array as argument of QueryDefinition::sort');
+    return function (docs) {
+      return docs;
+    };
+  } else {
+    var attributeOrders = sort.map(function (x) {
+      return Object.entries(x)[0];
+    });
+    var attrs = attributeOrders.map(function (x) {
+      return x[0];
+    }).map(makeCaseInsensitiveStringSorter);
+    var orders = attributeOrders.map(function (x) {
+      return x[1];
+    });
+    return function (docs) {
+      return (0, _orderBy.default)(docs, attrs, orders);
+    };
+  }
+};
 /**
- * Creates a function like `_.assign`.
+ * Updates query state when new data comes in
  *
- * @private
- * @param {Function} assigner The function to assign values.
- * @returns {Function} Returns the new assigner function.
+ * @param  {QueryState} query - Current query state
+ * @param  {Array<CozyClientDocument>} newData - New documents (in most case from the server)
+ * @param  {DocumentsStateSlice} documents - A reference to the documents slice
+ * @returns {QueryState} - Updated query state
  */
-function createAssigner(assigner) {
-  return baseRest(function(object, sources) {
-    var index = -1,
-        length = sources.length,
-        customizer = length > 1 ? sources[length - 1] : undefined,
-        guard = length > 2 ? sources[2] : undefined;
 
-    customizer = (assigner.length > 3 && typeof customizer == 'function')
-      ? (length--, customizer)
-      : undefined;
 
-    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
-      customizer = length < 3 ? undefined : customizer;
-      length = 1;
-    }
-    object = Object(object);
-    while (++index < length) {
-      var source = sources[index];
-      if (source) {
-        assigner(object, source, index, customizer);
-      }
-    }
-    return object;
+exports.makeSorterFromDefinition = makeSorterFromDefinition;
+
+var updateData = function updateData(query, newData, documents) {
+  var belongsToQuery = getQueryDocumentsChecker(query);
+  var res = (0, _mapValues.default)((0, _groupBy.default)(newData, belongsToQuery), function (docs) {
+    return docs.map(_helpers.properId);
   });
-}
+  var _res$true = res.true,
+      matchedIds = _res$true === void 0 ? [] : _res$true,
+      _res$false = res.false,
+      unmatchedIds = _res$false === void 0 ? [] : _res$false;
+  var originalIds = query.data;
+  var autoUpdate = query.options && query.options.autoUpdate;
+  var shouldRemove = !autoUpdate || autoUpdate.remove !== false;
+  var shouldAdd = !autoUpdate || autoUpdate.add !== false;
+  var shouldUpdate = !autoUpdate || autoUpdate.update !== false;
+  var toRemove = shouldRemove ? (0, _intersection.default)(originalIds, unmatchedIds) : [];
+  var toAdd = shouldAdd ? (0, _difference.default)(matchedIds, originalIds) : [];
+  var toUpdate = shouldUpdate ? (0, _intersection.default)(originalIds, matchedIds) : [];
+  var changed = toRemove.length || toAdd.length || toUpdate.length; // concat doesn't check duplicates (contrarily to union), which is ok as
+  // toAdd does not contain any id present in originalIds, by construction.
+  // It is also faster than union.
 
-module.exports = createAssigner;
+  var updatedData = (0, _difference.default)((0, _concat.default)(originalIds, toAdd), toRemove);
+
+  if (query.definition.sort && documents) {
+    var sorter = makeSorterFromDefinition(query.definition);
+    var allDocs = documents[query.definition.doctype];
+    var docs = updatedData.map(function (_id) {
+      return allDocs[_id];
+    });
+    var sortedDocs = sorter(docs);
+    updatedData = sortedDocs.map(_helpers.properId);
+  }
+
+  return _objectSpread(_objectSpread({}, query), {}, {
+    data: updatedData,
+    count: updatedData.length,
+    lastUpdate: changed ? Date.now() : query.lastUpdate
+  });
+};
+/**
+ * Creates a function that returns an updated query state
+ * from an action
+ *
+ * @param  {object} action - A redux action
+ * @param  {DocumentsStateSlice} documents - Reference to documents slice
+ * @returns {function(QueryState): QueryState} - Updater query state
+ */
 
 
-/***/ }),
-/* 749 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var autoQueryUpdater = function autoQueryUpdater(action, documents) {
+  return function (query) {
+    var data = (0, _get.default)(action, 'response.data') || (0, _get.default)(action, 'definition.document');
+    if (!data) return query;
 
-var eq = __webpack_require__(385),
-    isArrayLike = __webpack_require__(446),
-    isIndex = __webpack_require__(436),
-    isObject = __webpack_require__(52);
+    if (!Array.isArray(data)) {
+      data = [data];
+    }
+
+    if (!data.length) {
+      return query;
+    }
 
+    if (query.definition.doctype !== data[0]._type) {
+      return query;
+    }
+
+    return updateData(query, data, documents);
+  };
+};
 /**
- * Checks if the given arguments are from an iteratee call.
+ * Creates a function that returns an updated query state
+ * from an action
  *
- * @private
- * @param {*} value The potential iteratee value argument.
- * @param {*} index The potential iteratee index or key argument.
- * @param {*} object The potential iteratee object argument.
- * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
- *  else `false`.
+ * @param  {object} action - A redux action
+ * @param  {DocumentsStateSlice} documents - Reference to documents slice
+ * @returns {function(QueryState): QueryState} - Updater query state
  */
-function isIterateeCall(value, index, object) {
-  if (!isObject(object)) {
-    return false;
-  }
-  var type = typeof index;
-  if (type == 'number'
-        ? (isArrayLike(object) && isIndex(index, object.length))
-        : (type == 'string' && index in object)
-      ) {
-    return eq(object[index], value);
-  }
-  return false;
-}
 
-module.exports = isIterateeCall;
 
+var manualQueryUpdater = function manualQueryUpdater(action, documents) {
+  return function (query) {
+    var updateQueries = action.updateQueries;
+    var response = action.response;
+    var updater = updateQueries[query.id];
 
-/***/ }),
-/* 750 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+    if (!updater) {
+      return query;
+    }
 
-"use strict";
+    var doctype = query.definition.doctype;
+    var oldData = query.data;
+    var oldDocs = mapIdsToDocuments(documents, doctype, oldData);
+    var newData = updater(oldDocs, response);
+    var newDataIds = newData.map(_helpers.properId);
+    return _objectSpread(_objectSpread({}, query), {}, {
+      data: newDataIds,
+      count: newDataIds.length,
+      lastUpdate: Date.now()
+    });
+  };
+};
+/**
+ * @param  {QueriesStateSlice}  state - Redux slice containing all the query states indexed by name
+ * @param  {object}  action - Income redux action
+ * @param  {DocumentsStateSlice}  documents - Reference to documents slice
+ * @param  {boolean} haveDocumentsChanged - Has the document slice changed with current action
+ * @returns {QueriesStateSlice}
+ */
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var queries = function queries() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  var action = arguments.length > 1 ? arguments[1] : undefined;
+  var documents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+  var haveDocumentsChanged = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+  if (action.type == INIT_QUERY) {
+    var newQueryState = query(state[action.queryId], action, documents); // Do not create new object unnecessarily
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+    if (newQueryState === state[action.queryId]) {
+      return state;
+    }
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+    return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, action.queryId, newQueryState));
+  }
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+  if (isQueryAction(action)) {
+    var updater = autoQueryUpdater(action, documents);
+    return (0, _mapValues.default)(state, function (queryState) {
+      if (queryState.id == action.queryId) {
+        return query(queryState, action, documents);
+      } else if (haveDocumentsChanged) {
+        return updater(queryState);
+      } else {
+        return queryState;
+      }
+    });
+  }
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+  if ((0, _mutations.isReceivingMutationResult)(action)) {
+    var _updater = action.updateQueries ? manualQueryUpdater(action, documents) : autoQueryUpdater(action, documents);
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+    return (0, _mapValues.default)(state, _updater);
+  }
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+  return state;
+};
 
-var _get2 = _interopRequireDefault(__webpack_require__(358));
+var _default = queries;
+/**
+ * Create the query states in the store. Queries are indexed
+ * in the store by queryId
+ *
+ * @param  {string} queryId  Name/id of the query
+ * @param  {QueryDefinition} queryDefinition - Definition of the created query
+ * @param  {QueryOptions} [options] - Options for the created query
+ */
 
-var _set = _interopRequireDefault(__webpack_require__(751));
+exports["default"] = _default;
 
-var _dsl = __webpack_require__(607);
+var initQuery = function initQuery(queryId, queryDefinition) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
 
-var _types = __webpack_require__(610);
+  if (!queryDefinition.doctype) {
+    throw new Error('Cannot init query with no doctype');
+  }
 
-var _Association2 = _interopRequireDefault(__webpack_require__(740));
+  return {
+    type: INIT_QUERY,
+    queryId: queryId,
+    queryDefinition: queryDefinition,
+    options: options
+  };
+};
 
-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; }
+exports.initQuery = initQuery;
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
+var loadQuery = function loadQuery(queryId) {
+  return {
+    type: LOAD_QUERY,
+    queryId: queryId
+  };
+};
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+exports.loadQuery = loadQuery;
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var receiveQueryResult = function receiveQueryResult(queryId, response) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+  return _objectSpread({
+    type: RECEIVE_QUERY_RESULT,
+    queryId: queryId,
+    response: response
+  }, options);
+};
 
-var HasOne = /*#__PURE__*/function (_Association) {
-  (0, _inherits2.default)(HasOne, _Association);
+exports.receiveQueryResult = receiveQueryResult;
 
-  var _super = _createSuper(HasOne);
+var receiveQueryError = function receiveQueryError(queryId, error) {
+  return {
+    type: RECEIVE_QUERY_ERROR,
+    queryId: queryId,
+    error: error
+  };
+}; // selectors
 
-  function HasOne() {
-    (0, _classCallCheck2.default)(this, HasOne);
-    return _super.apply(this, arguments);
-  }
 
-  (0, _createClass2.default)(HasOne, [{
-    key: "add",
+exports.receiveQueryError = receiveQueryError;
 
-    /**
-     * Add the relationship to the target document
-     *
-     * @param {CozyClientDocument} doc - Document to add as a relationship
-     * @returns {CozyClientDocument} The saved target document
-     */
-    value: function add(doc) {
-      this.setRelationship(doc);
-      return this.save(this.target);
-    }
-    /**
-     * Remove the relationship from the target document
-     *
-     * @returns {CozyClientDocument} The saved target document
-     */
+var mapIdsToDocuments = function mapIdsToDocuments(documents, doctype, ids) {
+  return ids.map(function (id) {
+    return (0, _documents.getDocumentFromSlice)(documents, doctype, id);
+  });
+};
 
-  }, {
-    key: "remove",
-    value: function remove() {
-      this.setRelationship(undefined);
-      return this.save(this.target);
-    }
-  }, {
-    key: "setRelationship",
-    value: function setRelationship(doc) {
-      if (doc && doc._type !== this.doctype) {
-        throw new Error("Tried to associate a ".concat(doc._type, " document to a HasOne relationship on ").concat(this.doctype, " document"));
-      }
+var getQueryFromSlice = function getQueryFromSlice(state, queryId, documents) {
+  if (!state || !state[queryId]) {
+    return _objectSpread(_objectSpread({}, queryInitialState), {}, {
+      id: queryId,
+      data: null
+    });
+  }
 
-      var path = "relationships[".concat(this.name, "].data");
+  var query = state[queryId];
+  return documents ? _objectSpread(_objectSpread({}, query), {}, {
+    data: mapIdsToDocuments(documents, query.definition.doctype, query.data)
+  }) : query;
+};
 
-      if (doc) {
-        (0, _set.default)(this.target, path, {
-          _id: doc._id,
-          _type: doc._type
-        });
-      } else {
-        (0, _set.default)(this.target, path, undefined);
-      }
-    }
-  }, {
-    key: "set",
-    value: function set(doc) {
-      console.warn('set is deprecated for has-one relationships. Use `add` instead.');
-      this.setRelationship(doc);
-    }
-  }, {
-    key: "unset",
-    value: function unset() {
-      console.warn('unset is deprecated for has-one relationships. Use `remove` instead.');
-      this.setRelationship(undefined);
-    }
-  }, {
-    key: "dehydrate",
-    value: function dehydrate(doc) {
-      if (!this.raw) {
-        return doc;
-      }
+exports.getQueryFromSlice = getQueryFromSlice;
 
-      return _objectSpread(_objectSpread({}, doc), {}, {
-        relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, {
-          data: this.raw
-        }))
-      });
-    }
-  }, {
-    key: "raw",
-    get: function get() {
-      return (0, _get2.default)(this.target, "relationships[".concat(this.name, "].data"), null);
-    }
-  }, {
-    key: "data",
-    get: function get() {
-      if (!this.raw) {
-        return null;
-      }
+var QueryIDGenerator = /*#__PURE__*/function () {
+  function QueryIDGenerator() {
+    (0, _classCallCheck2.default)(this, QueryIDGenerator);
+    this.idCounter = 1;
+  }
+  /**
+   * Generates a random id for unamed queries
+   */
 
-      return this.get(this.doctype, this.raw._id);
+
+  (0, _createClass2.default)(QueryIDGenerator, [{
+    key: "generateRandomId",
+    value: function generateRandomId() {
+      var id = this.idCounter;
+      this.idCounter++;
+      return id.toString();
     }
     /**
-     * @param {CozyClientDocument} document - Document to query
-     * @param {object} client - The CozyClient instance
-     * @param {Association} assoc - The query params
+     * Generates an id for queries
+     * If the query is a getById only query,
+     * we can generate a name for it.
      *
-     * @returns {CozyClientDocument | QueryDefinition}
+     * If not, let's generate a random id
+     *
+     * @param {QueryDefinition} queryDefinition The query definition
+     * @returns {string}
      */
 
-  }], [{
-    key: "query",
-    value: function query(document, client, assoc) {
-      var relationship = (0, _get2.default)(document, "relationships.".concat(assoc.name, ".data"), {});
-
-      if (!relationship || !relationship._id) {
-        return null;
+  }, {
+    key: "generateId",
+    value: function generateId(queryDefinition) {
+      if (!(0, _dsl.isAGetByIdQuery)(queryDefinition)) {
+        return this.generateRandomId();
+      } else {
+        var id = queryDefinition.id,
+            doctype = queryDefinition.doctype;
+        return "".concat(doctype, "/").concat(id);
       }
-
-      return (0, _dsl.Q)(assoc.doctype).getById(relationship._id);
     }
   }]);
-  return HasOne;
-}(_Association2.default);
+  return QueryIDGenerator;
+}();
 
-exports["default"] = HasOne;
+exports.QueryIDGenerator = QueryIDGenerator;
+QueryIDGenerator.UNNAMED = 'unnamed';
 
 /***/ }),
-/* 751 */
+/* 736 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseSet = __webpack_require__(650);
+var baseAssignValue = __webpack_require__(546),
+    createAggregator = __webpack_require__(712);
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
 /**
- * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
- * it's created. Arrays are created for missing index properties while objects
- * are created for all other missing properties. Use `_.setWith` to customize
- * `path` creation.
- *
- * **Note:** This method mutates `object`.
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` thru `iteratee`. The order of grouped values
+ * is determined by the order they occur in `collection`. The corresponding
+ * value of each key is an array of elements responsible for generating the
+ * key. The iteratee is invoked with one argument: (value).
  *
  * @static
  * @memberOf _
- * @since 3.7.0
- * @category Object
- * @param {Object} object The object to modify.
- * @param {Array|string} path The path of the property to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns `object`.
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+ * @returns {Object} Returns the composed aggregate object.
  * @example
  *
- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
- *
- * _.set(object, 'a[0].b.c', 4);
- * console.log(object.a[0].b.c);
- * // => 4
+ * _.groupBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': [4.2], '6': [6.1, 6.3] }
  *
- * _.set(object, ['x', '0', 'y', 'z'], 5);
- * console.log(object.x[0].y.z);
- * // => 5
+ * // The `_.property` iteratee shorthand.
+ * _.groupBy(['one', 'two', 'three'], 'length');
+ * // => { '3': ['one', 'two'], '5': ['three'] }
  */
-function set(object, path, value) {
-  return object == null ? object : baseSet(object, path, value);
-}
+var groupBy = createAggregator(function(result, value, key) {
+  if (hasOwnProperty.call(result, key)) {
+    result[key].push(value);
+  } else {
+    baseAssignValue(result, key, [value]);
+  }
+});
 
-module.exports = set;
+module.exports = groupBy;
 
 
 /***/ }),
-/* 752 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.BelongsToInPlace = exports["default"] = void 0;
-
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
-
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
-
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+/* 737 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _Association2 = _interopRequireDefault(__webpack_require__(740));
+var baseDifference = __webpack_require__(738),
+    baseFlatten = __webpack_require__(553),
+    baseRest = __webpack_require__(556),
+    isArrayLikeObject = __webpack_require__(564);
 
-var _dsl = __webpack_require__(607);
+/**
+ * Creates an array of `array` values not included in the other given arrays
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. The order and references of result values are
+ * determined by the first array.
+ *
+ * **Note:** Unlike `_.pullAll`, this method returns a new array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @returns {Array} Returns the new array of filtered values.
+ * @see _.without, _.xor
+ * @example
+ *
+ * _.difference([2, 1], [2, 3]);
+ * // => [1]
+ */
+var difference = baseRest(function(array, values) {
+  return isArrayLikeObject(array)
+    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
+    : [];
+});
 
-var _types = __webpack_require__(610);
+module.exports = difference;
 
-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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
+/***/ }),
+/* 738 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+var SetCache = __webpack_require__(425),
+    arrayIncludes = __webpack_require__(476),
+    arrayIncludesWith = __webpack_require__(481),
+    arrayMap = __webpack_require__(410),
+    baseUnary = __webpack_require__(452),
+    cacheHas = __webpack_require__(429);
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
 
 /**
- * Here the id of the document is directly set in the attribute
- * of the document, not in the relationships attribute
+ * The base implementation of methods like `_.difference` without support
+ * for excluding multiple arrays or iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Array} values The values to exclude.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
  */
-var HasOneInPlace = /*#__PURE__*/function (_Association) {
-  (0, _inherits2.default)(HasOneInPlace, _Association);
-
-  var _super = _createSuper(HasOneInPlace);
+function baseDifference(array, values, iteratee, comparator) {
+  var index = -1,
+      includes = arrayIncludes,
+      isCommon = true,
+      length = array.length,
+      result = [],
+      valuesLength = values.length;
 
-  function HasOneInPlace() {
-    (0, _classCallCheck2.default)(this, HasOneInPlace);
-    return _super.apply(this, arguments);
+  if (!length) {
+    return result;
+  }
+  if (iteratee) {
+    values = arrayMap(values, baseUnary(iteratee));
+  }
+  if (comparator) {
+    includes = arrayIncludesWith;
+    isCommon = false;
+  }
+  else if (values.length >= LARGE_ARRAY_SIZE) {
+    includes = cacheHas;
+    isCommon = false;
+    values = new SetCache(values);
   }
+  outer:
+  while (++index < length) {
+    var value = array[index],
+        computed = iteratee == null ? value : iteratee(value);
 
-  (0, _createClass2.default)(HasOneInPlace, [{
-    key: "dehydrate",
-    value: function dehydrate(doc) {
-      return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || undefined));
-    }
-  }, {
-    key: "raw",
-    get: function get() {
-      return this.target[this.name];
+    value = (comparator || value !== 0) ? value : 0;
+    if (isCommon && computed === computed) {
+      var valuesIndex = valuesLength;
+      while (valuesIndex--) {
+        if (values[valuesIndex] === computed) {
+          continue outer;
+        }
+      }
+      result.push(value);
     }
-  }, {
-    key: "data",
-    get: function get() {
-      return this.get(this.doctype, this.raw);
+    else if (!includes(values, computed, comparator)) {
+      result.push(value);
     }
-    /**
-     * @param {CozyClientDocument} document - Document to query
-     * @param {object} client - The CozyClient instance
-     * @param {Association} assoc - The query params
-     *
-     * @returns {CozyClientDocument | QueryDefinition}
-     */
+  }
+  return result;
+}
 
-  }], [{
-    key: "query",
-    value: function query(document, client, assoc) {
-      var id = document[assoc.name];
-      return client.getDocumentFromState(assoc.doctype, id) || (0, _dsl.Q)(assoc.doctype).getById(id);
-    }
-  }]);
-  return HasOneInPlace;
-}(_Association2.default);
+module.exports = baseDifference;
 
-exports["default"] = HasOneInPlace;
-var BelongsToInPlace = HasOneInPlace;
-exports.BelongsToInPlace = BelongsToInPlace;
 
 /***/ }),
-/* 753 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
+/* 739 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var arrayMap = __webpack_require__(410),
+    baseIntersection = __webpack_require__(740),
+    baseRest = __webpack_require__(556),
+    castArrayLikeObject = __webpack_require__(741);
 
-var _interopRequireDefault = __webpack_require__(512);
+/**
+ * Creates an array of unique values that are included in all given arrays
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+ * for equality comparisons. The order and references of result values are
+ * determined by the first array.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * _.intersection([2, 1], [2, 3]);
+ * // => [2]
+ */
+var intersection = baseRest(function(arrays) {
+  var mapped = arrayMap(arrays, castArrayLikeObject);
+  return (mapped.length && mapped[0] === arrays[0])
+    ? baseIntersection(mapped)
+    : [];
+});
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+module.exports = intersection;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+/***/ }),
+/* 740 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var SetCache = __webpack_require__(425),
+    arrayIncludes = __webpack_require__(476),
+    arrayIncludesWith = __webpack_require__(481),
+    arrayMap = __webpack_require__(410),
+    baseUnary = __webpack_require__(452),
+    cacheHas = __webpack_require__(429);
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeMin = Math.min;
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+/**
+ * The base implementation of methods like `_.intersection`, without support
+ * for iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ */
+function baseIntersection(arrays, iteratee, comparator) {
+  var includes = comparator ? arrayIncludesWith : arrayIncludes,
+      length = arrays[0].length,
+      othLength = arrays.length,
+      othIndex = othLength,
+      caches = Array(othLength),
+      maxLength = Infinity,
+      result = [];
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+  while (othIndex--) {
+    var array = arrays[othIndex];
+    if (othIndex && iteratee) {
+      array = arrayMap(array, baseUnary(iteratee));
+    }
+    maxLength = nativeMin(array.length, maxLength);
+    caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
+      ? new SetCache(othIndex && array)
+      : undefined;
+  }
+  array = arrays[0];
 
-var _dsl = __webpack_require__(607);
+  var index = -1,
+      seen = caches[0];
 
-var _types = __webpack_require__(610);
+  outer:
+  while (++index < length && result.length < maxLength) {
+    var value = array[index],
+        computed = iteratee ? iteratee(value) : value;
 
-var _Association2 = _interopRequireDefault(__webpack_require__(740));
+    value = (comparator || value !== 0) ? value : 0;
+    if (!(seen
+          ? cacheHas(seen, computed)
+          : includes(result, computed, comparator)
+        )) {
+      othIndex = othLength;
+      while (--othIndex) {
+        var cache = caches[othIndex];
+        if (!(cache
+              ? cacheHas(cache, computed)
+              : includes(arrays[othIndex], computed, comparator))
+            ) {
+          continue outer;
+        }
+      }
+      if (seen) {
+        seen.push(computed);
+      }
+      result.push(value);
+    }
+  }
+  return result;
+}
 
-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; }
+module.exports = baseIntersection;
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+/***/ }),
+/* 741 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var isArrayLikeObject = __webpack_require__(564);
 
 /**
+ * Casts `value` to an empty array if it's not an array like object.
  *
- * Used when related documents are stored directly under the attribute with
- * only the ids.
- *
- * @property {Function} get
- *
- * @description
- *
- * An example document representing a TODO. See as the related
- * tasks are represented via ids.
- *
- * ```js
- * const todo = {
- *   label: "Protect people's privacy",
- *   tasks: [1, 2]
- * }
- * ```
- *
- * Here is the `Schema` that would represent this kind of document.
- * Components receiving todos via `Query`s would have an instance of `HasManyInPlace`
- * as their `tasks` attribute.
- *
- * ```js
- * const schema = {
- *   todos: {
- *      doctype: 'io.cozy.todos',
- *      relationships: {
- *        tasks: {
- *          doctype: 'io.cozy.tasks',
- *          type: 'has-many-in-place'
- *        }
- *      }
- *    }
- * }
- *
- * const todo = {
- *   label: "Get rich",
- *   tasks: [1, 2]
- * }
- * ```
- *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array|Object} Returns the cast array-like object.
  */
-var HasManyInPlace = /*#__PURE__*/function (_Association) {
-  (0, _inherits2.default)(HasManyInPlace, _Association);
-
-  var _super = _createSuper(HasManyInPlace);
+function castArrayLikeObject(value) {
+  return isArrayLikeObject(value) ? value : [];
+}
 
-  function HasManyInPlace() {
-    (0, _classCallCheck2.default)(this, HasManyInPlace);
-    return _super.apply(this, arguments);
-  }
+module.exports = castArrayLikeObject;
 
-  (0, _createClass2.default)(HasManyInPlace, [{
-    key: "addById",
-    value: function addById(id) {
-      var rel = this.getRelationship();
-      rel.push(id);
-    }
-  }, {
-    key: "removeById",
-    value: function removeById(id) {
-      var rel = this.getRelationship();
-      var index = rel.indexOf(id);
 
-      if (index !== -1) {
-        rel.splice(index, 1);
-      }
-    }
-  }, {
-    key: "existsById",
-    value: function existsById(id) {
-      var rel = this.getRelationship();
-      return rel.indexOf(id) !== -1;
-    }
-  }, {
-    key: "getRelationship",
-    value: function getRelationship() {
-      this.target[this.name] = this.target[this.name] || [];
-      return this.target[this.name];
-    }
-  }, {
-    key: "dehydrate",
-    value: function dehydrate(doc) {
-      return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || []));
-    }
-  }, {
-    key: "raw",
+/***/ }),
+/* 742 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-    /**
-     * Raw property
-     *
-     * @type {Array<string>}
-     */
-    get: function get() {
-      return this.target[this.name];
-    }
-  }, {
-    key: "data",
-    get: function get() {
-      var _this = this;
+var arrayPush = __webpack_require__(437),
+    baseFlatten = __webpack_require__(553),
+    copyArray = __webpack_require__(583),
+    isArray = __webpack_require__(55);
 
-      var doctype = this.doctype;
-      return (this.raw || []).map(function (_id) {
-        return _this.get(doctype, _id);
-      });
-    }
-    /**
-     * @param {CozyClientDocument} document - Document to query
-     * @param {object} client - The CozyClient instance
-     * @param {Association} assoc - The query params
-     *
-     * @returns {CozyClientDocument | QueryDefinition}
-     */
+/**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+function concat() {
+  var length = arguments.length;
+  if (!length) {
+    return [];
+  }
+  var args = Array(length - 1),
+      array = arguments[0],
+      index = length;
 
-  }], [{
-    key: "query",
-    value: function query(document, client, assoc) {
-      var ids = document[assoc.name];
+  while (index--) {
+    args[index - 1] = arguments[index];
+  }
+  return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
+}
 
-      if (ids && ids > 0) {
-        return (0, _dsl.Q)(assoc.doctype).getByIds(ids);
-      } else {
-        return null;
-      }
-    }
-  }]);
-  return HasManyInPlace;
-}(_Association2.default);
+module.exports = concat;
 
-var _default = HasManyInPlace;
-exports["default"] = _default;
 
 /***/ }),
-/* 754 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 743 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
+var baseOrderBy = __webpack_require__(744),
+    isArray = __webpack_require__(55);
 
+/**
+ * This method is like `_.sortBy` except that it allows specifying the sort
+ * orders of the iteratees to sort by. If `orders` is unspecified, all values
+ * are sorted in ascending order. Otherwise, specify an order of "desc" for
+ * descending or "asc" for ascending sort order of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
+ *  The iteratees to sort by.
+ * @param {string[]} [orders] The sort orders of `iteratees`.
+ * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ *   { 'user': 'fred',   'age': 48 },
+ *   { 'user': 'barney', 'age': 34 },
+ *   { 'user': 'fred',   'age': 40 },
+ *   { 'user': 'barney', 'age': 36 }
+ * ];
+ *
+ * // Sort by `user` in ascending order and by `age` in descending order.
+ * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+ */
+function orderBy(collection, iteratees, orders, guard) {
+  if (collection == null) {
+    return [];
+  }
+  if (!isArray(iteratees)) {
+    iteratees = iteratees == null ? [] : [iteratees];
+  }
+  orders = guard ? undefined : orders;
+  if (!isArray(orders)) {
+    orders = orders == null ? [] : [orders];
+  }
+  return baseOrderBy(collection, iteratees, orders);
+}
 
-var _interopRequireDefault = __webpack_require__(512);
+module.exports = orderBy;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+/***/ }),
+/* 744 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var arrayMap = __webpack_require__(410),
+    baseGet = __webpack_require__(371),
+    baseIteratee = __webpack_require__(413),
+    baseMap = __webpack_require__(745),
+    baseSortBy = __webpack_require__(746),
+    baseUnary = __webpack_require__(452),
+    compareMultiple = __webpack_require__(747),
+    identity = __webpack_require__(471),
+    isArray = __webpack_require__(55);
 
-var _get2 = _interopRequireDefault(__webpack_require__(670));
+/**
+ * The base implementation of `_.orderBy` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
+ * @param {string[]} orders The sort orders of `iteratees`.
+ * @returns {Array} Returns the new sorted array.
+ */
+function baseOrderBy(collection, iteratees, orders) {
+  if (iteratees.length) {
+    iteratees = arrayMap(iteratees, function(iteratee) {
+      if (isArray(iteratee)) {
+        return function(value) {
+          return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
+        }
+      }
+      return iteratee;
+    });
+  } else {
+    iteratees = [identity];
+  }
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+  var index = -1;
+  iteratees = arrayMap(iteratees, baseUnary(baseIteratee));
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+  var result = baseMap(collection, function(value, key, collection) {
+    var criteria = arrayMap(iteratees, function(iteratee) {
+      return iteratee(value);
+    });
+    return { 'criteria': criteria, 'index': ++index, 'value': value };
+  });
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+  return baseSortBy(result, function(object, other) {
+    return compareMultiple(object, other, orders);
+  });
+}
 
-var _HasMany2 = _interopRequireDefault(__webpack_require__(741));
+module.exports = baseOrderBy;
 
-var _dsl = __webpack_require__(607);
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+/***/ }),
+/* 745 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+var baseEach = __webpack_require__(567),
+    isArrayLike = __webpack_require__(458);
 
-var TRIGGERS_DOCTYPE = 'io.cozy.triggers';
 /**
- * Association used for konnectors to retrieve all their related triggers.
+ * The base implementation of `_.map` without support for iteratee shorthands.
  *
- * @augments HasMany
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
  */
+function baseMap(collection, iteratee) {
+  var index = -1,
+      result = isArrayLike(collection) ? Array(collection.length) : [];
 
-var HasManyTriggers = /*#__PURE__*/function (_HasMany) {
-  (0, _inherits2.default)(HasManyTriggers, _HasMany);
+  baseEach(collection, function(value, key, collection) {
+    result[++index] = iteratee(value, key, collection);
+  });
+  return result;
+}
 
-  var _super = _createSuper(HasManyTriggers);
+module.exports = baseMap;
 
-  function HasManyTriggers() {
-    (0, _classCallCheck2.default)(this, HasManyTriggers);
-    return _super.apply(this, arguments);
-  }
 
-  (0, _createClass2.default)(HasManyTriggers, [{
-    key: "data",
-    get: function get() {
-      var _this = this;
+/***/ }),
+/* 746 */
+/***/ ((module) => {
 
-      return (0, _get2.default)((0, _getPrototypeOf2.default)(HasManyTriggers.prototype), "data", this).filter(function (_ref) {
-        var slug = _ref.slug;
-        return slug === _this.target.slug;
-      });
-    }
-    /**
-     * In this association the query is special, we need to fetch all the triggers
-     * having for the 'konnector' worker, and then filter them based on their
-     * `message.konnector` attribute
-     */
+/**
+ * The base implementation of `_.sortBy` which uses `comparer` to define the
+ * sort order of `array` and replaces criteria objects with their corresponding
+ * values.
+ *
+ * @private
+ * @param {Array} array The array to sort.
+ * @param {Function} comparer The function to define sort order.
+ * @returns {Array} Returns `array`.
+ */
+function baseSortBy(array, comparer) {
+  var length = array.length;
 
-  }], [{
-    key: "query",
-    value: function query(doc, client) {
-      return (0, _dsl.Q)(TRIGGERS_DOCTYPE).where({
-        worker: 'konnector'
-      });
-    }
-  }]);
-  return HasManyTriggers;
-}(_HasMany2.default);
+  array.sort(comparer);
+  while (length--) {
+    array[length] = array[length].value;
+  }
+  return array;
+}
 
-var _default = HasManyTriggers;
-exports["default"] = _default;
+module.exports = baseSortBy;
 
-/***/ }),
-/* 755 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-"use strict";
+/***/ }),
+/* 747 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var compareAscending = __webpack_require__(748);
 
-var _interopRequireDefault = __webpack_require__(512);
+/**
+ * Used by `_.orderBy` to compare multiple properties of a value to another
+ * and stable sort them.
+ *
+ * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+ * specify an order of "desc" for descending or "asc" for ascending sort order
+ * of corresponding values.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {boolean[]|string[]} orders The order to sort by for each property.
+ * @returns {number} Returns the sort order indicator for `object`.
+ */
+function compareMultiple(object, other, orders) {
+  var index = -1,
+      objCriteria = object.criteria,
+      othCriteria = other.criteria,
+      length = objCriteria.length,
+      ordersLength = orders.length;
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.getReferencedById = exports.getReferencedBy = exports.isReferencedById = exports.isReferencedBy = exports.create = exports.resolveClass = exports.attachRelationships = exports.responseToRelationship = exports.pickTypeAndId = void 0;
+  while (++index < length) {
+    var result = compareAscending(objCriteria[index], othCriteria[index]);
+    if (result) {
+      if (index >= ordersLength) {
+        return result;
+      }
+      var order = orders[index];
+      return result * (order == 'desc' ? -1 : 1);
+    }
+  }
+  // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+  // that causes it, under certain circumstances, to provide the same value for
+  // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
+  // for more details.
+  //
+  // This also ensures a stable sort in V8 and other engines.
+  // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
+  return object.index - other.index;
+}
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+module.exports = compareMultiple;
 
-var _pick = _interopRequireDefault(__webpack_require__(664));
 
-var _pickBy = _interopRequireDefault(__webpack_require__(648));
+/***/ }),
+/* 748 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _Association = _interopRequireDefault(__webpack_require__(740));
+var isSymbol = __webpack_require__(374);
 
-var _HasOne = _interopRequireDefault(__webpack_require__(750));
+/**
+ * Compares values to sort them in ascending order.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {number} Returns the sort order indicator for `value`.
+ */
+function compareAscending(value, other) {
+  if (value !== other) {
+    var valIsDefined = value !== undefined,
+        valIsNull = value === null,
+        valIsReflexive = value === value,
+        valIsSymbol = isSymbol(value);
 
-var _HasOneInPlace = _interopRequireDefault(__webpack_require__(752));
+    var othIsDefined = other !== undefined,
+        othIsNull = other === null,
+        othIsReflexive = other === other,
+        othIsSymbol = isSymbol(other);
 
-var _HasMany = _interopRequireDefault(__webpack_require__(741));
+    if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
+        (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
+        (valIsNull && othIsDefined && othIsReflexive) ||
+        (!valIsDefined && othIsReflexive) ||
+        !valIsReflexive) {
+      return 1;
+    }
+    if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
+        (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
+        (othIsNull && valIsDefined && valIsReflexive) ||
+        (!othIsDefined && valIsReflexive) ||
+        !othIsReflexive) {
+      return -1;
+    }
+  }
+  return 0;
+}
 
-var _HasManyInPlace = _interopRequireDefault(__webpack_require__(753));
+module.exports = compareAscending;
 
-var _HasManyFiles = _interopRequireDefault(__webpack_require__(692));
 
-var _types = __webpack_require__(610);
+/***/ }),
+/* 749 */
+/***/ ((module, exports) => {
 
-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; }
+/*
+ * Sift 3.x
+ *
+ * Copryright 2015, Craig Condon
+ * Licensed under MIT
+ *
+ * Filter JavaScript objects with mongodb queries
+ */
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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() {
 
-var pickTypeAndId = function pickTypeAndId(x) {
-  return (0, _pick.default)(x, '_type', '_id');
-};
+  'use strict';
 
-exports.pickTypeAndId = pickTypeAndId;
+  /**
+   */
 
-var applyHelper = function applyHelper(fn, objOrArr) {
-  return Array.isArray(objOrArr) ? objOrArr.map(fn) : fn(objOrArr);
-};
+  function isFunction(value) {
+    return typeof value === 'function';
+  }
 
-var responseToRelationship = function responseToRelationship(response) {
-  return (0, _pickBy.default)({
-    data: applyHelper(pickTypeAndId, response.data),
-    meta: response.meta,
-    next: response.next,
-    skip: response.skip,
-    bookmark: response.bookmark
-  });
-};
+  /**
+   */
 
-exports.responseToRelationship = responseToRelationship;
+  function isArray(value) {
+    return Object.prototype.toString.call(value) === '[object Array]';
+  }
 
-var attachRelationship = function attachRelationship(doc, relationships) {
-  return _objectSpread(_objectSpread({}, doc), {}, {
-    relationships: _objectSpread(_objectSpread({}, doc.relationships), relationships)
-  });
-};
+  /**
+   */
 
-var attachRelationships = function attachRelationships(response, relationshipsByDocId) {
-  if (Array.isArray(response.data)) {
-    return _objectSpread(_objectSpread({}, response), {}, {
-      data: response.data.map(function (doc) {
-        return attachRelationship(doc, relationshipsByDocId[doc._id]);
-      })
-    });
-  } else {
-    var doc = response.data;
-    return _objectSpread(_objectSpread({}, response), {}, {
-      data: attachRelationship(doc, relationshipsByDocId[doc._id])
-    });
+  function comparable(value) {
+    if (value instanceof Date) {
+      return value.getTime();
+    } else if (isArray(value)) {
+      return value.map(comparable);
+    } else if (value && typeof value.toJSON === 'function') {
+      return value.toJSON();
+    } else {
+      return value;
+    }
   }
-};
-
-exports.attachRelationships = attachRelationships;
-var aliases = {
-  'io.cozy.files:has-many': _HasManyFiles.default,
-  'has-many': _HasMany.default,
-  'belongs-to-in-place': _HasOneInPlace.default,
-  'has-one': _HasOne.default,
-  'has-one-in-place': _HasOneInPlace.default,
-  'has-many-in-place': _HasManyInPlace.default
-};
-/**
- * Returns the relationship class for a given doctype/type.
- *
- * In the schema definition, some classes have string aliases
- * so you do not have to import directly the association.
- *
- * Some doctypes can have built-in overriden relationships.
- *
- * @private
- */
 
-var resolveClass = function resolveClass(doctype, type) {
-  if (type === undefined) {
-    throw new Error('Undefined type for ' + doctype);
+  function get(obj, key) {
+    return isFunction(obj.get) ? obj.get(key) : obj[key];
   }
 
-  if (typeof type !== 'string') {
-    return type;
-  } else {
-    var qualified = "".concat(doctype, ":").concat(type);
-    var cls = aliases[qualified] || aliases[type];
+  /**
+   */
 
-    if (!cls) {
-      throw new Error("Unknown association '".concat(type, "'"));
-    } else {
-      return cls;
+  function or(validator) {
+    return function(a, b) {
+      if (!isArray(b) || !b.length) {
+        return validator(a, b);
+      }
+      for (var i = 0, n = b.length; i < n; i++) {
+        if (validator(a, get(b,i))) return true;
+      }
+      return false;
     }
   }
-};
 
-exports.resolveClass = resolveClass;
+  /**
+   */
 
-var create = function create(target, _ref, accessors) {
-  var name = _ref.name,
-      type = _ref.type,
-      doctype = _ref.doctype;
+  function and(validator) {
+    return function(a, b) {
+      if (!isArray(b) || !b.length) {
+        return validator(a, b);
+      }
+      for (var i = 0, n = b.length; i < n; i++) {
+        if (!validator(a, get(b, i))) return false;
+      }
+      return true;
+    };
+  }
 
-  if (target[name] instanceof _Association.default) {
-    throw new Error("Association ".concat(name, " already exists"));
+  function validate(validator, b, k, o) {
+    return validator.v(validator.a, b, k, o);
   }
 
-  return new type(target, name, doctype, accessors);
-};
-/**
- * Checks if the file is referenced by a specific doctype
- *
- * @param {IOCozyFile} file - io.cozy.files document
- * @param {Doctype} referencedBy - Doctype where document is referenced
- * @returns {boolean} If a reference is found
- */
+  var OPERATORS = {
 
+    /**
+     */
 
-exports.create = create;
+    $eq: or(function(a, b) {
+      return a(b);
+    }),
 
-var isReferencedBy = function isReferencedBy(file, referencedBy) {
-  var _file$relationships, _file$relationships$r;
+    /**
+     */
 
-  var references = (file === null || file === void 0 ? void 0 : (_file$relationships = file.relationships) === null || _file$relationships === void 0 ? void 0 : (_file$relationships$r = _file$relationships.referenced_by) === null || _file$relationships$r === void 0 ? void 0 : _file$relationships$r.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
-  return references.some(function (reference) {
-    return reference.type === referencedBy;
-  });
-};
-/**
- * Checks if the file is referenced by a specific doctype and a specific Id of that reference
- *
- * @param {IOCozyFile} file - io.cozy.files document
- * @param {Doctype} referencedBy - Doctype where document is referenced
- * @param {string} referencedId - Id of the referenced document
- * @returns {boolean} If a reference is found
- */
+    $ne: and(function(a, b) {
+      return !a(b);
+    }),
 
+    /**
+     */
 
-exports.isReferencedBy = isReferencedBy;
+    $gt: or(function(a, b) {
+      return sift.compare(comparable(b), a) > 0;
+    }),
 
-var isReferencedById = function isReferencedById(file, referencedBy, referencedId) {
-  var _file$relationships2, _file$relationships2$;
+    /**
+     */
 
-  var references = (file === null || file === void 0 ? void 0 : (_file$relationships2 = file.relationships) === null || _file$relationships2 === void 0 ? void 0 : (_file$relationships2$ = _file$relationships2.referenced_by) === null || _file$relationships2$ === void 0 ? void 0 : _file$relationships2$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
-  return references.some(function (reference) {
-    return reference.type === referencedBy && reference.id === referencedId;
-  });
-};
-/**
- * Get array of reference by an specific doctype
- *
- * @param {IOCozyFile} file - io.cozy.files document
- * @param {Doctype} referencedBy - Doctype where document is referenced
- * @returns {Reference[]} Array of references found
- */
+    $gte: or(function(a, b) {
+      return sift.compare(comparable(b), a) >= 0;
+    }),
 
+    /**
+     */
 
-exports.isReferencedById = isReferencedById;
+    $lt: or(function(a, b) {
+      return sift.compare(comparable(b), a) < 0;
+    }),
 
-var getReferencedBy = function getReferencedBy(file, referencedBy) {
-  var _file$relationships3, _file$relationships3$;
+    /**
+     */
 
-  var references = (file === null || file === void 0 ? void 0 : (_file$relationships3 = file.relationships) === null || _file$relationships3 === void 0 ? void 0 : (_file$relationships3$ = _file$relationships3.referenced_by) === null || _file$relationships3$ === void 0 ? void 0 : _file$relationships3$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
-  return references.filter(function (reference) {
-    return reference.type === referencedBy;
-  });
-};
-/**
- * Get array of reference by an specific doctype and a specific Id of that reference
- *
- * @param {IOCozyFile} file - io.cozy.files document
- * @param {Doctype} referencedBy - Doctype where document is referenced
- * @param {string} referencedId - Id of the referenced document
- * @returns {Reference[]} Array of the reference found
- */
+    $lte: or(function(a, b) {
+      return sift.compare(comparable(b), a) <= 0;
+    }),
 
+    /**
+     */
 
-exports.getReferencedBy = getReferencedBy;
+    $mod: or(function(a, b) {
+      return b % a[0] == a[1];
+    }),
 
-var getReferencedById = function getReferencedById(file, referencedBy, referencedId) {
-  var _file$relationships4, _file$relationships4$;
+    /**
+     */
 
-  var references = (file === null || file === void 0 ? void 0 : (_file$relationships4 = file.relationships) === null || _file$relationships4 === void 0 ? void 0 : (_file$relationships4$ = _file$relationships4.referenced_by) === null || _file$relationships4$ === void 0 ? void 0 : _file$relationships4$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
-  return references.filter(function (reference) {
-    return reference.type === referencedBy && reference.id === referencedId;
-  });
-};
+    $in: function(a, b) {
 
-exports.getReferencedById = getReferencedById;
+      if (b instanceof Array) {
+        for (var i = b.length; i--;) {
+          if (~a.indexOf(comparable(get(b, i)))) {
+            return true;
+          }
+        }
+      } else {
+        var comparableB = comparable(b);
+        if (comparableB === b && typeof b === 'object') {
+          for (var i = a.length; i--;) {
+            if (String(a[i]) === String(b) && String(b) !== '[object Object]') {
+              return true;
+            }
+          }
+        }
 
-/***/ }),
-/* 756 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+        /*
+          Handles documents that are undefined, whilst also
+          having a 'null' element in the parameters to $in.
+        */
+        if (typeof comparableB == 'undefined') {
+          for (var i = a.length; i--;) {
+            if (a[i] == null) {
+              return true;
+            }
+          }
+        }
 
-"use strict";
+        /*
+          Handles the case of {'field': {$in: [/regexp1/, /regexp2/, ...]}}
+        */
+        for (var i = a.length; i--;) {
+          var validator = createRootValidator(get(a, i), undefined);
+          var result = validate(validator, b, i, a);
+          if ((result) && (String(result) !== '[object Object]') && (String(b) !== '[object Object]')) {
+            return true;
+          }
+        }
 
+        return !!~a.indexOf(comparableB);
+      }
 
-var _interopRequireDefault = __webpack_require__(512);
+      return false;
+    },
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.rootCozyUrl = exports.InvalidCozyUrlError = exports.InvalidProtocolError = exports.generateWebLink = exports.dehydrate = void 0;
+    /**
+     */
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+    $nin: function(a, b, k, o) {
+      return !OPERATORS.$in(a, b, k, o);
+    },
 
-var _toArray2 = _interopRequireDefault(__webpack_require__(514));
+    /**
+     */
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+    $not: function(a, b, k, o) {
+      return !validate(a, b, k, o);
+    },
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+    /**
+     */
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+    $type: function(a, b) {
+      return b != void 0 ? b instanceof a || b.constructor == a : false;
+     },
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+    /**
+     */
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+    $all: function(a, b, k, o) {
+      return OPERATORS.$and(a, b, k, o);
+    },
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+    /**
+     */
 
-var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652));
+    $size: function(a, b) {
+      return b ? a === b.length : false;
+    },
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+    /**
+     */
 
-var _associations = __webpack_require__(691);
+    $or: function(a, b, k, o) {
+      for (var i = 0, n = a.length; i < n; i++) if (validate(get(a, i), b, k, o)) return true;
+      return false;
+    },
 
-function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
+    /**
+     */
 
-function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
+    $nor: function(a, b, k, o) {
+      return !OPERATORS.$or(a, b, k, o);
+    },
 
-function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+    /**
+     */
 
-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); }
+    $and: function(a, b, k, o) {
+      for (var i = 0, n = a.length; i < n; i++) {
+        if (!validate(get(a, i), b, k, o)) {
+          return false;
+        }
+      }
+      return true;
+    },
 
-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; }
+    /**
+     */
 
-var dehydrate = function dehydrate(document) {
-  var dehydrated = Object.entries(document).reduce(function (documentArg, _ref) {
-    var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
-        key = _ref2[0],
-        value = _ref2[1];
+    $regex: or(function(a, b) {
+      return typeof b === 'string' && a.test(b);
+    }),
 
-    var document = documentArg;
+    /**
+     */
 
-    if (!(value instanceof _associations.Association)) {
-      document[key] = value; // @ts-ignore
-    } else if (value.dehydrate) {
-      // @ts-ignore
-      document = value.dehydrate(document);
-    } else {
-      throw new Error("Association on key ".concat(key, " should have a dehydrate method"));
+    $where: function(a, b, k, o) {
+      return a.call(b, b, k, o);
+    },
+
+    /**
+     */
+
+    $elemMatch: function(a, b, k, o) {
+      if (isArray(b)) {
+        return !!~search(b, a);
+      }
+      return validate(a, b, k, o);
+    },
+
+    /**
+     */
+
+    $exists: function(a, b, k, o) {
+      return o.hasOwnProperty(k) === a;
     }
+  };
 
-    return document;
-  }, {});
-  return dehydrated;
-};
+  /**
+   */
 
-exports.dehydrate = dehydrate;
+  var prepare = {
 
-var ensureFirstSlash = function ensureFirstSlash(path) {
-  if (!path) {
-    return '/';
-  } else {
-    return path.startsWith('/') ? path : '/' + path;
-  }
-};
-/**
- * generateWebLink - Construct a link to a web app
- *
- * This function does not get its cozy url from a CozyClient instance so it can
- * be used to build urls that point to other Cozies than the user's own Cozy.
- * This is useful when pointing to the Cozy of the owner of a shared note for
- * example.
- *
- * @param {object} options               Object of options
- * @param {string}   options.cozyUrl       Base URL of the cozy, eg. cozy.tools or test.mycozy.cloud
- * @param {Array}    [options.searchParams]  Array of search parameters as [key, value] arrays, eg. ['username', 'bob']
- * @param {string}   [options.pathname]      Path to a specific part of the app, eg. /public
- * @param {string}   [options.hash]          Path inside the app, eg. /files/test.jpg
- * @param {string}   [options.slug]          Slug of the app
- * @param {string}   [options.subDomainType] Whether the cozy is using flat or nested subdomains. Defaults to flat.
- *
- * @returns {string} Generated URL
- */
+    /**
+     */
 
+    $eq: function(a) {
 
-var generateWebLink = function generateWebLink(_ref3) {
-  var cozyUrl = _ref3.cozyUrl,
-      searchParamsOption = _ref3.searchParams,
-      pathname = _ref3.pathname,
-      hash = _ref3.hash,
-      slug = _ref3.slug,
-      subDomainType = _ref3.subDomainType;
-  var searchParams = searchParamsOption || [];
-  var url = new URL(cozyUrl);
-  url.host = subDomainType === 'nested' ? "".concat(slug, ".").concat(url.host) : url.host.split('.').map(function (x, i) {
-    return i === 0 ? x + '-' + slug : x;
-  }).join('.');
-  url.pathname = pathname;
-  url.hash = ensureFirstSlash(hash);
+      if (a instanceof RegExp) {
+        return function(b) {
+          return typeof b === 'string' && a.test(b);
+        };
+      } else if (a instanceof Function) {
+        return a;
+      } else if (isArray(a) && !a.length) {
+        // Special case of a == []
+        return function(b) {
+          return (isArray(b) && !b.length);
+        };
+      } else if (a === null){
+        return function(b){
+          //will match both null and undefined
+          return b == null;
+        }
+      }
 
-  var _iterator = _createForOfIteratorHelper(searchParams),
-      _step;
+      return function(b) {
+        return sift.compare(comparable(b), a) === 0;
+      };
+    },
 
-  try {
-    for (_iterator.s(); !(_step = _iterator.n()).done;) {
-      var _step$value = (0, _slicedToArray2.default)(_step.value, 2),
-          param = _step$value[0],
-          value = _step$value[1];
+    /**
+     */
 
-      url.searchParams.set(param, value);
-    }
-  } catch (err) {
-    _iterator.e(err);
-  } finally {
-    _iterator.f();
-  }
+    $ne: function(a) {
+      return prepare.$eq(a);
+    },
 
-  return url.toString();
-};
+    /**
+     */
 
-exports.generateWebLink = generateWebLink;
+    $and: function(a) {
+      return a.map(parse);
+    },
 
-var InvalidProtocolError = /*#__PURE__*/function (_Error) {
-  (0, _inherits2.default)(InvalidProtocolError, _Error);
+    /**
+     */
 
-  var _super = _createSuper(InvalidProtocolError);
+    $all: function(a) {
+      return prepare.$and(a);
+    },
 
-  function InvalidProtocolError(url) {
-    var _this;
+    /**
+     */
 
-    (0, _classCallCheck2.default)(this, InvalidProtocolError);
-    _this = _super.call(this, "Invalid URL protocol ".concat(url.protocol));
-    _this.url = url;
-    return _this;
-  }
+    $or: function(a) {
+      return a.map(parse);
+    },
 
-  return InvalidProtocolError;
-}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
+    /**
+     */
 
-exports.InvalidProtocolError = InvalidProtocolError;
+    $nor: function(a) {
+      return a.map(parse);
+    },
 
-var InvalidCozyUrlError = /*#__PURE__*/function (_Error2) {
-  (0, _inherits2.default)(InvalidCozyUrlError, _Error2);
+    /**
+     */
 
-  var _super2 = _createSuper(InvalidCozyUrlError);
+    $not: function(a) {
+      return parse(a);
+    },
 
-  function InvalidCozyUrlError(url) {
-    var _this2;
+    /**
+     */
 
-    (0, _classCallCheck2.default)(this, InvalidCozyUrlError);
-    _this2 = _super2.call(this, "URL ".concat(url.toString(), " does not seem to be a valid Cozy URL"));
-    _this2.url = url;
-    return _this2;
-  }
+    $regex: function(a, query) {
+      return new RegExp(a, query.$options);
+    },
 
-  return InvalidCozyUrlError;
-}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
-/* uri - Returns a well formed URL origin from a protocol, a hostname and a port
- *
- * If the protocol and/or port are omitted from the argument, the function will
- * default to HTTPS and omit the port in the returned origin.
- *
- * @param {object} url          Object of URL elements
- * @param {string} url.protocol Protocol to use in the origin (e.g. http)
- * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud)
- * @param {string} url.port     Port to use in the origin (e.g. 8080)
- *
- * @returns {string} Generated URL origin
- */
+    /**
+     */
 
+    $where: function(a) {
+      return typeof a === 'string' ? new Function('obj', 'return ' + a) : a;
+    },
 
-exports.InvalidCozyUrlError = InvalidCozyUrlError;
+    /**
+     */
 
-var uri = function uri(_ref4) {
-  var protocol = _ref4.protocol,
-      hostname = _ref4.hostname,
-      port = _ref4.port;
-  return (protocol !== '' ? "".concat(protocol, "//") : 'https://') + hostname + (port !== '' ? ":".concat(port) : '');
-};
-/* wellKnownUrl - Returns a valid URL string to a Well Known password change page
- *
- * The built URL will point to the origin generated from the given protocol,
- * hostname and port.
- *
- * @param {object} url          Object of URL elements
- * @param {string} url.protocol Protocol to use in the origin (e.g. http)
- * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud)
- * @param {string} url.port     Port to use in the origin (e.g. 8080)
- *
- * @returns {string} Generated Well Known password change URL string
- */
+    $elemMatch: function(a) {
+      return parse(a);
+    },
 
+    /**
+     */
 
-var wellKnownUrl = function wellKnownUrl(url) {
-  return uri(url) + '/.well-known/change-password';
-};
-/* isValidOrigin - Checks whether a given URL is a valid Cozy origin
- *
- * This method tries to fetch the Well Known change password page of the Cozy
- * supposedly at the given origin. This allows us to determine whether the given
- * origin is the root URL of a Cozy or not via the status of the response:
- * - a 200 response status means there's an actual Well Known password change
- *   page accessible from the given origin so we suppose it's a valid Cozy
- *   origin (i.e. it could be another site altogether though)
- * - a 401 response status means the pointed page requires authentication so the
- *   origin is probably pointing to a Cozy app
- * - another status means there aren't any Cozy behind to the given origin
- *
- * @param {object} url          Object of URL elements
- * @param {string} url.protocol Protocol to use in the origin (e.g. http)
- * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud)
- * @param {string} url.port     Port to use in the origin (e.g. 8080)
- *
- * @returns {Promise<boolean>} True if we believe there's a Cozy behind the given origin
- * @throws {InvalidCozyUrlError} Thrown when we know for sure there aren't any Cozy behind the given origin
- */
+    $exists: function(a) {
+      return !!a;
+    }
+  };
 
+  /**
+   */
 
-var isValidOrigin = /*#__PURE__*/function () {
-  var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) {
-    var _yield$fetch, status;
+  function search(array, validator) {
 
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            _context.next = 2;
-            return fetch(wellKnownUrl(url));
+    for (var i = 0; i < array.length; i++) {
+      var result = get(array, i);
+      if (validate(validator, get(array, i))) {
+        return i;
+      }
+    }
 
-          case 2:
-            _yield$fetch = _context.sent;
-            status = _yield$fetch.status;
+    return -1;
+  }
 
-            if (!(status === 404)) {
-              _context.next = 6;
-              break;
-            }
+  /**
+   */
 
-            throw new InvalidCozyUrlError(url);
+  function createValidator(a, validate) {
+    return { a: a, v: validate };
+  }
 
-          case 6:
-            return _context.abrupt("return", status === 200);
+  /**
+   */
 
-          case 7:
-          case "end":
-            return _context.stop();
-        }
+  function nestedValidator(a, b) {
+    var values  = [];
+    findValues(b, a.k, 0, b, values);
+
+    if (values.length === 1) {
+      var first = values[0];
+      return validate(a.nv, first[0], first[1], first[2]);
+    }
+
+    // If the query contains $ne, need to test all elements ANDed together
+    var inclusive = a && a.q && typeof a.q.$ne !== 'undefined';
+    var allValid = inclusive;
+    for (var i = 0; i < values.length; i++) {
+      var result = values[i];
+      var isValid = validate(a.nv, result[0], result[1], result[2]);
+      if (inclusive) {
+        allValid &= isValid;
+      } else {
+        allValid |= isValid;
       }
-    }, _callee);
-  }));
+    }
+    return allValid;
+  }
 
-  return function isValidOrigin(_x) {
-    return _ref5.apply(this, arguments);
-  };
-}();
-/**
- * rootCozyUrl - Get the root URL of a Cozy from more precise ones
- *
- * The goal is to allow users to use any URL copied from their browser as their
- * Cozy URL rather than trying to explain to them what we expect (e.g. when
- * requesting the Cozy URL to connect an app).
- * If we can't get the root URL either because there's no Cozy or the domain
- * does not exist or anything else, we'll throw an InvalidCozyUrlError.
- * Also, since we communicate only via HTTP or HTTPS, we'll throw an
- * InvalidProtocolError if any other protocol is used.
- *
- * This function expects a fully qualified URL thus with a protocol and a valid
- * hostname. If your application accepts Cozy intances as input (e.g. `claude`
- * when the Cozy can be found at `https://claude.mycozy.cloud`), it is your
- * responsibility to add the appropriate domain to the hostname before calling
- * this function.
- *
- * Examples:
- *
- * 1. getting the root URL when your user gives you its instance name
- *
- *   const userInput = 'claude'
- *   const rootUrl = await rootCozyUrl(new URL(`https://${userInput}.mycozy.cloud`))
- *   // → returns new URL('https://claude.mycozy.cloud')
- *
- * 2. getting the root URL when your user gives you a Cozy Drive URL
- *
- *   const userInput = 'https://claude-drive.mycozy.cloud/#/folder/io.cozy.files.root-dir'
- *   const rootUrl = await rootCozyUrl(new URL(userInput))
- *   // → returns new URL('https://claude.mycozy.cloud')
- *
- * 3. getting the root URL when the Cozy uses nested sub-domains
- *
- *   const userInput = 'http://photos.camille.nimbus.com:8080/#/album/1234567890'
- *   const rootCozyUrl = await rootCozyUrl(new URL(userInput))
- *   // → returns new URL('http://camille.nimbus.com:8080')
- *
- * @param {URL} url The URL from which we'll try to get the root Cozy URL
- *
- * @returns {Promise<URL>} The root Cozy URL
- */
+  /**
+   */
+
+  function findValues(current, keypath, index, object, values) {
+
+    if (index === keypath.length || current == void 0) {
+
+      values.push([current, keypath[index - 1], object]);
+      return;
+    }
+
+    var k = get(keypath, index);
+
+    // ensure that if current is an array, that the current key
+    // is NOT an array index. This sort of thing needs to work:
+    // sift({'foo.0':42}, [{foo: [42]}]);
+    if (isArray(current) && isNaN(Number(k))) {
+      for (var i = 0, n = current.length; i < n; i++) {
+        findValues(get(current, i), keypath, index, current, values);
+      }
+    } else {
+      findValues(get(current, k), keypath, index + 1, current, values);
+    }
+  }
 
+  /**
+   */
 
-var rootCozyUrl = /*#__PURE__*/function () {
-  var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(url) {
-    var _url$hostname$split, _url$hostname$split2, subDomain, domain, _hostname, hostname;
+  function createNestedValidator(keypath, a, q) {
+    return { a: { k: keypath, nv: a, q: q }, v: nestedValidator };
+  }
 
-    return _regenerator.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            if (['http:', 'https:'].includes(url.protocol)) {
-              _context2.next = 2;
-              break;
-            }
+  /**
+   * flatten the query
+   */
 
-            throw new InvalidProtocolError(url);
+  function isVanillaObject(value) {
+    return value && value.constructor === Object;
+  }
 
-          case 2:
-            _context2.next = 4;
-            return isValidOrigin(url);
+  function parse(query) {
+    query = comparable(query);
 
-          case 4:
-            if (!_context2.sent) {
-              _context2.next = 6;
-              break;
-            }
+    if (!query || !isVanillaObject(query)) { // cross browser support
+      query = { $eq: query };
+    }
 
-            return _context2.abrupt("return", url);
+    var validators = [];
 
-          case 6:
-            if (!/^[^.-][^.]+-[^.-]+\./.test(url.hostname)) {
-              _context2.next = 13;
-              break;
-            }
+    for (var key in query) {
+      var a = query[key];
 
-            _url$hostname$split = url.hostname.split('.'), _url$hostname$split2 = (0, _toArray2.default)(_url$hostname$split), subDomain = _url$hostname$split2[0], domain = _url$hostname$split2.slice(1);
-            _hostname = [subDomain.replace(/-.+/, '')].concat((0, _toConsumableArray2.default)(domain)).join('.');
-            _context2.next = 11;
-            return isValidOrigin({
-              protocol: url.protocol,
-              hostname: _hostname,
-              port: url.port
-            });
+      if (key === '$options') {
+        continue;
+      }
 
-          case 11:
-            if (!_context2.sent) {
-              _context2.next = 13;
-              break;
-            }
+      if (OPERATORS[key]) {
+        if (prepare[key]) a = prepare[key](a, query);
+        validators.push(createValidator(comparable(a), OPERATORS[key]));
+      } else {
 
-            return _context2.abrupt("return", new URL(uri({
-              protocol: url.protocol,
-              hostname: _hostname,
-              port: url.port
-            })));
+        if (key.charCodeAt(0) === 36) {
+          throw new Error('Unknown operation ' + key);
+        }
+        validators.push(createNestedValidator(key.split('.'), parse(a), a));
+      }
+    }
 
-          case 13:
-            // Try to remove the first sub-domain in case its a nested app name
-            // eslint-disable-next-line no-unused-vars
-            hostname = url.hostname.split('.').splice(1).join('.');
-            _context2.next = 16;
-            return isValidOrigin({
-              protocol: url.protocol,
-              hostname: hostname,
-              port: url.port
-            });
+    return validators.length === 1 ? validators[0] : createValidator(validators, OPERATORS.$and);
+  }
 
-          case 16:
-            if (!_context2.sent) {
-              _context2.next = 18;
-              break;
-            }
+  /**
+   */
 
-            return _context2.abrupt("return", new URL(uri({
-              protocol: url.protocol,
-              hostname: hostname,
-              port: url.port
-            })));
+  function createRootValidator(query, getter) {
+    var validator = parse(query);
+    if (getter) {
+      validator = {
+        a: validator,
+        v: function(a, b, k, o) {
+          return validate(a, getter(b), k, o);
+        }
+      };
+    }
+    return validator;
+  }
 
-          case 18:
-            throw new InvalidCozyUrlError(url);
+  /**
+   */
 
-          case 19:
-          case "end":
-            return _context2.stop();
-        }
+  function sift(query, array, getter) {
+
+    if (isFunction(array)) {
+      getter = array;
+      array  = void 0;
+    }
+
+    var validator = createRootValidator(query, getter);
+
+    function filter(b, k, o) {
+      return validate(validator, b, k, o);
+    }
+
+    if (array) {
+      return array.filter(filter);
+    }
+
+    return filter;
+  }
+
+  /**
+   */
+
+  sift.use = function(plugin) {
+    if (isFunction(plugin)) return plugin(sift);
+    for (var key in plugin) {
+      /* istanbul ignore else */
+      if (key.charCodeAt(0) === 36) {
+        OPERATORS[key] = plugin[key];
       }
-    }, _callee2);
-  }));
+    }
+  };
 
-  return function rootCozyUrl(_x2) {
-    return _ref6.apply(this, arguments);
+  /**
+   */
+
+  sift.indexOf = function(query, array, getter) {
+    return search(array, createRootValidator(query, getter));
   };
-}();
 
-exports.rootCozyUrl = rootCozyUrl;
+  /**
+   */
+
+  sift.compare = function(a, b) {
+    if(a===b) return 0;
+    if(typeof a === typeof b) {
+      if (a > b) {
+        return 1;
+      }
+      if (a < b) {
+        return -1;
+      }
+    }
+  };
+
+  /* istanbul ignore next */
+  if ( true && typeof module.exports !== 'undefined') {
+    Object.defineProperty(exports, "__esModule", ({
+      value: true
+    }));
+
+    module.exports = sift;
+    exports["default"] = module.exports["default"] = sift;
+  }
+
+  /* istanbul ignore next */
+  if (typeof window !== 'undefined') {
+    window.sift = sift;
+  }
+})();
+
 
 /***/ }),
-/* 757 */
+/* 750 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.authFunction = exports.authenticateWithCordova = void 0;
+exports.receiveMutationError = exports.receiveMutationResult = exports.initMutation = exports.isReceivingMutationResult = exports.isMutationAction = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+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; }
 
-var _const = __webpack_require__(685);
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var _cozyDeviceHelper = __webpack_require__(758);
+var INIT_MUTATION = 'INIT_MUTATION';
+var RECEIVE_MUTATION_RESULT = 'RECEIVE_MUTATION_RESULT';
+var RECEIVE_MUTATION_ERROR = 'RECEIVE_MUTATION_ERROR';
 
-var _types = __webpack_require__(610);
+var isMutationAction = function isMutationAction(action) {
+  return [INIT_MUTATION, RECEIVE_MUTATION_RESULT, RECEIVE_MUTATION_ERROR].indexOf(action.type) !== -1;
+};
 
-/* global prompt */
+exports.isMutationAction = isMutationAction;
 
-/**
- * @type {CordovaWindow}
- */
-// @ts-ignore
-var win = typeof window !== 'undefined' ? window : null;
-/**
- * Open a SafariView Controller and resolve with the URL containing the token
- *
- * @param {string} url
- * @returns {Promise}
- */
+var isReceivingMutationResult = function isReceivingMutationResult(action) {
+  return action.type === RECEIVE_MUTATION_RESULT;
+}; // actions
 
-var authenticateWithSafari = function authenticateWithSafari(url) {
-  return new Promise(function (resolve, reject) {
-    win.SafariViewController.show({
-      url: url,
-      transition: 'curl' // (this only works in iOS 9.1/9.2 and lower) unless animated is false you can choose from: curl, flip, fade, slide (default)
-      // enterReaderModeIfAvailable: readerMode, // default false
-      // tintColor: "#00ffff", // default is ios blue
-      // barColor: "#0000ff", // on iOS 10+ you can change the background color as well
-      // controlTintColor: "#ffffff" // on iOS 10+ you can override the default tintColor
 
-    }, // this success handler will be invoked for the lifecycle events 'opened', 'loaded' and 'closed'
-    function (result) {
-      if (result.event === 'closed') {
-        reject(new Error(_const.REGISTRATION_ABORT));
-      }
-    }, function (error) {
-      console.log('KO: ' + error);
-      reject(new Error(_const.REGISTRATION_ABORT));
-    });
-    var handle = win.handleOpenURL;
+exports.isReceivingMutationResult = isReceivingMutationResult;
 
-    win.handleOpenURL = function (url) {
-      win.SafariViewController.hide();
-      resolve(url);
+var initMutation = function initMutation(mutationId, definition) {
+  return {
+    type: INIT_MUTATION,
+    mutationId: mutationId,
+    definition: definition
+  };
+};
 
-      if (handle) {
-        win.handleOpenURL = handle;
-      }
-    };
+exports.initMutation = initMutation;
+
+var receiveMutationResult = function receiveMutationResult(mutationId, response) {
+  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+  var definition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+  return _objectSpread(_objectSpread({
+    type: RECEIVE_MUTATION_RESULT,
+    mutationId: mutationId,
+    response: response
+  }, options), {}, {
+    definition: definition
   });
 };
-/**
- * Opens an InAppBrowser and resolves with the URL containing the token
- *
- * @param {string} url
- * @returns {Promise}
- */
 
+exports.receiveMutationResult = receiveMutationResult;
 
-var authenticateWithInAppBrowser = function authenticateWithInAppBrowser(url) {
-  return new Promise(function (resolve, reject) {
-    var target = '_blank';
-    var options = 'clearcache=yes,zoom=no';
-    var inAppBrowser = win.cordova.InAppBrowser.open(url, target, options);
+var receiveMutationError = function receiveMutationError(mutationId, error) {
+  var definition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+  return {
+    type: RECEIVE_MUTATION_ERROR,
+    mutationId: mutationId,
+    error: error,
+    definition: definition
+  };
+};
 
-    var removeListener = function removeListener() {
-      inAppBrowser.removeEventListener('loadstart', onLoadStart);
-      inAppBrowser.removeEventListener('exit', onExit);
-    };
+exports.receiveMutationError = receiveMutationError;
 
-    var onLoadStart = function onLoadStart(_ref) {
-      var url = _ref.url;
-      var accessCode = /\?access_code=(.+)$/.test(url);
-      var state = /\?state=(.+)$/.test(url);
+/***/ }),
+/* 751 */
+/***/ ((__unused_webpack_module, exports) => {
 
-      if (accessCode || state) {
-        resolve(url);
-        removeListener();
-        inAppBrowser.close();
-      }
-    };
+"use strict";
 
-    var onExit = function onExit() {
-      reject(new Error(_const.REGISTRATION_ABORT));
-      removeListener();
-      inAppBrowser.close();
-    };
 
-    inAppBrowser.addEventListener('loadstart', onLoadStart);
-    inAppBrowser.addEventListener('exit', onExit);
-  });
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.properId = void 0;
+
+var properId = function properId(doc) {
+  return doc.id || doc._id;
 };
 
-var authenticateWithCordova = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) {
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            _context.t0 = (0, _cozyDeviceHelper.isIOSApp)();
+exports.properId = properId;
 
-            if (!_context.t0) {
-              _context.next = 5;
-              break;
-            }
+/***/ }),
+/* 752 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-            _context.next = 4;
-            return (0, _cozyDeviceHelper.hasSafariPlugin)();
+"use strict";
 
-          case 4:
-            _context.t0 = _context.sent;
 
-          case 5:
-            if (!_context.t0) {
-              _context.next = 9;
-              break;
-            }
+var _interopRequireDefault = __webpack_require__(524);
 
-            return _context.abrupt("return", authenticateWithSafari(url));
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-          case 9:
-            if (!(0, _cozyDeviceHelper.hasInAppBrowserPlugin)()) {
-              _context.next = 13;
-              break;
-            }
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-            return _context.abrupt("return", authenticateWithInAppBrowser(url));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-          case 13:
-            /**
-             * for dev purpose:
-             * In oauth workflow, the server displays an authorization page
-             * User must accept to give permission then the server gives an url
-             * with query parameters used by cozy-client-js to initialize itself.
-             *
-             * This hack let developers open the authorization page in a new tab
-             * then get the "access_code" url and paste it in the prompt to let the
-             * application initialize and redirect to other pages.
-             */
-            console.log(url); // Useful for dev (see above).
+var _types = __webpack_require__(622);
 
-            return _context.abrupt("return", new Promise(function (resolve) {
-              setTimeout(function () {
-                var token = prompt('Paste the url here:');
-                resolve(token);
-              }, 5000);
-            }));
+var _dsl = __webpack_require__(619);
 
-          case 15:
-          case "end":
-            return _context.stop();
-        }
-      }
-    }, _callee);
-  }));
+/**
+ * Associations are used by components to access related store documents that are
+ * linked in a document. They are also responsible for building the `QueryDefinition` that is
+ * used by the client to automatically fetch relationship data.
+ *
+ * Hydrated documents used by components come with Association instances.
+ *
+ * @interface
+ *
+ * @description
+ * Example: The schema defines an `author` relationship :
+ *
+ * ```js
+ * const BOOK_SCHEMA = {
+ *   relationships: {
+ *      author: 'has-one'
+ *   }
+ * }
+ * ```
+ *
+ * Hydrated `books` will have the `author` association instance under the `author` key.
+ * Accessing `hydratedBook.author.data` gives you the author from the store, for example :
+ *
+ * ```json
+ * {
+ *   "name": "St-Exupery",
+ *   "firstName": "Antoine",
+ *   "_id": "antoine"
+ * }
+ * ```
+ *
+ * It is the responsibility of the relationship to decide how the relationship data is stored.
+ * For example, here since we use the default `has-one` relationship, the relationship data
+ * is stored in the `relationships` attribute of the original document (in our case here, our book
+ * would be
+ *
+ * ```json
+ * {
+ *   "title": "Le petit prince",
+ *   "relationships": {
+ *     "author": {
+ *       "data": {
+ *         "doctype": "io.cozy.authors",
+ *         "_id": "antoine"
+ *       }
+ *     }
+ *   }
+ * }
+ * ```
+ *
+ * In the case of an "in-place" relationship, the relationship data is stored directly under the attribute named
+ * by the relationship (in our case `author`). Our book would be
+ *
+ * ```json
+ * {
+ *     "title": "Le petit prince",
+ *     "author": "antoine"
+ * }
+ * ```
+ *
+ * ---
+ *
+ * Each different type of Association may change:
+ *
+ * - `get raw`: how the relationship data is stored (either as per the JSON API spec or
+ *  in a custom way)
+ * - `get data`: how the store documents are then fetched from the store to be added to
+ * the hydrated document (.data method). View components will access
+ * `hydratedDoc[relationshipName].data`.
+ * - `get query`: how to build the query to fetch related documents
+ *
+ */
+var Association = /*#__PURE__*/function () {
+  /**
+   * @param  {object} target - Original object containing raw data
+   * @param  {string} name - Attribute under which the association is stored
+   * @param  {string} doctype - Doctype of the documents managed by the association
+   * @param {object} options - Options passed from the client
+   * @param {Function} options.get - Get a document from the store
+   * @param {Function} options.query - Execute client query
+   * @param {Function} options.mutate - Execute client mutate
+   * @param {Function} options.save - Execute client save
+   * @param  {Function} options.dispatch - Store's dispatch, comes from the client
+   */
+  function Association(target, name, doctype, options) {
+    (0, _classCallCheck2.default)(this, Association);
+    var dispatch = options.dispatch,
+        get = options.get,
+        query = options.query,
+        mutate = options.mutate,
+        save = options.save;
+    /**
+     * The original document declaring the relationship
+     *
+     * @type {object}
+     */
 
-  return function authenticateWithCordova(_x) {
-    return _ref2.apply(this, arguments);
-  };
+    this.target = target;
+    /**
+     * The name of the relationship.
+     *
+     * @type {string}
+     * @example 'author'
+     */
+
+    this.name = name;
+    /**
+     * Doctype of the relationship
+     *
+     * @type {string}
+     * @example 'io.cozy.authors'
+     */
+
+    this.doctype = doctype;
+    /**
+     * Returns the document from the store
+     *
+     * @type {Function}
+     */
+
+    this.get = get;
+    /**
+     * Performs a query to retrieve relationship documents.
+     *
+     * @param {QueryDefinition} queryDefinition
+     * @function
+     */
+
+    this.query = query;
+    /**
+     * Performs a mutation on the relationship.
+     *
+     * @function
+     */
+
+    this.mutate = mutate;
+    /**
+     * Saves the relationship in store.
+     *
+     * @type {Function}
+     */
+
+    this.save = save;
+    /**
+     * Dispatch an action on the store.
+     *
+     * @type {Function}
+     */
+
+    this.dispatch = dispatch;
+  }
+  /**
+   *
+   * Returns the raw relationship data as stored in the original document
+   *
+   * For a document with relationships stored as JSON API spec:
+   *
+   * ```js
+   * const book = {
+   *   title: 'Moby Dick',
+   *   relationships: {
+   *     author: {
+   *       data: {
+   *         doctype: 'io.cozy.authors',
+   *         id: 'herman'
+   *       }
+   *     }
+   *   }
+   *  }
+   * ```
+   *
+   * Raw value will be
+   *
+   * ```json
+   * {
+   *   "doctype": "io.cozy.authors",
+   *   "id": "herman"
+   * }
+   * ```
+   *
+   * Derived `Association`s need to implement this method.
+   *
+   * @returns {object}
+   */
+
+
+  (0, _createClass2.default)(Association, [{
+    key: "raw",
+    get: function get() {
+      throw new Error('A relationship must define its raw getter');
+    }
+    /**
+     * Returns the document(s) from the store
+     *
+     * For document with relationships stored as JSON API spec :
+     *
+     * ```js
+     * const book = {
+     *   title: 'Moby Dick',
+     *   relationships: {
+     *     author: {
+     *       data: {
+     *         doctype: 'io.cozy.authors',
+     *         id: 'herman'
+     *       }
+     *     }
+     *   }
+     *  }
+     * ```
+     *
+     * `data` will be
+     *
+     * ```json
+     * {
+     *   "_id": "herman"
+     *   "_type": "io.cozy.authors",
+     *   "firstName": "herman",
+     *   "name": "Melville"
+     * }
+     * ```
+     *
+     * Derived `Association`s need to implement this method.
+     *
+     * @returns {object}
+     */
+
+  }, {
+    key: "data",
+    get: function get() {
+      throw new Error('A relationship must define its data getter');
+    }
+    /**
+     * Derived `Association`s need to implement this method.
+     *
+     * @param {CozyClientDocument} document - Document to query
+     * @param {object} client - The CozyClient instance
+     * @param {Association} assoc - Association containing info on how to build the query to fetch related documents
+     *
+     * @returns {CozyClientDocument | QueryDefinition }
+     */
+
+  }], [{
+    key: "query",
+    value: function query(document, client, assoc) {
+      throw new Error('A custom relationship must define its query() function');
+    }
+  }]);
+  return Association;
 }();
 
-exports.authenticateWithCordova = authenticateWithCordova;
-var authFunction = authenticateWithCordova;
-exports.authFunction = authFunction;
+var _default = Association;
+exports["default"] = _default;
 
 /***/ }),
-/* 758 */
+/* 753 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
+var _interopRequireDefault = __webpack_require__(524);
+
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-Object.defineProperty(exports, "getPlatform", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.getPlatform;
-  }
-}));
-Object.defineProperty(exports, "isIOSApp", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isIOSApp;
-  }
-}));
-Object.defineProperty(exports, "isAndroidApp", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isAndroidApp;
-  }
-}));
-Object.defineProperty(exports, "isWebApp", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isWebApp;
-  }
-}));
-Object.defineProperty(exports, "isMobileApp", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isMobileApp;
-  }
-}));
-Object.defineProperty(exports, "isAndroid", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isAndroid;
-  }
-}));
-Object.defineProperty(exports, "isIOS", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isIOS;
-  }
-}));
-Object.defineProperty(exports, "isMobile", ({
-  enumerable: true,
-  get: function get() {
-    return _platform.isMobile;
-  }
-}));
-Object.defineProperty(exports, "getDeviceName", ({
-  enumerable: true,
-  get: function get() {
-    return _device.getDeviceName;
-  }
-}));
-Object.defineProperty(exports, "checkApp", ({
-  enumerable: true,
-  get: function get() {
-    return _apps.checkApp;
-  }
-}));
-Object.defineProperty(exports, "startApp", ({
-  enumerable: true,
-  get: function get() {
-    return _apps.startApp;
-  }
-}));
-Object.defineProperty(exports, "hasDevicePlugin", ({
-  enumerable: true,
-  get: function get() {
-    return _plugins.hasDevicePlugin;
-  }
-}));
-Object.defineProperty(exports, "hasInAppBrowserPlugin", ({
-  enumerable: true,
-  get: function get() {
-    return _plugins.hasInAppBrowserPlugin;
-  }
-}));
-Object.defineProperty(exports, "hasSafariPlugin", ({
-  enumerable: true,
-  get: function get() {
-    return _plugins.hasSafariPlugin;
-  }
-}));
-Object.defineProperty(exports, "hasNetworkInformationPlugin", ({
-  enumerable: true,
-  get: function get() {
-    return _plugins.hasNetworkInformationPlugin;
-  }
-}));
-Object.defineProperty(exports, "isCordova", ({
-  enumerable: true,
-  get: function get() {
-    return _cordova.isCordova;
-  }
-}));
-Object.defineProperty(exports, "nativeLinkOpen", ({
-  enumerable: true,
-  get: function get() {
-    return _link.nativeLinkOpen;
-  }
-}));
-Object.defineProperty(exports, "openDeeplinkOrRedirect", ({
-  enumerable: true,
-  get: function get() {
-    return _deeplink.openDeeplinkOrRedirect;
-  }
-}));
+exports["default"] = exports.updateRelationship = exports.updateHasManyItem = exports.removeHasManyItem = exports.setHasManyItem = exports.getHasManyItems = exports.getHasManyItem = void 0;
 
-var _platform = __webpack_require__(759);
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _device = __webpack_require__(761);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _apps = __webpack_require__(771);
+var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(606));
 
-var _plugins = __webpack_require__(770);
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _cordova = __webpack_require__(760);
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _link = __webpack_require__(772);
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _deeplink = __webpack_require__(773);
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-/***/ }),
-/* 759 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-"use strict";
+var _get = _interopRequireDefault(__webpack_require__(370));
 
+var _merge = _interopRequireDefault(__webpack_require__(754));
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.isMobile = exports.isIOS = exports.isAndroid = exports.isMobileApp = exports.isWebApp = exports.isAndroidApp = exports.isIOSApp = exports.getPlatform = void 0;
+var _dsl = __webpack_require__(619);
 
-var _cordova = __webpack_require__(760);
+var _store = __webpack_require__(705);
 
-var WEB_PLATFORM = 'web';
-var IOS_PLATFORM = 'ios';
-var ANDROID_PLATFORM = 'android';
+var _types = __webpack_require__(622);
 
-var getPlatform = function getPlatform() {
-  return (0, _cordova.isCordova)() ? window.cordova.platformId : WEB_PLATFORM;
-};
+var _Association2 = _interopRequireDefault(__webpack_require__(752));
 
-exports.getPlatform = getPlatform;
+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; }
 
-var isPlatform = function isPlatform(platform) {
-  return getPlatform() === platform;
-};
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var isIOSApp = function isIOSApp() {
-  return isPlatform(IOS_PLATFORM);
-};
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-exports.isIOSApp = isIOSApp;
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var isAndroidApp = function isAndroidApp() {
-  return isPlatform(ANDROID_PLATFORM);
-};
+/**
+ * @typedef {object} Relationship
+ * @property {string} relName - name of the relationship
+ * @property {string} relItemId - id of the relation
+ * @property {Relation} relItemAttrs - Attributes to be set (at least _id and _type)
+ */
 
-exports.isAndroidApp = isAndroidApp;
+/**
+ * @typedef {object} Relation
+ * @property {string} _id - id of the relation
+ * @property {string} _type - doctype of the relation
+ */
+var empty = function empty() {
+  return {
+    data: [],
+    next: true,
+    meta: {
+      count: 0
+    }
+  };
+};
 
-var isWebApp = function isWebApp() {
-  return isPlatform(WEB_PLATFORM);
+var updateArray = function updateArray(array, indexArg, el) {
+  var index = indexArg === -1 ? array.length : indexArg;
+  return [].concat((0, _toConsumableArray2.default)(array.slice(0, index)), [el], (0, _toConsumableArray2.default)(array.slice(index + 1)));
 };
+/**
+ * Related documents are stored in the relationships attribute of the object,
+ * following the JSON API spec.
+ *
+ * Responsible for
+ *
+ * - Creating relationships
+ * - Removing relationships
+ *
+ * @description
+ *
+ * ```
+ * const schema = {
+ *   todos: {
+ *      doctype: 'io.cozy.todos',
+ *      relationships: {
+ *        tasks: {
+ *          doctype: 'io.cozy.tasks',
+ *          type: 'has-many'
+ *        }
+ *      }
+ *    }
+ * }
+ *
+ * const todo = {
+ *   label: "Protect people's privacy",
+ *   relationships: {
+ *     tasks: {
+ *       data: [
+ *         {_id: 1, _type: 'io.cozy.tasks'},
+ *         {_id: 2, _type: 'io.cozy.tasks'}
+ *       ]
+ *     }
+ *   }
+ * }
+ * ```
+ */
 
-exports.isWebApp = isWebApp;
 
-var isMobileApp = function isMobileApp() {
-  return (0, _cordova.isCordova)();
-}; // return if is on an Android Device (native or browser)
+var HasMany = /*#__PURE__*/function (_Association) {
+  (0, _inherits2.default)(HasMany, _Association);
 
+  var _super = _createSuper(HasMany);
 
-exports.isMobileApp = isMobileApp;
+  function HasMany() {
+    var _this;
 
-var isAndroid = function isAndroid() {
-  return window.navigator.userAgent && window.navigator.userAgent.indexOf('Android') >= 0;
-}; // return if is on an iOS Device (native or browser)
+    (0, _classCallCheck2.default)(this, HasMany);
 
+    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
 
-exports.isAndroid = isAndroid;
+    _this = _super.call.apply(_super, [this].concat(args));
+    (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateRelationshipData", function (getUpdatedRelationshipData) {
+      return function (dispatch, getState) {
+        var previousRelationship = (0, _store.getDocumentFromState)(getState(), _this.target._type, _this.target._id);
+        dispatch((0, _store.receiveQueryResult)(null, {
+          data: _objectSpread(_objectSpread({}, previousRelationship), {}, {
+            relationships: _objectSpread(_objectSpread({}, previousRelationship.relationships), {}, (0, _defineProperty2.default)({}, _this.name, getUpdatedRelationshipData(previousRelationship.relationships[_this.name])))
+          })
+        }));
+      };
+    });
+    return _this;
+  }
 
-var isIOS = function isIOS() {
-  return window.navigator.userAgent && /iPad|iPhone|iPod/.test(window.navigator.userAgent);
-}; // isMobile checks if the user is on a smartphone : native app or browser
+  (0, _createClass2.default)(HasMany, [{
+    key: "fetchMore",
+    value: function fetchMore() {
+      throw 'Not implemented';
+    }
+  }, {
+    key: "exists",
+    value: function exists(document) {
+      return this.existsById(document._id);
+    }
+  }, {
+    key: "containsById",
+    value: function containsById(id) {
+      return this.getRelationship().data.find(function (_ref) {
+        var _id = _ref._id;
+        return id === _id;
+      }) !== undefined;
+    }
+  }, {
+    key: "existsById",
+    value: function existsById(id) {
+      return Boolean(this.containsById(id) && this.get(this.doctype, id));
+    }
+    /**
+     * Add the relationships to the target document
+     *
+     * @param {CozyClientDocument[]} docsArg - Documents to add as relationships
+     * @returns {CozyClientDocument} The saved target document
+     */
 
+  }, {
+    key: "add",
+    value: function add(docsArg) {
+      var docs = Array.isArray(docsArg) ? docsArg : [docsArg];
+      var ids = docs.map(function (doc) {
+        return doc._id;
+      });
+      return this.addById(ids);
+    }
+    /**
+     * Remove the relationships from the target document
+     *
+     * @param {CozyClientDocument[]} docsArg - Documents to remove as relationships
+     * @returns {CozyClientDocument} The saved target document
+     */
 
-exports.isIOS = isIOS;
+  }, {
+    key: "remove",
+    value: function remove(docsArg) {
+      var docs = Array.isArray(docsArg) ? docsArg : [docsArg];
+      var ids = docs.map(function (doc) {
+        return doc._id;
+      });
+      return this.removeById(ids);
+    }
+    /**
+     * Update target document with relationships
+     *
+     * @param {string[]} idsArg - The ids to add as a relationship
+     */
 
-var isMobile = function isMobile() {
-  return isAndroid() || isIOS();
-};
+  }, {
+    key: "addTargetRelationships",
+    value: function addTargetRelationships(idsArg) {
+      var _this2 = this,
+          _this$target$relation;
 
-exports.isMobile = isMobile;
+      if (!this.target.relationships) this.target.relationships = {};
 
-/***/ }),
-/* 760 */
-/***/ ((__unused_webpack_module, exports) => {
+      if (!this.target.relationships[this.name]) {
+        this.target.relationships[this.name] = {
+          data: []
+        };
+      }
 
-"use strict";
+      var ids = Array.isArray(idsArg) ? idsArg : [idsArg];
+      var newRelations = ids.filter(function (id) {
+        return !_this2.existsById(id);
+      }).map(function (id) {
+        return {
+          _id: id,
+          _type: _this2.doctype
+        };
+      });
 
+      (_this$target$relation = this.target.relationships[this.name].data).push.apply(_this$target$relation, (0, _toConsumableArray2.default)(newRelations));
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.isCordova = void 0;
+      this.updateMetaCount();
+    }
+    /**
+     * Add a referenced document by id. You need to call save()
+     * in order to synchronize your document with the store.
+     *
+     * @todo We shouldn't create the array of relationship manually since
+     * it'll not be present in the store as well.
+     * We certainly should use something like `updateRelationship`
+     *
+     */
 
-// cordova
-var isCordova = function isCordova() {
-  return typeof window !== 'undefined' && window.cordova !== undefined;
-};
+  }, {
+    key: "addById",
+    value: function addById(idsArg) {
+      this.addTargetRelationships(idsArg);
+      return this.save(this.target);
+    }
+    /**
+     * Remove relationships from target document
+     *
+     * @param {string[]} idsArg - The ids to remove from the target relationships
+     */
 
-exports.isCordova = isCordova;
+  }, {
+    key: "removeTargetRelationships",
+    value: function removeTargetRelationships(idsArg) {
+      var ids = Array.isArray(idsArg) ? idsArg : [idsArg];
+      this.target.relationships[this.name].data = this.target.relationships[this.name].data.filter(function (_ref2) {
+        var _id = _ref2._id;
+        return !ids.includes(_id);
+      });
+      this.updateMetaCount();
+    }
+  }, {
+    key: "removeById",
+    value: function removeById(idsArg) {
+      this.removeTargetRelationships(idsArg);
+      return this.save(this.target);
+    }
+  }, {
+    key: "updateMetaCount",
+    value: function updateMetaCount() {
+      if ((0, _get.default)(this.target.relationships[this.name], 'meta.count') !== undefined) {
+        this.target.relationships[this.name].meta = _objectSpread(_objectSpread({}, this.target.relationships[this.name].meta), {}, {
+          count: this.target.relationships[this.name].data.length
+        });
+      }
+    }
+  }, {
+    key: "getRelationship",
+    value: function getRelationship() {
+      var rawData = this.target[this.name];
+      var relationship = (0, _get.default)(this.target, "relationships.".concat(this.name));
 
-/***/ }),
-/* 761 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+      if (!relationship) {
+        if (rawData && rawData.length) {
+          console.warn("You're trying to access data on a relationship that appear to not be loaded yet. You may want to use 'include()' on your query");
+        }
 
-"use strict";
+        return empty();
+      }
 
+      return relationship;
+    }
+  }, {
+    key: "updateTargetRelationship",
+    value: function updateTargetRelationship(store, updateFn) {
+      // TODO See if updateTargetRelationship is still used, removing it would enable us
+      // to remove store.readDocument and store.writeDocument and the StoreProxy
+      var prevTarget = store.readDocument(this.target._type, this.target._id);
+      store.writeDocument(this.updateRelationship(prevTarget, updateFn));
+    }
+  }, {
+    key: "updateRelationship",
+    value: function updateRelationship(target, updateFn) {
+      return HasMany.updateRelationship(target, this.name, updateFn);
+    }
+  }, {
+    key: "dehydrate",
+    value: function dehydrate(doc) {
+      return _objectSpread(_objectSpread({}, doc), {}, {
+        relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, {
+          data: this.raw
+        }))
+      });
+    }
+    /**
+     * @param {CozyClientDocument} document - Document to query
+     * @param {object} client - The CozyClient instance
+     * @param {Association} assoc - The query params
+     *
+     * @returns {CozyClientDocument | QueryDefinition}
+     */
 
-var _interopRequireDefault = __webpack_require__(512);
+  }, {
+    key: "raw",
+    get: function get() {
+      return this.getRelationship().data;
+    }
+    /**
+     * Returns store documents
+     */
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.getDeviceName = void 0;
+  }, {
+    key: "data",
+    get: function get() {
+      var _this3 = this;
 
-var _capitalize = _interopRequireDefault(__webpack_require__(762));
+      return this.getRelationship().data.map(function (_ref3) {
+        var _id = _ref3._id,
+            _type = _ref3._type;
+        return _this3.get(_type, _id);
+      }).filter(Boolean);
+    }
+  }, {
+    key: "hasMore",
+    get: function get() {
+      return this.getRelationship().next;
+    }
+    /**
+     * Returns the total number of documents in the relationship.
+     * Does not handle documents absent from the store. If you want
+     * to do that, you can use .data.length.
+     *
+     * @returns {number} - Total number of documents in the relationships
+     */
 
-var _cordova = __webpack_require__(760);
+  }, {
+    key: "count",
+    get: function get() {
+      var relationship = this.getRelationship();
+      return relationship.meta ? relationship.meta.count : relationship.data.length;
+    }
+  }], [{
+    key: "query",
+    value: function query(document, client, assoc) {
+      var relationships = (0, _get.default)(document, "relationships.".concat(assoc.name, ".data"), []);
+      var ids = relationships.map(function (assoc) {
+        return assoc._id;
+      });
+      return new _dsl.QueryDefinition({
+        doctype: assoc.doctype,
+        ids: ids
+      });
+    }
+  }]);
+  return HasMany;
+}(_Association2.default);
+/**
+ * Gets a relationship item with the relationship name and id
+ *
+ * @param {object} doc - Document to be updated
+ * @param {string} relName - Name of the relationship
+ * @param {string} relItemId - Id of the relationship item
+ */
 
-var _plugins = __webpack_require__(770);
 
-var _platform = __webpack_require__(759);
+var getHasManyItem = HasMany.getHasManyItem = function (doc, relName, relItemId) {
+  var relData = (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []);
+  return relData.find(function (rel) {
+    return rel._id == relItemId;
+  });
+};
 
-var DEFAULT_DEVICE = 'Device'; // device
+exports.getHasManyItem = getHasManyItem;
 
-var getAppleModel = function getAppleModel(identifier) {
-  var devices = ['iPhone', 'iPad', 'Watch', 'AppleTV'];
+var getHasManyItems = HasMany.getHasManyItems = function (doc, relName) {
+  return (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []);
+};
+/**
+ * Sets a relationship item with the relationship name and id
+ *
+ * @param {object} doc - Document to be updated
+ * @param {string} relName - Name of the relationship
+ * @param {string} relItemId - Id of the relationship item
+ * @param {object} relItemAttrs - Attributes to be set (at least _id and _type)
+ */
 
-  for (var _i = 0, _devices = devices; _i < _devices.length; _i++) {
-    var device = _devices[_i];
 
-    if (identifier.match(new RegExp(device))) {
-      return device;
-    }
-  }
+exports.getHasManyItems = getHasManyItems;
 
-  return DEFAULT_DEVICE;
+var setHasManyItem = HasMany.setHasManyItem = function (doc, relName, relItemId, relItemAttrs) {
+  var relData = HasMany.getHasManyItems(doc, relName);
+  var relIndex = relData.findIndex(function (rel) {
+    return rel._id === relItemId;
+  });
+  var updatedRelItem = (0, _merge.default)({}, relData[relIndex], relItemAttrs);
+  var updatedRelData = updateArray(relData, relIndex, updatedRelItem);
+  var updatedDocument = HasMany.updateRelationship(doc, relName, function (relationship) {
+    return (0, _merge.default)({}, relationship, {
+      data: updatedRelData
+    });
+  });
+  return updatedDocument;
 };
+/**
+ * Remove one relationship item
+ *
+ * @param {object} doc - Document to be updated
+ * @param {string} relName - Name of the relationship
+ * @param {string} relItemId - Id of the relationship item
+ */
 
-var getDeviceName = function getDeviceName() {
-  if (!(0, _plugins.hasDevicePlugin)()) {
-    if ((0, _cordova.isCordova)()) {
-      console.warn('You should install `cordova-plugin-device`.'); // eslint-disable-line no-console
-    }
 
-    return DEFAULT_DEVICE;
-  }
+exports.setHasManyItem = setHasManyItem;
 
-  var _window$device = window.device,
-      manufacturer = _window$device.manufacturer,
-      originalModel = _window$device.model;
-  var model = (0, _platform.isIOSApp)() ? getAppleModel(originalModel) : originalModel;
-  return "".concat((0, _capitalize.default)(manufacturer), " ").concat(model);
+var removeHasManyItem = HasMany.removeHasManyItem = function (doc, relName, relItemId) {
+  var relData = HasMany.getHasManyItems(doc, relName);
+  var updatedRelData = relData.filter(function (rel) {
+    return rel._id !== relItemId;
+  });
+  var updatedDocument = HasMany.updateRelationship(doc, relName, function () {
+    return {
+      data: updatedRelData
+    };
+  });
+  return updatedDocument;
 };
+/**
+ * Updates a relationship item with the relationship name and id
+ *
+ * @param {object} doc - Document to be updated
+ * @param {string} relName - Name of the relationship
+ * @param {string} relItemId - Id of the relationship item
+ * @param {Function} updater - receives the current relationship item and should
+ * return an updated version. Merge should be used in the updater
+ * if previous relationship item fields are to be kept.
+ */
 
-exports.getDeviceName = getDeviceName;
 
-/***/ }),
-/* 762 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+exports.removeHasManyItem = removeHasManyItem;
 
-var toString = __webpack_require__(396),
-    upperFirst = __webpack_require__(763);
+var updateHasManyItem = HasMany.updateHasManyItem = function (doc, relName, relItemId, updater) {
+  var relItem = HasMany.getHasManyItem(doc, relName, relItemId);
+  var updatedRelItem = updater(relItem);
+  return HasMany.setHasManyItem(doc, relName, relItemId, updatedRelItem);
+};
 
-/**
- * Converts the first character of `string` to upper case and the remaining
- * to lower case.
- *
- * @static
- * @memberOf _
- * @since 3.0.0
- * @category String
- * @param {string} [string=''] The string to capitalize.
- * @returns {string} Returns the capitalized string.
- * @example
- *
- * _.capitalize('FRED');
- * // => 'Fred'
- */
-function capitalize(string) {
-  return upperFirst(toString(string).toLowerCase());
-}
+exports.updateHasManyItem = updateHasManyItem;
 
-module.exports = capitalize;
+var updateRelationship = HasMany.updateRelationship = function (doc, relName, updateFn) {
+  return _objectSpread(_objectSpread({}, doc), {}, {
+    relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, relName, _objectSpread(_objectSpread({}, doc.relationships ? doc.relationships[relName] : {}), updateFn(doc.relationships ? doc.relationships[relName] : {}))))
+  });
+};
 
+exports.updateRelationship = updateRelationship;
+var _default = HasMany;
+exports["default"] = _default;
 
 /***/ }),
-/* 763 */
+/* 754 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var createCaseFirst = __webpack_require__(764);
+var baseMerge = __webpack_require__(755),
+    createAssigner = __webpack_require__(760);
 
 /**
- * Converts the first character of `string` to upper case.
+ * This method is like `_.assign` except that it recursively merges own and
+ * inherited enumerable string keyed properties of source objects into the
+ * destination object. Source properties that resolve to `undefined` are
+ * skipped if a destination value exists. Array and plain object properties
+ * are merged recursively. Other objects and value types are overridden by
+ * assignment. Source objects are applied from left to right. Subsequent
+ * sources overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object`.
  *
  * @static
  * @memberOf _
- * @since 4.0.0
- * @category String
- * @param {string} [string=''] The string to convert.
- * @returns {string} Returns the converted string.
+ * @since 0.5.0
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
  * @example
  *
- * _.upperFirst('fred');
- * // => 'Fred'
+ * var object = {
+ *   'a': [{ 'b': 2 }, { 'd': 4 }]
+ * };
  *
- * _.upperFirst('FRED');
- * // => 'FRED'
+ * var other = {
+ *   'a': [{ 'c': 3 }, { 'e': 5 }]
+ * };
+ *
+ * _.merge(object, other);
+ * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
  */
-var upperFirst = createCaseFirst('toUpperCase');
+var merge = createAssigner(function(object, source, srcIndex) {
+  baseMerge(object, source, srcIndex);
+});
 
-module.exports = upperFirst;
+module.exports = merge;
 
 
 /***/ }),
-/* 764 */
+/* 755 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var castSlice = __webpack_require__(765),
-    hasUnicode = __webpack_require__(766),
-    stringToArray = __webpack_require__(767),
-    toString = __webpack_require__(396);
+var Stack = __webpack_require__(416),
+    assignMergeValue = __webpack_require__(756),
+    baseFor = __webpack_require__(549),
+    baseMergeDeep = __webpack_require__(757),
+    isObject = __webpack_require__(52),
+    keysIn = __webpack_require__(579),
+    safeGet = __webpack_require__(758);
 
 /**
- * Creates a function like `_.lowerFirst`.
+ * The base implementation of `_.merge` without support for multiple sources.
  *
  * @private
- * @param {string} methodName The name of the `String` case method to use.
- * @returns {Function} Returns the new case function.
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} [customizer] The function to customize merged values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ *  counterparts.
  */
-function createCaseFirst(methodName) {
-  return function(string) {
-    string = toString(string);
-
-    var strSymbols = hasUnicode(string)
-      ? stringToArray(string)
-      : undefined;
-
-    var chr = strSymbols
-      ? strSymbols[0]
-      : string.charAt(0);
-
-    var trailing = strSymbols
-      ? castSlice(strSymbols, 1).join('')
-      : string.slice(1);
+function baseMerge(object, source, srcIndex, customizer, stack) {
+  if (object === source) {
+    return;
+  }
+  baseFor(source, function(srcValue, key) {
+    stack || (stack = new Stack);
+    if (isObject(srcValue)) {
+      baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
+    }
+    else {
+      var newValue = customizer
+        ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
+        : undefined;
 
-    return chr[methodName]() + trailing;
-  };
+      if (newValue === undefined) {
+        newValue = srcValue;
+      }
+      assignMergeValue(object, key, newValue);
+    }
+  }, keysIn);
 }
 
-module.exports = createCaseFirst;
+module.exports = baseMerge;
 
 
 /***/ }),
-/* 765 */
+/* 756 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseSlice = __webpack_require__(617);
+var baseAssignValue = __webpack_require__(546),
+    eq = __webpack_require__(397);
 
 /**
- * Casts `array` to a slice if it's needed.
+ * This function is like `assignValue` except that it doesn't assign
+ * `undefined` values.
  *
  * @private
- * @param {Array} array The array to inspect.
- * @param {number} start The start position.
- * @param {number} [end=array.length] The end position.
- * @returns {Array} Returns the cast slice.
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
  */
-function castSlice(array, start, end) {
-  var length = array.length;
-  end = end === undefined ? length : end;
-  return (!start && end >= length) ? array : baseSlice(array, start, end);
+function assignMergeValue(object, key, value) {
+  if ((value !== undefined && !eq(object[key], value)) ||
+      (value === undefined && !(key in object))) {
+    baseAssignValue(object, key, value);
+  }
 }
 
-module.exports = castSlice;
+module.exports = assignMergeValue;
 
 
 /***/ }),
-/* 766 */
-/***/ ((module) => {
-
-/** Used to compose unicode character classes. */
-var rsAstralRange = '\\ud800-\\udfff',
-    rsComboMarksRange = '\\u0300-\\u036f',
-    reComboHalfMarksRange = '\\ufe20-\\ufe2f',
-    rsComboSymbolsRange = '\\u20d0-\\u20ff',
-    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
-    rsVarRange = '\\ufe0e\\ufe0f';
-
-/** Used to compose unicode capture groups. */
-var rsZWJ = '\\u200d';
+/* 757 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
-var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
+var assignMergeValue = __webpack_require__(756),
+    cloneBuffer = __webpack_require__(582),
+    cloneTypedArray = __webpack_require__(595),
+    copyArray = __webpack_require__(583),
+    initCloneObject = __webpack_require__(596),
+    isArguments = __webpack_require__(444),
+    isArray = __webpack_require__(55),
+    isArrayLikeObject = __webpack_require__(564),
+    isBuffer = __webpack_require__(446),
+    isFunction = __webpack_require__(45),
+    isObject = __webpack_require__(52),
+    isPlainObject = __webpack_require__(631),
+    isTypedArray = __webpack_require__(449),
+    safeGet = __webpack_require__(758),
+    toPlainObject = __webpack_require__(759);
 
 /**
- * Checks if `string` contains Unicode symbols.
+ * A specialized version of `baseMerge` for arrays and objects which performs
+ * deep merges and tracks traversed objects enabling objects with circular
+ * references to be merged.
  *
  * @private
- * @param {string} string The string to inspect.
- * @returns {boolean} Returns `true` if a symbol is found, else `false`.
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @param {string} key The key of the value to merge.
+ * @param {number} srcIndex The index of `source`.
+ * @param {Function} mergeFunc The function to merge values.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {Object} [stack] Tracks traversed source values and their merged
+ *  counterparts.
  */
-function hasUnicode(string) {
-  return reHasUnicode.test(string);
-}
-
-module.exports = hasUnicode;
+function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
+  var objValue = safeGet(object, key),
+      srcValue = safeGet(source, key),
+      stacked = stack.get(srcValue);
 
+  if (stacked) {
+    assignMergeValue(object, key, stacked);
+    return;
+  }
+  var newValue = customizer
+    ? customizer(objValue, srcValue, (key + ''), object, source, stack)
+    : undefined;
 
-/***/ }),
-/* 767 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  var isCommon = newValue === undefined;
 
-var asciiToArray = __webpack_require__(768),
-    hasUnicode = __webpack_require__(766),
-    unicodeToArray = __webpack_require__(769);
+  if (isCommon) {
+    var isArr = isArray(srcValue),
+        isBuff = !isArr && isBuffer(srcValue),
+        isTyped = !isArr && !isBuff && isTypedArray(srcValue);
 
-/**
- * Converts `string` to an array.
- *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the converted array.
- */
-function stringToArray(string) {
-  return hasUnicode(string)
-    ? unicodeToArray(string)
-    : asciiToArray(string);
+    newValue = srcValue;
+    if (isArr || isBuff || isTyped) {
+      if (isArray(objValue)) {
+        newValue = objValue;
+      }
+      else if (isArrayLikeObject(objValue)) {
+        newValue = copyArray(objValue);
+      }
+      else if (isBuff) {
+        isCommon = false;
+        newValue = cloneBuffer(srcValue, true);
+      }
+      else if (isTyped) {
+        isCommon = false;
+        newValue = cloneTypedArray(srcValue, true);
+      }
+      else {
+        newValue = [];
+      }
+    }
+    else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+      newValue = objValue;
+      if (isArguments(objValue)) {
+        newValue = toPlainObject(objValue);
+      }
+      else if (!isObject(objValue) || isFunction(objValue)) {
+        newValue = initCloneObject(srcValue);
+      }
+    }
+    else {
+      isCommon = false;
+    }
+  }
+  if (isCommon) {
+    // Recursively merge objects and arrays (susceptible to call stack limits).
+    stack.set(srcValue, newValue);
+    mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
+    stack['delete'](srcValue);
+  }
+  assignMergeValue(object, key, newValue);
 }
 
-module.exports = stringToArray;
+module.exports = baseMergeDeep;
 
 
 /***/ }),
-/* 768 */
+/* 758 */
 /***/ ((module) => {
 
 /**
- * Converts an ASCII `string` to an array.
+ * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
  *
  * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the converted array.
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the property to get.
+ * @returns {*} Returns the property value.
  */
-function asciiToArray(string) {
-  return string.split('');
-}
-
-module.exports = asciiToArray;
+function safeGet(object, key) {
+  if (key === 'constructor' && typeof object[key] === 'function') {
+    return;
+  }
 
+  if (key == '__proto__') {
+    return;
+  }
 
-/***/ }),
-/* 769 */
-/***/ ((module) => {
+  return object[key];
+}
 
-/** Used to compose unicode character classes. */
-var rsAstralRange = '\\ud800-\\udfff',
-    rsComboMarksRange = '\\u0300-\\u036f',
-    reComboHalfMarksRange = '\\ufe20-\\ufe2f',
-    rsComboSymbolsRange = '\\u20d0-\\u20ff',
-    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
-    rsVarRange = '\\ufe0e\\ufe0f';
+module.exports = safeGet;
 
-/** Used to compose unicode capture groups. */
-var rsAstral = '[' + rsAstralRange + ']',
-    rsCombo = '[' + rsComboRange + ']',
-    rsFitz = '\\ud83c[\\udffb-\\udfff]',
-    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
-    rsNonAstral = '[^' + rsAstralRange + ']',
-    rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
-    rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
-    rsZWJ = '\\u200d';
 
-/** Used to compose unicode regexes. */
-var reOptMod = rsModifier + '?',
-    rsOptVar = '[' + rsVarRange + ']?',
-    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
-    rsSeq = rsOptVar + reOptMod + rsOptJoin,
-    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+/***/ }),
+/* 759 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
-var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+var copyObject = __webpack_require__(577),
+    keysIn = __webpack_require__(579);
 
 /**
- * Converts a Unicode `string` to an array.
+ * Converts `value` to a plain object flattening inherited enumerable string
+ * keyed properties of `value` to own properties of the plain object.
  *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the converted array.
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Object} Returns the converted plain object.
+ * @example
+ *
+ * function Foo() {
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.assign({ 'a': 1 }, new Foo);
+ * // => { 'a': 1, 'b': 2 }
+ *
+ * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
+ * // => { 'a': 1, 'b': 2, 'c': 3 }
  */
-function unicodeToArray(string) {
-  return string.match(reUnicode) || [];
+function toPlainObject(value) {
+  return copyObject(value, keysIn(value));
 }
 
-module.exports = unicodeToArray;
+module.exports = toPlainObject;
 
 
 /***/ }),
-/* 770 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
+/* 760 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
+var baseRest = __webpack_require__(556),
+    isIterateeCall = __webpack_require__(761);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.hasNetworkInformationPlugin = exports.hasSafariPlugin = exports.hasInAppBrowserPlugin = exports.hasDevicePlugin = void 0;
+/**
+ * Creates a function like `_.assign`.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @returns {Function} Returns the new assigner function.
+ */
+function createAssigner(assigner) {
+  return baseRest(function(object, sources) {
+    var index = -1,
+        length = sources.length,
+        customizer = length > 1 ? sources[length - 1] : undefined,
+        guard = length > 2 ? sources[2] : undefined;
 
-var _cordova = __webpack_require__(760);
+    customizer = (assigner.length > 3 && typeof customizer == 'function')
+      ? (length--, customizer)
+      : undefined;
 
-var hasDevicePlugin = function hasDevicePlugin() {
-  return (0, _cordova.isCordova)() && window.device !== undefined;
-};
+    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+      customizer = length < 3 ? undefined : customizer;
+      length = 1;
+    }
+    object = Object(object);
+    while (++index < length) {
+      var source = sources[index];
+      if (source) {
+        assigner(object, source, index, customizer);
+      }
+    }
+    return object;
+  });
+}
 
-exports.hasDevicePlugin = hasDevicePlugin;
+module.exports = createAssigner;
 
-var hasInAppBrowserPlugin = function hasInAppBrowserPlugin() {
-  return (0, _cordova.isCordova)() && window.cordova.InAppBrowser !== undefined;
-};
 
-exports.hasInAppBrowserPlugin = hasInAppBrowserPlugin;
+/***/ }),
+/* 761 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var hasSafariPlugin = function hasSafariPlugin() {
-  return new Promise(function (resolve) {
-    if (!(0, _cordova.isCordova)() || window.SafariViewController === undefined) {
-      resolve(false);
-      return;
-    }
+var eq = __webpack_require__(397),
+    isArrayLike = __webpack_require__(458),
+    isIndex = __webpack_require__(448),
+    isObject = __webpack_require__(52);
 
-    window.SafariViewController.isAvailable(function (available) {
-      return resolve(available);
-    });
-  });
-};
 /**
- * Check if the Cordova's cordova-plugin-network-information plugin is installed
- * @see https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-network-information/
- * @returns {boolean}
+ * Checks if the given arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
+ *  else `false`.
  */
+function isIterateeCall(value, index, object) {
+  if (!isObject(object)) {
+    return false;
+  }
+  var type = typeof index;
+  if (type == 'number'
+        ? (isArrayLike(object) && isIndex(index, object.length))
+        : (type == 'string' && index in object)
+      ) {
+    return eq(object[index], value);
+  }
+  return false;
+}
 
+module.exports = isIterateeCall;
 
-exports.hasSafariPlugin = hasSafariPlugin;
-
-var hasNetworkInformationPlugin = function hasNetworkInformationPlugin() {
-  return (0, _cordova.isCordova)() && window.navigator.connection !== undefined;
-};
-
-exports.hasNetworkInformationPlugin = hasNetworkInformationPlugin;
 
 /***/ }),
-/* 771 */
+/* 762 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = exports.startApp = exports.checkApp = void 0;
+exports["default"] = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _platform = __webpack_require__(759);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var cordovaPluginIsInstalled = function cordovaPluginIsInstalled() {
-  return window.startApp;
-};
-/**
- * Normalize startApp params for Android and iOS
- */
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var getParams = function getParams(_ref) {
-  var appId = _ref.appId,
-      uri = _ref.uri;
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-  if ((0, _platform.isAndroidApp)()) {
-    return {
-      package: appId
-    };
-  } else {
-    return uri;
-  }
-};
+var _get2 = _interopRequireDefault(__webpack_require__(370));
 
-var exported = {};
-/**
- * Start an application if it is installed on the phone
- * @returns Promise - False if the application was not able to be started
- */
+var _set = _interopRequireDefault(__webpack_require__(763));
 
-var startApp = exported.startApp = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(appInfo) {
-    var startAppPlugin, isAppInstalled, params;
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            startAppPlugin = window.startApp;
-            _context.next = 3;
-            return exported.checkApp(appInfo);
+var _dsl = __webpack_require__(619);
 
-          case 3:
-            isAppInstalled = _context.sent;
+var _types = __webpack_require__(622);
 
-            if (!isAppInstalled) {
-              _context.next = 9;
-              break;
-            }
+var _Association2 = _interopRequireDefault(__webpack_require__(752));
 
-            params = getParams(appInfo);
-            return _context.abrupt("return", new Promise(function (resolve, reject) {
-              if (!cordovaPluginIsInstalled()) {
-                reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed. This plugin is needed to start a native app. Required by cozy-bar"));
-                return;
-              }
+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; }
 
-              startAppPlugin.set(params).start(resolve, reject);
-            }));
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-          case 9:
-            return _context.abrupt("return", false);
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-          case 10:
-          case "end":
-            return _context.stop();
-        }
-      }
-    }, _callee);
-  }));
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-  return function (_x) {
-    return _ref2.apply(this, arguments);
-  };
-}();
-/**
- * Check that an application is installed on the phone
- * @returns Promise - Promise containing information on the application
- *
- * @example
- * > checkApp({ appId: 'io.cozy.drive.mobile', uri: 'cozydrive://' })
- * Promise.resolve({
- *  versionName: "0.9.2",
- *  packageName: "io.cozy.drive.mobile",
- *  versionCode: 902,
- *  applicationInfo: "ApplicationInfo{70aa0ef io.cozy.drive.mobile}"
- * })
- */
+var HasOne = /*#__PURE__*/function (_Association) {
+  (0, _inherits2.default)(HasOne, _Association);
 
+  var _super = _createSuper(HasOne);
 
-exports.startApp = startApp;
+  function HasOne() {
+    (0, _classCallCheck2.default)(this, HasOne);
+    return _super.apply(this, arguments);
+  }
 
-var checkApp = exported.checkApp = /*#__PURE__*/function () {
-  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appInfo) {
-    var startAppPlugin, params;
-    return _regenerator.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            startAppPlugin = window.startApp;
-            params = getParams(appInfo);
-            return _context2.abrupt("return", new Promise(function (resolve, reject) {
-              if (!cordovaPluginIsInstalled()) {
-                reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed."));
-                return;
-              }
+  (0, _createClass2.default)(HasOne, [{
+    key: "add",
 
-              startAppPlugin.set(params).check(function (infos) {
-                resolve(infos === 'OK' ? true : infos);
-              }, function (error) {
-                if (error === false || error.indexOf('NameNotFoundException') === 0) {
-                  // Plugin returns an error 'NameNotFoundException' on Android and
-                  // false on iOS when an application is not found.
-                  // We prefer to always return false
-                  resolve(false);
-                } else {
-                  reject(error);
-                }
-              });
-            }));
+    /**
+     * Add the relationship to the target document
+     *
+     * @param {CozyClientDocument} doc - Document to add as a relationship
+     * @returns {CozyClientDocument} The saved target document
+     */
+    value: function add(doc) {
+      this.setRelationship(doc);
+      return this.save(this.target);
+    }
+    /**
+     * Remove the relationship from the target document
+     *
+     * @returns {CozyClientDocument} The saved target document
+     */
 
-          case 3:
-          case "end":
-            return _context2.stop();
-        }
+  }, {
+    key: "remove",
+    value: function remove() {
+      this.setRelationship(undefined);
+      return this.save(this.target);
+    }
+  }, {
+    key: "setRelationship",
+    value: function setRelationship(doc) {
+      if (doc && doc._type !== this.doctype) {
+        throw new Error("Tried to associate a ".concat(doc._type, " document to a HasOne relationship on ").concat(this.doctype, " document"));
       }
-    }, _callee2);
-  }));
-
-  return function (_x2) {
-    return _ref3.apply(this, arguments);
-  };
-}();
-
-exports.checkApp = checkApp;
-var _default = exported;
-exports["default"] = _default;
-
-/***/ }),
-/* 772 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.nativeLinkOpen = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _plugins = __webpack_require__(770);
-
-var nativeLinkOpen = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
-    var url, target, options;
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            url = _ref.url;
-            _context.next = 3;
-            return (0, _plugins.hasSafariPlugin)();
-
-          case 3:
-            _context.t0 = _context.sent;
 
-            if (!_context.t0) {
-              _context.next = 6;
-              break;
-            }
+      var path = "relationships[".concat(this.name, "].data");
 
-            _context.t0 = window.SafariViewController;
+      if (doc) {
+        (0, _set.default)(this.target, path, {
+          _id: doc._id,
+          _type: doc._type
+        });
+      } else {
+        (0, _set.default)(this.target, path, undefined);
+      }
+    }
+  }, {
+    key: "set",
+    value: function set(doc) {
+      console.warn('set is deprecated for has-one relationships. Use `add` instead.');
+      this.setRelationship(doc);
+    }
+  }, {
+    key: "unset",
+    value: function unset() {
+      console.warn('unset is deprecated for has-one relationships. Use `remove` instead.');
+      this.setRelationship(undefined);
+    }
+  }, {
+    key: "dehydrate",
+    value: function dehydrate(doc) {
+      if (!this.raw) {
+        return doc;
+      }
 
-          case 6:
-            if (!_context.t0) {
-              _context.next = 10;
-              break;
-            }
+      return _objectSpread(_objectSpread({}, doc), {}, {
+        relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, {
+          data: this.raw
+        }))
+      });
+    }
+  }, {
+    key: "raw",
+    get: function get() {
+      return (0, _get2.default)(this.target, "relationships[".concat(this.name, "].data"), null);
+    }
+  }, {
+    key: "data",
+    get: function get() {
+      if (!this.raw) {
+        return null;
+      }
 
-            window.SafariViewController.show({
-              url: url,
-              transition: 'curl'
-            }, function (result) {
-              if (result.event === 'closed') {
-                window.SafariViewController.hide();
-              }
-            }, function () {
-              window.SafariViewController.hide();
-            });
-            _context.next = 11;
-            break;
+      return this.get(this.doctype, this.raw._id);
+    }
+    /**
+     * @param {CozyClientDocument} document - Document to query
+     * @param {object} client - The CozyClient instance
+     * @param {Association} assoc - The query params
+     *
+     * @returns {CozyClientDocument | QueryDefinition}
+     */
 
-          case 10:
-            if ((0, _plugins.hasInAppBrowserPlugin)()) {
-              target = '_blank';
-              options = 'clearcache=yes,zoom=no';
-              window.cordova.InAppBrowser.open(url, target, options);
-            } else {
-              window.location = url;
-            }
+  }], [{
+    key: "query",
+    value: function query(document, client, assoc) {
+      var relationship = (0, _get2.default)(document, "relationships.".concat(assoc.name, ".data"), {});
 
-          case 11:
-          case "end":
-            return _context.stop();
-        }
+      if (!relationship || !relationship._id) {
+        return null;
       }
-    }, _callee);
-  }));
 
-  return function nativeLinkOpen(_x) {
-    return _ref2.apply(this, arguments);
-  };
-}();
+      return (0, _dsl.Q)(assoc.doctype).getById(relationship._id);
+    }
+  }]);
+  return HasOne;
+}(_Association2.default);
 
-exports.nativeLinkOpen = nativeLinkOpen;
+exports["default"] = HasOne;
 
 /***/ }),
-/* 773 */
-/***/ ((__unused_webpack_module, exports) => {
-
-"use strict";
-
+/* 763 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.openDeeplinkOrRedirect = void 0;
+var baseSet = __webpack_require__(662);
 
 /**
- * This file is used to open the native app from a webapp
- * if this native app is installed
+ * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
+ * it's created. Arrays are created for missing index properties while objects
+ * are created for all other missing properties. Use `_.setWith` to customize
+ * `path` creation.
  *
- * From a webapp, we don't have any clue if a native app is installed.
- * The only way to know that, is to try to open the custom link
- * (aka cozydrive://) and if nothing happens (no blur) we redirect to
- * the callback
+ * **Note:** This method mutates `object`.
  *
- * Firefox tries to open custom link, so we need to create an iframe
- * to detect if this is supported or not
- */
-var _createHiddenIframe = function _createHiddenIframe(target, uri, randomId) {
-  var iframe = document.createElement('iframe');
-  iframe.src = uri;
-  iframe.id = "hiddenIframe_".concat(randomId);
-  iframe.style.display = 'none';
-  target.appendChild(iframe);
-  return iframe;
-};
-
-var openUriWithHiddenFrame = function openUriWithHiddenFrame(uri, failCb) {
-  var randomId = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
-  window.addEventListener('blur', onBlur);
-
-  var iframe = _createHiddenIframe(document.body, 'about:blank', randomId);
-
-  var timeout = setTimeout(function () {
-    failCb();
-    window.removeEventListener('blur', onBlur);
-    iframe.parentElement.removeChild(iframe);
-  }, 500);
-
-  function onBlur() {
-    clearTimeout(timeout);
-    window.removeEventListener('blur', onBlur);
-    iframe.parentElement.removeChild(iframe);
-  }
-
-  iframe.contentWindow.location.href = uri;
-};
-
-var openUriWithTimeoutHack = function openUriWithTimeoutHack(uri, failCb) {
-  var timeout = setTimeout(function () {
-    failCb();
-    target.removeEventListener('blur', onBlur);
-  }, 500); // handle page running in an iframe (blur must be registered with top level window)
-
-  var target = window;
-
-  while (target != target.parent) {
-    target = target.parent;
-  }
-
-  target.addEventListener('blur', onBlur);
-
-  function onBlur() {
-    clearTimeout(timeout);
-    target.removeEventListener('blur', onBlur);
-  }
-
-  window.location = uri;
-};
-
-var openUriWithMsLaunchUri = function openUriWithMsLaunchUri(uri, failCb) {
-  navigator.msLaunchUri(uri, undefined, failCb);
-};
-
-var checkBrowser = function checkBrowser() {
-  var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
-  var ua = navigator.userAgent.toLowerCase();
-  var isSafari = ua.includes('safari') && !ua.includes('chrome') || Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
-  var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
-  var isIOS122 = isIOS && (ua.includes('os 12_2') || ua.includes('os 12_3'));
-  return {
-    isOpera: isOpera,
-    isFirefox: typeof InstallTrigger !== 'undefined',
-    isSafari: isSafari,
-    isChrome: !!window.chrome && !isOpera,
-    isIOS122: isIOS122,
-    isIOS: isIOS
-  };
-};
-/**
+ * @static
+ * @memberOf _
+ * @since 3.7.0
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns `object`.
+ * @example
  *
- * @param {String} deeplink (cozydrive://)
- * @param {String} failCb (http://drive.cozy.ios)
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.set(object, 'a[0].b.c', 4);
+ * console.log(object.a[0].b.c);
+ * // => 4
+ *
+ * _.set(object, ['x', '0', 'y', 'z'], 5);
+ * console.log(object.x[0].y.z);
+ * // => 5
  */
+function set(object, path, value) {
+  return object == null ? object : baseSet(object, path, value);
+}
 
+module.exports = set;
 
-var openDeeplinkOrRedirect = function openDeeplinkOrRedirect(deeplink, failCb) {
-  if (navigator.msLaunchUri) {
-    // for IE and Edge in Win 8 and Win 10
-    openUriWithMsLaunchUri(deeplink, failCb);
-  } else {
-    var browser = checkBrowser();
-
-    if (browser.isChrome || browser.isIOS && !browser.isIOS122) {
-      openUriWithTimeoutHack(deeplink, failCb);
-    } else if (browser.isSafari && !browser.isIOS122 || browser.isFirefox) {
-      openUriWithHiddenFrame(deeplink, failCb);
-    } else {
-      failCb();
-    }
-  }
-};
-
-exports.openDeeplinkOrRedirect = openDeeplinkOrRedirect;
 
 /***/ }),
-/* 774 */
+/* 764 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = void 0;
-
-var _mapValues = _interopRequireDefault(__webpack_require__(533));
-
-var _groupBy2 = _interopRequireDefault(__webpack_require__(724));
-
-var _flatten = _interopRequireDefault(__webpack_require__(540));
-
-var _isEqual = _interopRequireDefault(__webpack_require__(646));
+exports.BelongsToInPlace = exports["default"] = void 0;
 
-var _uniq = _interopRequireDefault(__webpack_require__(612));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _uniqWith = _interopRequireDefault(__webpack_require__(775));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _dsl = __webpack_require__(607);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var isIdQuery = function isIdQuery(query) {
-  return query.id || query.ids;
-};
-/**
- * Optimize queries on a single doctype
- *
- * @param  {QueryDefinition[]} queries - Queries of a same doctype
- * @returns {QueryDefinition[]} Optimized queries
- * @private
- */
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var optimizeDoctypeQueries = function optimizeDoctypeQueries(queries) {
-  var _groupBy = (0, _groupBy2.default)(queries, function (q) {
-    return isIdQuery(q) ? 'idQueries' : 'others';
-  }),
-      _groupBy$idQueries = _groupBy.idQueries,
-      idQueries = _groupBy$idQueries === void 0 ? [] : _groupBy$idQueries,
-      _groupBy$others = _groupBy.others,
-      others = _groupBy$others === void 0 ? [] : _groupBy$others;
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-  var groupedIdQueries = idQueries.length > 0 ? new _dsl.QueryDefinition({
-    doctype: queries[0].doctype,
-    ids: (0, _uniq.default)((0, _flatten.default)(idQueries.map(function (q) {
-      return q.id || q.ids;
-    })))
-  }) : []; // Deduplicate before concataining
+var _Association2 = _interopRequireDefault(__webpack_require__(752));
 
-  return (0, _uniqWith.default)(others, _isEqual.default).concat(groupedIdQueries);
-};
-/**
- * Reduce the number of queries used to fetch documents.
- *
- * - Deduplication of queries
- * - Groups id queries
- *
- * @param  {QueryDefinition[]} queries - Queries to optimized
- * @returns {QueryDefinition[]} Optimized queries
- * @private
- */
+var _dsl = __webpack_require__(619);
 
+var _types = __webpack_require__(622);
 
-var optimizeQueries = function optimizeQueries(queries) {
-  var byDoctype = (0, _groupBy2.default)(queries, function (q) {
-    return q.doctype;
-  });
-  return (0, _flatten.default)(Object.values((0, _mapValues.default)(byDoctype, optimizeDoctypeQueries)));
-};
+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; }
 
-var _default = optimizeQueries;
-exports["default"] = _default;
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-/***/ }),
-/* 775 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-var baseUniq = __webpack_require__(463);
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
 /**
- * This method is like `_.uniq` except that it accepts `comparator` which
- * is invoked to compare elements of `array`. The order of result values is
- * determined by the order they occur in the array.The comparator is invoked
- * with two arguments: (arrVal, othVal).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Array
- * @param {Array} array The array to inspect.
- * @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns the new duplicate free array.
- * @example
- *
- * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
- *
- * _.uniqWith(objects, _.isEqual);
- * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
+ * Here the id of the document is directly set in the attribute
+ * of the document, not in the relationships attribute
  */
-function uniqWith(array, comparator) {
-  comparator = typeof comparator == 'function' ? comparator : undefined;
-  return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
-}
-
-module.exports = uniqWith;
-
-
-/***/ }),
-/* 776 */
-/***/ ((__unused_webpack_module, exports) => {
+var HasOneInPlace = /*#__PURE__*/function (_Association) {
+  (0, _inherits2.default)(HasOneInPlace, _Association);
 
-"use strict";
+  var _super = _createSuper(HasOneInPlace);
 
+  function HasOneInPlace() {
+    (0, _classCallCheck2.default)(this, HasOneInPlace);
+    return _super.apply(this, arguments);
+  }
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
+  (0, _createClass2.default)(HasOneInPlace, [{
+    key: "dehydrate",
+    value: function dehydrate(doc) {
+      return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || undefined));
+    }
+  }, {
+    key: "raw",
+    get: function get() {
+      return this.target[this.name];
+    }
+  }, {
+    key: "data",
+    get: function get() {
+      return this.get(this.doctype, this.raw);
+    }
+    /**
+     * @param {CozyClientDocument} document - Document to query
+     * @param {object} client - The CozyClient instance
+     * @param {Association} assoc - The query params
+     *
+     * @returns {CozyClientDocument | QueryDefinition}
+     */
 
-/**
- * Use those fetch policies with `<Query />` to limit the number of re-fetch.
- *
- * @example
- * ```
- * import { fetchPolicies } from 'cozy-client'
- * const olderThan30s = fetchPolicies.olderThan(30 * 1000)
- * <Query fetchPolicy={olderThan30s} />
- * ```
- */
-var fetchPolicies = {
-  /**
-   * Returns a fetchPolicy that will only re-fetch queries that are older
-   * than `<delay>` ms.
-   *
-   * @param  {number} delay - Milliseconds since the query has been fetched
-   * @returns {Function} Fetch policy to be used with `<Query />`
-   */
-  olderThan: function olderThan(delay) {
-    return function (queryState) {
-      if (!queryState || !queryState.lastUpdate) {
-        return true;
-      } else {
-        var elapsed = Date.now() - queryState.lastUpdate;
-        return elapsed > delay;
-      }
-    };
-  },
+  }], [{
+    key: "query",
+    value: function query(document, client, assoc) {
+      var id = document[assoc.name];
+      return client.getDocumentFromState(assoc.doctype, id) || (0, _dsl.Q)(assoc.doctype).getById(id);
+    }
+  }]);
+  return HasOneInPlace;
+}(_Association2.default);
 
-  /**
-   * Fetch policy that deactivates any fetching.
-   */
-  noFetch: function noFetch() {
-    return false;
-  }
-};
-var _default = fetchPolicies;
-exports["default"] = _default;
+exports["default"] = HasOneInPlace;
+var BelongsToInPlace = HasOneInPlace;
+exports.BelongsToInPlace = BelongsToInPlace;
 
 /***/ }),
-/* 777 */
+/* 765 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports["default"] = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _keyBy = _interopRequireDefault(__webpack_require__(699));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-var _mapValues = _interopRequireDefault(__webpack_require__(533));
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-var _merge = _interopRequireDefault(__webpack_require__(742));
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-var _size = _interopRequireDefault(__webpack_require__(778));
+var _dsl = __webpack_require__(619);
 
-var _intersectionBy = _interopRequireDefault(__webpack_require__(782));
+var _types = __webpack_require__(622);
 
-var _associations = __webpack_require__(691);
+var _Association2 = _interopRequireDefault(__webpack_require__(752));
 
 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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-/**
- * @typedef {object} DoctypeSchema
- */
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-/**
- * @typedef {Record<string, DoctypeSchema>} SchemaDefinition
- */
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
 /**
- * Returns a normalized schema object from the schema definition.
  *
- * - Relationships are resolved to classes if needed
- * - The name of the relationship (its key in the schema definition)
- *   is included in the relationship
- * - Empty relationships are nulled
+ * Used when related documents are stored directly under the attribute with
+ * only the ids.
  *
- * @private
- */
-var normalizeDoctypeSchema = function normalizeDoctypeSchema(doctypeSchema) {
-  var relationships = (0, _mapValues.default)(doctypeSchema.relationships || {}, function (v, k) {
-    return _objectSpread(_objectSpread({}, v), {}, {
-      name: k,
-      type: (0, _associations.resolveClass)(v.doctype, v.type)
-    });
-  });
-  return _objectSpread(_objectSpread({}, doctypeSchema), {}, {
-    relationships: (0, _size.default)(relationships) > 0 ? (0, _keyBy.default)(relationships, 'name') : null
-  });
-};
-
-var assert = function assert(predicate, errorMessage) {
-  if (!predicate) throw new Error(errorMessage);
-};
-
-var ensureCanBeAdded = function ensureCanBeAdded(newSchemas, existingSchemas) {
-  var sameNames = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) {
-    return x.name;
-  });
-  assert(sameNames.length === 0, "Duplicated names in schemas being added: ".concat(sameNames.map(function (x) {
-    return x.name;
-  }).join(', ')));
-  var sameDoctypes = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) {
-    return x.doctype;
-  });
-  assert(sameDoctypes.length === 0, "Duplicated doctypes in schemas being added: ".concat(sameDoctypes.map(function (x) {
-    return x.name;
-  }).join(', ')));
-};
-/**
- * Stores information on a particular doctype.
+ * @property {Function} get
  *
- * - Attribute validation
- * - Relationship access
+ * @description
+ *
+ * An example document representing a TODO. See as the related
+ * tasks are represented via ids.
  *
  * ```js
- * const schema = new Schema({
+ * const todo = {
+ *   label: "Protect people's privacy",
+ *   tasks: [1, 2]
+ * }
+ * ```
+ *
+ * Here is the `Schema` that would represent this kind of document.
+ * Components receiving todos via `Query`s would have an instance of `HasManyInPlace`
+ * as their `tasks` attribute.
+ *
+ * ```js
+ * const schema = {
  *   todos: {
- *     attributes: {
- *       label: {
- *         unique: true
- *       }
- *     },
- *     relationships: {
- *       author: 'has-one-in-place'
- *     }
- *   }
- * }, cozyStackClient)
+ *      doctype: 'io.cozy.todos',
+ *      relationships: {
+ *        tasks: {
+ *          doctype: 'io.cozy.tasks',
+ *          type: 'has-many-in-place'
+ *        }
+ *      }
+ *    }
+ * }
+ *
+ * const todo = {
+ *   label: "Get rich",
+ *   tasks: [1, 2]
+ * }
  * ```
+ *
  */
+var HasManyInPlace = /*#__PURE__*/function (_Association) {
+  (0, _inherits2.default)(HasManyInPlace, _Association);
 
+  var _super = _createSuper(HasManyInPlace);
 
-var Schema = /*#__PURE__*/function () {
-  /**
-   * @param  {SchemaDefinition} schemaDefinition - Schema for the application documents
-   * @param  {object} client - An instance of cozy client (optional)
-   */
-  function Schema() {
-    var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-    var client = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
-    (0, _classCallCheck2.default)(this, Schema);
-    this.byDoctype = {};
-    this.add(schemaDefinition);
-    this.client = client;
+  function HasManyInPlace() {
+    (0, _classCallCheck2.default)(this, HasManyInPlace);
+    return _super.apply(this, arguments);
   }
-  /**
-   * @param {SchemaDefinition} schemaDefinition - Additional schema to merge to current schema
-   */
 
+  (0, _createClass2.default)(HasManyInPlace, [{
+    key: "addById",
+    value: function addById(id) {
+      var rel = this.getRelationship();
+      rel.push(id);
+    }
+  }, {
+    key: "removeById",
+    value: function removeById(id) {
+      var rel = this.getRelationship();
+      var index = rel.indexOf(id);
 
-  (0, _createClass2.default)(Schema, [{
-    key: "add",
-    value: function add() {
-      var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-      var normalizedSchemaDefinition = (0, _mapValues.default)(schemaDefinition, function (obj, name) {
-        return _objectSpread({
-          name: name
-        }, normalizeDoctypeSchema(obj));
-      });
-      ensureCanBeAdded(Object.values(normalizedSchemaDefinition), Object.values(this.byDoctype));
-      (0, _merge.default)(this.byDoctype, (0, _keyBy.default)(normalizedSchemaDefinition, function (x) {
-        return x.doctype;
-      }));
+      if (index !== -1) {
+        rel.splice(index, 1);
+      }
+    }
+  }, {
+    key: "existsById",
+    value: function existsById(id) {
+      var rel = this.getRelationship();
+      return rel.indexOf(id) !== -1;
+    }
+  }, {
+    key: "getRelationship",
+    value: function getRelationship() {
+      this.target[this.name] = this.target[this.name] || [];
+      return this.target[this.name];
+    }
+  }, {
+    key: "dehydrate",
+    value: function dehydrate(doc) {
+      return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || []));
     }
+  }, {
+    key: "raw",
+
     /**
-     * Returns the schema for a doctype
-     *
-     * Creates an empty schema implicitly if it does not exist
+     * Raw property
      *
-     * @param {string} doctype - Doctype
+     * @type {Array<string>}
      */
-
+    get: function get() {
+      return this.target[this.name];
+    }
   }, {
-    key: "getDoctypeSchema",
-    value: function getDoctypeSchema(doctype) {
-      var schema = this.byDoctype[doctype];
-
-      if (!schema) {
-        schema = normalizeDoctypeSchema({
-          name: doctype,
-          doctype: doctype
-        });
-        this.byDoctype[doctype] = schema;
-      }
+    key: "data",
+    get: function get() {
+      var _this = this;
 
-      return schema;
+      var doctype = this.doctype;
+      return (this.raw || []).map(function (_id) {
+        return _this.get(doctype, _id);
+      });
     }
     /**
-     * Returns the relationship for a given doctype/name
+     * @param {CozyClientDocument} document - Document to query
+     * @param {object} client - The CozyClient instance
+     * @param {Association} assoc - The query params
      *
-     * @param {string} doctype - Doctype
-     * @param {string} relationshipName - Relationship name
+     * @returns {CozyClientDocument | QueryDefinition}
      */
 
-  }, {
-    key: "getRelationship",
-    value: function getRelationship(doctype, relationshipName) {
-      if (!doctype) {
-        throw new TypeError("Invalid doctype ".concat(doctype));
-      }
-
-      var schema = this.getDoctypeSchema(doctype);
-
-      if (!schema) {
-        throw new Error("Cannot find doctype ".concat(doctype, " in schema"));
-      }
+  }], [{
+    key: "query",
+    value: function query(document, client, assoc) {
+      var ids = document[assoc.name];
 
-      if (!schema.relationships) {
-        throw new Error("Schema for doctype ".concat(doctype, " has no relationships"));
+      if (ids && ids > 0) {
+        return (0, _dsl.Q)(assoc.doctype).getByIds(ids);
+      } else {
+        return null;
       }
-
-      return schema.relationships[relationshipName];
     }
-    /**
-     * Validates a document considering the descriptions in schema.attributes.
-     */
+  }]);
+  return HasManyInPlace;
+}(_Association2.default);
 
-  }, {
-    key: "validate",
-    value: function () {
-      var _validate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(document) {
-        var errors, schema, n, ret;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                errors = {};
-                schema = this.byDoctype[document._type];
+var _default = HasManyInPlace;
+exports["default"] = _default;
 
-                if (schema) {
-                  _context.next = 4;
-                  break;
-                }
+/***/ }),
+/* 766 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-                return _context.abrupt("return", true);
+"use strict";
 
-              case 4:
-                if (schema.attributes) {
-                  _context.next = 6;
-                  break;
-                }
 
-                return _context.abrupt("return", true);
+var _interopRequireDefault = __webpack_require__(524);
 
-              case 6:
-                _context.t0 = _regenerator.default.keys(schema.attributes);
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-              case 7:
-                if ((_context.t1 = _context.t0()).done) {
-                  _context.next = 15;
-                  break;
-                }
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-                n = _context.t1.value;
-                _context.next = 11;
-                return this.validateAttribute(document, n, schema.attributes[n]);
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-              case 11:
-                ret = _context.sent;
-                if (ret !== true) errors[n] = ret;
-                _context.next = 7;
-                break;
+var _get2 = _interopRequireDefault(__webpack_require__(682));
 
-              case 15:
-                if (!(Object.keys(errors).length === 0)) {
-                  _context.next = 17;
-                  break;
-                }
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-                return _context.abrupt("return", true);
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-              case 17:
-                return _context.abrupt("return", errors);
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-              case 18:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this);
-      }));
+var _HasMany2 = _interopRequireDefault(__webpack_require__(753));
 
-      function validate(_x) {
-        return _validate.apply(this, arguments);
-      }
+var _dsl = __webpack_require__(619);
 
-      return validate;
-    }()
-  }, {
-    key: "validateAttribute",
-    value: function () {
-      var _validateAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(document, attrName, attrProps) {
-        var ret;
-        return _regenerator.default.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                if (!(attrProps.unique && this.client)) {
-                  _context2.next = 6;
-                  break;
-                }
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-                _context2.next = 3;
-                return this.client.collection(document._type).checkUniquenessOf(attrName, document[attrName]);
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-              case 3:
-                ret = _context2.sent;
+var TRIGGERS_DOCTYPE = 'io.cozy.triggers';
+/**
+ * Association used for konnectors to retrieve all their related triggers.
+ *
+ * @augments HasMany
+ */
 
-                if (!(ret !== true)) {
-                  _context2.next = 6;
-                  break;
-                }
+var HasManyTriggers = /*#__PURE__*/function (_HasMany) {
+  (0, _inherits2.default)(HasManyTriggers, _HasMany);
 
-                return _context2.abrupt("return", 'must be unique');
+  var _super = _createSuper(HasManyTriggers);
 
-              case 6:
-                return _context2.abrupt("return", true);
+  function HasManyTriggers() {
+    (0, _classCallCheck2.default)(this, HasManyTriggers);
+    return _super.apply(this, arguments);
+  }
 
-              case 7:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2, this);
-      }));
+  (0, _createClass2.default)(HasManyTriggers, [{
+    key: "data",
+    get: function get() {
+      var _this = this;
 
-      function validateAttribute(_x2, _x3, _x4) {
-        return _validateAttribute.apply(this, arguments);
-      }
+      return (0, _get2.default)((0, _getPrototypeOf2.default)(HasManyTriggers.prototype), "data", this).filter(function (_ref) {
+        var slug = _ref.slug;
+        return slug === _this.target.slug;
+      });
+    }
+    /**
+     * In this association the query is special, we need to fetch all the triggers
+     * having for the 'konnector' worker, and then filter them based on their
+     * `message.konnector` attribute
+     */
 
-      return validateAttribute;
-    }()
+  }], [{
+    key: "query",
+    value: function query(doc, client) {
+      return (0, _dsl.Q)(TRIGGERS_DOCTYPE).where({
+        worker: 'konnector'
+      });
+    }
   }]);
-  return Schema;
-}();
+  return HasManyTriggers;
+}(_HasMany2.default);
 
-var _default = Schema;
+var _default = HasManyTriggers;
 exports["default"] = _default;
 
 /***/ }),
-/* 778 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var baseKeys = __webpack_require__(442),
-    getTag = __webpack_require__(447),
-    isArrayLike = __webpack_require__(446),
-    isString = __webpack_require__(54),
-    stringSize = __webpack_require__(779);
-
-/** `Object#toString` result references. */
-var mapTag = '[object Map]',
-    setTag = '[object Set]';
+/* 767 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-/**
- * Gets the size of `collection` by returning its length for array-like
- * values or the number of own enumerable string keyed properties for objects.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Collection
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns the collection size.
- * @example
- *
- * _.size([1, 2, 3]);
- * // => 3
- *
- * _.size({ 'a': 1, 'b': 2 });
- * // => 2
- *
- * _.size('pebbles');
- * // => 7
- */
-function size(collection) {
-  if (collection == null) {
-    return 0;
-  }
-  if (isArrayLike(collection)) {
-    return isString(collection) ? stringSize(collection) : collection.length;
-  }
-  var tag = getTag(collection);
-  if (tag == mapTag || tag == setTag) {
-    return collection.size;
-  }
-  return baseKeys(collection).length;
-}
+"use strict";
 
-module.exports = size;
 
+var _interopRequireDefault = __webpack_require__(524);
 
-/***/ }),
-/* 779 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getReferencedById = exports.getReferencedBy = exports.isReferencedById = exports.isReferencedBy = exports.create = exports.resolveClass = exports.attachRelationships = exports.responseToRelationship = exports.pickTypeAndId = void 0;
 
-var asciiSize = __webpack_require__(780),
-    hasUnicode = __webpack_require__(766),
-    unicodeSize = __webpack_require__(781);
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-/**
- * Gets the number of symbols in `string`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @returns {number} Returns the string size.
- */
-function stringSize(string) {
-  return hasUnicode(string)
-    ? unicodeSize(string)
-    : asciiSize(string);
-}
+var _pick = _interopRequireDefault(__webpack_require__(676));
 
-module.exports = stringSize;
+var _pickBy = _interopRequireDefault(__webpack_require__(660));
 
+var _Association = _interopRequireDefault(__webpack_require__(752));
 
-/***/ }),
-/* 780 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _HasOne = _interopRequireDefault(__webpack_require__(762));
 
-var baseProperty = __webpack_require__(461);
+var _HasOneInPlace = _interopRequireDefault(__webpack_require__(764));
 
-/**
- * Gets the size of an ASCII `string`.
- *
- * @private
- * @param {string} string The string inspect.
- * @returns {number} Returns the string size.
- */
-var asciiSize = baseProperty('length');
+var _HasMany = _interopRequireDefault(__webpack_require__(753));
 
-module.exports = asciiSize;
+var _HasManyInPlace = _interopRequireDefault(__webpack_require__(765));
 
+var _HasManyFiles = _interopRequireDefault(__webpack_require__(704));
 
-/***/ }),
-/* 781 */
-/***/ ((module) => {
+var _types = __webpack_require__(622);
 
-/** Used to compose unicode character classes. */
-var rsAstralRange = '\\ud800-\\udfff',
-    rsComboMarksRange = '\\u0300-\\u036f',
-    reComboHalfMarksRange = '\\ufe20-\\ufe2f',
-    rsComboSymbolsRange = '\\u20d0-\\u20ff',
-    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
-    rsVarRange = '\\ufe0e\\ufe0f';
+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; }
 
-/** Used to compose unicode capture groups. */
-var rsAstral = '[' + rsAstralRange + ']',
-    rsCombo = '[' + rsComboRange + ']',
-    rsFitz = '\\ud83c[\\udffb-\\udfff]',
-    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
-    rsNonAstral = '[^' + rsAstralRange + ']',
-    rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
-    rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
-    rsZWJ = '\\u200d';
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-/** Used to compose unicode regexes. */
-var reOptMod = rsModifier + '?',
-    rsOptVar = '[' + rsVarRange + ']?',
-    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
-    rsSeq = rsOptVar + reOptMod + rsOptJoin,
-    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+var pickTypeAndId = function pickTypeAndId(x) {
+  return (0, _pick.default)(x, '_type', '_id');
+};
 
-/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
-var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+exports.pickTypeAndId = pickTypeAndId;
 
-/**
- * Gets the size of a Unicode `string`.
- *
- * @private
- * @param {string} string The string inspect.
- * @returns {number} Returns the string size.
- */
-function unicodeSize(string) {
-  var result = reUnicode.lastIndex = 0;
-  while (reUnicode.test(string)) {
-    ++result;
-  }
-  return result;
-}
+var applyHelper = function applyHelper(fn, objOrArr) {
+  return Array.isArray(objOrArr) ? objOrArr.map(fn) : fn(objOrArr);
+};
 
-module.exports = unicodeSize;
+var responseToRelationship = function responseToRelationship(response) {
+  return (0, _pickBy.default)({
+    data: applyHelper(pickTypeAndId, response.data),
+    meta: response.meta,
+    next: response.next,
+    skip: response.skip,
+    bookmark: response.bookmark
+  });
+};
 
+exports.responseToRelationship = responseToRelationship;
 
-/***/ }),
-/* 782 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var attachRelationship = function attachRelationship(doc, relationships) {
+  return _objectSpread(_objectSpread({}, doc), {}, {
+    relationships: _objectSpread(_objectSpread({}, doc.relationships), relationships)
+  });
+};
 
-var arrayMap = __webpack_require__(398),
-    baseIntersection = __webpack_require__(728),
-    baseIteratee = __webpack_require__(401),
-    baseRest = __webpack_require__(544),
-    castArrayLikeObject = __webpack_require__(729),
-    last = __webpack_require__(615);
+var attachRelationships = function attachRelationships(response, relationshipsByDocId) {
+  if (Array.isArray(response.data)) {
+    return _objectSpread(_objectSpread({}, response), {}, {
+      data: response.data.map(function (doc) {
+        return attachRelationship(doc, relationshipsByDocId[doc._id]);
+      })
+    });
+  } else {
+    var doc = response.data;
+    return _objectSpread(_objectSpread({}, response), {}, {
+      data: attachRelationship(doc, relationshipsByDocId[doc._id])
+    });
+  }
+};
 
+exports.attachRelationships = attachRelationships;
+var aliases = {
+  'io.cozy.files:has-many': _HasManyFiles.default,
+  'has-many': _HasMany.default,
+  'belongs-to-in-place': _HasOneInPlace.default,
+  'has-one': _HasOne.default,
+  'has-one-in-place': _HasOneInPlace.default,
+  'has-many-in-place': _HasManyInPlace.default
+};
 /**
- * This method is like `_.intersection` except that it accepts `iteratee`
- * which is invoked for each element of each `arrays` to generate the criterion
- * by which they're compared. The order and references of result values are
- * determined by the first array. The iteratee is invoked with one argument:
- * (value).
+ * Returns the relationship class for a given doctype/type.
  *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Array
- * @param {...Array} [arrays] The arrays to inspect.
- * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
- * @returns {Array} Returns the new array of intersecting values.
- * @example
+ * In the schema definition, some classes have string aliases
+ * so you do not have to import directly the association.
  *
- * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
- * // => [2.1]
+ * Some doctypes can have built-in overriden relationships.
  *
- * // The `_.property` iteratee shorthand.
- * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }]
+ * @private
  */
-var intersectionBy = baseRest(function(arrays) {
-  var iteratee = last(arrays),
-      mapped = arrayMap(arrays, castArrayLikeObject);
 
-  if (iteratee === last(mapped)) {
-    iteratee = undefined;
-  } else {
-    mapped.pop();
+var resolveClass = function resolveClass(doctype, type) {
+  if (type === undefined) {
+    throw new Error('Undefined type for ' + doctype);
   }
-  return (mapped.length && mapped[0] === arrays[0])
-    ? baseIntersection(mapped, baseIteratee(iteratee, 2))
-    : [];
-});
-
-module.exports = intersectionBy;
-
-
-/***/ }),
-/* 783 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports["default"] = void 0;
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+  if (typeof type !== 'string') {
+    return type;
+  } else {
+    var qualified = "".concat(doctype, ":").concat(type);
+    var cls = aliases[qualified] || aliases[type];
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+    if (!cls) {
+      throw new Error("Unknown association '".concat(type, "'"));
+    } else {
+      return cls;
+    }
+  }
+};
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+exports.resolveClass = resolveClass;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var create = function create(target, _ref, accessors) {
+  var name = _ref.name,
+      type = _ref.type,
+      doctype = _ref.doctype;
 
-var _store = __webpack_require__(693);
+  if (target[name] instanceof _Association.default) {
+    throw new Error("Association ".concat(name, " already exists"));
+  }
 
+  return new type(target, name, doctype, accessors);
+};
 /**
- * ObservableQueries are the glue between the store and observers
- * of the store. They have the responsibility to hydrate the documents
- * before passing them to the React component.
+ * Checks if the file is referenced by a specific doctype
+ *
+ * @param {IOCozyFile} file - io.cozy.files document
+ * @param {Doctype} referencedBy - Doctype where document is referenced
+ * @returns {boolean} If a reference is found
  */
-var hasOwn = Object.prototype.hasOwnProperty;
-
-var ObservableQuery = /*#__PURE__*/function () {
-  function ObservableQuery(queryId, definition, client, options) {
-    var _this = this;
-
-    (0, _classCallCheck2.default)(this, ObservableQuery);
-    (0, _defineProperty2.default)(this, "handleStoreChange", function () {
-      var nextResult = _this.currentRawResult();
-
-      if (!shallowEqual(nextResult, _this.lastResult)) {
-        _this.lastResult = nextResult;
-
-        _this.notifyObservers();
-      }
-    });
-
-    if (!queryId || !definition || !client) {
-      throw new Error('ObservableQuery takes 3 arguments: queryId, definition and client');
-    }
-
-    this.queryId = queryId;
-    this.definition = definition;
-    this.client = client;
-    this.observers = {};
-    this.idCounter = 1;
-    this.lastResult = this.currentRawResult();
-    this.options = options;
-  }
-
-  (0, _createClass2.default)(ObservableQuery, [{
-    key: "currentResult",
 
-    /**
-     * Returns the query from the store with hydrated documents.
-     *
-     * @typedef {object} HydratedQueryState
-     *
-     * @returns {HydratedQueryState}
-     */
-    value: function currentResult() {
-      return this.client.getQueryFromState(this.queryId, {
-        hydrated: (0, _get.default)(this.options, 'hydrated', true),
-        singleDocData: true
-      });
-    }
-  }, {
-    key: "fetch",
-    value: function fetch() {
-      return this.client.query(this.definition, {
-        as: this.queryId
-      });
-    }
-    /**
-     * Generates and executes a query that is offsetted by the number of documents
-     * we have in the store.
-     */
 
-  }, {
-    key: "fetchMore",
-    value: function fetchMore() {
-      var rawResult = this.currentRawResult();
-      return rawResult.bookmark ? this.client.query(this.definition.offsetBookmark(rawResult.bookmark), {
-        as: this.queryId
-      }) : this.client.query(this.definition.offset(rawResult.data.length), {
-        as: this.queryId
-      });
-    }
-  }, {
-    key: "currentRawResult",
-    value: function currentRawResult() {
-      return (0, _store.getRawQueryFromState)(this.getStore().getState(), this.queryId);
-    }
-  }, {
-    key: "notifyObservers",
-    value: function notifyObservers() {
-      var _this2 = this;
+exports.create = create;
 
-      Object.keys(this.observers).forEach(function (id) {
-        return _this2.observers[id]();
-      });
-    }
-  }, {
-    key: "subscribeToStore",
-    value: function subscribeToStore() {
-      if (this._unsubscribeStore) {
-        throw new Error('ObservableQuery instance is already subscribed to store.');
-      }
+var isReferencedBy = function isReferencedBy(file, referencedBy) {
+  var _file$relationships, _file$relationships$r;
 
-      this._unsubscribeStore = this.getStore().subscribe(this.handleStoreChange);
-    }
-  }, {
-    key: "unsubscribeFromStore",
-    value: function unsubscribeFromStore() {
-      if (!this._unsubscribeStore) {
-        throw new Error('ObservableQuery instance is not subscribed to store');
-      }
+  var references = (file === null || file === void 0 ? void 0 : (_file$relationships = file.relationships) === null || _file$relationships === void 0 ? void 0 : (_file$relationships$r = _file$relationships.referenced_by) === null || _file$relationships$r === void 0 ? void 0 : _file$relationships$r.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
+  return references.some(function (reference) {
+    return reference.type === referencedBy;
+  });
+};
+/**
+ * Checks if the file is referenced by a specific doctype and a specific Id of that reference
+ *
+ * @param {IOCozyFile} file - io.cozy.files document
+ * @param {Doctype} referencedBy - Doctype where document is referenced
+ * @param {string} referencedId - Id of the referenced document
+ * @returns {boolean} If a reference is found
+ */
 
-      this._unsubscribeStore();
-    }
-  }, {
-    key: "subscribe",
-    value: function subscribe(callback) {
-      var _this3 = this;
 
-      var callbackId = this.idCounter;
-      this.idCounter++;
-      this.observers[callbackId] = callback;
+exports.isReferencedBy = isReferencedBy;
 
-      if (Object.keys(this.observers).length === 1) {
-        this.subscribeToStore();
-      }
+var isReferencedById = function isReferencedById(file, referencedBy, referencedId) {
+  var _file$relationships2, _file$relationships2$;
 
-      return function () {
-        return _this3.unsubscribe(callbackId);
-      };
-    }
-  }, {
-    key: "unsubscribe",
-    value: function unsubscribe(callbackId) {
-      if (!this.observers[callbackId]) {
-        throw new Error("Cannot unsubscribe unknown callbackId ".concat(callbackId));
-      }
+  var references = (file === null || file === void 0 ? void 0 : (_file$relationships2 = file.relationships) === null || _file$relationships2 === void 0 ? void 0 : (_file$relationships2$ = _file$relationships2.referenced_by) === null || _file$relationships2$ === void 0 ? void 0 : _file$relationships2$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
+  return references.some(function (reference) {
+    return reference.type === referencedBy && reference.id === referencedId;
+  });
+};
+/**
+ * Get array of reference by an specific doctype
+ *
+ * @param {IOCozyFile} file - io.cozy.files document
+ * @param {Doctype} referencedBy - Doctype where document is referenced
+ * @returns {Reference[]} Array of references found
+ */
 
-      delete this.observers[callbackId];
 
-      if (Object.keys(this.observers).length === 0) {
-        this.unsubscribeFromStore();
-        this._unsubscribeStore = null;
-      }
-    }
-  }, {
-    key: "getStore",
-    value: function getStore() {
-      return this.client.store;
-    }
-  }]);
-  return ObservableQuery;
-}();
+exports.isReferencedById = isReferencedById;
 
-exports["default"] = ObservableQuery;
+var getReferencedBy = function getReferencedBy(file, referencedBy) {
+  var _file$relationships3, _file$relationships3$;
 
-function is(x, y) {
-  if (x === y) {
-    return x !== 0 || y !== 0 || 1 / x === 1 / y;
-  } else {
-    return x !== x && y !== y;
-  }
-}
+  var references = (file === null || file === void 0 ? void 0 : (_file$relationships3 = file.relationships) === null || _file$relationships3 === void 0 ? void 0 : (_file$relationships3$ = _file$relationships3.referenced_by) === null || _file$relationships3$ === void 0 ? void 0 : _file$relationships3$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
+  return references.filter(function (reference) {
+    return reference.type === referencedBy;
+  });
+};
+/**
+ * Get array of reference by an specific doctype and a specific Id of that reference
+ *
+ * @param {IOCozyFile} file - io.cozy.files document
+ * @param {Doctype} referencedBy - Doctype where document is referenced
+ * @param {string} referencedId - Id of the referenced document
+ * @returns {Reference[]} Array of the reference found
+ */
 
-function shallowEqual(objA, objB) {
-  if (is(objA, objB)) return true;
 
-  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
-    return false;
-  }
+exports.getReferencedBy = getReferencedBy;
 
-  var keysA = Object.keys(objA);
-  var keysB = Object.keys(objB);
-  if (keysA.length !== keysB.length) return false;
+var getReferencedById = function getReferencedById(file, referencedBy, referencedId) {
+  var _file$relationships4, _file$relationships4$;
 
-  for (var i = 0; i < keysA.length; i++) {
-    if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
-      return false;
-    }
-  }
+  var references = (file === null || file === void 0 ? void 0 : (_file$relationships4 = file.relationships) === null || _file$relationships4 === void 0 ? void 0 : (_file$relationships4$ = _file$relationships4.referenced_by) === null || _file$relationships4$ === void 0 ? void 0 : _file$relationships4$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || [];
+  return references.filter(function (reference) {
+    return reference.type === referencedBy && reference.id === referencedId;
+  });
+};
 
-  return true;
-}
+exports.getReferencedById = getReferencedById;
 
 /***/ }),
-/* 784 */
+/* 768 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.CozyClient = void 0;
+exports.rootCozyUrl = exports.InvalidCozyUrlError = exports.InvalidProtocolError = exports.generateWebLink = exports.dehydrate = void 0;
+
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
+
+var _toArray2 = _interopRequireDefault(__webpack_require__(526));
 
-var _inherits2 = _interopRequireDefault(__webpack_require__(591));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
+
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
+
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
+
+var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664));
+
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
+
+var _associations = __webpack_require__(703);
 
 function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
 function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-var SnapshotObject = function SnapshotObject(attrs) {
-  (0, _classCallCheck2.default)(this, SnapshotObject);
-  Object.assign(this, attrs);
+function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
+
+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; }
+
+var dehydrate = function dehydrate(document) {
+  var dehydrated = Object.entries(document).reduce(function (documentArg, _ref) {
+    var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
+        key = _ref2[0],
+        value = _ref2[1];
+
+    var document = documentArg;
+
+    if (!(value instanceof _associations.Association)) {
+      document[key] = value; // @ts-ignore
+    } else if (value.dehydrate) {
+      // @ts-ignore
+      document = value.dehydrate(document);
+    } else {
+      throw new Error("Association on key ".concat(key, " should have a dehydrate method"));
+    }
+
+    return document;
+  }, {});
+  return dehydrated;
 };
 
-var CozyClient = /*#__PURE__*/function (_SnapshotObject) {
-  (0, _inherits2.default)(CozyClient, _SnapshotObject);
+exports.dehydrate = dehydrate;
 
-  var _super = _createSuper(CozyClient);
+var ensureFirstSlash = function ensureFirstSlash(path) {
+  if (!path) {
+    return '/';
+  } else {
+    return path.startsWith('/') ? path : '/' + path;
+  }
+};
+/**
+ * generateWebLink - Construct a link to a web app
+ *
+ * This function does not get its cozy url from a CozyClient instance so it can
+ * be used to build urls that point to other Cozies than the user's own Cozy.
+ * This is useful when pointing to the Cozy of the owner of a shared note for
+ * example.
+ *
+ * @param {object} options               Object of options
+ * @param {string}   options.cozyUrl       Base URL of the cozy, eg. cozy.tools or test.mycozy.cloud
+ * @param {Array}    [options.searchParams]  Array of search parameters as [key, value] arrays, eg. ['username', 'bob']
+ * @param {string}   [options.pathname]      Path to a specific part of the app, eg. /public
+ * @param {string}   [options.hash]          Path inside the app, eg. /files/test.jpg
+ * @param {string}   [options.slug]          Slug of the app
+ * @param {string}   [options.subDomainType] Whether the cozy is using flat or nested subdomains. Defaults to flat.
+ *
+ * @returns {string} Generated URL
+ */
 
-  function CozyClient() {
-    (0, _classCallCheck2.default)(this, CozyClient);
-    return _super.apply(this, arguments);
+
+var generateWebLink = function generateWebLink(_ref3) {
+  var cozyUrl = _ref3.cozyUrl,
+      searchParamsOption = _ref3.searchParams,
+      pathname = _ref3.pathname,
+      hash = _ref3.hash,
+      slug = _ref3.slug,
+      subDomainType = _ref3.subDomainType;
+  var searchParams = searchParamsOption || [];
+  var url = new URL(cozyUrl);
+  url.host = subDomainType === 'nested' ? "".concat(slug, ".").concat(url.host) : url.host.split('.').map(function (x, i) {
+    return i === 0 ? x + '-' + slug : x;
+  }).join('.');
+  url.pathname = pathname;
+  url.hash = ensureFirstSlash(hash);
+
+  var _iterator = _createForOfIteratorHelper(searchParams),
+      _step;
+
+  try {
+    for (_iterator.s(); !(_step = _iterator.n()).done;) {
+      var _step$value = (0, _slicedToArray2.default)(_step.value, 2),
+          param = _step$value[0],
+          value = _step$value[1];
+
+      url.searchParams.set(param, value);
+    }
+  } catch (err) {
+    _iterator.e(err);
+  } finally {
+    _iterator.f();
   }
 
-  return CozyClient;
-}(SnapshotObject);
+  return url.toString();
+};
 
-exports.CozyClient = CozyClient;
+exports.generateWebLink = generateWebLink;
 
-/***/ }),
-/* 785 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var InvalidProtocolError = /*#__PURE__*/function (_Error) {
+  (0, _inherits2.default)(InvalidProtocolError, _Error);
 
-var json = typeof JSON !== 'undefined' ? JSON : __webpack_require__(786);
+  var _super = _createSuper(InvalidProtocolError);
 
-module.exports = function (obj, opts) {
-    if (!opts) opts = {};
-    if (typeof opts === 'function') opts = { cmp: opts };
-    var space = opts.space || '';
-    if (typeof space === 'number') space = Array(space+1).join(' ');
-    var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
-    var replacer = opts.replacer || function(key, value) { return value; };
+  function InvalidProtocolError(url) {
+    var _this;
 
-    var cmp = opts.cmp && (function (f) {
-        return function (node) {
-            return function (a, b) {
-                var aobj = { key: a, value: node[a] };
-                var bobj = { key: b, value: node[b] };
-                return f(aobj, bobj);
-            };
-        };
-    })(opts.cmp);
+    (0, _classCallCheck2.default)(this, InvalidProtocolError);
+    _this = _super.call(this, "Invalid URL protocol ".concat(url.protocol));
+    _this.url = url;
+    return _this;
+  }
 
-    var seen = [];
-    return (function stringify (parent, key, node, level) {
-        var indent = space ? ('\n' + new Array(level + 1).join(space)) : '';
-        var colonSeparator = space ? ': ' : ':';
+  return InvalidProtocolError;
+}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
 
-        if (node && node.toJSON && typeof node.toJSON === 'function') {
-            node = node.toJSON();
-        }
+exports.InvalidProtocolError = InvalidProtocolError;
 
-        node = replacer.call(parent, key, node);
+var InvalidCozyUrlError = /*#__PURE__*/function (_Error2) {
+  (0, _inherits2.default)(InvalidCozyUrlError, _Error2);
 
-        if (node === undefined) {
-            return;
-        }
-        if (typeof node !== 'object' || node === null) {
-            return json.stringify(node);
-        }
-        if (isArray(node)) {
-            var out = [];
-            for (var i = 0; i < node.length; i++) {
-                var item = stringify(node, i, node[i], level+1) || json.stringify(null);
-                out.push(indent + space + item);
-            }
-            return '[' + out.join(',') + indent + ']';
-        }
-        else {
-            if (seen.indexOf(node) !== -1) {
-                if (cycles) return json.stringify('__cycle__');
-                throw new TypeError('Converting circular structure to JSON');
-            }
-            else seen.push(node);
+  var _super2 = _createSuper(InvalidCozyUrlError);
 
-            var keys = objectKeys(node).sort(cmp && cmp(node));
-            var out = [];
-            for (var i = 0; i < keys.length; i++) {
-                var key = keys[i];
-                var value = stringify(node, key, node[key], level+1);
+  function InvalidCozyUrlError(url) {
+    var _this2;
 
-                if(!value) continue;
+    (0, _classCallCheck2.default)(this, InvalidCozyUrlError);
+    _this2 = _super2.call(this, "URL ".concat(url.toString(), " does not seem to be a valid Cozy URL"));
+    _this2.url = url;
+    return _this2;
+  }
 
-                var keyValue = json.stringify(key)
-                    + colonSeparator
-                    + value;
-                ;
-                out.push(indent + space + keyValue);
-            }
-            seen.splice(seen.indexOf(node), 1);
-            return '{' + out.join(',') + indent + '}';
-        }
-    })({ '': obj }, '', obj, 0);
-};
+  return InvalidCozyUrlError;
+}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
+/* uri - Returns a well formed URL origin from a protocol, a hostname and a port
+ *
+ * If the protocol and/or port are omitted from the argument, the function will
+ * default to HTTPS and omit the port in the returned origin.
+ *
+ * @param {object} url          Object of URL elements
+ * @param {string} url.protocol Protocol to use in the origin (e.g. http)
+ * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud)
+ * @param {string} url.port     Port to use in the origin (e.g. 8080)
+ *
+ * @returns {string} Generated URL origin
+ */
 
-var isArray = Array.isArray || function (x) {
-    return {}.toString.call(x) === '[object Array]';
+
+exports.InvalidCozyUrlError = InvalidCozyUrlError;
+
+var uri = function uri(_ref4) {
+  var protocol = _ref4.protocol,
+      hostname = _ref4.hostname,
+      port = _ref4.port;
+  return (protocol !== '' ? "".concat(protocol, "//") : 'https://') + hostname + (port !== '' ? ":".concat(port) : '');
 };
+/* wellKnownUrl - Returns a valid URL string to a Well Known password change page
+ *
+ * The built URL will point to the origin generated from the given protocol,
+ * hostname and port.
+ *
+ * @param {object} url          Object of URL elements
+ * @param {string} url.protocol Protocol to use in the origin (e.g. http)
+ * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud)
+ * @param {string} url.port     Port to use in the origin (e.g. 8080)
+ *
+ * @returns {string} Generated Well Known password change URL string
+ */
 
-var objectKeys = Object.keys || function (obj) {
-    var has = Object.prototype.hasOwnProperty || function () { return true };
-    var keys = [];
-    for (var key in obj) {
-        if (has.call(obj, key)) keys.push(key);
-    }
-    return keys;
+
+var wellKnownUrl = function wellKnownUrl(url) {
+  return uri(url) + '/.well-known/change-password';
 };
+/* isValidOrigin - Checks whether a given URL is a valid Cozy origin
+ *
+ * This method tries to fetch the Well Known change password page of the Cozy
+ * supposedly at the given origin. This allows us to determine whether the given
+ * origin is the root URL of a Cozy or not via the status of the response:
+ * - a 200 response status means there's an actual Well Known password change
+ *   page accessible from the given origin so we suppose it's a valid Cozy
+ *   origin (i.e. it could be another site altogether though)
+ * - a 401 response status means the pointed page requires authentication so the
+ *   origin is probably pointing to a Cozy app
+ * - another status means there aren't any Cozy behind to the given origin
+ *
+ * @param {object} url          Object of URL elements
+ * @param {string} url.protocol Protocol to use in the origin (e.g. http)
+ * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud)
+ * @param {string} url.port     Port to use in the origin (e.g. 8080)
+ *
+ * @returns {Promise<boolean>} True if we believe there's a Cozy behind the given origin
+ * @throws {InvalidCozyUrlError} Thrown when we know for sure there aren't any Cozy behind the given origin
+ */
 
 
-/***/ }),
-/* 786 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+var isValidOrigin = /*#__PURE__*/function () {
+  var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) {
+    var _yield$fetch, status;
 
-exports.parse = __webpack_require__(787);
-exports.stringify = __webpack_require__(788);
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            _context.next = 2;
+            return fetch(wellKnownUrl(url));
 
+          case 2:
+            _yield$fetch = _context.sent;
+            status = _yield$fetch.status;
 
-/***/ }),
-/* 787 */
-/***/ ((module) => {
+            if (!(status === 404)) {
+              _context.next = 6;
+              break;
+            }
 
-var at, // The index of the current character
-    ch, // The current character
-    escapee = {
-        '"':  '"',
-        '\\': '\\',
-        '/':  '/',
-        b:    '\b',
-        f:    '\f',
-        n:    '\n',
-        r:    '\r',
-        t:    '\t'
-    },
-    text,
+            throw new InvalidCozyUrlError(url);
 
-    error = function (m) {
-        // Call error when something is wrong.
-        throw {
-            name:    'SyntaxError',
-            message: m,
-            at:      at,
-            text:    text
-        };
-    },
-    
-    next = function (c) {
-        // If a c parameter is provided, verify that it matches the current character.
-        if (c && c !== ch) {
-            error("Expected '" + c + "' instead of '" + ch + "'");
-        }
-        
-        // Get the next character. When there are no more characters,
-        // return the empty string.
-        
-        ch = text.charAt(at);
-        at += 1;
-        return ch;
-    },
-    
-    number = function () {
-        // Parse a number value.
-        var number,
-            string = '';
-        
-        if (ch === '-') {
-            string = '-';
-            next('-');
-        }
-        while (ch >= '0' && ch <= '9') {
-            string += ch;
-            next();
+          case 6:
+            return _context.abrupt("return", status === 200);
+
+          case 7:
+          case "end":
+            return _context.stop();
         }
-        if (ch === '.') {
-            string += '.';
-            while (next() && ch >= '0' && ch <= '9') {
-                string += ch;
+      }
+    }, _callee);
+  }));
+
+  return function isValidOrigin(_x) {
+    return _ref5.apply(this, arguments);
+  };
+}();
+/**
+ * rootCozyUrl - Get the root URL of a Cozy from more precise ones
+ *
+ * The goal is to allow users to use any URL copied from their browser as their
+ * Cozy URL rather than trying to explain to them what we expect (e.g. when
+ * requesting the Cozy URL to connect an app).
+ * If we can't get the root URL either because there's no Cozy or the domain
+ * does not exist or anything else, we'll throw an InvalidCozyUrlError.
+ * Also, since we communicate only via HTTP or HTTPS, we'll throw an
+ * InvalidProtocolError if any other protocol is used.
+ *
+ * This function expects a fully qualified URL thus with a protocol and a valid
+ * hostname. If your application accepts Cozy intances as input (e.g. `claude`
+ * when the Cozy can be found at `https://claude.mycozy.cloud`), it is your
+ * responsibility to add the appropriate domain to the hostname before calling
+ * this function.
+ *
+ * Examples:
+ *
+ * 1. getting the root URL when your user gives you its instance name
+ *
+ *   const userInput = 'claude'
+ *   const rootUrl = await rootCozyUrl(new URL(`https://${userInput}.mycozy.cloud`))
+ *   // → returns new URL('https://claude.mycozy.cloud')
+ *
+ * 2. getting the root URL when your user gives you a Cozy Drive URL
+ *
+ *   const userInput = 'https://claude-drive.mycozy.cloud/#/folder/io.cozy.files.root-dir'
+ *   const rootUrl = await rootCozyUrl(new URL(userInput))
+ *   // → returns new URL('https://claude.mycozy.cloud')
+ *
+ * 3. getting the root URL when the Cozy uses nested sub-domains
+ *
+ *   const userInput = 'http://photos.camille.nimbus.com:8080/#/album/1234567890'
+ *   const rootCozyUrl = await rootCozyUrl(new URL(userInput))
+ *   // → returns new URL('http://camille.nimbus.com:8080')
+ *
+ * @param {URL} url The URL from which we'll try to get the root Cozy URL
+ *
+ * @returns {Promise<URL>} The root Cozy URL
+ */
+
+
+var rootCozyUrl = /*#__PURE__*/function () {
+  var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(url) {
+    var _url$hostname$split, _url$hostname$split2, subDomain, domain, _hostname, hostname;
+
+    return _regenerator.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            if (['http:', 'https:'].includes(url.protocol)) {
+              _context2.next = 2;
+              break;
             }
-        }
-        if (ch === 'e' || ch === 'E') {
-            string += ch;
-            next();
-            if (ch === '-' || ch === '+') {
-                string += ch;
-                next();
+
+            throw new InvalidProtocolError(url);
+
+          case 2:
+            _context2.next = 4;
+            return isValidOrigin(url);
+
+          case 4:
+            if (!_context2.sent) {
+              _context2.next = 6;
+              break;
             }
-            while (ch >= '0' && ch <= '9') {
-                string += ch;
-                next();
+
+            return _context2.abrupt("return", url);
+
+          case 6:
+            if (!/^[^.-][^.]+-[^.-]+\./.test(url.hostname)) {
+              _context2.next = 13;
+              break;
             }
-        }
-        number = +string;
-        if (!isFinite(number)) {
-            error("Bad number");
-        } else {
-            return number;
-        }
-    },
-    
-    string = function () {
-        // Parse a string value.
-        var hex,
-            i,
-            string = '',
-            uffff;
-        
-        // When parsing for string values, we must look for " and \ characters.
-        if (ch === '"') {
-            while (next()) {
-                if (ch === '"') {
-                    next();
-                    return string;
-                } else if (ch === '\\') {
-                    next();
-                    if (ch === 'u') {
-                        uffff = 0;
-                        for (i = 0; i < 4; i += 1) {
-                            hex = parseInt(next(), 16);
-                            if (!isFinite(hex)) {
-                                break;
-                            }
-                            uffff = uffff * 16 + hex;
-                        }
-                        string += String.fromCharCode(uffff);
-                    } else if (typeof escapee[ch] === 'string') {
-                        string += escapee[ch];
-                    } else {
-                        break;
-                    }
-                } else {
-                    string += ch;
-                }
+
+            _url$hostname$split = url.hostname.split('.'), _url$hostname$split2 = (0, _toArray2.default)(_url$hostname$split), subDomain = _url$hostname$split2[0], domain = _url$hostname$split2.slice(1);
+            _hostname = [subDomain.replace(/-.+/, '')].concat((0, _toConsumableArray2.default)(domain)).join('.');
+            _context2.next = 11;
+            return isValidOrigin({
+              protocol: url.protocol,
+              hostname: _hostname,
+              port: url.port
+            });
+
+          case 11:
+            if (!_context2.sent) {
+              _context2.next = 13;
+              break;
             }
-        }
-        error("Bad string");
-    },
 
-    white = function () {
+            return _context2.abrupt("return", new URL(uri({
+              protocol: url.protocol,
+              hostname: _hostname,
+              port: url.port
+            })));
 
-// Skip whitespace.
+          case 13:
+            // Try to remove the first sub-domain in case its a nested app name
+            // eslint-disable-next-line no-unused-vars
+            hostname = url.hostname.split('.').splice(1).join('.');
+            _context2.next = 16;
+            return isValidOrigin({
+              protocol: url.protocol,
+              hostname: hostname,
+              port: url.port
+            });
 
-        while (ch && ch <= ' ') {
-            next();
-        }
-    },
+          case 16:
+            if (!_context2.sent) {
+              _context2.next = 18;
+              break;
+            }
 
-    word = function () {
+            return _context2.abrupt("return", new URL(uri({
+              protocol: url.protocol,
+              hostname: hostname,
+              port: url.port
+            })));
 
-// true, false, or null.
+          case 18:
+            throw new InvalidCozyUrlError(url);
 
-        switch (ch) {
-        case 't':
-            next('t');
-            next('r');
-            next('u');
-            next('e');
-            return true;
-        case 'f':
-            next('f');
-            next('a');
-            next('l');
-            next('s');
-            next('e');
-            return false;
-        case 'n':
-            next('n');
-            next('u');
-            next('l');
-            next('l');
-            return null;
+          case 19:
+          case "end":
+            return _context2.stop();
         }
-        error("Unexpected '" + ch + "'");
-    },
+      }
+    }, _callee2);
+  }));
 
-    value,  // Place holder for the value function.
+  return function rootCozyUrl(_x2) {
+    return _ref6.apply(this, arguments);
+  };
+}();
 
-    array = function () {
+exports.rootCozyUrl = rootCozyUrl;
 
-// Parse an array value.
+/***/ }),
+/* 769 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-        var array = [];
+"use strict";
 
-        if (ch === '[') {
-            next('[');
-            white();
-            if (ch === ']') {
-                next(']');
-                return array;   // empty array
-            }
-            while (ch) {
-                array.push(value());
-                white();
-                if (ch === ']') {
-                    next(']');
-                    return array;
-                }
-                next(',');
-                white();
-            }
-        }
-        error("Bad array");
-    },
 
-    object = function () {
+var _interopRequireDefault = __webpack_require__(524);
 
-// Parse an object value.
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.authFunction = exports.authenticateWithCordova = void 0;
 
-        var key,
-            object = {};
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-        if (ch === '{') {
-            next('{');
-            white();
-            if (ch === '}') {
-                next('}');
-                return object;   // empty object
-            }
-            while (ch) {
-                key = string();
-                white();
-                next(':');
-                if (Object.hasOwnProperty.call(object, key)) {
-                    error('Duplicate key "' + key + '"');
-                }
-                object[key] = value();
-                white();
-                if (ch === '}') {
-                    next('}');
-                    return object;
-                }
-                next(',');
-                white();
-            }
-        }
-        error("Bad object");
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
+
+var _const = __webpack_require__(697);
+
+var _cozyDeviceHelper = __webpack_require__(770);
+
+var _types = __webpack_require__(622);
+
+/* global prompt */
+
+/**
+ * @type {CordovaWindow}
+ */
+// @ts-ignore
+var win = typeof window !== 'undefined' ? window : null;
+/**
+ * Open a SafariView Controller and resolve with the URL containing the token
+ *
+ * @param {string} url
+ * @returns {Promise}
+ */
+
+var authenticateWithSafari = function authenticateWithSafari(url) {
+  return new Promise(function (resolve, reject) {
+    win.SafariViewController.show({
+      url: url,
+      transition: 'curl' // (this only works in iOS 9.1/9.2 and lower) unless animated is false you can choose from: curl, flip, fade, slide (default)
+      // enterReaderModeIfAvailable: readerMode, // default false
+      // tintColor: "#00ffff", // default is ios blue
+      // barColor: "#0000ff", // on iOS 10+ you can change the background color as well
+      // controlTintColor: "#ffffff" // on iOS 10+ you can override the default tintColor
+
+    }, // this success handler will be invoked for the lifecycle events 'opened', 'loaded' and 'closed'
+    function (result) {
+      if (result.event === 'closed') {
+        reject(new Error(_const.REGISTRATION_ABORT));
+      }
+    }, function (error) {
+      console.log('KO: ' + error);
+      reject(new Error(_const.REGISTRATION_ABORT));
+    });
+    var handle = win.handleOpenURL;
+
+    win.handleOpenURL = function (url) {
+      win.SafariViewController.hide();
+      resolve(url);
+
+      if (handle) {
+        win.handleOpenURL = handle;
+      }
     };
+  });
+};
+/**
+ * Opens an InAppBrowser and resolves with the URL containing the token
+ *
+ * @param {string} url
+ * @returns {Promise}
+ */
 
-value = function () {
 
-// Parse a JSON value. It could be an object, an array, a string, a number,
-// or a word.
+var authenticateWithInAppBrowser = function authenticateWithInAppBrowser(url) {
+  return new Promise(function (resolve, reject) {
+    var target = '_blank';
+    var options = 'clearcache=yes,zoom=no';
+    var inAppBrowser = win.cordova.InAppBrowser.open(url, target, options);
 
-    white();
-    switch (ch) {
-    case '{':
-        return object();
-    case '[':
-        return array();
-    case '"':
-        return string();
-    case '-':
-        return number();
-    default:
-        return ch >= '0' && ch <= '9' ? number() : word();
-    }
+    var removeListener = function removeListener() {
+      inAppBrowser.removeEventListener('loadstart', onLoadStart);
+      inAppBrowser.removeEventListener('exit', onExit);
+    };
+
+    var onLoadStart = function onLoadStart(_ref) {
+      var url = _ref.url;
+      var accessCode = /\?access_code=(.+)$/.test(url);
+      var state = /\?state=(.+)$/.test(url);
+
+      if (accessCode || state) {
+        resolve(url);
+        removeListener();
+        inAppBrowser.close();
+      }
+    };
+
+    var onExit = function onExit() {
+      reject(new Error(_const.REGISTRATION_ABORT));
+      removeListener();
+      inAppBrowser.close();
+    };
+
+    inAppBrowser.addEventListener('loadstart', onLoadStart);
+    inAppBrowser.addEventListener('exit', onExit);
+  });
 };
 
-// Return the json_parse function. It will have access to all of the above
-// functions and variables.
+var authenticateWithCordova = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) {
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            _context.t0 = (0, _cozyDeviceHelper.isIOSApp)();
 
-module.exports = function (source, reviver) {
-    var result;
-    
-    text = source;
-    at = 0;
-    ch = ' ';
-    result = value();
-    white();
-    if (ch) {
-        error("Syntax error");
-    }
+            if (!_context.t0) {
+              _context.next = 5;
+              break;
+            }
 
-    // If there is a reviver function, we recursively walk the new structure,
-    // passing each name/value pair to the reviver function for possible
-    // transformation, starting with a temporary root object that holds the result
-    // in an empty key. If there is not a reviver function, we simply return the
-    // result.
+            _context.next = 4;
+            return (0, _cozyDeviceHelper.hasSafariPlugin)();
 
-    return typeof reviver === 'function' ? (function walk(holder, key) {
-        var k, v, value = holder[key];
-        if (value && typeof value === 'object') {
-            for (k in value) {
-                if (Object.prototype.hasOwnProperty.call(value, k)) {
-                    v = walk(value, k);
-                    if (v !== undefined) {
-                        value[k] = v;
-                    } else {
-                        delete value[k];
-                    }
-                }
+          case 4:
+            _context.t0 = _context.sent;
+
+          case 5:
+            if (!_context.t0) {
+              _context.next = 9;
+              break;
+            }
+
+            return _context.abrupt("return", authenticateWithSafari(url));
+
+          case 9:
+            if (!(0, _cozyDeviceHelper.hasInAppBrowserPlugin)()) {
+              _context.next = 13;
+              break;
             }
+
+            return _context.abrupt("return", authenticateWithInAppBrowser(url));
+
+          case 13:
+            /**
+             * for dev purpose:
+             * In oauth workflow, the server displays an authorization page
+             * User must accept to give permission then the server gives an url
+             * with query parameters used by cozy-client-js to initialize itself.
+             *
+             * This hack let developers open the authorization page in a new tab
+             * then get the "access_code" url and paste it in the prompt to let the
+             * application initialize and redirect to other pages.
+             */
+            console.log(url); // Useful for dev (see above).
+
+            return _context.abrupt("return", new Promise(function (resolve) {
+              setTimeout(function () {
+                var token = prompt('Paste the url here:');
+                resolve(token);
+              }, 5000);
+            }));
+
+          case 15:
+          case "end":
+            return _context.stop();
         }
-        return reviver.call(holder, key, value);
-    }({'': result}, '')) : result;
-};
+      }
+    }, _callee);
+  }));
+
+  return function authenticateWithCordova(_x) {
+    return _ref2.apply(this, arguments);
+  };
+}();
 
+exports.authenticateWithCordova = authenticateWithCordova;
+var authFunction = authenticateWithCordova;
+exports.authFunction = authFunction;
 
 /***/ }),
-/* 788 */
-/***/ ((module) => {
+/* 770 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-    escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-    gap,
-    indent,
-    meta = {    // table of character substitutions
-        '\b': '\\b',
-        '\t': '\\t',
-        '\n': '\\n',
-        '\f': '\\f',
-        '\r': '\\r',
-        '"' : '\\"',
-        '\\': '\\\\'
-    },
-    rep;
+"use strict";
 
-function quote(string) {
-    // If the string contains no control characters, no quote characters, and no
-    // backslash characters, then we can safely slap some quotes around it.
-    // Otherwise we must also replace the offending characters with safe escape
-    // sequences.
-    
-    escapable.lastIndex = 0;
-    return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
-        var c = meta[a];
-        return typeof c === 'string' ? c :
-            '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
-    }) + '"' : '"' + string + '"';
-}
 
-function str(key, holder) {
-    // Produce a string from holder[key].
-    var i,          // The loop counter.
-        k,          // The member key.
-        v,          // The member value.
-        length,
-        mind = gap,
-        partial,
-        value = holder[key];
-    
-    // If the value has a toJSON method, call it to obtain a replacement value.
-    if (value && typeof value === 'object' &&
-            typeof value.toJSON === 'function') {
-        value = value.toJSON(key);
-    }
-    
-    // If we were called with a replacer function, then call the replacer to
-    // obtain a replacement value.
-    if (typeof rep === 'function') {
-        value = rep.call(holder, key, value);
-    }
-    
-    // What happens next depends on the value's type.
-    switch (typeof value) {
-        case 'string':
-            return quote(value);
-        
-        case 'number':
-            // JSON numbers must be finite. Encode non-finite numbers as null.
-            return isFinite(value) ? String(value) : 'null';
-        
-        case 'boolean':
-        case 'null':
-            // If the value is a boolean or null, convert it to a string. Note:
-            // typeof null does not produce 'null'. The case is included here in
-            // the remote chance that this gets fixed someday.
-            return String(value);
-            
-        case 'object':
-            if (!value) return 'null';
-            gap += indent;
-            partial = [];
-            
-            // Array.isArray
-            if (Object.prototype.toString.apply(value) === '[object Array]') {
-                length = value.length;
-                for (i = 0; i < length; i += 1) {
-                    partial[i] = str(i, value) || 'null';
-                }
-                
-                // Join all of the elements together, separated with commas, and
-                // wrap them in brackets.
-                v = partial.length === 0 ? '[]' : gap ?
-                    '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
-                    '[' + partial.join(',') + ']';
-                gap = mind;
-                return v;
-            }
-            
-            // If the replacer is an array, use it to select the members to be
-            // stringified.
-            if (rep && typeof rep === 'object') {
-                length = rep.length;
-                for (i = 0; i < length; i += 1) {
-                    k = rep[i];
-                    if (typeof k === 'string') {
-                        v = str(k, value);
-                        if (v) {
-                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
-                        }
-                    }
-                }
-            }
-            else {
-                // Otherwise, iterate through all of the keys in the object.
-                for (k in value) {
-                    if (Object.prototype.hasOwnProperty.call(value, k)) {
-                        v = str(k, value);
-                        if (v) {
-                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
-                        }
-                    }
-                }
-            }
-            
-        // Join all of the member texts together, separated with commas,
-        // and wrap them in braces.
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+Object.defineProperty(exports, "checkApp", ({
+  enumerable: true,
+  get: function get() {
+    return _apps.checkApp;
+  }
+}));
+Object.defineProperty(exports, "getDeviceName", ({
+  enumerable: true,
+  get: function get() {
+    return _device.getDeviceName;
+  }
+}));
+Object.defineProperty(exports, "getFlagshipMetadata", ({
+  enumerable: true,
+  get: function get() {
+    return _flagship.getFlagshipMetadata;
+  }
+}));
+Object.defineProperty(exports, "getPlatform", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.getPlatform;
+  }
+}));
+Object.defineProperty(exports, "hasDevicePlugin", ({
+  enumerable: true,
+  get: function get() {
+    return _plugins.hasDevicePlugin;
+  }
+}));
+Object.defineProperty(exports, "hasInAppBrowserPlugin", ({
+  enumerable: true,
+  get: function get() {
+    return _plugins.hasInAppBrowserPlugin;
+  }
+}));
+Object.defineProperty(exports, "hasNetworkInformationPlugin", ({
+  enumerable: true,
+  get: function get() {
+    return _plugins.hasNetworkInformationPlugin;
+  }
+}));
+Object.defineProperty(exports, "hasSafariPlugin", ({
+  enumerable: true,
+  get: function get() {
+    return _plugins.hasSafariPlugin;
+  }
+}));
+Object.defineProperty(exports, "isAndroid", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isAndroid;
+  }
+}));
+Object.defineProperty(exports, "isAndroidApp", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isAndroidApp;
+  }
+}));
+Object.defineProperty(exports, "isCordova", ({
+  enumerable: true,
+  get: function get() {
+    return _cordova.isCordova;
+  }
+}));
+Object.defineProperty(exports, "isFlagshipApp", ({
+  enumerable: true,
+  get: function get() {
+    return _flagship.isFlagshipApp;
+  }
+}));
+Object.defineProperty(exports, "isIOS", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isIOS;
+  }
+}));
+Object.defineProperty(exports, "isIOSApp", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isIOSApp;
+  }
+}));
+Object.defineProperty(exports, "isMobile", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isMobile;
+  }
+}));
+Object.defineProperty(exports, "isMobileApp", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isMobileApp;
+  }
+}));
+Object.defineProperty(exports, "isWebApp", ({
+  enumerable: true,
+  get: function get() {
+    return _platform.isWebApp;
+  }
+}));
+Object.defineProperty(exports, "nativeLinkOpen", ({
+  enumerable: true,
+  get: function get() {
+    return _link.nativeLinkOpen;
+  }
+}));
+Object.defineProperty(exports, "openDeeplinkOrRedirect", ({
+  enumerable: true,
+  get: function get() {
+    return _deeplink.openDeeplinkOrRedirect;
+  }
+}));
+Object.defineProperty(exports, "startApp", ({
+  enumerable: true,
+  get: function get() {
+    return _apps.startApp;
+  }
+}));
 
-        v = partial.length === 0 ? '{}' : gap ?
-            '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
-            '{' + partial.join(',') + '}';
-        gap = mind;
-        return v;
-    }
-}
+var _platform = __webpack_require__(771);
 
-module.exports = function (value, replacer, space) {
-    var i;
-    gap = '';
-    indent = '';
-    
-    // If the space parameter is a number, make an indent string containing that
-    // many spaces.
-    if (typeof space === 'number') {
-        for (i = 0; i < space; i += 1) {
-            indent += ' ';
-        }
-    }
-    // If the space parameter is a string, it will be used as the indent string.
-    else if (typeof space === 'string') {
-        indent = space;
-    }
+var _device = __webpack_require__(773);
 
-    // If there is a replacer, it must be a function or an array.
-    // Otherwise, throw an error.
-    rep = replacer;
-    if (replacer && typeof replacer !== 'function'
-    && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
-        throw new Error('JSON.stringify');
-    }
-    
-    // Make a fake root object containing our value under the key of ''.
-    // Return the result of stringifying the value.
-    return str('', {'': value});
-};
+var _apps = __webpack_require__(783);
 
+var _plugins = __webpack_require__(782);
+
+var _cordova = __webpack_require__(772);
+
+var _link = __webpack_require__(784);
+
+var _deeplink = __webpack_require__(785);
+
+var _flagship = __webpack_require__(786);
 
 /***/ }),
-/* 789 */
+/* 771 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
-
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports["default"] = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
-
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
-
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
-
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
-
-/**
- * Caches promises while they are pending
- * Serves to dedupe equal queries requested at the same time
- */
-var PromiseCache = /*#__PURE__*/function () {
-  function PromiseCache() {
-    (0, _classCallCheck2.default)(this, PromiseCache);
+exports.isWebApp = exports.isMobileApp = exports.isMobile = exports.isIOSApp = exports.isIOS = exports.isAndroidApp = exports.isAndroid = exports.getPlatform = void 0;
 
-    /**
-     * Holds pending promises
-     *
-     * @type {Object.<string, Promise>}
-     */
-    this.pending = {};
-  }
-  /**
-   * Tries to find a pending promise corresponding to the result of keyFunc
-   * - If not found, promiseFunc is executed and the resulting promise is stored while it's pending
-   * - If found, it is immediately returned
-   *
-   * @template T
-   * @param  {function(): Promise<T>} promiseFunc - Not executed only if an "equal" promise is already pending.
-   * @param  {function(): string} keyFunc - Returns a key to find in cache to find a pending promise.
-   * @returns {Promise<T>}
-   */
+var _cordova = __webpack_require__(772);
 
+var ANDROID_PLATFORM = 'android';
+var IOS_PLATFORM = 'ios';
+var WEB_PLATFORM = 'web';
 
-  (0, _createClass2.default)(PromiseCache, [{
-    key: "exec",
-    value: function () {
-      var _exec = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(promiseFunc, keyFunc) {
-        var key, already, prom, response;
-        return _regenerator.default.wrap(function _callee$(_context) {
-          while (1) {
-            switch (_context.prev = _context.next) {
-              case 0:
-                key = keyFunc();
-                already = this.pending[key];
+var getPlatform = function getPlatform() {
+  return (0, _cordova.isCordova)() ? window.cordova.platformId : WEB_PLATFORM;
+};
 
-                if (already) {
-                  prom = already;
-                } else {
-                  prom = promiseFunc();
-                  this.pending[key] = prom;
-                }
+exports.getPlatform = getPlatform;
 
-                _context.prev = 3;
-                _context.next = 6;
-                return prom;
+var isPlatform = function isPlatform(platform) {
+  return getPlatform() === platform;
+};
 
-              case 6:
-                response = _context.sent;
-                return _context.abrupt("return", response);
+var isIOSApp = function isIOSApp() {
+  return isPlatform(IOS_PLATFORM);
+};
 
-              case 8:
-                _context.prev = 8;
-                this.pending[key] = null;
-                return _context.finish(8);
+exports.isIOSApp = isIOSApp;
 
-              case 11:
-              case "end":
-                return _context.stop();
-            }
-          }
-        }, _callee, this, [[3,, 8, 11]]);
-      }));
+var isAndroidApp = function isAndroidApp() {
+  return isPlatform(ANDROID_PLATFORM);
+};
 
-      function exec(_x, _x2) {
-        return _exec.apply(this, arguments);
-      }
+exports.isAndroidApp = isAndroidApp;
 
-      return exec;
-    }()
-    /**
-     *
-     * @param {function(): string} keyFunc - Returns a key to find in cache to find a pending promise.
-     * @returns {Promise | null}
-     */
+var isWebApp = function isWebApp() {
+  return isPlatform(WEB_PLATFORM);
+};
 
-  }, {
-    key: "get",
-    value: function get(keyFunc) {
-      var key = keyFunc();
-      var already = this.pending[key];
-      if (already) return already;
-      return null;
-    }
-  }]);
-  return PromiseCache;
-}();
+exports.isWebApp = isWebApp;
 
-var _default = PromiseCache;
-exports["default"] = _default;
+var isMobileApp = function isMobileApp() {
+  return (0, _cordova.isCordova)();
+}; // return if is on an Android Device (native or browser)
 
-/***/ }),
-/* 790 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-"use strict";
+exports.isMobileApp = isMobileApp;
 
+var isAndroid = function isAndroid() {
+  return window.navigator.userAgent && window.navigator.userAgent.indexOf('Android') >= 0;
+}; // return if is on an iOS Device (native or browser)
 
-var _interopRequireDefault = __webpack_require__(512);
 
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.certifyFlagship = void 0;
+exports.isAndroid = isAndroid;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var isIOS = function isIOS() {
+  return window.navigator.userAgent && /iPad|iPhone|iPod/.test(window.navigator.userAgent);
+}; // isMobile checks if the user is on a smartphone : native app or browser
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+exports.isIOS = isIOS;
 
-var _logger = _interopRequireDefault(__webpack_require__(703));
+var isMobile = function isMobile() {
+  return isAndroid() || isIOS();
+};
 
-var _storeAttestation = __webpack_require__(791);
+exports.isMobile = isMobile;
 
-/**
- * Request a challenge from the Stack that can be used to request the app attestation from the app store
- *
- * @param {CozyClient} client - the CozyClient instance
- * @returns {Promise<string>} - the Nonce string returned by the stack
- */
-var getStackChallenge = /*#__PURE__*/function () {
-  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) {
-    var stackClient, result;
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            _context.prev = 0;
-            stackClient = client.getStackClient();
-            _context.next = 4;
-            return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/challenge"), null, {
-              headers: {
-                Authorization: stackClient.registrationAccessTokenToAuthHeader()
-              }
-            });
+/***/ }),
+/* 772 */
+/***/ ((__unused_webpack_module, exports) => {
 
-          case 4:
-            result = _context.sent;
-            return _context.abrupt("return", result.nonce);
+"use strict";
 
-          case 8:
-            _context.prev = 8;
-            _context.t0 = _context["catch"](0);
-            throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while requesting a challenge from CozyStack:\n' + _context.t0.message);
 
-          case 11:
-          case "end":
-            return _context.stop();
-        }
-      }
-    }, _callee, null, [[0, 8]]);
-  }));
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.isCordova = void 0;
 
-  return function getStackChallenge(_x) {
-    return _ref.apply(this, arguments);
-  };
-}();
-/**
- * Give the app attestation to the Stack
- *
- * @param {AttestationResult} appAttestation - the app attestation that was returned by the app store
- * @param {string} nonce - the Nonce string retrieved from the stack
- * @param {CozyClient} client - the CozyClient instance
- */
+// cordova
+var isCordova = function isCordova() {
+  return typeof window !== 'undefined' && window.cordova !== undefined;
+};
 
+exports.isCordova = isCordova;
 
-var giveAppAttestationToStack = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appAttestation, nonce, client) {
-    var platform, attestation, keyId, stackClient;
-    return _regenerator.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            _context2.prev = 0;
-            platform = appAttestation.platform, attestation = appAttestation.attestation, keyId = appAttestation.keyId;
-            stackClient = client.getStackClient();
-            _context2.next = 5;
-            return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/attestation"), {
-              platform: platform,
-              attestation: attestation,
-              challenge: nonce,
-              keyId: keyId
-            }, {
-              headers: {
-                Authorization: stackClient.registrationAccessTokenToAuthHeader()
-              }
-            });
+/***/ }),
+/* 773 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-          case 5:
-            _context2.next = 10;
-            break;
+"use strict";
 
-          case 7:
-            _context2.prev = 7;
-            _context2.t0 = _context2["catch"](0);
-            throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while giving attestation to CozyStack:\n' + _context2.t0.message);
 
-          case 10:
-          case "end":
-            return _context2.stop();
-        }
-      }
-    }, _callee2, null, [[0, 7]]);
-  }));
+var _interopRequireDefault = __webpack_require__(524);
 
-  return function giveAppAttestationToStack(_x2, _x3, _x4) {
-    return _ref2.apply(this, arguments);
-  };
-}();
-/**
- * Verify app's identity and integrity so the Stack can trust it
- * Verification is done on Stack side by using information from the app's store (Google Play or Apple AppStore)
- *
- * @param {CertificationConfig} certificationConfig - the required configuration to access the stores API
- * @param {CozyClient} client - the CozyClient instance
- */
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getDeviceName = void 0;
 
+var _capitalize = _interopRequireDefault(__webpack_require__(774));
 
-var certifyFlagship = /*#__PURE__*/function () {
-  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(certificationConfig, client) {
-    var stackChallengeNonce, appAttestation;
-    return _regenerator.default.wrap(function _callee3$(_context3) {
-      while (1) {
-        switch (_context3.prev = _context3.next) {
-          case 0:
-            if (certificationConfig) {
-              _context3.next = 2;
-              break;
-            }
+var _cordova = __webpack_require__(772);
 
-            throw new Error('[FLAGSHIP_CERTIFICATION] Certification configuration is not set');
+var _plugins = __webpack_require__(782);
 
-          case 2:
-            _context3.prev = 2;
-            _context3.next = 5;
-            return getStackChallenge(client);
+var _platform = __webpack_require__(771);
 
-          case 5:
-            stackChallengeNonce = _context3.sent;
-            _context3.next = 8;
-            return (0, _storeAttestation.getAppAttestationFromStore)(stackChallengeNonce, certificationConfig);
+var DEFAULT_DEVICE = 'Device';
 
-          case 8:
-            appAttestation = _context3.sent;
-            _context3.next = 11;
-            return giveAppAttestationToStack(appAttestation, stackChallengeNonce, client);
+// device
+var getAppleModel = function getAppleModel(identifier) {
+  var devices = ['iPhone', 'iPad', 'Watch', 'AppleTV'];
 
-          case 11:
-            _context3.next = 17;
-            break;
+  for (var _i = 0, _devices = devices; _i < _devices.length; _i++) {
+    var _device = _devices[_i];
 
-          case 13:
-            _context3.prev = 13;
-            _context3.t0 = _context3["catch"](2);
+    if (identifier.match(new RegExp(_device))) {
+      return _device;
+    }
+  }
 
-            _logger.default.warn('[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification');
+  return DEFAULT_DEVICE;
+};
 
-            _logger.default.warn(_context3.t0.message);
+var getDeviceName = function getDeviceName() {
+  if (!(0, _plugins.hasDevicePlugin)()) {
+    if ((0, _cordova.isCordova)()) {
+      console.warn('You should install `cordova-plugin-device`.'); // eslint-disable-line no-console
+    }
 
-          case 17:
-          case "end":
-            return _context3.stop();
-        }
-      }
-    }, _callee3, null, [[2, 13]]);
-  }));
+    return DEFAULT_DEVICE;
+  }
 
-  return function certifyFlagship(_x5, _x6) {
-    return _ref3.apply(this, arguments);
-  };
-}();
+  var _window$device = window.device,
+      manufacturer = _window$device.manufacturer,
+      originalModel = _window$device.model;
+  var model = (0, _platform.isIOSApp)() ? getAppleModel(originalModel) : originalModel;
+  return "".concat((0, _capitalize.default)(manufacturer), " ").concat(model);
+};
 
-exports.certifyFlagship = certifyFlagship;
+exports.getDeviceName = getDeviceName;
 
 /***/ }),
-/* 791 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
-
-"use strict";
-
-
-var _interopRequireDefault = __webpack_require__(512);
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-exports.getAppAttestationFromStore = void 0;
-
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+/* 774 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var toString = __webpack_require__(408),
+    upperFirst = __webpack_require__(775);
 
 /**
- * Retrieve the app's attestation from the app's store
- * /!\ This is a mock implementation that should never be called
+ * Converts the first character of `string` to upper case and the remaining
+ * to lower case.
  *
- * @param {string} nonce - the Nonce string retrieved from the stack
- * @param {CertificationConfig} certificationConfig - Configuration to access the stores certification API
- * @returns {Promise<AttestationResult>} the app's attestation
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category String
+ * @param {string} [string=''] The string to capitalize.
+ * @returns {string} Returns the capitalized string.
+ * @example
+ *
+ * _.capitalize('FRED');
+ * // => 'Fred'
  */
-var validateAppMock = /*#__PURE__*/function () {
-  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(nonce, certificationConfig) {
-    return _regenerator.default.wrap(function _callee$(_context) {
-      while (1) {
-        switch (_context.prev = _context.next) {
-          case 0:
-            throw new Error("getAppAttestationFromStore can only be called from a React Native container");
-
-          case 1:
-          case "end":
-            return _context.stop();
-        }
-      }
-    }, _callee);
-  }));
+function capitalize(string) {
+  return upperFirst(toString(string).toLowerCase());
+}
 
-  return function validateAppMock(_x, _x2) {
-    return _ref.apply(this, arguments);
-  };
-}();
+module.exports = capitalize;
 
-var getAppAttestationFromStore = validateAppMock;
-exports.getAppAttestationFromStore = getAppAttestationFromStore;
 
 /***/ }),
-/* 792 */
+/* 775 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var createFlow = __webpack_require__(793);
+var createCaseFirst = __webpack_require__(776);
 
 /**
- * Creates a function that returns the result of invoking the given functions
- * with the `this` binding of the created function, where each successive
- * invocation is supplied the return value of the previous.
+ * Converts the first character of `string` to upper case.
  *
  * @static
  * @memberOf _
- * @since 3.0.0
- * @category Util
- * @param {...(Function|Function[])} [funcs] The functions to invoke.
- * @returns {Function} Returns the new composite function.
- * @see _.flowRight
+ * @since 4.0.0
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
  * @example
  *
- * function square(n) {
- *   return n * n;
- * }
+ * _.upperFirst('fred');
+ * // => 'Fred'
  *
- * var addSquare = _.flow([_.add, square]);
- * addSquare(1, 2);
- * // => 9
+ * _.upperFirst('FRED');
+ * // => 'FRED'
  */
-var flow = createFlow();
+var upperFirst = createCaseFirst('toUpperCase');
 
-module.exports = flow;
+module.exports = upperFirst;
 
 
 /***/ }),
-/* 793 */
+/* 776 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var LodashWrapper = __webpack_require__(794),
-    flatRest = __webpack_require__(620),
-    getData = __webpack_require__(796),
-    getFuncName = __webpack_require__(798),
-    isArray = __webpack_require__(55),
-    isLaziable = __webpack_require__(800);
-
-/** Error message constants. */
-var FUNC_ERROR_TEXT = 'Expected a function';
-
-/** Used to compose bitmasks for function metadata. */
-var WRAP_CURRY_FLAG = 8,
-    WRAP_PARTIAL_FLAG = 32,
-    WRAP_ARY_FLAG = 128,
-    WRAP_REARG_FLAG = 256;
+var castSlice = __webpack_require__(777),
+    hasUnicode = __webpack_require__(778),
+    stringToArray = __webpack_require__(779),
+    toString = __webpack_require__(408);
 
 /**
- * Creates a `_.flow` or `_.flowRight` function.
+ * Creates a function like `_.lowerFirst`.
  *
  * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new flow function.
+ * @param {string} methodName The name of the `String` case method to use.
+ * @returns {Function} Returns the new case function.
  */
-function createFlow(fromRight) {
-  return flatRest(function(funcs) {
-    var length = funcs.length,
-        index = length,
-        prereq = LodashWrapper.prototype.thru;
-
-    if (fromRight) {
-      funcs.reverse();
-    }
-    while (index--) {
-      var func = funcs[index];
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
-        var wrapper = new LodashWrapper([], true);
-      }
-    }
-    index = wrapper ? index : length;
-    while (++index < length) {
-      func = funcs[index];
+function createCaseFirst(methodName) {
+  return function(string) {
+    string = toString(string);
 
-      var funcName = getFuncName(func),
-          data = funcName == 'wrapper' ? getData(func) : undefined;
+    var strSymbols = hasUnicode(string)
+      ? stringToArray(string)
+      : undefined;
 
-      if (data && isLaziable(data[0]) &&
-            data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
-            !data[4].length && data[9] == 1
-          ) {
-        wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
-      } else {
-        wrapper = (func.length == 1 && isLaziable(func))
-          ? wrapper[funcName]()
-          : wrapper.thru(func);
-      }
-    }
-    return function() {
-      var args = arguments,
-          value = args[0];
+    var chr = strSymbols
+      ? strSymbols[0]
+      : string.charAt(0);
 
-      if (wrapper && args.length == 1 && isArray(value)) {
-        return wrapper.plant(value).value();
-      }
-      var index = 0,
-          result = length ? funcs[index].apply(this, args) : value;
+    var trailing = strSymbols
+      ? castSlice(strSymbols, 1).join('')
+      : string.slice(1);
 
-      while (++index < length) {
-        result = funcs[index].call(this, result);
-      }
-      return result;
-    };
-  });
+    return chr[methodName]() + trailing;
+  };
 }
 
-module.exports = createFlow;
+module.exports = createCaseFirst;
 
 
 /***/ }),
-/* 794 */
+/* 777 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseCreate = __webpack_require__(585),
-    baseLodash = __webpack_require__(795);
+var baseSlice = __webpack_require__(629);
 
 /**
- * The base constructor for creating `lodash` wrapper objects.
+ * Casts `array` to a slice if it's needed.
  *
  * @private
- * @param {*} value The value to wrap.
- * @param {boolean} [chainAll] Enable explicit method chain sequences.
+ * @param {Array} array The array to inspect.
+ * @param {number} start The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the cast slice.
  */
-function LodashWrapper(value, chainAll) {
-  this.__wrapped__ = value;
-  this.__actions__ = [];
-  this.__chain__ = !!chainAll;
-  this.__index__ = 0;
-  this.__values__ = undefined;
+function castSlice(array, start, end) {
+  var length = array.length;
+  end = end === undefined ? length : end;
+  return (!start && end >= length) ? array : baseSlice(array, start, end);
 }
 
-LodashWrapper.prototype = baseCreate(baseLodash.prototype);
-LodashWrapper.prototype.constructor = LodashWrapper;
-
-module.exports = LodashWrapper;
+module.exports = castSlice;
 
 
 /***/ }),
-/* 795 */
+/* 778 */
 /***/ ((module) => {
 
+/** Used to compose unicode character classes. */
+var rsAstralRange = '\\ud800-\\udfff',
+    rsComboMarksRange = '\\u0300-\\u036f',
+    reComboHalfMarksRange = '\\ufe20-\\ufe2f',
+    rsComboSymbolsRange = '\\u20d0-\\u20ff',
+    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
+    rsVarRange = '\\ufe0e\\ufe0f';
+
+/** Used to compose unicode capture groups. */
+var rsZWJ = '\\u200d';
+
+/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
+
 /**
- * The function whose prototype chain sequence wrappers inherit from.
+ * Checks if `string` contains Unicode symbols.
  *
  * @private
+ * @param {string} string The string to inspect.
+ * @returns {boolean} Returns `true` if a symbol is found, else `false`.
  */
-function baseLodash() {
-  // No operation performed.
+function hasUnicode(string) {
+  return reHasUnicode.test(string);
 }
 
-module.exports = baseLodash;
+module.exports = hasUnicode;
 
 
 /***/ }),
-/* 796 */
+/* 779 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var metaMap = __webpack_require__(797),
-    noop = __webpack_require__(471);
+var asciiToArray = __webpack_require__(780),
+    hasUnicode = __webpack_require__(778),
+    unicodeToArray = __webpack_require__(781);
 
 /**
- * Gets metadata for `func`.
+ * Converts `string` to an array.
  *
  * @private
- * @param {Function} func The function to query.
- * @returns {*} Returns the metadata for `func`.
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
  */
-var getData = !metaMap ? noop : function(func) {
-  return metaMap.get(func);
-};
+function stringToArray(string) {
+  return hasUnicode(string)
+    ? unicodeToArray(string)
+    : asciiToArray(string);
+}
 
-module.exports = getData;
+module.exports = stringToArray;
 
 
 /***/ }),
-/* 797 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-var WeakMap = __webpack_require__(451);
+/* 780 */
+/***/ ((module) => {
 
-/** Used to store function metadata. */
-var metaMap = WeakMap && new WeakMap;
+/**
+ * Converts an ASCII `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */
+function asciiToArray(string) {
+  return string.split('');
+}
 
-module.exports = metaMap;
+module.exports = asciiToArray;
 
 
 /***/ }),
-/* 798 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 781 */
+/***/ ((module) => {
 
-var realNames = __webpack_require__(799);
+/** Used to compose unicode character classes. */
+var rsAstralRange = '\\ud800-\\udfff',
+    rsComboMarksRange = '\\u0300-\\u036f',
+    reComboHalfMarksRange = '\\ufe20-\\ufe2f',
+    rsComboSymbolsRange = '\\u20d0-\\u20ff',
+    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
+    rsVarRange = '\\ufe0e\\ufe0f';
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+/** Used to compose unicode capture groups. */
+var rsAstral = '[' + rsAstralRange + ']',
+    rsCombo = '[' + rsComboRange + ']',
+    rsFitz = '\\ud83c[\\udffb-\\udfff]',
+    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
+    rsNonAstral = '[^' + rsAstralRange + ']',
+    rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+    rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+    rsZWJ = '\\u200d';
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+/** Used to compose unicode regexes. */
+var reOptMod = rsModifier + '?',
+    rsOptVar = '[' + rsVarRange + ']?',
+    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+    rsSeq = rsOptVar + reOptMod + rsOptJoin,
+    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+
+/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
 
 /**
- * Gets the name of `func`.
+ * Converts a Unicode `string` to an array.
  *
  * @private
- * @param {Function} func The function to query.
- * @returns {string} Returns the function name.
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
  */
-function getFuncName(func) {
-  var result = (func.name + ''),
-      array = realNames[result],
-      length = hasOwnProperty.call(realNames, result) ? array.length : 0;
-
-  while (length--) {
-    var data = array[length],
-        otherFunc = data.func;
-    if (otherFunc == null || otherFunc == func) {
-      return data.name;
-    }
-  }
-  return result;
+function unicodeToArray(string) {
+  return string.match(reUnicode) || [];
 }
 
-module.exports = getFuncName;
+module.exports = unicodeToArray;
 
 
 /***/ }),
-/* 799 */
-/***/ ((module) => {
+/* 782 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-/** Used to lookup unminified function names. */
-var realNames = {};
+"use strict";
 
-module.exports = realNames;
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.hasSafariPlugin = exports.hasNetworkInformationPlugin = exports.hasInAppBrowserPlugin = exports.hasDevicePlugin = void 0;
+
+var _cordova = __webpack_require__(772);
 
-/***/ }),
-/* 800 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var hasDevicePlugin = function hasDevicePlugin() {
+  return (0, _cordova.isCordova)() && window.device !== undefined;
+};
+
+exports.hasDevicePlugin = hasDevicePlugin;
+
+var hasInAppBrowserPlugin = function hasInAppBrowserPlugin() {
+  return (0, _cordova.isCordova)() && window.cordova.InAppBrowser !== undefined;
+};
+
+exports.hasInAppBrowserPlugin = hasInAppBrowserPlugin;
 
-var LazyWrapper = __webpack_require__(801),
-    getData = __webpack_require__(796),
-    getFuncName = __webpack_require__(798),
-    lodash = __webpack_require__(802);
+var hasSafariPlugin = function hasSafariPlugin() {
+  return new Promise(function (resolve) {
+    if (!(0, _cordova.isCordova)() || window.SafariViewController === undefined) {
+      resolve(false);
+      return;
+    }
 
+    window.SafariViewController.isAvailable(function (available) {
+      return resolve(available);
+    });
+  });
+};
 /**
- * Checks if `func` has a lazy counterpart.
- *
- * @private
- * @param {Function} func The function to check.
- * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
- *  else `false`.
+ * Check if the Cordova's cordova-plugin-network-information plugin is installed
+ * @see https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-network-information/
+ * @returns {boolean}
  */
-function isLaziable(func) {
-  var funcName = getFuncName(func),
-      other = lodash[funcName];
 
-  if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
-    return false;
-  }
-  if (func === other) {
-    return true;
-  }
-  var data = getData(other);
-  return !!data && func === data[0];
-}
 
-module.exports = isLaziable;
+exports.hasSafariPlugin = hasSafariPlugin;
+
+var hasNetworkInformationPlugin = function hasNetworkInformationPlugin() {
+  return (0, _cordova.isCordova)() && window.navigator.connection !== undefined;
+};
 
+exports.hasNetworkInformationPlugin = hasNetworkInformationPlugin;
 
 /***/ }),
-/* 801 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 783 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-var baseCreate = __webpack_require__(585),
-    baseLodash = __webpack_require__(795);
+"use strict";
 
-/** Used as references for the maximum length and index of an array. */
-var MAX_ARRAY_LENGTH = 4294967295;
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.startApp = exports["default"] = exports.checkApp = void 0;
+
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
+
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
+
+var _platform = __webpack_require__(771);
+
+var cordovaPluginIsInstalled = function cordovaPluginIsInstalled() {
+  return window.startApp;
+};
 
 /**
- * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
- *
- * @private
- * @constructor
- * @param {*} value The value to wrap.
+ * Normalize startApp params for Android and iOS
  */
-function LazyWrapper(value) {
-  this.__wrapped__ = value;
-  this.__actions__ = [];
-  this.__dir__ = 1;
-  this.__filtered__ = false;
-  this.__iteratees__ = [];
-  this.__takeCount__ = MAX_ARRAY_LENGTH;
-  this.__views__ = [];
-}
+var getParams = function getParams(_ref) {
+  var appId = _ref.appId,
+      uri = _ref.uri;
 
-// Ensure `LazyWrapper` is an instance of `baseLodash`.
-LazyWrapper.prototype = baseCreate(baseLodash.prototype);
-LazyWrapper.prototype.constructor = LazyWrapper;
+  if ((0, _platform.isAndroidApp)()) {
+    return {
+      package: appId
+    };
+  } else {
+    return uri;
+  }
+};
 
-module.exports = LazyWrapper;
+var exported = {};
+/**
+ * Start an application if it is installed on the phone
+ * @returns Promise - False if the application was not able to be started
+ */
 
+var startApp = exported.startApp = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(appInfo) {
+    var startAppPlugin, isAppInstalled, params;
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            startAppPlugin = window.startApp;
+            _context.next = 3;
+            return exported.checkApp(appInfo);
 
-/***/ }),
-/* 802 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+          case 3:
+            isAppInstalled = _context.sent;
 
-var LazyWrapper = __webpack_require__(801),
-    LodashWrapper = __webpack_require__(794),
-    baseLodash = __webpack_require__(795),
-    isArray = __webpack_require__(55),
-    isObjectLike = __webpack_require__(53),
-    wrapperClone = __webpack_require__(803);
+            if (!isAppInstalled) {
+              _context.next = 9;
+              break;
+            }
 
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
+            params = getParams(appInfo);
+            return _context.abrupt("return", new Promise(function (resolve, reject) {
+              if (!cordovaPluginIsInstalled()) {
+                reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed. This plugin is needed to start a native app. Required by cozy-bar"));
+                return;
+              }
 
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+              startAppPlugin.set(params).start(resolve, reject);
+            }));
+
+          case 9:
+            return _context.abrupt("return", false);
 
+          case 10:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
+
+  return function (_x) {
+    return _ref2.apply(this, arguments);
+  };
+}();
 /**
- * Creates a `lodash` object which wraps `value` to enable implicit method
- * chain sequences. Methods that operate on and return arrays, collections,
- * and functions can be chained together. Methods that retrieve a single value
- * or may return a primitive value will automatically end the chain sequence
- * and return the unwrapped value. Otherwise, the value must be unwrapped
- * with `_#value`.
- *
- * Explicit chain sequences, which must be unwrapped with `_#value`, may be
- * enabled using `_.chain`.
- *
- * The execution of chained methods is lazy, that is, it's deferred until
- * `_#value` is implicitly or explicitly called.
- *
- * Lazy evaluation allows several methods to support shortcut fusion.
- * Shortcut fusion is an optimization to merge iteratee calls; this avoids
- * the creation of intermediate arrays and can greatly reduce the number of
- * iteratee executions. Sections of a chain sequence qualify for shortcut
- * fusion if the section is applied to an array and iteratees accept only
- * one argument. The heuristic for whether a section qualifies for shortcut
- * fusion is subject to change.
- *
- * Chaining is supported in custom builds as long as the `_#value` method is
- * directly or indirectly included in the build.
- *
- * In addition to lodash methods, wrappers have `Array` and `String` methods.
- *
- * The wrapper `Array` methods are:
- * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
- *
- * The wrapper `String` methods are:
- * `replace` and `split`
- *
- * The wrapper methods that support shortcut fusion are:
- * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
- * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
- * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
- *
- * The chainable wrapper methods are:
- * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
- * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
- * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
- * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
- * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
- * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
- * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
- * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
- * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
- * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
- * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
- * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
- * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
- * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
- * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
- * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
- * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
- * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
- * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
- * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
- * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
- * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
- * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
- * `zipObject`, `zipObjectDeep`, and `zipWith`
- *
- * The wrapper methods that are **not** chainable by default are:
- * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
- * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
- * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
- * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
- * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
- * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
- * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
- * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
- * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
- * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
- * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
- * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
- * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
- * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
- * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
- * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
- * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
- * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
- * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
- * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
- * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
- * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
- * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
- * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
- * `upperFirst`, `value`, and `words`
- *
- * @name _
- * @constructor
- * @category Seq
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns the new `lodash` wrapper instance.
- * @example
- *
- * function square(n) {
- *   return n * n;
- * }
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // Returns an unwrapped value.
- * wrapped.reduce(_.add);
- * // => 6
- *
- * // Returns a wrapped value.
- * var squares = wrapped.map(square);
- *
- * _.isArray(squares);
- * // => false
+ * Check that an application is installed on the phone
+ * @returns Promise - Promise containing information on the application
  *
- * _.isArray(squares.value());
- * // => true
- */
-function lodash(value) {
-  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
-    if (value instanceof LodashWrapper) {
-      return value;
-    }
-    if (hasOwnProperty.call(value, '__wrapped__')) {
-      return wrapperClone(value);
-    }
-  }
-  return new LodashWrapper(value);
-}
-
-// Ensure wrappers are instances of `baseLodash`.
-lodash.prototype = baseLodash.prototype;
-lodash.prototype.constructor = lodash;
+ * @example
+ * > checkApp({ appId: 'io.cozy.drive.mobile', uri: 'cozydrive://' })
+ * Promise.resolve({
+ *  versionName: "0.9.2",
+ *  packageName: "io.cozy.drive.mobile",
+ *  versionCode: 902,
+ *  applicationInfo: "ApplicationInfo{70aa0ef io.cozy.drive.mobile}"
+ * })
+ */
 
-module.exports = lodash;
 
+exports.startApp = startApp;
 
-/***/ }),
-/* 803 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var checkApp = exported.checkApp = /*#__PURE__*/function () {
+  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appInfo) {
+    var startAppPlugin, params;
+    return _regenerator.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            startAppPlugin = window.startApp;
+            params = getParams(appInfo);
+            return _context2.abrupt("return", new Promise(function (resolve, reject) {
+              if (!cordovaPluginIsInstalled()) {
+                reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed."));
+                return;
+              }
 
-var LazyWrapper = __webpack_require__(801),
-    LodashWrapper = __webpack_require__(794),
-    copyArray = __webpack_require__(571);
+              startAppPlugin.set(params).check(function (infos) {
+                return resolve(infos === 'OK' ? true : infos);
+              }, function (error) {
+                if (error === false || error.indexOf('NameNotFoundException') === 0) {
+                  // Plugin returns an error 'NameNotFoundException' on Android and
+                  // false on iOS when an application is not found.
+                  // We prefer to always return false
+                  resolve(false);
+                } else {
+                  reject(error);
+                }
+              });
+            }));
 
-/**
- * Creates a clone of `wrapper`.
- *
- * @private
- * @param {Object} wrapper The wrapper to clone.
- * @returns {Object} Returns the cloned wrapper.
- */
-function wrapperClone(wrapper) {
-  if (wrapper instanceof LazyWrapper) {
-    return wrapper.clone();
-  }
-  var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
-  result.__actions__ = copyArray(wrapper.__actions__);
-  result.__index__  = wrapper.__index__;
-  result.__values__ = wrapper.__values__;
-  return result;
-}
+          case 3:
+          case "end":
+            return _context2.stop();
+        }
+      }
+    }, _callee2);
+  }));
 
-module.exports = wrapperClone;
+  return function (_x2) {
+    return _ref3.apply(this, arguments);
+  };
+}();
 
+exports.checkApp = checkApp;
+var _default = exported;
+exports["default"] = _default;
 
 /***/ }),
-/* 804 */
-/***/ ((__unused_webpack_module, exports) => {
+/* 784 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
+var _interopRequireDefault = __webpack_require__(524);
+
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.hasQueryBeenLoaded = exports.isQueryLoading = exports.cancelable = void 0;
+exports.nativeLinkOpen = void 0;
 
-/**
- * @typedef {Promise} CancelablePromise
- * @property {Function} cancel - Cancel the promise
- */
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-/**
- * Wraps a promise so that it can be canceled
- *
- * Rejects with canceled: true as soon as cancel is called
- *
- * @param  {Promise} promise  - Promise
- * @returns {CancelablePromise} - Promise with .cancel method
- */
-var cancelable = function cancelable(promise) {
-  var _reject;
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-  var wrapped = new Promise(function (resolve, reject) {
-    _reject = reject;
-    promise.then(resolve);
-    promise.catch(reject);
-  }); // @ts-ignore
+var _plugins = __webpack_require__(782);
 
-  wrapped.cancel = function () {
-    _reject({
-      canceled: true
-    });
-  };
+var nativeLinkOpen = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
+    var url, target, options;
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            url = _ref.url;
+            _context.next = 3;
+            return (0, _plugins.hasSafariPlugin)();
 
-  return wrapped;
-};
+          case 3:
+            _context.t0 = _context.sent;
 
-exports.cancelable = cancelable;
+            if (!_context.t0) {
+              _context.next = 6;
+              break;
+            }
 
-/**
- * Returns whether the result of a query (given via queryConnect or Query)
- * is loading.
- */
-var isQueryLoading = function isQueryLoading(col) {
-  if (!col) {
-    console.warn('isQueryLoading called on falsy value.'); // eslint-disable-line no-console
+            _context.t0 = window.SafariViewController;
 
-    return false;
-  }
+          case 6:
+            if (!_context.t0) {
+              _context.next = 10;
+              break;
+            }
 
-  return col.fetchStatus === 'loading' || col.fetchStatus === 'pending';
-};
-/**
- * Returns whether a query has been loaded at least once
- */
+            window.SafariViewController.show({
+              url: url,
+              transition: 'curl'
+            }, function (result) {
+              if (result.event === 'closed') {
+                window.SafariViewController.hide();
+              }
+            }, function () {
+              window.SafariViewController.hide();
+            });
+            _context.next = 11;
+            break;
 
+          case 10:
+            if ((0, _plugins.hasInAppBrowserPlugin)()) {
+              target = '_blank';
+              options = 'clearcache=yes,zoom=no';
+              window.cordova.InAppBrowser.open(url, target, options);
+            } else {
+              window.location = url;
+            }
 
-exports.isQueryLoading = isQueryLoading;
+          case 11:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
 
-var hasQueryBeenLoaded = function hasQueryBeenLoaded(col) {
-  return col.lastFetch;
-};
+  return function nativeLinkOpen(_x) {
+    return _ref2.apply(this, arguments);
+  };
+}();
 
-exports.hasQueryBeenLoaded = hasQueryBeenLoaded;
+exports.nativeLinkOpen = nativeLinkOpen;
 
 /***/ }),
-/* 805 */
-/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+/* 785 */
+/***/ ((__unused_webpack_module, exports) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
-
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.sanitizeCategories = sanitizeCategories;
-exports.areTermsValid = areTermsValid;
-exports.isPartnershipValid = isPartnershipValid;
-exports.sanitize = sanitize;
+exports.openDeeplinkOrRedirect = void 0;
+
+/**
+ * This file is used to open the native app from a webapp
+ * if this native app is installed
+ *
+ * From a webapp, we don't have any clue if a native app is installed.
+ * The only way to know that, is to try to open the custom link
+ * (aka cozydrive://) and if nothing happens (no blur) we redirect to
+ * the callback
+ *
+ * Firefox tries to open custom link, so we need to create an iframe
+ * to detect if this is supported or not
+ */
+var _createHiddenIframe = function _createHiddenIframe(target, uri, randomId) {
+  var iframe = document.createElement('iframe');
+  iframe.src = uri;
+  iframe.id = "hiddenIframe_".concat(randomId);
+  iframe.style.display = 'none';
+  target.appendChild(iframe);
+  return iframe;
+};
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var openUriWithHiddenFrame = function openUriWithHiddenFrame(uri, failCb) {
+  var randomId = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
+  window.addEventListener('blur', onBlur);
 
-var _types = __webpack_require__(610);
+  var iframe = _createHiddenIframe(document.body, 'about:blank', randomId);
 
-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; }
+  var timeout = setTimeout(function () {
+    failCb();
+    window.removeEventListener('blur', onBlur);
+    iframe.parentElement.removeChild(iframe);
+  }, 500);
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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 onBlur() {
+    clearTimeout(timeout);
+    window.removeEventListener('blur', onBlur);
+    iframe.parentElement.removeChild(iframe);
+  }
 
-var APP_CATEGORIES = ['banking', 'cozy', 'energy', 'health', 'host_provider', 'insurance', 'isp', 'mes_infos', 'online_services', 'others', 'partners', 'press', 'productivity', 'ptnb', 'public_service', 'shopping', 'social', 'telecom', 'transport'];
-/** Filters unauthorized categories. Defaults to ['others'] if no suitable category. */
+  iframe.contentWindow.location.href = uri;
+};
 
-function sanitizeCategories(categories) {
-  if (!categories) return ['others'];
-  var filteredList = categories.filter(function (c) {
-    return APP_CATEGORIES.includes(c);
-  });
-  if (!filteredList.length) return ['others'];
-  return filteredList;
-}
+var openUriWithTimeoutHack = function openUriWithTimeoutHack(uri, failCb) {
+  var timeout = setTimeout(function () {
+    failCb();
+    target.removeEventListener('blur', onBlur);
+  }, 500); // handle page running in an iframe (blur must be registered with top level window)
 
-function areTermsValid(terms) {
-  return Boolean(terms && terms.id && terms.url && terms.version);
-}
+  var target = window;
 
-function isPartnershipValid(partnership) {
-  return Boolean(partnership && partnership.description);
-}
+  while (target != target.parent) {
+    target = target.parent;
+  }
+
+  target.addEventListener('blur', onBlur);
+
+  function onBlur() {
+    clearTimeout(timeout);
+    target.removeEventListener('blur', onBlur);
+  } // Why is an uri assigned to location object?
+
+
+  window.location = uri;
+};
+
+var openUriWithMsLaunchUri = function openUriWithMsLaunchUri(uri, failCb) {
+  navigator.msLaunchUri(uri, undefined, failCb);
+};
+
+var checkBrowser = function checkBrowser() {
+  var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
+  var ua = navigator.userAgent.toLowerCase();
+  var isSafari = ua.includes('safari') && !ua.includes('chrome') || Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
+  var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
+  var isIOS122 = isIOS && (ua.includes('os 12_2') || ua.includes('os 12_3'));
+  return {
+    isOpera: isOpera,
+    isFirefox: typeof window.InstallTrigger !== 'undefined',
+    isSafari: isSafari,
+    isChrome: !!window.chrome && !isOpera,
+    isIOS122: isIOS122,
+    isIOS: isIOS
+  };
+};
 /**
- * Normalize app manifest, retrocompatibility for old manifests
  *
- * @param  {Manifest} manifest
- * @returns {Manifest}
+ * @param {String} deeplink (cozydrive://)
+ * @param {String} failCb (http://drive.cozy.ios)
  */
 
 
-function sanitize(manifest) {
-  var sanitized = _objectSpread({}, manifest); // Make categories an array and delete category attribute if it exists
-
+var openDeeplinkOrRedirect = function openDeeplinkOrRedirect(deeplink, failCb) {
+  if (navigator.msLaunchUri) {
+    // for IE and Edge in Win 8 and Win 10
+    openUriWithMsLaunchUri(deeplink, failCb);
+  } else {
+    var browser = checkBrowser();
 
-  if (!manifest.categories && manifest.category && typeof manifest.category === 'string') {
-    sanitized.categories = [manifest.category];
-    delete sanitized.category;
+    if (browser.isChrome || browser.isIOS && !browser.isIOS122) {
+      openUriWithTimeoutHack(deeplink, failCb);
+    } else if (browser.isSafari && !browser.isIOS122 || browser.isFirefox) {
+      openUriWithHiddenFrame(deeplink, failCb);
+    } else {
+      failCb();
+    }
   }
+};
 
-  sanitized.categories = sanitizeCategories(sanitized.categories); // manifest name is not an object
+exports.openDeeplinkOrRedirect = openDeeplinkOrRedirect;
 
-  if (typeof manifest.name === 'object') sanitized.name = manifest.name.en; // Fix camelCase from cozy-stack
+/***/ }),
+/* 786 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-  if (manifest.available_version) {
-    sanitized.availableVersion = manifest.available_version;
-    delete sanitized.available_version;
-  } // Fix camelCase from cozy-stack
+"use strict";
 
 
-  if (manifest.latest_version) {
-    sanitized.latestVersion = manifest.latestVersion;
-    delete sanitized.latest_version;
-  } // Remove invalid terms
+var _interopRequireDefault = __webpack_require__(524);
 
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.isFlagshipApp = exports.getFlagshipMetadata = exports.FlagshipRoutes = void 0;
 
-  if (sanitized.terms && !areTermsValid(sanitized.terms)) {
-    delete sanitized.terms;
-  } // Remove invalid partnership
+var _cozyLogger = _interopRequireDefault(__webpack_require__(354));
 
+var FlagshipRoutes;
+exports.FlagshipRoutes = FlagshipRoutes;
 
-  if (sanitized.partnership && !isPartnershipValid(sanitized.partnership)) {
-    delete sanitized.partnership;
+(function (FlagshipRoutes) {
+  FlagshipRoutes["Home"] = "home";
+  FlagshipRoutes["Cozyapp"] = "cozyapp";
+  FlagshipRoutes["Authenticate"] = "authenticate";
+  FlagshipRoutes["Onboarding"] = "onboarding";
+  FlagshipRoutes["Stack"] = "stack";
+})(FlagshipRoutes || (exports.FlagshipRoutes = FlagshipRoutes = {}));
+
+var getGlobalWindow = function getGlobalWindow() {
+  if (typeof window !== 'undefined') return window;else {
+    (0, _cozyLogger.default)('error', "\"window\" is not defined. This means that getGlobalWindow() shouldn't have been called and investigation should be done to prevent this call");
+    return undefined;
   }
+};
 
-  return sanitized;
-}
+var getFlagshipMetadata = function getFlagshipMetadata() {
+  var _getGlobalWindow, _getGlobalWindow$cozy;
+
+  return ((_getGlobalWindow = getGlobalWindow()) === null || _getGlobalWindow === void 0 ? void 0 : (_getGlobalWindow$cozy = _getGlobalWindow.cozy) === null || _getGlobalWindow$cozy === void 0 ? void 0 : _getGlobalWindow$cozy.flagship) || {};
+};
+
+exports.getFlagshipMetadata = getFlagshipMetadata;
+
+var isFlagshipApp = function isFlagshipApp() {
+  var _getGlobalWindow2, _getGlobalWindow2$coz;
+
+  return ((_getGlobalWindow2 = getGlobalWindow()) === null || _getGlobalWindow2 === void 0 ? void 0 : (_getGlobalWindow2$coz = _getGlobalWindow2.cozy) === null || _getGlobalWindow2$coz === void 0 ? void 0 : _getGlobalWindow2$coz.flagship) !== undefined;
+};
+
+exports.isFlagshipApp = isFlagshipApp;
 
 /***/ }),
-/* 806 */
+/* 787 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.createMockClient = void 0;
+exports["default"] = void 0;
 
-var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520));
+var _mapValues = _interopRequireDefault(__webpack_require__(545));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _groupBy2 = _interopRequireDefault(__webpack_require__(736));
 
-var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525));
+var _flatten = _interopRequireDefault(__webpack_require__(552));
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+var _isEqual = _interopRequireDefault(__webpack_require__(658));
 
-var _store = __webpack_require__(693);
+var _uniq = _interopRequireDefault(__webpack_require__(624));
 
-var _cozyStackClient = __webpack_require__(559);
+var _uniqWith = _interopRequireDefault(__webpack_require__(788));
 
-var _dsl = __webpack_require__(607);
+var _dsl = __webpack_require__(619);
 
-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; }
+var isIdQuery = function isIdQuery(query) {
+  return query.id || query.ids;
+};
+/**
+ * Optimize queries on a single doctype
+ *
+ * @param  {QueryDefinition[]} queries - Queries of a same doctype
+ * @returns {QueryDefinition[]} Optimized queries
+ * @private
+ */
 
-function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var fillQueryInsideClient = function fillQueryInsideClient(client, queryName, queryOptions) {
-  var definition = queryOptions.definition,
-      doctype = queryOptions.doctype,
-      data = queryOptions.data,
-      queryResult = (0, _objectWithoutProperties2.default)(queryOptions, ["definition", "doctype", "data"]);
-  client.store.dispatch((0, _store.initQuery)(queryName, definition || (0, _dsl.Q)(doctype)));
-  client.store.dispatch((0, _store.receiveQueryResult)(queryName, _objectSpread({
-    data: data ? data.map(function (doc) {
-      return (0, _cozyStackClient.normalizeDoc)(doc, doctype);
-    }) : data
-  }, queryResult)));
+var optimizeDoctypeQueries = function optimizeDoctypeQueries(queries) {
+  var _groupBy = (0, _groupBy2.default)(queries, function (q) {
+    return isIdQuery(q) ? 'idQueries' : 'others';
+  }),
+      _groupBy$idQueries = _groupBy.idQueries,
+      idQueries = _groupBy$idQueries === void 0 ? [] : _groupBy$idQueries,
+      _groupBy$others = _groupBy.others,
+      others = _groupBy$others === void 0 ? [] : _groupBy$others;
+
+  var groupedIdQueries = idQueries.length > 0 ? new _dsl.QueryDefinition({
+    doctype: queries[0].doctype,
+    ids: (0, _uniq.default)((0, _flatten.default)(idQueries.map(function (q) {
+      return q.id || q.ids;
+    })))
+  }) : []; // Deduplicate before concataining
+
+  return (0, _uniqWith.default)(others, _isEqual.default).concat(groupedIdQueries);
 };
+/**
+ * Reduce the number of queries used to fetch documents.
+ *
+ * - Deduplication of queries
+ * - Groups id queries
+ *
+ * @param  {QueryDefinition[]} queries - Queries to optimized
+ * @returns {QueryDefinition[]} Optimized queries
+ * @private
+ */
 
-var mockedQueryFromMockedRemoteData = function mockedQueryFromMockedRemoteData(remoteData) {
-  return function (qdef) {
-    if (!remoteData) {
-      return {
-        data: null
-      };
-    }
 
-    if (remoteData[qdef.doctype]) {
-      return {
-        data: remoteData[qdef.doctype]
-      };
-    } else {
-      return {
-        data: []
-      };
-    }
-  };
+var optimizeQueries = function optimizeQueries(queries) {
+  var byDoctype = (0, _groupBy2.default)(queries, function (q) {
+    return q.doctype;
+  });
+  return (0, _flatten.default)(Object.values((0, _mapValues.default)(byDoctype, optimizeDoctypeQueries)));
 };
+
+var _default = optimizeQueries;
+exports["default"] = _default;
+
+/***/ }),
+/* 788 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var baseUniq = __webpack_require__(475);
+
 /**
- * Creates a client suitable for use in tests
+ * This method is like `_.uniq` except that it accepts `comparator` which
+ * is invoked to compare elements of `array`. The order of result values is
+ * determined by the order they occur in the array.The comparator is invoked
+ * with two arguments: (arrVal, othVal).
  *
- * - client.{query,save} are mocked
- * - client.stackClient.fetchJSON is mocked
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
  *
- * @param  {object} options Options
- * @param  {object} [options.queries] Prefill queries inside the store
- * @param  {object} [options.remote] Mock data from the server
- * @param  {object} [options.clientOptions] Options passed to the client
- * @returns {CozyClient}
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.uniqWith(objects, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
  */
+function uniqWith(array, comparator) {
+  comparator = typeof comparator == 'function' ? comparator : undefined;
+  return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
+}
 
+module.exports = uniqWith;
 
-var createMockClient = function createMockClient(_ref) {
-  var queries = _ref.queries,
-      remote = _ref.remote,
-      clientOptions = _ref.clientOptions;
-  var client = new _CozyClient.default(clientOptions || {});
-  client.ensureStore();
 
-  for (var _i = 0, _Object$entries = Object.entries(queries || {}); _i < _Object$entries.length; _i++) {
-    var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
-        queryName = _Object$entries$_i[0],
-        queryOptions = _Object$entries$_i[1];
+/***/ }),
+/* 789 */
+/***/ ((__unused_webpack_module, exports) => {
 
-    fillQueryInsideClient(client, queryName, queryOptions);
-  }
+"use strict";
 
-  client.query = jest.fn().mockImplementation(mockedQueryFromMockedRemoteData(remote));
-  client.save = jest.fn();
-  client.saveAll = jest.fn();
-  client.stackClient.fetchJSON = jest.fn();
-  return client;
-};
 
-exports.createMockClient = createMockClient;
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
+
+/**
+ * Use those fetch policies with `<Query />` to limit the number of re-fetch.
+ *
+ * @example
+ * ```
+ * import { fetchPolicies } from 'cozy-client'
+ * const olderThan30s = fetchPolicies.olderThan(30 * 1000)
+ * <Query fetchPolicy={olderThan30s} />
+ * ```
+ */
+var fetchPolicies = {
+  /**
+   * Returns a fetchPolicy that will only re-fetch queries that are older
+   * than `<delay>` ms.
+   *
+   * @param  {number} delay - Milliseconds since the query has been fetched
+   * @returns {Function} Fetch policy to be used with `<Query />`
+   */
+  olderThan: function olderThan(delay) {
+    return function (queryState) {
+      if (!queryState || !queryState.lastUpdate) {
+        return true;
+      } else {
+        var elapsed = Date.now() - queryState.lastUpdate;
+        return elapsed > delay;
+      }
+    };
+  },
+
+  /**
+   * Fetch policy that deactivates any fetching.
+   */
+  noFetch: function noFetch() {
+    return false;
+  }
+};
+var _default = fetchPolicies;
+exports["default"] = _default;
 
 /***/ }),
-/* 807 */
-/***/ ((module, exports, __webpack_require__) => {
+/* 790 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
-/* module decorator */ module = __webpack_require__.nmd(module);
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.createClientInteractive = void 0;
+exports["default"] = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _http = _interopRequireDefault(__webpack_require__(80));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _open = _interopRequireDefault(__webpack_require__(808));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _fs = _interopRequireDefault(__webpack_require__(149));
+var _keyBy = _interopRequireDefault(__webpack_require__(711));
+
+var _mapValues = _interopRequireDefault(__webpack_require__(545));
 
-var _merge = _interopRequireDefault(__webpack_require__(742));
+var _merge = _interopRequireDefault(__webpack_require__(754));
 
-var _serverDestroy = _interopRequireDefault(__webpack_require__(812));
+var _size = _interopRequireDefault(__webpack_require__(791));
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+var _intersectionBy = _interopRequireDefault(__webpack_require__(795));
 
-var _cozyLogger = _interopRequireDefault(__webpack_require__(813));
+var _associations = __webpack_require__(703);
 
 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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-var log = _cozyLogger.default.namespace('create-cli-client');
+/**
+ * @typedef {object} DoctypeSchema
+ */
 
-var nodeFetch = __webpack_require__(481);
+/**
+ * @typedef {Record<string, DoctypeSchema>} SchemaDefinition
+ */
 
-var btoa = __webpack_require__(478);
 /**
- * Creates and starts and HTTP server suitable for OAuth authentication
- *
- * @param  {object} serverOptions - OAuth callback server options
- * @param  {Function} serverOptions.onAuthentication - Additional callback called
- * when the user authenticates
- * @param  {string} serverOptions.route - Route used for authentication
- * @param  {number} serverOptions.port - Port on which the server will listen
- * @param  {Function} serverOptions.onListen - Callback called when the
- * server starts
- *
- * @typedef {object} DestroyableServer
- * @function destroy
+ * Returns a normalized schema object from the schema definition.
  *
- * @returns {DestroyableServer}
+ * - Relationships are resolved to classes if needed
+ * - The name of the relationship (its key in the schema definition)
+ *   is included in the relationship
+ * - Empty relationships are nulled
  *
  * @private
  */
+var normalizeDoctypeSchema = function normalizeDoctypeSchema(doctypeSchema) {
+  var relationships = (0, _mapValues.default)(doctypeSchema.relationships || {}, function (v, k) {
+    return _objectSpread(_objectSpread({}, v), {}, {
+      name: k,
+      type: (0, _associations.resolveClass)(v.doctype, v.type)
+    });
+  });
+  return _objectSpread(_objectSpread({}, doctypeSchema), {}, {
+    relationships: (0, _size.default)(relationships) > 0 ? (0, _keyBy.default)(relationships, 'name') : null
+  });
+};
 
+var assert = function assert(predicate, errorMessage) {
+  if (!predicate) throw new Error(errorMessage);
+};
 
-var createCallbackServer = function createCallbackServer(serverOptions) {
-  var route = serverOptions.route,
-      onListen = serverOptions.onListen,
-      onAuthentication = serverOptions.onAuthentication,
-      port = serverOptions.port;
-
-  var server = _http.default.createServer(function (request, response) {
-    if (request.url.indexOf(route) === 0) {
-      onAuthentication(request.url);
-      response.write('Authentication successful, you can close this page.');
-      response.end();
-    }
+var ensureCanBeAdded = function ensureCanBeAdded(newSchemas, existingSchemas) {
+  var sameNames = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) {
+    return x.name;
   });
-
-  server.listen(port, function () {
-    onListen();
+  assert(sameNames.length === 0, "Duplicated names in schemas being added: ".concat(sameNames.map(function (x) {
+    return x.name;
+  }).join(', ')));
+  var sameDoctypes = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) {
+    return x.doctype;
   });
-  (0, _serverDestroy.default)(server);
-  return server;
+  assert(sameDoctypes.length === 0, "Duplicated doctypes in schemas being added: ".concat(sameDoctypes.map(function (x) {
+    return x.name;
+  }).join(', ')));
 };
 /**
- * Creates a function suitable for usage with CozyClient::startOAuthFlow
- *
- * Starts a local server. The stack upon user authentication will
- * redirect to this local server with a URL containing credentials.
- * The callback resolves with this authenticationURL which continues
- * the authentication flow inside startOAuthFlow.
- *
- * When the server is started, the authentication page is opened on the
- * desktop browser of the user.
+ * Stores information on a particular doctype.
  *
- * @param {object} serverOptions - Options for the OAuth callback server
- * @param {number} serverOptions.port - Port used for the OAuth callback server
- * @param {Function} serverOptions.onAuthentication - Callback when the user authenticates
- * @param {Function} serverOptions.onListen - Callback called with the authentication URL
- * @param {string} serverOptions.route - Route used for authentication
- * @param {boolean} serverOptions.shouldOpenAuthenticationPage - Whether the authentication
- * page should be automatically opened (default: true)
+ * - Attribute validation
+ * - Relationship access
  *
- * @private
+ * ```js
+ * const schema = new Schema({
+ *   todos: {
+ *     attributes: {
+ *       label: {
+ *         unique: true
+ *       }
+ *     },
+ *     relationships: {
+ *       author: 'has-one-in-place'
+ *     }
+ *   }
+ * }, cozyStackClient)
+ * ```
  */
 
 
-var mkServerFlowCallback = function mkServerFlowCallback(serverOptions) {
-  return function (authenticationURL) {
-    return new Promise(function (resolve, reject) {
-      var rejectTimeout, successTimeout;
-      var server = createCallbackServer(_objectSpread(_objectSpread({}, serverOptions), {}, {
-        onAuthentication: function onAuthentication(callbackURL) {
-          log('debug', 'Authenticated, Shutting server down');
-          successTimeout = setTimeout(function () {
-            // Is there a way to call destroy only after all requests have
-            // been completely served ? Otherwise we close the server while
-            // the successful oauth page is being served and the page does
-            // not get loaded on the client side.
-            server.destroy();
-            resolve('http://localhost:8000/' + callbackURL);
-            clearTimeout(rejectTimeout);
-          }, 300);
-        },
-        onListen: function onListen() {
-          log('debug', 'OAuth callback server started, waiting for authentication');
+var Schema = /*#__PURE__*/function () {
+  /**
+   * @param  {SchemaDefinition} schemaDefinition - Schema for the application documents
+   * @param  {object} client - An instance of cozy client (optional)
+   */
+  function Schema() {
+    var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+    var client = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
+    (0, _classCallCheck2.default)(this, Schema);
+    this.byDoctype = {};
+    this.add(schemaDefinition);
+    this.client = client;
+  }
+  /**
+   * @param {SchemaDefinition} schemaDefinition - Additional schema to merge to current schema
+   */
 
-          if (serverOptions.shouldOpenAuthenticationPage !== false) {
-            (0, _open.default)(authenticationURL, {
-              wait: false
-            });
-          }
 
-          if (serverOptions.onListen) {
-            serverOptions.onListen({
-              authenticationURL: authenticationURL
-            });
-          }
-        }
+  (0, _createClass2.default)(Schema, [{
+    key: "add",
+    value: function add() {
+      var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+      var normalizedSchemaDefinition = (0, _mapValues.default)(schemaDefinition, function (obj, name) {
+        return _objectSpread({
+          name: name
+        }, normalizeDoctypeSchema(obj));
+      });
+      ensureCanBeAdded(Object.values(normalizedSchemaDefinition), Object.values(this.byDoctype));
+      (0, _merge.default)(this.byDoctype, (0, _keyBy.default)(normalizedSchemaDefinition, function (x) {
+        return x.doctype;
       }));
-      rejectTimeout = setTimeout(function () {
-        clearTimeout(successTimeout);
-        server.destroy();
-        reject('Timeout for authentication');
-      }, 30 * 1000);
-    });
-  };
-};
-
-var hashCode = function hashCode(str) {
-  var hash = 0,
-      i,
-      chr;
-  if (str.length === 0) return hash;
+    }
+    /**
+     * Returns the schema for a doctype
+     *
+     * Creates an empty schema implicitly if it does not exist
+     *
+     * @param {string} doctype - Doctype
+     */
 
-  for (i = 0; i < str.length; i++) {
-    chr = str.charCodeAt(i);
-    hash = (hash << 5) - hash + chr;
-    hash |= 0; // Convert to 32bit integer
-  }
+  }, {
+    key: "getDoctypeSchema",
+    value: function getDoctypeSchema(doctype) {
+      var schema = this.byDoctype[doctype];
 
-  return hash;
-};
+      if (!schema) {
+        schema = normalizeDoctypeSchema({
+          name: doctype,
+          doctype: doctype
+        });
+        this.byDoctype[doctype] = schema;
+      }
 
-var DEFAULT_SERVER_OPTIONS = {
-  port: 3333,
-  route: '/do_access',
-  getSavedCredentials: function getSavedCredentials(clientOptions) {
-    if (!clientOptions.oauth.softwareID) {
-      throw new Error('Please provide oauth.softwareID in your clientOptions.');
+      return schema;
     }
+    /**
+     * Returns the relationship for a given doctype/name
+     *
+     * @param {string} doctype - Doctype
+     * @param {string} relationshipName - Relationship name
+     */
 
-    var doctypeHash = Math.abs(hashCode(JSON.stringify(clientOptions.scope)));
-    var sluggedURI = clientOptions.uri.replace(/https?:\/\//, '').replace(/\./g, '-');
-    return "/tmp/cozy-client-oauth-".concat(sluggedURI, "-").concat(clientOptions.oauth.softwareID, "-").concat(doctypeHash, ".json");
-  }
-};
+  }, {
+    key: "getRelationship",
+    value: function getRelationship(doctype, relationshipName) {
+      if (!doctype) {
+        throw new TypeError("Invalid doctype ".concat(doctype));
+      }
 
-var writeJSON = function writeJSON(fs, filename, data) {
-  fs.writeFileSync(filename, JSON.stringify(data));
-};
-/**
- * Parses a JSON from a file
- * Returns null in case of error
- *
- * @private
- */
+      var schema = this.getDoctypeSchema(doctype);
+
+      if (!schema) {
+        throw new Error("Cannot find doctype ".concat(doctype, " in schema"));
+      }
 
+      if (!schema.relationships) {
+        throw new Error("Schema for doctype ".concat(doctype, " has no relationships"));
+      }
 
-var readJSON = function readJSON(fs, filename) {
-  try {
-    if (!fs.existsSync(filename)) {
-      return null;
+      return schema.relationships[relationshipName];
     }
+    /**
+     * Validates a document considering the descriptions in schema.attributes.
+     */
 
-    var res = JSON.parse(fs.readFileSync(filename).toString());
-    return res;
-  } catch (e) {
-    console.warn("Could not load ".concat(filename, " (").concat(e.message, ")"));
-    return null;
-  }
-};
-/**
- * Creates a client with interactive authentication.
- *
- * - Will start an OAuth flow and open an authentication page
- * - Starts a local server to listen for the oauth callback
- * - Resolves with the client after user authentication
- *
- * @param {object} clientOptions Same as CozyClient::constructor.
- *
- * @example
- * ```
- * import { createClientInteractive } from 'cozy-client/dist/cli'
- * await createClientInteractive({
- *   uri: 'http://cozy.tools:8080',
- *   scope: ['io.cozy.bills'],
- *   oauth: {
- *     softwareID: 'my-cli-application-using-bills'
- *   }
- * })
- * ```
- *
- * @returns {Promise<CozyClient>} - A client that is ready with a token
- */
+  }, {
+    key: "validate",
+    value: function () {
+      var _validate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(document) {
+        var errors, schema, n, ret;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                errors = {};
+                schema = this.byDoctype[document._type];
 
+                if (schema) {
+                  _context.next = 4;
+                  break;
+                }
 
-var createClientInteractive = function createClientInteractive(clientOptions, serverOpts) {
-  global.fetch = nodeFetch;
-  global.btoa = btoa;
-  var serverOptions = (0, _merge.default)(DEFAULT_SERVER_OPTIONS, serverOpts);
-  var createClientFS = serverOptions.fs || _fs.default;
-  var mergedClientOptions = (0, _merge.default)({
-    oauth: {
-      clientName: 'cli-client',
-      redirectURI: "http://localhost:".concat(serverOptions.port).concat(serverOptions.route)
-    }
-  }, clientOptions);
+                return _context.abrupt("return", true);
 
-  if (!clientOptions.scope) {
-    throw new Error('scope must be provided in client options');
-  }
+              case 4:
+                if (schema.attributes) {
+                  _context.next = 6;
+                  break;
+                }
 
-  var getSavedCredentials = serverOptions.getSavedCredentials;
-  var savedCredentialsFilename = getSavedCredentials(mergedClientOptions);
-  var savedCredentials = readJSON(createClientFS, savedCredentialsFilename);
-  log('debug', "Starting OAuth flow");
-  return new Promise( /*#__PURE__*/function () {
-    var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(resolve, reject) {
-      var client;
-      return _regenerator.default.wrap(function _callee$(_context) {
-        while (1) {
-          switch (_context.prev = _context.next) {
-            case 0:
-              client = new _CozyClient.default(mergedClientOptions);
+                return _context.abrupt("return", true);
 
-              if (!savedCredentials) {
+              case 6:
+                _context.t0 = _regenerator.default.keys(schema.attributes);
+
+              case 7:
+                if ((_context.t1 = _context.t0()).done) {
+                  _context.next = 15;
+                  break;
+                }
+
+                n = _context.t1.value;
+                _context.next = 11;
+                return this.validateAttribute(document, n, schema.attributes[n]);
+
+              case 11:
+                ret = _context.sent;
+                if (ret !== true) errors[n] = ret;
                 _context.next = 7;
                 break;
-              }
 
-              log('debug', "Using saved credentials in ".concat(savedCredentialsFilename));
-              client.stackClient.setToken(savedCredentials.token);
-              client.stackClient.setOAuthOptions(savedCredentials.oauthOptions);
-              resolve(client);
-              return _context.abrupt("return");
+              case 15:
+                if (!(Object.keys(errors).length === 0)) {
+                  _context.next = 17;
+                  break;
+                }
 
-            case 7:
-              _context.next = 9;
-              return client.startOAuthFlow(mkServerFlowCallback(serverOptions));
+                return _context.abrupt("return", true);
 
-            case 9:
-              resolve(client);
-              log('debug', "Saving credentials to ".concat(savedCredentialsFilename));
-              writeJSON(createClientFS, savedCredentialsFilename, {
-                oauthOptions: client.stackClient.oauthOptions,
-                token: client.stackClient.token
-              });
+              case 17:
+                return _context.abrupt("return", errors);
 
-            case 12:
-            case "end":
-              return _context.stop();
+              case 18:
+              case "end":
+                return _context.stop();
+            }
           }
-        }
-      }, _callee);
-    }));
+        }, _callee, this);
+      }));
 
-    return function (_x, _x2) {
-      return _ref.apply(this, arguments);
-    };
-  }());
-};
+      function validate(_x) {
+        return _validate.apply(this, arguments);
+      }
 
-exports.createClientInteractive = createClientInteractive;
+      return validate;
+    }()
+  }, {
+    key: "validateAttribute",
+    value: function () {
+      var _validateAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(document, attrName, attrProps) {
+        var ret;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                if (!(attrProps.unique && this.client)) {
+                  _context2.next = 6;
+                  break;
+                }
 
-var main = /*#__PURE__*/function () {
-  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
-    var client;
-    return _regenerator.default.wrap(function _callee2$(_context2) {
-      while (1) {
-        switch (_context2.prev = _context2.next) {
-          case 0:
-            _context2.next = 2;
-            return createClientInteractive({
-              scope: ['io.cozy.files'],
-              uri: 'http://cozy.tools:8080',
-              oauth: {
-                softwareID: 'io.cozy.client.cli'
-              }
-            });
+                _context2.next = 3;
+                return this.client.collection(document._type).checkUniquenessOf(attrName, document[attrName]);
 
-          case 2:
-            client = _context2.sent;
-            console.log(client.toJSON());
+              case 3:
+                ret = _context2.sent;
 
-          case 4:
-          case "end":
-            return _context2.stop();
-        }
+                if (!(ret !== true)) {
+                  _context2.next = 6;
+                  break;
+                }
+
+                return _context2.abrupt("return", 'must be unique');
+
+              case 6:
+                return _context2.abrupt("return", true);
+
+              case 7:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
+
+      function validateAttribute(_x2, _x3, _x4) {
+        return _validateAttribute.apply(this, arguments);
       }
-    }, _callee2);
-  }));
 
-  return function main() {
-    return _ref2.apply(this, arguments);
-  };
-}();
+      return validateAttribute;
+    }()
+  }]);
+  return Schema;
+}();
+
+var _default = Schema;
+exports["default"] = _default;
+
+/***/ }),
+/* 791 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+
+var baseKeys = __webpack_require__(454),
+    getTag = __webpack_require__(459),
+    isArrayLike = __webpack_require__(458),
+    isString = __webpack_require__(54),
+    stringSize = __webpack_require__(792);
+
+/** `Object#toString` result references. */
+var mapTag = '[object Map]',
+    setTag = '[object Set]';
+
+/**
+ * Gets the size of `collection` by returning its length for array-like
+ * values or the number of own enumerable string keyed properties for objects.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to inspect.
+ * @returns {number} Returns the collection size.
+ * @example
+ *
+ * _.size([1, 2, 3]);
+ * // => 3
+ *
+ * _.size({ 'a': 1, 'b': 2 });
+ * // => 2
+ *
+ * _.size('pebbles');
+ * // => 7
+ */
+function size(collection) {
+  if (collection == null) {
+    return 0;
+  }
+  if (isArrayLike(collection)) {
+    return isString(collection) ? stringSize(collection) : collection.length;
+  }
+  var tag = getTag(collection);
+  if (tag == mapTag || tag == setTag) {
+    return collection.size;
+  }
+  return baseKeys(collection).length;
+}
+
+module.exports = size;
 
-if (__webpack_require__.c[__webpack_require__.s] === module) {
-  main().catch(function (e) {
-    console.error(e);
-    process.exit(1);
-  });
-}
 
 /***/ }),
-/* 808 */
+/* 792 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-"use strict";
-
-const {promisify} = __webpack_require__(64);
-const path = __webpack_require__(142);
-const childProcess = __webpack_require__(809);
-const fs = __webpack_require__(149);
-const isWsl = __webpack_require__(810);
-const isDocker = __webpack_require__(811);
-
-const pAccess = promisify(fs.access);
-const pReadFile = promisify(fs.readFile);
-
-// Path to included `xdg-open`.
-const localXdgOpenPath = path.join(__dirname, 'xdg-open');
+var asciiSize = __webpack_require__(793),
+    hasUnicode = __webpack_require__(778),
+    unicodeSize = __webpack_require__(794);
 
 /**
-Get the mount point for fixed drives in WSL.
+ * Gets the number of symbols in `string`.
+ *
+ * @private
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the string size.
+ */
+function stringSize(string) {
+  return hasUnicode(string)
+    ? unicodeSize(string)
+    : asciiSize(string);
+}
 
-@inner
-@returns {string} The mount point.
-*/
-const getWslDrivesMountPoint = (() => {
-	// Default value for "root" param
-	// according to https://docs.microsoft.com/en-us/windows/wsl/wsl-config
-	const defaultMountPoint = '/mnt/';
+module.exports = stringSize;
 
-	let mountPoint;
 
-	return async function () {
-		if (mountPoint) {
-			// Return memoized mount point value
-			return mountPoint;
-		}
+/***/ }),
+/* 793 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-		const configFilePath = '/etc/wsl.conf';
+var baseProperty = __webpack_require__(473);
 
-		let isConfigFileExists = false;
-		try {
-			await pAccess(configFilePath, fs.constants.F_OK);
-			isConfigFileExists = true;
-		} catch (_) {}
+/**
+ * Gets the size of an ASCII `string`.
+ *
+ * @private
+ * @param {string} string The string inspect.
+ * @returns {number} Returns the string size.
+ */
+var asciiSize = baseProperty('length');
 
-		if (!isConfigFileExists) {
-			return defaultMountPoint;
-		}
+module.exports = asciiSize;
 
-		const configContent = await pReadFile(configFilePath, {encoding: 'utf8'});
-		const configMountPoint = /root\s*=\s*(.*)/g.exec(configContent);
 
-		if (!configMountPoint) {
-			return defaultMountPoint;
-		}
+/***/ }),
+/* 794 */
+/***/ ((module) => {
 
-		mountPoint = configMountPoint[1].trim();
-		mountPoint = mountPoint.endsWith('/') ? mountPoint : mountPoint + '/';
+/** Used to compose unicode character classes. */
+var rsAstralRange = '\\ud800-\\udfff',
+    rsComboMarksRange = '\\u0300-\\u036f',
+    reComboHalfMarksRange = '\\ufe20-\\ufe2f',
+    rsComboSymbolsRange = '\\u20d0-\\u20ff',
+    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
+    rsVarRange = '\\ufe0e\\ufe0f';
 
-		return mountPoint;
-	};
-})();
+/** Used to compose unicode capture groups. */
+var rsAstral = '[' + rsAstralRange + ']',
+    rsCombo = '[' + rsComboRange + ']',
+    rsFitz = '\\ud83c[\\udffb-\\udfff]',
+    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
+    rsNonAstral = '[^' + rsAstralRange + ']',
+    rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+    rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+    rsZWJ = '\\u200d';
 
-module.exports = async (target, options) => {
-	if (typeof target !== 'string') {
-		throw new TypeError('Expected a `target`');
-	}
+/** Used to compose unicode regexes. */
+var reOptMod = rsModifier + '?',
+    rsOptVar = '[' + rsVarRange + ']?',
+    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+    rsSeq = rsOptVar + reOptMod + rsOptJoin,
+    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
 
-	options = {
-		wait: false,
-		background: false,
-		allowNonzeroExitCode: false,
-		...options
-	};
+/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
 
-	let command;
-	let {app} = options;
-	let appArguments = [];
-	const cliArguments = [];
-	const childProcessOptions = {};
+/**
+ * Gets the size of a Unicode `string`.
+ *
+ * @private
+ * @param {string} string The string inspect.
+ * @returns {number} Returns the string size.
+ */
+function unicodeSize(string) {
+  var result = reUnicode.lastIndex = 0;
+  while (reUnicode.test(string)) {
+    ++result;
+  }
+  return result;
+}
 
-	if (Array.isArray(app)) {
-		appArguments = app.slice(1);
-		app = app[0];
-	}
+module.exports = unicodeSize;
 
-	if (process.platform === 'darwin') {
-		command = 'open';
 
-		if (options.wait) {
-			cliArguments.push('--wait-apps');
-		}
+/***/ }),
+/* 795 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-		if (options.background) {
-			cliArguments.push('--background');
-		}
+var arrayMap = __webpack_require__(410),
+    baseIntersection = __webpack_require__(740),
+    baseIteratee = __webpack_require__(413),
+    baseRest = __webpack_require__(556),
+    castArrayLikeObject = __webpack_require__(741),
+    last = __webpack_require__(627);
 
-		if (app) {
-			cliArguments.push('-a', app);
-		}
-	} else if (process.platform === 'win32' || (isWsl && !isDocker())) {
-		const mountPoint = await getWslDrivesMountPoint();
+/**
+ * This method is like `_.intersection` except that it accepts `iteratee`
+ * which is invoked for each element of each `arrays` to generate the criterion
+ * by which they're compared. The order and references of result values are
+ * determined by the first array. The iteratee is invoked with one argument:
+ * (value).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of intersecting values.
+ * @example
+ *
+ * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+ * // => [2.1]
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }]
+ */
+var intersectionBy = baseRest(function(arrays) {
+  var iteratee = last(arrays),
+      mapped = arrayMap(arrays, castArrayLikeObject);
 
-		command = isWsl ?
-			`${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` :
-			`${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
+  if (iteratee === last(mapped)) {
+    iteratee = undefined;
+  } else {
+    mapped.pop();
+  }
+  return (mapped.length && mapped[0] === arrays[0])
+    ? baseIntersection(mapped, baseIteratee(iteratee, 2))
+    : [];
+});
 
-		cliArguments.push(
-			'-NoProfile',
-			'-NonInteractive',
-			'–ExecutionPolicy',
-			'Bypass',
-			'-EncodedCommand'
-		);
+module.exports = intersectionBy;
 
-		if (!isWsl) {
-			childProcessOptions.windowsVerbatimArguments = true;
-		}
 
-		const encodedArguments = ['Start'];
+/***/ }),
+/* 796 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-		if (options.wait) {
-			encodedArguments.push('-Wait');
-		}
+"use strict";
 
-		if (app) {
-			// Double quote with double quotes to ensure the inner quotes are passed through.
-			// Inner quotes are delimited for PowerShell interpretation with backticks.
-			encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList');
-			appArguments.unshift(target);
-		} else {
-			encodedArguments.push(`"${target}"`);
-		}
 
-		if (appArguments.length > 0) {
-			appArguments = appArguments.map(arg => `"\`"${arg}\`""`);
-			encodedArguments.push(appArguments.join(','));
-		}
+var _interopRequireDefault = __webpack_require__(524);
 
-		// Using Base64-encoded command, accepted by PowerShell, to allow special characters.
-		target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
-	} else {
-		if (app) {
-			command = app;
-		} else {
-			// When bundled by Webpack, there's no actual package file path and no local `xdg-open`.
-			const isBundled =  false || __dirname === '/';
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-			// Check if local `xdg-open` exists and is executable.
-			let exeLocalXdgOpen = false;
-			try {
-				await pAccess(localXdgOpenPath, fs.constants.X_OK);
-				exeLocalXdgOpen = true;
-			} catch (_) {}
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-			const useSystemXdgOpen = process.versions.electron ||
-				process.platform === 'android' || isBundled || !exeLocalXdgOpen;
-			command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
-		}
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-		if (appArguments.length > 0) {
-			cliArguments.push(...appArguments);
-		}
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-		if (!options.wait) {
-			// `xdg-open` will block the process unless stdio is ignored
-			// and it's detached from the parent even if it's unref'd.
-			childProcessOptions.stdio = 'ignore';
-			childProcessOptions.detached = true;
-		}
-	}
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-	cliArguments.push(target);
+var _store = __webpack_require__(705);
 
-	if (process.platform === 'darwin' && appArguments.length > 0) {
-		cliArguments.push('--args', ...appArguments);
-	}
+/**
+ * ObservableQueries are the glue between the store and observers
+ * of the store. They have the responsibility to hydrate the documents
+ * before passing them to the React component.
+ */
+var hasOwn = Object.prototype.hasOwnProperty;
 
-	const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
+var ObservableQuery = /*#__PURE__*/function () {
+  function ObservableQuery(queryId, definition, client, options) {
+    var _this = this;
 
-	if (options.wait) {
-		return new Promise((resolve, reject) => {
-			subprocess.once('error', reject);
+    (0, _classCallCheck2.default)(this, ObservableQuery);
+    (0, _defineProperty2.default)(this, "handleStoreChange", function () {
+      var nextResult = _this.currentRawResult();
 
-			subprocess.once('close', exitCode => {
-				if (options.allowNonzeroExitCode && exitCode > 0) {
-					reject(new Error(`Exited with code ${exitCode}`));
-					return;
-				}
+      if (!shallowEqual(nextResult, _this.lastResult)) {
+        _this.lastResult = nextResult;
 
-				resolve(subprocess);
-			});
-		});
-	}
+        _this.notifyObservers();
+      }
+    });
 
-	subprocess.unref();
+    if (!queryId || !definition || !client) {
+      throw new Error('ObservableQuery takes 3 arguments: queryId, definition and client');
+    }
 
-	return subprocess;
-};
+    this.queryId = queryId;
+    this.definition = definition;
+    this.client = client;
+    this.observers = {};
+    this.idCounter = 1;
+    this.lastResult = this.currentRawResult();
+    this.options = options;
+  }
 
+  (0, _createClass2.default)(ObservableQuery, [{
+    key: "currentResult",
 
-/***/ }),
-/* 809 */
-/***/ ((module) => {
+    /**
+     * Returns the query from the store with hydrated documents.
+     *
+     * @typedef {object} HydratedQueryState
+     *
+     * @returns {HydratedQueryState}
+     */
+    value: function currentResult() {
+      return this.client.getQueryFromState(this.queryId, {
+        hydrated: (0, _get.default)(this.options, 'hydrated', true),
+        singleDocData: true
+      });
+    }
+  }, {
+    key: "fetch",
+    value: function fetch() {
+      return this.client.query(this.definition, {
+        as: this.queryId
+      });
+    }
+    /**
+     * Generates and executes a query that is offsetted by the number of documents
+     * we have in the store.
+     */
 
-"use strict";
-module.exports = require("child_process");
+  }, {
+    key: "fetchMore",
+    value: function fetchMore() {
+      var rawResult = this.currentRawResult();
+      return rawResult.bookmark ? this.client.query(this.definition.offsetBookmark(rawResult.bookmark), {
+        as: this.queryId
+      }) : this.client.query(this.definition.offset(rawResult.data.length), {
+        as: this.queryId
+      });
+    }
+  }, {
+    key: "currentRawResult",
+    value: function currentRawResult() {
+      return (0, _store.getRawQueryFromState)(this.getStore().getState(), this.queryId);
+    }
+  }, {
+    key: "notifyObservers",
+    value: function notifyObservers() {
+      var _this2 = this;
 
-/***/ }),
-/* 810 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+      Object.keys(this.observers).forEach(function (id) {
+        return _this2.observers[id]();
+      });
+    }
+  }, {
+    key: "subscribeToStore",
+    value: function subscribeToStore() {
+      if (this._unsubscribeStore) {
+        throw new Error('ObservableQuery instance is already subscribed to store.');
+      }
 
-"use strict";
+      this._unsubscribeStore = this.getStore().subscribe(this.handleStoreChange);
+    }
+  }, {
+    key: "unsubscribeFromStore",
+    value: function unsubscribeFromStore() {
+      if (!this._unsubscribeStore) {
+        throw new Error('ObservableQuery instance is not subscribed to store');
+      }
 
-const os = __webpack_require__(252);
-const fs = __webpack_require__(149);
-const isDocker = __webpack_require__(811);
+      this._unsubscribeStore();
+    }
+  }, {
+    key: "subscribe",
+    value: function subscribe(callback) {
+      var _this3 = this;
 
-const isWsl = () => {
-	if (process.platform !== 'linux') {
-		return false;
-	}
+      var callbackId = this.idCounter;
+      this.idCounter++;
+      this.observers[callbackId] = callback;
 
-	if (os.release().toLowerCase().includes('microsoft')) {
-		if (isDocker()) {
-			return false;
-		}
+      if (Object.keys(this.observers).length === 1) {
+        this.subscribeToStore();
+      }
 
-		return true;
-	}
+      return function () {
+        return _this3.unsubscribe(callbackId);
+      };
+    }
+  }, {
+    key: "unsubscribe",
+    value: function unsubscribe(callbackId) {
+      if (!this.observers[callbackId]) {
+        throw new Error("Cannot unsubscribe unknown callbackId ".concat(callbackId));
+      }
 
-	try {
-		return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ?
-			!isDocker() : false;
-	} catch (_) {
-		return false;
-	}
-};
+      delete this.observers[callbackId];
 
-if (process.env.__IS_WSL_TEST__) {
-	module.exports = isWsl;
-} else {
-	module.exports = isWsl();
-}
+      if (Object.keys(this.observers).length === 0) {
+        this.unsubscribeFromStore();
+        this._unsubscribeStore = null;
+      }
+    }
+  }, {
+    key: "getStore",
+    value: function getStore() {
+      return this.client.store;
+    }
+  }]);
+  return ObservableQuery;
+}();
 
+exports["default"] = ObservableQuery;
 
-/***/ }),
-/* 811 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+function is(x, y) {
+  if (x === y) {
+    return x !== 0 || y !== 0 || 1 / x === 1 / y;
+  } else {
+    return x !== x && y !== y;
+  }
+}
 
-"use strict";
+function shallowEqual(objA, objB) {
+  if (is(objA, objB)) return true;
 
-const fs = __webpack_require__(149);
+  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
+    return false;
+  }
 
-let isDocker;
+  var keysA = Object.keys(objA);
+  var keysB = Object.keys(objB);
+  if (keysA.length !== keysB.length) return false;
 
-function hasDockerEnv() {
-	try {
-		fs.statSync('/.dockerenv');
-		return true;
-	} catch (_) {
-		return false;
-	}
-}
+  for (var i = 0; i < keysA.length; i++) {
+    if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
+      return false;
+    }
+  }
 
-function hasDockerCGroup() {
-	try {
-		return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
-	} catch (_) {
-		return false;
-	}
+  return true;
 }
 
-module.exports = () => {
-	if (isDocker === undefined) {
-		isDocker = hasDockerEnv() || hasDockerCGroup();
-	}
-
-	return isDocker;
-};
-
-
 /***/ }),
-/* 812 */
-/***/ ((module) => {
+/* 797 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-module.exports = enableDestroy;
+"use strict";
 
-function enableDestroy(server) {
-  var connections = {}
 
-  server.on('connection', function(conn) {
-    var key = conn.remoteAddress + ':' + conn.remotePort;
-    connections[key] = conn;
-    conn.on('close', function() {
-      delete connections[key];
-    });
-  });
+var _interopRequireDefault = __webpack_require__(524);
 
-  server.destroy = function(cb) {
-    server.close(cb);
-    for (var key in connections)
-      connections[key].destroy();
-  };
-}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.CozyClient = void 0;
 
+var _inherits2 = _interopRequireDefault(__webpack_require__(603));
 
-/***/ }),
-/* 813 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605));
 
-const { filterLevel, filterSecrets } = __webpack_require__(814)
-const Secret = __webpack_require__(815)
-const { LOG_LEVEL } = process.env
-let level = LOG_LEVEL || 'debug'
-const format = __webpack_require__(816)
-const filters = [filterLevel, filterSecrets]
+var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607));
 
-const filterOut = function() {
-  for (const filter of filters) {
-    if (filter.apply(null, arguments) === false) {
-      return true
-    }
-  }
-  return false
-}
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-/**
- * Use it to log messages in your konnector. Typical types are
- *
- * - `debug`
- * - `warning`
- * - `info`
- * - `error`
- * - `ok`
- *
- *
- * @example
- *
- * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector.
- *
- * ```js
- * logger = log('my-namespace')
- * logger('debug', '365 bills')
- * // my-namespace : debug : 365 bills
- * logger('info', 'Page fetched')
- * // my-namespace : info : Page fetched
- * ```
- * @param  {string} type
- * @param  {string} message
- * @param  {string} label
- * @param  {string} namespace
- */
-function log(type, message, label, namespace) {
-  if (filterOut(level, type, message, label, namespace)) {
-    return
-  }
-  // eslint-disable-next-line no-console
-  console.log(format(type, message, label, namespace))
-}
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
 
-log.addFilter = function(filter) {
-  return filters.push(filter)
-}
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 
-log.setLevel = function(lvl) {
-  level = lvl
-}
+var SnapshotObject = function SnapshotObject(attrs) {
+  (0, _classCallCheck2.default)(this, SnapshotObject);
+  Object.assign(this, attrs);
+};
 
-// Short-hands
-const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical']
-methods.forEach(level => {
-  log[level] = function(message, label, namespace) {
-    return log(level, message, label, namespace)
-  }
-})
+var CozyClient = /*#__PURE__*/function (_SnapshotObject) {
+  (0, _inherits2.default)(CozyClient, _SnapshotObject);
 
-module.exports = log
+  var _super = _createSuper(CozyClient);
 
-log.setNoRetry = obj => {
-  if (obj) obj.no_retry = true
-  else obj = { no_retry: true }
-  return obj.no_retry
-}
-log.Secret = Secret
-log.namespace = function(namespace) {
-  return function(type, message, label, ns = namespace) {
-    log(type, message, label, ns)
+  function CozyClient() {
+    (0, _classCallCheck2.default)(this, CozyClient);
+    return _super.apply(this, arguments);
   }
-}
 
+  return CozyClient;
+}(SnapshotObject);
+
+exports.CozyClient = CozyClient;
 
 /***/ }),
-/* 814 */
+/* 798 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const levels = {
-  secret: 0,
-  debug: 10,
-  info: 20,
-  warn: 30,
-  error: 40,
-  ok: 50,
-  critical: 50
-}
+var json = typeof JSON !== 'undefined' ? JSON : __webpack_require__(799);
 
-const Secret = __webpack_require__(815)
+module.exports = function (obj, opts) {
+    if (!opts) opts = {};
+    if (typeof opts === 'function') opts = { cmp: opts };
+    var space = opts.space || '';
+    if (typeof space === 'number') space = Array(space+1).join(' ');
+    var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
+    var replacer = opts.replacer || function(key, value) { return value; };
 
-const filterSecrets = function(level, type, message) {
-  if (type !== 'secret' && message instanceof Secret) {
-    throw new Error('You should log a secret with log.secret')
-  }
-}
+    var cmp = opts.cmp && (function (f) {
+        return function (node) {
+            return function (a, b) {
+                var aobj = { key: a, value: node[a] };
+                var bobj = { key: b, value: node[b] };
+                return f(aobj, bobj);
+            };
+        };
+    })(opts.cmp);
 
-const filterLevel = function(level, type) {
-  return levels[type] >= levels[level]
-}
+    var seen = [];
+    return (function stringify (parent, key, node, level) {
+        var indent = space ? ('\n' + new Array(level + 1).join(space)) : '';
+        var colonSeparator = space ? ': ' : ':';
 
-module.exports = {
-  filterSecrets,
-  filterLevel
-}
+        if (node && node.toJSON && typeof node.toJSON === 'function') {
+            node = node.toJSON();
+        }
 
+        node = replacer.call(parent, key, node);
 
-/***/ }),
-/* 815 */
-/***/ ((module) => {
+        if (node === undefined) {
+            return;
+        }
+        if (typeof node !== 'object' || node === null) {
+            return json.stringify(node);
+        }
+        if (isArray(node)) {
+            var out = [];
+            for (var i = 0; i < node.length; i++) {
+                var item = stringify(node, i, node[i], level+1) || json.stringify(null);
+                out.push(indent + space + item);
+            }
+            return '[' + out.join(',') + indent + ']';
+        }
+        else {
+            if (seen.indexOf(node) !== -1) {
+                if (cycles) return json.stringify('__cycle__');
+                throw new TypeError('Converting circular structure to JSON');
+            }
+            else seen.push(node);
 
-const Secret = function(data) {
-  Object.assign(this, data)
-  return this
-}
+            var keys = objectKeys(node).sort(cmp && cmp(node));
+            var out = [];
+            for (var i = 0; i < keys.length; i++) {
+                var key = keys[i];
+                var value = stringify(node, key, node[key], level+1);
 
-Secret.prototype.toString = function() {
-  throw new Error('Cannot convert Secret to string')
-}
+                if(!value) continue;
 
-module.exports = Secret
+                var keyValue = json.stringify(key)
+                    + colonSeparator
+                    + value;
+                ;
+                out.push(indent + space + keyValue);
+            }
+            seen.splice(seen.indexOf(node), 1);
+            return '{' + out.join(',') + indent + '}';
+        }
+    })({ '': obj }, '', obj, 0);
+};
 
+var isArray = Array.isArray || function (x) {
+    return {}.toString.call(x) === '[object Array]';
+};
 
-/***/ }),
-/* 816 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+var objectKeys = Object.keys || function (obj) {
+    var has = Object.prototype.hasOwnProperty || function () { return true };
+    var keys = [];
+    for (var key in obj) {
+        if (has.call(obj, key)) keys.push(key);
+    }
+    return keys;
+};
 
-const prodFormat = __webpack_require__(817)
-const devFormat = __webpack_require__(818)
 
-switch (process.env.NODE_ENV) {
-  case 'production':
-    module.exports = prodFormat
-    break
-  case 'development':
-    module.exports = devFormat
-    break
-  case 'standalone':
-    module.exports = devFormat
-    break
-  case 'test':
-    module.exports = devFormat
-    break
-  default:
-    module.exports = prodFormat
-}
+/***/ }),
+/* 799 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+exports.parse = __webpack_require__(800);
+exports.stringify = __webpack_require__(801);
 
 
 /***/ }),
-/* 817 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+/* 800 */
+/***/ ((module) => {
 
-const stringify = __webpack_require__(75)
+var at, // The index of the current character
+    ch, // The current character
+    escapee = {
+        '"':  '"',
+        '\\': '\\',
+        '/':  '/',
+        b:    '\b',
+        f:    '\f',
+        n:    '\n',
+        r:    '\r',
+        t:    '\t'
+    },
+    text,
 
-const LOG_LENGTH_LIMIT = 64 * 1024 - 1
+    error = function (m) {
+        // Call error when something is wrong.
+        throw {
+            name:    'SyntaxError',
+            message: m,
+            at:      at,
+            text:    text
+        };
+    },
+    
+    next = function (c) {
+        // If a c parameter is provided, verify that it matches the current character.
+        if (c && c !== ch) {
+            error("Expected '" + c + "' instead of '" + ch + "'");
+        }
+        
+        // Get the next character. When there are no more characters,
+        // return the empty string.
+        
+        ch = text.charAt(at);
+        at += 1;
+        return ch;
+    },
+    
+    number = function () {
+        // Parse a number value.
+        var number,
+            string = '';
+        
+        if (ch === '-') {
+            string = '-';
+            next('-');
+        }
+        while (ch >= '0' && ch <= '9') {
+            string += ch;
+            next();
+        }
+        if (ch === '.') {
+            string += '.';
+            while (next() && ch >= '0' && ch <= '9') {
+                string += ch;
+            }
+        }
+        if (ch === 'e' || ch === 'E') {
+            string += ch;
+            next();
+            if (ch === '-' || ch === '+') {
+                string += ch;
+                next();
+            }
+            while (ch >= '0' && ch <= '9') {
+                string += ch;
+                next();
+            }
+        }
+        number = +string;
+        if (!isFinite(number)) {
+            error("Bad number");
+        } else {
+            return number;
+        }
+    },
+    
+    string = function () {
+        // Parse a string value.
+        var hex,
+            i,
+            string = '',
+            uffff;
+        
+        // When parsing for string values, we must look for " and \ characters.
+        if (ch === '"') {
+            while (next()) {
+                if (ch === '"') {
+                    next();
+                    return string;
+                } else if (ch === '\\') {
+                    next();
+                    if (ch === 'u') {
+                        uffff = 0;
+                        for (i = 0; i < 4; i += 1) {
+                            hex = parseInt(next(), 16);
+                            if (!isFinite(hex)) {
+                                break;
+                            }
+                            uffff = uffff * 16 + hex;
+                        }
+                        string += String.fromCharCode(uffff);
+                    } else if (typeof escapee[ch] === 'string') {
+                        string += escapee[ch];
+                    } else {
+                        break;
+                    }
+                } else {
+                    string += ch;
+                }
+            }
+        }
+        error("Bad string");
+    },
 
-function prodFormat(type, message, label, namespace) {
-  const log = { time: new Date(), type, label, namespace }
+    white = function () {
 
-  if (typeof message === 'object') {
-    if (message && message.no_retry) {
-      log.no_retry = message.no_retry
-    }
-    if (message && message.message) {
-      log.message = message.message
-    }
-  } else {
-    log.message = message
-  }
+// Skip whitespace.
 
-  // properly display error messages
-  if (log.message && log.message.stack) {
-    log.message = log.message.stack
-  }
+        while (ch && ch <= ' ') {
+            next();
+        }
+    },
 
-  // cut the string to avoid a fail in the stack
-  let result = log
-  try {
-    result = stringify(log).substr(0, LOG_LENGTH_LIMIT)
-  } catch (err) {
-    // eslint-disable-next-line no-console
-    console.log(err.message, 'cozy-logger: Failed to convert message to JSON')
-  }
-  return result
-}
+    word = function () {
 
-module.exports = prodFormat
+// true, false, or null.
+
+        switch (ch) {
+        case 't':
+            next('t');
+            next('r');
+            next('u');
+            next('e');
+            return true;
+        case 'f':
+            next('f');
+            next('a');
+            next('l');
+            next('s');
+            next('e');
+            return false;
+        case 'n':
+            next('n');
+            next('u');
+            next('l');
+            next('l');
+            return null;
+        }
+        error("Unexpected '" + ch + "'");
+    },
 
+    value,  // Place holder for the value function.
 
-/***/ }),
-/* 818 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+    array = function () {
 
-const util = __webpack_require__(64)
-const chalk = __webpack_require__(819)
+// Parse an array value.
 
-if (util && util.inspect && util.inspect.defaultOptions) {
-  util.inspect.defaultOptions.maxArrayLength = null
-  util.inspect.defaultOptions.depth = 2
-  util.inspect.defaultOptions.colors = true
-}
+        var array = [];
 
-const type2color = {
-  debug: 'cyan',
-  warn: 'yellow',
-  info: 'blue',
-  error: 'red',
-  ok: 'green',
-  secret: 'red',
-  critical: 'red'
-}
+        if (ch === '[') {
+            next('[');
+            white();
+            if (ch === ']') {
+                next(']');
+                return array;   // empty array
+            }
+            while (ch) {
+                array.push(value());
+                white();
+                if (ch === ']') {
+                    next(']');
+                    return array;
+                }
+                next(',');
+                white();
+            }
+        }
+        error("Bad array");
+    },
 
-function devFormat(type, message, label, namespace) {
-  let formatmessage = message
+    object = function () {
 
-  if (typeof formatmessage !== 'string') {
-    formatmessage = util.inspect(formatmessage)
-  }
+// Parse an object value.
 
-  let formatlabel = label ? ` : "${label}" ` : ''
-  let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : ''
+        var key,
+            object = {};
 
-  let color = type2color[type]
-  let formattype = color ? chalk[color](type) : type
+        if (ch === '{') {
+            next('{');
+            white();
+            if (ch === '}') {
+                next('}');
+                return object;   // empty object
+            }
+            while (ch) {
+                key = string();
+                white();
+                next(':');
+                if (Object.hasOwnProperty.call(object, key)) {
+                    error('Duplicate key "' + key + '"');
+                }
+                object[key] = value();
+                white();
+                if (ch === '}') {
+                    next('}');
+                    return object;
+                }
+                next(',');
+                white();
+            }
+        }
+        error("Bad object");
+    };
 
-  return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}`
-}
+value = function () {
 
-module.exports = devFormat
+// Parse a JSON value. It could be an object, an array, a string, a number,
+// or a word.
 
+    white();
+    switch (ch) {
+    case '{':
+        return object();
+    case '[':
+        return array();
+    case '"':
+        return string();
+    case '-':
+        return number();
+    default:
+        return ch >= '0' && ch <= '9' ? number() : word();
+    }
+};
 
-/***/ }),
-/* 819 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+// Return the json_parse function. It will have access to all of the above
+// functions and variables.
 
-"use strict";
+module.exports = function (source, reviver) {
+    var result;
+    
+    text = source;
+    at = 0;
+    ch = ' ';
+    result = value();
+    white();
+    if (ch) {
+        error("Syntax error");
+    }
 
-const escapeStringRegexp = __webpack_require__(349);
-const ansiStyles = __webpack_require__(820);
-const stdoutColor = (__webpack_require__(825).stdout);
+    // If there is a reviver function, we recursively walk the new structure,
+    // passing each name/value pair to the reviver function for possible
+    // transformation, starting with a temporary root object that holds the result
+    // in an empty key. If there is not a reviver function, we simply return the
+    // result.
 
-const template = __webpack_require__(827);
+    return typeof reviver === 'function' ? (function walk(holder, key) {
+        var k, v, value = holder[key];
+        if (value && typeof value === 'object') {
+            for (k in value) {
+                if (Object.prototype.hasOwnProperty.call(value, k)) {
+                    v = walk(value, k);
+                    if (v !== undefined) {
+                        value[k] = v;
+                    } else {
+                        delete value[k];
+                    }
+                }
+            }
+        }
+        return reviver.call(holder, key, value);
+    }({'': result}, '')) : result;
+};
 
-const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
 
-// `supportsColor.level` → `ansiStyles.color[name]` mapping
-const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
+/***/ }),
+/* 801 */
+/***/ ((module) => {
 
-// `color-convert` models to exclude from the Chalk API due to conflicts and such
-const skipModels = new Set(['gray']);
+var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+    escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+    gap,
+    indent,
+    meta = {    // table of character substitutions
+        '\b': '\\b',
+        '\t': '\\t',
+        '\n': '\\n',
+        '\f': '\\f',
+        '\r': '\\r',
+        '"' : '\\"',
+        '\\': '\\\\'
+    },
+    rep;
 
-const styles = Object.create(null);
+function quote(string) {
+    // If the string contains no control characters, no quote characters, and no
+    // backslash characters, then we can safely slap some quotes around it.
+    // Otherwise we must also replace the offending characters with safe escape
+    // sequences.
+    
+    escapable.lastIndex = 0;
+    return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+        var c = meta[a];
+        return typeof c === 'string' ? c :
+            '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+    }) + '"' : '"' + string + '"';
+}
 
-function applyOptions(obj, options) {
-	options = options || {};
+function str(key, holder) {
+    // Produce a string from holder[key].
+    var i,          // The loop counter.
+        k,          // The member key.
+        v,          // The member value.
+        length,
+        mind = gap,
+        partial,
+        value = holder[key];
+    
+    // If the value has a toJSON method, call it to obtain a replacement value.
+    if (value && typeof value === 'object' &&
+            typeof value.toJSON === 'function') {
+        value = value.toJSON(key);
+    }
+    
+    // If we were called with a replacer function, then call the replacer to
+    // obtain a replacement value.
+    if (typeof rep === 'function') {
+        value = rep.call(holder, key, value);
+    }
+    
+    // What happens next depends on the value's type.
+    switch (typeof value) {
+        case 'string':
+            return quote(value);
+        
+        case 'number':
+            // JSON numbers must be finite. Encode non-finite numbers as null.
+            return isFinite(value) ? String(value) : 'null';
+        
+        case 'boolean':
+        case 'null':
+            // If the value is a boolean or null, convert it to a string. Note:
+            // typeof null does not produce 'null'. The case is included here in
+            // the remote chance that this gets fixed someday.
+            return String(value);
+            
+        case 'object':
+            if (!value) return 'null';
+            gap += indent;
+            partial = [];
+            
+            // Array.isArray
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+                
+                // Join all of the elements together, separated with commas, and
+                // wrap them in brackets.
+                v = partial.length === 0 ? '[]' : gap ?
+                    '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
+                    '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+            
+            // If the replacer is an array, use it to select the members to be
+            // stringified.
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+            else {
+                // Otherwise, iterate through all of the keys in the object.
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+            
+        // Join all of the member texts together, separated with commas,
+        // and wrap them in braces.
 
-	// Detect level if not set manually
-	const scLevel = stdoutColor ? stdoutColor.level : 0;
-	obj.level = options.level === undefined ? scLevel : options.level;
-	obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
+        v = partial.length === 0 ? '{}' : gap ?
+            '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
+            '{' + partial.join(',') + '}';
+        gap = mind;
+        return v;
+    }
 }
 
-function Chalk(options) {
-	// We check for this.template here since calling `chalk.constructor()`
-	// by itself will have a `this` of a previously constructed chalk object
-	if (!this || !(this instanceof Chalk) || this.template) {
-		const chalk = {};
-		applyOptions(chalk, options);
+module.exports = function (value, replacer, space) {
+    var i;
+    gap = '';
+    indent = '';
+    
+    // If the space parameter is a number, make an indent string containing that
+    // many spaces.
+    if (typeof space === 'number') {
+        for (i = 0; i < space; i += 1) {
+            indent += ' ';
+        }
+    }
+    // If the space parameter is a string, it will be used as the indent string.
+    else if (typeof space === 'string') {
+        indent = space;
+    }
 
-		chalk.template = function () {
-			const args = [].slice.call(arguments);
-			return chalkTag.apply(null, [chalk.template].concat(args));
-		};
+    // If there is a replacer, it must be a function or an array.
+    // Otherwise, throw an error.
+    rep = replacer;
+    if (replacer && typeof replacer !== 'function'
+    && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
+        throw new Error('JSON.stringify');
+    }
+    
+    // Make a fake root object containing our value under the key of ''.
+    // Return the result of stringifying the value.
+    return str('', {'': value});
+};
 
-		Object.setPrototypeOf(chalk, Chalk.prototype);
-		Object.setPrototypeOf(chalk.template, chalk);
 
-		chalk.template.constructor = Chalk;
+/***/ }),
+/* 802 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-		return chalk.template;
-	}
+"use strict";
 
-	applyOptions(this, options);
-}
 
-// Use bright blue on Windows as the normal blue color is illegible
-if (isSimpleWindowsTerm) {
-	ansiStyles.blue.open = '\u001B[94m';
-}
+var _interopRequireDefault = __webpack_require__(524);
 
-for (const key of Object.keys(ansiStyles)) {
-	ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports["default"] = void 0;
 
-	styles[key] = {
-		get() {
-			const codes = ansiStyles[key];
-			return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
-		}
-	};
-}
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-styles.visible = {
-	get() {
-		return build.call(this, this._styles || [], true, 'visible');
-	}
-};
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
-for (const model of Object.keys(ansiStyles.color.ansi)) {
-	if (skipModels.has(model)) {
-		continue;
-	}
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-	styles[model] = {
-		get() {
-			const level = this.level;
-			return function () {
-				const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
-				const codes = {
-					open,
-					close: ansiStyles.color.close,
-					closeRe: ansiStyles.color.closeRe
-				};
-				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
-			};
-		}
-	};
-}
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
-for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
-	if (skipModels.has(model)) {
-		continue;
-	}
+/**
+ * Caches promises while they are pending
+ * Serves to dedupe equal queries requested at the same time
+ */
+var PromiseCache = /*#__PURE__*/function () {
+  function PromiseCache() {
+    (0, _classCallCheck2.default)(this, PromiseCache);
 
-	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
-	styles[bgModel] = {
-		get() {
-			const level = this.level;
-			return function () {
-				const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
-				const codes = {
-					open,
-					close: ansiStyles.bgColor.close,
-					closeRe: ansiStyles.bgColor.closeRe
-				};
-				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
-			};
-		}
-	};
-}
+    /**
+     * Holds pending promises
+     *
+     * @type {Object.<string, Promise>}
+     */
+    this.pending = {};
+  }
+  /**
+   * Tries to find a pending promise corresponding to the result of keyFunc
+   * - If not found, promiseFunc is executed and the resulting promise is stored while it's pending
+   * - If found, it is immediately returned
+   *
+   * @template T
+   * @param  {function(): Promise<T>} promiseFunc - Not executed only if an "equal" promise is already pending.
+   * @param  {function(): string} keyFunc - Returns a key to find in cache to find a pending promise.
+   * @returns {Promise<T>}
+   */
 
-const proto = Object.defineProperties(() => {}, styles);
 
-function build(_styles, _empty, key) {
-	const builder = function () {
-		return applyStyle.apply(builder, arguments);
-	};
+  (0, _createClass2.default)(PromiseCache, [{
+    key: "exec",
+    value: function () {
+      var _exec = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(promiseFunc, keyFunc) {
+        var key, already, prom, response;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                key = keyFunc();
+                already = this.pending[key];
 
-	builder._styles = _styles;
-	builder._empty = _empty;
+                if (already) {
+                  prom = already;
+                } else {
+                  prom = promiseFunc();
+                  this.pending[key] = prom;
+                }
 
-	const self = this;
+                _context.prev = 3;
+                _context.next = 6;
+                return prom;
 
-	Object.defineProperty(builder, 'level', {
-		enumerable: true,
-		get() {
-			return self.level;
-		},
-		set(level) {
-			self.level = level;
-		}
-	});
+              case 6:
+                response = _context.sent;
+                return _context.abrupt("return", response);
 
-	Object.defineProperty(builder, 'enabled', {
-		enumerable: true,
-		get() {
-			return self.enabled;
-		},
-		set(enabled) {
-			self.enabled = enabled;
-		}
-	});
+              case 8:
+                _context.prev = 8;
+                this.pending[key] = null;
+                return _context.finish(8);
 
-	// See below for fix regarding invisible grey/dim combination on Windows
-	builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
+              case 11:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this, [[3,, 8, 11]]);
+      }));
 
-	// `__proto__` is used because we must return a function, but there is
-	// no way to create a function with a different prototype
-	builder.__proto__ = proto; // eslint-disable-line no-proto
+      function exec(_x, _x2) {
+        return _exec.apply(this, arguments);
+      }
 
-	return builder;
-}
+      return exec;
+    }()
+    /**
+     *
+     * @param {function(): string} keyFunc - Returns a key to find in cache to find a pending promise.
+     * @returns {Promise | null}
+     */
 
-function applyStyle() {
-	// Support varags, but simply cast to string in case there's only one arg
-	const args = arguments;
-	const argsLen = args.length;
-	let str = String(arguments[0]);
+  }, {
+    key: "get",
+    value: function get(keyFunc) {
+      var key = keyFunc();
+      var already = this.pending[key];
+      if (already) return already;
+      return null;
+    }
+  }]);
+  return PromiseCache;
+}();
 
-	if (argsLen === 0) {
-		return '';
-	}
+var _default = PromiseCache;
+exports["default"] = _default;
 
-	if (argsLen > 1) {
-		// Don't slice `arguments`, it prevents V8 optimizations
-		for (let a = 1; a < argsLen; a++) {
-			str += ' ' + args[a];
-		}
-	}
+/***/ }),
+/* 803 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-	if (!this.enabled || this.level <= 0 || !str) {
-		return this._empty ? '' : str;
-	}
+"use strict";
 
-	// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
-	// see https://github.com/chalk/chalk/issues/58
-	// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
-	const originalDim = ansiStyles.dim.open;
-	if (isSimpleWindowsTerm && this.hasGrey) {
-		ansiStyles.dim.open = '';
-	}
 
-	for (const code of this._styles.slice().reverse()) {
-		// Replace any instances already present with a re-opening code
-		// otherwise only the part of the string until said closing code
-		// will be colored, and the rest will simply be 'plain'.
-		str = code.open + str.replace(code.closeRe, code.open) + code.close;
+var _interopRequireDefault = __webpack_require__(524);
 
-		// Close the styling before a linebreak and reopen
-		// after next line to fix a bleed issue on macOS
-		// https://github.com/chalk/chalk/pull/92
-		str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
-	}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.certifyFlagship = void 0;
 
-	// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
-	ansiStyles.dim.open = originalDim;
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-	return str;
-}
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-function chalkTag(chalk, strings) {
-	if (!Array.isArray(strings)) {
-		// If chalk() was called by itself or with a string,
-		// return the string itself as a string.
-		return [].slice.call(arguments, 1).join(' ');
-	}
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
-	const args = [].slice.call(arguments, 2);
-	const parts = [strings.raw[0]];
+var _logger = _interopRequireDefault(__webpack_require__(715));
 
-	for (let i = 1; i < strings.length; i++) {
-		parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
-		parts.push(String(strings.raw[i]));
-	}
+var _storeAttestation = __webpack_require__(804);
 
-	return template(chalk, parts.join(''));
-}
+/**
+ * Request a challenge from the Stack that can be used to request the app attestation from the app store
+ *
+ * @param {CozyClient} client - the CozyClient instance
+ * @returns {Promise<string>} - the Nonce string returned by the stack
+ */
+var getStackChallenge = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) {
+    var stackClient, result;
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            _context.prev = 0;
+            stackClient = client.getStackClient();
+            _context.next = 4;
+            return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/challenge"), null, {
+              headers: {
+                Authorization: stackClient.registrationAccessTokenToAuthHeader()
+              }
+            });
 
-Object.defineProperties(Chalk.prototype, styles);
+          case 4:
+            result = _context.sent;
+            return _context.abrupt("return", result.nonce);
 
-module.exports = Chalk(); // eslint-disable-line new-cap
-module.exports.supportsColor = stdoutColor;
-module.exports["default"] = module.exports; // For TypeScript
+          case 8:
+            _context.prev = 8;
+            _context.t0 = _context["catch"](0);
+            throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while requesting a challenge from CozyStack:\n' + _context.t0.message);
 
+          case 11:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee, null, [[0, 8]]);
+  }));
 
-/***/ }),
-/* 820 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+  return function getStackChallenge(_x) {
+    return _ref.apply(this, arguments);
+  };
+}();
+/**
+ * Give the app attestation to the Stack
+ *
+ * @param {AttestationResult} appAttestation - the app attestation that was returned by the app store
+ * @param {string} nonce - the Nonce string retrieved from the stack
+ * @param {CozyClient} client - the CozyClient instance
+ */
 
-"use strict";
-/* module decorator */ module = __webpack_require__.nmd(module);
 
-const colorConvert = __webpack_require__(821);
+var giveAppAttestationToStack = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appAttestation, nonce, client) {
+    var platform, attestation, keyId, stackClient;
+    return _regenerator.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            _context2.prev = 0;
+            platform = appAttestation.platform, attestation = appAttestation.attestation, keyId = appAttestation.keyId;
+            stackClient = client.getStackClient();
+            _context2.next = 5;
+            return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/attestation"), {
+              platform: platform,
+              attestation: attestation,
+              challenge: nonce,
+              keyId: keyId
+            }, {
+              headers: {
+                Authorization: stackClient.registrationAccessTokenToAuthHeader()
+              }
+            });
+
+          case 5:
+            _context2.next = 10;
+            break;
 
-const wrapAnsi16 = (fn, offset) => function () {
-	const code = fn.apply(colorConvert, arguments);
-	return `\u001B[${code + offset}m`;
-};
+          case 7:
+            _context2.prev = 7;
+            _context2.t0 = _context2["catch"](0);
+            throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while giving attestation to CozyStack:\n' + _context2.t0.message);
 
-const wrapAnsi256 = (fn, offset) => function () {
-	const code = fn.apply(colorConvert, arguments);
-	return `\u001B[${38 + offset};5;${code}m`;
-};
+          case 10:
+          case "end":
+            return _context2.stop();
+        }
+      }
+    }, _callee2, null, [[0, 7]]);
+  }));
 
-const wrapAnsi16m = (fn, offset) => function () {
-	const rgb = fn.apply(colorConvert, arguments);
-	return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
-};
+  return function giveAppAttestationToStack(_x2, _x3, _x4) {
+    return _ref2.apply(this, arguments);
+  };
+}();
+/**
+ * Verify app's identity and integrity so the Stack can trust it
+ * Verification is done on Stack side by using information from the app's store (Google Play or Apple AppStore)
+ *
+ * @param {CertificationConfig} certificationConfig - the required configuration to access the stores API
+ * @param {CozyClient} client - the CozyClient instance
+ */
 
-function assembleStyles() {
-	const codes = new Map();
-	const styles = {
-		modifier: {
-			reset: [0, 0],
-			// 21 isn't widely supported and 22 does the same thing
-			bold: [1, 22],
-			dim: [2, 22],
-			italic: [3, 23],
-			underline: [4, 24],
-			inverse: [7, 27],
-			hidden: [8, 28],
-			strikethrough: [9, 29]
-		},
-		color: {
-			black: [30, 39],
-			red: [31, 39],
-			green: [32, 39],
-			yellow: [33, 39],
-			blue: [34, 39],
-			magenta: [35, 39],
-			cyan: [36, 39],
-			white: [37, 39],
-			gray: [90, 39],
 
-			// Bright color
-			redBright: [91, 39],
-			greenBright: [92, 39],
-			yellowBright: [93, 39],
-			blueBright: [94, 39],
-			magentaBright: [95, 39],
-			cyanBright: [96, 39],
-			whiteBright: [97, 39]
-		},
-		bgColor: {
-			bgBlack: [40, 49],
-			bgRed: [41, 49],
-			bgGreen: [42, 49],
-			bgYellow: [43, 49],
-			bgBlue: [44, 49],
-			bgMagenta: [45, 49],
-			bgCyan: [46, 49],
-			bgWhite: [47, 49],
+var certifyFlagship = /*#__PURE__*/function () {
+  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(certificationConfig, client) {
+    var stackChallengeNonce, appAttestation;
+    return _regenerator.default.wrap(function _callee3$(_context3) {
+      while (1) {
+        switch (_context3.prev = _context3.next) {
+          case 0:
+            if (certificationConfig) {
+              _context3.next = 2;
+              break;
+            }
 
-			// Bright color
-			bgBlackBright: [100, 49],
-			bgRedBright: [101, 49],
-			bgGreenBright: [102, 49],
-			bgYellowBright: [103, 49],
-			bgBlueBright: [104, 49],
-			bgMagentaBright: [105, 49],
-			bgCyanBright: [106, 49],
-			bgWhiteBright: [107, 49]
-		}
-	};
+            throw new Error('[FLAGSHIP_CERTIFICATION] Certification configuration is not set');
 
-	// Fix humans
-	styles.color.grey = styles.color.gray;
+          case 2:
+            _context3.prev = 2;
+            _context3.next = 5;
+            return getStackChallenge(client);
 
-	for (const groupName of Object.keys(styles)) {
-		const group = styles[groupName];
+          case 5:
+            stackChallengeNonce = _context3.sent;
+            _context3.next = 8;
+            return (0, _storeAttestation.getAppAttestationFromStore)(stackChallengeNonce, certificationConfig);
 
-		for (const styleName of Object.keys(group)) {
-			const style = group[styleName];
+          case 8:
+            appAttestation = _context3.sent;
+            _context3.next = 11;
+            return giveAppAttestationToStack(appAttestation, stackChallengeNonce, client);
 
-			styles[styleName] = {
-				open: `\u001B[${style[0]}m`,
-				close: `\u001B[${style[1]}m`
-			};
+          case 11:
+            _context3.next = 17;
+            break;
 
-			group[styleName] = styles[styleName];
+          case 13:
+            _context3.prev = 13;
+            _context3.t0 = _context3["catch"](2);
 
-			codes.set(style[0], style[1]);
-		}
+            _logger.default.warn('[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification');
 
-		Object.defineProperty(styles, groupName, {
-			value: group,
-			enumerable: false
-		});
+            _logger.default.warn(_context3.t0.message);
 
-		Object.defineProperty(styles, 'codes', {
-			value: codes,
-			enumerable: false
-		});
-	}
+          case 17:
+          case "end":
+            return _context3.stop();
+        }
+      }
+    }, _callee3, null, [[2, 13]]);
+  }));
 
-	const ansi2ansi = n => n;
-	const rgb2rgb = (r, g, b) => [r, g, b];
+  return function certifyFlagship(_x5, _x6) {
+    return _ref3.apply(this, arguments);
+  };
+}();
 
-	styles.color.close = '\u001B[39m';
-	styles.bgColor.close = '\u001B[49m';
+exports.certifyFlagship = certifyFlagship;
 
-	styles.color.ansi = {
-		ansi: wrapAnsi16(ansi2ansi, 0)
-	};
-	styles.color.ansi256 = {
-		ansi256: wrapAnsi256(ansi2ansi, 0)
-	};
-	styles.color.ansi16m = {
-		rgb: wrapAnsi16m(rgb2rgb, 0)
-	};
+/***/ }),
+/* 804 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-	styles.bgColor.ansi = {
-		ansi: wrapAnsi16(ansi2ansi, 10)
-	};
-	styles.bgColor.ansi256 = {
-		ansi256: wrapAnsi256(ansi2ansi, 10)
-	};
-	styles.bgColor.ansi16m = {
-		rgb: wrapAnsi16m(rgb2rgb, 10)
-	};
+"use strict";
 
-	for (let key of Object.keys(colorConvert)) {
-		if (typeof colorConvert[key] !== 'object') {
-			continue;
-		}
 
-		const suite = colorConvert[key];
+var _interopRequireDefault = __webpack_require__(524);
 
-		if (key === 'ansi16') {
-			key = 'ansi';
-		}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getAppAttestationFromStore = void 0;
 
-		if ('ansi16' in suite) {
-			styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0);
-			styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10);
-		}
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-		if ('ansi256' in suite) {
-			styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0);
-			styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10);
-		}
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-		if ('rgb' in suite) {
-			styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0);
-			styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10);
-		}
-	}
+/**
+ * Retrieve the app's attestation from the app's store
+ * /!\ This is a mock implementation that should never be called
+ *
+ * @param {string} nonce - the Nonce string retrieved from the stack
+ * @param {CertificationConfig} certificationConfig - Configuration to access the stores certification API
+ * @returns {Promise<AttestationResult>} the app's attestation
+ */
+var validateAppMock = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(nonce, certificationConfig) {
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            throw new Error("getAppAttestationFromStore can only be called from a React Native container");
 
-	return styles;
-}
+          case 1:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
 
-// Make the export immutable
-Object.defineProperty(module, 'exports', {
-	enumerable: true,
-	get: assembleStyles
-});
+  return function validateAppMock(_x, _x2) {
+    return _ref.apply(this, arguments);
+  };
+}();
 
+var getAppAttestationFromStore = validateAppMock;
+exports.getAppAttestationFromStore = getAppAttestationFromStore;
 
 /***/ }),
-/* 821 */
+/* 805 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var conversions = __webpack_require__(822);
-var route = __webpack_require__(824);
-
-var convert = {};
+var createFlow = __webpack_require__(806);
 
-var models = Object.keys(conversions);
+/**
+ * Creates a function that returns the result of invoking the given functions
+ * with the `this` binding of the created function, where each successive
+ * invocation is supplied the return value of the previous.
+ *
+ * @static
+ * @memberOf _
+ * @since 3.0.0
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] The functions to invoke.
+ * @returns {Function} Returns the new composite function.
+ * @see _.flowRight
+ * @example
+ *
+ * function square(n) {
+ *   return n * n;
+ * }
+ *
+ * var addSquare = _.flow([_.add, square]);
+ * addSquare(1, 2);
+ * // => 9
+ */
+var flow = createFlow();
 
-function wrapRaw(fn) {
-	var wrappedFn = function (args) {
-		if (args === undefined || args === null) {
-			return args;
-		}
+module.exports = flow;
 
-		if (arguments.length > 1) {
-			args = Array.prototype.slice.call(arguments);
-		}
 
-		return fn(args);
-	};
+/***/ }),
+/* 806 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-	// preserve .conversion property if there is one
-	if ('conversion' in fn) {
-		wrappedFn.conversion = fn.conversion;
-	}
+var LodashWrapper = __webpack_require__(807),
+    flatRest = __webpack_require__(632),
+    getData = __webpack_require__(809),
+    getFuncName = __webpack_require__(811),
+    isArray = __webpack_require__(55),
+    isLaziable = __webpack_require__(813);
 
-	return wrappedFn;
-}
+/** Error message constants. */
+var FUNC_ERROR_TEXT = 'Expected a function';
 
-function wrapRounded(fn) {
-	var wrappedFn = function (args) {
-		if (args === undefined || args === null) {
-			return args;
-		}
+/** Used to compose bitmasks for function metadata. */
+var WRAP_CURRY_FLAG = 8,
+    WRAP_PARTIAL_FLAG = 32,
+    WRAP_ARY_FLAG = 128,
+    WRAP_REARG_FLAG = 256;
 
-		if (arguments.length > 1) {
-			args = Array.prototype.slice.call(arguments);
-		}
+/**
+ * Creates a `_.flow` or `_.flowRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new flow function.
+ */
+function createFlow(fromRight) {
+  return flatRest(function(funcs) {
+    var length = funcs.length,
+        index = length,
+        prereq = LodashWrapper.prototype.thru;
 
-		var result = fn(args);
+    if (fromRight) {
+      funcs.reverse();
+    }
+    while (index--) {
+      var func = funcs[index];
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
+        var wrapper = new LodashWrapper([], true);
+      }
+    }
+    index = wrapper ? index : length;
+    while (++index < length) {
+      func = funcs[index];
 
-		// we're assuming the result is an array here.
-		// see notice in conversions.js; don't use box types
-		// in conversion functions.
-		if (typeof result === 'object') {
-			for (var len = result.length, i = 0; i < len; i++) {
-				result[i] = Math.round(result[i]);
-			}
-		}
+      var funcName = getFuncName(func),
+          data = funcName == 'wrapper' ? getData(func) : undefined;
 
-		return result;
-	};
+      if (data && isLaziable(data[0]) &&
+            data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
+            !data[4].length && data[9] == 1
+          ) {
+        wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
+      } else {
+        wrapper = (func.length == 1 && isLaziable(func))
+          ? wrapper[funcName]()
+          : wrapper.thru(func);
+      }
+    }
+    return function() {
+      var args = arguments,
+          value = args[0];
 
-	// preserve .conversion property if there is one
-	if ('conversion' in fn) {
-		wrappedFn.conversion = fn.conversion;
-	}
+      if (wrapper && args.length == 1 && isArray(value)) {
+        return wrapper.plant(value).value();
+      }
+      var index = 0,
+          result = length ? funcs[index].apply(this, args) : value;
 
-	return wrappedFn;
+      while (++index < length) {
+        result = funcs[index].call(this, result);
+      }
+      return result;
+    };
+  });
 }
 
-models.forEach(function (fromModel) {
-	convert[fromModel] = {};
-
-	Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
-	Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
-
-	var routes = route(fromModel);
-	var routeModels = Object.keys(routes);
-
-	routeModels.forEach(function (toModel) {
-		var fn = routes[toModel];
-
-		convert[fromModel][toModel] = wrapRounded(fn);
-		convert[fromModel][toModel].raw = wrapRaw(fn);
-	});
-});
-
-module.exports = convert;
+module.exports = createFlow;
 
 
 /***/ }),
-/* 822 */
+/* 807 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-/* MIT license */
-var cssKeywords = __webpack_require__(823);
-
-// NOTE: conversions should only return primitive values (i.e. arrays, or
-//       values that give correct `typeof` results).
-//       do not use box values types (i.e. Number(), String(), etc.)
+var baseCreate = __webpack_require__(597),
+    baseLodash = __webpack_require__(808);
 
-var reverseKeywords = {};
-for (var key in cssKeywords) {
-	if (cssKeywords.hasOwnProperty(key)) {
-		reverseKeywords[cssKeywords[key]] = key;
-	}
+/**
+ * The base constructor for creating `lodash` wrapper objects.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ * @param {boolean} [chainAll] Enable explicit method chain sequences.
+ */
+function LodashWrapper(value, chainAll) {
+  this.__wrapped__ = value;
+  this.__actions__ = [];
+  this.__chain__ = !!chainAll;
+  this.__index__ = 0;
+  this.__values__ = undefined;
 }
 
-var convert = module.exports = {
-	rgb: {channels: 3, labels: 'rgb'},
-	hsl: {channels: 3, labels: 'hsl'},
-	hsv: {channels: 3, labels: 'hsv'},
-	hwb: {channels: 3, labels: 'hwb'},
-	cmyk: {channels: 4, labels: 'cmyk'},
-	xyz: {channels: 3, labels: 'xyz'},
-	lab: {channels: 3, labels: 'lab'},
-	lch: {channels: 3, labels: 'lch'},
-	hex: {channels: 1, labels: ['hex']},
-	keyword: {channels: 1, labels: ['keyword']},
-	ansi16: {channels: 1, labels: ['ansi16']},
-	ansi256: {channels: 1, labels: ['ansi256']},
-	hcg: {channels: 3, labels: ['h', 'c', 'g']},
-	apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
-	gray: {channels: 1, labels: ['gray']}
-};
+LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+LodashWrapper.prototype.constructor = LodashWrapper;
 
-// hide .channels and .labels properties
-for (var model in convert) {
-	if (convert.hasOwnProperty(model)) {
-		if (!('channels' in convert[model])) {
-			throw new Error('missing channels property: ' + model);
-		}
+module.exports = LodashWrapper;
 
-		if (!('labels' in convert[model])) {
-			throw new Error('missing channel labels property: ' + model);
-		}
 
-		if (convert[model].labels.length !== convert[model].channels) {
-			throw new Error('channel and label counts mismatch: ' + model);
-		}
+/***/ }),
+/* 808 */
+/***/ ((module) => {
 
-		var channels = convert[model].channels;
-		var labels = convert[model].labels;
-		delete convert[model].channels;
-		delete convert[model].labels;
-		Object.defineProperty(convert[model], 'channels', {value: channels});
-		Object.defineProperty(convert[model], 'labels', {value: labels});
-	}
+/**
+ * The function whose prototype chain sequence wrappers inherit from.
+ *
+ * @private
+ */
+function baseLodash() {
+  // No operation performed.
 }
 
-convert.rgb.hsl = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var min = Math.min(r, g, b);
-	var max = Math.max(r, g, b);
-	var delta = max - min;
-	var h;
-	var s;
-	var l;
-
-	if (max === min) {
-		h = 0;
-	} else if (r === max) {
-		h = (g - b) / delta;
-	} else if (g === max) {
-		h = 2 + (b - r) / delta;
-	} else if (b === max) {
-		h = 4 + (r - g) / delta;
-	}
-
-	h = Math.min(h * 60, 360);
+module.exports = baseLodash;
 
-	if (h < 0) {
-		h += 360;
-	}
 
-	l = (min + max) / 2;
+/***/ }),
+/* 809 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-	if (max === min) {
-		s = 0;
-	} else if (l <= 0.5) {
-		s = delta / (max + min);
-	} else {
-		s = delta / (2 - max - min);
-	}
+var metaMap = __webpack_require__(810),
+    noop = __webpack_require__(483);
 
-	return [h, s * 100, l * 100];
+/**
+ * Gets metadata for `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {*} Returns the metadata for `func`.
+ */
+var getData = !metaMap ? noop : function(func) {
+  return metaMap.get(func);
 };
 
-convert.rgb.hsv = function (rgb) {
-	var rdif;
-	var gdif;
-	var bdif;
-	var h;
-	var s;
+module.exports = getData;
 
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var v = Math.max(r, g, b);
-	var diff = v - Math.min(r, g, b);
-	var diffc = function (c) {
-		return (v - c) / 6 / diff + 1 / 2;
-	};
 
-	if (diff === 0) {
-		h = s = 0;
-	} else {
-		s = diff / v;
-		rdif = diffc(r);
-		gdif = diffc(g);
-		bdif = diffc(b);
+/***/ }),
+/* 810 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-		if (r === v) {
-			h = bdif - gdif;
-		} else if (g === v) {
-			h = (1 / 3) + rdif - bdif;
-		} else if (b === v) {
-			h = (2 / 3) + gdif - rdif;
-		}
-		if (h < 0) {
-			h += 1;
-		} else if (h > 1) {
-			h -= 1;
-		}
-	}
+var WeakMap = __webpack_require__(463);
 
-	return [
-		h * 360,
-		s * 100,
-		v * 100
-	];
-};
+/** Used to store function metadata. */
+var metaMap = WeakMap && new WeakMap;
 
-convert.rgb.hwb = function (rgb) {
-	var r = rgb[0];
-	var g = rgb[1];
-	var b = rgb[2];
-	var h = convert.rgb.hsl(rgb)[0];
-	var w = 1 / 255 * Math.min(r, Math.min(g, b));
+module.exports = metaMap;
 
-	b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
 
-	return [h, w * 100, b * 100];
-};
+/***/ }),
+/* 811 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-convert.rgb.cmyk = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var c;
-	var m;
-	var y;
-	var k;
+var realNames = __webpack_require__(812);
 
-	k = Math.min(1 - r, 1 - g, 1 - b);
-	c = (1 - r - k) / (1 - k) || 0;
-	m = (1 - g - k) / (1 - k) || 0;
-	y = (1 - b - k) / (1 - k) || 0;
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-	return [c * 100, m * 100, y * 100, k * 100];
-};
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
 /**
- * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
- * */
-function comparativeDistance(x, y) {
-	return (
-		Math.pow(x[0] - y[0], 2) +
-		Math.pow(x[1] - y[1], 2) +
-		Math.pow(x[2] - y[2], 2)
-	);
-}
-
-convert.rgb.keyword = function (rgb) {
-	var reversed = reverseKeywords[rgb];
-	if (reversed) {
-		return reversed;
-	}
+ * Gets the name of `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {string} Returns the function name.
+ */
+function getFuncName(func) {
+  var result = (func.name + ''),
+      array = realNames[result],
+      length = hasOwnProperty.call(realNames, result) ? array.length : 0;
 
-	var currentClosestDistance = Infinity;
-	var currentClosestKeyword;
+  while (length--) {
+    var data = array[length],
+        otherFunc = data.func;
+    if (otherFunc == null || otherFunc == func) {
+      return data.name;
+    }
+  }
+  return result;
+}
 
-	for (var keyword in cssKeywords) {
-		if (cssKeywords.hasOwnProperty(keyword)) {
-			var value = cssKeywords[keyword];
+module.exports = getFuncName;
 
-			// Compute comparative distance
-			var distance = comparativeDistance(rgb, value);
 
-			// Check if its less, if so set as closest
-			if (distance < currentClosestDistance) {
-				currentClosestDistance = distance;
-				currentClosestKeyword = keyword;
-			}
-		}
-	}
+/***/ }),
+/* 812 */
+/***/ ((module) => {
 
-	return currentClosestKeyword;
-};
+/** Used to lookup unminified function names. */
+var realNames = {};
 
-convert.keyword.rgb = function (keyword) {
-	return cssKeywords[keyword];
-};
+module.exports = realNames;
 
-convert.rgb.xyz = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
 
-	// assume sRGB
-	r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
-	g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
-	b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
+/***/ }),
+/* 813 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-	var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
-	var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
-	var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
+var LazyWrapper = __webpack_require__(814),
+    getData = __webpack_require__(809),
+    getFuncName = __webpack_require__(811),
+    lodash = __webpack_require__(815);
 
-	return [x * 100, y * 100, z * 100];
-};
+/**
+ * Checks if `func` has a lazy counterpart.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
+ *  else `false`.
+ */
+function isLaziable(func) {
+  var funcName = getFuncName(func),
+      other = lodash[funcName];
 
-convert.rgb.lab = function (rgb) {
-	var xyz = convert.rgb.xyz(rgb);
-	var x = xyz[0];
-	var y = xyz[1];
-	var z = xyz[2];
-	var l;
-	var a;
-	var b;
+  if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
+    return false;
+  }
+  if (func === other) {
+    return true;
+  }
+  var data = getData(other);
+  return !!data && func === data[0];
+}
 
-	x /= 95.047;
-	y /= 100;
-	z /= 108.883;
+module.exports = isLaziable;
 
-	x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
-	y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
-	z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
 
-	l = (116 * y) - 16;
-	a = 500 * (x - y);
-	b = 200 * (y - z);
+/***/ }),
+/* 814 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-	return [l, a, b];
-};
+var baseCreate = __webpack_require__(597),
+    baseLodash = __webpack_require__(808);
 
-convert.hsl.rgb = function (hsl) {
-	var h = hsl[0] / 360;
-	var s = hsl[1] / 100;
-	var l = hsl[2] / 100;
-	var t1;
-	var t2;
-	var t3;
-	var rgb;
-	var val;
+/** Used as references for the maximum length and index of an array. */
+var MAX_ARRAY_LENGTH = 4294967295;
 
-	if (s === 0) {
-		val = l * 255;
-		return [val, val, val];
-	}
+/**
+ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+ *
+ * @private
+ * @constructor
+ * @param {*} value The value to wrap.
+ */
+function LazyWrapper(value) {
+  this.__wrapped__ = value;
+  this.__actions__ = [];
+  this.__dir__ = 1;
+  this.__filtered__ = false;
+  this.__iteratees__ = [];
+  this.__takeCount__ = MAX_ARRAY_LENGTH;
+  this.__views__ = [];
+}
 
-	if (l < 0.5) {
-		t2 = l * (1 + s);
-	} else {
-		t2 = l + s - l * s;
-	}
+// Ensure `LazyWrapper` is an instance of `baseLodash`.
+LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+LazyWrapper.prototype.constructor = LazyWrapper;
 
-	t1 = 2 * l - t2;
+module.exports = LazyWrapper;
 
-	rgb = [0, 0, 0];
-	for (var i = 0; i < 3; i++) {
-		t3 = h + 1 / 3 * -(i - 1);
-		if (t3 < 0) {
-			t3++;
-		}
-		if (t3 > 1) {
-			t3--;
-		}
 
-		if (6 * t3 < 1) {
-			val = t1 + (t2 - t1) * 6 * t3;
-		} else if (2 * t3 < 1) {
-			val = t2;
-		} else if (3 * t3 < 2) {
-			val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
-		} else {
-			val = t1;
-		}
+/***/ }),
+/* 815 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-		rgb[i] = val * 255;
-	}
+var LazyWrapper = __webpack_require__(814),
+    LodashWrapper = __webpack_require__(807),
+    baseLodash = __webpack_require__(808),
+    isArray = __webpack_require__(55),
+    isObjectLike = __webpack_require__(53),
+    wrapperClone = __webpack_require__(816);
 
-	return rgb;
-};
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
 
-convert.hsl.hsv = function (hsl) {
-	var h = hsl[0];
-	var s = hsl[1] / 100;
-	var l = hsl[2] / 100;
-	var smin = s;
-	var lmin = Math.max(l, 0.01);
-	var sv;
-	var v;
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
 
-	l *= 2;
-	s *= (l <= 1) ? l : 2 - l;
-	smin *= lmin <= 1 ? lmin : 2 - lmin;
-	v = (l + s) / 2;
-	sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
+/**
+ * Creates a `lodash` object which wraps `value` to enable implicit method
+ * chain sequences. Methods that operate on and return arrays, collections,
+ * and functions can be chained together. Methods that retrieve a single value
+ * or may return a primitive value will automatically end the chain sequence
+ * and return the unwrapped value. Otherwise, the value must be unwrapped
+ * with `_#value`.
+ *
+ * Explicit chain sequences, which must be unwrapped with `_#value`, may be
+ * enabled using `_.chain`.
+ *
+ * The execution of chained methods is lazy, that is, it's deferred until
+ * `_#value` is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion.
+ * Shortcut fusion is an optimization to merge iteratee calls; this avoids
+ * the creation of intermediate arrays and can greatly reduce the number of
+ * iteratee executions. Sections of a chain sequence qualify for shortcut
+ * fusion if the section is applied to an array and iteratees accept only
+ * one argument. The heuristic for whether a section qualifies for shortcut
+ * fusion is subject to change.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+ * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
+ * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
+ * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
+ * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
+ * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
+ * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
+ * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
+ * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
+ * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
+ * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
+ * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
+ * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
+ * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
+ * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
+ * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
+ * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
+ * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
+ * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
+ * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
+ * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
+ * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
+ * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
+ * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
+ * `zipObject`, `zipObjectDeep`, and `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
+ * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
+ * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
+ * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
+ * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+ * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+ * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
+ * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
+ * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
+ * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
+ * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
+ * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
+ * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
+ * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
+ * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
+ * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
+ * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
+ * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
+ * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
+ * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
+ * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
+ * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
+ * `upperFirst`, `value`, and `words`
+ *
+ * @name _
+ * @constructor
+ * @category Seq
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ *   return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // Returns an unwrapped value.
+ * wrapped.reduce(_.add);
+ * // => 6
+ *
+ * // Returns a wrapped value.
+ * var squares = wrapped.map(square);
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */
+function lodash(value) {
+  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+    if (value instanceof LodashWrapper) {
+      return value;
+    }
+    if (hasOwnProperty.call(value, '__wrapped__')) {
+      return wrapperClone(value);
+    }
+  }
+  return new LodashWrapper(value);
+}
 
-	return [h, sv * 100, v * 100];
-};
+// Ensure wrappers are instances of `baseLodash`.
+lodash.prototype = baseLodash.prototype;
+lodash.prototype.constructor = lodash;
 
-convert.hsv.rgb = function (hsv) {
-	var h = hsv[0] / 60;
-	var s = hsv[1] / 100;
-	var v = hsv[2] / 100;
-	var hi = Math.floor(h) % 6;
+module.exports = lodash;
 
-	var f = h - Math.floor(h);
-	var p = 255 * v * (1 - s);
-	var q = 255 * v * (1 - (s * f));
-	var t = 255 * v * (1 - (s * (1 - f)));
-	v *= 255;
 
-	switch (hi) {
-		case 0:
-			return [v, t, p];
-		case 1:
-			return [q, v, p];
-		case 2:
-			return [p, v, t];
-		case 3:
-			return [p, q, v];
-		case 4:
-			return [t, p, v];
-		case 5:
-			return [v, p, q];
-	}
-};
+/***/ }),
+/* 816 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-convert.hsv.hsl = function (hsv) {
-	var h = hsv[0];
-	var s = hsv[1] / 100;
-	var v = hsv[2] / 100;
-	var vmin = Math.max(v, 0.01);
-	var lmin;
-	var sl;
-	var l;
+var LazyWrapper = __webpack_require__(814),
+    LodashWrapper = __webpack_require__(807),
+    copyArray = __webpack_require__(583);
 
-	l = (2 - s) * v;
-	lmin = (2 - s) * vmin;
-	sl = s * vmin;
-	sl /= (lmin <= 1) ? lmin : 2 - lmin;
-	sl = sl || 0;
-	l /= 2;
+/**
+ * Creates a clone of `wrapper`.
+ *
+ * @private
+ * @param {Object} wrapper The wrapper to clone.
+ * @returns {Object} Returns the cloned wrapper.
+ */
+function wrapperClone(wrapper) {
+  if (wrapper instanceof LazyWrapper) {
+    return wrapper.clone();
+  }
+  var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
+  result.__actions__ = copyArray(wrapper.__actions__);
+  result.__index__  = wrapper.__index__;
+  result.__values__ = wrapper.__values__;
+  return result;
+}
 
-	return [h, sl * 100, l * 100];
-};
+module.exports = wrapperClone;
 
-// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
-convert.hwb.rgb = function (hwb) {
-	var h = hwb[0] / 360;
-	var wh = hwb[1] / 100;
-	var bl = hwb[2] / 100;
-	var ratio = wh + bl;
-	var i;
-	var v;
-	var f;
-	var n;
 
-	// wh + bl cant be > 1
-	if (ratio > 1) {
-		wh /= ratio;
-		bl /= ratio;
-	}
+/***/ }),
+/* 817 */
+/***/ ((__unused_webpack_module, exports) => {
 
-	i = Math.floor(6 * h);
-	v = 1 - bl;
-	f = 6 * h - i;
+"use strict";
 
-	if ((i & 0x01) !== 0) {
-		f = 1 - f;
-	}
 
-	n = wh + f * (v - wh); // linear interpolation
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.hasQueryBeenLoaded = exports.isQueryLoading = exports.cancelable = void 0;
 
-	var r;
-	var g;
-	var b;
-	switch (i) {
-		default:
-		case 6:
-		case 0: r = v; g = n; b = wh; break;
-		case 1: r = n; g = v; b = wh; break;
-		case 2: r = wh; g = v; b = n; break;
-		case 3: r = wh; g = n; b = v; break;
-		case 4: r = n; g = wh; b = v; break;
-		case 5: r = v; g = wh; b = n; break;
-	}
+/**
+ * @typedef {Promise} CancelablePromise
+ * @property {Function} cancel - Cancel the promise
+ */
 
-	return [r * 255, g * 255, b * 255];
-};
+/**
+ * Wraps a promise so that it can be canceled
+ *
+ * Rejects with canceled: true as soon as cancel is called
+ *
+ * @param  {Promise} promise  - Promise
+ * @returns {CancelablePromise} - Promise with .cancel method
+ */
+var cancelable = function cancelable(promise) {
+  var _reject;
 
-convert.cmyk.rgb = function (cmyk) {
-	var c = cmyk[0] / 100;
-	var m = cmyk[1] / 100;
-	var y = cmyk[2] / 100;
-	var k = cmyk[3] / 100;
-	var r;
-	var g;
-	var b;
+  var wrapped = new Promise(function (resolve, reject) {
+    _reject = reject;
+    promise.then(resolve);
+    promise.catch(reject);
+  }); // @ts-ignore
 
-	r = 1 - Math.min(1, c * (1 - k) + k);
-	g = 1 - Math.min(1, m * (1 - k) + k);
-	b = 1 - Math.min(1, y * (1 - k) + k);
+  wrapped.cancel = function () {
+    _reject({
+      canceled: true
+    });
+  };
 
-	return [r * 255, g * 255, b * 255];
+  return wrapped;
 };
 
-convert.xyz.rgb = function (xyz) {
-	var x = xyz[0] / 100;
-	var y = xyz[1] / 100;
-	var z = xyz[2] / 100;
-	var r;
-	var g;
-	var b;
+exports.cancelable = cancelable;
 
-	r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
-	g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
-	b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
+/**
+ * Returns whether the result of a query (given via queryConnect or Query)
+ * is loading.
+ */
+var isQueryLoading = function isQueryLoading(col) {
+  if (!col) {
+    console.warn('isQueryLoading called on falsy value.'); // eslint-disable-line no-console
 
-	// assume sRGB
-	r = r > 0.0031308
-		? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
-		: r * 12.92;
+    return false;
+  }
 
-	g = g > 0.0031308
-		? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
-		: g * 12.92;
+  return col.fetchStatus === 'loading' || col.fetchStatus === 'pending';
+};
+/**
+ * Returns whether a query has been loaded at least once
+ */
 
-	b = b > 0.0031308
-		? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
-		: b * 12.92;
 
-	r = Math.min(Math.max(0, r), 1);
-	g = Math.min(Math.max(0, g), 1);
-	b = Math.min(Math.max(0, b), 1);
+exports.isQueryLoading = isQueryLoading;
 
-	return [r * 255, g * 255, b * 255];
+var hasQueryBeenLoaded = function hasQueryBeenLoaded(col) {
+  return col.lastFetch;
 };
 
-convert.xyz.lab = function (xyz) {
-	var x = xyz[0];
-	var y = xyz[1];
-	var z = xyz[2];
-	var l;
-	var a;
-	var b;
+exports.hasQueryBeenLoaded = hasQueryBeenLoaded;
 
-	x /= 95.047;
-	y /= 100;
-	z /= 108.883;
+/***/ }),
+/* 818 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-	x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
-	y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
-	z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
+"use strict";
 
-	l = (116 * y) - 16;
-	a = 500 * (x - y);
-	b = 200 * (y - z);
 
-	return [l, a, b];
-};
+var _interopRequireDefault = __webpack_require__(524);
 
-convert.lab.xyz = function (lab) {
-	var l = lab[0];
-	var a = lab[1];
-	var b = lab[2];
-	var x;
-	var y;
-	var z;
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.sanitizeCategories = sanitizeCategories;
+exports.areTermsValid = areTermsValid;
+exports.isPartnershipValid = isPartnershipValid;
+exports.sanitize = sanitize;
 
-	y = (l + 16) / 116;
-	x = a / 500 + y;
-	z = y - b / 200;
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-	var y2 = Math.pow(y, 3);
-	var x2 = Math.pow(x, 3);
-	var z2 = Math.pow(z, 3);
-	y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
-	x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
-	z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
+var _types = __webpack_require__(622);
 
-	x *= 95.047;
-	y *= 100;
-	z *= 108.883;
+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; }
 
-	return [x, y, z];
-};
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-convert.lab.lch = function (lab) {
-	var l = lab[0];
-	var a = lab[1];
-	var b = lab[2];
-	var hr;
-	var h;
-	var c;
+var APP_CATEGORIES = ['banking', 'cozy', 'energy', 'health', 'host_provider', 'insurance', 'isp', 'mes_infos', 'online_services', 'others', 'partners', 'press', 'productivity', 'ptnb', 'public_service', 'shopping', 'social', 'telecom', 'transport'];
+/** Filters unauthorized categories. Defaults to ['others'] if no suitable category. */
 
-	hr = Math.atan2(b, a);
-	h = hr * 360 / 2 / Math.PI;
+function sanitizeCategories(categories) {
+  if (!categories) return ['others'];
+  var filteredList = categories.filter(function (c) {
+    return APP_CATEGORIES.includes(c);
+  });
+  if (!filteredList.length) return ['others'];
+  return filteredList;
+}
 
-	if (h < 0) {
-		h += 360;
-	}
+function areTermsValid(terms) {
+  return Boolean(terms && terms.id && terms.url && terms.version);
+}
 
-	c = Math.sqrt(a * a + b * b);
+function isPartnershipValid(partnership) {
+  return Boolean(partnership && partnership.description);
+}
+/**
+ * Normalize app manifest, retrocompatibility for old manifests
+ *
+ * @param  {Manifest} manifest
+ * @returns {Manifest}
+ */
 
-	return [l, c, h];
-};
 
-convert.lch.lab = function (lch) {
-	var l = lch[0];
-	var c = lch[1];
-	var h = lch[2];
-	var a;
-	var b;
-	var hr;
+function sanitize(manifest) {
+  var sanitized = _objectSpread({}, manifest); // Make categories an array and delete category attribute if it exists
 
-	hr = h / 360 * 2 * Math.PI;
-	a = c * Math.cos(hr);
-	b = c * Math.sin(hr);
 
-	return [l, a, b];
-};
+  if (!manifest.categories && manifest.category && typeof manifest.category === 'string') {
+    sanitized.categories = [manifest.category];
+    delete sanitized.category;
+  }
 
-convert.rgb.ansi16 = function (args) {
-	var r = args[0];
-	var g = args[1];
-	var b = args[2];
-	var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
+  sanitized.categories = sanitizeCategories(sanitized.categories); // manifest name is not an object
 
-	value = Math.round(value / 50);
+  if (typeof manifest.name === 'object') sanitized.name = manifest.name.en; // Fix camelCase from cozy-stack
 
-	if (value === 0) {
-		return 30;
-	}
+  if (manifest.available_version) {
+    sanitized.availableVersion = manifest.available_version;
+    delete sanitized.available_version;
+  } // Fix camelCase from cozy-stack
 
-	var ansi = 30
-		+ ((Math.round(b / 255) << 2)
-		| (Math.round(g / 255) << 1)
-		| Math.round(r / 255));
 
-	if (value === 2) {
-		ansi += 60;
-	}
+  if (manifest.latest_version) {
+    sanitized.latestVersion = manifest.latestVersion;
+    delete sanitized.latest_version;
+  } // Remove invalid terms
 
-	return ansi;
-};
 
-convert.hsv.ansi16 = function (args) {
-	// optimization here; we already know the value and don't need to get
-	// it converted for us.
-	return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
-};
+  if (sanitized.terms && !areTermsValid(sanitized.terms)) {
+    delete sanitized.terms;
+  } // Remove invalid partnership
 
-convert.rgb.ansi256 = function (args) {
-	var r = args[0];
-	var g = args[1];
-	var b = args[2];
 
-	// we use the extended greyscale palette here, with the exception of
-	// black and white. normal palette only has 4 greyscale shades.
-	if (r === g && g === b) {
-		if (r < 8) {
-			return 16;
-		}
+  if (sanitized.partnership && !isPartnershipValid(sanitized.partnership)) {
+    delete sanitized.partnership;
+  }
 
-		if (r > 248) {
-			return 231;
-		}
+  return sanitized;
+}
 
-		return Math.round(((r - 8) / 247) * 24) + 232;
-	}
+/***/ }),
+/* 819 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
-	var ansi = 16
-		+ (36 * Math.round(r / 255 * 5))
-		+ (6 * Math.round(g / 255 * 5))
-		+ Math.round(b / 255 * 5);
+"use strict";
 
-	return ansi;
-};
 
-convert.ansi16.rgb = function (args) {
-	var color = args % 10;
+var _interopRequireDefault = __webpack_require__(524);
 
-	// handle greyscale
-	if (color === 0 || color === 7) {
-		if (args > 50) {
-			color += 3.5;
-		}
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.createMockClient = void 0;
 
-		color = color / 10.5 * 255;
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532));
 
-		return [color, color, color];
-	}
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-	var mult = (~~(args > 50) + 1) * 0.5;
-	var r = ((color & 1) * mult) * 255;
-	var g = (((color >> 1) & 1) * mult) * 255;
-	var b = (((color >> 2) & 1) * mult) * 255;
+var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537));
 
-	return [r, g, b];
-};
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
-convert.ansi256.rgb = function (args) {
-	// handle greyscale
-	if (args >= 232) {
-		var c = (args - 232) * 10 + 8;
-		return [c, c, c];
-	}
+var _store = __webpack_require__(705);
 
-	args -= 16;
+var _cozyStackClient = __webpack_require__(571);
 
-	var rem;
-	var r = Math.floor(args / 36) / 5 * 255;
-	var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
-	var b = (rem % 6) / 5 * 255;
+var _dsl = __webpack_require__(619);
 
-	return [r, g, b];
+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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
+
+var fillQueryInsideClient = function fillQueryInsideClient(client, queryName, queryOptions) {
+  var definition = queryOptions.definition,
+      doctype = queryOptions.doctype,
+      data = queryOptions.data,
+      queryResult = (0, _objectWithoutProperties2.default)(queryOptions, ["definition", "doctype", "data"]);
+  client.store.dispatch((0, _store.initQuery)(queryName, definition || (0, _dsl.Q)(doctype)));
+  client.store.dispatch((0, _store.receiveQueryResult)(queryName, _objectSpread({
+    data: data ? data.map(function (doc) {
+      return (0, _cozyStackClient.normalizeDoc)(doc, doctype);
+    }) : data
+  }, queryResult)));
 };
 
-convert.rgb.hex = function (args) {
-	var integer = ((Math.round(args[0]) & 0xFF) << 16)
-		+ ((Math.round(args[1]) & 0xFF) << 8)
-		+ (Math.round(args[2]) & 0xFF);
+var mockedQueryFromMockedRemoteData = function mockedQueryFromMockedRemoteData(remoteData) {
+  return function (qdef) {
+    if (!remoteData) {
+      return {
+        data: null
+      };
+    }
 
-	var string = integer.toString(16).toUpperCase();
-	return '000000'.substring(string.length) + string;
+    if (remoteData[qdef.doctype]) {
+      return {
+        data: remoteData[qdef.doctype]
+      };
+    } else {
+      return {
+        data: []
+      };
+    }
+  };
 };
+/**
+ * Creates a client suitable for use in tests
+ *
+ * - client.{query,save} are mocked
+ * - client.stackClient.fetchJSON is mocked
+ *
+ * @param  {object} options Options
+ * @param  {object} [options.queries] Prefill queries inside the store
+ * @param  {object} [options.remote] Mock data from the server
+ * @param  {object} [options.clientOptions] Options passed to the client
+ * @returns {CozyClient}
+ */
 
-convert.hex.rgb = function (args) {
-	var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
-	if (!match) {
-		return [0, 0, 0];
-	}
 
-	var colorString = match[0];
+var createMockClient = function createMockClient(_ref) {
+  var queries = _ref.queries,
+      remote = _ref.remote,
+      clientOptions = _ref.clientOptions;
+  var client = new _CozyClient.default(clientOptions || {});
+  client.ensureStore();
 
-	if (match[0].length === 3) {
-		colorString = colorString.split('').map(function (char) {
-			return char + char;
-		}).join('');
-	}
+  for (var _i = 0, _Object$entries = Object.entries(queries || {}); _i < _Object$entries.length; _i++) {
+    var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
+        queryName = _Object$entries$_i[0],
+        queryOptions = _Object$entries$_i[1];
 
-	var integer = parseInt(colorString, 16);
-	var r = (integer >> 16) & 0xFF;
-	var g = (integer >> 8) & 0xFF;
-	var b = integer & 0xFF;
+    fillQueryInsideClient(client, queryName, queryOptions);
+  }
 
-	return [r, g, b];
+  client.query = jest.fn().mockImplementation(mockedQueryFromMockedRemoteData(remote));
+  client.save = jest.fn();
+  client.saveAll = jest.fn();
+  client.stackClient.fetchJSON = jest.fn();
+  return client;
 };
 
-convert.rgb.hcg = function (rgb) {
-	var r = rgb[0] / 255;
-	var g = rgb[1] / 255;
-	var b = rgb[2] / 255;
-	var max = Math.max(Math.max(r, g), b);
-	var min = Math.min(Math.min(r, g), b);
-	var chroma = (max - min);
-	var grayscale;
-	var hue;
+exports.createMockClient = createMockClient;
 
-	if (chroma < 1) {
-		grayscale = min / (1 - chroma);
-	} else {
-		grayscale = 0;
-	}
+/***/ }),
+/* 820 */
+/***/ ((module, exports, __webpack_require__) => {
 
-	if (chroma <= 0) {
-		hue = 0;
-	} else
-	if (max === r) {
-		hue = ((g - b) / chroma) % 6;
-	} else
-	if (max === g) {
-		hue = 2 + (b - r) / chroma;
-	} else {
-		hue = 4 + (r - g) / chroma + 4;
-	}
+"use strict";
+/* module decorator */ module = __webpack_require__.nmd(module);
 
-	hue /= 6;
-	hue %= 1;
 
-	return [hue * 360, chroma * 100, grayscale * 100];
-};
+var _interopRequireDefault = __webpack_require__(524);
 
-convert.hsl.hcg = function (hsl) {
-	var s = hsl[1] / 100;
-	var l = hsl[2] / 100;
-	var c = 1;
-	var f = 0;
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.createClientInteractive = void 0;
 
-	if (l < 0.5) {
-		c = 2.0 * s * l;
-	} else {
-		c = 2.0 * s * (1.0 - l);
-	}
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-	if (c < 1.0) {
-		f = (l - 0.5 * c) / (1.0 - c);
-	}
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-	return [hsl[0], c * 100, f * 100];
-};
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-convert.hsv.hcg = function (hsv) {
-	var s = hsv[1] / 100;
-	var v = hsv[2] / 100;
+var _http = _interopRequireDefault(__webpack_require__(80));
 
-	var c = s * v;
-	var f = 0;
+var _open = _interopRequireDefault(__webpack_require__(821));
 
-	if (c < 1.0) {
-		f = (v - c) / (1 - c);
-	}
+var _fs = _interopRequireDefault(__webpack_require__(149));
 
-	return [hsv[0], c * 100, f * 100];
-};
+var _merge = _interopRequireDefault(__webpack_require__(754));
 
-convert.hcg.rgb = function (hcg) {
-	var h = hcg[0] / 360;
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
+var _serverDestroy = _interopRequireDefault(__webpack_require__(825));
 
-	if (c === 0.0) {
-		return [g * 255, g * 255, g * 255];
-	}
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
-	var pure = [0, 0, 0];
-	var hi = (h % 1) * 6;
-	var v = hi % 1;
-	var w = 1 - v;
-	var mg = 0;
+var _cozyLogger = _interopRequireDefault(__webpack_require__(354));
 
-	switch (Math.floor(hi)) {
-		case 0:
-			pure[0] = 1; pure[1] = v; pure[2] = 0; break;
-		case 1:
-			pure[0] = w; pure[1] = 1; pure[2] = 0; break;
-		case 2:
-			pure[0] = 0; pure[1] = 1; pure[2] = v; break;
-		case 3:
-			pure[0] = 0; pure[1] = w; pure[2] = 1; break;
-		case 4:
-			pure[0] = v; pure[1] = 0; pure[2] = 1; break;
-		default:
-			pure[0] = 1; pure[1] = 0; pure[2] = w;
-	}
+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; }
 
-	mg = (1.0 - c) * g;
+function _objectSpread(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) { (0, _defineProperty2.default)(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; }
 
-	return [
-		(c * pure[0] + mg) * 255,
-		(c * pure[1] + mg) * 255,
-		(c * pure[2] + mg) * 255
-	];
-};
+var log = _cozyLogger.default.namespace('create-cli-client');
+
+var nodeFetch = __webpack_require__(493);
+
+var btoa = __webpack_require__(490);
+/**
+ * Creates and starts and HTTP server suitable for OAuth authentication
+ *
+ * @param  {object} serverOptions - OAuth callback server options
+ * @param  {Function} serverOptions.onAuthentication - Additional callback called
+ * when the user authenticates
+ * @param  {string} serverOptions.route - Route used for authentication
+ * @param  {number} serverOptions.port - Port on which the server will listen
+ * @param  {Function} serverOptions.onListen - Callback called when the
+ * server starts
+ *
+ * @typedef {object} DestroyableServer
+ * @function destroy
+ *
+ * @returns {DestroyableServer}
+ *
+ * @private
+ */
 
-convert.hcg.hsv = function (hcg) {
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
 
-	var v = c + g * (1.0 - c);
-	var f = 0;
+var createCallbackServer = function createCallbackServer(serverOptions) {
+  var route = serverOptions.route,
+      onListen = serverOptions.onListen,
+      onAuthentication = serverOptions.onAuthentication,
+      port = serverOptions.port;
 
-	if (v > 0.0) {
-		f = c / v;
-	}
+  var server = _http.default.createServer(function (request, response) {
+    if (request.url.indexOf(route) === 0) {
+      onAuthentication(request.url);
+      response.write('Authentication successful, you can close this page.');
+      response.end();
+    }
+  });
 
-	return [hcg[0], f * 100, v * 100];
+  server.listen(port, function () {
+    onListen();
+  });
+  (0, _serverDestroy.default)(server);
+  return server;
 };
+/**
+ * Creates a function suitable for usage with CozyClient::startOAuthFlow
+ *
+ * Starts a local server. The stack upon user authentication will
+ * redirect to this local server with a URL containing credentials.
+ * The callback resolves with this authenticationURL which continues
+ * the authentication flow inside startOAuthFlow.
+ *
+ * When the server is started, the authentication page is opened on the
+ * desktop browser of the user.
+ *
+ * @param {object} serverOptions - Options for the OAuth callback server
+ * @param {number} serverOptions.port - Port used for the OAuth callback server
+ * @param {Function} serverOptions.onAuthentication - Callback when the user authenticates
+ * @param {Function} serverOptions.onListen - Callback called with the authentication URL
+ * @param {string} serverOptions.route - Route used for authentication
+ * @param {boolean} serverOptions.shouldOpenAuthenticationPage - Whether the authentication
+ * page should be automatically opened (default: true)
+ *
+ * @private
+ */
 
-convert.hcg.hsl = function (hcg) {
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
-
-	var l = g * (1.0 - c) + 0.5 * c;
-	var s = 0;
 
-	if (l > 0.0 && l < 0.5) {
-		s = c / (2 * l);
-	} else
-	if (l >= 0.5 && l < 1.0) {
-		s = c / (2 * (1 - l));
-	}
+var mkServerFlowCallback = function mkServerFlowCallback(serverOptions) {
+  return function (authenticationURL) {
+    return new Promise(function (resolve, reject) {
+      var rejectTimeout, successTimeout;
+      var server = createCallbackServer(_objectSpread(_objectSpread({}, serverOptions), {}, {
+        onAuthentication: function onAuthentication(callbackURL) {
+          log('debug', 'Authenticated, Shutting server down');
+          successTimeout = setTimeout(function () {
+            // Is there a way to call destroy only after all requests have
+            // been completely served ? Otherwise we close the server while
+            // the successful oauth page is being served and the page does
+            // not get loaded on the client side.
+            server.destroy();
+            resolve('http://localhost:8000/' + callbackURL);
+            clearTimeout(rejectTimeout);
+          }, 300);
+        },
+        onListen: function onListen() {
+          log('debug', 'OAuth callback server started, waiting for authentication');
 
-	return [hcg[0], s * 100, l * 100];
-};
+          if (serverOptions.shouldOpenAuthenticationPage !== false) {
+            (0, _open.default)(authenticationURL, {
+              wait: false
+            });
+          }
 
-convert.hcg.hwb = function (hcg) {
-	var c = hcg[1] / 100;
-	var g = hcg[2] / 100;
-	var v = c + g * (1.0 - c);
-	return [hcg[0], (v - c) * 100, (1 - v) * 100];
+          if (serverOptions.onListen) {
+            serverOptions.onListen({
+              authenticationURL: authenticationURL
+            });
+          }
+        }
+      }));
+      rejectTimeout = setTimeout(function () {
+        clearTimeout(successTimeout);
+        server.destroy();
+        reject('Timeout for authentication');
+      }, 30 * 1000);
+    });
+  };
 };
 
-convert.hwb.hcg = function (hwb) {
-	var w = hwb[1] / 100;
-	var b = hwb[2] / 100;
-	var v = 1 - b;
-	var c = v - w;
-	var g = 0;
+var hashCode = function hashCode(str) {
+  var hash = 0,
+      i,
+      chr;
+  if (str.length === 0) return hash;
 
-	if (c < 1) {
-		g = (v - c) / (1 - c);
-	}
+  for (i = 0; i < str.length; i++) {
+    chr = str.charCodeAt(i);
+    hash = (hash << 5) - hash + chr;
+    hash |= 0; // Convert to 32bit integer
+  }
 
-	return [hwb[0], c * 100, g * 100];
+  return hash;
 };
 
-convert.apple.rgb = function (apple) {
-	return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
-};
+var DEFAULT_SERVER_OPTIONS = {
+  port: 3333,
+  route: '/do_access',
+  getSavedCredentials: function getSavedCredentials(clientOptions) {
+    if (!clientOptions.oauth.softwareID) {
+      throw new Error('Please provide oauth.softwareID in your clientOptions.');
+    }
 
-convert.rgb.apple = function (rgb) {
-	return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
+    var doctypeHash = Math.abs(hashCode(JSON.stringify(clientOptions.scope)));
+    var sluggedURI = clientOptions.uri.replace(/https?:\/\//, '').replace(/\./g, '-');
+    return "/tmp/cozy-client-oauth-".concat(sluggedURI, "-").concat(clientOptions.oauth.softwareID, "-").concat(doctypeHash, ".json");
+  }
 };
 
-convert.gray.rgb = function (args) {
-	return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
+var writeJSON = function writeJSON(fs, filename, data) {
+  fs.writeFileSync(filename, JSON.stringify(data));
 };
+/**
+ * Parses a JSON from a file
+ * Returns null in case of error
+ *
+ * @private
+ */
 
-convert.gray.hsl = convert.gray.hsv = function (args) {
-	return [0, 0, args[0]];
-};
 
-convert.gray.hwb = function (gray) {
-	return [0, 100, gray[0]];
-};
+var readJSON = function readJSON(fs, filename) {
+  try {
+    if (!fs.existsSync(filename)) {
+      return null;
+    }
 
-convert.gray.cmyk = function (gray) {
-	return [0, 0, 0, gray[0]];
+    var res = JSON.parse(fs.readFileSync(filename).toString());
+    return res;
+  } catch (e) {
+    console.warn("Could not load ".concat(filename, " (").concat(e.message, ")"));
+    return null;
+  }
 };
+/**
+ * Creates a client with interactive authentication.
+ *
+ * - Will start an OAuth flow and open an authentication page
+ * - Starts a local server to listen for the oauth callback
+ * - Resolves with the client after user authentication
+ *
+ * @param {object} clientOptions Same as CozyClient::constructor.
+ *
+ * @example
+ * ```
+ * import { createClientInteractive } from 'cozy-client/dist/cli'
+ * await createClientInteractive({
+ *   uri: 'http://cozy.tools:8080',
+ *   scope: ['io.cozy.bills'],
+ *   oauth: {
+ *     softwareID: 'my-cli-application-using-bills'
+ *   }
+ * })
+ * ```
+ *
+ * @returns {Promise<CozyClient>} - A client that is ready with a token
+ */
 
-convert.gray.lab = function (gray) {
-	return [gray[0], 0, 0];
-};
 
-convert.gray.hex = function (gray) {
-	var val = Math.round(gray[0] / 100 * 255) & 0xFF;
-	var integer = (val << 16) + (val << 8) + val;
+var createClientInteractive = function createClientInteractive(clientOptions, serverOpts) {
+  global.fetch = nodeFetch;
+  global.btoa = btoa;
+  var serverOptions = (0, _merge.default)(DEFAULT_SERVER_OPTIONS, serverOpts);
+  var createClientFS = serverOptions.fs || _fs.default;
+  var mergedClientOptions = (0, _merge.default)({
+    oauth: {
+      clientName: 'cli-client',
+      redirectURI: "http://localhost:".concat(serverOptions.port).concat(serverOptions.route)
+    }
+  }, clientOptions);
 
-	var string = integer.toString(16).toUpperCase();
-	return '000000'.substring(string.length) + string;
-};
+  if (!clientOptions.scope) {
+    throw new Error('scope must be provided in client options');
+  }
 
-convert.rgb.gray = function (rgb) {
-	var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
-	return [val / 255 * 100];
-};
+  var getSavedCredentials = serverOptions.getSavedCredentials;
+  var savedCredentialsFilename = getSavedCredentials(mergedClientOptions);
+  var savedCredentials = readJSON(createClientFS, savedCredentialsFilename);
+  log('debug', "Starting OAuth flow");
+  return new Promise( /*#__PURE__*/function () {
+    var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(resolve, reject) {
+      var client;
+      return _regenerator.default.wrap(function _callee$(_context) {
+        while (1) {
+          switch (_context.prev = _context.next) {
+            case 0:
+              client = new _CozyClient.default(mergedClientOptions);
 
+              if (!savedCredentials) {
+                _context.next = 7;
+                break;
+              }
 
-/***/ }),
-/* 823 */
-/***/ ((module) => {
+              log('debug', "Using saved credentials in ".concat(savedCredentialsFilename));
+              client.stackClient.setToken(savedCredentials.token);
+              client.stackClient.setOAuthOptions(savedCredentials.oauthOptions);
+              resolve(client);
+              return _context.abrupt("return");
 
-"use strict";
-
-
-module.exports = {
-	"aliceblue": [240, 248, 255],
-	"antiquewhite": [250, 235, 215],
-	"aqua": [0, 255, 255],
-	"aquamarine": [127, 255, 212],
-	"azure": [240, 255, 255],
-	"beige": [245, 245, 220],
-	"bisque": [255, 228, 196],
-	"black": [0, 0, 0],
-	"blanchedalmond": [255, 235, 205],
-	"blue": [0, 0, 255],
-	"blueviolet": [138, 43, 226],
-	"brown": [165, 42, 42],
-	"burlywood": [222, 184, 135],
-	"cadetblue": [95, 158, 160],
-	"chartreuse": [127, 255, 0],
-	"chocolate": [210, 105, 30],
-	"coral": [255, 127, 80],
-	"cornflowerblue": [100, 149, 237],
-	"cornsilk": [255, 248, 220],
-	"crimson": [220, 20, 60],
-	"cyan": [0, 255, 255],
-	"darkblue": [0, 0, 139],
-	"darkcyan": [0, 139, 139],
-	"darkgoldenrod": [184, 134, 11],
-	"darkgray": [169, 169, 169],
-	"darkgreen": [0, 100, 0],
-	"darkgrey": [169, 169, 169],
-	"darkkhaki": [189, 183, 107],
-	"darkmagenta": [139, 0, 139],
-	"darkolivegreen": [85, 107, 47],
-	"darkorange": [255, 140, 0],
-	"darkorchid": [153, 50, 204],
-	"darkred": [139, 0, 0],
-	"darksalmon": [233, 150, 122],
-	"darkseagreen": [143, 188, 143],
-	"darkslateblue": [72, 61, 139],
-	"darkslategray": [47, 79, 79],
-	"darkslategrey": [47, 79, 79],
-	"darkturquoise": [0, 206, 209],
-	"darkviolet": [148, 0, 211],
-	"deeppink": [255, 20, 147],
-	"deepskyblue": [0, 191, 255],
-	"dimgray": [105, 105, 105],
-	"dimgrey": [105, 105, 105],
-	"dodgerblue": [30, 144, 255],
-	"firebrick": [178, 34, 34],
-	"floralwhite": [255, 250, 240],
-	"forestgreen": [34, 139, 34],
-	"fuchsia": [255, 0, 255],
-	"gainsboro": [220, 220, 220],
-	"ghostwhite": [248, 248, 255],
-	"gold": [255, 215, 0],
-	"goldenrod": [218, 165, 32],
-	"gray": [128, 128, 128],
-	"green": [0, 128, 0],
-	"greenyellow": [173, 255, 47],
-	"grey": [128, 128, 128],
-	"honeydew": [240, 255, 240],
-	"hotpink": [255, 105, 180],
-	"indianred": [205, 92, 92],
-	"indigo": [75, 0, 130],
-	"ivory": [255, 255, 240],
-	"khaki": [240, 230, 140],
-	"lavender": [230, 230, 250],
-	"lavenderblush": [255, 240, 245],
-	"lawngreen": [124, 252, 0],
-	"lemonchiffon": [255, 250, 205],
-	"lightblue": [173, 216, 230],
-	"lightcoral": [240, 128, 128],
-	"lightcyan": [224, 255, 255],
-	"lightgoldenrodyellow": [250, 250, 210],
-	"lightgray": [211, 211, 211],
-	"lightgreen": [144, 238, 144],
-	"lightgrey": [211, 211, 211],
-	"lightpink": [255, 182, 193],
-	"lightsalmon": [255, 160, 122],
-	"lightseagreen": [32, 178, 170],
-	"lightskyblue": [135, 206, 250],
-	"lightslategray": [119, 136, 153],
-	"lightslategrey": [119, 136, 153],
-	"lightsteelblue": [176, 196, 222],
-	"lightyellow": [255, 255, 224],
-	"lime": [0, 255, 0],
-	"limegreen": [50, 205, 50],
-	"linen": [250, 240, 230],
-	"magenta": [255, 0, 255],
-	"maroon": [128, 0, 0],
-	"mediumaquamarine": [102, 205, 170],
-	"mediumblue": [0, 0, 205],
-	"mediumorchid": [186, 85, 211],
-	"mediumpurple": [147, 112, 219],
-	"mediumseagreen": [60, 179, 113],
-	"mediumslateblue": [123, 104, 238],
-	"mediumspringgreen": [0, 250, 154],
-	"mediumturquoise": [72, 209, 204],
-	"mediumvioletred": [199, 21, 133],
-	"midnightblue": [25, 25, 112],
-	"mintcream": [245, 255, 250],
-	"mistyrose": [255, 228, 225],
-	"moccasin": [255, 228, 181],
-	"navajowhite": [255, 222, 173],
-	"navy": [0, 0, 128],
-	"oldlace": [253, 245, 230],
-	"olive": [128, 128, 0],
-	"olivedrab": [107, 142, 35],
-	"orange": [255, 165, 0],
-	"orangered": [255, 69, 0],
-	"orchid": [218, 112, 214],
-	"palegoldenrod": [238, 232, 170],
-	"palegreen": [152, 251, 152],
-	"paleturquoise": [175, 238, 238],
-	"palevioletred": [219, 112, 147],
-	"papayawhip": [255, 239, 213],
-	"peachpuff": [255, 218, 185],
-	"peru": [205, 133, 63],
-	"pink": [255, 192, 203],
-	"plum": [221, 160, 221],
-	"powderblue": [176, 224, 230],
-	"purple": [128, 0, 128],
-	"rebeccapurple": [102, 51, 153],
-	"red": [255, 0, 0],
-	"rosybrown": [188, 143, 143],
-	"royalblue": [65, 105, 225],
-	"saddlebrown": [139, 69, 19],
-	"salmon": [250, 128, 114],
-	"sandybrown": [244, 164, 96],
-	"seagreen": [46, 139, 87],
-	"seashell": [255, 245, 238],
-	"sienna": [160, 82, 45],
-	"silver": [192, 192, 192],
-	"skyblue": [135, 206, 235],
-	"slateblue": [106, 90, 205],
-	"slategray": [112, 128, 144],
-	"slategrey": [112, 128, 144],
-	"snow": [255, 250, 250],
-	"springgreen": [0, 255, 127],
-	"steelblue": [70, 130, 180],
-	"tan": [210, 180, 140],
-	"teal": [0, 128, 128],
-	"thistle": [216, 191, 216],
-	"tomato": [255, 99, 71],
-	"turquoise": [64, 224, 208],
-	"violet": [238, 130, 238],
-	"wheat": [245, 222, 179],
-	"white": [255, 255, 255],
-	"whitesmoke": [245, 245, 245],
-	"yellow": [255, 255, 0],
-	"yellowgreen": [154, 205, 50]
-};
+            case 7:
+              _context.next = 9;
+              return client.startOAuthFlow(mkServerFlowCallback(serverOptions));
 
+            case 9:
+              resolve(client);
+              log('debug', "Saving credentials to ".concat(savedCredentialsFilename));
+              writeJSON(createClientFS, savedCredentialsFilename, {
+                oauthOptions: client.stackClient.oauthOptions,
+                token: client.stackClient.token
+              });
 
-/***/ }),
-/* 824 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+            case 12:
+            case "end":
+              return _context.stop();
+          }
+        }
+      }, _callee);
+    }));
 
-var conversions = __webpack_require__(822);
+    return function (_x, _x2) {
+      return _ref.apply(this, arguments);
+    };
+  }());
+};
 
-/*
-	this function routes a model to all other models.
+exports.createClientInteractive = createClientInteractive;
 
-	all functions that are routed have a property `.conversion` attached
-	to the returned synthetic function. This property is an array
-	of strings, each with the steps in between the 'from' and 'to'
-	color models (inclusive).
+var main = /*#__PURE__*/function () {
+  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
+    var client;
+    return _regenerator.default.wrap(function _callee2$(_context2) {
+      while (1) {
+        switch (_context2.prev = _context2.next) {
+          case 0:
+            _context2.next = 2;
+            return createClientInteractive({
+              scope: ['io.cozy.files'],
+              uri: 'http://cozy.tools:8080',
+              oauth: {
+                softwareID: 'io.cozy.client.cli'
+              }
+            });
 
-	conversions that are not possible simply are not included.
-*/
+          case 2:
+            client = _context2.sent;
+            console.log(client.toJSON());
 
-function buildGraph() {
-	var graph = {};
-	// https://jsperf.com/object-keys-vs-for-in-with-closure/3
-	var models = Object.keys(conversions);
+          case 4:
+          case "end":
+            return _context2.stop();
+        }
+      }
+    }, _callee2);
+  }));
 
-	for (var len = models.length, i = 0; i < len; i++) {
-		graph[models[i]] = {
-			// http://jsperf.com/1-vs-infinity
-			// micro-opt, but this is simple.
-			distance: -1,
-			parent: null
-		};
-	}
+  return function main() {
+    return _ref2.apply(this, arguments);
+  };
+}();
 
-	return graph;
+if (__webpack_require__.c[__webpack_require__.s] === module) {
+  main().catch(function (e) {
+    console.error(e);
+    process.exit(1);
+  });
 }
 
-// https://en.wikipedia.org/wiki/Breadth-first_search
-function deriveBFS(fromModel) {
-	var graph = buildGraph();
-	var queue = [fromModel]; // unshift -> queue -> pop
-
-	graph[fromModel].distance = 0;
+/***/ }),
+/* 821 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-	while (queue.length) {
-		var current = queue.pop();
-		var adjacents = Object.keys(conversions[current]);
+"use strict";
 
-		for (var len = adjacents.length, i = 0; i < len; i++) {
-			var adjacent = adjacents[i];
-			var node = graph[adjacent];
+const {promisify} = __webpack_require__(64);
+const path = __webpack_require__(142);
+const childProcess = __webpack_require__(822);
+const fs = __webpack_require__(149);
+const isWsl = __webpack_require__(823);
+const isDocker = __webpack_require__(824);
 
-			if (node.distance === -1) {
-				node.distance = graph[current].distance + 1;
-				node.parent = current;
-				queue.unshift(adjacent);
-			}
-		}
-	}
+const pAccess = promisify(fs.access);
+const pReadFile = promisify(fs.readFile);
 
-	return graph;
-}
+// Path to included `xdg-open`.
+const localXdgOpenPath = path.join(__dirname, 'xdg-open');
 
-function link(from, to) {
-	return function (args) {
-		return to(from(args));
-	};
-}
+/**
+Get the mount point for fixed drives in WSL.
 
-function wrapConversion(toModel, graph) {
-	var path = [graph[toModel].parent, toModel];
-	var fn = conversions[graph[toModel].parent][toModel];
+@inner
+@returns {string} The mount point.
+*/
+const getWslDrivesMountPoint = (() => {
+	// Default value for "root" param
+	// according to https://docs.microsoft.com/en-us/windows/wsl/wsl-config
+	const defaultMountPoint = '/mnt/';
 
-	var cur = graph[toModel].parent;
-	while (graph[cur].parent) {
-		path.unshift(graph[cur].parent);
-		fn = link(conversions[graph[cur].parent][cur], fn);
-		cur = graph[cur].parent;
-	}
+	let mountPoint;
 
-	fn.conversion = path;
-	return fn;
-}
+	return async function () {
+		if (mountPoint) {
+			// Return memoized mount point value
+			return mountPoint;
+		}
 
-module.exports = function (fromModel) {
-	var graph = deriveBFS(fromModel);
-	var conversion = {};
+		const configFilePath = '/etc/wsl.conf';
 
-	var models = Object.keys(graph);
-	for (var len = models.length, i = 0; i < len; i++) {
-		var toModel = models[i];
-		var node = graph[toModel];
+		let isConfigFileExists = false;
+		try {
+			await pAccess(configFilePath, fs.constants.F_OK);
+			isConfigFileExists = true;
+		} catch (_) {}
 
-		if (node.parent === null) {
-			// no possible conversion, or this node is the source model.
-			continue;
+		if (!isConfigFileExists) {
+			return defaultMountPoint;
 		}
 
-		conversion[toModel] = wrapConversion(toModel, graph);
-	}
+		const configContent = await pReadFile(configFilePath, {encoding: 'utf8'});
+		const configMountPoint = /root\s*=\s*(.*)/g.exec(configContent);
 
-	return conversion;
-};
+		if (!configMountPoint) {
+			return defaultMountPoint;
+		}
 
+		mountPoint = configMountPoint[1].trim();
+		mountPoint = mountPoint.endsWith('/') ? mountPoint : mountPoint + '/';
 
+		return mountPoint;
+	};
+})();
 
-/***/ }),
-/* 825 */
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
+module.exports = async (target, options) => {
+	if (typeof target !== 'string') {
+		throw new TypeError('Expected a `target`');
+	}
 
-"use strict";
+	options = {
+		wait: false,
+		background: false,
+		allowNonzeroExitCode: false,
+		...options
+	};
 
-const os = __webpack_require__(252);
-const hasFlag = __webpack_require__(826);
+	let command;
+	let {app} = options;
+	let appArguments = [];
+	const cliArguments = [];
+	const childProcessOptions = {};
 
-const env = process.env;
+	if (Array.isArray(app)) {
+		appArguments = app.slice(1);
+		app = app[0];
+	}
 
-let forceColor;
-if (hasFlag('no-color') ||
-	hasFlag('no-colors') ||
-	hasFlag('color=false')) {
-	forceColor = false;
-} else if (hasFlag('color') ||
-	hasFlag('colors') ||
-	hasFlag('color=true') ||
-	hasFlag('color=always')) {
-	forceColor = true;
-}
-if ('FORCE_COLOR' in env) {
-	forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
-}
+	if (process.platform === 'darwin') {
+		command = 'open';
 
-function translateLevel(level) {
-	if (level === 0) {
-		return false;
-	}
+		if (options.wait) {
+			cliArguments.push('--wait-apps');
+		}
 
-	return {
-		level,
-		hasBasic: true,
-		has256: level >= 2,
-		has16m: level >= 3
-	};
-}
+		if (options.background) {
+			cliArguments.push('--background');
+		}
 
-function supportsColor(stream) {
-	if (forceColor === false) {
-		return 0;
-	}
+		if (app) {
+			cliArguments.push('-a', app);
+		}
+	} else if (process.platform === 'win32' || (isWsl && !isDocker())) {
+		const mountPoint = await getWslDrivesMountPoint();
 
-	if (hasFlag('color=16m') ||
-		hasFlag('color=full') ||
-		hasFlag('color=truecolor')) {
-		return 3;
-	}
+		command = isWsl ?
+			`${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` :
+			`${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
 
-	if (hasFlag('color=256')) {
-		return 2;
-	}
+		cliArguments.push(
+			'-NoProfile',
+			'-NonInteractive',
+			'–ExecutionPolicy',
+			'Bypass',
+			'-EncodedCommand'
+		);
 
-	if (stream && !stream.isTTY && forceColor !== true) {
-		return 0;
-	}
+		if (!isWsl) {
+			childProcessOptions.windowsVerbatimArguments = true;
+		}
 
-	const min = forceColor ? 1 : 0;
+		const encodedArguments = ['Start'];
 
-	if (process.platform === 'win32') {
-		// Node.js 7.5.0 is the first version of Node.js to include a patch to
-		// libuv that enables 256 color output on Windows. Anything earlier and it
-		// won't work. However, here we target Node.js 8 at minimum as it is an LTS
-		// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
-		// release that supports 256 colors. Windows 10 build 14931 is the first release
-		// that supports 16m/TrueColor.
-		const osRelease = os.release().split('.');
-		if (
-			Number(process.versions.node.split('.')[0]) >= 8 &&
-			Number(osRelease[0]) >= 10 &&
-			Number(osRelease[2]) >= 10586
-		) {
-			return Number(osRelease[2]) >= 14931 ? 3 : 2;
+		if (options.wait) {
+			encodedArguments.push('-Wait');
 		}
 
-		return 1;
-	}
+		if (app) {
+			// Double quote with double quotes to ensure the inner quotes are passed through.
+			// Inner quotes are delimited for PowerShell interpretation with backticks.
+			encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList');
+			appArguments.unshift(target);
+		} else {
+			encodedArguments.push(`"${target}"`);
+		}
 
-	if ('CI' in env) {
-		if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
-			return 1;
+		if (appArguments.length > 0) {
+			appArguments = appArguments.map(arg => `"\`"${arg}\`""`);
+			encodedArguments.push(appArguments.join(','));
 		}
 
-		return min;
-	}
+		// Using Base64-encoded command, accepted by PowerShell, to allow special characters.
+		target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
+	} else {
+		if (app) {
+			command = app;
+		} else {
+			// When bundled by Webpack, there's no actual package file path and no local `xdg-open`.
+			const isBundled =  false || __dirname === '/';
 
-	if ('TEAMCITY_VERSION' in env) {
-		return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
-	}
+			// Check if local `xdg-open` exists and is executable.
+			let exeLocalXdgOpen = false;
+			try {
+				await pAccess(localXdgOpenPath, fs.constants.X_OK);
+				exeLocalXdgOpen = true;
+			} catch (_) {}
 
-	if (env.COLORTERM === 'truecolor') {
-		return 3;
-	}
+			const useSystemXdgOpen = process.versions.electron ||
+				process.platform === 'android' || isBundled || !exeLocalXdgOpen;
+			command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
+		}
 
-	if ('TERM_PROGRAM' in env) {
-		const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
+		if (appArguments.length > 0) {
+			cliArguments.push(...appArguments);
+		}
 
-		switch (env.TERM_PROGRAM) {
-			case 'iTerm.app':
-				return version >= 3 ? 3 : 2;
-			case 'Apple_Terminal':
-				return 2;
-			// No default
+		if (!options.wait) {
+			// `xdg-open` will block the process unless stdio is ignored
+			// and it's detached from the parent even if it's unref'd.
+			childProcessOptions.stdio = 'ignore';
+			childProcessOptions.detached = true;
 		}
 	}
 
-	if (/-256(color)?$/i.test(env.TERM)) {
-		return 2;
-	}
+	cliArguments.push(target);
 
-	if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
-		return 1;
+	if (process.platform === 'darwin' && appArguments.length > 0) {
+		cliArguments.push('--args', ...appArguments);
 	}
 
-	if ('COLORTERM' in env) {
-		return 1;
-	}
+	const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
 
-	if (env.TERM === 'dumb') {
-		return min;
-	}
+	if (options.wait) {
+		return new Promise((resolve, reject) => {
+			subprocess.once('error', reject);
 
-	return min;
-}
+			subprocess.once('close', exitCode => {
+				if (options.allowNonzeroExitCode && exitCode > 0) {
+					reject(new Error(`Exited with code ${exitCode}`));
+					return;
+				}
 
-function getSupportLevel(stream) {
-	const level = supportsColor(stream);
-	return translateLevel(level);
-}
+				resolve(subprocess);
+			});
+		});
+	}
 
-module.exports = {
-	supportsColor: getSupportLevel,
-	stdout: getSupportLevel(process.stdout),
-	stderr: getSupportLevel(process.stderr)
+	subprocess.unref();
+
+	return subprocess;
 };
 
 
 /***/ }),
-/* 826 */
+/* 822 */
 /***/ ((module) => {
 
 "use strict";
-
-module.exports = (flag, argv) => {
-	argv = argv || process.argv;
-	const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
-	const pos = argv.indexOf(prefix + flag);
-	const terminatorPos = argv.indexOf('--');
-	return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
-};
-
+module.exports = require("child_process");
 
 /***/ }),
-/* 827 */
-/***/ ((module) => {
+/* 823 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
-const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
-const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
-const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
-const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
-
-const ESCAPES = new Map([
-	['n', '\n'],
-	['r', '\r'],
-	['t', '\t'],
-	['b', '\b'],
-	['f', '\f'],
-	['v', '\v'],
-	['0', '\0'],
-	['\\', '\\'],
-	['e', '\u001B'],
-	['a', '\u0007']
-]);
+const os = __webpack_require__(253);
+const fs = __webpack_require__(149);
+const isDocker = __webpack_require__(824);
 
-function unescape(c) {
-	if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
-		return String.fromCharCode(parseInt(c.slice(1), 16));
+const isWsl = () => {
+	if (process.platform !== 'linux') {
+		return false;
 	}
 
-	return ESCAPES.get(c) || c;
-}
+	if (os.release().toLowerCase().includes('microsoft')) {
+		if (isDocker()) {
+			return false;
+		}
 
-function parseArguments(name, args) {
-	const results = [];
-	const chunks = args.trim().split(/\s*,\s*/g);
-	let matches;
+		return true;
+	}
 
-	for (const chunk of chunks) {
-		if (!isNaN(chunk)) {
-			results.push(Number(chunk));
-		} else if ((matches = chunk.match(STRING_REGEX))) {
-			results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
-		} else {
-			throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
-		}
+	try {
+		return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ?
+			!isDocker() : false;
+	} catch (_) {
+		return false;
 	}
+};
 
-	return results;
+if (process.env.__IS_WSL_TEST__) {
+	module.exports = isWsl;
+} else {
+	module.exports = isWsl();
 }
 
-function parseStyle(style) {
-	STYLE_REGEX.lastIndex = 0;
-
-	const results = [];
-	let matches;
 
-	while ((matches = STYLE_REGEX.exec(style)) !== null) {
-		const name = matches[1];
+/***/ }),
+/* 824 */
+/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-		if (matches[2]) {
-			const args = parseArguments(name, matches[2]);
-			results.push([name].concat(args));
-		} else {
-			results.push([name]);
-		}
-	}
+"use strict";
 
-	return results;
-}
+const fs = __webpack_require__(149);
 
-function buildStyle(chalk, styles) {
-	const enabled = {};
+let isDocker;
 
-	for (const layer of styles) {
-		for (const style of layer.styles) {
-			enabled[style[0]] = layer.inverse ? null : style.slice(1);
-		}
+function hasDockerEnv() {
+	try {
+		fs.statSync('/.dockerenv');
+		return true;
+	} catch (_) {
+		return false;
 	}
+}
 
-	let current = chalk;
-	for (const styleName of Object.keys(enabled)) {
-		if (Array.isArray(enabled[styleName])) {
-			if (!(styleName in current)) {
-				throw new Error(`Unknown Chalk style: ${styleName}`);
-			}
+function hasDockerCGroup() {
+	try {
+		return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
+	} catch (_) {
+		return false;
+	}
+}
 
-			if (enabled[styleName].length > 0) {
-				current = current[styleName].apply(current, enabled[styleName]);
-			} else {
-				current = current[styleName];
-			}
-		}
+module.exports = () => {
+	if (isDocker === undefined) {
+		isDocker = hasDockerEnv() || hasDockerCGroup();
 	}
 
-	return current;
-}
+	return isDocker;
+};
 
-module.exports = (chalk, tmp) => {
-	const styles = [];
-	const chunks = [];
-	let chunk = [];
 
-	// eslint-disable-next-line max-params
-	tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
-		if (escapeChar) {
-			chunk.push(unescape(escapeChar));
-		} else if (style) {
-			const str = chunk.join('');
-			chunk = [];
-			chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
-			styles.push({inverse, styles: parseStyle(style)});
-		} else if (close) {
-			if (styles.length === 0) {
-				throw new Error('Found extraneous } in Chalk template literal');
-			}
+/***/ }),
+/* 825 */
+/***/ ((module) => {
 
-			chunks.push(buildStyle(chalk, styles)(chunk.join('')));
-			chunk = [];
-			styles.pop();
-		} else {
-			chunk.push(chr);
-		}
-	});
+module.exports = enableDestroy;
 
-	chunks.push(chunk.join(''));
+function enableDestroy(server) {
+  var connections = {}
 
-	if (styles.length > 0) {
-		const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
-		throw new Error(errMsg);
-	}
+  server.on('connection', function(conn) {
+    var key = conn.remoteAddress + ':' + conn.remotePort;
+    connections[key] = conn;
+    conn.on('close', function() {
+      delete connections[key];
+    });
+  });
 
-	return chunks.join('');
-};
+  server.destroy = function(cb) {
+    server.close(cb);
+    for (var key in connections)
+      connections[key].destroy();
+  };
+}
 
 
 /***/ }),
-/* 828 */
+/* 826 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireWildcard = __webpack_require__(510);
+var _interopRequireWildcard = __webpack_require__(522);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.timeseries = exports.document = exports.contact = exports.utils = exports.permission = exports.note = exports.account = exports.folder = exports.file = exports.applications = exports.instance = exports.trigger = exports.accounts = exports.triggers = void 0;
+exports.dacc = exports.sharing = exports.timeseries = exports.document = exports.contact = exports.utils = exports.permission = exports.note = exports.account = exports.folder = exports.file = exports.applications = exports.instance = exports.trigger = exports.accounts = exports.triggers = void 0;
 
-var trigger = _interopRequireWildcard(__webpack_require__(829));
+var trigger = _interopRequireWildcard(__webpack_require__(827));
 
 exports.trigger = trigger;
 
-var instance = _interopRequireWildcard(__webpack_require__(831));
+var instance = _interopRequireWildcard(__webpack_require__(829));
 
 exports.instance = instance;
 
-var applications = _interopRequireWildcard(__webpack_require__(832));
+var applications = _interopRequireWildcard(__webpack_require__(830));
 
 exports.applications = applications;
 
-var file = _interopRequireWildcard(__webpack_require__(833));
+var file = _interopRequireWildcard(__webpack_require__(831));
 
 exports.file = file;
 
-var folder = _interopRequireWildcard(__webpack_require__(839));
+var folder = _interopRequireWildcard(__webpack_require__(837));
 
 exports.folder = folder;
 
-var account = _interopRequireWildcard(__webpack_require__(830));
+var account = _interopRequireWildcard(__webpack_require__(828));
 
 exports.account = account;
 
-var note = _interopRequireWildcard(__webpack_require__(841));
+var note = _interopRequireWildcard(__webpack_require__(839));
 
 exports.note = note;
 
-var permission = _interopRequireWildcard(__webpack_require__(842));
+var permission = _interopRequireWildcard(__webpack_require__(840));
 
 exports.permission = permission;
 
-var utils = _interopRequireWildcard(__webpack_require__(843));
+var utils = _interopRequireWildcard(__webpack_require__(841));
 
 exports.utils = utils;
 
-var contact = _interopRequireWildcard(__webpack_require__(844));
+var contact = _interopRequireWildcard(__webpack_require__(842));
 
 exports.contact = contact;
 
-var document = _interopRequireWildcard(__webpack_require__(846));
+var document = _interopRequireWildcard(__webpack_require__(844));
 
 exports.document = document;
 
-var timeseries = _interopRequireWildcard(__webpack_require__(908));
+var timeseries = _interopRequireWildcard(__webpack_require__(906));
 
 exports.timeseries = timeseries;
+
+var sharing = _interopRequireWildcard(__webpack_require__(907));
+
+exports.sharing = sharing;
+
+var dacc = _interopRequireWildcard(__webpack_require__(908));
+
+exports.dacc = dacc;
 // For backward compatibility before 9.0.0
 var triggers = trigger;
 exports.triggers = triggers;
@@ -125133,22 +125164,22 @@ var accounts = account;
 exports.accounts = accounts;
 
 /***/ }),
-/* 829 */
+/* 827 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.triggers = exports.triggerStates = void 0;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-var _account = __webpack_require__(830);
+var _account = __webpack_require__(828);
 
 var actionableErrors = ['CHALLENGE_ASKED', 'DISK_QUOTA_EXCEEDED', 'TERMS_VERSION_MISMATCH', 'USER_ACTION_NEEDED', 'USER_ACTION_NEEDED.CHANGE_PASSWORD', 'USER_ACTION_NEEDED.ACCOUNT_REMOVED', 'USER_ACTION_NEEDED.WEBAUTH_REQUIRED', 'USER_ACTION_NEEDED.SCA_REQUIRED', 'LOGIN_FAILED'];
 /** Trigger states come from /jobs/triggers */
@@ -125256,26 +125287,26 @@ var triggers = {
 exports.triggers = triggers;
 
 /***/ }),
-/* 830 */
+/* 828 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.setContractSyncStatusInAccount = exports.getContractSyncStatusFromAccount = exports.muteError = exports.getMutedErrors = void 0;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-var _merge = _interopRequireDefault(__webpack_require__(742));
+var _merge = _interopRequireDefault(__webpack_require__(754));
 
-var _HasMany = __webpack_require__(741);
+var _HasMany = __webpack_require__(753);
 
 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; }
 
@@ -125361,20 +125392,20 @@ var setContractSyncStatusInAccount = function setContractSyncStatusInAccount(acc
 exports.setContractSyncStatusInAccount = setContractSyncStatusInAccount;
 
 /***/ }),
-/* 831 */
+/* 829 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.buildPremiumLink = exports.hasAnOffer = exports.shouldDisplayOffers = exports.getUuid = exports.isFreemiumUser = exports.arePremiumLinksEnabled = exports.isSelfHosted = void 0;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
 var GB = 1000 * 1000 * 1000;
 var PREMIUM_QUOTA = 50 * GB;
@@ -125463,20 +125494,20 @@ var buildPremiumLink = function buildPremiumLink(instanceInfo) {
 exports.buildPremiumLink = buildPremiumLink;
 
 /***/ }),
-/* 832 */
+/* 830 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.getAppDisplayName = exports.getUrl = exports.isInstalled = exports.getStoreInstallationURL = exports.getStoreURL = void 0;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
 var STORE_SLUG = 'store';
 /**
@@ -125578,13 +125609,13 @@ var getAppDisplayName = function getAppDisplayName(app, lang) {
 exports.getAppDisplayName = getAppDisplayName;
 
 /***/ }),
-/* 833 */
+/* 831 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
@@ -125592,31 +125623,31 @@ Object.defineProperty(exports, "__esModule", ({
 exports.normalize = normalize;
 exports.ensureFilePath = ensureFilePath;
 exports.getParentFolderId = getParentFolderId;
-exports.fetchBlobFileById = exports.isFromKonnector = exports.hasCertifications = exports.hasQualifications = exports.isPlainText = exports.doMobileUpload = exports.readMobileFile = exports.uploadFileWithConflictStrategy = exports.generateFileNameForRevision = exports.generateNewFileNameOnConflict = exports.overrideFileForPath = exports.move = exports.getFullpath = exports.hasMetadataAttribute = exports.isReferencedByAlbum = exports.fetchFilesByQualificationRules = exports.saveFileQualification = exports.isSharingShorcutNew = exports.isSharingShortcutNew = exports.isSharingShorcut = exports.isSharingShortcut = exports.getSharingShortcutTargetDoctype = exports.getSharingShortcutTargetMime = exports.getSharingShortcutStatus = exports.isShortcut = exports.shouldBeOpenedByOnlyOffice = exports.isOnlyOfficeFile = exports.isNote = exports.isDirectory = exports.isFile = exports.splitFilename = exports.ALBUMS_DOCTYPE = void 0;
+exports.fetchBlobFileById = exports.isFromKonnector = exports.hasCertifications = exports.hasQualifications = exports.isPlainText = exports.doMobileUpload = exports.readMobileFile = exports.uploadFileWithConflictStrategy = exports.generateFileNameForRevision = exports.generateNewFileNameOnConflict = exports.overrideFileForPath = exports.move = exports.getFullpath = exports.hasMetadataAttribute = exports.isReferencedByAlbum = exports.fetchFilesByQualificationRules = exports.saveFileQualification = exports.isSharingShorcutNew = exports.isSharingShortcutNew = exports.isSharingShorcut = exports.isSharingShortcut = exports.getSharingShortcutTargetDoctype = exports.getSharingShortcutTargetMime = exports.getSharingShortcutStatus = exports.isShortcut = exports.shouldBeOpenedByOnlyOffice = exports.isOnlyOfficeFile = exports.isEncrypted = exports.isNote = exports.isDirectory = exports.isFile = exports.splitFilename = exports.ALBUMS_DOCTYPE = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
 var _isString = _interopRequireDefault(__webpack_require__(54));
 
-var _has = _interopRequireDefault(__webpack_require__(662));
+var _has = _interopRequireDefault(__webpack_require__(674));
 
-var _trimEnd = _interopRequireDefault(__webpack_require__(834));
+var _trimEnd = _interopRequireDefault(__webpack_require__(832));
 
-var _qualification = __webpack_require__(836);
+var _qualification = __webpack_require__(834);
 
-var _dsl = __webpack_require__(607);
+var _dsl = __webpack_require__(619);
 
-var _types = __webpack_require__(610);
+var _types = __webpack_require__(622);
 
-var _const = __webpack_require__(685);
+var _const = __webpack_require__(697);
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
 function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_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 s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
 
@@ -125693,6 +125724,19 @@ var isNote = function isNote(file) {
   if (file && file.name && file.name.endsWith('.cozy-note') && file.type === FILE_TYPE && file.metadata && file.metadata.content !== undefined && file.metadata.schema !== undefined && file.metadata.title !== undefined && file.metadata.version !== undefined) return true;
   return false;
 };
+/**
+ * Whether the file is client-side encrypted
+ *
+ * @param {IOCozyFile} file - io.cozy.files document
+ * @returns {boolean}
+ */
+
+
+exports.isNote = isNote;
+
+var isEncrypted = function isEncrypted(file) {
+  return !!file.encrypted;
+};
 /**
  * Whether the file is supported by Only Office
  *
@@ -125701,7 +125745,7 @@ var isNote = function isNote(file) {
  */
 
 
-exports.isNote = isNote;
+exports.isEncrypted = isEncrypted;
 
 var isOnlyOfficeFile = function isOnlyOfficeFile(file) {
   return isFile(file) && !isNote(file) && (file.class === 'text' || file.class === 'spreadsheet' || file.class === 'slide');
@@ -126652,15 +126696,15 @@ var fetchBlobFileById = /*#__PURE__*/function () {
 exports.fetchBlobFileById = fetchBlobFileById;
 
 /***/ }),
-/* 834 */
+/* 832 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseToString = __webpack_require__(397),
-    castSlice = __webpack_require__(765),
-    charsEndIndex = __webpack_require__(835),
-    stringToArray = __webpack_require__(767),
-    toString = __webpack_require__(396),
-    trimmedEndIndex = __webpack_require__(628);
+var baseToString = __webpack_require__(409),
+    castSlice = __webpack_require__(777),
+    charsEndIndex = __webpack_require__(833),
+    stringToArray = __webpack_require__(779),
+    toString = __webpack_require__(408),
+    trimmedEndIndex = __webpack_require__(640);
 
 /**
  * Removes trailing whitespace or specified characters from `string`.
@@ -126699,10 +126743,10 @@ module.exports = trimEnd;
 
 
 /***/ }),
-/* 835 */
+/* 833 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIndexOf = __webpack_require__(465);
+var baseIndexOf = __webpack_require__(477);
 
 /**
  * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
@@ -126724,30 +126768,30 @@ module.exports = charsEndIndex;
 
 
 /***/ }),
-/* 836 */
+/* 834 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireWildcard = __webpack_require__(510);
+var _interopRequireWildcard = __webpack_require__(522);
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.getQualification = exports.setQualification = exports.Qualification = void 0;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530));
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542));
 
-var _createClass2 = _interopRequireDefault(__webpack_require__(531));
+var _createClass2 = _interopRequireDefault(__webpack_require__(543));
 
-var _lodash = __webpack_require__(837);
+var _lodash = __webpack_require__(835);
 
-var qualificationModel = _interopRequireWildcard(__webpack_require__(838));
+var qualificationModel = _interopRequireWildcard(__webpack_require__(836));
 
 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; }
 
@@ -126994,7 +127038,7 @@ var getQualification = function getQualification(document) {
 exports.getQualification = getQualification;
 
 /***/ }),
-/* 837 */
+/* 835 */
 /***/ (function(module, exports, __webpack_require__) {
 
 /* module decorator */ module = __webpack_require__.nmd(module);
@@ -144202,37 +144246,37 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/**
 
 
 /***/ }),
-/* 838 */
+/* 836 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"qualifications":[{"label":"identity_photo","purpose":"attestation","subjects":["identity"]},{"label":"national_id_card","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["identity"]},{"label":"passport","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["identity"]},{"label":"residence_permit","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"immigration","subjects":["permit","identity"]},{"label":"family_record_book","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"birth_certificate","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["identity","family"]},{"label":"driver_license","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"transport","subjects":["permit","driving"]},{"label":"other_identity_document","purpose":"attestation","subjects":["identity"]},{"label":"wedding","purpose":"contract","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"pacs","purpose":"contract","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"divorce","purpose":"contract","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"large_family_card","purpose":"attestation","sourceCategory":"transport","subjects":["right"]},{"label":"caf","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"family","subjects":["right"]},{"label":"other_family_document","subjects":["family"]},{"label":"diploma","purpose":"attestation","sourceCategory":"education","subjects":["achievement"]},{"label":"work_contract","purpose":"contract","sourceCategory":"employer","subjects":["work","employment"]},{"label":"pay_sheet","purpose":"attestation","sourceCategory":"employer","subjects":["work","revenues"]},{"label":"unemployment_benefit","purpose":"attestation","sourceCategory":"gov","subjects":["revenues"]},{"label":"pension","purpose":"attestation","sourceCategory":"gov","subjects":["revenues"]},{"label":"other_revenue","purpose":"attestation","subjects":["revenues"]},{"label":"gradebook","purpose":"report","sourceCategory":"education","subjects":["history"]},{"label":"student_card","purpose":"attestation","sourceCategory":"education","subjects":["identity","right","employment","education"]},{"label":"resume","purpose":"description","subjects":["employment"]},{"label":"motivation_letter","purpose":"description","subjects":["employment"]},{"label":"other_work_document","purpose":"employment"},{"label":"health_book","purpose":"attestation","sourceCategory":"health","subjects":["capacity","vaccine"]},{"label":"health_certificate","purpose":"attestation","sourceCategory":"health","subjects":["capacity","vaccine"]},{"label":"pregnancy_medical_certificate","purpose":"attestation","sourceCategory":"health","subjects":["pregnancy"]},{"label":"work_disability_recognition","purpose":"attestation","sourceCategory":"health","subjects":["right"]},{"label":"national_health_insurance_card","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"health","subjects":["insurance"]},{"label":"national_health_insurance_right_certificate","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"health","subjects":["right","insurance"]},{"label":"health_insurance_card","purpose":"attestation","sourceCategory":"insurance","sourceSubCategory":"health","subjects":["insurance"]},{"label":"prescription","purpose":"attestation","sourceCategory":"health","subjects":["right","medecine"]},{"label":"health_invoice","purpose":"invoice","sourceCategory":"health"},{"label":"other_health_document","subjects":["health"]},{"label":"vehicle_registration","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"transport","subjects":["vehicule","identity","right"]},{"label":"car_insurance","purpose":"attestation","sourceCategory":"insurance","sourceSubCategory":"transport","subjects":["insurance","car"]},{"label":"mechanic_invoice","purpose":"invoice","sourceCategory":"transport"},{"label":"transport_invoice","purpose":"invoice","sourceCategory":"transport"},{"label":"other_transport_document","sourceCategory":"transport"},{"label":"house_sale_agreeement","purpose":"contract","sourceCategory":"real_estate","subjects":["house"]},{"label":"building_permit","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"real_estate","subjects":["permit","house"]},{"label":"technical_diagnostic_record","purpose":"report","sourceCategory":"real_estate","subjects":["compliance","house"]},{"label":"lease","purpose":"contract","sourceCategory":"real_estate","subjects":["house"]},{"label":"rent_receipt","purpose":"invoice","sourceCategory":"real_estate","subjects":["house"]},{"label":"house_insurance","purpose":"contract","sourceCategory":"insurance","sourceSubCategory":"real_estate","subjects":["insurance","house"]},{"label":"work_quote","purpose":"description","sourceCategory":"building","subjects":["building","house"]},{"label":"work_invoice","purpose":"invoice","sourceCategory":"building","subjects":["building","house"]},{"label":"other_house_document","subjects":["house"]},{"label":"phone_invoice","purpose":"invoice","sourceCategory":"telecom","sourceSubCategory":"mobile"},{"label":"isp_invoice","purpose":"invoice","sourceCategory":"telecom","sourceSubCategory":"internet","subjects":["subscription"]},{"label":"telecom_invoice","purpose":"invoice","sourceCategory":"telecom"},{"label":"energy_invoice","purpose":"invoice","sourceCategory":"energy"},{"label":"water_invoice","purpose":"invoice","sourceCategory":"water"},{"label":"appliance_invoice","purpose":"invoice","sourceCategory":"retail"},{"label":"web_service_invoice","purpose":"invoice","sourceCategory":"web"},{"label":"restaurant_invoice","purpose":"invoice","sourceCategory":"alimentation"},{"label":"grocery_invoice","purpose":"invoice","sourceCategory":"shopping"},{"label":"other_invoice","purpose":"invoice"},{"label":"tax_return","purpose":"report","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["tax"]},{"label":"tax_notice","purpose":"invoice","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["tax"]},{"label":"tax_timetable","purpose":"report","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["tax"]},{"label":"other_tax_document","subjects":["tax"]},{"label":"bank_details","purpose":"attestation","sourceCategory":"bank","subjects":["bank_account"]},{"label":"bank_statement","purpose":"report","sourceCategory":"bank","subjects":["history"]},{"label":"loan_agreement","purpose":"contract","sourceCategory":"bank"},{"label":"other_bank_document","sourceCategory":"bank"},{"label":"receipt","purpose":"report"},{"label":"payment_proof_family_allowance","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["subvention"]},{"label":"school_attendance_certificate","purpose":"attestation","sourceCategory":"education","subjects":["identity","right","education"]},{"label":"unfit_for_habitation_declaration","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"real_estate","subjects":["compliance"]},{"label":"accommodation_proof","purpose":"attestation","sourceCategory":"individual","subjects":["address"]},{"label":"citizen_registration_certificate","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["achievement","education"]},{"label":"personal_sporting_licence","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"sport","subjects":["permit","invoice"]},{"label":"other_activity_document","sourceSubCategory":"sport","subjects":["permit","invoice"]}],"purposeKnownValues":["attestation","contract","invoice","report","description","evaluation","employment"],"sourceCategoryKnownValues":["bank","insurance","retail","telecom","energy","water","health","gov","association","education","employer","transport","goods","alimentation","building","real_estate","web","individual","shopping"],"sourceSubCategoryKnownValues":["civil_registration","immigration","transport","family","tax","health","real_estate","mobile","internet","citizen","sport"],"subjectsKnownValues":["identity","permit","family","address","driving","right","subvention","achievement","degree","work","employment","revenues","history","insurance","medical_act","vehicule","car","moto","truck","boat","subscription","buy/sale","house","compliance","building","food","real_estate","tax","address","education","statement","course","internet","phone","vaccine","capacity","health","drugs","child","pregnancy","bank_account"]}');
 
 /***/ }),
-/* 839 */
+/* 837 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.getReferencedFolder = exports.createFolderWithReference = exports.ensureMagicFolder = exports.MAGIC_FOLDERS = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _sortBy = _interopRequireDefault(__webpack_require__(840));
+var _sortBy = _interopRequireDefault(__webpack_require__(838));
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
-var _types = __webpack_require__(610);
+var _types = __webpack_require__(622);
 
-var _const = __webpack_require__(685);
+var _const = __webpack_require__(697);
 
 var APP_DOCTYPE = 'io.cozy.apps';
 var administrative = 'administrative';
@@ -144420,13 +144464,13 @@ var getReferencedFolder = /*#__PURE__*/function () {
 exports.getReferencedFolder = getReferencedFolder;
 
 /***/ }),
-/* 840 */
+/* 838 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseFlatten = __webpack_require__(541),
-    baseOrderBy = __webpack_require__(732),
-    baseRest = __webpack_require__(544),
-    isIterateeCall = __webpack_require__(749);
+var baseFlatten = __webpack_require__(553),
+    baseOrderBy = __webpack_require__(744),
+    baseRest = __webpack_require__(556),
+    isIterateeCall = __webpack_require__(761);
 
 /**
  * Creates an array of elements, sorted in ascending order by the results of
@@ -144474,24 +144518,24 @@ module.exports = sortBy;
 
 
 /***/ }),
-/* 841 */
+/* 839 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.fetchURL = exports.generateUrlForNote = exports.generatePrivateUrl = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _helpers = __webpack_require__(756);
+var _helpers = __webpack_require__(768);
 
 /**
  *
@@ -144592,13 +144636,13 @@ var fetchURL = /*#__PURE__*/function () {
 exports.fetchURL = fetchURL;
 
 /***/ }),
-/* 842 */
+/* 840 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
@@ -144609,25 +144653,25 @@ exports.isForType = isForType;
 exports.isDocumentReadOnly = isDocumentReadOnly;
 exports.isShortcutCreatedOnTheRecipientCozy = void 0;
 
-var _defineProperty2 = _interopRequireDefault(__webpack_require__(532));
+var _defineProperty2 = _interopRequireDefault(__webpack_require__(544));
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522));
+var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534));
 
-var _intersection = _interopRequireDefault(__webpack_require__(727));
+var _intersection = _interopRequireDefault(__webpack_require__(739));
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-var _CozyClient = _interopRequireDefault(__webpack_require__(513));
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
 
-var _dsl = __webpack_require__(607);
+var _dsl = __webpack_require__(619);
 
-var _file = __webpack_require__(833);
+var _file = __webpack_require__(831);
 
-var _const = __webpack_require__(685);
+var _const = __webpack_require__(697);
 
 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; }
 
@@ -145024,20 +145068,20 @@ var isShortcutCreatedOnTheRecipientCozy = function isShortcutCreatedOnTheRecipie
 exports.isShortcutCreatedOnTheRecipientCozy = isShortcutCreatedOnTheRecipientCozy;
 
 /***/ }),
-/* 843 */
+/* 841 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.getCreatedByApp = exports.hasBeenUpdatedByApp = void 0;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
 var hasBeenUpdatedByApp = function hasBeenUpdatedByApp(doc, appSlug) {
   var updatedByApps = (0, _get.default)(doc, 'cozyMetadata.updatedByApps');
@@ -145055,22 +145099,22 @@ var getCreatedByApp = function getCreatedByApp(doc) {
 exports.getCreatedByApp = getCreatedByApp;
 
 /***/ }),
-/* 844 */
+/* 842 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.getIndexByFamilyNameGivenNameEmailCozyUrl = exports.getDefaultSortIndexValue = exports.makeDefaultSortIndexValue = exports.getDisplayName = exports.makeDisplayName = exports.getFullname = exports.makeFullname = exports.getPrimaryAddress = exports.getPrimaryPhone = exports.getPrimaryCozyDomain = exports.getPrimaryCozy = exports.getPrimaryEmail = exports.getInitials = exports.getPrimaryOrFirst = void 0;
 
-var _get = _interopRequireDefault(__webpack_require__(358));
+var _get = _interopRequireDefault(__webpack_require__(370));
 
-var _isEmpty = _interopRequireDefault(__webpack_require__(845));
+var _isEmpty = _interopRequireDefault(__webpack_require__(843));
 
 var getPrimaryOrFirst = function getPrimaryOrFirst(property) {
   return function (obj) {
@@ -145321,17 +145365,17 @@ var getIndexByFamilyNameGivenNameEmailCozyUrl = function getIndexByFamilyNameGiv
 exports.getIndexByFamilyNameGivenNameEmailCozyUrl = getIndexByFamilyNameGivenNameEmailCozyUrl;
 
 /***/ }),
-/* 845 */
+/* 843 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseKeys = __webpack_require__(442),
-    getTag = __webpack_require__(447),
-    isArguments = __webpack_require__(432),
+var baseKeys = __webpack_require__(454),
+    getTag = __webpack_require__(459),
+    isArguments = __webpack_require__(444),
     isArray = __webpack_require__(55),
-    isArrayLike = __webpack_require__(446),
-    isBuffer = __webpack_require__(434),
-    isPrototype = __webpack_require__(443),
-    isTypedArray = __webpack_require__(437);
+    isArrayLike = __webpack_require__(458),
+    isBuffer = __webpack_require__(446),
+    isPrototype = __webpack_require__(455),
+    isTypedArray = __webpack_require__(449);
 
 /** `Object#toString` result references. */
 var mapTag = '[object Map]',
@@ -145404,13 +145448,13 @@ module.exports = isEmpty;
 
 
 /***/ }),
-/* 846 */
+/* 844 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireWildcard = __webpack_require__(510);
+var _interopRequireWildcard = __webpack_require__(522);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
@@ -145435,35 +145479,35 @@ Object.defineProperty(exports, "getQualification", ({
 }));
 exports.helpers = exports.themes = exports.locales = void 0;
 
-var _qualification = __webpack_require__(836);
+var _qualification = __webpack_require__(834);
 
-var locales = _interopRequireWildcard(__webpack_require__(847));
+var locales = _interopRequireWildcard(__webpack_require__(845));
 
 exports.locales = locales;
 
-var themes = _interopRequireWildcard(__webpack_require__(906));
+var themes = _interopRequireWildcard(__webpack_require__(904));
 
 exports.themes = themes;
 
-var helpers = _interopRequireWildcard(__webpack_require__(907));
+var helpers = _interopRequireWildcard(__webpack_require__(905));
 
 exports.helpers = helpers;
 
 /***/ }),
-/* 847 */
+/* 845 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.getBoundT = void 0;
 
-var _nodePolyglot = _interopRequireDefault(__webpack_require__(848));
+var _nodePolyglot = _interopRequireDefault(__webpack_require__(846));
 
 var polyglots = {};
 var langs = ['fr', 'en'];
@@ -145473,7 +145517,7 @@ for (var _i = 0, _langs = langs; _i < _langs.length; _i++) {
   var locales = {};
 
   try {
-    locales = __webpack_require__(903)("./".concat(lang, ".json"));
+    locales = __webpack_require__(901)("./".concat(lang, ".json"));
   } catch (e) {// eslint-disable-line no-empty-block
   }
 
@@ -145496,7 +145540,7 @@ var getBoundT = function getBoundT(lang) {
 exports.getBoundT = getBoundT;
 
 /***/ }),
-/* 848 */
+/* 846 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -145519,11 +145563,11 @@ exports.getBoundT = getBoundT;
 
 
 
-var forEach = __webpack_require__(849);
-var entries = __webpack_require__(894);
-var warning = __webpack_require__(898);
-var has = __webpack_require__(637);
-var trim = __webpack_require__(899);
+var forEach = __webpack_require__(847);
+var entries = __webpack_require__(892);
+var warning = __webpack_require__(896);
+var has = __webpack_require__(649);
+var trim = __webpack_require__(897);
 
 var warn = function warn(message) {
   warning(false, message);
@@ -145932,21 +145976,21 @@ module.exports = Polyglot;
 
 
 /***/ }),
-/* 849 */
+/* 847 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var define = __webpack_require__(850);
-var callBind = __webpack_require__(639);
-var callBound = __webpack_require__(638);
-var RequireObjectCoercible = __webpack_require__(854);
+var define = __webpack_require__(848);
+var callBind = __webpack_require__(651);
+var callBound = __webpack_require__(650);
+var RequireObjectCoercible = __webpack_require__(852);
 
-var implementation = __webpack_require__(856);
-var getPolyfill = __webpack_require__(891);
+var implementation = __webpack_require__(854);
+var getPolyfill = __webpack_require__(889);
 var polyfill = getPolyfill();
-var shim = __webpack_require__(893);
+var shim = __webpack_require__(891);
 
 var $slice = callBound('Array.prototype.slice');
 
@@ -145967,13 +146011,13 @@ module.exports = boundCoercible;
 
 
 /***/ }),
-/* 850 */
+/* 848 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var keys = __webpack_require__(851);
+var keys = __webpack_require__(849);
 var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';
 
 var toStr = Object.prototype.toString;
@@ -146032,17 +146076,17 @@ module.exports = defineProperties;
 
 
 /***/ }),
-/* 851 */
+/* 849 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
 var slice = Array.prototype.slice;
-var isArgs = __webpack_require__(852);
+var isArgs = __webpack_require__(850);
 
 var origKeys = Object.keys;
-var keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(853);
+var keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(851);
 
 var originalKeys = Object.keys;
 
@@ -146071,7 +146115,7 @@ module.exports = keysShim;
 
 
 /***/ }),
-/* 852 */
+/* 850 */
 /***/ ((module) => {
 
 "use strict";
@@ -146095,7 +146139,7 @@ module.exports = function isArguments(value) {
 
 
 /***/ }),
-/* 853 */
+/* 851 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -146106,7 +146150,7 @@ if (!Object.keys) {
 	// modified from https://github.com/es-shims/es5-shim
 	var has = Object.prototype.hasOwnProperty;
 	var toStr = Object.prototype.toString;
-	var isArgs = __webpack_require__(852); // eslint-disable-line global-require
+	var isArgs = __webpack_require__(850); // eslint-disable-line global-require
 	var isEnumerable = Object.prototype.propertyIsEnumerable;
 	var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
 	var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
@@ -146224,23 +146268,23 @@ module.exports = keysShim;
 
 
 /***/ }),
-/* 854 */
+/* 852 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-module.exports = __webpack_require__(855);
+module.exports = __webpack_require__(853);
 
 
 /***/ }),
-/* 855 */
+/* 853 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $TypeError = GetIntrinsic('%TypeError%');
 
@@ -146255,25 +146299,25 @@ module.exports = function CheckObjectCoercible(value, optMessage) {
 
 
 /***/ }),
-/* 856 */
+/* 854 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
-var callBound = __webpack_require__(638);
+var GetIntrinsic = __webpack_require__(644);
+var callBound = __webpack_require__(650);
 var $TypeError = GetIntrinsic('%TypeError%');
 
-var Call = __webpack_require__(857);
-var Get = __webpack_require__(859);
-var HasProperty = __webpack_require__(863);
-var IsCallable = __webpack_require__(864);
-var LengthOfArrayLike = __webpack_require__(866);
-var ToObject = __webpack_require__(888);
-var ToString = __webpack_require__(889);
+var Call = __webpack_require__(855);
+var Get = __webpack_require__(857);
+var HasProperty = __webpack_require__(861);
+var IsCallable = __webpack_require__(862);
+var LengthOfArrayLike = __webpack_require__(864);
+var ToObject = __webpack_require__(886);
+var ToString = __webpack_require__(887);
 
-var isString = __webpack_require__(890);
+var isString = __webpack_require__(888);
 
 var $split = callBound('String.prototype.split');
 
@@ -146312,18 +146356,18 @@ module.exports = function forEach(callbackfn) {
 
 
 /***/ }),
-/* 857 */
+/* 855 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
-var callBound = __webpack_require__(638);
+var GetIntrinsic = __webpack_require__(644);
+var callBound = __webpack_require__(650);
 
 var $TypeError = GetIntrinsic('%TypeError%');
 
-var IsArray = __webpack_require__(858);
+var IsArray = __webpack_require__(856);
 
 var $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%');
 
@@ -146339,18 +146383,18 @@ module.exports = function Call(F, V) {
 
 
 /***/ }),
-/* 858 */
+/* 856 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $Array = GetIntrinsic('%Array%');
 
 // eslint-disable-next-line global-require
-var toStr = !$Array.isArray && __webpack_require__(638)('Object.prototype.toString');
+var toStr = !$Array.isArray && __webpack_require__(650)('Object.prototype.toString');
 
 // https://ecma-international.org/ecma-262/6.0/#sec-isarray
 
@@ -146360,20 +146404,20 @@ module.exports = $Array.isArray || function IsArray(argument) {
 
 
 /***/ }),
-/* 859 */
+/* 857 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $TypeError = GetIntrinsic('%TypeError%');
 
-var inspect = __webpack_require__(640);
+var inspect = __webpack_require__(652);
 
-var IsPropertyKey = __webpack_require__(860);
-var Type = __webpack_require__(861);
+var IsPropertyKey = __webpack_require__(858);
+var Type = __webpack_require__(859);
 
 /**
  * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p
@@ -146397,7 +146441,7 @@ module.exports = function Get(O, P) {
 
 
 /***/ }),
-/* 860 */
+/* 858 */
 /***/ ((module) => {
 
 "use strict";
@@ -146411,13 +146455,13 @@ module.exports = function IsPropertyKey(argument) {
 
 
 /***/ }),
-/* 861 */
+/* 859 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var ES5Type = __webpack_require__(862);
+var ES5Type = __webpack_require__(860);
 
 // https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values
 
@@ -146433,7 +146477,7 @@ module.exports = function Type(x) {
 
 
 /***/ }),
-/* 862 */
+/* 860 */
 /***/ ((module) => {
 
 "use strict";
@@ -146464,18 +146508,18 @@ module.exports = function Type(x) {
 
 
 /***/ }),
-/* 863 */
+/* 861 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $TypeError = GetIntrinsic('%TypeError%');
 
-var IsPropertyKey = __webpack_require__(860);
-var Type = __webpack_require__(861);
+var IsPropertyKey = __webpack_require__(858);
+var Type = __webpack_require__(859);
 
 // https://ecma-international.org/ecma-262/6.0/#sec-hasproperty
 
@@ -146491,7 +146535,7 @@ module.exports = function HasProperty(O, P) {
 
 
 /***/ }),
-/* 864 */
+/* 862 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -146499,11 +146543,11 @@ module.exports = function HasProperty(O, P) {
 
 // http://262.ecma-international.org/5.1/#sec-9.11
 
-module.exports = __webpack_require__(865);
+module.exports = __webpack_require__(863);
 
 
 /***/ }),
-/* 865 */
+/* 863 */
 /***/ ((module) => {
 
 "use strict";
@@ -146584,19 +146628,19 @@ module.exports = reflectApply
 
 
 /***/ }),
-/* 866 */
+/* 864 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $TypeError = GetIntrinsic('%TypeError%');
 
-var Get = __webpack_require__(859);
-var ToLength = __webpack_require__(867);
-var Type = __webpack_require__(861);
+var Get = __webpack_require__(857);
+var ToLength = __webpack_require__(865);
+var Type = __webpack_require__(859);
 
 // https://262.ecma-international.org/11.0/#sec-lengthofarraylike
 
@@ -146611,15 +146655,15 @@ module.exports = function LengthOfArrayLike(obj) {
 
 
 /***/ }),
-/* 867 */
+/* 865 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var MAX_SAFE_INTEGER = __webpack_require__(868);
+var MAX_SAFE_INTEGER = __webpack_require__(866);
 
-var ToIntegerOrInfinity = __webpack_require__(869);
+var ToIntegerOrInfinity = __webpack_require__(867);
 
 module.exports = function ToLength(argument) {
 	var len = ToIntegerOrInfinity(argument);
@@ -146630,13 +146674,13 @@ module.exports = function ToLength(argument) {
 
 
 /***/ }),
-/* 868 */
+/* 866 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $Math = GetIntrinsic('%Math%');
 var $Number = GetIntrinsic('%Number%');
@@ -146645,15 +146689,15 @@ module.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;
 
 
 /***/ }),
-/* 869 */
+/* 867 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var ES5ToInteger = __webpack_require__(870);
+var ES5ToInteger = __webpack_require__(868);
 
-var ToNumber = __webpack_require__(880);
+var ToNumber = __webpack_require__(878);
 
 // https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger
 
@@ -146667,19 +146711,19 @@ module.exports = function ToInteger(value) {
 
 
 /***/ }),
-/* 870 */
+/* 868 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var abs = __webpack_require__(871);
-var floor = __webpack_require__(872);
-var ToNumber = __webpack_require__(873);
+var abs = __webpack_require__(869);
+var floor = __webpack_require__(870);
+var ToNumber = __webpack_require__(871);
 
-var $isNaN = __webpack_require__(877);
-var $isFinite = __webpack_require__(878);
-var $sign = __webpack_require__(879);
+var $isNaN = __webpack_require__(875);
+var $isFinite = __webpack_require__(876);
+var $sign = __webpack_require__(877);
 
 // http://262.ecma-international.org/5.1/#sec-9.4
 
@@ -146692,13 +146736,13 @@ module.exports = function ToInteger(value) {
 
 
 /***/ }),
-/* 871 */
+/* 869 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $abs = GetIntrinsic('%Math.abs%');
 
@@ -146710,7 +146754,7 @@ module.exports = function abs(x) {
 
 
 /***/ }),
-/* 872 */
+/* 870 */
 /***/ ((module) => {
 
 "use strict";
@@ -146728,13 +146772,13 @@ module.exports = function floor(x) {
 
 
 /***/ }),
-/* 873 */
+/* 871 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var ToPrimitive = __webpack_require__(874);
+var ToPrimitive = __webpack_require__(872);
 
 // http://262.ecma-international.org/5.1/#sec-9.3
 
@@ -146755,7 +146799,7 @@ module.exports = function ToNumber(value) {
 
 
 /***/ }),
-/* 874 */
+/* 872 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -146763,11 +146807,11 @@ module.exports = function ToNumber(value) {
 
 // http://262.ecma-international.org/5.1/#sec-9.1
 
-module.exports = __webpack_require__(875);
+module.exports = __webpack_require__(873);
 
 
 /***/ }),
-/* 875 */
+/* 873 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -146775,9 +146819,9 @@ module.exports = __webpack_require__(875);
 
 var toStr = Object.prototype.toString;
 
-var isPrimitive = __webpack_require__(876);
+var isPrimitive = __webpack_require__(874);
 
-var isCallable = __webpack_require__(865);
+var isCallable = __webpack_require__(863);
 
 // http://ecma-international.org/ecma-262/5.1/#sec-8.12.8
 var ES5internalSlots = {
@@ -146819,7 +146863,7 @@ module.exports = function ToPrimitive(input) {
 
 
 /***/ }),
-/* 876 */
+/* 874 */
 /***/ ((module) => {
 
 "use strict";
@@ -146831,7 +146875,7 @@ module.exports = function isPrimitive(value) {
 
 
 /***/ }),
-/* 877 */
+/* 875 */
 /***/ ((module) => {
 
 "use strict";
@@ -146843,7 +146887,7 @@ module.exports = Number.isNaN || function isNaN(a) {
 
 
 /***/ }),
-/* 878 */
+/* 876 */
 /***/ ((module) => {
 
 "use strict";
@@ -146855,7 +146899,7 @@ module.exports = Number.isFinite || function (x) { return typeof x === 'number'
 
 
 /***/ }),
-/* 879 */
+/* 877 */
 /***/ ((module) => {
 
 "use strict";
@@ -146867,22 +146911,22 @@ module.exports = function sign(number) {
 
 
 /***/ }),
-/* 880 */
+/* 878 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $TypeError = GetIntrinsic('%TypeError%');
 var $Number = GetIntrinsic('%Number%');
 var $RegExp = GetIntrinsic('%RegExp%');
 var $parseInteger = GetIntrinsic('%parseInt%');
 
-var callBound = __webpack_require__(638);
-var regexTester = __webpack_require__(881);
-var isPrimitive = __webpack_require__(882);
+var callBound = __webpack_require__(650);
+var regexTester = __webpack_require__(879);
+var isPrimitive = __webpack_require__(880);
 
 var $strSlice = callBound('String.prototype.slice');
 var isBinary = regexTester(/^0b[01]+$/i);
@@ -146905,7 +146949,7 @@ var $trim = function (value) {
 	return $replace(value, trimRegex, '');
 };
 
-var ToPrimitive = __webpack_require__(883);
+var ToPrimitive = __webpack_require__(881);
 
 // https://ecma-international.org/ecma-262/6.0/#sec-tonumber
 
@@ -146936,17 +146980,17 @@ module.exports = function ToNumber(argument) {
 
 
 /***/ }),
-/* 881 */
+/* 879 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $test = GetIntrinsic('RegExp.prototype.test');
 
-var callBind = __webpack_require__(639);
+var callBind = __webpack_require__(651);
 
 module.exports = function regexTester(regex) {
 	return callBind($test, regex);
@@ -146954,7 +146998,7 @@ module.exports = function regexTester(regex) {
 
 
 /***/ }),
-/* 882 */
+/* 880 */
 /***/ ((module) => {
 
 "use strict";
@@ -146966,13 +147010,13 @@ module.exports = function isPrimitive(value) {
 
 
 /***/ }),
-/* 883 */
+/* 881 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var toPrimitive = __webpack_require__(884);
+var toPrimitive = __webpack_require__(882);
 
 // https://ecma-international.org/ecma-262/6.0/#sec-toprimitive
 
@@ -146985,7 +147029,7 @@ module.exports = function ToPrimitive(input) {
 
 
 /***/ }),
-/* 884 */
+/* 882 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -146993,10 +147037,10 @@ module.exports = function ToPrimitive(input) {
 
 var hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';
 
-var isPrimitive = __webpack_require__(876);
-var isCallable = __webpack_require__(865);
-var isDate = __webpack_require__(885);
-var isSymbol = __webpack_require__(887);
+var isPrimitive = __webpack_require__(874);
+var isCallable = __webpack_require__(863);
+var isDate = __webpack_require__(883);
+var isSymbol = __webpack_require__(885);
 
 var ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {
 	if (typeof O === 'undefined' || O === null) {
@@ -147067,7 +147111,7 @@ module.exports = function ToPrimitive(input) {
 
 
 /***/ }),
-/* 885 */
+/* 883 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -147085,7 +147129,7 @@ var tryDateObject = function tryDateGetDayCall(value) {
 
 var toStr = Object.prototype.toString;
 var dateClass = '[object Date]';
-var hasToStringTag = __webpack_require__(886)();
+var hasToStringTag = __webpack_require__(884)();
 
 module.exports = function isDateObject(value) {
 	if (typeof value !== 'object' || value === null) {
@@ -147096,13 +147140,13 @@ module.exports = function isDateObject(value) {
 
 
 /***/ }),
-/* 886 */
+/* 884 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var hasSymbols = __webpack_require__(634);
+var hasSymbols = __webpack_require__(646);
 
 module.exports = function hasToStringTagShams() {
 	return hasSymbols() && !!Symbol.toStringTag;
@@ -147110,14 +147154,14 @@ module.exports = function hasToStringTagShams() {
 
 
 /***/ }),
-/* 887 */
+/* 885 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
 var toStr = Object.prototype.toString;
-var hasSymbols = __webpack_require__(633)();
+var hasSymbols = __webpack_require__(645)();
 
 if (hasSymbols) {
 	var symToStr = Symbol.prototype.toString;
@@ -147152,17 +147196,17 @@ if (hasSymbols) {
 
 
 /***/ }),
-/* 888 */
+/* 886 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $Object = GetIntrinsic('%Object%');
 
-var RequireObjectCoercible = __webpack_require__(854);
+var RequireObjectCoercible = __webpack_require__(852);
 
 // https://ecma-international.org/ecma-262/6.0/#sec-toobject
 
@@ -147173,13 +147217,13 @@ module.exports = function ToObject(value) {
 
 
 /***/ }),
-/* 889 */
+/* 887 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var GetIntrinsic = __webpack_require__(632);
+var GetIntrinsic = __webpack_require__(644);
 
 var $String = GetIntrinsic('%String%');
 var $TypeError = GetIntrinsic('%TypeError%');
@@ -147195,7 +147239,7 @@ module.exports = function ToString(argument) {
 
 
 /***/ }),
-/* 890 */
+/* 888 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
@@ -147212,7 +147256,7 @@ var tryStringObject = function tryStringObject(value) {
 };
 var toStr = Object.prototype.toString;
 var strClass = '[object String]';
-var hasToStringTag = __webpack_require__(886)();
+var hasToStringTag = __webpack_require__(884)();
 
 module.exports = function isString(value) {
 	if (typeof value === 'string') {
@@ -147226,15 +147270,15 @@ module.exports = function isString(value) {
 
 
 /***/ }),
-/* 891 */
+/* 889 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var arrayMethodBoxesProperly = __webpack_require__(892);
+var arrayMethodBoxesProperly = __webpack_require__(890);
 
-var implementation = __webpack_require__(856);
+var implementation = __webpack_require__(854);
 
 module.exports = function getPolyfill() {
 	var method = Array.prototype.forEach;
@@ -147243,7 +147287,7 @@ module.exports = function getPolyfill() {
 
 
 /***/ }),
-/* 892 */
+/* 890 */
 /***/ ((module) => {
 
 module.exports = function properlyBoxed(method) {
@@ -147279,14 +147323,14 @@ module.exports = function properlyBoxed(method) {
 
 
 /***/ }),
-/* 893 */
+/* 891 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var define = __webpack_require__(850);
-var getPolyfill = __webpack_require__(891);
+var define = __webpack_require__(848);
+var getPolyfill = __webpack_require__(889);
 
 module.exports = function shimForEach() {
 	var polyfill = getPolyfill();
@@ -147300,18 +147344,18 @@ module.exports = function shimForEach() {
 
 
 /***/ }),
-/* 894 */
+/* 892 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var define = __webpack_require__(850);
-var callBind = __webpack_require__(639);
+var define = __webpack_require__(848);
+var callBind = __webpack_require__(651);
 
-var implementation = __webpack_require__(895);
-var getPolyfill = __webpack_require__(896);
-var shim = __webpack_require__(897);
+var implementation = __webpack_require__(893);
+var getPolyfill = __webpack_require__(894);
+var shim = __webpack_require__(895);
 
 var polyfill = callBind(getPolyfill(), Object);
 
@@ -147325,14 +147369,14 @@ module.exports = polyfill;
 
 
 /***/ }),
-/* 895 */
+/* 893 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var RequireObjectCoercible = __webpack_require__(854);
-var callBound = __webpack_require__(638);
+var RequireObjectCoercible = __webpack_require__(852);
+var callBound = __webpack_require__(650);
 var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
 var $push = callBound('Array.prototype.push');
 
@@ -147349,13 +147393,13 @@ module.exports = function entries(O) {
 
 
 /***/ }),
-/* 896 */
+/* 894 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var implementation = __webpack_require__(895);
+var implementation = __webpack_require__(893);
 
 module.exports = function getPolyfill() {
 	return typeof Object.entries === 'function' ? Object.entries : implementation;
@@ -147363,14 +147407,14 @@ module.exports = function getPolyfill() {
 
 
 /***/ }),
-/* 897 */
+/* 895 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var getPolyfill = __webpack_require__(896);
-var define = __webpack_require__(850);
+var getPolyfill = __webpack_require__(894);
+var define = __webpack_require__(848);
 
 module.exports = function shimEntries() {
 	var polyfill = getPolyfill();
@@ -147384,7 +147428,7 @@ module.exports = function shimEntries() {
 
 
 /***/ }),
-/* 898 */
+/* 896 */
 /***/ ((module) => {
 
 "use strict";
@@ -147453,18 +147497,18 @@ module.exports = warning;
 
 
 /***/ }),
-/* 899 */
+/* 897 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var callBind = __webpack_require__(639);
-var define = __webpack_require__(850);
+var callBind = __webpack_require__(651);
+var define = __webpack_require__(848);
 
-var implementation = __webpack_require__(900);
-var getPolyfill = __webpack_require__(901);
-var shim = __webpack_require__(902);
+var implementation = __webpack_require__(898);
+var getPolyfill = __webpack_require__(899);
+var shim = __webpack_require__(900);
 
 var boundTrim = callBind(getPolyfill());
 
@@ -147478,15 +147522,15 @@ module.exports = boundTrim;
 
 
 /***/ }),
-/* 900 */
+/* 898 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var RequireObjectCoercible = __webpack_require__(854);
-var ToString = __webpack_require__(889);
-var callBound = __webpack_require__(638);
+var RequireObjectCoercible = __webpack_require__(852);
+var ToString = __webpack_require__(887);
+var callBound = __webpack_require__(650);
 var $replace = callBound('String.prototype.replace');
 
 /* eslint-disable no-control-regex */
@@ -147501,13 +147545,13 @@ module.exports = function trim() {
 
 
 /***/ }),
-/* 901 */
+/* 899 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var implementation = __webpack_require__(900);
+var implementation = __webpack_require__(898);
 
 var zeroWidthSpace = '\u200b';
 
@@ -147520,14 +147564,14 @@ module.exports = function getPolyfill() {
 
 
 /***/ }),
-/* 902 */
+/* 900 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 "use strict";
 
 
-var define = __webpack_require__(850);
-var getPolyfill = __webpack_require__(901);
+var define = __webpack_require__(848);
+var getPolyfill = __webpack_require__(899);
 
 module.exports = function shimStringTrim() {
 	var polyfill = getPolyfill();
@@ -147541,12 +147585,12 @@ module.exports = function shimStringTrim() {
 
 
 /***/ }),
-/* 903 */
+/* 901 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 var map = {
-	"./en.json": 904,
-	"./fr.json": 905
+	"./en.json": 902,
+	"./fr.json": 903
 };
 
 
@@ -147567,24 +147611,24 @@ webpackContext.keys = function webpackContextKeys() {
 };
 webpackContext.resolve = webpackContextResolve;
 module.exports = webpackContext;
-webpackContext.id = 903;
+webpackContext.id = 901;
 
 /***/ }),
-/* 904 */
+/* 902 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"Scan":{"scan_a_doc":"Scan a doc","save_doc":"Save the doc","filename":"Filename","save":"Save","cancel":"Cancel","qualify":"Describe","apply":"Apply","error":{"offline":"You are currently offline and you can\'t use this functionality. Please, try again later.","uploading":"You are already uploading a file. Please wait until the end of this upload and try again.","generic":"Something went wrong. Please try again."},"successful":{"qualified_ok":"You just have successfully described your file! "},"items":{"identity":"Identity","family":"Family","work_study":"Work & Study","health":"Health","home":"Home","transport":"Transport","invoice":"Invoice","others":"Others","identity_photo":"Identity photo","national_id_card":"ID card","passport":"Passeport","residence_permit":"Residence permit","family_record_book":"Family record book","birth_certificate":"Birth certificate","citizen_registration_certificate":"Certificate of citizen registration","driver_license":"Driving license","other_identity_document":"Other document of identity","wedding":"Wedding contract","pacs":"Civil union","divorce":"Divorce","large_family_card":" Large Family Card","caf":"Social benefit rate","payment_proof_family_allowance":"family allowance payment proof","other_family_document":"Other family document","diploma":"Diploma","work_contract":"Work contract","pay_sheet":"Pay sheet","unemployment_benefit":"Unemployment benefit","pension":"Pension","other_revenue":"Other revenues","gradebook":"Gradebook","student_card":"Student card","school_attendance_certificate":"Certificate of school attendance","resume":"Resume","motivation_letter":"Motivation letter","other_work_document":"Other work document","health_book":"Health book","health_certificate":"Health/Vaccination certificate","disability_recognition":"Recognition of disability","pregnancy_medical_certificate":"Certificate of pregnancy","national_health_insurance_card":"National health insurance card","national_health_insurance_right_certificate":"National health insurance right certificate","health_insurance_card":"Insurance card","prescription":"Prescription","health_invoice":"Health invoice","other_health_document":"Other health document","vehicle_registration":"Vehicle registration","car_insurance":"Car insurance certificate","mechanic_invoice":"Repair bill","transport_invoice":"Transport invoice","other_transport_document":"Other transport document","phone_invoice":"Phone invoice","isp_invoice":"ISP invoice","telecom_invoice":"Telecom invoice","energy_invoice":"Energy invoice","water_invoice":"Water invoice","web_service_invoice":"Web service invoice","appliance_invoice":"Appliance invoice","restaurant_invoice":"Restaurant invoice","grocery_invoice":"Grocery invoice","house_sale_agreeement":"House sale agreement","building_permit":"Building permit","technical_diagnostic_record":"Technical diagnostic record","lease":"Lease","house_insurance":"Home insurance","unfit_for_habitation_declaration":"Declaration of unfit for habitation","rent_receipt":"Rent receipt","accommodation_proof":"Proof of accommodation","work_quote":"Work quote","work_invoice":"Work invoice","other_house_document":"Other house document","tax_return":"Tax return","tax_notice":"Tax notice","tax_timetable":"Payment Plans Installment Agreements","receipt":"Receipt","other_tax_document":"Other tax document","bank_details":"IBAN","bank_statement":"Bank statement","loan_agreement":"Loan agreement","other_bank_document":"Other banking document","invoices":"Invoices","personal_sporting_licence":"Sporting licence","other_invoice":"Other invoice","other_activity_document":"Other sports document"},"themes":{"identity":"Identity","family":"Family","work_study":"Work & Study","health":"Health","home":"Home","transport":"Transport","invoice":"Invoice","others":"Others","undefined":"Undefined","finance":"Finance","activity":"Activities"}}}');
 
 /***/ }),
-/* 905 */
+/* 903 */
 /***/ ((module) => {
 
 "use strict";
 module.exports = JSON.parse('{"Scan":{"scan_a_doc":"Numériser un doc","save_doc":"Enregistrer le document","filename":"Nom du fichier","save":"Sauvegarder","cancel":"Annuler","qualify":"Qualifier","apply":"Appliquer","error":{"offline":"Vous êtes actuellement déconnecté, vous ne pouvez donc pas utiliser cette fonctionnalité. Connectez-vous à internet et recommencez. ","uploading":"Vous avez déjà un fichier en cours de téléchargement. Attendez la fin et recommencez.","generic":"Un problème est survenu. Veuillez réessayer. "},"successful":{"qualified_ok":"Vous venez de qualifier votre fichier avec succès !"},"items":{"identity":"Identité","family":"Famille","work_study":"Travail & Études","health":"Santé","home":"Logement","transport":"Transport","invoice":"Factures","others":"Autres","identity_photo":"Photo d\'identité","national_id_card":"Carte d\'identité","passport":"Passeport","residence_permit":"Titre de séjour","family_record_book":"Livret de famille","birth_certificate":"Certificat de naissance","citizen_registration_certificate":"Attestation de recensement citoyen","driver_license":"Permis","other_identity_document":"Autre document d\'identité","wedding":"Contrat de mariage","pacs":"Attestation de PACS","divorce":"Attestation de divorce","large_family_card":"Carte famille nombreuse","caf":"Attestation de quotient familial (CAF)","payment_proof_family_allowance":"Attestation de paiement CAF","other_family_document":"Autre document de famille","diploma":"Diplôme","work_contract":"Contrat de travail","pay_sheet":"Fiche de paie","unemployment_benefit":"Allocations chômage","pension":"Retraite","other_revenue":"Autres revenus","gradebook":"Bulletin de notes","student_card":"Carte d\'étudiant","school_attendance_certificate":"Certificat de scolarité","resume":"CV","motivation_letter":"Lettre de motivation","other_work_document":"Autre document de travail","health_book":"Carnet de santé","health_certificate":"Certificat de santé/vaccination","work_disability_recognition":"Reconnaissance de handicap - RQTH","pregnancy_medical_certificate":"Certificat de grossesse","national_health_insurance_card":"Carte vitale","national_health_insurance_right_certificate":"Attestation de droits de l\'Assurance Maladie (vitale)","health_insurance_card":"Carte de mutuelle","prescription":"Ordonnance","health_invoice":"Facture médicale","other_health_document":"Autre document de santé","vehicle_registration":"Carte grise","car_insurance":"Attestation d\'assurance auto","mechanic_invoice":"Facture de réparation","transport_invoice":"Facture de transport","other_transport_document":"Autre document de transport","phone_invoice":"Facture de téléphone","isp_invoice":"Facture d\'internet","telecom_invoice":"Facture de télécom","energy_invoice":"Facture d\'énergie","water_invoice":"Facture d\'eau","web_service_invoice":"Facture de service web","appliance_invoice":"Facture d\'électroménager","restaurant_invoice":"Facture de restaurant","grocery_invoice":"Facture de courses","house_sale_agreeement":"Compromis de vente","building_permit":"Permis de construire","technical_diagnostic_record":"Dossier de diagnostic technique","lease":"Bail","unfit_for_habitation_declaration":"Arrêté d\'insalubrité","house_insurance":"Assurance logement","rent_receipt":"Quittance de loyer","accommodation_proof":"Attestation d\'hébergement","work_quote":"Devis de travaux","work_invoice":"Facture de travaux","other_house_document":"Autre document de logement","tax_return":"Impôts - Déclaration de revenus","tax_notice":"Impôts - Avis d\'imposition","tax_timetable":"Impôts - Echéancier","receipt":"Accusé de réception","other_tax_document":"Impôts - Autre document","bank_details":"IBAN","bank_statement":"Relevé de compte","loan_agreement":"Contrat de prêt","other_bank_document":"Autre document bancaire","invoices":"Factures","personal_sporting_licence":"Licences sportives","other_invoice":"Autre facture","other_activity_document":"Autre document sportif"},"themes":{"identity":"Identité","family":"Famille","work_study":"Travail & Études","health":"Santé","home":"Logement","transport":"Transport","invoice":"Factures","others":"Autres","undefined":"Indéfini","finance":"Finances","activity":"Activités & loisirs"}}}');
 
 /***/ }),
-/* 906 */
+/* 904 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
@@ -147595,9 +147639,9 @@ Object.defineProperty(exports, "__esModule", ({
 }));
 exports.themesList = void 0;
 
-var _qualification = __webpack_require__(836);
+var _qualification = __webpack_require__(834);
 
-var _types = __webpack_require__(610);
+var _types = __webpack_require__(622);
 
 /**
  *
@@ -147719,7 +147763,7 @@ var themesList = [{
 exports.themesList = themesList;
 
 /***/ }),
-/* 907 */
+/* 905 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
@@ -147730,9 +147774,9 @@ Object.defineProperty(exports, "__esModule", ({
 }));
 exports.getThemeByItem = void 0;
 
-var _types = __webpack_require__(610);
+var _types = __webpack_require__(622);
 
-var _documentTypeData = __webpack_require__(906);
+var _documentTypeData = __webpack_require__(904);
 
 /**
  * @param {QualificationAttributes} item - Qualification item
@@ -147766,26 +147810,26 @@ var getThemeByItem = function getThemeByItem(item) {
 exports.getThemeByItem = getThemeByItem;
 
 /***/ }),
-/* 908 */
+/* 906 */
 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__(512);
+var _interopRequireDefault = __webpack_require__(524);
 
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.fetchTimeSeriesByIntervalAndSource = exports.saveTimeSeries = void 0;
 
-var _regenerator = _interopRequireDefault(__webpack_require__(527));
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
 
-var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529));
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
 
-var _dsl = __webpack_require__(607);
+var _dsl = __webpack_require__(619);
 
-var _types = __webpack_require__(610);
+var _types = __webpack_require__(622);
 
 var validateTimeSeriesFormat = function validateTimeSeriesFormat(timeseries) {
   if (!timeseries.startDate || !timeseries.endDate) {
@@ -147927,6 +147971,203 @@ var fetchTimeSeriesByIntervalAndSource = /*#__PURE__*/function () {
 
 exports.fetchTimeSeriesByIntervalAndSource = fetchTimeSeriesByIntervalAndSource;
 
+/***/ }),
+/* 907 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.getSharingLink = void 0;
+
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
+
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
+
+var _const = __webpack_require__(697);
+
+var _CozyClient = _interopRequireDefault(__webpack_require__(525));
+
+var _helpers = __webpack_require__(768);
+
+/**
+ * Generate Sharing link for one or many files
+ *
+ * @param {CozyClient} client - Instance of CozyClient
+ * @param {string[]} filesIds - Array of io.cozy.files ids
+ * @param {boolean} [isFlatDomain] -
+ * @returns {Promise<string>} Shared link
+ */
+var getSharingLink = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, filesIds, isFlatDomain) {
+    var _sharedLink$attribute, _sharedLink$attribute2;
+
+    var PERMS, _yield$client$save, sharedLink, webLink;
+
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            PERMS = {
+              _type: _const.DOCTYPE_PERMISSIONS,
+              permissions: {
+                files: {
+                  type: _const.DOCTYPE_FILES,
+                  values: filesIds,
+                  verbs: ['GET']
+                }
+              }
+            };
+            _context.next = 3;
+            return client.save(PERMS);
+
+          case 3:
+            _yield$client$save = _context.sent;
+            sharedLink = _yield$client$save.data;
+            webLink = (0, _helpers.generateWebLink)({
+              cozyUrl: client.getStackClient().uri,
+              searchParams: [['sharecode', sharedLink === null || sharedLink === void 0 ? void 0 : (_sharedLink$attribute = sharedLink.attributes) === null || _sharedLink$attribute === void 0 ? void 0 : (_sharedLink$attribute2 = _sharedLink$attribute.shortcodes) === null || _sharedLink$attribute2 === void 0 ? void 0 : _sharedLink$attribute2.code]],
+              pathname: '/public',
+              slug: 'drive',
+              subDomainType: isFlatDomain ? 'flat' : 'nested'
+            });
+            return _context.abrupt("return", webLink);
+
+          case 7:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee);
+  }));
+
+  return function getSharingLink(_x, _x2, _x3) {
+    return _ref.apply(this, arguments);
+  };
+}();
+
+exports.getSharingLink = getSharingLink;
+
+/***/ }),
+/* 908 */
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(524);
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+exports.sendMeasureToDACC = exports.checkMeasureParams = void 0;
+
+var _regenerator = _interopRequireDefault(__webpack_require__(539));
+
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541));
+
+var _cozyLogger = _interopRequireDefault(__webpack_require__(354));
+
+var _types = __webpack_require__(622);
+
+/**
+ * Throw an errror if a DACC parameter is incorrect.
+ *
+ * @param { DACCMeasure} measure - The DACC measure
+ */
+var checkMeasureParams = function checkMeasureParams(measure) {
+  var createdBy = measure.createdBy,
+      measureName = measure.measureName,
+      startDate = measure.startDate,
+      value = measure.value,
+      group1 = measure.group1,
+      group2 = measure.group2,
+      group3 = measure.group3;
+
+  if (!createdBy || typeof createdBy !== 'string') {
+    throw new Error('Missing or wrong type parameter: createdBy');
+  }
+
+  if (!measureName || typeof measureName !== 'string') {
+    throw new Error('Missing or wrong type parameter: measureName');
+  }
+
+  if (!startDate) {
+    throw new Error('Missing parameter: startDate');
+  }
+
+  var parsedDate = new Date(Date.parse(startDate));
+
+  if (!parsedDate.toISOString().startsWith(startDate)) {
+    throw new Error('Date should be in YYYY-MM-DD format');
+  }
+
+  if (typeof value !== 'number') {
+    throw new Error('Missing or wrong type parameter: value');
+  }
+
+  if (group1 && (typeof group1 !== 'object' || Object.keys(group1).length === 0) || group2 && (typeof group2 !== 'object' || Object.keys(group2).length === 0) || group3 && (typeof group3 !== 'object' || Object.keys(group3).length === 0)) {
+    throw new Error('Groups should be key-value objects');
+  }
+
+  if (group3 && (!group2 || !group1) || group2 && !group1) {
+    throw new Error('Group order must be respected');
+  }
+};
+/**
+ * Send measures to a DACC through a remote doctype
+ *
+ * @param {object} client - The CozyClient instance
+ * @param {string} remoteDoctype - The remote doctype to use
+ * @param {DACCMeasure} measure - The DACC measure
+ */
+
+
+exports.checkMeasureParams = checkMeasureParams;
+
+var sendMeasureToDACC = /*#__PURE__*/function () {
+  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, remoteDoctype, measure) {
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            _context.prev = 0;
+            checkMeasureParams(measure);
+            _context.next = 4;
+            return client.getStackClient().fetchJSON('POST', "/remote/".concat(remoteDoctype), {
+              data: JSON.stringify(measure)
+            });
+
+          case 4:
+            _context.next = 10;
+            break;
+
+          case 6:
+            _context.prev = 6;
+            _context.t0 = _context["catch"](0);
+            (0, _cozyLogger.default)('error', "Error while sending measure to remote doctype: ".concat(_context.t0.message));
+            throw _context.t0;
+
+          case 10:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee, null, [[0, 6]]);
+  }));
+
+  return function sendMeasureToDACC(_x, _x2, _x3) {
+    return _ref.apply(this, arguments);
+  };
+}();
+
+exports.sendMeasureToDACC = sendMeasureToDACC;
+
 /***/ }),
 /* 909 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
@@ -148006,7 +148247,7 @@ const fs = __webpack_require__(149);
 
 const path = __webpack_require__(142);
 
-const log = (__webpack_require__(342).namespace)('cozy-client-js-stub');
+const log = (__webpack_require__(354).namespace)('cozy-client-js-stub');
 
 const mimetypes = __webpack_require__(139);
 
@@ -148014,7 +148255,7 @@ const low = __webpack_require__(911);
 
 const lodashId = __webpack_require__(913);
 
-const get = __webpack_require__(358);
+const get = __webpack_require__(370);
 
 const FileSync = __webpack_require__(914);
 
@@ -148028,7 +148269,7 @@ const sleep = (__webpack_require__(64).promisify)(global.setTimeout);
 
 const {
   models
-} = __webpack_require__(509);
+} = __webpack_require__(521);
 
 const newCozyClient = {
   models
@@ -148382,7 +148623,7 @@ async function waitForFileEnd(file, finalPath, writeStream) {
 "use strict";
 
 
-var lodash = __webpack_require__(837);
+var lodash = __webpack_require__(835);
 var isPromise = __webpack_require__(912);
 
 module.exports = function (adapter) {
@@ -154373,8 +154614,8 @@ module.exports = range;
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 var baseRange = __webpack_require__(961),
-    isIterateeCall = __webpack_require__(749),
-    toFinite = __webpack_require__(625);
+    isIterateeCall = __webpack_require__(761),
+    toFinite = __webpack_require__(637);
 
 /**
  * Creates a `_.range` or `_.rangeRight` function.
@@ -173308,7 +173549,7 @@ const {
   createModel: createLocalModel
 } = __webpack_require__(1237);
 
-const logger = __webpack_require__(342);
+const logger = __webpack_require__(354);
 
 const log = logger.namespace('categorization');
 /**
@@ -173348,7 +173589,7 @@ const log = logger.namespace('categorization');
  * }
  */
 
-async function createCategorizer(options) {
+async function createCategorizer(options = {}) {
   const {
     useGlobalModel = true,
     customTransactionFetcher,
@@ -173595,7 +173836,7 @@ const {
 
 const maxBy = __webpack_require__(1234);
 
-const logger = __webpack_require__(342);
+const logger = __webpack_require__(354);
 
 const log = logger.namespace('categorization/globalModel');
 
@@ -173638,7 +173879,7 @@ module.exports = {
 /* 1230 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const cozyClient = __webpack_require__(473);
+const cozyClient = __webpack_require__(485);
 
 async function fetchParameters() {
   const parameters = await cozyClient.fetchJSON('GET', '/remote/assets/bank_classifier_nb_and_voc');
@@ -178993,7 +179234,7 @@ PI = new Decimal(PI);
 
 var baseExtremum = __webpack_require__(1235),
     baseGt = __webpack_require__(1236),
-    baseIteratee = __webpack_require__(401);
+    baseIteratee = __webpack_require__(413);
 
 /**
  * This method is like `_.max` except that it accepts `iteratee` which is
@@ -179031,7 +179272,7 @@ module.exports = maxBy;
 /* 1235 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var isSymbol = __webpack_require__(362);
+var isSymbol = __webpack_require__(374);
 
 /**
  * The base implementation of methods like `_.max` and `_.min` which accepts a
@@ -179116,7 +179357,7 @@ const {
 
 const maxBy = __webpack_require__(1234);
 
-const logger = __webpack_require__(342);
+const logger = __webpack_require__(354);
 
 const {
   LOCAL_MODEL_CATEG_FALLBACK,
@@ -179204,7 +179445,7 @@ const {
   getLabelWithTags
 } = __webpack_require__(1227);
 
-const logger = __webpack_require__(342);
+const logger = __webpack_require__(354);
 
 const log = logger.namespace('categorization/localModel/classifier');
 const ALPHA_MIN = 2;
@@ -179348,11 +179589,11 @@ module.exports = {
 /* 1240 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const cozyClient = __webpack_require__(473);
+const cozyClient = __webpack_require__(485);
 
 const {
   Q
-} = __webpack_require__(509);
+} = __webpack_require__(521);
 
 async function fetchTransactionsWithManualCat() {
   const client = cozyClient.new;
@@ -179376,7 +179617,7 @@ module.exports = {
 /* 1241 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const uniq = __webpack_require__(612);
+const uniq = __webpack_require__(624);
 
 const getUniqueCategories = transactions => {
   return uniq(transactions.map(t => t.manualCategoryId));
@@ -179420,7 +179661,7 @@ module.exports = {
 /* 1243 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const log = (__webpack_require__(342).namespace)('cozy-konnector-libs');
+const log = (__webpack_require__(354).namespace)('cozy-konnector-libs');
 
 module.exports = log;
 
@@ -179428,13 +179669,13 @@ module.exports = log;
 /* 1244 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const cozy = __webpack_require__(473);
+const cozy = __webpack_require__(485);
 
-const log = (__webpack_require__(342).namespace)('BaseKonnector');
+const log = (__webpack_require__(354).namespace)('BaseKonnector');
 
 const {
   Secret
-} = __webpack_require__(342);
+} = __webpack_require__(354);
 
 const manifest = __webpack_require__(909);
 
@@ -179444,14 +179685,16 @@ const saveFiles = __webpack_require__(1246);
 
 const signin = __webpack_require__(1286);
 
-const get = __webpack_require__(358);
+const get = __webpack_require__(370);
 
-const omit = __webpack_require__(613);
+const omit = __webpack_require__(625);
 
 const updateOrCreate = __webpack_require__(1289);
 
 const saveIdentity = __webpack_require__(1290);
 
+const fs = (__webpack_require__(149).promises);
+
 const {
   wrapIfSentrySetUp,
   captureExceptionAndDie
@@ -179604,6 +179847,40 @@ class BaseKonnector {
       throw new Error('CANNOT_FIND_ACCOUNT');
     }
   }
+  /**
+   * Read an eventual payload from COZY_PAYLOAD env var, wether it is a JSON string or a reference
+   * to a file containing a JSON string
+   *
+   * @returns Promise<{Object|null}> result of JSON.parse from the JSON string or null if no payload
+   */
+
+
+  async readPayload() {
+    const cozyPayload = process.env.COZY_PAYLOAD;
+
+    if (cozyPayload == null) {
+      return null;
+    }
+
+    const isFileReference = get(cozyPayload, '[0]') === '@';
+
+    if (isFileReference) {
+      const filePath = cozyPayload.substr(1);
+
+      try {
+        const fileContent = await fs.readFile(filePath);
+        return JSON.parse(fileContent);
+      } catch (err) {
+        throw new Error(`Error while reading file ${filePath} payload: ${err.message}`);
+      }
+    } else {
+      try {
+        return JSON.parse(cozyPayload);
+      } catch (err) {
+        throw new Error('Could not parse JSON in COZY_PAYLOAD: ' + cozyPayload);
+      }
+    }
+  }
   /**
    * Initializes konnector attributes that will be used during its lifetime
    *
@@ -179969,21 +180246,21 @@ module.exports = BaseKonnector;
  *
  * @module saveBills
  */
-const utils = __webpack_require__(472);
+const utils = __webpack_require__(484);
 
 const saveFiles = __webpack_require__(1246);
 
-const hydrateAndFilter = __webpack_require__(341);
+const hydrateAndFilter = __webpack_require__(353);
 
 const addData = __webpack_require__(1266);
 
-const log = (__webpack_require__(342).namespace)('saveBills');
+const log = (__webpack_require__(354).namespace)('saveBills');
 
 const linkBankOperations = __webpack_require__(1267);
 
 const DOCTYPE = 'io.cozy.bills';
 
-const _ = __webpack_require__(837);
+const _ = __webpack_require__(835);
 
 const manifest = __webpack_require__(909);
 
@@ -180274,19 +180551,19 @@ const path = __webpack_require__(142);
 
 const requestFactory = __webpack_require__(2);
 
-const omit = __webpack_require__(613);
+const omit = __webpack_require__(625);
 
-const get = __webpack_require__(358);
+const get = __webpack_require__(370);
 
-const log = (__webpack_require__(342).namespace)('saveFiles');
+const log = (__webpack_require__(354).namespace)('saveFiles');
 
 const manifest = __webpack_require__(909);
 
-const cozy = __webpack_require__(473);
+const cozy = __webpack_require__(485);
 
 const {
   queryAll
-} = __webpack_require__(472);
+} = __webpack_require__(484);
 
 const mkdirp = __webpack_require__(1249);
 
@@ -181099,7 +181376,7 @@ const {
   join
 } = (__webpack_require__(142).posix);
 
-const cozyClient = __webpack_require__(473);
+const cozyClient = __webpack_require__(485);
 /**
  * Creates a directory and its missing ancestors as needed.
  *
@@ -184444,9 +184721,9 @@ module.exports = {
  */
 const bluebird = __webpack_require__(5);
 
-const omit = __webpack_require__(613);
+const omit = __webpack_require__(625);
 
-const log = (__webpack_require__(342).namespace)('addData');
+const log = (__webpack_require__(354).namespace)('addData');
 
 const {
   getCozyMetadata
@@ -184485,7 +184762,7 @@ const {
 
 
 const addData = (entries, doctype, options = {}) => {
-  const cozy = __webpack_require__(473);
+  const cozy = __webpack_require__(485);
 
   return bluebird.mapSeries(entries, async entry => {
     log('debug', entry, 'Adding this entry');
@@ -184517,7 +184794,7 @@ module.exports = addData;
  */
 const bluebird = __webpack_require__(5);
 
-const log = (__webpack_require__(342).namespace)('linkBankOperations');
+const log = (__webpack_require__(354).namespace)('linkBankOperations');
 
 const {
   findDebitOperation,
@@ -184528,9 +184805,9 @@ const fs = __webpack_require__(149);
 
 const defaults = __webpack_require__(1279);
 
-const groupBy = __webpack_require__(724);
+const groupBy = __webpack_require__(736);
 
-const flatten = __webpack_require__(540);
+const flatten = __webpack_require__(552);
 
 const sumBy = __webpack_require__(1275);
 
@@ -184540,7 +184817,7 @@ const {
   format
 } = __webpack_require__(962);
 
-const cozyClient = __webpack_require__(473);
+const cozyClient = __webpack_require__(485);
 
 const DOCTYPE_OPERATIONS = 'io.cozy.bank.operations';
 const DEFAULT_AMOUNT_DELTA = 0.001;
@@ -184842,7 +185119,7 @@ const linkBankOperations = async (bills, doctype, fields, options = {}) => {
     options.identifiers = [fields.bank_identifier];
   }
 
-  const cozyClient = __webpack_require__(473);
+  const cozyClient = __webpack_require__(485);
 
   const linker = new Linker(cozyClient);
 
@@ -185069,10 +185346,10 @@ module.exports = {
 /* 1270 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIndexOf = __webpack_require__(465),
-    isArrayLike = __webpack_require__(446),
+var baseIndexOf = __webpack_require__(477),
+    isArrayLike = __webpack_require__(458),
     isString = __webpack_require__(54),
-    toInteger = __webpack_require__(624),
+    toInteger = __webpack_require__(636),
     values = __webpack_require__(1271);
 
 /* Built-in method references for those with the same name as other `lodash` methods. */
@@ -185129,7 +185406,7 @@ module.exports = includes;
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 var baseValues = __webpack_require__(1272),
-    keys = __webpack_require__(429);
+    keys = __webpack_require__(441);
 
 /**
  * Creates an array of the own enumerable string keyed property values of `object`.
@@ -185168,7 +185445,7 @@ module.exports = values;
 /* 1272 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var arrayMap = __webpack_require__(398);
+var arrayMap = __webpack_require__(410);
 
 /**
  * The base implementation of `_.values` and `_.valuesIn` which creates an
@@ -185193,11 +185470,11 @@ module.exports = baseValues;
 /* 1273 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var arraySome = __webpack_require__(416),
-    baseIteratee = __webpack_require__(401),
+var arraySome = __webpack_require__(428),
+    baseIteratee = __webpack_require__(413),
     baseSome = __webpack_require__(1274),
     isArray = __webpack_require__(55),
-    isIterateeCall = __webpack_require__(749);
+    isIterateeCall = __webpack_require__(761);
 
 /**
  * Checks if `predicate` returns truthy for **any** element of `collection`.
@@ -185250,7 +185527,7 @@ module.exports = some;
 /* 1274 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseEach = __webpack_require__(555);
+var baseEach = __webpack_require__(567);
 
 /**
  * The base implementation of `_.some` without support for iteratee shorthands.
@@ -185278,7 +185555,7 @@ module.exports = baseSome;
 /* 1275 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIteratee = __webpack_require__(401),
+var baseIteratee = __webpack_require__(413),
     baseSum = __webpack_require__(1276);
 
 /**
@@ -185347,7 +185624,7 @@ module.exports = baseSum;
 /* 1277 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const sortBy = __webpack_require__(840);
+const sortBy = __webpack_require__(838);
 
 const {
   addDays,
@@ -185526,10 +185803,10 @@ module.exports = {
 /* 1279 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseRest = __webpack_require__(544),
-    eq = __webpack_require__(385),
-    isIterateeCall = __webpack_require__(749),
-    keysIn = __webpack_require__(567);
+var baseRest = __webpack_require__(556),
+    eq = __webpack_require__(397),
+    isIterateeCall = __webpack_require__(761),
+    keysIn = __webpack_require__(579);
 
 /** Used for built-in method references. */
 var objectProto = Object.prototype;
@@ -186077,11 +186354,11 @@ const errors = __webpack_require__(1250);
 
 const rerrors = __webpack_require__(1287);
 
-const log = (__webpack_require__(342).namespace)('cozy-konnector-libs');
+const log = (__webpack_require__(354).namespace)('cozy-konnector-libs');
 
 const requestFactory = __webpack_require__(2);
 
-const cheerio = __webpack_require__(255);
+const cheerio = __webpack_require__(256);
 /**
  * Provides an handy method to log the user in,
  * on HTML form pages. On success, it resolves to a promise with a parsed body.
@@ -186301,11 +186578,11 @@ module.exports = __webpack_require__(44);
  */
 const bluebird = __webpack_require__(5);
 
-const log = (__webpack_require__(342).namespace)('updateOrCreate');
+const log = (__webpack_require__(354).namespace)('updateOrCreate');
 
-const cozy = __webpack_require__(473);
+const cozy = __webpack_require__(485);
 
-const get = __webpack_require__(358);
+const get = __webpack_require__(370);
 
 const {
   getCozyMetadata
@@ -186363,7 +186640,7 @@ module.exports = updateOrCreate;
  *
  * @module saveIdentity
  */
-const log = (__webpack_require__(342).namespace)('saveIdentity');
+const log = (__webpack_require__(354).namespace)('saveIdentity');
 
 const updateOrCreate = __webpack_require__(1289);
 /**
@@ -186473,7 +186750,7 @@ module.exports = saveIdentity;
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
 /* global __APP_VERSION__ */
-const log = __webpack_require__(342);
+const log = __webpack_require__(354);
 
 const Raven = __webpack_require__(1292);
 
@@ -186650,7 +186927,7 @@ extend(Raven.prototype, {
     this.raw_dsn = dsn;
     this.dsn = utils.parseDSN(dsn);
     this.name =
-      options.name || global.process.env.SENTRY_NAME || (__webpack_require__(252).hostname)();
+      options.name || global.process.env.SENTRY_NAME || (__webpack_require__(253).hostname)();
     this.root = options.root || global.process.cwd();
     this.transport = options.transport || transports[this.dsn.protocol];
     this.sendTimeout = options.sendTimeout || 1;
@@ -189405,7 +189682,7 @@ module.exports = once;
 /* 1322 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var toInteger = __webpack_require__(624);
+var toInteger = __webpack_require__(636);
 
 /** Error message constants. */
 var FUNC_ERROR_TEXT = 'Expected a function';
@@ -189451,7 +189728,7 @@ module.exports = before;
 /* 1323 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const log = (__webpack_require__(342).namespace)('Error Interception');
+const log = (__webpack_require__(354).namespace)('Error Interception');
 
 const handleUncaughtException = err => {
   log('critical', err.message, 'uncaught exception');
@@ -189511,7 +189788,7 @@ module.exports = {
 /* 1324 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const log = (__webpack_require__(342).namespace)('CookieKonnector');
+const log = (__webpack_require__(354).namespace)('CookieKonnector');
 
 const BaseKonnector = __webpack_require__(1244);
 
@@ -189986,7 +190263,7 @@ module.exports = {
 
 const isEqualWith = __webpack_require__(1327);
 
-const omit = __webpack_require__(613);
+const omit = __webpack_require__(625);
 
 const maybeToISO = date => {
   try {
@@ -190051,7 +190328,7 @@ module.exports = Document;
 /* 1327 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-var baseIsEqual = __webpack_require__(410);
+var baseIsEqual = __webpack_require__(422);
 
 /**
  * This method is like `_.isEqual` except that it accepts `customizer` which
@@ -190098,7 +190375,7 @@ module.exports = isEqualWith;
 /* 1328 */
 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
 
-const log = (__webpack_require__(342).namespace)('scrape');
+const log = (__webpack_require__(354).namespace)('scrape');
 /**
  * Declarative scraping.
  *
@@ -190292,7 +190569,7 @@ module.exports = normalizeFilename;
  *
  * @module solveCaptcha
  */
-const log = (__webpack_require__(342).namespace)('solveCaptcha');
+const log = (__webpack_require__(354).namespace)('solveCaptcha');
 
 const errors = __webpack_require__(1250);
 
@@ -194218,7 +194495,7 @@ module.exports = require("tty");
 
 "use strict";
 
-const os = __webpack_require__(252);
+const os = __webpack_require__(253);
 const tty = __webpack_require__(1363);
 const hasFlag = __webpack_require__(1365);
 
diff --git a/package.json b/package.json
index c0bfb26..eb3c5f8 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
   },
   "dependencies": {
     "axios": "^0.27.2",
-    "cozy-konnector-libs": "4.52.1",
+    "cozy-konnector-libs": "4.54.0",
     "easy-soap-request": "^4.7.0",
     "jest": "^28.1.3",
     "moment": "^2.29.3",
@@ -49,8 +49,8 @@
     "xml2js": "^0.4.23"
   },
   "devDependencies": {
-    "cozy-jobs-cli": "1.17.6",
-    "cozy-konnector-build": "1.3.1",
+    "cozy-jobs-cli": "1.18.2",
+    "cozy-konnector-build": "1.3.4",
     "eslint-config-cozy-app": "1.3.3",
     "eslint-plugin-prettier": "^4.0.0",
     "git-directory-deploy": "1.5.1",
-- 
GitLab