diff --git a/index.html b/index.html
index 40ccdddbfb0f689810b8c6392b425e46d97e0488..9e5cdb8022dbfba22daa9d5d2198eda9584b8165 100644
--- a/index.html
+++ b/index.html
@@ -1 +1 @@
-<!DOCTYPE html><html lang="{{.Locale}}"><head><meta charset="utf-8"><title>Ecolyo</title><link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"><!-- PWA Manifest --><link rel="manifest" href="/manifest.json" crossorigin="use-credentials"><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#297EF2"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,viewport-fit=cover"><!-- PWA Chrome --><link rel="icon" sizes="192x192" href="/android-chrome-192x192.png"><link rel="icon" sizes="512x512" href="/android-chrome-512x512.png"><!-- PWA iOS --><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="apple-touch-startup-image" href="/apple-touch-icon.png"><meta name="apple-mobile-web-app-title" content="Ecolyo"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><!-- PWA Colors --><meta name="theme-color" content="#343641"><meta name="background-color" content="#121212">{{.ThemeCSS}} {{.CozyBar}}<script src="//{{.Domain}}/assets/js/piwik.js"></script></head><body><div role="application" class="application" data-cozy="{{.CozyData}}"><script src="vendors/ecolyo.7d2dc2a8de788a437224.js"></script><script src="app/ecolyo.554a8422165fe8f24237.js"></script></div></body></html>
\ No newline at end of file
+<!DOCTYPE html><html lang="{{.Locale}}"><head><meta charset="utf-8"><title>Ecolyo</title><link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"><!-- PWA Manifest --><link rel="manifest" href="/manifest.json" crossorigin="use-credentials"><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#297EF2"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,viewport-fit=cover"><!-- PWA Chrome --><link rel="icon" sizes="192x192" href="/android-chrome-192x192.png"><link rel="icon" sizes="512x512" href="/android-chrome-512x512.png"><!-- PWA iOS --><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="apple-touch-startup-image" href="/apple-touch-icon.png"><meta name="apple-mobile-web-app-title" content="Ecolyo"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><!-- PWA Colors --><meta name="theme-color" content="#343641"><meta name="background-color" content="#121212">{{.ThemeCSS}} {{.CozyBar}}<script src="//{{.Domain}}/assets/js/piwik.js"></script></head><body><div role="application" class="application" data-cozy="{{.CozyData}}"><script src="vendors/ecolyo.0f66f88c2aa7f446186b.js"></script><script src="app/ecolyo.554a8422165fe8f24237.js"></script></div></body></html>
\ No newline at end of file
diff --git a/public/ecolyo.fa7a0f4ba5b56c90e338.js b/public/ecolyo.297fa83f17e3216f8d1a.js
similarity index 99%
rename from public/ecolyo.fa7a0f4ba5b56c90e338.js
rename to public/ecolyo.297fa83f17e3216f8d1a.js
index a7c7b3cf350d80939f97b586c08373bb42b740ca..8cd569273bc7e9d56b822a3c0829f7d3e5313d42 100644
--- a/public/ecolyo.fa7a0f4ba5b56c90e338.js
+++ b/public/ecolyo.297fa83f17e3216f8d1a.js
@@ -25267,6 +25267,68 @@ module.exports = {"name":"Ecolyo","slug":"ecolyo","icon":"public/icon.svg","cate
 
 /***/ }),
 
+/***/ "6/w4":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Minilog = __webpack_require__("aY/w");
+
+var oldEnable = Minilog.enable,
+    oldDisable = Minilog.disable,
+    isChrome = typeof navigator != 'undefined' && /chrome/i.test(navigator.userAgent),
+    isReactNative = typeof navigator != 'undefined' && navigator.product === 'ReactNative',
+    console = __webpack_require__("FRkB"); // Use a more capable logging backend if on Chrome
+
+
+Minilog.defaultBackend = isChrome || isReactNative ? console.minilog : console; // apply enable inputs from localStorage and from the URL
+
+if (typeof window != 'undefined') {
+  try {
+    Minilog.enable(JSON.parse(window.localStorage['minilogSettings']));
+  } catch (e) {// ignore
+  }
+
+  if (window.location && window.location.search) {
+    var match = RegExp('[?&]minilog=([^&]*)').exec(window.location.search);
+    match && Minilog.enable(decodeURIComponent(match[1]));
+  }
+} // Make enable also add to localStorage
+
+
+Minilog.enable = function () {
+  oldEnable.call(Minilog, true);
+
+  try {
+    window.localStorage['minilogSettings'] = JSON.stringify(true);
+  } catch (e) {// ignore
+  }
+
+  return this;
+};
+
+Minilog.disable = function () {
+  oldDisable.call(Minilog);
+
+  try {
+    delete window.localStorage.minilogSettings;
+  } catch (e) {// ignore
+  }
+
+  return this;
+};
+
+exports = module.exports = Minilog;
+exports.backends = {
+  array: __webpack_require__("It/H"),
+  browser: Minilog.defaultBackend,
+  localStorage: __webpack_require__("dBgm"),
+  jQuery: __webpack_require__("Uc0E")
+};
+
+/***/ }),
+
 /***/ "67e+":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -36864,6 +36926,19 @@ Object.keys(_useWebviewIntent).forEach(function (key) {
   });
 });
 
+var _useIsAvailable = __webpack_require__("w0CX");
+
+Object.keys(_useIsAvailable).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  if (key in exports && exports[key] === _useIsAvailable[key]) return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function get() {
+      return _useIsAvailable[key];
+    }
+  });
+});
+
 /***/ }),
 
 /***/ "7zid":
@@ -57504,6 +57579,52 @@ module.exports = function isPrimitive(value) {
 };
 
 
+/***/ }),
+
+/***/ "FRkB":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* eslint-disable no-console */
+var Transform = __webpack_require__("UJNO");
+
+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) {// ignore
+    }
+
+    console.log(args.join(' '));
+  }
+};
+
+logger.formatters = ['color', 'minilog'];
+logger.color = __webpack_require__("IPbC");
+logger.minilog = __webpack_require__("U0A+");
+module.exports = logger;
+
 /***/ }),
 
 /***/ "FSf8":
@@ -63643,6 +63764,24 @@ module.exports = realNames;
 "use strict";
 
 
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.isFlagshipUI = void 0;
+
+/** App's description resulting of its manifest.webapp file */
+
+/** App's mobile information. Used to describe the app scheme and its store urls */
+
+/**
+ * All the different colors are optional
+ */
+var isFlagshipUI = function isFlagshipUI(item) {
+  return typeof item === 'object' && item !== null && ('bottomBackground' in item || 'bottomOverlay' in item || 'bottomTheme' in item || 'topBackground' in item || 'topOverlay' in item || 'topTheme' in item);
+};
+
+exports.isFlagshipUI = isFlagshipUI;
+
 /***/ }),
 
 /***/ "GsEq":
@@ -71275,6 +71414,40 @@ function jssNested() {
 /* harmony default export */ __webpack_exports__["default"] = (jssNested);
 
 
+/***/ }),
+
+/***/ "IPbC":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* eslint-disable no-console */
+var Transform = __webpack_require__("UJNO"),
+    color = __webpack_require__("OmjS");
+
+var colors = {
+  debug: ['cyan'],
+  info: ['purple'],
+  warn: ['yellow', true],
+  error: ['red', true]
+},
+    logger = new Transform();
+
+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;
+
 /***/ }),
 
 /***/ "IQ1l":
