popup/ 0000775 0001750 0001750 00000000000 14212136643 012443 5 ustar grothoff grothoff popup/popup_files/ 0000755 0001750 0001750 00000000000 14212136643 014766 5 ustar grothoff grothoff popup/popup_files/popupEntryPoint.js 0000664 0001750 0001750 00003226724 14212136643 020545 0 ustar grothoff grothoff (function () {
'use strict';
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
// TypeScript port in 2019 by Florian Dold.
// Public domain.
//
// Implementation derived from TweetNaCl version 20140427.
// See for details: http://tweetnacl.cr.yp.to/
const gf = function (init = []) {
const r = new Float64Array(16);
if (init)
for (let i = 0; i < init.length; i++)
r[i] = init[i];
return r;
};
// Pluggable, initialized in high-level API below.
let randombytes = function (x, n) {
throw new Error("no PRNG");
};
const _9 = new Uint8Array(32);
_9[0] = 9;
// prettier-ignore
gf();
gf([1]);
gf([0xdb41, 1]);
gf([
0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898,
0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203,
]);
gf([
0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130,
0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406,
]);
gf([
0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c,
0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169,
]);
gf([
0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
]);
gf([
0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7,
0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83,
]);
function ts64(x, i, h, l) {
x[i] = (h >> 24) & 0xff;
x[i + 1] = (h >> 16) & 0xff;
x[i + 2] = (h >> 8) & 0xff;
x[i + 3] = h & 0xff;
x[i + 4] = (l >> 24) & 0xff;
x[i + 5] = (l >> 16) & 0xff;
x[i + 6] = (l >> 8) & 0xff;
x[i + 7] = l & 0xff;
}
// prettier-ignore
const K$2 = [
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
];
function crypto_hashblocks_hl(hh, hl, m, n) {
const wh = new Int32Array(16), wl = new Int32Array(16);
let bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h, l, a, b, c, d;
let ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7];
let pos = 0;
while (n >= 128) {
for (i = 0; i < 16; i++) {
j = 8 * i + pos;
wh[i] = (m[j + 0] << 24) | (m[j + 1] << 16) | (m[j + 2] << 8) | m[j + 3];
wl[i] = (m[j + 4] << 24) | (m[j + 5] << 16) | (m[j + 6] << 8) | m[j + 7];
}
for (i = 0; i < 80; i++) {
bh0 = ah0;
bh1 = ah1;
bh2 = ah2;
bh3 = ah3;
bh4 = ah4;
bh5 = ah5;
bh6 = ah6;
bh7 = ah7;
bl0 = al0;
bl1 = al1;
bl2 = al2;
bl3 = al3;
bl4 = al4;
bl5 = al5;
bl6 = al6;
bl7 = al7;
// add
h = ah7;
l = al7;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
// Sigma1
h =
((ah4 >>> 14) | (al4 << (32 - 14))) ^
((ah4 >>> 18) | (al4 << (32 - 18))) ^
((al4 >>> (41 - 32)) | (ah4 << (32 - (41 - 32))));
l =
((al4 >>> 14) | (ah4 << (32 - 14))) ^
((al4 >>> 18) | (ah4 << (32 - 18))) ^
((ah4 >>> (41 - 32)) | (al4 << (32 - (41 - 32))));
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
// Ch
h = (ah4 & ah5) ^ (~ah4 & ah6);
l = (al4 & al5) ^ (~al4 & al6);
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
// K
h = K$2[i * 2];
l = K$2[i * 2 + 1];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
// w
h = wh[i % 16];
l = wl[i % 16];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
th = (c & 0xffff) | (d << 16);
tl = (a & 0xffff) | (b << 16);
// add
h = th;
l = tl;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
// Sigma0
h =
((ah0 >>> 28) | (al0 << (32 - 28))) ^
((al0 >>> (34 - 32)) | (ah0 << (32 - (34 - 32)))) ^
((al0 >>> (39 - 32)) | (ah0 << (32 - (39 - 32))));
l =
((al0 >>> 28) | (ah0 << (32 - 28))) ^
((ah0 >>> (34 - 32)) | (al0 << (32 - (34 - 32)))) ^
((ah0 >>> (39 - 32)) | (al0 << (32 - (39 - 32))));
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
// Maj
h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2);
l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2);
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
bh7 = (c & 0xffff) | (d << 16);
bl7 = (a & 0xffff) | (b << 16);
// add
h = bh3;
l = bl3;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = th;
l = tl;
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
bh3 = (c & 0xffff) | (d << 16);
bl3 = (a & 0xffff) | (b << 16);
ah1 = bh0;
ah2 = bh1;
ah3 = bh2;
ah4 = bh3;
ah5 = bh4;
ah6 = bh5;
ah7 = bh6;
ah0 = bh7;
al1 = bl0;
al2 = bl1;
al3 = bl2;
al4 = bl3;
al5 = bl4;
al6 = bl5;
al7 = bl6;
al0 = bl7;
if (i % 16 === 15) {
for (j = 0; j < 16; j++) {
// add
h = wh[j];
l = wl[j];
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = wh[(j + 9) % 16];
l = wl[(j + 9) % 16];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
// sigma0
th = wh[(j + 1) % 16];
tl = wl[(j + 1) % 16];
h =
((th >>> 1) | (tl << (32 - 1))) ^
((th >>> 8) | (tl << (32 - 8))) ^
(th >>> 7);
l =
((tl >>> 1) | (th << (32 - 1))) ^
((tl >>> 8) | (th << (32 - 8))) ^
((tl >>> 7) | (th << (32 - 7)));
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
// sigma1
th = wh[(j + 14) % 16];
tl = wl[(j + 14) % 16];
h =
((th >>> 19) | (tl << (32 - 19))) ^
((tl >>> (61 - 32)) | (th << (32 - (61 - 32)))) ^
(th >>> 6);
l =
((tl >>> 19) | (th << (32 - 19))) ^
((th >>> (61 - 32)) | (tl << (32 - (61 - 32)))) ^
((tl >>> 6) | (th << (32 - 6)));
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
wh[j] = (c & 0xffff) | (d << 16);
wl[j] = (a & 0xffff) | (b << 16);
}
}
}
// add
h = ah0;
l = al0;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[0];
l = hl[0];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[0] = ah0 = (c & 0xffff) | (d << 16);
hl[0] = al0 = (a & 0xffff) | (b << 16);
h = ah1;
l = al1;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[1];
l = hl[1];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[1] = ah1 = (c & 0xffff) | (d << 16);
hl[1] = al1 = (a & 0xffff) | (b << 16);
h = ah2;
l = al2;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[2];
l = hl[2];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[2] = ah2 = (c & 0xffff) | (d << 16);
hl[2] = al2 = (a & 0xffff) | (b << 16);
h = ah3;
l = al3;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[3];
l = hl[3];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[3] = ah3 = (c & 0xffff) | (d << 16);
hl[3] = al3 = (a & 0xffff) | (b << 16);
h = ah4;
l = al4;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[4];
l = hl[4];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[4] = ah4 = (c & 0xffff) | (d << 16);
hl[4] = al4 = (a & 0xffff) | (b << 16);
h = ah5;
l = al5;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[5];
l = hl[5];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[5] = ah5 = (c & 0xffff) | (d << 16);
hl[5] = al5 = (a & 0xffff) | (b << 16);
h = ah6;
l = al6;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[6];
l = hl[6];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[6] = ah6 = (c & 0xffff) | (d << 16);
hl[6] = al6 = (a & 0xffff) | (b << 16);
h = ah7;
l = al7;
a = l & 0xffff;
b = l >>> 16;
c = h & 0xffff;
d = h >>> 16;
h = hh[7];
l = hl[7];
a += l & 0xffff;
b += l >>> 16;
c += h & 0xffff;
d += h >>> 16;
b += a >>> 16;
c += b >>> 16;
d += c >>> 16;
hh[7] = ah7 = (c & 0xffff) | (d << 16);
hl[7] = al7 = (a & 0xffff) | (b << 16);
pos += 128;
n -= 128;
}
return n;
}
function crypto_hash(out, m, n) {
const hh = new Int32Array(8);
const hl = new Int32Array(8);
const x = new Uint8Array(256);
const b = n;
hh[0] = 0x6a09e667;
hh[1] = 0xbb67ae85;
hh[2] = 0x3c6ef372;
hh[3] = 0xa54ff53a;
hh[4] = 0x510e527f;
hh[5] = 0x9b05688c;
hh[6] = 0x1f83d9ab;
hh[7] = 0x5be0cd19;
hl[0] = 0xf3bcc908;
hl[1] = 0x84caa73b;
hl[2] = 0xfe94f82b;
hl[3] = 0x5f1d36f1;
hl[4] = 0xade682d1;
hl[5] = 0x2b3e6c1f;
hl[6] = 0xfb41bd6b;
hl[7] = 0x137e2179;
crypto_hashblocks_hl(hh, hl, m, n);
n %= 128;
for (let i = 0; i < n; i++)
x[i] = m[b - n + i];
x[n] = 128;
n = 256 - 128 * (n < 112 ? 1 : 0);
x[n - 9] = 0;
ts64(x, n - 8, (b / 0x20000000) | 0, b << 3);
crypto_hashblocks_hl(hh, hl, x, n);
for (let i = 0; i < 8; i++)
ts64(out, 8 * i, hh[i], hl[i]);
return 0;
}
const crypto_hash_BYTES = 64;
function checkArrayTypes(...args) {
for (let i = 0; i < args.length; i++) {
if (!(args[i] instanceof Uint8Array))
throw new TypeError("unexpected type, use Uint8Array");
}
}
function randomBytes(n) {
const b = new Uint8Array(n);
randombytes(b, n);
return b;
}
function hash$1(msg) {
checkArrayTypes(msg);
const h = new Uint8Array(crypto_hash_BYTES);
crypto_hash(h, msg, msg.length);
return h;
}
function setPRNG(fn) {
randombytes = fn;
}
function loadBrowserPrng() {
// Initialize PRNG if environment provides CSPRNG.
// If not, methods calling randombytes will throw.
// @ts-ignore-error
const cr = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
const QUOTA = 65536;
setPRNG(function (x, n) {
let i;
const v = new Uint8Array(n);
for (i = 0; i < n; i += QUOTA) {
cr.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
}
for (i = 0; i < n; i++)
x[i] = v[i];
for (i = 0; i < v.length; i++)
v[i] = 0;
});
}
/*
This file is part of GNU Taler
Copyright (C) 2012-2020 Taler Systems SA
GNU Taler is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
SPDX-License-Identifier: LGPL3.0-or-later
Note: the LGPL does not apply to all components of GNU Taler,
but it does apply to this file.
*/
var TalerErrorCode;
(function (TalerErrorCode) {
/**
* Special code to indicate success (no error).
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["NONE"] = 0] = "NONE";
/**
* A non-integer error code was returned in the JSON response.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["INVALID"] = 1] = "INVALID";
/**
* An internal failure happened on the client side.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_CLIENT_INTERNAL_ERROR"] = 2] = "GENERIC_CLIENT_INTERNAL_ERROR";
/**
* The response we got from the server was not even in JSON format.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_INVALID_RESPONSE"] = 10] = "GENERIC_INVALID_RESPONSE";
/**
* An operation timed out.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_TIMEOUT"] = 11] = "GENERIC_TIMEOUT";
/**
* The version string given does not follow the expected CURRENT:REVISION:AGE Format.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_VERSION_MALFORMED"] = 12] = "GENERIC_VERSION_MALFORMED";
/**
* The service responded with a reply that was in JSON but did not satsify the protocol. Note that invalid cryptographic signatures should have signature-specific error codes.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_REPLY_MALFORMED"] = 13] = "GENERIC_REPLY_MALFORMED";
/**
* There is an error in the client-side configuration, for example the base URL specified is malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_CONFIGURATION_INVALID"] = 14] = "GENERIC_CONFIGURATION_INVALID";
/**
* The HTTP method used is invalid for this endpoint.
* Returned with an HTTP status code of #MHD_HTTP_METHOD_NOT_ALLOWED (405).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_METHOD_INVALID"] = 20] = "GENERIC_METHOD_INVALID";
/**
* There is no endpoint defined for the URL provided by the client.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_ENDPOINT_UNKNOWN"] = 21] = "GENERIC_ENDPOINT_UNKNOWN";
/**
* The JSON in the client's request was malformed (generic parse error).
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_JSON_INVALID"] = 22] = "GENERIC_JSON_INVALID";
/**
* Some of the HTTP headers provided by the client caused the server to not be able to handle the request.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_HTTP_HEADERS_MALFORMED"] = 23] = "GENERIC_HTTP_HEADERS_MALFORMED";
/**
* The payto:// URI provided by the client is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_PAYTO_URI_MALFORMED"] = 24] = "GENERIC_PAYTO_URI_MALFORMED";
/**
* A required parameter in the request was missing.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_PARAMETER_MISSING"] = 25] = "GENERIC_PARAMETER_MISSING";
/**
* A parameter in the request was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_PARAMETER_MALFORMED"] = 26] = "GENERIC_PARAMETER_MALFORMED";
/**
* The currencies involved in the operation do not match.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_CURRENCY_MISMATCH"] = 30] = "GENERIC_CURRENCY_MISMATCH";
/**
* The URI is longer than the longest URI the HTTP server is willing to parse.
* Returned with an HTTP status code of #MHD_HTTP_URI_TOO_LONG (414).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_URI_TOO_LONG"] = 31] = "GENERIC_URI_TOO_LONG";
/**
* The body is too large to be permissible for the endpoint.
* Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_UPLOAD_EXCEEDS_LIMIT"] = 32] = "GENERIC_UPLOAD_EXCEEDS_LIMIT";
/**
* The service failed initialize its connection to the database.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_SETUP_FAILED"] = 50] = "GENERIC_DB_SETUP_FAILED";
/**
* The service encountered an error event to just start the database transaction.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_START_FAILED"] = 51] = "GENERIC_DB_START_FAILED";
/**
* The service failed to store information in its database.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_STORE_FAILED"] = 52] = "GENERIC_DB_STORE_FAILED";
/**
* The service failed to fetch information from its database.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_FETCH_FAILED"] = 53] = "GENERIC_DB_FETCH_FAILED";
/**
* The service encountered an error event to commit the database transaction (hard, unrecoverable error).
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_COMMIT_FAILED"] = 54] = "GENERIC_DB_COMMIT_FAILED";
/**
* The service encountered an error event to commit the database transaction, even after repeatedly retrying it there was always a conflicting transaction. (This indicates a repeated serialization error; should only happen if some client maliciously tries to create conflicting concurrent transactions.)
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_SOFT_FAILURE"] = 55] = "GENERIC_DB_SOFT_FAILURE";
/**
* The service's database is inconsistent and violates service-internal invariants.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_DB_INVARIANT_FAILURE"] = 56] = "GENERIC_DB_INVARIANT_FAILURE";
/**
* The HTTP server experienced an internal invariant failure (bug).
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_INTERNAL_INVARIANT_FAILURE"] = 60] = "GENERIC_INTERNAL_INVARIANT_FAILURE";
/**
* The service could not compute a cryptographic hash over some JSON value.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_FAILED_COMPUTE_JSON_HASH"] = 61] = "GENERIC_FAILED_COMPUTE_JSON_HASH";
/**
* The HTTP server had insufficient memory to parse the request.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_PARSER_OUT_OF_MEMORY"] = 70] = "GENERIC_PARSER_OUT_OF_MEMORY";
/**
* The HTTP server failed to allocate memory.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_ALLOCATION_FAILURE"] = 71] = "GENERIC_ALLOCATION_FAILURE";
/**
* The HTTP server failed to allocate memory for building JSON reply.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_JSON_ALLOCATION_FAILURE"] = 72] = "GENERIC_JSON_ALLOCATION_FAILURE";
/**
* The HTTP server failed to allocate memory for making a CURL request.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["GENERIC_CURL_ALLOCATION_FAILURE"] = 73] = "GENERIC_CURL_ALLOCATION_FAILURE";
/**
* Exchange is badly configured and thus cannot operate.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_BAD_CONFIGURATION"] = 1000] = "EXCHANGE_GENERIC_BAD_CONFIGURATION";
/**
* Operation specified unknown for this endpoint.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_OPERATION_UNKNOWN"] = 1001] = "EXCHANGE_GENERIC_OPERATION_UNKNOWN";
/**
* The number of segments included in the URI does not match the number of segments expected by the endpoint.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS"] = 1002] = "EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS";
/**
* The same coin was already used with a different denomination previously.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY"] = 1003] = "EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY";
/**
* The public key of given to a "/coins/" endpoint of the exchange was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB"] = 1004] = "EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB";
/**
* The exchange is not aware of the denomination key the wallet requested for the operation.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN"] = 1005] = "EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN";
/**
* The signature of the denomination key over the coin is not valid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_SIGNATURE_INVALID"] = 1006] = "EXCHANGE_DENOMINATION_SIGNATURE_INVALID";
/**
* The exchange failed to perform the operation as it could not find the private keys. This is a problem with the exchange setup, not with the client's request.
* Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_KEYS_MISSING"] = 1007] = "EXCHANGE_GENERIC_KEYS_MISSING";
/**
* Validity period of the denomination lies in the future.
* Returned with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED (412).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE"] = 1008] = "EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE";
/**
* Denomination key of the coin is past its expiration time for the requested operation.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_EXPIRED"] = 1009] = "EXCHANGE_GENERIC_DENOMINATION_EXPIRED";
/**
* Denomination key of the coin has been revoked.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_REVOKED"] = 1010] = "EXCHANGE_GENERIC_DENOMINATION_REVOKED";
/**
* An operation where the exchange interacted with a security module timed out.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_SECMOD_TIMEOUT"] = 1011] = "EXCHANGE_GENERIC_SECMOD_TIMEOUT";
/**
* The respective coin did not have sufficient residual value for the operation. The "history" in this response provides the "residual_value" of the coin, which may be less than its "original_value".
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_INSUFFICIENT_FUNDS"] = 1012] = "EXCHANGE_GENERIC_INSUFFICIENT_FUNDS";
/**
* The exchange had an internal error reconstructing the transaction history of the coin that was being processed.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COIN_HISTORY_COMPUTATION_FAILED"] = 1013] = "EXCHANGE_GENERIC_COIN_HISTORY_COMPUTATION_FAILED";
/**
* The exchange failed to obtain the transaction history of the given coin from the database while generating an insufficient funds errors.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS"] = 1014] = "EXCHANGE_GENERIC_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS";
/**
* The same coin was already used with a different age hash previously.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH"] = 1015] = "EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH";
/**
* The requested operation is not valid for the cipher used by the selected denomination.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION"] = 1016] = "EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION";
/**
* The provided arguments for the operation use inconsistent ciphers.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_CIPHER_MISMATCH"] = 1017] = "EXCHANGE_GENERIC_CIPHER_MISMATCH";
/**
* The number of denominations specified in the request exceeds the limit of the exchange.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE"] = 1018] = "EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE";
/**
* The exchange did not find information about the specified transaction in the database.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_NOT_FOUND"] = 1100] = "EXCHANGE_DEPOSITS_GET_NOT_FOUND";
/**
* The wire hash of given to a "/deposits/" handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_H_WIRE"] = 1101] = "EXCHANGE_DEPOSITS_GET_INVALID_H_WIRE";
/**
* The merchant key of given to a "/deposits/" handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_MERCHANT_PUB"] = 1102] = "EXCHANGE_DEPOSITS_GET_INVALID_MERCHANT_PUB";
/**
* The hash of the contract terms given to a "/deposits/" handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_H_CONTRACT_TERMS"] = 1103] = "EXCHANGE_DEPOSITS_GET_INVALID_H_CONTRACT_TERMS";
/**
* The coin public key of given to a "/deposits/" handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_COIN_PUB"] = 1104] = "EXCHANGE_DEPOSITS_GET_INVALID_COIN_PUB";
/**
* The signature returned by the exchange in a /deposits/ request was malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE"] = 1105] = "EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE";
/**
* The signature of the merchant is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID"] = 1106] = "EXCHANGE_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID";
/**
* The given reserve does not have sufficient funds to admit the requested withdraw operation at this time. The response includes the current "balance" of the reserve as well as the transaction "history" that lead to this balance.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS"] = 1150] = "EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS";
/**
* The exchange has no information about the "reserve_pub" that was given.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_RESERVE_UNKNOWN"] = 1151] = "EXCHANGE_WITHDRAW_RESERVE_UNKNOWN";
/**
* The amount to withdraw together with the fee exceeds the numeric range for Taler amounts. This is not a client failure, as the coin value and fees come from the exchange's configuration.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW"] = 1152] = "EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW";
/**
* The exchange failed to create the signature using the denomination key.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_SIGNATURE_FAILED"] = 1153] = "EXCHANGE_WITHDRAW_SIGNATURE_FAILED";
/**
* The signature of the reserve is not valid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID"] = 1154] = "EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID";
/**
* When computing the reserve history, we ended up with a negative overall balance, which should be impossible.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS"] = 1155] = "EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS";
/**
* Withdraw period of the coin to be withdrawn is in the past.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_DENOMINATION_KEY_LOST"] = 1158] = "EXCHANGE_WITHDRAW_DENOMINATION_KEY_LOST";
/**
* The client failed to unblind the blind signature.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_UNBLIND_FAILURE"] = 1159] = "EXCHANGE_WITHDRAW_UNBLIND_FAILURE";
/**
* The signature made by the coin over the deposit permission is not valid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID"] = 1205] = "EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID";
/**
* The same coin was already deposited for the same merchant and contract with other details.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT"] = 1206] = "EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT";
/**
* The stated value of the coin after the deposit fee is subtracted would be negative.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE"] = 1207] = "EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE";
/**
* The stated refund deadline is after the wire deadline.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE"] = 1208] = "EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE";
/**
* The stated wire deadline is "never", which makes no sense.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER"] = 1209] = "EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER";
/**
* The exchange failed to canonicalize and hash the given wire format. For example, the merchant failed to provide the "salt" or a valid payto:// URI in the wire details. Note that while the exchange will do some basic sanity checking on the wire details, it cannot warrant that the banking system will ultimately be able to route to the specified address, even if this check passed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_JSON"] = 1210] = "EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_JSON";
/**
* The hash of the given wire address does not match the wire hash specified in the proposal data.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT"] = 1211] = "EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT";
/**
* The signature provided by the exchange is not valid.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE"] = 1221] = "EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE";
/**
* The deposited amount is smaller than the deposit fee, which would result in a negative contribution.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT"] = 1222] = "EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT";
/**
* The reserve status was requested using a unknown key.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_GET_STATUS_UNKNOWN"] = 1250] = "EXCHANGE_RESERVES_GET_STATUS_UNKNOWN";
/**
* The exchange encountered melt fees exceeding the melted coin's contribution.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_FEES_EXCEED_CONTRIBUTION"] = 1302] = "EXCHANGE_MELT_FEES_EXCEED_CONTRIBUTION";
/**
* The signature made with the coin to be melted is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_COIN_SIGNATURE_INVALID"] = 1303] = "EXCHANGE_MELT_COIN_SIGNATURE_INVALID";
/**
* The denomination of the given coin has past its expiration date and it is also not a valid zombie (that is, was not refreshed with the fresh coin being subjected to recoup).
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_COIN_EXPIRED_NO_ZOMBIE"] = 1305] = "EXCHANGE_MELT_COIN_EXPIRED_NO_ZOMBIE";
/**
* The signature returned by the exchange in a melt request was malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE"] = 1306] = "EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE";
/**
* The provided transfer keys do not match up with the original commitment. Information about the original commitment is included in the response.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_COMMITMENT_VIOLATION"] = 1353] = "EXCHANGE_REFRESHES_REVEAL_COMMITMENT_VIOLATION";
/**
* Failed to produce the blinded signatures over the coins to be returned.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_SIGNING_ERROR"] = 1354] = "EXCHANGE_REFRESHES_REVEAL_SIGNING_ERROR";
/**
* The exchange is unaware of the refresh session specified in the request.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_SESSION_UNKNOWN"] = 1355] = "EXCHANGE_REFRESHES_REVEAL_SESSION_UNKNOWN";
/**
* The size of the cut-and-choose dimension of the private transfer keys request does not match #TALER_CNC_KAPPA - 1.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID"] = 1356] = "EXCHANGE_REFRESHES_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID";
/**
* The number of envelopes given does not match the number of denomination keys given.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISMATCH"] = 1358] = "EXCHANGE_REFRESHES_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISMATCH";
/**
* The exchange encountered a numeric overflow totaling up the cost for the refresh operation.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_COST_CALCULATION_OVERFLOW"] = 1359] = "EXCHANGE_REFRESHES_REVEAL_COST_CALCULATION_OVERFLOW";
/**
* The exchange's cost calculation shows that the melt amount is below the costs of the transaction.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_AMOUNT_INSUFFICIENT"] = 1360] = "EXCHANGE_REFRESHES_REVEAL_AMOUNT_INSUFFICIENT";
/**
* The signature made with the coin over the link data is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID"] = 1361] = "EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID";
/**
* The refresh session hash given to a /refreshes/ handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_INVALID_RCH"] = 1362] = "EXCHANGE_REFRESHES_REVEAL_INVALID_RCH";
/**
* Operation specified invalid for this endpoint.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_OPERATION_INVALID"] = 1363] = "EXCHANGE_REFRESHES_REVEAL_OPERATION_INVALID";
/**
* The client provided age commitment data, but age restriction is not supported on this server.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_NOT_SUPPORTED"] = 1364] = "EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_NOT_SUPPORTED";
/**
* The client provided invalid age commitment data: missing, not an array, or array of invalid size.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_COMMITMENT_INVALID"] = 1365] = "EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_COMMITMENT_INVALID";
/**
* The coin specified in the link request is unknown to the exchange.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_LINK_COIN_UNKNOWN"] = 1400] = "EXCHANGE_LINK_COIN_UNKNOWN";
/**
* The public key of given to a /transfers/ handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WTID_MALFORMED"] = 1450] = "EXCHANGE_TRANSFERS_GET_WTID_MALFORMED";
/**
* The exchange did not find information about the specified wire transfer identifier in the database.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WTID_NOT_FOUND"] = 1451] = "EXCHANGE_TRANSFERS_GET_WTID_NOT_FOUND";
/**
* The exchange did not find information about the wire transfer fees it charged.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WIRE_FEE_NOT_FOUND"] = 1452] = "EXCHANGE_TRANSFERS_GET_WIRE_FEE_NOT_FOUND";
/**
* The exchange found a wire fee that was above the total transfer value (and thus could not have been charged).
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WIRE_FEE_INCONSISTENT"] = 1453] = "EXCHANGE_TRANSFERS_GET_WIRE_FEE_INCONSISTENT";
/**
* The exchange knows literally nothing about the coin we were asked to refund. But without a transaction history, we cannot issue a refund. This is kind-of OK, the owner should just refresh it directly without executing the refund.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_COIN_NOT_FOUND"] = 1500] = "EXCHANGE_REFUND_COIN_NOT_FOUND";
/**
* We could not process the refund request as the coin's transaction history does not permit the requested refund because then refunds would exceed the deposit amount. The "history" in the response proves this.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_CONFLICT_DEPOSIT_INSUFFICIENT"] = 1501] = "EXCHANGE_REFUND_CONFLICT_DEPOSIT_INSUFFICIENT";
/**
* The exchange knows about the coin we were asked to refund, but not about the specific /deposit operation. Hence, we cannot issue a refund (as we do not know if this merchant public key is authorized to do a refund).
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_DEPOSIT_NOT_FOUND"] = 1502] = "EXCHANGE_REFUND_DEPOSIT_NOT_FOUND";
/**
* The exchange can no longer refund the customer/coin as the money was already transferred (paid out) to the merchant. (It should be past the refund deadline.)
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_MERCHANT_ALREADY_PAID"] = 1503] = "EXCHANGE_REFUND_MERCHANT_ALREADY_PAID";
/**
* The refund fee specified for the request is lower than the refund fee charged by the exchange for the given denomination key of the refunded coin.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_FEE_TOO_LOW"] = 1504] = "EXCHANGE_REFUND_FEE_TOO_LOW";
/**
* The refunded amount is smaller than the refund fee, which would result in a negative refund.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_FEE_ABOVE_AMOUNT"] = 1505] = "EXCHANGE_REFUND_FEE_ABOVE_AMOUNT";
/**
* The signature of the merchant is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID"] = 1506] = "EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID";
/**
* Merchant backend failed to create the refund confirmation signature.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_MERCHANT_SIGNING_FAILED"] = 1507] = "EXCHANGE_REFUND_MERCHANT_SIGNING_FAILED";
/**
* The signature returned by the exchange in a refund request was malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE"] = 1508] = "EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE";
/**
* The failure proof returned by the exchange is incorrect.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE"] = 1509] = "EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE";
/**
* Conflicting refund granted before with different amount but same refund transaction ID.
* Returned with an HTTP status code of #MHD_HTTP_FAILED_DEPENDENCY (424).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_INCONSISTENT_AMOUNT"] = 1510] = "EXCHANGE_REFUND_INCONSISTENT_AMOUNT";
/**
* The given coin signature is invalid for the request.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_SIGNATURE_INVALID"] = 1550] = "EXCHANGE_RECOUP_SIGNATURE_INVALID";
/**
* The exchange could not find the corresponding withdraw operation. The request is denied.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_WITHDRAW_NOT_FOUND"] = 1551] = "EXCHANGE_RECOUP_WITHDRAW_NOT_FOUND";
/**
* The coin's remaining balance is zero. The request is denied.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_COIN_BALANCE_ZERO"] = 1552] = "EXCHANGE_RECOUP_COIN_BALANCE_ZERO";
/**
* The exchange failed to reproduce the coin's blinding.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_BLINDING_FAILED"] = 1553] = "EXCHANGE_RECOUP_BLINDING_FAILED";
/**
* The coin's remaining balance is zero. The request is denied.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_COIN_BALANCE_NEGATIVE"] = 1554] = "EXCHANGE_RECOUP_COIN_BALANCE_NEGATIVE";
/**
* The coin's denomination has not been revoked yet.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_NOT_ELIGIBLE"] = 1555] = "EXCHANGE_RECOUP_NOT_ELIGIBLE";
/**
* The given coin signature is invalid for the request.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_SIGNATURE_INVALID"] = 1575] = "EXCHANGE_RECOUP_REFRESH_SIGNATURE_INVALID";
/**
* The exchange could not find the corresponding melt operation. The request is denied.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_MELT_NOT_FOUND"] = 1576] = "EXCHANGE_RECOUP_REFRESH_MELT_NOT_FOUND";
/**
* The exchange failed to reproduce the coin's blinding.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED"] = 1578] = "EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED";
/**
* The coin's denomination has not been revoked yet.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_NOT_ELIGIBLE"] = 1580] = "EXCHANGE_RECOUP_REFRESH_NOT_ELIGIBLE";
/**
* This exchange does not allow clients to request /keys for times other than the current (exchange) time.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_KEYS_TIMETRAVEL_FORBIDDEN"] = 1600] = "EXCHANGE_KEYS_TIMETRAVEL_FORBIDDEN";
/**
* A signature in the server's response was malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_SIGNATURE_INVALID"] = 1650] = "EXCHANGE_WIRE_SIGNATURE_INVALID";
/**
* No bank accounts are enabled for the exchange. The administrator should enable-account using the taler-exchange-offline tool.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED"] = 1651] = "EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED";
/**
* The payto:// URI stored in the exchange database for its bank account is malformed.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED"] = 1652] = "EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED";
/**
* No wire fees are configured for an enabled wire method of the exchange. The administrator must set the wire-fee using the taler-exchange-offline tool.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_FEES_NOT_CONFIGURED"] = 1653] = "EXCHANGE_WIRE_FEES_NOT_CONFIGURED";
/**
* The exchange failed to talk to the process responsible for its private denomination keys.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE"] = 1700] = "EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE";
/**
* The response from the denomination key helper process was malformed.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_HELPER_BUG"] = 1701] = "EXCHANGE_DENOMINATION_HELPER_BUG";
/**
* The helper refuses to sign with the key, because it is too early: the validity period has not yet started.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_HELPER_TOO_EARLY"] = 1702] = "EXCHANGE_DENOMINATION_HELPER_TOO_EARLY";
/**
* The exchange failed to talk to the process responsible for its private signing keys.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE"] = 1750] = "EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE";
/**
* The response from the online signing key helper process was malformed.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_SIGNKEY_HELPER_BUG"] = 1751] = "EXCHANGE_SIGNKEY_HELPER_BUG";
/**
* The helper refuses to sign with the key, because it is too early: the validity period has not yet started.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_SIGNKEY_HELPER_TOO_EARLY"] = 1752] = "EXCHANGE_SIGNKEY_HELPER_TOO_EARLY";
/**
* The auditor that was supposed to be disabled is unknown to this exchange.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_NOT_FOUND"] = 1800] = "EXCHANGE_MANAGEMENT_AUDITOR_NOT_FOUND";
/**
* The exchange has a more recently signed conflicting instruction and is thus refusing the current change (replay detected).
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_MORE_RECENT_PRESENT"] = 1801] = "EXCHANGE_MANAGEMENT_AUDITOR_MORE_RECENT_PRESENT";
/**
* The signature to add or enable the auditor does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID"] = 1802] = "EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID";
/**
* The signature to disable the auditor does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID"] = 1803] = "EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID";
/**
* The signature to revoke the denomination does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID"] = 1804] = "EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID";
/**
* The signature to revoke the online signing key does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID"] = 1805] = "EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID";
/**
* The exchange has a more recently signed conflicting instruction and is thus refusing the current change (replay detected).
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_MORE_RECENT_PRESENT"] = 1806] = "EXCHANGE_MANAGEMENT_WIRE_MORE_RECENT_PRESENT";
/**
* The signingkey specified is unknown to the exchange.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN"] = 1807] = "EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN";
/**
* The signature to publish wire account does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_DETAILS_SIGNATURE_INVALID"] = 1808] = "EXCHANGE_MANAGEMENT_WIRE_DETAILS_SIGNATURE_INVALID";
/**
* The signature to add the wire account does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID"] = 1809] = "EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID";
/**
* The signature to disable the wire account does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID"] = 1810] = "EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID";
/**
* The wire account to be disabled is unknown to the exchange.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_NOT_FOUND"] = 1811] = "EXCHANGE_MANAGEMENT_WIRE_NOT_FOUND";
/**
* The signature to affirm wire fees does not validate.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID"] = 1812] = "EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID";
/**
* The signature conflicts with a previous signature affirming different fees.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_FEE_MISMATCH"] = 1813] = "EXCHANGE_MANAGEMENT_WIRE_FEE_MISMATCH";
/**
* The signature affirming the denomination key is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID"] = 1814] = "EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID";
/**
* The signature affirming the signing key is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID"] = 1815] = "EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID";
/**
* The signature conflicts with a previous signature affirming different fees.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_GLOBAL_FEE_MISMATCH"] = 1816] = "EXCHANGE_MANAGEMENT_GLOBAL_FEE_MISMATCH";
/**
* The signature affirming the fee structure is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_GLOBAL_FEE_SIGNATURE_INVALID"] = 1817] = "EXCHANGE_MANAGEMENT_GLOBAL_FEE_SIGNATURE_INVALID";
/**
* The auditor signature over the denomination meta data is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_AUDITORS_AUDITOR_SIGNATURE_INVALID"] = 1900] = "EXCHANGE_AUDITORS_AUDITOR_SIGNATURE_INVALID";
/**
* The auditor that was specified is unknown to this exchange.
* Returned with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED (412).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_AUDITORS_AUDITOR_UNKNOWN"] = 1901] = "EXCHANGE_AUDITORS_AUDITOR_UNKNOWN";
/**
* The auditor that was specified is no longer used by this exchange.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_AUDITORS_AUDITOR_INACTIVE"] = 1902] = "EXCHANGE_AUDITORS_AUDITOR_INACTIVE";
/**
* The signature affirming the wallet's KYC request was invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_WALLET_SIGNATURE_INVALID"] = 1925] = "EXCHANGE_KYC_WALLET_SIGNATURE_INVALID";
/**
* The exchange received an unexpected malformed response from its KYC backend.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE"] = 1926] = "EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE";
/**
* The backend signaled an unexpected failure.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_BACKEND_ERROR"] = 1927] = "EXCHANGE_KYC_PROOF_BACKEND_ERROR";
/**
* The backend signaled an authorization failure.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_BACKEND_AUTHORIZATION_FAILED"] = 1928] = "EXCHANGE_KYC_PROOF_BACKEND_AUTHORIZATION_FAILED";
/**
* The payto-URI hash did not match. Hence the request was denied.
* Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED"] = 1930] = "EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED";
/**
* The backend could not find the merchant instance specified in the request.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_INSTANCE_UNKNOWN"] = 2000] = "MERCHANT_GENERIC_INSTANCE_UNKNOWN";
/**
* The start and end-times in the wire fee structure leave a hole. This is not allowed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_HOLE_IN_WIRE_FEE_STRUCTURE"] = 2001] = "MERCHANT_GENERIC_HOLE_IN_WIRE_FEE_STRUCTURE";
/**
* The reserve key of given to a /reserves/ handler was malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_RESERVE_PUB_MALFORMED"] = 2002] = "MERCHANT_GENERIC_RESERVE_PUB_MALFORMED";
/**
* The backend could not locate a required template to generate an HTML reply.
* Returned with an HTTP status code of #MHD_HTTP_NOT_ACCEPTABLE (406).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_FAILED_TO_LOAD_TEMPLATE"] = 2003] = "MERCHANT_GENERIC_FAILED_TO_LOAD_TEMPLATE";
/**
* The backend could not expand the template to generate an HTML reply.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_FAILED_TO_EXPAND_TEMPLATE"] = 2004] = "MERCHANT_GENERIC_FAILED_TO_EXPAND_TEMPLATE";
/**
* The proposal is not known to the backend.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_ORDER_UNKNOWN"] = 2005] = "MERCHANT_GENERIC_ORDER_UNKNOWN";
/**
* The order provided to the backend could not be completed, because a product to be completed via inventory data is not actually in our inventory.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_PRODUCT_UNKNOWN"] = 2006] = "MERCHANT_GENERIC_PRODUCT_UNKNOWN";
/**
* The tip ID is unknown. This could happen if the tip has expired.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_TIP_ID_UNKNOWN"] = 2007] = "MERCHANT_GENERIC_TIP_ID_UNKNOWN";
/**
* The contract obtained from the merchant backend was malformed.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID"] = 2008] = "MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID";
/**
* The order we found does not match the provided contract hash.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_CONTRACT_HASH_DOES_NOT_MATCH_ORDER"] = 2009] = "MERCHANT_GENERIC_CONTRACT_HASH_DOES_NOT_MATCH_ORDER";
/**
* The exchange failed to provide a valid response to the merchant's /keys request.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE"] = 2010] = "MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE";
/**
* The exchange failed to respond to the merchant on time.
* Returned with an HTTP status code of #MHD_HTTP_GATEWAY_TIMEOUT (504).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_TIMEOUT"] = 2011] = "MERCHANT_GENERIC_EXCHANGE_TIMEOUT";
/**
* The merchant failed to talk to the exchange.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE"] = 2012] = "MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE";
/**
* The exchange returned a maformed response.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED"] = 2013] = "MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED";
/**
* The exchange returned an unexpected response status.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS"] = 2014] = "MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS";
/**
* The merchant refused the request due to lack of authorization.
* Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_UNAUTHORIZED"] = 2015] = "MERCHANT_GENERIC_UNAUTHORIZED";
/**
* The merchant instance specified in the request was deleted.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_INSTANCE_DELETED"] = 2016] = "MERCHANT_GENERIC_INSTANCE_DELETED";
/**
* The backend could not find the inbound wire transfer specified in the request.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_TRANSFER_UNKNOWN"] = 2017] = "MERCHANT_GENERIC_TRANSFER_UNKNOWN";
/**
* The exchange failed to provide a valid answer to the tracking request, thus those details are not in the response.
* Returned with an HTTP status code of #MHD_HTTP_OK (200).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_EXCHANGE_TRACKING_FAILURE"] = 2100] = "MERCHANT_GET_ORDERS_EXCHANGE_TRACKING_FAILURE";
/**
* The merchant backend failed to construct the request for tracking to the exchange, thus tracking details are not in the response.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_EXCHANGE_REQUEST_FAILURE"] = 2103] = "MERCHANT_GET_ORDERS_ID_EXCHANGE_REQUEST_FAILURE";
/**
* The merchant backend failed trying to contact the exchange for tracking details, thus those details are not in the response.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_EXCHANGE_LOOKUP_START_FAILURE"] = 2104] = "MERCHANT_GET_ORDERS_ID_EXCHANGE_LOOKUP_START_FAILURE";
/**
* The claim token used to authenticate the client is invalid for this order.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_INVALID_TOKEN"] = 2105] = "MERCHANT_GET_ORDERS_ID_INVALID_TOKEN";
/**
* The contract terms hash used to authenticate the client is invalid for this order.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_INVALID_CONTRACT_HASH"] = 2106] = "MERCHANT_GET_ORDERS_ID_INVALID_CONTRACT_HASH";
/**
* The exchange responded saying that funds were insufficient (for example, due to double-spending).
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS"] = 2150] = "MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS";
/**
* The denomination key used for payment is not listed among the denomination keys of the exchange.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND"] = 2151] = "MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND";
/**
* The denomination key used for payment is not audited by an auditor approved by the merchant.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_AUDITOR_FAILURE"] = 2152] = "MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_AUDITOR_FAILURE";
/**
* There was an integer overflow totaling up the amounts or deposit fees in the payment.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW"] = 2153] = "MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW";
/**
* The deposit fees exceed the total value of the payment.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT"] = 2154] = "MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT";
/**
* After considering deposit and wire fees, the payment is insufficient to satisfy the required amount for the contract. The client should revisit the logic used to calculate fees it must cover.
* Returned with an HTTP status code of #MHD_HTTP_NOT_ACCEPTABLE (406).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES"] = 2155] = "MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES";
/**
* Even if we do not consider deposit and wire fees, the payment is insufficient to satisfy the required amount for the contract.
* Returned with an HTTP status code of #MHD_HTTP_NOT_ACCEPTABLE (406).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT"] = 2156] = "MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT";
/**
* The signature over the contract of one of the coins was invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_COIN_SIGNATURE_INVALID"] = 2157] = "MERCHANT_POST_ORDERS_ID_PAY_COIN_SIGNATURE_INVALID";
/**
* When we tried to find information about the exchange to issue the deposit, we failed. This usually only happens if the merchant backend is somehow unable to get its own HTTP client logic to work.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED"] = 2158] = "MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED";
/**
* The refund deadline in the contract is after the transfer deadline.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE"] = 2159] = "MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE";
/**
* The payment is too late, the offer has expired.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED"] = 2161] = "MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED";
/**
* The "merchant" field is missing in the proposal data. This is an internal error as the proposal is from the merchant's own database at this point.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING"] = 2162] = "MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING";
/**
* Failed to locate merchant's account information matching the wire hash given in the proposal.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN"] = 2163] = "MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN";
/**
* The deposit time for the denomination has expired.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED"] = 2165] = "MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED";
/**
* The exchange of the deposited coin charges a wire fee that could not be added to the total (total amount too high).
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED"] = 2166] = "MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED";
/**
* The contract was not fully paid because of refunds. Note that clients MAY treat this as paid if, for example, contracts must be executed despite of refunds.
* Returned with an HTTP status code of #MHD_HTTP_PAYMENT_REQUIRED (402).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_REFUNDED"] = 2167] = "MERCHANT_POST_ORDERS_ID_PAY_REFUNDED";
/**
* According to our database, we have refunded more than we were paid (which should not be possible).
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_REFUNDS_EXCEED_PAYMENTS"] = 2168] = "MERCHANT_POST_ORDERS_ID_PAY_REFUNDS_EXCEED_PAYMENTS";
/**
* Legacy stuff. Remove me with protocol v1.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["DEAD_QQQ_PAY_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE"] = 2169] = "DEAD_QQQ_PAY_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE";
/**
* The payment failed at the exchange.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_FAILED"] = 2170] = "MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_FAILED";
/**
* The contract hash does not match the given order ID.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH"] = 2200] = "MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH";
/**
* The signature of the merchant is not valid for the given contract hash.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID"] = 2201] = "MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID";
/**
* The merchant failed to send the exchange the refund request.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED"] = 2251] = "MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED";
/**
* The merchant failed to find the exchange to process the lookup.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED"] = 2252] = "MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED";
/**
* The merchant could not find the contract.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND"] = 2253] = "MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND";
/**
* The payment was already completed and thus cannot be aborted anymore.
* Returned with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED (412).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE"] = 2254] = "MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE";
/**
* The hash provided by the wallet does not match the order.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH"] = 2255] = "MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH";
/**
* The array of coins cannot be empty.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY"] = 2256] = "MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY";
/**
* We could not claim the order because the backend is unaware of it.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND"] = 2300] = "MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND";
/**
* We could not claim the order because someone else claimed it first.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED"] = 2301] = "MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED";
/**
* The client-side experienced an internal failure.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE"] = 2302] = "MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE";
/**
* The backend failed to sign the refund request.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_REFUND_SIGNATURE_FAILED"] = 2350] = "MERCHANT_POST_ORDERS_ID_REFUND_SIGNATURE_FAILED";
/**
* The client failed to unblind the signature returned by the merchant.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_UNBLIND_FAILURE"] = 2400] = "MERCHANT_TIP_PICKUP_UNBLIND_FAILURE";
/**
* The exchange returned a failure code for the withdraw operation.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_EXCHANGE_ERROR"] = 2403] = "MERCHANT_TIP_PICKUP_EXCHANGE_ERROR";
/**
* The merchant failed to add up the amounts to compute the pick up value.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_SUMMATION_FAILED"] = 2404] = "MERCHANT_TIP_PICKUP_SUMMATION_FAILED";
/**
* The tip expired.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_HAS_EXPIRED"] = 2405] = "MERCHANT_TIP_PICKUP_HAS_EXPIRED";
/**
* The requested withdraw amount exceeds the amount remaining to be picked up.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING"] = 2406] = "MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING";
/**
* The merchant did not find the specified denomination key in the exchange's key set.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_DENOMINATION_UNKNOWN"] = 2407] = "MERCHANT_TIP_PICKUP_DENOMINATION_UNKNOWN";
/**
* The backend lacks a wire transfer method configuration option for the given instance. Thus, this instance is unavailable (not findable for creating new orders).
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_INSTANCE_CONFIGURATION_LACKS_WIRE"] = 2500] = "MERCHANT_PRIVATE_POST_ORDERS_INSTANCE_CONFIGURATION_LACKS_WIRE";
/**
* The proposal had no timestamp and the backend failed to obtain the local time. Likely to be an internal error.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_NO_LOCALTIME"] = 2501] = "MERCHANT_PRIVATE_POST_ORDERS_NO_LOCALTIME";
/**
* The order provided to the backend could not be parsed, some required fields were missing or ill-formed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR"] = 2502] = "MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR";
/**
* The backend encountered an error: the proposal already exists.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS"] = 2503] = "MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS";
/**
* The request is invalid: the wire deadline is before the refund deadline.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_REFUND_AFTER_WIRE_DEADLINE"] = 2504] = "MERCHANT_PRIVATE_POST_ORDERS_REFUND_AFTER_WIRE_DEADLINE";
/**
* The request is invalid: a delivery date was given, but it is in the past.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_DELIVERY_DATE_IN_PAST"] = 2505] = "MERCHANT_PRIVATE_POST_ORDERS_DELIVERY_DATE_IN_PAST";
/**
* The request is invalid: the wire deadline for the order would be "never".
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_WIRE_DEADLINE_IS_NEVER"] = 2506] = "MERCHANT_PRIVATE_POST_ORDERS_WIRE_DEADLINE_IS_NEVER";
/**
* One of the paths to forget is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_SYNTAX_INCORRECT"] = 2510] = "MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_SYNTAX_INCORRECT";
/**
* One of the paths to forget was not marked as forgettable.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_NOT_FORGETTABLE"] = 2511] = "MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_NOT_FORGETTABLE";
/**
* The order provided to the backend could not be deleted, our offer is still valid and awaiting payment.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_ORDERS_AWAITING_PAYMENT"] = 2520] = "MERCHANT_PRIVATE_DELETE_ORDERS_AWAITING_PAYMENT";
/**
* The amount to be refunded is inconsistent: either is lower than the previous amount being awarded, or it is too big to be paid back. In this second case, the fault stays on the business dept. side.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_INCONSISTENT_AMOUNT"] = 2530] = "MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_INCONSISTENT_AMOUNT";
/**
* The frontend gave an unpaid order id to issue the refund to.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_ORDER_UNPAID"] = 2531] = "MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_ORDER_UNPAID";
/**
* The refund delay was set to 0 and thus no refunds are allowed for this order.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_NOT_ALLOWED_BY_CONTRACT"] = 2532] = "MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_NOT_ALLOWED_BY_CONTRACT";
/**
* The exchange says it does not know this transfer.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_EXCHANGE_UNKNOWN"] = 2550] = "MERCHANT_PRIVATE_POST_TRANSFERS_EXCHANGE_UNKNOWN";
/**
* We internally failed to execute the /track/transfer request.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_REQUEST_ERROR"] = 2551] = "MERCHANT_PRIVATE_POST_TRANSFERS_REQUEST_ERROR";
/**
* The amount transferred differs between what was submitted and what the exchange claimed.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_TRANSFERS"] = 2552] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_TRANSFERS";
/**
* The exchange gave conflicting information about a coin which has been wire transferred.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS"] = 2553] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS";
/**
* The exchange charged a different wire fee than what it originally advertised, and it is higher.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE"] = 2554] = "MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE";
/**
* We did not find the account that the transfer was made to.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND"] = 2555] = "MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND";
/**
* The backend could not delete the transfer as the echange already replied to our inquiry about it and we have integrated the result.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED"] = 2556] = "MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED";
/**
* The backend was previously informed about a wire transfer with the same ID but a different amount. Multiple wire transfers with the same ID are not allowed. If the new amount is correct, the old transfer should first be deleted.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION"] = 2557] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION";
/**
* The merchant backend cannot create an instance under the given identifier as one already exists. Use PATCH to modify the existing entry.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS"] = 2600] = "MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS";
/**
* The merchant backend cannot create an instance because the authentication configuration field is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH"] = 2601] = "MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH";
/**
* The merchant backend cannot update an instance's authentication settings because the provided authentication settings are malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH"] = 2602] = "MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH";
/**
* The merchant backend cannot create an instance under the given identifier, the previous one was deleted but must be purged first.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCES_PURGE_REQUIRED"] = 2603] = "MERCHANT_PRIVATE_POST_INSTANCES_PURGE_REQUIRED";
/**
* The merchant backend cannot update an instance under the given identifier, the previous one was deleted but must be purged first.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_INSTANCES_PURGE_REQUIRED"] = 2625] = "MERCHANT_PRIVATE_PATCH_INSTANCES_PURGE_REQUIRED";
/**
* The product ID exists.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS"] = 2650] = "MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS";
/**
* The update would have reduced the total amount of product lost, which is not allowed.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_REDUCED"] = 2660] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_REDUCED";
/**
* The update would have mean that more stocks were lost than what remains from total inventory after sales, which is not allowed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS"] = 2661] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS";
/**
* The update would have reduced the total amount of product in stock, which is not allowed.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_STOCKED_REDUCED"] = 2662] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_STOCKED_REDUCED";
/**
* The update would have reduced the total amount of product sold, which is not allowed.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_SOLD_REDUCED"] = 2663] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_SOLD_REDUCED";
/**
* The lock request is for more products than we have left (unlocked) in stock.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_PRODUCTS_LOCK_INSUFFICIENT_STOCKS"] = 2670] = "MERCHANT_PRIVATE_POST_PRODUCTS_LOCK_INSUFFICIENT_STOCKS";
/**
* The deletion request is for a product that is locked.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_PRODUCTS_CONFLICTING_LOCK"] = 2680] = "MERCHANT_PRIVATE_DELETE_PRODUCTS_CONFLICTING_LOCK";
/**
* The requested wire method is not supported by the exchange.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD"] = 2700] = "MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD";
/**
* The reserve could not be deleted because it is unknown.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_RESERVES_NO_SUCH_RESERVE"] = 2710] = "MERCHANT_PRIVATE_DELETE_RESERVES_NO_SUCH_RESERVE";
/**
* The reserve that was used to fund the tips has expired.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_EXPIRED"] = 2750] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_EXPIRED";
/**
* The reserve that was used to fund the tips was not found in the DB.
* Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_UNKNOWN"] = 2751] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_UNKNOWN";
/**
* The backend knows the instance that was supposed to support the tip, and it was configured for tipping. However, the funds remaining are insufficient to cover the tip, and the merchant should top up the reserve.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_INSUFFICIENT_FUNDS"] = 2752] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_INSUFFICIENT_FUNDS";
/**
* The backend failed to find a reserve needed to authorize the tip.
* Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_NOT_FOUND"] = 2753] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_NOT_FOUND";
/**
* The merchant backend encountered a failure in computing the deposit total.
* Returned with an HTTP status code of #MHD_HTTP_OK (200).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_GET_ORDERS_ID_AMOUNT_ARITHMETIC_FAILURE"] = 2800] = "MERCHANT_PRIVATE_GET_ORDERS_ID_AMOUNT_ARITHMETIC_FAILURE";
/**
* The signature from the exchange on the deposit confirmation is invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["AUDITOR_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID"] = 3100] = "AUDITOR_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID";
/**
* The exchange key used for the signature on the deposit confirmation was revoked.
* Returned with an HTTP status code of #MHD_HTTP_GONE (410).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["AUDITOR_EXCHANGE_SIGNING_KEY_REVOKED"] = 3101] = "AUDITOR_EXCHANGE_SIGNING_KEY_REVOKED";
/**
* Wire transfer attempted with credit and debit party being the same bank account.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_SAME_ACCOUNT"] = 5101] = "BANK_SAME_ACCOUNT";
/**
* Wire transfer impossible, due to financial limitation of the party that attempted the payment.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_UNALLOWED_DEBIT"] = 5102] = "BANK_UNALLOWED_DEBIT";
/**
* Negative number was used (as value and/or fraction) to initiate a Amount object.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_NEGATIVE_NUMBER_AMOUNT"] = 5103] = "BANK_NEGATIVE_NUMBER_AMOUNT";
/**
* A number too big was used (as value and/or fraction) to initiate a amount object.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_NUMBER_TOO_BIG"] = 5104] = "BANK_NUMBER_TOO_BIG";
/**
* Could not login for the requested operation.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_LOGIN_FAILED"] = 5105] = "BANK_LOGIN_FAILED";
/**
* The bank account referenced in the requested operation was not found. Returned along "400 Not found".
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_UNKNOWN_ACCOUNT"] = 5106] = "BANK_UNKNOWN_ACCOUNT";
/**
* The transaction referenced in the requested operation (typically a reject operation), was not found.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_TRANSACTION_NOT_FOUND"] = 5107] = "BANK_TRANSACTION_NOT_FOUND";
/**
* Bank received a malformed amount string.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_BAD_FORMAT_AMOUNT"] = 5108] = "BANK_BAD_FORMAT_AMOUNT";
/**
* The client does not own the account credited by the transaction which is to be rejected, so it has no rights do reject it. To be returned along HTTP 403 Forbidden.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_REJECT_NO_RIGHTS"] = 5109] = "BANK_REJECT_NO_RIGHTS";
/**
* This error code is returned when no known exception types captured the exception, and comes along with a 500 Internal Server Error.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_UNMANAGED_EXCEPTION"] = 5110] = "BANK_UNMANAGED_EXCEPTION";
/**
* This error code is used for all those exceptions that do not really need a specific error code to return to the client, but need to signal the middleware that the bank is not responding with 500 Internal Server Error. Used for example when a client is trying to register with a unavailable username.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_SOFT_EXCEPTION"] = 5111] = "BANK_SOFT_EXCEPTION";
/**
* The request UID for a request to transfer funds has already been used, but with different details for the transfer.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_TRANSFER_REQUEST_UID_REUSED"] = 5112] = "BANK_TRANSFER_REQUEST_UID_REUSED";
/**
* The withdrawal operation already has a reserve selected. The current request conflicts with the existing selection.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT"] = 5113] = "BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT";
/**
* The wire transfer subject duplicates an existing reserve public key. But wire transfer subjects must be unique.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["BANK_DUPLICATE_RESERVE_PUB_SUBJECT"] = 5114] = "BANK_DUPLICATE_RESERVE_PUB_SUBJECT";
/**
* The sync service failed find the account in its database.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_ACCOUNT_UNKNOWN"] = 6100] = "SYNC_ACCOUNT_UNKNOWN";
/**
* The SHA-512 hash provided in the If-None-Match header is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_BAD_IF_NONE_MATCH"] = 6101] = "SYNC_BAD_IF_NONE_MATCH";
/**
* The SHA-512 hash provided in the If-Match header is malformed or missing.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_BAD_IF_MATCH"] = 6102] = "SYNC_BAD_IF_MATCH";
/**
* The signature provided in the "Sync-Signature" header is malformed or missing.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_BAD_SYNC_SIGNATURE"] = 6103] = "SYNC_BAD_SYNC_SIGNATURE";
/**
* The signature provided in the "Sync-Signature" header does not match the account, old or new Etags.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_INVALID_SIGNATURE"] = 6104] = "SYNC_INVALID_SIGNATURE";
/**
* The "Content-length" field for the upload is not a number.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_MALFORMED_CONTENT_LENGTH"] = 6105] = "SYNC_MALFORMED_CONTENT_LENGTH";
/**
* The "Content-length" field for the upload is too big based on the server's terms of service.
* Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_EXCESSIVE_CONTENT_LENGTH"] = 6106] = "SYNC_EXCESSIVE_CONTENT_LENGTH";
/**
* The server is out of memory to handle the upload. Trying again later may succeed.
* Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH"] = 6107] = "SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH";
/**
* The uploaded data does not match the Etag.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_INVALID_UPLOAD"] = 6108] = "SYNC_INVALID_UPLOAD";
/**
* HTTP server experienced a timeout while awaiting promised payment.
* Returned with an HTTP status code of #MHD_HTTP_REQUEST_TIMEOUT (408).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_PAYMENT_GENERIC_TIMEOUT"] = 6109] = "SYNC_PAYMENT_GENERIC_TIMEOUT";
/**
* Sync could not setup the payment request with its own backend.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_PAYMENT_CREATE_BACKEND_ERROR"] = 6110] = "SYNC_PAYMENT_CREATE_BACKEND_ERROR";
/**
* The sync service failed find the backup to be updated in its database.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_PREVIOUS_BACKUP_UNKNOWN"] = 6111] = "SYNC_PREVIOUS_BACKUP_UNKNOWN";
/**
* The "Content-length" field for the upload is missing.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["SYNC_MISSING_CONTENT_LENGTH"] = 6112] = "SYNC_MISSING_CONTENT_LENGTH";
/**
* The wallet does not implement a version of the exchange protocol that is compatible with the protocol version of the exchange.
* Returned with an HTTP status code of #MHD_HTTP_NOT_IMPLEMENTED (501).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE"] = 7000] = "WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE";
/**
* The wallet encountered an unexpected exception. This is likely a bug in the wallet implementation.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_UNEXPECTED_EXCEPTION"] = 7001] = "WALLET_UNEXPECTED_EXCEPTION";
/**
* The wallet received a response from a server, but the response can't be parsed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_RECEIVED_MALFORMED_RESPONSE"] = 7002] = "WALLET_RECEIVED_MALFORMED_RESPONSE";
/**
* The wallet tried to make a network request, but it received no response.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_NETWORK_ERROR"] = 7003] = "WALLET_NETWORK_ERROR";
/**
* The wallet tried to make a network request, but it was throttled.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_HTTP_REQUEST_THROTTLED"] = 7004] = "WALLET_HTTP_REQUEST_THROTTLED";
/**
* The wallet made a request to a service, but received an error response it does not know how to handle.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_UNEXPECTED_REQUEST_ERROR"] = 7005] = "WALLET_UNEXPECTED_REQUEST_ERROR";
/**
* The denominations offered by the exchange are insufficient. Likely the exchange is badly configured or not maintained.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT"] = 7006] = "WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT";
/**
* The wallet does not support the operation requested by a client.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_CORE_API_OPERATION_UNKNOWN"] = 7007] = "WALLET_CORE_API_OPERATION_UNKNOWN";
/**
* The given taler://pay URI is invalid.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_INVALID_TALER_PAY_URI"] = 7008] = "WALLET_INVALID_TALER_PAY_URI";
/**
* The signature on a coin by the exchange's denomination key is invalid after unblinding it.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_COIN_SIGNATURE_INVALID"] = 7009] = "WALLET_EXCHANGE_COIN_SIGNATURE_INVALID";
/**
* The exchange does not know about the reserve (yet), and thus withdrawal can't progress.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN_AT_EXCHANGE"] = 7010] = "WALLET_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN_AT_EXCHANGE";
/**
* The wallet core service is not available.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_CORE_NOT_AVAILABLE"] = 7011] = "WALLET_CORE_NOT_AVAILABLE";
/**
* The bank has aborted a withdrawal operation, and thus a withdrawal can't complete.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK"] = 7012] = "WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK";
/**
* An HTTP request made by the wallet timed out.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_HTTP_REQUEST_GENERIC_TIMEOUT"] = 7013] = "WALLET_HTTP_REQUEST_GENERIC_TIMEOUT";
/**
* The order has already been claimed by another wallet.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_ORDER_ALREADY_CLAIMED"] = 7014] = "WALLET_ORDER_ALREADY_CLAIMED";
/**
* A group of withdrawal operations (typically for the same reserve at the same exchange) has errors and will be tried again later.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_WITHDRAWAL_GROUP_INCOMPLETE"] = 7015] = "WALLET_WITHDRAWAL_GROUP_INCOMPLETE";
/**
* The signature on a coin by the exchange's denomination key (obtained through the merchant via tipping) is invalid after unblinding it.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_TIPPING_COIN_SIGNATURE_INVALID"] = 7016] = "WALLET_TIPPING_COIN_SIGNATURE_INVALID";
/**
* The wallet does not implement a version of the bank integration API that is compatible with the version offered by the bank.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE"] = 7017] = "WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE";
/**
* The wallet processed a taler://pay URI, but the merchant base URL in the downloaded contract terms does not match the merchant base URL derived from the URI.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH"] = 7018] = "WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH";
/**
* The merchant's signature on the contract terms is invalid.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_CONTRACT_TERMS_SIGNATURE_INVALID"] = 7019] = "WALLET_CONTRACT_TERMS_SIGNATURE_INVALID";
/**
* The contract terms given by the merchant are malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["WALLET_CONTRACT_TERMS_MALFORMED"] = 7020] = "WALLET_CONTRACT_TERMS_MALFORMED";
/**
* We encountered a timeout with our payment backend.
* Returned with an HTTP status code of #MHD_HTTP_GATEWAY_TIMEOUT (504).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_BACKEND_TIMEOUT"] = 8000] = "ANASTASIS_GENERIC_BACKEND_TIMEOUT";
/**
* The backend requested payment, but the request is malformed.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST"] = 8001] = "ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST";
/**
* The backend got an unexpected reply from the payment processor.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_BACKEND_ERROR"] = 8002] = "ANASTASIS_GENERIC_BACKEND_ERROR";
/**
* The "Content-length" field for the upload is missing.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH"] = 8003] = "ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH";
/**
* The "Content-length" field for the upload is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH"] = 8004] = "ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH";
/**
* The backend failed to setup an order with the payment processor.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_ORDER_CREATE_BACKEND_ERROR"] = 8005] = "ANASTASIS_GENERIC_ORDER_CREATE_BACKEND_ERROR";
/**
* The backend was not authorized to check for payment with the payment processor.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_PAYMENT_CHECK_UNAUTHORIZED"] = 8006] = "ANASTASIS_GENERIC_PAYMENT_CHECK_UNAUTHORIZED";
/**
* The backend could not check payment status with the payment processor.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_PAYMENT_CHECK_START_FAILED"] = 8007] = "ANASTASIS_GENERIC_PAYMENT_CHECK_START_FAILED";
/**
* The Anastasis provider could not be reached.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_PROVIDER_UNREACHABLE"] = 8008] = "ANASTASIS_GENERIC_PROVIDER_UNREACHABLE";
/**
* HTTP server experienced a timeout while awaiting promised payment.
* Returned with an HTTP status code of #MHD_HTTP_REQUEST_TIMEOUT (408).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_PAYMENT_GENERIC_TIMEOUT"] = 8009] = "ANASTASIS_PAYMENT_GENERIC_TIMEOUT";
/**
* The key share is unknown to the provider.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UNKNOWN"] = 8108] = "ANASTASIS_TRUTH_UNKNOWN";
/**
* The authorization method used for the key share is no longer supported by the provider.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_AUTHORIZATION_METHOD_NO_LONGER_SUPPORTED"] = 8109] = "ANASTASIS_TRUTH_AUTHORIZATION_METHOD_NO_LONGER_SUPPORTED";
/**
* The client needs to respond to the challenge.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED"] = 8110] = "ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED";
/**
* The client's response to the challenge was invalid.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_FAILED"] = 8111] = "ANASTASIS_TRUTH_CHALLENGE_FAILED";
/**
* The backend is not aware of having issued the provided challenge code. Either this is the wrong code, or it has expired.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_UNKNOWN"] = 8112] = "ANASTASIS_TRUTH_CHALLENGE_UNKNOWN";
/**
* A challenge is already active, the service is thus not issuing a new one.
* Returned with an HTTP status code of #MHD_HTTP_ALREADY_REPORTED (208).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_ACTIVE"] = 8113] = "ANASTASIS_TRUTH_CHALLENGE_ACTIVE";
/**
* The backend failed to initiate the authorization process.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED"] = 8114] = "ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED";
/**
* The authorization succeeded, but the key share is no longer available.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_KEY_SHARE_GONE"] = 8115] = "ANASTASIS_TRUTH_KEY_SHARE_GONE";
/**
* The backend forgot the order we asked the client to pay for
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_ORDER_DISAPPEARED"] = 8116] = "ANASTASIS_TRUTH_ORDER_DISAPPEARED";
/**
* The backend itself reported a bad exchange interaction.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_BACKEND_EXCHANGE_BAD"] = 8117] = "ANASTASIS_TRUTH_BACKEND_EXCHANGE_BAD";
/**
* The backend reported a payment status we did not expect.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UNEXPECTED_PAYMENT_STATUS"] = 8118] = "ANASTASIS_TRUTH_UNEXPECTED_PAYMENT_STATUS";
/**
* The backend failed to setup the order for payment.
* Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_PAYMENT_CREATE_BACKEND_ERROR"] = 8119] = "ANASTASIS_TRUTH_PAYMENT_CREATE_BACKEND_ERROR";
/**
* The decryption of the key share failed with the provided key.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_DECRYPTION_FAILED"] = 8120] = "ANASTASIS_TRUTH_DECRYPTION_FAILED";
/**
* The request rate is too high. The server is refusing requests to guard against brute-force attacks.
* Returned with an HTTP status code of #MHD_HTTP_TOO_MANY_REQUESTS (429).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_RATE_LIMITED"] = 8121] = "ANASTASIS_TRUTH_RATE_LIMITED";
/**
* The authentication process did not yet complete. The user should try again later.
* Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_AUTH_TIMEOUT"] = 8122] = "ANASTASIS_TRUTH_AUTH_TIMEOUT";
/**
* A request to issue a challenge is not valid for this authentication method.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_WRONG_METHOD"] = 8123] = "ANASTASIS_TRUTH_CHALLENGE_WRONG_METHOD";
/**
* The backend failed to store the key share because the UUID is already in use.
* Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UPLOAD_UUID_EXISTS"] = 8150] = "ANASTASIS_TRUTH_UPLOAD_UUID_EXISTS";
/**
* The backend failed to store the key share because the authorization method is not supported.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UPLOAD_METHOD_NOT_SUPPORTED"] = 8151] = "ANASTASIS_TRUTH_UPLOAD_METHOD_NOT_SUPPORTED";
/**
* The provided phone number is not an acceptable number.
* Returned with an HTTP status code of #MHD_HTTP_EXPECTATION_FAILED (417).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_SMS_PHONE_INVALID"] = 8200] = "ANASTASIS_SMS_PHONE_INVALID";
/**
* Failed to run the SMS transmission helper process.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_SMS_HELPER_EXEC_FAILED"] = 8201] = "ANASTASIS_SMS_HELPER_EXEC_FAILED";
/**
* Provider failed to send SMS. Helper terminated with a non-successful result.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_SMS_HELPER_COMMAND_FAILED"] = 8202] = "ANASTASIS_SMS_HELPER_COMMAND_FAILED";
/**
* The provided email address is not an acceptable address.
* Returned with an HTTP status code of #MHD_HTTP_EXPECTATION_FAILED (417).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_EMAIL_INVALID"] = 8210] = "ANASTASIS_EMAIL_INVALID";
/**
* Failed to run the E-mail transmission helper process.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_EMAIL_HELPER_EXEC_FAILED"] = 8211] = "ANASTASIS_EMAIL_HELPER_EXEC_FAILED";
/**
* Provider failed to send E-mail. Helper terminated with a non-successful result.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_EMAIL_HELPER_COMMAND_FAILED"] = 8212] = "ANASTASIS_EMAIL_HELPER_COMMAND_FAILED";
/**
* The provided postal address is not an acceptable address.
* Returned with an HTTP status code of #MHD_HTTP_EXPECTATION_FAILED (417).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POST_INVALID"] = 8220] = "ANASTASIS_POST_INVALID";
/**
* Failed to run the mail transmission helper process.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POST_HELPER_EXEC_FAILED"] = 8221] = "ANASTASIS_POST_HELPER_EXEC_FAILED";
/**
* Provider failed to send mail. Helper terminated with a non-successful result.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POST_HELPER_COMMAND_FAILED"] = 8222] = "ANASTASIS_POST_HELPER_COMMAND_FAILED";
/**
* The provided IBAN address is not an acceptable IBAN.
* Returned with an HTTP status code of #MHD_HTTP_EXPECTATION_FAILED (417).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_IBAN_INVALID"] = 8230] = "ANASTASIS_IBAN_INVALID";
/**
* The backend did not find a TOTP key in the data provided.
* Returned with an HTTP status code of #MHD_HTTP_EXPECTATION_FAILED (417).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TOTP_KEY_MISSING"] = 8240] = "ANASTASIS_TOTP_KEY_MISSING";
/**
* The key provided does not satisfy the format restrictions for an Anastasis TOTP key.
* Returned with an HTTP status code of #MHD_HTTP_EXPECTATION_FAILED (417).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_TOTP_KEY_INVALID"] = 8241] = "ANASTASIS_TOTP_KEY_INVALID";
/**
* The given if-none-match header is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_BAD_IF_NONE_MATCH"] = 8301] = "ANASTASIS_POLICY_BAD_IF_NONE_MATCH";
/**
* The server is out of memory to handle the upload. Trying again later may succeed.
* Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_OUT_OF_MEMORY_ON_CONTENT_LENGTH"] = 8304] = "ANASTASIS_POLICY_OUT_OF_MEMORY_ON_CONTENT_LENGTH";
/**
* The signature provided in the "Anastasis-Policy-Signature" header is malformed or missing.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_BAD_SIGNATURE"] = 8305] = "ANASTASIS_POLICY_BAD_SIGNATURE";
/**
* The given if-match header is malformed.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_BAD_IF_MATCH"] = 8306] = "ANASTASIS_POLICY_BAD_IF_MATCH";
/**
* The uploaded data does not match the Etag.
* Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_INVALID_UPLOAD"] = 8307] = "ANASTASIS_POLICY_INVALID_UPLOAD";
/**
* The provider is unaware of the requested policy.
* Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_NOT_FOUND"] = 8350] = "ANASTASIS_POLICY_NOT_FOUND";
/**
* The given action is invalid for the current state of the reducer.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_ACTION_INVALID"] = 8400] = "ANASTASIS_REDUCER_ACTION_INVALID";
/**
* The given state of the reducer is invalid.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_STATE_INVALID"] = 8401] = "ANASTASIS_REDUCER_STATE_INVALID";
/**
* The given input to the reducer is invalid.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_INVALID"] = 8402] = "ANASTASIS_REDUCER_INPUT_INVALID";
/**
* The selected authentication method does not work for the Anastasis provider.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED"] = 8403] = "ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED";
/**
* The given input and action do not work for the current state.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE"] = 8404] = "ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE";
/**
* We experienced an unexpected failure interacting with the backend.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_BACKEND_FAILURE"] = 8405] = "ANASTASIS_REDUCER_BACKEND_FAILURE";
/**
* The contents of a resource file did not match our expectations.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_RESOURCE_MALFORMED"] = 8406] = "ANASTASIS_REDUCER_RESOURCE_MALFORMED";
/**
* A required resource file is missing.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_RESOURCE_MISSING"] = 8407] = "ANASTASIS_REDUCER_RESOURCE_MISSING";
/**
* An input did not match the regular expression.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_REGEX_FAILED"] = 8408] = "ANASTASIS_REDUCER_INPUT_REGEX_FAILED";
/**
* An input did not match the custom validation logic.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED"] = 8409] = "ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED";
/**
* Our attempts to download the recovery document failed with all providers. Most likely the personal information you entered differs from the information you provided during the backup process and you should go back to the previous step. Alternatively, if you used a backup provider that is unknown to this application, you should add that provider manually.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_POLICY_LOOKUP_FAILED"] = 8410] = "ANASTASIS_REDUCER_POLICY_LOOKUP_FAILED";
/**
* Anastasis provider reported a fatal failure.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_BACKUP_PROVIDER_FAILED"] = 8411] = "ANASTASIS_REDUCER_BACKUP_PROVIDER_FAILED";
/**
* Anastasis provider failed to respond to the configuration request.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED"] = 8412] = "ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED";
/**
* The policy we downloaded is malformed. Must have been a client error while creating the backup.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_POLICY_MALFORMED"] = 8413] = "ANASTASIS_REDUCER_POLICY_MALFORMED";
/**
* We failed to obtain the policy, likely due to a network issue.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_NETWORK_FAILED"] = 8414] = "ANASTASIS_REDUCER_NETWORK_FAILED";
/**
* The recovered secret did not match the required syntax.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_SECRET_MALFORMED"] = 8415] = "ANASTASIS_REDUCER_SECRET_MALFORMED";
/**
* The challenge data provided is too large for the available providers.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_CHALLENGE_DATA_TOO_BIG"] = 8416] = "ANASTASIS_REDUCER_CHALLENGE_DATA_TOO_BIG";
/**
* The provided core secret is too large for some of the providers.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_SECRET_TOO_BIG"] = 8417] = "ANASTASIS_REDUCER_SECRET_TOO_BIG";
/**
* The provider returned in invalid configuration.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG"] = 8418] = "ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG";
/**
* The reducer encountered an internal error, likely a bug that needs to be reported.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INTERNAL_ERROR"] = 8419] = "ANASTASIS_REDUCER_INTERNAL_ERROR";
/**
* A generic error happened in the LibEuFin nexus. See the enclose details JSON for more information.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["LIBEUFIN_NEXUS_GENERIC_ERROR"] = 9000] = "LIBEUFIN_NEXUS_GENERIC_ERROR";
/**
* An uncaught exception happened in the LibEuFin nexus service.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION"] = 9001] = "LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION";
/**
* A generic error happened in the LibEuFin sandbox. See the enclose details JSON for more information.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["LIBEUFIN_SANDBOX_GENERIC_ERROR"] = 9500] = "LIBEUFIN_SANDBOX_GENERIC_ERROR";
/**
* An uncaught exception happened in the LibEuFin sandbox service.
* Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["LIBEUFIN_SANDBOX_UNCAUGHT_EXCEPTION"] = 9501] = "LIBEUFIN_SANDBOX_UNCAUGHT_EXCEPTION";
/**
* End of error code range.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
TalerErrorCode[TalerErrorCode["END"] = 9999] = "END";
})(TalerErrorCode || (TalerErrorCode = {}));
/*
This file is part of GNU Taler
(C) 2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Number of fractional units that one value unit represents.
*/
const amountFractionalBase = 1e8;
/**
* How many digits behind the comma are required to represent the
* fractional value in human readable decimal format? Must match
* lg(fractionalBase)
*/
const amountFractionalLength = 8;
/**
* Maximum allowed value field of an amount.
*/
const amountMaxValue = Math.pow(2, 52);
/**
* Helper class for dealing with amounts.
*/
class Amounts {
constructor() {
throw Error("not instantiable");
}
/**
* Get an amount that represents zero units of a currency.
*/
static getZero(currency) {
return {
currency,
fraction: 0,
value: 0,
};
}
static jsonifyAmount(amt) {
if (typeof amt === "string") {
return Amounts.parseOrThrow(amt);
}
return amt;
}
static sum(amounts) {
if (amounts.length <= 0) {
throw Error("can't sum zero amounts");
}
const jsonAmounts = amounts.map((x) => Amounts.jsonifyAmount(x));
return Amounts.add(jsonAmounts[0], ...jsonAmounts.slice(1));
}
/**
* Add two amounts. Return the result and whether
* the addition overflowed. The overflow is always handled
* by saturating and never by wrapping.
*
* Throws when currencies don't match.
*/
static add(first, ...rest) {
const currency = first.currency;
let value = first.value + Math.floor(first.fraction / amountFractionalBase);
if (value > amountMaxValue) {
return {
amount: {
currency,
value: amountMaxValue,
fraction: amountFractionalBase - 1,
},
saturated: true,
};
}
let fraction = first.fraction % amountFractionalBase;
for (const x of rest) {
if (x.currency.toUpperCase() !== currency.toUpperCase()) {
throw Error(`Mismatched currency: ${x.currency} and ${currency}`);
}
value =
value +
x.value +
Math.floor((fraction + x.fraction) / amountFractionalBase);
fraction = Math.floor((fraction + x.fraction) % amountFractionalBase);
if (value > amountMaxValue) {
return {
amount: {
currency,
value: amountMaxValue,
fraction: amountFractionalBase - 1,
},
saturated: true,
};
}
}
return { amount: { currency, value, fraction }, saturated: false };
}
/**
* Subtract two amounts. Return the result and whether
* the subtraction overflowed. The overflow is always handled
* by saturating and never by wrapping.
*
* Throws when currencies don't match.
*/
static sub(a, ...rest) {
const currency = a.currency;
let value = a.value;
let fraction = a.fraction;
for (const b of rest) {
if (b.currency.toUpperCase() !== a.currency.toUpperCase()) {
throw Error(`Mismatched currency: ${b.currency} and ${currency}`);
}
if (fraction < b.fraction) {
if (value < 1) {
return {
amount: { currency, value: 0, fraction: 0 },
saturated: true,
};
}
value--;
fraction += amountFractionalBase;
}
console.assert(fraction >= b.fraction);
fraction -= b.fraction;
if (value < b.value) {
return { amount: { currency, value: 0, fraction: 0 }, saturated: true };
}
value -= b.value;
}
return { amount: { currency, value, fraction }, saturated: false };
}
/**
* Compare two amounts. Returns 0 when equal, -1 when a < b
* and +1 when a > b. Throws when currencies don't match.
*/
static cmp(a, b) {
a = Amounts.jsonifyAmount(a);
b = Amounts.jsonifyAmount(b);
if (a.currency !== b.currency) {
throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`);
}
const av = a.value + Math.floor(a.fraction / amountFractionalBase);
const af = a.fraction % amountFractionalBase;
const bv = b.value + Math.floor(b.fraction / amountFractionalBase);
const bf = b.fraction % amountFractionalBase;
switch (true) {
case av < bv:
return -1;
case av > bv:
return 1;
case af < bf:
return -1;
case af > bf:
return 1;
case af === bf:
return 0;
default:
throw Error("assertion failed");
}
}
/**
* Create a copy of an amount.
*/
static copy(a) {
return {
currency: a.currency,
fraction: a.fraction,
value: a.value,
};
}
/**
* Divide an amount. Throws on division by zero.
*/
static divide(a, n) {
if (n === 0) {
throw Error(`Division by 0`);
}
if (n === 1) {
return { value: a.value, fraction: a.fraction, currency: a.currency };
}
const r = a.value % n;
return {
currency: a.currency,
fraction: Math.floor((r * amountFractionalBase + a.fraction) / n),
value: Math.floor(a.value / n),
};
}
/**
* Check if an amount is non-zero.
*/
static isNonZero(a) {
return a.value > 0 || a.fraction > 0;
}
static isZero(a) {
a = Amounts.jsonifyAmount(a);
return a.value === 0 && a.fraction === 0;
}
/**
* Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct.
*/
static parse(s) {
const res = s.match(/^([a-zA-Z0-9_*-]+):([0-9]+)([.][0-9]+)?$/);
if (!res) {
return undefined;
}
const tail = res[3] || ".0";
if (tail.length > amountFractionalLength + 1) {
return undefined;
}
const value = Number.parseInt(res[2]);
if (value > amountMaxValue) {
return undefined;
}
return {
currency: res[1].toUpperCase(),
fraction: Math.round(amountFractionalBase * Number.parseFloat(tail)),
value,
};
}
/**
* Parse amount in standard string form (like 'EUR:20.5'),
* throw if the input is not a valid amount.
*/
static parseOrThrow(s) {
const res = Amounts.parse(s);
if (!res) {
throw Error(`Can't parse amount: "${s}"`);
}
return res;
}
/**
* Convert a float to a Taler amount.
* Loss of precision possible.
*/
static fromFloat(floatVal, currency) {
return {
currency,
fraction: Math.floor((floatVal - Math.floor(floatVal)) * amountFractionalBase),
value: Math.floor(floatVal),
};
}
static min(a, b) {
const cr = Amounts.cmp(a, b);
if (cr >= 0) {
return Amounts.jsonifyAmount(b);
}
else {
return Amounts.jsonifyAmount(a);
}
}
static max(a, b) {
const cr = Amounts.cmp(a, b);
if (cr >= 0) {
return Amounts.jsonifyAmount(a);
}
else {
return Amounts.jsonifyAmount(b);
}
}
static mult(a, n) {
a = this.jsonifyAmount(a);
if (!Number.isInteger(n)) {
throw Error("amount can only be multipied by an integer");
}
if (n < 0) {
throw Error("amount can only be multiplied by a positive integer");
}
if (n == 0) {
return { amount: Amounts.getZero(a.currency), saturated: false };
}
let x = a;
let acc = Amounts.getZero(a.currency);
while (n > 1) {
if (n % 2 == 0) {
n = n / 2;
}
else {
n = (n - 1) / 2;
const r2 = Amounts.add(acc, x);
if (r2.saturated) {
return r2;
}
acc = r2.amount;
}
const r2 = Amounts.add(x, x);
if (r2.saturated) {
return r2;
}
x = r2.amount;
}
return Amounts.add(acc, x);
}
/**
* Check if the argument is a valid amount in string form.
*/
static check(a) {
if (typeof a !== "string") {
return false;
}
try {
const parsedAmount = Amounts.parse(a);
return !!parsedAmount;
}
catch (_a) {
return false;
}
}
/**
* Convert to standard human-readable string representation that's
* also used in JSON formats.
*/
static stringify(a) {
a = Amounts.jsonifyAmount(a);
const s = this.stringifyValue(a);
return `${a.currency}:${s}`;
}
static isSameCurrency(a1, a2) {
const x1 = this.jsonifyAmount(a1);
const x2 = this.jsonifyAmount(a2);
return x1.currency.toUpperCase() === x2.currency.toUpperCase();
}
static stringifyValue(a, minFractional = 0) {
const av = a.value + Math.floor(a.fraction / amountFractionalBase);
const af = a.fraction % amountFractionalBase;
let s = av.toString();
if (af) {
s = s + ".";
let n = af;
for (let i = 0; i < amountFractionalLength; i++) {
if (!n && i >= minFractional) {
break;
}
s = s + Math.floor((n / amountFractionalBase) * 10).toString();
n = (n * 10) % amountFractionalBase;
}
}
return s;
}
}
/*
This file is part of GNU Taler
(C) 2020 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Types of coin sources.
*/
var BackupCoinSourceType;
(function (BackupCoinSourceType) {
BackupCoinSourceType["Withdraw"] = "withdraw";
BackupCoinSourceType["Refresh"] = "refresh";
BackupCoinSourceType["Tip"] = "tip";
})(BackupCoinSourceType || (BackupCoinSourceType = {}));
/**
* Reasons for why a coin is being refreshed.
*/
var BackupRefreshReason;
(function (BackupRefreshReason) {
BackupRefreshReason["Manual"] = "manual";
BackupRefreshReason["Pay"] = "pay";
BackupRefreshReason["Refund"] = "refund";
BackupRefreshReason["AbortPay"] = "abort-pay";
BackupRefreshReason["Recoup"] = "recoup";
BackupRefreshReason["BackupRestored"] = "backup-restored";
BackupRefreshReason["Scheduled"] = "scheduled";
})(BackupRefreshReason || (BackupRefreshReason = {}));
var BackupRefundState;
(function (BackupRefundState) {
BackupRefundState["Failed"] = "failed";
BackupRefundState["Applied"] = "applied";
BackupRefundState["Pending"] = "pending";
})(BackupRefundState || (BackupRefundState = {}));
var BackupProposalStatus;
(function (BackupProposalStatus) {
/**
* Proposed (and either downloaded or not,
* depending on whether contract terms are present),
* but the user needs to accept/reject it.
*/
BackupProposalStatus["Proposed"] = "proposed";
/**
* The user has rejected the proposal.
*/
BackupProposalStatus["Refused"] = "refused";
/**
* Downloading or processing the proposal has failed permanently.
*
* FIXME: Should this be modeled as a "misbehavior report" instead?
*/
BackupProposalStatus["PermanentlyFailed"] = "permanently-failed";
/**
* Downloaded proposal was detected as a re-purchase.
*/
BackupProposalStatus["Repurchase"] = "repurchase";
})(BackupProposalStatus || (BackupProposalStatus = {}));
/*
This file is part of GNU Taler
(C) 2020 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
// globalThis polyfill, see https://mathiasbynens.be/notes/globalthis
(function () {
if (typeof globalThis === "object")
return;
Object.defineProperty(Object.prototype, "__magic__", {
get: function () {
return this;
},
configurable: true, // This makes it possible to `delete` the getter later.
});
// @ts-ignore: polyfill magic
__magic__.globalThis = __magic__; // lolwat
// @ts-ignore: polyfill magic
delete Object.prototype.__magic__;
})();
// @ts-ignore
const _URL = globalThis.URL;
if (!_URL) {
throw Error("FATAL: URL not available");
}
// @ts-ignore
const _URLSearchParams = globalThis.URLSearchParams;
if (!_URLSearchParams) {
throw Error("FATAL: URLSearchParams not available");
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
/**
* Convert object to JSON with canonical ordering of keys
* and whitespace omitted.
*
* See RFC 4885 (https://tools.ietf.org/html/rfc8785).
*/
function canonicalJson(obj) {
// Check for cycles, etc.
obj = JSON.parse(JSON.stringify(obj));
if (typeof obj === "string") {
return JSON.stringify(obj);
}
if (typeof obj === "number" || typeof obj === "boolean" || obj === null) {
return JSON.stringify(obj);
}
if (Array.isArray(obj)) {
const objs = obj.map((e) => canonicalJson(e));
return `[${objs.join(",")}]`;
}
const keys = [];
for (const key in obj) {
keys.push(key);
}
keys.sort();
let s = "{";
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
s += JSON.stringify(key) + ":" + canonicalJson(obj[key]);
if (i !== keys.length - 1) {
s += ",";
}
}
return s + "}";
}
/**
* Lexically compare two strings.
*/
function strcmp(s1, s2) {
if (s1 < s2) {
return -1;
}
if (s1 > s2) {
return 1;
}
return 0;
}
/*
This file is part of TALER
(C) 2017 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
var LibtoolVersion;
(function (LibtoolVersion) {
/**
* Compare two libtool-style version strings.
*/
function compare(me, other) {
const meVer = parseVersion(me);
const otherVer = parseVersion(other);
if (!(meVer && otherVer)) {
return undefined;
}
const compatible = meVer.current - meVer.age <= otherVer.current &&
meVer.current >= otherVer.current - otherVer.age;
const currentCmp = Math.sign(meVer.current - otherVer.current);
return { compatible, currentCmp };
}
LibtoolVersion.compare = compare;
function parseVersion(v) {
const [currentStr, revisionStr, ageStr, ...rest] = v.split(":");
if (rest.length !== 0) {
return undefined;
}
const current = Number.parseInt(currentStr);
const revision = Number.parseInt(revisionStr);
const age = Number.parseInt(ageStr);
if (Number.isNaN(current)) {
return undefined;
}
if (Number.isNaN(revision)) {
return undefined;
}
if (Number.isNaN(age)) {
return undefined;
}
return { current, revision, age };
}
LibtoolVersion.parseVersion = parseVersion;
})(LibtoolVersion || (LibtoolVersion = {}));
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var NotificationType;
(function (NotificationType) {
NotificationType["CoinWithdrawn"] = "coin-withdrawn";
NotificationType["ProposalAccepted"] = "proposal-accepted";
NotificationType["ProposalDownloaded"] = "proposal-downloaded";
NotificationType["RefundsSubmitted"] = "refunds-submitted";
NotificationType["RecoupStarted"] = "recoup-started";
NotificationType["RecoupFinished"] = "recoup-finished";
NotificationType["RefreshRevealed"] = "refresh-revealed";
NotificationType["RefreshMelted"] = "refresh-melted";
NotificationType["RefreshStarted"] = "refresh-started";
NotificationType["RefreshUnwarranted"] = "refresh-unwarranted";
NotificationType["ReserveUpdated"] = "reserve-updated";
NotificationType["ReserveConfirmed"] = "reserve-confirmed";
NotificationType["ReserveCreated"] = "reserve-created";
NotificationType["WithdrawGroupCreated"] = "withdraw-group-created";
NotificationType["WithdrawGroupFinished"] = "withdraw-group-finished";
NotificationType["WaitingForRetry"] = "waiting-for-retry";
NotificationType["RefundStarted"] = "refund-started";
NotificationType["RefundQueried"] = "refund-queried";
NotificationType["RefundFinished"] = "refund-finished";
NotificationType["ExchangeOperationError"] = "exchange-operation-error";
NotificationType["ExchangeAdded"] = "exchange-added";
NotificationType["RefreshOperationError"] = "refresh-operation-error";
NotificationType["RecoupOperationError"] = "recoup-operation-error";
NotificationType["RefundApplyOperationError"] = "refund-apply-error";
NotificationType["RefundStatusOperationError"] = "refund-status-error";
NotificationType["ProposalOperationError"] = "proposal-error";
NotificationType["BackupOperationError"] = "backup-error";
NotificationType["TipOperationError"] = "tip-error";
NotificationType["PayOperationError"] = "pay-error";
NotificationType["PayOperationSuccess"] = "pay-operation-success";
NotificationType["WithdrawOperationError"] = "withdraw-error";
NotificationType["ReserveNotYetFound"] = "reserve-not-yet-found";
NotificationType["ReserveOperationError"] = "reserve-error";
NotificationType["InternalError"] = "internal-error";
NotificationType["PendingOperationProcessed"] = "pending-operation-processed";
NotificationType["ProposalRefused"] = "proposal-refused";
NotificationType["ReserveRegisteredWithBank"] = "reserve-registered-with-bank";
NotificationType["DepositOperationError"] = "deposit-operation-error";
})(NotificationType || (NotificationType = {}));
/*
This file is part of GNU Taler
(C) 2017-2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
let timeshift = 0;
function getTimestampNow() {
return {
t_ms: new Date().getTime() + timeshift,
};
}
function isTimestampExpired(t) {
return timestampCmp(t, getTimestampNow()) <= 0;
}
function getDurationRemaining(deadline, now = getTimestampNow()) {
if (deadline.t_ms === "never") {
return { d_ms: "forever" };
}
if (now.t_ms === "never") {
throw Error("invalid argument for 'now'");
}
if (deadline.t_ms < now.t_ms) {
return { d_ms: 0 };
}
return { d_ms: deadline.t_ms - now.t_ms };
}
var Duration;
(function (Duration) {
Duration.getRemaining = getDurationRemaining;
function toIntegerYears(d) {
if (typeof d.d_ms !== "number") {
throw Error("infinite duration");
}
return Math.ceil(d.d_ms / 1000 / 60 / 60 / 24 / 365);
}
Duration.toIntegerYears = toIntegerYears;
Duration.fromSpec = durationFromSpec;
})(Duration || (Duration = {}));
var Timestamp;
(function (Timestamp) {
Timestamp.now = getTimestampNow;
Timestamp.min = timestampMin;
Timestamp.isExpired = isTimestampExpired;
})(Timestamp || (Timestamp = {}));
function timestampMin(t1, t2) {
if (t1.t_ms === "never") {
return { t_ms: t2.t_ms };
}
if (t2.t_ms === "never") {
return { t_ms: t2.t_ms };
}
return { t_ms: Math.min(t1.t_ms, t2.t_ms) };
}
const SECONDS = 1000;
const MINUTES = SECONDS * 60;
const HOURS = MINUTES * 60;
const DAYS = HOURS * 24;
const MONTHS = DAYS * 30;
const YEARS = DAYS * 365;
function durationFromSpec(spec) {
var _a, _b, _c, _d, _e, _f;
let d_ms = 0;
d_ms += ((_a = spec.seconds) !== null && _a !== void 0 ? _a : 0) * SECONDS;
d_ms += ((_b = spec.minutes) !== null && _b !== void 0 ? _b : 0) * MINUTES;
d_ms += ((_c = spec.hours) !== null && _c !== void 0 ? _c : 0) * HOURS;
d_ms += ((_d = spec.days) !== null && _d !== void 0 ? _d : 0) * DAYS;
d_ms += ((_e = spec.months) !== null && _e !== void 0 ? _e : 0) * MONTHS;
d_ms += ((_f = spec.years) !== null && _f !== void 0 ? _f : 0) * YEARS;
return { d_ms };
}
function timestampCmp(t1, t2) {
if (t1.t_ms === "never") {
if (t2.t_ms === "never") {
return 0;
}
return 1;
}
if (t2.t_ms === "never") {
return -1;
}
if (t1.t_ms == t2.t_ms) {
return 0;
}
if (t1.t_ms > t2.t_ms) {
return 1;
}
return -1;
}
/*
This file is part of GNU Taler
(C) 2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var ReserveTransactionType;
(function (ReserveTransactionType) {
ReserveTransactionType["Withdraw"] = "WITHDRAW";
ReserveTransactionType["Credit"] = "CREDIT";
ReserveTransactionType["Recoup"] = "RECOUP";
ReserveTransactionType["Closing"] = "CLOSING";
})(ReserveTransactionType || (ReserveTransactionType = {}));
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var DenomKeyType;
(function (DenomKeyType) {
DenomKeyType["Rsa"] = "RSA";
DenomKeyType["ClauseSchnorr"] = "CS";
})(DenomKeyType || (DenomKeyType = {}));
(function (DenomKeyType) {
function toIntTag(t) {
switch (t) {
case DenomKeyType.Rsa:
return 1;
case DenomKeyType.ClauseSchnorr:
return 2;
}
}
DenomKeyType.toIntTag = toIntTag;
})(DenomKeyType || (DenomKeyType = {}));
var DenominationPubKey;
(function (DenominationPubKey) {
function cmp(p1, p2) {
var _a, _b, _c, _d, _e, _f, _g, _h;
if (p1.cipher < p2.cipher) {
return -1;
}
else if (p1.cipher > p2.cipher) {
return +1;
}
else if (p1.cipher === DenomKeyType.Rsa &&
p2.cipher === DenomKeyType.Rsa) {
if (((_a = p1.age_mask) !== null && _a !== void 0 ? _a : 0) < ((_b = p2.age_mask) !== null && _b !== void 0 ? _b : 0)) {
return -1;
}
else if (((_c = p1.age_mask) !== null && _c !== void 0 ? _c : 0) > ((_d = p2.age_mask) !== null && _d !== void 0 ? _d : 0)) {
return 1;
}
return strcmp(p1.rsa_public_key, p2.rsa_public_key);
}
else if (p1.cipher === DenomKeyType.ClauseSchnorr &&
p2.cipher === DenomKeyType.ClauseSchnorr) {
if (((_e = p1.age_mask) !== null && _e !== void 0 ? _e : 0) < ((_f = p2.age_mask) !== null && _f !== void 0 ? _f : 0)) {
return -1;
}
else if (((_g = p1.age_mask) !== null && _g !== void 0 ? _g : 0) > ((_h = p2.age_mask) !== null && _h !== void 0 ? _h : 0)) {
return 1;
}
return strcmp(p1.cs_public_key, p2.cs_public_key);
}
else {
throw Error("unsupported cipher");
}
}
DenominationPubKey.cmp = cmp;
})(DenominationPubKey || (DenominationPubKey = {}));
var ExchangeProtocolVersion;
(function (ExchangeProtocolVersion) {
/**
* Current version supported by the wallet.
*/
ExchangeProtocolVersion[ExchangeProtocolVersion["V12"] = 12] = "V12";
})(ExchangeProtocolVersion || (ExchangeProtocolVersion = {}));
var MerchantProtocolVersion;
(function (MerchantProtocolVersion) {
/**
* Current version supported by the wallet.
*/
MerchantProtocolVersion[MerchantProtocolVersion["V3"] = 3] = "V3";
})(MerchantProtocolVersion || (MerchantProtocolVersion = {}));
/*
This file is part of GNU Taler
(C) 2019-2020 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var TalerUriType;
(function (TalerUriType) {
TalerUriType["TalerPay"] = "taler-pay";
TalerUriType["TalerWithdraw"] = "taler-withdraw";
TalerUriType["TalerTip"] = "taler-tip";
TalerUriType["TalerRefund"] = "taler-refund";
TalerUriType["TalerNotifyReserve"] = "taler-notify-reserve";
TalerUriType["Unknown"] = "unknown";
})(TalerUriType || (TalerUriType = {}));
/**
* Classify a taler:// URI.
*/
function classifyTalerUri(s) {
const sl = s.toLowerCase();
if (sl.startsWith("taler://pay/")) {
return TalerUriType.TalerPay;
}
if (sl.startsWith("taler+http://pay/")) {
return TalerUriType.TalerPay;
}
if (sl.startsWith("taler://tip/")) {
return TalerUriType.TalerTip;
}
if (sl.startsWith("taler+http://tip/")) {
return TalerUriType.TalerTip;
}
if (sl.startsWith("taler://refund/")) {
return TalerUriType.TalerRefund;
}
if (sl.startsWith("taler+http://refund/")) {
return TalerUriType.TalerRefund;
}
if (sl.startsWith("taler://withdraw/")) {
return TalerUriType.TalerWithdraw;
}
if (sl.startsWith("taler+http://withdraw/")) {
return TalerUriType.TalerWithdraw;
}
if (sl.startsWith("taler://notify-reserve/")) {
return TalerUriType.TalerNotifyReserve;
}
return TalerUriType.Unknown;
}
/*
This file is part of GNU Taler
(C) 2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var TransactionType;
(function (TransactionType) {
TransactionType["Withdrawal"] = "withdrawal";
TransactionType["Payment"] = "payment";
TransactionType["Refund"] = "refund";
TransactionType["Refresh"] = "refresh";
TransactionType["Tip"] = "tip";
TransactionType["Deposit"] = "deposit";
})(TransactionType || (TransactionType = {}));
var WithdrawalType;
(function (WithdrawalType) {
WithdrawalType["TalerBankIntegrationApi"] = "taler-bank-integration-api";
WithdrawalType["ManualTransfer"] = "manual-transfer";
})(WithdrawalType || (WithdrawalType = {}));
var PaymentStatus$1;
(function (PaymentStatus) {
/**
* Explicitly aborted after timeout / failure
*/
PaymentStatus["Aborted"] = "aborted";
/**
* Payment failed, wallet will auto-retry.
* User should be given the option to retry now / abort.
*/
PaymentStatus["Failed"] = "failed";
/**
* Paid successfully
*/
PaymentStatus["Paid"] = "paid";
/**
* User accepted, payment is processing.
*/
PaymentStatus["Accepted"] = "accepted";
})(PaymentStatus$1 || (PaymentStatus$1 = {}));
/*
This file is part of GNU Taler
(C) 2015-2020 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
var ConfirmPayResultType;
(function (ConfirmPayResultType) {
ConfirmPayResultType["Done"] = "done";
ConfirmPayResultType["Pending"] = "pending";
})(ConfirmPayResultType || (ConfirmPayResultType = {}));
var PreparePayResultType;
(function (PreparePayResultType) {
PreparePayResultType["PaymentPossible"] = "payment-possible";
PreparePayResultType["InsufficientBalance"] = "insufficient-balance";
PreparePayResultType["AlreadyConfirmed"] = "already-confirmed";
})(PreparePayResultType || (PreparePayResultType = {}));
/**
* Reasons for why a coin is being refreshed.
*/
var RefreshReason;
(function (RefreshReason) {
RefreshReason["Manual"] = "manual";
RefreshReason["Pay"] = "pay";
RefreshReason["Refund"] = "refund";
RefreshReason["AbortPay"] = "abort-pay";
RefreshReason["Recoup"] = "recoup";
RefreshReason["BackupRestored"] = "backup-restored";
RefreshReason["Scheduled"] = "scheduled";
})(RefreshReason || (RefreshReason = {}));
/**
* Strategy for loading recovery information.
*/
var RecoveryMergeStrategy;
(function (RecoveryMergeStrategy) {
/**
* Keep the local wallet root key, import and take over providers.
*/
RecoveryMergeStrategy["Ours"] = "ours";
/**
* Migrate to the wallet root key from the recovery information.
*/
RecoveryMergeStrategy["Theirs"] = "theirs";
})(RecoveryMergeStrategy || (RecoveryMergeStrategy = {}));
function getAugmentedNamespace(n) {
if (n.__esModule) return n;
var a = Object.defineProperty({}, '__esModule', {value: true});
Object.keys(n).forEach(function (k) {
var d = Object.getOwnPropertyDescriptor(n, k);
Object.defineProperty(a, k, d.get ? d : {
enumerable: true,
get: function () {
return n[k];
}
});
});
return a;
}
var jed$1 = {exports: {}};
/**
* @preserve jed.js https://github.com/SlexAxton/Jed
*/
(function (module, exports) {
/*
-----------
A gettext compatible i18n library for modern JavaScript Applications
by Alex Sexton - AlexSexton [at] gmail - @SlexAxton
MIT License
A jQuery Foundation project - requires CLA to contribute -
https://contribute.jquery.org/CLA/
Jed offers the entire applicable GNU gettext spec'd set of
functions, but also offers some nicer wrappers around them.
The api for gettext was written for a language with no function
overloading, so Jed allows a little more of that.
Many thanks to Joshua I. Miller - unrtst@cpan.org - who wrote
gettext.js back in 2008. I was able to vet a lot of my ideas
against his. I also made sure Jed passed against his tests
in order to offer easy upgrades -- jsgettext.berlios.de
*/
(function (root, undef) {
// Set up some underscore-style functions, if you already have
// underscore, feel free to delete this section, and use it
// directly, however, the amount of functions used doesn't
// warrant having underscore as a full dependency.
// Underscore 1.3.0 was used to port and is licensed
// under the MIT License by Jeremy Ashkenas.
var ArrayProto = Array.prototype,
ObjProto = Object.prototype,
slice = ArrayProto.slice,
hasOwnProp = ObjProto.hasOwnProperty,
nativeForEach = ArrayProto.forEach,
breaker = {};
// We're not using the OOP style _ so we don't need the
// extra level of indirection. This still means that you
// sub out for real `_` though.
var _ = {
forEach : function( obj, iterator, context ) {
var i, l, key;
if ( obj === null ) {
return;
}
if ( nativeForEach && obj.forEach === nativeForEach ) {
obj.forEach( iterator, context );
}
else if ( obj.length === +obj.length ) {
for ( i = 0, l = obj.length; i < l; i++ ) {
if ( i in obj && iterator.call( context, obj[i], i, obj ) === breaker ) {
return;
}
}
}
else {
for ( key in obj) {
if ( hasOwnProp.call( obj, key ) ) {
if ( iterator.call (context, obj[key], key, obj ) === breaker ) {
return;
}
}
}
}
},
extend : function( obj ) {
this.forEach( slice.call( arguments, 1 ), function ( source ) {
for ( var prop in source ) {
obj[prop] = source[prop];
}
});
return obj;
}
};
// END Miniature underscore impl
// Jed is a constructor function
var Jed = function ( options ) {
// Some minimal defaults
this.defaults = {
"locale_data" : {
"messages" : {
"" : {
"domain" : "messages",
"lang" : "en",
"plural_forms" : "nplurals=2; plural=(n != 1);"
}
// There are no default keys, though
}
},
// The default domain if one is missing
"domain" : "messages",
// enable debug mode to log untranslated strings to the console
"debug" : false
};
// Mix in the sent options with the default options
this.options = _.extend( {}, this.defaults, options );
this.textdomain( this.options.domain );
if ( options.domain && ! this.options.locale_data[ this.options.domain ] ) {
throw new Error('Text domain set to non-existent domain: `' + options.domain + '`');
}
};
// The gettext spec sets this character as the default
// delimiter for context lookups.
// e.g.: context\u0004key
// If your translation company uses something different,
// just change this at any time and it will use that instead.
Jed.context_delimiter = String.fromCharCode( 4 );
function getPluralFormFunc ( plural_form_string ) {
return Jed.PF.compile( plural_form_string || "nplurals=2; plural=(n != 1);");
}
function Chain( key, i18n ){
this._key = key;
this._i18n = i18n;
}
// Create a chainable api for adding args prettily
_.extend( Chain.prototype, {
onDomain : function ( domain ) {
this._domain = domain;
return this;
},
withContext : function ( context ) {
this._context = context;
return this;
},
ifPlural : function ( num, pkey ) {
this._val = num;
this._pkey = pkey;
return this;
},
fetch : function ( sArr ) {
if ( {}.toString.call( sArr ) != '[object Array]' ) {
sArr = [].slice.call(arguments, 0);
}
return ( sArr && sArr.length ? Jed.sprintf : function(x){ return x; } )(
this._i18n.dcnpgettext(this._domain, this._context, this._key, this._pkey, this._val),
sArr
);
}
});
// Add functions to the Jed prototype.
// These will be the functions on the object that's returned
// from creating a `new Jed()`
// These seem redundant, but they gzip pretty well.
_.extend( Jed.prototype, {
// The sexier api start point
translate : function ( key ) {
return new Chain( key, this );
},
textdomain : function ( domain ) {
if ( ! domain ) {
return this._textdomain;
}
this._textdomain = domain;
},
gettext : function ( key ) {
return this.dcnpgettext.call( this, undef, undef, key );
},
dgettext : function ( domain, key ) {
return this.dcnpgettext.call( this, domain, undef, key );
},
dcgettext : function ( domain , key /*, category */ ) {
// Ignores the category anyways
return this.dcnpgettext.call( this, domain, undef, key );
},
ngettext : function ( skey, pkey, val ) {
return this.dcnpgettext.call( this, undef, undef, skey, pkey, val );
},
dngettext : function ( domain, skey, pkey, val ) {
return this.dcnpgettext.call( this, domain, undef, skey, pkey, val );
},
dcngettext : function ( domain, skey, pkey, val/*, category */) {
return this.dcnpgettext.call( this, domain, undef, skey, pkey, val );
},
pgettext : function ( context, key ) {
return this.dcnpgettext.call( this, undef, context, key );
},
dpgettext : function ( domain, context, key ) {
return this.dcnpgettext.call( this, domain, context, key );
},
dcpgettext : function ( domain, context, key/*, category */) {
return this.dcnpgettext.call( this, domain, context, key );
},
npgettext : function ( context, skey, pkey, val ) {
return this.dcnpgettext.call( this, undef, context, skey, pkey, val );
},
dnpgettext : function ( domain, context, skey, pkey, val ) {
return this.dcnpgettext.call( this, domain, context, skey, pkey, val );
},
// The most fully qualified gettext function. It has every option.
// Since it has every option, we can use it from every other method.
// This is the bread and butter.
// Technically there should be one more argument in this function for 'Category',
// but since we never use it, we might as well not waste the bytes to define it.
dcnpgettext : function ( domain, context, singular_key, plural_key, val ) {
// Set some defaults
plural_key = plural_key || singular_key;
// Use the global domain default if one
// isn't explicitly passed in
domain = domain || this._textdomain;
var fallback;
// Handle special cases
// No options found
if ( ! this.options ) {
// There's likely something wrong, but we'll return the correct key for english
// We do this by instantiating a brand new Jed instance with the default set
// for everything that could be broken.
fallback = new Jed();
return fallback.dcnpgettext.call( fallback, undefined, undefined, singular_key, plural_key, val );
}
// No translation data provided
if ( ! this.options.locale_data ) {
throw new Error('No locale data provided.');
}
if ( ! this.options.locale_data[ domain ] ) {
throw new Error('Domain `' + domain + '` was not found.');
}
if ( ! this.options.locale_data[ domain ][ "" ] ) {
throw new Error('No locale meta information provided.');
}
// Make sure we have a truthy key. Otherwise we might start looking
// into the empty string key, which is the options for the locale
// data.
if ( ! singular_key ) {
throw new Error('No translation key found.');
}
var key = context ? context + Jed.context_delimiter + singular_key : singular_key,
locale_data = this.options.locale_data,
dict = locale_data[ domain ],
defaultConf = (locale_data.messages || this.defaults.locale_data.messages)[""],
pluralForms = dict[""].plural_forms || dict[""]["Plural-Forms"] || dict[""]["plural-forms"] || defaultConf.plural_forms || defaultConf["Plural-Forms"] || defaultConf["plural-forms"],
val_list,
res;
var val_idx;
if (val === undefined) {
// No value passed in; assume singular key lookup.
val_idx = 0;
} else {
// Value has been passed in; use plural-forms calculations.
// Handle invalid numbers, but try casting strings for good measure
if ( typeof val != 'number' ) {
val = parseInt( val, 10 );
if ( isNaN( val ) ) {
throw new Error('The number that was passed in is not a number.');
}
}
val_idx = getPluralFormFunc(pluralForms)(val);
}
// Throw an error if a domain isn't found
if ( ! dict ) {
throw new Error('No domain named `' + domain + '` could be found.');
}
val_list = dict[ key ];
// If there is no match, then revert back to
// english style singular/plural with the keys passed in.
if ( ! val_list || val_idx > val_list.length ) {
if (this.options.missing_key_callback) {
this.options.missing_key_callback(key, domain);
}
res = [ singular_key, plural_key ];
// collect untranslated strings
if (this.options.debug===true) {
console.log(res[ getPluralFormFunc(pluralForms)( val ) ]);
}
return res[ getPluralFormFunc()( val ) ];
}
res = val_list[ val_idx ];
// This includes empty strings on purpose
if ( ! res ) {
res = [ singular_key, plural_key ];
return res[ getPluralFormFunc()( val ) ];
}
return res;
}
});
// We add in sprintf capabilities for post translation value interolation
// This is not internally used, so you can remove it if you have this
// available somewhere else, or want to use a different system.
// We _slightly_ modify the normal sprintf behavior to more gracefully handle
// undefined values.
/**
sprintf() for JavaScript 0.7-beta1
http://www.diveintojavascript.com/projects/javascript-sprintf
Copyright (c) Alexandru Marasteanu
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of sprintf() for JavaScript nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var sprintf = (function() {
function get_type(variable) {
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
}
function str_repeat(input, multiplier) {
for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
return output.join('');
}
var str_format = function() {
if (!str_format.cache.hasOwnProperty(arguments[0])) {
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
}
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
};
str_format.format = function(parse_tree, argv) {
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
for (i = 0; i < tree_length; i++) {
node_type = get_type(parse_tree[i]);
if (node_type === 'string') {
output.push(parse_tree[i]);
}
else if (node_type === 'array') {
match = parse_tree[i]; // convenience purposes only
if (match[2]) { // keyword argument
arg = argv[cursor];
for (k = 0; k < match[2].length; k++) {
if (!arg.hasOwnProperty(match[2][k])) {
throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
}
arg = arg[match[2][k]];
}
}
else if (match[1]) { // positional argument (explicit)
arg = argv[match[1]];
}
else { // positional argument (implicit)
arg = argv[cursor++];
}
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
}
// Jed EDIT
if ( typeof arg == 'undefined' || arg === null ) {
arg = '';
}
// Jed EDIT
switch (match[8]) {
case 'b': arg = arg.toString(2); break;
case 'c': arg = String.fromCharCode(arg); break;
case 'd': arg = parseInt(arg, 10); break;
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
case 'o': arg = arg.toString(8); break;
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
case 'u': arg = Math.abs(arg); break;
case 'x': arg = arg.toString(16); break;
case 'X': arg = arg.toString(16).toUpperCase(); break;
}
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
pad_length = match[6] - String(arg).length;
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
output.push(match[5] ? arg + pad : pad + arg);
}
}
return output.join('');
};
str_format.cache = {};
str_format.parse = function(fmt) {
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
while (_fmt) {
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
parse_tree.push(match[0]);
}
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
parse_tree.push('%');
}
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
if (match[2]) {
arg_names |= 1;
var field_list = [], replacement_field = match[2], field_match = [];
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
}
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
}
else {
throw('[sprintf] huh?');
}
}
}
else {
throw('[sprintf] huh?');
}
match[2] = field_list;
}
else {
arg_names |= 2;
}
if (arg_names === 3) {
throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
}
parse_tree.push(match);
}
else {
throw('[sprintf] huh?');
}
_fmt = _fmt.substring(match[0].length);
}
return parse_tree;
};
return str_format;
})();
var vsprintf = function(fmt, argv) {
argv.unshift(fmt);
return sprintf.apply(null, argv);
};
Jed.parse_plural = function ( plural_forms, n ) {
plural_forms = plural_forms.replace(/n/g, n);
return Jed.parse_expression(plural_forms);
};
Jed.sprintf = function ( fmt, args ) {
if ( {}.toString.call( args ) == '[object Array]' ) {
return vsprintf( fmt, [].slice.call(args) );
}
return sprintf.apply(this, [].slice.call(arguments) );
};
Jed.prototype.sprintf = function () {
return Jed.sprintf.apply(this, arguments);
};
// END sprintf Implementation
// Start the Plural forms section
// This is a full plural form expression parser. It is used to avoid
// running 'eval' or 'new Function' directly against the plural
// forms.
//
// This can be important if you get translations done through a 3rd
// party vendor. I encourage you to use this instead, however, I
// also will provide a 'precompiler' that you can use at build time
// to output valid/safe function representations of the plural form
// expressions. This means you can build this code out for the most
// part.
Jed.PF = {};
Jed.PF.parse = function ( p ) {
var plural_str = Jed.PF.extractPluralExpr( p );
return Jed.PF.parser.parse.call(Jed.PF.parser, plural_str);
};
Jed.PF.compile = function ( p ) {
// Handle trues and falses as 0 and 1
function imply( val ) {
return (val === true ? 1 : val ? val : 0);
}
var ast = Jed.PF.parse( p );
return function ( n ) {
return imply( Jed.PF.interpreter( ast )( n ) );
};
};
Jed.PF.interpreter = function ( ast ) {
return function ( n ) {
switch ( ast.type ) {
case 'GROUP':
return Jed.PF.interpreter( ast.expr )( n );
case 'TERNARY':
if ( Jed.PF.interpreter( ast.expr )( n ) ) {
return Jed.PF.interpreter( ast.truthy )( n );
}
return Jed.PF.interpreter( ast.falsey )( n );
case 'OR':
return Jed.PF.interpreter( ast.left )( n ) || Jed.PF.interpreter( ast.right )( n );
case 'AND':
return Jed.PF.interpreter( ast.left )( n ) && Jed.PF.interpreter( ast.right )( n );
case 'LT':
return Jed.PF.interpreter( ast.left )( n ) < Jed.PF.interpreter( ast.right )( n );
case 'GT':
return Jed.PF.interpreter( ast.left )( n ) > Jed.PF.interpreter( ast.right )( n );
case 'LTE':
return Jed.PF.interpreter( ast.left )( n ) <= Jed.PF.interpreter( ast.right )( n );
case 'GTE':
return Jed.PF.interpreter( ast.left )( n ) >= Jed.PF.interpreter( ast.right )( n );
case 'EQ':
return Jed.PF.interpreter( ast.left )( n ) == Jed.PF.interpreter( ast.right )( n );
case 'NEQ':
return Jed.PF.interpreter( ast.left )( n ) != Jed.PF.interpreter( ast.right )( n );
case 'MOD':
return Jed.PF.interpreter( ast.left )( n ) % Jed.PF.interpreter( ast.right )( n );
case 'VAR':
return n;
case 'NUM':
return ast.val;
default:
throw new Error("Invalid Token found.");
}
};
};
Jed.PF.extractPluralExpr = function ( p ) {
// trim first
p = p.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
if (! /;\s*$/.test(p)) {
p = p.concat(';');
}
var nplurals_re = /nplurals\=(\d+);/,
plural_re = /plural\=(.*);/,
nplurals_matches = p.match( nplurals_re ),
plural_matches;
// Find the nplurals number
if ( nplurals_matches.length > 1 ) ;
else {
throw new Error('nplurals not found in plural_forms string: ' + p );
}
// remove that data to get to the formula
p = p.replace( nplurals_re, "" );
plural_matches = p.match( plural_re );
if (!( plural_matches && plural_matches.length > 1 ) ) {
throw new Error('`plural` expression not found: ' + p);
}
return plural_matches[ 1 ];
};
/* Jison generated parser */
Jed.PF.parser = (function(){
var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"expressions":3,"e":4,"EOF":5,"?":6,":":7,"||":8,"&&":9,"<":10,"<=":11,">":12,">=":13,"!=":14,"==":15,"%":16,"(":17,")":18,"n":19,"NUMBER":20,"$accept":0,"$end":1},
terminals_: {2:"error",5:"EOF",6:"?",7:":",8:"||",9:"&&",10:"<",11:"<=",12:">",13:">=",14:"!=",15:"==",16:"%",17:"(",18:")",19:"n",20:"NUMBER"},
productions_: [0,[3,2],[4,5],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,1],[4,1]],
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1: return { type : 'GROUP', expr: $$[$0-1] };
case 2:this.$ = { type: 'TERNARY', expr: $$[$0-4], truthy : $$[$0-2], falsey: $$[$0] };
break;
case 3:this.$ = { type: "OR", left: $$[$0-2], right: $$[$0] };
break;
case 4:this.$ = { type: "AND", left: $$[$0-2], right: $$[$0] };
break;
case 5:this.$ = { type: 'LT', left: $$[$0-2], right: $$[$0] };
break;
case 6:this.$ = { type: 'LTE', left: $$[$0-2], right: $$[$0] };
break;
case 7:this.$ = { type: 'GT', left: $$[$0-2], right: $$[$0] };
break;
case 8:this.$ = { type: 'GTE', left: $$[$0-2], right: $$[$0] };
break;
case 9:this.$ = { type: 'NEQ', left: $$[$0-2], right: $$[$0] };
break;
case 10:this.$ = { type: 'EQ', left: $$[$0-2], right: $$[$0] };
break;
case 11:this.$ = { type: 'MOD', left: $$[$0-2], right: $$[$0] };
break;
case 12:this.$ = { type: 'GROUP', expr: $$[$0-1] };
break;
case 13:this.$ = { type: 'VAR' };
break;
case 14:this.$ = { type: 'NUM', val: Number(yytext) };
break;
}
},
table: [{3:1,4:2,17:[1,3],19:[1,4],20:[1,5]},{1:[3]},{5:[1,6],6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{4:17,17:[1,3],19:[1,4],20:[1,5]},{5:[2,13],6:[2,13],7:[2,13],8:[2,13],9:[2,13],10:[2,13],11:[2,13],12:[2,13],13:[2,13],14:[2,13],15:[2,13],16:[2,13],18:[2,13]},{5:[2,14],6:[2,14],7:[2,14],8:[2,14],9:[2,14],10:[2,14],11:[2,14],12:[2,14],13:[2,14],14:[2,14],15:[2,14],16:[2,14],18:[2,14]},{1:[2,1]},{4:18,17:[1,3],19:[1,4],20:[1,5]},{4:19,17:[1,3],19:[1,4],20:[1,5]},{4:20,17:[1,3],19:[1,4],20:[1,5]},{4:21,17:[1,3],19:[1,4],20:[1,5]},{4:22,17:[1,3],19:[1,4],20:[1,5]},{4:23,17:[1,3],19:[1,4],20:[1,5]},{4:24,17:[1,3],19:[1,4],20:[1,5]},{4:25,17:[1,3],19:[1,4],20:[1,5]},{4:26,17:[1,3],19:[1,4],20:[1,5]},{4:27,17:[1,3],19:[1,4],20:[1,5]},{6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[1,28]},{6:[1,7],7:[1,29],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{5:[2,3],6:[2,3],7:[2,3],8:[2,3],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,3]},{5:[2,4],6:[2,4],7:[2,4],8:[2,4],9:[2,4],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,4]},{5:[2,5],6:[2,5],7:[2,5],8:[2,5],9:[2,5],10:[2,5],11:[2,5],12:[2,5],13:[2,5],14:[2,5],15:[2,5],16:[1,16],18:[2,5]},{5:[2,6],6:[2,6],7:[2,6],8:[2,6],9:[2,6],10:[2,6],11:[2,6],12:[2,6],13:[2,6],14:[2,6],15:[2,6],16:[1,16],18:[2,6]},{5:[2,7],6:[2,7],7:[2,7],8:[2,7],9:[2,7],10:[2,7],11:[2,7],12:[2,7],13:[2,7],14:[2,7],15:[2,7],16:[1,16],18:[2,7]},{5:[2,8],6:[2,8],7:[2,8],8:[2,8],9:[2,8],10:[2,8],11:[2,8],12:[2,8],13:[2,8],14:[2,8],15:[2,8],16:[1,16],18:[2,8]},{5:[2,9],6:[2,9],7:[2,9],8:[2,9],9:[2,9],10:[2,9],11:[2,9],12:[2,9],13:[2,9],14:[2,9],15:[2,9],16:[1,16],18:[2,9]},{5:[2,10],6:[2,10],7:[2,10],8:[2,10],9:[2,10],10:[2,10],11:[2,10],12:[2,10],13:[2,10],14:[2,10],15:[2,10],16:[1,16],18:[2,10]},{5:[2,11],6:[2,11],7:[2,11],8:[2,11],9:[2,11],10:[2,11],11:[2,11],12:[2,11],13:[2,11],14:[2,11],15:[2,11],16:[2,11],18:[2,11]},{5:[2,12],6:[2,12],7:[2,12],8:[2,12],9:[2,12],10:[2,12],11:[2,12],12:[2,12],13:[2,12],14:[2,12],15:[2,12],16:[2,12],18:[2,12]},{4:30,17:[1,3],19:[1,4],20:[1,5]},{5:[2,2],6:[1,7],7:[2,2],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,2]}],
defaultActions: {6:[2,1]},
parseError: function parseError(str, hash) {
throw new Error(str);
},
parse: function parse(input) {
var self = this,
stack = [0],
vstack = [null], // semantic value stack
lstack = [], // location stack
table = this.table,
yytext = '',
yylineno = 0,
yyleng = 0,
recovering = 0,
TERROR = 2,
EOF = 1;
//this.reductionCount = this.shiftCount = 0;
this.lexer.setInput(input);
this.lexer.yy = this.yy;
this.yy.lexer = this.lexer;
if (typeof this.lexer.yylloc == 'undefined')
this.lexer.yylloc = {};
var yyloc = this.lexer.yylloc;
lstack.push(yyloc);
if (typeof this.yy.parseError === 'function')
this.parseError = this.yy.parseError;
function popStack (n) {
stack.length = stack.length - 2*n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
function lex() {
var token;
token = self.lexer.lex() || 1; // $end = 1
// if token isn't its numeric value, convert
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
}
var symbol, preErrorSymbol, state, action, r, yyval={},p,len,newState, expected;
while (true) {
// retreive state number from top of stack
state = stack[stack.length-1];
// use default actions if available
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol == null)
symbol = lex();
// read action for current state and first input
action = table[state] && table[state][symbol];
}
// handle parse error
if (typeof action === 'undefined' || !action.length || !action[0]) {
if (!recovering) {
// Report error
expected = [];
for (p in table[state]) if (this.terminals_[p] && p > 2) {
expected.push("'"+this.terminals_[p]+"'");
}
var errStr = '';
if (this.lexer.showPosition) {
errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'";
} else {
errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
(symbol == 1 /*EOF*/ ? "end of input" :
("'"+(this.terminals_[symbol] || symbol)+"'"));
}
this.parseError(errStr,
{text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
}
// just recovered from another error
if (recovering == 3) {
if (symbol == EOF) {
throw new Error(errStr || 'Parsing halted.');
}
// discard current lookahead and grab another
yyleng = this.lexer.yyleng;
yytext = this.lexer.yytext;
yylineno = this.lexer.yylineno;
yyloc = this.lexer.yylloc;
symbol = lex();
}
// try to recover from error
while (1) {
// check for error recovery rule in this state
if ((TERROR.toString()) in table[state]) {
break;
}
if (state == 0) {
throw new Error(errStr || 'Parsing halted.');
}
popStack(1);
state = stack[stack.length-1];
}
preErrorSymbol = symbol; // save the lookahead token
symbol = TERROR; // insert generic error symbol as new lookahead
state = stack[stack.length-1];
action = table[state] && table[state][TERROR];
recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
}
// this shouldn't happen, unless resolve defaults are off
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
}
switch (action[0]) {
case 1: // shift
//this.shiftCount++;
stack.push(symbol);
vstack.push(this.lexer.yytext);
lstack.push(this.lexer.yylloc);
stack.push(action[1]); // push state
symbol = null;
if (!preErrorSymbol) { // normal execution/no error
yyleng = this.lexer.yyleng;
yytext = this.lexer.yytext;
yylineno = this.lexer.yylineno;
yyloc = this.lexer.yylloc;
if (recovering > 0)
recovering--;
} else { // error just occurred, resume old lookahead f/ before error
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2: // reduce
//this.reductionCount++;
len = this.productions_[action[1]][1];
// perform semantic action
yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
// default location, uses first token for firsts, last for lasts
yyval._$ = {
first_line: lstack[lstack.length-(len||1)].first_line,
last_line: lstack[lstack.length-1].last_line,
first_column: lstack[lstack.length-(len||1)].first_column,
last_column: lstack[lstack.length-1].last_column
};
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
if (typeof r !== 'undefined') {
return r;
}
// pop off stack
if (len) {
stack = stack.slice(0,-1*len*2);
vstack = vstack.slice(0, -1*len);
lstack = lstack.slice(0, -1*len);
}
stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
vstack.push(yyval.$);
lstack.push(yyval._$);
// goto new state = table[STATE][NONTERMINAL]
newState = table[stack[stack.length-2]][stack[stack.length-1]];
stack.push(newState);
break;
case 3: // accept
return true;
}
}
return true;
}};/* Jison generated lexer */
var lexer = (function(){
var lexer = ({EOF:1,
parseError:function parseError(str, hash) {
if (this.yy.parseError) {
this.yy.parseError(str, hash);
} else {
throw new Error(str);
}
},
setInput:function (input) {
this._input = input;
this._more = this._less = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
return this;
},
input:function () {
var ch = this._input[0];
this.yytext+=ch;
this.yyleng++;
this.match+=ch;
this.matched+=ch;
var lines = ch.match(/\n/);
if (lines) this.yylineno++;
this._input = this._input.slice(1);
return ch;
},
unput:function (ch) {
this._input = ch + this._input;
return this;
},
more:function () {
this._more = true;
return this;
},
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20-next.length);
}
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
},
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c+"^";
},
next:function () {
if (this.done) {
return this.EOF;
}
if (!this._input) this.done = true;
var token,
match,
lines;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i=0;i < rules.length; i++) {
match = this._input.match(this.rules[rules[i]]);
if (match) {
lines = match[0].match(/\n.*/g);
if (lines) this.yylineno += lines.length;
this.yylloc = {first_line: this.yylloc.last_line,
last_line: this.yylineno+1,
first_column: this.yylloc.last_column,
last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
this._more = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
if (token) return token;
else return;
}
}
if (this._input === "") {
return this.EOF;
} else {
this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
{text: "", token: null, line: this.yylineno});
}
},
lex:function lex() {
var r = this.next();
if (typeof r !== 'undefined') {
return r;
} else {
return this.lex();
}
},
begin:function begin(condition) {
this.conditionStack.push(condition);
},
popState:function popState() {
return this.conditionStack.pop();
},
_currentRules:function _currentRules() {
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
},
topState:function () {
return this.conditionStack[this.conditionStack.length-2];
},
pushState:function begin(condition) {
this.begin(condition);
}});
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
switch($avoiding_name_collisions) {
case 0:/* skip whitespace */
break;
case 1:return 20
case 2:return 19
case 3:return 8
case 4:return 9
case 5:return 6
case 6:return 7
case 7:return 11
case 8:return 13
case 9:return 10
case 10:return 12
case 11:return 14
case 12:return 15
case 13:return 16
case 14:return 17
case 15:return 18
case 16:return 5
case 17:return 'INVALID'
}
};
lexer.rules = [/^\s+/,/^[0-9]+(\.[0-9]+)?\b/,/^n\b/,/^\|\|/,/^&&/,/^\?/,/^:/,/^<=/,/^>=/,/^,/^>/,/^!=/,/^==/,/^%/,/^\(/,/^\)/,/^$/,/^./];
lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"inclusive":true}};return lexer;})();
parser.lexer = lexer;
return parser;
})();
// End parser
// Handle node, amd, and global systems
{
if (module.exports) {
exports = module.exports = Jed;
}
exports.Jed = Jed;
}
})();
}(jed$1, jed$1.exports));
/*
This file is part of TALER
(C) 2019 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
/**
* Check if we are running under nodejs.
*/
const isNode = typeof process !== "undefined" &&
typeof process.release !== "undefined" &&
process.release.name === "node";
var LogLevel;
(function (LogLevel) {
LogLevel["Trace"] = "trace";
LogLevel["Message"] = "message";
LogLevel["Info"] = "info";
LogLevel["Warn"] = "warn";
LogLevel["Error"] = "error";
LogLevel["None"] = "none";
})(LogLevel || (LogLevel = {}));
let globalLogLevel = LogLevel.Info;
function writeNodeLog(message, tag, level, args) {
try {
let msg = `${new Date().toISOString()} ${tag} ${level} ${message}`;
if (args.length != 0) {
msg += ` ${JSON.stringify(args, undefined, 2)}\n`;
}
else {
msg += `\n`;
}
process.stderr.write(msg);
}
catch (e) {
// This can happen when we're trying to log something that doesn't want to be
// converted to a string.
let msg = `${new Date().toISOString()} (logger) FATAL `;
if (e instanceof Error) {
msg += `failed to write log: ${e.message}\n`;
}
else {
msg += "failed to write log\n";
}
process.stderr.write(msg);
}
}
/**
* Logger that writes to stderr when running under node,
* and uses the corresponding console.* method to log in the browser.
*/
class Logger {
constructor(tag) {
this.tag = tag;
}
shouldLogTrace() {
switch (globalLogLevel) {
case LogLevel.Trace:
return true;
case LogLevel.Message:
case LogLevel.Info:
case LogLevel.Warn:
case LogLevel.Error:
case LogLevel.None:
return false;
}
}
shouldLogInfo() {
switch (globalLogLevel) {
case LogLevel.Trace:
case LogLevel.Message:
case LogLevel.Info:
return true;
case LogLevel.Warn:
case LogLevel.Error:
case LogLevel.None:
return false;
}
}
shouldLogWarn() {
switch (globalLogLevel) {
case LogLevel.Trace:
case LogLevel.Message:
case LogLevel.Info:
case LogLevel.Warn:
return true;
case LogLevel.Error:
case LogLevel.None:
return false;
}
}
shouldLogError() {
switch (globalLogLevel) {
case LogLevel.Trace:
case LogLevel.Message:
case LogLevel.Info:
case LogLevel.Warn:
case LogLevel.Error:
return true;
case LogLevel.None:
return false;
}
}
info(message, ...args) {
if (!this.shouldLogInfo()) {
return;
}
if (isNode) {
writeNodeLog(message, this.tag, "INFO", args);
}
else {
console.info(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
}
}
warn(message, ...args) {
if (!this.shouldLogWarn()) {
return;
}
if (isNode) {
writeNodeLog(message, this.tag, "WARN", args);
}
else {
console.warn(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
}
}
error(message, ...args) {
if (!this.shouldLogError()) {
return;
}
if (isNode) {
writeNodeLog(message, this.tag, "ERROR", args);
}
else {
console.info(`${new Date().toISOString()} ${this.tag} ERROR ` + message, ...args);
}
}
trace(message, ...args) {
if (!this.shouldLogTrace()) {
return;
}
if (isNode) {
writeNodeLog(message, this.tag, "TRACE", args);
}
else {
console.info(`${new Date().toISOString()} ${this.tag} TRACE ` + message, ...args);
}
}
}
// @ts-ignore: no type decl for this library
const logger = new Logger("i18n/index.ts");
let jed = undefined;
/**
* Set up jed library for internationalization,
* based on browser language settings.
*/
function setupI18n(lang, strings) {
lang = lang.replace("_", "-");
if (!strings[lang]) {
lang = "en-US";
logger.warn(`language ${lang} not found, defaulting to english`);
}
jed = new jed$1.exports.Jed(strings[lang]);
}
/**
* Convert template strings to a msgid
*/
function toI18nString(stringSeq) {
let s = "";
for (let i = 0; i < stringSeq.length; i++) {
s += stringSeq[i];
if (i < stringSeq.length - 1) {
s += `%${i + 1}$s`;
}
}
return s;
}
/**
* Internationalize a string template with arbitrary serialized values.
*/
function singular(stringSeq, ...values) {
const s = toI18nString(stringSeq);
const tr = jed
.translate(s)
.ifPlural(1, s)
.fetch(...values);
return tr;
}
/**
* Internationalize a string template without serializing
*/
function translate(stringSeq, ...values) {
const s = toI18nString(stringSeq);
if (!s)
return [];
const translation = jed.ngettext(s, s, 1);
return replacePlaceholderWithValues(translation, values);
}
/**
* Internationalize a string template without serializing
*/
function Translate({ children, debug, }) {
const c = [].concat(children);
const s = stringifyArray(c);
if (!s)
return [];
const translation = jed.ngettext(s, s, 1);
if (debug) {
console.log("looking for ", s, "got", translation);
}
return replacePlaceholderWithValues(translation, c);
}
function replacePlaceholderWithValues(translation, childArray) {
const tr = translation.split(/%(\d+)\$s/);
// const childArray = toChildArray(children);
// Merge consecutive string children.
const placeholderChildren = [];
for (let i = 0; i < childArray.length; i++) {
const x = childArray[i];
if (x === undefined) {
continue;
}
else if (typeof x === "string") {
continue;
}
else {
placeholderChildren.push(x);
}
}
const result = [];
for (let i = 0; i < tr.length; i++) {
if (i % 2 == 0) {
// Text
result.push(tr[i]);
}
else {
const childIdx = Number.parseInt(tr[i]) - 1;
result.push(placeholderChildren[childIdx]);
}
}
return result;
}
function stringifyArray(children) {
let n = 1;
const ss = children.map((c) => {
if (typeof c === "string") {
return c;
}
return `%${n++}$s`;
});
const s = ss.join("").replace(/ +/g, " ").trim();
return s;
}
const i18n = {
str: singular,
singular,
Translate,
translate,
};
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Functional programming utilities.
*/
var fnutil;
(function (fnutil) {
function all(arr, f) {
for (const x of arr) {
if (!f(x)) {
return false;
}
}
return true;
}
fnutil.all = all;
function any(arr, f) {
for (const x of arr) {
if (f(x)) {
return true;
}
}
return false;
}
fnutil.any = any;
})(fnutil || (fnutil = {}));
// SHA-256 for JavaScript.
//
// Written in 2014-2016 by Dmitry Chestnykh.
// Public domain, no warranty.
//
// Functions (accept and return Uint8Arrays):
//
// sha256(message) -> hash
// sha256.hmac(key, message) -> mac
//
// Classes:
//
// new sha256.Hash()
const digestLength = 32;
const blockSize = 64;
// SHA-256 constants
const K$1 = new Uint32Array([
0x428a2f98,
0x71374491,
0xb5c0fbcf,
0xe9b5dba5,
0x3956c25b,
0x59f111f1,
0x923f82a4,
0xab1c5ed5,
0xd807aa98,
0x12835b01,
0x243185be,
0x550c7dc3,
0x72be5d74,
0x80deb1fe,
0x9bdc06a7,
0xc19bf174,
0xe49b69c1,
0xefbe4786,
0x0fc19dc6,
0x240ca1cc,
0x2de92c6f,
0x4a7484aa,
0x5cb0a9dc,
0x76f988da,
0x983e5152,
0xa831c66d,
0xb00327c8,
0xbf597fc7,
0xc6e00bf3,
0xd5a79147,
0x06ca6351,
0x14292967,
0x27b70a85,
0x2e1b2138,
0x4d2c6dfc,
0x53380d13,
0x650a7354,
0x766a0abb,
0x81c2c92e,
0x92722c85,
0xa2bfe8a1,
0xa81a664b,
0xc24b8b70,
0xc76c51a3,
0xd192e819,
0xd6990624,
0xf40e3585,
0x106aa070,
0x19a4c116,
0x1e376c08,
0x2748774c,
0x34b0bcb5,
0x391c0cb3,
0x4ed8aa4a,
0x5b9cca4f,
0x682e6ff3,
0x748f82ee,
0x78a5636f,
0x84c87814,
0x8cc70208,
0x90befffa,
0xa4506ceb,
0xbef9a3f7,
0xc67178f2,
]);
function hashBlocks(w, v, p, pos, len) {
let a, b, c, d, e, f, g, h, u, i, j, t1, t2;
while (len >= 64) {
a = v[0];
b = v[1];
c = v[2];
d = v[3];
e = v[4];
f = v[5];
g = v[6];
h = v[7];
for (i = 0; i < 16; i++) {
j = pos + i * 4;
w[i] =
((p[j] & 0xff) << 24) |
((p[j + 1] & 0xff) << 16) |
((p[j + 2] & 0xff) << 8) |
(p[j + 3] & 0xff);
}
for (i = 16; i < 64; i++) {
u = w[i - 2];
t1 =
((u >>> 17) | (u << (32 - 17))) ^
((u >>> 19) | (u << (32 - 19))) ^
(u >>> 10);
u = w[i - 15];
t2 =
((u >>> 7) | (u << (32 - 7))) ^
((u >>> 18) | (u << (32 - 18))) ^
(u >>> 3);
w[i] = ((t1 + w[i - 7]) | 0) + ((t2 + w[i - 16]) | 0);
}
for (i = 0; i < 64; i++) {
t1 =
((((((e >>> 6) | (e << (32 - 6))) ^
((e >>> 11) | (e << (32 - 11))) ^
((e >>> 25) | (e << (32 - 25)))) +
((e & f) ^ (~e & g))) |
0) +
((h + ((K$1[i] + w[i]) | 0)) | 0)) |
0;
t2 =
((((a >>> 2) | (a << (32 - 2))) ^
((a >>> 13) | (a << (32 - 13))) ^
((a >>> 22) | (a << (32 - 22)))) +
((a & b) ^ (a & c) ^ (b & c))) |
0;
h = g;
g = f;
f = e;
e = (d + t1) | 0;
d = c;
c = b;
b = a;
a = (t1 + t2) | 0;
}
v[0] += a;
v[1] += b;
v[2] += c;
v[3] += d;
v[4] += e;
v[5] += f;
v[6] += g;
v[7] += h;
pos += 64;
len -= 64;
}
return pos;
}
// Hash implements SHA256 hash algorithm.
class HashSha256 {
constructor() {
this.digestLength = digestLength;
this.blockSize = blockSize;
// Note: Int32Array is used instead of Uint32Array for performance reasons.
this.state = new Int32Array(8); // hash state
this.temp = new Int32Array(64); // temporary state
this.buffer = new Uint8Array(128); // buffer for data to hash
this.bufferLength = 0; // number of bytes in buffer
this.bytesHashed = 0; // number of total bytes hashed
this.finished = false; // indicates whether the hash was finalized
this.reset();
}
// Resets hash state making it possible
// to re-use this instance to hash other data.
reset() {
this.state[0] = 0x6a09e667;
this.state[1] = 0xbb67ae85;
this.state[2] = 0x3c6ef372;
this.state[3] = 0xa54ff53a;
this.state[4] = 0x510e527f;
this.state[5] = 0x9b05688c;
this.state[6] = 0x1f83d9ab;
this.state[7] = 0x5be0cd19;
this.bufferLength = 0;
this.bytesHashed = 0;
this.finished = false;
return this;
}
// Cleans internal buffers and re-initializes hash state.
clean() {
for (let i = 0; i < this.buffer.length; i++) {
this.buffer[i] = 0;
}
for (let i = 0; i < this.temp.length; i++) {
this.temp[i] = 0;
}
this.reset();
}
// Updates hash state with the given data.
//
// Optionally, length of the data can be specified to hash
// fewer bytes than data.length.
//
// Throws error when trying to update already finalized hash:
// instance must be reset to use it again.
update(data, dataLength = data.length) {
if (this.finished) {
throw new Error("SHA256: can't update because hash was finished.");
}
let dataPos = 0;
this.bytesHashed += dataLength;
if (this.bufferLength > 0) {
while (this.bufferLength < 64 && dataLength > 0) {
this.buffer[this.bufferLength++] = data[dataPos++];
dataLength--;
}
if (this.bufferLength === 64) {
hashBlocks(this.temp, this.state, this.buffer, 0, 64);
this.bufferLength = 0;
}
}
if (dataLength >= 64) {
dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);
dataLength %= 64;
}
while (dataLength > 0) {
this.buffer[this.bufferLength++] = data[dataPos++];
dataLength--;
}
return this;
}
// Finalizes hash state and puts hash into out.
//
// If hash was already finalized, puts the same value.
finish(out) {
if (!this.finished) {
const bytesHashed = this.bytesHashed;
const left = this.bufferLength;
const bitLenHi = (bytesHashed / 0x20000000) | 0;
const bitLenLo = bytesHashed << 3;
const padLength = bytesHashed % 64 < 56 ? 64 : 128;
this.buffer[left] = 0x80;
for (let i = left + 1; i < padLength - 8; i++) {
this.buffer[i] = 0;
}
this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;
this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;
this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;
this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;
this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;
this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;
this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;
this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;
hashBlocks(this.temp, this.state, this.buffer, 0, padLength);
this.finished = true;
}
for (let i = 0; i < 8; i++) {
out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;
out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;
out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;
out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;
}
return this;
}
// Returns the final hash digest.
digest() {
const out = new Uint8Array(this.digestLength);
this.finish(out);
return out;
}
// Internal function for use in HMAC for optimization.
_saveState(out) {
for (let i = 0; i < this.state.length; i++) {
out[i] = this.state[i];
}
}
// Internal function for use in HMAC for optimization.
_restoreState(from, bytesHashed) {
for (let i = 0; i < this.state.length; i++) {
this.state[i] = from[i];
}
this.bytesHashed = bytesHashed;
this.finished = false;
this.bufferLength = 0;
}
}
// Returns SHA256 hash of data.
function sha256(data) {
const h = new HashSha256().update(data);
const digest = h.digest();
h.clean();
return digest;
}
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function sha512(data) {
return hash$1(data);
}
function hmac(digest, blockSize, key, message) {
if (key.byteLength > blockSize) {
key = digest(key);
}
if (key.byteLength < blockSize) {
const k = key;
key = new Uint8Array(blockSize);
key.set(k, 0);
}
const okp = new Uint8Array(blockSize);
const ikp = new Uint8Array(blockSize);
for (let i = 0; i < blockSize; i++) {
ikp[i] = key[i] ^ 0x36;
okp[i] = key[i] ^ 0x5c;
}
const b1 = new Uint8Array(blockSize + message.byteLength);
b1.set(ikp, 0);
b1.set(message, blockSize);
const h0 = digest(b1);
const b2 = new Uint8Array(blockSize + h0.length);
b2.set(okp, 0);
b2.set(h0, blockSize);
return digest(b2);
}
function hmacSha512(key, message) {
return hmac(sha512, 128, key, message);
}
function hmacSha256(key, message) {
return hmac(sha256, 64, key, message);
}
function kdf(outputLength, ikm, salt, info) {
salt = salt !== null && salt !== void 0 ? salt : new Uint8Array(64);
// extract
const prk = hmacSha512(salt, ikm);
info = info !== null && info !== void 0 ? info : new Uint8Array(0);
// expand
const N = Math.ceil(outputLength / 32);
const output = new Uint8Array(N * 32);
for (let i = 0; i < N; i++) {
let buf;
if (i == 0) {
buf = new Uint8Array(info.byteLength + 1);
buf.set(info, 0);
}
else {
buf = new Uint8Array(info.byteLength + 1 + 32);
for (let j = 0; j < 32; j++) {
buf[j] = output[(i - 1) * 32 + j];
}
buf.set(info, 32);
}
buf[buf.length - 1] = i + 1;
const chunk = hmacSha256(prk, buf);
output.set(chunk, i * 32);
}
return output.slice(0, outputLength);
}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
var BigInteger = {exports: {}};
(function (module) {
var bigInt = (function (undefined$1) {
var BASE = 1e7,
LOG_BASE = 7,
MAX_INT = 9007199254740992,
MAX_INT_ARR = smallToArray(MAX_INT),
DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
var supportsNativeBigInt = typeof BigInt === "function";
function Integer(v, radix, alphabet, caseSensitive) {
if (typeof v === "undefined") return Integer[0];
if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
return parseValue(v);
}
function BigInteger(value, sign) {
this.value = value;
this.sign = sign;
this.isSmall = false;
}
BigInteger.prototype = Object.create(Integer.prototype);
function SmallInteger(value) {
this.value = value;
this.sign = value < 0;
this.isSmall = true;
}
SmallInteger.prototype = Object.create(Integer.prototype);
function NativeBigInt(value) {
this.value = value;
}
NativeBigInt.prototype = Object.create(Integer.prototype);
function isPrecise(n) {
return -MAX_INT < n && n < MAX_INT;
}
function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
if (n < 1e7)
return [n];
if (n < 1e14)
return [n % 1e7, Math.floor(n / 1e7)];
return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
}
function arrayToSmall(arr) { // If BASE changes this function may need to change
trim(arr);
var length = arr.length;
if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
switch (length) {
case 0: return 0;
case 1: return arr[0];
case 2: return arr[0] + arr[1] * BASE;
default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
}
}
return arr;
}
function trim(v) {
var i = v.length;
while (v[--i] === 0);
v.length = i + 1;
}
function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
var x = new Array(length);
var i = -1;
while (++i < length) {
x[i] = 0;
}
return x;
}
function truncate(n) {
if (n > 0) return Math.floor(n);
return Math.ceil(n);
}
function add(a, b) { // assumes a and b are arrays with a.length >= b.length
var l_a = a.length,
l_b = b.length,
r = new Array(l_a),
carry = 0,
base = BASE,
sum, i;
for (i = 0; i < l_b; i++) {
sum = a[i] + b[i] + carry;
carry = sum >= base ? 1 : 0;
r[i] = sum - carry * base;
}
while (i < l_a) {
sum = a[i] + carry;
carry = sum === base ? 1 : 0;
r[i++] = sum - carry * base;
}
if (carry > 0) r.push(carry);
return r;
}
function addAny(a, b) {
if (a.length >= b.length) return add(a, b);
return add(b, a);
}
function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
var l = a.length,
r = new Array(l),
base = BASE,
sum, i;
for (i = 0; i < l; i++) {
sum = a[i] - base + carry;
carry = Math.floor(sum / base);
r[i] = sum - carry * base;
carry += 1;
}
while (carry > 0) {
r[i++] = carry % base;
carry = Math.floor(carry / base);
}
return r;
}
BigInteger.prototype.add = function (v) {
var n = parseValue(v);
if (this.sign !== n.sign) {
return this.subtract(n.negate());
}
var a = this.value, b = n.value;
if (n.isSmall) {
return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
}
return new BigInteger(addAny(a, b), this.sign);
};
BigInteger.prototype.plus = BigInteger.prototype.add;
SmallInteger.prototype.add = function (v) {
var n = parseValue(v);
var a = this.value;
if (a < 0 !== n.sign) {
return this.subtract(n.negate());
}
var b = n.value;
if (n.isSmall) {
if (isPrecise(a + b)) return new SmallInteger(a + b);
b = smallToArray(Math.abs(b));
}
return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
};
SmallInteger.prototype.plus = SmallInteger.prototype.add;
NativeBigInt.prototype.add = function (v) {
return new NativeBigInt(this.value + parseValue(v).value);
};
NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
function subtract(a, b) { // assumes a and b are arrays with a >= b
var a_l = a.length,
b_l = b.length,
r = new Array(a_l),
borrow = 0,
base = BASE,
i, difference;
for (i = 0; i < b_l; i++) {
difference = a[i] - borrow - b[i];
if (difference < 0) {
difference += base;
borrow = 1;
} else borrow = 0;
r[i] = difference;
}
for (i = b_l; i < a_l; i++) {
difference = a[i] - borrow;
if (difference < 0) difference += base;
else {
r[i++] = difference;
break;
}
r[i] = difference;
}
for (; i < a_l; i++) {
r[i] = a[i];
}
trim(r);
return r;
}
function subtractAny(a, b, sign) {
var value;
if (compareAbs(a, b) >= 0) {
value = subtract(a, b);
} else {
value = subtract(b, a);
sign = !sign;
}
value = arrayToSmall(value);
if (typeof value === "number") {
if (sign) value = -value;
return new SmallInteger(value);
}
return new BigInteger(value, sign);
}
function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
var l = a.length,
r = new Array(l),
carry = -b,
base = BASE,
i, difference;
for (i = 0; i < l; i++) {
difference = a[i] + carry;
carry = Math.floor(difference / base);
difference %= base;
r[i] = difference < 0 ? difference + base : difference;
}
r = arrayToSmall(r);
if (typeof r === "number") {
if (sign) r = -r;
return new SmallInteger(r);
} return new BigInteger(r, sign);
}
BigInteger.prototype.subtract = function (v) {
var n = parseValue(v);
if (this.sign !== n.sign) {
return this.add(n.negate());
}
var a = this.value, b = n.value;
if (n.isSmall)
return subtractSmall(a, Math.abs(b), this.sign);
return subtractAny(a, b, this.sign);
};
BigInteger.prototype.minus = BigInteger.prototype.subtract;
SmallInteger.prototype.subtract = function (v) {
var n = parseValue(v);
var a = this.value;
if (a < 0 !== n.sign) {
return this.add(n.negate());
}
var b = n.value;
if (n.isSmall) {
return new SmallInteger(a - b);
}
return subtractSmall(b, Math.abs(a), a >= 0);
};
SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
NativeBigInt.prototype.subtract = function (v) {
return new NativeBigInt(this.value - parseValue(v).value);
};
NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
BigInteger.prototype.negate = function () {
return new BigInteger(this.value, !this.sign);
};
SmallInteger.prototype.negate = function () {
var sign = this.sign;
var small = new SmallInteger(-this.value);
small.sign = !sign;
return small;
};
NativeBigInt.prototype.negate = function () {
return new NativeBigInt(-this.value);
};
BigInteger.prototype.abs = function () {
return new BigInteger(this.value, false);
};
SmallInteger.prototype.abs = function () {
return new SmallInteger(Math.abs(this.value));
};
NativeBigInt.prototype.abs = function () {
return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
};
function multiplyLong(a, b) {
var a_l = a.length,
b_l = b.length,
l = a_l + b_l,
r = createArray(l),
base = BASE,
product, carry, i, a_i, b_j;
for (i = 0; i < a_l; ++i) {
a_i = a[i];
for (var j = 0; j < b_l; ++j) {
b_j = b[j];
product = a_i * b_j + r[i + j];
carry = Math.floor(product / base);
r[i + j] = product - carry * base;
r[i + j + 1] += carry;
}
}
trim(r);
return r;
}
function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
var l = a.length,
r = new Array(l),
base = BASE,
carry = 0,
product, i;
for (i = 0; i < l; i++) {
product = a[i] * b + carry;
carry = Math.floor(product / base);
r[i] = product - carry * base;
}
while (carry > 0) {
r[i++] = carry % base;
carry = Math.floor(carry / base);
}
return r;
}
function shiftLeft(x, n) {
var r = [];
while (n-- > 0) r.push(0);
return r.concat(x);
}
function multiplyKaratsuba(x, y) {
var n = Math.max(x.length, y.length);
if (n <= 30) return multiplyLong(x, y);
n = Math.ceil(n / 2);
var b = x.slice(n),
a = x.slice(0, n),
d = y.slice(n),
c = y.slice(0, n);
var ac = multiplyKaratsuba(a, c),
bd = multiplyKaratsuba(b, d),
abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
trim(product);
return product;
}
// The following function is derived from a surface fit of a graph plotting the performance difference
// between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
function useKaratsuba(l1, l2) {
return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
}
BigInteger.prototype.multiply = function (v) {
var n = parseValue(v),
a = this.value, b = n.value,
sign = this.sign !== n.sign,
abs;
if (n.isSmall) {
if (b === 0) return Integer[0];
if (b === 1) return this;
if (b === -1) return this.negate();
abs = Math.abs(b);
if (abs < BASE) {
return new BigInteger(multiplySmall(a, abs), sign);
}
b = smallToArray(abs);
}
if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
return new BigInteger(multiplyKaratsuba(a, b), sign);
return new BigInteger(multiplyLong(a, b), sign);
};
BigInteger.prototype.times = BigInteger.prototype.multiply;
function multiplySmallAndArray(a, b, sign) { // a >= 0
if (a < BASE) {
return new BigInteger(multiplySmall(b, a), sign);
}
return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
}
SmallInteger.prototype._multiplyBySmall = function (a) {
if (isPrecise(a.value * this.value)) {
return new SmallInteger(a.value * this.value);
}
return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
};
BigInteger.prototype._multiplyBySmall = function (a) {
if (a.value === 0) return Integer[0];
if (a.value === 1) return this;
if (a.value === -1) return this.negate();
return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
};
SmallInteger.prototype.multiply = function (v) {
return parseValue(v)._multiplyBySmall(this);
};
SmallInteger.prototype.times = SmallInteger.prototype.multiply;
NativeBigInt.prototype.multiply = function (v) {
return new NativeBigInt(this.value * parseValue(v).value);
};
NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
function square(a) {
//console.assert(2 * BASE * BASE < MAX_INT);
var l = a.length,
r = createArray(l + l),
base = BASE,
product, carry, i, a_i, a_j;
for (i = 0; i < l; i++) {
a_i = a[i];
carry = 0 - a_i * a_i;
for (var j = i; j < l; j++) {
a_j = a[j];
product = 2 * (a_i * a_j) + r[i + j] + carry;
carry = Math.floor(product / base);
r[i + j] = product - carry * base;
}
r[i + l] = carry;
}
trim(r);
return r;
}
BigInteger.prototype.square = function () {
return new BigInteger(square(this.value), false);
};
SmallInteger.prototype.square = function () {
var value = this.value * this.value;
if (isPrecise(value)) return new SmallInteger(value);
return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
};
NativeBigInt.prototype.square = function (v) {
return new NativeBigInt(this.value * this.value);
};
function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
var a_l = a.length,
b_l = b.length,
base = BASE,
result = createArray(b.length),
divisorMostSignificantDigit = b[b_l - 1],
// normalization
lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
remainder = multiplySmall(a, lambda),
divisor = multiplySmall(b, lambda),
quotientDigit, shift, carry, borrow, i, l, q;
if (remainder.length <= a_l) remainder.push(0);
divisor.push(0);
divisorMostSignificantDigit = divisor[b_l - 1];
for (shift = a_l - b_l; shift >= 0; shift--) {
quotientDigit = base - 1;
if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
}
// quotientDigit <= base - 1
carry = 0;
borrow = 0;
l = divisor.length;
for (i = 0; i < l; i++) {
carry += quotientDigit * divisor[i];
q = Math.floor(carry / base);
borrow += remainder[shift + i] - (carry - q * base);
carry = q;
if (borrow < 0) {
remainder[shift + i] = borrow + base;
borrow = -1;
} else {
remainder[shift + i] = borrow;
borrow = 0;
}
}
while (borrow !== 0) {
quotientDigit -= 1;
carry = 0;
for (i = 0; i < l; i++) {
carry += remainder[shift + i] - base + divisor[i];
if (carry < 0) {
remainder[shift + i] = carry + base;
carry = 0;
} else {
remainder[shift + i] = carry;
carry = 1;
}
}
borrow += carry;
}
result[shift] = quotientDigit;
}
// denormalization
remainder = divModSmall(remainder, lambda)[0];
return [arrayToSmall(result), arrayToSmall(remainder)];
}
function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
// Performs faster than divMod1 on larger input sizes.
var a_l = a.length,
b_l = b.length,
result = [],
part = [],
base = BASE,
guess, xlen, highx, highy, check;
while (a_l) {
part.unshift(a[--a_l]);
trim(part);
if (compareAbs(part, b) < 0) {
result.push(0);
continue;
}
xlen = part.length;
highx = part[xlen - 1] * base + part[xlen - 2];
highy = b[b_l - 1] * base + b[b_l - 2];
if (xlen > b_l) {
highx = (highx + 1) * base;
}
guess = Math.ceil(highx / highy);
do {
check = multiplySmall(b, guess);
if (compareAbs(check, part) <= 0) break;
guess--;
} while (guess);
result.push(guess);
part = subtract(part, check);
}
result.reverse();
return [arrayToSmall(result), arrayToSmall(part)];
}
function divModSmall(value, lambda) {
var length = value.length,
quotient = createArray(length),
base = BASE,
i, q, remainder, divisor;
remainder = 0;
for (i = length - 1; i >= 0; --i) {
divisor = remainder * base + value[i];
q = truncate(divisor / lambda);
remainder = divisor - q * lambda;
quotient[i] = q | 0;
}
return [quotient, remainder | 0];
}
function divModAny(self, v) {
var value, n = parseValue(v);
if (supportsNativeBigInt) {
return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
}
var a = self.value, b = n.value;
var quotient;
if (b === 0) throw new Error("Cannot divide by zero");
if (self.isSmall) {
if (n.isSmall) {
return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
}
return [Integer[0], self];
}
if (n.isSmall) {
if (b === 1) return [self, Integer[0]];
if (b == -1) return [self.negate(), Integer[0]];
var abs = Math.abs(b);
if (abs < BASE) {
value = divModSmall(a, abs);
quotient = arrayToSmall(value[0]);
var remainder = value[1];
if (self.sign) remainder = -remainder;
if (typeof quotient === "number") {
if (self.sign !== n.sign) quotient = -quotient;
return [new SmallInteger(quotient), new SmallInteger(remainder)];
}
return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
}
b = smallToArray(abs);
}
var comparison = compareAbs(a, b);
if (comparison === -1) return [Integer[0], self];
if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
// divMod1 is faster on smaller input sizes
if (a.length + b.length <= 200)
value = divMod1(a, b);
else value = divMod2(a, b);
quotient = value[0];
var qSign = self.sign !== n.sign,
mod = value[1],
mSign = self.sign;
if (typeof quotient === "number") {
if (qSign) quotient = -quotient;
quotient = new SmallInteger(quotient);
} else quotient = new BigInteger(quotient, qSign);
if (typeof mod === "number") {
if (mSign) mod = -mod;
mod = new SmallInteger(mod);
} else mod = new BigInteger(mod, mSign);
return [quotient, mod];
}
BigInteger.prototype.divmod = function (v) {
var result = divModAny(this, v);
return {
quotient: result[0],
remainder: result[1]
};
};
NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
BigInteger.prototype.divide = function (v) {
return divModAny(this, v)[0];
};
NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
return new NativeBigInt(this.value / parseValue(v).value);
};
SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
BigInteger.prototype.mod = function (v) {
return divModAny(this, v)[1];
};
NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
return new NativeBigInt(this.value % parseValue(v).value);
};
SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
BigInteger.prototype.pow = function (v) {
var n = parseValue(v),
a = this.value,
b = n.value,
value, x, y;
if (b === 0) return Integer[1];
if (a === 0) return Integer[0];
if (a === 1) return Integer[1];
if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
if (n.sign) {
return Integer[0];
}
if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
if (this.isSmall) {
if (isPrecise(value = Math.pow(a, b)))
return new SmallInteger(truncate(value));
}
x = this;
y = Integer[1];
while (true) {
if (b & 1 === 1) {
y = y.times(x);
--b;
}
if (b === 0) break;
b /= 2;
x = x.square();
}
return y;
};
SmallInteger.prototype.pow = BigInteger.prototype.pow;
NativeBigInt.prototype.pow = function (v) {
var n = parseValue(v);
var a = this.value, b = n.value;
var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
if (b === _0) return Integer[1];
if (a === _0) return Integer[0];
if (a === _1) return Integer[1];
if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
if (n.isNegative()) return new NativeBigInt(_0);
var x = this;
var y = Integer[1];
while (true) {
if ((b & _1) === _1) {
y = y.times(x);
--b;
}
if (b === _0) break;
b /= _2;
x = x.square();
}
return y;
};
BigInteger.prototype.modPow = function (exp, mod) {
exp = parseValue(exp);
mod = parseValue(mod);
if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
var r = Integer[1],
base = this.mod(mod);
if (exp.isNegative()) {
exp = exp.multiply(Integer[-1]);
base = base.modInv(mod);
}
while (exp.isPositive()) {
if (base.isZero()) return Integer[0];
if (exp.isOdd()) r = r.multiply(base).mod(mod);
exp = exp.divide(2);
base = base.square().mod(mod);
}
return r;
};
NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
function compareAbs(a, b) {
if (a.length !== b.length) {
return a.length > b.length ? 1 : -1;
}
for (var i = a.length - 1; i >= 0; i--) {
if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
}
return 0;
}
BigInteger.prototype.compareAbs = function (v) {
var n = parseValue(v),
a = this.value,
b = n.value;
if (n.isSmall) return 1;
return compareAbs(a, b);
};
SmallInteger.prototype.compareAbs = function (v) {
var n = parseValue(v),
a = Math.abs(this.value),
b = n.value;
if (n.isSmall) {
b = Math.abs(b);
return a === b ? 0 : a > b ? 1 : -1;
}
return -1;
};
NativeBigInt.prototype.compareAbs = function (v) {
var a = this.value;
var b = parseValue(v).value;
a = a >= 0 ? a : -a;
b = b >= 0 ? b : -b;
return a === b ? 0 : a > b ? 1 : -1;
};
BigInteger.prototype.compare = function (v) {
// See discussion about comparison with Infinity:
// https://github.com/peterolson/BigInteger.js/issues/61
if (v === Infinity) {
return -1;
}
if (v === -Infinity) {
return 1;
}
var n = parseValue(v),
a = this.value,
b = n.value;
if (this.sign !== n.sign) {
return n.sign ? 1 : -1;
}
if (n.isSmall) {
return this.sign ? -1 : 1;
}
return compareAbs(a, b) * (this.sign ? -1 : 1);
};
BigInteger.prototype.compareTo = BigInteger.prototype.compare;
SmallInteger.prototype.compare = function (v) {
if (v === Infinity) {
return -1;
}
if (v === -Infinity) {
return 1;
}
var n = parseValue(v),
a = this.value,
b = n.value;
if (n.isSmall) {
return a == b ? 0 : a > b ? 1 : -1;
}
if (a < 0 !== n.sign) {
return a < 0 ? -1 : 1;
}
return a < 0 ? 1 : -1;
};
SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
NativeBigInt.prototype.compare = function (v) {
if (v === Infinity) {
return -1;
}
if (v === -Infinity) {
return 1;
}
var a = this.value;
var b = parseValue(v).value;
return a === b ? 0 : a > b ? 1 : -1;
};
NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
BigInteger.prototype.equals = function (v) {
return this.compare(v) === 0;
};
NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
BigInteger.prototype.notEquals = function (v) {
return this.compare(v) !== 0;
};
NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
BigInteger.prototype.greater = function (v) {
return this.compare(v) > 0;
};
NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
BigInteger.prototype.lesser = function (v) {
return this.compare(v) < 0;
};
NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
BigInteger.prototype.greaterOrEquals = function (v) {
return this.compare(v) >= 0;
};
NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
BigInteger.prototype.lesserOrEquals = function (v) {
return this.compare(v) <= 0;
};
NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
BigInteger.prototype.isEven = function () {
return (this.value[0] & 1) === 0;
};
SmallInteger.prototype.isEven = function () {
return (this.value & 1) === 0;
};
NativeBigInt.prototype.isEven = function () {
return (this.value & BigInt(1)) === BigInt(0);
};
BigInteger.prototype.isOdd = function () {
return (this.value[0] & 1) === 1;
};
SmallInteger.prototype.isOdd = function () {
return (this.value & 1) === 1;
};
NativeBigInt.prototype.isOdd = function () {
return (this.value & BigInt(1)) === BigInt(1);
};
BigInteger.prototype.isPositive = function () {
return !this.sign;
};
SmallInteger.prototype.isPositive = function () {
return this.value > 0;
};
NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
BigInteger.prototype.isNegative = function () {
return this.sign;
};
SmallInteger.prototype.isNegative = function () {
return this.value < 0;
};
NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
BigInteger.prototype.isUnit = function () {
return false;
};
SmallInteger.prototype.isUnit = function () {
return Math.abs(this.value) === 1;
};
NativeBigInt.prototype.isUnit = function () {
return this.abs().value === BigInt(1);
};
BigInteger.prototype.isZero = function () {
return false;
};
SmallInteger.prototype.isZero = function () {
return this.value === 0;
};
NativeBigInt.prototype.isZero = function () {
return this.value === BigInt(0);
};
BigInteger.prototype.isDivisibleBy = function (v) {
var n = parseValue(v);
if (n.isZero()) return false;
if (n.isUnit()) return true;
if (n.compareAbs(2) === 0) return this.isEven();
return this.mod(n).isZero();
};
NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
function isBasicPrime(v) {
var n = v.abs();
if (n.isUnit()) return false;
if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
if (n.lesser(49)) return true;
// we don't know if it's prime: let the other functions figure it out
}
function millerRabinTest(n, a) {
var nPrev = n.prev(),
b = nPrev,
r = 0,
d, i, x;
while (b.isEven()) b = b.divide(2), r++;
next: for (i = 0; i < a.length; i++) {
if (n.lesser(a[i])) continue;
x = bigInt(a[i]).modPow(b, n);
if (x.isUnit() || x.equals(nPrev)) continue;
for (d = r - 1; d != 0; d--) {
x = x.square().mod(n);
if (x.isUnit()) return false;
if (x.equals(nPrev)) continue next;
}
return false;
}
return true;
}
// Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
BigInteger.prototype.isPrime = function (strict) {
var isPrime = isBasicPrime(this);
if (isPrime !== undefined$1) return isPrime;
var n = this.abs();
var bits = n.bitLength();
if (bits <= 64)
return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
var logN = Math.log(2) * bits.toJSNumber();
var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
for (var a = [], i = 0; i < t; i++) {
a.push(bigInt(i + 2));
}
return millerRabinTest(n, a);
};
NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
BigInteger.prototype.isProbablePrime = function (iterations, rng) {
var isPrime = isBasicPrime(this);
if (isPrime !== undefined$1) return isPrime;
var n = this.abs();
var t = iterations === undefined$1 ? 5 : iterations;
for (var a = [], i = 0; i < t; i++) {
a.push(bigInt.randBetween(2, n.minus(2), rng));
}
return millerRabinTest(n, a);
};
NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
BigInteger.prototype.modInv = function (n) {
var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
while (!newR.isZero()) {
q = r.divide(newR);
lastT = t;
lastR = r;
t = newT;
r = newR;
newT = lastT.subtract(q.multiply(newT));
newR = lastR.subtract(q.multiply(newR));
}
if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
if (t.compare(0) === -1) {
t = t.add(n);
}
if (this.isNegative()) {
return t.negate();
}
return t;
};
NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
BigInteger.prototype.next = function () {
var value = this.value;
if (this.sign) {
return subtractSmall(value, 1, this.sign);
}
return new BigInteger(addSmall(value, 1), this.sign);
};
SmallInteger.prototype.next = function () {
var value = this.value;
if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
return new BigInteger(MAX_INT_ARR, false);
};
NativeBigInt.prototype.next = function () {
return new NativeBigInt(this.value + BigInt(1));
};
BigInteger.prototype.prev = function () {
var value = this.value;
if (this.sign) {
return new BigInteger(addSmall(value, 1), true);
}
return subtractSmall(value, 1, this.sign);
};
SmallInteger.prototype.prev = function () {
var value = this.value;
if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
return new BigInteger(MAX_INT_ARR, true);
};
NativeBigInt.prototype.prev = function () {
return new NativeBigInt(this.value - BigInt(1));
};
var powersOfTwo = [1];
while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
function shift_isSmall(n) {
return Math.abs(n) <= BASE;
}
BigInteger.prototype.shiftLeft = function (v) {
var n = parseValue(v).toJSNumber();
if (!shift_isSmall(n)) {
throw new Error(String(n) + " is too large for shifting.");
}
if (n < 0) return this.shiftRight(-n);
var result = this;
if (result.isZero()) return result;
while (n >= powers2Length) {
result = result.multiply(highestPower2);
n -= powers2Length - 1;
}
return result.multiply(powersOfTwo[n]);
};
NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
BigInteger.prototype.shiftRight = function (v) {
var remQuo;
var n = parseValue(v).toJSNumber();
if (!shift_isSmall(n)) {
throw new Error(String(n) + " is too large for shifting.");
}
if (n < 0) return this.shiftLeft(-n);
var result = this;
while (n >= powers2Length) {
if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
remQuo = divModAny(result, highestPower2);
result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
n -= powers2Length - 1;
}
remQuo = divModAny(result, powersOfTwo[n]);
return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
};
NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
function bitwise(x, y, fn) {
y = parseValue(y);
var xSign = x.isNegative(), ySign = y.isNegative();
var xRem = xSign ? x.not() : x,
yRem = ySign ? y.not() : y;
var xDigit = 0, yDigit = 0;
var xDivMod = null, yDivMod = null;
var result = [];
while (!xRem.isZero() || !yRem.isZero()) {
xDivMod = divModAny(xRem, highestPower2);
xDigit = xDivMod[1].toJSNumber();
if (xSign) {
xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
}
yDivMod = divModAny(yRem, highestPower2);
yDigit = yDivMod[1].toJSNumber();
if (ySign) {
yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
}
xRem = xDivMod[0];
yRem = yDivMod[0];
result.push(fn(xDigit, yDigit));
}
var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
for (var i = result.length - 1; i >= 0; i -= 1) {
sum = sum.multiply(highestPower2).add(bigInt(result[i]));
}
return sum;
}
BigInteger.prototype.not = function () {
return this.negate().prev();
};
NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
BigInteger.prototype.and = function (n) {
return bitwise(this, n, function (a, b) { return a & b; });
};
NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
BigInteger.prototype.or = function (n) {
return bitwise(this, n, function (a, b) { return a | b; });
};
NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
BigInteger.prototype.xor = function (n) {
return bitwise(this, n, function (a, b) { return a ^ b; });
};
NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
function roughLOB(n) { // get lowestOneBit (rough)
// SmallInteger: return Min(lowestOneBit(n), 1 << 30)
// BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
var v = n.value,
x = typeof v === "number" ? v | LOBMASK_I :
typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
v[0] + v[1] * BASE | LOBMASK_BI;
return x & -x;
}
function integerLogarithm(value, base) {
if (base.compareTo(value) <= 0) {
var tmp = integerLogarithm(value, base.square(base));
var p = tmp.p;
var e = tmp.e;
var t = p.multiply(base);
return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
}
return { p: bigInt(1), e: 0 };
}
BigInteger.prototype.bitLength = function () {
var n = this;
if (n.compareTo(bigInt(0)) < 0) {
n = n.negate().subtract(bigInt(1));
}
if (n.compareTo(bigInt(0)) === 0) {
return bigInt(0);
}
return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
};
NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
function max(a, b) {
a = parseValue(a);
b = parseValue(b);
return a.greater(b) ? a : b;
}
function min(a, b) {
a = parseValue(a);
b = parseValue(b);
return a.lesser(b) ? a : b;
}
function gcd(a, b) {
a = parseValue(a).abs();
b = parseValue(b).abs();
if (a.equals(b)) return a;
if (a.isZero()) return b;
if (b.isZero()) return a;
var c = Integer[1], d, t;
while (a.isEven() && b.isEven()) {
d = min(roughLOB(a), roughLOB(b));
a = a.divide(d);
b = b.divide(d);
c = c.multiply(d);
}
while (a.isEven()) {
a = a.divide(roughLOB(a));
}
do {
while (b.isEven()) {
b = b.divide(roughLOB(b));
}
if (a.greater(b)) {
t = b; b = a; a = t;
}
b = b.subtract(a);
} while (!b.isZero());
return c.isUnit() ? a : a.multiply(c);
}
function lcm(a, b) {
a = parseValue(a).abs();
b = parseValue(b).abs();
return a.divide(gcd(a, b)).multiply(b);
}
function randBetween(a, b, rng) {
a = parseValue(a);
b = parseValue(b);
var usedRNG = rng || Math.random;
var low = min(a, b), high = max(a, b);
var range = high.subtract(low).add(1);
if (range.isSmall) return low.add(Math.floor(usedRNG() * range));
var digits = toBase(range, BASE).value;
var result = [], restricted = true;
for (var i = 0; i < digits.length; i++) {
var top = restricted ? digits[i] + (i + 1 < digits.length ? digits[i + 1] / BASE : 0) : BASE;
var digit = truncate(usedRNG() * top);
result.push(digit);
if (digit < digits[i]) restricted = false;
}
return low.add(Integer.fromArray(result, BASE, false));
}
var parseBase = function (text, base, alphabet, caseSensitive) {
alphabet = alphabet || DEFAULT_ALPHABET;
text = String(text);
if (!caseSensitive) {
text = text.toLowerCase();
alphabet = alphabet.toLowerCase();
}
var length = text.length;
var i;
var absBase = Math.abs(base);
var alphabetValues = {};
for (i = 0; i < alphabet.length; i++) {
alphabetValues[alphabet[i]] = i;
}
for (i = 0; i < length; i++) {
var c = text[i];
if (c === "-") continue;
if (c in alphabetValues) {
if (alphabetValues[c] >= absBase) {
if (c === "1" && absBase === 1) continue;
throw new Error(c + " is not a valid digit in base " + base + ".");
}
}
}
base = parseValue(base);
var digits = [];
var isNegative = text[0] === "-";
for (i = isNegative ? 1 : 0; i < text.length; i++) {
var c = text[i];
if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
else if (c === "<") {
var start = i;
do { i++; } while (text[i] !== ">" && i < text.length);
digits.push(parseValue(text.slice(start + 1, i)));
}
else throw new Error(c + " is not a valid character");
}
return parseBaseFromArray(digits, base, isNegative);
};
function parseBaseFromArray(digits, base, isNegative) {
var val = Integer[0], pow = Integer[1], i;
for (i = digits.length - 1; i >= 0; i--) {
val = val.add(digits[i].times(pow));
pow = pow.times(base);
}
return isNegative ? val.negate() : val;
}
function stringify(digit, alphabet) {
alphabet = alphabet || DEFAULT_ALPHABET;
if (digit < alphabet.length) {
return alphabet[digit];
}
return "<" + digit + ">";
}
function toBase(n, base) {
base = bigInt(base);
if (base.isZero()) {
if (n.isZero()) return { value: [0], isNegative: false };
throw new Error("Cannot convert nonzero numbers to base 0.");
}
if (base.equals(-1)) {
if (n.isZero()) return { value: [0], isNegative: false };
if (n.isNegative())
return {
value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
.map(Array.prototype.valueOf, [1, 0])
),
isNegative: false
};
var arr = Array.apply(null, Array(n.toJSNumber() - 1))
.map(Array.prototype.valueOf, [0, 1]);
arr.unshift([1]);
return {
value: [].concat.apply([], arr),
isNegative: false
};
}
var neg = false;
if (n.isNegative() && base.isPositive()) {
neg = true;
n = n.abs();
}
if (base.isUnit()) {
if (n.isZero()) return { value: [0], isNegative: false };
return {
value: Array.apply(null, Array(n.toJSNumber()))
.map(Number.prototype.valueOf, 1),
isNegative: neg
};
}
var out = [];
var left = n, divmod;
while (left.isNegative() || left.compareAbs(base) >= 0) {
divmod = left.divmod(base);
left = divmod.quotient;
var digit = divmod.remainder;
if (digit.isNegative()) {
digit = base.minus(digit).abs();
left = left.next();
}
out.push(digit.toJSNumber());
}
out.push(left.toJSNumber());
return { value: out.reverse(), isNegative: neg };
}
function toBaseString(n, base, alphabet) {
var arr = toBase(n, base);
return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
return stringify(x, alphabet);
}).join('');
}
BigInteger.prototype.toArray = function (radix) {
return toBase(this, radix);
};
SmallInteger.prototype.toArray = function (radix) {
return toBase(this, radix);
};
NativeBigInt.prototype.toArray = function (radix) {
return toBase(this, radix);
};
BigInteger.prototype.toString = function (radix, alphabet) {
if (radix === undefined$1) radix = 10;
if (radix !== 10) return toBaseString(this, radix, alphabet);
var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
while (--l >= 0) {
digit = String(v[l]);
str += zeros.slice(digit.length) + digit;
}
var sign = this.sign ? "-" : "";
return sign + str;
};
SmallInteger.prototype.toString = function (radix, alphabet) {
if (radix === undefined$1) radix = 10;
if (radix != 10) return toBaseString(this, radix, alphabet);
return String(this.value);
};
NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); };
BigInteger.prototype.valueOf = function () {
return parseInt(this.toString(), 10);
};
BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
SmallInteger.prototype.valueOf = function () {
return this.value;
};
SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
return parseInt(this.toString(), 10);
};
function parseStringValue(v) {
if (isPrecise(+v)) {
var x = +v;
if (x === truncate(x))
return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
throw new Error("Invalid integer: " + v);
}
var sign = v[0] === "-";
if (sign) v = v.slice(1);
var split = v.split(/e/i);
if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
if (split.length === 2) {
var exp = split[1];
if (exp[0] === "+") exp = exp.slice(1);
exp = +exp;
if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
var text = split[0];
var decimalPlace = text.indexOf(".");
if (decimalPlace >= 0) {
exp -= text.length - decimalPlace - 1;
text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
}
if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
text += (new Array(exp + 1)).join("0");
v = text;
}
var isValid = /^([0-9][0-9]*)$/.test(v);
if (!isValid) throw new Error("Invalid integer: " + v);
if (supportsNativeBigInt) {
return new NativeBigInt(BigInt(sign ? "-" + v : v));
}
var r = [], max = v.length, l = LOG_BASE, min = max - l;
while (max > 0) {
r.push(+v.slice(min, max));
min -= l;
if (min < 0) min = 0;
max -= l;
}
trim(r);
return new BigInteger(r, sign);
}
function parseNumberValue(v) {
if (supportsNativeBigInt) {
return new NativeBigInt(BigInt(v));
}
if (isPrecise(v)) {
if (v !== truncate(v)) throw new Error(v + " is not an integer.");
return new SmallInteger(v);
}
return parseStringValue(v.toString());
}
function parseValue(v) {
if (typeof v === "number") {
return parseNumberValue(v);
}
if (typeof v === "string") {
return parseStringValue(v);
}
if (typeof v === "bigint") {
return new NativeBigInt(v);
}
return v;
}
// Pre-define numbers in range [-999,999]
for (var i = 0; i < 1000; i++) {
Integer[i] = parseValue(i);
if (i > 0) Integer[-i] = parseValue(-i);
}
// Backwards compatibility
Integer.one = Integer[1];
Integer.zero = Integer[0];
Integer.minusOne = Integer[-1];
Integer.max = max;
Integer.min = min;
Integer.gcd = gcd;
Integer.lcm = lcm;
Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
Integer.randBetween = randBetween;
Integer.fromArray = function (digits, base, isNegative) {
return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
};
return Integer;
})();
// Node.js check
if (module.hasOwnProperty("exports")) {
module.exports = bigInt;
}
}(BigInteger));
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function getRandomBytes(n) {
return randomBytes(n);
}
const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
class EncodingError extends Error {
constructor() {
super("Encoding error");
Object.setPrototypeOf(this, EncodingError.prototype);
}
}
function getValue(chr) {
let a = chr;
switch (chr) {
case "O":
case "o":
a = "0;";
break;
case "i":
case "I":
case "l":
case "L":
a = "1";
break;
case "u":
case "U":
a = "V";
}
if (a >= "0" && a <= "9") {
return a.charCodeAt(0) - "0".charCodeAt(0);
}
if (a >= "a" && a <= "z")
a = a.toUpperCase();
let dec = 0;
if (a >= "A" && a <= "Z") {
if ("I" < a)
dec++;
if ("L" < a)
dec++;
if ("O" < a)
dec++;
if ("U" < a)
dec++;
return a.charCodeAt(0) - "A".charCodeAt(0) + 10 - dec;
}
throw new EncodingError();
}
function encodeCrock(data) {
const dataBytes = new Uint8Array(data);
let sb = "";
const size = data.byteLength;
let bitBuf = 0;
let numBits = 0;
let pos = 0;
while (pos < size || numBits > 0) {
if (pos < size && numBits < 5) {
const d = dataBytes[pos++];
bitBuf = (bitBuf << 8) | d;
numBits += 8;
}
if (numBits < 5) {
// zero-padding
bitBuf = bitBuf << (5 - numBits);
numBits = 5;
}
const v = (bitBuf >>> (numBits - 5)) & 31;
sb += encTable[v];
numBits -= 5;
}
return sb;
}
function decodeCrock(encoded) {
const size = encoded.length;
let bitpos = 0;
let bitbuf = 0;
let readPosition = 0;
const outLen = Math.floor((size * 5) / 8);
const out = new Uint8Array(outLen);
let outPos = 0;
while (readPosition < size || bitpos > 0) {
if (readPosition < size) {
const v = getValue(encoded[readPosition++]);
bitbuf = (bitbuf << 5) | v;
bitpos += 5;
}
while (bitpos >= 8) {
const d = (bitbuf >>> (bitpos - 8)) & 0xff;
out[outPos++] = d;
bitpos -= 8;
}
if (readPosition == size && bitpos > 0) {
bitbuf = (bitbuf << (8 - bitpos)) & 0xff;
bitpos = bitbuf == 0 ? 0 : 8;
}
}
return out;
}
// Newer versions of node have TextEncoder and TextDecoder as a global,
// just like modern browsers.
// In older versions of node or environments that do not have these
// globals, they must be polyfilled (by adding them to globa/globalThis)
// before stringToBytes or bytesToString is called the first time.
let encoder;
function stringToBytes(s) {
if (!encoder) {
// @ts-ignore
encoder = new TextEncoder();
}
return encoder.encode(s);
}
function hash(d) {
return hash$1(d);
}
new Logger("talerCrypto.ts");
var TalerSignaturePurpose;
(function (TalerSignaturePurpose) {
TalerSignaturePurpose[TalerSignaturePurpose["MERCHANT_TRACK_TRANSACTION"] = 1103] = "MERCHANT_TRACK_TRANSACTION";
TalerSignaturePurpose[TalerSignaturePurpose["WALLET_RESERVE_WITHDRAW"] = 1200] = "WALLET_RESERVE_WITHDRAW";
TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_DEPOSIT"] = 1201] = "WALLET_COIN_DEPOSIT";
TalerSignaturePurpose[TalerSignaturePurpose["MASTER_DENOMINATION_KEY_VALIDITY"] = 1025] = "MASTER_DENOMINATION_KEY_VALIDITY";
TalerSignaturePurpose[TalerSignaturePurpose["MASTER_WIRE_FEES"] = 1028] = "MASTER_WIRE_FEES";
TalerSignaturePurpose[TalerSignaturePurpose["MASTER_WIRE_DETAILS"] = 1030] = "MASTER_WIRE_DETAILS";
TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_MELT"] = 1202] = "WALLET_COIN_MELT";
TalerSignaturePurpose[TalerSignaturePurpose["TEST"] = 4242] = "TEST";
TalerSignaturePurpose[TalerSignaturePurpose["MERCHANT_PAYMENT_OK"] = 1104] = "MERCHANT_PAYMENT_OK";
TalerSignaturePurpose[TalerSignaturePurpose["MERCHANT_CONTRACT"] = 1101] = "MERCHANT_CONTRACT";
TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_RECOUP"] = 1203] = "WALLET_COIN_RECOUP";
TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_LINK"] = 1204] = "WALLET_COIN_LINK";
TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_RECOUP_REFRESH"] = 1206] = "WALLET_COIN_RECOUP_REFRESH";
TalerSignaturePurpose[TalerSignaturePurpose["EXCHANGE_CONFIRM_RECOUP"] = 1039] = "EXCHANGE_CONFIRM_RECOUP";
TalerSignaturePurpose[TalerSignaturePurpose["EXCHANGE_CONFIRM_RECOUP_REFRESH"] = 1041] = "EXCHANGE_CONFIRM_RECOUP_REFRESH";
TalerSignaturePurpose[TalerSignaturePurpose["ANASTASIS_POLICY_UPLOAD"] = 1400] = "ANASTASIS_POLICY_UPLOAD";
TalerSignaturePurpose[TalerSignaturePurpose["ANASTASIS_POLICY_DOWNLOAD"] = 1401] = "ANASTASIS_POLICY_DOWNLOAD";
TalerSignaturePurpose[TalerSignaturePurpose["SYNC_BACKUP_UPLOAD"] = 1450] = "SYNC_BACKUP_UPLOAD";
})(TalerSignaturePurpose || (TalerSignaturePurpose = {}));
/**
* Hypertext Transfer Protocol (HTTP) response status codes.
*
* @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
*/
var HttpStatusCode;
(function (HttpStatusCode) {
/**
* The server has received the request headers and the client should proceed to send the request body
* (in the case of a request for which a body needs to be sent; for example, a POST request).
* Sending a large request body to a server after a request has been rejected for inappropriate headers would be inefficient.
* To have a server check the request's headers, a client must send Expect: 100-continue as a header in its initial request
* and receive a 100 Continue status code in response before sending the body. The response 417 Expectation Failed indicates the request should not be continued.
*/
HttpStatusCode[HttpStatusCode["Continue"] = 100] = "Continue";
/**
* The requester has asked the server to switch protocols and the server has agreed to do so.
*/
HttpStatusCode[HttpStatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
/**
* A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request.
* This code indicates that the server has received and is processing the request, but no response is available yet.
* This prevents the client from timing out and assuming the request was lost.
*/
HttpStatusCode[HttpStatusCode["Processing"] = 102] = "Processing";
/**
* Standard response for successful HTTP requests.
* The actual response will depend on the request method used.
* In a GET request, the response will contain an entity corresponding to the requested resource.
* In a POST request, the response will contain an entity describing or containing the result of the action.
*/
HttpStatusCode[HttpStatusCode["Ok"] = 200] = "Ok";
/**
* The request has been fulfilled, resulting in the creation of a new resource.
*/
HttpStatusCode[HttpStatusCode["Created"] = 201] = "Created";
/**
* The request has been accepted for processing, but the processing has not been completed.
* The request might or might not be eventually acted upon, and may be disallowed when processing occurs.
*/
HttpStatusCode[HttpStatusCode["Accepted"] = 202] = "Accepted";
/**
* SINCE HTTP/1.1
* The server is a transforming proxy that received a 200 OK from its origin,
* but is returning a modified version of the origin's response.
*/
HttpStatusCode[HttpStatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
/**
* The server successfully processed the request and is not returning any content.
*/
HttpStatusCode[HttpStatusCode["NoContent"] = 204] = "NoContent";
/**
* The server successfully processed the request, but is not returning any content.
* Unlike a 204 response, this response requires that the requester reset the document view.
*/
HttpStatusCode[HttpStatusCode["ResetContent"] = 205] = "ResetContent";
/**
* The server is delivering only part of the resource (byte serving) due to a range header sent by the client.
* The range header is used by HTTP clients to enable resuming of interrupted downloads,
* or split a download into multiple simultaneous streams.
*/
HttpStatusCode[HttpStatusCode["PartialContent"] = 206] = "PartialContent";
/**
* The message body that follows is an XML message and can contain a number of separate response codes,
* depending on how many sub-requests were made.
*/
HttpStatusCode[HttpStatusCode["MultiStatus"] = 207] = "MultiStatus";
/**
* The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response,
* and are not being included again.
*/
HttpStatusCode[HttpStatusCode["AlreadyReported"] = 208] = "AlreadyReported";
/**
* The server has fulfilled a request for the resource,
* and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
*/
HttpStatusCode[HttpStatusCode["ImUsed"] = 226] = "ImUsed";
/**
* Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
* For example, this code could be used to present multiple video format options,
* to list files with different filename extensions, or to suggest word-sense disambiguation.
*/
HttpStatusCode[HttpStatusCode["MultipleChoices"] = 300] = "MultipleChoices";
/**
* This and all future requests should be directed to the given URI.
*/
HttpStatusCode[HttpStatusCode["MovedPermanently"] = 301] = "MovedPermanently";
/**
* This is an example of industry practice contradicting the standard.
* The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
* (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302
* with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307
* to distinguish between the two behaviours. However, some Web applications and frameworks
* use the 302 status code as if it were the 303.
*/
HttpStatusCode[HttpStatusCode["Found"] = 302] = "Found";
/**
* SINCE HTTP/1.1
* The response to the request can be found under another URI using a GET method.
* When received in response to a POST (or PUT/DELETE), the client should presume that
* the server has received the data and should issue a redirect with a separate GET message.
*/
HttpStatusCode[HttpStatusCode["SeeOther"] = 303] = "SeeOther";
/**
* Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
* In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
*/
HttpStatusCode[HttpStatusCode["NotModified"] = 304] = "NotModified";
/**
* SINCE HTTP/1.1
* The requested resource is available only through a proxy, the address for which is provided in the response.
* Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
*/
HttpStatusCode[HttpStatusCode["UseProxy"] = 305] = "UseProxy";
/**
* No longer used. Originally meant "Subsequent requests should use the specified proxy."
*/
HttpStatusCode[HttpStatusCode["SwitchProxy"] = 306] = "SwitchProxy";
/**
* SINCE HTTP/1.1
* In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
* In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request.
* For example, a POST request should be repeated using another POST request.
*/
HttpStatusCode[HttpStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
/**
* The request and all future requests should be repeated using another URI.
* 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change.
* So, for example, submitting a form to a permanently redirected resource may continue smoothly.
*/
HttpStatusCode[HttpStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
/**
* The server cannot or will not process the request due to an apparent client error
* (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).
*/
HttpStatusCode[HttpStatusCode["BadRequest"] = 400] = "BadRequest";
/**
* Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet
* been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the
* requested resource. See Basic access authentication and Digest access authentication. 401 semantically means
* "unauthenticated",i.e. the user does not have the necessary credentials.
*/
HttpStatusCode[HttpStatusCode["Unauthorized"] = 401] = "Unauthorized";
/**
* Reserved for future use. The original intention was that this code might be used as part of some form of digital
* cash or micro payment scheme, but that has not happened, and this code is not usually used.
* Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
*/
HttpStatusCode[HttpStatusCode["PaymentRequired"] = 402] = "PaymentRequired";
/**
* The request was valid, but the server is refusing action.
* The user might not have the necessary permissions for a resource.
*/
HttpStatusCode[HttpStatusCode["Forbidden"] = 403] = "Forbidden";
/**
* The requested resource could not be found but may be available in the future.
* Subsequent requests by the client are permissible.
*/
HttpStatusCode[HttpStatusCode["NotFound"] = 404] = "NotFound";
/**
* A request method is not supported for the requested resource;
* for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
*/
HttpStatusCode[HttpStatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
/**
* The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
*/
HttpStatusCode[HttpStatusCode["NotAcceptable"] = 406] = "NotAcceptable";
/**
* The client must first authenticate itself with the proxy.
*/
HttpStatusCode[HttpStatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
/**
* The server timed out waiting for the request.
* According to HTTP specifications:
* "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
*/
HttpStatusCode[HttpStatusCode["RequestTimeout"] = 408] = "RequestTimeout";
/**
* Indicates that the request could not be processed because of conflict in the request,
* such as an edit conflict between multiple simultaneous updates.
*/
HttpStatusCode[HttpStatusCode["Conflict"] = 409] = "Conflict";
/**
* Indicates that the resource requested is no longer available and will not be available again.
* This should be used when a resource has been intentionally removed and the resource should be purged.
* Upon receiving a 410 status code, the client should not request the resource in the future.
* Clients such as search engines should remove the resource from their indices.
* Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
*/
HttpStatusCode[HttpStatusCode["Gone"] = 410] = "Gone";
/**
* The request did not specify the length of its content, which is required by the requested resource.
*/
HttpStatusCode[HttpStatusCode["LengthRequired"] = 411] = "LengthRequired";
/**
* The server does not meet one of the preconditions that the requester put on the request.
*/
HttpStatusCode[HttpStatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
/**
* The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".
*/
HttpStatusCode[HttpStatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
/**
* The URI provided was too long for the server to process. Often the result of too much data being encoded as a query-string of a GET request,
* in which case it should be converted to a POST request.
* Called "Request-URI Too Long" previously.
*/
HttpStatusCode[HttpStatusCode["UriTooLong"] = 414] = "UriTooLong";
/**
* The request entity has a media type which the server or resource does not support.
* For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
*/
HttpStatusCode[HttpStatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
/**
* The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.
* For example, if the client asked for a part of the file that lies beyond the end of the file.
* Called "Requested Range Not Satisfiable" previously.
*/
HttpStatusCode[HttpStatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
/**
* The server cannot meet the requirements of the Expect request-header field.
*/
HttpStatusCode[HttpStatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
/**
* This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
* and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
* teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
*/
HttpStatusCode[HttpStatusCode["IAmATeapot"] = 418] = "IAmATeapot";
/**
* The request was directed at a server that is not able to produce a response (for example because a connection reuse).
*/
HttpStatusCode[HttpStatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
/**
* The request was well-formed but was unable to be followed due to semantic errors.
*/
HttpStatusCode[HttpStatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
/**
* The resource that is being accessed is locked.
*/
HttpStatusCode[HttpStatusCode["Locked"] = 423] = "Locked";
/**
* The request failed due to failure of a previous request (e.g., a PROPPATCH).
*/
HttpStatusCode[HttpStatusCode["FailedDependency"] = 424] = "FailedDependency";
/**
* The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
*/
HttpStatusCode[HttpStatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
/**
* The origin server requires the request to be conditional.
* Intended to prevent "the 'lost update' problem, where a client
* GETs a resource's state, modifies it, and PUTs it back to the server,
* when meanwhile a third party has modified the state on the server, leading to a conflict."
*/
HttpStatusCode[HttpStatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
/**
* The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes.
*/
HttpStatusCode[HttpStatusCode["TooManyRequests"] = 429] = "TooManyRequests";
/**
* The server is unwilling to process the request because either an individual header field,
* or all the header fields collectively, are too large.
*/
HttpStatusCode[HttpStatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
/**
* A server operator has received a legal demand to deny access to a resource or to a set of resources
* that includes the requested resource. The code 451 was chosen as a reference to the novel Fahrenheit 451.
*/
HttpStatusCode[HttpStatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
/**
* A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
*/
HttpStatusCode[HttpStatusCode["InternalServerError"] = 500] = "InternalServerError";
/**
* The server either does not recognize the request method, or it lacks the ability to fulfill the request.
* Usually this implies future availability (e.g., a new feature of a web-service API).
*/
HttpStatusCode[HttpStatusCode["NotImplemented"] = 501] = "NotImplemented";
/**
* The server was acting as a gateway or proxy and received an invalid response from the upstream server.
*/
HttpStatusCode[HttpStatusCode["BadGateway"] = 502] = "BadGateway";
/**
* The server is currently unavailable (because it is overloaded or down for maintenance).
* Generally, this is a temporary state.
*/
HttpStatusCode[HttpStatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
/**
* The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
*/
HttpStatusCode[HttpStatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
/**
* The server does not support the HTTP protocol version used in the request
*/
HttpStatusCode[HttpStatusCode["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
/**
* Transparent content negotiation for the request results in a circular reference.
*/
HttpStatusCode[HttpStatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
/**
* The server is unable to store the representation needed to complete the request.
*/
HttpStatusCode[HttpStatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
/**
* The server detected an infinite loop while processing the request.
*/
HttpStatusCode[HttpStatusCode["LoopDetected"] = 508] = "LoopDetected";
/**
* Further extensions to the request are required for the server to fulfill it.
*/
HttpStatusCode[HttpStatusCode["NotExtended"] = 510] = "NotExtended";
/**
* The client needs to authenticate to gain network access.
* Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
* to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
*/
HttpStatusCode[HttpStatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
})(HttpStatusCode || (HttpStatusCode = {}));
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Implementation of token bucket throttling.
*/
new Logger("RequestThrottler.ts");
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
loadBrowserPrng();
function _extends$1() {
_extends$1 = 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;
};
return _extends$1.apply(this, arguments);
}
var resolvePathname$2 = {exports: {}};
function isAbsolute(e){return "/"===e.charAt(0)}function spliceOne(e,t){for(var s=t,n=s+1,i=e.length;n2&&(f.children=arguments.length>3?n.call(arguments,2):i),"function"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===f[o]&&(f[o]=l.defaultProps[o]);return y$1(l,f,t,r,null)}function y$1(n,i,t,r,o){var f={type:n,props:i,key:t,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++u$1:o};return null==o&&null!=l$1.vnode&&l$1.vnode(f),f}function p$1(){return {current:null}}function d(n){return n.children}function _(n,l){this.props=n,this.context=l;}function k$1(n,l){if(null==l)return n.__?k$1(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l0?y$1(_.type,_.props,_.key,null,_.__v):_)){if(_.__=u,_.__b=u.__b+1,null===(p=w[h])||p&&_.key==p.key&&_.type===p.type)w[h]=void 0;else for(v=0;v2&&(f.children=arguments.length>3?n.call(arguments,2):i),y$1(l.type,f,t||l.key,r||l.ref,null)}function D(n,l){var u={__c:l="__cC"+f$1++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(m$1);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=c$1.slice,l$1={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n}},u$1=0,i$1=function(n){return null!=n&&void 0===n.constructor},_.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=a$1({},this.state),"function"==typeof n&&(n=n(a$1({},u),this.props)),n&&a$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),m$1(this));},_.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),m$1(this));},_.prototype.render=d,t$1=[],r$1="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,g$1.__r=0,f$1=0;
var preact_module = /*#__PURE__*/Object.freeze({
__proto__: null,
render: S$1,
hydrate: q$1,
createElement: v$1,
h: v$1,
Fragment: d,
createRef: p$1,
get isValidElement () { return i$1; },
Component: _,
cloneElement: B,
createContext: D,
toChildArray: A$1,
get options () { return l$1; }
});
var EMPTY$1 = {};
function assign(obj, props) {
// eslint-disable-next-line guard-for-in
for (var i in props) {
obj[i] = props[i];
}
return obj;
}
function exec(url, route, opts) {
var reg = /(?:\?([^#]*))?(#.*)?$/,
c = url.match(reg),
matches = {},
ret;
if (c && c[1]) {
var p = c[1].split('&');
for (var i=0; i b.rank) ? -1 :
(a.index - b.index)
);
}
// filter out VNodes without attributes (which are unrankeable), and add `index`/`rank` properties to be used in sorting.
function prepareVNodeForRanking(vnode, index) {
vnode.index = index;
vnode.rank = rankChild(vnode);
return vnode.props;
}
function segmentize(url) {
return url.replace(/(^\/+|\/+$)/g, '').split('/');
}
function rankSegment(segment) {
return segment.charAt(0)==':' ? (1 + '*+?'.indexOf(segment.charAt(segment.length-1))) || 4 : 5;
}
function rank(path) {
return segmentize(path).map(rankSegment).join('');
}
function rankChild(vnode) {
return vnode.props.default ? 0 : rank(vnode.props.path);
}
var customHistory = null;
var ROUTERS = [];
var subscribers = [];
var EMPTY = {};
function setUrl(url, type) {
if ( type === void 0 ) type='push';
if (customHistory && customHistory[type]) {
customHistory[type](url);
}
else if (typeof history!=='undefined' && history[type+'State']) {
history[type+'State'](null, null, url);
}
}
function getCurrentUrl() {
var url;
if (customHistory && customHistory.location) {
url = customHistory.location;
}
else if (customHistory && customHistory.getCurrentLocation) {
url = customHistory.getCurrentLocation();
}
else {
url = typeof location!=='undefined' ? location : EMPTY;
}
return ("" + (url.pathname || '') + (url.search || ''));
}
function route(url, replace) {
if ( replace === void 0 ) replace=false;
if (typeof url!=='string' && url.url) {
replace = url.replace;
url = url.url;
}
// only push URL into history if we can handle it
if (canRoute(url)) {
setUrl(url, replace ? 'replace' : 'push');
}
return routeTo(url);
}
/** Check if the given URL can be handled by any router instances. */
function canRoute(url) {
for (var i=ROUTERS.length; i--; ) {
if (ROUTERS[i].canRoute(url)) { return true; }
}
return false;
}
/** Tell all router instances to handle the given URL. */
function routeTo(url) {
var didRoute = false;
for (var i=0; i 0;
};
/** Re-render children with a new URL to match against. */
Router.prototype.routeTo = function routeTo (url) {
this.setState({ url: url });
var didRoute = this.canRoute(url);
// trigger a manual re-route if we're not in the middle of an update:
if (!this.updating) { this.forceUpdate(); }
return didRoute;
};
Router.prototype.componentWillMount = function componentWillMount () {
ROUTERS.push(this);
this.updating = true;
};
Router.prototype.componentDidMount = function componentDidMount () {
var this$1$1 = this;
if (customHistory) {
this.unlisten = customHistory.listen(function (location) {
this$1$1.routeTo(("" + (location.pathname || '') + (location.search || '')));
});
}
this.updating = false;
};
Router.prototype.componentWillUnmount = function componentWillUnmount () {
if (typeof this.unlisten==='function') { this.unlisten(); }
ROUTERS.splice(ROUTERS.indexOf(this), 1);
};
Router.prototype.componentWillUpdate = function componentWillUpdate () {
this.updating = true;
};
Router.prototype.componentDidUpdate = function componentDidUpdate () {
this.updating = false;
};
Router.prototype.getMatchingChildren = function getMatchingChildren (children, url, invoke) {
return children
.filter(prepareVNodeForRanking)
.sort(pathRankSort)
.map( function (vnode) {
var matches = exec(url, vnode.props.path, vnode.props);
if (matches) {
if (invoke !== false) {
var newProps = { url: url, matches: matches };
assign(newProps, matches);
delete newProps.ref;
delete newProps.key;
return B(vnode, newProps);
}
return vnode;
}
}).filter(Boolean);
};
Router.prototype.render = function render (ref, ref$1) {
var children = ref.children;
var onChange = ref.onChange;
var url = ref$1.url;
var active = this.getMatchingChildren(A$1(children), url, true);
var current = active[0] || null;
var previous = this.previousUrl;
if (url!==previous) {
this.previousUrl = url;
if (typeof onChange==='function') {
onChange({
router: this,
url: url,
previous: previous,
active: active,
current: current
});
}
}
return current;
};
return Router;
}(_));
var Link$1 = function (props) { return (
v$1('a', assign({ onClick: handleLinkClick }, props))
); };
var Route = function (props) { return v$1(props.component, props); };
Router.subscribers = subscribers;
Router.getCurrentUrl = getCurrentUrl;
Router.route = route;
Router.Router = Router;
Router.Route = Route;
Router.Link = Link$1;
Router.exec = exec;
var preactRouter_es = /*#__PURE__*/Object.freeze({
__proto__: null,
subscribers: subscribers,
getCurrentUrl: getCurrentUrl,
route: route,
Router: Router,
Route: Route,
Link: Link$1,
exec: exec,
'default': Router
});
var match$1 = {};
var require$$0 = /*@__PURE__*/getAugmentedNamespace(preact_module);
var require$$1 = /*@__PURE__*/getAugmentedNamespace(preactRouter_es);
var Match_1;
Object.defineProperty(match$1, "__esModule", {
value: true
});
match$1.Link = Match_1 = match$1.Match = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _preact = require$$0;
var _preactRouter = require$$1;
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Match = Match_1 = match$1.Match = function (_Component) {
_inherits(Match, _Component);
function Match() {
var _temp, _this, _ret;
_classCallCheck(this, Match);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.update = function (url) {
_this.nextUrl = url;
_this.setState({});
}, _temp), _possibleConstructorReturn(_this, _ret);
}
Match.prototype.componentDidMount = function componentDidMount() {
_preactRouter.subscribers.push(this.update);
};
Match.prototype.componentWillUnmount = function componentWillUnmount() {
_preactRouter.subscribers.splice(_preactRouter.subscribers.indexOf(this.update) >>> 0, 1);
};
Match.prototype.render = function render(props) {
var url = this.nextUrl || (0, _preactRouter.getCurrentUrl)(),
path = url.replace(/\?.+$/, '');
this.nextUrl = null;
return props.children({
url: url,
path: path,
matches: (0, _preactRouter.exec)(path, props.path, {}) !== false
});
};
return Match;
}(_preact.Component);
var Link = function Link(_ref) {
var activeClassName = _ref.activeClassName,
path = _ref.path,
props = _objectWithoutProperties(_ref, ['activeClassName', 'path']);
return (0, _preact.h)(
Match,
{ path: path || props.href },
function (_ref2) {
var matches = _ref2.matches;
return (0, _preact.h)(_preactRouter.Link, _extends({}, props, { 'class': [props.class || props.className, matches && activeClassName].filter(Boolean).join(' ') }));
}
);
};
match$1.Link = Link;
match$1.default = Match;
Match.Link = Link;
var t,u,r,o=0,i=[],c=l$1.__b,f=l$1.__r,e=l$1.diffed,a=l$1.__c,v=l$1.unmount;function m(t,r){l$1.__h&&l$1.__h(u,t,o||r),o=0;var i=u.__H||(u.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({}),i.__[t]}function l(n){return o=1,p(w$1,n)}function p(n,r,o){var i=m(t++,2);return i.t=n,i.__c||(i.__=[o?o(r):w$1(void 0,r),function(n){var t=i.t(i.__[0],n);i.__[0]!==t&&(i.__=[t,i.__[1]],i.__c.setState({}));}],i.__c=u),i.__}function y(r,o){var i=m(t++,3);!l$1.__s&&k(i.__H,o)&&(i.__=r,i.__H=o,u.__H.__h.push(i));}function F(n){var r=u.context[n.__c],o=m(t++,9);return o.c=n,r?(null==o.__&&(o.__=!0,r.sub(u)),r.props.value):n.__}function x$1(){for(var t;t=i.shift();)if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],l$1.__e(u,t.__v);}}l$1.__b=function(n){u=null,c&&c(n);},l$1.__r=function(n){f&&f(n),t=0;var r=(u=n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j$1),r.__h=[]);},l$1.diffed=function(t){e&&e(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i.push(o)&&r===l$1.requestAnimationFrame||((r=l$1.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x$1)),u=null;},l$1.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],l$1.__e(r,t.__v);}}),a&&a(t,u);},l$1.unmount=function(t){v&&v(t);var u,r=t.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{g(n);}catch(n){u=n;}}),u&&l$1.__e(u,r.__v));};var b="function"==typeof requestAnimationFrame;function g(n){var t=u,r=n.__c;"function"==typeof r&&(n.__c=void 0,r()),u=t;}function j$1(n){var t=u;n.__c=n.__(),u=t;}function k(n,t){return !n||n.length!==t.length||t.some(function(t,u){return t!==n[u]})}function w$1(n,t){return "function"==typeof t?t(n):t}
function C(n,t){for(var e in t)n[e]=t[e];return n}function S(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}(E.prototype=new _).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return S(this.props,n)||S(this.state,t)};var w=l$1.__b;l$1.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var R="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.forward_ref")||3911;function x(n){function t(t,e){var r=C({},t);return delete r.ref,n(r,(e=t.ref||e)&&("object"!=typeof e||"current"in e)?e:null)}return t.$$typeof=R,t.render=t,t.prototype.isReactComponent=t.__f=!0,t.displayName="ForwardRef("+(n.displayName||n.name)+")",t}var A=l$1.__e;l$1.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=l$1.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function M(){this.u=null,this.o=null;}l$1.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new _).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},c=!0===t.__h;r.__u++||c||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=C({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&v$1(d,null,n.fallback);return u&&(u.__h=null),[v$1(d,null,t.__e?null:n.children),u]};var T=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1] Object.keys(obj).filter(prop => keysToExclude.indexOf(prop) === -1).reduce((acc, curr) => {
acc[curr] = obj[curr];
return acc;
}, {}); // rest operator workaround
const warnIfInvalid = (value, componentName) => {
};
function styled(tag) {
return options => {
const render = (props, ref) => {
const {
as: component = tag,
class: className
} = props;
const rest = restOp(props, ['as', 'class']);
let filteredProps; // Check if it's an HTML tag and not a custom element
if (typeof component === 'string' && component.indexOf('-') === -1) {
filteredProps = {}; // eslint-disable-next-line guard-for-in
for (const key in rest) {
if (key === 'as' || index(key)) {
// Don't pass through invalid attributes to HTML elements
filteredProps[key] = rest[key];
}
}
} else {
filteredProps = rest;
}
filteredProps.ref = ref;
filteredProps.className = cx$1(filteredProps.className || className, options.class);
const {
vars
} = options;
if (vars) {
const style = {}; // eslint-disable-next-line guard-for-in
for (const name in vars) {
const variable = vars[name];
const result = variable[0];
const unit = variable[1] || '';
const value = typeof result === 'function' ? result(props) : result;
warnIfInvalid(value, options.name);
style[`--${name}`] = `${value}${unit}`;
}
const ownStyle = filteredProps.style || {};
const keys = Object.keys(ownStyle);
if (keys.length > 0) {
keys.forEach(key => {
style[key] = ownStyle[key];
});
}
filteredProps.style = style;
}
if (tag.__linaria && tag !== component) {
// If the underlying tag is a styled component, forward the `as` prop
// Otherwise the styles from the underlying component will be ignored
filteredProps.as = component;
return /*#__PURE__*/v$1(tag, filteredProps);
}
return /*#__PURE__*/v$1(component, filteredProps);
};
const Result = x ? /*#__PURE__*/x(render) : // React.forwardRef won't available on older React versions and in Preact
// Fallback to a innerRef prop in that case
props => {
const rest = restOp(props, ['innerRef']);
return render(rest, props.innerRef);
};
Result.displayName = options.name; // These properties will be read by the babel plugin for interpolation
Result.__linaria = {
className: options.class,
extends: tag
};
return Result;
};
}
var styled$1 = styled;
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
const PaymentStatus = /*#__PURE__*/styled$1("div")({
name: "PaymentStatus",
class: "p8kxxmr",
vars: {
"p8kxxmr-0": [p => p.color]
}
});
const PopupBox = /*#__PURE__*/styled$1("div")({
name: "PopupBox",
class: "p9s0zpp",
vars: {
"p9s0zpp-0": [({
noPadding
}) => noPadding ? "0px" : "8px"]
}
});
const TableWithRoundRows = /*#__PURE__*/styled$1("table")({
name: "TableWithRoundRows",
class: "tklbasy"
});
const Button = /*#__PURE__*/styled$1("button")({
name: "Button",
class: "bmxsa5t",
vars: {
"bmxsa5t-0": [({
upperCased
}) => upperCased ? "uppercase" : "none"]
}
});
const ButtonBox = /*#__PURE__*/styled$1(Button)({
name: "ButtonBox",
class: "boxc317"
});
const ButtonVariant = /*#__PURE__*/styled$1(Button)({
name: "ButtonVariant",
class: "b1cqzri0"
});
const ButtonPrimary = /*#__PURE__*/styled$1(ButtonVariant)({
name: "ButtonPrimary",
class: "b15xqgyz",
vars: {
"b15xqgyz-0": [({
small
}) => small ? "small" : "inherit"]
}
});
const ButtonBoxPrimary = /*#__PURE__*/styled$1(ButtonBox)({
name: "ButtonBoxPrimary",
class: "b1o8pbk0"
});
const ButtonSuccess = /*#__PURE__*/styled$1(ButtonVariant)({
name: "ButtonSuccess",
class: "b12bvjx5"
});
const ButtonBoxWarning = /*#__PURE__*/styled$1(ButtonBox)({
name: "ButtonBoxWarning",
class: "b13r71ri"
});
const ButtonDestructive = /*#__PURE__*/styled$1(ButtonVariant)({
name: "ButtonDestructive",
class: "b1rfnbo"
});
const BoldLight = /*#__PURE__*/styled$1("div")({
name: "BoldLight",
class: "bly3p82"
});
const Centered = /*#__PURE__*/styled$1("div")({
name: "Centered",
class: "c1t1aglz"
});
const Row = /*#__PURE__*/styled$1("div")({
name: "Row",
class: "r1no9mkk"
});
const RowBorderGray = /*#__PURE__*/styled$1(Row)({
name: "RowBorderGray",
class: "rfg5y6x"
});
const SmallText = /*#__PURE__*/styled$1("div")({
name: "SmallText",
class: "sywvifb"
});
const SmallLightText = /*#__PURE__*/styled$1(SmallText)({
name: "SmallLightText",
class: "s12qexhk"
});
const CenteredText = /*#__PURE__*/styled$1("div")({
name: "CenteredText",
class: "c1f8kx9d"
});
const CenteredBoldText = /*#__PURE__*/styled$1(CenteredText)({
name: "CenteredBoldText",
class: "c1umffj2",
vars: {
"c1umffj2-0": [props => String(props.color)]
}
});
const InputWithLabel = /*#__PURE__*/styled$1("div")({
name: "InputWithLabel",
class: "i1k2hu52",
vars: {
"i1k2hu52-0": [({
invalid
}) => !invalid ? "inherit" : "red"],
"i1k2hu52-1": [({
invalid
}) => !invalid ? "lightgray" : "red"]
}
});
const ErrorBox = /*#__PURE__*/styled$1("div")({
name: "ErrorBox",
class: "e9bmv5f"
});
const WarningBox = /*#__PURE__*/styled$1(ErrorBox)({
name: "WarningBox",
class: "w1av4lor"
});
const NavigationHeader = /*#__PURE__*/styled$1("div")({
name: "NavigationHeader",
class: "nvdsr6i"
});
const ParagraphClickable = /*#__PURE__*/styled$1("p")({
name: "ParagraphClickable",
class: "p1k66yn8"
});
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = l(() => {
return typeof window !== "undefined"
? window.localStorage.getItem(key) || initialValue
: initialValue;
});
const setValue = (value) => {
setStoredValue((p) => {
const toStore = value instanceof Function ? value(p) : value;
if (typeof window !== "undefined") {
if (!toStore) {
window.localStorage.removeItem(key);
}
else {
window.localStorage.setItem(key, toStore);
}
}
return toStore;
});
};
return [storedValue, setValue];
}
//TODO: merge with the above function
function useNotNullLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = l(() => {
return typeof window !== "undefined"
? window.localStorage.getItem(key) || initialValue
: initialValue;
});
const setValue = (value) => {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
if (typeof window !== "undefined") {
if (!valueToStore) {
window.localStorage.removeItem(key);
}
else {
window.localStorage.setItem(key, valueToStore);
}
}
};
return [storedValue, setValue];
}
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
const Context$2 = D({
devMode: false,
toggleDevMode: () => null,
});
const useDevContext = () => F(Context$2);
const DevContextProvider = ({ children }) => {
const [value, setter] = useLocalStorage("devMode");
const devMode = value === "true";
const toggleDevMode = () => setter((v) => (!v ? "true" : undefined));
children = children.length === 1 && typeof children === "function" ? children({ devMode }) : children;
return v$1(Context$2.Provider, { value: { devMode, toggleDevMode }, children });
};
function searchForTalerLinks() {
let found;
found = document.querySelector("a[href^='taler://'");
if (found)
return found.toString();
found = document.querySelector("a[href^='taler+http://'");
if (found)
return found.toString();
return undefined;
}
function getCurrentTab$1() {
return __awaiter(this, void 0, void 0, function* () {
let queryOptions = { active: true, currentWindow: true };
let [tab] = yield chrome.tabs.query(queryOptions);
return tab;
});
}
function findTalerUriInActiveTab() {
return __awaiter(this, void 0, void 0, function* () {
if (chrome.runtime.getManifest().manifest_version === 3) {
// manifest v3
const tab = yield getCurrentTab$1();
const res = yield chrome.scripting.executeScript({
target: {
tabId: tab.id,
allFrames: true,
},
func: searchForTalerLinks,
args: []
});
return res[0].result;
}
return new Promise((resolve, reject) => {
//manifest v2
chrome.tabs.executeScript({
code: `
(() => {
let x = document.querySelector("a[href^='taler://'") || document.querySelector("a[href^='taler+http://'");
return x ? x.href.toString() : null;
})();
`,
allFrames: false,
}, (result) => {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
resolve(undefined);
return;
}
resolve(result[0]);
});
});
});
}
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
const Context$1 = D({
findTalerUriInActiveTab: () => __awaiter(void 0, void 0, void 0, function* () { return undefined; }),
});
/**
* Inversion of control Context
*
* This context act as a proxy between API that need to be replaced in
* different environments
*
* @returns
*/
const useIocContext = () => F(Context$1);
const IoCProviderForRuntime = ({ children }) => {
return v$1(Context$1.Provider, { value: { findTalerUriInActiveTab }, children });
};
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function useLang(initial) {
const browserLang = typeof window !== "undefined"
? navigator.language || navigator.userLanguage
: undefined;
const defaultLang = (browserLang || initial || "en").substring(0, 2);
return useNotNullLocalStorage("lang-preference", defaultLang);
}
const strings = {};
strings['de'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "de"
},
"Balance": [
"Guthaben"
],
"Backup": [
""
],
"Settings": [
""
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
"Abhebegebühr"
],
"Back": [
""
],
"You have no balance to show.": [
"Sie haben kein Guthaben. Wollen Sie %1$s abheben?"
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
""
],
"Withdraw": [
"Abgehoben"
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
""
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
"Debug"
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
""
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
""
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
"Abbrechen"
],
"Loading terms..": [
""
],
"Add exchange": [
""
],
"Add exchange anyway": [
""
],
"Add new exchange": [
""
],
"Add exchange for %1$s": [
""
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
""
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
"Abgehoben"
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
""
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
"Guthaben"
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
""
],
"Total deposit": [
""
],
"Deposit": [
""
],
"Deposit %1$s %2$s": [
"Testkonto #%1$s auf %2$s"
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
""
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
""
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
""
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
"Erneut versuchen"
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
"Bestätigen"
],
"Withdrawal": [
"Abgehoben"
],
"Total withdrawn": [
"Abgehoben"
],
"Exchange fee": [
""
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
"Bezahlung bestätigen"
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
""
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
""
],
"Refresh": [
""
],
"Total refresh": [
""
],
"Refresh amount": [
""
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
"Abhebegebühren:"
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
"Der Händler %1$s bietet Ihnen zum Kauf an:"
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
"Abgehoben"
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
""
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
strings['en-US'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "en-US"
},
"Balance": [
"Balance"
],
"Backup": [
""
],
"Settings": [
""
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
""
],
"Back": [
""
],
"You have no balance to show.": [
"You have no deposit to show. Need some %1$s getting started?"
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
""
],
"Withdraw": [
""
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
""
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
""
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
""
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
""
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
"Abort"
],
"Loading terms..": [
""
],
"Add exchange": [
""
],
"Add exchange anyway": [
""
],
"Add new exchange": [
""
],
"Add exchange for %1$s": [
""
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
""
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
""
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
""
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
"no balance"
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
""
],
"Total deposit": [
""
],
"Deposit": [
""
],
"Deposit %1$s %2$s": [
""
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
""
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
""
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
""
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
""
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
"Accept"
],
"Withdrawal": [
""
],
"Total withdrawn": [
""
],
"Exchange fee": [
""
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
""
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
""
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
""
],
"Refresh": [
""
],
"Total refresh": [
""
],
"Refresh amount": [
""
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
""
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
""
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
""
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
""
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
strings['es'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "es"
},
"Balance": [
"Balance"
],
"Backup": [
""
],
"Settings": [
"Configuración"
],
"Dev": [
"Dev"
],
"Loading": [
"Cargando"
],
"Open reserve page": [
"Abrir página de reserva"
],
"Open pay page": [
"Abrir página de pago"
],
"Open refund page": [
"Abrir página de devolución"
],
"Open tip page": [
"Abrir página de propina"
],
"Open withdraw page": [
"Abrir página de extracción"
],
"Back": [
"Volver"
],
"You have no balance to show.": [
"No tienes balance para mostrar."
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
"Para retirar dinero puedes empezar desde el sitio de tu banco o cliquear en el botón \"extraer\" para usar un exchange conocido"
],
"Withdraw": [
"Extraer"
],
"Could not load balance page": [
"No se pudo cargar la página"
],
"Deposit %1$s": [
"Depositar %1$s"
],
"Enter URI": [
"Ingresar URI"
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
"El diagnóstico caducó. No nos pudimos comunicar con la billetera."
],
"Problems detected:": [
"Problemas detectados:"
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
"Por favor revisa en tu configuración %1$s que tienes IndexedDB habilitado (el nombre de la preferencia %2$s)."
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
"La base de datos de la billetera expiró. Por ahora la migración automática no está soportada. Por favor dirijasé a %1$s para reiniciar la base de datos de la billetera"
],
"Running diagnostics": [
"Ejecutando diagnósticos"
],
"Debug tools": [
"Herramientas de desarrollo"
],
"reset": [
"Reiniciar"
],
"import database": [
"Importar base de datos"
],
"export database": [
"Exportar base de datos"
],
"Database exported at %1$s %2$s to download": [
"Base de datos exportada a %1$s %2$s para descargar"
],
"Coins": [
"Monedas"
],
"Pending operations": [
"Operaciones pendientes"
],
"usable coins": [
"monedas usables"
],
"id": [
"id"
],
"denom": [
"denominación"
],
"value": [
"valor"
],
"status": [
"estado"
],
"from refresh?": [
"desde refresco?"
],
"spent coins": [
"monedas gastadas"
],
"click to show": [
"cliquear para mostrar"
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
"Quieres DESTRUIR IRREVOCABLEMENTE todo dentro de tu billetera y PERDER TODAS TUS MONEDAS?"
],
"Taler Action": [
"Acción Taler"
],
"This page has pay action.": [
"Esta página tiene una acción."
],
"This page has a withdrawal action.": [
"Esta página tiene una acción de extracción."
],
"This page has a tip action.": [
"Esta página tiene una acción de propina."
],
"This page has a notify reserve action.": [
"Esta página tiene una acción de notificación de reserva."
],
"Notify": [
"Notificar"
],
"This page has a refund action.": [
"Esta página tiene una acción de devolución"
],
"This page has a malformed taler uri.": [
"Esta página tiene una URI de Taler malformada"
],
"Dismiss": [
"Desechar"
],
"Could not load backup providers": [
"No se pudo cargar los proveedores de backup"
],
"No backup providers configured": [
"No hay proveedores de backup configurados"
],
"Add provider": [
"Agregar proveedor"
],
"Sync all backups": [
"Sincronizar todos los backups"
],
"Sync now": [
"Syncronizar ahora"
],
"Last synced": [
"Ultima vez sincronizado"
],
"Not synced": [
"No sincronizado"
],
"Expires in": [
"Expira en"
],
"Exchange doesn't have terms of service": [
"Exchange no tiene terminos de service"
],
"Review exchange terms of service": [
"Revizar terminos de servicio"
],
"Review new version of terms of service": [
"Revisar los nuevos terminos de servicio"
],
"Show terms of service": [
"Mostrar terminos de servicio"
],
"I accept the exchange terms of service": [
"Acepto los terminos de servicio del exchange"
],
"The exchange reply with a empty terms of service": [
"El exchange respondió con unos terminos de servicio vacíos"
],
"Download Terms of Service": [
"Descargar los terminos de servicio"
],
"Hide terms of service": [
"Escoder los terminos de servicio"
],
"Review terms of service": [
"Revizar los terminos de servicio"
],
"Exchange URL": [
"Exchange URL"
],
"Cancel": [
"Cancelar"
],
"Loading terms..": [
"Cargando terminos..."
],
"Add exchange": [
"Agregar exchange"
],
"Add exchange anyway": [
"Agregar exchange de todas maneras"
],
"Add new exchange": [
"Agregar nuevo exchange"
],
"Add exchange for %1$s": [
"Agregar exchange para %1$s"
],
"Enter the URL of an exchange you trust.": [
"Ingresar la URL de un exchange que tu confíes."
],
"An exchange has been found! Review the information and click next": [
"Un exchange ha sido encontrado! Revisa la información y cliquea en siguente"
],
"This exchange doesn't match the expected currency %1$s": [
"Este exchange no es para la divisa %1$s"
],
"Unable to verify this exchange": [
"No fue posible verificar este exchange"
],
"Unable to add this exchange": [
"No fue posible agregar este exchange"
],
"loading": [
"cargando"
],
"Version": [
"Versión"
],
"Currency": [
"Divisa"
],
"Next": [
"Siguiente"
],
"Add backup provider": [
"Agregar proveedor de backup"
],
"Could not get provider information": [
"No se puedo conseguir la información del proveedor"
],
"Backup providers may charge for their service": [
"Provedores de backup pueden pueden cobrarte por su servicio"
],
"URL": [
"URL"
],
"Name": [
"Nombre"
],
"Provider URL": [
"URL del proveedor"
],
"Please review and accept this provider's terms of service": [
"Por favor revisa y acepta los terminos de servicio del proveedor"
],
"Pricing": [
"Precios"
],
"free of charge": [
"Gratis"
],
"%1$s per year of service": [
"%1$s por año de servicio"
],
"Storage": [
"Alamcenamiento"
],
"%1$s megabytes of storage per year of service": [
"%1$s megabytes de almacenamiento por año de servicio"
],
"Accept terms of service": [
"Aceptar terminos de servicio"
],
"There was an error loading the provider detail for \"%1$s\"": [
"Hubo un error cargando los detalles del proveedor para \"%1$s\""
],
"There is not known provider with url \"%1$s\".": [
"No hay proveedor conocido con url \"%1$s\"."
],
"Last backup": [
"Último backup"
],
"Back up": [
"Backup"
],
"Provider fee": [
"Tarifa del proveedor"
],
"per year": [
"por año"
],
"Extend": [
"Extender"
],
"terms has changed, extending the service will imply accepting the new terms of service": [
"los terminos han cambiado, extender el servicio implicará aceptar los nuevos terminos de servicio"
],
"old": [
"viejo"
],
"new": [
"nuevo"
],
"fee": [
"tarifa"
],
"storage": [
"almacenamiento"
],
"back": [
"volver"
],
"Remove provider": [
"Eliminar proveedor"
],
"This provider has reported an error": [
"Este proveedor ha reportado un error"
],
"There is conflict with another backup from %1$s": [
"Hubo un conflicto con otro backup de %1$s"
],
"Backup is not readable": [
"El backup no se puede leer"
],
"Unknown backup problem: %1$s": [
"Problema de backup desconocido: %1$s"
],
"service paid": [
"servicio pagado"
],
"Backup valid until": [
"Backup valido hasta"
],
"this popup is being closed and you are being redirected to %1$s": [
"Este popup se cerrará y estás siendo redirijido a %1$s"
],
"Select one option": [
"Seleccione una opción"
],
"Manual Withdrawal": [
"Extracción Manual"
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
"Elija un exchange desde donde las monedas serán extraídas. El exchange enviará las monedas a esta billetera después de recibir una transferencia con el asunto correcto."
],
"No exchange configured": [
"Sin exchange configurado"
],
"Can't create the reserve": [
"No se pudo create una reserva"
],
"Exchange": [
"Exchange"
],
"Add Exchange": [
"Agregar Exchange"
],
"Amount": [
"Monto"
],
"Start withdrawal": [
"Comenzar extracción"
],
"no balance": [
"sin balance"
],
"There is no known bank account to send money to": [
"No hay cuenta bancaria conocida donde enviar el dinero"
],
"Send %1$s to your account": [
"Enviar %1$s a tu cuenta"
],
"Bank account IBAN number": [
"Número IBAN de cuenta bancaria"
],
"Deposit fee": [
"Taria de depósito"
],
"Total deposit": [
"Deposito total"
],
"Deposit": [
"Depósito"
],
"Deposit %1$s %2$s": [
"Depositar %1$s %2$s"
],
"Waiting for confirmation": [
"Esperando confirmación"
],
"PENDING": [
"PENDIENTE"
],
"Could not load the list of transactions": [
"No se pudo cargar la lista de transacciones"
],
"There is no history for this currency": [
"No hay historial para esta divisa"
],
"Account": [
"Cuenta"
],
"Bank host": [
"Host del banco"
],
"Bank account": [
"Cuenta del banco"
],
"IBAN": [
"IBAN"
],
"Chosen amount": [
"Elegir monto"
],
"Subject": [
"Asunto"
],
"could not parse payto uri from exchange %1$s": [
"No se pudo analizar la URI payto del exchange %1$s"
],
"Exchange is ready for withdrawal": [
"El exchange está listo para la extracción"
],
"To complete the process you need to wire %1$s to the exchange bank account": [
"Para completar el proceso necesitas enviar %1$s a la cuenta bancaria del exchange"
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
"Asegurate de usar el asunto correcto, de otra manera el dinero no llegará a esta billetera"
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
"Alternativamente, también puedes escanear el código QR o abrir %1$s si tienes una aplicación bancaria instalada que soporta RFC 8905"
],
"Cancel withdrawal": [
"Cancelar extracción"
],
"Display": [
"Pantalla"
],
"Current Language": [
"Lenguage actual"
],
"Navigator": [
"Navegador"
],
"Automatically open wallet based on page content": [
"Abrir automáticamente la billetera basado en el contenido de la página"
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
"Habilitar esta opción debajo hará el uso de la billetera mas rápido, pero requiere mas permisos de tu navegador"
],
"Trust": [
"Confianza"
],
"No exchange yet": [
"No hay exchanges todavía"
],
"Term of Service": [
"Terminos de servicio"
],
"ok": [
"ok"
],
"changed": [
"modificado"
],
"not accepted": [
"no aceptado"
],
"Add an exchange": [
"Agregar un exchange"
],
"Developer mode": [
"Modo desarrollador"
],
"(More options and information useful for debugging)": [
"(Mas información y opciones útiles para depuración)"
],
"Could not load the transaction information": [
"No se pudo cargar información de la transacción"
],
"There was an error trying to complete the transaction": [
"Hubo un error intentando completar la transacción"
],
"This transaction is not completed": [
"Esta tansacción no está completa"
],
"Retry": [
"Reintentar"
],
"Forget": [
"Olvidar"
],
"Caution!": [
"Cuidado!"
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
"Si ya has transferido dinero al exchange perderas la oportunidad de recivir las monedas"
],
"Confirm": [
"Confirmar"
],
"Withdrawal": [
"Extracción"
],
"Total withdrawn": [
"Total extraido"
],
"Exchange fee": [
"Tarifa del exchange"
],
"The bank is waiting for confirmation. Go to the %1$s": [
"El banco espera la confirmación. Dirigete a %1$s"
],
"Waiting for the coins to arrive": [
"Esperando a que las monedas lleguen"
],
"Payment": [
"Pago"
],
"Total paid": [
"Total pagado"
],
"Purchase amount": [
"Monto de compra"
],
"Fee": [
"Tarifa"
],
"Merchant": [
"Comerciante"
],
"Purchase": [
"Compra"
],
"Receipt": [
"Recibo"
],
"Total send": [
"Total enviado"
],
"Deposit amount": [
"Monto a depositar"
],
"Refresh": [
"Actualizar"
],
"Total refresh": [
"Actualización total"
],
"Refresh amount": [
"Monto de actualización"
],
"Tip": [
"Propina"
],
"Total tip": [
"Total de propina"
],
"Received amount": [
"Monto recibido"
],
"Refund": [
"Devolución"
],
"Total refund": [
"Devolución total"
],
"Refund amount": [
"Monto de devolución"
],
"Browser Extension Installed!": [
"Extensión del navegador instalada!"
],
"Thank you for installing the wallet.": [
"Gracias por haber instalado la billetera."
],
"Permissions": [
"Permisos"
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
"(Habilitar esta opción debajo hará el uso de la billetera mas rápido, pero requiere mas permisos de tu navegador)"
],
"Next Steps": [
"Próximos pasos"
],
"Try the demo": [
"Probar la demostración"
],
"Learn how to top up your wallet balance": [
"Aprender como llenar tu billetera"
],
"Could not load pay status": [
"No se pudo cargar el estado del pago"
],
"Could not load contract terms from merchant or wallet backend.": [
"No se pudo cargar los terminos de contrato del comerciante o de la billetera."
],
"Pay with a mobile phone": [
"Pagar con un teléfono móbil"
],
"Hide QR": [
"Esconder QR"
],
"Scan the QR code or %1$s": [
"Escanear el código QR o %1$s"
],
"Processing": [
"Procesando"
],
"Pay %1$s": [
"Pagar %1$s"
],
"Your balance of %1$s is not enough to pay for this purchase": [
"Tu balance de %1$s no es suficiente para pagar por esta compra"
],
"Your balance is not enough to pay for this purchase.": [
"Tu balance no es suficiente para pagar esta compra."
],
"Withdraw digital cash": [
"Extraer dinero digital"
],
"Merchant message": [
"Mensaje del comerciante"
],
"Digital cash payment": [
"Pago con dinero digital"
],
"Already paid, you are going to be redirected to %1$s": [
"Ya pagado, estás siendo dirigido a %1$s"
],
"Already paid": [
"Ya pagado"
],
"Already claimed": [
"Ya reclamado"
],
"Payment complete": [
"Pago completo"
],
"You are going to be redirected to $ %1$s": [
"Estas siendo redirigido a %1$s"
],
"You can close this page.": [
"Puedes cerrar esta página."
],
"Total to pay": [
"Total a pagar"
],
"List of products": [
"Lista de productos"
],
"Total": [
"Total"
],
"free": [
"Gratis"
],
"Refund Status": [
"Estado del reembolso"
],
"The product %1$s has received a total effective refund of": [
"El producto %1$s ha recibido un total efectivo de"
],
"Refund processing is still in progress.": [
"El proceso de reembolso está todavía en progreso"
],
"The refund amount of %1$s could not be applied.": [
"El monto del reembolso de %1$s no pudo ser aplicado."
],
"missing taler refund uri": [
"falta la URI Taler de reembolso"
],
"Error: %1$s": [
"Error: %1$s"
],
"Updating refund status": [
"Actualizando el estado de reembolso"
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
"Propina de %1$s aceptada. Revisa tu lista de transacciones para mas detalle."
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
"El comerciante %1$s está ofreciendo una propina de %2$s usando el exchange %3$s"
],
"Accept tip": [
"Aceptar propina"
],
"Ignore": [
"Ignorar"
],
"missing tip uri": [
"URI de propina faltante"
],
"You've ignored the tip.": [
"Has ignorado la propina"
],
"Digital cash withdrawal": [
"Extracción de dinero digital"
],
"Could not finish the withdrawal operation": [
"No se pudo completar la operación de extracción"
],
"Total to withdraw": [
"Total a extraer"
],
"Known exchanges": [
"Exchange conocidos"
],
"Cancel exchange selection": [
"Cancelar selección de exchange"
],
"Confirm exchange selection": [
"Confirmar selección de exchange"
],
"Switch exchange": [
"Cambiar exchange"
],
"Confirm withdrawal": [
"Confirmar extracción"
],
"Withdraw anyway": [
"Extraer de todas maneras"
],
"Could not load the withdrawal details": [
"No se pudo cargar los detalles de extracción"
],
"missing withdraw uri": [
"URI de extracción faltante"
],
"Could not get the info from the URI": [
"No se pudo obtener la información desde la URI"
],
"Could not load the list of known exchanges": [
"No se pudo cargar la lista de exchange conocidos"
],
"All done, your transaction is in progress": [
"Todo completo, su transacción está en progreso"
],
"Edit": [
"Editar"
],
"missing pay uri": [
"URI de pago faltante"
],
"Could not get the payment information for this order": [
"No se pudo obtener la información de pago para esta orden"
],
"Loading payment information": [
"Cargado la información de pago"
],
"Digital cash deposit": [
"Deposito de dinero digital"
],
"You will now be sent back to the merchant you came from.": [
"Ahora serás enviado otra vez al sitio del comerciante"
],
"Manual Reset Required": [
"Reinicio Manual Necesario"
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
"La base de datos de billetera en tu navegador es incompatible con la billetera instalada actualmente. Por favor reinicie manualmente"
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
"Una vez que el formato de la base de datos esté estabilizzado, proveeremos de actualizaciones automáticas"
],
"I understand that I will lose all my data": [
"Entiendo que perderé toda mi información"
],
"Reset": [
"Reiniciar"
],
"Everything is fine!": [
"Todo está bien!"
],
"A reset is not required anymore, you can close this page.": [
"Un reinicio ya no es necesario, puede cerrar esta página."
],
"Not implemented yet.": [
"Todavía no implementado"
]
}
}
};
strings['fr'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=(n!=1);",
"lang": "fr"
},
"Balance": [
""
],
"Backup": [
""
],
"Settings": [
""
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
""
],
"Back": [
""
],
"You have no balance to show.": [
""
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
""
],
"Withdraw": [
""
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
""
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
""
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
""
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
""
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
""
],
"Loading terms..": [
""
],
"Add exchange": [
""
],
"Add exchange anyway": [
""
],
"Add new exchange": [
""
],
"Add exchange for %1$s": [
""
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
""
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
""
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
""
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
""
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
""
],
"Total deposit": [
""
],
"Deposit": [
""
],
"Deposit %1$s %2$s": [
""
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
""
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
""
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
""
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
""
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
"Confirmer"
],
"Withdrawal": [
""
],
"Total withdrawn": [
""
],
"Exchange fee": [
""
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
""
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
""
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
""
],
"Refresh": [
""
],
"Total refresh": [
""
],
"Refresh amount": [
""
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
""
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
""
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
""
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
""
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
strings['it'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "it"
},
"Balance": [
""
],
"Backup": [
""
],
"Settings": [
""
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
""
],
"Back": [
""
],
"You have no balance to show.": [
""
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
""
],
"Withdraw": [
""
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
""
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
""
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
""
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
""
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
""
],
"Loading terms..": [
""
],
"Add exchange": [
""
],
"Add exchange anyway": [
""
],
"Add new exchange": [
""
],
"Add exchange for %1$s": [
""
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
""
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
""
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
""
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
""
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
""
],
"Total deposit": [
""
],
"Deposit": [
""
],
"Deposit %1$s %2$s": [
""
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
""
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
""
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
""
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
""
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
"Confermare"
],
"Withdrawal": [
""
],
"Total withdrawn": [
""
],
"Exchange fee": [
""
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
""
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
""
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
""
],
"Refresh": [
""
],
"Total refresh": [
""
],
"Refresh amount": [
""
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
""
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
""
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
""
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
""
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
strings['ja'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "ja"
},
"Balance": [
"残高"
],
"Backup": [
"バックアップ"
],
"Settings": [
"設定"
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
""
],
"Back": [
""
],
"You have no balance to show.": [
"表示するバランスがありません"
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
"お金を引き出すには、銀行のサイトから開始するか、[引き出し]ボタンをクリックして既知の取引所を使用します。"
],
"Withdraw": [
"撤退"
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
""
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
""
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
""
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
""
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
""
],
"Loading terms..": [
""
],
"Add exchange": [
""
],
"Add exchange anyway": [
""
],
"Add new exchange": [
""
],
"Add exchange for %1$s": [
""
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
""
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
""
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
""
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
""
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
""
],
"Total deposit": [
""
],
"Deposit": [
""
],
"Deposit %1$s %2$s": [
""
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
""
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
""
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
""
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
""
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
""
],
"Withdrawal": [
""
],
"Total withdrawn": [
""
],
"Exchange fee": [
""
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
""
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
""
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
""
],
"Refresh": [
""
],
"Total refresh": [
""
],
"Refresh amount": [
""
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
""
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
""
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
""
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
""
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
strings['sv'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "sv"
},
"Balance": [
"Balans"
],
"Backup": [
""
],
"Settings": [
""
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
"Utbetalnings avgift"
],
"Back": [
""
],
"You have no balance to show.": [
"Du har ingen balans att visa. Behöver du\n %1$s att börja?\n"
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
""
],
"Withdraw": [
"Utbetalnings avgift"
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
"Depostitions avgift"
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
""
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
"# Mynt"
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
"Värde"
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
"Avbryt"
],
"Loading terms..": [
""
],
"Add exchange": [
"Accepterade tjänsteleverantörer:"
],
"Add exchange anyway": [
""
],
"Add new exchange": [
"Accepterade tjänsteleverantörer:"
],
"Add exchange for %1$s": [
"Accepterade tjänsteleverantörer:"
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
"Återbetalning"
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
"Utbetalnings avgift"
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
"Accepterade tjänsteleverantörer:"
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
"Balans"
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
"Depostitions avgift"
],
"Total deposit": [
""
],
"Deposit": [
"Depostitions avgift"
],
"Deposit %1$s %2$s": [
""
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
"Övervisa till bank konto"
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
"Tjänsteleverantörer i plånboken:"
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
"Accepterade tjänsteleverantörer:"
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
""
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
"Bekräfta"
],
"Withdrawal": [
"Utbetalnings avgift"
],
"Total withdrawn": [
"Utbetalnings avgift"
],
"Exchange fee": [
"Tjänsteleverantörer i plånboken:"
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
"Godkän betalning"
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
""
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
"Depostitions avgift"
],
"Refresh": [
"Återhämtnings avgift"
],
"Total refresh": [
""
],
"Refresh amount": [
"Återhämtnings avgift"
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
"Utbetalnings avgifter:"
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
"Säljaren %1$s erbjuder följande:"
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
"Utbetalnings avgift"
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
""
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
strings['tr'] = {
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"plural_forms": "nplurals=2; plural=n != 1;",
"lang": "tr"
},
"Balance": [
"Bakiye"
],
"Backup": [
""
],
"Settings": [
""
],
"Dev": [
""
],
"Loading": [
""
],
"Open reserve page": [
""
],
"Open pay page": [
""
],
"Open refund page": [
""
],
"Open tip page": [
""
],
"Open withdraw page": [
""
],
"Back": [
""
],
"You have no balance to show.": [
""
],
"To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [
""
],
"Withdraw": [
""
],
"Could not load balance page": [
""
],
"Deposit %1$s": [
""
],
"Enter URI": [
""
],
"Diagnostics timed out. Could not talk to the wallet backend.": [
""
],
"Problems detected:": [
""
],
"Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [
""
],
"Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [
""
],
"Running diagnostics": [
""
],
"Debug tools": [
""
],
"reset": [
""
],
"import database": [
""
],
"export database": [
""
],
"Database exported at %1$s %2$s to download": [
""
],
"Coins": [
""
],
"Pending operations": [
""
],
"usable coins": [
""
],
"id": [
""
],
"denom": [
""
],
"value": [
""
],
"status": [
""
],
"from refresh?": [
""
],
"spent coins": [
""
],
"click to show": [
""
],
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [
""
],
"Taler Action": [
""
],
"This page has pay action.": [
""
],
"This page has a withdrawal action.": [
""
],
"This page has a tip action.": [
""
],
"This page has a notify reserve action.": [
""
],
"Notify": [
""
],
"This page has a refund action.": [
""
],
"This page has a malformed taler uri.": [
""
],
"Dismiss": [
""
],
"Could not load backup providers": [
""
],
"No backup providers configured": [
""
],
"Add provider": [
""
],
"Sync all backups": [
""
],
"Sync now": [
""
],
"Last synced": [
""
],
"Not synced": [
""
],
"Expires in": [
""
],
"Exchange doesn't have terms of service": [
""
],
"Review exchange terms of service": [
""
],
"Review new version of terms of service": [
""
],
"Show terms of service": [
""
],
"I accept the exchange terms of service": [
""
],
"The exchange reply with a empty terms of service": [
""
],
"Download Terms of Service": [
""
],
"Hide terms of service": [
""
],
"Review terms of service": [
""
],
"Exchange URL": [
""
],
"Cancel": [
"Bakiye"
],
"Loading terms..": [
""
],
"Add exchange": [
""
],
"Add exchange anyway": [
""
],
"Add new exchange": [
""
],
"Add exchange for %1$s": [
""
],
"Enter the URL of an exchange you trust.": [
""
],
"An exchange has been found! Review the information and click next": [
""
],
"This exchange doesn't match the expected currency %1$s": [
""
],
"Unable to verify this exchange": [
""
],
"Unable to add this exchange": [
""
],
"loading": [
""
],
"Version": [
""
],
"Currency": [
""
],
"Next": [
""
],
"Add backup provider": [
""
],
"Could not get provider information": [
""
],
"Backup providers may charge for their service": [
""
],
"URL": [
""
],
"Name": [
""
],
"Provider URL": [
""
],
"Please review and accept this provider's terms of service": [
""
],
"Pricing": [
""
],
"free of charge": [
""
],
"%1$s per year of service": [
""
],
"Storage": [
""
],
"%1$s megabytes of storage per year of service": [
""
],
"Accept terms of service": [
""
],
"There was an error loading the provider detail for \"%1$s\"": [
""
],
"There is not known provider with url \"%1$s\".": [
""
],
"Last backup": [
""
],
"Back up": [
""
],
"Provider fee": [
""
],
"per year": [
""
],
"Extend": [
""
],
"terms has changed, extending the service will imply accepting the new terms of service": [
""
],
"old": [
""
],
"new": [
""
],
"fee": [
""
],
"storage": [
""
],
"back": [
""
],
"Remove provider": [
""
],
"This provider has reported an error": [
""
],
"There is conflict with another backup from %1$s": [
""
],
"Backup is not readable": [
""
],
"Unknown backup problem: %1$s": [
""
],
"service paid": [
""
],
"Backup valid until": [
""
],
"this popup is being closed and you are being redirected to %1$s": [
""
],
"Select one option": [
""
],
"Manual Withdrawal": [
""
],
"Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [
""
],
"No exchange configured": [
""
],
"Can't create the reserve": [
""
],
"Exchange": [
""
],
"Add Exchange": [
""
],
"Amount": [
""
],
"Start withdrawal": [
""
],
"no balance": [
"Bakiye"
],
"There is no known bank account to send money to": [
""
],
"Send %1$s to your account": [
""
],
"Bank account IBAN number": [
""
],
"Deposit fee": [
""
],
"Total deposit": [
""
],
"Deposit": [
""
],
"Deposit %1$s %2$s": [
"Test Havale Hesap #%1$s üzerinde %2$s"
],
"Waiting for confirmation": [
""
],
"PENDING": [
""
],
"Could not load the list of transactions": [
""
],
"There is no history for this currency": [
""
],
"Account": [
""
],
"Bank host": [
""
],
"Bank account": [
""
],
"IBAN": [
""
],
"Chosen amount": [
""
],
"Subject": [
""
],
"could not parse payto uri from exchange %1$s": [
""
],
"Exchange is ready for withdrawal": [
""
],
"To complete the process you need to wire %1$s to the exchange bank account": [
""
],
"Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [
""
],
"Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [
""
],
"Cancel withdrawal": [
""
],
"Display": [
""
],
"Current Language": [
""
],
"Navigator": [
""
],
"Automatically open wallet based on page content": [
""
],
"Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [
""
],
"Trust": [
""
],
"No exchange yet": [
""
],
"Term of Service": [
""
],
"ok": [
""
],
"changed": [
""
],
"not accepted": [
""
],
"Add an exchange": [
""
],
"Developer mode": [
""
],
"(More options and information useful for debugging)": [
""
],
"Could not load the transaction information": [
""
],
"There was an error trying to complete the transaction": [
""
],
"This transaction is not completed": [
""
],
"Retry": [
"Yeniden deneyin"
],
"Forget": [
""
],
"Caution!": [
""
],
"If you have already wired money to the exchange you will loose the chance to get the coins form it.": [
""
],
"Confirm": [
"Onaylamak"
],
"Withdrawal": [
"Çekildi"
],
"Total withdrawn": [
"Çekildi"
],
"Exchange fee": [
""
],
"The bank is waiting for confirmation. Go to the %1$s": [
""
],
"Waiting for the coins to arrive": [
""
],
"Payment": [
"Ödeme gönderildi"
],
"Total paid": [
""
],
"Purchase amount": [
""
],
"Fee": [
"Ücretler "
],
"Merchant": [
""
],
"Purchase": [
""
],
"Receipt": [
""
],
"Total send": [
""
],
"Deposit amount": [
"Depozito Ücreti"
],
"Refresh": [
"Ücreti yenile"
],
"Total refresh": [
""
],
"Refresh amount": [
"Ücreti yenile"
],
"Tip": [
""
],
"Total tip": [
""
],
"Received amount": [
""
],
"Refund": [
""
],
"Total refund": [
""
],
"Refund amount": [
""
],
"Browser Extension Installed!": [
""
],
"Thank you for installing the wallet.": [
""
],
"Permissions": [
""
],
"(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [
""
],
"Next Steps": [
""
],
"Try the demo": [
""
],
"Learn how to top up your wallet balance": [
""
],
"Could not load pay status": [
""
],
"Could not load contract terms from merchant or wallet backend.": [
""
],
"Pay with a mobile phone": [
""
],
"Hide QR": [
""
],
"Scan the QR code or %1$s": [
""
],
"Processing": [
""
],
"Pay %1$s": [
""
],
"Your balance of %1$s is not enough to pay for this purchase": [
""
],
"Your balance is not enough to pay for this purchase.": [
""
],
"Withdraw digital cash": [
""
],
"Merchant message": [
""
],
"Digital cash payment": [
""
],
"Already paid, you are going to be redirected to %1$s": [
""
],
"Already paid": [
""
],
"Already claimed": [
""
],
"Payment complete": [
""
],
"You are going to be redirected to $ %1$s": [
""
],
"You can close this page.": [
""
],
"Total to pay": [
""
],
"List of products": [
""
],
"Total": [
""
],
"free": [
""
],
"Refund Status": [
""
],
"The product %1$s has received a total effective refund of": [
""
],
"Refund processing is still in progress.": [
""
],
"The refund amount of %1$s could not be applied.": [
""
],
"missing taler refund uri": [
""
],
"Error: %1$s": [
""
],
"Updating refund status": [
""
],
"Tip from %1$s accepted. Check your transactions list for more details.": [
""
],
"The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [
""
],
"Accept tip": [
""
],
"Ignore": [
""
],
"missing tip uri": [
""
],
"You've ignored the tip.": [
""
],
"Digital cash withdrawal": [
""
],
"Could not finish the withdrawal operation": [
""
],
"Total to withdraw": [
""
],
"Known exchanges": [
""
],
"Cancel exchange selection": [
""
],
"Confirm exchange selection": [
""
],
"Switch exchange": [
""
],
"Confirm withdrawal": [
""
],
"Withdraw anyway": [
""
],
"Could not load the withdrawal details": [
""
],
"missing withdraw uri": [
""
],
"Could not get the info from the URI": [
""
],
"Could not load the list of known exchanges": [
""
],
"All done, your transaction is in progress": [
""
],
"Edit": [
"Lütfen bir exchange seçin. Detayları seçiminizden önce inceleyebilirsiniz."
],
"missing pay uri": [
""
],
"Could not get the payment information for this order": [
""
],
"Loading payment information": [
""
],
"Digital cash deposit": [
""
],
"You will now be sent back to the merchant you came from.": [
""
],
"Manual Reset Required": [
""
],
"The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [
""
],
"Once the database format has stabilized, we will provide automatic upgrades.": [
""
],
"I understand that I will lose all my data": [
""
],
"Reset": [
""
],
"Everything is fine!": [
""
],
"A reset is not required anymore, you can close this page.": [
""
],
"Not implemented yet.": [
""
]
}
}
};
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
const supportedLang = {
es: "Español [es]",
ja: "日本語 [ja]",
en: "English [en]",
fr: "Français [fr]",
de: "Deutsch [de]",
sv: "Svenska [sv]",
it: "Italiano [it]",
// ko: "한국어 [ko]",
// ru: "Ру́сский язы́к [ru]",
tr: "Türk [tr]"
};
const initial = {
lang: "en",
supportedLang,
changeLanguage: () => {
// do not change anything
},
};
const Context = D(initial);
//we use forceLang when we don't want to use the saved state, but sone forced
//runtime lang predefined lang
const TranslationProvider = ({ initial, children, forceLang, }) => {
const [lang, changeLanguage2] = useLang(initial);
function changeLanguage(s) {
console.log("trying to change lang to ", s, "current lang", lang);
changeLanguage2(s);
}
y(() => {
if (forceLang) {
changeLanguage(forceLang);
}
});
y(() => {
setupI18n(lang, strings);
}, [lang]);
if (forceLang) {
setupI18n(forceLang, strings);
}
else {
setupI18n(lang, strings);
}
return v$1(Context.Provider, { value: { lang, changeLanguage, supportedLang }, children });
};
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function useTalerActionURL() {
const [talerActionUrl, setTalerActionUrl] = l(undefined);
const [dismissed, setDismissed] = l(false);
const { findTalerUriInActiveTab } = useIocContext();
y(() => {
function check() {
return __awaiter(this, void 0, void 0, function* () {
const talerUri = yield findTalerUriInActiveTab();
setTalerActionUrl(talerUri);
});
}
check();
}, []);
const url = dismissed ? undefined : talerActionUrl;
return [url, setDismissed];
}
function JustInDevMode({ children, }) {
const { devMode } = useDevContext();
if (!devMode)
return v$1(d, null);
return v$1(d, null, children);
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
/**
* List of pages used by the wallet
*
* @author sebasjm
*/
var Pages;
(function (Pages) {
Pages["welcome"] = "/welcome";
Pages["balance"] = "/balance";
Pages["balance_history"] = "/balance/history/:currency?";
Pages["balance_manual_withdraw"] = "/balance/manual-withdraw/:currency?";
Pages["balance_deposit"] = "/balance/deposit/:currency";
Pages["balance_transaction"] = "/balance/transaction/:tid";
Pages["dev"] = "/dev";
Pages["backup"] = "/backup";
Pages["backup_provider_detail"] = "/backup/provider/:pid";
Pages["backup_provider_add"] = "/backup/provider/add";
Pages["settings"] = "/settings";
Pages["settings_exchange_add"] = "/settings/exchange/add";
Pages["cta"] = "/cta/:action";
Pages["cta_pay"] = "/cta/pay";
Pages["cta_refund"] = "/cta/refund";
Pages["cta_tips"] = "/cta/tip";
Pages["cta_withdraw"] = "/cta/withdraw";
})(Pages || (Pages = {}));
function PopupNavBar({ path = "" }) {
const innerUrl = chrome.runtime
? new URL(chrome.runtime.getURL("/static/wallet.html#/settings")).href
: "#";
return (v$1(NavigationHeader, null,
v$1("a", { href: "/balance", class: path.startsWith("/balance") ? "active" : "" },
v$1(i18n.Translate, null, "Balance")),
v$1("a", { href: "/backup", class: path.startsWith("/backup") ? "active" : "" },
v$1(i18n.Translate, null, "Backup")),
v$1("a", null),
v$1("a", { href: innerUrl, target: "_blank", rel: "noreferrer" },
v$1("div", { class: "settings-icon", title: i18n.str `Settings` }))));
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function BalanceTable({ balances, goToWalletHistory, }) {
return (v$1(TableWithRoundRows, null, balances.map((entry, idx) => {
const av = Amounts.parseOrThrow(entry.available);
return (v$1("tr", { key: idx, onClick: () => goToWalletHistory(av.currency), style: { cursor: "pointer" } },
v$1("td", null, av.currency),
v$1("td", { style: {
fontSize: "2em",
textAlign: "right",
width: "100%",
} }, Amounts.stringifyValue(av))));
})));
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function Loading() {
return (v$1("div", null,
v$1(i18n.Translate, null, "Loading"),
"..."));
}
var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Generator: Adobe Illustrator 19.2.1%2c SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3e%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='92px' height='92px' viewBox='0 0 92 92' enable-background='new 0 0 92 92' xml:space='preserve'%3e%3cpath id='XMLID_467_' d='M46%2c63c-1.1%2c0-2.1-0.4-2.9-1.2l-25-26c-1.5-1.6-1.5-4.1%2c0.1-5.7c1.6-1.5%2c4.1-1.5%2c5.7%2c0.1l22.1%2c23l22.1-23 c1.5-1.6%2c4.1-1.6%2c5.7-0.1c1.6%2c1.5%2c1.6%2c4.1%2c0.1%2c5.7l-25%2c26C48.1%2c62.6%2c47.1%2c63%2c46%2c63z'/%3e%3c/svg%3e";
/*
This file is part of GNU Taler
(C) 2019 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function ErrorMessage({ title, description, }) {
const [showErrorDetail, setShowErrorDetail] = l(false);
return (v$1(ErrorBox, { style: { paddingTop: 0, paddingBottom: 0 } },
v$1("div", null,
v$1("p", null, title),
description && (v$1("button", { onClick: () => {
setShowErrorDetail((v) => !v);
} },
v$1("img", { style: { height: "1.5em" }, src: img })))),
showErrorDetail && v$1("p", null, description)));
}
function ErrorTalerOperation({ title, error, }) {
var _a, _b;
const { devMode } = useDevContext();
const [showErrorDetail, setShowErrorDetail] = l(false);
if (!title || !error)
return null;
// const errorCode: number | undefined = (error.details as any)?.errorResponse?.code
const errorHint = (_b = (_a = error.details) === null || _a === void 0 ? void 0 : _a.errorResponse) === null || _b === void 0 ? void 0 : _b.hint;
return (v$1(ErrorBox, { style: { paddingTop: 0, paddingBottom: 0 } },
v$1("div", null,
v$1("p", null, title),
error && (v$1("button", { onClick: () => {
setShowErrorDetail((v) => !v);
} },
v$1("img", { style: {
transform: !showErrorDetail ? undefined : "scaleY(-1)",
height: "1.5em",
}, src: img })))),
showErrorDetail && (v$1(d, null,
v$1("div", { style: { padding: 5, textAlign: "left" } },
v$1("div", null,
v$1("b", null, error.message),
" ",
!errorHint ? "" : `: ${errorHint}`,
" ")),
devMode && (v$1("div", { style: { textAlign: "left", overflowX: "auto" } },
v$1("pre", null, JSON.stringify(error, undefined, 2))))))));
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function LoadingError({ title, error }) {
if (error.operational) {
return v$1(ErrorTalerOperation, { title: title, error: error.details });
}
return v$1(ErrorMessage, { title: title, description: error.message });
}
/**
* functionality: it will receive a list of actions, take the first actions as
* the first chosen action
* the user may change the chosen action
* when the user click the button it will call onClick with the chosen action
* as argument
*
* visually: it is a primary button with a select handler on the right
*
* @returns
*/
function MultiActionButton({ label, actions, onClick: doClick, }) {
const defaultAction = actions.length > 0 ? actions[0] : "";
const [opened, setOpened] = l(false);
const [selected, setSelected] = l(defaultAction);
const canChange = actions.length > 1;
const options = canChange ? actions.filter((a) => a !== selected) : [];
function select(m) {
setSelected(m);
setOpened(false);
}
if (!canChange) {
return (v$1(ButtonPrimary, { onClick: () => doClick(selected) }, label(selected)));
}
return (v$1("div", { style: { position: "relative", display: "inline-block" } },
opened && (v$1("div", { style: {
position: "absolute",
bottom: 32 + 5,
right: 0,
marginLeft: 8,
marginRight: 8,
borderRadius: 5,
border: "1px solid blue",
background: "white",
boxShadow: "0px 8px 16px 0px rgba(0,0,0,0.2)",
zIndex: 1,
} }, options.map((m) => (v$1(ParagraphClickable, { key: m, onClick: () => select(m) }, label(m)))))),
v$1(ButtonBoxPrimary, { onClick: () => doClick(selected), style: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
marginRight: 0,
maxWidth: 170,
overflowX: "hidden",
textOverflow: "ellipsis",
} }, label(selected)),
v$1(ButtonPrimary, { onClick: () => setOpened((s) => !s), style: {
marginLeft: 0,
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
} },
v$1("img", { style: { height: 14 }, src: img }))));
}
/*
This file is part of GNU Taler
(C) 2019-2020 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* This exception is thrown when an error occurred and the caller is
* responsible for recording the failure in the database.
*/
class OperationFailedError extends Error {
constructor(operationError) {
super(operationError.message);
this.operationError = operationError;
// Set the prototype explicitly.
Object.setPrototypeOf(this, OperationFailedError.prototype);
}
static fromCode(ec, message, details) {
return new OperationFailedError(makeErrorDetails(ec, message, details));
}
}
function makeErrorDetails(ec, message, details) {
return {
code: ec,
hint: `Error: ${TalerErrorCode[ec]}`,
details: details,
message,
};
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
new Logger("query.ts");
function describeContents(name, options) {
return { name, keyPath: options.keyPath, _dummy: undefined };
}
function describeIndex(name, keyPath, options = {}) {
return {
keyPath,
name,
multiEntry: options.multiEntry,
};
}
const storeWithIndexesSymbol = Symbol("StoreWithIndexesMark");
function describeStore(s, m) {
return {
store: s,
indexMap: m,
mark: storeWithIndexesSymbol,
};
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
new Logger("http.ts");
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var ReserveRecordStatus;
(function (ReserveRecordStatus) {
/**
* Reserve must be registered with the bank.
*/
ReserveRecordStatus["RegisteringBank"] = "registering-bank";
/**
* We've registered reserve's information with the bank
* and are now waiting for the user to confirm the withdraw
* with the bank (typically 2nd factor auth).
*/
ReserveRecordStatus["WaitConfirmBank"] = "wait-confirm-bank";
/**
* Querying reserve status with the exchange.
*/
ReserveRecordStatus["QueryingStatus"] = "querying-status";
/**
* The corresponding withdraw record has been created.
* No further processing is done, unless explicitly requested
* by the user.
*/
ReserveRecordStatus["Dormant"] = "dormant";
/**
* The bank aborted the withdrawal.
*/
ReserveRecordStatus["BankAborted"] = "bank-aborted";
})(ReserveRecordStatus || (ReserveRecordStatus = {}));
/**
* Status of a denomination.
*/
var DenominationVerificationStatus;
(function (DenominationVerificationStatus) {
/**
* Verification was delayed.
*/
DenominationVerificationStatus["Unverified"] = "unverified";
/**
* Verified as valid.
*/
DenominationVerificationStatus["VerifiedGood"] = "verified-good";
/**
* Verified as invalid.
*/
DenominationVerificationStatus["VerifiedBad"] = "verified-bad";
})(DenominationVerificationStatus || (DenominationVerificationStatus = {}));
/**
* Status of a coin.
*/
var CoinStatus;
(function (CoinStatus) {
/**
* Withdrawn and never shown to anybody.
*/
CoinStatus["Fresh"] = "fresh";
/**
* A coin that has been spent and refreshed.
*/
CoinStatus["Dormant"] = "dormant";
})(CoinStatus || (CoinStatus = {}));
var CoinSourceType;
(function (CoinSourceType) {
CoinSourceType["Withdraw"] = "withdraw";
CoinSourceType["Refresh"] = "refresh";
CoinSourceType["Tip"] = "tip";
})(CoinSourceType || (CoinSourceType = {}));
var ProposalStatus;
(function (ProposalStatus) {
/**
* Not downloaded yet.
*/
ProposalStatus["Downloading"] = "downloading";
/**
* Proposal downloaded, but the user needs to accept/reject it.
*/
ProposalStatus["Proposed"] = "proposed";
/**
* The user has accepted the proposal.
*/
ProposalStatus["Accepted"] = "accepted";
/**
* The user has rejected the proposal.
*/
ProposalStatus["Refused"] = "refused";
/**
* Downloading or processing the proposal has failed permanently.
*/
ProposalStatus["PermanentlyFailed"] = "permanently-failed";
/**
* Downloaded proposal was detected as a re-purchase.
*/
ProposalStatus["Repurchase"] = "repurchase";
})(ProposalStatus || (ProposalStatus = {}));
var RefreshCoinStatus;
(function (RefreshCoinStatus) {
RefreshCoinStatus["Pending"] = "pending";
RefreshCoinStatus["Finished"] = "finished";
/**
* The refresh for this coin has been frozen, because of a permanent error.
* More info in lastErrorPerCoin.
*/
RefreshCoinStatus["Frozen"] = "frozen";
})(RefreshCoinStatus || (RefreshCoinStatus = {}));
var OperationStatus;
(function (OperationStatus) {
OperationStatus["Finished"] = "finished";
OperationStatus["Pending"] = "pending";
})(OperationStatus || (OperationStatus = {}));
var RefundState;
(function (RefundState) {
RefundState["Failed"] = "failed";
RefundState["Applied"] = "applied";
RefundState["Pending"] = "pending";
})(RefundState || (RefundState = {}));
var RefundReason;
(function (RefundReason) {
/**
* Normal refund given by the merchant.
*/
RefundReason["NormalRefund"] = "normal-refund";
/**
* Refund from an aborted payment.
*/
RefundReason["AbortRefund"] = "abort-pay-refund";
})(RefundReason || (RefundReason = {}));
var AbortStatus;
(function (AbortStatus) {
AbortStatus["None"] = "none";
AbortStatus["AbortRefund"] = "abort-refund";
AbortStatus["AbortFinished"] = "abort-finished";
})(AbortStatus || (AbortStatus = {}));
var BackupProviderStateTag;
(function (BackupProviderStateTag) {
BackupProviderStateTag["Provisional"] = "provisional";
BackupProviderStateTag["Ready"] = "ready";
BackupProviderStateTag["Retrying"] = "retrying";
})(BackupProviderStateTag || (BackupProviderStateTag = {}));
({
coins: describeStore(describeContents("coins", {
keyPath: "coinPub",
}), {
byBaseUrl: describeIndex("byBaseUrl", "exchangeBaseUrl"),
byDenomPubHash: describeIndex("byDenomPubHash", "denomPubHash"),
byCoinEvHash: describeIndex("byCoinEvHash", "coinEvHash"),
}),
config: describeStore(describeContents("config", { keyPath: "key" }), {}),
auditorTrust: describeStore(describeContents("auditorTrust", {
keyPath: ["currency", "auditorBaseUrl"],
}), {
byAuditorPub: describeIndex("byAuditorPub", "auditorPub"),
byUid: describeIndex("byUid", "uids", {
multiEntry: true,
}),
}),
exchangeTrust: describeStore(describeContents("exchangeTrust", {
keyPath: ["currency", "exchangeBaseUrl"],
}), {
byExchangeMasterPub: describeIndex("byExchangeMasterPub", "exchangeMasterPub"),
}),
denominations: describeStore(describeContents("denominations", {
keyPath: ["exchangeBaseUrl", "denomPubHash"],
}), {
byExchangeBaseUrl: describeIndex("byExchangeBaseUrl", "exchangeBaseUrl"),
}),
exchanges: describeStore(describeContents("exchanges", {
keyPath: "baseUrl",
}), {}),
exchangeDetails: describeStore(describeContents("exchangeDetails", {
keyPath: ["exchangeBaseUrl", "currency", "masterPublicKey"],
}), {}),
proposals: describeStore(describeContents("proposals", { keyPath: "proposalId" }), {
byUrlAndOrderId: describeIndex("byUrlAndOrderId", [
"merchantBaseUrl",
"orderId",
]),
}),
refreshGroups: describeStore(describeContents("refreshGroups", {
keyPath: "refreshGroupId",
}), {
byStatus: describeIndex("byStatus", "operationStatus"),
}),
recoupGroups: describeStore(describeContents("recoupGroups", {
keyPath: "recoupGroupId",
}), {}),
reserves: describeStore(describeContents("reserves", { keyPath: "reservePub" }), {
byInitialWithdrawalGroupId: describeIndex("byInitialWithdrawalGroupId", "initialWithdrawalGroupId"),
byStatus: describeIndex("byStatus", "operationStatus"),
}),
purchases: describeStore(describeContents("purchases", { keyPath: "proposalId" }), {
byFulfillmentUrl: describeIndex("byFulfillmentUrl", "download.contractData.fulfillmentUrl"),
byMerchantUrlAndOrderId: describeIndex("byMerchantUrlAndOrderId", [
"download.contractData.merchantBaseUrl",
"download.contractData.orderId",
]),
}),
tips: describeStore(describeContents("tips", { keyPath: "walletTipId" }), {
byMerchantTipIdAndBaseUrl: describeIndex("byMerchantTipIdAndBaseUrl", [
"merchantTipId",
"merchantBaseUrl",
]),
}),
withdrawalGroups: describeStore(describeContents("withdrawalGroups", {
keyPath: "withdrawalGroupId",
}), {
byReservePub: describeIndex("byReservePub", "reservePub"),
byStatus: describeIndex("byStatus", "operationStatus"),
}),
planchets: describeStore(describeContents("planchets", { keyPath: "coinPub" }), {
byGroupAndIndex: describeIndex("byGroupAndIndex", [
"withdrawalGroupId",
"coinIdx",
]),
byGroup: describeIndex("byGroup", "withdrawalGroupId"),
byCoinEvHash: describeIndex("byCoinEv", "coinEvHash"),
}),
bankWithdrawUris: describeStore(describeContents("bankWithdrawUris", {
keyPath: "talerWithdrawUri",
}), {}),
backupProviders: describeStore(describeContents("backupProviders", {
keyPath: "baseUrl",
}), {
byPaymentProposalId: describeIndex("byPaymentProposalId", "paymentProposalIds", {
multiEntry: true,
}),
}),
depositGroups: describeStore(describeContents("depositGroups", {
keyPath: "depositGroupId",
}), {
byStatus: describeIndex("byStatus", "operationStatus"),
}),
tombstones: describeStore(describeContents("tombstones", { keyPath: "id" }), {}),
ghostDepositGroups: describeStore(describeContents("ghostDepositGroups", {
keyPath: "contractTermsHash",
}), {}),
balancesPerCurrency: describeStore(describeContents("balancesPerCurrency", {
keyPath: "currency",
}), {}),
});
({
metaConfig: describeStore(describeContents("metaConfig", { keyPath: "key" }), {}),
});
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("db-utils.ts");
/*
This file is part of GNU Taler
(C) 2017-2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("timer.ts");
/**
* Get a performance counter in nanoseconds.
*/
(() => {
// @ts-ignore
if (typeof process !== "undefined" && process.hrtime) {
return () => {
return process.hrtime.bigint();
};
}
// @ts-ignore
if (typeof performance !== "undefined") {
// @ts-ignore
return () => BigInt(Math.floor(performance.now() * 1000)) * BigInt(1000);
}
return () => BigInt(0);
})();
/*
This file is part of GNU Taler
(C) 2019-2020 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
new Logger("cryptoImplementation.ts");
/*
This file is part of GNU Taler
(C) 2016 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("cryptoApi.ts");
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("synchronousWorker.ts");
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var PendingTaskType;
(function (PendingTaskType) {
PendingTaskType["ExchangeUpdate"] = "exchange-update";
PendingTaskType["ExchangeCheckRefresh"] = "exchange-check-refresh";
PendingTaskType["Pay"] = "pay";
PendingTaskType["ProposalChoice"] = "proposal-choice";
PendingTaskType["ProposalDownload"] = "proposal-download";
PendingTaskType["Refresh"] = "refresh";
PendingTaskType["Reserve"] = "reserve";
PendingTaskType["Recoup"] = "recoup";
PendingTaskType["RefundQuery"] = "refund-query";
PendingTaskType["TipPickup"] = "tip-pickup";
PendingTaskType["Withdraw"] = "withdraw";
PendingTaskType["Deposit"] = "deposit";
PendingTaskType["Backup"] = "backup";
})(PendingTaskType || (PendingTaskType = {}));
var ReserveType;
(function (ReserveType) {
/**
* Manually created.
*/
ReserveType["Manual"] = "manual";
/**
* Withdrawn from a bank that has "tight" Taler integration
*/
ReserveType["TalerBankWithdraw"] = "taler-bank-withdraw";
})(ReserveType || (ReserveType = {}));
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
var WalletApiOperation;
(function (WalletApiOperation) {
WalletApiOperation["InitWallet"] = "initWallet";
WalletApiOperation["WithdrawTestkudos"] = "withdrawTestkudos";
WalletApiOperation["WithdrawTestBalance"] = "withdrawTestBalance";
WalletApiOperation["PreparePayForUri"] = "preparePayForUri";
WalletApiOperation["RunIntegrationTest"] = "runIntegrationTest";
WalletApiOperation["TestPay"] = "testPay";
WalletApiOperation["AddExchange"] = "addExchange";
WalletApiOperation["GetTransactions"] = "getTransactions";
WalletApiOperation["ListExchanges"] = "listExchanges";
WalletApiOperation["ListKnownBankAccounts"] = "listKnownBankAccounts";
WalletApiOperation["GetWithdrawalDetailsForUri"] = "getWithdrawalDetailsForUri";
WalletApiOperation["GetWithdrawalDetailsForAmount"] = "getWithdrawalDetailsForAmount";
WalletApiOperation["AcceptManualWithdrawal"] = "acceptManualWithdrawal";
WalletApiOperation["GetBalances"] = "getBalances";
WalletApiOperation["GetPendingOperations"] = "getPendingOperations";
WalletApiOperation["SetExchangeTosAccepted"] = "setExchangeTosAccepted";
WalletApiOperation["ApplyRefund"] = "applyRefund";
WalletApiOperation["AcceptBankIntegratedWithdrawal"] = "acceptBankIntegratedWithdrawal";
WalletApiOperation["GetExchangeTos"] = "getExchangeTos";
WalletApiOperation["RetryPendingNow"] = "retryPendingNow";
WalletApiOperation["AbortFailedPayWithRefund"] = "abortFailedPayWithRefund";
WalletApiOperation["ConfirmPay"] = "confirmPay";
WalletApiOperation["DumpCoins"] = "dumpCoins";
WalletApiOperation["SetCoinSuspended"] = "setCoinSuspended";
WalletApiOperation["ForceRefresh"] = "forceRefresh";
WalletApiOperation["PrepareTip"] = "prepareTip";
WalletApiOperation["AcceptTip"] = "acceptTip";
WalletApiOperation["ExportBackup"] = "exportBackup";
WalletApiOperation["AddBackupProvider"] = "addBackupProvider";
WalletApiOperation["RunBackupCycle"] = "runBackupCycle";
WalletApiOperation["ExportBackupRecovery"] = "exportBackupRecovery";
WalletApiOperation["ImportBackupRecovery"] = "importBackupRecovery";
WalletApiOperation["GetBackupInfo"] = "getBackupInfo";
WalletApiOperation["TrackDepositGroup"] = "trackDepositGroup";
WalletApiOperation["DeleteTransaction"] = "deleteTransaction";
WalletApiOperation["RetryTransaction"] = "retryTransaction";
WalletApiOperation["GetCoins"] = "getCoins";
WalletApiOperation["ListCurrencies"] = "listCurrencies";
WalletApiOperation["CreateDepositGroup"] = "createDepositGroup";
WalletApiOperation["SetWalletDeviceId"] = "setWalletDeviceId";
WalletApiOperation["ExportBackupPlain"] = "exportBackupPlain";
WalletApiOperation["WithdrawFakebank"] = "withdrawFakebank";
WalletApiOperation["ExportDb"] = "exportDb";
})(WalletApiOperation || (WalletApiOperation = {}));
/*
This file is part of GNU Taler
(C) 2020 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("backup/export.ts");
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("coinSelection.ts");
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("contractTerms.ts");
var ContractTermsUtil;
(function (ContractTermsUtil) {
/**
* Scrub all forgettable members from an object.
*/
function scrub(anyJson) {
return forgetAllImpl(anyJson, [], () => true);
}
ContractTermsUtil.scrub = scrub;
/**
* Recursively forget all forgettable members of an object,
* where the path matches a predicate.
*/
function forgetAll(anyJson, pred) {
return forgetAllImpl(anyJson, [], pred);
}
ContractTermsUtil.forgetAll = forgetAll;
function forgetAllImpl(anyJson, path, pred) {
const dup = JSON.parse(JSON.stringify(anyJson));
if (Array.isArray(dup)) {
for (let i = 0; i < dup.length; i++) {
dup[i] = forgetAllImpl(dup[i], [...path, `${i}`], pred);
}
}
else if (typeof dup === "object" && dup != null) {
if (typeof dup.$forgettable === "object") {
for (const x of Object.keys(dup.$forgettable)) {
if (!pred([...path, x])) {
continue;
}
if (!dup.$forgotten) {
dup.$forgotten = {};
}
if (!dup.$forgotten[x]) {
const membValCanon = stringToBytes(canonicalJson(scrub(dup[x])) + "\0");
const membSalt = stringToBytes(dup.$forgettable[x] + "\0");
const h = kdf(64, membValCanon, membSalt, new Uint8Array([]));
dup.$forgotten[x] = encodeCrock(h);
}
delete dup[x];
delete dup.$forgettable[x];
}
if (Object.keys(dup.$forgettable).length === 0) {
delete dup.$forgettable;
}
}
for (const x of Object.keys(dup)) {
if (x.startsWith("$")) {
continue;
}
dup[x] = forgetAllImpl(dup[x], [...path, x], pred);
}
}
return dup;
}
/**
* Generate a salt for all members marked as forgettable,
* but which don't have an actual salt yet.
*/
function saltForgettable(anyJson) {
const dup = JSON.parse(JSON.stringify(anyJson));
if (Array.isArray(dup)) {
for (let i = 0; i < dup.length; i++) {
dup[i] = saltForgettable(dup[i]);
}
}
else if (typeof dup === "object" && dup !== null) {
if (typeof dup.$forgettable === "object") {
for (const k of Object.keys(dup.$forgettable)) {
if (dup.$forgettable[k] === true) {
dup.$forgettable[k] = encodeCrock(getRandomBytes(32));
}
}
}
for (const x of Object.keys(dup)) {
if (x.startsWith("$")) {
continue;
}
dup[x] = saltForgettable(dup[x]);
}
}
return dup;
}
ContractTermsUtil.saltForgettable = saltForgettable;
const nameRegex = /^[0-9A-Za-z_]+$/;
/**
* Check that the given JSON object is well-formed with regards
* to forgettable fields and other restrictions for forgettable JSON.
*/
function validateForgettable(anyJson) {
var _a;
if (typeof anyJson === "string") {
return true;
}
if (typeof anyJson === "number") {
return (Number.isInteger(anyJson) &&
anyJson >= Number.MIN_SAFE_INTEGER &&
anyJson <= Number.MAX_SAFE_INTEGER);
}
if (typeof anyJson === "boolean") {
return true;
}
if (anyJson === null) {
return true;
}
if (Array.isArray(anyJson)) {
return anyJson.every((x) => validateForgettable(x));
}
if (typeof anyJson === "object") {
for (const k of Object.keys(anyJson)) {
if (k.match(nameRegex)) {
if (validateForgettable(anyJson[k])) {
continue;
}
else {
return false;
}
}
if (k === "$forgettable") {
const fga = anyJson.$forgettable;
if (!fga || typeof fga !== "object") {
return false;
}
for (const fk of Object.keys(fga)) {
if (!fk.match(nameRegex)) {
return false;
}
if (!(fk in anyJson)) {
return false;
}
const fv = anyJson.$forgettable[fk];
if (typeof fv !== "string") {
return false;
}
}
}
else if (k === "$forgotten") {
const fgo = anyJson.$forgotten;
if (!fgo || typeof fgo !== "object") {
return false;
}
for (const fk of Object.keys(fgo)) {
if (!fk.match(nameRegex)) {
return false;
}
// Check that the value has actually been forgotten.
if (fk in anyJson) {
return false;
}
const fv = anyJson.$forgotten[fk];
if (typeof fv !== "string") {
return false;
}
try {
const decFv = decodeCrock(fv);
if (decFv.length != 64) {
return false;
}
}
catch (e) {
return false;
}
// Check that salt has been deleted after forgetting.
if (((_a = anyJson.$forgettable) === null || _a === void 0 ? void 0 : _a[k]) !== undefined) {
return false;
}
}
}
else {
return false;
}
}
return true;
}
return false;
}
ContractTermsUtil.validateForgettable = validateForgettable;
/**
* Check that no forgettable information has been forgotten.
*
* Must only be called on an object already validated with validateForgettable.
*/
function validateNothingForgotten(contractTerms) {
throw Error("not implemented yet");
}
ContractTermsUtil.validateNothingForgotten = validateNothingForgotten;
/**
* Hash a contract terms object. Forgettable fields
* are scrubbed and JSON canonicalization is applied
* before hashing.
*/
function hashContractTerms(contractTerms) {
const cleaned = scrub(contractTerms);
const canon = canonicalJson(cleaned) + "\0";
const bytes = stringToBytes(canon);
return encodeCrock(hash(bytes));
}
ContractTermsUtil.hashContractTerms = hashContractTerms;
})(ContractTermsUtil || (ContractTermsUtil = {}));
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("exchanges.ts");
/*
This file is part of GNU Taler
(C) 2019-2021 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Logger for this file.
*/
new Logger("operations/withdraw.ts");
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("refresh.ts");
/*
This file is part of GNU Taler
(C) 2019-2022 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Logger.
*/
new Logger("pay.ts");
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
* Logger.
*/
new Logger("deposits.ts");
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("taler-wallet-core:reserves.ts");
/*
This file is part of GNU Taler
(C) 2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("operations/tip.ts");
/*
This file is part of GNU Taler
(C) 2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("taler-wallet-core:transactions.ts");
var TombstoneTag;
(function (TombstoneTag) {
TombstoneTag["DeleteWithdrawalGroup"] = "delete-withdrawal-group";
TombstoneTag["DeleteReserve"] = "delete-reserve";
TombstoneTag["DeletePayment"] = "delete-payment";
TombstoneTag["DeleteTip"] = "delete-tip";
TombstoneTag["DeleteRefreshGroup"] = "delete-refresh-group";
TombstoneTag["DeleteDepositGroup"] = "delete-deposit-group";
TombstoneTag["DeleteRefund"] = "delete-refund";
})(TombstoneTag || (TombstoneTag = {}));
/*
This file is part of GNU Taler
(C) 2020 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("operations/backup/import.ts");
/*
This file is part of GNU Taler
(C) 2020 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("operations/backup.ts");
var ProviderPaymentType;
(function (ProviderPaymentType) {
ProviderPaymentType["Unpaid"] = "unpaid";
ProviderPaymentType["Pending"] = "pending";
ProviderPaymentType["InsufficientBalance"] = "insufficient-balance";
ProviderPaymentType["Paid"] = "paid";
ProviderPaymentType["TermsChanged"] = "terms-changed";
})(ProviderPaymentType || (ProviderPaymentType = {}));
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("operations/balance.ts");
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A..
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("taler-wallet-core:merchants.ts");
/*
This file is part of GNU Taler
(C) 2019-2020 Taler Systems SA
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("operations/recoup.ts");
/*
This file is part of GNU Taler
(C) 2019-2019 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("refund.ts");
/*
This file is part of GNU Taler
(C) 2020 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("operations/testing.ts");
/*
This file is part of GNU Taler
(C) 2015-2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
new Logger("wallet.ts");
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function callBackend(operation, payload) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
// eslint-disable-next-line no-undef
chrome.runtime.sendMessage({ operation, payload, id: "(none)" }, (resp) => {
// eslint-disable-next-line no-undef
if (chrome.runtime.lastError) {
console.log("Error calling backend");
reject(new Error(`Error contacting backend: ${chrome.runtime.lastError.message}`));
}
console.log("got response", resp);
const r = resp;
if (r.type === "error") {
reject(new OperationFailedError(r.error));
return;
}
resolve(r.result);
});
});
});
}
/**
* Get balances for all currencies/exchanges.
*/
function getBalance() {
return callBackend("getBalances", {});
}
/**
* Get information about the current state of wallet backups.
*/
function getBackupInfo() {
return callBackend("getBackupInfo", {});
}
function syncAllProviders() {
return callBackend("runBackupCycle", {});
}
function syncOneProvider(url) {
return callBackend("runBackupCycle", { providers: [url] });
}
function removeProvider(url) {
return callBackend("removeBackupProvider", {
provider: url,
});
}
function onUpdateNotification(messageTypes, doCallback) {
// eslint-disable-next-line no-undef
const port = chrome.runtime.connect({ name: "notifications" });
const listener = (message) => {
const shouldNotify = messageTypes.includes(message.type);
console.log("Notification arrived, should notify?", shouldNotify, message.type, messageTypes);
if (shouldNotify) {
doCallback();
}
};
port.onMessage.addListener(listener);
return () => {
port.onMessage.removeListener(listener);
};
}
//"withdraw-group-finished"
function useAsyncAsHook(fn, updateOnNotification) {
const [result, setHookResponse] = l(undefined);
y(() => {
function doAsync() {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield fn();
setHookResponse({ hasError: false, response });
}
catch (e) {
if (e instanceof OperationFailedError) {
setHookResponse({ hasError: true, operational: true, details: e.operationError });
}
else if (e instanceof Error) {
setHookResponse({ hasError: true, operational: false, message: e.message });
}
}
});
}
doAsync();
if (updateOnNotification && updateOnNotification.length > 0) {
return onUpdateNotification(updateOnNotification, () => {
doAsync();
});
}
}, []);
return result;
}
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function actionForTalerUri(uriType, talerUri) {
switch (uriType) {
case TalerUriType.TalerWithdraw:
return makeExtensionUrlWithParams("static/wallet.html#/cta/withdraw", {
talerWithdrawUri: talerUri,
});
case TalerUriType.TalerPay:
return makeExtensionUrlWithParams("static/wallet.html#/cta/pay", {
talerPayUri: talerUri,
});
case TalerUriType.TalerTip:
return makeExtensionUrlWithParams("static/wallet.html#/cta/tip", {
talerTipUri: talerUri,
});
case TalerUriType.TalerRefund:
return makeExtensionUrlWithParams("static/wallet.html#/cta/refund", {
talerRefundUri: talerUri,
});
case TalerUriType.TalerNotifyReserve:
// FIXME: implement
break;
default:
console.warn("Response with HTTP 402 has Taler header, but header value is not a taler:// URI.");
break;
}
return undefined;
}
function makeExtensionUrlWithParams(url, params) {
// eslint-disable-next-line no-undef
const innerUrl = new URL(chrome.runtime.getURL("/" + url));
if (params) {
const hParams = Object.keys(params)
.map((k) => `${k}=${params[k]}`)
.join("&");
innerUrl.hash = innerUrl.hash + "?" + hParams;
}
return innerUrl.href;
}
function buttonLabelByTalerType(type) {
switch (type) {
case TalerUriType.TalerNotifyReserve:
return v$1(i18n.Translate, null, "Open reserve page");
case TalerUriType.TalerPay:
return v$1(i18n.Translate, null, "Open pay page");
case TalerUriType.TalerRefund:
return v$1(i18n.Translate, null, "Open refund page");
case TalerUriType.TalerTip:
return v$1(i18n.Translate, null, "Open tip page");
case TalerUriType.TalerWithdraw:
return v$1(i18n.Translate, null, "Open withdraw page");
}
return v$1(d, null);
}
function AddNewActionView({ onCancel }) {
const [url, setUrl] = l("");
const uriType = classifyTalerUri(url);
return (v$1(d, null,
v$1("section", null,
v$1(InputWithLabel, { invalid: url !== "" && uriType === TalerUriType.Unknown },
v$1("label", null, "GNU Taler URI"),
v$1("div", null,
v$1("input", { style: { width: "100%" }, type: "text", value: url, placeholder: "taler://pay/....", onInput: (e) => setUrl(e.currentTarget.value) })))),
v$1("footer", null,
v$1(Button, { onClick: onCancel },
v$1(i18n.Translate, null, "Back")),
uriType !== TalerUriType.Unknown && (v$1(ButtonSuccess, { onClick: () => {
// eslint-disable-next-line no-undef
chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
} }, buttonLabelByTalerType(uriType))))));
}
function NoBalanceHelp({ goToWalletManualWithdraw, }) {
return (v$1(WarningBox, null,
v$1("p", null,
v$1("b", null,
v$1(i18n.Translate, null, "You have no balance to show.")),
v$1("br", null),
v$1(i18n.Translate, null, "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.")),
v$1(ButtonBoxWarning, { onClick: () => goToWalletManualWithdraw() },
v$1(i18n.Translate, null, "Withdraw"))));
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function BalancePage({ goToWalletManualWithdraw, goToWalletDeposit, goToWalletHistory, }) {
const [addingAction, setAddingAction] = l(false);
const state = useAsyncAsHook(getBalance);
const balances = !state || state.hasError ? [] : state.response.balances;
if (!state) {
return v$1(Loading, null);
}
if (state.hasError) {
return (v$1(LoadingError, { title: v$1(i18n.Translate, null, "Could not load balance page"), error: state }));
}
if (addingAction) {
return v$1(AddNewActionView, { onCancel: () => setAddingAction(false) });
}
return (v$1(BalanceView, { balances: balances, goToWalletManualWithdraw: goToWalletManualWithdraw, goToWalletDeposit: goToWalletDeposit, goToWalletHistory: goToWalletHistory, goToAddAction: () => setAddingAction(true) }));
}
function BalanceView({ balances, goToWalletManualWithdraw, goToWalletDeposit, goToWalletHistory, goToAddAction, }) {
const currencyWithNonZeroAmount = balances
.filter((b) => !Amounts.isZero(b.available))
.map((b) => b.available.split(":")[0]);
if (balances.length === 0) {
return (v$1(NoBalanceHelp, { goToWalletManualWithdraw: goToWalletManualWithdraw }));
}
return (v$1(d, null,
v$1("section", null,
v$1(BalanceTable, { balances: balances, goToWalletHistory: goToWalletHistory })),
v$1("footer", { style: { justifyContent: "space-between" } },
v$1(ButtonPrimary, { onClick: goToWalletManualWithdraw },
v$1(i18n.Translate, null, "Withdraw")),
currencyWithNonZeroAmount.length > 0 && (v$1(MultiActionButton, { label: (s) => (v$1(i18n.Translate, { debug: true },
"Deposit ",
v$1("span", null, s))), actions: currencyWithNonZeroAmount, onClick: (c) => goToWalletDeposit(c) })),
v$1(JustInDevMode, null,
v$1(ButtonBoxPrimary, { onClick: goToAddAction },
v$1(i18n.Translate, null, "Enter URI"))))));
}
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function getCurrentTab() {
return __awaiter(this, void 0, void 0, function* () {
let queryOptions = { active: true, currentWindow: true };
const tab = yield new Promise((res, rej) => {
chrome.tabs.query(queryOptions, (tabs) => {
res(tabs[0]);
});
});
return tab;
});
}
function navigateTo(url) {
return __awaiter(this, void 0, void 0, function* () {
if (!url)
return;
const tab = yield getCurrentTab();
if (!tab.id)
return;
yield chrome.tabs.update(tab.id, { url });
window.close();
});
}
function TalerActionFound({ url, onDismiss }) {
const uriType = classifyTalerUri(url);
return (v$1(d, null,
v$1("section", null,
v$1("h1", null,
v$1(i18n.Translate, null, "Taler Action")),
uriType === TalerUriType.TalerPay && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "This page has pay action.")),
v$1(ButtonSuccess, { onClick: () => {
navigateTo(actionForTalerUri(uriType, url));
} },
v$1(i18n.Translate, null, "Open pay page")))),
uriType === TalerUriType.TalerWithdraw && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "This page has a withdrawal action.")),
v$1(ButtonSuccess, { onClick: () => {
navigateTo(actionForTalerUri(uriType, url));
} },
v$1(i18n.Translate, null, "Open withdraw page")))),
uriType === TalerUriType.TalerTip && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "This page has a tip action.")),
v$1(ButtonSuccess, { onClick: () => {
navigateTo(actionForTalerUri(uriType, url));
} },
v$1(i18n.Translate, null, "Open tip page")))),
uriType === TalerUriType.TalerNotifyReserve && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "This page has a notify reserve action.")),
v$1(ButtonSuccess, { onClick: () => {
navigateTo(actionForTalerUri(uriType, url));
} },
v$1(i18n.Translate, null, "Notify")))),
uriType === TalerUriType.TalerRefund && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "This page has a refund action.")),
v$1(ButtonSuccess, { onClick: () => {
navigateTo(actionForTalerUri(uriType, url));
} },
v$1(i18n.Translate, null, "Open refund page")))),
uriType === TalerUriType.Unknown && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "This page has a malformed taler uri.")),
v$1("p", null, url)))),
v$1("footer", null,
v$1("div", null),
v$1(ButtonPrimary, { onClick: () => onDismiss() },
" ",
v$1(i18n.Translate, null, "Dismiss"),
" "))));
}
function toInteger(dirtyNumber) {
if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
return NaN;
}
var number = Number(dirtyNumber);
if (isNaN(number)) {
return number;
}
return number < 0 ? Math.ceil(number) : Math.floor(number);
}
function requiredArgs(required, args) {
if (args.length < required) {
throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');
}
}
/**
* @name toDate
* @category Common Helpers
* @summary Convert the given argument to an instance of Date.
*
* @description
* Convert the given argument to an instance of Date.
*
* If the argument is an instance of Date, the function returns its clone.
*
* If the argument is a number, it is treated as a timestamp.
*
* If the argument is none of the above, the function returns Invalid Date.
*
* **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
*
* @param {Date|Number} argument - the value to convert
* @returns {Date} the parsed date in the local time zone
* @throws {TypeError} 1 argument required
*
* @example
* // Clone the date:
* const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
* //=> Tue Feb 11 2014 11:30:30
*
* @example
* // Convert the timestamp to date:
* const result = toDate(1392098430000)
* //=> Tue Feb 11 2014 11:30:30
*/
function toDate(argument) {
requiredArgs(1, arguments);
var argStr = Object.prototype.toString.call(argument); // Clone the date
if (argument instanceof Date || typeof argument === 'object' && argStr === '[object Date]') {
// Prevent the date to lose the milliseconds when passed to new Date() in IE10
return new Date(argument.getTime());
} else if (typeof argument === 'number' || argStr === '[object Number]') {
return new Date(argument);
} else {
if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {
// eslint-disable-next-line no-console
console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule"); // eslint-disable-next-line no-console
console.warn(new Error().stack);
}
return new Date(NaN);
}
}
/**
* @name addDays
* @category Day Helpers
* @summary Add the specified number of days to the given date.
*
* @description
* Add the specified number of days to the given date.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to be changed
* @param {Number} amount - the amount of days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
* @returns {Date} - the new date with the days added
* @throws {TypeError} - 2 arguments required
*
* @example
* // Add 10 days to 1 September 2014:
* const result = addDays(new Date(2014, 8, 1), 10)
* //=> Thu Sep 11 2014 00:00:00
*/
function addDays(dirtyDate, dirtyAmount) {
requiredArgs(2, arguments);
var date = toDate(dirtyDate);
var amount = toInteger(dirtyAmount);
if (isNaN(amount)) {
return new Date(NaN);
}
if (!amount) {
// If 0 days, no-op to avoid changing times in the hour before end of DST
return date;
}
date.setDate(date.getDate() + amount);
return date;
}
/**
* @name addMonths
* @category Month Helpers
* @summary Add the specified number of months to the given date.
*
* @description
* Add the specified number of months to the given date.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to be changed
* @param {Number} amount - the amount of months to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
* @returns {Date} the new date with the months added
* @throws {TypeError} 2 arguments required
*
* @example
* // Add 5 months to 1 September 2014:
* const result = addMonths(new Date(2014, 8, 1), 5)
* //=> Sun Feb 01 2015 00:00:00
*/
function addMonths(dirtyDate, dirtyAmount) {
requiredArgs(2, arguments);
var date = toDate(dirtyDate);
var amount = toInteger(dirtyAmount);
if (isNaN(amount)) {
return new Date(NaN);
}
if (!amount) {
// If 0 months, no-op to avoid changing times in the hour before end of DST
return date;
}
var dayOfMonth = date.getDate(); // The JS Date object supports date math by accepting out-of-bounds values for
// month, day, etc. For example, new Date(2020, 0, 0) returns 31 Dec 2019 and
// new Date(2020, 13, 1) returns 1 Feb 2021. This is *almost* the behavior we
// want except that dates will wrap around the end of a month, meaning that
// new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So
// we'll default to the end of the desired month by adding 1 to the desired
// month and using a date of 0 to back up one day to the end of the desired
// month.
var endOfDesiredMonth = new Date(date.getTime());
endOfDesiredMonth.setMonth(date.getMonth() + amount + 1, 0);
var daysInMonth = endOfDesiredMonth.getDate();
if (dayOfMonth >= daysInMonth) {
// If we're already at the end of the month, then this is the correct date
// and we're done.
return endOfDesiredMonth;
} else {
// Otherwise, we now know that setting the original day-of-month value won't
// cause an overflow, so set the desired day-of-month. Note that we can't
// just set the date of `endOfDesiredMonth` because that object may have had
// its time changed in the unusual case where where a DST transition was on
// the last day of the month and its local time was in the hour skipped or
// repeated next to a DST transition. So we use `date` instead which is
// guaranteed to still have the original time.
date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
return date;
}
}
/**
* @name addMilliseconds
* @category Millisecond Helpers
* @summary Add the specified number of milliseconds to the given date.
*
* @description
* Add the specified number of milliseconds to the given date.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to be changed
* @param {Number} amount - the amount of milliseconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
* @returns {Date} the new date with the milliseconds added
* @throws {TypeError} 2 arguments required
*
* @example
* // Add 750 milliseconds to 10 July 2014 12:45:30.000:
* const result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)
* //=> Thu Jul 10 2014 12:45:30.750
*/
function addMilliseconds(dirtyDate, dirtyAmount) {
requiredArgs(2, arguments);
var timestamp = toDate(dirtyDate).getTime();
var amount = toInteger(dirtyAmount);
return new Date(timestamp + amount);
}
/**
* Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.
* They usually appear for dates that denote time before the timezones were introduced
* (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891
* and GMT+01:00:00 after that date)
*
* Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,
* which would lead to incorrect calculations.
*
* This function returns the timezone offset in milliseconds that takes seconds in account.
*/
function getTimezoneOffsetInMilliseconds(date) {
var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
utcDate.setUTCFullYear(date.getFullYear());
return date.getTime() - utcDate.getTime();
}
/**
* @name startOfDay
* @category Day Helpers
* @summary Return the start of a day for the given date.
*
* @description
* Return the start of a day for the given date.
* The result will be in the local timezone.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the original date
* @returns {Date} the start of a day
* @throws {TypeError} 1 argument required
*
* @example
* // The start of a day for 2 September 2014 11:55:00:
* const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 02 2014 00:00:00
*/
function startOfDay(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
date.setHours(0, 0, 0, 0);
return date;
}
var MILLISECONDS_IN_DAY$1 = 86400000;
/**
* @name differenceInCalendarDays
* @category Day Helpers
* @summary Get the number of calendar days between the given dates.
*
* @description
* Get the number of calendar days between the given dates. This means that the times are removed
* from the dates and then the difference in days is calculated.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of calendar days
* @throws {TypeError} 2 arguments required
*
* @example
* // How many calendar days are between
* // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
* const result = differenceInCalendarDays(
* new Date(2012, 6, 2, 0, 0),
* new Date(2011, 6, 2, 23, 0)
* )
* //=> 366
* // How many calendar days are between
* // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?
* const result = differenceInCalendarDays(
* new Date(2011, 6, 3, 0, 1),
* new Date(2011, 6, 2, 23, 59)
* )
* //=> 1
*/
function differenceInCalendarDays(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var startOfDayLeft = startOfDay(dirtyDateLeft);
var startOfDayRight = startOfDay(dirtyDateRight);
var timestampLeft = startOfDayLeft.getTime() - getTimezoneOffsetInMilliseconds(startOfDayLeft);
var timestampRight = startOfDayRight.getTime() - getTimezoneOffsetInMilliseconds(startOfDayRight); // Round the number of days to the nearest integer
// because the number of milliseconds in a day is not constant
// (e.g. it's different in the day of the daylight saving time clock shift)
return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY$1);
}
/**
* @name compareAsc
* @category Common Helpers
* @summary Compare the two dates and return -1, 0 or 1.
*
* @description
* Compare the two dates and return 1 if the first date is after the second,
* -1 if the first date is before the second or 0 if dates are equal.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the first date to compare
* @param {Date|Number} dateRight - the second date to compare
* @returns {Number} the result of the comparison
* @throws {TypeError} 2 arguments required
*
* @example
* // Compare 11 February 1987 and 10 July 1989:
* const result = compareAsc(new Date(1987, 1, 11), new Date(1989, 6, 10))
* //=> -1
*
* @example
* // Sort the array of dates:
* const result = [
* new Date(1995, 6, 2),
* new Date(1987, 1, 11),
* new Date(1989, 6, 10)
* ].sort(compareAsc)
* //=> [
* // Wed Feb 11 1987 00:00:00,
* // Mon Jul 10 1989 00:00:00,
* // Sun Jul 02 1995 00:00:00
* // ]
*/
function compareAsc(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var dateLeft = toDate(dirtyDateLeft);
var dateRight = toDate(dirtyDateRight);
var diff = dateLeft.getTime() - dateRight.getTime();
if (diff < 0) {
return -1;
} else if (diff > 0) {
return 1; // Return 0 if diff is 0; return NaN if diff is NaN
} else {
return diff;
}
}
/**
* Days in 1 week.
*
* @name daysInWeek
* @constant
* @type {number}
* @default
*/
/**
* Milliseconds in 1 minute
*
* @name millisecondsInMinute
* @constant
* @type {number}
* @default
*/
var millisecondsInMinute = 60000;
/**
* Milliseconds in 1 hour
*
* @name millisecondsInHour
* @constant
* @type {number}
* @default
*/
var millisecondsInHour = 3600000;
/**
* @name isDate
* @category Common Helpers
* @summary Is the given value a date?
*
* @description
* Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {*} value - the value to check
* @returns {boolean} true if the given value is a date
* @throws {TypeError} 1 arguments required
*
* @example
* // For a valid date:
* const result = isDate(new Date())
* //=> true
*
* @example
* // For an invalid date:
* const result = isDate(new Date(NaN))
* //=> true
*
* @example
* // For some value:
* const result = isDate('2014-02-31')
* //=> false
*
* @example
* // For an object:
* const result = isDate({})
* //=> false
*/
function isDate(value) {
requiredArgs(1, arguments);
return value instanceof Date || typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]';
}
/**
* @name isValid
* @category Common Helpers
* @summary Is the given date valid?
*
* @description
* Returns false if argument is Invalid Date and true otherwise.
* Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}
* Invalid Date is a Date, whose time value is NaN.
*
* Time value of Date: http://es5.github.io/#x15.9.1.1
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* - Now `isValid` doesn't throw an exception
* if the first argument is not an instance of Date.
* Instead, argument is converted beforehand using `toDate`.
*
* Examples:
*
* | `isValid` argument | Before v2.0.0 | v2.0.0 onward |
* |---------------------------|---------------|---------------|
* | `new Date()` | `true` | `true` |
* | `new Date('2016-01-01')` | `true` | `true` |
* | `new Date('')` | `false` | `false` |
* | `new Date(1488370835081)` | `true` | `true` |
* | `new Date(NaN)` | `false` | `false` |
* | `'2016-01-01'` | `TypeError` | `false` |
* | `''` | `TypeError` | `false` |
* | `1488370835081` | `TypeError` | `true` |
* | `NaN` | `TypeError` | `false` |
*
* We introduce this change to make *date-fns* consistent with ECMAScript behavior
* that try to coerce arguments to the expected type
* (which is also the case with other *date-fns* functions).
*
* @param {*} date - the date to check
* @returns {Boolean} the date is valid
* @throws {TypeError} 1 argument required
*
* @example
* // For the valid date:
* const result = isValid(new Date(2014, 1, 31))
* //=> true
*
* @example
* // For the value, convertable into a date:
* const result = isValid(1393804800000)
* //=> true
*
* @example
* // For the invalid date:
* const result = isValid(new Date(''))
* //=> false
*/
function isValid(dirtyDate) {
requiredArgs(1, arguments);
if (!isDate(dirtyDate) && typeof dirtyDate !== 'number') {
return false;
}
var date = toDate(dirtyDate);
return !isNaN(Number(date));
}
/**
* @name differenceInCalendarMonths
* @category Month Helpers
* @summary Get the number of calendar months between the given dates.
*
* @description
* Get the number of calendar months between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of calendar months
* @throws {TypeError} 2 arguments required
*
* @example
* // How many calendar months are between 31 January 2014 and 1 September 2014?
* var result = differenceInCalendarMonths(
* new Date(2014, 8, 1),
* new Date(2014, 0, 31)
* )
* //=> 8
*/
function differenceInCalendarMonths(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var dateLeft = toDate(dirtyDateLeft);
var dateRight = toDate(dirtyDateRight);
var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear();
var monthDiff = dateLeft.getMonth() - dateRight.getMonth();
return yearDiff * 12 + monthDiff;
}
/**
* @name differenceInCalendarYears
* @category Year Helpers
* @summary Get the number of calendar years between the given dates.
*
* @description
* Get the number of calendar years between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of calendar years
* @throws {TypeError} 2 arguments required
*
* @example
* // How many calendar years are between 31 December 2013 and 11 February 2015?
* const result = differenceInCalendarYears(
* new Date(2015, 1, 11),
* new Date(2013, 11, 31)
* )
* //=> 2
*/
function differenceInCalendarYears(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var dateLeft = toDate(dirtyDateLeft);
var dateRight = toDate(dirtyDateRight);
return dateLeft.getFullYear() - dateRight.getFullYear();
}
// for accurate equality comparisons of UTC timestamps that end up
// having the same representation in local time, e.g. one hour before
// DST ends vs. the instant that DST ends.
function compareLocalAsc(dateLeft, dateRight) {
var diff = dateLeft.getFullYear() - dateRight.getFullYear() || dateLeft.getMonth() - dateRight.getMonth() || dateLeft.getDate() - dateRight.getDate() || dateLeft.getHours() - dateRight.getHours() || dateLeft.getMinutes() - dateRight.getMinutes() || dateLeft.getSeconds() - dateRight.getSeconds() || dateLeft.getMilliseconds() - dateRight.getMilliseconds();
if (diff < 0) {
return -1;
} else if (diff > 0) {
return 1; // Return 0 if diff is 0; return NaN if diff is NaN
} else {
return diff;
}
}
/**
* @name differenceInDays
* @category Day Helpers
* @summary Get the number of full days between the given dates.
*
* @description
* Get the number of full day periods between two dates. Fractional days are
* truncated towards zero.
*
* One "full day" is the distance between a local time in one day to the same
* local time on the next or previous day. A full day can sometimes be less than
* or more than 24 hours if a daylight savings change happens between two dates.
*
* To ignore DST and only measure exact 24-hour periods, use this instead:
* `Math.floor(differenceInHours(dateLeft, dateRight)/24)|0`.
*
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of full days according to the local timezone
* @throws {TypeError} 2 arguments required
*
* @example
* // How many full days are between
* // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
* const result = differenceInDays(
* new Date(2012, 6, 2, 0, 0),
* new Date(2011, 6, 2, 23, 0)
* )
* //=> 365
* // How many full days are between
* // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?
* const result = differenceInDays(
* new Date(2011, 6, 3, 0, 1),
* new Date(2011, 6, 2, 23, 59)
* )
* //=> 0
* // How many full days are between
* // 1 March 2020 0:00 and 1 June 2020 0:00 ?
* // Note: because local time is used, the
* // result will always be 92 days, even in
* // time zones where DST starts and the
* // period has only 92*24-1 hours.
* const result = differenceInDays(
* new Date(2020, 5, 1),
* new Date(2020, 2, 1)
* )
//=> 92
*/
function differenceInDays(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var dateLeft = toDate(dirtyDateLeft);
var dateRight = toDate(dirtyDateRight);
var sign = compareLocalAsc(dateLeft, dateRight);
var difference = Math.abs(differenceInCalendarDays(dateLeft, dateRight));
dateLeft.setDate(dateLeft.getDate() - sign * difference); // Math.abs(diff in full days - diff in calendar days) === 1 if last calendar day is not full
// If so, result must be decreased by 1 in absolute value
var isLastDayNotFull = Number(compareLocalAsc(dateLeft, dateRight) === -sign);
var result = sign * (difference - isLastDayNotFull); // Prevent negative zero
return result === 0 ? 0 : result;
}
/**
* @name differenceInMilliseconds
* @category Millisecond Helpers
* @summary Get the number of milliseconds between the given dates.
*
* @description
* Get the number of milliseconds between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of milliseconds
* @throws {TypeError} 2 arguments required
*
* @example
* // How many milliseconds are between
* // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?
* const result = differenceInMilliseconds(
* new Date(2014, 6, 2, 12, 30, 21, 700),
* new Date(2014, 6, 2, 12, 30, 20, 600)
* )
* //=> 1100
*/
function differenceInMilliseconds(dateLeft, dateRight) {
requiredArgs(2, arguments);
return toDate(dateLeft).getTime() - toDate(dateRight).getTime();
}
var roundingMap = {
ceil: Math.ceil,
round: Math.round,
floor: Math.floor,
trunc: function (value) {
return value < 0 ? Math.ceil(value) : Math.floor(value);
} // Math.trunc is not supported by IE
};
var defaultRoundingMethod = 'trunc';
function getRoundingMethod(method) {
return method ? roundingMap[method] : roundingMap[defaultRoundingMethod];
}
/**
* @name differenceInHours
* @category Hour Helpers
* @summary Get the number of hours between the given dates.
*
* @description
* Get the number of hours between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @param {Object} [options] - an object with options.
* @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
* @returns {Number} the number of hours
* @throws {TypeError} 2 arguments required
*
* @example
* // How many hours are between 2 July 2014 06:50:00 and 2 July 2014 19:00:00?
* const result = differenceInHours(
* new Date(2014, 6, 2, 19, 0),
* new Date(2014, 6, 2, 6, 50)
* )
* //=> 12
*/
function differenceInHours(dateLeft, dateRight, options) {
requiredArgs(2, arguments);
var diff = differenceInMilliseconds(dateLeft, dateRight) / millisecondsInHour;
return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
}
/**
* @name differenceInMinutes
* @category Minute Helpers
* @summary Get the number of minutes between the given dates.
*
* @description
* Get the signed number of full (rounded towards 0) minutes between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @param {Object} [options] - an object with options.
* @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
* @returns {Number} the number of minutes
* @throws {TypeError} 2 arguments required
*
* @example
* // How many minutes are between 2 July 2014 12:07:59 and 2 July 2014 12:20:00?
* const result = differenceInMinutes(
* new Date(2014, 6, 2, 12, 20, 0),
* new Date(2014, 6, 2, 12, 7, 59)
* )
* //=> 12
*
* @example
* // How many minutes are between 10:01:59 and 10:00:00
* const result = differenceInMinutes(
* new Date(2000, 0, 1, 10, 0, 0),
* new Date(2000, 0, 1, 10, 1, 59)
* )
* //=> -1
*/
function differenceInMinutes(dateLeft, dateRight, options) {
requiredArgs(2, arguments);
var diff = differenceInMilliseconds(dateLeft, dateRight) / millisecondsInMinute;
return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
}
/**
* @name endOfDay
* @category Day Helpers
* @summary Return the end of a day for the given date.
*
* @description
* Return the end of a day for the given date.
* The result will be in the local timezone.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the original date
* @returns {Date} the end of a day
* @throws {TypeError} 1 argument required
*
* @example
* // The end of a day for 2 September 2014 11:55:00:
* const result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 02 2014 23:59:59.999
*/
function endOfDay(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
date.setHours(23, 59, 59, 999);
return date;
}
/**
* @name endOfMonth
* @category Month Helpers
* @summary Return the end of a month for the given date.
*
* @description
* Return the end of a month for the given date.
* The result will be in the local timezone.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the original date
* @returns {Date} the end of a month
* @throws {TypeError} 1 argument required
*
* @example
* // The end of a month for 2 September 2014 11:55:00:
* const result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 30 2014 23:59:59.999
*/
function endOfMonth(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
var month = date.getMonth();
date.setFullYear(date.getFullYear(), month + 1, 0);
date.setHours(23, 59, 59, 999);
return date;
}
/**
* @name isLastDayOfMonth
* @category Month Helpers
* @summary Is the given date the last day of a month?
*
* @description
* Is the given date the last day of a month?
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to check
* @returns {Boolean} the date is the last day of a month
* @throws {TypeError} 1 argument required
*
* @example
* // Is 28 February 2014 the last day of a month?
* var result = isLastDayOfMonth(new Date(2014, 1, 28))
* //=> true
*/
function isLastDayOfMonth(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
return endOfDay(date).getTime() === endOfMonth(date).getTime();
}
/**
* @name differenceInMonths
* @category Month Helpers
* @summary Get the number of full months between the given dates.
*
* @description
* Get the number of full months between the given dates using trunc as a default rounding method.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of full months
* @throws {TypeError} 2 arguments required
*
* @example
* // How many full months are between 31 January 2014 and 1 September 2014?
* const result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))
* //=> 7
*/
function differenceInMonths(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var dateLeft = toDate(dirtyDateLeft);
var dateRight = toDate(dirtyDateRight);
var sign = compareAsc(dateLeft, dateRight);
var difference = Math.abs(differenceInCalendarMonths(dateLeft, dateRight));
var result; // Check for the difference of less than month
if (difference < 1) {
result = 0;
} else {
if (dateLeft.getMonth() === 1 && dateLeft.getDate() > 27) {
// This will check if the date is end of Feb and assign a higher end of month date
// to compare it with Jan
dateLeft.setDate(30);
}
dateLeft.setMonth(dateLeft.getMonth() - sign * difference); // Math.abs(diff in full months - diff in calendar months) === 1 if last calendar month is not full
// If so, result must be decreased by 1 in absolute value
var isLastMonthNotFull = compareAsc(dateLeft, dateRight) === -sign; // Check for cases of one full calendar month
if (isLastDayOfMonth(toDate(dirtyDateLeft)) && difference === 1 && compareAsc(dirtyDateLeft, dateRight) === 1) {
isLastMonthNotFull = false;
}
result = sign * (difference - Number(isLastMonthNotFull));
} // Prevent negative zero
return result === 0 ? 0 : result;
}
/**
* @name differenceInSeconds
* @category Second Helpers
* @summary Get the number of seconds between the given dates.
*
* @description
* Get the number of seconds between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @param {Object} [options] - an object with options.
* @param {String} [options.roundingMethod='trunc'] - a rounding method (`ceil`, `floor`, `round` or `trunc`)
* @returns {Number} the number of seconds
* @throws {TypeError} 2 arguments required
*
* @example
* // How many seconds are between
* // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?
* const result = differenceInSeconds(
* new Date(2014, 6, 2, 12, 30, 20, 0),
* new Date(2014, 6, 2, 12, 30, 7, 999)
* )
* //=> 12
*/
function differenceInSeconds(dateLeft, dateRight, options) {
requiredArgs(2, arguments);
var diff = differenceInMilliseconds(dateLeft, dateRight) / 1000;
return getRoundingMethod(options === null || options === void 0 ? void 0 : options.roundingMethod)(diff);
}
/**
* @name differenceInYears
* @category Year Helpers
* @summary Get the number of full years between the given dates.
*
* @description
* Get the number of full years between the given dates.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} dateLeft - the later date
* @param {Date|Number} dateRight - the earlier date
* @returns {Number} the number of full years
* @throws {TypeError} 2 arguments required
*
* @example
* // How many full years are between 31 December 2013 and 11 February 2015?
* const result = differenceInYears(new Date(2015, 1, 11), new Date(2013, 11, 31))
* //=> 1
*/
function differenceInYears(dirtyDateLeft, dirtyDateRight) {
requiredArgs(2, arguments);
var dateLeft = toDate(dirtyDateLeft);
var dateRight = toDate(dirtyDateRight);
var sign = compareAsc(dateLeft, dateRight);
var difference = Math.abs(differenceInCalendarYears(dateLeft, dateRight)); // Set both dates to a valid leap year for accurate comparison when dealing
// with leap days
dateLeft.setFullYear(1584);
dateRight.setFullYear(1584); // Math.abs(diff in full years - diff in calendar years) === 1 if last calendar year is not full
// If so, result must be decreased by 1 in absolute value
var isLastYearNotFull = compareAsc(dateLeft, dateRight) === -sign;
var result = sign * (difference - Number(isLastYearNotFull)); // Prevent negative zero
return result === 0 ? 0 : result;
}
var formatDistanceLocale = {
lessThanXSeconds: {
one: 'less than a second',
other: 'less than {{count}} seconds'
},
xSeconds: {
one: '1 second',
other: '{{count}} seconds'
},
halfAMinute: 'half a minute',
lessThanXMinutes: {
one: 'less than a minute',
other: 'less than {{count}} minutes'
},
xMinutes: {
one: '1 minute',
other: '{{count}} minutes'
},
aboutXHours: {
one: 'about 1 hour',
other: 'about {{count}} hours'
},
xHours: {
one: '1 hour',
other: '{{count}} hours'
},
xDays: {
one: '1 day',
other: '{{count}} days'
},
aboutXWeeks: {
one: 'about 1 week',
other: 'about {{count}} weeks'
},
xWeeks: {
one: '1 week',
other: '{{count}} weeks'
},
aboutXMonths: {
one: 'about 1 month',
other: 'about {{count}} months'
},
xMonths: {
one: '1 month',
other: '{{count}} months'
},
aboutXYears: {
one: 'about 1 year',
other: 'about {{count}} years'
},
xYears: {
one: '1 year',
other: '{{count}} years'
},
overXYears: {
one: 'over 1 year',
other: 'over {{count}} years'
},
almostXYears: {
one: 'almost 1 year',
other: 'almost {{count}} years'
}
};
var formatDistance = function (token, count, options) {
var result;
var tokenValue = formatDistanceLocale[token];
if (typeof tokenValue === 'string') {
result = tokenValue;
} else if (count === 1) {
result = tokenValue.one;
} else {
result = tokenValue.other.replace('{{count}}', count.toString());
}
if (options !== null && options !== void 0 && options.addSuffix) {
if (options.comparison && options.comparison > 0) {
return 'in ' + result;
} else {
return result + ' ago';
}
}
return result;
};
function buildFormatLongFn(args) {
return function () {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// TODO: Remove String()
var width = options.width ? String(options.width) : args.defaultWidth;
var format = args.formats[width] || args.formats[args.defaultWidth];
return format;
};
}
var dateFormats = {
full: 'EEEE, MMMM do, y',
long: 'MMMM do, y',
medium: 'MMM d, y',
short: 'MM/dd/yyyy'
};
var timeFormats = {
full: 'h:mm:ss a zzzz',
long: 'h:mm:ss a z',
medium: 'h:mm:ss a',
short: 'h:mm a'
};
var dateTimeFormats = {
full: "{{date}} 'at' {{time}}",
long: "{{date}} 'at' {{time}}",
medium: '{{date}}, {{time}}',
short: '{{date}}, {{time}}'
};
var formatLong = {
date: buildFormatLongFn({
formats: dateFormats,
defaultWidth: 'full'
}),
time: buildFormatLongFn({
formats: timeFormats,
defaultWidth: 'full'
}),
dateTime: buildFormatLongFn({
formats: dateTimeFormats,
defaultWidth: 'full'
})
};
var formatRelativeLocale = {
lastWeek: "'last' eeee 'at' p",
yesterday: "'yesterday at' p",
today: "'today at' p",
tomorrow: "'tomorrow at' p",
nextWeek: "eeee 'at' p",
other: 'P'
};
var formatRelative = function (token, _date, _baseDate, _options) {
return formatRelativeLocale[token];
};
function buildLocalizeFn(args) {
return function (dirtyIndex, dirtyOptions) {
var options = dirtyOptions || {};
var context = options.context ? String(options.context) : 'standalone';
var valuesArray;
if (context === 'formatting' && args.formattingValues) {
var defaultWidth = args.defaultFormattingWidth || args.defaultWidth;
var width = options.width ? String(options.width) : defaultWidth;
valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];
} else {
var _defaultWidth = args.defaultWidth;
var _width = options.width ? String(options.width) : args.defaultWidth;
valuesArray = args.values[_width] || args.values[_defaultWidth];
}
var index = args.argumentCallback ? args.argumentCallback(dirtyIndex) : dirtyIndex; // @ts-ignore: For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it!
return valuesArray[index];
};
}
var eraValues = {
narrow: ['B', 'A'],
abbreviated: ['BC', 'AD'],
wide: ['Before Christ', 'Anno Domini']
};
var quarterValues = {
narrow: ['1', '2', '3', '4'],
abbreviated: ['Q1', 'Q2', 'Q3', 'Q4'],
wide: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter']
}; // Note: in English, the names of days of the week and months are capitalized.
// If you are making a new locale based on this one, check if the same is true for the language you're working on.
// Generally, formatted dates should look like they are in the middle of a sentence,
// e.g. in Spanish language the weekdays and months should be in the lowercase.
var monthValues = {
narrow: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
abbreviated: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
wide: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
};
var dayValues = {
narrow: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
short: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
abbreviated: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
wide: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
};
var dayPeriodValues = {
narrow: {
am: 'a',
pm: 'p',
midnight: 'mi',
noon: 'n',
morning: 'morning',
afternoon: 'afternoon',
evening: 'evening',
night: 'night'
},
abbreviated: {
am: 'AM',
pm: 'PM',
midnight: 'midnight',
noon: 'noon',
morning: 'morning',
afternoon: 'afternoon',
evening: 'evening',
night: 'night'
},
wide: {
am: 'a.m.',
pm: 'p.m.',
midnight: 'midnight',
noon: 'noon',
morning: 'morning',
afternoon: 'afternoon',
evening: 'evening',
night: 'night'
}
};
var formattingDayPeriodValues = {
narrow: {
am: 'a',
pm: 'p',
midnight: 'mi',
noon: 'n',
morning: 'in the morning',
afternoon: 'in the afternoon',
evening: 'in the evening',
night: 'at night'
},
abbreviated: {
am: 'AM',
pm: 'PM',
midnight: 'midnight',
noon: 'noon',
morning: 'in the morning',
afternoon: 'in the afternoon',
evening: 'in the evening',
night: 'at night'
},
wide: {
am: 'a.m.',
pm: 'p.m.',
midnight: 'midnight',
noon: 'noon',
morning: 'in the morning',
afternoon: 'in the afternoon',
evening: 'in the evening',
night: 'at night'
}
};
var ordinalNumber = function (dirtyNumber, _options) {
var number = Number(dirtyNumber); // If ordinal numbers depend on context, for example,
// if they are different for different grammatical genders,
// use `options.unit`.
//
// `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',
// 'day', 'hour', 'minute', 'second'.
var rem100 = number % 100;
if (rem100 > 20 || rem100 < 10) {
switch (rem100 % 10) {
case 1:
return number + 'st';
case 2:
return number + 'nd';
case 3:
return number + 'rd';
}
}
return number + 'th';
};
var localize = {
ordinalNumber: ordinalNumber,
era: buildLocalizeFn({
values: eraValues,
defaultWidth: 'wide'
}),
quarter: buildLocalizeFn({
values: quarterValues,
defaultWidth: 'wide',
argumentCallback: function (quarter) {
return quarter - 1;
}
}),
month: buildLocalizeFn({
values: monthValues,
defaultWidth: 'wide'
}),
day: buildLocalizeFn({
values: dayValues,
defaultWidth: 'wide'
}),
dayPeriod: buildLocalizeFn({
values: dayPeriodValues,
defaultWidth: 'wide',
formattingValues: formattingDayPeriodValues,
defaultFormattingWidth: 'wide'
})
};
function buildMatchFn(args) {
return function (string) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var width = options.width;
var matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];
var matchResult = string.match(matchPattern);
if (!matchResult) {
return null;
}
var matchedString = matchResult[0];
var parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];
var key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, function (pattern) {
return pattern.test(matchedString);
}) : findKey(parsePatterns, function (pattern) {
return pattern.test(matchedString);
});
var value;
value = args.valueCallback ? args.valueCallback(key) : key;
value = options.valueCallback ? options.valueCallback(value) : value;
var rest = string.slice(matchedString.length);
return {
value: value,
rest: rest
};
};
}
function findKey(object, predicate) {
for (var key in object) {
if (object.hasOwnProperty(key) && predicate(object[key])) {
return key;
}
}
return undefined;
}
function findIndex(array, predicate) {
for (var key = 0; key < array.length; key++) {
if (predicate(array[key])) {
return key;
}
}
return undefined;
}
function buildMatchPatternFn(args) {
return function (string) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var matchResult = string.match(args.matchPattern);
if (!matchResult) return null;
var matchedString = matchResult[0];
var parseResult = string.match(args.parsePattern);
if (!parseResult) return null;
var value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];
value = options.valueCallback ? options.valueCallback(value) : value;
var rest = string.slice(matchedString.length);
return {
value: value,
rest: rest
};
};
}
var matchOrdinalNumberPattern = /^(\d+)(th|st|nd|rd)?/i;
var parseOrdinalNumberPattern = /\d+/i;
var matchEraPatterns = {
narrow: /^(b|a)/i,
abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,
wide: /^(before christ|before common era|anno domini|common era)/i
};
var parseEraPatterns = {
any: [/^b/i, /^(a|c)/i]
};
var matchQuarterPatterns = {
narrow: /^[1234]/i,
abbreviated: /^q[1234]/i,
wide: /^[1234](th|st|nd|rd)? quarter/i
};
var parseQuarterPatterns = {
any: [/1/i, /2/i, /3/i, /4/i]
};
var matchMonthPatterns = {
narrow: /^[jfmasond]/i,
abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,
wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i
};
var parseMonthPatterns = {
narrow: [/^j/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i],
any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i]
};
var matchDayPatterns = {
narrow: /^[smtwf]/i,
short: /^(su|mo|tu|we|th|fr|sa)/i,
abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,
wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i
};
var parseDayPatterns = {
narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],
any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]
};
var matchDayPeriodPatterns = {
narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,
any: /^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i
};
var parseDayPeriodPatterns = {
any: {
am: /^a/i,
pm: /^p/i,
midnight: /^mi/i,
noon: /^no/i,
morning: /morning/i,
afternoon: /afternoon/i,
evening: /evening/i,
night: /night/i
}
};
var match = {
ordinalNumber: buildMatchPatternFn({
matchPattern: matchOrdinalNumberPattern,
parsePattern: parseOrdinalNumberPattern,
valueCallback: function (value) {
return parseInt(value, 10);
}
}),
era: buildMatchFn({
matchPatterns: matchEraPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseEraPatterns,
defaultParseWidth: 'any'
}),
quarter: buildMatchFn({
matchPatterns: matchQuarterPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseQuarterPatterns,
defaultParseWidth: 'any',
valueCallback: function (index) {
return index + 1;
}
}),
month: buildMatchFn({
matchPatterns: matchMonthPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseMonthPatterns,
defaultParseWidth: 'any'
}),
day: buildMatchFn({
matchPatterns: matchDayPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseDayPatterns,
defaultParseWidth: 'any'
}),
dayPeriod: buildMatchFn({
matchPatterns: matchDayPeriodPatterns,
defaultMatchWidth: 'any',
parsePatterns: parseDayPeriodPatterns,
defaultParseWidth: 'any'
})
};
/**
* @type {Locale}
* @category Locales
* @summary English locale (United States).
* @language English
* @iso-639-2 eng
* @author Sasha Koss [@kossnocorp]{@link https://github.com/kossnocorp}
* @author Lesha Koss [@leshakoss]{@link https://github.com/leshakoss}
*/
var locale = {
code: 'en-US',
formatDistance: formatDistance,
formatLong: formatLong,
formatRelative: formatRelative,
localize: localize,
match: match,
options: {
weekStartsOn: 0
/* Sunday */
,
firstWeekContainsDate: 1
}
};
var defaultLocale = locale;
/**
* @name subMilliseconds
* @category Millisecond Helpers
* @summary Subtract the specified number of milliseconds from the given date.
*
* @description
* Subtract the specified number of milliseconds from the given date.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to be changed
* @param {Number} amount - the amount of milliseconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
* @returns {Date} the new date with the milliseconds subtracted
* @throws {TypeError} 2 arguments required
*
* @example
* // Subtract 750 milliseconds from 10 July 2014 12:45:30.000:
* const result = subMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)
* //=> Thu Jul 10 2014 12:45:29.250
*/
function subMilliseconds(dirtyDate, dirtyAmount) {
requiredArgs(2, arguments);
var amount = toInteger(dirtyAmount);
return addMilliseconds(dirtyDate, -amount);
}
var MILLISECONDS_IN_DAY = 86400000; // This function will be a part of public API when UTC function will be implemented.
// See issue: https://github.com/date-fns/date-fns/issues/376
function getUTCDayOfYear(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
var timestamp = date.getTime();
date.setUTCMonth(0, 1);
date.setUTCHours(0, 0, 0, 0);
var startOfYearTimestamp = date.getTime();
var difference = timestamp - startOfYearTimestamp;
return Math.floor(difference / MILLISECONDS_IN_DAY) + 1;
}
// See issue: https://github.com/date-fns/date-fns/issues/376
function startOfUTCISOWeek(dirtyDate) {
requiredArgs(1, arguments);
var weekStartsOn = 1;
var date = toDate(dirtyDate);
var day = date.getUTCDay();
var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
date.setUTCDate(date.getUTCDate() - diff);
date.setUTCHours(0, 0, 0, 0);
return date;
}
// See issue: https://github.com/date-fns/date-fns/issues/376
function getUTCISOWeekYear(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
var year = date.getUTCFullYear();
var fourthOfJanuaryOfNextYear = new Date(0);
fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4);
fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0);
var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear);
var fourthOfJanuaryOfThisYear = new Date(0);
fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4);
fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0);
var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear);
if (date.getTime() >= startOfNextYear.getTime()) {
return year + 1;
} else if (date.getTime() >= startOfThisYear.getTime()) {
return year;
} else {
return year - 1;
}
}
// See issue: https://github.com/date-fns/date-fns/issues/376
function startOfUTCISOWeekYear(dirtyDate) {
requiredArgs(1, arguments);
var year = getUTCISOWeekYear(dirtyDate);
var fourthOfJanuary = new Date(0);
fourthOfJanuary.setUTCFullYear(year, 0, 4);
fourthOfJanuary.setUTCHours(0, 0, 0, 0);
var date = startOfUTCISOWeek(fourthOfJanuary);
return date;
}
var MILLISECONDS_IN_WEEK$1 = 604800000; // This function will be a part of public API when UTC function will be implemented.
// See issue: https://github.com/date-fns/date-fns/issues/376
function getUTCISOWeek(dirtyDate) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
var diff = startOfUTCISOWeek(date).getTime() - startOfUTCISOWeekYear(date).getTime(); // Round the number of days to the nearest integer
// because the number of milliseconds in a week is not constant
// (e.g. it's different in the week of the daylight saving time clock shift)
return Math.round(diff / MILLISECONDS_IN_WEEK$1) + 1;
}
// See issue: https://github.com/date-fns/date-fns/issues/376
function startOfUTCWeek(dirtyDate, dirtyOptions) {
requiredArgs(1, arguments);
var options = dirtyOptions || {};
var locale = options.locale;
var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn;
var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);
var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
}
var date = toDate(dirtyDate);
var day = date.getUTCDay();
var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
date.setUTCDate(date.getUTCDate() - diff);
date.setUTCHours(0, 0, 0, 0);
return date;
}
// See issue: https://github.com/date-fns/date-fns/issues/376
function getUTCWeekYear(dirtyDate, dirtyOptions) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
var year = date.getUTCFullYear();
var options = dirtyOptions || {};
var locale = options.locale;
var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;
var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);
var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN
if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {
throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');
}
var firstWeekOfNextYear = new Date(0);
firstWeekOfNextYear.setUTCFullYear(year + 1, 0, firstWeekContainsDate);
firstWeekOfNextYear.setUTCHours(0, 0, 0, 0);
var startOfNextYear = startOfUTCWeek(firstWeekOfNextYear, dirtyOptions);
var firstWeekOfThisYear = new Date(0);
firstWeekOfThisYear.setUTCFullYear(year, 0, firstWeekContainsDate);
firstWeekOfThisYear.setUTCHours(0, 0, 0, 0);
var startOfThisYear = startOfUTCWeek(firstWeekOfThisYear, dirtyOptions);
if (date.getTime() >= startOfNextYear.getTime()) {
return year + 1;
} else if (date.getTime() >= startOfThisYear.getTime()) {
return year;
} else {
return year - 1;
}
}
// See issue: https://github.com/date-fns/date-fns/issues/376
function startOfUTCWeekYear(dirtyDate, dirtyOptions) {
requiredArgs(1, arguments);
var options = dirtyOptions || {};
var locale = options.locale;
var localeFirstWeekContainsDate = locale && locale.options && locale.options.firstWeekContainsDate;
var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);
var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate);
var year = getUTCWeekYear(dirtyDate, dirtyOptions);
var firstWeek = new Date(0);
firstWeek.setUTCFullYear(year, 0, firstWeekContainsDate);
firstWeek.setUTCHours(0, 0, 0, 0);
var date = startOfUTCWeek(firstWeek, dirtyOptions);
return date;
}
var MILLISECONDS_IN_WEEK = 604800000; // This function will be a part of public API when UTC function will be implemented.
// See issue: https://github.com/date-fns/date-fns/issues/376
function getUTCWeek(dirtyDate, options) {
requiredArgs(1, arguments);
var date = toDate(dirtyDate);
var diff = startOfUTCWeek(date, options).getTime() - startOfUTCWeekYear(date, options).getTime(); // Round the number of days to the nearest integer
// because the number of milliseconds in a week is not constant
// (e.g. it's different in the week of the daylight saving time clock shift)
return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;
}
function addLeadingZeros(number, targetLength) {
var sign = number < 0 ? '-' : '';
var output = Math.abs(number).toString();
while (output.length < targetLength) {
output = '0' + output;
}
return sign + output;
}
/*
* | | Unit | | Unit |
* |-----|--------------------------------|-----|--------------------------------|
* | a | AM, PM | A* | |
* | d | Day of month | D | |
* | h | Hour [1-12] | H | Hour [0-23] |
* | m | Minute | M | Month |
* | s | Second | S | Fraction of second |
* | y | Year (abs) | Y | |
*
* Letters marked by * are not implemented but reserved by Unicode standard.
*/
var formatters$2 = {
// Year
y: function (date, token) {
// From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens
// | Year | y | yy | yyy | yyyy | yyyyy |
// |----------|-------|----|-------|-------|-------|
// | AD 1 | 1 | 01 | 001 | 0001 | 00001 |
// | AD 12 | 12 | 12 | 012 | 0012 | 00012 |
// | AD 123 | 123 | 23 | 123 | 0123 | 00123 |
// | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 |
// | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |
var signedYear = date.getUTCFullYear(); // Returns 1 for 1 BC (which is year 0 in JavaScript)
var year = signedYear > 0 ? signedYear : 1 - signedYear;
return addLeadingZeros(token === 'yy' ? year % 100 : year, token.length);
},
// Month
M: function (date, token) {
var month = date.getUTCMonth();
return token === 'M' ? String(month + 1) : addLeadingZeros(month + 1, 2);
},
// Day of the month
d: function (date, token) {
return addLeadingZeros(date.getUTCDate(), token.length);
},
// AM or PM
a: function (date, token) {
var dayPeriodEnumValue = date.getUTCHours() / 12 >= 1 ? 'pm' : 'am';
switch (token) {
case 'a':
case 'aa':
return dayPeriodEnumValue.toUpperCase();
case 'aaa':
return dayPeriodEnumValue;
case 'aaaaa':
return dayPeriodEnumValue[0];
case 'aaaa':
default:
return dayPeriodEnumValue === 'am' ? 'a.m.' : 'p.m.';
}
},
// Hour [1-12]
h: function (date, token) {
return addLeadingZeros(date.getUTCHours() % 12 || 12, token.length);
},
// Hour [0-23]
H: function (date, token) {
return addLeadingZeros(date.getUTCHours(), token.length);
},
// Minute
m: function (date, token) {
return addLeadingZeros(date.getUTCMinutes(), token.length);
},
// Second
s: function (date, token) {
return addLeadingZeros(date.getUTCSeconds(), token.length);
},
// Fraction of second
S: function (date, token) {
var numberOfDigits = token.length;
var milliseconds = date.getUTCMilliseconds();
var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, numberOfDigits - 3));
return addLeadingZeros(fractionalSeconds, token.length);
}
};
var dayPeriodEnum = {
am: 'am',
pm: 'pm',
midnight: 'midnight',
noon: 'noon',
morning: 'morning',
afternoon: 'afternoon',
evening: 'evening',
night: 'night'
};
/*
* | | Unit | | Unit |
* |-----|--------------------------------|-----|--------------------------------|
* | a | AM, PM | A* | Milliseconds in day |
* | b | AM, PM, noon, midnight | B | Flexible day period |
* | c | Stand-alone local day of week | C* | Localized hour w/ day period |
* | d | Day of month | D | Day of year |
* | e | Local day of week | E | Day of week |
* | f | | F* | Day of week in month |
* | g* | Modified Julian day | G | Era |
* | h | Hour [1-12] | H | Hour [0-23] |
* | i! | ISO day of week | I! | ISO week of year |
* | j* | Localized hour w/ day period | J* | Localized hour w/o day period |
* | k | Hour [1-24] | K | Hour [0-11] |
* | l* | (deprecated) | L | Stand-alone month |
* | m | Minute | M | Month |
* | n | | N | |
* | o! | Ordinal number modifier | O | Timezone (GMT) |
* | p! | Long localized time | P! | Long localized date |
* | q | Stand-alone quarter | Q | Quarter |
* | r* | Related Gregorian year | R! | ISO week-numbering year |
* | s | Second | S | Fraction of second |
* | t! | Seconds timestamp | T! | Milliseconds timestamp |
* | u | Extended year | U* | Cyclic year |
* | v* | Timezone (generic non-locat.) | V* | Timezone (location) |
* | w | Local week of year | W* | Week of month |
* | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) |
* | y | Year (abs) | Y | Local week-numbering year |
* | z | Timezone (specific non-locat.) | Z* | Timezone (aliases) |
*
* Letters marked by * are not implemented but reserved by Unicode standard.
*
* Letters marked by ! are non-standard, but implemented by date-fns:
* - `o` modifies the previous token to turn it into an ordinal (see `format` docs)
* - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,
* i.e. 7 for Sunday, 1 for Monday, etc.
* - `I` is ISO week of year, as opposed to `w` which is local week of year.
* - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.
* `R` is supposed to be used in conjunction with `I` and `i`
* for universal ISO week-numbering date, whereas
* `Y` is supposed to be used in conjunction with `w` and `e`
* for week-numbering date specific to the locale.
* - `P` is long localized date format
* - `p` is long localized time format
*/
var formatters = {
// Era
G: function (date, token, localize) {
var era = date.getUTCFullYear() > 0 ? 1 : 0;
switch (token) {
// AD, BC
case 'G':
case 'GG':
case 'GGG':
return localize.era(era, {
width: 'abbreviated'
});
// A, B
case 'GGGGG':
return localize.era(era, {
width: 'narrow'
});
// Anno Domini, Before Christ
case 'GGGG':
default:
return localize.era(era, {
width: 'wide'
});
}
},
// Year
y: function (date, token, localize) {
// Ordinal number
if (token === 'yo') {
var signedYear = date.getUTCFullYear(); // Returns 1 for 1 BC (which is year 0 in JavaScript)
var year = signedYear > 0 ? signedYear : 1 - signedYear;
return localize.ordinalNumber(year, {
unit: 'year'
});
}
return formatters$2.y(date, token);
},
// Local week-numbering year
Y: function (date, token, localize, options) {
var signedWeekYear = getUTCWeekYear(date, options); // Returns 1 for 1 BC (which is year 0 in JavaScript)
var weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear; // Two digit year
if (token === 'YY') {
var twoDigitYear = weekYear % 100;
return addLeadingZeros(twoDigitYear, 2);
} // Ordinal number
if (token === 'Yo') {
return localize.ordinalNumber(weekYear, {
unit: 'year'
});
} // Padding
return addLeadingZeros(weekYear, token.length);
},
// ISO week-numbering year
R: function (date, token) {
var isoWeekYear = getUTCISOWeekYear(date); // Padding
return addLeadingZeros(isoWeekYear, token.length);
},
// Extended year. This is a single number designating the year of this calendar system.
// The main difference between `y` and `u` localizers are B.C. years:
// | Year | `y` | `u` |
// |------|-----|-----|
// | AC 1 | 1 | 1 |
// | BC 1 | 1 | 0 |
// | BC 2 | 2 | -1 |
// Also `yy` always returns the last two digits of a year,
// while `uu` pads single digit years to 2 characters and returns other years unchanged.
u: function (date, token) {
var year = date.getUTCFullYear();
return addLeadingZeros(year, token.length);
},
// Quarter
Q: function (date, token, localize) {
var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);
switch (token) {
// 1, 2, 3, 4
case 'Q':
return String(quarter);
// 01, 02, 03, 04
case 'QQ':
return addLeadingZeros(quarter, 2);
// 1st, 2nd, 3rd, 4th
case 'Qo':
return localize.ordinalNumber(quarter, {
unit: 'quarter'
});
// Q1, Q2, Q3, Q4
case 'QQQ':
return localize.quarter(quarter, {
width: 'abbreviated',
context: 'formatting'
});
// 1, 2, 3, 4 (narrow quarter; could be not numerical)
case 'QQQQQ':
return localize.quarter(quarter, {
width: 'narrow',
context: 'formatting'
});
// 1st quarter, 2nd quarter, ...
case 'QQQQ':
default:
return localize.quarter(quarter, {
width: 'wide',
context: 'formatting'
});
}
},
// Stand-alone quarter
q: function (date, token, localize) {
var quarter = Math.ceil((date.getUTCMonth() + 1) / 3);
switch (token) {
// 1, 2, 3, 4
case 'q':
return String(quarter);
// 01, 02, 03, 04
case 'qq':
return addLeadingZeros(quarter, 2);
// 1st, 2nd, 3rd, 4th
case 'qo':
return localize.ordinalNumber(quarter, {
unit: 'quarter'
});
// Q1, Q2, Q3, Q4
case 'qqq':
return localize.quarter(quarter, {
width: 'abbreviated',
context: 'standalone'
});
// 1, 2, 3, 4 (narrow quarter; could be not numerical)
case 'qqqqq':
return localize.quarter(quarter, {
width: 'narrow',
context: 'standalone'
});
// 1st quarter, 2nd quarter, ...
case 'qqqq':
default:
return localize.quarter(quarter, {
width: 'wide',
context: 'standalone'
});
}
},
// Month
M: function (date, token, localize) {
var month = date.getUTCMonth();
switch (token) {
case 'M':
case 'MM':
return formatters$2.M(date, token);
// 1st, 2nd, ..., 12th
case 'Mo':
return localize.ordinalNumber(month + 1, {
unit: 'month'
});
// Jan, Feb, ..., Dec
case 'MMM':
return localize.month(month, {
width: 'abbreviated',
context: 'formatting'
});
// J, F, ..., D
case 'MMMMM':
return localize.month(month, {
width: 'narrow',
context: 'formatting'
});
// January, February, ..., December
case 'MMMM':
default:
return localize.month(month, {
width: 'wide',
context: 'formatting'
});
}
},
// Stand-alone month
L: function (date, token, localize) {
var month = date.getUTCMonth();
switch (token) {
// 1, 2, ..., 12
case 'L':
return String(month + 1);
// 01, 02, ..., 12
case 'LL':
return addLeadingZeros(month + 1, 2);
// 1st, 2nd, ..., 12th
case 'Lo':
return localize.ordinalNumber(month + 1, {
unit: 'month'
});
// Jan, Feb, ..., Dec
case 'LLL':
return localize.month(month, {
width: 'abbreviated',
context: 'standalone'
});
// J, F, ..., D
case 'LLLLL':
return localize.month(month, {
width: 'narrow',
context: 'standalone'
});
// January, February, ..., December
case 'LLLL':
default:
return localize.month(month, {
width: 'wide',
context: 'standalone'
});
}
},
// Local week of year
w: function (date, token, localize, options) {
var week = getUTCWeek(date, options);
if (token === 'wo') {
return localize.ordinalNumber(week, {
unit: 'week'
});
}
return addLeadingZeros(week, token.length);
},
// ISO week of year
I: function (date, token, localize) {
var isoWeek = getUTCISOWeek(date);
if (token === 'Io') {
return localize.ordinalNumber(isoWeek, {
unit: 'week'
});
}
return addLeadingZeros(isoWeek, token.length);
},
// Day of the month
d: function (date, token, localize) {
if (token === 'do') {
return localize.ordinalNumber(date.getUTCDate(), {
unit: 'date'
});
}
return formatters$2.d(date, token);
},
// Day of year
D: function (date, token, localize) {
var dayOfYear = getUTCDayOfYear(date);
if (token === 'Do') {
return localize.ordinalNumber(dayOfYear, {
unit: 'dayOfYear'
});
}
return addLeadingZeros(dayOfYear, token.length);
},
// Day of week
E: function (date, token, localize) {
var dayOfWeek = date.getUTCDay();
switch (token) {
// Tue
case 'E':
case 'EE':
case 'EEE':
return localize.day(dayOfWeek, {
width: 'abbreviated',
context: 'formatting'
});
// T
case 'EEEEE':
return localize.day(dayOfWeek, {
width: 'narrow',
context: 'formatting'
});
// Tu
case 'EEEEEE':
return localize.day(dayOfWeek, {
width: 'short',
context: 'formatting'
});
// Tuesday
case 'EEEE':
default:
return localize.day(dayOfWeek, {
width: 'wide',
context: 'formatting'
});
}
},
// Local day of week
e: function (date, token, localize, options) {
var dayOfWeek = date.getUTCDay();
var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
switch (token) {
// Numerical value (Nth day of week with current locale or weekStartsOn)
case 'e':
return String(localDayOfWeek);
// Padded numerical value
case 'ee':
return addLeadingZeros(localDayOfWeek, 2);
// 1st, 2nd, ..., 7th
case 'eo':
return localize.ordinalNumber(localDayOfWeek, {
unit: 'day'
});
case 'eee':
return localize.day(dayOfWeek, {
width: 'abbreviated',
context: 'formatting'
});
// T
case 'eeeee':
return localize.day(dayOfWeek, {
width: 'narrow',
context: 'formatting'
});
// Tu
case 'eeeeee':
return localize.day(dayOfWeek, {
width: 'short',
context: 'formatting'
});
// Tuesday
case 'eeee':
default:
return localize.day(dayOfWeek, {
width: 'wide',
context: 'formatting'
});
}
},
// Stand-alone local day of week
c: function (date, token, localize, options) {
var dayOfWeek = date.getUTCDay();
var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
switch (token) {
// Numerical value (same as in `e`)
case 'c':
return String(localDayOfWeek);
// Padded numerical value
case 'cc':
return addLeadingZeros(localDayOfWeek, token.length);
// 1st, 2nd, ..., 7th
case 'co':
return localize.ordinalNumber(localDayOfWeek, {
unit: 'day'
});
case 'ccc':
return localize.day(dayOfWeek, {
width: 'abbreviated',
context: 'standalone'
});
// T
case 'ccccc':
return localize.day(dayOfWeek, {
width: 'narrow',
context: 'standalone'
});
// Tu
case 'cccccc':
return localize.day(dayOfWeek, {
width: 'short',
context: 'standalone'
});
// Tuesday
case 'cccc':
default:
return localize.day(dayOfWeek, {
width: 'wide',
context: 'standalone'
});
}
},
// ISO day of week
i: function (date, token, localize) {
var dayOfWeek = date.getUTCDay();
var isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
switch (token) {
// 2
case 'i':
return String(isoDayOfWeek);
// 02
case 'ii':
return addLeadingZeros(isoDayOfWeek, token.length);
// 2nd
case 'io':
return localize.ordinalNumber(isoDayOfWeek, {
unit: 'day'
});
// Tue
case 'iii':
return localize.day(dayOfWeek, {
width: 'abbreviated',
context: 'formatting'
});
// T
case 'iiiii':
return localize.day(dayOfWeek, {
width: 'narrow',
context: 'formatting'
});
// Tu
case 'iiiiii':
return localize.day(dayOfWeek, {
width: 'short',
context: 'formatting'
});
// Tuesday
case 'iiii':
default:
return localize.day(dayOfWeek, {
width: 'wide',
context: 'formatting'
});
}
},
// AM or PM
a: function (date, token, localize) {
var hours = date.getUTCHours();
var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';
switch (token) {
case 'a':
case 'aa':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'abbreviated',
context: 'formatting'
});
case 'aaa':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'abbreviated',
context: 'formatting'
}).toLowerCase();
case 'aaaaa':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'narrow',
context: 'formatting'
});
case 'aaaa':
default:
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'wide',
context: 'formatting'
});
}
},
// AM, PM, midnight, noon
b: function (date, token, localize) {
var hours = date.getUTCHours();
var dayPeriodEnumValue;
if (hours === 12) {
dayPeriodEnumValue = dayPeriodEnum.noon;
} else if (hours === 0) {
dayPeriodEnumValue = dayPeriodEnum.midnight;
} else {
dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am';
}
switch (token) {
case 'b':
case 'bb':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'abbreviated',
context: 'formatting'
});
case 'bbb':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'abbreviated',
context: 'formatting'
}).toLowerCase();
case 'bbbbb':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'narrow',
context: 'formatting'
});
case 'bbbb':
default:
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'wide',
context: 'formatting'
});
}
},
// in the morning, in the afternoon, in the evening, at night
B: function (date, token, localize) {
var hours = date.getUTCHours();
var dayPeriodEnumValue;
if (hours >= 17) {
dayPeriodEnumValue = dayPeriodEnum.evening;
} else if (hours >= 12) {
dayPeriodEnumValue = dayPeriodEnum.afternoon;
} else if (hours >= 4) {
dayPeriodEnumValue = dayPeriodEnum.morning;
} else {
dayPeriodEnumValue = dayPeriodEnum.night;
}
switch (token) {
case 'B':
case 'BB':
case 'BBB':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'abbreviated',
context: 'formatting'
});
case 'BBBBB':
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'narrow',
context: 'formatting'
});
case 'BBBB':
default:
return localize.dayPeriod(dayPeriodEnumValue, {
width: 'wide',
context: 'formatting'
});
}
},
// Hour [1-12]
h: function (date, token, localize) {
if (token === 'ho') {
var hours = date.getUTCHours() % 12;
if (hours === 0) hours = 12;
return localize.ordinalNumber(hours, {
unit: 'hour'
});
}
return formatters$2.h(date, token);
},
// Hour [0-23]
H: function (date, token, localize) {
if (token === 'Ho') {
return localize.ordinalNumber(date.getUTCHours(), {
unit: 'hour'
});
}
return formatters$2.H(date, token);
},
// Hour [0-11]
K: function (date, token, localize) {
var hours = date.getUTCHours() % 12;
if (token === 'Ko') {
return localize.ordinalNumber(hours, {
unit: 'hour'
});
}
return addLeadingZeros(hours, token.length);
},
// Hour [1-24]
k: function (date, token, localize) {
var hours = date.getUTCHours();
if (hours === 0) hours = 24;
if (token === 'ko') {
return localize.ordinalNumber(hours, {
unit: 'hour'
});
}
return addLeadingZeros(hours, token.length);
},
// Minute
m: function (date, token, localize) {
if (token === 'mo') {
return localize.ordinalNumber(date.getUTCMinutes(), {
unit: 'minute'
});
}
return formatters$2.m(date, token);
},
// Second
s: function (date, token, localize) {
if (token === 'so') {
return localize.ordinalNumber(date.getUTCSeconds(), {
unit: 'second'
});
}
return formatters$2.s(date, token);
},
// Fraction of second
S: function (date, token) {
return formatters$2.S(date, token);
},
// Timezone (ISO-8601. If offset is 0, output is always `'Z'`)
X: function (date, token, _localize, options) {
var originalDate = options._originalDate || date;
var timezoneOffset = originalDate.getTimezoneOffset();
if (timezoneOffset === 0) {
return 'Z';
}
switch (token) {
// Hours and optional minutes
case 'X':
return formatTimezoneWithOptionalMinutes(timezoneOffset);
// Hours, minutes and optional seconds without `:` delimiter
// Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
// so this token always has the same output as `XX`
case 'XXXX':
case 'XX':
// Hours and minutes without `:` delimiter
return formatTimezone(timezoneOffset);
// Hours, minutes and optional seconds with `:` delimiter
// Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
// so this token always has the same output as `XXX`
case 'XXXXX':
case 'XXX': // Hours and minutes with `:` delimiter
default:
return formatTimezone(timezoneOffset, ':');
}
},
// Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent)
x: function (date, token, _localize, options) {
var originalDate = options._originalDate || date;
var timezoneOffset = originalDate.getTimezoneOffset();
switch (token) {
// Hours and optional minutes
case 'x':
return formatTimezoneWithOptionalMinutes(timezoneOffset);
// Hours, minutes and optional seconds without `:` delimiter
// Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
// so this token always has the same output as `xx`
case 'xxxx':
case 'xx':
// Hours and minutes without `:` delimiter
return formatTimezone(timezoneOffset);
// Hours, minutes and optional seconds with `:` delimiter
// Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
// so this token always has the same output as `xxx`
case 'xxxxx':
case 'xxx': // Hours and minutes with `:` delimiter
default:
return formatTimezone(timezoneOffset, ':');
}
},
// Timezone (GMT)
O: function (date, token, _localize, options) {
var originalDate = options._originalDate || date;
var timezoneOffset = originalDate.getTimezoneOffset();
switch (token) {
// Short
case 'O':
case 'OO':
case 'OOO':
return 'GMT' + formatTimezoneShort(timezoneOffset, ':');
// Long
case 'OOOO':
default:
return 'GMT' + formatTimezone(timezoneOffset, ':');
}
},
// Timezone (specific non-location)
z: function (date, token, _localize, options) {
var originalDate = options._originalDate || date;
var timezoneOffset = originalDate.getTimezoneOffset();
switch (token) {
// Short
case 'z':
case 'zz':
case 'zzz':
return 'GMT' + formatTimezoneShort(timezoneOffset, ':');
// Long
case 'zzzz':
default:
return 'GMT' + formatTimezone(timezoneOffset, ':');
}
},
// Seconds timestamp
t: function (date, token, _localize, options) {
var originalDate = options._originalDate || date;
var timestamp = Math.floor(originalDate.getTime() / 1000);
return addLeadingZeros(timestamp, token.length);
},
// Milliseconds timestamp
T: function (date, token, _localize, options) {
var originalDate = options._originalDate || date;
var timestamp = originalDate.getTime();
return addLeadingZeros(timestamp, token.length);
}
};
function formatTimezoneShort(offset, dirtyDelimiter) {
var sign = offset > 0 ? '-' : '+';
var absOffset = Math.abs(offset);
var hours = Math.floor(absOffset / 60);
var minutes = absOffset % 60;
if (minutes === 0) {
return sign + String(hours);
}
var delimiter = dirtyDelimiter || '';
return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2);
}
function formatTimezoneWithOptionalMinutes(offset, dirtyDelimiter) {
if (offset % 60 === 0) {
var sign = offset > 0 ? '-' : '+';
return sign + addLeadingZeros(Math.abs(offset) / 60, 2);
}
return formatTimezone(offset, dirtyDelimiter);
}
function formatTimezone(offset, dirtyDelimiter) {
var delimiter = dirtyDelimiter || '';
var sign = offset > 0 ? '-' : '+';
var absOffset = Math.abs(offset);
var hours = addLeadingZeros(Math.floor(absOffset / 60), 2);
var minutes = addLeadingZeros(absOffset % 60, 2);
return sign + hours + delimiter + minutes;
}
var formatters$1 = formatters;
function dateLongFormatter(pattern, formatLong) {
switch (pattern) {
case 'P':
return formatLong.date({
width: 'short'
});
case 'PP':
return formatLong.date({
width: 'medium'
});
case 'PPP':
return formatLong.date({
width: 'long'
});
case 'PPPP':
default:
return formatLong.date({
width: 'full'
});
}
}
function timeLongFormatter(pattern, formatLong) {
switch (pattern) {
case 'p':
return formatLong.time({
width: 'short'
});
case 'pp':
return formatLong.time({
width: 'medium'
});
case 'ppp':
return formatLong.time({
width: 'long'
});
case 'pppp':
default:
return formatLong.time({
width: 'full'
});
}
}
function dateTimeLongFormatter(pattern, formatLong) {
var matchResult = pattern.match(/(P+)(p+)?/) || [];
var datePattern = matchResult[1];
var timePattern = matchResult[2];
if (!timePattern) {
return dateLongFormatter(pattern, formatLong);
}
var dateTimeFormat;
switch (datePattern) {
case 'P':
dateTimeFormat = formatLong.dateTime({
width: 'short'
});
break;
case 'PP':
dateTimeFormat = formatLong.dateTime({
width: 'medium'
});
break;
case 'PPP':
dateTimeFormat = formatLong.dateTime({
width: 'long'
});
break;
case 'PPPP':
default:
dateTimeFormat = formatLong.dateTime({
width: 'full'
});
break;
}
return dateTimeFormat.replace('{{date}}', dateLongFormatter(datePattern, formatLong)).replace('{{time}}', timeLongFormatter(timePattern, formatLong));
}
var longFormatters = {
p: timeLongFormatter,
P: dateTimeLongFormatter
};
var longFormatters$1 = longFormatters;
var protectedDayOfYearTokens = ['D', 'DD'];
var protectedWeekYearTokens = ['YY', 'YYYY'];
function isProtectedDayOfYearToken(token) {
return protectedDayOfYearTokens.indexOf(token) !== -1;
}
function isProtectedWeekYearToken(token) {
return protectedWeekYearTokens.indexOf(token) !== -1;
}
function throwProtectedError(token, format, input) {
if (token === 'YYYY') {
throw new RangeError("Use `yyyy` instead of `YYYY` (in `".concat(format, "`) for formatting years to the input `").concat(input, "`; see: https://git.io/fxCyr"));
} else if (token === 'YY') {
throw new RangeError("Use `yy` instead of `YY` (in `".concat(format, "`) for formatting years to the input `").concat(input, "`; see: https://git.io/fxCyr"));
} else if (token === 'D') {
throw new RangeError("Use `d` instead of `D` (in `".concat(format, "`) for formatting days of the month to the input `").concat(input, "`; see: https://git.io/fxCyr"));
} else if (token === 'DD') {
throw new RangeError("Use `dd` instead of `DD` (in `".concat(format, "`) for formatting days of the month to the input `").concat(input, "`; see: https://git.io/fxCyr"));
}
}
// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token
// (one of the certain letters followed by `o`)
// - (\w)\1* matches any sequences of the same letter
// - '' matches two quote characters in a row
// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),
// except a single quote symbol, which ends the sequence.
// Two quote characters do not end the sequence.
// If there is no matching single quote
// then the sequence will continue until the end of the string.
// - . matches any single character unmatched by previous parts of the RegExps
var formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g; // This RegExp catches symbols escaped by quotes, and also
// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`
var longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
var escapedStringRegExp = /^'([^]*?)'?$/;
var doubleQuoteRegExp = /''/g;
var unescapedLatinCharacterRegExp = /[a-zA-Z]/;
/**
* @name format
* @category Common Helpers
* @summary Format the date.
*
* @description
* Return the formatted date string in the given format. The result may vary by locale.
*
* > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.
* > See: https://git.io/fxCyr
*
* The characters wrapped between two single quotes characters (') are escaped.
* Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
* (see the last example)
*
* Format of the string is based on Unicode Technical Standard #35:
* https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* with a few additions (see note 7 below the table).
*
* Accepted patterns:
* | Unit | Pattern | Result examples | Notes |
* |---------------------------------|---------|-----------------------------------|-------|
* | Era | G..GGG | AD, BC | |
* | | GGGG | Anno Domini, Before Christ | 2 |
* | | GGGGG | A, B | |
* | Calendar year | y | 44, 1, 1900, 2017 | 5 |
* | | yo | 44th, 1st, 0th, 17th | 5,7 |
* | | yy | 44, 01, 00, 17 | 5 |
* | | yyy | 044, 001, 1900, 2017 | 5 |
* | | yyyy | 0044, 0001, 1900, 2017 | 5 |
* | | yyyyy | ... | 3,5 |
* | Local week-numbering year | Y | 44, 1, 1900, 2017 | 5 |
* | | Yo | 44th, 1st, 1900th, 2017th | 5,7 |
* | | YY | 44, 01, 00, 17 | 5,8 |
* | | YYY | 044, 001, 1900, 2017 | 5 |
* | | YYYY | 0044, 0001, 1900, 2017 | 5,8 |
* | | YYYYY | ... | 3,5 |
* | ISO week-numbering year | R | -43, 0, 1, 1900, 2017 | 5,7 |
* | | RR | -43, 00, 01, 1900, 2017 | 5,7 |
* | | RRR | -043, 000, 001, 1900, 2017 | 5,7 |
* | | RRRR | -0043, 0000, 0001, 1900, 2017 | 5,7 |
* | | RRRRR | ... | 3,5,7 |
* | Extended year | u | -43, 0, 1, 1900, 2017 | 5 |
* | | uu | -43, 01, 1900, 2017 | 5 |
* | | uuu | -043, 001, 1900, 2017 | 5 |
* | | uuuu | -0043, 0001, 1900, 2017 | 5 |
* | | uuuuu | ... | 3,5 |
* | Quarter (formatting) | Q | 1, 2, 3, 4 | |
* | | Qo | 1st, 2nd, 3rd, 4th | 7 |
* | | QQ | 01, 02, 03, 04 | |
* | | QQQ | Q1, Q2, Q3, Q4 | |
* | | QQQQ | 1st quarter, 2nd quarter, ... | 2 |
* | | QQQQQ | 1, 2, 3, 4 | 4 |
* | Quarter (stand-alone) | q | 1, 2, 3, 4 | |
* | | qo | 1st, 2nd, 3rd, 4th | 7 |
* | | qq | 01, 02, 03, 04 | |
* | | qqq | Q1, Q2, Q3, Q4 | |
* | | qqqq | 1st quarter, 2nd quarter, ... | 2 |
* | | qqqqq | 1, 2, 3, 4 | 4 |
* | Month (formatting) | M | 1, 2, ..., 12 | |
* | | Mo | 1st, 2nd, ..., 12th | 7 |
* | | MM | 01, 02, ..., 12 | |
* | | MMM | Jan, Feb, ..., Dec | |
* | | MMMM | January, February, ..., December | 2 |
* | | MMMMM | J, F, ..., D | |
* | Month (stand-alone) | L | 1, 2, ..., 12 | |
* | | Lo | 1st, 2nd, ..., 12th | 7 |
* | | LL | 01, 02, ..., 12 | |
* | | LLL | Jan, Feb, ..., Dec | |
* | | LLLL | January, February, ..., December | 2 |
* | | LLLLL | J, F, ..., D | |
* | Local week of year | w | 1, 2, ..., 53 | |
* | | wo | 1st, 2nd, ..., 53th | 7 |
* | | ww | 01, 02, ..., 53 | |
* | ISO week of year | I | 1, 2, ..., 53 | 7 |
* | | Io | 1st, 2nd, ..., 53th | 7 |
* | | II | 01, 02, ..., 53 | 7 |
* | Day of month | d | 1, 2, ..., 31 | |
* | | do | 1st, 2nd, ..., 31st | 7 |
* | | dd | 01, 02, ..., 31 | |
* | Day of year | D | 1, 2, ..., 365, 366 | 9 |
* | | Do | 1st, 2nd, ..., 365th, 366th | 7 |
* | | DD | 01, 02, ..., 365, 366 | 9 |
* | | DDD | 001, 002, ..., 365, 366 | |
* | | DDDD | ... | 3 |
* | Day of week (formatting) | E..EEE | Mon, Tue, Wed, ..., Sun | |
* | | EEEE | Monday, Tuesday, ..., Sunday | 2 |
* | | EEEEE | M, T, W, T, F, S, S | |
* | | EEEEEE | Mo, Tu, We, Th, Fr, Sa, Su | |
* | ISO day of week (formatting) | i | 1, 2, 3, ..., 7 | 7 |
* | | io | 1st, 2nd, ..., 7th | 7 |
* | | ii | 01, 02, ..., 07 | 7 |
* | | iii | Mon, Tue, Wed, ..., Sun | 7 |
* | | iiii | Monday, Tuesday, ..., Sunday | 2,7 |
* | | iiiii | M, T, W, T, F, S, S | 7 |
* | | iiiiii | Mo, Tu, We, Th, Fr, Sa, Su | 7 |
* | Local day of week (formatting) | e | 2, 3, 4, ..., 1 | |
* | | eo | 2nd, 3rd, ..., 1st | 7 |
* | | ee | 02, 03, ..., 01 | |
* | | eee | Mon, Tue, Wed, ..., Sun | |
* | | eeee | Monday, Tuesday, ..., Sunday | 2 |
* | | eeeee | M, T, W, T, F, S, S | |
* | | eeeeee | Mo, Tu, We, Th, Fr, Sa, Su | |
* | Local day of week (stand-alone) | c | 2, 3, 4, ..., 1 | |
* | | co | 2nd, 3rd, ..., 1st | 7 |
* | | cc | 02, 03, ..., 01 | |
* | | ccc | Mon, Tue, Wed, ..., Sun | |
* | | cccc | Monday, Tuesday, ..., Sunday | 2 |
* | | ccccc | M, T, W, T, F, S, S | |
* | | cccccc | Mo, Tu, We, Th, Fr, Sa, Su | |
* | AM, PM | a..aa | AM, PM | |
* | | aaa | am, pm | |
* | | aaaa | a.m., p.m. | 2 |
* | | aaaaa | a, p | |
* | AM, PM, noon, midnight | b..bb | AM, PM, noon, midnight | |
* | | bbb | am, pm, noon, midnight | |
* | | bbbb | a.m., p.m., noon, midnight | 2 |
* | | bbbbb | a, p, n, mi | |
* | Flexible day period | B..BBB | at night, in the morning, ... | |
* | | BBBB | at night, in the morning, ... | 2 |
* | | BBBBB | at night, in the morning, ... | |
* | Hour [1-12] | h | 1, 2, ..., 11, 12 | |
* | | ho | 1st, 2nd, ..., 11th, 12th | 7 |
* | | hh | 01, 02, ..., 11, 12 | |
* | Hour [0-23] | H | 0, 1, 2, ..., 23 | |
* | | Ho | 0th, 1st, 2nd, ..., 23rd | 7 |
* | | HH | 00, 01, 02, ..., 23 | |
* | Hour [0-11] | K | 1, 2, ..., 11, 0 | |
* | | Ko | 1st, 2nd, ..., 11th, 0th | 7 |
* | | KK | 01, 02, ..., 11, 00 | |
* | Hour [1-24] | k | 24, 1, 2, ..., 23 | |
* | | ko | 24th, 1st, 2nd, ..., 23rd | 7 |
* | | kk | 24, 01, 02, ..., 23 | |
* | Minute | m | 0, 1, ..., 59 | |
* | | mo | 0th, 1st, ..., 59th | 7 |
* | | mm | 00, 01, ..., 59 | |
* | Second | s | 0, 1, ..., 59 | |
* | | so | 0th, 1st, ..., 59th | 7 |
* | | ss | 00, 01, ..., 59 | |
* | Fraction of second | S | 0, 1, ..., 9 | |
* | | SS | 00, 01, ..., 99 | |
* | | SSS | 000, 001, ..., 999 | |
* | | SSSS | ... | 3 |
* | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | |
* | | XX | -0800, +0530, Z | |
* | | XXX | -08:00, +05:30, Z | |
* | | XXXX | -0800, +0530, Z, +123456 | 2 |
* | | XXXXX | -08:00, +05:30, Z, +12:34:56 | |
* | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | |
* | | xx | -0800, +0530, +0000 | |
* | | xxx | -08:00, +05:30, +00:00 | 2 |
* | | xxxx | -0800, +0530, +0000, +123456 | |
* | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | |
* | Timezone (GMT) | O...OOO | GMT-8, GMT+5:30, GMT+0 | |
* | | OOOO | GMT-08:00, GMT+05:30, GMT+00:00 | 2 |
* | Timezone (specific non-locat.) | z...zzz | GMT-8, GMT+5:30, GMT+0 | 6 |
* | | zzzz | GMT-08:00, GMT+05:30, GMT+00:00 | 2,6 |
* | Seconds timestamp | t | 512969520 | 7 |
* | | tt | ... | 3,7 |
* | Milliseconds timestamp | T | 512969520900 | 7 |
* | | TT | ... | 3,7 |
* | Long localized date | P | 04/29/1453 | 7 |
* | | PP | Apr 29, 1453 | 7 |
* | | PPP | April 29th, 1453 | 7 |
* | | PPPP | Friday, April 29th, 1453 | 2,7 |
* | Long localized time | p | 12:00 AM | 7 |
* | | pp | 12:00:00 AM | 7 |
* | | ppp | 12:00:00 AM GMT+2 | 7 |
* | | pppp | 12:00:00 AM GMT+02:00 | 2,7 |
* | Combination of date and time | Pp | 04/29/1453, 12:00 AM | 7 |
* | | PPpp | Apr 29, 1453, 12:00:00 AM | 7 |
* | | PPPppp | April 29th, 1453 at ... | 7 |
* | | PPPPpppp| Friday, April 29th, 1453 at ... | 2,7 |
* Notes:
* 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale
* are the same as "stand-alone" units, but are different in some languages.
* "Formatting" units are declined according to the rules of the language
* in the context of a date. "Stand-alone" units are always nominative singular:
*
* `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`
*
* `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`
*
* 2. Any sequence of the identical letters is a pattern, unless it is escaped by
* the single quote characters (see below).
* If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)
* the output will be the same as default pattern for this unit, usually
* the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units
* are marked with "2" in the last column of the table.
*
* `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`
*
* `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`
*
* `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`
*
* `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`
*
* `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`
*
* 3. Some patterns could be unlimited length (such as `yyyyyyyy`).
* The output will be padded with zeros to match the length of the pattern.
*
* `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`
*
* 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.
* These tokens represent the shortest form of the quarter.
*
* 5. The main difference between `y` and `u` patterns are B.C. years:
*
* | Year | `y` | `u` |
* |------|-----|-----|
* | AC 1 | 1 | 1 |
* | BC 1 | 1 | 0 |
* | BC 2 | 2 | -1 |
*
* Also `yy` always returns the last two digits of a year,
* while `uu` pads single digit years to 2 characters and returns other years unchanged:
*
* | Year | `yy` | `uu` |
* |------|------|------|
* | 1 | 01 | 01 |
* | 14 | 14 | 14 |
* | 376 | 76 | 376 |
* | 1453 | 53 | 1453 |
*
* The same difference is true for local and ISO week-numbering years (`Y` and `R`),
* except local week-numbering years are dependent on `options.weekStartsOn`
* and `options.firstWeekContainsDate` (compare [getISOWeekYear]{@link https://date-fns.org/docs/getISOWeekYear}
* and [getWeekYear]{@link https://date-fns.org/docs/getWeekYear}).
*
* 6. Specific non-location timezones are currently unavailable in `date-fns`,
* so right now these tokens fall back to GMT timezones.
*
* 7. These patterns are not in the Unicode Technical Standard #35:
* - `i`: ISO day of week
* - `I`: ISO week of year
* - `R`: ISO week-numbering year
* - `t`: seconds timestamp
* - `T`: milliseconds timestamp
* - `o`: ordinal number modifier
* - `P`: long localized date
* - `p`: long localized time
*
* 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.
* You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr
*
* 9. `D` and `DD` tokens represent days of the year but they are often confused with days of the month.
* You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* - The second argument is now required for the sake of explicitness.
*
* ```javascript
* // Before v2.0.0
* format(new Date(2016, 0, 1))
*
* // v2.0.0 onward
* format(new Date(2016, 0, 1), "yyyy-MM-dd'T'HH:mm:ss.SSSxxx")
* ```
*
* - New format string API for `format` function
* which is based on [Unicode Technical Standard #35](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table).
* See [this post](https://blog.date-fns.org/post/unicode-tokens-in-date-fns-v2-sreatyki91jg) for more details.
*
* - Characters are now escaped using single quote symbols (`'`) instead of square brackets.
*
* @param {Date|Number} date - the original date
* @param {String} format - the string of tokens
* @param {Object} [options] - an object with options.
* @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
* @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @param {Number} [options.firstWeekContainsDate=1] - the day of January, which is
* @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`;
* see: https://git.io/fxCyr
* @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`;
* see: https://git.io/fxCyr
* @returns {String} the formatted date string
* @throws {TypeError} 2 arguments required
* @throws {RangeError} `date` must not be Invalid Date
* @throws {RangeError} `options.locale` must contain `localize` property
* @throws {RangeError} `options.locale` must contain `formatLong` property
* @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
* @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7
* @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr
* @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://git.io/fxCyr
* @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr
* @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://git.io/fxCyr
* @throws {RangeError} format string contains an unescaped latin alphabet character
*
* @example
* // Represent 11 February 2014 in middle-endian format:
* var result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')
* //=> '02/11/2014'
*
* @example
* // Represent 2 July 2014 in Esperanto:
* import { eoLocale } from 'date-fns/locale/eo'
* var result = format(new Date(2014, 6, 2), "do 'de' MMMM yyyy", {
* locale: eoLocale
* })
* //=> '2-a de julio 2014'
*
* @example
* // Escape string by single quote characters:
* var result = format(new Date(2014, 6, 2, 15), "h 'o''clock'")
* //=> "3 o'clock"
*/
function format(dirtyDate, dirtyFormatStr, dirtyOptions) {
requiredArgs(2, arguments);
var formatStr = String(dirtyFormatStr);
var options = dirtyOptions || {};
var locale = options.locale || defaultLocale;
var localeFirstWeekContainsDate = locale.options && locale.options.firstWeekContainsDate;
var defaultFirstWeekContainsDate = localeFirstWeekContainsDate == null ? 1 : toInteger(localeFirstWeekContainsDate);
var firstWeekContainsDate = options.firstWeekContainsDate == null ? defaultFirstWeekContainsDate : toInteger(options.firstWeekContainsDate); // Test if weekStartsOn is between 1 and 7 _and_ is not NaN
if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {
throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');
}
var localeWeekStartsOn = locale.options && locale.options.weekStartsOn;
var defaultWeekStartsOn = localeWeekStartsOn == null ? 0 : toInteger(localeWeekStartsOn);
var weekStartsOn = options.weekStartsOn == null ? defaultWeekStartsOn : toInteger(options.weekStartsOn); // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
}
if (!locale.localize) {
throw new RangeError('locale must contain localize property');
}
if (!locale.formatLong) {
throw new RangeError('locale must contain formatLong property');
}
var originalDate = toDate(dirtyDate);
if (!isValid(originalDate)) {
throw new RangeError('Invalid time value');
} // Convert the date in system timezone to the same date in UTC+00:00 timezone.
// This ensures that when UTC functions will be implemented, locales will be compatible with them.
// See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376
var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);
var utcDate = subMilliseconds(originalDate, timezoneOffset);
var formatterOptions = {
firstWeekContainsDate: firstWeekContainsDate,
weekStartsOn: weekStartsOn,
locale: locale,
_originalDate: originalDate
};
var result = formatStr.match(longFormattingTokensRegExp).map(function (substring) {
var firstCharacter = substring[0];
if (firstCharacter === 'p' || firstCharacter === 'P') {
var longFormatter = longFormatters$1[firstCharacter];
return longFormatter(substring, locale.formatLong, formatterOptions);
}
return substring;
}).join('').match(formattingTokensRegExp).map(function (substring) {
// Replace two single quote characters with one single quote character
if (substring === "''") {
return "'";
}
var firstCharacter = substring[0];
if (firstCharacter === "'") {
return cleanEscapedString(substring);
}
var formatter = formatters$1[firstCharacter];
if (formatter) {
if (!options.useAdditionalWeekYearTokens && isProtectedWeekYearToken(substring)) {
throwProtectedError(substring, dirtyFormatStr, dirtyDate);
}
if (!options.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(substring)) {
throwProtectedError(substring, dirtyFormatStr, dirtyDate);
}
return formatter(utcDate, substring, locale.localize, formatterOptions);
}
if (firstCharacter.match(unescapedLatinCharacterRegExp)) {
throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');
}
return substring;
}).join('');
return result;
}
function cleanEscapedString(input) {
return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, "'");
}
var defaultFormat = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'];
/**
* @name formatDuration
* @category Common Helpers
* @summary Formats a duration in human-readable format
*
* @description
* Return human-readable duration string i.e. "9 months 2 days"
*
* @param {Duration} duration - the duration to format
* @param {Object} [options] - an object with options.
* @param {string[]} [options.format=['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds']] - the array of units to format
* @param {boolean} [options.zero=false] - should zeros be included in the output?
* @param {string} [options.delimiter=' '] - delimiter string
* @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
* @returns {string} the formatted date string
* @throws {TypeError} 1 argument required
*
* @example
* // Format full duration
* formatDuration({
* years: 2,
* months: 9,
* weeks: 1,
* days: 7,
* hours: 5,
* minutes: 9,
* seconds: 30
* })
* //=> '2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds'
*
* @example
* // Format partial duration
* formatDuration({ months: 9, days: 2 })
* //=> '9 months 2 days'
*
* @example
* // Customize the format
* formatDuration(
* {
* years: 2,
* months: 9,
* weeks: 1,
* days: 7,
* hours: 5,
* minutes: 9,
* seconds: 30
* },
* { format: ['months', 'weeks'] }
* ) === '9 months 1 week'
*
* @example
* // Customize the zeros presence
* formatDuration({ years: 0, months: 9 })
* //=> '9 months'
* formatDuration({ years: 0, months: 9 }, { zero: true })
* //=> '0 years 9 months'
*
* @example
* // Customize the delimiter
* formatDuration({ years: 2, months: 9, weeks: 3 }, { delimiter: ', ' })
* //=> '2 years, 9 months, 3 weeks'
*/
function formatDuration(duration) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (arguments.length < 1) {
throw new TypeError("1 argument required, but only ".concat(arguments.length, " present"));
}
var format = (options === null || options === void 0 ? void 0 : options.format) || defaultFormat;
var locale = (options === null || options === void 0 ? void 0 : options.locale) || defaultLocale;
var zero = (options === null || options === void 0 ? void 0 : options.zero) || false;
var delimiter = (options === null || options === void 0 ? void 0 : options.delimiter) || ' ';
var result = format.reduce(function (acc, unit) {
var token = "x".concat(unit.replace(/(^.)/, function (m) {
return m.toUpperCase();
}));
var addChunk = typeof duration[unit] === 'number' && (zero || duration[unit]);
return addChunk && locale.formatDistance ? acc.concat(locale.formatDistance(token, duration[unit])) : acc;
}, []).join(delimiter);
return result;
}
/**
* @name formatISO
* @category Common Helpers
* @summary Format the date according to the ISO 8601 standard (https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003169814.htm).
*
* @description
* Return the formatted date string in ISO 8601 format. Options may be passed to control the parts and notations of the date.
*
* @param {Date|Number} date - the original date
* @param {Object} [options] - an object with options.
* @param {'extended'|'basic'} [options.format='extended'] - if 'basic', hide delimiters between date and time values.
* @param {'complete'|'date'|'time'} [options.representation='complete'] - format date, time with local time zone, or both.
* @returns {String} the formatted date string (in local time zone)
* @throws {TypeError} 1 argument required
* @throws {RangeError} `date` must not be Invalid Date
* @throws {RangeError} `options.format` must be 'extended' or 'basic'
* @throws {RangeError} `options.represenation` must be 'date', 'time' or 'complete'
*
* @example
* // Represent 18 September 2019 in ISO 8601 format (local time zone is UTC):
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52))
* //=> '2019-09-18T19:00:52Z'
*
* @example
* // Represent 18 September 2019 in ISO 8601, short format (local time zone is UTC):
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { format: 'basic' })
* //=> '20190918T190052'
*
* @example
* // Represent 18 September 2019 in ISO 8601 format, date only:
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'date' })
* //=> '2019-09-18'
*
* @example
* // Represent 18 September 2019 in ISO 8601 format, time only (local time zone is UTC):
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'time' })
* //=> '19:00:52Z'
*/
function formatISO(date, options) {
requiredArgs(1, arguments);
var originalDate = toDate(date);
if (isNaN(originalDate.getTime())) {
throw new RangeError('Invalid time value');
}
var format = !(options !== null && options !== void 0 && options.format) ? 'extended' : String(options.format);
var representation = !(options !== null && options !== void 0 && options.representation) ? 'complete' : String(options.representation);
if (format !== 'extended' && format !== 'basic') {
throw new RangeError("format must be 'extended' or 'basic'");
}
if (representation !== 'date' && representation !== 'time' && representation !== 'complete') {
throw new RangeError("representation must be 'date', 'time', or 'complete'");
}
var result = '';
var tzOffset = '';
var dateDelimiter = format === 'extended' ? '-' : '';
var timeDelimiter = format === 'extended' ? ':' : ''; // Representation is either 'date' or 'complete'
if (representation !== 'time') {
var day = addLeadingZeros(originalDate.getDate(), 2);
var month = addLeadingZeros(originalDate.getMonth() + 1, 2);
var year = addLeadingZeros(originalDate.getFullYear(), 4); // yyyyMMdd or yyyy-MM-dd.
result = "".concat(year).concat(dateDelimiter).concat(month).concat(dateDelimiter).concat(day);
} // Representation is either 'time' or 'complete'
if (representation !== 'date') {
// Add the timezone.
var offset = originalDate.getTimezoneOffset();
if (offset !== 0) {
var absoluteOffset = Math.abs(offset);
var hourOffset = addLeadingZeros(Math.floor(absoluteOffset / 60), 2);
var minuteOffset = addLeadingZeros(absoluteOffset % 60, 2); // If less than 0, the sign is +, because it is ahead of time.
var sign = offset < 0 ? '+' : '-';
tzOffset = "".concat(sign).concat(hourOffset, ":").concat(minuteOffset);
} else {
tzOffset = 'Z';
}
var hour = addLeadingZeros(originalDate.getHours(), 2);
var minute = addLeadingZeros(originalDate.getMinutes(), 2);
var second = addLeadingZeros(originalDate.getSeconds(), 2); // If there's also date, separate it with time with 'T'
var separator = result === '' ? '' : 'T'; // Creates a time string consisting of hour, minute, and second, separated by delimiters, if defined.
var time = [hour, minute, second].join(timeDelimiter); // HHmmss or HH:mm:ss.
result = "".concat(result).concat(separator).concat(time).concat(tzOffset);
}
return result;
}
/**
* @name subDays
* @category Day Helpers
* @summary Subtract the specified number of days from the given date.
*
* @description
* Subtract the specified number of days from the given date.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to be changed
* @param {Number} amount - the amount of days to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
* @returns {Date} the new date with the days subtracted
* @throws {TypeError} 2 arguments required
*
* @example
* // Subtract 10 days from 1 September 2014:
* const result = subDays(new Date(2014, 8, 1), 10)
* //=> Fri Aug 22 2014 00:00:00
*/
function subDays(dirtyDate, dirtyAmount) {
requiredArgs(2, arguments);
var amount = toInteger(dirtyAmount);
return addDays(dirtyDate, -amount);
}
/**
* @name subMonths
* @category Month Helpers
* @summary Subtract the specified number of months from the given date.
*
* @description
* Subtract the specified number of months from the given date.
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* @param {Date|Number} date - the date to be changed
* @param {Number} amount - the amount of months to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
* @returns {Date} the new date with the months subtracted
* @throws {TypeError} 2 arguments required
*
* @example
* // Subtract 5 months from 1 February 2015:
* const result = subMonths(new Date(2015, 1, 1), 5)
* //=> Mon Sep 01 2014 00:00:00
*/
function subMonths(dirtyDate, dirtyAmount) {
requiredArgs(2, arguments);
var amount = toInteger(dirtyAmount);
return addMonths(dirtyDate, -amount);
}
/**
* @name sub
* @category Common Helpers
* @summary Subtract the specified years, months, weeks, days, hours, minutes and seconds from the given date.
*
* @description
* Subtract the specified years, months, weeks, days, hours, minutes and seconds from the given date.
*
* @param {Date|Number} date - the date to be changed
* @param {Duration} duration - the object with years, months, weeks, days, hours, minutes and seconds to be subtracted
*
* | Key | Description |
* |---------|------------------------------------|
* | years | Amount of years to be subtracted |
* | months | Amount of months to be subtracted |
* | weeks | Amount of weeks to be subtracted |
* | days | Amount of days to be subtracted |
* | hours | Amount of hours to be subtracted |
* | minutes | Amount of minutes to be subtracted |
* | seconds | Amount of seconds to be subtracted |
*
* All values default to 0
*
* @returns {Date} the new date with the seconds subtracted
* @throws {TypeError} 2 arguments required
*
* @example
* // Subtract the following duration from 15 June 2017 15:29:20
* const result = sub(new Date(2017, 5, 15, 15, 29, 20), {
* years: 2,
* months: 9,
* weeks: 1,
* days: 7,
* hours: 5,
* minutes: 9,
* seconds: 30
* })
* //=> Mon Sep 1 2014 10:19:50
*/
function sub(date, duration) {
requiredArgs(2, arguments);
if (!duration || typeof duration !== 'object') return new Date(NaN);
var years = duration.years ? toInteger(duration.years) : 0;
var months = duration.months ? toInteger(duration.months) : 0;
var weeks = duration.weeks ? toInteger(duration.weeks) : 0;
var days = duration.days ? toInteger(duration.days) : 0;
var hours = duration.hours ? toInteger(duration.hours) : 0;
var minutes = duration.minutes ? toInteger(duration.minutes) : 0;
var seconds = duration.seconds ? toInteger(duration.seconds) : 0; // Subtract years and months
var dateWithoutMonths = subMonths(date, months + years * 12); // Subtract weeks and days
var dateWithoutDays = subDays(dateWithoutMonths, days + weeks * 7); // Subtract hours, minutes and seconds
var minutestoSub = minutes + hours * 60;
var secondstoSub = seconds + minutestoSub * 60;
var mstoSub = secondstoSub * 1000;
var finalDate = new Date(dateWithoutDays.getTime() - mstoSub);
return finalDate;
}
/**
* @name intervalToDuration
* @category Common Helpers
* @summary Convert interval to duration
*
* @description
* Convert a interval object to a duration object.
*
* @param {Interval} interval - the interval to convert to duration
*
* @returns {Duration} The duration Object
* @throws {TypeError} Requires 2 arguments
* @throws {RangeError} `start` must not be Invalid Date
* @throws {RangeError} `end` must not be Invalid Date
*
* @example
* // Get the duration between January 15, 1929 and April 4, 1968.
* intervalToDuration({
* start: new Date(1929, 0, 15, 12, 0, 0),
* end: new Date(1968, 3, 4, 19, 5, 0)
* })
* // => { years: 39, months: 2, days: 20, hours: 7, minutes: 5, seconds: 0 }
*/
function intervalToDuration(_ref) {
var start = _ref.start,
end = _ref.end;
requiredArgs(1, arguments);
var dateLeft = toDate(start);
var dateRight = toDate(end);
if (!isValid(dateLeft)) {
throw new RangeError('Start Date is invalid');
}
if (!isValid(dateRight)) {
throw new RangeError('End Date is invalid');
}
var duration = {
years: 0,
months: 0,
days: 0,
hours: 0,
minutes: 0,
seconds: 0
};
var sign = compareAsc(dateLeft, dateRight);
duration.years = Math.abs(differenceInYears(dateLeft, dateRight));
var remainingMonths = sub(dateLeft, {
years: sign * duration.years
});
duration.months = Math.abs(differenceInMonths(remainingMonths, dateRight));
var remainingDays = sub(remainingMonths, {
months: sign * duration.months
});
duration.days = Math.abs(differenceInDays(remainingDays, dateRight));
var remainingHours = sub(remainingDays, {
days: sign * duration.days
});
duration.hours = Math.abs(differenceInHours(remainingHours, dateRight));
var remainingMinutes = sub(remainingHours, {
hours: sign * duration.hours
});
duration.minutes = Math.abs(differenceInMinutes(remainingMinutes, dateRight));
var remainingSeconds = sub(remainingMinutes, {
minutes: sign * duration.minutes
});
duration.seconds = Math.abs(differenceInSeconds(remainingSeconds, dateRight));
return duration;
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
// interface BackupStatus {
// deviceName: string;
// providers: ProviderInfo[];
// }
// async function getBackupInfoOrdered(): BackupStatus {
// //create a first list of backup info by currency
// const status = await wxApi.getBackupInfo();
// return { deviceName: status.deviceId, providers };
// }
// async function sync() {
// await wxApi.syncAllProviders();
// }
function BackupPage({ onAddProvider }) {
const status = useAsyncAsHook(getBackupInfo);
if (!status) {
return v$1(Loading, null);
}
if (status.hasError) {
return (v$1(LoadingError, { title: v$1(i18n.Translate, null, "Could not load backup providers"), error: status }));
}
const providers = status.response.providers.sort((a, b) => {
if (a.paymentStatus.type === ProviderPaymentType.Paid &&
b.paymentStatus.type === ProviderPaymentType.Paid) {
return getStatusPaidOrder(a.paymentStatus, b.paymentStatus);
}
return (getStatusTypeOrder(a.paymentStatus) - getStatusTypeOrder(b.paymentStatus));
});
return (v$1(BackupView, { providers: providers, onAddProvider: onAddProvider, onSyncAll: syncAllProviders }));
}
function BackupView({ providers, onAddProvider, onSyncAll, }) {
return (v$1(d, null,
v$1("section", null,
providers.map((provider, idx) => (v$1(BackupLayout, { key: idx, status: provider.paymentStatus, timestamp: provider.lastSuccessfulBackupTimestamp, id: provider.syncProviderBaseUrl, active: provider.active, title: provider.name }))),
!providers.length && (v$1(Centered, { style: { marginTop: 100 } },
v$1(BoldLight, null,
v$1(i18n.Translate, null, "No backup providers configured")),
v$1(ButtonSuccess, { onClick: onAddProvider },
v$1(i18n.Translate, null, "Add provider"))))),
!!providers.length && (v$1("footer", null,
v$1("div", null),
v$1("div", null,
v$1(ButtonPrimary, { onClick: onSyncAll }, providers.length > 1 ? (v$1(i18n.Translate, null, "Sync all backups")) : (v$1(i18n.Translate, null, "Sync now"))),
v$1(ButtonSuccess, { onClick: onAddProvider },
v$1(i18n.Translate, null, "Add provider")))))));
}
function BackupLayout(props) {
var _a;
const date = !props.timestamp ? undefined : new Date(props.timestamp.t_ms);
const dateStr = date === null || date === void 0 ? void 0 : date.toLocaleString([], {
dateStyle: "medium",
timeStyle: "short",
});
return (v$1(RowBorderGray, null,
v$1("div", { style: { color: !props.active ? "grey" : undefined } },
v$1("a", { href: Pages.backup_provider_detail.replace(":pid", encodeURIComponent(props.id)) },
v$1("span", null, props.title)),
dateStr && (v$1(SmallText, { style: { marginTop: 5 } },
v$1(i18n.Translate, null, "Last synced"),
": ",
dateStr)),
!dateStr && (v$1(SmallLightText, { style: { marginTop: 5 } },
v$1(i18n.Translate, null, "Not synced")))),
v$1("div", null, ((_a = props.status) === null || _a === void 0 ? void 0 : _a.type) === "paid" ? (v$1(ExpirationText, { until: props.status.paidUntil })) : (v$1("div", null, props.status.type)))));
}
function ExpirationText({ until }) {
return (v$1(d, null,
v$1(CenteredText, null,
v$1(i18n.Translate, null, "Expires in")),
v$1(CenteredBoldText, Object.assign({}, { color: colorByTimeToExpire(until) }),
" ",
daysUntil(until),
" ")));
}
function colorByTimeToExpire(d) {
if (d.t_ms === "never")
return "rgb(28, 184, 65)";
const months = differenceInMonths(d.t_ms, new Date());
return months > 1 ? "rgb(28, 184, 65)" : "rgb(223, 117, 20)";
}
function daysUntil(d) {
if (d.t_ms === "never")
return "";
const duration = intervalToDuration({
start: d.t_ms,
end: new Date(),
});
const str = formatDuration(duration, {
delimiter: ", ",
format: [
(duration === null || duration === void 0 ? void 0 : duration.years)
? "years"
: (duration === null || duration === void 0 ? void 0 : duration.months)
? "months"
: (duration === null || duration === void 0 ? void 0 : duration.days)
? "days"
: duration.hours
? "hours"
: "minutes",
],
});
return `${str}`;
}
function getStatusTypeOrder(t) {
return [
ProviderPaymentType.InsufficientBalance,
ProviderPaymentType.TermsChanged,
ProviderPaymentType.Unpaid,
ProviderPaymentType.Paid,
ProviderPaymentType.Pending,
].indexOf(t.type);
}
function getStatusPaidOrder(a, b) {
return a.paidUntil.t_ms === "never"
? -1
: b.paidUntil.t_ms === "never"
? 1
: a.paidUntil.t_ms - b.paidUntil.t_ms;
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function Time({ timestamp, format: formatString, }) {
return (v$1("time", { dateTime: !timestamp || timestamp.t_ms === "never"
? undefined
: formatISO(timestamp.t_ms) }, !timestamp || timestamp.t_ms === "never"
? "never"
: format(timestamp.t_ms, formatString)));
}
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
function ProviderDetailPage({ pid: providerURL, onBack }) {
function getProviderInfo() {
return __awaiter(this, void 0, void 0, function* () {
//create a first list of backup info by currency
const status = yield getBackupInfo();
const providers = status.providers.filter((p) => p.syncProviderBaseUrl === providerURL);
return providers.length ? providers[0] : null;
});
}
const state = useAsyncAsHook(getProviderInfo);
if (!state) {
return v$1(Loading, null);
}
if (state.hasError) {
return (v$1(LoadingError, { title: v$1(i18n.Translate, null,
"There was an error loading the provider detail for \"",
providerURL,
"\""), error: state }));
}
return (v$1(ProviderView, { url: providerURL, info: state.response, onSync: () => __awaiter(this, void 0, void 0, function* () { return syncOneProvider(providerURL); }), onDelete: () => __awaiter(this, void 0, void 0, function* () { return removeProvider(providerURL).then(onBack); }), onBack: onBack, onExtend: () => {
} }));
}
function ProviderView({ info, url, onDelete, onSync, onBack, onExtend, }) {
if (info === null) {
return (v$1(d, null,
v$1("section", null,
v$1("p", null,
v$1(i18n.Translate, null,
"There is not known provider with url \"",
url,
"\"."))),
v$1("footer", null,
v$1(Button, { onClick: onBack },
"< ",
v$1(i18n.Translate, null, "Back")),
v$1("div", null))));
}
const lb = info.lastSuccessfulBackupTimestamp;
const isPaid = info.paymentStatus.type === ProviderPaymentType.Paid ||
info.paymentStatus.type === ProviderPaymentType.TermsChanged;
return (v$1(d, null,
v$1(Error$1, { info: info }),
v$1("header", null,
v$1("h3", null,
info.name,
" ",
v$1(SmallLightText, null, info.syncProviderBaseUrl)),
v$1(PaymentStatus, { color: isPaid ? "rgb(28, 184, 65)" : "rgb(202, 60, 60)" }, isPaid ? "Paid" : "Unpaid")),
v$1("section", null,
v$1("p", null,
v$1("b", null,
v$1(i18n.Translate, null, "Last backup"),
":"),
" ",
v$1(Time, { timestamp: lb, format: "dd MMMM yyyy" })),
v$1(ButtonPrimary, { onClick: onSync },
v$1(i18n.Translate, null, "Back up")),
info.terms && (v$1(d, null,
v$1("p", null,
v$1("b", null,
v$1(i18n.Translate, null, "Provider fee"),
":"),
" ",
info.terms && info.terms.annualFee,
" ",
v$1(i18n.Translate, null, "per year")))),
v$1("p", null, descriptionByStatus(info.paymentStatus)),
v$1(ButtonPrimary, { disabled: true, onClick: onExtend },
v$1(i18n.Translate, null, "Extend")),
info.paymentStatus.type === ProviderPaymentType.TermsChanged && (v$1("div", null,
v$1("p", null,
v$1(i18n.Translate, null, "terms has changed, extending the service will imply accepting the new terms of service")),
v$1("table", null,
v$1("thead", null,
v$1("tr", null,
v$1("td", null, "\u00A0"),
v$1("td", null,
v$1(i18n.Translate, null, "old")),
v$1("td", null, " ->"),
v$1("td", null,
v$1(i18n.Translate, null, "new")))),
v$1("tbody", null,
v$1("tr", null,
v$1("td", null,
v$1(i18n.Translate, null, "fee")),
v$1("td", null, info.paymentStatus.oldTerms.annualFee),
v$1("td", null, "->"),
v$1("td", null, info.paymentStatus.newTerms.annualFee)),
v$1("tr", null,
v$1("td", null,
v$1(i18n.Translate, null, "storage")),
v$1("td", null, info.paymentStatus.oldTerms.storageLimitInMegabytes),
v$1("td", null, "->"),
v$1("td", null, info.paymentStatus.newTerms.storageLimitInMegabytes))))))),
v$1("footer", null,
v$1(Button, { onClick: onBack },
"< ",
v$1(i18n.Translate, null, "back")),
v$1("div", null,
v$1(ButtonDestructive, { onClick: onDelete },
v$1(i18n.Translate, null, "Remove provider"))))));
}
function Error$1({ info }) {
if (info.lastError) {
return (v$1(ErrorMessage, { title: v$1(i18n.Translate, null, "This provider has reported an error"), description: info.lastError.hint }));
}
if (info.backupProblem) {
switch (info.backupProblem.type) {
case "backup-conflicting-device":
return (v$1(ErrorMessage, { title: v$1(d, null,
v$1(i18n.Translate, null,
"There is conflict with another backup from",
" ",
v$1("b", null, info.backupProblem.otherDeviceId))) }));
case "backup-unreadable":
return (v$1(ErrorMessage, { title: v$1(i18n.Translate, null, "Backup is not readable") }));
default:
return (v$1(ErrorMessage, { title: v$1(d, null,
v$1(i18n.Translate, null,
"Unknown backup problem: ",
JSON.stringify(info.backupProblem))) }));
}
}
return v$1(d, null);
}
function descriptionByStatus(status) {
switch (status.type) {
case ProviderPaymentType.Paid:
case ProviderPaymentType.TermsChanged:
if (status.paidUntil.t_ms === "never") {
return (v$1("span", null,
v$1(i18n.Translate, null, "service paid")));
}
return (v$1(d, null,
v$1("b", null,
v$1(i18n.Translate, null, "Backup valid until"),
":"),
" ",
v$1(Time, { timestamp: status.paidUntil, format: "dd MMM yyyy" })));
case ProviderPaymentType.Unpaid:
case ProviderPaymentType.InsufficientBalance:
case ProviderPaymentType.Pending:
return v$1("span", null);
}
}
/*
This file is part of GNU Taler
(C) 2020 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
function main() {
try {
const container = document.getElementById("container");
if (!container) {
throw Error("container not found, can't mount page contents");
}
S$1(v$1(Application, null), container);
}
catch (e) {
console.error("got error", e);
if (e instanceof Error) {
document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`;
}
}
}
setupI18n("en-US", strings);
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", main);
}
else {
main();
}
function CheckTalerActionComponent() {
const [talerActionUrl] = useTalerActionURL();
y(() => {
if (talerActionUrl)
route(Pages.cta.replace(":action", encodeURIComponent(talerActionUrl)));
}, [talerActionUrl]);
return v$1(d, null);
}
function Application() {
const hash_history = createHashHistory();
return (v$1(TranslationProvider, null,
v$1(DevContextProvider, null, ({ devMode }) => (v$1(IoCProviderForRuntime, null,
v$1(Match_1, null, ({ path }) => v$1(PopupNavBar, { path: path })),
v$1(CheckTalerActionComponent, null),
v$1(PopupBox, { devMode: devMode },
v$1(Router, { history: hash_history },
v$1(Route, { path: Pages.balance, component: BalancePage, goToWalletManualWithdraw: () => route(Pages.balance_manual_withdraw.replace(":currency?", "")), goToWalletDeposit: (currency) => route(Pages.balance_deposit.replace(":currency", currency)), goToWalletHistory: (currency) => route(Pages.balance_history.replace(":currency", currency)) }),
v$1(Route, { path: Pages.cta, component: function Action({ action }) {
const [, setDismissed] = useTalerActionURL();
return (v$1(TalerActionFound, { url: decodeURIComponent(action), onDismiss: () => {
setDismissed(true);
route(Pages.balance);
} }));
} }),
v$1(Route, { path: Pages.backup, component: BackupPage, onAddProvider: () => {
route(Pages.backup_provider_add);
} }),
v$1(Route, { path: Pages.backup_provider_detail, component: ProviderDetailPage, onBack: () => {
route(Pages.backup);
} }),
v$1(Route, { path: Pages.balance_manual_withdraw, component: RedirectToWalletPage }),
v$1(Route, { path: Pages.balance_deposit, component: RedirectToWalletPage }),
v$1(Route, { path: Pages.balance_history, component: RedirectToWalletPage }),
v$1(Route, { path: Pages.backup_provider_add, component: RedirectToWalletPage }),
v$1(Route, { path: Pages.settings, component: RedirectToWalletPage }),
v$1(Route, { path: Pages.settings_exchange_add, component: RedirectToWalletPage }),
v$1(Route, { path: Pages.dev, component: RedirectToWalletPage }),
v$1(Route, { default: true, component: Redirect, to: Pages.balance }))))))));
}
function RedirectToWalletPage() {
const page = document.location.hash || "#/";
y(() => {
chrome.tabs.create({
active: true,
// eslint-disable-next-line no-undef
url: chrome.runtime.getURL(`/static/wallet.html${page}`),
}, () => {
window.close();
});
});
return (v$1("span", null,
v$1(i18n.Translate, null,
"this popup is being closed and you are being redirected to ",
page)));
}
function Redirect({ to }) {
y(() => {
route(to, true);
});
return null;
}
})();
//# sourceMappingURL=popupEntryPoint.js.map
popup/popup_files/popupEntryPoint.css 0000664 0001750 0001750 00000142662 14212136643 020714 0 ustar grothoff grothoff .p8kxxmr{padding:5px;border-radius:5px;color:white;background-color:var(--p8kxxmr-0);}
.w1dd2erw{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;text-align:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:auto;height:100%;}.w1dd2erw h1:first-child{margin-top:0;}.w1dd2erw section{margin-bottom:2em;}.w1dd2erw section button{margin-right:8px;margin-left:8px;}
.w15ac81j{border:solid 5px black;border-radius:10px;margin-left:auto;margin-right:auto;padding-top:2em;max-width:50%;padding:2em;margin:auto;height:100%;}.w15ac81j h1:first-child{margin-top:0;}
.d1jcx3wd{color:gray;margin:0.2em;margin-top:1em;}
.w1bn6ssr{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.w1bn6ssr > *{width:500px;}.w1bn6ssr > section{padding:var(--w1bn6ssr-0);margin-bottom:auto;overflow:auto;}.w1bn6ssr > section table td{padding:5px 5px;}.w1bn6ssr > section table tr{border-bottom:1px solid black;border-top:1px solid black;}.w1bn6ssr > section button{margin-right:8px;margin-left:8px;}.w1bn6ssr > header{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:8px;margin-bottom:5px;}.w1bn6ssr > header > div{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;}.w1bn6ssr > header > h3{margin:0px;}.w1bn6ssr > header > .title{font-size:large;color:#3c4e92;}.w1bn6ssr > footer{padding-top:8px;padding-bottom:8px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#f7f7f7;}.w1bn6ssr > footer button{margin-right:8px;margin-left:8px;}
.m1iqn4js{-webkit-box-pack:space-around;-webkit-justify-content:space-around;-ms-flex-pack:space-around;justify-content:space-around;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:100%;}
.p9s0zpp{height:290px;width:500px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}.p9s0zpp > section{padding:var(--p9s0zpp-0);margin-bottom:auto;overflow-y:auto;}.p9s0zpp > section table td{padding:5px 10px;}.p9s0zpp > section table tr{border-bottom:1px solid black;border-top:1px solid black;}.p9s0zpp > section button{margin-right:8px;margin-left:8px;}.p9s0zpp > section[data-expanded]{height:100%;}.p9s0zpp > section[data-centered]{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.p9s0zpp > header{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:8px;margin-bottom:5px;}.p9s0zpp > header > div{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;}.p9s0zpp > header > h3{margin:0px;}.p9s0zpp > header > .title{font-size:large;color:#3c4e92;}.p9s0zpp > footer{padding-top:8px;padding-bottom:8px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.p9s0zpp > footer button{margin-right:8px;margin-left:8px;}
.tklbasy{border-collapse:separate;border-spacing:0px 10px;margin-top:-10px;}.tklbasy td{border:solid 1px #000;border-style:solid none;padding:10px;}.tklbasy td:first-child{border-left-style:solid;border-top-left-radius:5px;border-bottom-left-radius:5px;}.tklbasy td:last-child{border-right-style:solid;border-bottom-right-radius:5px;border-top-right-radius:5px;}
.t4xg52x{display:block;position:relative;}.t4xg52x::before{position:absolute;z-index:1000001;width:0;height:0;color:darkgray;pointer-events:none;content:"";border:6px solid transparent;border-bottom-color:darkgray;}.t4xg52x::after{position:absolute;z-index:1000001;padding:0.5em 0.75em;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI", Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";-webkit-font-smoothing:subpixel-antialiased;color:white;text-align:center;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;text-transform:none;-webkit-letter-spacing:normal;-moz-letter-spacing:normal;-ms-letter-spacing:normal;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(content);background:darkgray;border-radius:6px;}
.t66q533.t4xg52x::before{top:auto;right:50%;bottom:-7px;margin-right:-6px;}.t66q533.t4xg52x::after{top:100%;right:-50%;margin-top:6px;}
.t1mesvkz.t4xg52x::before{top:0px;left:16px;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);}.t1mesvkz.t4xg52x::after{top:-50%;left:28px;margin-top:6px;}
.okr2v81{position:fixed;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2;cursor:pointer;}
.nxtbw4g{border:2px solid red;-webkit-transition:all 0.4s ease-out;transition:all 0.4s ease-out;-webkit-animation:fadeout-nxtbw4g 1s forwards;animation:fadeout-nxtbw4g 1s forwards;-webkit-animation-delay:0.1s;animation-delay:0.1s;}@-webkit-keyframes fadeout-nxtbw4g{to{border-color:#f5f5f5;}}@keyframes fadeout-nxtbw4g{to{border-color:#f5f5f5;}}
.c1yesuww{position:absolute;text-align:left;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;top:50%;left:50%;color:black;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);cursor:initial;background-color:white;border-radius:10px;max-height:70%;}.c1yesuww > header{border-top-right-radius:6px;border-top-left-radius:6px;padding:10px;background-color:#f5f5f5;border-bottom:1px solid #dbdbdb;font-weight:bold;}.c1yesuww > section{padding:10px;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;overflow:auto;}.c1yesuww > footer{border-top:1px solid #dbdbdb;border-bottom-right-radius:6px;border-bottom-left-radius:6px;padding:10px;background-color:#f5f5f5;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}
.bmxsa5t{display:inline-block;line-height:normal;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;text-transform:var(--bmxsa5t-0);font-family:inherit;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:1px solid #999;background-color:"#e6e6e6";-webkit-text-decoration:none;text-decoration:none;border-radius:2px;text-transform:uppercase;}.bmxsa5t:focus{outline:0;}.bmxsa5t:disabled{border:none;background-image:none;-webkit-filter:alpha(opacity=40);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none;pointer-events:none;}.bmxsa5t:hover{-webkit-filter:alpha(opacity=80);filter:alpha(opacity=80);background-image:linear-gradient( transparent, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.2) );}
.lz4m0ui{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;text-transform:var(--lz4m0ui-0);font-family:inherit;font-size:100%;padding:0.5em 1em;background-color:transparent;-webkit-text-decoration:none;text-decoration:none;}.lz4m0ui:focus{outline:0;}.lz4m0ui:disabled{border:none;background-image:none;-webkit-filter:alpha(opacity=40);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none;pointer-events:none;}.lz4m0ui:hover{-webkit-text-decoration:underline;text-decoration:underline;}
.f1e1j1v5{font-family:monospace;font-size:x-large;text-align:center;font-weight:bold;}
.boxc317.bmxsa5t{padding:8px;background-color:#f7f7f7;border:1px solid;border-radius:4px;border-color:black;color:black;}.boxc317.bmxsa5t > .f1e1j1v5{width:1em;height:1em;display:inline;line-height:0px;}
.b1cqzri0.bmxsa5t{color:white;border-radius:4px;text-shadow:0 1px 1px rgba(0,0,0,0.2);}
.l1lz3jip.lz4m0ui{background-color:rgb(202,60,60);}
.l67je3i.lz4m0ui{color:rgb(66,184,221);}
.b15xqgyz.b1cqzri0.bmxsa5t{font-size:var(--b15xqgyz-0);background-color:#0042b2;border-color:#0042b2;}
.b1o8pbk0.boxc317.bmxsa5t{color:#0042b2;border-color:#0042b2;}
.b12bvjx5.b1cqzri0.bmxsa5t{background-color:#388e3c;}
.l10qh7bz.lz4m0ui{color:#388e3c;}
.b10b74cx.boxc317.bmxsa5t{color:#388e3c;border-color:#388e3c;}
.b19q5gs8.b1cqzri0.bmxsa5t{background-color:rgb(223,117,20);}
.l5peldw.lz4m0ui{color:rgb(223,117,20);}
.b13r71ri.boxc317.bmxsa5t{color:rgb(223,117,20);border-color:rgb(223,117,20);}
.b1rfnbo.b1cqzri0.bmxsa5t{background-color:rgb(202,60,60);}
.bfc1ne6.boxc317.bmxsa5t{color:rgb(202,60,60);border-color:rgb(202,60,60);}
.bly3p82{color:gray;font-weight:bold;}
.c1t1aglz{text-align:center;}.c1t1aglz > :not(:first-child){margin-top:15px;}
.r1no9mkk{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0.5em 0;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:0.5em;}
.r1rj9wn8{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:0.5em;}
.ckqh4cs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin:0em 1em;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}
.rfg5y6x.r1no9mkk{border:1px solid gray;}
.rs33xdb.r1rj9wn8{border:1px solid lightgray;border-top:0px;}.d1jcx3wd + .rs33xdb.r1rj9wn8{border:1px solid lightgray;background-color:red;}
.hdvap33{-webkit-text-decoration:none;text-decoration:none;color:#212121;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:0.5em;border:1px solid lightgray;border-top:0px;}.d1jcx3wd + .hdvap33{border:1px solid lightgray;}.hdvap33:hover{background-color:lightgray;}.hdvap33 > .ckqh4cs:last-of-type{margin-left:auto;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;}
.lbgvqlh > div > a > img{max-width:100%;display:inline-block;width:32px;height:32px;}.lbgvqlh > div > div{margin-right:auto;margin-left:1em;}
.lyqngaf{color:gray;}
.s1b867xx{color:#388e3c;}
.dv1hymk{color:rgb(202,60,60);}
.w1vnutle{color:rgb(223,117,20);}
.sywvifb{font-size:small;}
.l1ogslqd{font-size:large;}
.e1f15u4h{font-size:x-large;}
.s12qexhk.sywvifb{color:gray;}
.c1f8kx9d{white-space:nowrap;text-align:center;}
.c1umffj2.c1f8kx9d{white-space:nowrap;text-align:center;font-weight:bold;color:var(--c1umffj2-0);}
.i1bml4i9 label{display:block;padding:5px;color:var(--i1bml4i9-0);}.i1bml4i9 input{display:block;padding:5px;width:calc(100% - 4px - 10px);border-color:var(--i1bml4i9-0);}
.i1k2hu52{margin-bottom:16px;}.i1k2hu52 label{display:block;font-weight:bold;margin-left:0.5em;padding:5px;color:var(--i1k2hu52-0);}.i1k2hu52 div{line-height:24px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.i1k2hu52 div > span{background-color:lightgray;box-sizing:border-box;border-bottom-left-radius:0.25em;border-top-left-radius:0.25em;height:2em;display:inline-block;padding-left:0.5em;padding-right:0.5em;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.i1k2hu52 input{border-width:1px;box-sizing:border-box;height:2em;border-bottom-right-radius:0.25em;border-top-right-radius:0.25em;border-color:var(--i1k2hu52-1);}
.e118sxth{color:red;}
.e9bmv5f{border:2px solid #f5c6cb;border-radius:0.25em;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:1em;margin:1em;color:#721c24;background:#f8d7da;}.e9bmv5f > div{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}.e9bmv5f > div > button{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;font-size:100%;padding:0;height:28px;width:28px;}
.i1pn3jqt.e9bmv5f{color:black;background-color:#d1e7dd;border-color:#badbcc;}
.sgqgedv.e9bmv5f{color:#0f5132;background-color:#d1e7dd;border-color:#badbcc;}
.w1av4lor.e9bmv5f{color:#664d03;background-color:#fff3cd;border-color:#ffecb5;}
.n1crewby{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#0042b2;}
.nvdsr6i{background-color:#0042b2;height:35px;-webkit-box-pack:space-around;-webkit-justify-content:space-around;-ms-flex-pack:space-around;justify-content:space-around;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.nvdsr6i{width:500px;}.nvdsr6i > a{color:#f8faf7;display:inline-block;width:100%;text-align:center;-webkit-text-decoration:none;text-decoration:none;vertical-align:middle;line-height:35px;}.nvdsr6i > a > div.settings-icon{-webkit-mask:url(../../../static/img/settings_black_24dp.svg) no-repeat center;mask:url(../../../static/img/settings_black_24dp.svg) no-repeat center;background-color:white;width:24px;height:24px;margin-left:auto;margin-right:8px;padding:4px;}.nvdsr6i > a.active{background-color:#f8faf7;color:#0042b2;font-weight:bold;}.nvdsr6i > a.active > div.settings-icon{background-color:#0042b2;}
.n1yi0qs5{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow:hidden;border-radius:0.25em;}.n1yi0qs5 > select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:0;box-shadow:none;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");background-position:right 4px center;background-repeat:no-repeat;background-size:32px 32px;background-color:white;border-radius:0.25rem;font-size:1em;padding:8px 32px 8px 8px;cursor:pointer;}
.osudf5q{border:2px solid #388e3c;padding:0.5em 1em;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;border-radius:2px;color:#388e3c;}
.c1ip8lai{vertical-align:center;}
.t1jzgljv{border:1px solid black;border-radius:5px;padding:1em;margin-top:2px;margin-bottom:2px;-webkit-text-decoration:none;text-decoration:none;color:inherit;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.t1jzgljv[data-open="true"]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.t1jzgljv[data-open="false"] > *:not(:first-child){display:none;}.t1jzgljv header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-weight:bold;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:auto;}.t1jzgljv[data-open="true"] header:after{content:"\2227";}.t1jzgljv[data-open="false"] header:after{content:"\2228";}
.t1eqvnzi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;text-align:left;max-width:500px;}.t1eqvnzi > header{text-align:center;font-size:2em;}.t1eqvnzi a{-webkit-text-decoration:none;text-decoration:none;color:inherit;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.t1eqvnzi > a{border:1px solid black;border-radius:5px;padding:1em;margin-top:2px;margin-bottom:2px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.t1eqvnzi > a[data-open="true"]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.t1eqvnzi > a[data-open="false"] > *:not(:first-child){display:none;}.t1eqvnzi > a header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-weight:bold;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:auto;}.t1eqvnzi > a[data-open="true"] > header:after{content:"\2227";}.t1eqvnzi > a[data-open="false"] > header:after{content:"\2228";}
.s144sjcr{color:green;text-transform:uppercase;text-align:center;cursor:pointer;}.s144sjcr span input{display:none;opacity:0;width:1em;height:1em;cursor:pointer;}.s144sjcr span div{display:inline-grid;width:1em;height:1em;margin-right:1em;border-radius:2px;border:2px solid currentColor;}.s144sjcr span div svg{-webkit-transition:-webkit-transform 0.1s ease-in 25ms;-webkit-transition:transform 0.1s ease-in 25ms;transition:transform 0.1s ease-in 25ms;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:bottom left;-ms-transform-origin:bottom left;transform-origin:bottom left;}.s144sjcr span label{padding:0px;font-size:small;cursor:pointer;}.s144sjcr input:checked + div svg{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);}.s144sjcr input:disabled + div{color:#959495;}.s144sjcr input:disabled + div + label{color:#959495;}.s144sjcr input:focus + div + label{box-shadow:0 0 0 0.05em #fff,0 0 0.15em 0.1em currentColor;}
.p1k66yn8{cursor:pointer;margin:0px;padding:8px 16px;}.p1k66yn8:hover{-webkit-filter:alpha(opacity=80);filter:alpha(opacity=80);background-image:linear-gradient( transparent, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.2) );}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2RvbGQvcmVwb3MvdGFsZXIvd2FsbGV0LWNvcmUvcGFja2FnZXMvdGFsZXItd2FsbGV0LXdlYmV4dGVuc2lvbi9zcmMvY29tcG9uZW50cy9zdHlsZWQvaW5kZXgudHN4Il0sIm5hbWVzIjpbIi5wOGt4eG1yIiwiLncxZGQyZXJ3IiwiLncxNWFjODFqIiwiLmQxamN4M3dkIiwiLncxYm42c3NyIiwiLm0xaXFuNGpzIiwiLnA5czB6cHAiLCIudGtsYmFzeSIsIi50NHhnNTJ4IiwiLnQ2NnE1MzMudDR4ZzUyeCIsIi50MW1lc3Zrei50NHhnNTJ4IiwiLm9rcjJ2ODEiLCIubnh0Ync0ZyIsIi5jMXllc3V3dyIsIi5ibXhzYTV0IiwiLmx6NG0wdWkiLCIuZjFlMWoxdjUiLCIuYm94YzMxNy5ibXhzYTV0IiwiLmIxY3F6cmkwLmJteHNhNXQiLCIubDFsejNqaXAubHo0bTB1aSIsIi5sNjdqZTNpLmx6NG0wdWkiLCIuYjE1eHFneXouYjFjcXpyaTAuYm14c2E1dCIsIi5iMW84cGJrMC5ib3hjMzE3LmJteHNhNXQiLCIuYjEyYnZqeDUuYjFjcXpyaTAuYm14c2E1dCIsIi5sMTBxaDdiei5sejRtMHVpIiwiLmIxMGI3NGN4LmJveGMzMTcuYm14c2E1dCIsIi5iMTlxNWdzOC5iMWNxenJpMC5ibXhzYTV0IiwiLmw1cGVsZHcubHo0bTB1aSIsIi5iMTNyNzFyaS5ib3hjMzE3LmJteHNhNXQiLCIuYjFyZm5iby5iMWNxenJpMC5ibXhzYTV0IiwiLmJmYzFuZTYuYm94YzMxNy5ibXhzYTV0IiwiLmJseTNwODIiLCIuYzF0MWFnbHoiLCIucjFubzlta2siLCIucjFyajl3bjgiLCIuY2txaDRjcyIsIi5yZmc1eTZ4LnIxbm85bWtrIiwiLnJzMzN4ZGIucjFyajl3bjgiLCIuaGR2YXAzMyIsIi5sYmd2cWxoIiwiLmx5cW5nYWYiLCIuczFiODY3eHgiLCIuZHYxaHltayIsIi53MXZudXRsZSIsIi5zeXd2aWZiIiwiLmwxb2dzbHFkIiwiLmUxZjE1dTRoIiwiLnMxMnFleGhrLnN5d3ZpZmIiLCIuYzFmOGt4OWQiLCIuYzF1bWZmajIuYzFmOGt4OWQiLCIuaTFibWw0aTkiLCIuaTFrMmh1NTIiLCIuZTExOHN4dGgiLCIuZTlibXY1ZiIsIi5pMXBuM2pxdC5lOWJtdjVmIiwiLnNncWdlZHYuZTlibXY1ZiIsIi53MWF2NGxvci5lOWJtdjVmIiwiLm4xY3Jld2J5IiwiLm52ZHNyNmkiLCIubjF5aTBxczUiLCIub3N1ZGY1cSIsIi5jMWlwOGxhaSIsIi50MWp6Z2xqdiIsIi50MWVxdm56aSIsIi5zMTQ0c2pjciIsIi5wMWs2NnluOCJdLCJtYXBwaW5ncyI6IkFBZ0JhQTtBQU1BQztBQXFCQUM7QUFnQkFDO0FBS0FDO0FBOERBQztBQU1BQztBQXNFQUM7QUFxQlBDO0FBc0NPQztBQWFBQztBQVlBQztBQVlBQztBQVdBQztBQTRDQUM7QUFpREFDO0FBNENBQztBQU9BQztBQW9CUEM7QUFLT0M7QUFHQUM7QUFHQUM7QUFLQUM7QUFJQUM7QUFHQUM7QUFHQUM7QUFJQUM7QUFHQUM7QUFHQUM7QUFJQUM7QUFHQUM7QUFJQUM7QUFJQUM7QUFNQUM7QUFNQUM7QUFNQUM7QUFNQUM7QUFJQUM7QUFTQUM7QUF3QkFDO0FBYUFDO0FBR0FDO0FBR0FDO0FBR0FDO0FBR0FDO0FBR0FDO0FBR0FDO0FBR0FDO0FBR0FDO0FBSUFDO0FBTUFDO0FBYUFDO0FBc0NBQztBQUdBQztBQTBCQUM7QUFLQUM7QUFLQUM7QUFNQUM7QUFPQUM7QUF1Q0FDO0FBNkJBQztBQVFBQztBQUdBQztBQWlDQUM7QUFnREFDO0FBZ0RBQyIsImZpbGUiOiIvaG9tZS9kb2xkL3JlcG9zL3RhbGVyL3dhbGxldC1jb3JlL3BhY2thZ2VzL3RhbGVyLXdhbGxldC13ZWJleHRlbnNpb24vc3JjL2NvbXBvbmVudHMvc3R5bGVkL2luZGV4LnRzeCIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gVGhpcyBmaWxlIGlzIHBhcnQgb2YgR05VIFRhbGVyXG4gKEMpIDIwMjEgVGFsZXIgU3lzdGVtcyBTLkEuXG5cbiBHTlUgVGFsZXIgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdCB1bmRlciB0aGVcbiB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlXG4gRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMywgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cblxuIEdOVSBUYWxlciBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTllcbiBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUlxuIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuXG4gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcgd2l0aFxuIEdOVSBUYWxlcjsgc2VlIHRoZSBmaWxlIENPUFlJTkcuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz5cbiAqL1xuaW1wb3J0IHsgc3R5bGVkIH0gZnJvbSBcIkBsaW5hcmlhL3JlYWN0XCI7XG5leHBvcnQgY29uc3QgUGF5bWVudFN0YXR1cyA9IHN0eWxlZC5kaXYgYFxuICBwYWRkaW5nOiA1cHg7XG4gIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgY29sb3I6IHdoaXRlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkeyhwKSA9PiBwLmNvbG9yfTtcbmA7XG5leHBvcnQgY29uc3QgV2FsbGV0QWN0aW9uID0gc3R5bGVkLmRpdiBgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuXG4gIG1hcmdpbjogYXV0bztcbiAgaGVpZ2h0OiAxMDAlO1xuXG4gICYgaDE6Zmlyc3QtY2hpbGQge1xuICAgIG1hcmdpbi10b3A6IDA7XG4gIH1cbiAgc2VjdGlvbiB7XG4gICAgbWFyZ2luLWJvdHRvbTogMmVtO1xuICAgIGJ1dHRvbiB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbiAgICAgIG1hcmdpbi1sZWZ0OiA4cHg7XG4gICAgfVxuICB9XG5gO1xuZXhwb3J0IGNvbnN0IFdhbGxldEFjdGlvbk9sZCA9IHN0eWxlZC5zZWN0aW9uIGBcbiAgYm9yZGVyOiBzb2xpZCA1cHggYmxhY2s7XG4gIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gIG1hcmdpbi1sZWZ0OiBhdXRvO1xuICBtYXJnaW4tcmlnaHQ6IGF1dG87XG4gIHBhZGRpbmctdG9wOiAyZW07XG4gIG1heC13aWR0aDogNTAlO1xuICBwYWRkaW5nOiAyZW07XG5cbiAgbWFyZ2luOiBhdXRvO1xuICBoZWlnaHQ6IDEwMCU7XG5cbiAgJiBoMTpmaXJzdC1jaGlsZCB7XG4gICAgbWFyZ2luLXRvcDogMDtcbiAgfVxuYDtcbmV4cG9ydCBjb25zdCBEYXRlU2VwYXJhdG9yID0gc3R5bGVkLmRpdiBgXG4gIGNvbG9yOiBncmF5O1xuICBtYXJnaW46IDAuMmVtO1xuICBtYXJnaW4tdG9wOiAxZW07XG5gO1xuZXhwb3J0IGNvbnN0IFdhbGxldEJveCA9IHN0eWxlZC5kaXYgYFxuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICYgPiAqIHtcbiAgICB3aWR0aDogNTAwcHg7XG4gIH1cbiAgJiA+IHNlY3Rpb24ge1xuICAgIHBhZGRpbmc6ICR7KHsgbm9QYWRkaW5nIH0pID0+IChub1BhZGRpbmcgPyBcIjBweFwiIDogXCI4cHhcIil9O1xuXG4gICAgbWFyZ2luLWJvdHRvbTogYXV0bztcbiAgICBvdmVyZmxvdzogYXV0bztcblxuICAgIHRhYmxlIHRkIHtcbiAgICAgIHBhZGRpbmc6IDVweCA1cHg7XG4gICAgfVxuICAgIHRhYmxlIHRyIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBibGFjaztcbiAgICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCBibGFjaztcbiAgICB9XG4gICAgYnV0dG9uIHtcbiAgICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICB9XG4gIH1cblxuICAmID4gaGVhZGVyIHtcbiAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIHBhZGRpbmc6IDhweDtcbiAgICBtYXJnaW4tYm90dG9tOiA1cHg7XG5cbiAgICAmID4gZGl2IHtcbiAgICAgIGFsaWduLXNlbGY6IGNlbnRlcjtcbiAgICB9XG5cbiAgICAmID4gaDMge1xuICAgICAgbWFyZ2luOiAwcHg7XG4gICAgfVxuXG4gICAgJiA+IC50aXRsZSB7XG4gICAgICAvKiBtYXJnaW46IDFlbTsgKi9cbiAgICAgIGZvbnQtc2l6ZTogbGFyZ2U7XG4gICAgICBjb2xvcjogIzNjNGU5MjtcbiAgICB9XG4gIH1cblxuICAmID4gZm9vdGVyIHtcbiAgICBwYWRkaW5nLXRvcDogOHB4O1xuICAgIHBhZGRpbmctYm90dG9tOiA4cHg7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3O1xuICAgIGJ1dHRvbiB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbiAgICAgIG1hcmdpbi1sZWZ0OiA4cHg7XG4gICAgfVxuICB9XG5gO1xuZXhwb3J0IGNvbnN0IE1pZGRsZSA9IHN0eWxlZC5kaXYgYFxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgaGVpZ2h0OiAxMDAlO1xuYDtcbmV4cG9ydCBjb25zdCBQb3B1cEJveCA9IHN0eWxlZC5kaXYgYFxuICBoZWlnaHQ6IDI5MHB4O1xuICB3aWR0aDogNTAwcHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcblxuICAmID4gc2VjdGlvbiB7XG4gICAgcGFkZGluZzogJHsoeyBub1BhZGRpbmcgfSkgPT4gKG5vUGFkZGluZyA/IFwiMHB4XCIgOiBcIjhweFwiKX07XG4gICAgLy8gdGhpcyBtYXJnaW4gd2lsbCBzZW5kIHRoZSBzZWN0aW9uIHVwIHdoZW4gdXNlZCB3aXRoIGEgaGVhZGVyXG4gICAgbWFyZ2luLWJvdHRvbTogYXV0bztcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xuXG4gICAgdGFibGUgdGQge1xuICAgICAgcGFkZGluZzogNXB4IDEwcHg7XG4gICAgfVxuICAgIHRhYmxlIHRyIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBibGFjaztcbiAgICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCBibGFjaztcbiAgICB9XG4gICAgYnV0dG9uIHtcbiAgICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICB9XG4gIH1cblxuICAmID4gc2VjdGlvbltkYXRhLWV4cGFuZGVkXSB7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICB9XG5cbiAgJiA+IHNlY3Rpb25bZGF0YS1jZW50ZXJlZF0ge1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgLyogZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgKi9cbiAgfVxuXG4gICYgPiBoZWFkZXIge1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgcGFkZGluZzogOHB4O1xuICAgIG1hcmdpbi1ib3R0b206IDVweDtcblxuICAgICYgPiBkaXYge1xuICAgICAgYWxpZ24tc2VsZjogY2VudGVyO1xuICAgIH1cblxuICAgICYgPiBoMyB7XG4gICAgICBtYXJnaW46IDBweDtcbiAgICB9XG5cbiAgICAmID4gLnRpdGxlIHtcbiAgICAgIC8qIG1hcmdpbjogMWVtOyAqL1xuICAgICAgZm9udC1zaXplOiBsYXJnZTtcbiAgICAgIGNvbG9yOiAjM2M0ZTkyO1xuICAgIH1cbiAgfVxuXG4gICYgPiBmb290ZXIge1xuICAgIHBhZGRpbmctdG9wOiA4cHg7XG4gICAgcGFkZGluZy1ib3R0b206IDhweDtcbiAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGJ1dHRvbiB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbiAgICAgIG1hcmdpbi1sZWZ0OiA4cHg7XG4gICAgfVxuICB9XG5gO1xuZXhwb3J0IGNvbnN0IFRhYmxlV2l0aFJvdW5kUm93cyA9IHN0eWxlZC50YWJsZSBgXG4gIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7XG4gIGJvcmRlci1zcGFjaW5nOiAwcHggMTBweDtcbiAgbWFyZ2luLXRvcDogLTEwcHg7XG5cbiAgdGQge1xuICAgIGJvcmRlcjogc29saWQgMXB4ICMwMDA7XG4gICAgYm9yZGVyLXN0eWxlOiBzb2xpZCBub25lO1xuICAgIHBhZGRpbmc6IDEwcHg7XG4gIH1cbiAgdGQ6Zmlyc3QtY2hpbGQge1xuICAgIGJvcmRlci1sZWZ0LXN0eWxlOiBzb2xpZDtcbiAgICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiA1cHg7XG4gICAgYm9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1czogNXB4O1xuICB9XG4gIHRkOmxhc3QtY2hpbGQge1xuICAgIGJvcmRlci1yaWdodC1zdHlsZTogc29saWQ7XG4gICAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IDVweDtcbiAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogNXB4O1xuICB9XG5gO1xuY29uc3QgVG9vbHRpcCA9IHN0eWxlZC5kaXYgYFxuICBkaXNwbGF5OiBibG9jaztcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gIDo6YmVmb3JlIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgei1pbmRleDogMTAwMDAwMTtcbiAgICB3aWR0aDogMDtcbiAgICBoZWlnaHQ6IDA7XG4gICAgY29sb3I6IGRhcmtncmF5O1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIGNvbnRlbnQ6IFwiXCI7XG4gICAgYm9yZGVyOiA2cHggc29saWQgdHJhbnNwYXJlbnQ7XG5cbiAgICBib3JkZXItYm90dG9tLWNvbG9yOiBkYXJrZ3JheTtcbiAgfVxuXG4gIDo6YWZ0ZXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB6LWluZGV4OiAxMDAwMDAxO1xuICAgIHBhZGRpbmc6IDAuNWVtIDAuNzVlbTtcbiAgICBmb250OiBub3JtYWwgbm9ybWFsIDExcHgvMS41IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgXCJTZWdvZSBVSVwiLFxuICAgICAgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZiwgXCJBcHBsZSBDb2xvciBFbW9qaVwiLCBcIlNlZ29lIFVJIEVtb2ppXCI7XG4gICAgLXdlYmtpdC1mb250LXNtb290aGluZzogc3VicGl4ZWwtYW50aWFsaWFzZWQ7XG4gICAgY29sb3I6IHdoaXRlO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgdGV4dC1zaGFkb3c6IG5vbmU7XG4gICAgdGV4dC10cmFuc2Zvcm06IG5vbmU7XG4gICAgbGV0dGVyLXNwYWNpbmc6IG5vcm1hbDtcbiAgICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7XG4gICAgd2hpdGUtc3BhY2U6IHByZTtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICBjb250ZW50OiBhdHRyKGNvbnRlbnQpO1xuICAgIGJhY2tncm91bmQ6IGRhcmtncmF5O1xuICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgfVxuYDtcbmV4cG9ydCBjb25zdCBUb29sdGlwQm90dG9tID0gc3R5bGVkKFRvb2x0aXApIGBcbiAgOjpiZWZvcmUge1xuICAgIHRvcDogYXV0bztcbiAgICByaWdodDogNTAlO1xuICAgIGJvdHRvbTogLTdweDtcbiAgICBtYXJnaW4tcmlnaHQ6IC02cHg7XG4gIH1cbiAgOjphZnRlciB7XG4gICAgdG9wOiAxMDAlO1xuICAgIHJpZ2h0OiAtNTAlO1xuICAgIG1hcmdpbi10b3A6IDZweDtcbiAgfVxuYDtcbmV4cG9ydCBjb25zdCBUb29sdGlwUmlnaHQgPSBzdHlsZWQoVG9vbHRpcCkgYFxuICA6OmJlZm9yZSB7XG4gICAgdG9wOiAwcHg7XG4gICAgbGVmdDogMTZweDtcbiAgICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpO1xuICB9XG4gIDo6YWZ0ZXIge1xuICAgIHRvcDogLTUwJTtcbiAgICBsZWZ0OiAyOHB4O1xuICAgIG1hcmdpbi10b3A6IDZweDtcbiAgfVxuYDtcbmV4cG9ydCBjb25zdCBPdmVybGF5ID0gc3R5bGVkLmRpdiBgXG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICByaWdodDogMDtcbiAgYm90dG9tOiAwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNSk7XG4gIHotaW5kZXg6IDI7XG4gIGN1cnNvcjogcG9pbnRlcjtcbmA7XG5leHBvcnQgY29uc3QgTm90aWZ5VXBkYXRlRmFkZU91dCA9IHN0eWxlZC5kaXYgYFxuICBib3JkZXI6IDJweCBzb2xpZCByZWQ7XG4gIHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2Utb3V0O1xuICBhbmltYXRpb246IGZhZGVvdXQgMXMgZm9yd2FyZHM7XG4gIGFuaW1hdGlvbi1kZWxheTogMC4xcztcbiAgQGtleWZyYW1lcyBmYWRlb3V0IHtcbiAgICB0byB7XG4gICAgICBib3JkZXItY29sb3I6ICNmNWY1ZjU7XG4gICAgfVxuICB9XG5gO1xuZXhwb3J0IGNvbnN0IENlbnRlcmVkRGlhbG9nID0gc3R5bGVkLmRpdiBgXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdGV4dC1hbGlnbjogbGVmdDtcblxuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG5cbiAgdG9wOiA1MCU7XG4gIGxlZnQ6IDUwJTtcbiAgLyogZm9udC1zaXplOiA1MHB4OyAqL1xuICBjb2xvcjogYmxhY2s7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xuICAtbXMtdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gIGN1cnNvcjogaW5pdGlhbDtcbiAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG4gIGJvcmRlci1yYWRpdXM6IDEwcHg7XG5cbiAgbWF4LWhlaWdodDogNzAlO1xuXG4gICYgPiBoZWFkZXIge1xuICAgIGJvcmRlci10b3AtcmlnaHQtcmFkaXVzOiA2cHg7XG4gICAgYm9yZGVyLXRvcC1sZWZ0LXJhZGl1czogNnB4O1xuICAgIHBhZGRpbmc6IDEwcHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjVmNTtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RiZGJkYjtcbiAgICBmb250LXdlaWdodDogYm9sZDtcbiAgfVxuICAmID4gc2VjdGlvbiB7XG4gICAgcGFkZGluZzogMTBweDtcbiAgICBmbGV4LWdyb3c6IDE7XG4gICAgZmxleC1zaHJpbms6IDE7XG4gICAgb3ZlcmZsb3c6IGF1dG87XG4gIH1cbiAgJiA+IGZvb3RlciB7XG4gICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNkYmRiZGI7XG4gICAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IDZweDtcbiAgICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiA2cHg7XG4gICAgcGFkZGluZzogMTBweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjVmNWY1O1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICB9XG5gO1xuZXhwb3J0IGNvbnN0IEJ1dHRvbiA9IHN0eWxlZC5idXR0b24gYFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIC8qIHpvb206IDE7ICovXG4gIGxpbmUtaGVpZ2h0OiBub3JtYWw7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7IC8vY2hlY2sgdGhpc1xuICAvKiB0ZXh0LWFsaWduOiBjZW50ZXI7ICovXG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIHRleHQtdHJhbnNmb3JtOiAkeyh7IHVwcGVyQ2FzZWQgfSkgPT4gKHVwcGVyQ2FzZWQgPyBcInVwcGVyY2FzZVwiIDogXCJub25lXCIpfTtcblxuICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxMDAlO1xuICBwYWRkaW5nOiAwLjVlbSAxZW07XG4gIC8qIGNvbG9yOiAjNDQ0OyByZ2JhIG5vdCBzdXBwb3J0ZWQgKElFIDgpICovXG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuOCk7IC8qIHJnYmEgc3VwcG9ydGVkICovXG4gIGJvcmRlcjogMXB4IHNvbGlkICM5OTk7IC8qSUUgNi83LzgqL1xuICAvKiBib3JkZXI6IG5vbmUgcmdiYSgwLCAwLCAwLCAwKTsgSUU5ICsgZXZlcnl0aGluZyBlbHNlICovXG4gIGJhY2tncm91bmQtY29sb3I6IFwiI2U2ZTZlNlwiO1xuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcblxuICA6Zm9jdXMge1xuICAgIG91dGxpbmU6IDA7XG4gIH1cblxuICAmOmRpc2FibGVkIHtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogbm9uZTtcbiAgICAvKiBjc3NsaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGZpbHRlcjogYWxwaGEob3BhY2l0eT00MCk7XG4gICAgLyogY3NzbGludCBpZ25vcmU6ZW5kICovXG4gICAgb3BhY2l0eTogMC40O1xuICAgIGN1cnNvcjogbm90LWFsbG93ZWQ7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgfVxuXG4gIDpob3ZlciB7XG4gICAgZmlsdGVyOiBhbHBoYShvcGFjaXR5PTgwKTtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQoXG4gICAgICB0cmFuc3BhcmVudCxcbiAgICAgIHJnYmEoMCwgMCwgMCwgMC4xKSA0MCUsXG4gICAgICByZ2JhKDAsIDAsIDAsIDAuMilcbiAgICApO1xuICB9XG5gO1xuZXhwb3J0IGNvbnN0IExpbmsgPSBzdHlsZWQuYSBgXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgem9vbTogMTtcbiAgbGluZS1oZWlnaHQ6IG5vcm1hbDtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgLyogdmVydGljYWwtYWxpZ246IG1pZGRsZTsgKi9cbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHVzZXItc2VsZWN0OiBub25lO1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB0ZXh0LXRyYW5zZm9ybTogJHsoeyB1cHBlckNhc2VkIH0pID0+ICh1cHBlckNhc2VkID8gXCJ1cHBlcmNhc2VcIiA6IFwibm9uZVwiKX07XG5cbiAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTAwJTtcbiAgcGFkZGluZzogMC41ZW0gMWVtO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuXG4gIDpmb2N1cyB7XG4gICAgb3V0bGluZTogMDtcbiAgfVxuXG4gICY6ZGlzYWJsZWQge1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiBub25lO1xuICAgIC8qIGNzc2xpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgZmlsdGVyOiBhbHBoYShvcGFjaXR5PTQwKTtcbiAgICAvKiBjc3NsaW50IGlnbm9yZTplbmQgKi9cbiAgICBvcGFjaXR5OiAwLjQ7XG4gICAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICB9XG5cbiAgOmhvdmVyIHtcbiAgICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTtcbiAgICAvKiBmaWx0ZXI6IGFscGhhKG9wYWNpdHk9OTApO1xuICAgIGJhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudChcbiAgICAgIHRyYW5zcGFyZW50LFxuICAgICAgcmdiYSgwLCAwLCAwLCAwLjA1KSA0MCUsXG4gICAgICByZ2JhKDAsIDAsIDAsIDAuMSlcbiAgICApOyAqL1xuICB9XG5gO1xuZXhwb3J0IGNvbnN0IEZvbnRJY29uID0gc3R5bGVkLmRpdiBgXG4gIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7XG4gIGZvbnQtc2l6ZTogeC1sYXJnZTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LXdlaWdodDogYm9sZDtcbiAgLyogdmVydGljYWwtYWxpZ246IHRleHQtdG9wOyAqL1xuYDtcbmV4cG9ydCBjb25zdCBCdXR0b25Cb3ggPSBzdHlsZWQoQnV0dG9uKSBgXG4gIHBhZGRpbmc6IDhweDtcbiAgLyogZm9udC1zaXplOiBzbWFsbDsgKi9cblxuICAmID4gJHtGb250SWNvbn0ge1xuICAgIHdpZHRoOiAxZW07XG4gICAgaGVpZ2h0OiAxZW07XG4gICAgZGlzcGxheTogaW5saW5lO1xuICAgIGxpbmUtaGVpZ2h0OiAwcHg7XG4gIH1cbiAgYmFja2dyb3VuZC1jb2xvcjogI2Y3ZjdmNztcblxuICBib3JkZXI6IDFweCBzb2xpZDtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBib3JkZXItY29sb3I6IGJsYWNrO1xuICBjb2xvcjogYmxhY2s7XG4gIC8qIHRleHQtc2hhZG93OiAwIDFweCAxcHggcmdiYSgwLCAwLCAwLCAwLjIpOyAqL1xuICAvKiAtd2Via2l0LWJvcmRlci1ob3Jpem9udGFsLXNwYWNpbmc6IDBweDtcbiAgLXdlYmtpdC1ib3JkZXItdmVydGljYWwtc3BhY2luZzogMHB4OyAqL1xuYDtcbmNvbnN0IEJ1dHRvblZhcmlhbnQgPSBzdHlsZWQoQnV0dG9uKSBgXG4gIGNvbG9yOiB3aGl0ZTtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICB0ZXh0LXNoYWRvdzogMCAxcHggMXB4IHJnYmEoMCwgMCwgMCwgMC4yKTtcbmA7XG5leHBvcnQgY29uc3QgTGlua0Rlc3RydWN0aXZlID0gc3R5bGVkKExpbmspIGBcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDIwMiwgNjAsIDYwKTtcbmA7XG5leHBvcnQgY29uc3QgTGlua1ByaW1hcnkgPSBzdHlsZWQoTGluaykgYFxuICBjb2xvcjogcmdiKDY2LCAxODQsIDIyMSk7XG5gO1xuZXhwb3J0IGNvbnN0IEJ1dHRvblByaW1hcnkgPSBzdHlsZWQoQnV0dG9uVmFyaWFudCkgYFxuICBmb250LXNpemU6ICR7KHsgc21hbGwgfSkgPT4gKHNtYWxsID8gXCJzbWFsbFwiIDogXCJpbmhlcml0XCIpfTtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwNDJiMjtcbiAgYm9yZGVyLWNvbG9yOiAjMDA0MmIyO1xuYDtcbmV4cG9ydCBjb25zdCBCdXR0b25Cb3hQcmltYXJ5ID0gc3R5bGVkKEJ1dHRvbkJveCkgYFxuICBjb2xvcjogIzAwNDJiMjtcbiAgYm9yZGVyLWNvbG9yOiAjMDA0MmIyO1xuYDtcbmV4cG9ydCBjb25zdCBCdXR0b25TdWNjZXNzID0gc3R5bGVkKEJ1dHRvblZhcmlhbnQpIGBcbiAgYmFja2dyb3VuZC1jb2xvcjogIzM4OGUzYztcbmA7XG5leHBvcnQgY29uc3QgTGlua1N1Y2Nlc3MgPSBzdHlsZWQoTGluaykgYFxuICBjb2xvcjogIzM4OGUzYztcbmA7XG5leHBvcnQgY29uc3QgQnV0dG9uQm94U3VjY2VzcyA9IHN0eWxlZChCdXR0b25Cb3gpIGBcbiAgY29sb3I6ICMzODhlM2M7XG4gIGJvcmRlci1jb2xvcjogIzM4OGUzYztcbmA7XG5leHBvcnQgY29uc3QgQnV0dG9uV2FybmluZyA9IHN0eWxlZChCdXR0b25WYXJpYW50KSBgXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYigyMjMsIDExNywgMjApO1xuYDtcbmV4cG9ydCBjb25zdCBMaW5rV2FybmluZyA9IHN0eWxlZChMaW5rKSBgXG4gIGNvbG9yOiByZ2IoMjIzLCAxMTcsIDIwKTtcbmA7XG5leHBvcnQgY29uc3QgQnV0dG9uQm94V2FybmluZyA9IHN0eWxlZChCdXR0b25Cb3gpIGBcbiAgY29sb3I6IHJnYigyMjMsIDExNywgMjApO1xuICBib3JkZXItY29sb3I6IHJnYigyMjMsIDExNywgMjApO1xuYDtcbmV4cG9ydCBjb25zdCBCdXR0b25EZXN0cnVjdGl2ZSA9IHN0eWxlZChCdXR0b25WYXJpYW50KSBgXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYigyMDIsIDYwLCA2MCk7XG5gO1xuZXhwb3J0IGNvbnN0IEJ1dHRvbkJveERlc3RydWN0aXZlID0gc3R5bGVkKEJ1dHRvbkJveCkgYFxuICBjb2xvcjogcmdiKDIwMiwgNjAsIDYwKTtcbiAgYm9yZGVyLWNvbG9yOiByZ2IoMjAyLCA2MCwgNjApO1xuYDtcbmV4cG9ydCBjb25zdCBCb2xkTGlnaHQgPSBzdHlsZWQuZGl2IGBcbiAgY29sb3I6IGdyYXk7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuYDtcbmV4cG9ydCBjb25zdCBDZW50ZXJlZCA9IHN0eWxlZC5kaXYgYFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICYgPiA6bm90KDpmaXJzdC1jaGlsZCkge1xuICAgIG1hcmdpbi10b3A6IDE1cHg7XG4gIH1cbmA7XG5leHBvcnQgY29uc3QgUm93ID0gc3R5bGVkLmRpdiBgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIG1hcmdpbjogMC41ZW0gMDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBwYWRkaW5nOiAwLjVlbTtcbmA7XG5leHBvcnQgY29uc3QgUm93MiA9IHN0eWxlZC5kaXYgYFxuICBkaXNwbGF5OiBmbGV4O1xuICAvKiBtYXJnaW46IDAuNWVtIDA7ICovXG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgcGFkZGluZzogMC41ZW07XG5gO1xuZXhwb3J0IGNvbnN0IENvbHVtbiA9IHN0eWxlZC5kaXYgYFxuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBtYXJnaW46IDBlbSAxZW07XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbmA7XG5leHBvcnQgY29uc3QgUm93Qm9yZGVyR3JheSA9IHN0eWxlZChSb3cpIGBcbiAgYm9yZGVyOiAxcHggc29saWQgZ3JheTtcbiAgLyogYm9yZGVyLXJhZGl1czogMC41ZW07ICovXG5gO1xuZXhwb3J0IGNvbnN0IFJvd0xpZ2h0Qm9yZGVyR3JheSA9IHN0eWxlZChSb3cyKSBgXG4gIGJvcmRlcjogMXB4IHNvbGlkIGxpZ2h0Z3JheTtcbiAgYm9yZGVyLXRvcDogMHB4O1xuXG4gICR7RGF0ZVNlcGFyYXRvcn0gKyAmIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCBsaWdodGdyYXk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmVkO1xuICB9XG5gO1xuZXhwb3J0IGNvbnN0IEhpc3RvcnlSb3cgPSBzdHlsZWQuYSBgXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgY29sb3I6ICMyMTIxMjE7XG5cbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBwYWRkaW5nOiAwLjVlbTtcblxuICBib3JkZXI6IDFweCBzb2xpZCBsaWdodGdyYXk7XG4gIGJvcmRlci10b3A6IDBweDtcblxuICAke0RhdGVTZXBhcmF0b3J9ICsgJiB7XG4gICAgYm9yZGVyOiAxcHggc29saWQgbGlnaHRncmF5O1xuICB9XG5cbiAgOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBsaWdodGdyYXk7XG4gIH1cblxuICAmID4gJHtDb2x1bW59Omxhc3Qtb2YtdHlwZSB7XG4gICAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gICAgYWxpZ24tc2VsZjogY2VudGVyO1xuICB9XG5gO1xuZXhwb3J0IGNvbnN0IExpc3RPZlByb2R1Y3RzID0gc3R5bGVkLmRpdiBgXG4gICYgPiBkaXYgPiBhID4gaW1nIHtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuXG4gICAgd2lkdGg6IDMycHg7XG4gICAgaGVpZ2h0OiAzMnB4O1xuICB9XG4gICYgPiBkaXYgPiBkaXYge1xuICAgIG1hcmdpbi1yaWdodDogYXV0bztcbiAgICBtYXJnaW4tbGVmdDogMWVtO1xuICB9XG5gO1xuZXhwb3J0IGNvbnN0IExpZ2h0VGV4dCA9IHN0eWxlZC5kaXYgYFxuICBjb2xvcjogZ3JheTtcbmA7XG5leHBvcnQgY29uc3QgU3VjY2Vzc1RleHQgPSBzdHlsZWQuZGl2IGBcbiAgY29sb3I6ICMzODhlM2M7XG5gO1xuZXhwb3J0IGNvbnN0IERlc3RydWN0aXZlVGV4dCA9IHN0eWxlZC5kaXYgYFxuICBjb2xvcjogcmdiKDIwMiwgNjAsIDYwKTtcbmA7XG5leHBvcnQgY29uc3QgV2FybmluZ1RleHQgPSBzdHlsZWQuZGl2IGBcbiAgY29sb3I6IHJnYigyMjMsIDExNywgMjApO1xuYDtcbmV4cG9ydCBjb25zdCBTbWFsbFRleHQgPSBzdHlsZWQuZGl2IGBcbiAgZm9udC1zaXplOiBzbWFsbDtcbmA7XG5leHBvcnQgY29uc3QgTGFyZ2VUZXh0ID0gc3R5bGVkLmRpdiBgXG4gIGZvbnQtc2l6ZTogbGFyZ2U7XG5gO1xuZXhwb3J0IGNvbnN0IEV4dHJhTGFyZ2VUZXh0ID0gc3R5bGVkLmRpdiBgXG4gIGZvbnQtc2l6ZTogeC1sYXJnZTtcbmA7XG5leHBvcnQgY29uc3QgU21hbGxMaWdodFRleHQgPSBzdHlsZWQoU21hbGxUZXh0KSBgXG4gIGNvbG9yOiBncmF5O1xuYDtcbmV4cG9ydCBjb25zdCBDZW50ZXJlZFRleHQgPSBzdHlsZWQuZGl2IGBcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuYDtcbmV4cG9ydCBjb25zdCBDZW50ZXJlZEJvbGRUZXh0ID0gc3R5bGVkKENlbnRlcmVkVGV4dCkgYFxuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICBjb2xvcjogJHsoKHByb3BzKSA9PiBTdHJpbmcocHJvcHMuY29sb3IpKX07XG5gO1xuZXhwb3J0IGNvbnN0IElucHV0ID0gc3R5bGVkLmRpdiBgXG4gICYgbGFiZWwge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBhZGRpbmc6IDVweDtcbiAgICBjb2xvcjogJHsoeyBpbnZhbGlkIH0pID0+ICghaW52YWxpZCA/IFwiaW5oZXJpdFwiIDogXCJyZWRcIil9O1xuICB9XG4gICYgaW5wdXQge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBhZGRpbmc6IDVweDtcbiAgICB3aWR0aDogY2FsYygxMDAlIC0gNHB4IC0gMTBweCk7XG4gICAgYm9yZGVyLWNvbG9yOiAkeyh7IGludmFsaWQgfSkgPT4gKCFpbnZhbGlkID8gXCJpbmhlcml0XCIgOiBcInJlZFwiKX07XG4gIH1cbmA7XG5leHBvcnQgY29uc3QgSW5wdXRXaXRoTGFiZWwgPSBzdHlsZWQuZGl2IGBcbiAgLyogZGlzcGxheTogZmxleDsgKi9cblxuICAmIGxhYmVsIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBmb250LXdlaWdodDogYm9sZDtcbiAgICBtYXJnaW4tbGVmdDogMC41ZW07XG4gICAgcGFkZGluZzogNXB4O1xuICAgIGNvbG9yOiAkeyh7IGludmFsaWQgfSkgPT4gKCFpbnZhbGlkID8gXCJpbmhlcml0XCIgOiBcInJlZFwiKX07XG4gIH1cblxuICAmIGRpdiB7XG4gICAgbGluZS1oZWlnaHQ6IDI0cHg7XG4gICAgZGlzcGxheTogZmxleDtcbiAgfVxuICAmIGRpdiA+IHNwYW4ge1xuICAgIGJhY2tncm91bmQtY29sb3I6IGxpZ2h0Z3JheTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIGJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6IDAuMjVlbTtcbiAgICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiAwLjI1ZW07XG4gICAgaGVpZ2h0OiAyZW07XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHBhZGRpbmctbGVmdDogMC41ZW07XG4gICAgcGFkZGluZy1yaWdodDogMC41ZW07XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICB9XG4gICYgaW5wdXQge1xuICAgIGJvcmRlci13aWR0aDogMXB4O1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgaGVpZ2h0OiAyZW07XG4gICAgLyogYm9yZGVyLWNvbG9yOiBsaWdodGdyYXk7ICovXG4gICAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IDAuMjVlbTtcbiAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogMC4yNWVtO1xuICAgIGJvcmRlci1jb2xvcjogJHsoeyBpbnZhbGlkIH0pID0+ICghaW52YWxpZCA/IFwibGlnaHRncmF5XCIgOiBcInJlZFwiKX07XG4gIH1cbiAgbWFyZ2luLWJvdHRvbTogMTZweDtcbmA7XG5leHBvcnQgY29uc3QgRXJyb3JUZXh0ID0gc3R5bGVkLmRpdiBgXG4gIGNvbG9yOiByZWQ7XG5gO1xuZXhwb3J0IGNvbnN0IEVycm9yQm94ID0gc3R5bGVkLmRpdiBgXG4gIGJvcmRlcjogMnB4IHNvbGlkICNmNWM2Y2I7XG4gIGJvcmRlci1yYWRpdXM6IDAuMjVlbTtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAvKiBtYXJnaW46IDAuNWVtOyAqL1xuICBwYWRkaW5nOiAxZW07XG4gIG1hcmdpbjogMWVtO1xuICAvKiB3aWR0aDogMTAwJTsgKi9cbiAgY29sb3I6ICM3MjFjMjQ7XG4gIGJhY2tncm91bmQ6ICNmOGQ3ZGE7XG5cbiAgJiA+IGRpdiB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG5cbiAgICAmID4gYnV0dG9uIHtcbiAgICAgIGFsaWduLXNlbGY6IGNlbnRlcjtcbiAgICAgIGZvbnQtc2l6ZTogMTAwJTtcbiAgICAgIHBhZGRpbmc6IDA7XG4gICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICB3aWR0aDogMjhweDtcbiAgICB9XG4gIH1cbmA7XG5leHBvcnQgY29uc3QgSW5mb0JveCA9IHN0eWxlZChFcnJvckJveCkgYFxuICBjb2xvcjogYmxhY2s7XG4gIGJhY2tncm91bmQtY29sb3I6ICNkMWU3ZGQ7XG4gIGJvcmRlci1jb2xvcjogI2JhZGJjYztcbmA7XG5leHBvcnQgY29uc3QgU3VjY2Vzc0JveCA9IHN0eWxlZChFcnJvckJveCkgYFxuICBjb2xvcjogIzBmNTEzMjtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2QxZTdkZDtcbiAgYm9yZGVyLWNvbG9yOiAjYmFkYmNjO1xuYDtcbmV4cG9ydCBjb25zdCBXYXJuaW5nQm94ID0gc3R5bGVkKEVycm9yQm94KSBgXG4gIGNvbG9yOiAjNjY0ZDAzO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmM2NkO1xuICBib3JkZXItY29sb3I6ICNmZmVjYjU7XG5gO1xuaW1wb3J0IHNldHRpbmdzSWNvbiBmcm9tIFwiLi4vLi4vLi4vc3RhdGljL2ltZy9zZXR0aW5nc19ibGFja18yNGRwLnN2Z1wiO1xuZXhwb3J0IGNvbnN0IE5hdmlnYXRpb25IZWFkZXJIb2xkZXIgPSBzdHlsZWQuZGl2IGBcbiAgd2lkdGg6IDEwMCU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDQyYjI7XG5gO1xuZXhwb3J0IGNvbnN0IE5hdmlnYXRpb25IZWFkZXIgPSBzdHlsZWQuZGl2IGBcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwNDJiMjtcbiAgaGVpZ2h0OiAzNXB4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbiAgZGlzcGxheTogZmxleDtcblxuICAmIHtcbiAgICB3aWR0aDogNTAwcHg7XG4gIH1cblxuICAmID4gYSB7XG4gICAgY29sb3I6ICNmOGZhZjc7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgICBsaW5lLWhlaWdodDogMzVweDtcbiAgfVxuXG4gICYgPiBhID4gZGl2LnNldHRpbmdzLWljb24ge1xuICAgIG1hc2s6IHVybCgke3NldHRpbmdzSWNvbn0pIG5vLXJlcGVhdCBjZW50ZXI7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG4gICAgd2lkdGg6IDI0cHg7XG4gICAgaGVpZ2h0OiAyNHB4O1xuICAgIG1hcmdpbi1sZWZ0OiBhdXRvO1xuICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgIHBhZGRpbmc6IDRweDtcbiAgfVxuICAmID4gYS5hY3RpdmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmOGZhZjc7XG4gICAgY29sb3I6ICMwMDQyYjI7XG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gIH1cbiAgJiA+IGEuYWN0aXZlID4gZGl2LnNldHRpbmdzLWljb24ge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICMwMDQyYjI7XG4gIH1cbmA7XG5jb25zdCBpbWFnZSA9IGB1cmwoXCJkYXRhOmltYWdlL3N2Zyt4bWwsJTNjc3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgZmlsbD0nbm9uZScgdmlld0JveD0nMCAwIDIwIDIwJyUzZSUzY3BhdGggc3Ryb2tlPSclMjM2YjcyODAnIHN0cm9rZS1saW5lY2FwPSdyb3VuZCcgc3Ryb2tlLWxpbmVqb2luPSdyb3VuZCcgc3Ryb2tlLXdpZHRoPScxLjUnIGQ9J002IDhsNCA0IDQtNCcvJTNlJTNjL3N2ZyUzZVwiKWA7XG5leHBvcnQgY29uc3QgTmljZVNlbGVjdCA9IHN0eWxlZC5kaXYgYFxuICAmID4gc2VsZWN0IHtcbiAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgb3V0bGluZTogMDtcbiAgICBib3gtc2hhZG93OiBub25lO1xuXG4gICAgYmFja2dyb3VuZC1pbWFnZTogJHtpbWFnZX07XG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogcmlnaHQgNHB4IGNlbnRlcjtcbiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgIGJhY2tncm91bmQtc2l6ZTogMzJweCAzMnB4O1xuXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG5cbiAgICBib3JkZXItcmFkaXVzOiAwLjI1cmVtO1xuICAgIGZvbnQtc2l6ZTogMWVtO1xuICAgIHBhZGRpbmc6IDhweCAzMnB4IDhweCA4cHg7XG4gICAgLyogMC41ZW0gM2VtIDAuNWVtIDFlbTsgKi9cbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cblxuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIC8qIHdpZHRoOiAxMGVtOyAqL1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBib3JkZXItcmFkaXVzOiAwLjI1ZW07XG5gO1xuZXhwb3J0IGNvbnN0IE91dGxpbmVkID0gc3R5bGVkLmRpdiBgXG4gIGJvcmRlcjogMnB4IHNvbGlkICMzODhlM2M7XG4gIHBhZGRpbmc6IDAuNWVtIDFlbTtcbiAgd2lkdGg6IGZpdC1jb250ZW50O1xuICBib3JkZXItcmFkaXVzOiAycHg7XG4gIGNvbG9yOiAjMzg4ZTNjO1xuYDtcbi8qIHsgd2lkdGg6IFwiMS41ZW1cIiwgaGVpZ2h0OiBcIjEuNWVtXCIsIHZlcnRpY2FsQWxpZ246IFwibWlkZGxlXCIgfSAqL1xuZXhwb3J0IGNvbnN0IENoZWNrYm94U3VjY2VzcyA9IHN0eWxlZC5pbnB1dCBgXG4gIHZlcnRpY2FsLWFsaWduOiBjZW50ZXI7XG5gO1xuZXhwb3J0IGNvbnN0IFRlcm1zU2VjdGlvbiA9IHN0eWxlZC5hIGBcbiAgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7XG4gIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgcGFkZGluZzogMWVtO1xuICBtYXJnaW4tdG9wOiAycHg7XG4gIG1hcmdpbi1ib3R0b206IDJweDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICBjb2xvcjogaW5oZXJpdDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcblxuICBkaXNwbGF5OiBmbGV4O1xuICAmW2RhdGEtb3Blbj1cInRydWVcIl0ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gIH1cbiAgJltkYXRhLW9wZW49XCJmYWxzZVwiXSA+ICo6bm90KDpmaXJzdC1jaGlsZCkge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICBoZWFkZXIge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICBmb250LXdlaWdodDogYm9sZDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgaGVpZ2h0OiBhdXRvO1xuICB9XG5cbiAgJltkYXRhLW9wZW49XCJ0cnVlXCJdIGhlYWRlcjphZnRlciB7XG4gICAgY29udGVudDogXCJcXFxcMjIyN1wiO1xuICB9XG4gICZbZGF0YS1vcGVuPVwiZmFsc2VcIl0gaGVhZGVyOmFmdGVyIHtcbiAgICBjb250ZW50OiBcIlxcXFwyMjI4XCI7XG4gIH1cbmA7XG5leHBvcnQgY29uc3QgVGVybXNPZlNlcnZpY2UgPSBzdHlsZWQuZGl2IGBcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbiAgbWF4LXdpZHRoOiA1MDBweDtcblxuICAmID4gaGVhZGVyIHtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgZm9udC1zaXplOiAyZW07XG4gIH1cblxuICBhIHtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgY29sb3I6IGluaGVyaXQ7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgfVxuXG4gICYgPiBhIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCBibGFjaztcbiAgICBib3JkZXItcmFkaXVzOiA1cHg7XG4gICAgcGFkZGluZzogMWVtO1xuICAgIG1hcmdpbi10b3A6IDJweDtcbiAgICBtYXJnaW4tYm90dG9tOiAycHg7XG5cbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgICZbZGF0YS1vcGVuPVwidHJ1ZVwiXSB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgIH1cbiAgICAmW2RhdGEtb3Blbj1cImZhbHNlXCJdID4gKjpub3QoOmZpcnN0LWNoaWxkKSB7XG4gICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cblxuICAgIGhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgaGVpZ2h0OiBhdXRvO1xuICAgIH1cblxuICAgICZbZGF0YS1vcGVuPVwidHJ1ZVwiXSA+IGhlYWRlcjphZnRlciB7XG4gICAgICBjb250ZW50OiBcIlxcXFwyMjI3XCI7XG4gICAgfVxuICAgICZbZGF0YS1vcGVuPVwiZmFsc2VcIl0gPiBoZWFkZXI6YWZ0ZXIge1xuICAgICAgY29udGVudDogXCJcXFxcMjIyOFwiO1xuICAgIH1cbiAgfVxuYDtcbmV4cG9ydCBjb25zdCBTdHlsZWRDaGVja2JveExhYmVsID0gc3R5bGVkLmRpdiBgXG4gIGNvbG9yOiBncmVlbjtcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgLyogZm9udC13ZWlnaHQ6IGJvbGQ7ICovXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBzcGFuIHtcbiAgICBpbnB1dCB7XG4gICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgb3BhY2l0eTogMDtcbiAgICAgIHdpZHRoOiAxZW07XG4gICAgICBoZWlnaHQ6IDFlbTtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB9XG4gICAgZGl2IHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1ncmlkO1xuICAgICAgd2lkdGg6IDFlbTtcbiAgICAgIGhlaWdodDogMWVtO1xuICAgICAgbWFyZ2luLXJpZ2h0OiAxZW07XG4gICAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgICBib3JkZXI6IDJweCBzb2xpZCBjdXJyZW50Q29sb3I7XG5cbiAgICAgIHN2ZyB7XG4gICAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjFzIGVhc2UtaW4gMjVtcztcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgwKTtcbiAgICAgICAgdHJhbnNmb3JtLW9yaWdpbjogYm90dG9tIGxlZnQ7XG4gICAgICB9XG4gICAgfVxuICAgIGxhYmVsIHtcbiAgICAgIHBhZGRpbmc6IDBweDtcbiAgICAgIGZvbnQtc2l6ZTogc21hbGw7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuICB9XG5cbiAgaW5wdXQ6Y2hlY2tlZCArIGRpdiBzdmcge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMSk7XG4gIH1cbiAgaW5wdXQ6ZGlzYWJsZWQgKyBkaXYge1xuICAgIGNvbG9yOiAjOTU5NDk1O1xuICB9XG4gIGlucHV0OmRpc2FibGVkICsgZGl2ICsgbGFiZWwge1xuICAgIGNvbG9yOiAjOTU5NDk1O1xuICB9XG4gIGlucHV0OmZvY3VzICsgZGl2ICsgbGFiZWwge1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDAuMDVlbSAjZmZmLCAwIDAgMC4xNWVtIDAuMWVtIGN1cnJlbnRDb2xvcjtcbiAgfVxuYDtcbmV4cG9ydCBjb25zdCBQYXJhZ3JhcGhDbGlja2FibGUgPSBzdHlsZWQucCBgXG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgbWFyZ2luOiAwcHg7XG4gIHBhZGRpbmc6IDhweCAxNnB4O1xuICA6aG92ZXIge1xuICAgIGZpbHRlcjogYWxwaGEob3BhY2l0eT04MCk7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KFxuICAgICAgdHJhbnNwYXJlbnQsXG4gICAgICByZ2JhKDAsIDAsIDAsIDAuMSkgNDAlLFxuICAgICAgcmdiYSgwLCAwLCAwLCAwLjIpXG4gICAgKTtcbiAgfVxuYDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCJdfQ==*/ popup/popup.html 0000664 0001750 0001750 00000003237 14212136643 014501 0 ustar grothoff grothoff