UNPKG

send-crypto

Version:

A minimal JavaScript library / wallet for sending crypto assets

216 lines 19.5 kB
import BigNumber from "bignumber.js"; import { BCHHandler } from "./handlers/BCH/BCHHandler"; import { BTCHandler } from "./handlers/BTC/BTCHandler"; import { ERC20Handler } from "./handlers/ERC20/ERC20Handler"; import { ETHHandler } from "./handlers/ETH/ETHHandler"; import { FILHandler } from "./handlers/FIL/FILHandler"; import { LTCHandler } from "./handlers/LTC/LTCHandler"; import { TERRAHandler } from "./handlers/TERRA/TERRAHandler"; import { ZECHandler } from "./handlers/ZEC/ZECHandler"; import { strip0x, toHex } from "./lib/utils"; export default class CryptoAccount { handlers = []; privateKey; network; defaultAsset; constructorOptions; sharedState; constructor(privateKey, options) { this.privateKey = strip0x(privateKey instanceof Uint8Array ? toHex(privateKey) : privateKey); this.network = (options && options.network) || "mainnet"; this.constructorOptions = options; this.sharedState = {}; this.registerHandler(BTCHandler, 0); this.registerHandler(ZECHandler, 10); this.registerHandler(BCHHandler, 20); this.registerHandler(ETHHandler, 30); this.registerHandler(FILHandler, 40); this.registerHandler(TERRAHandler, 50); this.registerHandler(ERC20Handler, 60); this.registerHandler(LTCHandler, 60); if (options && options.extraHandlers) { for (const handler of options.extraHandlers) { this.registerHandler(handler); } } this.defaultAsset = options && options.defaultAsset; } registerHandler = (handlerClass, priorityIn) => { const priority = priorityIn === undefined ? this.handlers.length === 0 ? 0 : this.handlers[this.handlers.length - 1].priority : priorityIn; const lastPosition = this.handlers.reduce((index, item, currentIndex) => item.priority <= priority ? currentIndex + 1 : index, 0); this.handlers.splice(lastPosition, 0, { handler: new handlerClass(this.privateKey, this.network, this.constructorOptions, this.sharedState), priority, }); }; address = async (assetIn, options) => { const asset = assetIn || this.defaultAsset; if (!asset) { throw new Error(`Must provide an asset`); } return this.deferHandler().address(asset, options); }; getBalance = async (assetIn, options) => { const asset = assetIn || this.defaultAsset; if (!asset) { throw new Error(`Must provide an asset`); } const bn = await this.deferHandler().getBalance(asset, options); return (options && options.bn ? new options.bn(bn.toFixed()) : bn.toNumber()); }; // tslint:disable-next-line: member-ordering balanceOf = this.getBalance; getBalanceInSats = async (assetIn, options) => { const asset = assetIn || this.defaultAsset; if (!asset) { throw new Error(`Must provide an asset`); } const bn = await this.deferHandler().getBalanceInSats(asset, options); return (options && options.bn ? new options.bn(bn.toFixed()) : bn.toNumber()); }; // tslint:disable-next-line: member-ordering balanceOfInSats = this.getBalanceInSats; send = (to, value, assetIn, options) => { const asset = assetIn || this.defaultAsset; if (!asset) { throw new Error(`Must provide an asset`); } return this.deferHandler().send(to, new BigNumber(value.toString()), asset, options); }; sendSats = (to, value, assetIn, options) => { const asset = assetIn || this.defaultAsset; if (!asset) { throw new Error(`Must provide an asset`); } return this.deferHandler().sendSats(to, new BigNumber(value.toString()), asset, options); }; deferHandler = (thisHandler) => { return { address: (deferredAsset, deferredOptions) => { const nextHandler = this.findHandler(deferredAsset, thisHandler); if (nextHandler.address) { return nextHandler.address(deferredAsset, deferredOptions || {}, this.deferHandler(nextHandler)); } else { return this.deferHandler(nextHandler).address(deferredAsset, deferredOptions); } }, getBalance: (deferredAsset, deferredOptions) => { const nextHandler = this.findHandler(deferredAsset, thisHandler); if (nextHandler.getBalance) { return nextHandler.getBalance(deferredAsset, deferredOptions || {}, this.deferHandler(nextHandler)); } else { return this.deferHandler(nextHandler).getBalance(deferredAsset, deferredOptions); } }, getBalanceInSats: (deferredAsset, deferredOptions) => { const nextHandler = this.findHandler(deferredAsset, thisHandler); if (nextHandler.getBalanceInSats) { return nextHandler.getBalanceInSats(deferredAsset, deferredOptions || {}, this.deferHandler(nextHandler)); } else { return this.deferHandler(nextHandler).getBalanceInSats(deferredAsset, deferredOptions); } }, send: (deferredTo, deferredValue, deferredAsset, deferredOptions) => { const nextHandler = this.findHandler(deferredAsset, thisHandler); if (nextHandler.send) { return nextHandler.send(deferredTo, deferredValue, deferredAsset, deferredOptions || {}, this.deferHandler(nextHandler)); } else { return this.deferHandler(nextHandler).send(deferredTo, deferredValue, deferredAsset, deferredOptions); } }, sendSats: (deferredTo, deferredValue, deferredAsset, deferredOptions) => { const nextHandler = this.findHandler(deferredAsset, thisHandler); if (nextHandler.sendSats) { return nextHandler.sendSats(deferredTo, deferredValue, deferredAsset, deferredOptions || {}, this.deferHandler(nextHandler)); } else { return this.deferHandler(nextHandler).sendSats(deferredTo, deferredValue, deferredAsset, deferredOptions); } }, }; }; findHandler = (asset, from) => { const fromIndex = from ? this.handlers.findIndex((i) => i.handler === from) : -1; for (let i = (fromIndex === -1 ? this.handlers.length : fromIndex) - 1; i >= 0; i--) { const handler = this.handlers[i].handler; // console.log(handler); if (handler.handlesAsset(asset)) { return handler; } } let assetString; try { assetString = JSON.stringify(asset); } catch (error) { assetString = (asset && asset.name) || asset; } throw new Error(`Unsupported asset ${assetString}`); }; } export const newPrivateKey = () => { // @ts-ignore try { // @ts-ignore const array = new Uint8Array(32); // @ts-ignore window.crypto.getRandomValues(array); return toHex(array); } catch (error) { // Ignore window error. } return require("crypto").randomBytes(32).toString("hex"); }; CryptoAccount.newPrivateKey = newPrivateKey; //////////////////////////////////////////////////////////////////////////////// // EXPORTS // // Based on https://github.com/MikeMcl/bignumber.js/blob/master/bignumber.js // //////////////////////////////////////////////////////////////////////////////// // tslint:disable: no-object-mutation // tslint:disable-next-line: no-string-literal CryptoAccount.default = CryptoAccount.CryptoAccount = CryptoAccount; // AMD try { // @ts-ignore if (typeof define === "function" && define.amd) { // @ts-ignore define(() => CryptoAccount); } } catch (error) { /* ignore */ } // Node.js and other environments that support module.exports. try { // @ts-ignore if (typeof module !== "undefined" && module.exports) { module.exports = CryptoAccount; } } catch (error) { /* ignore */ } // Browser. try { // @ts-ignore if (typeof window !== "undefined" && window) { // @ts-ignore window.CryptoAccount = CryptoAccount; } } catch (error) { /* ignore */ } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzdELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFpQjdDLE1BQU0sQ0FBQyxPQUFPLE9BQU8sYUFBYTtJQUNiLFFBQVEsR0FHcEIsRUFBRSxDQUFDO0lBQ1MsVUFBVSxDQUFTO0lBQ25CLE9BQU8sQ0FBUztJQUNoQixZQUFZLENBQW9CO0lBQ2hDLGtCQUFrQixDQUFpQztJQUU1RCxXQUFXLENBQU07SUFFekIsWUFDSSxVQUErQixFQUMvQixPQUFxRDtRQUVyRCxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FDckIsVUFBVSxZQUFZLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQ3BFLENBQUM7UUFDRixJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxTQUFTLENBQUM7UUFDekQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztRQUNsQyxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyQyxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFO1lBQ2xDLEtBQUssTUFBTSxPQUFPLElBQUksT0FBTyxDQUFDLGFBQWEsRUFBRTtnQkFDekMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUNqQztTQUNKO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQztJQUN4RCxDQUFDO0lBRWUsZUFBZSxHQUFHLENBQzlCLFlBQTBCLEVBQzFCLFVBQW1CLEVBQ3JCLEVBQUU7UUFDQSxNQUFNLFFBQVEsR0FDVixVQUFVLEtBQUssU0FBUztZQUNwQixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFDeEIsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUTtZQUN0RCxDQUFDLENBQUMsVUFBVSxDQUFDO1FBQ3JCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUNyQyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEVBQUUsQ0FDMUIsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFDeEQsQ0FBQyxDQUNKLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFFO1lBQ2xDLE9BQU8sRUFBRSxJQUFJLFlBQVksQ0FDckIsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsT0FBTyxFQUNaLElBQUksQ0FBQyxrQkFBa0IsRUFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FDbkI7WUFDRCxRQUFRO1NBQ1gsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDO0lBRWMsT0FBTyxHQUFHLEtBQUssRUFDM0IsT0FBZSxFQUNmLE9BQWlCLEVBQ25CLEVBQUU7UUFDQSxNQUFNLEtBQUssR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQztRQUMzQyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1NBQzVDO1FBQ0QsT0FBTyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxDQUFDLENBQUM7SUFFYyxVQUFVLEdBQUcsS0FBSyxFQUk5QixPQUFlLEVBQ2YsT0FBaUIsRUFDUCxFQUFFO1FBQ1osTUFBTSxLQUFLLEdBQUcsT0FBTyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDM0MsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNSLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztTQUM1QztRQUNELE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDaEUsT0FBTyxDQUNILE9BQU8sSUFBSSxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FDbEUsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUNGLDRDQUE0QztJQUM1QixTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUU1QixnQkFBZ0IsR0FBRyxLQUFLLEVBSXBDLE9BQWUsRUFDZixPQUFpQixFQUNQLEVBQUU7UUFDWixNQUFNLEtBQUssR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQztRQUMzQyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1NBQzVDO1FBQ0QsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sQ0FDSCxPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQ2xFLENBQUM7SUFDWCxDQUFDLENBQUM7SUFDRiw0Q0FBNEM7SUFDNUIsZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUV4QyxJQUFJLEdBQUcsQ0FDbkIsRUFBVSxFQUNWLEtBQVksRUFDWixPQUFlLEVBQ2YsT0FBaUIsRUFDQyxFQUFFO1FBQ3BCLE1BQU0sS0FBSyxHQUFHLE9BQU8sSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzNDLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDUixNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7U0FDNUM7UUFDRCxPQUFPLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxJQUFJLENBQzNCLEVBQUUsRUFDRixJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsRUFDL0IsS0FBSyxFQUNMLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQyxDQUFDO0lBRWMsUUFBUSxHQUFHLENBQ3ZCLEVBQVUsRUFDVixLQUFZLEVBQ1osT0FBZSxFQUNmLE9BQWlCLEVBQ0MsRUFBRTtRQUNwQixNQUFNLEtBQUssR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQztRQUMzQyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1NBQzVDO1FBQ0QsT0FBTyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUMvQixFQUFFLEVBQ0YsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQy9CLEtBQUssRUFDTCxPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUMsQ0FBQztJQUVlLFlBQVksR0FBRyxDQUFDLFdBQXFCLEVBQWdCLEVBQUU7UUFDcEUsT0FBTztZQUNILE9BQU8sRUFBRSxDQUFDLGFBQW9CLEVBQUUsZUFBcUIsRUFBRSxFQUFFO2dCQUNyRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUNoQyxhQUFhLEVBQ2IsV0FBVyxDQUNkLENBQUM7Z0JBQ0YsSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFO29CQUNyQixPQUFPLFdBQVcsQ0FBQyxPQUFPLENBQ3RCLGFBQWEsRUFDYixlQUFlLElBQUksRUFBRSxFQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUNqQyxDQUFDO2lCQUNMO3FCQUFNO29CQUNILE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQ3pDLGFBQWEsRUFDYixlQUFlLENBQ2xCLENBQUM7aUJBQ0w7WUFDTCxDQUFDO1lBQ0QsVUFBVSxFQUFFLENBQUMsYUFBb0IsRUFBRSxlQUFxQixFQUFFLEVBQUU7Z0JBQ3hELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQ2hDLGFBQWEsRUFDYixXQUFXLENBQ2QsQ0FBQztnQkFDRixJQUFJLFdBQVcsQ0FBQyxVQUFVLEVBQUU7b0JBQ3hCLE9BQU8sV0FBVyxDQUFDLFVBQVUsQ0FDekIsYUFBYSxFQUNiLGVBQWUsSUFBSSxFQUFFLEVBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQ2pDLENBQUM7aUJBQ0w7cUJBQU07b0JBQ0gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFVBQVUsQ0FDNUMsYUFBYSxFQUNiLGVBQWUsQ0FDbEIsQ0FBQztpQkFDTDtZQUNMLENBQUM7WUFDRCxnQkFBZ0IsRUFBRSxDQUFDLGFBQW9CLEVBQUUsZUFBcUIsRUFBRSxFQUFFO2dCQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUNoQyxhQUFhLEVBQ2IsV0FBVyxDQUNkLENBQUM7Z0JBQ0YsSUFBSSxXQUFXLENBQUMsZ0JBQWdCLEVBQUU7b0JBQzlCLE9BQU8sV0FBVyxDQUFDLGdCQUFnQixDQUMvQixhQUFhLEVBQ2IsZUFBZSxJQUFJLEVBQUUsRUFDckIsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FDakMsQ0FBQztpQkFDTDtxQkFBTTtvQkFDSCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUMsZ0JBQWdCLENBQ2xELGFBQWEsRUFDYixlQUFlLENBQ2xCLENBQUM7aUJBQ0w7WUFDTCxDQUFDO1lBQ0QsSUFBSSxFQUFFLENBQ0YsVUFBa0IsRUFDbEIsYUFBd0IsRUFDeEIsYUFBb0IsRUFDcEIsZUFBcUIsRUFDdkIsRUFBRTtnQkFDQSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUNoQyxhQUFhLEVBQ2IsV0FBVyxDQUNkLENBQUM7Z0JBQ0YsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFO29CQUNsQixPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQ25CLFVBQVUsRUFDVixhQUFhLEVBQ2IsYUFBYSxFQUNiLGVBQWUsSUFBSSxFQUFFLEVBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQ2pDLENBQUM7aUJBQ0w7cUJBQU07b0JBQ0gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FDdEMsVUFBVSxFQUNWLGFBQWEsRUFDYixhQUFhLEVBQ2IsZUFBZSxDQUNsQixDQUFDO2lCQUNMO1lBQ0wsQ0FBQztZQUNELFFBQVEsRUFBRSxDQUNOLFVBQWtCLEVBQ2xCLGFBQXdCLEVBQ3hCLGFBQW9CLEVBQ3BCLGVBQXFCLEVBQ3ZCLEVBQUU7Z0JBQ0EsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FDaEMsYUFBYSxFQUNiLFdBQVcsQ0FDZCxDQUFDO2dCQUNGLElBQUksV0FBVyxDQUFDLFFBQVEsRUFBRTtvQkFDdEIsT0FBTyxXQUFXLENBQUMsUUFBUSxDQUN2QixVQUFVLEVBQ1YsYUFBYSxFQUNiLGFBQWEsRUFDYixlQUFlLElBQUksRUFBRSxFQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUNqQyxDQUFDO2lCQUNMO3FCQUFNO29CQUNILE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxRQUFRLENBQzFDLFVBQVUsRUFDVixhQUFhLEVBQ2IsYUFBYSxFQUNiLGVBQWUsQ0FDbEIsQ0FBQztpQkFDTDtZQUNMLENBQUM7U0FDSixDQUFDO0lBQ04sQ0FBQyxDQUFDO0lBRWUsV0FBVyxHQUFHLENBQUMsS0FBWSxFQUFFLElBQWMsRUFBVyxFQUFFO1FBQ3JFLE1BQU0sU0FBUyxHQUFHLElBQUk7WUFDbEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQztZQUNwRCxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDVCxLQUNJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUNqRSxDQUFDLElBQUksQ0FBQyxFQUNOLENBQUMsRUFBRSxFQUNMO1lBQ0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDekMsd0JBQXdCO1lBQ3hCLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDN0IsT0FBTyxPQUFPLENBQUM7YUFDbEI7U0FDSjtRQUNELElBQUksV0FBVyxDQUFDO1FBQ2hCLElBQUk7WUFDQSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN2QztRQUFDLE9BQU8sS0FBVSxFQUFFO1lBQ2pCLFdBQVcsR0FBRyxDQUFDLEtBQUssSUFBSyxLQUFhLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDO1NBQ3pEO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN4RCxDQUFDLENBQUM7Q0FDTDtBQUVELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUU7SUFDOUIsYUFBYTtJQUNiLElBQUk7UUFDQSxhQUFhO1FBQ2IsTUFBTSxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakMsYUFBYTtRQUNiLE1BQU0sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3ZCO0lBQUMsT0FBTyxLQUFVLEVBQUU7UUFDakIsdUJBQXVCO0tBQzFCO0lBQ0QsT0FBTyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3RCxDQUFDLENBQUM7QUFFRCxhQUFxQixDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFFckQsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRixnRkFBZ0Y7QUFDaEYsZ0ZBQWdGO0FBRWhGLHFDQUFxQztBQUVyQyw4Q0FBOEM7QUFDN0MsYUFBcUIsQ0FBQyxPQUFPLEdBQUksYUFBcUIsQ0FBQyxhQUFhO0lBQ2pFLGFBQWEsQ0FBQztBQUVsQixNQUFNO0FBQ04sSUFBSTtJQUNBLGFBQWE7SUFDYixJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFO1FBQzVDLGFBQWE7UUFDYixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUM7S0FDL0I7Q0FDSjtBQUFDLE9BQU8sS0FBVSxFQUFFO0lBQ2pCLFlBQVk7Q0FDZjtBQUVELDhEQUE4RDtBQUM5RCxJQUFJO0lBQ0EsYUFBYTtJQUNiLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDakQsTUFBTSxDQUFDLE9BQU8sR0FBRyxhQUFhLENBQUM7S0FDbEM7Q0FDSjtBQUFDLE9BQU8sS0FBVSxFQUFFO0lBQ2pCLFlBQVk7Q0FDZjtBQUVELFdBQVc7QUFDWCxJQUFJO0lBQ0EsYUFBYTtJQUNiLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxJQUFJLE1BQU0sRUFBRTtRQUN6QyxhQUFhO1FBQ1osTUFBYyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7S0FDakQ7Q0FDSjtBQUFDLE9BQU8sS0FBVSxFQUFFO0lBQ2pCLFlBQVk7Q0FDZiJ9