@@ -71676,6 +71849,34 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+/***/ }),
+
+/***/ "It/H":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO"),
+    cache = [];
+
+var logger = new Transform();
+
+logger.write = function (name, level, args) {
+  cache.push([name, level, args]);
+}; // utility functions
+
+
+logger.get = function () {
+  return cache;
+};
+
+logger.empty = function () {
+  cache = [];
+};
+
+module.exports = logger;
+
 /***/ }),
 
 /***/ "Itbq":
@@ -79402,10 +79603,12 @@ var _interopRequireDefault = __webpack_require__("jm00");
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isWebDevMode = exports.isNativeDevMode = exports.interpolate = exports.getErrorMessage = void 0;
+exports.isWebDevMode = exports.isThemeArg = exports.isNativeDevMode = exports.isFlagshipUiArgsArray = exports.interpolate = exports.getErrorMessage = void 0;
 
 var _construct2 = _interopRequireDefault(__webpack_require__("GZTL"));
 
+var _api = __webpack_require__("VXXh");
+
 var interpolate = function interpolate(str, params) {
   if (!params) return str;
   var names = Object.keys(params);
@@ -79451,6 +79654,18 @@ var getErrorMessage = function getErrorMessage(error) {
 
 exports.getErrorMessage = getErrorMessage;
 
+var isFlagshipUiArgsArray = function isFlagshipUiArgsArray(item) {
+  return Array.isArray(item) && (0, _api.isFlagshipUI)(item[0]);
+};
+
+exports.isFlagshipUiArgsArray = isFlagshipUiArgsArray;
+
+var isThemeArg = function isThemeArg(item) {
+  return typeof item === 'string';
+};
+
+exports.isThemeArg = isThemeArg;
+
 /***/ }),
 
 /***/ "M+cw":
@@ -84723,6 +84938,36 @@ var AppBar = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_2__["forwardRef"](funct
 
 /***/ }),
 
+/***/ "OmjS":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+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;
+
+/***/ }),
+
 /***/ "OqZc":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -85129,6 +85374,87 @@ function persistReducer(config, baseReducer) {
 
 /***/ }),
 
+/***/ "Oxkl":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// default filter
+var Transform = __webpack_require__("UJNO");
+
+var levelMap = {
+  debug: 1,
+  info: 2,
+  warn: 3,
+  error: 4
+};
+
+function Filter() {
+  this.enabled = true;
+  this.defaultResult = true;
+  this.clear();
+}
+
+Transform.mixin(Filter); // allow all matching, with level >= given level
+
+Filter.prototype.allow = function (name, level) {
+  this._white.push({
+    n: name,
+    l: levelMap[level]
+  });
+
+  return this;
+}; // 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;
+};
+
+function test(rule, name) {
+  // use .test for RegExps
+  return rule.n.test ? rule.n.test(name) : rule.n == name;
+}
+
+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;
+};
+
+Filter.prototype.write = function (name, level, args) {
+  if (!this.enabled || this.test(name, level)) {
+    return this.emit('item', name, level, args);
+  }
+};
+
+module.exports = Filter;
+
+/***/ }),
+
 /***/ "P3Kl":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -93778,7 +94104,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
 var log = (0, _postMe.debug)('NativeService');
 
 var NativeService = /*#__PURE__*/function () {
-  function NativeService(localMethods) {
+  function NativeService(_localMethods) {
     var _this = this;
 
     var messengerService = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _api.NativeMessenger;
@@ -93786,6 +94112,9 @@ var NativeService = /*#__PURE__*/function () {
     (0, _defineProperty2.default)(this, "messengerService", void 0);
     (0, _defineProperty2.default)(this, "localMethods", void 0);
     (0, _defineProperty2.default)(this, "messengerRegister", {});
+    (0, _defineProperty2.default)(this, "updateLocalMethods", function (localMethods) {
+      _this.localMethods = localMethods;
+    });
     (0, _defineProperty2.default)(this, "getUri", function (source) {
       return new URL(source.nativeEvent.url).hostname.toLowerCase();
     });
@@ -93799,14 +94128,15 @@ var NativeService = /*#__PURE__*/function () {
     (0, _defineProperty2.default)(this, "isInitMessage", function (message) {
       return message.message === _api.strings.webviewIsRendered;
     });
-    (0, _defineProperty2.default)(this, "registerWebview", function (uri, ref) {
+    (0, _defineProperty2.default)(this, "registerWebview", function (uri, slug, ref) {
       log(_api.strings.logging.registering(uri));
       if (_this.messengerRegister[uri]) return log((0, _utils.interpolate)(_api.strings.errorRegisterWebview, {
         uri: uri
       }));
       var messenger = new _this.messengerService(ref);
       _this.messengerRegister = _objectSpread(_objectSpread({}, _this.messengerRegister), {}, (0, _defineProperty2.default)({}, uri, {
-        messenger: (0, _utils.isNativeDevMode)() ? (0, _api.DebugNativeMessenger)(messenger) : messenger
+        messenger: (0, _utils.isNativeDevMode)() ? (0, _api.DebugNativeMessenger)(messenger) : messenger,
+        slug: slug
       }));
       log(_api.strings.logging.registered(uri));
     });
@@ -93843,7 +94173,7 @@ var NativeService = /*#__PURE__*/function () {
       };
     }());
     (0, _defineProperty2.default)(this, "tryEmit", /*#__PURE__*/function () {
-      var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(event) {
+      var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(event, componentId) {
         var parsedEvent;
         return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
@@ -93859,21 +94189,32 @@ var NativeService = /*#__PURE__*/function () {
               case 2:
                 parsedEvent = _this.parseNativeEvent(event);
 
+                if (parsedEvent.methodName === 'setFlagshipUI' && (0, _utils.isFlagshipUiArgsArray)(parsedEvent.args)) {
+                  parsedEvent.args[0].componentId = componentId;
+                }
+
+                if (parsedEvent.methodName === 'setTheme' && Array.isArray(parsedEvent.args) && (0, _utils.isThemeArg)(parsedEvent.args[0])) {
+                  parsedEvent.args[0] = {
+                    homeTheme: parsedEvent.args[0],
+                    componentId: componentId
+                  };
+                }
+
                 if (!_this.isInitMessage(parsedEvent)) {
-                  _context2.next = 7;
+                  _context2.next = 9;
                   break;
                 }
 
-                _context2.next = 6;
+                _context2.next = 8;
                 return _this.tryInit(event);
 
-              case 6:
+              case 8:
                 return _context2.abrupt("return", _context2.sent);
 
-              case 7:
+              case 9:
                 if (_this.isPostMeMessage(parsedEvent)) _this.tryOnMessage(event, parsedEvent);
 
-              case 8:
+              case 10:
               case "end":
                 return _context2.stop();
             }
@@ -93881,7 +94222,7 @@ var NativeService = /*#__PURE__*/function () {
         }, _callee2);
       }));
 
-      return function (_x2) {
+      return function (_x2, _x3) {
         return _ref3.apply(this, arguments);
       };
     }());
@@ -93930,11 +94271,13 @@ var NativeService = /*#__PURE__*/function () {
         }, _callee3, null, [[2, 10]]);
       }));
 
-      return function (_x3) {
+      return function (_x4) {
         return _ref4.apply(this, arguments);
       };
     }());
     (0, _defineProperty2.default)(this, "tryOnMessage", function (event, message) {
+      var _message$args;
+
       var webviewUri = _this.getUri(event);
 
       var registeredWebview = _this.messengerRegister[webviewUri];
@@ -93945,6 +94288,9 @@ var NativeService = /*#__PURE__*/function () {
         }));
       }
 
