Wallet/src/js/services/bitpayCardService.js

1386 lines
30 KiB
JavaScript
Raw Normal View History

2016-08-10 15:29:31 -03:00
'use strict';
2016-10-07 19:21:46 -03:00
angular.module('copayApp.services').factory('bitpayCardService', function($http, $log, $window, lodash, storageService, bitauthService, platformInfo) {
2016-08-10 15:29:31 -03:00
var root = {};
var credentials = {};
var bpSession = {};
2016-10-06 19:23:39 -03:00
var pubkey, sin;
2016-08-10 15:29:31 -03:00
2016-08-22 17:43:31 -03:00
var _setCredentials = function() {
2016-10-07 19:21:46 -03:00
if (!$window.externalServices || !$window.externalServices.bitpayCard) {
return;
}
var bitpayCard = $window.externalServices.bitpayCard;
2016-08-22 17:43:31 -03:00
/*
* Development: 'testnet'
* Production: 'livenet'
*/
credentials.NETWORK = 'livenet';
if (credentials.NETWORK == 'testnet') {
2016-10-07 19:21:46 -03:00
credentials.BITPAY_PRIV_KEY = bitpayCard.sandbox.secret;
credentials.BITPAY_API_URL = bitpayCard.sandbox.host;
2016-08-10 15:29:31 -03:00
}
else {
2016-10-07 19:21:46 -03:00
credentials.BITPAY_PRIV_KEY = bitpayCard.production.secret;
credentials.BITPAY_API_URL = bitpayCard.production.host;
2016-10-06 19:23:39 -03:00
}
try {
pubkey = bitauthService.getPublicKeyFromPrivateKey(credentials.BITPAY_PRIV_KEY);
sin = bitauthService.getSinFromPublicKey(pubkey);
}
catch (e) {
$log.error(e);
2016-08-10 15:29:31 -03:00
};
};
var _setError = function(msg, e) {
$log.error(msg);
2016-10-06 19:23:39 -03:00
var error = e.data ? e.data.error : msg;
return error;
};
2016-08-10 15:29:31 -03:00
var _getSession = function(cb) {
2016-08-22 17:43:31 -03:00
_setCredentials();
2016-08-10 15:29:31 -03:00
$http({
method: 'GET',
url: credentials.BITPAY_API_URL + '/api/session',
2016-08-10 15:29:31 -03:00
headers: {
'content-type': 'application/json'
}
}).then(function(data) {
$log.info('BitPay Get Session: SUCCESS');
bpSession = data.data.data;
return cb(null, bpSession);
}, function(data) {
return cb(_setError('BitPay Card Error: Get Session', data));
2016-08-10 15:29:31 -03:00
});
};
var _getBitPay = function(endpoint) {
2016-08-22 17:43:31 -03:00
_setCredentials();
2016-08-10 15:29:31 -03:00
return {
method: 'GET',
url: credentials.BITPAY_API_URL + endpoint,
headers: {
'content-type': 'application/json',
'x-csrf-token': bpSession.csrfToken
}
};
};
var _postBitPay = function(endpoint, data) {
2016-08-22 17:43:31 -03:00
_setCredentials();
2016-08-10 15:29:31 -03:00
return {
method: 'POST',
url: credentials.BITPAY_API_URL + endpoint,
headers: {
'Content-Type': 'application/json',
'x-csrf-token': bpSession.csrfToken
},
data: data
};
};
2016-08-22 17:43:31 -03:00
root.getEnvironment = function() {
_setCredentials();
return credentials.NETWORK;
};
2016-10-06 19:23:39 -03:00
root.getApiUrl = function() {
_setCredentials();
return credentials.BITPAY_API_URL;
};
2016-10-07 19:21:46 -03:00
root.testSession = function(cb) {
_getSession(function(err, session) {
return cb(err, session);
});
};
2016-10-06 19:23:39 -03:00
var _postBitAuth = function(endpoint, data) {
var dataToSign = credentials.BITPAY_API_URL + endpoint + JSON.stringify(data);
var signedData = bitauthService.sign(dataToSign, credentials.BITPAY_PRIV_KEY);
return {
method: 'POST',
url: credentials.BITPAY_API_URL + endpoint,
headers: {
'content-type': 'application/json',
'x-identity': pubkey,
'x-signature': signedData
},
data: data
2016-08-10 15:29:31 -03:00
};
};
2016-10-06 19:23:39 -03:00
var _afterBitAuthSuccess = function(obj, cb) {
var data = {
method: 'getTokens'
};
// Get tokens
$http(_postBitAuth('/api/v2/', data)).then(function(data) {
$log.info('BitPay Get Tokens: SUCCESS');
var token = lodash.find(data.data.data, 'visaUser');
if (lodash.isEmpty(token)) return cb(_setError('No token for visaUser'));
token = token.visaUser;
data['method'] = 'getDebitCards';
// Get Debit Cards
$http(_postBitAuth('/api/v2/' + token, data)).then(function(data) {
$log.info('BitPay Get Debit Cards: SUCCESS');
var cards = data.data.data;
return cb(null, {token: token, cards: cards, email: obj.email});
}, function(data) {
return cb(_setError('BitPay Card Error: Get Debit Cards', data));
});
2016-08-10 15:29:31 -03:00
}, function(data) {
2016-10-06 19:23:39 -03:00
return cb(_setError('BitPay Card Error: Get Token', data));
2016-08-10 15:29:31 -03:00
});
};
2016-10-06 19:23:39 -03:00
root.bitAuthPair = function(obj, cb) {
_getSession(function(err, session) {
if (err) return cb(err);
var deviceName = 'Unknow device';
if (platformInfo.isNW) {
deviceName = require('os').platform();
} else if (platformInfo.isCordova) {
deviceName = device.model;
}
var userData = {
csrf: session.csrfToken,
secret: obj.secret,
deviceName: deviceName,
code: obj.otp
};
var dataToSign = credentials.BITPAY_API_URL + '/api/validateBitAuthPairingCode' + JSON.stringify(userData);
2016-10-06 19:23:39 -03:00
var signedData = bitauthService.sign(dataToSign, credentials.BITPAY_PRIV_KEY);
$http({
method: 'POST',
url: credentials.BITPAY_API_URL + '/api/validateBitAuthPairingCode',
2016-10-06 19:23:39 -03:00
headers: {
'content-type': 'application/json',
'x-csrf-token': session.csrfToken,
'x-identity': pubkey,
'x-signature': signedData
},
data: userData
}).then(function(data) {
$log.info('BitPay Card BitAuth: SUCCESS');
// Get cards
_afterBitAuthSuccess(obj, cb);
}, function(data) {
return cb(_setError('BitPay Card Error: BitAuth', data));
});
2016-08-10 15:29:31 -03:00
});
};
2016-10-06 19:23:39 -03:00
var _processTransactions = function(invoices, history) {
invoices = invoices || [];
for (var i = 0; i < invoices.length; i++) {
var matched = false;
for (var j = 0; j < history.length; j++) {
if (history[j].description[0].indexOf(invoices[i].id) > -1) {
matched = true;
}
}
if (!matched && ['paid', 'confirmed', 'complete'].indexOf(invoices[i].status) > -1) {
history.unshift({
timestamp: invoices[i].invoiceTime,
description: invoices[i].itemDesc,
amount: invoices[i].price,
type: '00611 = Client Funded Deposit',
pending: true,
status: invoices[i].status
});
}
}
return history;
};
root.getHistory = function(cardId, params, cb) {
params = params || {};
var json = {};
json = {
method: 'getInvoiceHistory',
params: JSON.stringify(params)
};
2016-10-06 19:23:39 -03:00
root.getBitpayDebitCards(function(err, data) {
var card = lodash.find(data.cards, {id : cardId});
if (!card) return cb(_setError('No card available'));
// Get invoices
$http(_postBitAuth('/api/v2/' + card.token, json)).then(function(data) {
$log.info('BitPay Get Invoices: SUCCESS');
var invoices = data.data.data;
2016-10-06 19:23:39 -03:00
json = {
method: 'getTransactionHistory',
params: JSON.stringify(params)
};
// Get transactions list
$http(_postBitAuth('/api/v2/' + card.token, json)).then(function(data) {
$log.info('BitPay Get Transactions: SUCCESS');
var history = data.data.data || data.data;
history['txs'] = _processTransactions(invoices, history.transactionList);
2016-10-06 19:23:39 -03:00
return cb(null, history);
}, function(data) {
return cb(_setError('BitPay Card Error: Get Transactions', data));
});
}, function(data) {
return cb(_setError('BitPay Card Error: Get Invoices', data));
});
2016-08-10 15:29:31 -03:00
});
};
2016-10-06 19:23:39 -03:00
root.topUp = function(cardId, params, cb) {
var json = {
method: 'generateTopUpInvoice',
params: JSON.stringify(params)
};
root.getBitpayDebitCards(function(err, data) {
var card = lodash.find(data.cards, {id : cardId});
if (!card) return cb(_setError('No card available'));
$http(_postBitAuth('/api/v2/' + card.token, json)).then(function(data) {
$log.info('BitPay TopUp: SUCCESS');
var invoiceId = data.data.data.invoice;
return cb(null, invoiceId);
2016-08-10 15:29:31 -03:00
}, function(data) {
2016-10-06 19:23:39 -03:00
return cb(_setError('BitPay Card Error: TopUp', data));
2016-08-10 15:29:31 -03:00
});
});
};
2016-10-06 19:23:39 -03:00
root.getInvoice = function(id, cb) {
$http(_getBitPay('/invoices/' + id)).then(function(data) {
$log.info('BitPay Get Invoice: SUCCESS');
return cb(null, data.data.data);
2016-08-10 15:29:31 -03:00
}, function(data) {
2016-10-06 19:23:39 -03:00
return cb(_setError('BitPay Card Error: Get Invoice', data));
2016-08-10 15:29:31 -03:00
});
};
2016-10-06 19:23:39 -03:00
root.getBitpayDebitCards = function(cb) {
2016-09-28 21:09:41 -03:00
_setCredentials();
2016-10-06 19:23:39 -03:00
storageService.getBitpayDebitCards(credentials.NETWORK, function(err, data) {
2016-09-28 21:09:41 -03:00
if (err) return cb(err);
if (lodash.isString(data)) {
data = JSON.parse(data);
}
data = data || {};
return cb(null, data);
});
};
2016-10-06 19:23:39 -03:00
root.setBitpayDebitCards = function(data, cb) {
2016-09-28 21:09:41 -03:00
_setCredentials();
data = JSON.stringify(data);
2016-10-06 19:23:39 -03:00
storageService.setBitpayDebitCards(credentials.NETWORK, data, function(err) {
2016-09-28 21:09:41 -03:00
if (err) return cb(err);
return cb();
});
};
2016-10-06 19:23:39 -03:00
root.removeBitpayDebitCards = function(cb) {
2016-09-28 21:09:41 -03:00
_setCredentials();
2016-10-06 19:23:39 -03:00
storageService.removeBitpayDebitCards(credentials.NETWORK, function(err) {
2016-09-28 21:09:41 -03:00
if (err) return cb(err);
return cb();
});
};
2016-10-07 13:51:55 -03:00
root.getBitpayDebitCardsHistory = function(cardId, cb) {
_setCredentials();
storageService.getBitpayDebitCardsHistory(credentials.NETWORK, function(err, data) {
if (err) return cb(err);
if (lodash.isString(data)) {
data = JSON.parse(data);
}
data = data || {};
if (cardId) data = data[cardId];
return cb(null, data);
});
};
root.setBitpayDebitCardsHistory = function(cardId, data, opts, cb) {
_setCredentials();
storageService.getBitpayDebitCardsHistory(credentials.NETWORK, function(err, oldData) {
if (lodash.isString(oldData)) {
oldData = JSON.parse(oldData);
}
if (lodash.isString(data)) {
data = JSON.parse(data);
}
var inv = oldData || {};
inv[cardId] = data;
if (opts && opts.remove) {
delete(inv[cardId]);
}
inv = JSON.stringify(inv);
storageService.setBitpayDebitCardsHistory(credentials.NETWORK, inv, function(err) {
return cb(err);
});
});
};
root.removeBitpayDebitCardsHistory = function(cb) {
_setCredentials();
storageService.removeBitpayDebitCardsHistory(credentials.NETWORK, function(err) {
if (err) return cb(err);
return cb();
});
};
root.remove = function(cb) {
2016-08-22 17:43:31 -03:00
_setCredentials();
2016-10-06 19:23:39 -03:00
storageService.removeBitpayDebitCards(credentials.NETWORK, function(err) {
storageService.removeBitpayDebitCardsHistory(credentials.NETWORK, function(err) {
$log.info('BitPay Debit Cards Removed: SUCCESS');
return cb();
});
2016-08-10 15:29:31 -03:00
});
};
/*
* CONSTANTS
*/
root.bpTranCodes = {
'00611': {
merchant: {
name: 'BitPay',
city: 'Atlanta',
state: 'GA'
},
category: 'bp001',
description: 'Top-Up'
},
'602': {
merchant: {
name: 'ATM Withdrawal Fee',
},
category: 'bp002',
description: ''
},
'606': {
merchant: {
name: 'International ATM Fee',
},
category: 'bp002',
description: ''
},
'00240': {
merchant: {
name: 'ACH Debit Fee',
},
category: 'bp002',
description: ''
},
'5032': {
merchant: {
name: 'ACH Debit',
},
category: 'bp002',
description: ''
},
'37': {
merchant: {
name: 'ACH / Payroll Deposit',
},
category: 'bp002',
description: ''
}
};
root.iconMap = {
742: 'medical',
763: 'plant',
780: 'plant',
1520: 'repair',
1711: 'repair',
1731: 'repair',
1740: 'repair',
1750: 'repair',
1761: 'repair',
1771: 'repair',
1799: 'repair',
2741: 'books',
2791: 'books',
2842: 'clean',
3000: 'airplane',
3001: 'airplane',
3002: 'airplane',
3003: 'airplane',
3004: 'airplane',
3005: 'airplane',
3006: 'airplane',
3007: 'airplane',
3008: 'airplane',
3009: 'airplane',
3010: 'airplane',
3011: 'airplane',
3012: 'airplane',
3013: 'airplane',
3014: 'airplane',
3015: 'airplane',
3016: 'airplane',
3017: 'airplane',
3018: 'airplane',
3019: 'airplane',
3020: 'airplane',
3021: 'airplane',
3022: 'airplane',
3023: 'airplane',
3024: 'airplane',
3025: 'airplane',
3026: 'airplane',
3027: 'airplane',
3028: 'airplane',
3029: 'airplane',
3030: 'airplane',
3031: 'airplane',
3032: 'airplane',
3033: 'airplane',
3034: 'airplane',
3035: 'airplane',
3036: 'airplane',
3037: 'airplane',
3038: 'airplane',
3039: 'airplane',
3040: 'airplane',
3041: 'airplane',
3042: 'airplane',
3043: 'airplane',
3044: 'airplane',
3045: 'airplane',
3046: 'airplane',
3047: 'airplane',
3048: 'airplane',
3049: 'airplane',
3050: 'airplane',
3051: 'airplane',
3052: 'airplane',
3053: 'airplane',
3054: 'airplane',
3055: 'airplane',
3056: 'airplane',
3057: 'airplane',
3058: 'airplane',
3059: 'airplane',
3060: 'airplane',
3061: 'airplane',
3062: 'airplane',
3063: 'airplane',
3064: 'airplane',
3065: 'airplane',
3066: 'airplane',
3067: 'airplane',
3068: 'airplane',
3069: 'airplane',
3070: 'airplane',
3071: 'airplane',
3072: 'airplane',
3073: 'airplane',
3074: 'airplane',
3075: 'airplane',
3076: 'airplane',
3077: 'airplane',
3078: 'airplane',
3079: 'airplane',
3080: 'airplane',
3081: 'airplane',
3082: 'airplane',
3083: 'airplane',
3084: 'airplane',
3085: 'airplane',
3086: 'airplane',
3087: 'airplane',
3088: 'airplane',
3089: 'airplane',
3090: 'airplane',
3091: 'airplane',
3092: 'airplane',
3093: 'airplane',
3094: 'airplane',
3095: 'airplane',
3096: 'airplane',
3097: 'airplane',
3098: 'airplane',
3099: 'airplane',
3100: 'airplane',
3101: 'airplane',
3102: 'airplane',
3103: 'airplane',
3104: 'airplane',
3105: 'airplane',
3106: 'airplane',
3107: 'airplane',
3108: 'airplane',
3109: 'airplane',
3110: 'airplane',
3111: 'airplane',
3112: 'airplane',
3113: 'airplane',
3114: 'airplane',
3115: 'airplane',
3116: 'airplane',
3117: 'airplane',
3118: 'airplane',
3119: 'airplane',
3120: 'airplane',
3121: 'airplane',
3122: 'airplane',
3123: 'airplane',
3124: 'airplane',
3125: 'airplane',
3126: 'airplane',
3127: 'airplane',
3128: 'airplane',
3129: 'airplane',
3130: 'airplane',
3131: 'airplane',
3132: 'airplane',
3133: 'airplane',
3134: 'airplane',
3135: 'airplane',
3136: 'airplane',
3137: 'airplane',
3138: 'airplane',
3139: 'airplane',
3140: 'airplane',
3141: 'airplane',
3142: 'airplane',
3143: 'airplane',
3144: 'airplane',
3145: 'airplane',
3146: 'airplane',
3147: 'airplane',
3148: 'airplane',
3149: 'airplane',
3150: 'airplane',
3151: 'airplane',
3152: 'airplane',
3153: 'airplane',
3154: 'airplane',
3155: 'airplane',
3156: 'airplane',
3157: 'airplane',
3158: 'airplane',
3159: 'airplane',
3160: 'airplane',
3161: 'airplane',
3162: 'airplane',
3163: 'airplane',
3164: 'airplane',
3165: 'airplane',
3166: 'airplane',
3167: 'airplane',
3168: 'airplane',
3169: 'airplane',
3170: 'airplane',
3171: 'airplane',
3172: 'airplane',
3173: 'airplane',
3174: 'airplane',
3175: 'airplane',
3176: 'airplane',
3177: 'airplane',
3178: 'airplane',
3179: 'airplane',
3180: 'airplane',
3181: 'airplane',
3182: 'airplane',
3183: 'airplane',
3184: 'airplane',
3185: 'airplane',
3186: 'airplane',
3187: 'airplane',
3188: 'airplane',
3189: 'airplane',
3190: 'airplane',
3191: 'airplane',
3192: 'airplane',
3193: 'airplane',
3194: 'airplane',
3195: 'airplane',
3196: 'airplane',
3197: 'airplane',
3198: 'airplane',
3199: 'airplane',
3200: 'airplane',
3201: 'airplane',
3202: 'airplane',
3203: 'airplane',
3204: 'airplane',
3205: 'airplane',
3206: 'airplane',
3207: 'airplane',
3208: 'airplane',
3209: 'airplane',
3210: 'airplane',
3211: 'airplane',
3212: 'airplane',
3213: 'airplane',
3214: 'airplane',
3215: 'airplane',
3216: 'airplane',
3217: 'airplane',
3218: 'airplane',
3219: 'airplane',
3220: 'airplane',
3221: 'airplane',
3222: 'airplane',
3223: 'airplane',
3224: 'airplane',
3225: 'airplane',
3226: 'airplane',
3227: 'airplane',
3228: 'airplane',
3229: 'airplane',
3230: 'airplane',
3231: 'airplane',
3232: 'airplane',
3233: 'airplane',
3234: 'airplane',
3235: 'airplane',
3236: 'airplane',
3237: 'airplane',
3238: 'airplane',
3239: 'airplane',
3240: 'airplane',
3241: 'airplane',
3242: 'airplane',
3243: 'airplane',
3244: 'airplane',
3245: 'airplane',
3246: 'airplane',
3247: 'airplane',
3248: 'airplane',
3249: 'airplane',
3250: 'airplane',
3251: 'airplane',
3252: 'airplane',
3253: 'airplane',
3254: 'airplane',
3255: 'airplane',
3256: 'airplane',
3257: 'airplane',
3258: 'airplane',
3259: 'airplane',
3260: 'airplane',
3261: 'airplane',
3262: 'airplane',
3263: 'airplane',
3264: 'airplane',
3265: 'airplane',
3266: 'airplane',
3267: 'airplane',
3268: 'airplane',
3269: 'airplane',
3270: 'airplane',
3271: 'airplane',
3272: 'airplane',
3273: 'airplane',
3274: 'airplane',
3275: 'airplane',
3276: 'airplane',
3277: 'airplane',
3278: 'airplane',
3279: 'airplane',
3280: 'airplane',
3281: 'airplane',
3282: 'airplane',
3283: 'airplane',
3284: 'airplane',
3285: 'airplane',
3286: 'airplane',
3287: 'airplane',
3288: 'airplane',
3289: 'airplane',
3290: 'airplane',
3291: 'airplane',
3292: 'airplane',
3293: 'airplane',
3294: 'airplane',
3295: 'airplane',
3296: 'airplane',
3297: 'airplane',
3298: 'airplane',
3299: 'airplane',
3351: 'car',
3352: 'car',
3353: 'car',
3354: 'car',
3355: 'car',
3356: 'car',
3357: 'car',
3358: 'car',
3359: 'car',
3360: 'car',
3361: 'car',
3362: 'car',
3363: 'car',
3364: 'car',
3365: 'car',
3366: 'car',
3367: 'car',
3368: 'car',
3369: 'car',
3370: 'car',
3371: 'car',
3372: 'car',
3373: 'car',
3374: 'car',
3375: 'car',
3376: 'car',
3377: 'car',
3378: 'car',
3379: 'car',
3380: 'car',
3381: 'car',
3382: 'car',
3383: 'car',
3384: 'car',
3385: 'car',
3386: 'car',
3387: 'car',
3388: 'car',
3389: 'car',
3390: 'car',
3391: 'car',
3392: 'car',
3393: 'car',
3394: 'car',
3395: 'car',
3396: 'car',
3397: 'car',
3398: 'car',
3399: 'car',
3400: 'car',
3401: 'car',
3402: 'car',
3403: 'car',
3404: 'car',
3405: 'car',
3406: 'car',
3407: 'car',
3408: 'car',
3409: 'car',
3410: 'car',
3411: 'car',
3412: 'car',
3413: 'car',
3414: 'car',
3415: 'car',
3416: 'car',
3417: 'car',
3418: 'car',
3419: 'car',
3420: 'car',
3421: 'car',
3422: 'car',
3423: 'car',
3424: 'car',
3425: 'car',
3426: 'car',
3427: 'car',
3428: 'car',
3429: 'car',
3430: 'car',
3431: 'car',
3432: 'car',
3433: 'car',
3434: 'car',
3435: 'car',
3436: 'car',
3437: 'car',
3438: 'car',
3439: 'car',
3440: 'car',
3441: 'car',
3501: 'hotel',
3502: 'hotel',
3503: 'hotel',
3504: 'hotel',
3505: 'hotel',
3506: 'hotel',
3507: 'hotel',
3508: 'hotel',
3509: 'hotel',
3510: 'hotel',
3511: 'hotel',
3512: 'hotel',
3513: 'hotel',
3514: 'hotel',
3515: 'hotel',
3516: 'hotel',
3517: 'hotel',
3518: 'hotel',
3519: 'hotel',
3520: 'hotel',
3521: 'hotel',
3522: 'hotel',
3523: 'hotel',
3524: 'hotel',
3525: 'hotel',
3526: 'hotel',
3527: 'hotel',
3528: 'hotel',
3529: 'hotel',
3530: 'hotel',
3531: 'hotel',
3532: 'hotel',
3533: 'hotel',
3534: 'hotel',
3535: 'hotel',
3536: 'hotel',
3537: 'hotel',
3538: 'hotel',
3539: 'hotel',
3540: 'hotel',
3541: 'hotel',
3542: 'hotel',
3543: 'hotel',
3544: 'hotel',
3545: 'hotel',
3546: 'hotel',
3547: 'hotel',
3548: 'hotel',
3549: 'hotel',
3550: 'hotel',
3551: 'hotel',
3552: 'hotel',
3553: 'hotel',
3554: 'hotel',
3555: 'hotel',
3556: 'hotel',
3557: 'hotel',
3558: 'hotel',
3559: 'hotel',
3560: 'hotel',
3561: 'hotel',
3562: 'hotel',
3563: 'hotel',
3564: 'hotel',
3565: 'hotel',
3566: 'hotel',
3567: 'hotel',
3568: 'hotel',
3569: 'hotel',
3570: 'hotel',
3571: 'hotel',
3572: 'hotel',
3573: 'hotel',
3574: 'hotel',
3575: 'hotel',
3576: 'hotel',
3577: 'hotel',
3578: 'hotel',
3579: 'hotel',
3580: 'hotel',
3581: 'hotel',
3582: 'hotel',
3583: 'hotel',
3584: 'hotel',
3585: 'hotel',
3586: 'hotel',
3587: 'hotel',
3588: 'hotel',
3589: 'hotel',
3590: 'hotel',
3591: 'hotel',
3592: 'hotel',
3593: 'hotel',
3594: 'hotel',
3595: 'hotel',
3596: 'hotel',
3597: 'hotel',
3598: 'hotel',
3599: 'hotel',
3600: 'hotel',
3601: 'hotel',
3602: 'hotel',
3603: 'hotel',
3604: 'hotel',
3605: 'hotel',
3606: 'hotel',
3607: 'hotel',
3608: 'hotel',
3609: 'hotel',
3610: 'hotel',
3611: 'hotel',
3612: 'hotel',
3613: 'hotel',
3614: 'hotel',
3615: 'hotel',
3616: 'hotel',
3617: 'hotel',
3618: 'hotel',
3619: 'hotel',
3620: 'hotel',
3621: 'hotel',
3622: 'hotel',
3623: 'hotel',
3624: 'hotel',
3625: 'hotel',
3626: 'hotel',
3627: 'hotel',
3628: 'hotel',
3629: 'hotel',
3630: 'hotel',
3631: 'hotel',
3632: 'hotel',
3633: 'hotel',
3634: 'hotel',
3635: 'hotel',
3636: 'hotel',
3637: 'hotel',
3638: 'hotel',
3639: 'hotel',
3640: 'hotel',
3641: 'hotel',
3642: 'hotel',
3643: 'hotel',
3644: 'hotel',
3645: 'hotel',
3646: 'hotel',
3647: 'hotel',
3648: 'hotel',
3649: 'hotel',
3650: 'hotel',
3651: 'hotel',
3652: 'hotel',
3653: 'hotel',
3654: 'hotel',
3655: 'hotel',
3656: 'hotel',
3657: 'hotel',
3658: 'hotel',
3659: 'hotel',
3660: 'hotel',
3661: 'hotel',
3662: 'hotel',
3663: 'hotel',
3664: 'hotel',
3665: 'hotel',
3666: 'hotel',
3667: 'hotel',
3668: 'hotel',
3669: 'hotel',
3670: 'hotel',
3671: 'hotel',
3672: 'hotel',
3673: 'hotel',
3674: 'hotel',
3675: 'hotel',
3676: 'hotel',
3677: 'hotel',
3678: 'hotel',
3679: 'hotel',
3680: 'hotel',
3681: 'hotel',
3682: 'hotel',
3683: 'hotel',
3684: 'hotel',
3685: 'hotel',
3686: 'hotel',
3687: 'hotel',
3688: 'hotel',
3689: 'hotel',
3690: 'hotel',
3691: 'hotel',
3692: 'hotel',
3693: 'hotel',
3694: 'hotel',
3695: 'hotel',
3696: 'hotel',
3697: 'hotel',
3698: 'hotel',
3699: 'hotel',
3700: 'hotel',
3701: 'hotel',
3702: 'hotel',
3703: 'hotel',
3704: 'hotel',
3705: 'hotel',
3706: 'hotel',
3707: 'hotel',
3708: 'hotel',
3709: 'hotel',
3710: 'hotel',
3711: 'hotel',
3712: 'hotel',
3713: 'hotel',
3714: 'hotel',
3715: 'hotel',
3716: 'hotel',
3717: 'hotel',
3718: 'hotel',
3719: 'hotel',
3720: 'hotel',
3721: 'hotel',
3722: 'hotel',
3723: 'hotel',
3724: 'hotel',
3725: 'hotel',
3726: 'hotel',
3727: 'hotel',
3728: 'hotel',
3729: 'hotel',
3730: 'hotel',
3731: 'hotel',
3732: 'hotel',
3733: 'hotel',
3734: 'hotel',
3735: 'hotel',
3736: 'hotel',
3737: 'hotel',
3738: 'hotel',
3739: 'hotel',
3740: 'hotel',
3741: 'hotel',
3742: 'hotel',
3743: 'hotel',
3744: 'hotel',
3745: 'hotel',
3746: 'hotel',
3747: 'hotel',
3748: 'hotel',
3749: 'hotel',
3750: 'hotel',
3751: 'hotel',
3752: 'hotel',
3753: 'hotel',
3754: 'hotel',
3755: 'hotel',
3756: 'hotel',
3757: 'hotel',
3758: 'hotel',
3759: 'hotel',
3760: 'hotel',
3761: 'hotel',
3762: 'hotel',
3763: 'hotel',
3764: 'hotel',
3765: 'hotel',
3766: 'hotel',
3767: 'hotel',
3768: 'hotel',
3769: 'hotel',
3770: 'hotel',
3771: 'hotel',
3772: 'hotel',
3773: 'hotel',
3774: 'hotel',
3775: 'hotel',
3776: 'hotel',
3777: 'hotel',
3778: 'hotel',
3779: 'hotel',
3780: 'hotel',
3781: 'hotel',
3782: 'hotel',
3783: 'hotel',
3784: 'hotel',
3785: 'hotel',
3786: 'hotel',
3787: 'hotel',
3788: 'hotel',
3789: 'hotel',
3790: 'hotel',
3816: 'hotel',
3835: 'hotel',
4011: 'car',
4111: 'car',
4112: 'car',
4119: 'car',
4121: 'car',
4131: 'car',
4214: 'car',
4215: 'bus',
4225: 'default',
4411: 'boat',
4457: 'boat',
4468: 'boat',
4511: 'airplane',
4582: 'airplane',
4722: 'airplane',
4723: 'airplane',
4784: 'car',
4789: 'car',
4812: 'car',
4814: 'telephone',
4815: 'telephone',
4816: 'computer',
4821: 'money',
4829: 'money',
4899: 'television',
4900: 'gas',
5013: 'car',
5021: 'default',
5039: 'repair',
5044: 'computer',
5045: 'computer',
5046: 'default',
5047: 'medical',
5051: 'default',
5065: 'default',
5072: 'default',
5074: 'default',
5085: 'default',
5094: 'diamond-ring',
5099: 'default',
5111: 'default',
5122: 'medical',
5131: 'default',
5137: 'shirt',
5139: 'shoes',
5169: 'gas',
5172: 'gas',
5192: 'books',
5193: 'plant',
5198: 'repair',
5199: 'repair',
5200: 'repair',
5211: 'repair',
5231: 'repair',
5251: 'default',
5261: 'plant',
5271: 'bus',
5300: 'purchase',
5309: 'purchase',
5310: 'purchase',
5311: 'purchase',
5331: 'purchase',
5399: 'purchase',
5411: 'food',
5422: 'food',
5441: 'food',
5451: 'food',
5462: 'food',
5499: 'food',
5511: 'car',
5521: 'car',
5531: 'car',
5532: 'car',
5533: 'car',
5541: 'gas',
5542: 'gas',
5551: 'boat',
5561: 'motorcycle',
5571: 'motorcycle',
5592: 'default',
5598: 'default',
5599: 'car',
5611: 'shirt',
5621: 'shirt',
5631: 'shirt',
5641: 'shirt',
5651: 'shirt',
5655: 'shirt',
5661: 'shoes',
5681: 'default',
5691: 'shirt',
5697: 'default',
5698: 'default',
5699: 'default',
5712: 'default',
5713: 'default',
5714: 'default',
5718: 'default',
5719: 'default',
5722: 'default',
5732: 'computer',
5733: 'music',
5734: 'computer',
5735: 'music',
5811: 'food',
5812: 'food',
5813: 'cocktail',
5814: 'food',
5815: 'books',
5816: 'computer',
5817: 'default',
5818: 'default',
5832: 'default',
5912: 'medical',
5921: 'cocktail',
5931: 'default',
5932: 'default',
5933: 'default',
5935: 'default',
5937: 'default',
5940: 'bicycle',
5941: 'bicycle',
5942: 'books',
5943: 'default',
5944: 'clock',
5945: 'toy',
5946: 'camera',
5947: 'default',
5948: 'default',
5949: 'default',
5950: 'default',
5960: 'default',
5961: 'mail',
5962: 'telephone',
5963: 'default',
5964: 'telephone',
5965: 'telephone',
5966: 'telephone',
5967: 'telephone',
5968: 'telephone',
5969: 'telephone',
5970: 'art',
5971: 'art',
5972: 'coins',
5973: 'default',
5975: 'default',
5976: 'default',
5977: 'default',
5978: 'default',
5983: 'gas',
5992: 'plant',
5993: 'default',
5994: 'newspaper',
5995: 'pet',
5996: 'cocktail',
5997: 'purchase',
5998: 'tent',
5999: 'money',
6010: 'money',
6011: 'money',
6012: 'money',
6051: 'money',
6211: 'money',
6300: 'money',
6381: 'money',
6399: 'repair',
6513: 'repair',
7011: 'hotel',
7012: 'hotel',
7032: 'park',
7033: 'park',
7210: 'shirt',
7211: 'shirt',
7216: 'shirt',
7217: 'default',
7221: 'camera',
7230: 'scissors',
7251: 'shoe',
7261: 'sadface',
7273: 'smiley-face',
7276: 'money',
7277: 'people',
7278: 'people',
7296: 'shirt',
7297: 'smiley-face',
7298: 'smiley-face',
7299: 'default',
7311: 'default',
7321: 'default',
7332: 'computer',
7333: 'camera',
7338: 'computer',
7339: 'people',
7342: 'bug',
7349: 'default',
7361: 'people',
7372: 'computer',
7375: 'computer',
7379: 'computer',
7392: 'people',
7393: 'search',
7394: 'default',
7395: 'car',
7399: 'car',
7511: 'truck',
7512: 'car',
7513: 'truck',
7519: 'truck',
7523: 'car',
7531: 'car',
7534: 'car',
7535: 'car',
7538: 'car',
7542: 'car',
7549: 'truck',
7622: 'television',
7623: 'default',
7629: 'default',
7631: 'watch',
7641: 'furniture',
7692: 'default',
7699: 'default',
7800: 'money',
7801: 'money',
7802: 'money',
7829: 'money',
7832: 'film',
7841: 'film',
7911: 'music',
7922: 'ticket',
7929: 'ticket',
7932: 'music',
7933: 'bowling',
7941: 'football',
7991: 'people',
7992: 'golf',
7993: 'game',
7994: 'game',
7995: 'coins',
7996: 'ticket',
7997: 'money',
7998: 'ticket',
7999: 'people',
8011: 'medical',
8021: 'medical',
8031: 'medical',
8041: 'medical',
8042: 'medical',
8043: 'medical',
8044: 'medical',
8049: 'medical',
8050: 'medical',
8062: 'medical',
8071: 'medical',
8099: 'medical',
8111: 'law',
8211: 'books',
8220: 'books',
8241: 'books',
8244: 'books',
8249: 'books',
8299: 'people',
8351: 'people',
8398: 'people',
8641: 'people',
8651: 'people',
8661: 'people',
8675: 'car',
8699: 'people',
8734: 'medical',
8911: 'tree',
8931: 'books',
8999: 'suitcase',
9211: 'law',
9222: 'law',
9223: 'law',
9311: 'law',
9399: 'default',
9402: 'mail',
9405: 'default',
9700: 'default',
9701: 'default',
9702: 'default',
9950: 'default',
'bp001': 'bitcoin-topup',
'bp002': 'default'
};
return root;
});