- @*
*@
-
-
-
+
-
-
- @if (Model.AvailableCryptos.Count > 1)
- {
-
-
-
-
- @foreach (var crypto in Model.AvailableCryptos)
- {
-
-
-
- }
-
-
-
-
- }
-
-
-
-
- {{ srvModel.storeName }}
-
-
- {{ srvModel.itemDesc }}
-
-
-
-
-
- {{ srvModel.btcDue }} {{ srvModel.cryptoCode }}
-
-
-
- 1 {{ srvModel.cryptoCode }} = {{ srvModel.rate }}
-
-
-
-
-
-
-
-
-
-
-
-
-
Order Amount
-
{{srvModel.orderAmount}} {{ srvModel.cryptoCode }}
-
-
-
- Network Cost
-
-
{{srvModel.networkFeeDescription }}
-
-
-
- Already Paid
-
-
-{{srvModel.btcPaid }} {{ srvModel.cryptoCode }}
-
-
-
Due
-
{{srvModel.btcDue}} {{ srvModel.cryptoCode }}
-
-
-
-
-
-
- Scan
-
-
- Copy
-
- @if (Model.AllowCoinConversion)
- {
-
- Conversion
-
-
- }
- else
- {
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- To complete your payment, please send {{ srvModel.btcDue }} {{ srvModel.cryptoCode }} to the address below.
-
-
-
-
Amount
-
-
-
{{srvModel.btcDue}} {{ srvModel.cryptoCode }}
-
- Copied
-
-
-
-
-
-
-
-
-
-
Address
-
-
-
-
-
-
-
{{srvModel.btcAddress}}
-
-
- Copied
-
-
-
-
-
-
-
-
- @if (Model.AllowCoinConversion)
- {
-
-
-
-
- You can pay {{ srvModel.btcDue }} {{ srvModel.cryptoCode }} using altcoins other than the ones merchant directly supports.
-
- This service is provided by 3rd party. Please keep in mind that
- we have no control over how providers will forward your funds.
- Invoice will only be marked paid once funds are received on {{srvModel.cryptoCode}} Blockchain.
-
-
-
-
-
-
-
-
- @*Changelly doesn't have TO_AMOUNT support so we can't include it
-
-
-
- *@
-
-
-
-
-
- No conversion providers available for BTC Lightning Network payments.
-
-
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
This invoice has been paid.
-
-
-
- Return to {{srvModel.storeName}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The amount below will be refunded to you within 1-2 business days.
-
-
-
-
-
-
-
- Amount To Be Refunded
-
-
{BTC Amount} BTC
-
-
-
-
-
-
-
Will Be Refunded To
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
This payment was made with a low
bitcoin miner fee , which may prevent it from being accepted by the Bitcoin network.
-
This is an issue with the configuration of your bitcoin wallet.
-
- If the transaction
- doesn't confirm, the funds will be spendable again in your wallet.
- Depending on the wallet, this may take 48-72 hours.
-
-
-
-
-
-
-
-
Transaction created
-
-
-
-
-
-
- Transaction confirming — funds have not yet moved
-
-
-
-
-
Payment received by {{srvModel.storeName}}
-
-
-
-
-
-
-
-
-
-
- Return to {{srvModel.storeName}}
-
-
-
-
-
-
-
-
-
This invoice has expired. An invoice is only valid for @Model.MaxTimeMinutes minutes. You can
return to {{srvModel.storeName}}
if you would like to submit your payment again.
-
If you tried to send a payment, it has not yet been accepted by the Bitcoin network. We have not yet received your funds.
-
- If the transaction
- is not accepted by the Bitcoin network, the funds will be spendable
- again in your wallet. Depending on your wallet, this may take 48-72
- hours.
-
-
- Invoice ID: {{srvModel.invoiceId}}
-
-
- Order ID: {{srvModel.orderId}}
-
-
-
-
-
-
-
- Return to {{srvModel.storeName}}
-
-
-
-
-
-
-
-
-
-
-
-
-
- Please contact the store for order information or assistance.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Refund Complete
-
-
-
-
-
-
-
-
- Overpaid By
-
-
- Amount Refunded
-
-
-
-
{BTC amount} BTC
-
-
-
-
-
-
-
Refunded To
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Return to {{srvModel.storeName}}
-
-
-
-
-
+ @Html.Partial("Checkout-Body")
+
+ @* Not working because of nsSeparator: false, keySeparator: false,
+ {{$t("nested.lang")}} >>
+ *@
+
+ English
+ Deutsch
+ 日本語
+ Français
+ Spanish
+
+
+
diff --git a/BTCPayServer/bundleconfig.json b/BTCPayServer/bundleconfig.json
index 632689c2f..4e4a7ec0c 100644
--- a/BTCPayServer/bundleconfig.json
+++ b/BTCPayServer/bundleconfig.json
@@ -33,7 +33,8 @@
"inputFiles": [
"wwwroot/vendor/font-awesome/css/font-awesome.css",
"wwwroot/css/css.css",
- "wwwroot/css/normalizer.css"
+ "wwwroot/css/normalizer.css",
+ "wwwroot/vendor/jquery-prettydropdowns/prettydropdowns.css"
]
},
{
@@ -41,9 +42,12 @@
"inputFiles": [
"wwwroot/vendor/clipboard.js/clipboard.js",
"wwwroot/vendor/jquery/jquery.js",
- "wwwroot/js/vue.min.js",
- "wwwroot/js/vue-qrcode.js",
- "wwwroot/js/core.js"
+ "wwwroot/vendor/vuejs/vue.min.js",
+ "wwwroot/vendor/vuejs/vue-qrcode.js",
+ "wwwroot/vendor/i18next/i18next.js",
+ "wwwroot/vendor/i18next/vue-i18next.js",
+ "wwwroot/vendor/jquery-prettydropdowns/jquery.prettydropdowns.js",
+ "wwwroot/js/checkout/**/*.js"
]
}
]
diff --git a/BTCPayServer/wwwroot/js/core.js b/BTCPayServer/wwwroot/js/checkout/core.js
similarity index 96%
rename from BTCPayServer/wwwroot/js/core.js
rename to BTCPayServer/wwwroot/js/checkout/core.js
index 158d4985e..5ef377d03 100644
--- a/BTCPayServer/wwwroot/js/core.js
+++ b/BTCPayServer/wwwroot/js/checkout/core.js
@@ -1,3 +1,5 @@
+// TODO: Refactor... switch from jQuery to Vue.js
+// public methods
function resetTabsSlider() {
$("#tabsSlider").removeClass("slide-copy");
$("#tabsSlider").removeClass("slide-altcoins");
@@ -16,8 +18,11 @@ function resetTabsSlider() {
$("#altcoins").removeClass("active");
}
-// public methods
function onDataCallback(jsonData) {
+ // extender properties used
+ jsonData.shapeshiftUrl = "https://shapeshift.io/shifty.html?destination=" + jsonData.btcAddress + "&output=" + jsonData.paymentMethodId + "&amount=" + jsonData.btcDue;
+ //
+
var newStatus = jsonData.status;
if (newStatus === "complete" ||
@@ -44,7 +49,6 @@ function onDataCallback(jsonData) {
if (newStatus === "expired" || newStatus === "invalid") { //TODO: different state if the invoice is invalid (failed to confirm after timeout)
$(".timer-row").removeClass("expiring-soon");
- $(".timer-row__message span").html("Invoice expired.");
$(".timer-row__spinner").html("");
$("#emailAddressView").removeClass("active");
$(".modal-dialog").addClass("expired");
@@ -63,7 +67,6 @@ function onDataCallback(jsonData) {
$(".payment__spinner").hide();
}
- jsonData.shapeshiftUrl = "https://shapeshift.io/shifty.html?destination=" + jsonData.btcAddress + "&output=" + jsonData.paymentMethodId + "&amount=" + jsonData.btcDue;
// updating ui
checkoutCtrl.srvModel = jsonData;
}
@@ -125,7 +128,6 @@ $(document).ready(function () {
function hideEmailForm() {
- $("[role=document]").removeClass("enter-purchaser-email");
$("#emailAddressView").removeClass("active");
$("placeholder-refundEmail").html(srvModel.customerEmail);
@@ -163,6 +165,8 @@ $(document).ready(function () {
} else {
$("#emailAddressForm").addClass("ng-touched ng-dirty ng-submitted ng-invalid");
}
+
+ return false;
});
}
@@ -282,23 +286,23 @@ $(document).ready(function () {
}
function animateUpdate() {
-
var now = new Date();
var timeDiff = end.getTime() - now.getTime();
var perc = 100 - Math.round(timeDiff / timerMax * 100);
+ var status = checkoutCtrl.srvModel.status;
if (perc === 75 && (status === "paidPartial" || status === "new")) {
$(".timer-row").addClass("expiring-soon");
- $(".timer-row__message span").html("Invoice expiring soon ...");
+ checkoutCtrl.expiringSoon = true;
updateProgress(perc);
}
if (perc <= 100) {
updateProgress(perc);
setTimeout(animateUpdate, timeoutVal);
}
- if (perc >= 100 && status === "expired") {
- onDataCallback(status);
- }
+ //if (perc >= 100 && status === "expired") {
+ // onDataCallback(status);
+ //}
}
}
diff --git a/BTCPayServer/wwwroot/js/checkout/langs/de.js b/BTCPayServer/wwwroot/js/checkout/langs/de.js
new file mode 100644
index 000000000..ac3e9f98d
--- /dev/null
+++ b/BTCPayServer/wwwroot/js/checkout/langs/de.js
@@ -0,0 +1,48 @@
+const locales_de = {
+ nested: {
+ lang: 'Sprache',
+ },
+ "Awaiting Payment...": "Warten auf Zahlung...",
+ "Pay with": "Bezahlen mit",
+ "Contact and Refund Email": "Kontakt und Rückerstattungs Email",
+ "Contact_Body": "Bitte geben Sie unten eine E-Mail-Adresse an. Wir werden Sie unter dieser Adresse kontaktieren, wenn ein Problem mit Ihrer Zahlung vorliegt.",
+ "Your email": "Deine Email",
+ "Continue": "Fortsetzen",
+ "Please enter a valid email address": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
+ "Order Amount": "Bestellbetrag",
+ "Network Cost": "Netzwerkkosten",
+ "Already Paid": "Bereits bezahlt",
+ "Due": "Fällig",
+ // Tabs
+ "Scan": "Scan",
+ "Copy": "Kopieren",
+ "Conversion": "Umwandlung",
+ // Scan tab
+ "Open in wallet": "In der Brieftasche öffnen",
+ // Copy tab
+ "CompletePay_Body": "Um Ihre Zahlung abzuschließen, senden Sie bitte {{btcDue}} {{cryptoCode}} an die unten angegebene Adresse.",
+ "Amount": "Menge",
+ "Address": "Adresse",
+ "Copied": "Kopiert",
+ // Conversion tab
+ "ConversionTab_BodyTop": "Sie können {{btcDue}} {{cryptoCode}} mit altcoins bezahlen, die nicht direkt vom Händler unterstützt werden.",
+ "ConversionTab_BodyDesc": "Dieser Service wird von Drittanbietern bereitgestellt. Bitte beachten Sie, dass wir keine Kontrolle darüber haben, wie die Anbieter Ihre Gelder weiterleiten. Die Rechnung wird erst bezahlt, wenn das Geld in {{cryptoCode}} Blockchain eingegangen ist.",
+ "Shapeshift_Button_Text": "Bezahlen mit Altcoins",
+ "ConversionTab_Lightning": "Für BTC Lightning Network-Zahlungen sind keine Conversion-Anbieter verfügbar.",
+ // Invoice expired
+ "Invoice expiring soon...": "Die Rechnung läuft bald ab...",
+ "Invoice expired": "Die Rechnung ist abgelaufen",
+ "What happened?": "Was ist passiert?",
+ "InvoiceExpired_Body_1": "Diese Rechnung ist abgelaufen. Eine Rechnung ist nur für {{maxTimeMinutes}} Minuten gültig. \
+Sie können zu {{storeName}} zurückkehren, wenn Sie Ihre Zahlung erneut senden möchten.",
+ "InvoiceExpired_Body_2": "Wenn Sie versucht haben, eine Zahlung zu senden, wurde sie vom Bitcoin-Netzwerk noch nicht akzeptiert. Wir haben Ihre Gelder noch nicht erhalten.",
+ "InvoiceExpired_Body_3": "Wenn die Transaktion vom Bitcoin-Netzwerk nicht akzeptiert wird, ist das Geld wieder in Ihrer Brieftasche verfügbar. Abhängig von Ihrem Geldbeutel, kann dies 48-72 Stunden dauern.",
+ "Invoice ID": "Rechnungs ID",
+ "Order ID": "Auftrag ID",
+ "Return to StoreName": "Zurück zu {{storeName}}",
+ // Invoice paid
+ "This invoice has been paid": "Diese Rechnung wurde bezahlt",
+ // Invoice archived
+ "This invoice has been archived": "Diese Rechnung wurde archiviert",
+ "Archived_Body": "Bitte kontaktieren Sie den Shop für Bestellinformationen oder Hilfe"
+};
diff --git a/BTCPayServer/wwwroot/js/checkout/langs/en.js b/BTCPayServer/wwwroot/js/checkout/langs/en.js
new file mode 100644
index 000000000..8867b4108
--- /dev/null
+++ b/BTCPayServer/wwwroot/js/checkout/langs/en.js
@@ -0,0 +1,48 @@
+const locales_en = {
+ nested: {
+ lang: 'Language',
+ },
+ "Awaiting Payment...": "Awaiting Payment...",
+ "Pay with": "Pay with",
+ "Contact and Refund Email": "Contact & Refund Email",
+ "Contact_Body": "Please provide an email address below. We’ll contact you at this address if there is an issue with your payment.",
+ "Your email": "Your email",
+ "Continue": "Continue",
+ "Please enter a valid email address": "Please enter a valid email address",
+ "Order Amount": "Order Amount",
+ "Network Cost": "Network Cost",
+ "Already Paid": "Already Paid",
+ "Due": "Due",
+ // Tabs
+ "Scan": "Scan",
+ "Copy": "Copy",
+ "Conversion": "Conversion",
+ // Scan tab
+ "Open in wallet": "Open in wallet",
+ // Copy tab
+ "CompletePay_Body": "To complete your payment, please send {{btcDue}} {{cryptoCode}} to the address below.",
+ "Amount": "Amount",
+ "Address": "Address",
+ "Copied": "Copied",
+ // Conversion tab
+ "ConversionTab_BodyTop": "You can pay {{btcDue}} {{cryptoCode}} using altcoins other than the ones merchant directly supports.",
+ "ConversionTab_BodyDesc": "This service is provided by 3rd party. Please keep in mind that we have no control over how providers will forward your funds. Invoice will only be marked paid once funds are received on {{cryptoCode}} Blockchain.",
+ "Shapeshift_Button_Text": "Pay with Altcoins",
+ "ConversionTab_Lightning": "No conversion providers available for BTC Lightning Network payments.",
+ // Invoice expired
+ "Invoice expiring soon...": "Invoice expiring soon...",
+ "Invoice expired": "Invoice expired",
+ "What happened?": "What happened?",
+ "InvoiceExpired_Body_1": "This invoice has expired. An invoice is only valid for {{maxTimeMinutes}} minutes. \
+You can return to {{storeName}} if you would like to submit your payment again.",
+ "InvoiceExpired_Body_2": "If you tried to send a payment, it has not yet been accepted by the Bitcoin network. We have not yet received your funds.",
+ "InvoiceExpired_Body_3": "If the transaction is not accepted by the Bitcoin network, the funds will be spendable again in your wallet. Depending on your wallet, this may take 48-72 hours.",
+ "Invoice ID": "Invoice ID",
+ "Order ID": "Order ID",
+ "Return to StoreName": "Return to {{storeName}}",
+ // Invoice paid
+ "This invoice has been paid": "This invoice has been paid",
+ // Invoice archived
+ "This invoice has been archived": "This invoice has been archived",
+ "Archived_Body": "Please contact the store for order information or assistance"
+};
diff --git a/BTCPayServer/wwwroot/js/checkout/langs/es.js b/BTCPayServer/wwwroot/js/checkout/langs/es.js
new file mode 100644
index 000000000..b444542e6
--- /dev/null
+++ b/BTCPayServer/wwwroot/js/checkout/langs/es.js
@@ -0,0 +1,2 @@
+const locales_es = {
+};
diff --git a/BTCPayServer/wwwroot/js/checkout/langs/fr.js b/BTCPayServer/wwwroot/js/checkout/langs/fr.js
new file mode 100644
index 000000000..a7fcb8a43
--- /dev/null
+++ b/BTCPayServer/wwwroot/js/checkout/langs/fr.js
@@ -0,0 +1,2 @@
+const locales_fr = {
+};
diff --git a/BTCPayServer/wwwroot/js/checkout/langs/ja.js b/BTCPayServer/wwwroot/js/checkout/langs/ja.js
new file mode 100644
index 000000000..8f1290463
--- /dev/null
+++ b/BTCPayServer/wwwroot/js/checkout/langs/ja.js
@@ -0,0 +1,2 @@
+const locales_ja = {
+};
diff --git a/BTCPayServer/wwwroot/js/checkout/querystring.js b/BTCPayServer/wwwroot/js/checkout/querystring.js
new file mode 100644
index 000000000..cc911d965
--- /dev/null
+++ b/BTCPayServer/wwwroot/js/checkout/querystring.js
@@ -0,0 +1,12 @@
+var urlParams;
+(window.onpopstate = function () {
+ var match,
+ pl = /\+/g, // Regex for replacing addition symbol with a space
+ search = /([^&=]+)=?([^&]*)/g,
+ decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
+ query = window.location.search.substring(1);
+
+ urlParams = {};
+ while (match = search.exec(query))
+ urlParams[decode(match[1])] = decode(match[2]);
+})();
diff --git a/BTCPayServer/wwwroot/vendor/i18next/i18next.js b/BTCPayServer/wwwroot/vendor/i18next/i18next.js
new file mode 100644
index 000000000..75c6189e3
--- /dev/null
+++ b/BTCPayServer/wwwroot/vendor/i18next/i18next.js
@@ -0,0 +1,2122 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global.i18next = factory());
+}(this, (function () { 'use strict';
+
+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;
+};
+
+
+
+
+
+
+
+
+
+
+
+var classCallCheck = function (instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+};
+
+
+
+
+
+
+
+
+
+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 inherits = function (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 possibleConstructorReturn = function (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;
+};
+
+
+
+
+
+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 consoleLogger = {
+ type: 'logger',
+
+ log: function log(args) {
+ this._output('log', args);
+ },
+ warn: function warn(args) {
+ this._output('warn', args);
+ },
+ error: function error(args) {
+ this._output('error', args);
+ },
+ _output: function _output(type, args) {
+ if (console && console[type]) console[type].apply(console, Array.prototype.slice.call(args));
+ }
+};
+
+var Logger = function () {
+ function Logger(concreteLogger) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ classCallCheck(this, Logger);
+
+ this.init(concreteLogger, options);
+ }
+
+ Logger.prototype.init = function init(concreteLogger) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ this.prefix = options.prefix || 'i18next:';
+ this.logger = concreteLogger || consoleLogger;
+ this.options = options;
+ this.debug = options.debug === false ? false : true;
+ };
+
+ Logger.prototype.setDebug = function setDebug(bool) {
+ this.debug = bool;
+ };
+
+ Logger.prototype.log = function log() {
+ this.forward(arguments, 'log', '', true);
+ };
+
+ Logger.prototype.warn = function warn() {
+ this.forward(arguments, 'warn', '', true);
+ };
+
+ Logger.prototype.error = function error() {
+ this.forward(arguments, 'error', '');
+ };
+
+ Logger.prototype.deprecate = function deprecate() {
+ this.forward(arguments, 'warn', 'WARNING DEPRECATED: ', true);
+ };
+
+ Logger.prototype.forward = function forward(args, lvl, prefix, debugOnly) {
+ if (debugOnly && !this.debug) return;
+ if (typeof args[0] === 'string') args[0] = prefix + this.prefix + ' ' + args[0];
+ this.logger[lvl](args);
+ };
+
+ Logger.prototype.create = function create(moduleName) {
+ var sub = new Logger(this.logger, _extends({ prefix: this.prefix + ':' + moduleName + ':' }, this.options));
+
+ return sub;
+ };
+
+ // createInstance(options = {}) {
+ // return new Logger(options, callback);
+ // }
+
+ return Logger;
+}();
+
+
+
+var baseLogger = new Logger();
+
+var EventEmitter = function () {
+ function EventEmitter() {
+ classCallCheck(this, EventEmitter);
+
+ this.observers = {};
+ }
+
+ EventEmitter.prototype.on = function on(events, listener) {
+ var _this = this;
+
+ events.split(' ').forEach(function (event) {
+ _this.observers[event] = _this.observers[event] || [];
+ _this.observers[event].push(listener);
+ });
+ };
+
+ EventEmitter.prototype.off = function off(event, listener) {
+ var _this2 = this;
+
+ if (!this.observers[event]) {
+ return;
+ }
+
+ this.observers[event].forEach(function () {
+ if (!listener) {
+ delete _this2.observers[event];
+ } else {
+ var index = _this2.observers[event].indexOf(listener);
+ if (index > -1) {
+ _this2.observers[event].splice(index, 1);
+ }
+ }
+ });
+ };
+
+ EventEmitter.prototype.emit = function emit(event) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ if (this.observers[event]) {
+ var cloned = [].concat(this.observers[event]);
+ cloned.forEach(function (observer) {
+ observer.apply(undefined, args);
+ });
+ }
+
+ if (this.observers['*']) {
+ var _cloned = [].concat(this.observers['*']);
+ _cloned.forEach(function (observer) {
+ var _ref;
+
+ observer.apply(observer, (_ref = [event]).concat.apply(_ref, args));
+ });
+ }
+ };
+
+ return EventEmitter;
+}();
+
+function makeString(object) {
+ if (object == null) return '';
+ return '' + object;
+}
+
+function copy(a, s, t) {
+ a.forEach(function (m) {
+ if (s[m]) t[m] = s[m];
+ });
+}
+
+function getLastOfPath(object, path, Empty) {
+ function cleanKey(key) {
+ return key && key.indexOf('###') > -1 ? key.replace(/###/g, '.') : key;
+ }
+
+ function canNotTraverseDeeper() {
+ return !object || typeof object === 'string';
+ }
+
+ var stack = typeof path !== 'string' ? [].concat(path) : path.split('.');
+ while (stack.length > 1) {
+ if (canNotTraverseDeeper()) return {};
+
+ var key = cleanKey(stack.shift());
+ if (!object[key] && Empty) object[key] = new Empty();
+ object = object[key];
+ }
+
+ if (canNotTraverseDeeper()) return {};
+ return {
+ obj: object,
+ k: cleanKey(stack.shift())
+ };
+}
+
+function setPath(object, path, newValue) {
+ var _getLastOfPath = getLastOfPath(object, path, Object),
+ obj = _getLastOfPath.obj,
+ k = _getLastOfPath.k;
+
+ obj[k] = newValue;
+}
+
+function pushPath(object, path, newValue, concat) {
+ var _getLastOfPath2 = getLastOfPath(object, path, Object),
+ obj = _getLastOfPath2.obj,
+ k = _getLastOfPath2.k;
+
+ obj[k] = obj[k] || [];
+ if (concat) obj[k] = obj[k].concat(newValue);
+ if (!concat) obj[k].push(newValue);
+}
+
+function getPath(object, path) {
+ var _getLastOfPath3 = getLastOfPath(object, path),
+ obj = _getLastOfPath3.obj,
+ k = _getLastOfPath3.k;
+
+ if (!obj) return undefined;
+ return obj[k];
+}
+
+function deepExtend(target, source, overwrite) {
+ for (var prop in source) {
+ if (prop in target) {
+ // If we reached a leaf string in target or source then replace with source or skip depending on the 'overwrite' switch
+ if (typeof target[prop] === 'string' || target[prop] instanceof String || typeof source[prop] === 'string' || source[prop] instanceof String) {
+ if (overwrite) target[prop] = source[prop];
+ } else {
+ deepExtend(target[prop], source[prop], overwrite);
+ }
+ } else {
+ target[prop] = source[prop];
+ }
+ }return target;
+}
+
+function regexEscape(str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
+}
+
+/* eslint-disable */
+var _entityMap = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': '"',
+ "'": ''',
+ "/": '/'
+};
+/* eslint-enable */
+
+function escape(data) {
+ if (typeof data === 'string') {
+ return data.replace(/[&<>"'\/]/g, function (s) {
+ return _entityMap[s];
+ });
+ } else {
+ return data;
+ }
+}
+
+var ResourceStore = function (_EventEmitter) {
+ inherits(ResourceStore, _EventEmitter);
+
+ function ResourceStore() {
+ var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { ns: ['translation'], defaultNS: 'translation' };
+ classCallCheck(this, ResourceStore);
+
+ var _this = possibleConstructorReturn(this, _EventEmitter.call(this));
+
+ _this.data = data;
+ _this.options = options;
+ return _this;
+ }
+
+ ResourceStore.prototype.addNamespaces = function addNamespaces(ns) {
+ if (this.options.ns.indexOf(ns) < 0) {
+ this.options.ns.push(ns);
+ }
+ };
+
+ ResourceStore.prototype.removeNamespaces = function removeNamespaces(ns) {
+ var index = this.options.ns.indexOf(ns);
+ if (index > -1) {
+ this.options.ns.splice(index, 1);
+ }
+ };
+
+ ResourceStore.prototype.getResource = function getResource(lng, ns, key) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+ var keySeparator = options.keySeparator || this.options.keySeparator;
+ if (keySeparator === undefined) keySeparator = '.';
+
+ var path = [lng, ns];
+ if (key && typeof key !== 'string') path = path.concat(key);
+ if (key && typeof key === 'string') path = path.concat(keySeparator ? key.split(keySeparator) : key);
+
+ if (lng.indexOf('.') > -1) {
+ path = lng.split('.');
+ }
+
+ return getPath(this.data, path);
+ };
+
+ ResourceStore.prototype.addResource = function addResource(lng, ns, key, value) {
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : { silent: false };
+
+ var keySeparator = this.options.keySeparator;
+ if (keySeparator === undefined) keySeparator = '.';
+
+ var path = [lng, ns];
+ if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
+
+ if (lng.indexOf('.') > -1) {
+ path = lng.split('.');
+ value = ns;
+ ns = path[1];
+ }
+
+ this.addNamespaces(ns);
+
+ setPath(this.data, path, value);
+
+ if (!options.silent) this.emit('added', lng, ns, key, value);
+ };
+
+ ResourceStore.prototype.addResources = function addResources(lng, ns, resources) {
+ for (var m in resources) {
+ if (typeof resources[m] === 'string') this.addResource(lng, ns, m, resources[m], { silent: true });
+ }
+ this.emit('added', lng, ns, resources);
+ };
+
+ ResourceStore.prototype.addResourceBundle = function addResourceBundle(lng, ns, resources, deep, overwrite) {
+ var path = [lng, ns];
+ if (lng.indexOf('.') > -1) {
+ path = lng.split('.');
+ deep = resources;
+ resources = ns;
+ ns = path[1];
+ }
+
+ this.addNamespaces(ns);
+
+ var pack = getPath(this.data, path) || {};
+
+ if (deep) {
+ deepExtend(pack, resources, overwrite);
+ } else {
+ pack = _extends({}, pack, resources);
+ }
+
+ setPath(this.data, path, pack);
+
+ this.emit('added', lng, ns, resources);
+ };
+
+ ResourceStore.prototype.removeResourceBundle = function removeResourceBundle(lng, ns) {
+ if (this.hasResourceBundle(lng, ns)) {
+ delete this.data[lng][ns];
+ }
+ this.removeNamespaces(ns);
+
+ this.emit('removed', lng, ns);
+ };
+
+ ResourceStore.prototype.hasResourceBundle = function hasResourceBundle(lng, ns) {
+ return this.getResource(lng, ns) !== undefined;
+ };
+
+ ResourceStore.prototype.getResourceBundle = function getResourceBundle(lng, ns) {
+ if (!ns) ns = this.options.defaultNS;
+
+ // TODO: COMPATIBILITY remove extend in v2.1.0
+ if (this.options.compatibilityAPI === 'v1') return _extends({}, this.getResource(lng, ns));
+
+ return this.getResource(lng, ns);
+ };
+
+ ResourceStore.prototype.toJSON = function toJSON() {
+ return this.data;
+ };
+
+ return ResourceStore;
+}(EventEmitter);
+
+var postProcessor = {
+
+ processors: {},
+
+ addPostProcessor: function addPostProcessor(module) {
+ this.processors[module.name] = module;
+ },
+ handle: function handle(processors, value, key, options, translator) {
+ var _this = this;
+
+ processors.forEach(function (processor) {
+ if (_this.processors[processor]) value = _this.processors[processor].process(value, key, options, translator);
+ });
+
+ return value;
+ }
+};
+
+function convertInterpolation(options) {
+
+ options.interpolation = {
+ unescapeSuffix: 'HTML'
+ };
+
+ options.interpolation.prefix = options.interpolationPrefix || '__';
+ options.interpolation.suffix = options.interpolationSuffix || '__';
+ options.interpolation.escapeValue = options.escapeInterpolation || false;
+
+ options.interpolation.nestingPrefix = options.reusePrefix || '$t(';
+ options.interpolation.nestingSuffix = options.reuseSuffix || ')';
+
+ return options;
+}
+
+function convertAPIOptions(options) {
+ if (options.resStore) options.resources = options.resStore;
+
+ if (options.ns && options.ns.defaultNs) {
+ options.defaultNS = options.ns.defaultNs;
+ options.ns = options.ns.namespaces;
+ } else {
+ options.defaultNS = options.ns || 'translation';
+ }
+
+ if (options.fallbackToDefaultNS && options.defaultNS) options.fallbackNS = options.defaultNS;
+
+ options.saveMissing = options.sendMissing;
+ options.saveMissingTo = options.sendMissingTo || 'current';
+ options.returnNull = options.fallbackOnNull ? false : true;
+ options.returnEmptyString = options.fallbackOnEmpty ? false : true;
+ options.returnObjects = options.returnObjectTrees;
+ options.joinArrays = '\n';
+
+ options.returnedObjectHandler = options.objectTreeKeyHandler;
+ options.parseMissingKeyHandler = options.parseMissingKey;
+ options.appendNamespaceToMissingKey = true;
+
+ options.nsSeparator = options.nsseparator || ':';
+ options.keySeparator = options.keyseparator || '.';
+
+ if (options.shortcutFunction === 'sprintf') {
+ options.overloadTranslationOptionHandler = function (args) {
+ var values = [];
+
+ for (var i = 1; i < args.length; i++) {
+ values.push(args[i]);
+ }
+
+ return {
+ postProcess: 'sprintf',
+ sprintf: values
+ };
+ };
+ }
+
+ options.whitelist = options.lngWhitelist;
+ options.preload = options.preload;
+ if (options.load === 'current') options.load = 'currentOnly';
+ if (options.load === 'unspecific') options.load = 'languageOnly';
+
+ // backend
+ options.backend = options.backend || {};
+ options.backend.loadPath = options.resGetPath || 'locales/__lng__/__ns__.json';
+ options.backend.addPath = options.resPostPath || 'locales/add/__lng__/__ns__';
+ options.backend.allowMultiLoading = options.dynamicLoad;
+
+ // cache
+ options.cache = options.cache || {};
+ options.cache.prefix = 'res_';
+ options.cache.expirationTime = 7 * 24 * 60 * 60 * 1000;
+ options.cache.enabled = options.useLocalStorage ? true : false;
+
+ options = convertInterpolation(options);
+ if (options.defaultVariables) options.interpolation.defaultVariables = options.defaultVariables;
+
+ // TODO: deprecation
+ // if (options.getAsync === false) throw deprecation error
+
+ return options;
+}
+
+function convertJSONOptions(options) {
+ options = convertInterpolation(options);
+ options.joinArrays = '\n';
+
+ return options;
+}
+
+function convertTOptions(options) {
+ if (options.interpolationPrefix || options.interpolationSuffix || options.escapeInterpolation) {
+ options = convertInterpolation(options);
+ }
+
+ options.nsSeparator = options.nsseparator;
+ options.keySeparator = options.keyseparator;
+
+ options.returnObjects = options.returnObjectTrees;
+
+ return options;
+}
+
+function appendBackwardsAPI(i18n) {
+ i18n.lng = function () {
+ baseLogger.deprecate('i18next.lng() can be replaced by i18next.language for detected language or i18next.languages for languages ordered by translation lookup.');
+ return i18n.services.languageUtils.toResolveHierarchy(i18n.language)[0];
+ };
+
+ i18n.preload = function (lngs, cb) {
+ baseLogger.deprecate('i18next.preload() can be replaced with i18next.loadLanguages()');
+ i18n.loadLanguages(lngs, cb);
+ };
+
+ i18n.setLng = function (lng, options, callback) {
+ baseLogger.deprecate('i18next.setLng() can be replaced with i18next.changeLanguage() or i18next.getFixedT() to get a translation function with fixed language or namespace.');
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+ if (!options) options = {};
+
+ if (options.fixLng === true) {
+ if (callback) return callback(null, i18n.getFixedT(lng));
+ }
+
+ i18n.changeLanguage(lng, callback);
+ };
+
+ i18n.addPostProcessor = function (name, fc) {
+ baseLogger.deprecate('i18next.addPostProcessor() can be replaced by i18next.use({ type: \'postProcessor\', name: \'name\', process: fc })');
+ i18n.use({
+ type: 'postProcessor',
+ name: name,
+ process: fc
+ });
+ };
+}
+
+var Translator = function (_EventEmitter) {
+ inherits(Translator, _EventEmitter);
+
+ function Translator(services) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ classCallCheck(this, Translator);
+
+ var _this = possibleConstructorReturn(this, _EventEmitter.call(this));
+
+ copy(['resourceStore', 'languageUtils', 'pluralResolver', 'interpolator', 'backendConnector'], services, _this);
+
+ _this.options = options;
+ _this.logger = baseLogger.create('translator');
+ return _this;
+ }
+
+ Translator.prototype.changeLanguage = function changeLanguage(lng) {
+ if (lng) this.language = lng;
+ };
+
+ Translator.prototype.exists = function exists(key) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { interpolation: {} };
+
+ if (this.options.compatibilityAPI === 'v1') {
+ options = convertTOptions(options);
+ }
+
+ return this.resolve(key, options) !== undefined;
+ };
+
+ Translator.prototype.extractFromKey = function extractFromKey(key, options) {
+ var nsSeparator = options.nsSeparator || this.options.nsSeparator;
+ if (nsSeparator === undefined) nsSeparator = ':';
+ var keySeparator = options.keySeparator || this.options.keySeparator || '.';
+
+ var namespaces = options.ns || this.options.defaultNS;
+ if (nsSeparator && key.indexOf(nsSeparator) > -1) {
+ var parts = key.split(nsSeparator);
+ if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift();
+ key = parts.join(keySeparator);
+ }
+ if (typeof namespaces === 'string') namespaces = [namespaces];
+
+ return {
+ key: key,
+ namespaces: namespaces
+ };
+ };
+
+ Translator.prototype.translate = function translate(keys) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
+ options = this.options.overloadTranslationOptionHandler(arguments);
+ } else if (this.options.compatibilityAPI === 'v1') {
+ options = convertTOptions(options);
+ }
+
+ // non valid keys handling
+ if (keys === undefined || keys === null || keys === '') return '';
+ if (typeof keys === 'number') keys = String(keys);
+ if (typeof keys === 'string') keys = [keys];
+
+ // separators
+ var keySeparator = options.keySeparator || this.options.keySeparator || '.';
+
+ // get namespace(s)
+
+ var _extractFromKey = this.extractFromKey(keys[keys.length - 1], options),
+ key = _extractFromKey.key,
+ namespaces = _extractFromKey.namespaces;
+
+ var namespace = namespaces[namespaces.length - 1];
+
+ // return key on CIMode
+ var lng = options.lng || this.language;
+ var appendNamespaceToCIMode = options.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
+ if (lng && lng.toLowerCase() === 'cimode') {
+ if (appendNamespaceToCIMode) {
+ var nsSeparator = options.nsSeparator || this.options.nsSeparator;
+ return namespace + nsSeparator + key;
+ }
+
+ return key;
+ }
+
+ // resolve from store
+ var res = this.resolve(keys, options);
+
+ var resType = Object.prototype.toString.apply(res);
+ var noObject = ['[object Number]', '[object Function]', '[object RegExp]'];
+ var joinArrays = options.joinArrays !== undefined ? options.joinArrays : this.options.joinArrays;
+
+ // object
+ if (res && typeof res !== 'string' && noObject.indexOf(resType) < 0 && !(joinArrays && resType === '[object Array]')) {
+ if (!options.returnObjects && !this.options.returnObjects) {
+ this.logger.warn('accessing an object - but returnObjects options is not enabled!');
+ return this.options.returnedObjectHandler ? this.options.returnedObjectHandler(key, res, options) : 'key \'' + key + ' (' + this.language + ')\' returned an object instead of string.';
+ }
+
+ // if we got a separator we loop over children - else we just return object as is
+ // as having it set to false means no hierarchy so no lookup for nested values
+ if (options.keySeparator || this.options.keySeparator) {
+ var copy$$1 = resType === '[object Array]' ? [] : {}; // apply child translation on a copy
+
+ for (var m in res) {
+ if (res.hasOwnProperty(m)) {
+ copy$$1[m] = this.translate('' + key + keySeparator + m, _extends({}, options, { joinArrays: false, ns: namespaces }));
+ }
+ }
+ res = copy$$1;
+ }
+ }
+ // array special treatment
+ else if (joinArrays && resType === '[object Array]') {
+ res = res.join(joinArrays);
+ if (res) res = this.extendTranslation(res, key, options);
+ }
+ // string, empty or null
+ else {
+ var usedDefault = false,
+ usedKey = false;
+
+ // fallback value
+ if (!this.isValidLookup(res) && options.defaultValue !== undefined) {
+ usedDefault = true;
+ res = options.defaultValue;
+ }
+ if (!this.isValidLookup(res)) {
+ usedKey = true;
+ res = key;
+ }
+
+ // save missing
+ if (usedKey || usedDefault) {
+ this.logger.log('missingKey', lng, namespace, key, res);
+
+ var lngs = [];
+ var fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, options.lng || this.language);
+ if (this.options.saveMissingTo === 'fallback' && fallbackLngs && fallbackLngs[0]) {
+ for (var i = 0; i < fallbackLngs.length; i++) {
+ lngs.push(fallbackLngs[i]);
+ }
+ } else if (this.options.saveMissingTo === 'all') {
+ lngs = this.languageUtils.toResolveHierarchy(options.lng || this.language);
+ } else {
+ //(this.options.saveMissingTo === 'current' || (this.options.saveMissingTo === 'fallback' && this.options.fallbackLng[0] === false) ) {
+ lngs.push(options.lng || this.language);
+ }
+
+ if (this.options.saveMissing) {
+ if (this.options.missingKeyHandler) {
+ this.options.missingKeyHandler(lngs, namespace, key, res);
+ } else if (this.backendConnector && this.backendConnector.saveMissing) {
+ this.backendConnector.saveMissing(lngs, namespace, key, res);
+ }
+ }
+
+ this.emit('missingKey', lngs, namespace, key, res);
+ }
+
+ // extend
+ res = this.extendTranslation(res, key, options);
+
+ // append namespace if still key
+ if (usedKey && res === key && this.options.appendNamespaceToMissingKey) res = namespace + ':' + key;
+
+ // parseMissingKeyHandler
+ if (usedKey && this.options.parseMissingKeyHandler) res = this.options.parseMissingKeyHandler(res);
+ }
+
+ // return
+ return res;
+ };
+
+ Translator.prototype.extendTranslation = function extendTranslation(res, key, options) {
+ var _this2 = this;
+
+ if (options.interpolation) this.interpolator.init(_extends({}, options, { interpolation: _extends({}, this.options.interpolation, options.interpolation) }));
+
+ // interpolate
+ var data = options.replace && typeof options.replace !== 'string' ? options.replace : options;
+ if (this.options.interpolation.defaultVariables) data = _extends({}, this.options.interpolation.defaultVariables, data);
+ res = this.interpolator.interpolate(res, data, this.language);
+
+ // nesting
+ res = this.interpolator.nest(res, function () {
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ return _this2.translate.apply(_this2, args);
+ }, options);
+
+ if (options.interpolation) this.interpolator.reset();
+
+ // post process
+ var postProcess = options.postProcess || this.options.postProcess;
+ var postProcessorNames = typeof postProcess === 'string' ? [postProcess] : postProcess;
+
+ if (res !== undefined && postProcessorNames && postProcessorNames.length && options.applyPostProcessor !== false) {
+ res = postProcessor.handle(postProcessorNames, res, key, options, this);
+ }
+
+ return res;
+ };
+
+ Translator.prototype.resolve = function resolve(keys) {
+ var _this3 = this;
+
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ var found = void 0;
+
+ if (typeof keys === 'string') keys = [keys];
+
+ // forEach possible key
+ keys.forEach(function (k) {
+ if (_this3.isValidLookup(found)) return;
+
+ var _extractFromKey2 = _this3.extractFromKey(k, options),
+ key = _extractFromKey2.key,
+ namespaces = _extractFromKey2.namespaces;
+
+ if (_this3.options.fallbackNS) namespaces = namespaces.concat(_this3.options.fallbackNS);
+
+ var needsPluralHandling = options.count !== undefined && typeof options.count !== 'string';
+ var needsContextHandling = options.context !== undefined && typeof options.context === 'string' && options.context !== '';
+
+ var codes = options.lngs ? options.lngs : _this3.languageUtils.toResolveHierarchy(options.lng || _this3.language);
+
+ namespaces.forEach(function (ns) {
+ if (_this3.isValidLookup(found)) return;
+
+ codes.forEach(function (code) {
+ if (_this3.isValidLookup(found)) return;
+
+ var finalKey = key;
+ var finalKeys = [finalKey];
+
+ var pluralSuffix = void 0;
+ if (needsPluralHandling) pluralSuffix = _this3.pluralResolver.getSuffix(code, options.count);
+
+ // fallback for plural if context not found
+ if (needsPluralHandling && needsContextHandling) finalKeys.push(finalKey + pluralSuffix);
+
+ // get key for context if needed
+ if (needsContextHandling) finalKeys.push(finalKey += '' + _this3.options.contextSeparator + options.context);
+
+ // get key for plural if needed
+ if (needsPluralHandling) finalKeys.push(finalKey += pluralSuffix);
+
+ // iterate over finalKeys starting with most specific pluralkey (-> contextkey only) -> singularkey only
+ var possibleKey = void 0;
+ while (possibleKey = finalKeys.pop()) {
+ if (_this3.isValidLookup(found)) continue;
+ found = _this3.getResource(code, ns, possibleKey, options);
+ }
+ });
+ });
+ });
+
+ return found;
+ };
+
+ Translator.prototype.isValidLookup = function isValidLookup(res) {
+ return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === '');
+ };
+
+ Translator.prototype.getResource = function getResource(code, ns, key) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+ return this.resourceStore.getResource(code, ns, key, options);
+ };
+
+ return Translator;
+}(EventEmitter);
+
+function capitalize(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+}
+
+var LanguageUtil = function () {
+ function LanguageUtil(options) {
+ classCallCheck(this, LanguageUtil);
+
+ this.options = options;
+
+ this.whitelist = this.options.whitelist || false;
+ this.logger = baseLogger.create('languageUtils');
+ }
+
+ LanguageUtil.prototype.getScriptPartFromCode = function getScriptPartFromCode(code) {
+ if (!code || code.indexOf('-') < 0) return null;
+
+ var p = code.split('-');
+ if (p.length === 2) return null;
+ p.pop();
+ return this.formatLanguageCode(p.join('-'));
+ };
+
+ LanguageUtil.prototype.getLanguagePartFromCode = function getLanguagePartFromCode(code) {
+ if (!code || code.indexOf('-') < 0) return code;
+
+ var p = code.split('-');
+ return this.formatLanguageCode(p[0]);
+ };
+
+ LanguageUtil.prototype.formatLanguageCode = function formatLanguageCode(code) {
+ // http://www.iana.org/assignments/language-tags/language-tags.xhtml
+ if (typeof code === 'string' && code.indexOf('-') > -1) {
+ var specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab'];
+ var p = code.split('-');
+
+ if (this.options.lowerCaseLng) {
+ p = p.map(function (part) {
+ return part.toLowerCase();
+ });
+ } else if (p.length === 2) {
+ p[0] = p[0].toLowerCase();
+ p[1] = p[1].toUpperCase();
+
+ if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
+ } else if (p.length === 3) {
+ p[0] = p[0].toLowerCase();
+
+ // if lenght 2 guess it's a country
+ if (p[1].length === 2) p[1] = p[1].toUpperCase();
+ if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase();
+
+ if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase());
+ if (specialCases.indexOf(p[2].toLowerCase()) > -1) p[2] = capitalize(p[2].toLowerCase());
+ }
+
+ return p.join('-');
+ } else {
+ return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code;
+ }
+ };
+
+ LanguageUtil.prototype.isWhitelisted = function isWhitelisted(code) {
+ if (this.options.load === 'languageOnly' || this.options.nonExplicitWhitelist) {
+ code = this.getLanguagePartFromCode(code);
+ }
+ return !this.whitelist || !this.whitelist.length || this.whitelist.indexOf(code) > -1;
+ };
+
+ LanguageUtil.prototype.getFallbackCodes = function getFallbackCodes(fallbacks, code) {
+ if (!fallbacks) return [];
+ if (typeof fallbacks === 'string') fallbacks = [fallbacks];
+ if (Object.prototype.toString.apply(fallbacks) === '[object Array]') return fallbacks;
+
+ if (!code) return fallbacks.default || [];
+
+ // asume we have an object defining fallbacks
+ var found = fallbacks[code];
+ if (!found) found = fallbacks[this.getScriptPartFromCode(code)];
+ if (!found) found = fallbacks[this.formatLanguageCode(code)];
+ if (!found) found = fallbacks.default;
+
+ return found || [];
+ };
+
+ LanguageUtil.prototype.toResolveHierarchy = function toResolveHierarchy(code, fallbackCode) {
+ var _this = this;
+
+ var fallbackCodes = this.getFallbackCodes(fallbackCode || this.options.fallbackLng || [], code);
+
+ var codes = [];
+ var addCode = function addCode(code) {
+ if (!code) return;
+ if (_this.isWhitelisted(code)) {
+ codes.push(code);
+ } else {
+ _this.logger.warn('rejecting non-whitelisted language code: ' + code);
+ }
+ };
+
+ if (typeof code === 'string' && code.indexOf('-') > -1) {
+ if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code));
+ if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code));
+ if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code));
+ } else if (typeof code === 'string') {
+ addCode(this.formatLanguageCode(code));
+ }
+
+ fallbackCodes.forEach(function (fc) {
+ if (codes.indexOf(fc) < 0) addCode(_this.formatLanguageCode(fc));
+ });
+
+ return codes;
+ };
+
+ return LanguageUtil;
+}();
+
+// definition http://translate.sourceforge.net/wiki/l10n/pluralforms
+/* eslint-disable */
+var sets = [{ lngs: ['ach', 'ak', 'am', 'arn', 'br', 'fil', 'gun', 'ln', 'mfe', 'mg', 'mi', 'oc', 'tg', 'ti', 'tr', 'uz', 'wa'], nr: [1, 2], fc: 1 }, { lngs: ['af', 'an', 'ast', 'az', 'bg', 'bn', 'ca', 'da', 'de', 'dev', 'el', 'en', 'eo', 'es', 'es_ar', 'et', 'eu', 'fi', 'fo', 'fur', 'fy', 'gl', 'gu', 'ha', 'he', 'hi', 'hu', 'hy', 'ia', 'it', 'kn', 'ku', 'lb', 'mai', 'ml', 'mn', 'mr', 'nah', 'nap', 'nb', 'ne', 'nl', 'nn', 'no', 'nso', 'pa', 'pap', 'pms', 'ps', 'pt', 'pt_br', 'rm', 'sco', 'se', 'si', 'so', 'son', 'sq', 'sv', 'sw', 'ta', 'te', 'tk', 'ur', 'yo'], nr: [1, 2], fc: 2 }, { lngs: ['ay', 'bo', 'cgg', 'fa', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky', 'lo', 'ms', 'sah', 'su', 'th', 'tt', 'ug', 'vi', 'wo', 'zh'], nr: [1], fc: 3 }, { lngs: ['be', 'bs', 'dz', 'hr', 'ru', 'sr', 'uk'], nr: [1, 2, 5], fc: 4 }, { lngs: ['ar'], nr: [0, 1, 2, 3, 11, 100], fc: 5 }, { lngs: ['cs', 'sk'], nr: [1, 2, 5], fc: 6 }, { lngs: ['csb', 'pl'], nr: [1, 2, 5], fc: 7 }, { lngs: ['cy'], nr: [1, 2, 3, 8], fc: 8 }, { lngs: ['fr'], nr: [1, 2], fc: 9 }, { lngs: ['ga'], nr: [1, 2, 3, 7, 11], fc: 10 }, { lngs: ['gd'], nr: [1, 2, 3, 20], fc: 11 }, { lngs: ['is'], nr: [1, 2], fc: 12 }, { lngs: ['jv'], nr: [0, 1], fc: 13 }, { lngs: ['kw'], nr: [1, 2, 3, 4], fc: 14 }, { lngs: ['lt'], nr: [1, 2, 10], fc: 15 }, { lngs: ['lv'], nr: [1, 2, 0], fc: 16 }, { lngs: ['mk'], nr: [1, 2], fc: 17 }, { lngs: ['mnk'], nr: [0, 1, 2], fc: 18 }, { lngs: ['mt'], nr: [1, 2, 11, 20], fc: 19 }, { lngs: ['or'], nr: [2, 1], fc: 2 }, { lngs: ['ro'], nr: [1, 2, 20], fc: 20 }, { lngs: ['sl'], nr: [5, 1, 2, 3], fc: 21 }];
+
+var _rulesPluralsTypes = {
+ 1: function _(n) {
+ return Number(n > 1);
+ },
+ 2: function _(n) {
+ return Number(n != 1);
+ },
+ 3: function _(n) {
+ return 0;
+ },
+ 4: function _(n) {
+ return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
+ },
+ 5: function _(n) {
+ return Number(n === 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5);
+ },
+ 6: function _(n) {
+ return Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2);
+ },
+ 7: function _(n) {
+ return Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
+ },
+ 8: function _(n) {
+ return Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3);
+ },
+ 9: function _(n) {
+ return Number(n >= 2);
+ },
+ 10: function _(n) {
+ return Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4);
+ },
+ 11: function _(n) {
+ return Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3);
+ },
+ 12: function _(n) {
+ return Number(n % 10 != 1 || n % 100 == 11);
+ },
+ 13: function _(n) {
+ return Number(n !== 0);
+ },
+ 14: function _(n) {
+ return Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3);
+ },
+ 15: function _(n) {
+ return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
+ },
+ 16: function _(n) {
+ return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2);
+ },
+ 17: function _(n) {
+ return Number(n == 1 || n % 10 == 1 ? 0 : 1);
+ },
+ 18: function _(n) {
+ return Number(n == 0 ? 0 : n == 1 ? 1 : 2);
+ },
+ 19: function _(n) {
+ return Number(n == 1 ? 0 : n === 0 || n % 100 > 1 && n % 100 < 11 ? 1 : n % 100 > 10 && n % 100 < 20 ? 2 : 3);
+ },
+ 20: function _(n) {
+ return Number(n == 1 ? 0 : n === 0 || n % 100 > 0 && n % 100 < 20 ? 1 : 2);
+ },
+ 21: function _(n) {
+ return Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0);
+ }
+};
+/* eslint-enable */
+
+function createRules() {
+ var l,
+ rules = {};
+ sets.forEach(function (set$$1) {
+ set$$1.lngs.forEach(function (l) {
+ return rules[l] = {
+ numbers: set$$1.nr,
+ plurals: _rulesPluralsTypes[set$$1.fc]
+ };
+ });
+ });
+ return rules;
+}
+
+var PluralResolver = function () {
+ function PluralResolver(languageUtils) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ classCallCheck(this, PluralResolver);
+
+ this.languageUtils = languageUtils;
+ this.options = options;
+
+ this.logger = baseLogger.create('pluralResolver');
+
+ this.rules = createRules();
+ }
+
+ PluralResolver.prototype.addRule = function addRule(lng, obj) {
+ this.rules[lng] = obj;
+ };
+
+ PluralResolver.prototype.getRule = function getRule(code) {
+ return this.rules[this.languageUtils.getLanguagePartFromCode(code)];
+ };
+
+ PluralResolver.prototype.needsPlural = function needsPlural(code) {
+ var rule = this.getRule(code);
+
+ return rule && rule.numbers.length <= 1 ? false : true;
+ };
+
+ PluralResolver.prototype.getSuffix = function getSuffix(code, count) {
+ var _this = this;
+
+ var rule = this.getRule(code);
+
+ if (rule) {
+ if (rule.numbers.length === 1) return ''; // only singular
+
+ var idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count));
+ var suffix = rule.numbers[idx];
+
+ // special treatment for lngs only having singular and plural
+ if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
+ if (suffix === 2) {
+ suffix = 'plural';
+ } else if (suffix === 1) {
+ suffix = '';
+ }
+ }
+
+ var returnSuffix = function returnSuffix() {
+ return _this.options.prepend && suffix.toString() ? _this.options.prepend + suffix.toString() : suffix.toString();
+ };
+
+ // COMPATIBILITY JSON
+ // v1
+ if (this.options.compatibilityJSON === 'v1') {
+ if (suffix === 1) return '';
+ if (typeof suffix === 'number') return '_plural_' + suffix.toString();
+ return returnSuffix();
+ }
+ // v2
+ else if (this.options.compatibilityJSON === 'v2' || rule.numbers.length === 2 && rule.numbers[0] === 1) {
+ return returnSuffix();
+ }
+ // v3 - gettext index
+ else if (rule.numbers.length === 2 && rule.numbers[0] === 1) {
+ return returnSuffix();
+ }
+ return this.options.prepend && idx.toString() ? this.options.prepend + idx.toString() : idx.toString();
+ } else {
+ this.logger.warn('no plural rule found for: ' + code);
+ return '';
+ }
+ };
+
+ return PluralResolver;
+}();
+
+var Interpolator = function () {
+ function Interpolator() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ classCallCheck(this, Interpolator);
+
+ this.logger = baseLogger.create('interpolator');
+
+ this.init(options, true);
+ }
+
+ Interpolator.prototype.init = function init() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var reset = arguments[1];
+
+ if (reset) {
+ this.options = options;
+ this.format = options.interpolation && options.interpolation.format || function (value) {
+ return value;
+ };
+ this.escape = options.interpolation && options.interpolation.escape || escape;
+ }
+ if (!options.interpolation) options.interpolation = { escapeValue: true };
+
+ var iOpts = options.interpolation;
+
+ this.escapeValue = iOpts.escapeValue !== undefined ? iOpts.escapeValue : true;
+
+ this.prefix = iOpts.prefix ? regexEscape(iOpts.prefix) : iOpts.prefixEscaped || '{{';
+ this.suffix = iOpts.suffix ? regexEscape(iOpts.suffix) : iOpts.suffixEscaped || '}}';
+
+ this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ',';
+
+ this.unescapePrefix = iOpts.unescapeSuffix ? '' : iOpts.unescapePrefix || '-';
+ this.unescapeSuffix = this.unescapePrefix ? '' : iOpts.unescapeSuffix || '';
+
+ this.nestingPrefix = iOpts.nestingPrefix ? regexEscape(iOpts.nestingPrefix) : iOpts.nestingPrefixEscaped || regexEscape('$t(');
+ this.nestingSuffix = iOpts.nestingSuffix ? regexEscape(iOpts.nestingSuffix) : iOpts.nestingSuffixEscaped || regexEscape(')');
+
+ // the regexp
+ this.resetRegExp();
+ };
+
+ Interpolator.prototype.reset = function reset() {
+ if (this.options) this.init(this.options);
+ };
+
+ Interpolator.prototype.resetRegExp = function resetRegExp() {
+ // the regexp
+ var regexpStr = this.prefix + '(.+?)' + this.suffix;
+ this.regexp = new RegExp(regexpStr, 'g');
+
+ var regexpUnescapeStr = this.prefix + this.unescapePrefix + '(.+?)' + this.unescapeSuffix + this.suffix;
+ this.regexpUnescape = new RegExp(regexpUnescapeStr, 'g');
+
+ var nestingRegexpStr = this.nestingPrefix + '(.+?)' + this.nestingSuffix;
+ this.nestingRegexp = new RegExp(nestingRegexpStr, 'g');
+ };
+
+ Interpolator.prototype.interpolate = function interpolate(str, data, lng) {
+ var _this = this;
+
+ var match = void 0,
+ value = void 0;
+
+ function regexSafe(val) {
+ return val.replace(/\$/g, '$$$$');
+ }
+
+ var handleFormat = function handleFormat(key) {
+ if (key.indexOf(_this.formatSeparator) < 0) return getPath(data, key);
+
+ var p = key.split(_this.formatSeparator);
+ var k = p.shift().trim();
+ var f = p.join(_this.formatSeparator).trim();
+
+ return _this.format(getPath(data, k), f, lng);
+ };
+
+ this.resetRegExp();
+
+ // unescape if has unescapePrefix/Suffix
+ while (match = this.regexpUnescape.exec(str)) {
+ var _value = handleFormat(match[1].trim());
+ str = str.replace(match[0], _value);
+ this.regexpUnescape.lastIndex = 0;
+ }
+
+ // regular escape on demand
+ while (match = this.regexp.exec(str)) {
+ value = handleFormat(match[1].trim());
+ if (typeof value !== 'string') value = makeString(value);
+ if (!value) {
+ this.logger.warn('missed to pass in variable ' + match[1] + ' for interpolating ' + str);
+ value = '';
+ }
+ value = this.escapeValue ? regexSafe(this.escape(value)) : regexSafe(value);
+ str = str.replace(match[0], value);
+ this.regexp.lastIndex = 0;
+ }
+ return str;
+ };
+
+ Interpolator.prototype.nest = function nest(str, fc) {
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+
+ var match = void 0,
+ value = void 0;
+
+ var clonedOptions = _extends({}, options);
+ clonedOptions.applyPostProcessor = false; // avoid post processing on nested lookup
+
+ function handleHasOptions(key) {
+ if (key.indexOf(',') < 0) return key;
+
+ var p = key.split(',');
+ key = p.shift();
+ var optionsString = p.join(',');
+ optionsString = this.interpolate(optionsString, clonedOptions);
+ optionsString = optionsString.replace(/'/g, '"');
+
+ try {
+ clonedOptions = JSON.parse(optionsString);
+ } catch (e) {
+ this.logger.error('failed parsing options string in nesting for key ' + key, e);
+ }
+
+ return key;
+ }
+
+ // regular escape on demand
+ while (match = this.nestingRegexp.exec(str)) {
+ value = fc(handleHasOptions.call(this, match[1].trim()), clonedOptions);
+ if (typeof value !== 'string') value = makeString(value);
+ if (!value) {
+ this.logger.warn('missed to pass in variable ' + match[1] + ' for interpolating ' + str);
+ value = '';
+ }
+ // Nested keys should not be escaped by default #854
+ // value = this.escapeValue ? regexSafe(utils.escape(value)) : regexSafe(value);
+ str = str.replace(match[0], value);
+ this.regexp.lastIndex = 0;
+ }
+ return str;
+ };
+
+ return Interpolator;
+}();
+
+function remove(arr, what) {
+ var found = arr.indexOf(what);
+
+ while (found !== -1) {
+ arr.splice(found, 1);
+ found = arr.indexOf(what);
+ }
+}
+
+var Connector = function (_EventEmitter) {
+ inherits(Connector, _EventEmitter);
+
+ function Connector(backend, store, services) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+ classCallCheck(this, Connector);
+
+ var _this = possibleConstructorReturn(this, _EventEmitter.call(this));
+
+ _this.backend = backend;
+ _this.store = store;
+ _this.services = services;
+ _this.options = options;
+ _this.logger = baseLogger.create('backendConnector');
+
+ _this.state = {};
+ _this.queue = [];
+
+ _this.backend && _this.backend.init && _this.backend.init(services, options.backend, options);
+ return _this;
+ }
+
+ Connector.prototype.queueLoad = function queueLoad(languages, namespaces, callback) {
+ var _this2 = this;
+
+ // find what needs to be loaded
+ var toLoad = [],
+ pending = [],
+ toLoadLanguages = [],
+ toLoadNamespaces = [];
+
+ languages.forEach(function (lng) {
+ var hasAllNamespaces = true;
+
+ namespaces.forEach(function (ns) {
+ var name = lng + '|' + ns;
+
+ if (_this2.store.hasResourceBundle(lng, ns)) {
+ _this2.state[name] = 2; // loaded
+ } else if (_this2.state[name] < 0) {
+ // nothing to do for err
+ } else if (_this2.state[name] === 1) {
+ if (pending.indexOf(name) < 0) pending.push(name);
+ } else {
+ _this2.state[name] = 1; // pending
+
+ hasAllNamespaces = false;
+
+ if (pending.indexOf(name) < 0) pending.push(name);
+ if (toLoad.indexOf(name) < 0) toLoad.push(name);
+ if (toLoadNamespaces.indexOf(ns) < 0) toLoadNamespaces.push(ns);
+ }
+ });
+
+ if (!hasAllNamespaces) toLoadLanguages.push(lng);
+ });
+
+ if (toLoad.length || pending.length) {
+ this.queue.push({
+ pending: pending,
+ loaded: {},
+ errors: [],
+ callback: callback
+ });
+ }
+
+ return {
+ toLoad: toLoad,
+ pending: pending,
+ toLoadLanguages: toLoadLanguages,
+ toLoadNamespaces: toLoadNamespaces
+ };
+ };
+
+ Connector.prototype.loaded = function loaded(name, err, data) {
+ var _this3 = this;
+
+ var _name$split = name.split('|'),
+ _name$split2 = slicedToArray(_name$split, 2),
+ lng = _name$split2[0],
+ ns = _name$split2[1];
+
+ if (err) this.emit('failedLoading', lng, ns, err);
+
+ if (data) {
+ this.store.addResourceBundle(lng, ns, data);
+ }
+
+ // set loaded
+ this.state[name] = err ? -1 : 2;
+ // callback if ready
+ this.queue.forEach(function (q) {
+ pushPath(q.loaded, [lng], ns);
+ remove(q.pending, name);
+
+ if (err) q.errors.push(err);
+
+ if (q.pending.length === 0 && !q.done) {
+ _this3.emit('loaded', q.loaded);
+ q.errors.length ? q.callback(q.errors) : q.callback();
+ q.done = true;
+ }
+ });
+
+ // remove done load requests
+ this.queue = this.queue.filter(function (q) {
+ return !q.done;
+ });
+ };
+
+ Connector.prototype.read = function read(lng, ns, fcName, tried, wait, callback) {
+ var _this4 = this;
+
+ if (!tried) tried = 0;
+ if (!wait) wait = 250;
+
+ if (!lng.length) return callback(null, {}); // noting to load
+
+ this.backend[fcName](lng, ns, function (err, data) {
+ if (err && data /* = retryFlag */ && tried < 5) {
+ setTimeout(function () {
+ _this4.read.call(_this4, lng, ns, fcName, ++tried, wait * 2, callback);
+ }, wait);
+ return;
+ }
+ callback(err, data);
+ });
+ };
+
+ Connector.prototype.load = function load(languages, namespaces, callback) {
+ var _this5 = this;
+
+ if (!this.backend) {
+ this.logger.warn('No backend was added via i18next.use. Will not load resources.');
+ return callback && callback();
+ }
+ var options = _extends({}, this.backend.options, this.options.backend);
+
+ if (typeof languages === 'string') languages = this.services.languageUtils.toResolveHierarchy(languages);
+ if (typeof namespaces === 'string') namespaces = [namespaces];
+
+ var toLoad = this.queueLoad(languages, namespaces, callback);
+ if (!toLoad.toLoad.length) {
+ if (!toLoad.pending.length) callback(); // nothing to load and no pendings...callback now
+ return; // pendings will trigger callback
+ }
+
+ // load with multi-load
+ if (options.allowMultiLoading && this.backend.readMulti) {
+ this.read(toLoad.toLoadLanguages, toLoad.toLoadNamespaces, 'readMulti', null, null, function (err, data) {
+ if (err) _this5.logger.warn('loading namespaces ' + toLoad.toLoadNamespaces.join(', ') + ' for languages ' + toLoad.toLoadLanguages.join(', ') + ' via multiloading failed', err);
+ if (!err && data) _this5.logger.log('loaded namespaces ' + toLoad.toLoadNamespaces.join(', ') + ' for languages ' + toLoad.toLoadLanguages.join(', ') + ' via multiloading', data);
+
+ toLoad.toLoad.forEach(function (name) {
+ var _name$split3 = name.split('|'),
+ _name$split4 = slicedToArray(_name$split3, 2),
+ l = _name$split4[0],
+ n = _name$split4[1];
+
+ var bundle = getPath(data, [l, n]);
+ if (bundle) {
+ _this5.loaded(name, err, bundle);
+ } else {
+ var _err = 'loading namespace ' + n + ' for language ' + l + ' via multiloading failed';
+ _this5.loaded(name, _err);
+ _this5.logger.error(_err);
+ }
+ });
+ });
+ }
+
+ // load one by one
+ else {
+ var readOne = function readOne(name) {
+ var _this6 = this;
+
+ var _name$split5 = name.split('|'),
+ _name$split6 = slicedToArray(_name$split5, 2),
+ lng = _name$split6[0],
+ ns = _name$split6[1];
+
+ this.read(lng, ns, 'read', null, null, function (err, data) {
+ if (err) _this6.logger.warn('loading namespace ' + ns + ' for language ' + lng + ' failed', err);
+ if (!err && data) _this6.logger.log('loaded namespace ' + ns + ' for language ' + lng, data);
+
+ _this6.loaded(name, err, data);
+ });
+ };
+
+
+
+ toLoad.toLoad.forEach(function (name) {
+ readOne.call(_this5, name);
+ });
+ }
+ };
+
+ Connector.prototype.reload = function reload(languages, namespaces) {
+ var _this7 = this;
+
+ if (!this.backend) {
+ this.logger.warn('No backend was added via i18next.use. Will not load resources.');
+ }
+ var options = _extends({}, this.backend.options, this.options.backend);
+
+ if (typeof languages === 'string') languages = this.services.languageUtils.toResolveHierarchy(languages);
+ if (typeof namespaces === 'string') namespaces = [namespaces];
+
+ // load with multi-load
+ if (options.allowMultiLoading && this.backend.readMulti) {
+ this.read(languages, namespaces, 'readMulti', null, null, function (err, data) {
+ if (err) _this7.logger.warn('reloading namespaces ' + namespaces.join(', ') + ' for languages ' + languages.join(', ') + ' via multiloading failed', err);
+ if (!err && data) _this7.logger.log('reloaded namespaces ' + namespaces.join(', ') + ' for languages ' + languages.join(', ') + ' via multiloading', data);
+
+ languages.forEach(function (l) {
+ namespaces.forEach(function (n) {
+ var bundle = getPath(data, [l, n]);
+ if (bundle) {
+ _this7.loaded(l + '|' + n, err, bundle);
+ } else {
+ var _err2 = 'reloading namespace ' + n + ' for language ' + l + ' via multiloading failed';
+ _this7.loaded(l + '|' + n, _err2);
+ _this7.logger.error(_err2);
+ }
+ });
+ });
+ });
+ }
+
+ // load one by one
+ else {
+ var readOne = function readOne(name) {
+ var _this8 = this;
+
+ var _name$split7 = name.split('|'),
+ _name$split8 = slicedToArray(_name$split7, 2),
+ lng = _name$split8[0],
+ ns = _name$split8[1];
+
+ this.read(lng, ns, 'read', null, null, function (err, data) {
+ if (err) _this8.logger.warn('reloading namespace ' + ns + ' for language ' + lng + ' failed', err);
+ if (!err && data) _this8.logger.log('reloaded namespace ' + ns + ' for language ' + lng, data);
+
+ _this8.loaded(name, err, data);
+ });
+ };
+
+
+
+ languages.forEach(function (l) {
+ namespaces.forEach(function (n) {
+ readOne.call(_this7, l + '|' + n);
+ });
+ });
+ }
+ };
+
+ Connector.prototype.saveMissing = function saveMissing(languages, namespace, key, fallbackValue) {
+ if (this.backend && this.backend.create) this.backend.create(languages, namespace, key, fallbackValue);
+
+ // write to store to avoid resending
+ if (!languages || !languages[0]) return;
+ this.store.addResource(languages[0], namespace, key, fallbackValue);
+ };
+
+ return Connector;
+}(EventEmitter);
+
+var Connector$1 = function (_EventEmitter) {
+ inherits(Connector, _EventEmitter);
+
+ function Connector(cache, store, services) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+ classCallCheck(this, Connector);
+
+ var _this = possibleConstructorReturn(this, _EventEmitter.call(this));
+
+ _this.cache = cache;
+ _this.store = store;
+ _this.services = services;
+ _this.options = options;
+ _this.logger = baseLogger.create('cacheConnector');
+
+ _this.cache && _this.cache.init && _this.cache.init(services, options.cache, options);
+ return _this;
+ }
+
+ Connector.prototype.load = function load(languages, namespaces, callback) {
+ var _this2 = this;
+
+ if (!this.cache) return callback && callback();
+ var options = _extends({}, this.cache.options, this.options.cache);
+
+ if (typeof languages === 'string') languages = this.services.languageUtils.toResolveHierarchy(languages);
+ if (typeof namespaces === 'string') namespaces = [namespaces];
+
+ if (options.enabled) {
+ this.cache.load(languages, function (err, data) {
+ if (err) _this2.logger.error('loading languages ' + languages.join(', ') + ' from cache failed', err);
+ if (data) {
+ for (var l in data) {
+ for (var n in data[l]) {
+ if (n === 'i18nStamp') continue;
+ var bundle = data[l][n];
+ if (bundle) _this2.store.addResourceBundle(l, n, bundle);
+ }
+ }
+ }
+ if (callback) callback();
+ });
+ } else {
+ if (callback) callback();
+ }
+ };
+
+ Connector.prototype.save = function save() {
+ if (this.cache && this.options.cache && this.options.cache.enabled) this.cache.save(this.store.data);
+ };
+
+ return Connector;
+}(EventEmitter);
+
+function get$1() {
+ return {
+ debug: false,
+ initImmediate: true,
+
+ ns: ['translation'],
+ defaultNS: ['translation'],
+ fallbackLng: ['dev'],
+ fallbackNS: false, // string or array of namespaces
+
+ whitelist: false, // array with whitelisted languages
+ nonExplicitWhitelist: false,
+ load: 'all', // | currentOnly | languageOnly
+ preload: false, // array with preload languages
+
+ simplifyPluralSuffix: true,
+ keySeparator: '.',
+ nsSeparator: ':',
+ pluralSeparator: '_',
+ contextSeparator: '_',
+
+ saveMissing: false, // enable to send missing values
+ saveMissingTo: 'fallback', // 'current' || 'all'
+ missingKeyHandler: false, // function(lng, ns, key, fallbackValue) -> override if prefer on handling
+
+ postProcess: false, // string or array of postProcessor names
+ returnNull: true, // allows null value as valid translation
+ returnEmptyString: true, // allows empty string value as valid translation
+ returnObjects: false,
+ joinArrays: false, // or string to join array
+ returnedObjectHandler: function returnedObjectHandler() {}, // function(key, value, options) triggered if key returns object but returnObjects is set to false
+ parseMissingKeyHandler: false, // function(key) parsed a key that was not found in t() before returning
+ appendNamespaceToMissingKey: false,
+ appendNamespaceToCIMode: false,
+ overloadTranslationOptionHandler: function overloadTranslationOptionHandler(args) {
+ return { defaultValue: args[1] };
+ },
+
+ interpolation: {
+ escapeValue: true,
+ format: function format(value, _format, lng) {
+ return value;
+ },
+ prefix: '{{',
+ suffix: '}}',
+ formatSeparator: ',',
+ // prefixEscaped: '{{',
+ // suffixEscaped: '}}',
+ // unescapeSuffix: '',
+ unescapePrefix: '-',
+
+ nestingPrefix: '$t(',
+ nestingSuffix: ')',
+ // nestingPrefixEscaped: '$t(',
+ // nestingSuffixEscaped: ')',
+ defaultVariables: undefined // object that can have values to interpolate on - extends passed in interpolation data
+ }
+ };
+}
+
+function transformOptions(options) {
+ // create namespace object if namespace is passed in as string
+ if (typeof options.ns === 'string') options.ns = [options.ns];
+ if (typeof options.fallbackLng === 'string') options.fallbackLng = [options.fallbackLng];
+ if (typeof options.fallbackNS === 'string') options.fallbackNS = [options.fallbackNS];
+
+ // extend whitelist with cimode
+ if (options.whitelist && options.whitelist.indexOf('cimode') < 0) options.whitelist.push('cimode');
+
+ return options;
+}
+
+function noop() {}
+
+var I18n = function (_EventEmitter) {
+ inherits(I18n, _EventEmitter);
+
+ function I18n() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var callback = arguments[1];
+ classCallCheck(this, I18n);
+
+ var _this = possibleConstructorReturn(this, _EventEmitter.call(this));
+
+ _this.options = transformOptions(options);
+ _this.services = {};
+ _this.logger = baseLogger;
+ _this.modules = { external: [] };
+
+ if (callback && !_this.isInitialized && !options.isClone) {
+ var _ret;
+
+ // https://github.com/i18next/i18next/issues/879
+ if (!_this.options.initImmediate) return _ret = _this.init(options, callback), possibleConstructorReturn(_this, _ret);
+ setTimeout(function () {
+ _this.init(options, callback);
+ }, 0);
+ }
+ return _this;
+ }
+
+ I18n.prototype.init = function init(options, callback) {
+ var _this2 = this;
+
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+ if (!options) options = {};
+
+ if (options.compatibilityAPI === 'v1') {
+ this.options = _extends({}, get$1(), transformOptions(convertAPIOptions(options)), {});
+ } else if (options.compatibilityJSON === 'v1') {
+ this.options = _extends({}, get$1(), transformOptions(convertJSONOptions(options)), {});
+ } else {
+ this.options = _extends({}, get$1(), this.options, transformOptions(options));
+ }
+ if (!callback) callback = noop;
+
+ function createClassOnDemand(ClassOrObject) {
+ if (!ClassOrObject) return;
+ if (typeof ClassOrObject === 'function') return new ClassOrObject();
+ return ClassOrObject;
+ }
+
+ // init services
+ if (!this.options.isClone) {
+ if (this.modules.logger) {
+ baseLogger.init(createClassOnDemand(this.modules.logger), this.options);
+ } else {
+ baseLogger.init(null, this.options);
+ }
+
+ var lu = new LanguageUtil(this.options);
+ this.store = new ResourceStore(this.options.resources, this.options);
+
+ var s = this.services;
+ s.logger = baseLogger;
+ s.resourceStore = this.store;
+ s.resourceStore.on('added removed', function (lng, ns) {
+ s.cacheConnector.save();
+ });
+ s.languageUtils = lu;
+ s.pluralResolver = new PluralResolver(lu, { prepend: this.options.pluralSeparator, compatibilityJSON: this.options.compatibilityJSON, simplifyPluralSuffix: this.options.simplifyPluralSuffix });
+ s.interpolator = new Interpolator(this.options);
+
+ s.backendConnector = new Connector(createClassOnDemand(this.modules.backend), s.resourceStore, s, this.options);
+ // pipe events from backendConnector
+ s.backendConnector.on('*', function (event) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ _this2.emit.apply(_this2, [event].concat(args));
+ });
+
+ s.backendConnector.on('loaded', function (loaded) {
+ s.cacheConnector.save();
+ });
+
+ s.cacheConnector = new Connector$1(createClassOnDemand(this.modules.cache), s.resourceStore, s, this.options);
+ // pipe events from backendConnector
+ s.cacheConnector.on('*', function (event) {
+ for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ args[_key2 - 1] = arguments[_key2];
+ }
+
+ _this2.emit.apply(_this2, [event].concat(args));
+ });
+
+ if (this.modules.languageDetector) {
+ s.languageDetector = createClassOnDemand(this.modules.languageDetector);
+ s.languageDetector.init(s, this.options.detection, this.options);
+ }
+
+ this.translator = new Translator(this.services, this.options);
+ // pipe events from translator
+ this.translator.on('*', function (event) {
+ for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
+ args[_key3 - 1] = arguments[_key3];
+ }
+
+ _this2.emit.apply(_this2, [event].concat(args));
+ });
+
+ this.modules.external.forEach(function (m) {
+ if (m.init) m.init(_this2);
+ });
+ }
+
+ // append api
+ var storeApi = ['getResource', 'addResource', 'addResources', 'addResourceBundle', 'removeResourceBundle', 'hasResourceBundle', 'getResourceBundle'];
+ storeApi.forEach(function (fcName) {
+ _this2[fcName] = function () {
+ return this.store[fcName].apply(this.store, arguments);
+ };
+ });
+
+ // TODO: COMPATIBILITY remove this
+ if (this.options.compatibilityAPI === 'v1') appendBackwardsAPI(this);
+
+ var load = function load() {
+ _this2.changeLanguage(_this2.options.lng, function (err, t) {
+ _this2.isInitialized = true;
+ _this2.logger.log('initialized', _this2.options);
+ _this2.emit('initialized', _this2.options);
+
+ callback(err, t);
+ });
+ };
+
+ if (this.options.resources || !this.options.initImmediate) {
+ load();
+ } else {
+ setTimeout(load, 0);
+ }
+
+ return this;
+ };
+
+ I18n.prototype.loadResources = function loadResources() {
+ var _this3 = this;
+
+ var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;
+
+ if (!this.options.resources) {
+ if (this.language && this.language.toLowerCase() === 'cimode') return callback(); // avoid loading resources for cimode
+
+ var toLoad = [];
+
+ var append = function append(lng) {
+ if (!lng) return;
+ var lngs = _this3.services.languageUtils.toResolveHierarchy(lng);
+ lngs.forEach(function (l) {
+ if (toLoad.indexOf(l) < 0) toLoad.push(l);
+ });
+ };
+
+ if (!this.language) {
+ // at least load fallbacks in this case
+ var fallbacks = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
+ fallbacks.forEach(function (l) {
+ return append(l);
+ });
+ } else {
+ append(this.language);
+ }
+
+ if (this.options.preload) {
+ this.options.preload.forEach(function (l) {
+ return append(l);
+ });
+ }
+
+ this.services.cacheConnector.load(toLoad, this.options.ns, function () {
+ _this3.services.backendConnector.load(toLoad, _this3.options.ns, callback);
+ });
+ } else {
+ callback(null);
+ }
+ };
+
+ I18n.prototype.reloadResources = function reloadResources(lngs, ns) {
+ if (!lngs) lngs = this.languages;
+ if (!ns) ns = this.options.ns;
+ this.services.backendConnector.reload(lngs, ns);
+ };
+
+ I18n.prototype.use = function use(module) {
+ if (module.type === 'backend') {
+ this.modules.backend = module;
+ }
+
+ if (module.type === 'cache') {
+ this.modules.cache = module;
+ }
+
+ if (module.type === 'logger' || module.log && module.warn && module.error) {
+ this.modules.logger = module;
+ }
+
+ if (module.type === 'languageDetector') {
+ this.modules.languageDetector = module;
+ }
+
+ if (module.type === 'postProcessor') {
+ postProcessor.addPostProcessor(module);
+ }
+
+ if (module.type === '3rdParty') {
+ this.modules.external.push(module);
+ }
+
+ return this;
+ };
+
+ I18n.prototype.changeLanguage = function changeLanguage(lng, callback) {
+ var _this4 = this;
+
+ var done = function done(err) {
+ if (lng) {
+ _this4.emit('languageChanged', lng);
+ _this4.logger.log('languageChanged', lng);
+ }
+
+ if (callback) callback(err, function () {
+ for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
+ args[_key4] = arguments[_key4];
+ }
+
+ return _this4.t.apply(_this4, args);
+ });
+ };
+
+ if (!lng && this.services.languageDetector) lng = this.services.languageDetector.detect();
+
+ if (lng) {
+ this.language = lng;
+ this.languages = this.services.languageUtils.toResolveHierarchy(lng);
+
+ this.translator.changeLanguage(lng);
+
+ if (this.services.languageDetector) this.services.languageDetector.cacheUserLanguage(lng);
+ }
+
+ this.loadResources(function (err) {
+ done(err);
+ });
+ };
+
+ I18n.prototype.getFixedT = function getFixedT(lng, ns) {
+ var _this5 = this;
+
+ var fixedT = function fixedT(key) {
+ var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ var options = _extends({}, opts);
+ options.lng = options.lng || fixedT.lng;
+ options.ns = options.ns || fixedT.ns;
+ return _this5.t(key, options);
+ };
+ fixedT.lng = lng;
+ fixedT.ns = ns;
+ return fixedT;
+ };
+
+ I18n.prototype.t = function t() {
+ return this.translator && this.translator.translate.apply(this.translator, arguments);
+ };
+
+ I18n.prototype.exists = function exists() {
+ return this.translator && this.translator.exists.apply(this.translator, arguments);
+ };
+
+ I18n.prototype.setDefaultNamespace = function setDefaultNamespace(ns) {
+ this.options.defaultNS = ns;
+ };
+
+ I18n.prototype.loadNamespaces = function loadNamespaces(ns, callback) {
+ var _this6 = this;
+
+ if (!this.options.ns) return callback && callback();
+ if (typeof ns === 'string') ns = [ns];
+
+ ns.forEach(function (n) {
+ if (_this6.options.ns.indexOf(n) < 0) _this6.options.ns.push(n);
+ });
+
+ this.loadResources(callback);
+ };
+
+ I18n.prototype.loadLanguages = function loadLanguages(lngs, callback) {
+ if (typeof lngs === 'string') lngs = [lngs];
+ var preloaded = this.options.preload || [];
+
+ var newLngs = lngs.filter(function (lng) {
+ return preloaded.indexOf(lng) < 0;
+ });
+ // Exit early if all given languages are already preloaded
+ if (!newLngs.length) return callback();
+
+ this.options.preload = preloaded.concat(newLngs);
+ this.loadResources(callback);
+ };
+
+ I18n.prototype.dir = function dir(lng) {
+ if (!lng) lng = this.language;
+ if (!lng) return 'rtl';
+
+ var rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam'];
+
+ return rtlLngs.indexOf(this.services.languageUtils.getLanguagePartFromCode(lng)) >= 0 ? 'rtl' : 'ltr';
+ };
+
+ I18n.prototype.createInstance = function createInstance() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var callback = arguments[1];
+
+ return new I18n(options, callback);
+ };
+
+ I18n.prototype.cloneInstance = function cloneInstance() {
+ var _this7 = this;
+
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
+
+ var mergedOptions = _extends({}, options, this.options, { isClone: true });
+ var clone = new I18n(mergedOptions, callback);
+ var membersToCopy = ['store', 'services', 'language'];
+ membersToCopy.forEach(function (m) {
+ clone[m] = _this7[m];
+ });
+ clone.translator = new Translator(clone.services, clone.options);
+ clone.translator.on('*', function (event) {
+ for (var _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
+ args[_key5 - 1] = arguments[_key5];
+ }
+
+ clone.emit.apply(clone, [event].concat(args));
+ });
+ clone.init(mergedOptions, callback);
+
+ return clone;
+ };
+
+ return I18n;
+}(EventEmitter);
+
+var i18next = new I18n();
+
+return i18next;
+
+})));
diff --git a/BTCPayServer/wwwroot/vendor/i18next/vue-i18next.js b/BTCPayServer/wwwroot/vendor/i18next/vue-i18next.js
new file mode 100644
index 000000000..dbd53027e
--- /dev/null
+++ b/BTCPayServer/wwwroot/vendor/i18next/vue-i18next.js
@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("VueI18next",[],t):"object"==typeof exports?exports.VueI18next=t():e.VueI18next=t()}(this,function(){return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist/",t(t.s=2)}([function(e,t,n){"use strict";function i(e){i.installed||(i.installed=!0,t.Vue=u=e,u.mixin({computed:{$t:function(){var e=this;return function(t,n){return e.$i18n.t(t,n,e.$i18n.i18nLoadedAt)}}},beforeCreate:function(){var e=this.$options;e.i18n?this.$i18n=e.i18n:e.parent&&e.parent.$i18n&&(this.$i18n=e.parent.$i18n)}}),u.component(r.default.name,r.default))}Object.defineProperty(t,"__esModule",{value:!0}),t.Vue=void 0,t.install=i;var o=n(1),r=function(e){return e&&e.__esModule?e:{default:e}}(o),u=t.Vue=void 0},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={name:"i18next",functional:!0,props:{tag:{type:String,default:"span"},path:{type:String,required:!0}},render:function(e,t){var n=t.props,i=t.data,o=t.children,r=t.parent,u=r.$i18n;if(!u)return o;var a=n.path,s=u.i18next.services.interpolator.regexp,f=u.t(a,{interpolation:{prefix:"#$?",suffix:"?$#"}}),d=[],c={};return o.forEach(function(e){e.data&&e.data.attrs&&e.data.attrs.tkey&&(c[e.data.attrs.tkey]=e)}),f.split(s).reduce(function(e,t,n){var i=void 0;if(n%2==0){if(0===t.length)return e;i=t}else i=o[parseInt(t,10)];return e.push(i),e},d),e(n.tag,i,d)}},e.exports=t.default},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=function(){function e(e,t){for(var n=0;n
1&&void 0!==arguments[1]?arguments[1]:{};i(this,e);var o=n.bindI18n,r=void 0===o?"languageChanged loaded":o,u=n.bindStore,a=void 0===u?"added removed":u;this._vm=null,this.i18next=t,this.onI18nChanged=this.onI18nChanged.bind(this),r&&this.i18next.on(r,this.onI18nChanged),a&&this.i18next.store&&this.i18next.store.on(a,this.onI18nChanged),this.resetVM({i18nLoadedAt:new Date})}return r(e,[{key:"resetVM",value:function(e){var t=this._vm,n=u.Vue.config.silent;u.Vue.config.silent=!0,this._vm=new u.Vue({data:e}),u.Vue.config.silent=n,t&&u.Vue.nextTick(function(){return t.$destroy()})}},{key:"t",value:function(e,t){return this.i18next.t(e,t)}},{key:"onI18nChanged",value:function(){this.i18nLoadedAt=new Date}},{key:"i18nLoadedAt",get:function(){return this._vm.$data.i18nLoadedAt},set:function(e){this._vm.$set(this._vm,"i18nLoadedAt",e)}}]),e}();t.default=a,a.install=u.install,a.version="0.4.0",("undefined"==typeof window?"undefined":o(window))&&window.Vue&&window.Vue.use(a),e.exports=t.default}])});
+//# sourceMappingURL=vue-i18next.js.map
\ No newline at end of file
diff --git a/BTCPayServer/wwwroot/vendor/jquery-prettydropdowns/jquery.prettydropdowns.js b/BTCPayServer/wwwroot/vendor/jquery-prettydropdowns/jquery.prettydropdowns.js
new file mode 100644
index 000000000..f5c59ca72
--- /dev/null
+++ b/BTCPayServer/wwwroot/vendor/jquery-prettydropdowns/jquery.prettydropdowns.js
@@ -0,0 +1,490 @@
+/*!
+ * jQuery Pretty Dropdowns Plugin v4.11.0 by T. H. Doan (http://thdoan.github.io/pretty-dropdowns/)
+ *
+ * jQuery Pretty Dropdowns by T. H. Doan is licensed under the MIT License.
+ * Read a copy of the license in the LICENSE file or at
+ * http://choosealicense.com/licenses/mit
+ */
+
+(function($) {
+ $.fn.prettyDropdown = function(oOptions) {
+
+ // Default options
+ oOptions = $.extend({
+ classic: false,
+ customClass: 'arrow',
+ height: 50,
+ hoverIntent: 200,
+ multiDelimiter: '; ',
+ multiVerbosity: 99,
+ selectedMarker: '✓',
+ reverse: false,
+ afterLoad: function(){}
+ }, oOptions);
+
+ oOptions.selectedMarker = ' ' + oOptions.selectedMarker + ' ';
+ // Validate options
+ if (isNaN(oOptions.height) || oOptions.height<8) oOptions.height = 8;
+ if (isNaN(oOptions.hoverIntent) || oOptions.hoverIntent<0) oOptions.hoverIntent = 200;
+ if (isNaN(oOptions.multiVerbosity)) oOptions.multiVerbosity = 99;
+
+ // Translatable strings
+ var MULTI_NONE = 'None selected',
+ MULTI_PREFIX = 'Selected: ',
+ MULTI_POSTFIX = ' selected';
+
+ // Globals
+ var $current,
+ aKeys = [
+ '0','1','2','3','4','5','6','7','8','9',,,,,,,,
+ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
+ ],
+ nCount,
+ nHoverIndex,
+ nLastIndex,
+ nTimer,
+ nTimestamp,
+
+ // Initiate pretty drop-downs
+ init = function(elSel) {
+ var $select = $(elSel),
+ nSize = elSel.size,
+ sId = elSel.name || elSel.id || '',
+ sLabelId;
+ // Exit if widget has already been initiated
+ if ($select.data('loaded')) return;
+ // Remove 'size' attribute to it doesn't affect vertical alignment
+ $select.data('size', nSize).removeAttr('size');
+ // Set height to reserve space for container
+ $select.css('visibility', 'hidden').outerHeight(oOptions.height);
+ nTimestamp = +new Date();
+ // Test whether to add 'aria-labelledby'
+ if (elSel.id) {
+ // Look for
+ var $label = $('label[for=' + elSel.id + ']');
+ if ($label.length) {
+ // Add 'id' to if necessary
+ if ($label.attr('id') && !/^menu\d{13,}$/.test($label.attr('id'))) sLabelId = $label.attr('id');
+ else $label.attr('id', (sLabelId = 'menu' + nTimestamp));
+ }
+ }
+ nCount = 0;
+ var $items = $('optgroup, option', $select),
+ $selected = $items.filter(':selected'),
+ bMultiple = elSel.multiple,
+ // Height - 2px for borders
+ sHtml = '';
+ if (bMultiple) {
+ sHtml += renderItem(null, 'selected');
+ $items.each(function() {
+ if (this.selected) {
+ sHtml += renderItem(this, '', true)
+ } else {
+ sHtml += renderItem(this);
+ }
+ });
+ } else {
+ if (oOptions.classic) {
+ $items.each(function() {
+ sHtml += renderItem(this);
+ });
+ } else {
+ sHtml += renderItem($selected[0], 'selected');
+ $items.filter(':not(:selected)').each(function() {
+ sHtml += renderItem(this);
+ });
+ }
+ }
+ sHtml += ' ';
+ $select.wrap(' has the
+ // 'multiple' attribute or 'size' attribute with a value larger than 1. To fix this, we
+ // have to inline the height.
+ + ((bMultiple || nSize>1) ? ' style="height:' + oOptions.height + 'px;"' : '')
+ +'>
').before(sHtml).data('loaded', true);
+ var $dropdown = $select.parent().children('ul'),
+ nWidth = $dropdown.outerWidth(true),
+ nOuterWidth;
+ $items = $dropdown.children();
+ // Update default selected values for multi-select menu
+ if (bMultiple) updateSelected($dropdown);
+ else if (oOptions.classic) $('[data-value="' + $selected.val() + '"]', $dropdown).addClass('selected').append(oOptions.selectedMarker);
+ // Calculate width if initially hidden
+ if ($dropdown.width()<=0) {
+ var $clone = $dropdown.parent().clone().css({
+ position: 'absolute',
+ top: '-100%'
+ });
+ $('body').append($clone);
+ nWidth = $clone.children('ul').outerWidth(true);
+ $('li', $clone).width(nWidth);
+ nOuterWidth = $clone.children('ul').outerWidth(true);
+ $clone.remove();
+ }
+ // Set dropdown width and event handler
+ // NOTE: Setting width using width(), then css() because width() only can return a float,
+ // which can result in a missing right border when there is a scrollbar.
+ $items.width(nWidth).css('width', $items.css('width')).click(function() {
+ var $li = $(this),
+ $selected = $dropdown.children('.selected');
+ // Ignore disabled menu
+ if ($dropdown.parent().hasClass('disabled')) return;
+ // Only update if not disabled, not a label, and a different value selected
+ if ($dropdown.hasClass('active') && !$li.hasClass('disabled') && !$li.hasClass('label') && $li.data('value')!==$selected.data('value')) {
+ // Select highlighted item
+ if (bMultiple) {
+ if ($li.children('span.checked').length) $li.children('span.checked').remove();
+ else $li.append(oOptions.selectedMarker);
+ // Sync element
+ $dropdown.children(':not(.selected)').each(function(nIndex) {
+ $('optgroup, option', $select).eq(nIndex).prop('selected', $(this).children('span.checked').length>0);
+ });
+ // Update selected values for multi-select menu
+ updateSelected($dropdown);
+ } else {
+ $selected.removeClass('selected').children('span.checked').remove();
+ $li.addClass('selected').append(oOptions.selectedMarker);
+ if (!oOptions.classic) $dropdown.prepend($li);
+ $dropdown.removeClass('reverse').attr('aria-activedescendant', $li.attr('id'));
+ if ($selected.data('group') && !oOptions.classic) $dropdown.children('.label').filter(function() {
+ return $(this).text()===$selected.data('group');
+ }).after($selected);
+ // Sync element
+ $('optgroup, option', $select).filter(function() {
+ // NOTE: .data('value') can return numeric, so using == comparison instead.
+ return this.value==$li.data('value') || this.text===$li.contents().filter(function() {
+ // Filter out selected marker
+ return this.nodeType===3;
+ }).text();
+ }).prop('selected', true);
+ }
+ $select.trigger('change');
+ }
+ if ($li.hasClass('selected') || !bMultiple) {
+ $dropdown.toggleClass('active');
+ $dropdown.attr('aria-expanded', $dropdown.hasClass('active'));
+ }
+ // Try to keep drop-down menu within viewport
+ if ($dropdown.hasClass('active')) {
+ // Close any other open menus
+ if ($('.prettydropdown > ul.active').length>1) resetDropdown($('.prettydropdown > ul.active').not($dropdown)[0]);
+ var nWinHeight = window.innerHeight,
+ nMaxHeight,
+ nOffsetTop = $dropdown.offset().top,
+ nScrollTop = document.body.scrollTop,
+ nDropdownHeight = $dropdown.outerHeight();
+ if (nSize) {
+ nMaxHeight = nSize*(oOptions.height-2);
+ if (nMaxHeight nWinHeight ||
+ oOptions.reverse) {
+ // Expand to direction that has the most space
+ if (nOffsetTop - nScrollTop > nWinHeight - (nOffsetTop - nScrollTop + oOptions.height) ||
+ oOptions.reverse) {
+ $dropdown.addClass('reverse');
+ if (!oOptions.classic) $dropdown.append($selected);
+ if (nOffsetTop-nScrollTop+oOptions.height ul.active, .prettydropdown > ul:focus');
+ if (!$dropdown.length) return;
+ if (e.which===9) { // Tab
+ resetDropdown($dropdown[0]);
+ return;
+ } else {
+ // Intercept non-Tab keys only
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ var $items = $dropdown.children(),
+ bOpen = $dropdown.hasClass('active'),
+ nItemsHeight = $dropdown.height()/(oOptions.height-2),
+ nItemsPerPage = nItemsHeight%1<0.5 ? Math.floor(nItemsHeight) : Math.ceil(nItemsHeight),
+ sKey;
+ nHoverIndex = Math.max(0, $dropdown.children('.hover').index());
+ nLastIndex = $items.length-1;
+ $current = $items.eq(nHoverIndex);
+ $dropdown.data('lastKeypress', +new Date());
+ switch (e.which) {
+ case 13: // Enter
+ if (!bOpen) {
+ $current = $items.filter('.selected');
+ toggleHover($current, 1);
+ }
+ $current.click();
+ break;
+ case 27: // Esc
+ if (bOpen) resetDropdown($dropdown[0]);
+ break;
+ case 32: // Space
+ if (bOpen) {
+ sKey = ' ';
+ } else {
+ $current = $items.filter('.selected');
+ toggleHover($current, 1);
+ $current.click();
+ }
+ break;
+ case 33: // Page Up
+ if (bOpen) {
+ toggleHover($current, 0);
+ toggleHover($items.eq(Math.max(nHoverIndex-nItemsPerPage-1, 0)), 1);
+ }
+ break;
+ case 34: // Page Down
+ if (bOpen) {
+ toggleHover($current, 0);
+ toggleHover($items.eq(Math.min(nHoverIndex+nItemsPerPage-1, nLastIndex)), 1);
+ }
+ break;
+ case 35: // End
+ if (bOpen) {
+ toggleHover($current, 0);
+ toggleHover($items.eq(nLastIndex), 1);
+ }
+ break;
+ case 36: // Home
+ if (bOpen) {
+ toggleHover($current, 0);
+ toggleHover($items.eq(0), 1);
+ }
+ break;
+ case 38: // Up
+ if (bOpen) {
+ toggleHover($current, 0);
+ // If not already key-navigated or first item is selected, cycle to the last item; or
+ // else select the previous item
+ toggleHover(nHoverIndex ? $items.eq(nHoverIndex-1) : $items.eq(nLastIndex), 1);
+ }
+ break;
+ case 40: // Down
+ if (bOpen) {
+ toggleHover($current, 0);
+ // If last item is selected, cycle to the first item; or else select the next item
+ toggleHover(nHoverIndex===nLastIndex ? $items.eq(0) : $items.eq(nHoverIndex+1), 1);
+ }
+ break;
+ default:
+ if (bOpen) sKey = aKeys[e.which-48];
+ }
+ if (sKey) { // Alphanumeric key pressed
+ clearTimeout(nTimer);
+ $dropdown.data('keysPressed', $dropdown.data('keysPressed')===undefined ? sKey : $dropdown.data('keysPressed') + sKey);
+ nTimer = setTimeout(function() {
+ $dropdown.removeData('keysPressed');
+ // NOTE: Windows keyboard repeat delay is 250-1000 ms. See
+ // https://technet.microsoft.com/en-us/library/cc978658.aspx
+ }, 300);
+ // Build index of matches
+ var aMatches = [],
+ nCurrentIndex = $current.index();
+ $items.each(function(nIndex) {
+ if ($(this).text().toLowerCase().indexOf($dropdown.data('keysPressed'))===0) aMatches.push(nIndex);
+ });
+ if (aMatches.length) {
+ // Cycle through items matching key(s) pressed
+ for (var i=0; inCurrentIndex) {
+ toggleHover($items, 0);
+ toggleHover($items.eq(aMatches[i]), 1);
+ break;
+ }
+ if (i===aMatches.length-1) {
+ toggleHover($items, 0);
+ toggleHover($items.eq(aMatches[0]), 1);
+ }
+ }
+ }
+ }
+ },
+
+ // Highlight menu item
+ hoverDropdownItem = function(e) {
+ var $dropdown = $(e.currentTarget);
+ if (e.target.nodeName!=='LI' || !$dropdown.hasClass('active') || new Date()-$dropdown.data('lastKeypress')<200) return;
+ toggleHover($dropdown.children(), 0, 1);
+ toggleHover($(e.target), 1, 1);
+ },
+
+ // Construct menu item
+ // elOpt is null for first item in multi-select menus
+ renderItem = function(elOpt, sClass, bSelected) {
+ var sGroup = '',
+ sText = '',
+ sTitle;
+ sClass = sClass || '';
+ if (elOpt) {
+ switch (elOpt.nodeName) {
+ case 'OPTION':
+ if (elOpt.parentNode.nodeName==='OPTGROUP') sGroup = elOpt.parentNode.getAttribute('label');
+ sText = (elOpt.getAttribute('data-prefix') || '') + elOpt.text + (elOpt.getAttribute('data-suffix') || '');
+ break;
+ case 'OPTGROUP':
+ sClass += ' label';
+ sText = elOpt.getAttribute('label');
+ break;
+ }
+ if (elOpt.disabled || (sGroup && elOpt.parentNode.disabled)) sClass += ' disabled';
+ sTitle = elOpt.title;
+ if (sGroup && !sTitle) sTitle = elOpt.parentNode.title;
+ }
+ ++nCount;
+ return '' + sText
+ + ((bSelected || sClass==='selected') ? oOptions.selectedMarker : '') + ' ';
+ },
+
+ // Reset menu state
+ // @param o Event or Element object
+ resetDropdown = function(o) {
+ var $dropdown = $(o.currentTarget||o);
+ // NOTE: Sometimes it's possible for $dropdown to point to the wrong element when you
+ // quickly hover over another menu. To prevent this, we need to check for .active as a
+ // backup and manually reassign $dropdown. This also requires that it's not clicked on
+ // because in rare cases the reassignment fails and the reverse menu will not get reset.
+ if (o.type==='mouseleave' && !$dropdown.hasClass('active') && !$dropdown.data('clicked')) $dropdown = $('.prettydropdown > ul.active');
+ $dropdown.data('hover', false);
+ clearTimeout(nTimer);
+ nTimer = setTimeout(function() {
+ if ($dropdown.data('hover')) return;
+ if ($dropdown.hasClass('reverse') && !oOptions.classic) $dropdown.prepend($dropdown.children(':last-child'));
+ $dropdown.removeClass('active reverse').removeData('clicked').attr('aria-expanded', 'false').css('height', '');
+ $dropdown.children().removeClass('hover nohover');
+ }, (o.type==='mouseleave' && !$dropdown.data('clicked')) ? oOptions.hoverIntent : 0);
+ },
+
+ // Set menu item hover state
+ // bNoScroll set on hoverDropdownItem()
+ toggleHover = function($li, bOn, bNoScroll) {
+ if (bOn) {
+ $li.removeClass('nohover').addClass('hover');
+ if ($li.length===1 && $current && !bNoScroll) {
+ // Ensure items are always in view
+ var $dropdown = $li.parent(),
+ nDropdownHeight = $dropdown.outerHeight(),
+ nItemOffset = $li.offset().top-$dropdown.offset().top-1; // -1px for top border
+ if ($li.index()===0) {
+ $dropdown.scrollTop(0);
+ } else if ($li.index()===nLastIndex) {
+ $dropdown.scrollTop($dropdown.children().length*oOptions.height);
+ } else {
+ if (nItemOffset+oOptions.height>nDropdownHeight) $dropdown.scrollTop($dropdown.scrollTop()+oOptions.height+nItemOffset-nDropdownHeight);
+ else if (nItemOffset<0) $dropdown.scrollTop($dropdown.scrollTop()+nItemOffset);
+ }
+ }
+ } else {
+ $li.removeClass('hover').addClass('nohover');
+ }
+ },
+
+ // Update selected values for multi-select menu
+ updateSelected = function($dropdown) {
+ var $select = $dropdown.parent().children('select'),
+ aSelected = $('option', $select).map(function() {
+ if (this.selected) return this.text;
+ }).get(),
+ sSelected;
+ if (oOptions.multiVerbosity>=aSelected.length) sSelected = aSelected.join(oOptions.multiDelimiter) || MULTI_NONE;
+ else sSelected = aSelected.length + '/' + $('option', $select).length + MULTI_POSTFIX;
+ if (sSelected) {
+ var sTitle = ($select.attr('title') ? $select.attr('title') : '') + (aSelected.length ? '\n' + MULTI_PREFIX + aSelected.join(oOptions.multiDelimiter) : '');
+ $dropdown.children('.selected').text(sSelected);
+ $dropdown.attr({
+ 'title': sTitle,
+ 'aria-label': sTitle
+ });
+ } else {
+ $dropdown.children('.selected').empty();
+ $dropdown.attr({
+ 'title': $select.attr('title'),
+ 'aria-label': $select.attr('title')
+ });
+ }
+ };
+
+ /**
+ * Public Functions
+ */
+
+ // Resync the menu with to reflect state changes
+ this.refresh = function(oOptions) {
+ return this.each(function() {
+ var $select = $(this);
+ $select.prevAll('ul').remove();
+ $select.unwrap().data('loaded', false);
+ this.size = $select.data('size');
+ init(this);
+ });
+ };
+
+ return this.each(function() {
+ init(this);
+ });
+
+ };
+}(jQuery));
diff --git a/BTCPayServer/wwwroot/vendor/jquery-prettydropdowns/prettydropdowns.css b/BTCPayServer/wwwroot/vendor/jquery-prettydropdowns/prettydropdowns.css
new file mode 100644
index 000000000..00b87a37f
--- /dev/null
+++ b/BTCPayServer/wwwroot/vendor/jquery-prettydropdowns/prettydropdowns.css
@@ -0,0 +1,206 @@
+.prettydropdown {
+ position: relative;
+ min-width: 72px; /* 70px + borders */
+ display: inline-block;
+}
+
+ .prettydropdown.loading {
+ min-width: 0;
+ }
+
+ .prettydropdown > ul {
+ border-radius: 5px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: #fff;
+ border: 1px solid #a9a9a9;
+ box-sizing: content-box;
+ color: #000;
+ cursor: pointer;
+ font: normal 18px Calibri, sans-serif;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ text-align: left;
+ -webkit-user-select: none; /* Chrome all / Safari all */
+ -moz-user-select: none; /* Firefox all */
+ -ms-user-select: none; /* IE 10+ */
+ user-select: none; /* Likely future */
+ z-index: 1;
+ }
+
+ .prettydropdown.loading > ul {
+ visibility: hidden;
+ white-space: nowrap;
+ }
+
+ .prettydropdown > ul:focus, .prettydropdown:not(.disabled) > ul:hover {
+ border-color: #7f7f7f;
+ }
+
+ .prettydropdown:not(.disabled) > ul.active {
+ width: auto;
+ max-height: 400px !important;
+ border-color: #1e90ff;
+ overflow-x: hidden;
+ overflow-y: auto;
+ z-index: 99;
+ }
+
+ .prettydropdown > ul.active:focus {
+ outline: none;
+ }
+
+ .prettydropdown > ul.active.reverse {
+ top: auto;
+ bottom: 0;
+ }
+
+ .prettydropdown > ul > li {
+ font-size: 14px;
+ position: relative;
+ min-width: 70px;
+ height: 48px; /* 50px - borders */
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ box-sizing: border-box;
+ display: none;
+ line-height: 46px; /* 48px - borders */
+ margin: 0;
+ padding-left: 0.8rem;
+ }
+
+ .prettydropdown.loading > ul > li {
+ min-width: 0;
+ display: block;
+ padding-right: 0.8rem;
+ }
+
+ .prettydropdown > ul:not(.active) > li:not(.selected):first-child {
+ color: transparent; /* Prevent FOUC */
+ }
+
+ .prettydropdown > ul > li:first-child, .prettydropdown > ul.active > li {
+ display: block;
+ }
+
+ .prettydropdown > ul.active > li:not(.label):hover, .prettydropdown > ul.active > li.hover:not(.label), .prettydropdown > ul.active > li:first-child:hover:after {
+ background: #1e90ff;
+ color: #fff;
+ }
+
+ .prettydropdown > ul.active > li.nohover {
+ background: inherit !important;
+ color: inherit !important;
+ }
+
+ .prettydropdown > ul.active > li.hover:before, .prettydropdown > ul.active > li.nohover:after {
+ border-top-color: #fff !important;
+ }
+
+ .prettydropdown > ul.active > li.hover:after, .prettydropdown > ul.active > li.nohover:before {
+ border-top-color: #1e90ff !important;
+ }
+
+ .prettydropdown.arrow > ul > li.selected:before, .prettydropdown.arrow > ul > li.selected:after {
+ position: absolute;
+ top: 8px;
+ bottom: 0;
+ right: 8px;
+ height: 16px;
+ border: 8px solid transparent; /* Arrow size */
+ box-sizing: border-box;
+ content: '';
+ display: block;
+ margin: auto;
+ }
+
+ .prettydropdown.arrow.small > ul > li.selected:before, .prettydropdown.arrow.small > ul > li.selected:after {
+ top: 4px;
+ height: 8px;
+ border-width: 4px;
+ }
+
+ .prettydropdown.arrow > ul > li.selected:before {
+ border-top-color: #a9a9a9; /* Arrow color */
+ }
+
+ .prettydropdown.arrow > ul > li.selected:after {
+ top: 4px; /* Chevron thickness */
+ border-top-color: #fff; /* Match background colour */
+ }
+
+ .prettydropdown.arrow.small > ul > li.selected:after {
+ top: 2px; /* Chevron thickness */
+ }
+
+ .prettydropdown.arrow.triangle > ul > li.selected:after {
+ content: none;
+ }
+
+ .prettydropdown > ul:hover > li.selected:before {
+ border-top-color: #7f7f7f;
+ }
+
+ .prettydropdown > ul.active > li.selected:before,
+ .prettydropdown > ul.active > li.selected:after {
+ border: none;
+ }
+
+ .prettydropdown > ul:not(.active) > li > span.checked {
+ display: none;
+ }
+
+ /* Multi-Select */
+ .prettydropdown.multiple > ul > li.selected {
+ overflow: hidden;
+ padding-right: 2rem;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .prettydropdown > ul > li > span.checked {
+ clear: both;
+ float: right;
+ font-weight: bold;
+ margin-right: 0.8rem;
+ }
+
+ /* Option Groups */
+ .prettydropdown > ul > li.label {
+ cursor: default;
+ font-weight: bold;
+ }
+
+ .prettydropdown > ul > li.label:first-child,
+ .prettydropdown.classic > ul > li.label ~ li.selected {
+ border-top: none;
+ }
+
+ .prettydropdown > ul > li.label ~ li:not(.label):not(.selected),
+ .prettydropdown.classic > ul.active > li.label ~ li:not(.label) {
+ padding-left: 1.6rem;
+ }
+
+ /* Classic Behavior */
+ .prettydropdown.classic > ul:not(.active) > li.selected:not(:first-child) {
+ position: absolute;
+ top: 0;
+ display: block;
+ }
+
+ /* Disabled */
+ .prettydropdown.disabled, .prettydropdown > ul > li.disabled {
+ opacity: 0.3;
+ }
+
+ .prettydropdown.disabled > ul > li, .prettydropdown > ul > li.disabled {
+ cursor: not-allowed;
+ }
+
+ /* Divider Lines */
+ .prettydropdown.multiple > ul > li.selected + li, .prettydropdown.multiple > ul.reverse > li.selected,
+ .prettydropdown > ul > li.label, .prettydropdown > ul > li.label ~ li.selected {
+ border-top-color: #dedede;
+ }
diff --git a/BTCPayServer/wwwroot/js/vue-qrcode.js b/BTCPayServer/wwwroot/vendor/vuejs/vue-qrcode.js
similarity index 100%
rename from BTCPayServer/wwwroot/js/vue-qrcode.js
rename to BTCPayServer/wwwroot/vendor/vuejs/vue-qrcode.js
diff --git a/BTCPayServer/wwwroot/js/vue-qrcode.js.map b/BTCPayServer/wwwroot/vendor/vuejs/vue-qrcode.js.map
similarity index 100%
rename from BTCPayServer/wwwroot/js/vue-qrcode.js.map
rename to BTCPayServer/wwwroot/vendor/vuejs/vue-qrcode.js.map
diff --git a/BTCPayServer/wwwroot/js/vue-qrcode.min.js b/BTCPayServer/wwwroot/vendor/vuejs/vue-qrcode.min.js
similarity index 100%
rename from BTCPayServer/wwwroot/js/vue-qrcode.min.js
rename to BTCPayServer/wwwroot/vendor/vuejs/vue-qrcode.min.js
diff --git a/BTCPayServer/wwwroot/js/vue.js b/BTCPayServer/wwwroot/vendor/vuejs/vue.js
similarity index 100%
rename from BTCPayServer/wwwroot/js/vue.js
rename to BTCPayServer/wwwroot/vendor/vuejs/vue.js
diff --git a/BTCPayServer/wwwroot/js/vue.min.js b/BTCPayServer/wwwroot/vendor/vuejs/vue.min.js
similarity index 100%
rename from BTCPayServer/wwwroot/js/vue.min.js
rename to BTCPayServer/wwwroot/vendor/vuejs/vue.min.js