+      (_message$args = message.args) === null || _message$args === void 0 ? void 0 : _message$args.unshift({
+        slug: registeredWebview.slug
+      });
       registeredWebview.messenger.onMessage(message);
     });
     (0, _defineProperty2.default)(this, "getHostname", function (uri) {
@@ -93964,15 +94310,13 @@ var NativeService = /*#__PURE__*/function () {
       return (_this$messengerRegist = _this.messengerRegister[_this.getHostname(uri)]) === null || _this$messengerRegist === void 0 ? void 0 : (_this$messengerRegist2 = _this$messengerRegist.connection) === null || _this$messengerRegist2 === void 0 ? void 0 : (_this$messengerRegist3 = _this$messengerRegist2.remoteHandle()).call.apply(_this$messengerRegist3, [methodName].concat(args));
     });
     this.messengerService = messengerService;
-    this.localMethods = localMethods;
+    this.localMethods = _localMethods;
   }
 
   (0, _createClass2.default)(NativeService, [{
     key: "isNativeEvent",
     value: function isNativeEvent(object) {
-      var _nativeEvent;
-
-      return ((_nativeEvent = object.nativeEvent) === null || _nativeEvent === void 0 ? void 0 : _nativeEvent.data) !== undefined;
+      return object.nativeEvent.data !== undefined;
     }
   }]);
   return NativeService;
@@ -97270,6 +97614,52 @@ class BrowserClient extends _sentry_core__WEBPACK_IMPORTED_MODULE_0__["BaseClien
 //# sourceMappingURL=client.js.map
 
 
+/***/ }),
+
+/***/ "U0A+":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* eslint-disable no-console */
+var Transform = __webpack_require__("UJNO"),
+    color = __webpack_require__("OmjS"),
+    colors = {
+  debug: ['gray'],
+  info: ['purple'],
+  warn: ['yellow', true],
+  error: ['red', true]
+},
+    logger = new Transform();
+
+logger.write = function (name, level, args) {
+  var fn = console.log;
+
+  if (level != 'debug' && console[level]) {
+    fn = console[level];
+  } // eslint-disable-next-line no-unused-vars
+
+
+  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));
+  }
+}; // NOP, because piping the formatted logs can only cause trouble.
+
+
+logger.pipe = function () {};
+
+module.exports = logger;
+
 /***/ }),
 
 /***/ "U9vJ":
@@ -97730,6 +98120,87 @@ exports.default = _default;
 
 /***/ }),
 
+/***/ "UJNO":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var microee = __webpack_require__("GIvT"); // Implements a subset of Node's stream.Transform - in a cross-platform manner.
+
+
+function Transform() {}
+
+microee.mixin(Transform); // 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);
+};
+
+Transform.prototype.end = function () {
+  this.emit('end');
+  this.removeAllListeners();
+};
+
+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();
+  }
+
+  s.on('item', onItem);
+  s.on('end', onEnd);
+  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;
+  });
+  return dest;
+};
+
+Transform.prototype.unpipe = function (from) {
+  this.emit('unpipe', from);
+  return this;
+};
+
+Transform.prototype.format = function () {
+  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'));
+};
+
+Transform.mixin = function (dest) {
+  var o = Transform.prototype,
+      k;
+
+  for (k in o) {
+    // eslint-disable-next-line no-prototype-builtins
+    o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
+  }
+};
+
+module.exports = Transform;
+
+/***/ }),
+
 /***/ "UMYs":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -98292,6 +98763,103 @@ if (__webpack_require__("WXXH") && (!CORRECT_NEW || __webpack_require__("enc5")(
 __webpack_require__("iaIa")('RegExp');
 
 
+/***/ }),
+
+/***/ "Uc0E":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO");
+
+var cid = new Date().valueOf().toString(36);
+
+function AjaxLogger(options) {
+  this.url = options.url || '';
+  this.cache = [];
+  this.timer = null;
+  this.interval = options.interval || 30 * 1000;
+  this.enabled = true;
+  this.jQuery = window.jQuery;
+  this.extras = {};
+}
+
+Transform.mixin(AjaxLogger);
+
+AjaxLogger.prototype.write = function (name, level, args) {
+  if (!this.timer) {
+    this.init();
+  }
+
+  this.cache.push([name, level].concat(args));
+};
+
+AjaxLogger.prototype.init = function () {
+  if (!this.enabled || !this.jQuery) return;
+  var self = this;
+  this.timer = setTimeout(function () {
+    var i,
+        logs = [],
+        ajaxData,
+        url = self.url;
+    if (self.cache.length == 0) return self.init(); // Test each log line and only log the ones that are valid (e.g. don't have circular references).
+    // Slight performance hit but benefit is we log all valid lines.
+
+    for (i = 0; i < self.cache.length; i++) {
+      try {
+        JSON.stringify(self.cache[i]);
+        logs.push(self.cache[i]);
+      } catch (e) {// ignore
+      }
+    }
+
+    if (self.jQuery.isEmptyObject(self.extras)) {
+      ajaxData = JSON.stringify({
+        logs: logs
+      });
+      url = self.url + '?client_id=' + cid;
+    } else {
+      ajaxData = JSON.stringify(self.jQuery.extend({
+        logs: logs
+      }, self.extras));
+    }
+
+    self.jQuery.ajax(url, {
+      type: 'POST',
+      cache: false,
+      processData: false,
+      data: ajaxData,
+      contentType: 'application/json',
+      timeout: 10000
+    }).success(function (data) {
+      if (data.interval) {
+        self.interval = Math.max(1000, data.interval);
+      }
+    }).error(function () {
+      self.interval = 30000;
+    }).always(function () {
+      self.init();
+    });
+    self.cache = [];
+  }, this.interval);
+};
+
+AjaxLogger.prototype.end = function () {}; // wait until jQuery is defined. Useful if you don't control the load order.
+
+
+AjaxLogger.jQueryWait = function (onDone) {
+  if (typeof window !== 'undefined' && (window.jQuery || window.$)) {
+    return onDone(window.jQuery || window.$);
+  } else if (typeof window !== 'undefined') {
+    setTimeout(function () {
+      AjaxLogger.jQueryWait(onDone);
+    }, 200);
+  }
+};
+
+module.exports = AjaxLogger;
+
 /***/ }),
 
 /***/ "Uc5S":
@@ -104168,7 +104736,7 @@ var _interopRequireDefault = __webpack_require__("jm00");
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.NativeMessenger = exports.DebugNativeMessenger = void 0;
+exports.logger = exports.NativeMessenger = exports.DebugNativeMessenger = void 0;
 
 var _createClass2 = _interopRequireDefault(__webpack_require__("Zvb3"));
 
@@ -104178,16 +104746,28 @@ var _defineProperty2 = _interopRequireDefault(__webpack_require__("J58c"));
 
 var _postMe = __webpack_require__("L5KM");
 
+var _cozyMinilog = _interopRequireDefault(__webpack_require__("6/w4"));
+
 var _api = __webpack_require__("VXXh");
 
+var logger = (0, _cozyMinilog.default)('cozy-intent');
+exports.logger = logger;
 var log = (0, _postMe.debug)('NativeMessenger');
 var NativeMessenger = /*#__PURE__*/(0, _createClass2.default)(function NativeMessenger(webviewRef) {
-  var _this = this;
+  var _this = this,
+      _webviewRef$props$sou;
 
   (0, _classCallCheck2.default)(this, NativeMessenger);
   (0, _defineProperty2.default)(this, "injectJavaScript", void 0);
   (0, _defineProperty2.default)(this, "listener", void 0);
+  (0, _defineProperty2.default)(this, "webviewUri", void 0);
   (0, _defineProperty2.default)(this, "postMessage", function (message) {
+    if (message.error) {
+      var _this$webviewUri;
+
+      logger.warn("Error during intent to ".concat((_this$webviewUri = _this.webviewUri) !== null && _this$webviewUri !== void 0 ? _this$webviewUri : 'undefined webview', " : "), JSON.stringify(message.error));
+    }
+
     try {
       var _this$injectJavaScrip;
 
@@ -104214,6 +104794,7 @@ var NativeMessenger = /*#__PURE__*/(0, _createClass2.default)(function NativeMes
     });
   });
   this.injectJavaScript = webviewRef.injectJavaScript;
+  this.webviewUri = (_webviewRef$props$sou = webviewRef.props.source.uri) !== null && _webviewRef$props$sou !== void 0 ? _webviewRef$props$sou : webviewRef.props.source.baseUrl;
 });
 exports.NativeMessenger = NativeMessenger;
 
@@ -111216,6 +111797,91 @@ exports.default = _default;
 
 /***/ }),
 
+/***/ "aY/w":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO"),
+    Filter = __webpack_require__("Oxkl");
+
+var log = new Transform(),
+    slice = Array.prototype.slice;
+
+exports = module.exports = function create(name) {
+  var o = function o() {
+    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;
+}; // filled in separately
+
+
+exports.defaultBackend = exports.defaultFormatter = null;
+
+exports.pipe = function (dest) {
+  return log.pipe(dest);
+};
+
+exports.end = exports.unpipe = exports.disable = function (from) {
+  return log.unpipe(from);
+};
+
+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
+};
+
+/***/ }),
+
 /***/ "aY11":
 /***/ (function(module, exports) {
 
@@ -118175,6 +118841,35 @@ Icon.muiName = 'Icon';
 
 /***/ }),
 
+/***/ "dBgm":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO"),
+    cache = false;
+
+var logger = new Transform();
+
+logger.write = function (name, level, args) {
+  if (typeof window == 'undefined' || typeof JSON == 'undefined' || !JSON.stringify || !JSON.parse) return;
+
+  try {
+    if (!cache) {
+      cache = window.localStorage.minilog ? JSON.parse(window.localStorage.minilog) : [];
+    }
+
+    cache.push([new Date().toString(), name, level, args]);
+    window.localStorage.minilog = JSON.stringify(cache);
+  } catch (e) {// ignore
+  }
+};
+
+module.exports = logger;
+
+/***/ }),
+
 /***/ "dCuL":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -172191,24 +172886,60 @@ module.exports = __webpack_require__("WXXH") ? Object.defineProperties : functio
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__("jm00");
-
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.NativeIntentProvider = void 0;
+exports.getNativeIntentService = exports.NativeIntentProvider = void 0;
 
-var _react = _interopRequireDefault(__webpack_require__("ivGQ"));
+var _postMe = __webpack_require__("L5KM");
 
-var _view = __webpack_require__("7zRI");
+var _react = _interopRequireWildcard(__webpack_require__("ivGQ"));
 
 var _api = __webpack_require__("VXXh");
 
+var _view = __webpack_require__("7zRI");
+
+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); }
+
+function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
+var log = (0, _postMe.debug)('NativeIntentProvider');
+var nativeIntentService;
+
+var getNativeIntentService = function getNativeIntentService() {
+  if (!nativeIntentService) {
+    throw new Error('nativeIntentService has not been instantiated in a NativeIntentProvider');
+  }
+
+  return nativeIntentService;
+};
+
+exports.getNativeIntentService = getNativeIntentService;
+
+var setNativeIntentService = function setNativeIntentService(service) {
+  nativeIntentService = service;
+};
+
 var NativeIntentProvider = function NativeIntentProvider(_ref) {
   var children = _ref.children,
       localMethods = _ref.localMethods;
+  // Use useRef to hold the service instance in a way that does not trigger re-renders
+  var serviceRef = (0, _react.useRef)(null);
+
+  if (serviceRef.current === null) {
+    serviceRef.current = new _api.NativeService(localMethods);
+    setNativeIntentService(serviceRef.current);
+  }
+
+  (0, _react.useEffect)(function () {
+    var _serviceRef$current;
+
+    // Always update methods since either they've changed, or this is the first run
+    log('Updating localMethods on nativeIntentService');
+    (_serviceRef$current = serviceRef.current) === null || _serviceRef$current === void 0 ? void 0 : _serviceRef$current.updateLocalMethods(localMethods);
+  }, [localMethods]);
   return /*#__PURE__*/_react.default.createElement(_view.NativeContext.Provider, {
-    value: new _api.NativeService(localMethods)
+    value: serviceRef.current
   }, children);
 };
 
@@ -189250,6 +189981,105 @@ function insertIntentIframe(intent, element, url, onload) {
 
 /***/ }),
 
+/***/ "w0CX":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__("jm00");
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.useIsAvailable = void 0;
+
+var _regenerator = _interopRequireDefault(__webpack_require__("hJxD"));
+
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("HZZ/"));
+
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__("XkwL"));
+
+var _react = __webpack_require__("ivGQ");
+
+var _useWebviewIntent = __webpack_require__("dMYP");
+
+var _utils = __webpack_require__("Lv97");
+
+var useIsAvailable = function useIsAvailable(methodName) {
+  var webviewIntent = (0, _useWebviewIntent.useWebviewIntent)();
+
+  var _useState = (0, _react.useState)(null),
+      _useState2 = (0, _slicedToArray2.default)(_useState, 2),
+      isAvailable = _useState2[0],
+      setIsAvailable = _useState2[1];
+
+  var _useState3 = (0, _react.useState)(undefined),
+      _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
+      error = _useState4[0],
+      setError = _useState4[1];
+
+  (0, _react.useEffect)(function () {
+    if (!webviewIntent) return;
+
+    var checkIsAvailable = /*#__PURE__*/function () {
+      var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var result;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.prev = 0;
+                _context.next = 3;
+                return webviewIntent.call('isAvailable', methodName);
+
+              case 3:
+                result = _context.sent;
+
+                if (!(typeof result !== 'boolean')) {
+                  _context.next = 6;
+                  break;
+                }
+
+                throw new Error("Invalid result from isAvailable method: ".concat(result));
+
+              case 6:
+                setError(undefined);
+                setIsAvailable(result);
+                _context.next = 14;
+                break;
+
+              case 10:
+                _context.prev = 10;
+                _context.t0 = _context["catch"](0);
+                setError((0, _utils.getErrorMessage)(_context.t0));
+                setIsAvailable(false);
+
+              case 14:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, null, [[0, 10]]);
+      }));
+
+      return function checkIsAvailable() {
+        return _ref.apply(this, arguments);
+      };
+    }();
+
+    void checkIsAvailable();
+  }, [webviewIntent, methodName]);
+  return {
+    isAvailable: isAvailable,
+    error: error
+  };
+};
+
+exports.useIsAvailable = useIsAvailable;
+
+/***/ }),
+
 /***/ "w4Eu":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
diff --git a/public/index.html b/public/index.html
index 4b03081bcb98f1af6d299b7adf297ba635bf0636..2b3debb1d7d5bee9895eebc404cb3733dcd9117b 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1 +1 @@
-<!DOCTYPE html><html lang="{{.Locale}}"><head><meta charset="utf-8"><title>Ecolyo | Désabonnement</title><link rel="icon" type="image/png" href="public/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="public/favicon-16x16.png" sizes="16x16"><!-- PWA Manifest --><link rel="mask-icon" href="public/safari-pinned-tab.svg" color="#297EF2"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,viewport-fit=cover"><!-- PWA iOS --><link rel="apple-touch-icon" sizes="180x180" href="public/apple-touch-icon.png"><link rel="apple-touch-startup-image" href="public/apple-touch-icon.png"><meta name="apple-mobile-web-app-title" content="Ecolyo"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><!-- PWA Colors --><meta name="theme-color" content="#343641"><meta name="background-color" content="#121212">{{.ThemeCSS}} {{.CozyBar}}<script src="//{{.Domain}}/assets/js/piwik.js"></script></head><body><div role="application" class="application" data-cozy="{{.CozyData}}"><script src="../public/ecolyo.fa7a0f4ba5b56c90e338.js"></script></div></body></html>
\ No newline at end of file
+<!DOCTYPE html><html lang="{{.Locale}}"><head><meta charset="utf-8"><title>Ecolyo | Désabonnement</title><link rel="icon" type="image/png" href="public/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="public/favicon-16x16.png" sizes="16x16"><!-- PWA Manifest --><link rel="mask-icon" href="public/safari-pinned-tab.svg" color="#297EF2"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,viewport-fit=cover"><!-- PWA iOS --><link rel="apple-touch-icon" sizes="180x180" href="public/apple-touch-icon.png"><link rel="apple-touch-startup-image" href="public/apple-touch-icon.png"><meta name="apple-mobile-web-app-title" content="Ecolyo"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><!-- PWA Colors --><meta name="theme-color" content="#343641"><meta name="background-color" content="#121212">{{.ThemeCSS}} {{.CozyBar}}<script src="//{{.Domain}}/assets/js/piwik.js"></script></head><body><div role="application" class="application" data-cozy="{{.CozyData}}"><script src="../public/ecolyo.297fa83f17e3216f8d1a.js"></script></div></body></html>
\ No newline at end of file
diff --git a/vendors/ecolyo.7d2dc2a8de788a437224.js b/vendors/ecolyo.0f66f88c2aa7f446186b.js
similarity index 99%
rename from vendors/ecolyo.7d2dc2a8de788a437224.js
rename to vendors/ecolyo.0f66f88c2aa7f446186b.js
index 1383031bc719a67919ec4c28b1cb97e4958a7e72..571458bed006763b5e1f831f3979113689cb0a2e 100644
--- a/vendors/ecolyo.7d2dc2a8de788a437224.js
+++ b/vendors/ecolyo.0f66f88c2aa7f446186b.js
@@ -51088,6 +51088,68 @@ function get(target, propertyKey /* , receiver */) {
 $export($export.S, 'Reflect', { get: get });
 
 
+/***/ }),
+
+/***/ "6/w4":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Minilog = __webpack_require__("aY/w");
+
+var oldEnable = Minilog.enable,
+    oldDisable = Minilog.disable,
+    isChrome = typeof navigator != 'undefined' && /chrome/i.test(navigator.userAgent),
+    isReactNative = typeof navigator != 'undefined' && navigator.product === 'ReactNative',
+    console = __webpack_require__("FRkB"); // Use a more capable logging backend if on Chrome
+
+
+Minilog.defaultBackend = isChrome || isReactNative ? console.minilog : console; // apply enable inputs from localStorage and from the URL
+
+if (typeof window != 'undefined') {
+  try {
+    Minilog.enable(JSON.parse(window.localStorage['minilogSettings']));
+  } catch (e) {// ignore
+  }
+
+  if (window.location && window.location.search) {
+    var match = RegExp('[?&]minilog=([^&]*)').exec(window.location.search);
+    match && Minilog.enable(decodeURIComponent(match[1]));
+  }
+} // Make enable also add to localStorage
+
+
+Minilog.enable = function () {
+  oldEnable.call(Minilog, true);
+
+  try {
+    window.localStorage['minilogSettings'] = JSON.stringify(true);
+  } catch (e) {// ignore
+  }
+
+  return this;
+};
+
+Minilog.disable = function () {
+  oldDisable.call(Minilog);
+
+  try {
+    delete window.localStorage.minilogSettings;
+  } catch (e) {// ignore
+  }
+
+  return this;
+};
+
+exports = module.exports = Minilog;
+exports.backends = {
+  array: __webpack_require__("It/H"),
+  browser: Minilog.defaultBackend,
+  localStorage: __webpack_require__("dBgm"),
+  jQuery: __webpack_require__("Uc0E")
+};
+
 /***/ }),
 
 /***/ "60+6":
@@ -70313,6 +70375,19 @@ Object.keys(_useWebviewIntent).forEach(function (key) {
   });
 });
 
+var _useIsAvailable = __webpack_require__("w0CX");
+
+Object.keys(_useIsAvailable).forEach(function (key) {
+  if (key === "default" || key === "__esModule") return;
+  if (key in exports && exports[key] === _useIsAvailable[key]) return;
+  Object.defineProperty(exports, key, {
+    enumerable: true,
+    get: function get() {
+      return _useIsAvailable[key];
+    }
+  });
+});
+
 /***/ }),
 
 /***/ "7zid":
@@ -119625,6 +119700,52 @@ p7v.recipientInfoValidator = {
 };
 
 
+/***/ }),
+
+/***/ "FRkB":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* eslint-disable no-console */
+var Transform = __webpack_require__("UJNO");
+
+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) {// ignore
+    }
+
+    console.log(args.join(' '));
+  }
+};
+
+logger.formatters = ['color', 'minilog'];
+logger.color = __webpack_require__("IPbC");
+logger.minilog = __webpack_require__("U0A+");
+module.exports = logger;
+
 /***/ }),
 
 /***/ "FSf8":
@@ -130288,6 +130409,24 @@ module.exports = realNames;
 "use strict";
 
 
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.isFlagshipUI = void 0;
+
+/** App's description resulting of its manifest.webapp file */
+
+/** App's mobile information. Used to describe the app scheme and its store urls */
+
+/**
+ * All the different colors are optional
+ */
+var isFlagshipUI = function isFlagshipUI(item) {
+  return typeof item === 'object' && item !== null && ('bottomBackground' in item || 'bottomOverlay' in item || 'bottomTheme' in item || 'topBackground' in item || 'topOverlay' in item || 'topTheme' in item);
+};
+
+exports.isFlagshipUI = isFlagshipUI;
+
 /***/ }),
 
 /***/ "Gq/X":
@@ -142339,6 +142478,40 @@ __webpack_require__.r(__webpack_exports__);
 const linear = t => +t;
 
 
+/***/ }),
+
+/***/ "IPbC":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* eslint-disable no-console */
+var Transform = __webpack_require__("UJNO"),
+    color = __webpack_require__("OmjS");
+
+var colors = {
+  debug: ['cyan'],
+  info: ['purple'],
+  warn: ['yellow', true],
+  error: ['red', true]
+},
+    logger = new Transform();
+
+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;
+
 /***/ }),
 
 /***/ "IQ1l":
@@ -143741,6 +143914,34 @@ __webpack_require__.r(__webpack_exports__);
 });
 
 
+/***/ }),
+
+/***/ "It/H":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO"),
+    cache = [];
+
+var logger = new Transform();
+
+logger.write = function (name, level, args) {
+  cache.push([name, level, args]);
+}; // utility functions
+
+
+logger.get = function () {
+  return cache;
+};
+
+logger.empty = function () {
+  cache = [];
+};
+
+module.exports = logger;
+
 /***/ }),
 
 /***/ "Itbq":
@@ -162483,10 +162684,12 @@ var _interopRequireDefault = __webpack_require__("jm00");
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isWebDevMode = exports.isNativeDevMode = exports.interpolate = exports.getErrorMessage = void 0;
+exports.isWebDevMode = exports.isThemeArg = exports.isNativeDevMode = exports.isFlagshipUiArgsArray = exports.interpolate = exports.getErrorMessage = void 0;
 
 var _construct2 = _interopRequireDefault(__webpack_require__("GZTL"));
 
+var _api = __webpack_require__("VXXh");
+
 var interpolate = function interpolate(str, params) {
   if (!params) return str;
   var names = Object.keys(params);
@@ -162532,6 +162735,18 @@ var getErrorMessage = function getErrorMessage(error) {
 
 exports.getErrorMessage = getErrorMessage;
 
+var isFlagshipUiArgsArray = function isFlagshipUiArgsArray(item) {
+  return Array.isArray(item) && (0, _api.isFlagshipUI)(item[0]);
+};
+
+exports.isFlagshipUiArgsArray = isFlagshipUiArgsArray;
+
+var isThemeArg = function isThemeArg(item) {
+  return typeof item === 'string';
+};
+
+exports.isThemeArg = isThemeArg;
+
 /***/ }),
 
 /***/ "LvT5":
@@ -181020,6 +181235,36 @@ mgf1.create = function(md) {
 };
 
 
+/***/ }),
+
+/***/ "OmjS":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+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;
+
 /***/ }),
 
 /***/ "OqB0":
@@ -181902,6 +182147,87 @@ function persistReducer(config, baseReducer) {
 
 /***/ }),
 
+/***/ "Oxkl":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// default filter
+var Transform = __webpack_require__("UJNO");
+
+var levelMap = {
+  debug: 1,
+  info: 2,
+  warn: 3,
+  error: 4
+};
+
+function Filter() {
+  this.enabled = true;
+  this.defaultResult = true;
+  this.clear();
+}
+
+Transform.mixin(Filter); // allow all matching, with level >= given level
+
+Filter.prototype.allow = function (name, level) {
+  this._white.push({
+    n: name,
+    l: levelMap[level]
+  });
+
+  return this;
+}; // 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;
+};
+
+function test(rule, name) {
+  // use .test for RegExps
+  return rule.n.test ? rule.n.test(name) : rule.n == name;
+}
+
+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;
+};
+
+Filter.prototype.write = function (name, level, args) {
+  if (!this.enabled || this.test(name, level)) {
+    return this.emit('item', name, level, args);
+  }
+};
+
+module.exports = Filter;
+
+/***/ }),
+
 /***/ "OyUe":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -200925,7 +201251,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
 var log = (0, _postMe.debug)('NativeService');
 
 var NativeService = /*#__PURE__*/function () {
-  function NativeService(localMethods) {
+  function NativeService(_localMethods) {
     var _this = this;
 
     var messengerService = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _api.NativeMessenger;
@@ -200933,6 +201259,9 @@ var NativeService = /*#__PURE__*/function () {
     (0, _defineProperty2.default)(this, "messengerService", void 0);
     (0, _defineProperty2.default)(this, "localMethods", void 0);
     (0, _defineProperty2.default)(this, "messengerRegister", {});
+    (0, _defineProperty2.default)(this, "updateLocalMethods", function (localMethods) {
+      _this.localMethods = localMethods;
+    });
     (0, _defineProperty2.default)(this, "getUri", function (source) {
       return new URL(source.nativeEvent.url).hostname.toLowerCase();
     });
@@ -200946,14 +201275,15 @@ var NativeService = /*#__PURE__*/function () {
     (0, _defineProperty2.default)(this, "isInitMessage", function (message) {
       return message.message === _api.strings.webviewIsRendered;
     });
-    (0, _defineProperty2.default)(this, "registerWebview", function (uri, ref) {
+    (0, _defineProperty2.default)(this, "registerWebview", function (uri, slug, ref) {
       log(_api.strings.logging.registering(uri));
       if (_this.messengerRegister[uri]) return log((0, _utils.interpolate)(_api.strings.errorRegisterWebview, {
         uri: uri
       }));
       var messenger = new _this.messengerService(ref);
       _this.messengerRegister = _objectSpread(_objectSpread({}, _this.messengerRegister), {}, (0, _defineProperty2.default)({}, uri, {
-        messenger: (0, _utils.isNativeDevMode)() ? (0, _api.DebugNativeMessenger)(messenger) : messenger
+        messenger: (0, _utils.isNativeDevMode)() ? (0, _api.DebugNativeMessenger)(messenger) : messenger,
+        slug: slug
       }));
       log(_api.strings.logging.registered(uri));
     });
@@ -200990,7 +201320,7 @@ var NativeService = /*#__PURE__*/function () {
       };
     }());
     (0, _defineProperty2.default)(this, "tryEmit", /*#__PURE__*/function () {
-      var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(event) {
+      var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(event, componentId) {
         var parsedEvent;
         return _regenerator.default.wrap(function _callee2$(_context2) {
           while (1) {
@@ -201006,21 +201336,32 @@ var NativeService = /*#__PURE__*/function () {
               case 2:
                 parsedEvent = _this.parseNativeEvent(event);
 
+                if (parsedEvent.methodName === 'setFlagshipUI' && (0, _utils.isFlagshipUiArgsArray)(parsedEvent.args)) {
+                  parsedEvent.args[0].componentId = componentId;
+                }
+
+                if (parsedEvent.methodName === 'setTheme' && Array.isArray(parsedEvent.args) && (0, _utils.isThemeArg)(parsedEvent.args[0])) {
+                  parsedEvent.args[0] = {
+                    homeTheme: parsedEvent.args[0],
+                    componentId: componentId
+                  };
+                }
+
                 if (!_this.isInitMessage(parsedEvent)) {
-                  _context2.next = 7;
+                  _context2.next = 9;
                   break;
                 }
 
-                _context2.next = 6;
+                _context2.next = 8;
                 return _this.tryInit(event);
 
-              case 6:
+              case 8:
                 return _context2.abrupt("return", _context2.sent);
 
-              case 7:
+              case 9:
                 if (_this.isPostMeMessage(parsedEvent)) _this.tryOnMessage(event, parsedEvent);
 
-              case 8:
+              case 10:
               case "end":
                 return _context2.stop();
             }
@@ -201028,7 +201369,7 @@ var NativeService = /*#__PURE__*/function () {
         }, _callee2);
       }));
 
-      return function (_x2) {
+      return function (_x2, _x3) {
         return _ref3.apply(this, arguments);
       };
     }());
@@ -201077,11 +201418,13 @@ var NativeService = /*#__PURE__*/function () {
         }, _callee3, null, [[2, 10]]);
       }));
 
-      return function (_x3) {
+      return function (_x4) {
         return _ref4.apply(this, arguments);
       };
     }());
     (0, _defineProperty2.default)(this, "tryOnMessage", function (event, message) {
+      var _message$args;
+
       var webviewUri = _this.getUri(event);
 
       var registeredWebview = _this.messengerRegister[webviewUri];
@@ -201092,6 +201435,9 @@ var NativeService = /*#__PURE__*/function () {
         }));
       }
 
+      (_message$args = message.args) === null || _message$args === void 0 ? void 0 : _message$args.unshift({
+        slug: registeredWebview.slug
+      });
       registeredWebview.messenger.onMessage(message);
     });
     (0, _defineProperty2.default)(this, "getHostname", function (uri) {
@@ -201111,15 +201457,13 @@ var NativeService = /*#__PURE__*/function () {
       return (_this$messengerRegist = _this.messengerRegister[_this.getHostname(uri)]) === null || _this$messengerRegist === void 0 ? void 0 : (_this$messengerRegist2 = _this$messengerRegist.connection) === null || _this$messengerRegist2 === void 0 ? void 0 : (_this$messengerRegist3 = _this$messengerRegist2.remoteHandle()).call.apply(_this$messengerRegist3, [methodName].concat(args));
     });
     this.messengerService = messengerService;
-    this.localMethods = localMethods;
+    this.localMethods = _localMethods;
   }
 
   (0, _createClass2.default)(NativeService, [{
     key: "isNativeEvent",
     value: function isNativeEvent(object) {
-      var _nativeEvent;
-
-      return ((_nativeEvent = object.nativeEvent) === null || _nativeEvent === void 0 ? void 0 : _nativeEvent.data) !== undefined;
+      return object.nativeEvent.data !== undefined;
     }
   }]);
   return NativeService;
@@ -207699,6 +208043,52 @@ class BrowserClient extends _sentry_core__WEBPACK_IMPORTED_MODULE_0__["BaseClien
 //# sourceMappingURL=client.js.map
 
 
+/***/ }),
+
+/***/ "U0A+":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* eslint-disable no-console */
+var Transform = __webpack_require__("UJNO"),
+    color = __webpack_require__("OmjS"),
+    colors = {
+  debug: ['gray'],
+  info: ['purple'],
+  warn: ['yellow', true],
+  error: ['red', true]
+},
+    logger = new Transform();
+
+logger.write = function (name, level, args) {
+  var fn = console.log;
+
+  if (level != 'debug' && console[level]) {
+    fn = console[level];
+  } // eslint-disable-next-line no-unused-vars
+
+
+  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));
+  }
+}; // NOP, because piping the formatted logs can only cause trouble.
+
+
+logger.pipe = function () {};
+
+module.exports = logger;
+
 /***/ }),
 
 /***/ "U2Bz":
@@ -209069,6 +209459,87 @@ exports.default = _default;
 
 /***/ }),
 
+/***/ "UJNO":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var microee = __webpack_require__("GIvT"); // Implements a subset of Node's stream.Transform - in a cross-platform manner.
+
+
+function Transform() {}
+
+microee.mixin(Transform); // 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);
+};
+
+Transform.prototype.end = function () {
+  this.emit('end');
+  this.removeAllListeners();
+};
+
+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();
+  }
+
+  s.on('item', onItem);
+  s.on('end', onEnd);
+  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;
+  });
+  return dest;
+};
+
+Transform.prototype.unpipe = function (from) {
+  this.emit('unpipe', from);
+  return this;
+};
+
+Transform.prototype.format = function () {
+  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'));
+};
+
+Transform.mixin = function (dest) {
+  var o = Transform.prototype,
+      k;
+
+  for (k in o) {
+    // eslint-disable-next-line no-prototype-builtins
+    o.hasOwnProperty(k) && (dest.prototype[k] = o[k]);
+  }
+};
+
+module.exports = Transform;
+
+/***/ }),
+
 /***/ "UJYq":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -210577,6 +211048,103 @@ __webpack_require__.r(__webpack_exports__);
 
 /***/ }),
 
+/***/ "Uc0E":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO");
+
+var cid = new Date().valueOf().toString(36);
+
+function AjaxLogger(options) {
+  this.url = options.url || '';
+  this.cache = [];
+  this.timer = null;
+  this.interval = options.interval || 30 * 1000;
+  this.enabled = true;
+  this.jQuery = window.jQuery;
+  this.extras = {};
+}
+
+Transform.mixin(AjaxLogger);
+
+AjaxLogger.prototype.write = function (name, level, args) {
+  if (!this.timer) {
+    this.init();
+  }
+
+  this.cache.push([name, level].concat(args));
+};
+
+AjaxLogger.prototype.init = function () {
+  if (!this.enabled || !this.jQuery) return;
+  var self = this;
+  this.timer = setTimeout(function () {
+    var i,
+        logs = [],
+        ajaxData,
+        url = self.url;
+    if (self.cache.length == 0) return self.init(); // Test each log line and only log the ones that are valid (e.g. don't have circular references).
+    // Slight performance hit but benefit is we log all valid lines.
+
+    for (i = 0; i < self.cache.length; i++) {
+      try {
+        JSON.stringify(self.cache[i]);
+        logs.push(self.cache[i]);
+      } catch (e) {// ignore
+      }
+    }
+
+    if (self.jQuery.isEmptyObject(self.extras)) {
+      ajaxData = JSON.stringify({
+        logs: logs
+      });
+      url = self.url + '?client_id=' + cid;
+    } else {
+      ajaxData = JSON.stringify(self.jQuery.extend({
+        logs: logs
+      }, self.extras));
+    }
+
+    self.jQuery.ajax(url, {
+      type: 'POST',
+      cache: false,
+      processData: false,
+      data: ajaxData,
+      contentType: 'application/json',
+      timeout: 10000
+    }).success(function (data) {
+      if (data.interval) {
+        self.interval = Math.max(1000, data.interval);
+      }
+    }).error(function () {
+      self.interval = 30000;
+    }).always(function () {
+      self.init();
+    });
+    self.cache = [];
+  }, this.interval);
+};
+
+AjaxLogger.prototype.end = function () {}; // wait until jQuery is defined. Useful if you don't control the load order.
+
+
+AjaxLogger.jQueryWait = function (onDone) {
+  if (typeof window !== 'undefined' && (window.jQuery || window.$)) {
+    return onDone(window.jQuery || window.$);
+  } else if (typeof window !== 'undefined') {
+    setTimeout(function () {
+      AjaxLogger.jQueryWait(onDone);
+    }, 200);
+  }
+};
+
+module.exports = AjaxLogger;
+
+/***/ }),
+
 /***/ "Uc5S":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -227799,7 +228367,7 @@ var _interopRequireDefault = __webpack_require__("jm00");
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.NativeMessenger = exports.DebugNativeMessenger = void 0;
+exports.logger = exports.NativeMessenger = exports.DebugNativeMessenger = void 0;
 
 var _createClass2 = _interopRequireDefault(__webpack_require__("Zvb3"));
 
@@ -227809,16 +228377,28 @@ var _defineProperty2 = _interopRequireDefault(__webpack_require__("J58c"));
 
 var _postMe = __webpack_require__("L5KM");
 
+var _cozyMinilog = _interopRequireDefault(__webpack_require__("6/w4"));
+
 var _api = __webpack_require__("VXXh");
 
+var logger = (0, _cozyMinilog.default)('cozy-intent');
+exports.logger = logger;
 var log = (0, _postMe.debug)('NativeMessenger');
 var NativeMessenger = /*#__PURE__*/(0, _createClass2.default)(function NativeMessenger(webviewRef) {
-  var _this = this;
+  var _this = this,
+      _webviewRef$props$sou;
 
   (0, _classCallCheck2.default)(this, NativeMessenger);
   (0, _defineProperty2.default)(this, "injectJavaScript", void 0);
   (0, _defineProperty2.default)(this, "listener", void 0);
+  (0, _defineProperty2.default)(this, "webviewUri", void 0);
   (0, _defineProperty2.default)(this, "postMessage", function (message) {
+    if (message.error) {
+      var _this$webviewUri;
+
+      logger.warn("Error during intent to ".concat((_this$webviewUri = _this.webviewUri) !== null && _this$webviewUri !== void 0 ? _this$webviewUri : 'undefined webview', " : "), JSON.stringify(message.error));
+    }
+
     try {
       var _this$injectJavaScrip;
 
@@ -227845,6 +228425,7 @@ var NativeMessenger = /*#__PURE__*/(0, _createClass2.default)(function NativeMes
     });
   });
   this.injectJavaScript = webviewRef.injectJavaScript;
+  this.webviewUri = (_webviewRef$props$sou = webviewRef.props.source.uri) !== null && _webviewRef$props$sou !== void 0 ? _webviewRef$props$sou : webviewRef.props.source.baseUrl;
 });
 exports.NativeMessenger = NativeMessenger;
 
@@ -246000,6 +246581,91 @@ exports.default = _default;
 
 /***/ }),
 
+/***/ "aY/w":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO"),
+    Filter = __webpack_require__("Oxkl");
+
+var log = new Transform(),
+    slice = Array.prototype.slice;
+
+exports = module.exports = function create(name) {
+  var o = function o() {
+    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;
+}; // filled in separately
+
+
+exports.defaultBackend = exports.defaultFormatter = null;
+
+exports.pipe = function (dest) {
+  return log.pipe(dest);
+};
+
+exports.end = exports.unpipe = exports.disable = function (from) {
+  return log.unpipe(from);
+};
+
+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
+};
+
+/***/ }),
+
 /***/ "aY11":
 /***/ (function(module, exports) {
 
@@ -267217,6 +267883,35 @@ Icon.muiName = 'Icon';
 
 /***/ }),
 
+/***/ "dBgm":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Transform = __webpack_require__("UJNO"),
+    cache = false;
+
+var logger = new Transform();
+
+logger.write = function (name, level, args) {
+  if (typeof window == 'undefined' || typeof JSON == 'undefined' || !JSON.stringify || !JSON.parse) return;
+
+  try {
+    if (!cache) {
+      cache = window.localStorage.minilog ? JSON.parse(window.localStorage.minilog) : [];
+    }
+
+    cache.push([new Date().toString(), name, level, args]);
+    window.localStorage.minilog = JSON.stringify(cache);
+  } catch (e) {// ignore
+  }
+};
+
+module.exports = logger;
+
+/***/ }),
+
 /***/ "dCuL":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -379654,24 +380349,60 @@ module.exports = __webpack_require__("WXXH") ? Object.defineProperties : functio
 "use strict";
 
 
-var _interopRequireDefault = __webpack_require__("jm00");
-
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.NativeIntentProvider = void 0;
+exports.getNativeIntentService = exports.NativeIntentProvider = void 0;
 
-var _react = _interopRequireDefault(__webpack_require__("ivGQ"));
+var _postMe = __webpack_require__("L5KM");
 
-var _view = __webpack_require__("7zRI");
+var _react = _interopRequireWildcard(__webpack_require__("ivGQ"));
 
 var _api = __webpack_require__("VXXh");
 
+var _view = __webpack_require__("7zRI");
+
+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); }
+
+function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
+var log = (0, _postMe.debug)('NativeIntentProvider');
+var nativeIntentService;
+
+var getNativeIntentService = function getNativeIntentService() {
+  if (!nativeIntentService) {
+    throw new Error('nativeIntentService has not been instantiated in a NativeIntentProvider');
+  }
+
+  return nativeIntentService;
+};
+
+exports.getNativeIntentService = getNativeIntentService;
+
+var setNativeIntentService = function setNativeIntentService(service) {
+  nativeIntentService = service;
+};
+
 var NativeIntentProvider = function NativeIntentProvider(_ref) {
   var children = _ref.children,
       localMethods = _ref.localMethods;
+  // Use useRef to hold the service instance in a way that does not trigger re-renders
+  var serviceRef = (0, _react.useRef)(null);
+
+  if (serviceRef.current === null) {
+    serviceRef.current = new _api.NativeService(localMethods);
+    setNativeIntentService(serviceRef.current);
+  }
+
+  (0, _react.useEffect)(function () {
+    var _serviceRef$current;
+
+    // Always update methods since either they've changed, or this is the first run
+    log('Updating localMethods on nativeIntentService');
+    (_serviceRef$current = serviceRef.current) === null || _serviceRef$current === void 0 ? void 0 : _serviceRef$current.updateLocalMethods(localMethods);
+  }, [localMethods]);
   return /*#__PURE__*/_react.default.createElement(_view.NativeContext.Provider, {
-    value: new _api.NativeService(localMethods)
+    value: serviceRef.current
   }, children);
 };
 
@@ -426292,6 +427023,105 @@ var CardData = function CardData(data) {
 
 /***/ }),
 
+/***/ "w0CX":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__("jm00");
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.useIsAvailable = void 0;
+
+var _regenerator = _interopRequireDefault(__webpack_require__("hJxD"));
+
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("HZZ/"));
+
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__("XkwL"));
+
+var _react = __webpack_require__("ivGQ");
+
+var _useWebviewIntent = __webpack_require__("dMYP");
+
+var _utils = __webpack_require__("Lv97");
+
+var useIsAvailable = function useIsAvailable(methodName) {
+  var webviewIntent = (0, _useWebviewIntent.useWebviewIntent)();
+
+  var _useState = (0, _react.useState)(null),
+      _useState2 = (0, _slicedToArray2.default)(_useState, 2),
+      isAvailable = _useState2[0],
+      setIsAvailable = _useState2[1];
+
+  var _useState3 = (0, _react.useState)(undefined),
+      _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
+      error = _useState4[0],
+      setError = _useState4[1];
+
+  (0, _react.useEffect)(function () {
+    if (!webviewIntent) return;
+
+    var checkIsAvailable = /*#__PURE__*/function () {
+      var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
+        var result;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.prev = 0;
+                _context.next = 3;
+                return webviewIntent.call('isAvailable', methodName);
+
+              case 3:
+                result = _context.sent;
+
+                if (!(typeof result !== 'boolean')) {
+                  _context.next = 6;
+                  break;
+                }
+
+                throw new Error("Invalid result from isAvailable method: ".concat(result));
+
+              case 6:
+                setError(undefined);
+                setIsAvailable(result);
+                _context.next = 14;
+                break;
+
+              case 10:
+                _context.prev = 10;
+                _context.t0 = _context["catch"](0);
+                setError((0, _utils.getErrorMessage)(_context.t0));
+                setIsAvailable(false);
+
+              case 14:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, null, [[0, 10]]);
+      }));
+
+      return function checkIsAvailable() {
+        return _ref.apply(this, arguments);
+      };
+    }();
+
+    void checkIsAvailable();
+  }, [webviewIntent, methodName]);
+  return {
+    isAvailable: isAvailable,
+    error: error
+  };
+};
+
+exports.useIsAvailable = useIsAvailable;
+
+/***/ }),
+
 /***/ "w0OA":
 /***/ (function(module, __webpack_exports__, __webpack_require__) {