diff --git a/deps/js/ripple.js b/deps/js/ripple.js index a7e465c4f..1c39ed19e 100644 --- a/deps/js/ripple.js +++ b/deps/js/ripple.js @@ -52,7 +52,7 @@ var ripple = /* 1 */ /***/ function(module, exports, __webpack_require__) { - eval("// Remote access to a server.\n// - We never send binary data.\n// - We use the W3C interface for node and browser compatibility:\n// http://www.w3.org/TR/websockets/#the-websocket-interface\n//\n// This class is intended for both browser and Node.js use.\n//\n// This class is designed to work via peer protocol via either the public or\n// private WebSocket interfaces. The JavaScript class for the peer protocol\n// has not yet been implemented. However, this class has been designed for it\n// to be a very simple drop option.\n//\n// YYY Will later provide js/network.js which will transparently use multiple\n// instances of this class for network access.\n\nvar EventEmitter = __webpack_require__(36).EventEmitter;\nvar util = __webpack_require__(37);\nvar LRU = __webpack_require__(47);\nvar Server = __webpack_require__(20).Server;\nvar Request = __webpack_require__(2).Request;\nvar Server = __webpack_require__(20).Server;\nvar Amount = __webpack_require__(3).Amount;\nvar Currency = __webpack_require__(6).Currency;\nvar UInt160 = __webpack_require__(8).UInt160;\nvar Transaction = __webpack_require__(5).Transaction;\nvar Account = __webpack_require__(4).Account;\nvar Meta = __webpack_require__(11).Meta;\nvar OrderBook = __webpack_require__(22).OrderBook;\nvar PathFind = __webpack_require__(23).PathFind;\nvar SerializedObject = __webpack_require__(12).SerializedObject;\nvar RippleError = __webpack_require__(13).RippleError;\nvar utils = __webpack_require__(19);\nvar sjcl = __webpack_require__(19).sjcl;\nvar config = __webpack_require__(21);\nvar log = __webpack_require__(24).internal.sub('remote');\n\n/**\n * Interface to manage the connection to a Ripple server.\n *\n * This implementation uses WebSockets.\n *\n * Keys for opts:\n *\n * trace\n * max_listeners : Set maxListeners for remote; prevents EventEmitter warnings\n * connection_offset : Connect to remote servers on supplied interval (in seconds)\n * trusted : truthy, if remote is trusted\n * max_fee : Maximum acceptable transaction fee\n * fee_cushion : Extra fee multiplier to account for async fee changes.\n * servers : Array of server objects with the following form\n * canonical_signing : Signatures should be canonicalized and the \"canonical\" flag set\n *\n * {\n * host: \n * , port: \n * , secure: \n * }\n *\n * Events:\n * 'connect'\n * 'disconnect'\n * 'state':\n * - 'online' : Connected and subscribed.\n * - 'offline' : Not subscribed or not connected.\n * 'subscribed' : This indicates stand-alone is available.\n *\n * Server events:\n * 'ledger_closed' : A good indicate of ready to serve.\n * 'transaction' : Transactions we receive based on current subscriptions.\n * 'transaction_all' : Listening triggers a subscribe to all transactions\n * globally in the network.\n *\n * @param opts Connection options.\n * @param trace\n */\n\nfunction Remote(opts, trace) {\n EventEmitter.call(this);\n\n var self = this;\n var opts = opts || { };\n\n this.trusted = Boolean(opts.trusted);\n this.state = 'offline'; // 'online', 'offline'\n this._server_fatal = false; // True, if we know server exited.\n\n this.local_sequence = Boolean(opts.local_sequence); // Locally track sequence numbers\n this.local_fee = (typeof opts.local_fee === 'boolean') ? opts.local_fee : true;// Locally set fees\n this.local_signing = (typeof opts.local_signing === 'boolean') ? opts.local_signing : true;\n this.canonical_signing = (typeof opts.canonical_signing === 'boolean') ? opts.canonical_signing : true;\n\n this.fee_cushion = (typeof opts.fee_cushion === 'number') ? opts.fee_cushion : 1.2;\n this.max_fee = (typeof opts.max_fee === 'number') ? opts.max_fee : Infinity;\n\n this._ledger_current_index = void(0);\n this._ledger_hash = void(0);\n this._ledger_time = void(0);\n\n this._stand_alone = void(0);\n this._testnet = void(0);\n this.trace = Boolean(opts.trace);\n\n this._transaction_subs = 0;\n this._connection_count = 0;\n this._connected = false;\n this._should_connect = true;\n\n this._submission_timeout = 1000 * (typeof opts.submission_timeout === 'number' ? opts.submission_timeout : 20);\n\n this._received_tx = LRU({ max: 100 });\n this._cur_path_find = null;\n\n // Local signing implies local fees and sequences\n if (this.local_signing) {\n this.local_sequence = true;\n this.local_fee = true;\n }\n\n this._servers = [ ];\n this._primary_server = void(0);\n\n // Cache information for accounts.\n // DEPRECATED, will be removed\n // Consider sequence numbers stable if you know you're not generating bad transactions.\n // Otherwise, clear it to have it automatically refreshed from the network.\n // account : { seq : __ }\n this.accounts = { };\n\n // Account objects by AccountId.\n this._accounts = { };\n\n // OrderBook objects\n this._books = { };\n\n // Secrets that we know about.\n // Secrets can be set by calling set_secret(account, secret).\n // account : secret\n this.secrets = { };\n\n // Cache for various ledgers.\n // XXX Clear when ledger advances.\n this.ledgers = {\n current : {\n account_root : { }\n }\n };\n\n if (typeof this._submission_timeout !== 'number') {\n throw new TypeError('Remote \"submission_timeout\" configuration is not a Number');\n }\n\n if (typeof this.max_fee !== 'number') {\n throw new TypeError('Remote \"max_fee\" configuration is not a Number');\n }\n\n if (typeof this.fee_cushion !== 'number') {\n throw new TypeError('Remote \"fee_cushion\" configuration is not a Number');\n }\n\n if (!/^(undefined|boolean)$/.test(typeof opts.trace)) {\n throw new TypeError('Remote \"trace\" configuration is not a Boolean');\n }\n\n if (typeof this.local_signing !== 'boolean') {\n throw new TypeError('Remote \"local_signing\" configuration is not a Boolean');\n }\n\n if (typeof this.local_fee !== 'boolean') {\n throw new TypeError('Remote \"local_fee\" configuration is not a Boolean');\n }\n\n if (typeof this.local_sequence !== 'boolean') {\n throw new TypeError('Remote \"local_sequence\" configuration is not a Boolean');\n }\n\n if (!/^(undefined|number)$/.test(typeof opts.ping)) {\n throw new TypeError('Remote \"ping\" configuration is not a Number');\n }\n\n if (!/^(undefined|object)$/.test(typeof opts.storage)) {\n throw new TypeError('Remote \"storage\" configuration is not an Object');\n }\n\n // Fallback for previous API\n if (!opts.hasOwnProperty('servers') && opts.hasOwnProperty('websocket_ip')) {\n opts.servers = [\n {\n host: opts.websocket_ip,\n port: opts.websocket_port,\n secure: opts.websocket_ssl,\n trusted: opts.trusted\n }\n ];\n }\n\n (opts.servers || []).forEach(function(server) {\n self.addServer(server);\n });\n\n // This is used to remove Node EventEmitter warnings\n var maxListeners = opts.maxListeners || opts.max_listeners || 0;\n\n this._servers.concat(this).forEach(function(emitter) {\n if (emitter instanceof EventEmitter) {\n emitter.setMaxListeners(maxListeners);\n }\n });\n\n function listenerAdded(type, listener) {\n if (type === 'transaction_all') {\n if (!self._transaction_subs && self._connected) {\n self.request_subscribe('transactions').request();\n }\n self._transaction_subs += 1;\n }\n };\n\n this.on('newListener', listenerAdded);\n\n function listenerRemoved(type, listener) {\n if (type === 'transaction_all') {\n self._transaction_subs -= 1;\n if (!self._transaction_subs && self._connected) {\n self.request_unsubscribe('transactions').request();\n }\n }\n };\n\n this.on('removeListener', listenerRemoved);\n\n if (opts.storage) {\n this.storage = opts.storage;\n this.once('connect', this.getPendingTransactions.bind(this));\n }\n\n function pingServers() {\n self._pingInterval = setInterval(function() {\n var pingRequest = self.requestPing();\n pingRequest.on('error', function(){});\n pingRequest.broadcast();\n }, opts.ping * 1000);\n };\n\n if (opts.ping) {\n this.once('connect', pingServers);\n }\n\n function reconnect() {\n self.reconnect();\n };\n\n //if we are using a browser, reconnect\n //the servers whenever the network comes online\n if (typeof window !== 'undefined') {\n if (window.addEventListener) {\n // W3C DOM\n window.addEventListener('online', reconnect);\n } else if (window.attachEvent) {\n // IE DOM\n window.attachEvent('ononline', reconnect);\n }\n }\n};\n\nutil.inherits(Remote, EventEmitter);\n\n// Flags for ledger entries. In support of account_root().\nRemote.flags = {\n // Account Root\n account_root: {\n PasswordSpent: 0x00010000, // True, if password set fee is spent.\n RequireDestTag: 0x00020000, // True, to require a DestinationTag for payments.\n RequireAuth: 0x00040000, // True, to require a authorization to hold IOUs.\n DisallowXRP: 0x00080000, // True, to disallow sending XRP.\n DisableMaster: 0x00100000 // True, force regular key.\n },\n\n // Offer\n offer: {\n Passive: 0x00010000,\n Sell: 0x00020000 // True, offer was placed as a sell.\n },\n\n // Ripple State\n state: {\n LowReserve: 0x00010000, // True, if entry counts toward reserve.\n HighReserve: 0x00020000,\n LowAuth: 0x00040000,\n HighAuth: 0x00080000,\n LowNoRipple: 0x00100000,\n HighNoRipple: 0x00200000\n }\n};\n\nRemote.from_config = function(obj, trace) {\n var serverConfig = (typeof obj === 'string') ? config.servers[obj] : obj;\n var remote = new Remote(serverConfig, trace);\n\n function initializeAccount(account) {\n var accountInfo = config.accounts[account];\n if (typeof accountInfo === 'object') {\n if (accountInfo.secret) {\n // Index by nickname\n remote.setSecret(account, accountInfo.secret);\n // Index by account ID\n remote.setSecret(accountInfo.account, accountInfo.secret);\n }\n }\n };\n\n if (config.accounts) {\n Object.keys(config.accounts).forEach(initializeAccount);\n }\n\n return remote;\n};\n\n/**\n * Check that server message is valid\n *\n * @param {Object} message\n */\n\nRemote.isValidMessage = function(message) {\n return (typeof message === 'object')\n && (typeof message.type === 'string');\n};\n\n/**\n * Check that server message contains valid\n * ledger data\n *\n * @param {Object} message\n */\n\nRemote.isValidLedgerData = function(message) {\n return (typeof message === 'object')\n && (typeof message.fee_base === 'number')\n && (typeof message.fee_ref === 'number')\n && (typeof message.fee_base === 'number')\n && (typeof message.ledger_hash === 'string')\n && (typeof message.ledger_index === 'number')\n && (typeof message.ledger_time === 'number')\n && (typeof message.reserve_base === 'number')\n && (typeof message.reserve_inc === 'number')\n && (typeof message.txn_count === 'number');\n};\n\n/**\n * Check that server message contains valid\n * load status data\n *\n * @param {Object} message\n */\n\nRemote.isValidLoadStatus = function(message) {\n return (typeof message.load_base === 'number')\n && (typeof message.load_factor === 'number');\n};\n\n/**\n * Set the emitted state: 'online' or 'offline'\n *\n * @param {String} state\n */\n\nRemote.prototype._setState = function(state) {\n if (this.state !== state) {\n if (this.trace) {\n log.info('set_state:', state);\n }\n\n this.state = state;\n this.emit('state', state);\n\n switch (state) {\n case 'online':\n this._online_state = 'open';\n this._connected = true;\n this.emit('connect');\n this.emit('connected');\n break;\n case 'offline':\n this._online_state = 'closed';\n this._connected = false;\n this.emit('disconnect');\n this.emit('disconnected');\n break;\n }\n }\n};\n\n/**\n * Inform remote that the remote server is not comming back.\n */\n\nRemote.prototype.setServerFatal = function() {\n this._server_fatal = true;\n};\n\n/**\n * Enable debug output\n *\n * @param {Boolean} trace\n */\n\nRemote.prototype.setTrace = function(trace) {\n this.trace = (trace === void(0) || trace);\n return this;\n};\n\nRemote.prototype._trace = function() {\n if (this.trace) {\n log.info.apply(log, arguments);\n }\n};\n\n/**\n * Store a secret - allows the Remote to automatically fill \n * out auth information.\n *\n * @param {String} account\n * @param {String} secret\n */\n\nRemote.prototype.setSecret = function(account, secret) {\n this.secrets[account] = secret;\n};\n\nRemote.prototype.getPendingTransactions = function() {\n var self = this;\n\n function resubmitTransaction(tx) {\n if (typeof tx !== 'object') {\n return;\n }\n\n var transaction = self.transaction();\n transaction.parseJson(tx.tx_json);\n transaction.clientID(tx.clientID);\n\n Object.keys(tx).forEach(function(prop) {\n switch (prop) {\n case 'secret':\n case 'submittedIDs':\n case 'submitIndex':\n transaction[prop] = tx[prop];\n break;\n }\n });\n\n transaction.submit();\n };\n\n this.storage.getPendingTransactions(function(err, transactions) {\n if (!err && Array.isArray(transactions)) {\n transactions.forEach(resubmitTransaction);\n }\n });\n};\n\nRemote.prototype.addServer = function(opts) {\n var self = this;\n\n var server = new Server(this, opts);\n\n function serverMessage(data) {\n self._handleMessage(data, server);\n };\n\n server.on('message', serverMessage);\n\n function serverConnect() {\n self._connection_count += 1;\n\n if (opts.primary) {\n self._setPrimaryServer(server);\n }\n if (self._connection_count === 1) {\n self._setState('online');\n }\n if (self._connection_count === self._servers.length) {\n self.emit('ready');\n }\n };\n\n server.on('connect', serverConnect);\n\n function serverDisconnect() {\n self._connection_count--;\n if (self._connection_count === 0) {\n self._setState('offline');\n }\n };\n\n server.on('disconnect', serverDisconnect);\n\n this._servers.push(server);\n\n return this;\n};\n\n/**\n * Reconnect to Ripple network\n */\n\nRemote.prototype.reconnect = function() {\n var self = this;\n\n if (!this._should_connect) {\n return;\n }\n\n log.info('reconnecting');\n\n ;(function nextServer(i) {\n self._servers[i].reconnect();\n if (++i < self._servers.length) {\n nextServer(i);\n }\n })(0);\n\n return this;\n};\n\n/**\n * Connect to the Ripple network\n *\n * @param {Function} callback\n * @api public\n */\n\nRemote.prototype.connect = function(online) {\n if (!this._servers.length) {\n throw new Error('No servers available.');\n }\n\n switch (typeof online) {\n case 'undefined':\n break;\n case 'function':\n this.once('connect', online);\n break;\n default:\n // Downwards compatibility\n if (!Boolean(online)) {\n return this.disconnect();\n }\n }\n\n var self = this;\n\n this._should_connect = true;\n\n ;(function nextServer(i) {\n self._servers[i].connect();\n if (++i < self._servers.length) {\n nextServer(i);\n }\n })(0);\n\n return this;\n};\n\n/**\n * Disconnect from the Ripple network.\n *\n * @param {Function} callback\n * @api public\n */\n\nRemote.prototype.disconnect = function(callback) {\n if (!this._servers.length) {\n throw new Error('No servers available, not disconnecting');\n }\n\n var callback = (typeof callback === 'function') ? callback : function(){};\n\n if (!this._connected) {\n callback();\n return this;\n }\n\n this._should_connect = false;\n\n this.once('disconnect', callback);\n\n this._servers.forEach(function(server) {\n server.disconnect();\n });\n\n this._set_state('offline');\n\n return this;\n};\n\n/**\n * Handle server message. Server messages are proxied to\n * the Remote, such that global events can be handled\n *\n * It is possible for messages to be dispatched after the\n * connection is closed.\n *\n * @param {JSON} message\n * @param {Server} server\n */\n\nRemote.prototype._handleMessage = function(message, server) {\n var self = this;\n\n try {\n message = JSON.parse(message);\n } catch (e) {\n }\n\n if (!Remote.isValidMessage(message)) {\n // Unexpected response from remote.\n this.emit('error', new RippleError('remoteUnexpected', 'Unexpected response from remote'));\n return;\n }\n\n switch (message.type) {\n case 'ledgerClosed':\n this._handleLedgerClosed(message);\n break;\n case 'serverStatus':\n this._handleServerStatus(message);\n break;\n case 'transaction':\n this._handleTransaction(message);\n break;\n case 'path_find':\n this._handlePathFind(message);\n break;\n default:\n if (this.trace) {\n log.info(message.type + ': ', message);\n }\n break;\n }\n};\n\n/**\n * Handle server ledger_closed event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handleLedgerClosed = function(message) {\n var self = this;\n\n // XXX If not trusted, need to verify we consider ledger closed.\n // XXX Also need to consider a slow server or out of order response.\n // XXX Be more defensive fields could be missing or of wrong type.\n // YYY Might want to do some cache management.\n if (!Remote.isValidLedgerData(message)) {\n return;\n }\n\n var ledgerAdvanced = message.ledger_index >= this._ledger_current_index;\n\n if (ledgerAdvanced) {\n this._ledger_time = message.ledger_time;\n this._ledger_hash = message.ledger_hash;\n this._ledger_current_index = message.ledger_index + 1;\n this.emit('ledger_closed', message);\n }\n};\n\n/**\n * Handle server server_status event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handleServerStatus = function(message) {\n this.emit('server_status', message);\n};\n\n/**\n * Handle server transaction event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handleTransaction = function(message) {\n var self = this;\n\n // XXX If not trusted, need proof.\n\n // De-duplicate transactions\n var transactionHash = message.transaction.hash;\n\n if (this._received_tx.get(transactionHash)) {\n return;\n }\n\n if (message.validated) {\n this._received_tx.set(transactionHash, true);\n }\n\n if (this.trace) {\n log.info('tx:', message);\n }\n\n function notify(el) {\n var item = this[el];\n if (item && typeof item.notify === 'function') {\n item.notify(message);\n }\n };\n\n var metadata = message.meta || message.metadata;\n\n if (metadata) {\n // Process metadata\n message.mmeta = new Meta(metadata);\n\n // Pass the event on to any related Account objects\n var affectedAccounts = message.mmeta.getAffectedAccounts();\n affectedAccounts.forEach(notify.bind(this._accounts));\n\n // Pass the event on to any related OrderBooks\n var affectedBooks = message.mmeta.getAffectedBooks();\n affectedBooks.forEach(notify.bind(this._books));\n } else {\n // Transaction could be from proposed transaction stream\n [ 'Account', 'Destination' ].forEach(function(prop) {\n notify.call(self._accounts, message.transaction[prop]);\n });\n }\n\n this.emit('transaction', message);\n this.emit('transaction_all', message);\n};\n\n/**\n * Handle server path_find event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handlePathFind = function(message) {\n var self = this;\n\n // Pass the event to the currently open PathFind object\n if (this._cur_path_find) {\n this._cur_path_find.notify_update(message);\n }\n\n this.emit('path_find_all', message);\n};\n\n/**\n * Returns the current ledger hash\n *\n * @return {String} ledger hash\n */\n\nRemote.prototype.getLedgerHash = function() {\n return this._ledger_hash;\n};\n\n/**\n * Set primary server. Primary server will be selected\n * to handle requested regardless of its internally-tracked\n * priority score\n *\n * @param {Server} server\n */\n\nRemote.prototype._setPrimaryServer =\nRemote.prototype.setPrimaryServer = function(server) {\n if (this._primary_server) {\n this._primary_server._primary = false;\n }\n this._primary_server = server;\n this._primary_server._primary = true;\n};\n\n/**\n * Get connected state\n *\n * @return {Boolean} connected\n */\n\nRemote.prototype.isConnected = function() {\n return this._connected;\n};\n\n/**\n * Get array of connected servers\n */\n\nRemote.prototype.getConnectedServers = function() {\n var servers = [ ];\n for (var i=0; i\n * , port: \n * , secure: \n * }\n *\n * Events:\n * 'connect'\n * 'disconnect'\n * 'state':\n * - 'online' : Connected and subscribed.\n * - 'offline' : Not subscribed or not connected.\n * 'subscribed' : This indicates stand-alone is available.\n *\n * Server events:\n * 'ledger_closed' : A good indicate of ready to serve.\n * 'transaction' : Transactions we receive based on current subscriptions.\n * 'transaction_all' : Listening triggers a subscribe to all transactions\n * globally in the network.\n *\n * @param opts Connection options.\n * @param trace\n */\n\nfunction Remote(opts, trace) {\n EventEmitter.call(this);\n\n var self = this;\n var opts = opts || { };\n\n this.trusted = Boolean(opts.trusted);\n this.state = 'offline'; // 'online', 'offline'\n this._server_fatal = false; // True, if we know server exited.\n this._allow_partial_history = (typeof opts.allow_partial_history === 'boolean') ? opts.allow_partial_history : true;\n\n this.local_sequence = Boolean(opts.local_sequence); // Locally track sequence numbers\n this.local_fee = (typeof opts.local_fee === 'boolean') ? opts.local_fee : true;// Locally set fees\n this.local_signing = (typeof opts.local_signing === 'boolean') ? opts.local_signing : true;\n this.canonical_signing = (typeof opts.canonical_signing === 'boolean') ? opts.canonical_signing : true;\n\n this.fee_cushion = (typeof opts.fee_cushion === 'number') ? opts.fee_cushion : 1.2;\n this.max_fee = (typeof opts.max_fee === 'number') ? opts.max_fee : Infinity;\n\n this._ledger_current_index = void(0);\n this._ledger_hash = void(0);\n this._ledger_time = void(0);\n\n this._stand_alone = void(0);\n this._testnet = void(0);\n this.trace = Boolean(opts.trace);\n\n this._transaction_subs = 0;\n this._connection_count = 0;\n this._connected = false;\n this._should_connect = true;\n\n this._submission_timeout = 1000 * (typeof opts.submission_timeout === 'number' ? opts.submission_timeout : 20);\n\n this._received_tx = LRU({ max: 100 });\n this._cur_path_find = null;\n\n // Local signing implies local fees and sequences\n if (this.local_signing) {\n this.local_sequence = true;\n this.local_fee = true;\n }\n\n this._servers = [ ];\n this._primary_server = void(0);\n\n // Cache information for accounts.\n // DEPRECATED, will be removed\n // Consider sequence numbers stable if you know you're not generating bad transactions.\n // Otherwise, clear it to have it automatically refreshed from the network.\n // account : { seq : __ }\n this.accounts = { };\n\n // Account objects by AccountId.\n this._accounts = { };\n\n // OrderBook objects\n this._books = { };\n\n // Secrets that we know about.\n // Secrets can be set by calling set_secret(account, secret).\n // account : secret\n this.secrets = { };\n\n // Cache for various ledgers.\n // XXX Clear when ledger advances.\n this.ledgers = {\n current : {\n account_root : { }\n }\n };\n\n if (typeof this._submission_timeout !== 'number') {\n throw new TypeError('Remote \"submission_timeout\" configuration is not a Number');\n }\n\n if (typeof this.max_fee !== 'number') {\n throw new TypeError('Remote \"max_fee\" configuration is not a Number');\n }\n\n if (typeof this.fee_cushion !== 'number') {\n throw new TypeError('Remote \"fee_cushion\" configuration is not a Number');\n }\n\n if (!/^(undefined|boolean)$/.test(typeof opts.trace)) {\n throw new TypeError('Remote \"trace\" configuration is not a Boolean');\n }\n\n if (typeof this.local_signing !== 'boolean') {\n throw new TypeError('Remote \"local_signing\" configuration is not a Boolean');\n }\n\n if (typeof this.local_fee !== 'boolean') {\n throw new TypeError('Remote \"local_fee\" configuration is not a Boolean');\n }\n\n if (typeof this.local_sequence !== 'boolean') {\n throw new TypeError('Remote \"local_sequence\" configuration is not a Boolean');\n }\n\n if (!/^(undefined|number)$/.test(typeof opts.ping)) {\n throw new TypeError('Remote \"ping\" configuration is not a Number');\n }\n\n if (!/^(undefined|object)$/.test(typeof opts.storage)) {\n throw new TypeError('Remote \"storage\" configuration is not an Object');\n }\n\n // Fallback for previous API\n if (!opts.hasOwnProperty('servers') && opts.hasOwnProperty('websocket_ip')) {\n opts.servers = [\n {\n host: opts.websocket_ip,\n port: opts.websocket_port,\n secure: opts.websocket_ssl,\n trusted: opts.trusted\n }\n ];\n }\n\n (opts.servers || []).forEach(function(server) {\n self.addServer(server);\n });\n\n // This is used to remove Node EventEmitter warnings\n var maxListeners = opts.maxListeners || opts.max_listeners || 0;\n\n this._servers.concat(this).forEach(function(emitter) {\n if (emitter instanceof EventEmitter) {\n emitter.setMaxListeners(maxListeners);\n }\n });\n\n function listenerAdded(type, listener) {\n if (type === 'transaction_all') {\n if (!self._transaction_subs && self._connected) {\n self.request_subscribe('transactions').request();\n }\n self._transaction_subs += 1;\n }\n };\n\n this.on('newListener', listenerAdded);\n\n function listenerRemoved(type, listener) {\n if (type === 'transaction_all') {\n self._transaction_subs -= 1;\n if (!self._transaction_subs && self._connected) {\n self.request_unsubscribe('transactions').request();\n }\n }\n };\n\n this.on('removeListener', listenerRemoved);\n\n if (opts.storage) {\n this.storage = opts.storage;\n this.once('connect', this.getPendingTransactions.bind(this));\n }\n\n function pingServers() {\n self._pingInterval = setInterval(function() {\n var pingRequest = self.requestPing();\n pingRequest.on('error', function(){});\n pingRequest.broadcast();\n }, opts.ping * 1000);\n };\n\n if (opts.ping) {\n this.once('connect', pingServers);\n }\n\n function reconnect() {\n self.reconnect();\n };\n\n //if we are using a browser, reconnect\n //the servers whenever the network comes online\n if (typeof window !== 'undefined') {\n if (window.addEventListener) {\n // W3C DOM\n window.addEventListener('online', reconnect);\n } else if (window.attachEvent) {\n // IE DOM\n window.attachEvent('ononline', reconnect);\n }\n }\n};\n\nutil.inherits(Remote, EventEmitter);\n\n// Flags for ledger entries. In support of account_root().\nRemote.flags = {\n // Account Root\n account_root: {\n PasswordSpent: 0x00010000, // True, if password set fee is spent.\n RequireDestTag: 0x00020000, // True, to require a DestinationTag for payments.\n RequireAuth: 0x00040000, // True, to require a authorization to hold IOUs.\n DisallowXRP: 0x00080000, // True, to disallow sending XRP.\n DisableMaster: 0x00100000 // True, force regular key.\n },\n\n // Offer\n offer: {\n Passive: 0x00010000,\n Sell: 0x00020000 // True, offer was placed as a sell.\n },\n\n // Ripple State\n state: {\n LowReserve: 0x00010000, // True, if entry counts toward reserve.\n HighReserve: 0x00020000,\n LowAuth: 0x00040000,\n HighAuth: 0x00080000,\n LowNoRipple: 0x00100000,\n HighNoRipple: 0x00200000\n }\n};\n\nRemote.from_config = function(obj, trace) {\n var serverConfig = (typeof obj === 'string') ? config.servers[obj] : obj;\n var remote = new Remote(serverConfig, trace);\n\n function initializeAccount(account) {\n var accountInfo = config.accounts[account];\n if (typeof accountInfo === 'object') {\n if (accountInfo.secret) {\n // Index by nickname\n remote.setSecret(account, accountInfo.secret);\n // Index by account ID\n remote.setSecret(accountInfo.account, accountInfo.secret);\n }\n }\n };\n\n if (config.accounts) {\n Object.keys(config.accounts).forEach(initializeAccount);\n }\n\n return remote;\n};\n\n/**\n * Check that server message is valid\n *\n * @param {Object} message\n */\n\nRemote.isValidMessage = function(message) {\n return (typeof message === 'object')\n && (typeof message.type === 'string');\n};\n\n/**\n * Check that server message contains valid\n * ledger data\n *\n * @param {Object} message\n */\n\nRemote.isValidLedgerData = function(message) {\n return (typeof message === 'object')\n && (typeof message.fee_base === 'number')\n && (typeof message.fee_ref === 'number')\n && (typeof message.fee_base === 'number')\n && (typeof message.ledger_hash === 'string')\n && (typeof message.ledger_index === 'number')\n && (typeof message.ledger_time === 'number')\n && (typeof message.reserve_base === 'number')\n && (typeof message.reserve_inc === 'number')\n && (typeof message.txn_count === 'number');\n};\n\n/**\n * Check that server message contains valid\n * load status data\n *\n * @param {Object} message\n */\n\nRemote.isValidLoadStatus = function(message) {\n return (typeof message.load_base === 'number')\n && (typeof message.load_factor === 'number');\n};\n\n/**\n * Set the emitted state: 'online' or 'offline'\n *\n * @param {String} state\n */\n\nRemote.prototype._setState = function(state) {\n if (this.state !== state) {\n if (this.trace) {\n log.info('set_state:', state);\n }\n\n this.state = state;\n this.emit('state', state);\n\n switch (state) {\n case 'online':\n this._online_state = 'open';\n this._connected = true;\n this.emit('connect');\n this.emit('connected');\n break;\n case 'offline':\n this._online_state = 'closed';\n this._connected = false;\n this.emit('disconnect');\n this.emit('disconnected');\n break;\n }\n }\n};\n\n/**\n * Inform remote that the remote server is not comming back.\n */\n\nRemote.prototype.setServerFatal = function() {\n this._server_fatal = true;\n};\n\n/**\n * Enable debug output\n *\n * @param {Boolean} trace\n */\n\nRemote.prototype.setTrace = function(trace) {\n this.trace = (trace === void(0) || trace);\n return this;\n};\n\nRemote.prototype._trace = function() {\n if (this.trace) {\n log.info.apply(log, arguments);\n }\n};\n\n/**\n * Store a secret - allows the Remote to automatically fill \n * out auth information.\n *\n * @param {String} account\n * @param {String} secret\n */\n\nRemote.prototype.setSecret = function(account, secret) {\n this.secrets[account] = secret;\n};\n\nRemote.prototype.getPendingTransactions = function() {\n var self = this;\n\n function resubmitTransaction(tx) {\n if (typeof tx !== 'object') {\n return;\n }\n\n var transaction = self.transaction();\n transaction.parseJson(tx.tx_json);\n transaction.clientID(tx.clientID);\n\n Object.keys(tx).forEach(function(prop) {\n switch (prop) {\n case 'secret':\n case 'submittedIDs':\n case 'submitIndex':\n transaction[prop] = tx[prop];\n break;\n }\n });\n\n transaction.submit();\n };\n\n this.storage.getPendingTransactions(function(err, transactions) {\n if (!err && Array.isArray(transactions)) {\n transactions.forEach(resubmitTransaction);\n }\n });\n};\n\nRemote.prototype.addServer = function(opts) {\n var self = this;\n\n var server = new Server(this, opts);\n\n function serverMessage(data) {\n self._handleMessage(data, server);\n };\n\n server.on('message', serverMessage);\n\n function serverConnect() {\n self._connection_count += 1;\n\n if (opts.primary) {\n self._setPrimaryServer(server);\n }\n if (self._connection_count === 1) {\n self._setState('online');\n }\n if (self._connection_count === self._servers.length) {\n self.emit('ready');\n }\n };\n\n server.on('connect', serverConnect);\n\n function serverDisconnect() {\n self._connection_count--;\n if (self._connection_count === 0) {\n self._setState('offline');\n }\n };\n\n server.on('disconnect', serverDisconnect);\n\n this._servers.push(server);\n\n return this;\n};\n\n/**\n * Reconnect to Ripple network\n */\n\nRemote.prototype.reconnect = function() {\n var self = this;\n\n if (!this._should_connect) {\n return;\n }\n\n log.info('reconnecting');\n\n ;(function nextServer(i) {\n self._servers[i].reconnect();\n if (++i < self._servers.length) {\n nextServer(i);\n }\n })(0);\n\n return this;\n};\n\n/**\n * Connect to the Ripple network\n *\n * @param {Function} callback\n * @api public\n */\n\nRemote.prototype.connect = function(online) {\n if (!this._servers.length) {\n throw new Error('No servers available.');\n }\n\n switch (typeof online) {\n case 'undefined':\n break;\n case 'function':\n this.once('connect', online);\n break;\n default:\n // Downwards compatibility\n if (!Boolean(online)) {\n return this.disconnect();\n }\n }\n\n var self = this;\n\n this._should_connect = true;\n\n ;(function nextServer(i) {\n self._servers[i].connect();\n if (++i < self._servers.length) {\n nextServer(i);\n }\n })(0);\n\n return this;\n};\n\n/**\n * Disconnect from the Ripple network.\n *\n * @param {Function} callback\n * @api public\n */\n\nRemote.prototype.disconnect = function(callback) {\n if (!this._servers.length) {\n throw new Error('No servers available, not disconnecting');\n }\n\n var callback = (typeof callback === 'function') ? callback : function(){};\n\n if (!this._connected) {\n callback();\n return this;\n }\n\n this._should_connect = false;\n\n this.once('disconnect', callback);\n\n this._servers.forEach(function(server) {\n server.disconnect();\n });\n\n this._set_state('offline');\n\n return this;\n};\n\n/**\n * Handle server message. Server messages are proxied to\n * the Remote, such that global events can be handled\n *\n * It is possible for messages to be dispatched after the\n * connection is closed.\n *\n * @param {JSON} message\n * @param {Server} server\n */\n\nRemote.prototype._handleMessage = function(message, server) {\n var self = this;\n\n try {\n message = JSON.parse(message);\n } catch (e) {\n }\n\n if (!Remote.isValidMessage(message)) {\n // Unexpected response from remote.\n this.emit('error', new RippleError('remoteUnexpected', 'Unexpected response from remote'));\n return;\n }\n\n switch (message.type) {\n case 'ledgerClosed':\n this._handleLedgerClosed(message);\n break;\n case 'serverStatus':\n this._handleServerStatus(message);\n break;\n case 'transaction':\n this._handleTransaction(message);\n break;\n case 'path_find':\n this._handlePathFind(message);\n break;\n default:\n if (this.trace) {\n log.info(message.type + ': ', message);\n }\n break;\n }\n};\n\n/**\n * Handle server ledger_closed event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handleLedgerClosed = function(message) {\n var self = this;\n\n // XXX If not trusted, need to verify we consider ledger closed.\n // XXX Also need to consider a slow server or out of order response.\n // XXX Be more defensive fields could be missing or of wrong type.\n // YYY Might want to do some cache management.\n if (!Remote.isValidLedgerData(message)) {\n return;\n }\n\n var ledgerAdvanced = message.ledger_index >= this._ledger_current_index;\n\n if (ledgerAdvanced) {\n this._ledger_time = message.ledger_time;\n this._ledger_hash = message.ledger_hash;\n this._ledger_current_index = message.ledger_index + 1;\n this.emit('ledger_closed', message);\n }\n};\n\n/**\n * Handle server server_status event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handleServerStatus = function(message) {\n this.emit('server_status', message);\n};\n\n/**\n * Handle server transaction event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handleTransaction = function(message) {\n var self = this;\n\n // XXX If not trusted, need proof.\n\n // De-duplicate transactions\n var transactionHash = message.transaction.hash;\n\n if (this._received_tx.get(transactionHash)) {\n return;\n }\n\n if (message.validated) {\n this._received_tx.set(transactionHash, true);\n }\n\n if (this.trace) {\n log.info('tx:', message);\n }\n\n function notify(el) {\n var item = this[el];\n if (item && typeof item.notify === 'function') {\n item.notify(message);\n }\n };\n\n var metadata = message.meta || message.metadata;\n\n if (metadata) {\n // Process metadata\n message.mmeta = new Meta(metadata);\n\n // Pass the event on to any related Account objects\n var affectedAccounts = message.mmeta.getAffectedAccounts();\n affectedAccounts.forEach(notify.bind(this._accounts));\n\n // Pass the event on to any related OrderBooks\n var affectedBooks = message.mmeta.getAffectedBooks();\n affectedBooks.forEach(notify.bind(this._books));\n } else {\n // Transaction could be from proposed transaction stream\n [ 'Account', 'Destination' ].forEach(function(prop) {\n notify.call(self._accounts, message.transaction[prop]);\n });\n }\n\n this.emit('transaction', message);\n this.emit('transaction_all', message);\n};\n\n/**\n * Handle server path_find event\n *\n * @param {Object} message\n */\n\nRemote.prototype._handlePathFind = function(message) {\n var self = this;\n\n // Pass the event to the currently open PathFind object\n if (this._cur_path_find) {\n this._cur_path_find.notify_update(message);\n }\n\n this.emit('path_find_all', message);\n};\n\n/**\n * Returns the current ledger hash\n *\n * @return {String} ledger hash\n */\n\nRemote.prototype.getLedgerHash = function() {\n return this._ledger_hash;\n};\n\n/**\n * Set primary server. Primary server will be selected\n * to handle requested regardless of its internally-tracked\n * priority score\n *\n * @param {Server} server\n */\n\nRemote.prototype._setPrimaryServer =\nRemote.prototype.setPrimaryServer = function(server) {\n if (this._primary_server) {\n this._primary_server._primary = false;\n }\n this._primary_server = server;\n this._primary_server._primary = true;\n};\n\n/**\n * Get connected state\n *\n * @return {Boolean} connected\n */\n\nRemote.prototype.isConnected = function() {\n return this._connected;\n};\n\n/**\n * Get array of connected servers\n */\n\nRemote.prototype.getConnectedServers = function() {\n var servers = [ ];\n for (var i=0; i= this.consts.telLOCAL_ERROR && ter < this.consts.temMALFORMED;\n};\n\nTransaction.prototype.isTemMalformed = function(ter) {\n return ter >= this.consts.temMALFORMED && ter < this.consts.tefFAILURE;\n};\n\nTransaction.prototype.isTefFailure = function(ter) {\n return ter >= this.consts.tefFAILURE && ter < this.consts.terRETRY;\n};\n\nTransaction.prototype.isTerRetry = function(ter) {\n return ter >= this.consts.terRETRY && ter < this.consts.tesSUCCESS;\n};\n\nTransaction.prototype.isTepSuccess = function(ter) {\n return ter >= this.consts.tesSUCCESS;\n};\n\nTransaction.prototype.isTecClaimed = function(ter) {\n return ter >= this.consts.tecCLAIMED;\n};\n\nTransaction.prototype.isRejected = function(ter) {\n return this.isTelLocal(ter) || this.isTemMalformed(ter) || this.isTefFailure(ter);\n};\n\nTransaction.prototype.setState = function(state) {\n if (this.state !== state) {\n this.state = state;\n this.emit('state', state);\n this.emit('save');\n }\n};\n\nTransaction.prototype.finalize = function(message) {\n this.finalized = true;\n\n if (this.result) {\n this.result.ledger_index = message.ledger_index;\n this.result.ledger_hash = message.ledger_hash;\n } else {\n this.result = message;\n this.result.tx_json = this.tx_json;\n }\n\n return this;\n};\n\nTransaction.prototype._accountSecret = function(account) {\n return this.remote.secrets[account];\n};\n\n/**\n * Returns the number of fee units this transaction will cost.\n *\n * Each Ripple transaction based on its type and makeup costs a certain number\n * of fee units. The fee units are calculated on a per-server basis based on the\n * current load on both the network and the server.\n *\n * @see https://ripple.com/wiki/Transaction_Fee\n *\n * @return {Number} Number of fee units for this transaction.\n */\n\nTransaction.prototype._getFeeUnits =\nTransaction.prototype.feeUnits = function() {\n return Transaction.fee_units['default'];\n};\n\n/**\n * Compute median server fee\n */\n\nTransaction.prototype._computeFee = function() {\n var servers = this.remote._servers;\n var fees = [ ];\n\n for (var i=0; i b) {\n return 1;\n } else if (a < b) {\n return -1;\n } else {\n return 0;\n }\n });\n\n var midInd = Math.floor(fees.length / 2);\n\n var median = fees.length % 2 === 0\n ? Math.floor(0.5 + (fees[midInd] + fees[midInd - 1]) / 2)\n : fees[midInd];\n\n return String(median);\n};\n\n/**\n * Attempts to complete the transaction for submission.\n *\n * This function seeks to fill out certain fields, such as Fee and\n * SigningPubKey, which can be determined by the library based on network\n * information and other fields.\n */\n\nTransaction.prototype.complete = function() {\n if (this.remote) {\n if (!this.remote.trusted && !this.remote.local_signing) {\n this.emit('error', new RippleError('tejServerUntrusted', 'Attempt to give secret to untrusted server'));\n return false;\n }\n }\n\n // Try to auto-fill the secret\n if (!this._secret && !(this._secret = this._accountSecret(this.tx_json.Account))) {\n this.emit('error', new RippleError('tejSecretUnknown', 'Missing secret'));\n return false;\n }\n\n if (typeof this.tx_json.SigningPubKey === 'undefined') {\n try {\n var seed = Seed.from_json(this._secret);\n var key = seed.get_key(this.tx_json.Account);\n this.tx_json.SigningPubKey = key.to_hex_pub();\n } catch(e) {\n this.emit('error', new RippleError('tejSecretInvalid', 'Invalid secret'));\n return false;\n }\n }\n\n // If the Fee hasn't been set, one needs to be computed by\n // an assigned server\n if (this.remote && typeof this.tx_json.Fee === 'undefined') {\n if (this.remote.local_fee || !this.remote.trusted) {\n if (!(this.tx_json.Fee = this._computeFee())) {\n this.emit('error', new RippleError('tejUnconnected'));\n return;\n }\n }\n }\n\n if (Number(this.tx_json.Fee) > this._maxFee) {\n this.emit('error', new RippleError('tejMaxFeeExceeded', 'Max fee exceeded'));\n return false;\n }\n\n // Set canonical flag - this enables canonicalized signature checking\n if (this.remote && this.remote.local_signing && this.canonical) {\n this.tx_json.Flags |= Transaction.flags.Universal.FullyCanonicalSig;\n\n // JavaScript converts operands to 32-bit signed ints before doing bitwise\n // operations. We need to convert it back to an unsigned int.\n this.tx_json.Flags = this.tx_json.Flags >>> 0;\n }\n\n return this.tx_json;\n};\n\nTransaction.prototype.serialize = function() {\n return SerializedObject.from_json(this.tx_json);\n};\n\nTransaction.prototype.signingHash = function() {\n return this.hash(config.testnet ? 'HASH_TX_SIGN_TESTNET' : 'HASH_TX_SIGN');\n};\n\nTransaction.prototype.hash = function(prefix, as_uint256) {\n if (typeof prefix === 'string') {\n if (typeof hashprefixes[prefix] === 'undefined') {\n throw new Error('Unknown hashing prefix requested.');\n }\n prefix = hashprefixes[prefix];\n } else if (!prefix) {\n prefix = hashprefixes.HASH_TX_ID;\n }\n\n var hash = SerializedObject.from_json(this.tx_json).hash(prefix);\n\n return as_uint256 ? hash : hash.to_hex();\n};\n\nTransaction.prototype.sign = function(callback) {\n var callback = typeof callback === 'function' ? callback : function(){};\n var seed = Seed.from_json(this._secret);\n\n var prev_sig = this.tx_json.TxnSignature;\n delete this.tx_json.TxnSignature;\n\n var hash = this.signingHash();\n\n // If the hash is the same, we can re-use the previous signature\n if (prev_sig && hash === this.previousSigningHash) {\n this.tx_json.TxnSignature = prev_sig;\n callback();\n return this;\n }\n\n var key = seed.get_key(this.tx_json.Account);\n var sig = key.sign(hash, 0);\n var hex = sjcl.codec.hex.fromBits(sig).toUpperCase();\n\n this.tx_json.TxnSignature = hex;\n this.previousSigningHash = hash;\n\n callback();\n\n return this;\n};\n\n/**\n * Add a ID to list of submitted IDs for this transaction\n */\n\nTransaction.prototype.addId = function(hash) {\n if (this.submittedIDs.indexOf(hash) === -1) {\n this.submittedIDs.unshift(hash);\n this.emit('signed', hash);\n this.emit('save');\n }\n};\n\n/**\n * Find ID within list of submitted IDs for this transaction\n */\n\nTransaction.prototype.findId = function(cache) {\n var result;\n\n for (var i=0; i build: true, to have server blindly construct a path.\n//\n// \"blindly\" because the sender has no idea of the actual cost except that is must be less than send max.\nTransaction.prototype.buildPath = function(build) {\n this._build_path = build;\n return this;\n};\n\n// tag should be undefined or a 32 bit integer.\n// YYY Add range checking for tag.\nTransaction.prototype.destinationTag = function(tag) {\n if (tag !== void(0)) {\n this.tx_json.DestinationTag = tag;\n }\n return this;\n};\n\nTransaction.prototype.invoiceID = function(id) {\n if (typeof id === 'string') {\n while (id.length < 64) {\n id += '0';\n }\n this.tx_json.InvoiceID = id;\n }\n return this;\n};\n\nTransaction.prototype.clientID = function(id) {\n if (typeof id === 'string') {\n this._clientID = id;\n }\n return this;\n};\n\nTransaction.prototype.lastLedger = function(sequence) {\n if (typeof sequence === 'number') {\n this._setLastLedger = true;\n this.tx_json.LastLedgerSequence = sequence;\n }\n return this;\n};\n\nTransaction._pathRewrite = function(path) {\n if (!Array.isArray(path)) {\n return;\n }\n\n var newPath = path.map(function(node) {\n var newNode = { };\n\n if (node.hasOwnProperty('account')) {\n newNode.account = UInt160.json_rewrite(node.account);\n }\n\n if (node.hasOwnProperty('issuer')) {\n newNode.issuer = UInt160.json_rewrite(node.issuer);\n }\n\n if (node.hasOwnProperty('currency')) {\n newNode.currency = Currency.json_rewrite(node.currency);\n }\n\n if (node.hasOwnProperty('type_hex')) {\n newNode.type_hex = node.type_hex;\n }\n\n return newNode;\n });\n\n return newPath;\n};\n\nTransaction.prototype.pathAdd = function(path) {\n if (Array.isArray(path)) {\n this.tx_json.Paths = this.tx_json.Paths || [];\n this.tx_json.Paths.push(Transaction._pathRewrite(path));\n }\n return this;\n};\n\n// --> paths: undefined or array of path\n// // A path is an array of objects containing some combination of: account, currency, issuer\n\nTransaction.prototype.paths = function(paths) {\n if (Array.isArray(paths)) {\n for (var i=0, l=paths.length; i rate: In billionths.\nTransaction.prototype.transferRate = function(rate) {\n this.tx_json.TransferRate = Number(rate);\n\n if (this.tx_json.TransferRate < 1e9) {\n throw new Error('invalidTransferRate');\n }\n\n return this;\n};\n\n// Add flags to a transaction.\n// --> flags: undefined, _flag_, or [ _flags_ ]\nTransaction.prototype.setFlags = function(flags) {\n if (flags === void(0)) {\n return this;\n }\n\n if (typeof flags === 'number') {\n this.tx_json.Flags = flags;\n return this;\n }\n\n var flag_set = Array.isArray(flags) ? flags : Array.prototype.slice.call(arguments);\n var transaction_flags = Transaction.flags[this.tx_json.TransactionType] || { };\n\n for (var i=0, l=flag_set.length; i expiration : if not undefined, Date or Number\n// --> cancel_sequence : if not undefined, Sequence\nTransaction.prototype.offerCreate = function(src, taker_pays, taker_gets, expiration, cancel_sequence) {\n if (typeof src === 'object') {\n var options = src;\n cancel_sequence = options.cancel_sequence;\n expiration = options.expiration;\n taker_gets = options.taker_gets || options.sell;\n taker_pays = options.taker_pays || options.buy;\n src = options.source || options.from || options.account;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this.tx_json.TransactionType = 'OfferCreate';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.TakerPays = Amount.json_rewrite(taker_pays);\n this.tx_json.TakerGets = Amount.json_rewrite(taker_gets);\n\n if (expiration) {\n this.tx_json.Expiration = utils.time.toRipple(expiration);\n }\n\n if (cancel_sequence) {\n this.tx_json.OfferSequence = Number(cancel_sequence);\n }\n\n return this;\n};\n\n/**\n * Construct a 'SetRegularKey' transaction.\n * If the RegularKey is set, the private key that corresponds to\n * it can be used to sign transactions instead of the master key\n *\n * The RegularKey must be a valid Ripple Address, or a Hash160 of\n * the public key corresponding to the new private signing key.\n */\n\nTransaction.prototype.setRegularKey = function(src, regular_key) {\n if (typeof src === 'object') {\n var options = src;\n src = options.address || options.account || options.from;\n regular_key = options.regular_key;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n if (!UInt160.is_valid(regular_key)) {\n throw new Error('RegularKey must be a valid Ripple Address (a Hash160 of the public key)');\n }\n\n this.tx_json.TransactionType = 'SetRegularKey';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.RegularKey = UInt160.json_rewrite(regular_key);\n\n return this;\n};\n\n// Construct a 'payment' transaction.\n//\n// When a transaction is submitted:\n// - If the connection is reliable and the server is not merely forwarding and is not malicious,\n// --> src : UInt160 or String\n// --> dst : UInt160 or String\n// --> deliver_amount : Amount or String.\n//\n// Options:\n// .paths()\n// .build_path()\n// .destination_tag()\n// .path_add()\n// .secret()\n// .send_max()\n// .set_flags()\n// .source_tag()\nTransaction.prototype.payment = function(src, dst, amount) {\n if (typeof src === 'object') {\n var options = src;\n amount = options.amount;\n dst = options.destination || options.to;\n src = options.source || options.from || options.account;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Payment source address invalid');\n }\n\n if (!UInt160.is_valid(dst)) {\n throw new Error('Payment destination address invalid');\n }\n\n this.tx_json.TransactionType = 'Payment';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.Amount = Amount.json_rewrite(amount);\n this.tx_json.Destination = UInt160.json_rewrite(dst);\n\n return this;\n};\n\nTransaction.prototype.trustSet =\nTransaction.prototype.rippleLineSet = function(src, limit, quality_in, quality_out) {\n if (typeof src === 'object') {\n var options = src;\n quality_out = options.quality_out;\n quality_in = options.quality_in;\n limit = options.limit;\n src = options.source || options.from || options.account;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this.tx_json.TransactionType = 'TrustSet';\n this.tx_json.Account = UInt160.json_rewrite(src);\n\n if (limit !== void(0)) {\n this.tx_json.LimitAmount = Amount.json_rewrite(limit);\n }\n\n if (quality_in) {\n this.tx_json.QualityIn = quality_in;\n }\n\n if (quality_out) {\n this.tx_json.QualityOut = quality_out;\n }\n\n // XXX Throw an error if nothing is set.\n\n return this;\n};\n\n// Submit a transaction to the network.\nTransaction.prototype.submit = function(callback) {\n var self = this;\n\n this.callback = (typeof callback === 'function') ? callback : function(){};\n\n function transactionError(error, message) {\n if (!(error instanceof RippleError)) {\n error = new RippleError(error, message);\n }\n self.callback(error);\n };\n\n this._errorHandler = transactionError;\n\n function transactionSuccess(message) {\n self.callback(null, message);\n };\n\n this._successHandler = transactionSuccess;\n\n this.on('error', function(){});\n\n var account = this.tx_json.Account;\n\n if (!UInt160.is_valid(account)) {\n return this.emit('error', new RippleError('tejInvalidAccount', 'Account is missing or invalid'));\n }\n\n // YYY Might check paths for invalid accounts.\n this.remote.account(account).submit(this);\n\n return this;\n};\n\nTransaction.prototype.abort = function(callback) {\n var callback = (typeof callback === 'function') ? callback : function(){};\n if (!this.finalized) {\n this.once('final', callback);\n this.emit('abort');\n }\n};\n\nTransaction.prototype.summary = function() {\n return Transaction.summary.call(this);\n};\n\nTransaction.summary = function() {\n var result = {\n tx_json: this.tx_json,\n clientID: this._clientID,\n submittedIDs: this.submittedIDs,\n submissionAttempts: this.attempts,\n submitIndex: this.submitIndex,\n initialSubmitIndex: this.initialSubmitIndex,\n lastLedgerSequence: this.lastLedgerSequence,\n state: this.state,\n server: this._server ? this._server._opts.url : void(0),\n finalized: this.finalized\n };\n\n if (this.result) {\n result.result = {\n engine_result : this.result.engine_result,\n engine_result_message: this.result.engine_result_message,\n ledger_hash : this.result.ledger_hash,\n ledger_index : this.result.ledger_index,\n transaction_hash : this.result.tx_json.hash\n };\n }\n\n return result;\n};\n\nexports.Transaction = Transaction;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 5\n// module.readableIdentifier = ./src/js/ripple/transaction.js\n//@ sourceURL=webpack-module:///./src/js/ripple/transaction.js"); + eval("// Transactions\n//\n// Construction:\n// remote.transaction() // Build a transaction object.\n// .offer_create(...) // Set major parameters.\n// .set_flags() // Set optional parameters.\n// .on() // Register for events.\n// .submit(); // Send to network.\n//\n// Events:\n// 'success' : Transaction submitted without error.\n// 'error' : Error submitting transaction.\n// 'proposed' : Advisory proposed status transaction.\n// - A client should expect 0 to multiple results.\n// - Might not get back. The remote might just forward the transaction.\n// - A success could be reverted in final.\n// - local error: other remotes might like it.\n// - malformed error: local server thought it was malformed.\n// - The client should only trust this when talking to a trusted server.\n// 'final' : Final status of transaction.\n// - Only expect a final from dishonest servers after a tesSUCCESS or ter*.\n// 'lost' : Gave up looking for on ledger_closed.\n// 'pending' : Transaction was not found on ledger_closed.\n// 'state' : Follow the state of a transaction.\n// 'client_submitted' - Sent to remote\n// |- 'remoteError' - Remote rejected transaction.\n// \\- 'client_proposed' - Remote provisionally accepted transaction.\n// |- 'client_missing' - Transaction has not appeared in ledger as expected.\n// | |\\- 'client_lost' - No longer monitoring missing transaction.\n// |/\n// |- 'tesSUCCESS' - Transaction in ledger as expected.\n// |- 'ter...' - Transaction failed.\n// \\- 'tec...' - Transaction claimed fee only.\n//\n// Notes:\n// - All transactions including those with local and malformed errors may be\n// forwarded anyway.\n// - A malicous server can:\n// - give any proposed result.\n// - it may declare something correct as incorrect or something incorrect as correct.\n// - it may not communicate with the rest of the network.\n// - may or may not forward.\n//\n\nvar EventEmitter = __webpack_require__(36).EventEmitter;\nvar util = __webpack_require__(37);\nvar utils = __webpack_require__(19);\nvar sjcl = __webpack_require__(19).sjcl;\nvar Amount = __webpack_require__(3).Amount;\nvar Currency = __webpack_require__(3).Currency;\nvar UInt160 = __webpack_require__(3).UInt160;\nvar Seed = __webpack_require__(10).Seed;\nvar SerializedObject = __webpack_require__(12).SerializedObject;\nvar RippleError = __webpack_require__(13).RippleError;\nvar hashprefixes = __webpack_require__(27);\nvar config = __webpack_require__(21);\n\nfunction Transaction(remote) {\n EventEmitter.call(this);\n\n var self = this;\n\n var remote = remote || { };\n\n this.remote = remote;\n\n // Transaction data\n this.tx_json = { Flags: 0 };\n\n this._secret = void(0);\n this._build_path = false;\n this._maxFee = this.remote.max_fee;\n\n this.state = 'unsubmitted';\n this.finalized = false;\n this.previousSigningHash = void(0);\n\n // Index at which transaction was submitted\n this.submitIndex = void(0);\n\n // Canonical signing setting defaults to the Remote's configuration\n this.canonical = (typeof remote === 'object') ? Boolean(remote.canonical_signing) : true;\n\n // We aren't clever enough to eschew preventative measures so we keep an array\n // of all submitted transactionIDs (which can change due to load_factor\n // effecting the Fee amount). This should be populated with a transactionID\n // any time it goes on the network\n this.submittedIDs = [ ];\n\n this.once('success', function(message) {\n self.finalize(message);\n self.setState('validated');\n self.emit('cleanup', message);\n });\n\n this.once('error', function(message) {\n self.finalize(message);\n self.setState('failed');\n self.emit('cleanup', message);\n });\n\n this.once('submitted', function() {\n self.setState('submitted');\n });\n\n this.once('proposed', function() {\n self.setState('pending');\n });\n};\n\nutil.inherits(Transaction, EventEmitter);\n\n// XXX This needs to be determined from the network.\nTransaction.fee_units = {\n default: 10\n};\n\nTransaction.flags = {\n // Universal flags can apply to any transaction type\n Universal: {\n FullyCanonicalSig: 0x80000000\n },\n\n AccountSet: {\n RequireDestTag: 0x00010000,\n OptionalDestTag: 0x00020000,\n RequireAuth: 0x00040000,\n OptionalAuth: 0x00080000,\n DisallowXRP: 0x00100000,\n AllowXRP: 0x00200000\n },\n\n TrustSet: {\n SetAuth: 0x00010000,\n NoRipple: 0x00020000,\n SetNoRipple: 0x00020000,\n ClearNoRipple: 0x00040000,\n SetFreeze: 0x00100000,\n ClearFreeze: 0x00200000\n },\n\n OfferCreate: {\n Passive: 0x00010000,\n ImmediateOrCancel: 0x00020000,\n FillOrKill: 0x00040000,\n Sell: 0x00080000\n },\n\n Payment: {\n NoRippleDirect: 0x00010000,\n PartialPayment: 0x00020000,\n LimitQuality: 0x00040000\n }\n};\n\n// The following are integer (as opposed to bit) flags\n// that can be set for particular transactions in the\n// SetFlag or ClearFlag field\nTransaction.set_clear_flags = {\n AccountSet: {\n asfRequireDest: 1,\n asfRequireAuth: 2,\n asfDisallowXRP: 3,\n asfDisableMaster: 4,\n asfNoFreeze: 6,\n asfGlobalFreeze: 7\n }\n};\n\nTransaction.MEMO_TYPES = {\n};\n\nTransaction.formats = __webpack_require__(18).tx;\n\nTransaction.prototype.consts = {\n telLOCAL_ERROR: -399,\n temMALFORMED: -299,\n tefFAILURE: -199,\n terRETRY: -99,\n tesSUCCESS: 0,\n tecCLAIMED: 100\n};\n\nTransaction.from_json = function(j) {\n return (new Transaction()).parseJson(j);\n};\n\nTransaction.prototype.parseJson = function(v) {\n this.tx_json = v;\n return this;\n};\n\nTransaction.prototype.isTelLocal = function(ter) {\n return ter >= this.consts.telLOCAL_ERROR && ter < this.consts.temMALFORMED;\n};\n\nTransaction.prototype.isTemMalformed = function(ter) {\n return ter >= this.consts.temMALFORMED && ter < this.consts.tefFAILURE;\n};\n\nTransaction.prototype.isTefFailure = function(ter) {\n return ter >= this.consts.tefFAILURE && ter < this.consts.terRETRY;\n};\n\nTransaction.prototype.isTerRetry = function(ter) {\n return ter >= this.consts.terRETRY && ter < this.consts.tesSUCCESS;\n};\n\nTransaction.prototype.isTepSuccess = function(ter) {\n return ter >= this.consts.tesSUCCESS;\n};\n\nTransaction.prototype.isTecClaimed = function(ter) {\n return ter >= this.consts.tecCLAIMED;\n};\n\nTransaction.prototype.isRejected = function(ter) {\n return this.isTelLocal(ter) || this.isTemMalformed(ter) || this.isTefFailure(ter);\n};\n\nTransaction.prototype.setState = function(state) {\n if (this.state !== state) {\n this.state = state;\n this.emit('state', state);\n this.emit('save');\n }\n};\n\nTransaction.prototype.finalize = function(message) {\n this.finalized = true;\n\n if (this.result) {\n this.result.ledger_index = message.ledger_index;\n this.result.ledger_hash = message.ledger_hash;\n } else {\n this.result = message;\n this.result.tx_json = this.tx_json;\n }\n\n return this;\n};\n\nTransaction.prototype._accountSecret = function(account) {\n return this.remote.secrets[account];\n};\n\n/**\n * Returns the number of fee units this transaction will cost.\n *\n * Each Ripple transaction based on its type and makeup costs a certain number\n * of fee units. The fee units are calculated on a per-server basis based on the\n * current load on both the network and the server.\n *\n * @see https://ripple.com/wiki/Transaction_Fee\n *\n * @return {Number} Number of fee units for this transaction.\n */\n\nTransaction.prototype._getFeeUnits =\nTransaction.prototype.feeUnits = function() {\n return Transaction.fee_units['default'];\n};\n\n/**\n * Compute median server fee\n */\n\nTransaction.prototype._computeFee = function() {\n var servers = this.remote._servers;\n var fees = [ ];\n\n for (var i=0; i b) {\n return 1;\n } else if (a < b) {\n return -1;\n } else {\n return 0;\n }\n });\n\n var midInd = Math.floor(fees.length / 2);\n\n var median = fees.length % 2 === 0\n ? Math.floor(0.5 + (fees[midInd] + fees[midInd - 1]) / 2)\n : fees[midInd];\n\n return String(median);\n};\n\n/**\n * Attempts to complete the transaction for submission.\n *\n * This function seeks to fill out certain fields, such as Fee and\n * SigningPubKey, which can be determined by the library based on network\n * information and other fields.\n */\n\nTransaction.prototype.complete = function() {\n if (this.remote) {\n if (!this.remote.trusted && !this.remote.local_signing) {\n this.emit('error', new RippleError('tejServerUntrusted', 'Attempt to give secret to untrusted server'));\n return false;\n }\n }\n\n // Try to auto-fill the secret\n if (!this._secret && !(this._secret = this._accountSecret(this.tx_json.Account))) {\n this.emit('error', new RippleError('tejSecretUnknown', 'Missing secret'));\n return false;\n }\n\n if (typeof this.tx_json.SigningPubKey === 'undefined') {\n try {\n var seed = Seed.from_json(this._secret);\n var key = seed.get_key(this.tx_json.Account);\n this.tx_json.SigningPubKey = key.to_hex_pub();\n } catch(e) {\n this.emit('error', new RippleError('tejSecretInvalid', 'Invalid secret'));\n return false;\n }\n }\n\n // If the Fee hasn't been set, one needs to be computed by\n // an assigned server\n if (this.remote && typeof this.tx_json.Fee === 'undefined') {\n if (this.remote.local_fee || !this.remote.trusted) {\n if (!(this.tx_json.Fee = this._computeFee())) {\n this.emit('error', new RippleError('tejUnconnected'));\n return;\n }\n }\n }\n\n if (Number(this.tx_json.Fee) > this._maxFee) {\n this.emit('error', new RippleError('tejMaxFeeExceeded', 'Max fee exceeded'));\n return false;\n }\n\n // Set canonical flag - this enables canonicalized signature checking\n if (this.remote && this.remote.local_signing && this.canonical) {\n this.tx_json.Flags |= Transaction.flags.Universal.FullyCanonicalSig;\n\n // JavaScript converts operands to 32-bit signed ints before doing bitwise\n // operations. We need to convert it back to an unsigned int.\n this.tx_json.Flags = this.tx_json.Flags >>> 0;\n }\n\n return this.tx_json;\n};\n\nTransaction.prototype.serialize = function() {\n return SerializedObject.from_json(this.tx_json);\n};\n\nTransaction.prototype.signingHash = function() {\n return this.hash(config.testnet ? 'HASH_TX_SIGN_TESTNET' : 'HASH_TX_SIGN');\n};\n\nTransaction.prototype.hash = function(prefix, as_uint256) {\n if (typeof prefix === 'string') {\n if (typeof hashprefixes[prefix] === 'undefined') {\n throw new Error('Unknown hashing prefix requested.');\n }\n prefix = hashprefixes[prefix];\n } else if (!prefix) {\n prefix = hashprefixes.HASH_TX_ID;\n }\n\n var hash = SerializedObject.from_json(this.tx_json).hash(prefix);\n\n return as_uint256 ? hash : hash.to_hex();\n};\n\nTransaction.prototype.sign = function(callback) {\n var callback = typeof callback === 'function' ? callback : function(){};\n var seed = Seed.from_json(this._secret);\n\n var prev_sig = this.tx_json.TxnSignature;\n delete this.tx_json.TxnSignature;\n\n var hash = this.signingHash();\n\n // If the hash is the same, we can re-use the previous signature\n if (prev_sig && hash === this.previousSigningHash) {\n this.tx_json.TxnSignature = prev_sig;\n callback();\n return this;\n }\n\n var key = seed.get_key(this.tx_json.Account);\n var sig = key.sign(hash, 0);\n var hex = sjcl.codec.hex.fromBits(sig).toUpperCase();\n\n this.tx_json.TxnSignature = hex;\n this.previousSigningHash = hash;\n\n callback();\n\n return this;\n};\n\n/**\n * Add a ID to list of submitted IDs for this transaction\n */\n\nTransaction.prototype.addId = function(hash) {\n if (this.submittedIDs.indexOf(hash) === -1) {\n this.submittedIDs.unshift(hash);\n this.emit('signed', hash);\n this.emit('save');\n }\n};\n\n/**\n * Find ID within list of submitted IDs for this transaction\n */\n\nTransaction.prototype.findId = function(cache) {\n var result;\n\n for (var i=0; i build: true, to have server blindly construct a path.\n//\n// \"blindly\" because the sender has no idea of the actual cost except that is must be less than send max.\nTransaction.prototype.buildPath = function(build) {\n this._build_path = build;\n return this;\n};\n\n// tag should be undefined or a 32 bit integer.\n// YYY Add range checking for tag.\nTransaction.prototype.destinationTag = function(tag) {\n if (tag !== void(0)) {\n this.tx_json.DestinationTag = tag;\n }\n return this;\n};\n\nTransaction.prototype.invoiceID = function(id) {\n if (typeof id === 'string') {\n while (id.length < 64) {\n id += '0';\n }\n this.tx_json.InvoiceID = id;\n }\n return this;\n};\n\nTransaction.prototype.clientID = function(id) {\n if (typeof id === 'string') {\n this._clientID = id;\n }\n return this;\n};\n\nTransaction.prototype.lastLedger = function(sequence) {\n if (typeof sequence === 'number') {\n this._setLastLedger = true;\n this.tx_json.LastLedgerSequence = sequence;\n }\n return this;\n};\n\nTransaction._pathRewrite = function(path) {\n if (!Array.isArray(path)) {\n return;\n }\n\n var newPath = path.map(function(node) {\n var newNode = { };\n\n if (node.hasOwnProperty('account')) {\n newNode.account = UInt160.json_rewrite(node.account);\n }\n\n if (node.hasOwnProperty('issuer')) {\n newNode.issuer = UInt160.json_rewrite(node.issuer);\n }\n\n if (node.hasOwnProperty('currency')) {\n newNode.currency = Currency.json_rewrite(node.currency);\n }\n\n if (node.hasOwnProperty('type_hex')) {\n newNode.type_hex = node.type_hex;\n }\n\n return newNode;\n });\n\n return newPath;\n};\n\nTransaction.prototype.pathAdd = function(path) {\n if (Array.isArray(path)) {\n this.tx_json.Paths = this.tx_json.Paths || [];\n this.tx_json.Paths.push(Transaction._pathRewrite(path));\n }\n return this;\n};\n\n// --> paths: undefined or array of path\n// // A path is an array of objects containing some combination of: account, currency, issuer\n\nTransaction.prototype.paths = function(paths) {\n if (Array.isArray(paths)) {\n for (var i=0, l=paths.length; i rate: In billionths.\nTransaction.prototype.transferRate = function(rate) {\n this.tx_json.TransferRate = Number(rate);\n\n if (this.tx_json.TransferRate < 1e9) {\n throw new Error('invalidTransferRate');\n }\n\n return this;\n};\n\n// Add flags to a transaction.\n// --> flags: undefined, _flag_, or [ _flags_ ]\nTransaction.prototype.setFlags = function(flags) {\n if (flags === void(0)) {\n return this;\n }\n\n if (typeof flags === 'number') {\n this.tx_json.Flags = flags;\n return this;\n }\n\n var flag_set = Array.isArray(flags) ? flags : Array.prototype.slice.call(arguments);\n var transaction_flags = Transaction.flags[this.tx_json.TransactionType] || { };\n\n for (var i=0, l=flag_set.length; i expiration : if not undefined, Date or Number\n// --> cancel_sequence : if not undefined, Sequence\nTransaction.prototype.offerCreate = function(src, taker_pays, taker_gets, expiration, cancel_sequence) {\n if (typeof src === 'object') {\n var options = src;\n cancel_sequence = options.cancel_sequence;\n expiration = options.expiration;\n taker_gets = options.taker_gets || options.sell;\n taker_pays = options.taker_pays || options.buy;\n src = options.source || options.from || options.account;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this.tx_json.TransactionType = 'OfferCreate';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.TakerPays = Amount.json_rewrite(taker_pays);\n this.tx_json.TakerGets = Amount.json_rewrite(taker_gets);\n\n if (expiration) {\n this.tx_json.Expiration = utils.time.toRipple(expiration);\n }\n\n if (cancel_sequence) {\n this.tx_json.OfferSequence = Number(cancel_sequence);\n }\n\n return this;\n};\n\n/**\n * Construct a 'SetRegularKey' transaction.\n * If the RegularKey is set, the private key that corresponds to\n * it can be used to sign transactions instead of the master key\n *\n * The RegularKey must be a valid Ripple Address, or a Hash160 of\n * the public key corresponding to the new private signing key.\n */\n\nTransaction.prototype.setRegularKey = function(src, regular_key) {\n if (typeof src === 'object') {\n var options = src;\n src = options.address || options.account || options.from;\n regular_key = options.regular_key;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n if (!UInt160.is_valid(regular_key)) {\n throw new Error('RegularKey must be a valid Ripple Address (a Hash160 of the public key)');\n }\n\n this.tx_json.TransactionType = 'SetRegularKey';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.RegularKey = UInt160.json_rewrite(regular_key);\n\n return this;\n};\n\n// Construct a 'payment' transaction.\n//\n// When a transaction is submitted:\n// - If the connection is reliable and the server is not merely forwarding and is not malicious,\n// --> src : UInt160 or String\n// --> dst : UInt160 or String\n// --> deliver_amount : Amount or String.\n//\n// Options:\n// .paths()\n// .build_path()\n// .destination_tag()\n// .path_add()\n// .secret()\n// .send_max()\n// .set_flags()\n// .source_tag()\nTransaction.prototype.payment = function(src, dst, amount) {\n if (typeof src === 'object') {\n var options = src;\n amount = options.amount;\n dst = options.destination || options.to;\n src = options.source || options.from || options.account;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Payment source address invalid');\n }\n\n if (!UInt160.is_valid(dst)) {\n throw new Error('Payment destination address invalid');\n }\n\n this.tx_json.TransactionType = 'Payment';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.Amount = Amount.json_rewrite(amount);\n this.tx_json.Destination = UInt160.json_rewrite(dst);\n\n return this;\n};\n\nTransaction.prototype.trustSet =\nTransaction.prototype.rippleLineSet = function(src, limit, quality_in, quality_out) {\n if (typeof src === 'object') {\n var options = src;\n quality_out = options.quality_out;\n quality_in = options.quality_in;\n limit = options.limit;\n src = options.source || options.from || options.account;\n }\n\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this.tx_json.TransactionType = 'TrustSet';\n this.tx_json.Account = UInt160.json_rewrite(src);\n\n if (limit !== void(0)) {\n this.tx_json.LimitAmount = Amount.json_rewrite(limit);\n }\n\n if (quality_in) {\n this.tx_json.QualityIn = quality_in;\n }\n\n if (quality_out) {\n this.tx_json.QualityOut = quality_out;\n }\n\n // XXX Throw an error if nothing is set.\n\n return this;\n};\n\n// Submit a transaction to the network.\nTransaction.prototype.submit = function(callback) {\n var self = this;\n\n this.callback = (typeof callback === 'function') ? callback : function(){};\n\n function transactionError(error, message) {\n if (!(error instanceof RippleError)) {\n error = new RippleError(error, message);\n }\n self.callback(error);\n };\n\n this._errorHandler = transactionError;\n\n function transactionSuccess(message) {\n self.callback(null, message);\n };\n\n this._successHandler = transactionSuccess;\n\n this.on('error', function(){});\n\n var account = this.tx_json.Account;\n\n if (!UInt160.is_valid(account)) {\n return this.emit('error', new RippleError('tejInvalidAccount', 'Account is missing or invalid'));\n }\n\n // YYY Might check paths for invalid accounts.\n this.remote.account(account).submit(this);\n\n return this;\n};\n\nTransaction.prototype.abort = function(callback) {\n var callback = (typeof callback === 'function') ? callback : function(){};\n if (!this.finalized) {\n this.once('final', callback);\n this.emit('abort');\n }\n};\n\nTransaction.prototype.summary = function() {\n return Transaction.summary.call(this);\n};\n\nTransaction.summary = function() {\n var result = {\n tx_json: this.tx_json,\n clientID: this._clientID,\n submittedIDs: this.submittedIDs,\n submissionAttempts: this.attempts,\n submitIndex: this.submitIndex,\n initialSubmitIndex: this.initialSubmitIndex,\n lastLedgerSequence: this.lastLedgerSequence,\n state: this.state,\n server: this._server ? this._server._opts.url : void(0),\n finalized: this.finalized\n };\n\n if (this.result) {\n result.result = {\n engine_result : this.result.engine_result,\n engine_result_message: this.result.engine_result_message,\n ledger_hash : this.result.ledger_hash,\n ledger_index : this.result.ledger_index,\n transaction_hash : this.result.tx_json.hash\n };\n }\n\n return result;\n};\n\nexports.Transaction = Transaction;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 5\n// module.readableIdentifier = ./src/js/ripple/transaction.js\n//@ sourceURL=webpack-module:///./src/js/ripple/transaction.js"); /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { - eval("var extend = __webpack_require__(43);\nvar UInt160 = __webpack_require__(8).UInt160;\nvar utils = __webpack_require__(19);\nvar Float = __webpack_require__(27).Float;\n\n//\n// Currency support\n//\n\nvar Currency = extend(function() {\n // Internal form: 0 = XRP. 3 letter-code.\n // XXX Internal should be 0 or hex with three letter annotation when valid.\n\n // Json form:\n // '', 'XRP', '0': 0\n // 3-letter code: ...\n // XXX Should support hex, C++ doesn't currently allow it.\n\n this._value = NaN;\n\n this._update();\n}, UInt160);\n\nCurrency.prototype = extend({}, UInt160.prototype);\nCurrency.prototype.constructor = Currency;\n\nCurrency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000';\n\n/**\n * Tries to correctly interpret a Currency as entered by a user.\n *\n * Examples:\n *\n * USD => currency\n * USD - Dollar => currency with optional full currency name\n * XAU (-0.5%pa) => XAU with 0.5% effective demurrage rate per year\n * XAU - Gold (-0.5%pa) => Optionally allowed full currency name\n * USD (1%pa) => US dollars with 1% effective interest per year\n * INR - Indian Rupees => Optional full currency name with spaces\n * TYX - 30-Year Treasuries => Optional full currency with numbers and a dash\n * TYX - 30-Year Treasuries (1.5%pa) => Optional full currency with numbers, dash and interest rate\n *\n * The regular expression below matches above cases, broken down for better understanding:\n *\n * ^\\s* // start with any amount of whitespace\n * ([a-zA-Z]{3}|[0-9]{3}) // either 3 letter alphabetic currency-code or 3 digit numeric currency-code. See ISO 4217\n * (\\s*-\\s*[- \\w]+) // optional full currency name following the dash after currency code,\n * full currency code can contain letters, numbers and dashes\n * (\\s*\\(-?\\d+\\.?\\d*%pa\\))? // optional demurrage rate, has optional - and . notation (-0.5%pa)\n * \\s*$ // end with any amount of whitespace\n *\n */\nCurrency.prototype.human_RE = /^\\s*([a-zA-Z]{3}|[0-9]{3})(\\s*-\\s*[- \\w]+)?(\\s*\\(-?\\d+\\.?\\d*%pa\\))?\\s*$/;\n\nCurrency.from_json = function(j, shouldInterpretXrpAsIou) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_json(j, shouldInterpretXrpAsIou);\n }\n};\n\nCurrency.from_human = function(j, opts) {\n return (new Currency().parse_human(j, opts));\n}\n\n// this._value = NaN on error.\nCurrency.prototype.parse_json = function(j, shouldInterpretXrpAsIou) {\n this._value = NaN;\n\n switch (typeof j) {\n case 'string':\n\n if (!j || /^(0|XRP)$/.test(j)) {\n if (shouldInterpretXrpAsIou) {\n this.parse_hex(Currency.HEX_CURRENCY_BAD);\n } else {\n this.parse_hex(Currency.HEX_ZERO);\n }\n break;\n }\n\n // match the given string to see if it's in an allowed format\n var matches = String(j).match(this.human_RE);\n\n if (matches) {\n\n var currencyCode = matches[1];\n // the full currency is matched as it is part of the valid currency format, but not stored\n // var full_currency = matches[2] || '';\n var interest = matches[3] || '';\n\n // interest is defined as interest per year, per annum (pa)\n var percentage = interest.match(/(-?\\d+\\.?\\d+)/);\n\n currencyCode = currencyCode.toUpperCase();\n\n var currencyData = utils.arraySet(20, 0);\n\n if (percentage) {\n /*\n * 20 byte layout of a interest bearing currency\n *\n * 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n * CURCODE- DATE------- RATE------------------- RESERVED---\n */\n\n // byte 1 for type, use '1' to denote demurrage currency\n currencyData[0] = 1;\n\n // byte 2-4 for currency code\n currencyData[1] = currencyCode.charCodeAt(0) & 0xff;\n currencyData[2] = currencyCode.charCodeAt(1) & 0xff;\n currencyData[3] = currencyCode.charCodeAt(2) & 0xff;\n\n // byte 5-8 are for reference date, but should always be 0 so we won't fill it\n\n // byte 9-16 are for the interest\n percentage = parseFloat(percentage[0]);\n\n // the interest or demurrage is expressed as a yearly (per annum) value\n var secondsPerYear = 31536000; // 60 * 60 * 24 * 365\n\n // Calculating the interest e-fold\n // 0.5% demurrage is expressed 0.995, 0.005 less than 1\n // 0.5% interest is expressed as 1.005, 0.005 more than 1\n var interestEfold = secondsPerYear / Math.log(1 + percentage/100);\n var bytes = Float.toIEEE754Double(interestEfold);\n\n for (var i=0; i<=bytes.length; i++) {\n currencyData[8 + i] = bytes[i] & 0xff;\n }\n\n // the last 4 bytes are reserved for future use, so we won't fill those\n\n } else {\n currencyData[12] = currencyCode.charCodeAt(0) & 0xff;\n currencyData[13] = currencyCode.charCodeAt(1) & 0xff;\n currencyData[14] = currencyCode.charCodeAt(2) & 0xff;\n }\n\n this.parse_bytes(currencyData);\n } else {\n this.parse_hex(j);\n }\n break;\n\n case 'number':\n if (!isNaN(j)) {\n this.parse_number(j);\n }\n break;\n\n case 'object':\n if (j instanceof Currency) {\n this._value = j.copyTo({})._value;\n this._update();\n }\n break;\n }\n\n return this;\n};\n\n\nCurrency.prototype.parse_human = function(j) {\n return this.parse_json(j);\n};\n\n/**\n * Recalculate internal representation.\n *\n * You should never need to call this.\n */\nCurrency.prototype._update = function() {\n var bytes = this.to_bytes();\n\n // is it 0 everywhere except 12, 13, 14?\n var isZeroExceptInStandardPositions = true;\n\n if (!bytes) {\n return 'XRP';\n }\n\n this._native = false;\n this._type = -1;\n this._interest_start = NaN;\n this._interest_period = NaN;\n this._iso_code = '';\n\n for (var i=0; i<20; i++) {\n isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || bytes[i]===0);\n }\n\n if (isZeroExceptInStandardPositions) {\n this._iso_code = String.fromCharCode(bytes[12])\n + String.fromCharCode(bytes[13])\n + String.fromCharCode(bytes[14]);\n\n if (this._iso_code === '\\0\\0\\0') {\n this._native = true;\n this._iso_code = 'XRP';\n }\n\n this._type = 0;\n } else if (bytes[0] === 0x01) { // Demurrage currency\n this._iso_code = String.fromCharCode(bytes[1])\n + String.fromCharCode(bytes[2])\n + String.fromCharCode(bytes[3]);\n\n this._type = 1;\n this._interest_start = (bytes[4] << 24) +\n (bytes[5] << 16) +\n (bytes[6] << 8) +\n (bytes[7] );\n this._interest_period = Float.fromIEEE754Double(bytes.slice(8, 16));\n }\n};\n\n// XXX Probably not needed anymore?\n/*\nCurrency.prototype.parse_bytes = function(byte_array) {\n if (Array.isArray(byte_array) && byte_array.length === 20) {\n var result;\n // is it 0 everywhere except 12, 13, 14?\n var isZeroExceptInStandardPositions = true;\n\n for (var i=0; i<20; i++) {\n isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || byte_array[0]===0)\n }\n\n if (isZeroExceptInStandardPositions) {\n var currencyCode = String.fromCharCode(byte_array[12])\n + String.fromCharCode(byte_array[13])\n + String.fromCharCode(byte_array[14]);\n if (/^[A-Z0-9]{3}$/.test(currencyCode) && currencyCode !== 'XRP' ) {\n this._value = currencyCode;\n } else if (currencyCode === '\\0\\0\\0') {\n this._value = 0;\n } else {\n this._value = NaN;\n }\n } else {\n // XXX Should support non-standard currency codes\n this._value = NaN;\n }\n } else {\n this._value = NaN;\n }\n return this;\n};\n*/\n\nCurrency.prototype.is_native = function() {\n return this._native;\n};\n\n/**\n * Whether this currency is an interest-bearing/demurring currency.\n */\nCurrency.prototype.has_interest = function() {\n return this._type === 1 && !isNaN(this._interest_start) && !isNaN(this._interest_period);\n};\n\n/**\n *\n * @param referenceDate - number of seconds since the Ripple Epoch (0:00 on January 1, 2000 UTC)\n * used to calculate the interest over provided interval\n * pass in one years worth of seconds to ge the yearly interest\n * @returns {number} - interest for provided interval, can be negative for demurred currencies\n */\nCurrency.prototype.get_interest_at = function(referenceDate, decimals) {\n if (!this.has_interest) {\n return 0;\n }\n\n // use one year as a default period\n if (!referenceDate) {\n referenceDate = this._interest_start + 3600 * 24 * 365;\n }\n\n if (referenceDate instanceof Date) {\n referenceDate = utils.fromTimestamp(referenceDate.getTime());\n }\n\n // calculate interest by e-fold number\n return Math.exp((referenceDate - this._interest_start) / this._interest_period);\n};\n\nCurrency.prototype.get_interest_percentage_at = function(referenceDate, decimals) {\n var interest = this.get_interest_at(referenceDate, decimals);\n\n // convert to percentage\n var interest = (interest*100)-100;\n var decimalMultiplier = decimals ? Math.pow(10,decimals) : 100;\n\n // round to two decimals behind the dot\n return Math.round(interest*decimalMultiplier) / decimalMultiplier;\n};\n\n// XXX Currently we inherit UInt.prototype.is_valid, which is mostly fine.\n//\n// We could be doing further checks into the internal format of the\n// currency data, since there are some values that are invalid.\n//\n//Currency.prototype.is_valid = function() {\n// return this._value instanceof BigInteger && ...;\n//};\n\nCurrency.prototype.to_json = function(opts) {\n if (!this.is_valid()) {\n // XXX This is backwards compatible behavior, but probably not very good.\n return 'XRP';\n }\n\n var opts = opts || {};\n\n var currency;\n var fullName = opts && opts.full_name ? \" - \" + opts.full_name : \"\";\n\n // Any currency with standard properties and a valid code can be abbreviated\n // in the JSON wire format as the three character code.\n if (!opts.force_hex && /^[A-Z0-9]{3}$/.test(this._iso_code) && !this.has_interest()) {\n currency = this._iso_code + fullName;\n\n // If there is interest, append the annual interest to the full currency name\n } else if (!opts.force_hex && this.has_interest()) {\n var decimals = opts ? opts.decimals : undefined;\n currency = this._iso_code + fullName + \" (\" + this.get_interest_percentage_at(this._interest_start + 3600 * 24 * 365, decimals) + \"%pa)\";\n } else {\n\n // Fallback to returning the raw currency hex\n currency = this.to_hex();\n\n // XXX This is to maintain backwards compatibility, but it is very, very odd\n // behavior, so we should deprecate it and get rid of it as soon as\n // possible.\n if (currency === Currency.HEX_ONE) {\n currency = 1;\n }\n }\n\n return currency;\n};\n\nCurrency.prototype.to_human = function(opts) {\n // to_human() will always print the human-readable currency code if available.\n return this.to_json(opts);\n};\n\nCurrency.prototype.get_iso = function() {\n return this._iso_code;\n};\n\nexports.Currency = Currency;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 6\n// module.readableIdentifier = ./src/js/ripple/currency.js\n//@ sourceURL=webpack-module:///./src/js/ripple/currency.js"); + eval("var extend = __webpack_require__(43);\nvar UInt160 = __webpack_require__(8).UInt160;\nvar utils = __webpack_require__(19);\nvar Float = __webpack_require__(31).Float;\n\n//\n// Currency support\n//\n\nvar Currency = extend(function() {\n // Internal form: 0 = XRP. 3 letter-code.\n // XXX Internal should be 0 or hex with three letter annotation when valid.\n\n // Json form:\n // '', 'XRP', '0': 0\n // 3-letter code: ...\n // XXX Should support hex, C++ doesn't currently allow it.\n\n this._value = NaN;\n\n this._update();\n}, UInt160);\n\nCurrency.prototype = extend({}, UInt160.prototype);\nCurrency.prototype.constructor = Currency;\n\nCurrency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000';\n\n/**\n * Tries to correctly interpret a Currency as entered by a user.\n *\n * Examples:\n *\n * USD => currency\n * USD - Dollar => currency with optional full currency name\n * XAU (-0.5%pa) => XAU with 0.5% effective demurrage rate per year\n * XAU - Gold (-0.5%pa) => Optionally allowed full currency name\n * USD (1%pa) => US dollars with 1% effective interest per year\n * INR - Indian Rupees => Optional full currency name with spaces\n * TYX - 30-Year Treasuries => Optional full currency with numbers and a dash\n * TYX - 30-Year Treasuries (1.5%pa) => Optional full currency with numbers, dash and interest rate\n *\n * The regular expression below matches above cases, broken down for better understanding:\n *\n * ^\\s* // start with any amount of whitespace\n * ([a-zA-Z]{3}|[0-9]{3}) // either 3 letter alphabetic currency-code or 3 digit numeric currency-code. See ISO 4217\n * (\\s*-\\s*[- \\w]+) // optional full currency name following the dash after currency code,\n * full currency code can contain letters, numbers and dashes\n * (\\s*\\(-?\\d+\\.?\\d*%pa\\))? // optional demurrage rate, has optional - and . notation (-0.5%pa)\n * \\s*$ // end with any amount of whitespace\n *\n */\nCurrency.prototype.human_RE = /^\\s*([a-zA-Z]{3}|[0-9]{3})(\\s*-\\s*[- \\w]+)?(\\s*\\(-?\\d+\\.?\\d*%pa\\))?\\s*$/;\n\nCurrency.from_json = function(j, shouldInterpretXrpAsIou) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_json(j, shouldInterpretXrpAsIou);\n }\n};\n\nCurrency.from_human = function(j, opts) {\n return (new Currency().parse_human(j, opts));\n}\n\n// this._value = NaN on error.\nCurrency.prototype.parse_json = function(j, shouldInterpretXrpAsIou) {\n this._value = NaN;\n\n switch (typeof j) {\n case 'string':\n\n if (!j || /^(0|XRP)$/.test(j)) {\n if (shouldInterpretXrpAsIou) {\n this.parse_hex(Currency.HEX_CURRENCY_BAD);\n } else {\n this.parse_hex(Currency.HEX_ZERO);\n }\n break;\n }\n\n // match the given string to see if it's in an allowed format\n var matches = String(j).match(this.human_RE);\n\n if (matches) {\n\n var currencyCode = matches[1];\n // the full currency is matched as it is part of the valid currency format, but not stored\n // var full_currency = matches[2] || '';\n var interest = matches[3] || '';\n\n // interest is defined as interest per year, per annum (pa)\n var percentage = interest.match(/(-?\\d+\\.?\\d+)/);\n\n currencyCode = currencyCode.toUpperCase();\n\n var currencyData = utils.arraySet(20, 0);\n\n if (percentage) {\n /*\n * 20 byte layout of a interest bearing currency\n *\n * 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n * CURCODE- DATE------- RATE------------------- RESERVED---\n */\n\n // byte 1 for type, use '1' to denote demurrage currency\n currencyData[0] = 1;\n\n // byte 2-4 for currency code\n currencyData[1] = currencyCode.charCodeAt(0) & 0xff;\n currencyData[2] = currencyCode.charCodeAt(1) & 0xff;\n currencyData[3] = currencyCode.charCodeAt(2) & 0xff;\n\n // byte 5-8 are for reference date, but should always be 0 so we won't fill it\n\n // byte 9-16 are for the interest\n percentage = parseFloat(percentage[0]);\n\n // the interest or demurrage is expressed as a yearly (per annum) value\n var secondsPerYear = 31536000; // 60 * 60 * 24 * 365\n\n // Calculating the interest e-fold\n // 0.5% demurrage is expressed 0.995, 0.005 less than 1\n // 0.5% interest is expressed as 1.005, 0.005 more than 1\n var interestEfold = secondsPerYear / Math.log(1 + percentage/100);\n var bytes = Float.toIEEE754Double(interestEfold);\n\n for (var i=0; i<=bytes.length; i++) {\n currencyData[8 + i] = bytes[i] & 0xff;\n }\n\n // the last 4 bytes are reserved for future use, so we won't fill those\n\n } else {\n currencyData[12] = currencyCode.charCodeAt(0) & 0xff;\n currencyData[13] = currencyCode.charCodeAt(1) & 0xff;\n currencyData[14] = currencyCode.charCodeAt(2) & 0xff;\n }\n\n this.parse_bytes(currencyData);\n } else {\n this.parse_hex(j);\n }\n break;\n\n case 'number':\n if (!isNaN(j)) {\n this.parse_number(j);\n }\n break;\n\n case 'object':\n if (j instanceof Currency) {\n this._value = j.copyTo({})._value;\n this._update();\n }\n break;\n }\n\n return this;\n};\n\n\nCurrency.prototype.parse_human = function(j) {\n return this.parse_json(j);\n};\n\n/**\n * Recalculate internal representation.\n *\n * You should never need to call this.\n */\nCurrency.prototype._update = function() {\n var bytes = this.to_bytes();\n\n // is it 0 everywhere except 12, 13, 14?\n var isZeroExceptInStandardPositions = true;\n\n if (!bytes) {\n return 'XRP';\n }\n\n this._native = false;\n this._type = -1;\n this._interest_start = NaN;\n this._interest_period = NaN;\n this._iso_code = '';\n\n for (var i=0; i<20; i++) {\n isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || bytes[i]===0);\n }\n\n if (isZeroExceptInStandardPositions) {\n this._iso_code = String.fromCharCode(bytes[12])\n + String.fromCharCode(bytes[13])\n + String.fromCharCode(bytes[14]);\n\n if (this._iso_code === '\\0\\0\\0') {\n this._native = true;\n this._iso_code = 'XRP';\n }\n\n this._type = 0;\n } else if (bytes[0] === 0x01) { // Demurrage currency\n this._iso_code = String.fromCharCode(bytes[1])\n + String.fromCharCode(bytes[2])\n + String.fromCharCode(bytes[3]);\n\n this._type = 1;\n this._interest_start = (bytes[4] << 24) +\n (bytes[5] << 16) +\n (bytes[6] << 8) +\n (bytes[7] );\n this._interest_period = Float.fromIEEE754Double(bytes.slice(8, 16));\n }\n};\n\n// XXX Probably not needed anymore?\n/*\nCurrency.prototype.parse_bytes = function(byte_array) {\n if (Array.isArray(byte_array) && byte_array.length === 20) {\n var result;\n // is it 0 everywhere except 12, 13, 14?\n var isZeroExceptInStandardPositions = true;\n\n for (var i=0; i<20; i++) {\n isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || byte_array[0]===0)\n }\n\n if (isZeroExceptInStandardPositions) {\n var currencyCode = String.fromCharCode(byte_array[12])\n + String.fromCharCode(byte_array[13])\n + String.fromCharCode(byte_array[14]);\n if (/^[A-Z0-9]{3}$/.test(currencyCode) && currencyCode !== 'XRP' ) {\n this._value = currencyCode;\n } else if (currencyCode === '\\0\\0\\0') {\n this._value = 0;\n } else {\n this._value = NaN;\n }\n } else {\n // XXX Should support non-standard currency codes\n this._value = NaN;\n }\n } else {\n this._value = NaN;\n }\n return this;\n};\n*/\n\nCurrency.prototype.is_native = function() {\n return this._native;\n};\n\n/**\n * Whether this currency is an interest-bearing/demurring currency.\n */\nCurrency.prototype.has_interest = function() {\n return this._type === 1 && !isNaN(this._interest_start) && !isNaN(this._interest_period);\n};\n\n/**\n *\n * @param referenceDate - number of seconds since the Ripple Epoch (0:00 on January 1, 2000 UTC)\n * used to calculate the interest over provided interval\n * pass in one years worth of seconds to ge the yearly interest\n * @returns {number} - interest for provided interval, can be negative for demurred currencies\n */\nCurrency.prototype.get_interest_at = function(referenceDate, decimals) {\n if (!this.has_interest) {\n return 0;\n }\n\n // use one year as a default period\n if (!referenceDate) {\n referenceDate = this._interest_start + 3600 * 24 * 365;\n }\n\n if (referenceDate instanceof Date) {\n referenceDate = utils.fromTimestamp(referenceDate.getTime());\n }\n\n // calculate interest by e-fold number\n return Math.exp((referenceDate - this._interest_start) / this._interest_period);\n};\n\nCurrency.prototype.get_interest_percentage_at = function(referenceDate, decimals) {\n var interest = this.get_interest_at(referenceDate, decimals);\n\n // convert to percentage\n var interest = (interest*100)-100;\n var decimalMultiplier = decimals ? Math.pow(10,decimals) : 100;\n\n // round to two decimals behind the dot\n return Math.round(interest*decimalMultiplier) / decimalMultiplier;\n};\n\n// XXX Currently we inherit UInt.prototype.is_valid, which is mostly fine.\n//\n// We could be doing further checks into the internal format of the\n// currency data, since there are some values that are invalid.\n//\n//Currency.prototype.is_valid = function() {\n// return this._value instanceof BigInteger && ...;\n//};\n\nCurrency.prototype.to_json = function(opts) {\n if (!this.is_valid()) {\n // XXX This is backwards compatible behavior, but probably not very good.\n return 'XRP';\n }\n\n var opts = opts || {};\n\n var currency;\n var fullName = opts && opts.full_name ? \" - \" + opts.full_name : \"\";\n\n // Any currency with standard properties and a valid code can be abbreviated\n // in the JSON wire format as the three character code.\n if (!opts.force_hex && /^[A-Z0-9]{3}$/.test(this._iso_code) && !this.has_interest()) {\n currency = this._iso_code + fullName;\n\n // If there is interest, append the annual interest to the full currency name\n } else if (!opts.force_hex && this.has_interest()) {\n var decimals = opts ? opts.decimals : undefined;\n currency = this._iso_code + fullName + \" (\" + this.get_interest_percentage_at(this._interest_start + 3600 * 24 * 365, decimals) + \"%pa)\";\n } else {\n\n // Fallback to returning the raw currency hex\n currency = this.to_hex();\n\n // XXX This is to maintain backwards compatibility, but it is very, very odd\n // behavior, so we should deprecate it and get rid of it as soon as\n // possible.\n if (currency === Currency.HEX_ONE) {\n currency = 1;\n }\n }\n\n return currency;\n};\n\nCurrency.prototype.to_human = function(opts) {\n // to_human() will always print the human-readable currency code if available.\n return this.to_json(opts);\n};\n\nCurrency.prototype.get_iso = function() {\n return this._iso_code;\n};\n\nexports.Currency = Currency;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 6\n// module.readableIdentifier = ./src/js/ripple/currency.js\n//@ sourceURL=webpack-module:///./src/js/ripple/currency.js"); /***/ }, /* 7 */ @@ -94,19 +94,19 @@ var ripple = /* 8 */ /***/ function(module, exports, __webpack_require__) { - eval("var utils = __webpack_require__(19);\nvar config = __webpack_require__(21);\nvar extend = __webpack_require__(43);\n\nvar BigInteger = utils.jsbn.BigInteger;\n\nvar UInt = __webpack_require__(28).UInt;\nvar Base = __webpack_require__(7).Base;\n\n//\n// UInt160 support\n//\n\nvar UInt160 = extend(function() {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n this._version_byte = void(0);\n this._update();\n}, UInt);\n\nUInt160.width = 20;\nUInt160.prototype = extend({}, UInt.prototype);\nUInt160.prototype.constructor = UInt160;\n\nvar ACCOUNT_ZERO = UInt160.ACCOUNT_ZERO = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';\nvar ACCOUNT_ONE = UInt160.ACCOUNT_ONE = 'rrrrrrrrrrrrrrrrrrrrBZbvji';\nvar HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000';\nvar HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000001';\nvar STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);\nvar STR_ONE = UInt160.STR_ONE = utils.hexToString(HEX_ONE);\n\nUInt160.prototype.set_version = function(j) {\n this._version_byte = j;\n return this;\n};\n\nUInt160.prototype.get_version = function() {\n return this._version_byte;\n};\n\n// value = NaN on error.\nUInt160.prototype.parse_json = function(j) {\n // Canonicalize and validate\n if (config.accounts && (j in config.accounts)) {\n j = config.accounts[j].account;\n }\n\n if (typeof j === 'number' && !isNaN(j)) {\n // Allow raw numbers - DEPRECATED\n // This is used mostly by the test suite and is supported\n // as a legacy feature only. DO NOT RELY ON THIS BEHAVIOR.\n this._value = new BigInteger(String(j));\n this._version_byte = Base.VER_ACCOUNT_ID;\n } else if (typeof j !== 'string') {\n this._value = NaN;\n } else if (j[0] === 'r') {\n this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);\n this._version_byte = Base.VER_ACCOUNT_ID;\n } else {\n this.parse_hex(j);\n }\n\n this._update();\n\n return this;\n};\n\nUInt160.prototype.parse_generic = function(j) {\n UInt.prototype.parse_generic.call(this, j);\n\n if (isNaN(this._value)) {\n if ((typeof j === 'string') && j[0] === 'r') {\n this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);\n }\n }\n\n this._update();\n\n return this;\n};\n\n// XXX Json form should allow 0 and 1, C++ doesn't currently allow it.\nUInt160.prototype.to_json = function(opts) {\n opts = opts || {};\n\n if (this._value instanceof BigInteger) {\n // If this value has a type, return a Base58 encoded string.\n if (typeof this._version_byte === 'number') {\n var output = Base.encode_check(this._version_byte, this.to_bytes());\n\n if (opts.gateways && output in opts.gateways) {\n output = opts.gateways[output];\n }\n\n return output;\n } else {\n return this.to_hex();\n }\n }\n return NaN;\n};\n\nexports.UInt160 = UInt160;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 8\n// module.readableIdentifier = ./src/js/ripple/uint160.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint160.js"); + eval("var utils = __webpack_require__(19);\nvar config = __webpack_require__(21);\nvar extend = __webpack_require__(43);\n\nvar BigInteger = utils.jsbn.BigInteger;\n\nvar UInt = __webpack_require__(26).UInt;\nvar Base = __webpack_require__(7).Base;\n\n//\n// UInt160 support\n//\n\nvar UInt160 = extend(function() {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n this._version_byte = void(0);\n this._update();\n}, UInt);\n\nUInt160.width = 20;\nUInt160.prototype = extend({}, UInt.prototype);\nUInt160.prototype.constructor = UInt160;\n\nvar ACCOUNT_ZERO = UInt160.ACCOUNT_ZERO = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';\nvar ACCOUNT_ONE = UInt160.ACCOUNT_ONE = 'rrrrrrrrrrrrrrrrrrrrBZbvji';\nvar HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000';\nvar HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000001';\nvar STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);\nvar STR_ONE = UInt160.STR_ONE = utils.hexToString(HEX_ONE);\n\nUInt160.prototype.set_version = function(j) {\n this._version_byte = j;\n return this;\n};\n\nUInt160.prototype.get_version = function() {\n return this._version_byte;\n};\n\n// value = NaN on error.\nUInt160.prototype.parse_json = function(j) {\n // Canonicalize and validate\n if (config.accounts && (j in config.accounts)) {\n j = config.accounts[j].account;\n }\n\n if (typeof j === 'number' && !isNaN(j)) {\n // Allow raw numbers - DEPRECATED\n // This is used mostly by the test suite and is supported\n // as a legacy feature only. DO NOT RELY ON THIS BEHAVIOR.\n this._value = new BigInteger(String(j));\n this._version_byte = Base.VER_ACCOUNT_ID;\n } else if (typeof j !== 'string') {\n this._value = NaN;\n } else if (j[0] === 'r') {\n this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);\n this._version_byte = Base.VER_ACCOUNT_ID;\n } else {\n this.parse_hex(j);\n }\n\n this._update();\n\n return this;\n};\n\nUInt160.prototype.parse_generic = function(j) {\n UInt.prototype.parse_generic.call(this, j);\n\n if (isNaN(this._value)) {\n if ((typeof j === 'string') && j[0] === 'r') {\n this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);\n }\n }\n\n this._update();\n\n return this;\n};\n\n// XXX Json form should allow 0 and 1, C++ doesn't currently allow it.\nUInt160.prototype.to_json = function(opts) {\n opts = opts || {};\n\n if (this._value instanceof BigInteger) {\n // If this value has a type, return a Base58 encoded string.\n if (typeof this._version_byte === 'number') {\n var output = Base.encode_check(this._version_byte, this.to_bytes());\n\n if (opts.gateways && output in opts.gateways) {\n output = opts.gateways[output];\n }\n\n return output;\n } else {\n return this.to_hex();\n }\n }\n return NaN;\n};\n\nexports.UInt160 = UInt160;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 8\n// module.readableIdentifier = ./src/js/ripple/uint160.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint160.js"); /***/ }, /* 9 */ /***/ function(module, exports, __webpack_require__) { - eval("var utils = __webpack_require__(19);\nvar extend = __webpack_require__(43);\nvar UInt = __webpack_require__(28).UInt;\n\n//\n// UInt256 support\n//\n\nvar UInt256 = extend(function() {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n}, UInt);\n\nUInt256.width = 32;\nUInt256.prototype = extend({}, UInt.prototype);\nUInt256.prototype.constructor = UInt256;\n\nvar HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' + '00000000000000000000000000000000';\nvar HEX_ONE = UInt256.HEX_ONE = '00000000000000000000000000000000' + '00000000000000000000000000000001';\nvar STR_ZERO = UInt256.STR_ZERO = utils.hexToString(HEX_ZERO);\nvar STR_ONE = UInt256.STR_ONE = utils.hexToString(HEX_ONE);\n\nexports.UInt256 = UInt256;\n\n\n// WEBPACK FOOTER\n// module.id = 9\n// module.readableIdentifier = ./src/js/ripple/uint256.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint256.js"); + eval("var utils = __webpack_require__(19);\nvar extend = __webpack_require__(43);\nvar UInt = __webpack_require__(26).UInt;\n\n//\n// UInt256 support\n//\n\nvar UInt256 = extend(function() {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n}, UInt);\n\nUInt256.width = 32;\nUInt256.prototype = extend({}, UInt.prototype);\nUInt256.prototype.constructor = UInt256;\n\nvar HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' + '00000000000000000000000000000000';\nvar HEX_ONE = UInt256.HEX_ONE = '00000000000000000000000000000000' + '00000000000000000000000000000001';\nvar STR_ZERO = UInt256.STR_ZERO = utils.hexToString(HEX_ZERO);\nvar STR_ONE = UInt256.STR_ONE = utils.hexToString(HEX_ONE);\n\nexports.UInt256 = UInt256;\n\n\n// WEBPACK FOOTER\n// module.id = 9\n// module.readableIdentifier = ./src/js/ripple/uint256.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint256.js"); /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { - eval("//\n// Seed support\n//\n\nvar extend = __webpack_require__(43);\nvar utils = __webpack_require__(19);\nvar sjcl = utils.sjcl;\n\nvar BigInteger = utils.jsbn.BigInteger;\n\nvar Base = __webpack_require__(7).Base;\nvar UInt = __webpack_require__(28).UInt;\nvar UInt256 = __webpack_require__(9).UInt256;\nvar UInt160 = __webpack_require__(8).UInt160;\nvar KeyPair = __webpack_require__(29).KeyPair;\n\nvar Seed = extend(function () {\n // Internal form: NaN or BigInteger\n this._curve = sjcl.ecc.curves.c256;\n this._value = NaN;\n}, UInt);\n\nSeed.width = 16;\nSeed.prototype = extend({}, UInt.prototype);\nSeed.prototype.constructor = Seed;\n\n// value = NaN on error.\n// One day this will support rfc1751 too.\nSeed.prototype.parse_json = function (j) {\n if (typeof j === 'string') {\n if (!j.length) {\n this._value = NaN;\n // XXX Should actually always try and continue if it failed.\n } else if (j[0] === 's') {\n this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);\n } else if (j.length === 32) {\n this._value = this.parse_hex(j);\n // XXX Should also try 1751\n } else {\n this.parse_passphrase(j);\n }\n } else {\n this._value = NaN;\n }\n\n return this;\n};\n\nSeed.prototype.parse_passphrase = function (j) {\n if (typeof j !== 'string') {\n throw new Error('Passphrase must be a string');\n }\n\n var hash = sjcl.hash.sha512.hash(sjcl.codec.utf8String.toBits(j));\n var bits = sjcl.bitArray.bitSlice(hash, 0, 128);\n\n this.parse_bits(bits);\n\n return this;\n};\n\nSeed.prototype.to_json = function () {\n if (!(this._value instanceof BigInteger)) {\n return NaN;\n }\n\n var output = Base.encode_check(Base.VER_FAMILY_SEED, this.to_bytes());\n\n return output;\n};\n\nfunction append_int(a, i) {\n return [].concat(a, i >> 24, (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff);\n};\n\nfunction firstHalfOfSHA512(bytes) {\n return sjcl.bitArray.bitSlice(\n sjcl.hash.sha512.hash(sjcl.codec.bytes.toBits(bytes)),\n 0, 256\n );\n};\n\nfunction SHA256_RIPEMD160(bits) {\n return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));\n};\n\n/**\n* @param account\n* {undefined} take first, default, KeyPair\n*\n* {Number} specifies the account number of the KeyPair\n* desired.\n*\n* {Uint160} (from_json able), specifies the address matching the KeyPair\n* that is desired.\n*/\nSeed.prototype.get_key = function (account) {\n var account_number = 0, address;\n\n if (!this.is_valid()) {\n throw new Error('Cannot generate keys from invalid seed!');\n }\n if (account) {\n if (typeof account === 'number') {\n account_number = account;\n } else {\n address = UInt160.from_json(account);\n }\n }\n\n var private_gen, public_gen;\n var curve = this._curve;\n var i = 0;\n\n do {\n private_gen = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(this.to_bytes(), i)));\n i++;\n } while (!curve.r.greaterEquals(private_gen));\n\n public_gen = curve.G.mult(private_gen);\n\n var sec;\n var key_pair;\n var max_loops = 1000; // TODO\n\n do {\n i = 0;\n\n do {\n sec = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(append_int(public_gen.toBytesCompressed(), account_number), i)));\n i++;\n } while (!curve.r.greaterEquals(sec));\n\n account_number++;\n sec = sec.add(private_gen).mod(curve.r);\n key_pair = KeyPair.from_bn_secret(sec);\n\n if (--max_loops <= 0) {\n // We are almost certainly looking for an account that would take same\n // value of $too_long {forever, ...}\n throw new Error('Too many loops looking for KeyPair yielding '+\n address.to_json() +' from ' + this.to_json());\n };\n } while (address && !key_pair.get_address().equals(address));\n\n return key_pair;\n};\n\nexports.Seed = Seed;\n\n\n// WEBPACK FOOTER\n// module.id = 10\n// module.readableIdentifier = ./src/js/ripple/seed.js\n//@ sourceURL=webpack-module:///./src/js/ripple/seed.js"); + eval("//\n// Seed support\n//\n\nvar extend = __webpack_require__(43);\nvar utils = __webpack_require__(19);\nvar sjcl = utils.sjcl;\n\nvar BigInteger = utils.jsbn.BigInteger;\n\nvar Base = __webpack_require__(7).Base;\nvar UInt = __webpack_require__(26).UInt;\nvar UInt256 = __webpack_require__(9).UInt256;\nvar UInt160 = __webpack_require__(8).UInt160;\nvar KeyPair = __webpack_require__(28).KeyPair;\n\nvar Seed = extend(function () {\n // Internal form: NaN or BigInteger\n this._curve = sjcl.ecc.curves.c256;\n this._value = NaN;\n}, UInt);\n\nSeed.width = 16;\nSeed.prototype = extend({}, UInt.prototype);\nSeed.prototype.constructor = Seed;\n\n// value = NaN on error.\n// One day this will support rfc1751 too.\nSeed.prototype.parse_json = function (j) {\n if (typeof j === 'string') {\n if (!j.length) {\n this._value = NaN;\n // XXX Should actually always try and continue if it failed.\n } else if (j[0] === 's') {\n this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);\n } else if (j.length === 32) {\n this._value = this.parse_hex(j);\n // XXX Should also try 1751\n } else {\n this.parse_passphrase(j);\n }\n } else {\n this._value = NaN;\n }\n\n return this;\n};\n\nSeed.prototype.parse_passphrase = function (j) {\n if (typeof j !== 'string') {\n throw new Error('Passphrase must be a string');\n }\n\n var hash = sjcl.hash.sha512.hash(sjcl.codec.utf8String.toBits(j));\n var bits = sjcl.bitArray.bitSlice(hash, 0, 128);\n\n this.parse_bits(bits);\n\n return this;\n};\n\nSeed.prototype.to_json = function () {\n if (!(this._value instanceof BigInteger)) {\n return NaN;\n }\n\n var output = Base.encode_check(Base.VER_FAMILY_SEED, this.to_bytes());\n\n return output;\n};\n\nfunction append_int(a, i) {\n return [].concat(a, i >> 24, (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff);\n};\n\nfunction firstHalfOfSHA512(bytes) {\n return sjcl.bitArray.bitSlice(\n sjcl.hash.sha512.hash(sjcl.codec.bytes.toBits(bytes)),\n 0, 256\n );\n};\n\nfunction SHA256_RIPEMD160(bits) {\n return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));\n};\n\n/**\n* @param account\n* {undefined} take first, default, KeyPair\n*\n* {Number} specifies the account number of the KeyPair\n* desired.\n*\n* {Uint160} (from_json able), specifies the address matching the KeyPair\n* that is desired.\n*/\nSeed.prototype.get_key = function (account) {\n var account_number = 0, address;\n\n if (!this.is_valid()) {\n throw new Error('Cannot generate keys from invalid seed!');\n }\n if (account) {\n if (typeof account === 'number') {\n account_number = account;\n } else {\n address = UInt160.from_json(account);\n }\n }\n\n var private_gen, public_gen;\n var curve = this._curve;\n var i = 0;\n\n do {\n private_gen = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(this.to_bytes(), i)));\n i++;\n } while (!curve.r.greaterEquals(private_gen));\n\n public_gen = curve.G.mult(private_gen);\n\n var sec;\n var key_pair;\n var max_loops = 1000; // TODO\n\n do {\n i = 0;\n\n do {\n sec = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(append_int(public_gen.toBytesCompressed(), account_number), i)));\n i++;\n } while (!curve.r.greaterEquals(sec));\n\n account_number++;\n sec = sec.add(private_gen).mod(curve.r);\n key_pair = KeyPair.from_bn_secret(sec);\n\n if (--max_loops <= 0) {\n // We are almost certainly looking for an account that would take same\n // value of $too_long {forever, ...}\n throw new Error('Too many loops looking for KeyPair yielding '+\n address.to_json() +' from ' + this.to_json());\n };\n } while (address && !key_pair.get_address().equals(address));\n\n return key_pair;\n};\n\nexports.Seed = Seed;\n\n\n// WEBPACK FOOTER\n// module.id = 10\n// module.readableIdentifier = ./src/js/ripple/seed.js\n//@ sourceURL=webpack-module:///./src/js/ripple/seed.js"); /***/ }, /* 11 */ @@ -118,7 +118,7 @@ var ripple = /* 12 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var assert = __webpack_require__(39);\nvar extend = __webpack_require__(43);\nvar binformat = __webpack_require__(18);\nvar stypes = __webpack_require__(30);\nvar UInt256 = __webpack_require__(9).UInt256;\nvar Crypt = __webpack_require__(31).Crypt;\nvar utils = __webpack_require__(19);\n\nvar sjcl = utils.sjcl;\nvar BigInteger = utils.jsbn.BigInteger;\n\nvar TRANSACTION_TYPES = { };\n\nObject.keys(binformat.tx).forEach(function(key) {\n TRANSACTION_TYPES[binformat.tx[key][0]] = key;\n});\n\nvar LEDGER_ENTRY_TYPES = {};\n\nObject.keys(binformat.ledger).forEach(function(key) {\n LEDGER_ENTRY_TYPES[binformat.ledger[key][0]] = key;\n});\n\nvar TRANSACTION_RESULTS = {};\n\nObject.keys(binformat.ter).forEach(function(key) {\n TRANSACTION_RESULTS[binformat.ter[key]] = key;\n});\n\nfunction SerializedObject(buf) {\n if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {\n this.buffer = buf;\n } else if (typeof buf === 'string') {\n this.buffer = sjcl.codec.bytes.fromBits(sjcl.codec.hex.toBits(buf));\n } else if (!buf) {\n this.buffer = [];\n } else {\n throw new Error('Invalid buffer passed.');\n }\n this.pointer = 0;\n};\n\nSerializedObject.from_json = function(obj) {\n // Create a copy of the object so we don't modify it\n var obj = extend({}, obj);\n var so = new SerializedObject();\n var typedef;\n\n if (typeof obj.TransactionType === 'number') {\n obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType);\n if (!obj.TransactionType) {\n throw new Error('Transaction type ID is invalid.');\n }\n }\n\n if (typeof obj.LedgerEntryType === 'number') {\n obj.LedgerEntryType = SerializedObject.lookup_type_le(obj.LedgerEntryType);\n\n if (!obj.LedgerEntryType) {\n throw new Error('LedgerEntryType ID is invalid.');\n }\n }\n\n if (typeof obj.TransactionType === 'string') {\n typedef = binformat.tx[obj.TransactionType];\n if (!Array.isArray(typedef)) {\n throw new Error('Transaction type is invalid');\n }\n\n typedef = typedef.slice();\n obj.TransactionType = typedef.shift();\n } else if (typeof obj.LedgerEntryType === 'string') {\n typedef = binformat.ledger[obj.LedgerEntryType];\n\n if (!Array.isArray(typedef)) {\n throw new Error('LedgerEntryType is invalid');\n }\n\n typedef = typedef.slice();\n obj.LedgerEntryType = typedef.shift();\n\n } else if (typeof obj.AffectedNodes === 'object') {\n typedef = binformat.metadata;\n } else {\n throw new Error('Object to be serialized must contain either' +\n ' TransactionType, LedgerEntryType or AffectedNodes.');\n }\n\n // ND: This from_*json* seems a reasonable place to put validation of `json`\n SerializedObject.check_no_missing_fields(typedef, obj);\n so.serialize(typedef, obj);\n\n return so;\n};\n\nSerializedObject.check_no_missing_fields = function(typedef, obj) {\n var missing_fields = [];\n\n for (var i = typedef.length - 1; i >= 0; i--) {\n var spec = typedef[i];\n var field = spec[0];\n var requirement = spec[1];\n\n if (binformat.REQUIRED === requirement && obj[field] === void(0)) {\n missing_fields.push(field);\n };\n };\n\n if (missing_fields.length > 0) {\n var object_name;\n\n if (obj.TransactionType !== void(0)) {\n object_name = SerializedObject.lookup_type_tx(obj.TransactionType);\n } else if (obj.LedgerEntryType != null){\n object_name = SerializedObject.lookup_type_le(obj.LedgerEntryType);\n } else {\n object_name = \"TransactionMetaData\";\n }\n\n throw new Error(object_name + \" is missing fields: \" +\n JSON.stringify(missing_fields));\n };\n};\n\nSerializedObject.prototype.append = function(bytes) {\n if (bytes instanceof SerializedObject) {\n bytes = bytes.buffer;\n }\n\n this.buffer = this.buffer.concat(bytes);\n this.pointer += bytes.length;\n};\n\nSerializedObject.prototype.resetPointer = function() {\n this.pointer = 0;\n};\n\nfunction readOrPeek(advance) {\n return function(bytes) {\n var start = this.pointer;\n var end = start + bytes;\n\n if (end > this.buffer.length) {\n throw new Error('Buffer length exceeded');\n }\n\n var result = this.buffer.slice(start, end);\n\n if (advance) {\n this.pointer = end;\n }\n\n return result;\n };\n};\n\nSerializedObject.prototype.read = readOrPeek(true);\n\nSerializedObject.prototype.peek = readOrPeek(false);\n\nSerializedObject.prototype.to_bits = function() {\n return sjcl.codec.bytes.toBits(this.buffer);\n};\n\nSerializedObject.prototype.to_hex = function() {\n return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase();\n};\n\nSerializedObject.prototype.to_json = function() {\n var old_pointer = this.pointer;\n this.resetPointer();\n var output = { };\n\n while (this.pointer < this.buffer.length) {\n var key_and_value = stypes.parse(this);\n var key = key_and_value[0];\n var value = key_and_value[1];\n output[key] = SerializedObject.jsonify_structure(value, key);\n }\n\n this.pointer = old_pointer;\n\n return output;\n};\n\nSerializedObject.jsonify_structure = function(structure, field_name) {\n var output;\n\n switch (typeof structure) {\n case 'number':\n switch (field_name) {\n case 'LedgerEntryType':\n output = LEDGER_ENTRY_TYPES[structure];\n break;\n case 'TransactionResult':\n output = TRANSACTION_RESULTS[structure];\n break;\n case 'TransactionType':\n output = TRANSACTION_TYPES[structure];\n break;\n default:\n output = structure;\n }\n break;\n case 'object':\n if (structure === null) {\n break;\n }\n\n if (typeof structure.to_json === 'function') {\n output = structure.to_json();\n } else if (structure instanceof BigInteger) {\n output = structure.toString(16).toUpperCase();\n } else {\n //new Array or Object\n output = new structure.constructor();\n\n var keys = Object.keys(structure);\n\n for (var i=0, l=keys.length; i 0xF) {\n buffer.push(type_id & 0xFF);\n } else {\n buffer[0] += (type_id & 0xF) << 4;\n }\n\n if (field_id > 0xF) {\n buffer.push(field_id & 0xFF);\n } else {\n buffer[0] += field_id & 0xF;\n }\n\n return buffer;\n};\n\nSerializedObject.sort_typedef = function(typedef) {\n assert(Array.isArray(typedef));\n\n function sort_field_compare(a, b) {\n // Sort by type id first, then by field id\n return a[3] !== b[3] ? stypes[a[3]].id - stypes[b[3]].id : a[2] - b[2];\n };\n\n return typedef.sort(sort_field_compare);\n};\n\nSerializedObject.lookup_type_tx = function(id) {\n assert.strictEqual(typeof id, 'number');\n return TRANSACTION_TYPES[id];\n};\n\nSerializedObject.lookup_type_le = function (id) {\n assert(typeof id === 'number');\n return LEDGER_ENTRY_TYPES[id];\n};\n\nexports.SerializedObject = SerializedObject;\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 12\n// module.readableIdentifier = ./src/js/ripple/serializedobject.js\n//@ sourceURL=webpack-module:///./src/js/ripple/serializedobject.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var assert = __webpack_require__(39);\nvar extend = __webpack_require__(43);\nvar binformat = __webpack_require__(18);\nvar stypes = __webpack_require__(29);\nvar UInt256 = __webpack_require__(9).UInt256;\nvar Crypt = __webpack_require__(30).Crypt;\nvar utils = __webpack_require__(19);\n\nvar sjcl = utils.sjcl;\nvar BigInteger = utils.jsbn.BigInteger;\n\nvar TRANSACTION_TYPES = { };\n\nObject.keys(binformat.tx).forEach(function(key) {\n TRANSACTION_TYPES[binformat.tx[key][0]] = key;\n});\n\nvar LEDGER_ENTRY_TYPES = {};\n\nObject.keys(binformat.ledger).forEach(function(key) {\n LEDGER_ENTRY_TYPES[binformat.ledger[key][0]] = key;\n});\n\nvar TRANSACTION_RESULTS = {};\n\nObject.keys(binformat.ter).forEach(function(key) {\n TRANSACTION_RESULTS[binformat.ter[key]] = key;\n});\n\nfunction SerializedObject(buf) {\n if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {\n this.buffer = buf;\n } else if (typeof buf === 'string') {\n this.buffer = sjcl.codec.bytes.fromBits(sjcl.codec.hex.toBits(buf));\n } else if (!buf) {\n this.buffer = [];\n } else {\n throw new Error('Invalid buffer passed.');\n }\n this.pointer = 0;\n};\n\nSerializedObject.from_json = function(obj) {\n // Create a copy of the object so we don't modify it\n var obj = extend({}, obj);\n var so = new SerializedObject();\n var typedef;\n\n if (typeof obj.TransactionType === 'number') {\n obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType);\n if (!obj.TransactionType) {\n throw new Error('Transaction type ID is invalid.');\n }\n }\n\n if (typeof obj.LedgerEntryType === 'number') {\n obj.LedgerEntryType = SerializedObject.lookup_type_le(obj.LedgerEntryType);\n\n if (!obj.LedgerEntryType) {\n throw new Error('LedgerEntryType ID is invalid.');\n }\n }\n\n if (typeof obj.TransactionType === 'string') {\n typedef = binformat.tx[obj.TransactionType];\n if (!Array.isArray(typedef)) {\n throw new Error('Transaction type is invalid');\n }\n\n typedef = typedef.slice();\n obj.TransactionType = typedef.shift();\n } else if (typeof obj.LedgerEntryType === 'string') {\n typedef = binformat.ledger[obj.LedgerEntryType];\n\n if (!Array.isArray(typedef)) {\n throw new Error('LedgerEntryType is invalid');\n }\n\n typedef = typedef.slice();\n obj.LedgerEntryType = typedef.shift();\n\n } else if (typeof obj.AffectedNodes === 'object') {\n typedef = binformat.metadata;\n } else {\n throw new Error('Object to be serialized must contain either' +\n ' TransactionType, LedgerEntryType or AffectedNodes.');\n }\n\n // ND: This from_*json* seems a reasonable place to put validation of `json`\n SerializedObject.check_no_missing_fields(typedef, obj);\n so.serialize(typedef, obj);\n\n return so;\n};\n\nSerializedObject.check_no_missing_fields = function(typedef, obj) {\n var missing_fields = [];\n\n for (var i = typedef.length - 1; i >= 0; i--) {\n var spec = typedef[i];\n var field = spec[0];\n var requirement = spec[1];\n\n if (binformat.REQUIRED === requirement && obj[field] === void(0)) {\n missing_fields.push(field);\n };\n };\n\n if (missing_fields.length > 0) {\n var object_name;\n\n if (obj.TransactionType !== void(0)) {\n object_name = SerializedObject.lookup_type_tx(obj.TransactionType);\n } else if (obj.LedgerEntryType != null){\n object_name = SerializedObject.lookup_type_le(obj.LedgerEntryType);\n } else {\n object_name = \"TransactionMetaData\";\n }\n\n throw new Error(object_name + \" is missing fields: \" +\n JSON.stringify(missing_fields));\n };\n};\n\nSerializedObject.prototype.append = function(bytes) {\n if (bytes instanceof SerializedObject) {\n bytes = bytes.buffer;\n }\n\n this.buffer = this.buffer.concat(bytes);\n this.pointer += bytes.length;\n};\n\nSerializedObject.prototype.resetPointer = function() {\n this.pointer = 0;\n};\n\nfunction readOrPeek(advance) {\n return function(bytes) {\n var start = this.pointer;\n var end = start + bytes;\n\n if (end > this.buffer.length) {\n throw new Error('Buffer length exceeded');\n }\n\n var result = this.buffer.slice(start, end);\n\n if (advance) {\n this.pointer = end;\n }\n\n return result;\n };\n};\n\nSerializedObject.prototype.read = readOrPeek(true);\n\nSerializedObject.prototype.peek = readOrPeek(false);\n\nSerializedObject.prototype.to_bits = function() {\n return sjcl.codec.bytes.toBits(this.buffer);\n};\n\nSerializedObject.prototype.to_hex = function() {\n return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase();\n};\n\nSerializedObject.prototype.to_json = function() {\n var old_pointer = this.pointer;\n this.resetPointer();\n var output = { };\n\n while (this.pointer < this.buffer.length) {\n var key_and_value = stypes.parse(this);\n var key = key_and_value[0];\n var value = key_and_value[1];\n output[key] = SerializedObject.jsonify_structure(value, key);\n }\n\n this.pointer = old_pointer;\n\n return output;\n};\n\nSerializedObject.jsonify_structure = function(structure, field_name) {\n var output;\n\n switch (typeof structure) {\n case 'number':\n switch (field_name) {\n case 'LedgerEntryType':\n output = LEDGER_ENTRY_TYPES[structure];\n break;\n case 'TransactionResult':\n output = TRANSACTION_RESULTS[structure];\n break;\n case 'TransactionType':\n output = TRANSACTION_TYPES[structure];\n break;\n default:\n output = structure;\n }\n break;\n case 'object':\n if (structure === null) {\n break;\n }\n\n if (typeof structure.to_json === 'function') {\n output = structure.to_json();\n } else if (structure instanceof BigInteger) {\n output = structure.toString(16).toUpperCase();\n } else {\n //new Array or Object\n output = new structure.constructor();\n\n var keys = Object.keys(structure);\n\n for (var i=0, l=keys.length; i 0xF) {\n buffer.push(type_id & 0xFF);\n } else {\n buffer[0] += (type_id & 0xF) << 4;\n }\n\n if (field_id > 0xF) {\n buffer.push(field_id & 0xFF);\n } else {\n buffer[0] += field_id & 0xF;\n }\n\n return buffer;\n};\n\nSerializedObject.sort_typedef = function(typedef) {\n assert(Array.isArray(typedef));\n\n function sort_field_compare(a, b) {\n // Sort by type id first, then by field id\n return a[3] !== b[3] ? stypes[a[3]].id - stypes[b[3]].id : a[2] - b[2];\n };\n\n return typedef.sort(sort_field_compare);\n};\n\nSerializedObject.lookup_type_tx = function(id) {\n assert.strictEqual(typeof id, 'number');\n return TRANSACTION_TYPES[id];\n};\n\nSerializedObject.lookup_type_le = function (id) {\n assert(typeof id === 'number');\n return LEDGER_ENTRY_TYPES[id];\n};\n\nexports.SerializedObject = SerializedObject;\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 12\n// module.readableIdentifier = ./src/js/ripple/serializedobject.js\n//@ sourceURL=webpack-module:///./src/js/ripple/serializedobject.js"); /***/ }, /* 13 */ @@ -130,25 +130,25 @@ var ripple = /* 14 */ /***/ function(module, exports, __webpack_require__) { - eval("var async = __webpack_require__(48);\nvar crypto = __webpack_require__(41);\nvar sjcl = __webpack_require__(19).sjcl;\nvar Remote = __webpack_require__(1).Remote;\nvar Seed = __webpack_require__(10).Seed;\nvar KeyPair = __webpack_require__(29).KeyPair;\nvar Account = __webpack_require__(4).Account;\nvar UInt160 = __webpack_require__(8).UInt160;\n\n// Message class (static)\nvar Message = {};\n\nMessage.HASH_FUNCTION = sjcl.hash.sha512.hash;\nMessage.MAGIC_BYTES = 'Ripple Signed Message:\\n';\n\nvar REGEX_HEX = /^[0-9a-fA-F]+$/;\nvar REGEX_BASE64 = /^([A-Za-z0-9\\+]{4})*([A-Za-z0-9\\+]{2}==)|([A-Za-z0-9\\+]{3}=)?$/;\n\n/**\n * Produce a Base64-encoded signature on the given message with\n * the string 'Ripple Signed Message:\\n' prepended.\n *\n * Note that this signature uses the signing function that includes\n * a recovery_factor to be able to extract the public key from the signature\n * without having to pass the public key along with the signature.\n *\n * @static\n *\n * @param {String} message\n * @param {sjcl.ecc.ecdsa.secretKey|Any format accepted by Seed.from_json} secret_key\n * @param {RippleAddress} [The first key] account Field to specify the signing account. \n * If this is omitted the first account produced by the secret generator will be used.\n * @returns {Base64-encoded String} signature\n */\nMessage.signMessage = function(message, secret_key, account) {\n\n return Message.signHash(Message.HASH_FUNCTION(Message.MAGIC_BYTES + message), secret_key, account);\n\n};\n\n/**\n * Produce a Base64-encoded signature on the given hex-encoded hash.\n *\n * Note that this signature uses the signing function that includes\n * a recovery_factor to be able to extract the public key from the signature\n * without having to pass the public key along with the signature.\n *\n * @static\n *\n * @param {bitArray|Hex-encoded String} hash\n * @param {sjcl.ecc.ecdsa.secretKey|Any format accepted by Seed.from_json} secret_key\n * @param {RippleAddress} [The first key] account Field to specify the signing account. \n * If this is omitted the first account produced by the secret generator will be used.\n * @returns {Base64-encoded String} signature\n */\nMessage.signHash = function(hash, secret_key, account) {\n\n if (typeof hash === 'string' && /^[0-9a-fA-F]+$/.test(hash)) {\n hash = sjcl.codec.hex.toBits(hash);\n }\n\n if (typeof hash !== 'object' || hash.length <= 0 || typeof hash[0] !== 'number') {\n throw new Error('Hash must be a bitArray or hex-encoded string');\n }\n\n if (!(secret_key instanceof sjcl.ecc.ecdsa.secretKey)) {\n secret_key = Seed.from_json(secret_key).get_key(account)._secret;\n }\n\n var signature_bits = secret_key.signWithRecoverablePublicKey(hash);\n var signature_base64 = sjcl.codec.base64.fromBits(signature_bits);\n\n return signature_base64;\n\n};\n\n\n/**\n * Verify the signature on a given message.\n *\n * Note that this function is asynchronous. \n * The ripple-lib remote is used to check that the public\n * key extracted from the signature corresponds to one that is currently\n * active for the given account.\n *\n * @static\n *\n * @param {String} data.message\n * @param {RippleAddress} data.account\n * @param {Base64-encoded String} data.signature\n * @param {ripple-lib Remote} remote\n * @param {Function} callback\n *\n * @callback callback\n * @param {Error} error\n * @param {boolean} is_valid true if the signature is valid, false otherwise\n */\nMessage.verifyMessageSignature = function(data, remote, callback) {\n\n if (typeof data.message === 'string') {\n data.hash = Message.HASH_FUNCTION(Message.MAGIC_BYTES + data.message);\n } else {\n return callback(new Error('Data object must contain message field to verify signature'));\n }\n\n return Message.verifyHashSignature(data, remote, callback);\n\n};\n\n\n/**\n * Verify the signature on a given hash.\n *\n * Note that this function is asynchronous. \n * The ripple-lib remote is used to check that the public\n * key extracted from the signature corresponds to one that is currently\n * active for the given account.\n *\n * @static\n *\n * @param {bitArray|Hex-encoded String} data.hash\n * @param {RippleAddress} data.account\n * @param {Base64-encoded String} data.signature\n * @param {ripple-lib Remote} remote\n * @param {Function} callback\n *\n * @callback callback\n * @param {Error} error\n * @param {boolean} is_valid true if the signature is valid, false otherwise\n */\nMessage.verifyHashSignature = function(data, remote, callback) {\n\n var hash,\n account,\n signature;\n\n if(typeof callback !== 'function') {\n throw new Error('Must supply callback function');\n }\n\n hash = data.hash;\n if (hash && typeof hash === 'string' && REGEX_HEX.test(hash)) {\n hash = sjcl.codec.hex.toBits(hash);\n }\n\n if (typeof hash !== 'object' || hash.length <= 0 || typeof hash[0] !== 'number') {\n return callback(new Error('Hash must be a bitArray or hex-encoded string'));\n }\n\n account = data.account || data.address;\n if (!account || !UInt160.from_json(account).is_valid()) {\n return callback(new Error('Account must be a valid ripple address'));\n }\n\n signature = data.signature;\n if (typeof signature !== 'string' || !REGEX_BASE64.test(signature)) {\n return callback(new Error('Signature must be a Base64-encoded string'));\n }\n signature = sjcl.codec.base64.toBits(signature);\n\n if (!(remote instanceof Remote) || remote.state !== 'online') {\n return callback(new Error('Must supply connected Remote to verify signature'));\n }\n\n function recoverPublicKey (async_callback) {\n\n var public_key;\n try {\n public_key = sjcl.ecc.ecdsa.publicKey.recoverFromSignature(hash, signature);\n } catch (err) {\n return async_callback(err);\n }\n\n if (public_key) {\n async_callback(null, public_key);\n } else {\n async_callback(new Error('Could not recover public key from signature'));\n }\n\n };\n\n function checkPublicKeyIsValid (public_key, async_callback) {\n\n // Get hex-encoded public key\n var key_pair = new KeyPair();\n key_pair._pubkey = public_key;\n var public_key_hex = key_pair.to_hex_pub();\n\n var account_class_instance = new Account(remote, account);\n account_class_instance.publicKeyIsActive(public_key_hex, async_callback);\n\n };\n\n var steps = [\n recoverPublicKey,\n checkPublicKeyIsValid\n ];\n\n async.waterfall(steps, callback);\n\n};\n\nexports.Message = Message;\n\n\n// WEBPACK FOOTER\n// module.id = 14\n// module.readableIdentifier = ./src/js/ripple/message.js\n//@ sourceURL=webpack-module:///./src/js/ripple/message.js"); + eval("var async = __webpack_require__(48);\nvar crypto = __webpack_require__(41);\nvar sjcl = __webpack_require__(19).sjcl;\nvar Remote = __webpack_require__(1).Remote;\nvar Seed = __webpack_require__(10).Seed;\nvar KeyPair = __webpack_require__(28).KeyPair;\nvar Account = __webpack_require__(4).Account;\nvar UInt160 = __webpack_require__(8).UInt160;\n\n// Message class (static)\nvar Message = {};\n\nMessage.HASH_FUNCTION = sjcl.hash.sha512.hash;\nMessage.MAGIC_BYTES = 'Ripple Signed Message:\\n';\n\nvar REGEX_HEX = /^[0-9a-fA-F]+$/;\nvar REGEX_BASE64 = /^([A-Za-z0-9\\+]{4})*([A-Za-z0-9\\+]{2}==)|([A-Za-z0-9\\+]{3}=)?$/;\n\n/**\n * Produce a Base64-encoded signature on the given message with\n * the string 'Ripple Signed Message:\\n' prepended.\n *\n * Note that this signature uses the signing function that includes\n * a recovery_factor to be able to extract the public key from the signature\n * without having to pass the public key along with the signature.\n *\n * @static\n *\n * @param {String} message\n * @param {sjcl.ecc.ecdsa.secretKey|Any format accepted by Seed.from_json} secret_key\n * @param {RippleAddress} [The first key] account Field to specify the signing account. \n * If this is omitted the first account produced by the secret generator will be used.\n * @returns {Base64-encoded String} signature\n */\nMessage.signMessage = function(message, secret_key, account) {\n\n return Message.signHash(Message.HASH_FUNCTION(Message.MAGIC_BYTES + message), secret_key, account);\n\n};\n\n/**\n * Produce a Base64-encoded signature on the given hex-encoded hash.\n *\n * Note that this signature uses the signing function that includes\n * a recovery_factor to be able to extract the public key from the signature\n * without having to pass the public key along with the signature.\n *\n * @static\n *\n * @param {bitArray|Hex-encoded String} hash\n * @param {sjcl.ecc.ecdsa.secretKey|Any format accepted by Seed.from_json} secret_key\n * @param {RippleAddress} [The first key] account Field to specify the signing account. \n * If this is omitted the first account produced by the secret generator will be used.\n * @returns {Base64-encoded String} signature\n */\nMessage.signHash = function(hash, secret_key, account) {\n\n if (typeof hash === 'string' && /^[0-9a-fA-F]+$/.test(hash)) {\n hash = sjcl.codec.hex.toBits(hash);\n }\n\n if (typeof hash !== 'object' || hash.length <= 0 || typeof hash[0] !== 'number') {\n throw new Error('Hash must be a bitArray or hex-encoded string');\n }\n\n if (!(secret_key instanceof sjcl.ecc.ecdsa.secretKey)) {\n secret_key = Seed.from_json(secret_key).get_key(account)._secret;\n }\n\n var signature_bits = secret_key.signWithRecoverablePublicKey(hash);\n var signature_base64 = sjcl.codec.base64.fromBits(signature_bits);\n\n return signature_base64;\n\n};\n\n\n/**\n * Verify the signature on a given message.\n *\n * Note that this function is asynchronous. \n * The ripple-lib remote is used to check that the public\n * key extracted from the signature corresponds to one that is currently\n * active for the given account.\n *\n * @static\n *\n * @param {String} data.message\n * @param {RippleAddress} data.account\n * @param {Base64-encoded String} data.signature\n * @param {ripple-lib Remote} remote\n * @param {Function} callback\n *\n * @callback callback\n * @param {Error} error\n * @param {boolean} is_valid true if the signature is valid, false otherwise\n */\nMessage.verifyMessageSignature = function(data, remote, callback) {\n\n if (typeof data.message === 'string') {\n data.hash = Message.HASH_FUNCTION(Message.MAGIC_BYTES + data.message);\n } else {\n return callback(new Error('Data object must contain message field to verify signature'));\n }\n\n return Message.verifyHashSignature(data, remote, callback);\n\n};\n\n\n/**\n * Verify the signature on a given hash.\n *\n * Note that this function is asynchronous. \n * The ripple-lib remote is used to check that the public\n * key extracted from the signature corresponds to one that is currently\n * active for the given account.\n *\n * @static\n *\n * @param {bitArray|Hex-encoded String} data.hash\n * @param {RippleAddress} data.account\n * @param {Base64-encoded String} data.signature\n * @param {ripple-lib Remote} remote\n * @param {Function} callback\n *\n * @callback callback\n * @param {Error} error\n * @param {boolean} is_valid true if the signature is valid, false otherwise\n */\nMessage.verifyHashSignature = function(data, remote, callback) {\n\n var hash,\n account,\n signature;\n\n if(typeof callback !== 'function') {\n throw new Error('Must supply callback function');\n }\n\n hash = data.hash;\n if (hash && typeof hash === 'string' && REGEX_HEX.test(hash)) {\n hash = sjcl.codec.hex.toBits(hash);\n }\n\n if (typeof hash !== 'object' || hash.length <= 0 || typeof hash[0] !== 'number') {\n return callback(new Error('Hash must be a bitArray or hex-encoded string'));\n }\n\n account = data.account || data.address;\n if (!account || !UInt160.from_json(account).is_valid()) {\n return callback(new Error('Account must be a valid ripple address'));\n }\n\n signature = data.signature;\n if (typeof signature !== 'string' || !REGEX_BASE64.test(signature)) {\n return callback(new Error('Signature must be a Base64-encoded string'));\n }\n signature = sjcl.codec.base64.toBits(signature);\n\n if (!(remote instanceof Remote) || remote.state !== 'online') {\n return callback(new Error('Must supply connected Remote to verify signature'));\n }\n\n function recoverPublicKey (async_callback) {\n\n var public_key;\n try {\n public_key = sjcl.ecc.ecdsa.publicKey.recoverFromSignature(hash, signature);\n } catch (err) {\n return async_callback(err);\n }\n\n if (public_key) {\n async_callback(null, public_key);\n } else {\n async_callback(new Error('Could not recover public key from signature'));\n }\n\n };\n\n function checkPublicKeyIsValid (public_key, async_callback) {\n\n // Get hex-encoded public key\n var key_pair = new KeyPair();\n key_pair._pubkey = public_key;\n var public_key_hex = key_pair.to_hex_pub();\n\n var account_class_instance = new Account(remote, account);\n account_class_instance.publicKeyIsActive(public_key_hex, async_callback);\n\n };\n\n var steps = [\n recoverPublicKey,\n checkPublicKeyIsValid\n ];\n\n async.waterfall(steps, callback);\n\n};\n\nexports.Message = Message;\n\n\n// WEBPACK FOOTER\n// module.id = 14\n// module.readableIdentifier = ./src/js/ripple/message.js\n//@ sourceURL=webpack-module:///./src/js/ripple/message.js"); /***/ }, /* 15 */ /***/ function(module, exports, __webpack_require__) { - eval("var async = __webpack_require__(48);\nvar blobClient = __webpack_require__(32).BlobClient;\nvar AuthInfo = __webpack_require__(16).AuthInfo;\nvar crypt = __webpack_require__(31).Crypt;\nvar log = __webpack_require__(24).sub('vault');\nfunction VaultClient(opts) {\n \n var self = this;\n \n if (!opts) {\n opts = { };\n }\n\n if (typeof opts === 'string') {\n opts = { domain: opts };\n }\n\n this.domain = opts.domain || 'ripple.com';\n this.infos = { };\n};\n\n/**\n * getAuthInfo\n * gets auth info for a username. returns authinfo\n * even if user does not exists (with exist set to false)\n * @param {string} username\n * @param {function} callback\n */\nVaultClient.prototype.getAuthInfo = function (username, callback) {\n\n AuthInfo.get(this.domain, username, function(err, authInfo) {\n if (err) {\n return callback(err);\n }\n\n if (authInfo.version !== 3) {\n return callback(new Error('This wallet is incompatible with this version of the vault-client.'));\n }\n\n if (!authInfo.pakdf) {\n return callback(new Error('No settings for PAKDF in auth packet.'));\n }\n\n if (typeof authInfo.blobvault !== 'string') {\n return callback(new Error('No blobvault specified in the authinfo.'));\n }\n\n callback(null, authInfo);\n }); \n};\n\n/**\n * _deriveLoginKeys\n * method designed for asnyc waterfall\n */\n\nVaultClient.prototype._deriveLoginKeys = function (authInfo, password, callback) {\n var normalizedUsername = authInfo.username.toLowerCase().replace(/-/g, '');\n \n //derive login keys\n crypt.derive(authInfo.pakdf, 'login', normalizedUsername, password, function(err, keys) {\n if (err) {\n callback(err);\n } else {\n callback(null, authInfo, password, keys);\n }\n });\n};\n\n\n\n/**\n * _deriveUnlockKey\n * method designed for asnyc waterfall\n */\n\nVaultClient.prototype._deriveUnlockKey = function (authInfo, password, keys, callback) {\n var normalizedUsername = authInfo.username.toLowerCase().replace(/-/g, '');\n \n //derive unlock key\n crypt.derive(authInfo.pakdf, 'unlock', normalizedUsername, password, function(err, unlock) {\n if (err) {\n log.error('derive:', err);\n return callback(err);\n }\n\n if (!keys) {\n keys = { };\n }\n \n keys.unlock = unlock.unlock;\n callback(null, authInfo, keys);\n });\n};\n \n/**\n * Get a ripple name from a given account address, if it has one\n * @param {string} address - Account address to query\n * @param {string} url - Url of blob vault\n */\n\nVaultClient.prototype.getRippleName = function(address, url, callback) {\n //use the url from previously retrieved authInfo, if necessary\n if (!url) {\n callback(new Error('Blob vault URL is required'));\n } else {\n blobClient.getRippleName(url, address, callback);\n }\n};\n\n/**\n * Check blobvault for existance of username\n *\n * @param {string} username\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.exists = function(username, callback) {\n AuthInfo.get(this.domain, username.toLowerCase(), function(err, authInfo) {\n if (err) {\n callback(err);\n } else {\n callback(null, !!authInfo.exists);\n }\n });\n};\n\n/**\n * Authenticate and retrieve a decrypted blob using a ripple name and password\n *\n * @param {string} username\n * @param {string} password\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.login = function(username, password, device_id, callback) {\n var self = this;\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n getBlob\n ];\n\n async.waterfall(steps, callback);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(username, function(err, authInfo){\n \n if (authInfo && !authInfo.exists) {\n return callback(new Error('User does not exist.'));\n }\n \n return callback (err, authInfo, password);\n }); \n }\n \n function getBlob(authInfo, password, keys, callback) {\n var options = {\n url : authInfo.blobvault,\n blob_id : keys.id,\n key : keys.crypt,\n device_id : device_id\n };\n \n blobClient.get(options, function(err, blob) {\n if (err) {\n return callback(err);\n }\n\n //save for relogin\n self.infos[keys.id] = authInfo;\n\n //migrate missing fields\n if (blob.missing_fields) {\n if (blob.missing_fields.encrypted_blobdecrypt_key) { \n log.info('migration: saving encrypted blob decrypt key');\n authInfo.blob = blob;\n //get the key to unlock the secret, then update the blob keys \n self._deriveUnlockKey(authInfo, password, keys, updateKeys);\n }\n }\n \n callback(null, {\n blob : blob,\n username : authInfo.username,\n verified : authInfo.emailVerified\n });\n });\n };\n \n function updateKeys (err, params, keys) {\n if (err || !keys.unlock) {\n return; //unable to unlock\n }\n \n var secret;\n try {\n secret = crypt.decrypt(keys.unlock, params.blob.encrypted_secret);\n } catch (error) {\n return log.error('decrypt:', error);\n } \n \n options = {\n username : params.username,\n blob : params.blob,\n masterkey : secret,\n keys : keys\n };\n \n blobClient.updateKeys(options, function(err, resp){\n if (err) {\n log.error('updateKeys:', err);\n }\n }); \n } \n};\n\n/**\n * Retreive and decrypt blob using a blob url, id and crypt derived previously.\n *\n * @param {string} url - Blob vault url\n * @param {string} id - Blob id from previously retreived blob\n * @param {string} key - Blob decryption key\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.relogin = function(url, id, key, device_id, callback) {\n //use the url from previously retrieved authInfo, if necessary\n if (!url && this.infos[id]) {\n url = this.infos[id].blobvault;\n }\n\n if (!url) {\n return callback(new Error('Blob vault URL is required'));\n }\n\n var options = {\n url : url,\n blob_id : id,\n key : key,\n device_id : device_id\n };\n \n blobClient.get(options, function(err, blob) {\n if (err) {\n callback(err);\n } else {\n callback (null, { blob: blob });\n }\n });\n};\n\n/**\n * Decrypt the secret key using a username and password\n *\n * @param {string} username\n * @param {string} password\n * @param {string} encryptSecret\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.unlock = function(username, password, encryptSecret, fn) {\n var self = this;\n \n var steps = [\n getAuthInfo,\n self._deriveUnlockKey,\n unlockSecret\n ];\n\n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(username, function(err, authInfo){\n \n if (authInfo && !authInfo.exists) {\n return callback(new Error('User does not exist.'));\n }\n \n return callback (err, authInfo, password, {});\n }); \n }\n \n function unlockSecret (authinfo, keys, callback) {\n\n var secret;\n try {\n secret = crypt.decrypt(keys.unlock, encryptSecret);\n } catch (error) {\n return callback(error);\n } \n \n callback(null, {\n keys : keys,\n secret : secret\n }); \n }\n};\n\n/**\n * Retrieve the decrypted blob and secret key in one step using\n * the username and password\n *\n * @param {string} username\n * @param {string} password\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.loginAndUnlock = function(username, password, device_id, fn) {\n var self = this;\n\n var steps = [\n login,\n deriveUnlockKey,\n unlockSecret\n ];\n\n async.waterfall(steps, fn); \n \n function login (callback) {\n self.login(username, password, device_id, function(err, resp) {\n\n if (err) {\n return callback(err);\n }\n \n if (!resp.blob || !resp.blob.encrypted_secret) {\n return callback(new Error('Unable to retrieve blob and secret.'));\n }\n \n if (!resp.blob.id || !resp.blob.key) {\n return callback(new Error('Unable to retrieve keys.'));\n }\n \n //get authInfo via id - would have been saved from login\n var authInfo = self.infos[resp.blob.id];\n \n if (!authInfo) {\n return callback(new Error('Unable to find authInfo'));\n }\n \n callback(null, authInfo, password, resp.blob);\n }); \n };\n\n function deriveUnlockKey (authInfo, password, blob, callback) {\n self._deriveUnlockKey(authInfo, password, null, function(err, authInfo, keys){\n callback(err, keys.unlock, authInfo, blob);\n });\n };\n \n function unlockSecret (unlock, authInfo, blob, callback) {\n var secret;\n try {\n secret = crypt.decrypt(unlock, blob.encrypted_secret);\n } catch (error) {\n return callback(error);\n } \n \n callback(null, {\n blob : blob,\n unlock : unlock,\n secret : secret,\n username : authInfo.username,\n verified : authInfo.emailVerified\n }); \n }; \n};\n\n/**\n * Verify an email address for an existing user\n *\n * @param {string} username\n * @param {string} token - Verification token\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.verify = function(username, token, callback) {\n var self = this;\n\n self.getAuthInfo(username, function (err, authInfo){\n if (err) {\n return callback(err);\n }\n \n blobClient.verify(authInfo.blobvault, username.toLowerCase(), token, callback); \n });\n};\n\n/*\n * changePassword\n * @param {object} options\n * @param {string} options.username\n * @param {string} options.password\n * @param {string} options.masterkey\n * @param {object} options.blob\n */\n\nVaultClient.prototype.changePassword = function (options, fn) {\n var self = this;\n var password = String(options.password).trim();\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n self._deriveUnlockKey,\n changePassword\n ];\n \n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(options.username, function(err, authInfo) { \n return callback (err, authInfo, password); \n });\n };\n \n function changePassword (authInfo, keys, callback) {\n options.keys = keys;\n blobClient.updateKeys(options, callback); \n };\n};\n\n/**\n * rename\n * rename a ripple account\n * @param {object} options\n * @param {string} options.username\n * @param {string} options.new_username\n * @param {string} options.password\n * @param {string} options.masterkey\n * @param {object} options.blob\n * @param {function} fn\n */\n\nVaultClient.prototype.rename = function (options, fn) {\n var self = this;\n var new_username = String(options.new_username).trim();\n var password = String(options.password).trim();\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n self._deriveUnlockKey,\n renameBlob\n ];\n\n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(new_username, function(err, authInfo){\n \n if (authInfo && authInfo.exists) {\n return callback(new Error('username already taken.'));\n } else {\n authInfo.username = new_username;\n }\n \n return callback (err, authInfo, password);\n }); \n };\n \n function renameBlob (authInfo, keys, callback) {\n options.keys = keys;\n blobClient.rename(options, callback); \n };\n};\n\n/**\n * Register a new user and save to the blob vault\n *\n * @param {object} options\n * @param {string} options.username\n * @param {string} options.password\n * @param {string} options.masterkey //optional, will create if absent\n * @param {string} options.email\n * @param {string} options.activateLink\n * @param {object} options.oldUserBlob //optional\n * @param {function} fn\n */\n\nVaultClient.prototype.register = function(options, fn) {\n var self = this;\n var username = String(options.username).trim();\n var password = String(options.password).trim();\n var result = self.validateUsername(username);\n \n if (!result.valid) {\n return fn(new Error('invalid username.')); \n }\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n self._deriveUnlockKey,\n create\n ];\n \n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(username, function(err, authInfo){ \n return callback (err, authInfo, password);\n }); \n };\n\n function create(authInfo, keys, callback) {\n var params = {\n url : authInfo.blobvault,\n id : keys.id,\n crypt : keys.crypt,\n unlock : keys.unlock,\n username : username,\n email : options.email,\n masterkey : options.masterkey || crypt.createMaster(),\n activateLink : options.activateLink,\n oldUserBlob : options.oldUserBlob,\n domain : options.domain\n };\n \n blobClient.create(params, function(err, blob) {\n if (err) {\n callback(err);\n } else {\n callback(null, {\n blob : blob, \n username : username\n });\n }\n });\n };\n};\n\n/**\n * validateUsername\n * check username for validity \n */\n\nVaultClient.prototype.validateUsername = function (username) {\n username = String(username).trim();\n var result = {\n valid : false,\n reason : ''\n };\n \n if (username.length < 2) {\n result.reason = 'tooshort';\n } else if (username.length > 20) {\n result.reason = 'toolong'; \n } else if (!/^[a-zA-Z0-9\\-]+$/.exec(username)) {\n result.reason = 'charset'; \n } else if (/^-/.exec(username)) {\n result.reason = 'starthyphen'; \n } else if (/-$/.exec(username)) {\n result.reason = 'endhyphen'; \n } else if (/--/.exec(username)) {\n result.reason = 'multhyphen'; \n } else {\n result.valid = true;\n }\n \n return result;\n};\n\n/**\n * generateDeviceID\n * create a new random device ID for 2FA\n */\nVaultClient.prototype.generateDeviceID = function () {\n return crypt.createSecret(4);\n};\n\n/*** pass thru some blob client function ***/\n\nVaultClient.prototype.resendEmail = blobClient.resendEmail;\n\nVaultClient.prototype.updateProfile = blobClient.updateProfile;\n\nVaultClient.prototype.recoverBlob = blobClient.recoverBlob;\n\nVaultClient.prototype.deleteBlob = blobClient.deleteBlob;\n\nVaultClient.prototype.requestToken = blobClient.requestToken;\n\nVaultClient.prototype.verifyToken = blobClient.verifyToken;\n\n//export by name\nexports.VaultClient = VaultClient;\n\n\n// WEBPACK FOOTER\n// module.id = 15\n// module.readableIdentifier = ./src/js/ripple/vaultclient.js\n//@ sourceURL=webpack-module:///./src/js/ripple/vaultclient.js"); + eval("var async = __webpack_require__(48);\nvar blobClient = __webpack_require__(32).BlobClient;\nvar AuthInfo = __webpack_require__(16).AuthInfo;\nvar crypt = __webpack_require__(30).Crypt;\nvar log = __webpack_require__(24).sub('vault');\nfunction VaultClient(opts) {\n \n var self = this;\n \n if (!opts) {\n opts = { };\n }\n\n if (typeof opts === 'string') {\n opts = { domain: opts };\n }\n\n this.domain = opts.domain || 'ripple.com';\n this.infos = { };\n};\n\n/**\n * getAuthInfo\n * gets auth info for a username. returns authinfo\n * even if user does not exists (with exist set to false)\n * @param {string} username\n * @param {function} callback\n */\nVaultClient.prototype.getAuthInfo = function (username, callback) {\n\n AuthInfo.get(this.domain, username, function(err, authInfo) {\n if (err) {\n return callback(err);\n }\n\n if (authInfo.version !== 3) {\n return callback(new Error('This wallet is incompatible with this version of the vault-client.'));\n }\n\n if (!authInfo.pakdf) {\n return callback(new Error('No settings for PAKDF in auth packet.'));\n }\n\n if (typeof authInfo.blobvault !== 'string') {\n return callback(new Error('No blobvault specified in the authinfo.'));\n }\n\n callback(null, authInfo);\n }); \n};\n\n/**\n * _deriveLoginKeys\n * method designed for asnyc waterfall\n */\n\nVaultClient.prototype._deriveLoginKeys = function (authInfo, password, callback) {\n var normalizedUsername = authInfo.username.toLowerCase().replace(/-/g, '');\n \n //derive login keys\n crypt.derive(authInfo.pakdf, 'login', normalizedUsername, password, function(err, keys) {\n if (err) {\n callback(err);\n } else {\n callback(null, authInfo, password, keys);\n }\n });\n};\n\n\n\n/**\n * _deriveUnlockKey\n * method designed for asnyc waterfall\n */\n\nVaultClient.prototype._deriveUnlockKey = function (authInfo, password, keys, callback) {\n var normalizedUsername = authInfo.username.toLowerCase().replace(/-/g, '');\n \n //derive unlock key\n crypt.derive(authInfo.pakdf, 'unlock', normalizedUsername, password, function(err, unlock) {\n if (err) {\n log.error('derive:', err);\n return callback(err);\n }\n\n if (!keys) {\n keys = { };\n }\n \n keys.unlock = unlock.unlock;\n callback(null, authInfo, keys);\n });\n};\n \n/**\n * Get a ripple name from a given account address, if it has one\n * @param {string} address - Account address to query\n * @param {string} url - Url of blob vault\n */\n\nVaultClient.prototype.getRippleName = function(address, url, callback) {\n //use the url from previously retrieved authInfo, if necessary\n if (!url) {\n callback(new Error('Blob vault URL is required'));\n } else {\n blobClient.getRippleName(url, address, callback);\n }\n};\n\n/**\n * Check blobvault for existance of username\n *\n * @param {string} username\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.exists = function(username, callback) {\n AuthInfo.get(this.domain, username.toLowerCase(), function(err, authInfo) {\n if (err) {\n callback(err);\n } else {\n callback(null, !!authInfo.exists);\n }\n });\n};\n\n/**\n * Authenticate and retrieve a decrypted blob using a ripple name and password\n *\n * @param {string} username\n * @param {string} password\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.login = function(username, password, device_id, callback) {\n var self = this;\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n getBlob\n ];\n\n async.waterfall(steps, callback);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(username, function(err, authInfo){\n \n if (authInfo && !authInfo.exists) {\n return callback(new Error('User does not exist.'));\n }\n \n return callback (err, authInfo, password);\n }); \n }\n \n function getBlob(authInfo, password, keys, callback) {\n var options = {\n url : authInfo.blobvault,\n blob_id : keys.id,\n key : keys.crypt,\n device_id : device_id\n };\n \n blobClient.get(options, function(err, blob) {\n if (err) {\n return callback(err);\n }\n\n //save for relogin\n self.infos[keys.id] = authInfo;\n\n //migrate missing fields\n if (blob.missing_fields) {\n if (blob.missing_fields.encrypted_blobdecrypt_key) { \n log.info('migration: saving encrypted blob decrypt key');\n authInfo.blob = blob;\n //get the key to unlock the secret, then update the blob keys \n self._deriveUnlockKey(authInfo, password, keys, updateKeys);\n }\n }\n \n callback(null, {\n blob : blob,\n username : authInfo.username,\n verified : authInfo.emailVerified\n });\n });\n };\n \n function updateKeys (err, params, keys) {\n if (err || !keys.unlock) {\n return; //unable to unlock\n }\n \n var secret;\n try {\n secret = crypt.decrypt(keys.unlock, params.blob.encrypted_secret);\n } catch (error) {\n return log.error('decrypt:', error);\n } \n \n options = {\n username : params.username,\n blob : params.blob,\n masterkey : secret,\n keys : keys\n };\n \n blobClient.updateKeys(options, function(err, resp){\n if (err) {\n log.error('updateKeys:', err);\n }\n }); \n } \n};\n\n/**\n * Retreive and decrypt blob using a blob url, id and crypt derived previously.\n *\n * @param {string} url - Blob vault url\n * @param {string} id - Blob id from previously retreived blob\n * @param {string} key - Blob decryption key\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.relogin = function(url, id, key, device_id, callback) {\n //use the url from previously retrieved authInfo, if necessary\n if (!url && this.infos[id]) {\n url = this.infos[id].blobvault;\n }\n\n if (!url) {\n return callback(new Error('Blob vault URL is required'));\n }\n\n var options = {\n url : url,\n blob_id : id,\n key : key,\n device_id : device_id\n };\n \n blobClient.get(options, function(err, blob) {\n if (err) {\n callback(err);\n } else {\n callback (null, { blob: blob });\n }\n });\n};\n\n/**\n * Decrypt the secret key using a username and password\n *\n * @param {string} username\n * @param {string} password\n * @param {string} encryptSecret\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.unlock = function(username, password, encryptSecret, fn) {\n var self = this;\n \n var steps = [\n getAuthInfo,\n self._deriveUnlockKey,\n unlockSecret\n ];\n\n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(username, function(err, authInfo){\n \n if (authInfo && !authInfo.exists) {\n return callback(new Error('User does not exist.'));\n }\n \n return callback (err, authInfo, password, {});\n }); \n }\n \n function unlockSecret (authinfo, keys, callback) {\n\n var secret;\n try {\n secret = crypt.decrypt(keys.unlock, encryptSecret);\n } catch (error) {\n return callback(error);\n } \n \n callback(null, {\n keys : keys,\n secret : secret\n }); \n }\n};\n\n/**\n * Retrieve the decrypted blob and secret key in one step using\n * the username and password\n *\n * @param {string} username\n * @param {string} password\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.loginAndUnlock = function(username, password, device_id, fn) {\n var self = this;\n\n var steps = [\n login,\n deriveUnlockKey,\n unlockSecret\n ];\n\n async.waterfall(steps, fn); \n \n function login (callback) {\n self.login(username, password, device_id, function(err, resp) {\n\n if (err) {\n return callback(err);\n }\n \n if (!resp.blob || !resp.blob.encrypted_secret) {\n return callback(new Error('Unable to retrieve blob and secret.'));\n }\n \n if (!resp.blob.id || !resp.blob.key) {\n return callback(new Error('Unable to retrieve keys.'));\n }\n \n //get authInfo via id - would have been saved from login\n var authInfo = self.infos[resp.blob.id];\n \n if (!authInfo) {\n return callback(new Error('Unable to find authInfo'));\n }\n \n callback(null, authInfo, password, resp.blob);\n }); \n };\n\n function deriveUnlockKey (authInfo, password, blob, callback) {\n self._deriveUnlockKey(authInfo, password, null, function(err, authInfo, keys){\n callback(err, keys.unlock, authInfo, blob);\n });\n };\n \n function unlockSecret (unlock, authInfo, blob, callback) {\n var secret;\n try {\n secret = crypt.decrypt(unlock, blob.encrypted_secret);\n } catch (error) {\n return callback(error);\n } \n \n callback(null, {\n blob : blob,\n unlock : unlock,\n secret : secret,\n username : authInfo.username,\n verified : authInfo.emailVerified\n }); \n }; \n};\n\n/**\n * Verify an email address for an existing user\n *\n * @param {string} username\n * @param {string} token - Verification token\n * @param {function} fn - Callback function\n */\n\nVaultClient.prototype.verify = function(username, token, callback) {\n var self = this;\n\n self.getAuthInfo(username, function (err, authInfo){\n if (err) {\n return callback(err);\n }\n \n blobClient.verify(authInfo.blobvault, username.toLowerCase(), token, callback); \n });\n};\n\n/*\n * changePassword\n * @param {object} options\n * @param {string} options.username\n * @param {string} options.password\n * @param {string} options.masterkey\n * @param {object} options.blob\n */\n\nVaultClient.prototype.changePassword = function (options, fn) {\n var self = this;\n var password = String(options.password).trim();\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n self._deriveUnlockKey,\n changePassword\n ];\n \n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(options.username, function(err, authInfo) { \n return callback (err, authInfo, password); \n });\n };\n \n function changePassword (authInfo, keys, callback) {\n options.keys = keys;\n blobClient.updateKeys(options, callback); \n };\n};\n\n/**\n * rename\n * rename a ripple account\n * @param {object} options\n * @param {string} options.username\n * @param {string} options.new_username\n * @param {string} options.password\n * @param {string} options.masterkey\n * @param {object} options.blob\n * @param {function} fn\n */\n\nVaultClient.prototype.rename = function (options, fn) {\n var self = this;\n var new_username = String(options.new_username).trim();\n var password = String(options.password).trim();\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n self._deriveUnlockKey,\n renameBlob\n ];\n\n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(new_username, function(err, authInfo){\n \n if (authInfo && authInfo.exists) {\n return callback(new Error('username already taken.'));\n } else {\n authInfo.username = new_username;\n }\n \n return callback (err, authInfo, password);\n }); \n };\n \n function renameBlob (authInfo, keys, callback) {\n options.keys = keys;\n blobClient.rename(options, callback); \n };\n};\n\n/**\n * Register a new user and save to the blob vault\n *\n * @param {object} options\n * @param {string} options.username\n * @param {string} options.password\n * @param {string} options.masterkey //optional, will create if absent\n * @param {string} options.email\n * @param {string} options.activateLink\n * @param {object} options.oldUserBlob //optional\n * @param {function} fn\n */\n\nVaultClient.prototype.register = function(options, fn) {\n var self = this;\n var username = String(options.username).trim();\n var password = String(options.password).trim();\n var result = self.validateUsername(username);\n \n if (!result.valid) {\n return fn(new Error('invalid username.')); \n }\n \n var steps = [\n getAuthInfo,\n self._deriveLoginKeys,\n self._deriveUnlockKey,\n create\n ];\n \n async.waterfall(steps, fn);\n \n function getAuthInfo(callback) {\n self.getAuthInfo(username, function(err, authInfo){ \n return callback (err, authInfo, password);\n }); \n };\n\n function create(authInfo, keys, callback) {\n var params = {\n url : authInfo.blobvault,\n id : keys.id,\n crypt : keys.crypt,\n unlock : keys.unlock,\n username : username,\n email : options.email,\n masterkey : options.masterkey || crypt.createMaster(),\n activateLink : options.activateLink,\n oldUserBlob : options.oldUserBlob,\n domain : options.domain\n };\n \n blobClient.create(params, function(err, blob) {\n if (err) {\n callback(err);\n } else {\n callback(null, {\n blob : blob, \n username : username\n });\n }\n });\n };\n};\n\n/**\n * validateUsername\n * check username for validity \n */\n\nVaultClient.prototype.validateUsername = function (username) {\n username = String(username).trim();\n var result = {\n valid : false,\n reason : ''\n };\n \n if (username.length < 2) {\n result.reason = 'tooshort';\n } else if (username.length > 20) {\n result.reason = 'toolong'; \n } else if (!/^[a-zA-Z0-9\\-]+$/.exec(username)) {\n result.reason = 'charset'; \n } else if (/^-/.exec(username)) {\n result.reason = 'starthyphen'; \n } else if (/-$/.exec(username)) {\n result.reason = 'endhyphen'; \n } else if (/--/.exec(username)) {\n result.reason = 'multhyphen'; \n } else {\n result.valid = true;\n }\n \n return result;\n};\n\n/**\n * generateDeviceID\n * create a new random device ID for 2FA\n */\nVaultClient.prototype.generateDeviceID = function () {\n return crypt.createSecret(4);\n};\n\n/*** pass thru some blob client function ***/\n\nVaultClient.prototype.resendEmail = blobClient.resendEmail;\n\nVaultClient.prototype.updateProfile = blobClient.updateProfile;\n\nVaultClient.prototype.recoverBlob = blobClient.recoverBlob;\n\nVaultClient.prototype.deleteBlob = blobClient.deleteBlob;\n\nVaultClient.prototype.requestToken = blobClient.requestToken;\n\nVaultClient.prototype.verifyToken = blobClient.verifyToken;\n\n//export by name\nexports.VaultClient = VaultClient;\n\n\n// WEBPACK FOOTER\n// module.id = 15\n// module.readableIdentifier = ./src/js/ripple/vaultclient.js\n//@ sourceURL=webpack-module:///./src/js/ripple/vaultclient.js"); /***/ }, /* 16 */ /***/ function(module, exports, __webpack_require__) { - eval("var async = __webpack_require__(48);\nvar superagent = __webpack_require__(54);\nvar RippleTxt = __webpack_require__(17).RippleTxt;\n\nvar AuthInfo = { };\n\nAuthInfo._getRippleTxt = function(domain, callback) {\n RippleTxt.get(domain, callback);\n};\n\nAuthInfo._getUser = function(url, callback) {\n superagent.get(url, callback);\n};\n\n\n/**\n * Get auth info for a given username\n *\n * @param {string} domain - Domain which hosts the user's info\n * @param {string} username - Username who's info we are retreiving\n * @param {function} fn - Callback function\n */\n\nAuthInfo.get = function(domain, username, callback) {\n var self = this;\n username = username.toLowerCase();\n \n function getRippleTxt(callback) {\n self._getRippleTxt(domain, function(err, txt) {\n if (err) {\n return callback(err);\n }\n\n if (!txt.authinfo_url) {\n return callback(new Error('Authentication is not supported on ' + domain));\n }\n\n var url = Array.isArray(txt.authinfo_url) ? txt.authinfo_url[0] : txt.authinfo_url;\n\n url += '?domain=' + domain + '&username=' + username;\n\n callback(null, url);\n });\n };\n\n function getUser(url, callback) {\n self._getUser(url, function(err, res) {\n if (err || res.error) {\n callback(new Error('Authentication info server unreachable'));\n } else {\n callback(null, res.body);\n }\n });\n };\n\n async.waterfall([ getRippleTxt, getUser ], callback);\n};\n\nexports.AuthInfo = AuthInfo;\n\n\n// WEBPACK FOOTER\n// module.id = 16\n// module.readableIdentifier = ./src/js/ripple/authinfo.js\n//@ sourceURL=webpack-module:///./src/js/ripple/authinfo.js"); + eval("var async = __webpack_require__(48);\nvar superagent = __webpack_require__(49);\nvar RippleTxt = __webpack_require__(17).RippleTxt;\n\nvar AuthInfo = { };\n\nAuthInfo._getRippleTxt = function(domain, callback) {\n RippleTxt.get(domain, callback);\n};\n\nAuthInfo._getUser = function(url, callback) {\n superagent.get(url, callback);\n};\n\n\n/**\n * Get auth info for a given username\n *\n * @param {string} domain - Domain which hosts the user's info\n * @param {string} username - Username who's info we are retreiving\n * @param {function} fn - Callback function\n */\n\nAuthInfo.get = function(domain, username, callback) {\n var self = this;\n username = username.toLowerCase();\n \n function getRippleTxt(callback) {\n self._getRippleTxt(domain, function(err, txt) {\n if (err) {\n return callback(err);\n }\n\n if (!txt.authinfo_url) {\n return callback(new Error('Authentication is not supported on ' + domain));\n }\n\n var url = Array.isArray(txt.authinfo_url) ? txt.authinfo_url[0] : txt.authinfo_url;\n\n url += '?domain=' + domain + '&username=' + username;\n\n callback(null, url);\n });\n };\n\n function getUser(url, callback) {\n self._getUser(url, function(err, res) {\n if (err || res.error) {\n callback(new Error('Authentication info server unreachable'));\n } else {\n callback(null, res.body);\n }\n });\n };\n\n async.waterfall([ getRippleTxt, getUser ], callback);\n};\n\nexports.AuthInfo = AuthInfo;\n\n\n// WEBPACK FOOTER\n// module.id = 16\n// module.readableIdentifier = ./src/js/ripple/authinfo.js\n//@ sourceURL=webpack-module:///./src/js/ripple/authinfo.js"); /***/ }, /* 17 */ /***/ function(module, exports, __webpack_require__) { - eval("var request = __webpack_require__(54);\nvar Currency = __webpack_require__(6).Currency;\n\nvar RippleTxt = {\n txts : { }\n};\n\nRippleTxt.urlTemplates = [\n 'https://{{domain}}/ripple.txt',\n 'https://www.{{domain}}/ripple.txt',\n 'https://ripple.{{domain}}/ripple.txt',\n 'http://{{domain}}/ripple.txt',\n 'http://www.{{domain}}/ripple.txt',\n 'http://ripple.{{domain}}/ripple.txt'\n];\n\n/**\n * Gets the ripple.txt file for the given domain\n * @param {string} domain - Domain to retrieve file from\n * @param {function} fn - Callback function\n */\n\nRippleTxt.get = function(domain, fn) {\n var self = this;\n\n if (self.txts[domain]) {\n return fn(null, self.txts[domain]);\n }\n\n ;(function nextUrl(i) {\n var url = RippleTxt.urlTemplates[i];\n \n if (!url) {\n return fn(new Error('No ripple.txt found'));\n }\n\n url = url.replace('{{domain}}', domain);\n \n request.get(url, function(err, resp) {\n if (err || !resp.text) {\n return nextUrl(++i);\n }\n\n var sections = self.parse(resp.text);\n self.txts[domain] = sections;\n\n fn(null, sections);\n });\n })(0);\n};\n\n/**\n * Parse a ripple.txt file\n * @param {string} txt - Unparsed ripple.txt data\n */\n\nRippleTxt.parse = function(txt) {\n var currentSection = '';\n var sections = { };\n \n txt = txt.replace(/\\r?\\n/g, '\\n').split('\\n');\n\n for (var i = 0, l = txt.length; i < l; i++) {\n var line = txt[i];\n\n if (!line.length || line[0] === '#') {\n continue;\n }\n\n if (line[0] === '[' && line[line.length - 1] === ']') {\n currentSection = line.slice(1, line.length - 1);\n sections[currentSection] = [];\n } else {\n line = line.replace(/^\\s+|\\s+$/g, '');\n if (sections[currentSection]) {\n sections[currentSection].push(line);\n }\n }\n }\n\n return sections;\n};\n\n/**\n * extractDomain\n * attempt to extract the domain from a given url\n * returns the url if unsuccessful\n * @param {Object} url\n */\n\nRippleTxt.extractDomain = function (url) {\n match = /[^.]*\\.[^.]{2,3}(?:\\.[^.]{2,3})?([^.\\?][^\\?.]+?)?$/.exec(url);\n return match && match[0] ? match[0] : url;\n};\n\n/**\n * getCurrencies\n * returns domain, issuer account and currency object\n * for each currency found in the domain's ripple.txt file\n * @param {Object} domain\n * @param {Object} fn\n */\n\nRippleTxt.getCurrencies = function(domain, fn) {\n domain = RippleTxt.extractDomain(domain);\n this.get(domain, function(err, txt) {\n if (err) {\n return fn(err); \n }\n \n if (err || !txt.currencies || !txt.accounts) {\n return fn(null, []);\n }\n \n //NOTE: this won't be accurate if there are\n //multiple issuer accounts with different \n //currencies associated with each.\n var issuer = txt.accounts[0];\n var currencies = [];\n \n txt.currencies.forEach(function(currency) {\n currencies.push({\n issuer : issuer,\n currency : Currency.from_json(currency),\n domain : domain\n });\n });\n \n fn(null, currencies);\n });\n}; \n\nexports.RippleTxt = RippleTxt;\n\n\n// WEBPACK FOOTER\n// module.id = 17\n// module.readableIdentifier = ./src/js/ripple/rippletxt.js\n//@ sourceURL=webpack-module:///./src/js/ripple/rippletxt.js"); + eval("var request = __webpack_require__(49);\nvar Currency = __webpack_require__(6).Currency;\n\nvar RippleTxt = {\n txts : { }\n};\n\nRippleTxt.urlTemplates = [\n 'https://{{domain}}/ripple.txt',\n 'https://www.{{domain}}/ripple.txt',\n 'https://ripple.{{domain}}/ripple.txt',\n 'http://{{domain}}/ripple.txt',\n 'http://www.{{domain}}/ripple.txt',\n 'http://ripple.{{domain}}/ripple.txt'\n];\n\n/**\n * Gets the ripple.txt file for the given domain\n * @param {string} domain - Domain to retrieve file from\n * @param {function} fn - Callback function\n */\n\nRippleTxt.get = function(domain, fn) {\n var self = this;\n\n if (self.txts[domain]) {\n return fn(null, self.txts[domain]);\n }\n\n ;(function nextUrl(i) {\n var url = RippleTxt.urlTemplates[i];\n \n if (!url) {\n return fn(new Error('No ripple.txt found'));\n }\n\n url = url.replace('{{domain}}', domain);\n \n request.get(url, function(err, resp) {\n if (err || !resp.text) {\n return nextUrl(++i);\n }\n\n var sections = self.parse(resp.text);\n self.txts[domain] = sections;\n\n fn(null, sections);\n });\n })(0);\n};\n\n/**\n * Parse a ripple.txt file\n * @param {string} txt - Unparsed ripple.txt data\n */\n\nRippleTxt.parse = function(txt) {\n var currentSection = '';\n var sections = { };\n \n txt = txt.replace(/\\r?\\n/g, '\\n').split('\\n');\n\n for (var i = 0, l = txt.length; i < l; i++) {\n var line = txt[i];\n\n if (!line.length || line[0] === '#') {\n continue;\n }\n\n if (line[0] === '[' && line[line.length - 1] === ']') {\n currentSection = line.slice(1, line.length - 1);\n sections[currentSection] = [];\n } else {\n line = line.replace(/^\\s+|\\s+$/g, '');\n if (sections[currentSection]) {\n sections[currentSection].push(line);\n }\n }\n }\n\n return sections;\n};\n\n/**\n * extractDomain\n * attempt to extract the domain from a given url\n * returns the url if unsuccessful\n * @param {Object} url\n */\n\nRippleTxt.extractDomain = function (url) {\n match = /[^.]*\\.[^.]{2,3}(?:\\.[^.]{2,3})?([^.\\?][^\\?.]+?)?$/.exec(url);\n return match && match[0] ? match[0] : url;\n};\n\n/**\n * getCurrencies\n * returns domain, issuer account and currency object\n * for each currency found in the domain's ripple.txt file\n * @param {Object} domain\n * @param {Object} fn\n */\n\nRippleTxt.getCurrencies = function(domain, fn) {\n domain = RippleTxt.extractDomain(domain);\n this.get(domain, function(err, txt) {\n if (err) {\n return fn(err); \n }\n \n if (err || !txt.currencies || !txt.accounts) {\n return fn(null, []);\n }\n \n //NOTE: this won't be accurate if there are\n //multiple issuer accounts with different \n //currencies associated with each.\n var issuer = txt.accounts[0];\n var currencies = [];\n \n txt.currencies.forEach(function(currency) {\n currencies.push({\n issuer : issuer,\n currency : Currency.from_json(currency),\n domain : domain\n });\n });\n \n fn(null, currencies);\n });\n}; \n\nexports.RippleTxt = RippleTxt;\n\n\n// WEBPACK FOOTER\n// module.id = 17\n// module.readableIdentifier = ./src/js/ripple/rippletxt.js\n//@ sourceURL=webpack-module:///./src/js/ripple/rippletxt.js"); /***/ }, /* 18 */ @@ -166,7 +166,7 @@ var ripple = /* 20 */ /***/ function(module, exports, __webpack_require__) { - eval("var util = __webpack_require__(37);\nvar url = __webpack_require__(42);\nvar EventEmitter = __webpack_require__(36).EventEmitter;\nvar Amount = __webpack_require__(3).Amount;\nvar Transaction = __webpack_require__(5).Transaction;\nvar log = __webpack_require__(24).internal.sub('server');\n\n/**\n * @constructor Server\n *\n * @param {Remote} Reference to a Remote object\n * @param {Object} Options\n * @param {String} host\n * @param {Number|String} port\n * @param [Boolean] securec\n */\n\nfunction Server(remote, opts) {\n EventEmitter.call(this);\n\n var self = this;\n\n if (typeof opts === 'string') {\n var parsedUrl = url.parse(opts);\n opts = {\n host: parsedUrl.hostname,\n port: parsedUrl.port,\n secure: (parsedUrl.protocol === 'ws:') ? false : true\n };\n }\n\n if (typeof opts !== 'object') {\n throw new TypeError('Server configuration is not an Object');\n }\n\n if (!Server.domainRE.test(opts.host)) {\n throw new Error('Server host is malformed, use \"host\" and \"port\" server configuration');\n }\n\n // We want to allow integer strings as valid port numbers for backward compatibility\n if (!(opts.port = Number(opts.port))) {\n throw new TypeError('Server port must be a number');\n }\n\n if (opts.port < 1 || opts.port > 65535) {\n throw new TypeError('Server \"port\" must be an integer in range 1-65535');\n }\n\n if (typeof opts.secure !== 'boolean') {\n opts.secure = true;\n }\n\n this._remote = remote;\n this._opts = opts;\n this._ws = void(0);\n\n this._connected = false;\n this._shouldConnect = false;\n this._state = 'offline';\n\n this._id = 0; // request ID\n this._retry = 0;\n this._requests = { };\n\n this._load_base = 256;\n this._load_factor = 256;\n\n this._fee = 10;\n this._fee_ref = 10;\n this._fee_base = 10;\n this._reserve_base = void(0);\n this._reserve_inc = void(0);\n this._fee_cushion = this._remote.fee_cushion;\n\n this._lastLedgerIndex = NaN;\n this._lastLedgerClose = NaN;\n\n this._score = 0;\n\n this._scoreWeights = {\n ledgerclose: 5,\n response: 1\n };\n\n this._pubkey_node = '';\n\n this._url = this._opts.url = (this._opts.secure ? 'wss://' : 'ws://')\n + this._opts.host + ':' + this._opts.port;\n\n this.on('message', function onMessage(message) {\n self._handleMessage(message);\n });\n\n this.on('response_subscribe', function onSubscribe(message) {\n self._handleResponseSubscribe(message);\n });\n\n function setActivityInterval() {\n var interval = self._checkActivity.bind(self);\n self._activityInterval = setInterval(interval, 1000);\n };\n\n this.on('disconnect', function onDisconnect() {\n clearInterval(self._activityInterval);\n self.once('ledger_closed', setActivityInterval);\n });\n\n this.once('ledger_closed', setActivityInterval);\n\n this._remote.on('ledger_closed', function onRemoteLedgerClose(ledger) {\n self._updateScore('ledgerclose', ledger);\n });\n\n this.on('response_ping', function onPingResponse(message, request) {\n self._updateScore('response', request);\n });\n\n this.on('load_changed', function onLoadChange(load) {\n self._updateScore('loadchange', load);\n });\n\n // If server is not up-to-date, request server_info\n // for getting pubkey_node & hostid information.\n // Otherwise this information is available on the\n // initial server subscribe response\n this.on('connect', function requestServerID() {\n if (self._pubkey_node) {\n return;\n }\n\n self.on('response_server_info', function setServerID(message) {\n try {\n self._pubkey_node = message.info.pubkey_node;\n } catch (e) {\n }\n });\n\n self._request(self._remote.requestServerInfo());\n });\n};\n\nutil.inherits(Server, EventEmitter);\n\nServer.domainRE = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?(?:\\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?)*\\.?$/;\n\n/**\n * Server states that we will treat as the server being online.\n *\n * Our requirements are that the server can process transactions and notify\n * us of changes.\n */\n\nServer.onlineStates = [\n 'syncing',\n 'tracking',\n 'proposing',\n 'validating',\n 'full'\n];\n\n/**\n * This is the final interface between client code and a socket connection to a\n * `rippled` server. As such, this is a decent hook point to allow a WebSocket\n * interface conforming object to be used as a basis to mock rippled. This\n * avoids the need to bind a websocket server to a port and allows a more\n * synchronous style of code to represent a client <-> server message sequence.\n * We can also use this to log a message sequence to a buffer.\n *\n * @api private\n */\n\nServer.websocketConstructor = function() {\n // We require this late, because websocket shims may be loaded after\n // ripple-lib in the browser\n return __webpack_require__(35);\n};\n\n/**\n * Set server state\n *\n * @param {String} state\n * @api private\n */\n\nServer.prototype._setState = function(state) {\n if (state !== this._state) {\n if (this._remote.trace) {\n log.info(this.getHostID(), 'set_state:', state);\n }\n\n this._state = state;\n this.emit('state', state);\n\n switch (state) {\n case 'online':\n this._connected = true;\n this._retry = 0;\n this.emit('connect');\n break;\n case 'offline':\n this._connected = false;\n this.emit('disconnect');\n break;\n }\n }\n};\n\n/**\n * Check that server is still active.\n *\n * Server activity is determined by ledger_closed events.\n * Maximum delay to receive a ledger_closed event is 20s.\n *\n * If server is inactive, reconnect\n *\n * @api private\n */\n\nServer.prototype._checkActivity = function() {\n if (!this.isConnected()) {\n return;\n }\n\n if (isNaN(this._lastLedgerClose)) {\n return;\n }\n\n var delta = (Date.now() - this._lastLedgerClose);\n\n if (delta > (1000 * 25)) {\n if (this._remote.trace) {\n log.info(this.getHostID(), 'reconnect: activity delta:', delta);\n }\n this.reconnect();\n }\n};\n\n/**\n * Server maintains a score for request prioritization.\n *\n * The score is determined by various data including\n * this server's lag to receive ledger_closed events,\n * ping response time, and load(fee) change\n *\n * @param {String} type\n * @param {Object} data\n * @api private\n */\n\nServer.prototype._updateScore = function(type, data) {\n if (!this.isConnected()) {\n return;\n }\n\n var weight = this._scoreWeights[type] || 1;\n\n switch (type) {\n case 'ledgerclose':\n // Ledger lag\n var delta = data.ledger_index - this._lastLedgerIndex;\n if (delta > 0) {\n this._score += weight * delta;\n }\n break;\n case 'response':\n // Ping lag\n var delta = Math.floor((Date.now() - data.time) / 200);\n this._score += weight * delta;\n break;\n case 'loadchange':\n // Load/fee change\n this._fee = Number(this._computeFee(10));\n break;\n }\n\n if (this._score > 1e3) {\n if (this._remote.trace) {\n log.info(this.getHostID(), 'reconnect: score:', this._score);\n }\n this.reconnect();\n }\n};\n\n/**\n * Get the server's remote address\n *\n * Incompatible with ripple-lib client build\n */\n\nServer.prototype.getRemoteAddress =\nServer.prototype._remoteAddress = function() {\n var address;\n try {\n address = this._ws._socket.remoteAddress;\n } catch (e) {\n }\n return address;\n};\n\n/**\n * Get the server's hostid\n */\n\nServer.prototype.getHostID =\nServer.prototype.getServerID = function() {\n return this._url + ' (' + (this._pubkey_node ? this._pubkey_node : '') + ')';\n};\n\n/**\n * Disconnect from rippled WebSocket server\n *\n * @api public\n */\n\nServer.prototype.disconnect = function() {\n var self = this;\n\n if (!this.isConnected()) {\n this.once('socket_open', function() {\n self.disconnect();\n });\n return;\n }\n\n //these need to be reset so that updateScore \n //and checkActivity do not trigger reconnect\n this._lastLedgerIndex = NaN;\n this._lastLedgerClose = NaN;\n this._score = 0;\n this._shouldConnect = false;\n this._setState('offline');\n\n if (this._ws) {\n this._ws.close();\n }\n};\n\n/**\n * Reconnect to rippled WebSocket server\n *\n * @api public\n */\n\nServer.prototype.reconnect = function() {\n var self = this;\n\n function reconnect() {\n self._shouldConnect = true;\n self._retry = 0;\n self.connect();\n };\n\n if (this._ws && this._shouldConnect) {\n if (this.isConnected()) {\n this.once('disconnect', reconnect);\n this.disconnect();\n } else {\n reconnect();\n }\n }\n};\n\n/**\n * Connect to rippled WebSocket server and subscribe to events that are\n * internally requisite. Automatically retry connections with a gradual\n * back-off\n *\n * @api public\n */\n\nServer.prototype.connect = function() {\n var self = this;\n\n var WebSocket = Server.websocketConstructor();\n\n if (!WebSocket) {\n throw new Error('No websocket support detected!');\n }\n\n // We don't connect if we believe we're already connected. This means we have\n // recently received a message from the server and the WebSocket has not\n // reported any issues either. If we do fail to ping or the connection drops,\n // we will automatically reconnect.\n if (this.isConnected()) {\n return;\n }\n\n // Ensure any existing socket is given the command to close first.\n if (this._ws) {\n this._ws.close();\n }\n\n if (this._remote.trace) {\n log.info(this.getServerID(), 'connect');\n }\n\n var ws = this._ws = new WebSocket(this._opts.url);\n\n this._shouldConnect = true;\n\n self.emit('connecting');\n\n ws.onmessage = function onMessage(msg) {\n self.emit('message', msg.data);\n };\n\n ws.onopen = function onOpen() {\n if (ws === self._ws) {\n self.emit('socket_open');\n // Subscribe to events\n self._request(self._remote._serverPrepareSubscribe());\n }\n };\n\n ws.onerror = function onError(e) {\n if (ws === self._ws) {\n self.emit('socket_error');\n\n if (self._remote.trace) {\n log.info(self.getServerID(), 'onerror:', e.data || e);\n }\n\n // Most connection errors for WebSockets are conveyed as 'close' events with\n // code 1006. This is done for security purposes and therefore unlikely to\n // ever change.\n\n // This means that this handler is hardly ever called in practice. If it is,\n // it probably means the server's WebSocket implementation is corrupt, or\n // the connection is somehow producing corrupt data.\n\n // Most WebSocket applications simply log and ignore this error. Once we\n // support for multiple servers, we may consider doing something like\n // lowering this server's quality score.\n\n // However, in Node.js this event may be triggered instead of the close\n // event, so we need to handle it.\n self._handleClose();\n }\n };\n\n ws.onclose = function onClose() {\n if (ws === self._ws) {\n if (self._remote.trace) {\n log.info(self.getServerID(), 'onclose:', ws.readyState);\n }\n self._handleClose();\n }\n };\n};\n\n/**\n * Retry connection to rippled server\n *\n * @api private\n */\n\nServer.prototype._retryConnect = function() {\n var self = this;\n\n this._retry += 1;\n\n var retryTimeout = (this._retry < 40)\n // First, for 2 seconds: 20 times per second\n ? (1000 / 20)\n : (this._retry < 40 + 60)\n // Then, for 1 minute: once per second\n ? (1000)\n : (this._retry < 40 + 60 + 60)\n // Then, for 10 minutes: once every 10 seconds\n ? (10 * 1000)\n // Then: once every 30 seconds\n : (30 * 1000);\n\n function connectionRetry() {\n if (self._shouldConnect) {\n if (self._remote.trace) {\n log.info(self.getServerID(), 'retry', self._retry);\n }\n self.connect();\n }\n };\n\n this._retryTimer = setTimeout(connectionRetry, retryTimeout);\n};\n\n/**\n * Handle connection closes\n *\n * @api private\n */\n\nServer.prototype._handleClose = function() {\n var self = this;\n var ws = this._ws;\n\n function noOp(){};\n\n // Prevent additional events from this socket\n ws.onopen = ws.onerror = ws.onclose = ws.onmessage = noOp;\n\n this.emit('socket_close');\n this._setState('offline');\n\n if (this._shouldConnect) {\n this._retryConnect();\n }\n};\n\n/**\n * Handle incoming messages from rippled WebSocket server\n *\n * @param {JSON-parseable} message\n * @api private\n */\n\nServer.prototype._handleMessage = function(message) {\n var self = this;\n\n try {\n message = JSON.parse(message);\n } catch(e) {\n }\n\n if (!Server.isValidMessage(message)) {\n this.emit('unexpected', message);\n return;\n }\n\n switch (message.type) {\n case 'ledgerClosed':\n this._handleLedgerClosed(message);\n break;\n case 'serverStatus':\n this._handleServerStatus(message);\n break;\n case 'response':\n this._handleResponse(message);\n break;\n case 'path_find':\n this._handlePathFind(message);\n break;\n }\n};\n\nServer.prototype._handleLedgerClosed = function(message) {\n this._lastLedgerIndex = message.ledger_index;\n this._lastLedgerClose = Date.now();\n this.emit('ledger_closed', message);\n};\n\nServer.prototype._handleServerStatus = function(message) {\n // This message is only received when online.\n // As we are connected, it is the definitive final state.\n var isOnline = ~Server.onlineStates.indexOf(message.server_status);\n\n this._setState(isOnline ? 'online' : 'offline');\n\n if (!Server.isLoadStatus(message)) {\n return;\n }\n\n this.emit('load', message, this);\n this._remote.emit('load', message, this);\n\n var loadChanged = message.load_base !== this._load_base\n || message.load_factor !== this._load_factor\n\n if (loadChanged) {\n this._load_base = message.load_base;\n this._load_factor = message.load_factor;\n this.emit('load_changed', message, this);\n this._remote.emit('load_changed', message, this);\n }\n};\n\nServer.prototype._handleResponse = function(message) {\n // A response to a request.\n var request = this._requests[message.id];\n\n delete this._requests[message.id];\n\n if (!request) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'UNEXPECTED:', message);\n }\n return;\n }\n\n if (message.status === 'success') {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'response:', message);\n }\n\n var command = request.message.command;\n var result = message.result;\n var responseEvent = 'response_' + command;\n\n request.emit('success', result);\n\n [ this, this._remote ].forEach(function(emitter) {\n emitter.emit(responseEvent, result, request, message);\n });\n } else if (message.error) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'error:', message);\n }\n\n request.emit('error', {\n error: 'remoteError',\n error_message: 'Remote reported an error.',\n remote: message\n });\n }\n};\n\nServer.prototype._handlePathFind = function(message) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'path_find:', message);\n }\n};\n\n/**\n * Handle subscription response messages. Subscription response\n * messages indicate that a connection to the server is ready\n *\n * @api private\n */\n\nServer.prototype._handleResponseSubscribe = function(message) {\n if (Server.isLoadStatus(message)) {\n this._load_base = message.load_base || 256;\n this._load_factor = message.load_factor || 256;\n this._fee_ref = message.fee_ref;\n this._fee_base = message.fee_base;\n this._reserve_base = message.reserve_base;\n this._reserve_inc = message.reserve_inc;\n }\n if (message.pubkey_node) {\n this._pubkey_node = message.pubkey_node;\n }\n if (~(Server.onlineStates.indexOf(message.server_status))) {\n this._setState('online');\n }\n};\n\n/**\n * Check that received message from rippled is valid\n *\n * @api private\n */\n\nServer.isValidMessage = function(message) {\n return (typeof message === 'object')\n && (typeof message.type === 'string');\n};\n\n/**\n * Check that received serverStatus message contains\n * load status information\n *\n * @api private\n */\n\nServer.isLoadStatus = function(message) {\n return (typeof message.load_base === 'number')\n && (typeof message.load_factor === 'number');\n};\n\n/**\n * Send JSON message to rippled WebSocket server\n *\n * @param {JSON-Stringifiable} message\n * @api private\n */\n\nServer.prototype._sendMessage = function(message) {\n if (this._ws) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'request:', message);\n }\n this._ws.send(JSON.stringify(message));\n }\n};\n\n/**\n * Submit a Request object.\n *\n * Requests are indexed by message ID, which is repeated\n * in the response from rippled WebSocket server\n *\n * @param {Request} request\n * @api private\n */\n\nServer.prototype._request = function(request) {\n var self = this;\n\n // Only bother if we are still connected.\n if (!this._ws) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'request: DROPPING:', request.message);\n }\n return;\n }\n\n request.server = this;\n request.message.id = this._id;\n request.time = Date.now();\n\n this._requests[request.message.id] = request;\n\n // Advance message ID\n this._id++;\n\n function sendRequest() {\n self._sendMessage(request.message);\n };\n\n var isOpen = this._ws.readyState === 1;\n var isSubscribeRequest = request && request.message.command === 'subscribe';\n\n if (this.isConnected() || (isOpen && isSubscribeRequest)) {\n sendRequest();\n } else {\n this.once('connect', sendRequest);\n }\n};\n\nServer.prototype.isConnected =\nServer.prototype._isConnected = function() {\n return this._connected;\n};\n\n/**\n * Calculate transaction fee\n *\n * @param {Transaction|Number} Fee units for a provided transaction\n * @return {Number} Final fee in XRP for specified number of fee units\n * @api private\n */\n\nServer.prototype._computeFee = function(transaction) {\n var units;\n\n if (transaction instanceof Transaction) {\n units = transaction._getFeeUnits();\n } else if (typeof transaction === 'number') {\n units = transaction;\n } else {\n throw new Error('Invalid argument');\n }\n\n return this._feeTx(units).to_json();\n};\n\n/**\n * Calculate a transaction fee for a number of tx fee units.\n *\n * This takes into account the last known network and local load fees.\n *\n * @param {Number} Fee units for a provided transaction\n * @return {Amount} Final fee in XRP for specified number of fee units.\n */\n\nServer.prototype._feeTx = function(units) {\n var fee_unit = this._feeTxUnit();\n return Amount.from_json(String(Math.ceil(units * fee_unit)));\n};\n\n/**\n * Get the current recommended transaction fee unit.\n *\n * Multiply this value with the number of fee units in order to calculate the\n * recommended fee for the transaction you are trying to submit.\n *\n * @return {Number} Recommended amount for one fee unit as float.\n */\n\nServer.prototype._feeTxUnit = function() {\n var fee_unit = this._fee_base / this._fee_ref;\n\n // Apply load fees\n fee_unit *= this._load_factor / this._load_base;\n\n // Apply fee cushion (a safety margin in case fees rise since we were last updated)\n fee_unit *= this._fee_cushion;\n\n return fee_unit;\n};\n\n/**\n * Get the current recommended reserve base.\n *\n * Returns the base reserve with load fees and safety margin applied.\n */\n\nServer.prototype._reserve = function(ownerCount) {\n var reserve_base = Amount.from_json(String(this._reserve_base));\n var reserve_inc = Amount.from_json(String(this._reserve_inc));\n var owner_count = ownerCount || 0;\n\n if (owner_count < 0) {\n throw new Error('Owner count must not be negative.');\n }\n\n return reserve_base.add(reserve_inc.product_human(owner_count));\n};\n\nexports.Server = Server;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 20\n// module.readableIdentifier = ./src/js/ripple/server.js\n//@ sourceURL=webpack-module:///./src/js/ripple/server.js"); + eval("var util = __webpack_require__(37);\nvar url = __webpack_require__(42);\nvar EventEmitter = __webpack_require__(36).EventEmitter;\nvar Amount = __webpack_require__(3).Amount;\nvar Transaction = __webpack_require__(5).Transaction;\nvar log = __webpack_require__(24).internal.sub('server');\n\n/**\n * @constructor Server\n *\n * @param {Remote} Reference to a Remote object\n * @param {Object} Options\n * @param {String} host\n * @param {Number|String} port\n * @param [Boolean] securec\n */\n\nfunction Server(remote, opts) {\n EventEmitter.call(this);\n\n var self = this;\n\n if (typeof opts === 'string') {\n var parsedUrl = url.parse(opts);\n opts = {\n host: parsedUrl.hostname,\n port: parsedUrl.port,\n secure: (parsedUrl.protocol === 'ws:') ? false : true\n };\n }\n\n if (typeof opts !== 'object') {\n throw new TypeError('Server configuration is not an Object');\n }\n\n if (!Server.domainRE.test(opts.host)) {\n throw new Error('Server host is malformed, use \"host\" and \"port\" server configuration');\n }\n\n // We want to allow integer strings as valid port numbers for backward compatibility\n if (!(opts.port = Number(opts.port))) {\n throw new TypeError('Server port must be a number');\n }\n\n if (opts.port < 1 || opts.port > 65535) {\n throw new TypeError('Server \"port\" must be an integer in range 1-65535');\n }\n\n if (typeof opts.secure !== 'boolean') {\n opts.secure = true;\n }\n\n this._remote = remote;\n this._opts = opts;\n this._ws = void(0);\n\n this._connected = false;\n this._shouldConnect = false;\n this._state = 'offline';\n\n this._id = 0; // request ID\n this._retry = 0;\n this._requests = { };\n\n this._load_base = 256;\n this._load_factor = 256;\n\n this._fee = 10;\n this._fee_ref = 10;\n this._fee_base = 10;\n this._reserve_base = void(0);\n this._reserve_inc = void(0);\n this._fee_cushion = this._remote.fee_cushion;\n\n this._lastLedgerIndex = NaN;\n this._lastLedgerClose = NaN;\n\n this._score = 0;\n this._scoreWeights = {\n ledgerclose: 5,\n response: 1\n };\n\n this._pubkey_node = '';\n\n this._url = this._opts.url = (this._opts.secure ? 'wss://' : 'ws://')\n + this._opts.host + ':' + this._opts.port;\n\n this.on('message', function onMessage(message) {\n self._handleMessage(message);\n });\n\n this.on('response_subscribe', function onSubscribe(message) {\n self._handleResponseSubscribe(message);\n });\n\n function setActivityInterval() {\n var interval = self._checkActivity.bind(self);\n self._activityInterval = setInterval(interval, 1000);\n };\n\n this.on('disconnect', function onDisconnect() {\n clearInterval(self._activityInterval);\n self.once('ledger_closed', setActivityInterval);\n });\n\n this.once('ledger_closed', setActivityInterval);\n\n this._remote.on('ledger_closed', function onRemoteLedgerClose(ledger) {\n self._updateScore('ledgerclose', ledger);\n });\n\n this.on('response_ping', function onPingResponse(message, request) {\n self._updateScore('response', request);\n });\n\n this.on('load_changed', function onLoadChange(load) {\n self._updateScore('loadchange', load);\n });\n\n // If server is not up-to-date, request server_info\n // for getting pubkey_node & hostid information.\n // Otherwise this information is available on the\n // initial server subscribe response\n this.on('connect', function requestServerID() {\n if (self._pubkey_node) {\n return;\n }\n\n self.on('response_server_info', function setServerID(message) {\n try {\n self._pubkey_node = message.info.pubkey_node;\n } catch (e) {\n }\n });\n\n self._request(self._remote.requestServerInfo());\n });\n};\n\nutil.inherits(Server, EventEmitter);\n\nServer.domainRE = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?(?:\\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?)*\\.?$/;\n\n/**\n * Server states that we will treat as the server being online.\n *\n * Our requirements are that the server can process transactions and notify\n * us of changes.\n */\n\nServer.onlineStates = [\n 'syncing',\n 'tracking',\n 'proposing',\n 'validating',\n 'full'\n];\n\n/**\n * This is the final interface between client code and a socket connection to a\n * `rippled` server. As such, this is a decent hook point to allow a WebSocket\n * interface conforming object to be used as a basis to mock rippled. This\n * avoids the need to bind a websocket server to a port and allows a more\n * synchronous style of code to represent a client <-> server message sequence.\n * We can also use this to log a message sequence to a buffer.\n *\n * @api private\n */\n\nServer.websocketConstructor = function() {\n // We require this late, because websocket shims may be loaded after\n // ripple-lib in the browser\n return __webpack_require__(35);\n};\n\n/**\n * Set server state\n *\n * @param {String} state\n * @api private\n */\n\nServer.prototype._setState = function(state) {\n if (state !== this._state) {\n if (this._remote.trace) {\n log.info(this.getHostID(), 'set_state:', state);\n }\n\n this._state = state;\n this.emit('state', state);\n\n switch (state) {\n case 'online':\n this._connected = true;\n this._retry = 0;\n this.emit('connect');\n break;\n case 'offline':\n this._connected = false;\n this.emit('disconnect');\n break;\n }\n }\n};\n\n/**\n * Check that server is still active.\n *\n * Server activity is determined by ledger_closed events.\n * Maximum delay to receive a ledger_closed event is 20s.\n *\n * If server is inactive, reconnect\n *\n * @api private\n */\n\nServer.prototype._checkActivity = function() {\n if (!this.isConnected()) {\n return;\n }\n\n if (isNaN(this._lastLedgerClose)) {\n return;\n }\n\n var delta = (Date.now() - this._lastLedgerClose);\n\n if (delta > (1000 * 25)) {\n if (this._remote.trace) {\n log.info(this.getHostID(), 'reconnect: activity delta:', delta);\n }\n this.reconnect();\n }\n};\n\n/**\n * Server maintains a score for request prioritization.\n *\n * The score is determined by various data including\n * this server's lag to receive ledger_closed events,\n * ping response time, and load(fee) change\n *\n * @param {String} type\n * @param {Object} data\n * @api private\n */\n\nServer.prototype._updateScore = function(type, data) {\n if (!this.isConnected()) {\n return;\n }\n\n var weight = this._scoreWeights[type] || 1;\n\n switch (type) {\n case 'ledgerclose':\n // Ledger lag\n var delta = data.ledger_index - this._lastLedgerIndex;\n if (delta > 0) {\n this._score += weight * delta;\n }\n break;\n case 'response':\n // Ping lag\n var delta = Math.floor((Date.now() - data.time) / 200);\n this._score += weight * delta;\n break;\n case 'loadchange':\n // Load/fee change\n this._fee = Number(this._computeFee(10));\n break;\n }\n\n if (this._score > 1e3) {\n if (this._remote.trace) {\n log.info(this.getHostID(), 'reconnect: score:', this._score);\n }\n this.reconnect();\n }\n};\n\n/**\n * Get the server's remote address\n *\n * Incompatible with ripple-lib client build\n */\n\nServer.prototype.getRemoteAddress =\nServer.prototype._remoteAddress = function() {\n var address;\n try {\n address = this._ws._socket.remoteAddress;\n } catch (e) {\n }\n return address;\n};\n\n/**\n * Get the server's hostid\n */\n\nServer.prototype.getHostID =\nServer.prototype.getServerID = function() {\n return this._url + ' (' + (this._pubkey_node ? this._pubkey_node : '') + ')';\n};\n\n/**\n * Disconnect from rippled WebSocket server\n *\n * @api public\n */\n\nServer.prototype.disconnect = function() {\n var self = this;\n\n if (!this.isConnected()) {\n this.once('socket_open', function() {\n self.disconnect();\n });\n return;\n }\n\n //these need to be reset so that updateScore \n //and checkActivity do not trigger reconnect\n this._lastLedgerIndex = NaN;\n this._lastLedgerClose = NaN;\n this._score = 0;\n this._shouldConnect = false;\n this._setState('offline');\n\n if (this._ws) {\n this._ws.close();\n }\n};\n\n/**\n * Reconnect to rippled WebSocket server\n *\n * @api public\n */\n\nServer.prototype.reconnect = function() {\n var self = this;\n\n function reconnect() {\n self._shouldConnect = true;\n self._retry = 0;\n self.connect();\n };\n\n if (this._ws && this._shouldConnect) {\n if (this.isConnected()) {\n this.once('disconnect', reconnect);\n this.disconnect();\n } else {\n reconnect();\n }\n }\n};\n\n/**\n * Connect to rippled WebSocket server and subscribe to events that are\n * internally requisite. Automatically retry connections with a gradual\n * back-off\n *\n * @api public\n */\n\nServer.prototype.connect = function() {\n var self = this;\n\n var WebSocket = Server.websocketConstructor();\n\n if (!WebSocket) {\n throw new Error('No websocket support detected!');\n }\n\n // We don't connect if we believe we're already connected. This means we have\n // recently received a message from the server and the WebSocket has not\n // reported any issues either. If we do fail to ping or the connection drops,\n // we will automatically reconnect.\n if (this.isConnected()) {\n return;\n }\n\n // Ensure any existing socket is given the command to close first.\n if (this._ws) {\n this._ws.close();\n }\n\n if (this._remote.trace) {\n log.info(this.getServerID(), 'connect');\n }\n\n var ws = this._ws = new WebSocket(this._opts.url);\n\n this._shouldConnect = true;\n\n self.emit('connecting');\n\n ws.onmessage = function onMessage(msg) {\n self.emit('message', msg.data);\n };\n\n ws.onopen = function onOpen() {\n if (ws === self._ws) {\n self.emit('socket_open');\n // Subscribe to events\n self._request(self._remote._serverPrepareSubscribe());\n }\n };\n\n ws.onerror = function onError(e) {\n if (ws === self._ws) {\n self.emit('socket_error');\n\n if (self._remote.trace) {\n log.info(self.getServerID(), 'onerror:', e.data || e);\n }\n\n // Most connection errors for WebSockets are conveyed as 'close' events with\n // code 1006. This is done for security purposes and therefore unlikely to\n // ever change.\n\n // This means that this handler is hardly ever called in practice. If it is,\n // it probably means the server's WebSocket implementation is corrupt, or\n // the connection is somehow producing corrupt data.\n\n // Most WebSocket applications simply log and ignore this error. Once we\n // support for multiple servers, we may consider doing something like\n // lowering this server's quality score.\n\n // However, in Node.js this event may be triggered instead of the close\n // event, so we need to handle it.\n self._handleClose();\n }\n };\n\n ws.onclose = function onClose() {\n if (ws === self._ws) {\n if (self._remote.trace) {\n log.info(self.getServerID(), 'onclose:', ws.readyState);\n }\n self._handleClose();\n }\n };\n};\n\n/**\n * Retry connection to rippled server\n *\n * @api private\n */\n\nServer.prototype._retryConnect = function() {\n var self = this;\n\n this._retry += 1;\n\n var retryTimeout = (this._retry < 40)\n // First, for 2 seconds: 20 times per second\n ? (1000 / 20)\n : (this._retry < 40 + 60)\n // Then, for 1 minute: once per second\n ? (1000)\n : (this._retry < 40 + 60 + 60)\n // Then, for 10 minutes: once every 10 seconds\n ? (10 * 1000)\n // Then: once every 30 seconds\n : (30 * 1000);\n\n function connectionRetry() {\n if (self._shouldConnect) {\n if (self._remote.trace) {\n log.info(self.getServerID(), 'retry', self._retry);\n }\n self.connect();\n }\n };\n\n this._retryTimer = setTimeout(connectionRetry, retryTimeout);\n};\n\n/**\n * Handle connection closes\n *\n * @api private\n */\n\nServer.prototype._handleClose = function() {\n var self = this;\n var ws = this._ws;\n\n function noOp(){};\n\n // Prevent additional events from this socket\n ws.onopen = ws.onerror = ws.onclose = ws.onmessage = noOp;\n\n this.emit('socket_close');\n this._setState('offline');\n\n if (this._shouldConnect) {\n this._retryConnect();\n }\n};\n\n/**\n * Handle incoming messages from rippled WebSocket server\n *\n * @param {JSON-parseable} message\n * @api private\n */\n\nServer.prototype._handleMessage = function(message) {\n var self = this;\n\n try {\n message = JSON.parse(message);\n } catch(e) {\n }\n\n if (!Server.isValidMessage(message)) {\n this.emit('unexpected', message);\n return;\n }\n\n switch (message.type) {\n case 'ledgerClosed':\n this._handleLedgerClosed(message);\n break;\n case 'serverStatus':\n this._handleServerStatus(message);\n break;\n case 'response':\n this._handleResponse(message);\n break;\n case 'path_find':\n this._handlePathFind(message);\n break;\n }\n};\n\nServer.prototype._handleLedgerClosed = function(message) {\n this._lastLedgerIndex = message.ledger_index;\n this._lastLedgerClose = Date.now();\n this.emit('ledger_closed', message);\n};\n\nServer.prototype._handleServerStatus = function(message) {\n // This message is only received when online.\n // As we are connected, it is the definitive final state.\n var isOnline = ~Server.onlineStates.indexOf(message.server_status);\n\n this._setState(isOnline ? 'online' : 'offline');\n\n if (!Server.isLoadStatus(message)) {\n return;\n }\n\n this.emit('load', message, this);\n this._remote.emit('load', message, this);\n\n var loadChanged = message.load_base !== this._load_base\n || message.load_factor !== this._load_factor\n\n if (loadChanged) {\n this._load_base = message.load_base;\n this._load_factor = message.load_factor;\n this.emit('load_changed', message, this);\n this._remote.emit('load_changed', message, this);\n }\n};\n\nServer.prototype._handleResponse = function(message) {\n // A response to a request.\n var request = this._requests[message.id];\n\n delete this._requests[message.id];\n\n if (!request) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'UNEXPECTED:', message);\n }\n return;\n }\n\n if (message.status === 'success') {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'response:', message);\n }\n\n var command = request.message.command;\n var result = message.result;\n var responseEvent = 'response_' + command;\n\n request.emit('success', result);\n\n [ this, this._remote ].forEach(function(emitter) {\n emitter.emit(responseEvent, result, request, message);\n });\n } else if (message.error) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'error:', message);\n }\n\n request.emit('error', {\n error: 'remoteError',\n error_message: 'Remote reported an error.',\n remote: message\n });\n }\n};\n\nServer.prototype._handlePathFind = function(message) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'path_find:', message);\n }\n};\n\n/**\n * Handle subscription response messages. Subscription response\n * messages indicate that a connection to the server is ready\n *\n * @api private\n */\n\nServer.prototype._handleResponseSubscribe = function(message) {\n if (!this._remote._allow_partial_history\n && !Server.hasFullLedgerHistory(message)) {\n // Server has partial history and Remote has been configured to disallow\n // servers with incomplete history\n return this.reconnect();\n }\n if (Server.isLoadStatus(message)) {\n this._load_base = message.load_base || 256;\n this._load_factor = message.load_factor || 256;\n this._fee_ref = message.fee_ref;\n this._fee_base = message.fee_base;\n this._reserve_base = message.reserve_base;\n this._reserve_inc = message.reserve_inc;\n }\n if (message.pubkey_node) {\n this._pubkey_node = message.pubkey_node;\n }\n if (~(Server.onlineStates.indexOf(message.server_status))) {\n this._setState('online');\n }\n};\n\n/**\n * Check that server message indicates that server has complete ledger history\n *\n * @param {Object} message\n * @return {Boolean}\n */\n\nServer.hasFullLedgerHistory = function(message) {\n return (typeof message === 'object')\n && (message.server_status === 'full')\n && (typeof message.validated_ledgers === 'string')\n && (message.validated_ledgers.split('-').length === 2);\n};\n\n/**\n * Check that received message from rippled is valid\n *\n * @param {Object} message\n * @return {Boolean}\n */\n\nServer.isValidMessage = function(message) {\n return (typeof message === 'object')\n && (typeof message.type === 'string');\n};\n\n/**\n * Check that received serverStatus message contains load status information\n *\n * @param {Object} message\n * @return {Boolean}\n */\n\nServer.isLoadStatus = function(message) {\n return (typeof message === 'object')\n && (typeof message.load_base === 'number')\n && (typeof message.load_factor === 'number');\n};\n\n/**\n * Send JSON message to rippled WebSocket server\n *\n * @param {JSON-Stringifiable} message\n * @api private\n */\n\nServer.prototype._sendMessage = function(message) {\n if (this._ws) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'request:', message);\n }\n this._ws.send(JSON.stringify(message));\n }\n};\n\n/**\n * Submit a Request object\n *\n * Requests are indexed by message ID, which is repeated in the response from\n * rippled WebSocket server\n *\n * @param {Request} request\n * @api private\n */\n\nServer.prototype._request = function(request) {\n var self = this;\n\n // Only bother if we are still connected.\n if (!this._ws) {\n if (this._remote.trace) {\n log.info(this.getServerID(), 'request: DROPPING:', request.message);\n }\n return;\n }\n\n request.server = this;\n request.message.id = this._id;\n request.time = Date.now();\n\n this._requests[request.message.id] = request;\n\n // Advance message ID\n this._id++;\n\n function sendRequest() {\n self._sendMessage(request.message);\n };\n\n var isOpen = this._ws.readyState === 1;\n var isSubscribeRequest = request && request.message.command === 'subscribe';\n\n if (this.isConnected() || (isOpen && isSubscribeRequest)) {\n sendRequest();\n } else {\n this.once('connect', sendRequest);\n }\n};\n\nServer.prototype.isConnected =\nServer.prototype._isConnected = function() {\n return this._connected;\n};\n\n/**\n * Calculate transaction fee\n *\n * @param {Transaction|Number} Fee units for a provided transaction\n * @return {Number} Final fee in XRP for specified number of fee units\n * @api private\n */\n\nServer.prototype._computeFee = function(transaction) {\n var units;\n\n if (transaction instanceof Transaction) {\n units = transaction._getFeeUnits();\n } else if (typeof transaction === 'number') {\n units = transaction;\n } else {\n throw new Error('Invalid argument');\n }\n\n return this._feeTx(units).to_json();\n};\n\n/**\n * Calculate a transaction fee for a number of tx fee units.\n *\n * This takes into account the last known network and local load fees.\n *\n * @param {Number} Fee units for a provided transaction\n * @return {Amount} Final fee in XRP for specified number of fee units.\n */\n\nServer.prototype._feeTx = function(units) {\n var fee_unit = this._feeTxUnit();\n return Amount.from_json(String(Math.ceil(units * fee_unit)));\n};\n\n/**\n * Get the current recommended transaction fee unit.\n *\n * Multiply this value with the number of fee units in order to calculate the\n * recommended fee for the transaction you are trying to submit.\n *\n * @return {Number} Recommended amount for one fee unit as float.\n */\n\nServer.prototype._feeTxUnit = function() {\n var fee_unit = this._fee_base / this._fee_ref;\n\n // Apply load fees\n fee_unit *= this._load_factor / this._load_base;\n\n // Apply fee cushion (a safety margin in case fees rise since we were last updated)\n fee_unit *= this._fee_cushion;\n\n return fee_unit;\n};\n\n/**\n * Get the current recommended reserve base.\n *\n * Returns the base reserve with load fees and safety margin applied.\n */\n\nServer.prototype._reserve = function(ownerCount) {\n var reserve_base = Amount.from_json(String(this._reserve_base));\n var reserve_inc = Amount.from_json(String(this._reserve_inc));\n var owner_count = ownerCount || 0;\n\n if (owner_count < 0) {\n throw new Error('Owner count must not be negative.');\n }\n\n return reserve_base.add(reserve_inc.product_human(owner_count));\n};\n\nexports.Server = Server;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 20\n// module.readableIdentifier = ./src/js/ripple/server.js\n//@ sourceURL=webpack-module:///./src/js/ripple/server.js"); /***/ }, /* 21 */ @@ -178,7 +178,7 @@ var ripple = /* 22 */ /***/ function(module, exports, __webpack_require__) { - eval("// Routines for working with an orderbook.\n//\n// One OrderBook object represents one half of an order book. (i.e. bids OR\n// asks) Which one depends on the ordering of the parameters.\n//\n// Events:\n// - model\n// - trade\n// - transaction\n\nvar util = __webpack_require__(37);\nvar extend = __webpack_require__(43);\nvar assert = __webpack_require__(39);\nvar async = __webpack_require__(48);\nvar EventEmitter = __webpack_require__(36).EventEmitter;\nvar Amount = __webpack_require__(3).Amount;\nvar UInt160 = __webpack_require__(8).UInt160;\nvar Currency = __webpack_require__(6).Currency;\nvar log = __webpack_require__(24).internal.sub('orderbook');\n\n/**\n * @constructor OrderBook\n * @param {Remote} remote\n * @param {String} ask currency\n * @param {String} ask issuer\n * @param {String} bid currency\n * @param {String} bid issuer\n * @param {String} orderbook key\n */\n\nfunction OrderBook(remote, getsC, getsI, paysC, paysI, key) {\n EventEmitter.call(this);\n\n var self = this;\n\n this._remote = remote;\n this._currencyGets = Currency.from_json(getsC);\n this._issuerGets = getsI;\n this._currencyPays = Currency.from_json(paysC);\n this._issuerPays = paysI;\n this._key = key;\n this._subscribed = false;\n this._shouldSubscribe = true;\n this._listeners = 0;\n this._offers = [ ];\n this._ownerFunds = { };\n this._offerCounts = { };\n\n // We consider ourselves synchronized if we have a current\n // copy of the offers, we are online and subscribed to updates.\n this._synchronized = false;\n\n function listenersModified(action, event) {\n // Automatically subscribe and unsubscribe to orderbook\n // on the basis of existing event listeners\n if (~OrderBook.EVENTS.indexOf(event)) {\n switch (action) {\n case 'add':\n if (++self._listeners === 1) {\n self.subscribe();\n }\n break;\n case 'remove':\n if (--self._listeners === 0) {\n self.unsubscribe();\n }\n break;\n }\n }\n };\n\n this.on('newListener', function(event) {\n listenersModified('add', event);\n });\n\n this.on('removeListener', function(event) {\n listenersModified('remove', event);\n });\n\n this.on('unsubscribe', function() {\n self._ownerFunds = { };\n self._remote.removeListener('transaction', updateFundedAmounts);\n self._remote.removeListener('transaction', updateTransferRate);\n });\n\n this._remote.on('prepare_subscribe', function() {\n self.subscribe();\n });\n\n this._remote.on('disconnect', function() {\n self._ownerFunds = { };\n self._offerCounts = { };\n self._synchronized = false;\n });\n\n function updateFundedAmounts(message) {\n self.updateFundedAmounts(message);\n };\n\n this._remote.on('transaction', updateFundedAmounts);\n\n function updateTransferRate(message) {\n self.updateTransferRate(message);\n };\n\n this._remote.on('transaction', updateTransferRate);\n\n return this;\n};\n\nutil.inherits(OrderBook, EventEmitter);\n\n/**\n * Events emitted from OrderBook\n */\n\nOrderBook.EVENTS = [ 'transaction', 'model', 'trade', 'offer' ];\n\nOrderBook.DEFAULT_TRANSFER_RATE = 1000000000;\n\n/**\n * Whether the OrderBook is valid.\n *\n * Note: This only checks whether the parameters (currencies and issuer) are\n * syntactically valid. It does not check anything against the ledger.\n *\n * @return {Boolean} is valid\n */\n\nOrderBook.prototype.isValid =\nOrderBook.prototype.is_valid = function() {\n // XXX Should check for same currency (non-native) && same issuer\n return (\n this._currencyPays && this._currencyPays.is_valid() &&\n (this._currencyPays.is_native() || UInt160.is_valid(this._issuerPays)) &&\n this._currencyGets && this._currencyGets.is_valid() &&\n (this._currencyGets.is_native() || UInt160.is_valid(this._issuerGets)) &&\n !(this._currencyPays.is_native() && this._currencyGets.is_native())\n );\n};\n\n/**\n * Initialize orderbook. Get orderbook offers and subscribe to transactions\n */\n\nOrderBook.prototype.subscribe = function() {\n var self = this;\n\n if (!this._shouldSubscribe) {\n return;\n }\n\n if (this._remote.trace) {\n log.info('subscribing', this._key);\n }\n\n var steps = [\n function(callback) {\n self.requestTransferRate(callback);\n },\n function(callback) {\n self.requestOffers(callback);\n },\n function(callback) {\n self.subscribeTransactions(callback);\n }\n ];\n\n async.series(steps, function(err) {\n //XXX What now?\n });\n};\n\n/**\n * Unhook event listeners and prevent ripple-lib from further work on this\n * orderbook. There is no more orderbook stream, so \"unsubscribe\" is nominal\n */\n\nOrderBook.prototype.unsubscribe = function() {\n var self = this;\n\n if (this._remote.trace) {\n log.info('unsubscribing', this._key);\n }\n\n this._subscribed = false;\n this._shouldSubscribe = false;\n\n OrderBook.EVENTS.forEach(function(event) {\n if (self.listeners(event).length > 0) {\n self.removeAllListeners(event);\n }\n });\n\n this.emit('unsubscribe');\n};\n\n/**\n * Check that the funds for offer owner have been cached\n *\n * @param {String} account address\n */\n\nOrderBook.prototype.hasCachedFunds = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n return this._ownerFunds[account] !== void(0);\n};\n\n/**\n * Add cached offer owner funds\n *\n * @param {String} account address\n * @param {String} funded amount\n */\n\nOrderBook.prototype.addCachedFunds = function(account, fundedAmount) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n assert(!isNaN(fundedAmount), 'Funded amount is invalid');\n this._ownerFunds[account] = fundedAmount;\n};\n\n/**\n * Get cached offer owner funds\n *\n * @param {String} account address\n */\n\nOrderBook.prototype.getCachedFunds = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n return this._ownerFunds[account];\n};\n\n/**\n * Remove cached offer owner funds\n *\n * @param {String} account address\n */\n\nOrderBook.prototype.removeCachedFunds = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n this._ownerFunds[account] = void(0);\n};\n\n/**\n * Get offer count for offer owner\n */\n\nOrderBook.prototype.getOfferCount = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n return this._offerCounts[account] || 0;\n};\n\n/**\n * Increment offer count for offer owner\n */\n\nOrderBook.prototype.incrementOfferCount = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n var result = (this._offerCounts[account] || 0) + 1;\n this._offerCounts[account] = result;\n return result;\n};\n\n/**\n * Decrement offer count for offer owner\n */\n\nOrderBook.prototype.decrementOfferCount = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n var result = (this._offerCounts[account] || 1) - 1;\n this._offerCounts[account] = result;\n return result;\n};\n\n/**\n * Compute funded amount for a balance/transferRate\n *\n * @param {String} balance\n * @param [String] transferRate\n * @return {Amount} funded amount\n */\n\nOrderBook.prototype.applyTransferRate = function(balance, transferRate) {\n assert(!isNaN(balance), 'Balance is invalid');\n\n if (this._currencyGets.is_native()) {\n return balance;\n }\n\n if (transferRate === void(0)) {\n transferRate = this._issuerTransferRate;\n }\n\n assert(!isNaN(transferRate), 'Transfer rate is invalid');\n\n if (transferRate === OrderBook.DEFAULT_TRANSFER_RATE) {\n return balance;\n }\n\n var iouSuffix = '/USD/rrrrrrrrrrrrrrrrrrrrBZbvji';\n var adjustedBalance = Amount.from_json(balance + iouSuffix)\n .divide(transferRate)\n .multiply(Amount.from_json(OrderBook.DEFAULT_TRANSFER_RATE))\n .to_json()\n .value;\n\n return adjustedBalance;\n};\n\n/**\n * Request transfer rate for this orderbook's issuer\n *\n * @param [Function] calback\n */\n\nOrderBook.prototype.requestTransferRate = function(callback) {\n var self = this;\n var issuer = this._issuerGets;\n\n this.once('transfer_rate', function(rate) {\n if (typeof callback === 'function') {\n callback(null, rate);\n }\n });\n\n if (this._currencyGets.is_native()) {\n // Transfer rate is default\n return this.emit('transfer_rate', OrderBook.DEFAULT_TRANSFER_RATE);\n }\n\n if (this._issuerTransferRate) {\n // Transfer rate has been cached\n return this.emit('transfer_rate', this._issuerTransferRate);\n }\n\n this._remote.requestAccountInfo(issuer, function(err, info) {\n if (err) {\n // XXX What now?\n return callback(err);\n }\n\n var transferRate = info.account_data.TransferRate\n || OrderBook.DEFAULT_TRANSFER_RATE;\n\n self._issuerTransferRate = transferRate;\n self.emit('transfer_rate', transferRate);\n });\n};\n\n/**\n * Set funded amount on offer. All offers have taker_gets_funded property,\n * which reflects the amount this account can afford to offer. All offers have\n * is_fully_funded property, indicating whether these funds are sufficient for\n * the offer placed.\n *\n * @param {Object} offer\n * @param {String} funds\n * @return offer\n */\n\nOrderBook.prototype.setFundedAmount = function(offer, fundedAmount) {\n assert.strictEqual(typeof offer, 'object', 'Offer is invalid');\n assert(!isNaN(fundedAmount), 'Funds is invalid');\n\n if (fundedAmount === '0') {\n offer.taker_gets_funded = '0';\n offer.taker_pays_funded = '0';\n offer.is_fully_funded = false;\n return offer;\n }\n\n var iouSuffix = '/' + this._currencyGets.to_json()\n + '/' + this._issuerGets;\n\n offer.is_fully_funded = Amount.from_json(\n this._currencyGets.is_native() ? fundedAmount : fundedAmount + iouSuffix\n ).compareTo(Amount.from_json(offer.TakerGets)) >= 0;\n\n if (offer.is_fully_funded) {\n offer.taker_gets_funded = Amount.from_json(offer.TakerGets).to_text();\n offer.taker_pays_funded = Amount.from_json(offer.TakerPays).to_text();\n return offer;\n }\n\n offer.taker_gets_funded = fundedAmount;\n\n var rate = Amount.from_json(offer.TakerPays)\n .divide(Amount.from_json(offer.TakerGets));\n\n var takerPays = Amount.from_json(offer.TakerPays);\n\n takerPays.set_currency('XXX');\n takerPays.set_issuer('rrrrrrrrrrrrrrrrrrrrBZbvji');\n\n var fundedPays = Amount.from_json(\n fundedAmount + '/XXX/rrrrrrrrrrrrrrrrrrrrBZbvji'\n );\n\n fundedPays = fundedPays.multiply(rate);\n\n if (fundedPays.compareTo(takerPays) < 0) {\n offer.taker_pays_funded = fundedPays.to_text();\n } else {\n offer.taker_pays_funded = Amount.from_json(offer.TakerPays).to_text();\n }\n\n return offer;\n};\n\n/**\n * Determine what an account is funded to offer for orderbook's\n * currency/issuer\n *\n * @param {String} account\n * @param {Function} callback\n */\n\nOrderBook.prototype.requestFundedAmount = function(account, callback) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n assert.strictEqual(typeof callback, 'function', 'Callback is invalid');\n\n var self = this;\n\n if (self._remote.trace) {\n log.info('requesting funds', account);\n }\n\n function requestNativeBalance(callback) {\n self._remote.requestAccountInfo(account, function(err, info) {\n if (err) {\n callback(err);\n } else {\n callback(null, String(info.account_data.Balance));\n }\n });\n };\n\n function requestLineBalance(callback) {\n var request = self._remote.requestAccountLines(\n account, // account\n void(0), // account index\n 'VALIDATED', // ledger\n self._issuerGets //peer\n );\n\n request.request(function(err, res) {\n if (err) {\n return callback(err);\n }\n\n var currency = self._currencyGets.to_json();\n var balance = '0';\n\n for (var i=0, line; (line=res.lines[i]); i++) {\n if (line.currency === currency) {\n balance = line.balance;\n break;\n }\n }\n\n callback(null, balance);\n });\n };\n\n function computeFundedAmount(err, results) {\n if (err) {\n if (self._remote.trace) {\n log.info('failed to request funds', err);\n }\n //XXX What now?\n return callback(err);\n }\n\n if (self._remote.trace) {\n log.info('requested funds', account, results);\n }\n\n var balance;\n var fundedAmount;\n\n if (self._currencyGets.is_native()) {\n balance = results[0];\n fundedAmount = balance;\n } else {\n balance = results[1];\n fundedAmount = self.applyTransferRate(balance, results[0]);\n }\n\n callback(null, fundedAmount);\n };\n\n var steps = [ ];\n\n if (this._currencyGets.is_native()) {\n steps.push(requestNativeBalance);\n } else {\n steps.push(this.requestTransferRate.bind(this));\n steps.push(requestLineBalance);\n }\n\n async.parallel(steps, computeFundedAmount);\n};\n\n/**\n * Get changed balance of an affected node\n *\n * @param {Object} RippleState or AccountRoot node\n * @return {Object} { account, balance }\n */\n\nOrderBook.prototype.getBalanceChange = function(node) {\n var result = {\n account: void(0),\n balance: void(0)\n };\n\n switch (node.entryType) {\n case 'AccountRoot':\n result.account = node.fields.Account;\n result.balance = node.fieldsFinal.Balance;\n break;\n\n case 'RippleState':\n if (node.fields.HighLimit.issuer === this._issuerGets) {\n result.account = node.fields.LowLimit.issuer;\n result.balance = node.fieldsFinal.Balance.value;\n } else if (node.fields.LowLimit.issuer === this._issuerGets) {\n // Negate balance\n result.account = node.fields.HighLimit.issuer;\n result.balance = Amount.from_json(\n node.fieldsFinal.Balance\n ).negate().to_json().value;\n }\n break;\n }\n\n result.isValid = !isNaN(result.balance)\n && UInt160.is_valid(result.account);\n\n return result;\n};\n\n/**\n * Check that affected node represents a balance change\n *\n * @param {Object} RippleState or AccountRoot node\n * @return {Boolean}\n */\n\nOrderBook.prototype.isBalanceChange = function(node) {\n // Check balance change\n if (!(node.fields && node.fields.Balance\n && node.fieldsPrev && node.fieldsFinal\n && node.fieldsPrev.Balance && node.fieldsFinal.Balance)) {\n return false;\n }\n\n // Check currency\n if (this._currencyGets.is_native()) {\n return !isNaN(node.fields.Balance);\n }\n\n if (node.fields.Balance.currency !== this._currencyGets.to_json()) {\n return false;\n }\n\n // Check issuer\n if (!(node.fields.HighLimit.issuer === this._issuerGets\n || node.fields.LowLimit.issuer === this._issuerGets)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Update funded amounts for offers in the orderbook as new transactions are\n * streamed from server\n *\n * @param {Object} transaction\n */\n\nOrderBook.prototype.updateFundedAmounts = function(message) {\n var self = this;\n\n var affectedAccounts = message.mmeta.getAffectedAccounts();\n\n var isOwnerAffected = affectedAccounts.some(function(account) {\n return self.hasCachedFunds(account);\n });\n\n if (!isOwnerAffected) {\n return;\n }\n\n if (!this._currencyGets.is_native() && !this._issuerTransferRate) {\n // Defer until transfer rate is requested\n if (self._remote.trace) {\n log.info('waiting for transfer rate');\n }\n\n this.once('transfer_rate', function() {\n self.updateFundedAmounts(message);\n });\n\n this.requestTransferRate();\n return;\n }\n\n var nodes = message.mmeta.getNodes({\n nodeType: 'ModifiedNode',\n entryType: this._currencyGets.is_native() ? 'AccountRoot' : 'RippleState'\n });\n\n for (var i=0; i 0) {\n self.removeAllListeners(event);\n }\n });\n\n this.emit('unsubscribe');\n};\n\n/**\n * Check that the funds for offer owner have been cached\n *\n * @param {String} account address\n */\n\nOrderBook.prototype.hasCachedFunds = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n return this._ownerFunds[account] !== void(0);\n};\n\n/**\n * Add cached offer owner funds\n *\n * @param {String} account address\n * @param {String} funded amount\n */\n\nOrderBook.prototype.addCachedFunds = function(account, fundedAmount) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n assert(!isNaN(fundedAmount), 'Funded amount is invalid');\n this._ownerFunds[account] = fundedAmount;\n};\n\n/**\n * Get cached offer owner funds\n *\n * @param {String} account address\n */\n\nOrderBook.prototype.getCachedFunds = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n return this._ownerFunds[account];\n};\n\n/**\n * Remove cached offer owner funds\n *\n * @param {String} account address\n */\n\nOrderBook.prototype.removeCachedFunds = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n this._ownerFunds[account] = void(0);\n};\n\n/**\n * Get offer count for offer owner\n */\n\nOrderBook.prototype.getOfferCount = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n return this._offerCounts[account] || 0;\n};\n\n/**\n * Increment offer count for offer owner\n */\n\nOrderBook.prototype.incrementOfferCount = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n var result = (this._offerCounts[account] || 0) + 1;\n this._offerCounts[account] = result;\n return result;\n};\n\n/**\n * Decrement offer count for offer owner\n */\n\nOrderBook.prototype.decrementOfferCount = function(account) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n var result = (this._offerCounts[account] || 1) - 1;\n this._offerCounts[account] = result;\n return result;\n};\n\n/**\n * Compute funded amount for a balance/transferRate\n *\n * @param {String} balance\n * @param [String] transferRate\n * @return {Amount} funded amount\n */\n\nOrderBook.prototype.applyTransferRate = function(balance, transferRate) {\n assert(!isNaN(balance), 'Balance is invalid');\n\n if (this._currencyGets.is_native()) {\n return balance;\n }\n\n if (transferRate === void(0)) {\n transferRate = this._issuerTransferRate;\n }\n\n assert(!isNaN(transferRate), 'Transfer rate is invalid');\n\n if (transferRate === OrderBook.DEFAULT_TRANSFER_RATE) {\n return balance;\n }\n\n var iouSuffix = '/USD/rrrrrrrrrrrrrrrrrrrrBZbvji';\n var adjustedBalance = Amount.from_json(balance + iouSuffix)\n .divide(transferRate)\n .multiply(Amount.from_json(OrderBook.DEFAULT_TRANSFER_RATE))\n .to_json()\n .value;\n\n return adjustedBalance;\n};\n\n/**\n * Request transfer rate for this orderbook's issuer\n *\n * @param [Function] calback\n */\n\nOrderBook.prototype.requestTransferRate = function(callback) {\n var self = this;\n var issuer = this._issuerGets;\n\n this.once('transfer_rate', function(rate) {\n if (typeof callback === 'function') {\n callback(null, rate);\n }\n });\n\n if (this._currencyGets.is_native()) {\n // Transfer rate is default\n return this.emit('transfer_rate', OrderBook.DEFAULT_TRANSFER_RATE);\n }\n\n if (this._issuerTransferRate) {\n // Transfer rate has been cached\n return this.emit('transfer_rate', this._issuerTransferRate);\n }\n\n this._remote.requestAccountInfo(issuer, function(err, info) {\n if (err) {\n // XXX What now?\n return callback(err);\n }\n\n var transferRate = info.account_data.TransferRate\n || OrderBook.DEFAULT_TRANSFER_RATE;\n\n self._issuerTransferRate = transferRate;\n self.emit('transfer_rate', transferRate);\n });\n};\n\n/**\n * Set funded amount on offer. All offers have taker_gets_funded property,\n * which reflects the amount this account can afford to offer. All offers have\n * is_fully_funded property, indicating whether these funds are sufficient for\n * the offer placed.\n *\n * @param {Object} offer\n * @param {String} funds\n * @return offer\n */\n\nOrderBook.prototype.setFundedAmount = function(offer, fundedAmount) {\n assert.strictEqual(typeof offer, 'object', 'Offer is invalid');\n assert(!isNaN(fundedAmount), 'Funds is invalid');\n\n if (fundedAmount === '0') {\n offer.taker_gets_funded = '0';\n offer.taker_pays_funded = '0';\n offer.is_fully_funded = false;\n return offer;\n }\n\n var iouSuffix = '/' + this._currencyGets.to_json()\n + '/' + this._issuerGets;\n\n offer.is_fully_funded = Amount.from_json(\n this._currencyGets.is_native() ? fundedAmount : fundedAmount + iouSuffix\n ).compareTo(Amount.from_json(offer.TakerGets)) >= 0;\n\n if (offer.is_fully_funded) {\n offer.taker_gets_funded = Amount.from_json(offer.TakerGets).to_text();\n offer.taker_pays_funded = Amount.from_json(offer.TakerPays).to_text();\n return offer;\n }\n\n offer.taker_gets_funded = fundedAmount;\n\n var takerPaysValue = typeof offer.TakerPays === 'object'\n ? offer.TakerPays.value\n : offer.TakerPays;\n\n var takerGetsValue = typeof offer.TakerGets === 'object'\n ? offer.TakerGets.value\n : offer.TakerGets;\n\n var takerPays = Amount.from_json(\n takerPaysValue + '/000/rrrrrrrrrrrrrrrrrrrrBZbvji'\n );\n\n var takerGets = Amount.from_json(\n takerGetsValue + '/000/rrrrrrrrrrrrrrrrrrrrBZbvji'\n );\n\n var fundedPays = Amount.from_json(\n fundedAmount + '/000/rrrrrrrrrrrrrrrrrrrrBZbvji'\n );\n\n var rate = takerPays.divide(takerGets);\n\n fundedPays = fundedPays.multiply(rate);\n\n if (fundedPays.compareTo(takerPays) < 0) {\n offer.taker_pays_funded = fundedPays.to_json().value;\n } else {\n offer.taker_pays_funded = takerPays.to_json().value;\n }\n\n return offer;\n};\n\n/**\n * Determine what an account is funded to offer for orderbook's\n * currency/issuer\n *\n * @param {String} account\n * @param {Function} callback\n */\n\nOrderBook.prototype.requestFundedAmount = function(account, callback) {\n assert(UInt160.is_valid(account), 'Account is invalid');\n assert.strictEqual(typeof callback, 'function', 'Callback is invalid');\n\n var self = this;\n\n if (self._remote.trace) {\n log.info('requesting funds', account);\n }\n\n function requestNativeBalance(callback) {\n self._remote.requestAccountInfo(account, function(err, info) {\n if (err) {\n callback(err);\n } else {\n callback(null, String(info.account_data.Balance));\n }\n });\n };\n\n function requestLineBalance(callback) {\n var request = self._remote.requestAccountLines(\n account, // account\n void(0), // account index\n 'VALIDATED', // ledger\n self._issuerGets //peer\n );\n\n request.request(function(err, res) {\n if (err) {\n return callback(err);\n }\n\n var currency = self._currencyGets.to_json();\n var balance = '0';\n\n for (var i=0, line; (line=res.lines[i]); i++) {\n if (line.currency === currency) {\n balance = line.balance;\n break;\n }\n }\n\n callback(null, balance);\n });\n };\n\n function computeFundedAmount(err, results) {\n if (err) {\n if (self._remote.trace) {\n log.info('failed to request funds', err);\n }\n //XXX What now?\n return callback(err);\n }\n\n if (self._remote.trace) {\n log.info('requested funds', account, results);\n }\n\n var balance;\n var fundedAmount;\n\n if (self._currencyGets.is_native()) {\n balance = results[0];\n fundedAmount = balance;\n } else {\n balance = results[1];\n fundedAmount = self.applyTransferRate(balance, results[0]);\n }\n\n callback(null, fundedAmount);\n };\n\n var steps = [ ];\n\n if (this._currencyGets.is_native()) {\n steps.push(requestNativeBalance);\n } else {\n steps.push(this.requestTransferRate.bind(this));\n steps.push(requestLineBalance);\n }\n\n async.parallel(steps, computeFundedAmount);\n};\n\n/**\n * Get changed balance of an affected node\n *\n * @param {Object} RippleState or AccountRoot node\n * @return {Object} { account, balance }\n */\n\nOrderBook.prototype.getBalanceChange = function(node) {\n var result = {\n account: void(0),\n balance: void(0)\n };\n\n switch (node.entryType) {\n case 'AccountRoot':\n result.account = node.fields.Account;\n result.balance = node.fieldsFinal.Balance;\n break;\n\n case 'RippleState':\n if (node.fields.HighLimit.issuer === this._issuerGets) {\n result.account = node.fields.LowLimit.issuer;\n result.balance = node.fieldsFinal.Balance.value;\n } else if (node.fields.LowLimit.issuer === this._issuerGets) {\n // Negate balance\n result.account = node.fields.HighLimit.issuer;\n result.balance = Amount.from_json(\n node.fieldsFinal.Balance\n ).negate().to_json().value;\n }\n break;\n }\n\n result.isValid = !isNaN(result.balance)\n && UInt160.is_valid(result.account);\n\n return result;\n};\n\n/**\n * Check that affected node represents a balance change\n *\n * @param {Object} RippleState or AccountRoot node\n * @return {Boolean}\n */\n\nOrderBook.prototype.isBalanceChange = function(node) {\n // Check balance change\n if (!(node.fields && node.fields.Balance\n && node.fieldsPrev && node.fieldsFinal\n && node.fieldsPrev.Balance && node.fieldsFinal.Balance)) {\n return false;\n }\n\n // Check currency\n if (this._currencyGets.is_native()) {\n return !isNaN(node.fields.Balance);\n }\n\n if (node.fields.Balance.currency !== this._currencyGets.to_json()) {\n return false;\n }\n\n // Check issuer\n if (!(node.fields.HighLimit.issuer === this._issuerGets\n || node.fields.LowLimit.issuer === this._issuerGets)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Update funded amounts for offers in the orderbook as new transactions are\n * streamed from server\n *\n * @param {Object} transaction\n */\n\nOrderBook.prototype.updateFundedAmounts = function(message) {\n var self = this;\n\n var affectedAccounts = message.mmeta.getAffectedAccounts();\n\n var isOwnerAffected = affectedAccounts.some(function(account) {\n return self.hasCachedFunds(account);\n });\n\n if (!isOwnerAffected) {\n return;\n }\n\n if (!this._currencyGets.is_native() && !this._issuerTransferRate) {\n // Defer until transfer rate is requested\n if (self._remote.trace) {\n log.info('waiting for transfer rate');\n }\n\n this.once('transfer_rate', function() {\n self.updateFundedAmounts(message);\n });\n\n this.requestTransferRate();\n return;\n }\n\n var nodes = message.mmeta.getNodes({\n nodeType: 'ModifiedNode',\n entryType: this._currencyGets.is_native() ? 'AccountRoot' : 'RippleState'\n });\n\n for (var i=0; i= 0) {\n this._value = new BigInteger(String(j));\n }\n\n this._update();\n\n return this;\n};\n\n// Convert from internal form.\nUInt.prototype.to_bytes = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bytes = this._value.toByteArray();\n\n bytes = bytes.map(function(b) {\n return (b + 256) % 256;\n });\n\n var target = this.constructor.width;\n\n // XXX Make sure only trim off leading zeros.\n bytes = bytes.slice(-target);\n\n while (bytes.length < target) {\n bytes.unshift(0);\n }\n\n return bytes;\n};\n\nUInt.prototype.to_hex = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bytes = this.to_bytes();\n return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(bytes)).toUpperCase();\n};\n\nUInt.prototype.to_json = UInt.prototype.to_hex;\n\nUInt.prototype.to_bits = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bytes = this.to_bytes();\n\n return sjcl.codec.bytes.toBits(bytes);\n};\n\nUInt.prototype.to_bn = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bits = this.to_bits();\n\n return sjcl.bn.fromBits(bits);\n};\n\nexports.UInt = UInt;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 26\n// module.readableIdentifier = ./src/js/ripple/uint.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint.js"); /***/ }, /* 27 */ /***/ function(module, exports, __webpack_require__) { - eval("// Convert a JavaScript number to IEEE-754 Double Precision\n// value represented as an array of 8 bytes (octets)\n//\n// Based on:\n// http://cautionsingularityahead.blogspot.com/2010/04/javascript-and-ieee754-redux.html\n//\n// Found and modified from:\n// https://gist.github.com/bartaz/1119041\n\nvar Float = exports.Float = {};\n\nFloat.toIEEE754 = function(v, ebits, fbits) {\n\n var bias = (1 << (ebits - 1)) - 1;\n\n // Compute sign, exponent, fraction\n var s, e, f;\n if (isNaN(v)) {\n e = (1 << bias) - 1; f = 1; s = 0;\n }\n else if (v === Infinity || v === -Infinity) {\n e = (1 << bias) - 1; f = 0; s = (v < 0) ? 1 : 0;\n }\n else if (v === 0) {\n e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0;\n }\n else {\n s = v < 0;\n v = Math.abs(v);\n\n if (v >= Math.pow(2, 1 - bias)) {\n var ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);\n e = ln + bias;\n f = v * Math.pow(2, fbits - ln) - Math.pow(2, fbits);\n }\n else {\n e = 0;\n f = v / Math.pow(2, 1 - bias - fbits);\n }\n }\n\n // Pack sign, exponent, fraction\n var i, bits = [];\n for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = Math.floor(f / 2); }\n for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = Math.floor(e / 2); }\n bits.push(s ? 1 : 0);\n bits.reverse();\n var str = bits.join('');\n\n // Bits to bytes\n var bytes = [];\n while (str.length) {\n bytes.push(parseInt(str.substring(0, 8), 2));\n str = str.substring(8);\n }\n return bytes;\n}\n\nFloat.fromIEEE754 = function(bytes, ebits, fbits) {\n\n // Bytes to bits\n var bits = [];\n for (var i = bytes.length; i; i -= 1) {\n var byte = bytes[i - 1];\n for (var j = 8; j; j -= 1) {\n bits.push(byte % 2 ? 1 : 0); byte = byte >> 1;\n }\n }\n bits.reverse();\n var str = bits.join('');\n\n // Unpack sign, exponent, fraction\n var bias = (1 << (ebits - 1)) - 1;\n var s = parseInt(str.substring(0, 1), 2) ? -1 : 1;\n var e = parseInt(str.substring(1, 1 + ebits), 2);\n var f = parseInt(str.substring(1 + ebits), 2);\n\n // Produce number\n if (e === (1 << ebits) - 1) {\n return f !== 0 ? NaN : s * Infinity;\n }\n else if (e > 0) {\n return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits));\n }\n else if (f !== 0) {\n return s * Math.pow(2, -(bias-1)) * (f / Math.pow(2, fbits));\n }\n else {\n return s * 0;\n }\n}\n\nFloat.fromIEEE754Double = function(b) { return Float.fromIEEE754(b, 11, 52); }\nFloat.toIEEE754Double = function(v) { return Float.toIEEE754(v, 11, 52); }\nFloat.fromIEEE754Single = function(b) { return Float.fromIEEE754(b, 8, 23); }\nFloat.toIEEE754Single = function(v) { return Float.toIEEE754(v, 8, 23); }\n\n\n// Convert array of octets to string binary representation\n// by bartaz\n\nFloat.toIEEE754DoubleString = function(v) {\n return exports.toIEEE754Double(v)\n .map(function(n){ for(n = n.toString(2);n.length < 8;n=\"0\"+n); return n })\n .join('')\n .replace(/(.)(.{11})(.{52})/, \"$1 $2 $3\")\n}\n\n// WEBPACK FOOTER\n// module.id = 27\n// module.readableIdentifier = ./src/js/ripple/ieee754.js\n//@ sourceURL=webpack-module:///./src/js/ripple/ieee754.js"); + eval("/**\n * Prefix for hashing functions.\n *\n * These prefixes are inserted before the source material used to\n * generate various hashes. This is done to put each hash in its own\n * \"space.\" This way, two different types of objects with the\n * same binary data will produce different hashes.\n *\n * Each prefix is a 4-byte value with the last byte set to zero\n * and the first three bytes formed from the ASCII equivalent of\n * some arbitrary string. For example \"TXN\".\n */\n\n// transaction plus signature to give transaction ID\nexports.HASH_TX_ID = 0x54584E00; // 'TXN'\n// transaction plus metadata\nexports.HASH_TX_NODE = 0x534E4400; // 'TND'\n// inner node in tree\nexports.HASH_INNER_NODE = 0x4D494E00; // 'MIN'\n// leaf node in tree\nexports.HASH_LEAF_NODE = 0x4D4C4E00; // 'MLN'\n// inner transaction to sign\nexports.HASH_TX_SIGN = 0x53545800; // 'STX'\n// inner transaction to sign (TESTNET)\nexports.HASH_TX_SIGN_TESTNET = 0x73747800; // 'stx'\n\n\n// WEBPACK FOOTER\n// module.id = 27\n// module.readableIdentifier = ./src/js/ripple/hashprefixes.js\n//@ sourceURL=webpack-module:///./src/js/ripple/hashprefixes.js"); /***/ }, /* 28 */ /***/ function(module, exports, __webpack_require__) { - eval("var utils = __webpack_require__(19);\nvar sjcl = utils.sjcl;\nvar config = __webpack_require__(21);\n\nvar BigInteger = utils.jsbn.BigInteger;\n\n//\n// Abstract UInt class\n//\n// Base class for UInt classes\n//\n\nvar UInt = function() {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n\n this._update();\n};\n\nUInt.json_rewrite = function(j, opts) {\n return this.from_json(j).to_json(opts);\n};\n\n// Return a new UInt from j.\nUInt.from_generic = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_generic(j);\n }\n};\n\n// Return a new UInt from j.\nUInt.from_hex = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_hex(j);\n }\n};\n\n// Return a new UInt from j.\nUInt.from_json = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_json(j);\n }\n};\n\n// Return a new UInt from j.\nUInt.from_bits = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_bits(j);\n }\n};\n\n// Return a new UInt from j.\nUInt.from_bytes = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_bytes(j);\n }\n};\n\n// Return a new UInt from j.\nUInt.from_bn = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_bn(j);\n }\n};\n\n// Return a new UInt from j.\nUInt.from_number = function(j) {\n if (j instanceof this) {\n return j.clone();\n } else {\n return (new this()).parse_number(j);\n }\n};\n\nUInt.is_valid = function(j) {\n return this.from_json(j).is_valid();\n};\n\nUInt.prototype.clone = function() {\n return this.copyTo(new this.constructor());\n};\n\n// Returns copy.\nUInt.prototype.copyTo = function(d) {\n d._value = this._value;\n\n if (typeof d._update === 'function') {\n d._update();\n }\n\n return d;\n};\n\nUInt.prototype.equals = function(d) {\n return this._value instanceof BigInteger && d._value instanceof BigInteger && this._value.equals(d._value);\n};\n\nUInt.prototype.is_valid = function() {\n return this._value instanceof BigInteger;\n};\n\nUInt.prototype.is_zero = function() {\n return this._value.equals(BigInteger.ZERO);\n};\n\n/**\n * Update any derivative values.\n *\n * This allows subclasses to maintain caches of any data that they derive from\n * the main _value. For example, the Currency class keeps the currency type, the\n * currency code and other information about the currency cached.\n *\n * The reason for keeping this mechanism in this class is so every subclass can\n * call it whenever it modifies the internal state.\n */\nUInt.prototype._update = function() {\n // Nothing to do by default. Subclasses will override this.\n};\n\n// value = NaN on error.\nUInt.prototype.parse_generic = function(j) {\n // Canonicalize and validate\n if (config.accounts && (j in config.accounts)) {\n j = config.accounts[j].account;\n }\n\n switch (j) {\n case undefined:\n case '0':\n case this.constructor.STR_ZERO:\n case this.constructor.ACCOUNT_ZERO:\n case this.constructor.HEX_ZERO:\n this._value = BigInteger.valueOf();\n break;\n\n case '1':\n case this.constructor.STR_ONE:\n case this.constructor.ACCOUNT_ONE:\n case this.constructor.HEX_ONE:\n this._value = new BigInteger([1]);\n break;\n\n default:\n if (typeof j !== 'string') {\n this._value = NaN;\n } else if (this.constructor.width === j.length) {\n this._value = new BigInteger(utils.stringToArray(j), 256);\n } else if ((this.constructor.width * 2) === j.length) {\n // XXX Check char set!\n this._value = new BigInteger(j, 16);\n } else {\n this._value = NaN;\n }\n }\n\n this._update();\n\n return this;\n};\n\nUInt.prototype.parse_hex = function(j) {\n if (typeof j === 'string' && j.length === (this.constructor.width * 2)) {\n this._value = new BigInteger(j, 16);\n } else {\n this._value = NaN;\n }\n\n this._update();\n\n return this;\n};\n\nUInt.prototype.parse_bits = function(j) {\n if (sjcl.bitArray.bitLength(j) !== this.constructor.width * 8) {\n this._value = NaN;\n } else {\n var bytes = sjcl.codec.bytes.fromBits(j);\n this.parse_bytes(bytes);\n }\n\n this._update();\n\n return this;\n};\n\n\nUInt.prototype.parse_bytes = function(j) {\n if (!Array.isArray(j) || j.length !== this.constructor.width) {\n this._value = NaN;\n } else {\n this._value = new BigInteger([0].concat(j), 256);\n }\n\n this._update();\n\n return this;\n};\n\n\nUInt.prototype.parse_json = UInt.prototype.parse_hex;\n\nUInt.prototype.parse_bn = function(j) {\n if ((j instanceof sjcl.bn) && j.bitLength() <= this.constructor.width * 8) {\n var bytes = sjcl.codec.bytes.fromBits(j.toBits());\n this._value = new BigInteger(bytes, 256);\n } else {\n this._value = NaN;\n }\n\n this._update();\n\n return this;\n};\n\nUInt.prototype.parse_number = function(j) {\n this._value = NaN;\n\n if (typeof j === 'number' && isFinite(j) && j >= 0) {\n this._value = new BigInteger(String(j));\n }\n\n this._update();\n\n return this;\n};\n\n// Convert from internal form.\nUInt.prototype.to_bytes = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bytes = this._value.toByteArray();\n\n bytes = bytes.map(function(b) {\n return (b + 256) % 256;\n });\n\n var target = this.constructor.width;\n\n // XXX Make sure only trim off leading zeros.\n bytes = bytes.slice(-target);\n\n while (bytes.length < target) {\n bytes.unshift(0);\n }\n\n return bytes;\n};\n\nUInt.prototype.to_hex = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bytes = this.to_bytes();\n return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(bytes)).toUpperCase();\n};\n\nUInt.prototype.to_json = UInt.prototype.to_hex;\n\nUInt.prototype.to_bits = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bytes = this.to_bytes();\n\n return sjcl.codec.bytes.toBits(bytes);\n};\n\nUInt.prototype.to_bn = function() {\n if (!(this._value instanceof BigInteger)) {\n return null;\n }\n\n var bits = this.to_bits();\n\n return sjcl.bn.fromBits(bits);\n};\n\nexports.UInt = UInt;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 28\n// module.readableIdentifier = ./src/js/ripple/uint.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint.js"); + eval("var sjcl = __webpack_require__(19).sjcl;\n\nvar UInt160 = __webpack_require__(8).UInt160;\nvar UInt256 = __webpack_require__(9).UInt256;\nvar Base = __webpack_require__(7).Base;\n\nfunction KeyPair() {\n this._curve = sjcl.ecc.curves.c256;\n this._secret = null;\n this._pubkey = null;\n};\n\nKeyPair.from_bn_secret = function(j) {\n return (j instanceof this) ? j.clone() : (new this()).parse_bn_secret(j);\n};\n\nKeyPair.prototype.parse_bn_secret = function(j) {\n this._secret = new sjcl.ecc.ecdsa.secretKey(sjcl.ecc.curves.c256, j);\n return this;\n};\n\n/**\n * Returns public key as sjcl public key.\n *\n * @private\n */\nKeyPair.prototype._pub = function() {\n var curve = this._curve;\n\n if (!this._pubkey && this._secret) {\n var exponent = this._secret._exponent;\n this._pubkey = new sjcl.ecc.ecdsa.publicKey(curve, curve.G.mult(exponent));\n }\n\n return this._pubkey;\n};\n\n/**\n * Returns public key in compressed format as bit array.\n *\n * @private\n */\nKeyPair.prototype._pub_bits = function() {\n var pub = this._pub();\n\n if (!pub) {\n return null;\n }\n\n var point = pub._point, y_even = point.y.mod(2).equals(0);\n\n return sjcl.bitArray.concat(\n [sjcl.bitArray.partial(8, y_even ? 0x02 : 0x03)],\n point.x.toBits(this._curve.r.bitLength())\n );\n};\n\n/**\n * Returns public key as hex.\n *\n * Key will be returned as a compressed pubkey - 33 bytes converted to hex.\n */\nKeyPair.prototype.to_hex_pub = function() {\n var bits = this._pub_bits();\n\n if (!bits) {\n return null;\n }\n\n return sjcl.codec.hex.fromBits(bits).toUpperCase();\n};\n\nfunction SHA256_RIPEMD160(bits) {\n return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));\n}\n\nKeyPair.prototype.get_address = function() {\n var bits = this._pub_bits();\n\n if (!bits) {\n return null;\n }\n\n var hash = SHA256_RIPEMD160(bits);\n\n var address = UInt160.from_bits(hash);\n address.set_version(Base.VER_ACCOUNT_ID);\n return address;\n};\n\nKeyPair.prototype.sign = function(hash) {\n hash = UInt256.from_json(hash);\n var sig = this._secret.sign(hash.to_bits(), 0);\n sig = this._secret.canonicalizeSignature(sig);\n return this._secret.encodeDER(sig);\n};\n\nexports.KeyPair = KeyPair;\n\n\n// WEBPACK FOOTER\n// module.id = 28\n// module.readableIdentifier = ./src/js/ripple/keypair.js\n//@ sourceURL=webpack-module:///./src/js/ripple/keypair.js"); /***/ }, /* 29 */ /***/ function(module, exports, __webpack_require__) { - eval("var sjcl = __webpack_require__(19).sjcl;\n\nvar UInt160 = __webpack_require__(8).UInt160;\nvar UInt256 = __webpack_require__(9).UInt256;\nvar Base = __webpack_require__(7).Base;\n\nfunction KeyPair() {\n this._curve = sjcl.ecc.curves.c256;\n this._secret = null;\n this._pubkey = null;\n};\n\nKeyPair.from_bn_secret = function(j) {\n return (j instanceof this) ? j.clone() : (new this()).parse_bn_secret(j);\n};\n\nKeyPair.prototype.parse_bn_secret = function(j) {\n this._secret = new sjcl.ecc.ecdsa.secretKey(sjcl.ecc.curves.c256, j);\n return this;\n};\n\n/**\n * Returns public key as sjcl public key.\n *\n * @private\n */\nKeyPair.prototype._pub = function() {\n var curve = this._curve;\n\n if (!this._pubkey && this._secret) {\n var exponent = this._secret._exponent;\n this._pubkey = new sjcl.ecc.ecdsa.publicKey(curve, curve.G.mult(exponent));\n }\n\n return this._pubkey;\n};\n\n/**\n * Returns public key in compressed format as bit array.\n *\n * @private\n */\nKeyPair.prototype._pub_bits = function() {\n var pub = this._pub();\n\n if (!pub) {\n return null;\n }\n\n var point = pub._point, y_even = point.y.mod(2).equals(0);\n\n return sjcl.bitArray.concat(\n [sjcl.bitArray.partial(8, y_even ? 0x02 : 0x03)],\n point.x.toBits(this._curve.r.bitLength())\n );\n};\n\n/**\n * Returns public key as hex.\n *\n * Key will be returned as a compressed pubkey - 33 bytes converted to hex.\n */\nKeyPair.prototype.to_hex_pub = function() {\n var bits = this._pub_bits();\n\n if (!bits) {\n return null;\n }\n\n return sjcl.codec.hex.fromBits(bits).toUpperCase();\n};\n\nfunction SHA256_RIPEMD160(bits) {\n return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));\n}\n\nKeyPair.prototype.get_address = function() {\n var bits = this._pub_bits();\n\n if (!bits) {\n return null;\n }\n\n var hash = SHA256_RIPEMD160(bits);\n\n var address = UInt160.from_bits(hash);\n address.set_version(Base.VER_ACCOUNT_ID);\n return address;\n};\n\nKeyPair.prototype.sign = function(hash) {\n hash = UInt256.from_json(hash);\n var sig = this._secret.sign(hash.to_bits(), 0);\n sig = this._secret.canonicalizeSignature(sig);\n return this._secret.encodeDER(sig);\n};\n\nexports.KeyPair = KeyPair;\n\n\n// WEBPACK FOOTER\n// module.id = 29\n// module.readableIdentifier = ./src/js/ripple/keypair.js\n//@ sourceURL=webpack-module:///./src/js/ripple/keypair.js"); + eval("/**\n * Type definitions for binary format.\n *\n * This file should not be included directly. Instead, find the format you're\n * trying to parse or serialize in binformat.js and pass that to\n * SerializedObject.parse() or SerializedObject.serialize().\n */\n\nvar assert = __webpack_require__(39);\nvar extend = __webpack_require__(43);\nvar binformat = __webpack_require__(18);\nvar utils = __webpack_require__(19);\nvar sjcl = utils.sjcl;\n\nvar UInt128 = __webpack_require__(45).UInt128;\nvar UInt160 = __webpack_require__(8).UInt160;\nvar UInt256 = __webpack_require__(9).UInt256;\nvar Base = __webpack_require__(7).Base;\n\nvar amount = __webpack_require__(3);\nvar Amount = amount.Amount;\nvar Currency = amount.Currency;\n\n// Shortcuts\nvar hex = sjcl.codec.hex;\nvar bytes = sjcl.codec.bytes;\n\nvar BigInteger = utils.jsbn.BigInteger;\n\n\nvar SerializedType = function (methods) {\n extend(this, methods);\n};\n\nfunction isNumber(val) {\n return typeof val === 'number' && isFinite(val);\n};\n\nfunction isString(val) {\n return typeof val === 'string';\n};\n\nfunction isHexInt64String(val) {\n return isString(val) && /^[0-9A-F]{0,16}$/i.test(val);\n};\n\nfunction isCurrencyString(val) {\n return isString(val) && /^[A-Z0-9]{3}$/.test(val);\n};\n\nfunction isBigInteger(val) {\n return val instanceof BigInteger;\n};\n\nfunction serialize_hex(so, hexData, noLength) {\n var byteData = bytes.fromBits(hex.toBits(hexData));\n if (!noLength) {\n SerializedType.serialize_varint(so, byteData.length);\n }\n so.append(byteData);\n};\n\n/**\n * parses bytes as hex\n */\nfunction convert_bytes_to_hex (byte_array) {\n return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(byte_array)).toUpperCase();\n};\n\nSerializedType.serialize_varint = function (so, val) {\n if (val < 0) {\n throw new Error('Variable integers are unsigned.');\n }\n\n if (val <= 192) {\n so.append([val]);\n } else if (val <= 12480) {\n val -= 193;\n so.append([193 + (val >>> 8), val & 0xff]);\n } else if (val <= 918744) {\n val -= 12481;\n so.append([ 241 + (val >>> 16), val >>> 8 & 0xff, val & 0xff ]);\n } else {\n throw new Error('Variable integer overflow.');\n }\n};\n\nSerializedType.prototype.parse_varint = function (so) {\n var b1 = so.read(1)[0], b2, b3;\n var result;\n\n if (b1 > 254) {\n throw new Error('Invalid varint length indicator');\n }\n\n if (b1 <= 192) {\n result = b1;\n } else if (b1 <= 240) {\n b2 = so.read(1)[0];\n result = 193 + (b1 - 193) * 256 + b2;\n } else if (b1 <= 254) {\n b2 = so.read(1)[0];\n b3 = so.read(1)[0];\n result = 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;\n }\n\n return result;\n};\n\n// In the following, we assume that the inputs are in the proper range. Is this correct?\n// Helper functions for 1-, 2-, and 4-byte integers.\n\n/**\n * Convert an integer value into an array of bytes.\n *\n * The result is appended to the serialized object ('so').\n */\nfunction append_byte_array(so, val, bytes) {\n if (!isNumber(val)) {\n throw new Error('Value is not a number');\n }\n\n if (val < 0 || val >= Math.pow(256, bytes)) {\n throw new Error('Value out of bounds');\n }\n\n var newBytes = [ ];\n\n for (var i=0; i>> (i * 8) & 0xff);\n }\n\n so.append(newBytes);\n};\n\n// Convert a certain number of bytes from the serialized object ('so') into an integer.\nfunction readAndSum(so, bytes) {\n var sum = 0;\n\n if (bytes > 4) {\n throw new Error('This function only supports up to four bytes.');\n }\n\n for (var i=0; i>> 0;\n};\n\nvar STInt8 = exports.Int8 = new SerializedType({\n serialize: function (so, val) {\n append_byte_array(so, val, 1);\n },\n parse: function (so) {\n return readAndSum(so, 1);\n }\n});\n\nSTInt8.id = 16;\n\nvar STInt16 = exports.Int16 = new SerializedType({\n serialize: function (so, val) {\n append_byte_array(so, val, 2);\n },\n parse: function (so) {\n return readAndSum(so, 2);\n }\n});\n\nSTInt16.id = 1;\n\nvar STInt32 = exports.Int32 = new SerializedType({\n serialize: function (so, val) {\n append_byte_array(so, val, 4);\n },\n parse: function (so) {\n return readAndSum(so, 4);\n }\n});\n\nSTInt32.id = 2;\n\nvar STInt64 = exports.Int64 = new SerializedType({\n serialize: function (so, val) {\n var bigNumObject;\n\n if (isNumber(val)) {\n val = Math.floor(val);\n if (val < 0) {\n throw new Error('Negative value for unsigned Int64 is invalid.');\n }\n bigNumObject = new BigInteger(String(val), 10);\n } else if (isString(val)) {\n if (!isHexInt64String(val)) {\n throw new Error('Not a valid hex Int64.');\n }\n bigNumObject = new BigInteger(val, 16);\n } else if (isBigInteger(val)) {\n if (val.compareTo(BigInteger.ZERO) < 0) {\n throw new Error('Negative value for unsigned Int64 is invalid.');\n }\n bigNumObject = val;\n } else {\n throw new Error('Invalid type for Int64');\n }\n\n var hex = bigNumObject.toString(16);\n\n if (hex.length > 16) {\n throw new Error('Int64 is too large');\n }\n\n while (hex.length < 16) {\n hex = '0' + hex;\n }\n\n serialize_hex(so, hex, true); //noLength = true\n },\n parse: function (so) {\n var bytes = so.read(8);\n // We need to add a 0, so if the high bit is set it won't think it's a\n // pessimistic numeric fraek. What doth lief?\n var result = new BigInteger([0].concat(bytes), 256);\n assert(result instanceof BigInteger);\n return result;\n }\n});\n\nSTInt64.id = 3;\n\nvar STHash128 = exports.Hash128 = new SerializedType({\n serialize: function (so, val) {\n var hash = UInt128.from_json(val);\n if (!hash.is_valid()) {\n throw new Error('Invalid Hash128');\n }\n serialize_hex(so, hash.to_hex(), true); //noLength = true\n },\n parse: function (so) {\n return UInt128.from_bytes(so.read(16));\n }\n});\n\nSTHash128.id = 4;\n\nvar STHash256 = exports.Hash256 = new SerializedType({\n serialize: function (so, val) {\n var hash = UInt256.from_json(val);\n if (!hash.is_valid()) {\n throw new Error('Invalid Hash256');\n }\n serialize_hex(so, hash.to_hex(), true); //noLength = true\n },\n parse: function (so) {\n return UInt256.from_bytes(so.read(32));\n }\n});\n\nSTHash256.id = 5;\n\nvar STHash160 = exports.Hash160 = new SerializedType({\n serialize: function (so, val) {\n var hash = UInt160.from_json(val);\n if (!hash.is_valid()) {\n throw new Error('Invalid Hash160');\n }\n serialize_hex(so, hash.to_hex(), true); //noLength = true\n },\n parse: function (so) {\n return UInt160.from_bytes(so.read(20));\n }\n});\n\nSTHash160.id = 17;\n\n// Internal\nvar STCurrency = new SerializedType({\n serialize: function (so, val, xrp_as_ascii) {\n var currencyData = val.to_bytes();\n\n if (!currencyData) {\n throw new Error('Tried to serialize invalid/unimplemented currency type.');\n }\n\n so.append(currencyData);\n },\n parse: function (so) {\n var bytes = so.read(20);\n var currency = Currency.from_bytes(bytes);\n // XXX Disabled check. Theoretically, the Currency class should support any\n // UInt160 value and consider it valid. But it doesn't, so for the\n // deserialization to be usable, we need to allow invalid results for now.\n //if (!currency.is_valid()) {\n // throw new Error('Invalid currency: '+convert_bytes_to_hex(bytes));\n //}\n return currency;\n }\n});\n\nvar STAmount = exports.Amount = new SerializedType({\n serialize: function (so, val) {\n var amount = Amount.from_json(val);\n if (!amount.is_valid()) {\n throw new Error('Not a valid Amount object.');\n }\n\n // Amount (64-bit integer)\n var valueBytes = utils.arraySet(8, 0);\n\n if (amount.is_native()) {\n var valueHex = amount._value.toString(16);\n\n // Enforce correct length (64 bits)\n if (valueHex.length > 16) {\n throw new Error('Value out of bounds');\n }\n\n while (valueHex.length < 16) {\n valueHex = '0' + valueHex;\n }\n\n valueBytes = bytes.fromBits(hex.toBits(valueHex));\n // Clear most significant two bits - these bits should already be 0 if\n // Amount enforces the range correctly, but we'll clear them anyway just\n // so this code can make certain guarantees about the encoded value.\n valueBytes[0] &= 0x3f;\n\n if (!amount.is_negative()) {\n valueBytes[0] |= 0x40;\n }\n } else {\n var hi = 0, lo = 0;\n\n // First bit: non-native\n hi |= 1 << 31;\n\n if (!amount.is_zero()) {\n // Second bit: non-negative?\n if (!amount.is_negative()) {\n hi |= 1 << 30;\n }\n\n // Next eight bits: offset/exponent\n hi |= ((97 + amount._offset) & 0xff) << 22;\n // Remaining 52 bits: mantissa\n hi |= amount._value.shiftRight(32).intValue() & 0x3fffff;\n lo = amount._value.intValue() & 0xffffffff;\n }\n\n valueBytes = sjcl.codec.bytes.fromBits([hi, lo]);\n }\n\n so.append(valueBytes);\n\n if (!amount.is_native()) {\n // Currency (160-bit hash)\n var currency = amount.currency();\n STCurrency.serialize(so, currency, true);\n\n // Issuer (160-bit hash)\n so.append(amount.issuer().to_bytes());\n }\n },\n parse: function (so) {\n var amount = new Amount();\n var value_bytes = so.read(8);\n var is_zero = !(value_bytes[0] & 0x7f);\n\n for (var i=1; i<8; i++) {\n is_zero = is_zero && !value_bytes[i];\n }\n\n if (value_bytes[0] & 0x80) {\n //non-native\n var currency = STCurrency.parse(so);\n var issuer_bytes = so.read(20);\n var issuer = UInt160.from_bytes(issuer_bytes);\n issuer.set_version(Base.VER_ACCOUNT_ID);\n var offset = ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97;\n var mantissa_bytes = value_bytes.slice(1);\n mantissa_bytes[0] &= 0x3f;\n var value = new BigInteger(mantissa_bytes, 256);\n\n if (value.equals(BigInteger.ZERO) && !is_zero ) {\n throw new Error('Invalid zero representation');\n }\n\n amount._value = value;\n amount._offset = offset;\n amount._currency = currency;\n amount._issuer = issuer;\n amount._is_native = false;\n } else {\n //native\n var integer_bytes = value_bytes.slice();\n integer_bytes[0] &= 0x3f;\n amount._value = new BigInteger(integer_bytes, 256);\n amount._is_native = true;\n }\n amount._is_negative = !is_zero && !(value_bytes[0] & 0x40);\n return amount;\n }\n});\n\nSTAmount.id = 6;\n\nvar STVL = exports.VariableLength = exports.VL = new SerializedType({\n serialize: function (so, val) {\n if (typeof val === 'string') {\n serialize_hex(so, val);\n } else {\n throw new Error('Unknown datatype.');\n }\n },\n parse: function (so) {\n var len = this.parse_varint(so);\n return convert_bytes_to_hex(so.read(len));\n }\n});\n\nSTVL.id = 7;\n\nvar STAccount = exports.Account = new SerializedType({\n serialize: function (so, val) {\n var account = UInt160.from_json(val);\n if (!account.is_valid()) {\n throw new Error('Invalid account!');\n }\n serialize_hex(so, account.to_hex());\n },\n parse: function (so) {\n var len = this.parse_varint(so);\n\n if (len !== 20) {\n throw new Error('Non-standard-length account ID');\n }\n\n var result = UInt160.from_bytes(so.read(len));\n result.set_version(Base.VER_ACCOUNT_ID);\n\n //console.log('PARSED 160:', result.to_json());\n if (false) {\n throw new Error('Invalid Account');\n }\n\n return result;\n }\n});\n\nSTAccount.id = 8;\n\nvar STPathSet = exports.PathSet = new SerializedType({\n typeBoundary: 0xff,\n typeEnd: 0x00,\n typeAccount: 0x01,\n typeCurrency: 0x10,\n typeIssuer: 0x20,\n serialize: function (so, val) {\n for (var i=0, l=val.length; i= 16) {\n STInt8.serialize(so, type_bits);\n }\n\n if (field_bits >= 16) {\n STInt8.serialize(so, field_bits);\n }\n\n // Get the serializer class (ST...) for a field based on the type bits.\n var serialized_object_type = exports[binformat.types[type_bits]];\n //do something with val[keys] and val[keys[i]];\n serialized_object_type.serialize(so, value);\n}\n\n//Take the serialized object, figure out what type/field it is, and return the parsing of that.\nexports.parse = exports.parse_whatever = parse;\n\nfunction parse(so) {\n var tag_byte = so.read(1)[0];\n var type_bits = tag_byte >> 4;\n\n if (type_bits === 0) {\n type_bits = so.read(1)[0];\n }\n\n // Get the parser class (ST...) for a field based on the type bits.\n var type = exports[binformat.types[type_bits]];\n\n assert(type, 'Unknown type - header byte is 0x' + tag_byte.toString(16));\n\n var field_bits = tag_byte & 0x0f;\n var field_name = (field_bits === 0)\n ? field_name = binformat.fields[type_bits][so.read(1)[0]]\n : field_name = binformat.fields[type_bits][field_bits];\n\n assert(field_name, 'Unknown field - header byte is 0x' + tag_byte.toString(16));\n\n return [ field_name, type.parse(so) ]; //key, value\n};\n\nfunction sort_fields(keys) {\n function sort_field_compare(a, b) {\n var a_field_coordinates = binformat.fieldsInverseMap[a];\n var a_type_bits = a_field_coordinates[0];\n var a_field_bits = a_field_coordinates[1];\n var b_field_coordinates = binformat.fieldsInverseMap[b];\n var b_type_bits = b_field_coordinates[0];\n var b_field_bits = b_field_coordinates[1];\n\n // Sort by type id first, then by field id\n return a_type_bits !== b_type_bits ? a_type_bits - b_type_bits : a_field_bits - b_field_bits;\n };\n\n return keys.sort(sort_field_compare);\n}\n\nvar STObject = exports.Object = new SerializedType({\n serialize: function (so, val, no_marker) {\n var keys = Object.keys(val);\n\n // Ignore lowercase field names - they're non-serializable fields by\n // convention.\n keys = keys.filter(function (key) {\n return key[0] !== key[0].toLowerCase();\n });\n\n keys.forEach(function (key) {\n if (typeof binformat.fieldsInverseMap[key] === 'undefined') {\n throw new Error('JSON contains unknown field: \"' + key + '\"');\n }\n });\n\n // Sort fields\n keys = sort_fields(keys);\n\n for (var i=0; i>> 8), val & 0xff]);\n } else if (val <= 918744) {\n val -= 12481;\n so.append([ 241 + (val >>> 16), val >>> 8 & 0xff, val & 0xff ]);\n } else {\n throw new Error('Variable integer overflow.');\n }\n};\n\nSerializedType.prototype.parse_varint = function (so) {\n var b1 = so.read(1)[0], b2, b3;\n var result;\n\n if (b1 > 254) {\n throw new Error('Invalid varint length indicator');\n }\n\n if (b1 <= 192) {\n result = b1;\n } else if (b1 <= 240) {\n b2 = so.read(1)[0];\n result = 193 + (b1 - 193) * 256 + b2;\n } else if (b1 <= 254) {\n b2 = so.read(1)[0];\n b3 = so.read(1)[0];\n result = 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;\n }\n\n return result;\n};\n\n// In the following, we assume that the inputs are in the proper range. Is this correct?\n// Helper functions for 1-, 2-, and 4-byte integers.\n\n/**\n * Convert an integer value into an array of bytes.\n *\n * The result is appended to the serialized object ('so').\n */\nfunction append_byte_array(so, val, bytes) {\n if (!isNumber(val)) {\n throw new Error('Value is not a number');\n }\n\n if (val < 0 || val >= Math.pow(256, bytes)) {\n throw new Error('Value out of bounds');\n }\n\n var newBytes = [ ];\n\n for (var i=0; i>> (i * 8) & 0xff);\n }\n\n so.append(newBytes);\n};\n\n// Convert a certain number of bytes from the serialized object ('so') into an integer.\nfunction readAndSum(so, bytes) {\n var sum = 0;\n\n if (bytes > 4) {\n throw new Error('This function only supports up to four bytes.');\n }\n\n for (var i=0; i>> 0;\n};\n\nvar STInt8 = exports.Int8 = new SerializedType({\n serialize: function (so, val) {\n append_byte_array(so, val, 1);\n },\n parse: function (so) {\n return readAndSum(so, 1);\n }\n});\n\nSTInt8.id = 16;\n\nvar STInt16 = exports.Int16 = new SerializedType({\n serialize: function (so, val) {\n append_byte_array(so, val, 2);\n },\n parse: function (so) {\n return readAndSum(so, 2);\n }\n});\n\nSTInt16.id = 1;\n\nvar STInt32 = exports.Int32 = new SerializedType({\n serialize: function (so, val) {\n append_byte_array(so, val, 4);\n },\n parse: function (so) {\n return readAndSum(so, 4);\n }\n});\n\nSTInt32.id = 2;\n\nvar STInt64 = exports.Int64 = new SerializedType({\n serialize: function (so, val) {\n var bigNumObject;\n\n if (isNumber(val)) {\n val = Math.floor(val);\n if (val < 0) {\n throw new Error('Negative value for unsigned Int64 is invalid.');\n }\n bigNumObject = new BigInteger(String(val), 10);\n } else if (isString(val)) {\n if (!isHexInt64String(val)) {\n throw new Error('Not a valid hex Int64.');\n }\n bigNumObject = new BigInteger(val, 16);\n } else if (isBigInteger(val)) {\n if (val.compareTo(BigInteger.ZERO) < 0) {\n throw new Error('Negative value for unsigned Int64 is invalid.');\n }\n bigNumObject = val;\n } else {\n throw new Error('Invalid type for Int64');\n }\n\n var hex = bigNumObject.toString(16);\n\n if (hex.length > 16) {\n throw new Error('Int64 is too large');\n }\n\n while (hex.length < 16) {\n hex = '0' + hex;\n }\n\n serialize_hex(so, hex, true); //noLength = true\n },\n parse: function (so) {\n var bytes = so.read(8);\n // We need to add a 0, so if the high bit is set it won't think it's a\n // pessimistic numeric fraek. What doth lief?\n var result = new BigInteger([0].concat(bytes), 256);\n assert(result instanceof BigInteger);\n return result;\n }\n});\n\nSTInt64.id = 3;\n\nvar STHash128 = exports.Hash128 = new SerializedType({\n serialize: function (so, val) {\n var hash = UInt128.from_json(val);\n if (!hash.is_valid()) {\n throw new Error('Invalid Hash128');\n }\n serialize_hex(so, hash.to_hex(), true); //noLength = true\n },\n parse: function (so) {\n return UInt128.from_bytes(so.read(16));\n }\n});\n\nSTHash128.id = 4;\n\nvar STHash256 = exports.Hash256 = new SerializedType({\n serialize: function (so, val) {\n var hash = UInt256.from_json(val);\n if (!hash.is_valid()) {\n throw new Error('Invalid Hash256');\n }\n serialize_hex(so, hash.to_hex(), true); //noLength = true\n },\n parse: function (so) {\n return UInt256.from_bytes(so.read(32));\n }\n});\n\nSTHash256.id = 5;\n\nvar STHash160 = exports.Hash160 = new SerializedType({\n serialize: function (so, val) {\n var hash = UInt160.from_json(val);\n if (!hash.is_valid()) {\n throw new Error('Invalid Hash160');\n }\n serialize_hex(so, hash.to_hex(), true); //noLength = true\n },\n parse: function (so) {\n return UInt160.from_bytes(so.read(20));\n }\n});\n\nSTHash160.id = 17;\n\n// Internal\nvar STCurrency = new SerializedType({\n serialize: function (so, val, xrp_as_ascii) {\n var currencyData = val.to_bytes();\n\n if (!currencyData) {\n throw new Error('Tried to serialize invalid/unimplemented currency type.');\n }\n\n so.append(currencyData);\n },\n parse: function (so) {\n var bytes = so.read(20);\n var currency = Currency.from_bytes(bytes);\n // XXX Disabled check. Theoretically, the Currency class should support any\n // UInt160 value and consider it valid. But it doesn't, so for the\n // deserialization to be usable, we need to allow invalid results for now.\n //if (!currency.is_valid()) {\n // throw new Error('Invalid currency: '+convert_bytes_to_hex(bytes));\n //}\n return currency;\n }\n});\n\nvar STAmount = exports.Amount = new SerializedType({\n serialize: function (so, val) {\n var amount = Amount.from_json(val);\n if (!amount.is_valid()) {\n throw new Error('Not a valid Amount object.');\n }\n\n // Amount (64-bit integer)\n var valueBytes = utils.arraySet(8, 0);\n\n if (amount.is_native()) {\n var valueHex = amount._value.toString(16);\n\n // Enforce correct length (64 bits)\n if (valueHex.length > 16) {\n throw new Error('Value out of bounds');\n }\n\n while (valueHex.length < 16) {\n valueHex = '0' + valueHex;\n }\n\n valueBytes = bytes.fromBits(hex.toBits(valueHex));\n // Clear most significant two bits - these bits should already be 0 if\n // Amount enforces the range correctly, but we'll clear them anyway just\n // so this code can make certain guarantees about the encoded value.\n valueBytes[0] &= 0x3f;\n\n if (!amount.is_negative()) {\n valueBytes[0] |= 0x40;\n }\n } else {\n var hi = 0, lo = 0;\n\n // First bit: non-native\n hi |= 1 << 31;\n\n if (!amount.is_zero()) {\n // Second bit: non-negative?\n if (!amount.is_negative()) {\n hi |= 1 << 30;\n }\n\n // Next eight bits: offset/exponent\n hi |= ((97 + amount._offset) & 0xff) << 22;\n // Remaining 52 bits: mantissa\n hi |= amount._value.shiftRight(32).intValue() & 0x3fffff;\n lo = amount._value.intValue() & 0xffffffff;\n }\n\n valueBytes = sjcl.codec.bytes.fromBits([hi, lo]);\n }\n\n so.append(valueBytes);\n\n if (!amount.is_native()) {\n // Currency (160-bit hash)\n var currency = amount.currency();\n STCurrency.serialize(so, currency, true);\n\n // Issuer (160-bit hash)\n so.append(amount.issuer().to_bytes());\n }\n },\n parse: function (so) {\n var amount = new Amount();\n var value_bytes = so.read(8);\n var is_zero = !(value_bytes[0] & 0x7f);\n\n for (var i=1; i<8; i++) {\n is_zero = is_zero && !value_bytes[i];\n }\n\n if (value_bytes[0] & 0x80) {\n //non-native\n var currency = STCurrency.parse(so);\n var issuer_bytes = so.read(20);\n var issuer = UInt160.from_bytes(issuer_bytes);\n issuer.set_version(Base.VER_ACCOUNT_ID);\n var offset = ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97;\n var mantissa_bytes = value_bytes.slice(1);\n mantissa_bytes[0] &= 0x3f;\n var value = new BigInteger(mantissa_bytes, 256);\n\n if (value.equals(BigInteger.ZERO) && !is_zero ) {\n throw new Error('Invalid zero representation');\n }\n\n amount._value = value;\n amount._offset = offset;\n amount._currency = currency;\n amount._issuer = issuer;\n amount._is_native = false;\n } else {\n //native\n var integer_bytes = value_bytes.slice();\n integer_bytes[0] &= 0x3f;\n amount._value = new BigInteger(integer_bytes, 256);\n amount._is_native = true;\n }\n amount._is_negative = !is_zero && !(value_bytes[0] & 0x40);\n return amount;\n }\n});\n\nSTAmount.id = 6;\n\nvar STVL = exports.VariableLength = exports.VL = new SerializedType({\n serialize: function (so, val) {\n if (typeof val === 'string') {\n serialize_hex(so, val);\n } else {\n throw new Error('Unknown datatype.');\n }\n },\n parse: function (so) {\n var len = this.parse_varint(so);\n return convert_bytes_to_hex(so.read(len));\n }\n});\n\nSTVL.id = 7;\n\nvar STAccount = exports.Account = new SerializedType({\n serialize: function (so, val) {\n var account = UInt160.from_json(val);\n if (!account.is_valid()) {\n throw new Error('Invalid account!');\n }\n serialize_hex(so, account.to_hex());\n },\n parse: function (so) {\n var len = this.parse_varint(so);\n\n if (len !== 20) {\n throw new Error('Non-standard-length account ID');\n }\n\n var result = UInt160.from_bytes(so.read(len));\n result.set_version(Base.VER_ACCOUNT_ID);\n\n //console.log('PARSED 160:', result.to_json());\n if (false) {\n throw new Error('Invalid Account');\n }\n\n return result;\n }\n});\n\nSTAccount.id = 8;\n\nvar STPathSet = exports.PathSet = new SerializedType({\n typeBoundary: 0xff,\n typeEnd: 0x00,\n typeAccount: 0x01,\n typeCurrency: 0x10,\n typeIssuer: 0x20,\n serialize: function (so, val) {\n for (var i=0, l=val.length; i= 16) {\n STInt8.serialize(so, type_bits);\n }\n\n if (field_bits >= 16) {\n STInt8.serialize(so, field_bits);\n }\n\n // Get the serializer class (ST...) for a field based on the type bits.\n var serialized_object_type = exports[binformat.types[type_bits]];\n //do something with val[keys] and val[keys[i]];\n serialized_object_type.serialize(so, value);\n}\n\n//Take the serialized object, figure out what type/field it is, and return the parsing of that.\nexports.parse = exports.parse_whatever = parse;\n\nfunction parse(so) {\n var tag_byte = so.read(1)[0];\n var type_bits = tag_byte >> 4;\n\n if (type_bits === 0) {\n type_bits = so.read(1)[0];\n }\n\n // Get the parser class (ST...) for a field based on the type bits.\n var type = exports[binformat.types[type_bits]];\n\n assert(type, 'Unknown type - header byte is 0x' + tag_byte.toString(16));\n\n var field_bits = tag_byte & 0x0f;\n var field_name = (field_bits === 0)\n ? field_name = binformat.fields[type_bits][so.read(1)[0]]\n : field_name = binformat.fields[type_bits][field_bits];\n\n assert(field_name, 'Unknown field - header byte is 0x' + tag_byte.toString(16));\n\n return [ field_name, type.parse(so) ]; //key, value\n};\n\nfunction sort_fields(keys) {\n function sort_field_compare(a, b) {\n var a_field_coordinates = binformat.fieldsInverseMap[a];\n var a_type_bits = a_field_coordinates[0];\n var a_field_bits = a_field_coordinates[1];\n var b_field_coordinates = binformat.fieldsInverseMap[b];\n var b_type_bits = b_field_coordinates[0];\n var b_field_bits = b_field_coordinates[1];\n\n // Sort by type id first, then by field id\n return a_type_bits !== b_type_bits ? a_type_bits - b_type_bits : a_field_bits - b_field_bits;\n };\n\n return keys.sort(sort_field_compare);\n}\n\nvar STObject = exports.Object = new SerializedType({\n serialize: function (so, val, no_marker) {\n var keys = Object.keys(val);\n\n // Ignore lowercase field names - they're non-serializable fields by\n // convention.\n keys = keys.filter(function (key) {\n return key[0] !== key[0].toLowerCase();\n });\n\n keys.forEach(function (key) {\n if (typeof binformat.fieldsInverseMap[key] === 'undefined') {\n throw new Error('JSON contains unknown field: \"' + key + '\"');\n }\n });\n\n // Sort fields\n keys = sort_fields(keys);\n\n for (var i=0; i>> 3, 256) / 8);\n var publicHash = fdh(publicInfo, publicSize);\n var publicHex = sjcl.codec.hex.fromBits(publicHash);\n var iPublic = new sjcl.bn(String(publicHex)).setBitM(0);\n var secretInfo = [ publicInfo, secret.length, secret ].join(':') + ':';\n var secretSize = (7 + iModulus.bitLength()) >>> 3;\n var secretHash = fdh(secretInfo, secretSize);\n var secretHex = sjcl.codec.hex.fromBits(secretHash);\n var iSecret = new sjcl.bn(String(secretHex)).mod(iModulus);\n\n if (iSecret.jacobi(iModulus) !== 1) {\n iSecret = iSecret.mul(iAlpha).mod(iModulus);\n }\n\n var iRandom;\n\n for (;;) {\n iRandom = sjcl.bn.random(iModulus, 0);\n if (iRandom.jacobi(iModulus) === 1) {\n break;\n }\n }\n\n var iBlind = iRandom.powermodMontgomery(iPublic.mul(iExponent), iModulus);\n var iSignreq = iSecret.mulmod(iBlind, iModulus);\n var signreq = sjcl.codec.hex.fromBits(iSignreq.toBits());\n\n request.post(opts.url)\n .send({ info: publicInfo, signreq: signreq })\n .end(function(err, resp) {\n if (err || !resp) {\n return fn(new Error('Could not query PAKDF server ' + opts.host));\n }\n\n var data = resp.body || resp.text ? JSON.parse(resp.text) : {};\n\n if (data.result !== 'success') {\n return fn(new Error('Could not query PAKDF server '+opts.host));\n }\n\n var iSignres = new sjcl.bn(String(data.signres));\n var iRandomInv = iRandom.inverseMod(iModulus);\n var iSigned = iSignres.mulmod(iRandomInv, iModulus);\n var key = iSigned.toBits();\n var result = { };\n\n tokens.forEach(function(token) {\n result[token] = keyHash(key, token);\n });\n\n fn(null, result);\n });\n};\n\n/**\n * Imported from ripple-client\n */\n\n\n\n/**\n * Encrypt data\n *\n * @param {string} key\n * @param {string} data\n */\n\nCrypt.encrypt = function(key, data) {\n key = sjcl.codec.hex.toBits(key);\n\n var opts = extend(true, {}, cryptConfig);\n\n var encryptedObj = JSON.parse(sjcl.encrypt(key, data, opts));\n var version = [sjcl.bitArray.partial(8, 0)];\n var initVector = sjcl.codec.base64.toBits(encryptedObj.iv);\n var ciphertext = sjcl.codec.base64.toBits(encryptedObj.ct);\n\n var encryptedBits = sjcl.bitArray.concat(version, initVector);\n encryptedBits = sjcl.bitArray.concat(encryptedBits, ciphertext);\n\n return sjcl.codec.base64.fromBits(encryptedBits);\n};\n\n/**\n * Decrypt data\n *\n * @param {string} key\n * @param {string} data\n */\n\nCrypt.decrypt = function (key, data) {\n \n key = sjcl.codec.hex.toBits(key);\n var encryptedBits = sjcl.codec.base64.toBits(data);\n\n var version = sjcl.bitArray.extract(encryptedBits, 0, 8);\n\n if (version !== 0) {\n throw new Error('Unsupported encryption version: '+version);\n }\n\n var encrypted = extend(true, {}, cryptConfig, {\n iv: sjcl.codec.base64.fromBits(sjcl.bitArray.bitSlice(encryptedBits, 8, 8+128)),\n ct: sjcl.codec.base64.fromBits(sjcl.bitArray.bitSlice(encryptedBits, 8+128))\n });\n\n return sjcl.decrypt(key, JSON.stringify(encrypted));\n};\n\n\n/**\n * Validate a ripple address\n *\n * @param {string} address\n */\n\nCrypt.isValidAddress = function (address) {\n return UInt160.is_valid(address);\n};\n\n/**\n * Create an encryption key\n *\n * @param {integer} nWords - number of words\n */\n\nCrypt.createSecret = function (nWords) {\n return sjcl.codec.hex.fromBits(randomWords(nWords));\n};\n\n/**\n * Create a new master key\n */\n\nCrypt.createMaster = function () {\n return base.encode_check(33, sjcl.codec.bytes.fromBits(randomWords(4)));\n};\n\n\n/**\n * Create a ripple address from a master key\n *\n * @param {string} masterkey\n */\n\nCrypt.getAddress = function (masterkey) {\n return Seed.from_json(masterkey).get_key().get_address().to_json();\n};\n\n/**\n * Hash data using SHA-512.\n *\n * @param {string|bitArray} data\n * @return {string} Hash of the data\n */\n\nCrypt.hashSha512 = function (data) {\n // XXX Should return a UInt512\n return sjcl.codec.hex.fromBits(sjcl.hash.sha512.hash(data)); \n};\n\n/**\n * Hash data using SHA-512 and return the first 256 bits.\n *\n * @param {string|bitArray} data\n * @return {UInt256} Hash of the data\n */\nCrypt.hashSha512Half = function (data) {\n return UInt256.from_hex(Crypt.hashSha512(data).substr(0, 64));\n};\n\n\n/**\n * Sign a data string with a secret key\n *\n * @param {string} secret\n * @param {string} data\n */\n\nCrypt.signString = function(secret, data) {\n var hmac = new sjcl.misc.hmac(sjcl.codec.hex.toBits(secret), sjcl.hash.sha512);\n return sjcl.codec.hex.fromBits(hmac.mac(data));\n};\n\n/**\n * Create an an accout recovery key\n *\n * @param {string} secret\n */\n\nCrypt.deriveRecoveryEncryptionKeyFromSecret = function(secret) {\n var seed = Seed.from_json(secret).to_bits();\n var hmac = new sjcl.misc.hmac(seed, sjcl.hash.sha512);\n var key = hmac.mac('ripple/hmac/recovery_encryption_key/v1');\n key = sjcl.bitArray.bitSlice(key, 0, 256);\n return sjcl.codec.hex.fromBits(key);\n};\n\n/**\n * Convert base64 encoded data into base64url encoded data.\n *\n * @param {String} base64 Data\n */\n\nCrypt.base64ToBase64Url = function(encodedData) {\n return encodedData.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/[=]+$/, '');\n};\n\n/**\n * Convert base64url encoded data into base64 encoded data.\n *\n * @param {String} base64 Data\n */\n\nCrypt.base64UrlToBase64 = function(encodedData) {\n encodedData = encodedData.replace(/-/g, '+').replace(/_/g, '/');\n\n while (encodedData.length % 4) {\n encodedData += '=';\n }\n\n return encodedData;\n};\n\nexports.Crypt = Crypt;\n\n\n// WEBPACK FOOTER\n// module.id = 30\n// module.readableIdentifier = ./src/js/ripple/crypt.js\n//@ sourceURL=webpack-module:///./src/js/ripple/crypt.js"); /***/ }, /* 31 */ /***/ function(module, exports, __webpack_require__) { - eval("var sjcl = __webpack_require__(19).sjcl;\nvar base = __webpack_require__(7).Base;\nvar Seed = __webpack_require__(10).Seed;\nvar UInt160 = __webpack_require__(8).UInt160;\nvar UInt256 = __webpack_require__(9).UInt256;\nvar request = __webpack_require__(54);\nvar querystring = __webpack_require__(49);\nvar extend = __webpack_require__(43);\nvar parser = __webpack_require__(42);\nvar Crypt = { };\n\nvar cryptConfig = {\n cipher : 'aes',\n mode : 'ccm',\n ts : 64, // tag length\n ks : 256, // key size\n iter : 1000 // iterations (key derivation)\n};\n\n/**\n * Full domain hash based on SHA512\n */\n\nfunction fdh(data, bytelen) {\n var bitlen = bytelen << 3;\n\n if (typeof data === 'string') {\n data = sjcl.codec.utf8String.toBits(data);\n }\n\n // Add hashing rounds until we exceed desired length in bits\n var counter = 0, output = [];\n\n while (sjcl.bitArray.bitLength(output) < bitlen) {\n var hash = sjcl.hash.sha512.hash(sjcl.bitArray.concat([counter], data));\n output = sjcl.bitArray.concat(output, hash);\n counter++;\n }\n\n // Truncate to desired length\n output = sjcl.bitArray.clamp(output, bitlen);\n\n return output;\n};\n\n/**\n * This is a function to derive different hashes from the same key. \n * Each hash is derived as HMAC-SHA512HALF(key, token).\n *\n * @param {string} key\n * @param {string} hash\n */\n\nfunction keyHash(key, token) {\n var hmac = new sjcl.misc.hmac(key, sjcl.hash.sha512);\n return sjcl.codec.hex.fromBits(sjcl.bitArray.bitSlice(hmac.encrypt(token), 0, 256));\n};\n\n/**\n * add entropy at each call to get random words\n * @param {number} nWords\n */\nfunction randomWords (nWords) {\n for (var i = 0; i < 8; i++) {\n sjcl.random.addEntropy(Math.random(), 32, \"Math.random()\");\n } \n \n return sjcl.random.randomWords(nWords); \n}\n\n/****** exposed functions ******/\n\n/**\n * KEY DERIVATION FUNCTION\n *\n * This service takes care of the key derivation, i.e. converting low-entropy\n * secret into higher entropy secret via either computationally expensive\n * processes or peer-assisted key derivation (PAKDF).\n *\n * @param {object} opts\n * @param {string} purpose - Key type/purpose\n * @param {string} username\n * @param {string} secret - Also known as passphrase/password\n * @param {function} fn\n */\n\nCrypt.derive = function(opts, purpose, username, secret, fn) {\n var tokens;\n\n if (purpose === 'login') {\n tokens = ['id', 'crypt'];\n } else {\n tokens = ['unlock'];\n }\n\n var iExponent = new sjcl.bn(String(opts.exponent));\n var iModulus = new sjcl.bn(String(opts.modulus));\n var iAlpha = new sjcl.bn(String(opts.alpha));\n\n var publicInfo = [ 'PAKDF_1_0_0', opts.host.length, opts.host, username.length, username, purpose.length, purpose ].join(':') + ':';\n var publicSize = Math.ceil(Math.min((7 + iModulus.bitLength()) >>> 3, 256) / 8);\n var publicHash = fdh(publicInfo, publicSize);\n var publicHex = sjcl.codec.hex.fromBits(publicHash);\n var iPublic = new sjcl.bn(String(publicHex)).setBitM(0);\n var secretInfo = [ publicInfo, secret.length, secret ].join(':') + ':';\n var secretSize = (7 + iModulus.bitLength()) >>> 3;\n var secretHash = fdh(secretInfo, secretSize);\n var secretHex = sjcl.codec.hex.fromBits(secretHash);\n var iSecret = new sjcl.bn(String(secretHex)).mod(iModulus);\n\n if (iSecret.jacobi(iModulus) !== 1) {\n iSecret = iSecret.mul(iAlpha).mod(iModulus);\n }\n\n var iRandom;\n\n for (;;) {\n iRandom = sjcl.bn.random(iModulus, 0);\n if (iRandom.jacobi(iModulus) === 1) {\n break;\n }\n }\n\n var iBlind = iRandom.powermodMontgomery(iPublic.mul(iExponent), iModulus);\n var iSignreq = iSecret.mulmod(iBlind, iModulus);\n var signreq = sjcl.codec.hex.fromBits(iSignreq.toBits());\n\n request.post(opts.url)\n .send({ info: publicInfo, signreq: signreq })\n .end(function(err, resp) {\n if (err || !resp) {\n return fn(new Error('Could not query PAKDF server ' + opts.host));\n }\n\n var data = resp.body || resp.text ? JSON.parse(resp.text) : {};\n\n if (data.result !== 'success') {\n return fn(new Error('Could not query PAKDF server '+opts.host));\n }\n\n var iSignres = new sjcl.bn(String(data.signres));\n var iRandomInv = iRandom.inverseMod(iModulus);\n var iSigned = iSignres.mulmod(iRandomInv, iModulus);\n var key = iSigned.toBits();\n var result = { };\n\n tokens.forEach(function(token) {\n result[token] = keyHash(key, token);\n });\n\n fn(null, result);\n });\n};\n\n/**\n * Imported from ripple-client\n */\n\n\n\n/**\n * Encrypt data\n *\n * @param {string} key\n * @param {string} data\n */\n\nCrypt.encrypt = function(key, data) {\n key = sjcl.codec.hex.toBits(key);\n\n var opts = extend(true, {}, cryptConfig);\n\n var encryptedObj = JSON.parse(sjcl.encrypt(key, data, opts));\n var version = [sjcl.bitArray.partial(8, 0)];\n var initVector = sjcl.codec.base64.toBits(encryptedObj.iv);\n var ciphertext = sjcl.codec.base64.toBits(encryptedObj.ct);\n\n var encryptedBits = sjcl.bitArray.concat(version, initVector);\n encryptedBits = sjcl.bitArray.concat(encryptedBits, ciphertext);\n\n return sjcl.codec.base64.fromBits(encryptedBits);\n};\n\n/**\n * Decrypt data\n *\n * @param {string} key\n * @param {string} data\n */\n\nCrypt.decrypt = function (key, data) {\n \n key = sjcl.codec.hex.toBits(key);\n var encryptedBits = sjcl.codec.base64.toBits(data);\n\n var version = sjcl.bitArray.extract(encryptedBits, 0, 8);\n\n if (version !== 0) {\n throw new Error('Unsupported encryption version: '+version);\n }\n\n var encrypted = extend(true, {}, cryptConfig, {\n iv: sjcl.codec.base64.fromBits(sjcl.bitArray.bitSlice(encryptedBits, 8, 8+128)),\n ct: sjcl.codec.base64.fromBits(sjcl.bitArray.bitSlice(encryptedBits, 8+128))\n });\n\n return sjcl.decrypt(key, JSON.stringify(encrypted));\n};\n\n\n/**\n * Validate a ripple address\n *\n * @param {string} address\n */\n\nCrypt.isValidAddress = function (address) {\n return UInt160.is_valid(address);\n};\n\n/**\n * Create an encryption key\n *\n * @param {integer} nWords - number of words\n */\n\nCrypt.createSecret = function (nWords) {\n return sjcl.codec.hex.fromBits(randomWords(nWords));\n};\n\n/**\n * Create a new master key\n */\n\nCrypt.createMaster = function () {\n return base.encode_check(33, sjcl.codec.bytes.fromBits(randomWords(4)));\n};\n\n\n/**\n * Create a ripple address from a master key\n *\n * @param {string} masterkey\n */\n\nCrypt.getAddress = function (masterkey) {\n return Seed.from_json(masterkey).get_key().get_address().to_json();\n};\n\n/**\n * Hash data using SHA-512.\n *\n * @param {string|bitArray} data\n * @return {string} Hash of the data\n */\n\nCrypt.hashSha512 = function (data) {\n // XXX Should return a UInt512\n return sjcl.codec.hex.fromBits(sjcl.hash.sha512.hash(data)); \n};\n\n/**\n * Hash data using SHA-512 and return the first 256 bits.\n *\n * @param {string|bitArray} data\n * @return {UInt256} Hash of the data\n */\nCrypt.hashSha512Half = function (data) {\n return UInt256.from_hex(Crypt.hashSha512(data).substr(0, 64));\n};\n\n\n/**\n * Sign a data string with a secret key\n *\n * @param {string} secret\n * @param {string} data\n */\n\nCrypt.signString = function(secret, data) {\n var hmac = new sjcl.misc.hmac(sjcl.codec.hex.toBits(secret), sjcl.hash.sha512);\n return sjcl.codec.hex.fromBits(hmac.mac(data));\n};\n\n/**\n * Create an an accout recovery key\n *\n * @param {string} secret\n */\n\nCrypt.deriveRecoveryEncryptionKeyFromSecret = function(secret) {\n var seed = Seed.from_json(secret).to_bits();\n var hmac = new sjcl.misc.hmac(seed, sjcl.hash.sha512);\n var key = hmac.mac('ripple/hmac/recovery_encryption_key/v1');\n key = sjcl.bitArray.bitSlice(key, 0, 256);\n return sjcl.codec.hex.fromBits(key);\n};\n\n/**\n * Convert base64 encoded data into base64url encoded data.\n *\n * @param {String} base64 Data\n */\n\nCrypt.base64ToBase64Url = function(encodedData) {\n return encodedData.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/[=]+$/, '');\n};\n\n/**\n * Convert base64url encoded data into base64 encoded data.\n *\n * @param {String} base64 Data\n */\n\nCrypt.base64UrlToBase64 = function(encodedData) {\n encodedData = encodedData.replace(/-/g, '+').replace(/_/g, '/');\n\n while (encodedData.length % 4) {\n encodedData += '=';\n }\n\n return encodedData;\n};\n\nexports.Crypt = Crypt;\n\n\n// WEBPACK FOOTER\n// module.id = 31\n// module.readableIdentifier = ./src/js/ripple/crypt.js\n//@ sourceURL=webpack-module:///./src/js/ripple/crypt.js"); + eval("// Convert a JavaScript number to IEEE-754 Double Precision\n// value represented as an array of 8 bytes (octets)\n//\n// Based on:\n// http://cautionsingularityahead.blogspot.com/2010/04/javascript-and-ieee754-redux.html\n//\n// Found and modified from:\n// https://gist.github.com/bartaz/1119041\n\nvar Float = exports.Float = {};\n\nFloat.toIEEE754 = function(v, ebits, fbits) {\n\n var bias = (1 << (ebits - 1)) - 1;\n\n // Compute sign, exponent, fraction\n var s, e, f;\n if (isNaN(v)) {\n e = (1 << bias) - 1; f = 1; s = 0;\n }\n else if (v === Infinity || v === -Infinity) {\n e = (1 << bias) - 1; f = 0; s = (v < 0) ? 1 : 0;\n }\n else if (v === 0) {\n e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0;\n }\n else {\n s = v < 0;\n v = Math.abs(v);\n\n if (v >= Math.pow(2, 1 - bias)) {\n var ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);\n e = ln + bias;\n f = v * Math.pow(2, fbits - ln) - Math.pow(2, fbits);\n }\n else {\n e = 0;\n f = v / Math.pow(2, 1 - bias - fbits);\n }\n }\n\n // Pack sign, exponent, fraction\n var i, bits = [];\n for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = Math.floor(f / 2); }\n for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = Math.floor(e / 2); }\n bits.push(s ? 1 : 0);\n bits.reverse();\n var str = bits.join('');\n\n // Bits to bytes\n var bytes = [];\n while (str.length) {\n bytes.push(parseInt(str.substring(0, 8), 2));\n str = str.substring(8);\n }\n return bytes;\n}\n\nFloat.fromIEEE754 = function(bytes, ebits, fbits) {\n\n // Bytes to bits\n var bits = [];\n for (var i = bytes.length; i; i -= 1) {\n var byte = bytes[i - 1];\n for (var j = 8; j; j -= 1) {\n bits.push(byte % 2 ? 1 : 0); byte = byte >> 1;\n }\n }\n bits.reverse();\n var str = bits.join('');\n\n // Unpack sign, exponent, fraction\n var bias = (1 << (ebits - 1)) - 1;\n var s = parseInt(str.substring(0, 1), 2) ? -1 : 1;\n var e = parseInt(str.substring(1, 1 + ebits), 2);\n var f = parseInt(str.substring(1 + ebits), 2);\n\n // Produce number\n if (e === (1 << ebits) - 1) {\n return f !== 0 ? NaN : s * Infinity;\n }\n else if (e > 0) {\n return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits));\n }\n else if (f !== 0) {\n return s * Math.pow(2, -(bias-1)) * (f / Math.pow(2, fbits));\n }\n else {\n return s * 0;\n }\n}\n\nFloat.fromIEEE754Double = function(b) { return Float.fromIEEE754(b, 11, 52); }\nFloat.toIEEE754Double = function(v) { return Float.toIEEE754(v, 11, 52); }\nFloat.fromIEEE754Single = function(b) { return Float.fromIEEE754(b, 8, 23); }\nFloat.toIEEE754Single = function(v) { return Float.toIEEE754(v, 8, 23); }\n\n\n// Convert array of octets to string binary representation\n// by bartaz\n\nFloat.toIEEE754DoubleString = function(v) {\n return exports.toIEEE754Double(v)\n .map(function(n){ for(n = n.toString(2);n.length < 8;n=\"0\"+n); return n })\n .join('')\n .replace(/(.)(.{11})(.{52})/, \"$1 $2 $3\")\n}\n\n// WEBPACK FOOTER\n// module.id = 31\n// module.readableIdentifier = ./src/js/ripple/ieee754.js\n//@ sourceURL=webpack-module:///./src/js/ripple/ieee754.js"); /***/ }, /* 32 */ /***/ function(module, exports, __webpack_require__) { - eval("var crypt = __webpack_require__(31).Crypt;\nvar SignedRequest = __webpack_require__(46).SignedRequest;\nvar request = __webpack_require__(54);\nvar extend = __webpack_require__(43);\nvar async = __webpack_require__(48);\nvar log = __webpack_require__(24).sub('blob');\nvar BlobClient = {};\n\n//Blob object class\nfunction BlobObj(options) {\n if (!options) options = { };\n \n this.device_id = options.device_id;\n this.url = options.url;\n this.id = options.blob_id;\n this.key = options.key; \n this.identity = new Identity(this);\n this.data = { };\n};\n\n// Blob operations\n// Do NOT change the mapping of existing ops\nBlobObj.ops = {\n // Special\n noop: 0,\n\n // Simple ops\n set: 16,\n unset: 17,\n extend: 18,\n\n // Meta ops\n push: 32,\n pop: 33,\n shift: 34,\n unshift: 35,\n filter: 36\n};\n\n\nBlobObj.opsReverseMap = [ ];\nfor (var name in BlobObj.ops) {\n BlobObj.opsReverseMap[BlobObj.ops[name]] = name;\n}\n\n//Identity fields\nvar identityRoot = 'identityVault';\nvar identityFields = [\n 'name',\n 'entityType',\n 'email',\n 'phone',\n 'address',\n 'nationalID',\n 'birthday',\n 'birthplace'\n];\n\nvar entityTypes = [\n 'individual',\n 'organization',\n 'corporation'\n];\n\nvar addressFields = [\n 'contact',\n 'line1',\n 'line2',\n 'city',\n 'region', //state/province/region\n 'postalCode',\n 'country'\n];\n\nvar nationalIDFields = [\n 'number',\n 'type',\n 'country',\n];\n\nvar idTypeFields = [\n 'ssn',\n 'taxID',\n 'passport',\n 'driversLicense',\n 'other'\n];\n\n/**\n * Initialize a new blob object\n *\n * @param {function} fn - Callback function\n */\n\nBlobObj.prototype.init = function(fn) {\n var self = this, url;\n\n if (self.url.indexOf('://') === -1) {\n self.url = 'http://' + url;\n }\n\n url = self.url + '/v1/blob/' + self.id;\n if (this.device_id) url += '?device_id=' + this.device_id;\n \n request.get(url, function(err, resp) {\n if (err) {\n return fn(new Error(err.message || 'Could not retrieve blob'));\n } else if (!resp.body) {\n return fn(new Error('Could not retrieve blob'));\n } else if (resp.body.twofactor) {\n resp.body.twofactor.blob_id = self.id;\n resp.body.twofactor.blob_url = self.url;\n resp.body.twofactor.device_id = self.device_id;\n resp.body.twofactor.blob_key = self.key\n return fn(resp.body);\n } else if (resp.body.result !== 'success') {\n return fn(new Error('Incorrect username or password'));\n }\n \n self.revision = resp.body.revision;\n self.encrypted_secret = resp.body.encrypted_secret;\n self.missing_fields = resp.body.missing_fields;\n \n if (!self.decrypt(resp.body.blob)) {\n return fn(new Error('Error while decrypting blob'));\n }\n\n //Apply patches\n if (resp.body.patches && resp.body.patches.length) {\n var successful = true;\n resp.body.patches.forEach(function(patch) {\n successful = successful && self.applyEncryptedPatch(patch);\n });\n\n if (successful) {\n self.consolidate();\n }\n }\n\n //return with newly decrypted blob\n fn(null, self);\n }).timeout(8000);\n};\n\n/**\n * Consolidate -\n * Consolidate patches as a new revision\n *\n * @param {function} fn - Callback function\n */\n\nBlobObj.prototype.consolidate = function(fn) {\n // Callback is optional\n if (typeof fn !== 'function') {\n fn = function(){};\n }\n\n //console.log('client: blob: consolidation at revision', this.revision);\n var encrypted = this.encrypt();\n\n var config = {\n method: 'POST',\n url: this.url + '/v1/blob/consolidate',\n dataType: 'json',\n data: {\n blob_id: this.id,\n data: encrypted,\n revision: this.revision\n },\n };\n\n var signedRequest = new SignedRequest(config);\n\n var signed = signedRequest.signHmac(this.data.auth_secret, this.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n // XXX Add better error information to exception\n if (err) {\n fn(new Error('Failed to consolidate blob - XHR error'));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else {\n fn(new Error('Failed to consolidate blob'));\n }\n });\n};\n\n/**\n * ApplyEncryptedPatch -\n * save changes from a downloaded patch to the blob\n *\n * @param {string} patch - encrypted patch string\n */\n\nBlobObj.prototype.applyEncryptedPatch = function(patch) {\n try {\n var args = JSON.parse(crypt.decrypt(this.key, patch));\n var op = args.shift();\n var path = args.shift();\n\n this.applyUpdate(op, path, args);\n this.revision++;\n\n return true;\n } catch (err) {\n //console.log('client: blob: failed to apply patch:', err.toString());\n //console.log(err.stack);\n return false;\n }\n};\n\n/**\n * Encrypt secret with unlock key\n *\n * @param {string} secretUnlockkey\n */\nBlobObj.prototype.encryptSecret = function (secretUnlockKey, secret) {\n return crypt.encrypt(secretUnlockKey, secret);\n};\n\n/**\n * Decrypt secret with unlock key\n *\n * @param {string} secretUnlockkey\n */\n\nBlobObj.prototype.decryptSecret = function(secretUnlockKey) {\n return crypt.decrypt(secretUnlockKey, this.encrypted_secret);\n};\n\n/**\n * Decrypt blob with crypt key\n *\n * @param {string} data - encrypted blob data\n */\n\nBlobObj.prototype.decrypt = function(data) {\n try {\n this.data = JSON.parse(crypt.decrypt(this.key, data));\n return this;\n } catch (e) {\n //console.log('client: blob: decryption failed', e.toString());\n //console.log(e.stack);\n return false;\n }\n};\n\n/**\n * Encrypt blob with crypt key\n */\n\nBlobObj.prototype.encrypt = function() {\n// Filter Angular metadata before encryption\n// if ('object' === typeof this.data &&\n// 'object' === typeof this.data.contacts)\n// this.data.contacts = angular.fromJson(angular.toJson(this.data.contacts));\n\n return crypt.encrypt(this.key, JSON.stringify(this.data));\n};\n\n/**\n * Encrypt recovery key\n *\n * @param {string} secret\n * @param {string} blobDecryptKey\n */\n\nBlobObj.prototype.encryptBlobCrypt = function(secret, blobDecryptKey) {\n var recoveryEncryptionKey = crypt.deriveRecoveryEncryptionKeyFromSecret(secret);\n return crypt.encrypt(recoveryEncryptionKey, blobDecryptKey);\n};\n\n/**\n * Decrypt recovery key\n *\n * @param {string} secret\n * @param {string} encryptedKey\n */\n\nfunction decryptBlobCrypt (secret, encryptedKey) {\n var recoveryEncryptionKey = crypt.deriveRecoveryEncryptionKeyFromSecret(secret);\n return crypt.decrypt(recoveryEncryptionKey, encryptedKey);\n};\n\n/**** Blob updating functions ****/\n\n/**\n * Set blob element\n */\n\nBlobObj.prototype.set = function(pointer, value, fn) {\n if (pointer == \"/\" + identityRoot && this.data[identityRoot]) {\n return fn(new Error('Cannot overwrite Identity Vault')); \n }\n \n this.applyUpdate('set', pointer, [value]);\n this.postUpdate('set', pointer, [value], fn);\n};\n\n/**\n * Remove blob element\n */\n\nBlobObj.prototype.unset = function(pointer, fn) {\n if (pointer == \"/\" + identityRoot) {\n return fn(new Error('Cannot remove Identity Vault')); \n }\n \n this.applyUpdate('unset', pointer, []);\n this.postUpdate('unset', pointer, [], fn);\n};\n\n/**\n * Extend blob object\n */\n\nBlobObj.prototype.extend = function(pointer, value, fn) {\n this.applyUpdate('extend', pointer, [value]);\n this.postUpdate('extend', pointer, [value], fn);\n};\n\n/**\n * Prepend blob array\n */\n\nBlobObj.prototype.unshift = function(pointer, value, fn) { \n this.applyUpdate('unshift', pointer, [value]);\n this.postUpdate('unshift', pointer, [value], fn);\n};\n\n/**\n * Filter the row(s) from an array.\n *\n * This method will find any entries from the array stored under `pointer` and\n * apply the `subcommands` to each of them.\n *\n * The subcommands can be any commands with the pointer parameter left out.\n */\n\nBlobObj.prototype.filter = function(pointer, field, value, subcommands, callback) {\n var args = Array.prototype.slice.apply(arguments);\n\n if (typeof args[args.length - 1] === 'function') {\n callback = args.pop();\n }\n\n args.shift();\n\n // Normalize subcommands to minimize the patch size\n args = args.slice(0, 2).concat(normalizeSubcommands(args.slice(2), true));\n\n this.applyUpdate('filter', pointer, args);\n this.postUpdate('filter', pointer, args, callback);\n};\n\n/**\n * Apply udpdate to the blob\n */\n\nBlobObj.prototype.applyUpdate = function(op, path, params) {\n // Exchange from numeric op code to string\n if (typeof op === 'number') {\n op = BlobObj.opsReverseMap[op];\n }\n\n if (typeof op !== 'string') {\n throw new Error('Blob update op code must be a number or a valid op id string');\n }\n\n // Separate each step in the 'pointer'\n var pointer = path.split('/');\n var first = pointer.shift();\n\n if (first !== '') {\n throw new Error('Invalid JSON pointer: '+path);\n }\n\n this._traverse(this.data, pointer, path, op, params);\n};\n\n//for applyUpdate function\nBlobObj.prototype._traverse = function(context, pointer, originalPointer, op, params) {\n var _this = this;\n var part = _this.unescapeToken(pointer.shift());\n\n if (Array.isArray(context)) {\n if (part === '-') {\n part = context.length;\n } else if (part % 1 !== 0 && part >= 0) {\n throw new Error('Invalid pointer, array element segments must be a positive integer, zero or '-'');\n }\n } else if (typeof context !== 'object') {\n return null;\n } else if (!context.hasOwnProperty(part)) {\n // Some opcodes create the path as they're going along\n if (op === 'set') {\n context[part] = {};\n } else if (op === 'unshift') {\n context[part] = [];\n } else {\n return null;\n }\n }\n\n if (pointer.length !== 0) {\n return this._traverse(context[part], pointer, originalPointer, op, params);\n }\n\n switch (op) {\n case 'set':\n context[part] = params[0];\n break;\n case 'unset':\n if (Array.isArray(context)) {\n context.splice(part, 1);\n } else {\n delete context[part];\n }\n break;\n case 'extend':\n if (typeof context[part] !== 'object') {\n throw new Error('Tried to extend a non-object');\n }\n extend(true, context[part], params[0]);\n break;\n case 'unshift':\n if (typeof context[part] === 'undefined') {\n context[part] = [ ];\n } else if (!Array.isArray(context[part])) {\n throw new Error('Operator \"unshift\" must be applied to an array.');\n }\n context[part].unshift(params[0]);\n break;\n case 'filter':\n if (Array.isArray(context[part])) {\n context[part].forEach(function(element, i) {\n if (typeof element === 'object' && element.hasOwnProperty(params[0]) && element[params[0]] === params[1]) {\n var subpointer = originalPointer + '/' + i;\n var subcommands = normalizeSubcommands(params.slice(2));\n\n subcommands.forEach(function(subcommand) {\n var op = subcommand[0];\n var pointer = subpointer + subcommand[1];\n _this.applyUpdate(op, pointer, subcommand.slice(2));\n });\n }\n });\n }\n break;\n default:\n throw new Error('Unsupported op '+op);\n }\n};\n\nBlobObj.prototype.escapeToken = function(token) {\n return token.replace(/[~\\/]/g, function(key) {\n return key === '~' ? '~0' : '~1';\n });\n};\n\nBlobObj.prototype.unescapeToken = function(str) {\n return str.replace(/~./g, function(m) {\n switch (m) {\n case '~0':\n return '~';\n case '~1':\n return '/';\n }\n throw new Error('Invalid tilde escape: ' + m);\n });\n};\n\n/**\n * Sumbit update to blob vault\n */\n\nBlobObj.prototype.postUpdate = function(op, pointer, params, fn) {\n // Callback is optional\n if (typeof fn !== 'function') {\n fn = function(){};\n }\n\n if (typeof op === 'string') {\n op = BlobObj.ops[op];\n }\n\n if (typeof op !== 'number') {\n throw new Error('Blob update op code must be a number or a valid op id string');\n }\n\n if (op < 0 || op > 255) {\n throw new Error('Blob update op code out of bounds');\n }\n\n //console.log('client: blob: submitting update', BlobObj.opsReverseMap[op], pointer, params);\n\n params.unshift(pointer);\n params.unshift(op);\n\n var config = {\n method: 'POST',\n url: this.url + '/v1/blob/patch',\n dataType: 'json',\n data: {\n blob_id: this.id,\n patch: crypt.encrypt(this.key, JSON.stringify(params))\n }\n };\n\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signHmac(this.data.auth_secret, this.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n fn(new Error('Patch could not be saved - XHR error'));\n } else if (!resp.body || resp.body.result !== 'success') {\n fn(new Error('Patch could not be saved - bad result')); \n } else {\n fn(null, resp.body);\n }\n });\n};\n\n/**\n * get2FA - ECDSA signed request\n */\n\nBlobObj.prototype.get2FA = function (masterkey, fn) {\n var config = {\n method : 'GET',\n url : this.url + '/v1/blob/' + this.id + '/2FA?device_id=' + this.device_id,\n };\n \n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(masterkey, this.data.account_id, this.id);\n\n request.get(signed.url)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Unable to retrieve settings.'));\n }\n }); \n}\n\n/**\n * set2FA\n * modify 2 factor auth settings\n * @params {object} options\n * @params {string} options.masterkey\n * @params {boolean} options.enabled\n * @params {string} options.phone\n * @params {string} options.country_code\n * @params {string} options.via //sms, etc\n */\n\nBlobObj.prototype.set2FA = function(options, fn) {\n \n var config = {\n method : 'POST',\n url : this.url + '/v1/blob/' + this.id + '/2FA',\n data : {\n enabled : options.enabled,\n phone : options.phone,\n country_code : options.country_code,\n via : options.via\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(options.masterkey, this.data.account_id, this.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(resp.body); \n } else {\n fn(new Error('Unable to update settings.'));\n }\n }); \n};\n\n/***** helper functions *****/\n\nfunction normalizeSubcommands(subcommands, compress) {\n // Normalize parameter structure\n if (/(number|string)/.test(typeof subcommands[0])) {\n // Case 1: Single subcommand inline\n subcommands = [subcommands];\n } else if (subcommands.length === 1 && Array.isArray(subcommands[0]) && /(number|string)/.test(typeof subcommands[0][0])) {\n // Case 2: Single subcommand as array\n // (nothing to do)\n } else if (Array.isArray(subcommands[0])) {\n // Case 3: Multiple subcommands as array of arrays\n subcommands = subcommands[0];\n }\n\n // Normalize op name and convert strings to numeric codes\n subcommands = subcommands.map(function(subcommand) {\n if (typeof subcommand[0] === 'string') {\n subcommand[0] = BlobObj.ops[subcommand[0]];\n }\n\n if (typeof subcommand[0] !== 'number') {\n throw new Error('Invalid op in subcommand');\n }\n\n if (typeof subcommand[1] !== 'string') {\n throw new Error('Invalid path in subcommand');\n }\n\n return subcommand;\n });\n\n if (compress) {\n // Convert to the minimal possible format\n if (subcommands.length === 1) {\n return subcommands[0];\n } else {\n return [subcommands];\n }\n } else {\n return subcommands;\n }\n}\n\n\n/***** identity ****/\n\n/** \n * Identity class\n * \n */\n\nvar Identity = function (blob) {\n this._getBlob = function() {\n return blob;\n };\n}; \n\n/**\n * getFullAddress\n * returns the address formed into a text string\n * @param {string} key - Encryption key\n */\n\nIdentity.prototype.getFullAddress = function (key) {\n var blob = this._getBlob();\n if (!blob || \n !blob.data || \n !blob.data[identityRoot] ||\n !blob.data[identityRoot].address) {\n return \"\";\n } \n \n var address = this.get('address', key);\n var text = \"\";\n \n if (address.value.contact) text += address.value.contact;\n if (address.value.line1) text += \" \" + address.value.line1;\n if (address.value.line2) text += \" \" + address.value.line2;\n if (address.value.city) text += \" \" + address.value.city;\n if (address.value.region) text += \" \" + address.value.region;\n if (address.value.postalCode) text += \" \" + address.value.postalCode;\n if (address.value.country) text += \" \" + address.value.country;\n return text;\n};\n\n/**\n * getAll\n * get and decrypt all identity fields\n * @param {string} key - Encryption key\n * @param {function} fn - Callback function\n */\n\nIdentity.prototype.getAll = function (key) {\n var blob = this._getBlob();\n if (!blob || !blob.data || !blob.data[identityRoot]) {\n return {};\n } \n \n var result = {}, identity = blob.data[identityRoot];\n for (var i in identity) {\n result[i] = this.get(i, key);\n }\n \n return result;\n};\n\n/**\n * get\n * get and decrypt a single identity field\n * @param {string} pointer - Field to retrieve\n * @param {string} key - Encryption key\n */\n\nIdentity.prototype.get = function (pointer, key) {\n var blob = this._getBlob();\n if (!blob || !blob.data || !blob.data[identityRoot]) {\n return null;\n }\n \n var data = blob.data[identityRoot][pointer];\n if (data && data.encrypted) {\n return decrypt(key, data);\n \n } else if (data) {\n return data;\n \n } else {\n return null;\n }\n \n function decrypt (key, data) {\n var value;\n var result = {encrypted : true};\n \n try {\n value = crypt.decrypt(key, data.value);\n } catch (e) {\n result.value = data.value;\n result.error = e; \n return result;\n }\n \n try {\n result.value = JSON.parse(value);\n } catch (e) {\n result.value = value;\n }\n \n return result;\n }\n};\n\n/**\n * set\n * set and encrypt a single identity field.\n * @param {string} pointer - Field to set\n * @param {string} key - Encryption key\n * @param {string} value - Unencrypted data\n * @param {function} fn - Callback function\n */\n\nIdentity.prototype.set = function (pointer, key, value, fn) {\n var self = this, blob = this._getBlob();\n \n if (!fn) fn = function(){ };\n \n //check fields for validity\n if (identityFields.indexOf(pointer) === -1) {\n return fn(new Error(\"invalid identity field\")); \n \n //validate address fields \n } else if (pointer === 'address') {\n if (typeof value !== 'object') {\n return fn(new Error(\"address must be an object\")); \n }\n \n for (var addressField in value) {\n if (addressFields.indexOf(addressField) === -1) {\n return fn(new Error(\"invalid address field\")); \n }\n }\n \n //validate nationalID fields \n } else if (pointer === 'nationalID') {\n if (typeof value !== 'object') {\n return fn(new Error(\"nationalID must be an object\")); \n }\n \n for (var idField in value) {\n if (nationalIDFields.indexOf(idField) === -1) {\n return fn(new Error(\"invalid nationalID field\")); \n }\n \n if (idField === 'type') {\n if (idTypeFields.indexOf(value[idField]) === -1) {\n return fn(new Error(\"invalid nationalID type\")); \n } \n }\n } \n \n //validate entity type \n } else if (pointer === 'entityType') {\n if (entityTypes.indexOf(value) === -1) {\n return fn(new Error(\"invalid entity type\")); \n } \n }\n\n async.waterfall([ validate, set ], fn);\n \n //make sure the identity setup is valid\n function validate (callback) {\n \n if (!blob) return fn(new Error(\"Identity must be associated with a blob\"));\n else if (!blob.data) return fn(new Error(\"Invalid Blob\")); \n else if (!blob.data[identityRoot]) {\n blob.set(\"/\" + identityRoot, {}, function(err, res){\n if (err) return callback (err);\n else return callback (null);\n }); \n } else return callback (null);\n };\n \n function set (callback) {\n\n //NOTE: currently we will overwrite if it already exists\n //the other option would be to require decrypting with the\n //existing key as a form of authorization\n //var current = self.get(pointer, key); \n //if (current && current.error) {\n // return fn ? fn(current.error) : undefined;\n //}\n \n var data = {};\n data[pointer] = {\n encrypted : key ? true : false,\n value : key ? encrypt(key, value) : value \n };\n \n self._getBlob().extend(\"/\" + identityRoot, data, callback);\n };\n \n function encrypt (key, value) {\n if (typeof value === 'object') value = JSON.stringify(value);\n return crypt.encrypt(key, value);\n }\n};\n\n/**\n * unset\n * remove a single identity field - will only be removed\n * with a valid decryption key\n * @param {string} pointer - Field to remove\n * @param {string} key - Encryption key\n * @param {function} fn - Callback function\n */\n\nIdentity.prototype.unset = function (pointer, key, fn) {\n \n if (!fn) fn = function(){ };\n \n //NOTE: this is rather useless since you can overwrite\n //without an encryption key\n var data = this.get(pointer, key);\n if (data && data.error) {\n return fn(data.error);\n }\n \n this._getBlob().unset(\"/\" + identityRoot+\"/\" + pointer, fn);\n};\n\n/***** blob client methods ****/\n\n/**\n * Blob object class\n */ \n \nexports.Blob = BlobObj;\n\n/**\n * Get ripple name for a given address\n */\n\nBlobClient.getRippleName = function(url, address, fn) {\n if (!crypt.isValidAddress(address)) {\n return fn (new Error('Invalid ripple address'));\n }\n\n if (!crypt.isValidAddress(address)) return fn (new Error(\"Invalid ripple address\"));\n request.get(url + '/v1/user/' + address, function(err, resp){\n if (err) {\n fn(new Error('Unable to access vault sever'));\n } else if (resp.body && resp.body.username) {\n fn(null, resp.body.username);\n } else if (resp.body && resp.body.exists === false) {\n fn (new Error('No ripple name for this address'));\n } else {\n fn(new Error('Unable to determine if ripple name exists'));\n }\n });\n};\n\n/**\n * Retrive a blob with url, id and key\n * @params {object} options\n * @params {string} options.url\n * @params {string} options.blob_id\n * @params {string} options.key\n * @params {string} options.device_id //optional\n */\n\nBlobClient.get = function (options, fn) {\n var blob = new BlobObj(options);\n blob.init(fn);\n};\n\n/**\n * requestToken\n * request new token to be sent for 2FA\n * @param {string} url\n * @param {string} id\n * @param {string} force_sms\n */\n\nBlobClient.requestToken = function (url, id, force_sms, fn) {\n var config = {\n method : 'GET',\n url : url + '/v1/blob/' + id + '/2FA/requestToken'\n };\n \n \n if (force_sms && force_sms instanceof Function) {\n fn = force_sms;\n } else if (force_sms) {\n config.url += \"?force_sms=true\";\n }\n \n request.get(config.url)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Unable to request authentication token.'));\n }\n }); \n}; \n\n/**\n * verifyToken\n * verify a device token for 2FA \n * @param {object} options\n * @param {string} options.url\n * @param {string} options.id \n * @param {string} options.device_id \n * @param {string} options.token\n * @param {boolean} options.remember_me\n */\n\nBlobClient.verifyToken = function (options, fn) {\n var config = {\n method : 'POST',\n url : options.url + '/v1/blob/' + options.id + '/2FA/verifyToken',\n data : {\n device_id : options.device_id,\n token : options.token,\n remember_me : options.remember_me\n }\n };\n \n request.post(config.url)\n .send(config.data)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Unable to verify authentication token.'));\n }\n }); \n};\n\n/**\n * Verify email address\n */\n\nBlobClient.verify = function(url, username, token, fn) {\n url += '/v1/user/' + username + '/verify/' + token;\n request.get(url, function(err, resp) {\n if (err) { \n fn(new Error(\"Failed to verify the account - XHR error\"));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else {\n fn(new Error('Failed to verify the account'));\n }\n });\n};\n\n/**\n * resendEmail\n * send a new verification email\n * @param {object} opts\n * @param {string} opts.id\n * @param {string} opts.username\n * @param {string} opts.account_id\n * @param {string} opts.email\n * @param {string} opts.activateLink\n * @param {function} fn - Callback\n */\n\nBlobClient.resendEmail = function (opts, fn) {\n var config = {\n method : 'POST',\n url : opts.url + '/v1/user/email',\n data : {\n blob_id : opts.id,\n username : opts.username,\n email : opts.email,\n hostlink : opts.activateLink\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(opts.masterkey, opts.account_id, opts.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error(\"resendEmail:\", err);\n fn(new Error(\"Failed to resend the token\"));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n log.error(\"resendEmail:\", resp.body.message);\n fn(new Error(\"Failed to resend the token\"));\n } else {\n fn(new Error(\"Failed to resend the token\")); \n }\n });\n};\n\n/**\n * RecoverBlob\n * recover a blob using the account secret\n * @param {object} opts\n * @param {string} opts.url\n * @param {string} opts.username\n * @param {string} opts.masterkey\n * @param {function} fn\n */\n\nBlobClient.recoverBlob = function (opts, fn) {\n var username = String(opts.username).trim();\n var config = {\n method : 'GET',\n url : opts.url + '/v1/user/recov/' + username,\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetricRecovery(opts.masterkey, username); \n\n request.get(signed.url)\n .end(function(err, resp) {\n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n if (!resp.body.encrypted_blobdecrypt_key) {\n fn(new Error('Missing encrypted blob decrypt key.')); \n } else {\n handleRecovery(resp); \n } \n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Could not recover blob'));\n }\n });\n \n function handleRecovery (resp) {\n\n var params = {\n url : opts.url,\n blob_id : resp.body.blob_id,\n key : decryptBlobCrypt(opts.masterkey, resp.body.encrypted_blobdecrypt_key)\n }\n \n var blob = new BlobObj(params);\n \n blob.revision = resp.body.revision;\n blob.encrypted_secret = resp.body.encrypted_secret;\n\n if (!blob.decrypt(resp.body.blob)) {\n return fn(new Error('Error while decrypting blob'));\n }\n\n //Apply patches\n if (resp.body.patches && resp.body.patches.length) {\n var successful = true;\n resp.body.patches.forEach(function(patch) {\n successful = successful && blob.applyEncryptedPatch(patch);\n });\n\n if (successful) {\n blob.consolidate();\n }\n }\n\n //return with newly decrypted blob\n fn(null, blob);\n };\n};\n\n/**\n * updateProfile\n * update information stored outside the blob - HMAC signed\n * @param {object}\n * @param {string} opts.url\n * @param {string} opts.username\n * @param {string} opts.auth_secret\n * @param {srring} opts.blob_id\n * @param {object} opts.profile\n * @param {string} opts.profile.phone - optional\n * @param {string} opts.profile.country - optional\n * @param {string} opts.profile.region - optional\n * @param {string} opts.profile.city - optional\n */\n\nBlobClient.updateProfile = function (opts, fn) {\n var config = {\n method: 'POST',\n url: opts.url + '/v1/user/' + opts.username + '/profile',\n dataType: 'json',\n data: opts.profile\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signHmac(opts.auth_secret, opts.blob_id); \n \n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error('updateProfile:', err);\n fn(new Error('Failed to update profile - XHR error'));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body) {\n log.error('updateProfile:', resp.body);\n } else {\n fn(new Error('Failed to update profile'));\n }\n });\n \n};\n\n/**\n * updateKeys\n * Change the blob encryption keys\n * @param {object} opts\n * @param {string} opts.username\n * @param {object} opts.keys\n * @param {object} opts.blob\n * @param {string} masterkey\n */\n\nBlobClient.updateKeys = function (opts, fn) {\n var old_id = opts.blob.id;\n opts.blob.id = opts.keys.id;\n opts.blob.key = opts.keys.crypt;\n opts.blob.encrypted_secret = opts.blob.encryptSecret(opts.keys.unlock, opts.masterkey);\n \n var config = {\n method : 'POST',\n url : opts.blob.url + '/v1/user/' + opts.username + '/updatekeys',\n data : {\n blob_id : opts.blob.id,\n data : opts.blob.encrypt(),\n revision : opts.blob.revision,\n encrypted_secret : opts.blob.encrypted_secret,\n encrypted_blobdecrypt_key : opts.blob.encryptBlobCrypt(opts.masterkey, opts.keys.crypt),\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(opts.masterkey, opts.blob.data.account_id, old_id); \n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error(\"updateKeys:\", err);\n fn(new Error('Failed to update blob - XHR error'));\n } else if (!resp.body || resp.body.result !== 'success') {\n log.error(\"updateKeys:\", resp.body ? resp.body.message : null);\n fn(new Error('Failed to update blob - bad result')); \n } else {\n fn(null, resp.body);\n }\n }); \n}; \n \n/**\n * rename\n * Change the username\n * @param {object} opts\n * @param {string} opts.username\n * @param {string} opts.new_username\n * @param {object} opts.keys\n * @param {object} opts.blob\n * @param {string} masterkey\n */\n\nBlobClient.rename = function (opts, fn) {\n var old_id = opts.blob.id;\n opts.blob.id = opts.keys.id;\n opts.blob.key = opts.keys.crypt;\n opts.blob.encryptedSecret = opts.blob.encryptSecret(opts.keys.unlock, opts.masterkey);\n\n var config = {\n method: 'POST',\n url: opts.blob.url + '/v1/user/' + opts.username + '/rename',\n data: {\n blob_id : opts.blob.id,\n username : opts.new_username,\n data : opts.blob.encrypt(),\n revision : opts.blob.revision,\n encrypted_secret : opts.blob.encryptedSecret,\n encrypted_blobdecrypt_key : opts.blob.encryptBlobCrypt(opts.masterkey, opts.keys.crypt)\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(opts.masterkey, opts.blob.data.account_id, old_id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error(\"rename:\", err);\n fn(new Error(\"Failed to rename\"));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n log.error(\"rename:\", resp.body.message);\n fn(new Error(\"Failed to rename\"));\n } else {\n fn(new Error(\"Failed to rename\"));\n }\n });\n};\n\n/**\n * Create a blob object\n *\n * @param {object} options\n * @param {string} options.url\n * @param {string} options.id\n * @param {string} options.crypt\n * @param {string} options.unlock\n * @param {string} options.username\n * @param {string} options.masterkey\n * @param {object} options.oldUserBlob\n * @param {function} fn\n */\n\nBlobClient.create = function(options, fn) {\n var params = {\n url : options.url,\n blob_id : options.id,\n key : options.crypt\n }\n var blob = new BlobObj(params);\n\n blob.revision = 0;\n\n blob.data = {\n auth_secret : crypt.createSecret(8),\n account_id : crypt.getAddress(options.masterkey),\n email : options.email,\n contacts : [],\n created : (new Date()).toJSON()\n };\n\n blob.encrypted_secret = blob.encryptSecret(options.unlock, options.masterkey);\n\n // Migration\n if (options.oldUserBlob) {\n blob.data.contacts = options.oldUserBlob.data.contacts;\n }\n\n //post to the blob vault to create\n var config = {\n method : 'POST',\n url : options.url + '/v1/user',\n data : {\n blob_id : options.id,\n username : options.username,\n address : blob.data.account_id,\n auth_secret : blob.data.auth_secret,\n data : blob.encrypt(),\n email : options.email,\n hostlink : options.activateLink,\n domain : options.domain,\n encrypted_blobdecrypt_key : blob.encryptBlobCrypt(options.masterkey, options.crypt),\n encrypted_secret : blob.encrypted_secret\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(options.masterkey, blob.data.account_id, options.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, blob, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Could not create blob'));\n }\n });\n};\n\n/**\n * deleteBlob\n * @param {object} options\n * @param {string} options.url\n * @param {string} options.username\n * @param {string} options.blob_id\n * @param {string} options.account_id\n * @param {string} options.masterkey \n */\n\nBlobClient.deleteBlob = function(options, fn) {\n \n var config = {\n method : 'DELETE',\n url : options.url + '/v1/user/' + options.username,\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(options.masterkey, options.account_id, options.blob_id);\n\n request.del(signed.url)\n .end(function(err, resp) {\n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Could not delete blob'));\n }\n }); \n};\n\nexports.BlobClient = BlobClient;\n\n\n// WEBPACK FOOTER\n// module.id = 32\n// module.readableIdentifier = ./src/js/ripple/blob.js\n//@ sourceURL=webpack-module:///./src/js/ripple/blob.js"); + eval("var crypt = __webpack_require__(30).Crypt;\nvar SignedRequest = __webpack_require__(46).SignedRequest;\nvar request = __webpack_require__(49);\nvar extend = __webpack_require__(43);\nvar async = __webpack_require__(48);\nvar log = __webpack_require__(24).sub('blob');\nvar BlobClient = {};\n\n//Blob object class\nfunction BlobObj(options) {\n if (!options) options = { };\n \n this.device_id = options.device_id;\n this.url = options.url;\n this.id = options.blob_id;\n this.key = options.key; \n this.identity = new Identity(this);\n this.data = { };\n};\n\n// Blob operations\n// Do NOT change the mapping of existing ops\nBlobObj.ops = {\n // Special\n noop: 0,\n\n // Simple ops\n set: 16,\n unset: 17,\n extend: 18,\n\n // Meta ops\n push: 32,\n pop: 33,\n shift: 34,\n unshift: 35,\n filter: 36\n};\n\n\nBlobObj.opsReverseMap = [ ];\nfor (var name in BlobObj.ops) {\n BlobObj.opsReverseMap[BlobObj.ops[name]] = name;\n}\n\n//Identity fields\nvar identityRoot = 'identityVault';\nvar identityFields = [\n 'name',\n 'entityType',\n 'email',\n 'phone',\n 'address',\n 'nationalID',\n 'birthday',\n 'birthplace'\n];\n\nvar entityTypes = [\n 'individual',\n 'organization',\n 'corporation'\n];\n\nvar addressFields = [\n 'contact',\n 'line1',\n 'line2',\n 'city',\n 'region', //state/province/region\n 'postalCode',\n 'country'\n];\n\nvar nationalIDFields = [\n 'number',\n 'type',\n 'country',\n];\n\nvar idTypeFields = [\n 'ssn',\n 'taxID',\n 'passport',\n 'driversLicense',\n 'other'\n];\n\n/**\n * Initialize a new blob object\n *\n * @param {function} fn - Callback function\n */\n\nBlobObj.prototype.init = function(fn) {\n var self = this, url;\n\n if (self.url.indexOf('://') === -1) {\n self.url = 'http://' + url;\n }\n\n url = self.url + '/v1/blob/' + self.id;\n if (this.device_id) url += '?device_id=' + this.device_id;\n \n request.get(url, function(err, resp) {\n if (err) {\n return fn(new Error(err.message || 'Could not retrieve blob'));\n } else if (!resp.body) {\n return fn(new Error('Could not retrieve blob'));\n } else if (resp.body.twofactor) {\n resp.body.twofactor.blob_id = self.id;\n resp.body.twofactor.blob_url = self.url;\n resp.body.twofactor.device_id = self.device_id;\n resp.body.twofactor.blob_key = self.key\n return fn(resp.body);\n } else if (resp.body.result !== 'success') {\n return fn(new Error('Incorrect username or password'));\n }\n \n self.revision = resp.body.revision;\n self.encrypted_secret = resp.body.encrypted_secret;\n self.missing_fields = resp.body.missing_fields;\n \n if (!self.decrypt(resp.body.blob)) {\n return fn(new Error('Error while decrypting blob'));\n }\n\n //Apply patches\n if (resp.body.patches && resp.body.patches.length) {\n var successful = true;\n resp.body.patches.forEach(function(patch) {\n successful = successful && self.applyEncryptedPatch(patch);\n });\n\n if (successful) {\n self.consolidate();\n }\n }\n\n //return with newly decrypted blob\n fn(null, self);\n }).timeout(8000);\n};\n\n/**\n * Consolidate -\n * Consolidate patches as a new revision\n *\n * @param {function} fn - Callback function\n */\n\nBlobObj.prototype.consolidate = function(fn) {\n // Callback is optional\n if (typeof fn !== 'function') {\n fn = function(){};\n }\n\n //console.log('client: blob: consolidation at revision', this.revision);\n var encrypted = this.encrypt();\n\n var config = {\n method: 'POST',\n url: this.url + '/v1/blob/consolidate',\n dataType: 'json',\n data: {\n blob_id: this.id,\n data: encrypted,\n revision: this.revision\n },\n };\n\n var signedRequest = new SignedRequest(config);\n\n var signed = signedRequest.signHmac(this.data.auth_secret, this.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n // XXX Add better error information to exception\n if (err) {\n fn(new Error('Failed to consolidate blob - XHR error'));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else {\n fn(new Error('Failed to consolidate blob'));\n }\n });\n};\n\n/**\n * ApplyEncryptedPatch -\n * save changes from a downloaded patch to the blob\n *\n * @param {string} patch - encrypted patch string\n */\n\nBlobObj.prototype.applyEncryptedPatch = function(patch) {\n try {\n var args = JSON.parse(crypt.decrypt(this.key, patch));\n var op = args.shift();\n var path = args.shift();\n\n this.applyUpdate(op, path, args);\n this.revision++;\n\n return true;\n } catch (err) {\n //console.log('client: blob: failed to apply patch:', err.toString());\n //console.log(err.stack);\n return false;\n }\n};\n\n/**\n * Encrypt secret with unlock key\n *\n * @param {string} secretUnlockkey\n */\nBlobObj.prototype.encryptSecret = function (secretUnlockKey, secret) {\n return crypt.encrypt(secretUnlockKey, secret);\n};\n\n/**\n * Decrypt secret with unlock key\n *\n * @param {string} secretUnlockkey\n */\n\nBlobObj.prototype.decryptSecret = function(secretUnlockKey) {\n return crypt.decrypt(secretUnlockKey, this.encrypted_secret);\n};\n\n/**\n * Decrypt blob with crypt key\n *\n * @param {string} data - encrypted blob data\n */\n\nBlobObj.prototype.decrypt = function(data) {\n try {\n this.data = JSON.parse(crypt.decrypt(this.key, data));\n return this;\n } catch (e) {\n //console.log('client: blob: decryption failed', e.toString());\n //console.log(e.stack);\n return false;\n }\n};\n\n/**\n * Encrypt blob with crypt key\n */\n\nBlobObj.prototype.encrypt = function() {\n// Filter Angular metadata before encryption\n// if ('object' === typeof this.data &&\n// 'object' === typeof this.data.contacts)\n// this.data.contacts = angular.fromJson(angular.toJson(this.data.contacts));\n\n return crypt.encrypt(this.key, JSON.stringify(this.data));\n};\n\n/**\n * Encrypt recovery key\n *\n * @param {string} secret\n * @param {string} blobDecryptKey\n */\n\nBlobObj.prototype.encryptBlobCrypt = function(secret, blobDecryptKey) {\n var recoveryEncryptionKey = crypt.deriveRecoveryEncryptionKeyFromSecret(secret);\n return crypt.encrypt(recoveryEncryptionKey, blobDecryptKey);\n};\n\n/**\n * Decrypt recovery key\n *\n * @param {string} secret\n * @param {string} encryptedKey\n */\n\nfunction decryptBlobCrypt (secret, encryptedKey) {\n var recoveryEncryptionKey = crypt.deriveRecoveryEncryptionKeyFromSecret(secret);\n return crypt.decrypt(recoveryEncryptionKey, encryptedKey);\n};\n\n/**** Blob updating functions ****/\n\n/**\n * Set blob element\n */\n\nBlobObj.prototype.set = function(pointer, value, fn) {\n if (pointer == \"/\" + identityRoot && this.data[identityRoot]) {\n return fn(new Error('Cannot overwrite Identity Vault')); \n }\n \n this.applyUpdate('set', pointer, [value]);\n this.postUpdate('set', pointer, [value], fn);\n};\n\n/**\n * Remove blob element\n */\n\nBlobObj.prototype.unset = function(pointer, fn) {\n if (pointer == \"/\" + identityRoot) {\n return fn(new Error('Cannot remove Identity Vault')); \n }\n \n this.applyUpdate('unset', pointer, []);\n this.postUpdate('unset', pointer, [], fn);\n};\n\n/**\n * Extend blob object\n */\n\nBlobObj.prototype.extend = function(pointer, value, fn) {\n this.applyUpdate('extend', pointer, [value]);\n this.postUpdate('extend', pointer, [value], fn);\n};\n\n/**\n * Prepend blob array\n */\n\nBlobObj.prototype.unshift = function(pointer, value, fn) { \n this.applyUpdate('unshift', pointer, [value]);\n this.postUpdate('unshift', pointer, [value], fn);\n};\n\n/**\n * Filter the row(s) from an array.\n *\n * This method will find any entries from the array stored under `pointer` and\n * apply the `subcommands` to each of them.\n *\n * The subcommands can be any commands with the pointer parameter left out.\n */\n\nBlobObj.prototype.filter = function(pointer, field, value, subcommands, callback) {\n var args = Array.prototype.slice.apply(arguments);\n\n if (typeof args[args.length - 1] === 'function') {\n callback = args.pop();\n }\n\n args.shift();\n\n // Normalize subcommands to minimize the patch size\n args = args.slice(0, 2).concat(normalizeSubcommands(args.slice(2), true));\n\n this.applyUpdate('filter', pointer, args);\n this.postUpdate('filter', pointer, args, callback);\n};\n\n/**\n * Apply udpdate to the blob\n */\n\nBlobObj.prototype.applyUpdate = function(op, path, params) {\n // Exchange from numeric op code to string\n if (typeof op === 'number') {\n op = BlobObj.opsReverseMap[op];\n }\n\n if (typeof op !== 'string') {\n throw new Error('Blob update op code must be a number or a valid op id string');\n }\n\n // Separate each step in the 'pointer'\n var pointer = path.split('/');\n var first = pointer.shift();\n\n if (first !== '') {\n throw new Error('Invalid JSON pointer: '+path);\n }\n\n this._traverse(this.data, pointer, path, op, params);\n};\n\n//for applyUpdate function\nBlobObj.prototype._traverse = function(context, pointer, originalPointer, op, params) {\n var _this = this;\n var part = _this.unescapeToken(pointer.shift());\n\n if (Array.isArray(context)) {\n if (part === '-') {\n part = context.length;\n } else if (part % 1 !== 0 && part >= 0) {\n throw new Error('Invalid pointer, array element segments must be a positive integer, zero or '-'');\n }\n } else if (typeof context !== 'object') {\n return null;\n } else if (!context.hasOwnProperty(part)) {\n // Some opcodes create the path as they're going along\n if (op === 'set') {\n context[part] = {};\n } else if (op === 'unshift') {\n context[part] = [];\n } else {\n return null;\n }\n }\n\n if (pointer.length !== 0) {\n return this._traverse(context[part], pointer, originalPointer, op, params);\n }\n\n switch (op) {\n case 'set':\n context[part] = params[0];\n break;\n case 'unset':\n if (Array.isArray(context)) {\n context.splice(part, 1);\n } else {\n delete context[part];\n }\n break;\n case 'extend':\n if (typeof context[part] !== 'object') {\n throw new Error('Tried to extend a non-object');\n }\n extend(true, context[part], params[0]);\n break;\n case 'unshift':\n if (typeof context[part] === 'undefined') {\n context[part] = [ ];\n } else if (!Array.isArray(context[part])) {\n throw new Error('Operator \"unshift\" must be applied to an array.');\n }\n context[part].unshift(params[0]);\n break;\n case 'filter':\n if (Array.isArray(context[part])) {\n context[part].forEach(function(element, i) {\n if (typeof element === 'object' && element.hasOwnProperty(params[0]) && element[params[0]] === params[1]) {\n var subpointer = originalPointer + '/' + i;\n var subcommands = normalizeSubcommands(params.slice(2));\n\n subcommands.forEach(function(subcommand) {\n var op = subcommand[0];\n var pointer = subpointer + subcommand[1];\n _this.applyUpdate(op, pointer, subcommand.slice(2));\n });\n }\n });\n }\n break;\n default:\n throw new Error('Unsupported op '+op);\n }\n};\n\nBlobObj.prototype.escapeToken = function(token) {\n return token.replace(/[~\\/]/g, function(key) {\n return key === '~' ? '~0' : '~1';\n });\n};\n\nBlobObj.prototype.unescapeToken = function(str) {\n return str.replace(/~./g, function(m) {\n switch (m) {\n case '~0':\n return '~';\n case '~1':\n return '/';\n }\n throw new Error('Invalid tilde escape: ' + m);\n });\n};\n\n/**\n * Sumbit update to blob vault\n */\n\nBlobObj.prototype.postUpdate = function(op, pointer, params, fn) {\n // Callback is optional\n if (typeof fn !== 'function') {\n fn = function(){};\n }\n\n if (typeof op === 'string') {\n op = BlobObj.ops[op];\n }\n\n if (typeof op !== 'number') {\n throw new Error('Blob update op code must be a number or a valid op id string');\n }\n\n if (op < 0 || op > 255) {\n throw new Error('Blob update op code out of bounds');\n }\n\n //console.log('client: blob: submitting update', BlobObj.opsReverseMap[op], pointer, params);\n\n params.unshift(pointer);\n params.unshift(op);\n\n var config = {\n method: 'POST',\n url: this.url + '/v1/blob/patch',\n dataType: 'json',\n data: {\n blob_id: this.id,\n patch: crypt.encrypt(this.key, JSON.stringify(params))\n }\n };\n\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signHmac(this.data.auth_secret, this.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n fn(new Error('Patch could not be saved - XHR error'));\n } else if (!resp.body || resp.body.result !== 'success') {\n fn(new Error('Patch could not be saved - bad result')); \n } else {\n fn(null, resp.body);\n }\n });\n};\n\n/**\n * get2FA - ECDSA signed request\n */\n\nBlobObj.prototype.get2FA = function (masterkey, fn) {\n var config = {\n method : 'GET',\n url : this.url + '/v1/blob/' + this.id + '/2FA?device_id=' + this.device_id,\n };\n \n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(masterkey, this.data.account_id, this.id);\n\n request.get(signed.url)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Unable to retrieve settings.'));\n }\n }); \n}\n\n/**\n * set2FA\n * modify 2 factor auth settings\n * @params {object} options\n * @params {string} options.masterkey\n * @params {boolean} options.enabled\n * @params {string} options.phone\n * @params {string} options.country_code\n * @params {string} options.via //sms, etc\n */\n\nBlobObj.prototype.set2FA = function(options, fn) {\n \n var config = {\n method : 'POST',\n url : this.url + '/v1/blob/' + this.id + '/2FA',\n data : {\n enabled : options.enabled,\n phone : options.phone,\n country_code : options.country_code,\n via : options.via\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(options.masterkey, this.data.account_id, this.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(resp.body); \n } else {\n fn(new Error('Unable to update settings.'));\n }\n }); \n};\n\n/***** helper functions *****/\n\nfunction normalizeSubcommands(subcommands, compress) {\n // Normalize parameter structure\n if (/(number|string)/.test(typeof subcommands[0])) {\n // Case 1: Single subcommand inline\n subcommands = [subcommands];\n } else if (subcommands.length === 1 && Array.isArray(subcommands[0]) && /(number|string)/.test(typeof subcommands[0][0])) {\n // Case 2: Single subcommand as array\n // (nothing to do)\n } else if (Array.isArray(subcommands[0])) {\n // Case 3: Multiple subcommands as array of arrays\n subcommands = subcommands[0];\n }\n\n // Normalize op name and convert strings to numeric codes\n subcommands = subcommands.map(function(subcommand) {\n if (typeof subcommand[0] === 'string') {\n subcommand[0] = BlobObj.ops[subcommand[0]];\n }\n\n if (typeof subcommand[0] !== 'number') {\n throw new Error('Invalid op in subcommand');\n }\n\n if (typeof subcommand[1] !== 'string') {\n throw new Error('Invalid path in subcommand');\n }\n\n return subcommand;\n });\n\n if (compress) {\n // Convert to the minimal possible format\n if (subcommands.length === 1) {\n return subcommands[0];\n } else {\n return [subcommands];\n }\n } else {\n return subcommands;\n }\n}\n\n\n/***** identity ****/\n\n/** \n * Identity class\n * \n */\n\nvar Identity = function (blob) {\n this._getBlob = function() {\n return blob;\n };\n}; \n\n/**\n * getFullAddress\n * returns the address formed into a text string\n * @param {string} key - Encryption key\n */\n\nIdentity.prototype.getFullAddress = function (key) {\n var blob = this._getBlob();\n if (!blob || \n !blob.data || \n !blob.data[identityRoot] ||\n !blob.data[identityRoot].address) {\n return \"\";\n } \n \n var address = this.get('address', key);\n var text = \"\";\n \n if (address.value.contact) text += address.value.contact;\n if (address.value.line1) text += \" \" + address.value.line1;\n if (address.value.line2) text += \" \" + address.value.line2;\n if (address.value.city) text += \" \" + address.value.city;\n if (address.value.region) text += \" \" + address.value.region;\n if (address.value.postalCode) text += \" \" + address.value.postalCode;\n if (address.value.country) text += \" \" + address.value.country;\n return text;\n};\n\n/**\n * getAll\n * get and decrypt all identity fields\n * @param {string} key - Encryption key\n * @param {function} fn - Callback function\n */\n\nIdentity.prototype.getAll = function (key) {\n var blob = this._getBlob();\n if (!blob || !blob.data || !blob.data[identityRoot]) {\n return {};\n } \n \n var result = {}, identity = blob.data[identityRoot];\n for (var i in identity) {\n result[i] = this.get(i, key);\n }\n \n return result;\n};\n\n/**\n * get\n * get and decrypt a single identity field\n * @param {string} pointer - Field to retrieve\n * @param {string} key - Encryption key\n */\n\nIdentity.prototype.get = function (pointer, key) {\n var blob = this._getBlob();\n if (!blob || !blob.data || !blob.data[identityRoot]) {\n return null;\n }\n \n var data = blob.data[identityRoot][pointer];\n if (data && data.encrypted) {\n return decrypt(key, data);\n \n } else if (data) {\n return data;\n \n } else {\n return null;\n }\n \n function decrypt (key, data) {\n var value;\n var result = {encrypted : true};\n \n try {\n value = crypt.decrypt(key, data.value);\n } catch (e) {\n result.value = data.value;\n result.error = e; \n return result;\n }\n \n try {\n result.value = JSON.parse(value);\n } catch (e) {\n result.value = value;\n }\n \n return result;\n }\n};\n\n/**\n * set\n * set and encrypt a single identity field.\n * @param {string} pointer - Field to set\n * @param {string} key - Encryption key\n * @param {string} value - Unencrypted data\n * @param {function} fn - Callback function\n */\n\nIdentity.prototype.set = function (pointer, key, value, fn) {\n var self = this, blob = this._getBlob();\n \n if (!fn) fn = function(){ };\n \n //check fields for validity\n if (identityFields.indexOf(pointer) === -1) {\n return fn(new Error(\"invalid identity field\")); \n \n //validate address fields \n } else if (pointer === 'address') {\n if (typeof value !== 'object') {\n return fn(new Error(\"address must be an object\")); \n }\n \n for (var addressField in value) {\n if (addressFields.indexOf(addressField) === -1) {\n return fn(new Error(\"invalid address field\")); \n }\n }\n \n //validate nationalID fields \n } else if (pointer === 'nationalID') {\n if (typeof value !== 'object') {\n return fn(new Error(\"nationalID must be an object\")); \n }\n \n for (var idField in value) {\n if (nationalIDFields.indexOf(idField) === -1) {\n return fn(new Error(\"invalid nationalID field\")); \n }\n \n if (idField === 'type') {\n if (idTypeFields.indexOf(value[idField]) === -1) {\n return fn(new Error(\"invalid nationalID type\")); \n } \n }\n } \n \n //validate entity type \n } else if (pointer === 'entityType') {\n if (entityTypes.indexOf(value) === -1) {\n return fn(new Error(\"invalid entity type\")); \n } \n }\n\n async.waterfall([ validate, set ], fn);\n \n //make sure the identity setup is valid\n function validate (callback) {\n \n if (!blob) return fn(new Error(\"Identity must be associated with a blob\"));\n else if (!blob.data) return fn(new Error(\"Invalid Blob\")); \n else if (!blob.data[identityRoot]) {\n blob.set(\"/\" + identityRoot, {}, function(err, res){\n if (err) return callback (err);\n else return callback (null);\n }); \n } else return callback (null);\n };\n \n function set (callback) {\n\n //NOTE: currently we will overwrite if it already exists\n //the other option would be to require decrypting with the\n //existing key as a form of authorization\n //var current = self.get(pointer, key); \n //if (current && current.error) {\n // return fn ? fn(current.error) : undefined;\n //}\n \n var data = {};\n data[pointer] = {\n encrypted : key ? true : false,\n value : key ? encrypt(key, value) : value \n };\n \n self._getBlob().extend(\"/\" + identityRoot, data, callback);\n };\n \n function encrypt (key, value) {\n if (typeof value === 'object') value = JSON.stringify(value);\n return crypt.encrypt(key, value);\n }\n};\n\n/**\n * unset\n * remove a single identity field - will only be removed\n * with a valid decryption key\n * @param {string} pointer - Field to remove\n * @param {string} key - Encryption key\n * @param {function} fn - Callback function\n */\n\nIdentity.prototype.unset = function (pointer, key, fn) {\n \n if (!fn) fn = function(){ };\n \n //NOTE: this is rather useless since you can overwrite\n //without an encryption key\n var data = this.get(pointer, key);\n if (data && data.error) {\n return fn(data.error);\n }\n \n this._getBlob().unset(\"/\" + identityRoot+\"/\" + pointer, fn);\n};\n\n/***** blob client methods ****/\n\n/**\n * Blob object class\n */ \n \nexports.Blob = BlobObj;\n\n/**\n * Get ripple name for a given address\n */\n\nBlobClient.getRippleName = function(url, address, fn) {\n if (!crypt.isValidAddress(address)) {\n return fn (new Error('Invalid ripple address'));\n }\n\n if (!crypt.isValidAddress(address)) return fn (new Error(\"Invalid ripple address\"));\n request.get(url + '/v1/user/' + address, function(err, resp){\n if (err) {\n fn(new Error('Unable to access vault sever'));\n } else if (resp.body && resp.body.username) {\n fn(null, resp.body.username);\n } else if (resp.body && resp.body.exists === false) {\n fn (new Error('No ripple name for this address'));\n } else {\n fn(new Error('Unable to determine if ripple name exists'));\n }\n });\n};\n\n/**\n * Retrive a blob with url, id and key\n * @params {object} options\n * @params {string} options.url\n * @params {string} options.blob_id\n * @params {string} options.key\n * @params {string} options.device_id //optional\n */\n\nBlobClient.get = function (options, fn) {\n var blob = new BlobObj(options);\n blob.init(fn);\n};\n\n/**\n * requestToken\n * request new token to be sent for 2FA\n * @param {string} url\n * @param {string} id\n * @param {string} force_sms\n */\n\nBlobClient.requestToken = function (url, id, force_sms, fn) {\n var config = {\n method : 'GET',\n url : url + '/v1/blob/' + id + '/2FA/requestToken'\n };\n \n \n if (force_sms && force_sms instanceof Function) {\n fn = force_sms;\n } else if (force_sms) {\n config.url += \"?force_sms=true\";\n }\n \n request.get(config.url)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Unable to request authentication token.'));\n }\n }); \n}; \n\n/**\n * verifyToken\n * verify a device token for 2FA \n * @param {object} options\n * @param {string} options.url\n * @param {string} options.id \n * @param {string} options.device_id \n * @param {string} options.token\n * @param {boolean} options.remember_me\n */\n\nBlobClient.verifyToken = function (options, fn) {\n var config = {\n method : 'POST',\n url : options.url + '/v1/blob/' + options.id + '/2FA/verifyToken',\n data : {\n device_id : options.device_id,\n token : options.token,\n remember_me : options.remember_me\n }\n };\n \n request.post(config.url)\n .send(config.data)\n .end(function(err, resp) { \n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Unable to verify authentication token.'));\n }\n }); \n};\n\n/**\n * Verify email address\n */\n\nBlobClient.verify = function(url, username, token, fn) {\n url += '/v1/user/' + username + '/verify/' + token;\n request.get(url, function(err, resp) {\n if (err) { \n fn(new Error(\"Failed to verify the account - XHR error\"));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else {\n fn(new Error('Failed to verify the account'));\n }\n });\n};\n\n/**\n * resendEmail\n * send a new verification email\n * @param {object} opts\n * @param {string} opts.id\n * @param {string} opts.username\n * @param {string} opts.account_id\n * @param {string} opts.email\n * @param {string} opts.activateLink\n * @param {function} fn - Callback\n */\n\nBlobClient.resendEmail = function (opts, fn) {\n var config = {\n method : 'POST',\n url : opts.url + '/v1/user/email',\n data : {\n blob_id : opts.id,\n username : opts.username,\n email : opts.email,\n hostlink : opts.activateLink\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(opts.masterkey, opts.account_id, opts.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error(\"resendEmail:\", err);\n fn(new Error(\"Failed to resend the token\"));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n log.error(\"resendEmail:\", resp.body.message);\n fn(new Error(\"Failed to resend the token\"));\n } else {\n fn(new Error(\"Failed to resend the token\")); \n }\n });\n};\n\n/**\n * RecoverBlob\n * recover a blob using the account secret\n * @param {object} opts\n * @param {string} opts.url\n * @param {string} opts.username\n * @param {string} opts.masterkey\n * @param {function} fn\n */\n\nBlobClient.recoverBlob = function (opts, fn) {\n var username = String(opts.username).trim();\n var config = {\n method : 'GET',\n url : opts.url + '/v1/user/recov/' + username,\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetricRecovery(opts.masterkey, username); \n\n request.get(signed.url)\n .end(function(err, resp) {\n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n if (!resp.body.encrypted_blobdecrypt_key) {\n fn(new Error('Missing encrypted blob decrypt key.')); \n } else {\n handleRecovery(resp); \n } \n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Could not recover blob'));\n }\n });\n \n function handleRecovery (resp) {\n\n var params = {\n url : opts.url,\n blob_id : resp.body.blob_id,\n key : decryptBlobCrypt(opts.masterkey, resp.body.encrypted_blobdecrypt_key)\n }\n \n var blob = new BlobObj(params);\n \n blob.revision = resp.body.revision;\n blob.encrypted_secret = resp.body.encrypted_secret;\n\n if (!blob.decrypt(resp.body.blob)) {\n return fn(new Error('Error while decrypting blob'));\n }\n\n //Apply patches\n if (resp.body.patches && resp.body.patches.length) {\n var successful = true;\n resp.body.patches.forEach(function(patch) {\n successful = successful && blob.applyEncryptedPatch(patch);\n });\n\n if (successful) {\n blob.consolidate();\n }\n }\n\n //return with newly decrypted blob\n fn(null, blob);\n };\n};\n\n/**\n * updateProfile\n * update information stored outside the blob - HMAC signed\n * @param {object}\n * @param {string} opts.url\n * @param {string} opts.username\n * @param {string} opts.auth_secret\n * @param {srring} opts.blob_id\n * @param {object} opts.profile\n * @param {string} opts.profile.phone - optional\n * @param {string} opts.profile.country - optional\n * @param {string} opts.profile.region - optional\n * @param {string} opts.profile.city - optional\n */\n\nBlobClient.updateProfile = function (opts, fn) {\n var config = {\n method: 'POST',\n url: opts.url + '/v1/user/' + opts.username + '/profile',\n dataType: 'json',\n data: opts.profile\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signHmac(opts.auth_secret, opts.blob_id); \n \n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error('updateProfile:', err);\n fn(new Error('Failed to update profile - XHR error'));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body) {\n log.error('updateProfile:', resp.body);\n } else {\n fn(new Error('Failed to update profile'));\n }\n });\n \n};\n\n/**\n * updateKeys\n * Change the blob encryption keys\n * @param {object} opts\n * @param {string} opts.username\n * @param {object} opts.keys\n * @param {object} opts.blob\n * @param {string} masterkey\n */\n\nBlobClient.updateKeys = function (opts, fn) {\n var old_id = opts.blob.id;\n opts.blob.id = opts.keys.id;\n opts.blob.key = opts.keys.crypt;\n opts.blob.encrypted_secret = opts.blob.encryptSecret(opts.keys.unlock, opts.masterkey);\n \n var config = {\n method : 'POST',\n url : opts.blob.url + '/v1/user/' + opts.username + '/updatekeys',\n data : {\n blob_id : opts.blob.id,\n data : opts.blob.encrypt(),\n revision : opts.blob.revision,\n encrypted_secret : opts.blob.encrypted_secret,\n encrypted_blobdecrypt_key : opts.blob.encryptBlobCrypt(opts.masterkey, opts.keys.crypt),\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(opts.masterkey, opts.blob.data.account_id, old_id); \n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error(\"updateKeys:\", err);\n fn(new Error('Failed to update blob - XHR error'));\n } else if (!resp.body || resp.body.result !== 'success') {\n log.error(\"updateKeys:\", resp.body ? resp.body.message : null);\n fn(new Error('Failed to update blob - bad result')); \n } else {\n fn(null, resp.body);\n }\n }); \n}; \n \n/**\n * rename\n * Change the username\n * @param {object} opts\n * @param {string} opts.username\n * @param {string} opts.new_username\n * @param {object} opts.keys\n * @param {object} opts.blob\n * @param {string} masterkey\n */\n\nBlobClient.rename = function (opts, fn) {\n var old_id = opts.blob.id;\n opts.blob.id = opts.keys.id;\n opts.blob.key = opts.keys.crypt;\n opts.blob.encryptedSecret = opts.blob.encryptSecret(opts.keys.unlock, opts.masterkey);\n\n var config = {\n method: 'POST',\n url: opts.blob.url + '/v1/user/' + opts.username + '/rename',\n data: {\n blob_id : opts.blob.id,\n username : opts.new_username,\n data : opts.blob.encrypt(),\n revision : opts.blob.revision,\n encrypted_secret : opts.blob.encryptedSecret,\n encrypted_blobdecrypt_key : opts.blob.encryptBlobCrypt(opts.masterkey, opts.keys.crypt)\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(opts.masterkey, opts.blob.data.account_id, old_id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n log.error(\"rename:\", err);\n fn(new Error(\"Failed to rename\"));\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n log.error(\"rename:\", resp.body.message);\n fn(new Error(\"Failed to rename\"));\n } else {\n fn(new Error(\"Failed to rename\"));\n }\n });\n};\n\n/**\n * Create a blob object\n *\n * @param {object} options\n * @param {string} options.url\n * @param {string} options.id\n * @param {string} options.crypt\n * @param {string} options.unlock\n * @param {string} options.username\n * @param {string} options.masterkey\n * @param {object} options.oldUserBlob\n * @param {function} fn\n */\n\nBlobClient.create = function(options, fn) {\n var params = {\n url : options.url,\n blob_id : options.id,\n key : options.crypt\n }\n var blob = new BlobObj(params);\n\n blob.revision = 0;\n\n blob.data = {\n auth_secret : crypt.createSecret(8),\n account_id : crypt.getAddress(options.masterkey),\n email : options.email,\n contacts : [],\n created : (new Date()).toJSON()\n };\n\n blob.encrypted_secret = blob.encryptSecret(options.unlock, options.masterkey);\n\n // Migration\n if (options.oldUserBlob) {\n blob.data.contacts = options.oldUserBlob.data.contacts;\n }\n\n //post to the blob vault to create\n var config = {\n method : 'POST',\n url : options.url + '/v1/user',\n data : {\n blob_id : options.id,\n username : options.username,\n address : blob.data.account_id,\n auth_secret : blob.data.auth_secret,\n data : blob.encrypt(),\n email : options.email,\n hostlink : options.activateLink,\n domain : options.domain,\n encrypted_blobdecrypt_key : blob.encryptBlobCrypt(options.masterkey, options.crypt),\n encrypted_secret : blob.encrypted_secret\n }\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(options.masterkey, blob.data.account_id, options.id);\n\n request.post(signed.url)\n .send(signed.data)\n .end(function(err, resp) {\n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, blob, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Could not create blob'));\n }\n });\n};\n\n/**\n * deleteBlob\n * @param {object} options\n * @param {string} options.url\n * @param {string} options.username\n * @param {string} options.blob_id\n * @param {string} options.account_id\n * @param {string} options.masterkey \n */\n\nBlobClient.deleteBlob = function(options, fn) {\n \n var config = {\n method : 'DELETE',\n url : options.url + '/v1/user/' + options.username,\n };\n\n var signedRequest = new SignedRequest(config);\n var signed = signedRequest.signAsymmetric(options.masterkey, options.account_id, options.blob_id);\n\n request.del(signed.url)\n .end(function(err, resp) {\n if (err) {\n fn(err);\n } else if (resp.body && resp.body.result === 'success') {\n fn(null, resp.body);\n } else if (resp.body && resp.body.result === 'error') {\n fn(new Error(resp.body.message)); \n } else {\n fn(new Error('Could not delete blob'));\n }\n }); \n};\n\nexports.BlobClient = BlobClient;\n\n\n// WEBPACK FOOTER\n// module.id = 32\n// module.readableIdentifier = ./src/js/ripple/blob.js\n//@ sourceURL=webpack-module:///./src/js/ripple/blob.js"); /***/ }, /* 33 */ @@ -286,13 +286,13 @@ var ripple = /* 40 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n\nvar base64 = __webpack_require__(65)\nvar ieee754 = __webpack_require__(60)\n\nexports.Buffer = Buffer\nexports.SlowBuffer = Buffer\nexports.INSPECT_MAX_BYTES = 50\nBuffer.poolSize = 8192\n\n/**\n * If `Buffer._useTypedArrays`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (compatible down to IE6)\n */\nBuffer._useTypedArrays = (function () {\n // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,\n // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding\n // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support\n // because we need to be able to add all the node Buffer API methods. This is an issue\n // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438\n try {\n var buf = new ArrayBuffer(0)\n var arr = new Uint8Array(buf)\n arr.foo = function () { return 42 }\n return 42 === arr.foo() &&\n typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`\n } catch (e) {\n return false\n }\n})()\n\n/**\n * Class: Buffer\n * =============\n *\n * The Buffer constructor returns instances of `Uint8Array` that are augmented\n * with function properties for all the node `Buffer` API functions. We use\n * `Uint8Array` so that square bracket notation works as expected -- it returns\n * a single octet.\n *\n * By augmenting the instances, we can avoid modifying the `Uint8Array`\n * prototype.\n */\nfunction Buffer (subject, encoding, noZero) {\n if (!(this instanceof Buffer))\n return new Buffer(subject, encoding, noZero)\n\n var type = typeof subject\n\n // Workaround: node's base64 implementation allows for non-padded strings\n // while base64-js does not.\n if (encoding === 'base64' && type === 'string') {\n subject = stringtrim(subject)\n while (subject.length % 4 !== 0) {\n subject = subject + '='\n }\n }\n\n // Find the length\n var length\n if (type === 'number')\n length = coerce(subject)\n else if (type === 'string')\n length = Buffer.byteLength(subject, encoding)\n else if (type === 'object')\n length = coerce(subject.length) // assume that object is array-like\n else\n throw new Error('First argument needs to be a number, array or string.')\n\n var buf\n if (Buffer._useTypedArrays) {\n // Preferred: Return an augmented `Uint8Array` instance for best performance\n buf = Buffer._augment(new Uint8Array(length))\n } else {\n // Fallback: Return THIS instance of Buffer (created by `new`)\n buf = this\n buf.length = length\n buf._isBuffer = true\n }\n\n var i\n if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {\n // Speed optimization -- use set if we're copying from a typed array\n buf._set(subject)\n } else if (isArrayish(subject)) {\n // Treat array-ish objects as a byte array\n for (i = 0; i < length; i++) {\n if (Buffer.isBuffer(subject))\n buf[i] = subject.readUInt8(i)\n else\n buf[i] = subject[i]\n }\n } else if (type === 'string') {\n buf.write(subject, 0, encoding)\n } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {\n for (i = 0; i < length; i++) {\n buf[i] = 0\n }\n }\n\n return buf\n}\n\n// STATIC METHODS\n// ==============\n\nBuffer.isEncoding = function (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'binary':\n case 'base64':\n case 'raw':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.isBuffer = function (b) {\n return !!(b !== null && b !== undefined && b._isBuffer)\n}\n\nBuffer.byteLength = function (str, encoding) {\n var ret\n str = str + ''\n switch (encoding || 'utf8') {\n case 'hex':\n ret = str.length / 2\n break\n case 'utf8':\n case 'utf-8':\n ret = utf8ToBytes(str).length\n break\n case 'ascii':\n case 'binary':\n case 'raw':\n ret = str.length\n break\n case 'base64':\n ret = base64ToBytes(str).length\n break\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n ret = str.length * 2\n break\n default:\n throw new Error('Unknown encoding')\n }\n return ret\n}\n\nBuffer.concat = function (list, totalLength) {\n assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\\n' +\n 'list should be an Array.')\n\n if (list.length === 0) {\n return new Buffer(0)\n } else if (list.length === 1) {\n return list[0]\n }\n\n var i\n if (typeof totalLength !== 'number') {\n totalLength = 0\n for (i = 0; i < list.length; i++) {\n totalLength += list[i].length\n }\n }\n\n var buf = new Buffer(totalLength)\n var pos = 0\n for (i = 0; i < list.length; i++) {\n var item = list[i]\n item.copy(buf, pos)\n pos += item.length\n }\n return buf\n}\n\n// BUFFER INSTANCE METHODS\n// =======================\n\nfunction _hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n assert(strLen % 2 === 0, 'Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; i++) {\n var byte = parseInt(string.substr(i * 2, 2), 16)\n assert(!isNaN(byte), 'Invalid hex string')\n buf[offset + i] = byte\n }\n Buffer._charsWritten = i * 2\n return i\n}\n\nfunction _utf8Write (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(utf8ToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nfunction _asciiWrite (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(asciiToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nfunction _binaryWrite (buf, string, offset, length) {\n return _asciiWrite(buf, string, offset, length)\n}\n\nfunction _base64Write (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(base64ToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nfunction _utf16leWrite (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(utf16leToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nBuffer.prototype.write = function (string, offset, length, encoding) {\n // Support both (string, offset, length, encoding)\n // and the legacy (string, encoding, offset, length)\n if (isFinite(offset)) {\n if (!isFinite(length)) {\n encoding = length\n length = undefined\n }\n } else { // legacy\n var swap = encoding\n encoding = offset\n offset = length\n length = swap\n }\n\n offset = Number(offset) || 0\n var remaining = this.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n encoding = String(encoding || 'utf8').toLowerCase()\n\n var ret\n switch (encoding) {\n case 'hex':\n ret = _hexWrite(this, string, offset, length)\n break\n case 'utf8':\n case 'utf-8':\n ret = _utf8Write(this, string, offset, length)\n break\n case 'ascii':\n ret = _asciiWrite(this, string, offset, length)\n break\n case 'binary':\n ret = _binaryWrite(this, string, offset, length)\n break\n case 'base64':\n ret = _base64Write(this, string, offset, length)\n break\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n ret = _utf16leWrite(this, string, offset, length)\n break\n default:\n throw new Error('Unknown encoding')\n }\n return ret\n}\n\nBuffer.prototype.toString = function (encoding, start, end) {\n var self = this\n\n encoding = String(encoding || 'utf8').toLowerCase()\n start = Number(start) || 0\n end = (end !== undefined)\n ? Number(end)\n : end = self.length\n\n // Fastpath empty strings\n if (end === start)\n return ''\n\n var ret\n switch (encoding) {\n case 'hex':\n ret = _hexSlice(self, start, end)\n break\n case 'utf8':\n case 'utf-8':\n ret = _utf8Slice(self, start, end)\n break\n case 'ascii':\n ret = _asciiSlice(self, start, end)\n break\n case 'binary':\n ret = _binarySlice(self, start, end)\n break\n case 'base64':\n ret = _base64Slice(self, start, end)\n break\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n ret = _utf16leSlice(self, start, end)\n break\n default:\n throw new Error('Unknown encoding')\n }\n return ret\n}\n\nBuffer.prototype.toJSON = function () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function (target, target_start, start, end) {\n var source = this\n\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (!target_start) target_start = 0\n\n // Copy 0 bytes; we're done\n if (end === start) return\n if (target.length === 0 || source.length === 0) return\n\n // Fatal error conditions\n assert(end >= start, 'sourceEnd < sourceStart')\n assert(target_start >= 0 && target_start < target.length,\n 'targetStart out of bounds')\n assert(start >= 0 && start < source.length, 'sourceStart out of bounds')\n assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length)\n end = this.length\n if (target.length - target_start < end - start)\n end = target.length - target_start + start\n\n var len = end - start\n\n if (len < 100 || !Buffer._useTypedArrays) {\n for (var i = 0; i < len; i++)\n target[i + target_start] = this[i + start]\n } else {\n target._set(this.subarray(start, start + len), target_start)\n }\n}\n\nfunction _base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction _utf8Slice (buf, start, end) {\n var res = ''\n var tmp = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; i++) {\n if (buf[i] <= 0x7F) {\n res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])\n tmp = ''\n } else {\n tmp += '%' + buf[i].toString(16)\n }\n }\n\n return res + decodeUtf8Char(tmp)\n}\n\nfunction _asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; i++)\n ret += String.fromCharCode(buf[i])\n return ret\n}\n\nfunction _binarySlice (buf, start, end) {\n return _asciiSlice(buf, start, end)\n}\n\nfunction _hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; i++) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction _utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i+1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function (start, end) {\n var len = this.length\n start = clamp(start, len, 0)\n end = clamp(end, len, len)\n\n if (Buffer._useTypedArrays) {\n return Buffer._augment(this.subarray(start, end))\n } else {\n var sliceLen = end - start\n var newBuf = new Buffer(sliceLen, undefined, true)\n for (var i = 0; i < sliceLen; i++) {\n newBuf[i] = this[i + start]\n }\n return newBuf\n }\n}\n\n// `get` will be removed in Node 0.13+\nBuffer.prototype.get = function (offset) {\n console.log('.get() is deprecated. Access using array indexes instead.')\n return this.readUInt8(offset)\n}\n\n// `set` will be removed in Node 0.13+\nBuffer.prototype.set = function (v, offset) {\n console.log('.set() is deprecated. Access using array indexes instead.')\n return this.writeUInt8(v, offset)\n}\n\nBuffer.prototype.readUInt8 = function (offset, noAssert) {\n if (!noAssert) {\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset < this.length, 'Trying to read beyond buffer length')\n }\n\n if (offset >= this.length)\n return\n\n return this[offset]\n}\n\nfunction _readUInt16 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val\n if (littleEndian) {\n val = buf[offset]\n if (offset + 1 < len)\n val |= buf[offset + 1] << 8\n } else {\n val = buf[offset] << 8\n if (offset + 1 < len)\n val |= buf[offset + 1]\n }\n return val\n}\n\nBuffer.prototype.readUInt16LE = function (offset, noAssert) {\n return _readUInt16(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readUInt16BE = function (offset, noAssert) {\n return _readUInt16(this, offset, false, noAssert)\n}\n\nfunction _readUInt32 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val\n if (littleEndian) {\n if (offset + 2 < len)\n val = buf[offset + 2] << 16\n if (offset + 1 < len)\n val |= buf[offset + 1] << 8\n val |= buf[offset]\n if (offset + 3 < len)\n val = val + (buf[offset + 3] << 24 >>> 0)\n } else {\n if (offset + 1 < len)\n val = buf[offset + 1] << 16\n if (offset + 2 < len)\n val |= buf[offset + 2] << 8\n if (offset + 3 < len)\n val |= buf[offset + 3]\n val = val + (buf[offset] << 24 >>> 0)\n }\n return val\n}\n\nBuffer.prototype.readUInt32LE = function (offset, noAssert) {\n return _readUInt32(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readUInt32BE = function (offset, noAssert) {\n return _readUInt32(this, offset, false, noAssert)\n}\n\nBuffer.prototype.readInt8 = function (offset, noAssert) {\n if (!noAssert) {\n assert(offset !== undefined && offset !== null,\n 'missing offset')\n assert(offset < this.length, 'Trying to read beyond buffer length')\n }\n\n if (offset >= this.length)\n return\n\n var neg = this[offset] & 0x80\n if (neg)\n return (0xff - this[offset] + 1) * -1\n else\n return this[offset]\n}\n\nfunction _readInt16 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val = _readUInt16(buf, offset, littleEndian, true)\n var neg = val & 0x8000\n if (neg)\n return (0xffff - val + 1) * -1\n else\n return val\n}\n\nBuffer.prototype.readInt16LE = function (offset, noAssert) {\n return _readInt16(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readInt16BE = function (offset, noAssert) {\n return _readInt16(this, offset, false, noAssert)\n}\n\nfunction _readInt32 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val = _readUInt32(buf, offset, littleEndian, true)\n var neg = val & 0x80000000\n if (neg)\n return (0xffffffff - val + 1) * -1\n else\n return val\n}\n\nBuffer.prototype.readInt32LE = function (offset, noAssert) {\n return _readInt32(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readInt32BE = function (offset, noAssert) {\n return _readInt32(this, offset, false, noAssert)\n}\n\nfunction _readFloat (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n }\n\n return ieee754.read(buf, offset, littleEndian, 23, 4)\n}\n\nBuffer.prototype.readFloatLE = function (offset, noAssert) {\n return _readFloat(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readFloatBE = function (offset, noAssert) {\n return _readFloat(this, offset, false, noAssert)\n}\n\nfunction _readDouble (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')\n }\n\n return ieee754.read(buf, offset, littleEndian, 52, 8)\n}\n\nBuffer.prototype.readDoubleLE = function (offset, noAssert) {\n return _readDouble(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readDoubleBE = function (offset, noAssert) {\n return _readDouble(this, offset, false, noAssert)\n}\n\nBuffer.prototype.writeUInt8 = function (value, offset, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset < this.length, 'trying to write beyond buffer length')\n verifuint(value, 0xff)\n }\n\n if (offset >= this.length) return\n\n this[offset] = value\n}\n\nfunction _writeUInt16 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'trying to write beyond buffer length')\n verifuint(value, 0xffff)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {\n buf[offset + i] =\n (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function (value, offset, noAssert) {\n _writeUInt16(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeUInt16BE = function (value, offset, noAssert) {\n _writeUInt16(this, value, offset, false, noAssert)\n}\n\nfunction _writeUInt32 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'trying to write beyond buffer length')\n verifuint(value, 0xffffffff)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {\n buf[offset + i] =\n (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function (value, offset, noAssert) {\n _writeUInt32(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeUInt32BE = function (value, offset, noAssert) {\n _writeUInt32(this, value, offset, false, noAssert)\n}\n\nBuffer.prototype.writeInt8 = function (value, offset, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset < this.length, 'Trying to write beyond buffer length')\n verifsint(value, 0x7f, -0x80)\n }\n\n if (offset >= this.length)\n return\n\n if (value >= 0)\n this.writeUInt8(value, offset, noAssert)\n else\n this.writeUInt8(0xff + value + 1, offset, noAssert)\n}\n\nfunction _writeInt16 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')\n verifsint(value, 0x7fff, -0x8000)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n if (value >= 0)\n _writeUInt16(buf, value, offset, littleEndian, noAssert)\n else\n _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)\n}\n\nBuffer.prototype.writeInt16LE = function (value, offset, noAssert) {\n _writeInt16(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeInt16BE = function (value, offset, noAssert) {\n _writeInt16(this, value, offset, false, noAssert)\n}\n\nfunction _writeInt32 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')\n verifsint(value, 0x7fffffff, -0x80000000)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n if (value >= 0)\n _writeUInt32(buf, value, offset, littleEndian, noAssert)\n else\n _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)\n}\n\nBuffer.prototype.writeInt32LE = function (value, offset, noAssert) {\n _writeInt32(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeInt32BE = function (value, offset, noAssert) {\n _writeInt32(this, value, offset, false, noAssert)\n}\n\nfunction _writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')\n verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n}\n\nBuffer.prototype.writeFloatLE = function (value, offset, noAssert) {\n _writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function (value, offset, noAssert) {\n _writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction _writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 7 < buf.length,\n 'Trying to write beyond buffer length')\n verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n}\n\nBuffer.prototype.writeDoubleLE = function (value, offset, noAssert) {\n _writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function (value, offset, noAssert) {\n _writeDouble(this, value, offset, false, noAssert)\n}\n\n// fill(value, start=0, end=buffer.length)\nBuffer.prototype.fill = function (value, start, end) {\n if (!value) value = 0\n if (!start) start = 0\n if (!end) end = this.length\n\n if (typeof value === 'string') {\n value = value.charCodeAt(0)\n }\n\n assert(typeof value === 'number' && !isNaN(value), 'value is not a number')\n assert(end >= start, 'end < start')\n\n // Fill 0 bytes; we're done\n if (end === start) return\n if (this.length === 0) return\n\n assert(start >= 0 && start < this.length, 'start out of bounds')\n assert(end >= 0 && end <= this.length, 'end out of bounds')\n\n for (var i = start; i < end; i++) {\n this[i] = value\n }\n}\n\nBuffer.prototype.inspect = function () {\n var out = []\n var len = this.length\n for (var i = 0; i < len; i++) {\n out[i] = toHex(this[i])\n if (i === exports.INSPECT_MAX_BYTES) {\n out[i + 1] = '...'\n break\n }\n }\n return ''\n}\n\n/**\n * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\n * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\n */\nBuffer.prototype.toArrayBuffer = function () {\n if (typeof Uint8Array !== 'undefined') {\n if (Buffer._useTypedArrays) {\n return (new Buffer(this)).buffer\n } else {\n var buf = new Uint8Array(this.length)\n for (var i = 0, len = buf.length; i < len; i += 1)\n buf[i] = this[i]\n return buf.buffer\n }\n } else {\n throw new Error('Buffer.toArrayBuffer not supported in this browser')\n }\n}\n\n// HELPER FUNCTIONS\n// ================\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nvar BP = Buffer.prototype\n\n/**\n * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\n */\nBuffer._augment = function (arr) {\n arr._isBuffer = true\n\n // save reference to original Uint8Array get/set methods before overwriting\n arr._get = arr.get\n arr._set = arr.set\n\n // deprecated, will be removed in node 0.13+\n arr.get = BP.get\n arr.set = BP.set\n\n arr.write = BP.write\n arr.toString = BP.toString\n arr.toLocaleString = BP.toString\n arr.toJSON = BP.toJSON\n arr.copy = BP.copy\n arr.slice = BP.slice\n arr.readUInt8 = BP.readUInt8\n arr.readUInt16LE = BP.readUInt16LE\n arr.readUInt16BE = BP.readUInt16BE\n arr.readUInt32LE = BP.readUInt32LE\n arr.readUInt32BE = BP.readUInt32BE\n arr.readInt8 = BP.readInt8\n arr.readInt16LE = BP.readInt16LE\n arr.readInt16BE = BP.readInt16BE\n arr.readInt32LE = BP.readInt32LE\n arr.readInt32BE = BP.readInt32BE\n arr.readFloatLE = BP.readFloatLE\n arr.readFloatBE = BP.readFloatBE\n arr.readDoubleLE = BP.readDoubleLE\n arr.readDoubleBE = BP.readDoubleBE\n arr.writeUInt8 = BP.writeUInt8\n arr.writeUInt16LE = BP.writeUInt16LE\n arr.writeUInt16BE = BP.writeUInt16BE\n arr.writeUInt32LE = BP.writeUInt32LE\n arr.writeUInt32BE = BP.writeUInt32BE\n arr.writeInt8 = BP.writeInt8\n arr.writeInt16LE = BP.writeInt16LE\n arr.writeInt16BE = BP.writeInt16BE\n arr.writeInt32LE = BP.writeInt32LE\n arr.writeInt32BE = BP.writeInt32BE\n arr.writeFloatLE = BP.writeFloatLE\n arr.writeFloatBE = BP.writeFloatBE\n arr.writeDoubleLE = BP.writeDoubleLE\n arr.writeDoubleBE = BP.writeDoubleBE\n arr.fill = BP.fill\n arr.inspect = BP.inspect\n arr.toArrayBuffer = BP.toArrayBuffer\n\n return arr\n}\n\n// slice(start, end)\nfunction clamp (index, len, defaultValue) {\n if (typeof index !== 'number') return defaultValue\n index = ~~index; // Coerce to integer.\n if (index >= len) return len\n if (index >= 0) return index\n index += len\n if (index >= 0) return index\n return 0\n}\n\nfunction coerce (length) {\n // Coerce length to a number (possibly NaN), round up\n // in case it's fractional (e.g. 123.456) then do a\n // double negate to coerce a NaN to 0. Easy, right?\n length = ~~Math.ceil(+length)\n return length < 0 ? 0 : length\n}\n\nfunction isArray (subject) {\n return (Array.isArray || function (subject) {\n return Object.prototype.toString.call(subject) === '[object Array]'\n })(subject)\n}\n\nfunction isArrayish (subject) {\n return isArray(subject) || Buffer.isBuffer(subject) ||\n subject && typeof subject === 'object' &&\n typeof subject.length === 'number'\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; i++) {\n var b = str.charCodeAt(i)\n if (b <= 0x7F)\n byteArray.push(str.charCodeAt(i))\n else {\n var start = i\n if (b >= 0xD800 && b <= 0xDFFF) i++\n var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')\n for (var j = 0; j < h.length; j++)\n byteArray.push(parseInt(h[j], 16))\n }\n }\n return byteArray\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; i++) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; i++) {\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(str)\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n var pos\n for (var i = 0; i < length; i++) {\n if ((i + offset >= dst.length) || (i >= src.length))\n break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction decodeUtf8Char (str) {\n try {\n return decodeURIComponent(str)\n } catch (err) {\n return String.fromCharCode(0xFFFD) // UTF 8 invalid char\n }\n}\n\n/*\n * We have to make sure that the value is a valid integer. This means that it\n * is non-negative. It has no fractional component and that it does not\n * exceed the maximum allowed value.\n */\nfunction verifuint (value, max) {\n assert(typeof value === 'number', 'cannot write a non-number as a number')\n assert(value >= 0, 'specified a negative value for writing an unsigned value')\n assert(value <= max, 'value is larger than maximum value for type')\n assert(Math.floor(value) === value, 'value has a fractional component')\n}\n\nfunction verifsint (value, max, min) {\n assert(typeof value === 'number', 'cannot write a non-number as a number')\n assert(value <= max, 'value larger than maximum allowed value')\n assert(value >= min, 'value smaller than minimum allowed value')\n assert(Math.floor(value) === value, 'value has a fractional component')\n}\n\nfunction verifIEEE754 (value, max, min) {\n assert(typeof value === 'number', 'cannot write a non-number as a number')\n assert(value <= max, 'value larger than maximum allowed value')\n assert(value >= min, 'value smaller than minimum allowed value')\n}\n\nfunction assert (test, message) {\n if (!test) throw new Error(message || 'Failed assertion')\n}\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 40\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/buffer/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/buffer/index.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n\nvar base64 = __webpack_require__(65)\nvar ieee754 = __webpack_require__(57)\n\nexports.Buffer = Buffer\nexports.SlowBuffer = Buffer\nexports.INSPECT_MAX_BYTES = 50\nBuffer.poolSize = 8192\n\n/**\n * If `Buffer._useTypedArrays`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (compatible down to IE6)\n */\nBuffer._useTypedArrays = (function () {\n // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,\n // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding\n // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support\n // because we need to be able to add all the node Buffer API methods. This is an issue\n // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438\n try {\n var buf = new ArrayBuffer(0)\n var arr = new Uint8Array(buf)\n arr.foo = function () { return 42 }\n return 42 === arr.foo() &&\n typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`\n } catch (e) {\n return false\n }\n})()\n\n/**\n * Class: Buffer\n * =============\n *\n * The Buffer constructor returns instances of `Uint8Array` that are augmented\n * with function properties for all the node `Buffer` API functions. We use\n * `Uint8Array` so that square bracket notation works as expected -- it returns\n * a single octet.\n *\n * By augmenting the instances, we can avoid modifying the `Uint8Array`\n * prototype.\n */\nfunction Buffer (subject, encoding, noZero) {\n if (!(this instanceof Buffer))\n return new Buffer(subject, encoding, noZero)\n\n var type = typeof subject\n\n // Workaround: node's base64 implementation allows for non-padded strings\n // while base64-js does not.\n if (encoding === 'base64' && type === 'string') {\n subject = stringtrim(subject)\n while (subject.length % 4 !== 0) {\n subject = subject + '='\n }\n }\n\n // Find the length\n var length\n if (type === 'number')\n length = coerce(subject)\n else if (type === 'string')\n length = Buffer.byteLength(subject, encoding)\n else if (type === 'object')\n length = coerce(subject.length) // assume that object is array-like\n else\n throw new Error('First argument needs to be a number, array or string.')\n\n var buf\n if (Buffer._useTypedArrays) {\n // Preferred: Return an augmented `Uint8Array` instance for best performance\n buf = Buffer._augment(new Uint8Array(length))\n } else {\n // Fallback: Return THIS instance of Buffer (created by `new`)\n buf = this\n buf.length = length\n buf._isBuffer = true\n }\n\n var i\n if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {\n // Speed optimization -- use set if we're copying from a typed array\n buf._set(subject)\n } else if (isArrayish(subject)) {\n // Treat array-ish objects as a byte array\n for (i = 0; i < length; i++) {\n if (Buffer.isBuffer(subject))\n buf[i] = subject.readUInt8(i)\n else\n buf[i] = subject[i]\n }\n } else if (type === 'string') {\n buf.write(subject, 0, encoding)\n } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {\n for (i = 0; i < length; i++) {\n buf[i] = 0\n }\n }\n\n return buf\n}\n\n// STATIC METHODS\n// ==============\n\nBuffer.isEncoding = function (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'binary':\n case 'base64':\n case 'raw':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.isBuffer = function (b) {\n return !!(b !== null && b !== undefined && b._isBuffer)\n}\n\nBuffer.byteLength = function (str, encoding) {\n var ret\n str = str + ''\n switch (encoding || 'utf8') {\n case 'hex':\n ret = str.length / 2\n break\n case 'utf8':\n case 'utf-8':\n ret = utf8ToBytes(str).length\n break\n case 'ascii':\n case 'binary':\n case 'raw':\n ret = str.length\n break\n case 'base64':\n ret = base64ToBytes(str).length\n break\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n ret = str.length * 2\n break\n default:\n throw new Error('Unknown encoding')\n }\n return ret\n}\n\nBuffer.concat = function (list, totalLength) {\n assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\\n' +\n 'list should be an Array.')\n\n if (list.length === 0) {\n return new Buffer(0)\n } else if (list.length === 1) {\n return list[0]\n }\n\n var i\n if (typeof totalLength !== 'number') {\n totalLength = 0\n for (i = 0; i < list.length; i++) {\n totalLength += list[i].length\n }\n }\n\n var buf = new Buffer(totalLength)\n var pos = 0\n for (i = 0; i < list.length; i++) {\n var item = list[i]\n item.copy(buf, pos)\n pos += item.length\n }\n return buf\n}\n\n// BUFFER INSTANCE METHODS\n// =======================\n\nfunction _hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n assert(strLen % 2 === 0, 'Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; i++) {\n var byte = parseInt(string.substr(i * 2, 2), 16)\n assert(!isNaN(byte), 'Invalid hex string')\n buf[offset + i] = byte\n }\n Buffer._charsWritten = i * 2\n return i\n}\n\nfunction _utf8Write (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(utf8ToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nfunction _asciiWrite (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(asciiToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nfunction _binaryWrite (buf, string, offset, length) {\n return _asciiWrite(buf, string, offset, length)\n}\n\nfunction _base64Write (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(base64ToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nfunction _utf16leWrite (buf, string, offset, length) {\n var charsWritten = Buffer._charsWritten =\n blitBuffer(utf16leToBytes(string), buf, offset, length)\n return charsWritten\n}\n\nBuffer.prototype.write = function (string, offset, length, encoding) {\n // Support both (string, offset, length, encoding)\n // and the legacy (string, encoding, offset, length)\n if (isFinite(offset)) {\n if (!isFinite(length)) {\n encoding = length\n length = undefined\n }\n } else { // legacy\n var swap = encoding\n encoding = offset\n offset = length\n length = swap\n }\n\n offset = Number(offset) || 0\n var remaining = this.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n encoding = String(encoding || 'utf8').toLowerCase()\n\n var ret\n switch (encoding) {\n case 'hex':\n ret = _hexWrite(this, string, offset, length)\n break\n case 'utf8':\n case 'utf-8':\n ret = _utf8Write(this, string, offset, length)\n break\n case 'ascii':\n ret = _asciiWrite(this, string, offset, length)\n break\n case 'binary':\n ret = _binaryWrite(this, string, offset, length)\n break\n case 'base64':\n ret = _base64Write(this, string, offset, length)\n break\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n ret = _utf16leWrite(this, string, offset, length)\n break\n default:\n throw new Error('Unknown encoding')\n }\n return ret\n}\n\nBuffer.prototype.toString = function (encoding, start, end) {\n var self = this\n\n encoding = String(encoding || 'utf8').toLowerCase()\n start = Number(start) || 0\n end = (end !== undefined)\n ? Number(end)\n : end = self.length\n\n // Fastpath empty strings\n if (end === start)\n return ''\n\n var ret\n switch (encoding) {\n case 'hex':\n ret = _hexSlice(self, start, end)\n break\n case 'utf8':\n case 'utf-8':\n ret = _utf8Slice(self, start, end)\n break\n case 'ascii':\n ret = _asciiSlice(self, start, end)\n break\n case 'binary':\n ret = _binarySlice(self, start, end)\n break\n case 'base64':\n ret = _base64Slice(self, start, end)\n break\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n ret = _utf16leSlice(self, start, end)\n break\n default:\n throw new Error('Unknown encoding')\n }\n return ret\n}\n\nBuffer.prototype.toJSON = function () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function (target, target_start, start, end) {\n var source = this\n\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (!target_start) target_start = 0\n\n // Copy 0 bytes; we're done\n if (end === start) return\n if (target.length === 0 || source.length === 0) return\n\n // Fatal error conditions\n assert(end >= start, 'sourceEnd < sourceStart')\n assert(target_start >= 0 && target_start < target.length,\n 'targetStart out of bounds')\n assert(start >= 0 && start < source.length, 'sourceStart out of bounds')\n assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length)\n end = this.length\n if (target.length - target_start < end - start)\n end = target.length - target_start + start\n\n var len = end - start\n\n if (len < 100 || !Buffer._useTypedArrays) {\n for (var i = 0; i < len; i++)\n target[i + target_start] = this[i + start]\n } else {\n target._set(this.subarray(start, start + len), target_start)\n }\n}\n\nfunction _base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction _utf8Slice (buf, start, end) {\n var res = ''\n var tmp = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; i++) {\n if (buf[i] <= 0x7F) {\n res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])\n tmp = ''\n } else {\n tmp += '%' + buf[i].toString(16)\n }\n }\n\n return res + decodeUtf8Char(tmp)\n}\n\nfunction _asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; i++)\n ret += String.fromCharCode(buf[i])\n return ret\n}\n\nfunction _binarySlice (buf, start, end) {\n return _asciiSlice(buf, start, end)\n}\n\nfunction _hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; i++) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction _utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i+1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function (start, end) {\n var len = this.length\n start = clamp(start, len, 0)\n end = clamp(end, len, len)\n\n if (Buffer._useTypedArrays) {\n return Buffer._augment(this.subarray(start, end))\n } else {\n var sliceLen = end - start\n var newBuf = new Buffer(sliceLen, undefined, true)\n for (var i = 0; i < sliceLen; i++) {\n newBuf[i] = this[i + start]\n }\n return newBuf\n }\n}\n\n// `get` will be removed in Node 0.13+\nBuffer.prototype.get = function (offset) {\n console.log('.get() is deprecated. Access using array indexes instead.')\n return this.readUInt8(offset)\n}\n\n// `set` will be removed in Node 0.13+\nBuffer.prototype.set = function (v, offset) {\n console.log('.set() is deprecated. Access using array indexes instead.')\n return this.writeUInt8(v, offset)\n}\n\nBuffer.prototype.readUInt8 = function (offset, noAssert) {\n if (!noAssert) {\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset < this.length, 'Trying to read beyond buffer length')\n }\n\n if (offset >= this.length)\n return\n\n return this[offset]\n}\n\nfunction _readUInt16 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val\n if (littleEndian) {\n val = buf[offset]\n if (offset + 1 < len)\n val |= buf[offset + 1] << 8\n } else {\n val = buf[offset] << 8\n if (offset + 1 < len)\n val |= buf[offset + 1]\n }\n return val\n}\n\nBuffer.prototype.readUInt16LE = function (offset, noAssert) {\n return _readUInt16(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readUInt16BE = function (offset, noAssert) {\n return _readUInt16(this, offset, false, noAssert)\n}\n\nfunction _readUInt32 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val\n if (littleEndian) {\n if (offset + 2 < len)\n val = buf[offset + 2] << 16\n if (offset + 1 < len)\n val |= buf[offset + 1] << 8\n val |= buf[offset]\n if (offset + 3 < len)\n val = val + (buf[offset + 3] << 24 >>> 0)\n } else {\n if (offset + 1 < len)\n val = buf[offset + 1] << 16\n if (offset + 2 < len)\n val |= buf[offset + 2] << 8\n if (offset + 3 < len)\n val |= buf[offset + 3]\n val = val + (buf[offset] << 24 >>> 0)\n }\n return val\n}\n\nBuffer.prototype.readUInt32LE = function (offset, noAssert) {\n return _readUInt32(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readUInt32BE = function (offset, noAssert) {\n return _readUInt32(this, offset, false, noAssert)\n}\n\nBuffer.prototype.readInt8 = function (offset, noAssert) {\n if (!noAssert) {\n assert(offset !== undefined && offset !== null,\n 'missing offset')\n assert(offset < this.length, 'Trying to read beyond buffer length')\n }\n\n if (offset >= this.length)\n return\n\n var neg = this[offset] & 0x80\n if (neg)\n return (0xff - this[offset] + 1) * -1\n else\n return this[offset]\n}\n\nfunction _readInt16 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val = _readUInt16(buf, offset, littleEndian, true)\n var neg = val & 0x8000\n if (neg)\n return (0xffff - val + 1) * -1\n else\n return val\n}\n\nBuffer.prototype.readInt16LE = function (offset, noAssert) {\n return _readInt16(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readInt16BE = function (offset, noAssert) {\n return _readInt16(this, offset, false, noAssert)\n}\n\nfunction _readInt32 (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n var val = _readUInt32(buf, offset, littleEndian, true)\n var neg = val & 0x80000000\n if (neg)\n return (0xffffffff - val + 1) * -1\n else\n return val\n}\n\nBuffer.prototype.readInt32LE = function (offset, noAssert) {\n return _readInt32(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readInt32BE = function (offset, noAssert) {\n return _readInt32(this, offset, false, noAssert)\n}\n\nfunction _readFloat (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n }\n\n return ieee754.read(buf, offset, littleEndian, 23, 4)\n}\n\nBuffer.prototype.readFloatLE = function (offset, noAssert) {\n return _readFloat(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readFloatBE = function (offset, noAssert) {\n return _readFloat(this, offset, false, noAssert)\n}\n\nfunction _readDouble (buf, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')\n }\n\n return ieee754.read(buf, offset, littleEndian, 52, 8)\n}\n\nBuffer.prototype.readDoubleLE = function (offset, noAssert) {\n return _readDouble(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readDoubleBE = function (offset, noAssert) {\n return _readDouble(this, offset, false, noAssert)\n}\n\nBuffer.prototype.writeUInt8 = function (value, offset, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset < this.length, 'trying to write beyond buffer length')\n verifuint(value, 0xff)\n }\n\n if (offset >= this.length) return\n\n this[offset] = value\n}\n\nfunction _writeUInt16 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'trying to write beyond buffer length')\n verifuint(value, 0xffff)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {\n buf[offset + i] =\n (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function (value, offset, noAssert) {\n _writeUInt16(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeUInt16BE = function (value, offset, noAssert) {\n _writeUInt16(this, value, offset, false, noAssert)\n}\n\nfunction _writeUInt32 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'trying to write beyond buffer length')\n verifuint(value, 0xffffffff)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {\n buf[offset + i] =\n (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function (value, offset, noAssert) {\n _writeUInt32(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeUInt32BE = function (value, offset, noAssert) {\n _writeUInt32(this, value, offset, false, noAssert)\n}\n\nBuffer.prototype.writeInt8 = function (value, offset, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset < this.length, 'Trying to write beyond buffer length')\n verifsint(value, 0x7f, -0x80)\n }\n\n if (offset >= this.length)\n return\n\n if (value >= 0)\n this.writeUInt8(value, offset, noAssert)\n else\n this.writeUInt8(0xff + value + 1, offset, noAssert)\n}\n\nfunction _writeInt16 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')\n verifsint(value, 0x7fff, -0x8000)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n if (value >= 0)\n _writeUInt16(buf, value, offset, littleEndian, noAssert)\n else\n _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)\n}\n\nBuffer.prototype.writeInt16LE = function (value, offset, noAssert) {\n _writeInt16(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeInt16BE = function (value, offset, noAssert) {\n _writeInt16(this, value, offset, false, noAssert)\n}\n\nfunction _writeInt32 (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')\n verifsint(value, 0x7fffffff, -0x80000000)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n if (value >= 0)\n _writeUInt32(buf, value, offset, littleEndian, noAssert)\n else\n _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)\n}\n\nBuffer.prototype.writeInt32LE = function (value, offset, noAssert) {\n _writeInt32(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeInt32BE = function (value, offset, noAssert) {\n _writeInt32(this, value, offset, false, noAssert)\n}\n\nfunction _writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')\n verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n}\n\nBuffer.prototype.writeFloatLE = function (value, offset, noAssert) {\n _writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function (value, offset, noAssert) {\n _writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction _writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n assert(value !== undefined && value !== null, 'missing value')\n assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n assert(offset !== undefined && offset !== null, 'missing offset')\n assert(offset + 7 < buf.length,\n 'Trying to write beyond buffer length')\n verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n\n var len = buf.length\n if (offset >= len)\n return\n\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n}\n\nBuffer.prototype.writeDoubleLE = function (value, offset, noAssert) {\n _writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function (value, offset, noAssert) {\n _writeDouble(this, value, offset, false, noAssert)\n}\n\n// fill(value, start=0, end=buffer.length)\nBuffer.prototype.fill = function (value, start, end) {\n if (!value) value = 0\n if (!start) start = 0\n if (!end) end = this.length\n\n if (typeof value === 'string') {\n value = value.charCodeAt(0)\n }\n\n assert(typeof value === 'number' && !isNaN(value), 'value is not a number')\n assert(end >= start, 'end < start')\n\n // Fill 0 bytes; we're done\n if (end === start) return\n if (this.length === 0) return\n\n assert(start >= 0 && start < this.length, 'start out of bounds')\n assert(end >= 0 && end <= this.length, 'end out of bounds')\n\n for (var i = start; i < end; i++) {\n this[i] = value\n }\n}\n\nBuffer.prototype.inspect = function () {\n var out = []\n var len = this.length\n for (var i = 0; i < len; i++) {\n out[i] = toHex(this[i])\n if (i === exports.INSPECT_MAX_BYTES) {\n out[i + 1] = '...'\n break\n }\n }\n return ''\n}\n\n/**\n * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\n * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\n */\nBuffer.prototype.toArrayBuffer = function () {\n if (typeof Uint8Array !== 'undefined') {\n if (Buffer._useTypedArrays) {\n return (new Buffer(this)).buffer\n } else {\n var buf = new Uint8Array(this.length)\n for (var i = 0, len = buf.length; i < len; i += 1)\n buf[i] = this[i]\n return buf.buffer\n }\n } else {\n throw new Error('Buffer.toArrayBuffer not supported in this browser')\n }\n}\n\n// HELPER FUNCTIONS\n// ================\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nvar BP = Buffer.prototype\n\n/**\n * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\n */\nBuffer._augment = function (arr) {\n arr._isBuffer = true\n\n // save reference to original Uint8Array get/set methods before overwriting\n arr._get = arr.get\n arr._set = arr.set\n\n // deprecated, will be removed in node 0.13+\n arr.get = BP.get\n arr.set = BP.set\n\n arr.write = BP.write\n arr.toString = BP.toString\n arr.toLocaleString = BP.toString\n arr.toJSON = BP.toJSON\n arr.copy = BP.copy\n arr.slice = BP.slice\n arr.readUInt8 = BP.readUInt8\n arr.readUInt16LE = BP.readUInt16LE\n arr.readUInt16BE = BP.readUInt16BE\n arr.readUInt32LE = BP.readUInt32LE\n arr.readUInt32BE = BP.readUInt32BE\n arr.readInt8 = BP.readInt8\n arr.readInt16LE = BP.readInt16LE\n arr.readInt16BE = BP.readInt16BE\n arr.readInt32LE = BP.readInt32LE\n arr.readInt32BE = BP.readInt32BE\n arr.readFloatLE = BP.readFloatLE\n arr.readFloatBE = BP.readFloatBE\n arr.readDoubleLE = BP.readDoubleLE\n arr.readDoubleBE = BP.readDoubleBE\n arr.writeUInt8 = BP.writeUInt8\n arr.writeUInt16LE = BP.writeUInt16LE\n arr.writeUInt16BE = BP.writeUInt16BE\n arr.writeUInt32LE = BP.writeUInt32LE\n arr.writeUInt32BE = BP.writeUInt32BE\n arr.writeInt8 = BP.writeInt8\n arr.writeInt16LE = BP.writeInt16LE\n arr.writeInt16BE = BP.writeInt16BE\n arr.writeInt32LE = BP.writeInt32LE\n arr.writeInt32BE = BP.writeInt32BE\n arr.writeFloatLE = BP.writeFloatLE\n arr.writeFloatBE = BP.writeFloatBE\n arr.writeDoubleLE = BP.writeDoubleLE\n arr.writeDoubleBE = BP.writeDoubleBE\n arr.fill = BP.fill\n arr.inspect = BP.inspect\n arr.toArrayBuffer = BP.toArrayBuffer\n\n return arr\n}\n\n// slice(start, end)\nfunction clamp (index, len, defaultValue) {\n if (typeof index !== 'number') return defaultValue\n index = ~~index; // Coerce to integer.\n if (index >= len) return len\n if (index >= 0) return index\n index += len\n if (index >= 0) return index\n return 0\n}\n\nfunction coerce (length) {\n // Coerce length to a number (possibly NaN), round up\n // in case it's fractional (e.g. 123.456) then do a\n // double negate to coerce a NaN to 0. Easy, right?\n length = ~~Math.ceil(+length)\n return length < 0 ? 0 : length\n}\n\nfunction isArray (subject) {\n return (Array.isArray || function (subject) {\n return Object.prototype.toString.call(subject) === '[object Array]'\n })(subject)\n}\n\nfunction isArrayish (subject) {\n return isArray(subject) || Buffer.isBuffer(subject) ||\n subject && typeof subject === 'object' &&\n typeof subject.length === 'number'\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; i++) {\n var b = str.charCodeAt(i)\n if (b <= 0x7F)\n byteArray.push(str.charCodeAt(i))\n else {\n var start = i\n if (b >= 0xD800 && b <= 0xDFFF) i++\n var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')\n for (var j = 0; j < h.length; j++)\n byteArray.push(parseInt(h[j], 16))\n }\n }\n return byteArray\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; i++) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; i++) {\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(str)\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n var pos\n for (var i = 0; i < length; i++) {\n if ((i + offset >= dst.length) || (i >= src.length))\n break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction decodeUtf8Char (str) {\n try {\n return decodeURIComponent(str)\n } catch (err) {\n return String.fromCharCode(0xFFFD) // UTF 8 invalid char\n }\n}\n\n/*\n * We have to make sure that the value is a valid integer. This means that it\n * is non-negative. It has no fractional component and that it does not\n * exceed the maximum allowed value.\n */\nfunction verifuint (value, max) {\n assert(typeof value === 'number', 'cannot write a non-number as a number')\n assert(value >= 0, 'specified a negative value for writing an unsigned value')\n assert(value <= max, 'value is larger than maximum value for type')\n assert(Math.floor(value) === value, 'value has a fractional component')\n}\n\nfunction verifsint (value, max, min) {\n assert(typeof value === 'number', 'cannot write a non-number as a number')\n assert(value <= max, 'value larger than maximum allowed value')\n assert(value >= min, 'value smaller than minimum allowed value')\n assert(Math.floor(value) === value, 'value has a fractional component')\n}\n\nfunction verifIEEE754 (value, max, min) {\n assert(typeof value === 'number', 'cannot write a non-number as a number')\n assert(value <= max, 'value larger than maximum allowed value')\n assert(value >= min, 'value smaller than minimum allowed value')\n}\n\nfunction assert (test, message) {\n if (!test) throw new Error(message || 'Failed assertion')\n}\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 40\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/buffer/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/buffer/index.js"); /***/ }, /* 41 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var rng = __webpack_require__(50)\n\nfunction error () {\n var m = [].slice.call(arguments).join(' ')\n throw new Error([\n m,\n 'we accept pull requests',\n 'http://github.com/dominictarr/crypto-browserify'\n ].join('\\n'))\n}\n\nexports.createHash = __webpack_require__(51)\n\nexports.createHmac = __webpack_require__(52)\n\nexports.randomBytes = function(size, callback) {\n if (callback && callback.call) {\n try {\n callback.call(this, undefined, new Buffer(rng(size)))\n } catch (err) { callback(err) }\n } else {\n return new Buffer(rng(size))\n }\n}\n\nfunction each(a, f) {\n for(var i in a)\n f(a[i], i)\n}\n\nexports.getHashes = function () {\n return ['sha1', 'sha256', 'md5', 'rmd160']\n\n}\n\nvar p = __webpack_require__(53)(exports.createHmac)\nexports.pbkdf2 = p.pbkdf2\nexports.pbkdf2Sync = p.pbkdf2Sync\n\n\n// the least I can do is make error messages for the rest of the node.js/crypto api.\neach(['createCredentials'\n, 'createCipher'\n, 'createCipheriv'\n, 'createDecipher'\n, 'createDecipheriv'\n, 'createSign'\n, 'createVerify'\n, 'createDiffieHellman'\n], function (name) {\n exports[name] = function () {\n error('sorry,', name, 'is not implemented yet')\n }\n})\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 41\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/index.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var rng = __webpack_require__(51)\n\nfunction error () {\n var m = [].slice.call(arguments).join(' ')\n throw new Error([\n m,\n 'we accept pull requests',\n 'http://github.com/dominictarr/crypto-browserify'\n ].join('\\n'))\n}\n\nexports.createHash = __webpack_require__(52)\n\nexports.createHmac = __webpack_require__(53)\n\nexports.randomBytes = function(size, callback) {\n if (callback && callback.call) {\n try {\n callback.call(this, undefined, new Buffer(rng(size)))\n } catch (err) { callback(err) }\n } else {\n return new Buffer(rng(size))\n }\n}\n\nfunction each(a, f) {\n for(var i in a)\n f(a[i], i)\n}\n\nexports.getHashes = function () {\n return ['sha1', 'sha256', 'md5', 'rmd160']\n\n}\n\nvar p = __webpack_require__(54)(exports.createHmac)\nexports.pbkdf2 = p.pbkdf2\nexports.pbkdf2Sync = p.pbkdf2Sync\n\n\n// the least I can do is make error messages for the rest of the node.js/crypto api.\neach(['createCredentials'\n, 'createCipher'\n, 'createCipheriv'\n, 'createDecipher'\n, 'createDecipheriv'\n, 'createSign'\n, 'createVerify'\n, 'createDiffieHellman'\n], function (name) {\n exports[name] = function () {\n error('sorry,', name, 'is not implemented yet')\n }\n})\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 41\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/index.js"); /***/ }, /* 42 */ @@ -316,13 +316,13 @@ var ripple = /* 45 */ /***/ function(module, exports, __webpack_require__) { - eval("var utils = __webpack_require__(19);\nvar extend = __webpack_require__(43);\nvar UInt = __webpack_require__(28).UInt;\n\n//\n// UInt128 support\n//\n\nvar UInt128 = extend(function () {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n}, UInt);\n\nUInt128.width = 16;\nUInt128.prototype = extend({}, UInt.prototype);\nUInt128.prototype.constructor = UInt128;\n\nvar HEX_ZERO = UInt128.HEX_ZERO = '00000000000000000000000000000000';\nvar HEX_ONE = UInt128.HEX_ONE = '00000000000000000000000000000000';\nvar STR_ZERO = UInt128.STR_ZERO = utils.hexToString(HEX_ZERO);\nvar STR_ONE = UInt128.STR_ONE = utils.hexToString(HEX_ONE);\n\nexports.UInt128 = UInt128;\n\n\n// WEBPACK FOOTER\n// module.id = 45\n// module.readableIdentifier = ./src/js/ripple/uint128.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint128.js"); + eval("var utils = __webpack_require__(19);\nvar extend = __webpack_require__(43);\nvar UInt = __webpack_require__(26).UInt;\n\n//\n// UInt128 support\n//\n\nvar UInt128 = extend(function () {\n // Internal form: NaN or BigInteger\n this._value = NaN;\n}, UInt);\n\nUInt128.width = 16;\nUInt128.prototype = extend({}, UInt.prototype);\nUInt128.prototype.constructor = UInt128;\n\nvar HEX_ZERO = UInt128.HEX_ZERO = '00000000000000000000000000000000';\nvar HEX_ONE = UInt128.HEX_ONE = '00000000000000000000000000000000';\nvar STR_ZERO = UInt128.STR_ZERO = utils.hexToString(HEX_ZERO);\nvar STR_ONE = UInt128.STR_ONE = utils.hexToString(HEX_ONE);\n\nexports.UInt128 = UInt128;\n\n\n// WEBPACK FOOTER\n// module.id = 45\n// module.readableIdentifier = ./src/js/ripple/uint128.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint128.js"); /***/ }, /* 46 */ /***/ function(module, exports, __webpack_require__) { - eval("var Crypt = __webpack_require__(31).Crypt;\nvar Message = __webpack_require__(14).Message;\nvar parser = __webpack_require__(42);\nvar querystring = __webpack_require__(49);\nvar extend = __webpack_require__(43);\n\nvar SignedRequest = function (config) {\n // XXX Constructor should be generalized and constructing from an Angular.js\n // $http config should be a SignedRequest.from... utility method.\n this.config = extend(true, {}, config);\n if (!this.config.data) this.config.data = {};\n};\n\n\n\n/**\n * Create a string from request parameters that\n * will be used to sign a request\n * @param {Object} parsed - parsed url\n * @param {Object} date \n * @param {Object} mechanism - type of signing\n */\nSignedRequest.prototype.getStringToSign = function (parsed, date, mechanism) {\n // XXX This method doesn't handle signing GET requests correctly. The data\n // field will be merged into the search string, not the request body.\n\n // Sort the properties of the JSON object into canonical form\n var canonicalData = JSON.stringify(copyObjectWithSortedKeys(this.config.data));\n\n // Canonical request using Amazon's v4 signature format\n // See: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html\n var canonicalRequest = [\n this.config.method || 'GET',\n parsed.pathname || '',\n parsed.search || '',\n // XXX Headers signing not supported\n '',\n '',\n Crypt.hashSha512(canonicalData).toLowerCase()\n ].join('\\n');\n\n // String to sign inspired by Amazon's v4 signature format\n // See: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html\n //\n // We don't have a credential scope, so we skip it.\n //\n // But that modifies the format, so the format ID is RIPPLE1, instead of AWS4.\n return [\n mechanism,\n date,\n Crypt.hashSha512(canonicalRequest).toLowerCase()\n ].join('\\n');\n};\n\n//prepare for signing\nfunction copyObjectWithSortedKeys(object) {\n if (isPlainObject(object)) {\n var newObj = {};\n var keysSorted = Object.keys(object).sort();\n var key;\n for (var i in keysSorted) {\n key = keysSorted[i];\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n newObj[key] = copyObjectWithSortedKeys(object[key]);\n }\n }\n return newObj;\n } else if (Array.isArray(object)) {\n return object.map(copyObjectWithSortedKeys);\n } else {\n return object;\n }\n}\n\n//from npm extend\nfunction isPlainObject(obj) {\n var hasOwn = Object.prototype.hasOwnProperty;\n var toString = Object.prototype.toString;\n\n if (!obj || toString.call(obj) !== '[object Object]' || obj.nodeType || obj.setInterval)\n return false;\n\n var has_own_constructor = hasOwn.call(obj, 'constructor');\n var has_is_property_of_method = hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n // Not own constructor property must be Object\n if (obj.constructor && !has_own_constructor && !has_is_property_of_method)\n return false;\n\n // Own properties are enumerated firstly, so to speed up,\n // if last one is own, then all properties are own.\n var key;\n for ( key in obj ) {}\n\n return key === undefined || hasOwn.call( obj, key );\n};\n\n/**\n * HMAC signed request\n * @param {Object} config\n * @param {Object} auth_secret\n * @param {Object} blob_id\n */\nSignedRequest.prototype.signHmac = function (auth_secret, blob_id) {\n var config = extend(true, {}, this.config);\n\n // Parse URL\n var parsed = parser.parse(config.url);\n var date = dateAsIso8601();\n var signatureType = 'RIPPLE1-HMAC-SHA512';\n var stringToSign = this.getStringToSign(parsed, date, signatureType);\n var signature = Crypt.signString(auth_secret, stringToSign);\n\n var query = querystring.stringify({\n signature: Crypt.base64ToBase64Url(signature),\n signature_date: date,\n signature_blob_id: blob_id,\n signature_type: signatureType\n });\n\n config.url += (parsed.search ? '&' : '?') + query;\n return config;\n};\n\n/**\n * Asymmetric signed request\n * @param {Object} config\n * @param {Object} secretKey\n * @param {Object} account\n * @param {Object} blob_id\n */\nSignedRequest.prototype.signAsymmetric = function (secretKey, account, blob_id) {\n var config = extend(true, {}, this.config);\n\n // Parse URL\n var parsed = parser.parse(config.url);\n var date = dateAsIso8601();\n var signatureType = 'RIPPLE1-ECDSA-SHA512';\n var stringToSign = this.getStringToSign(parsed, date, signatureType);\n var signature = Message.signMessage(stringToSign, secretKey);\n \n var query = querystring.stringify({\n signature: Crypt.base64ToBase64Url(signature),\n signature_date: date,\n signature_blob_id: blob_id,\n signature_account: account,\n signature_type: signatureType\n });\n\n config.url += (parsed.search ? '&' : '?') + query;\n\n return config;\n};\n\n/**\n * Asymmetric signed request for vault recovery\n * @param {Object} config\n * @param {Object} secretKey\n * @param {Object} username\n */\nSignedRequest.prototype.signAsymmetricRecovery = function (secretKey, username) {\n var config = extend(true, {}, this.config);\n\n // Parse URL\n var parsed = parser.parse(config.url);\n var date = dateAsIso8601();\n var signatureType = 'RIPPLE1-ECDSA-SHA512';\n var stringToSign = this.getStringToSign(parsed, date, signatureType);\n var signature = Message.signMessage(stringToSign, secretKey);\n \n var query = querystring.stringify({\n signature: Crypt.base64ToBase64Url(signature),\n signature_date: date,\n signature_username: username,\n signature_type: signatureType\n });\n\n config.url += (parsed.search ? '&' : '?') + query;\n\n return config;\n};\n\nvar dateAsIso8601 = (function () {\n function pad(n) {\n return (n < 0 || n > 9 ? \"\" : \"0\") + n;\n }\n\n return function dateAsIso8601() {\n var date = new Date();\n return date.getUTCFullYear() + \"-\" +\n pad(date.getUTCMonth() + 1) + \"-\" +\n pad(date.getUTCDate()) + \"T\" +\n pad(date.getUTCHours()) + \":\" +\n pad(date.getUTCMinutes()) + \":\" +\n pad(date.getUTCSeconds()) + \".000Z\";\n };\n})();\n\n// XXX Add methods for verifying requests\n// SignedRequest.prototype.verifySignatureHmac\n// SignedRequest.prototype.verifySignatureAsymetric\n\nexports.SignedRequest = SignedRequest;\n\n\n\n// WEBPACK FOOTER\n// module.id = 46\n// module.readableIdentifier = ./src/js/ripple/signedrequest.js\n//@ sourceURL=webpack-module:///./src/js/ripple/signedrequest.js"); + eval("var Crypt = __webpack_require__(30).Crypt;\nvar Message = __webpack_require__(14).Message;\nvar parser = __webpack_require__(42);\nvar querystring = __webpack_require__(50);\nvar extend = __webpack_require__(43);\n\nvar SignedRequest = function (config) {\n // XXX Constructor should be generalized and constructing from an Angular.js\n // $http config should be a SignedRequest.from... utility method.\n this.config = extend(true, {}, config);\n if (!this.config.data) this.config.data = {};\n};\n\n\n\n/**\n * Create a string from request parameters that\n * will be used to sign a request\n * @param {Object} parsed - parsed url\n * @param {Object} date \n * @param {Object} mechanism - type of signing\n */\nSignedRequest.prototype.getStringToSign = function (parsed, date, mechanism) {\n // XXX This method doesn't handle signing GET requests correctly. The data\n // field will be merged into the search string, not the request body.\n\n // Sort the properties of the JSON object into canonical form\n var canonicalData = JSON.stringify(copyObjectWithSortedKeys(this.config.data));\n\n // Canonical request using Amazon's v4 signature format\n // See: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html\n var canonicalRequest = [\n this.config.method || 'GET',\n parsed.pathname || '',\n parsed.search || '',\n // XXX Headers signing not supported\n '',\n '',\n Crypt.hashSha512(canonicalData).toLowerCase()\n ].join('\\n');\n\n // String to sign inspired by Amazon's v4 signature format\n // See: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html\n //\n // We don't have a credential scope, so we skip it.\n //\n // But that modifies the format, so the format ID is RIPPLE1, instead of AWS4.\n return [\n mechanism,\n date,\n Crypt.hashSha512(canonicalRequest).toLowerCase()\n ].join('\\n');\n};\n\n//prepare for signing\nfunction copyObjectWithSortedKeys(object) {\n if (isPlainObject(object)) {\n var newObj = {};\n var keysSorted = Object.keys(object).sort();\n var key;\n for (var i in keysSorted) {\n key = keysSorted[i];\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n newObj[key] = copyObjectWithSortedKeys(object[key]);\n }\n }\n return newObj;\n } else if (Array.isArray(object)) {\n return object.map(copyObjectWithSortedKeys);\n } else {\n return object;\n }\n}\n\n//from npm extend\nfunction isPlainObject(obj) {\n var hasOwn = Object.prototype.hasOwnProperty;\n var toString = Object.prototype.toString;\n\n if (!obj || toString.call(obj) !== '[object Object]' || obj.nodeType || obj.setInterval)\n return false;\n\n var has_own_constructor = hasOwn.call(obj, 'constructor');\n var has_is_property_of_method = hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n // Not own constructor property must be Object\n if (obj.constructor && !has_own_constructor && !has_is_property_of_method)\n return false;\n\n // Own properties are enumerated firstly, so to speed up,\n // if last one is own, then all properties are own.\n var key;\n for ( key in obj ) {}\n\n return key === undefined || hasOwn.call( obj, key );\n};\n\n/**\n * HMAC signed request\n * @param {Object} config\n * @param {Object} auth_secret\n * @param {Object} blob_id\n */\nSignedRequest.prototype.signHmac = function (auth_secret, blob_id) {\n var config = extend(true, {}, this.config);\n\n // Parse URL\n var parsed = parser.parse(config.url);\n var date = dateAsIso8601();\n var signatureType = 'RIPPLE1-HMAC-SHA512';\n var stringToSign = this.getStringToSign(parsed, date, signatureType);\n var signature = Crypt.signString(auth_secret, stringToSign);\n\n var query = querystring.stringify({\n signature: Crypt.base64ToBase64Url(signature),\n signature_date: date,\n signature_blob_id: blob_id,\n signature_type: signatureType\n });\n\n config.url += (parsed.search ? '&' : '?') + query;\n return config;\n};\n\n/**\n * Asymmetric signed request\n * @param {Object} config\n * @param {Object} secretKey\n * @param {Object} account\n * @param {Object} blob_id\n */\nSignedRequest.prototype.signAsymmetric = function (secretKey, account, blob_id) {\n var config = extend(true, {}, this.config);\n\n // Parse URL\n var parsed = parser.parse(config.url);\n var date = dateAsIso8601();\n var signatureType = 'RIPPLE1-ECDSA-SHA512';\n var stringToSign = this.getStringToSign(parsed, date, signatureType);\n var signature = Message.signMessage(stringToSign, secretKey);\n \n var query = querystring.stringify({\n signature: Crypt.base64ToBase64Url(signature),\n signature_date: date,\n signature_blob_id: blob_id,\n signature_account: account,\n signature_type: signatureType\n });\n\n config.url += (parsed.search ? '&' : '?') + query;\n\n return config;\n};\n\n/**\n * Asymmetric signed request for vault recovery\n * @param {Object} config\n * @param {Object} secretKey\n * @param {Object} username\n */\nSignedRequest.prototype.signAsymmetricRecovery = function (secretKey, username) {\n var config = extend(true, {}, this.config);\n\n // Parse URL\n var parsed = parser.parse(config.url);\n var date = dateAsIso8601();\n var signatureType = 'RIPPLE1-ECDSA-SHA512';\n var stringToSign = this.getStringToSign(parsed, date, signatureType);\n var signature = Message.signMessage(stringToSign, secretKey);\n \n var query = querystring.stringify({\n signature: Crypt.base64ToBase64Url(signature),\n signature_date: date,\n signature_username: username,\n signature_type: signatureType\n });\n\n config.url += (parsed.search ? '&' : '?') + query;\n\n return config;\n};\n\nvar dateAsIso8601 = (function () {\n function pad(n) {\n return (n < 0 || n > 9 ? \"\" : \"0\") + n;\n }\n\n return function dateAsIso8601() {\n var date = new Date();\n return date.getUTCFullYear() + \"-\" +\n pad(date.getUTCMonth() + 1) + \"-\" +\n pad(date.getUTCDate()) + \"T\" +\n pad(date.getUTCHours()) + \":\" +\n pad(date.getUTCMinutes()) + \":\" +\n pad(date.getUTCSeconds()) + \".000Z\";\n };\n})();\n\n// XXX Add methods for verifying requests\n// SignedRequest.prototype.verifySignatureHmac\n// SignedRequest.prototype.verifySignatureAsymetric\n\nexports.SignedRequest = SignedRequest;\n\n\n\n// WEBPACK FOOTER\n// module.id = 46\n// module.readableIdentifier = ./src/js/ripple/signedrequest.js\n//@ sourceURL=webpack-module:///./src/js/ripple/signedrequest.js"); /***/ }, /* 47 */ @@ -340,37 +340,37 @@ var ripple = /* 49 */ /***/ function(module, exports, __webpack_require__) { - eval("'use strict';\n\nexports.decode = exports.parse = __webpack_require__(57);\nexports.encode = exports.stringify = __webpack_require__(58);\n\n\n// WEBPACK FOOTER\n// module.id = 49\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/querystring-es3/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/querystring-es3/index.js"); + eval("/**\n * Module dependencies.\n */\n\nvar Emitter = __webpack_require__(67);\nvar reduce = __webpack_require__(66);\n\n/**\n * Root reference for iframes.\n */\n\nvar root = 'undefined' == typeof window\n ? this\n : window;\n\n/**\n * Noop.\n */\n\nfunction noop(){};\n\n/**\n * Check if `obj` is a host object,\n * we don't want to serialize these :)\n *\n * TODO: future proof, move to compoent land\n *\n * @param {Object} obj\n * @return {Boolean}\n * @api private\n */\n\nfunction isHost(obj) {\n var str = {}.toString.call(obj);\n\n switch (str) {\n case '[object File]':\n case '[object Blob]':\n case '[object FormData]':\n return true;\n default:\n return false;\n }\n}\n\n/**\n * Determine XHR.\n */\n\nfunction getXHR() {\n if (root.XMLHttpRequest\n && ('file:' != root.location.protocol || !root.ActiveXObject)) {\n return new XMLHttpRequest;\n } else {\n try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}\n try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}\n try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}\n try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}\n }\n return false;\n}\n\n/**\n * Removes leading and trailing whitespace, added to support IE.\n *\n * @param {String} s\n * @return {String}\n * @api private\n */\n\nvar trim = ''.trim\n ? function(s) { return s.trim(); }\n : function(s) { return s.replace(/(^\\s*|\\s*$)/g, ''); };\n\n/**\n * Check if `obj` is an object.\n *\n * @param {Object} obj\n * @return {Boolean}\n * @api private\n */\n\nfunction isObject(obj) {\n return obj === Object(obj);\n}\n\n/**\n * Serialize the given `obj`.\n *\n * @param {Object} obj\n * @return {String}\n * @api private\n */\n\nfunction serialize(obj) {\n if (!isObject(obj)) return obj;\n var pairs = [];\n for (var key in obj) {\n if (null != obj[key]) {\n pairs.push(encodeURIComponent(key)\n + '=' + encodeURIComponent(obj[key]));\n }\n }\n return pairs.join('&');\n}\n\n/**\n * Expose serialization method.\n */\n\n request.serializeObject = serialize;\n\n /**\n * Parse the given x-www-form-urlencoded `str`.\n *\n * @param {String} str\n * @return {Object}\n * @api private\n */\n\nfunction parseString(str) {\n var obj = {};\n var pairs = str.split('&');\n var parts;\n var pair;\n\n for (var i = 0, len = pairs.length; i < len; ++i) {\n pair = pairs[i];\n parts = pair.split('=');\n obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);\n }\n\n return obj;\n}\n\n/**\n * Expose parser.\n */\n\nrequest.parseString = parseString;\n\n/**\n * Default MIME type map.\n *\n * superagent.types.xml = 'application/xml';\n *\n */\n\nrequest.types = {\n html: 'text/html',\n json: 'application/json',\n xml: 'application/xml',\n urlencoded: 'application/x-www-form-urlencoded',\n 'form': 'application/x-www-form-urlencoded',\n 'form-data': 'application/x-www-form-urlencoded'\n};\n\n/**\n * Default serialization map.\n *\n * superagent.serialize['application/xml'] = function(obj){\n * return 'generated xml here';\n * };\n *\n */\n\n request.serialize = {\n 'application/x-www-form-urlencoded': serialize,\n 'application/json': JSON.stringify\n };\n\n /**\n * Default parsers.\n *\n * superagent.parse['application/xml'] = function(str){\n * return { object parsed from str };\n * };\n *\n */\n\nrequest.parse = {\n 'application/x-www-form-urlencoded': parseString,\n 'application/json': JSON.parse\n};\n\n/**\n * Parse the given header `str` into\n * an object containing the mapped fields.\n *\n * @param {String} str\n * @return {Object}\n * @api private\n */\n\nfunction parseHeader(str) {\n var lines = str.split(/\\r?\\n/);\n var fields = {};\n var index;\n var line;\n var field;\n var val;\n\n lines.pop(); // trailing CRLF\n\n for (var i = 0, len = lines.length; i < len; ++i) {\n line = lines[i];\n index = line.indexOf(':');\n field = line.slice(0, index).toLowerCase();\n val = trim(line.slice(index + 1));\n fields[field] = val;\n }\n\n return fields;\n}\n\n/**\n * Return the mime type for the given `str`.\n *\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nfunction type(str){\n return str.split(/ *; */).shift();\n};\n\n/**\n * Return header field parameters.\n *\n * @param {String} str\n * @return {Object}\n * @api private\n */\n\nfunction params(str){\n return reduce(str.split(/ *; */), function(obj, str){\n var parts = str.split(/ *= */)\n , key = parts.shift()\n , val = parts.shift();\n\n if (key && val) obj[key] = val;\n return obj;\n }, {});\n};\n\n/**\n * Initialize a new `Response` with the given `xhr`.\n *\n * - set flags (.ok, .error, etc)\n * - parse header\n *\n * Examples:\n *\n * Aliasing `superagent` as `request` is nice:\n *\n * request = superagent;\n *\n * We can use the promise-like API, or pass callbacks:\n *\n * request.get('/').end(function(res){});\n * request.get('/', function(res){});\n *\n * Sending data can be chained:\n *\n * request\n * .post('/user')\n * .send({ name: 'tj' })\n * .end(function(res){});\n *\n * Or passed to `.send()`:\n *\n * request\n * .post('/user')\n * .send({ name: 'tj' }, function(res){});\n *\n * Or passed to `.post()`:\n *\n * request\n * .post('/user', { name: 'tj' })\n * .end(function(res){});\n *\n * Or further reduced to a single call for simple cases:\n *\n * request\n * .post('/user', { name: 'tj' }, function(res){});\n *\n * @param {XMLHTTPRequest} xhr\n * @param {Object} options\n * @api private\n */\n\nfunction Response(req, options) {\n options = options || {};\n this.req = req;\n this.xhr = this.req.xhr;\n this.text = this.xhr.responseText;\n this.setStatusProperties(this.xhr.status);\n this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());\n // getAllResponseHeaders sometimes falsely returns \"\" for CORS requests, but\n // getResponseHeader still works. so we get content-type even if getting\n // other headers fails.\n this.header['content-type'] = this.xhr.getResponseHeader('content-type');\n this.setHeaderProperties(this.header);\n this.body = this.req.method != 'HEAD'\n ? this.parseBody(this.text)\n : null;\n}\n\n/**\n * Get case-insensitive `field` value.\n *\n * @param {String} field\n * @return {String}\n * @api public\n */\n\nResponse.prototype.get = function(field){\n return this.header[field.toLowerCase()];\n};\n\n/**\n * Set header related properties:\n *\n * - `.type` the content type without params\n *\n * A response of \"Content-Type: text/plain; charset=utf-8\"\n * will provide you with a `.type` of \"text/plain\".\n *\n * @param {Object} header\n * @api private\n */\n\nResponse.prototype.setHeaderProperties = function(header){\n // content-type\n var ct = this.header['content-type'] || '';\n this.type = type(ct);\n\n // params\n var obj = params(ct);\n for (var key in obj) this[key] = obj[key];\n};\n\n/**\n * Parse the given body `str`.\n *\n * Used for auto-parsing of bodies. Parsers\n * are defined on the `superagent.parse` object.\n *\n * @param {String} str\n * @return {Mixed}\n * @api private\n */\n\nResponse.prototype.parseBody = function(str){\n var parse = request.parse[this.type];\n return parse\n ? parse(str)\n : null;\n};\n\n/**\n * Set flags such as `.ok` based on `status`.\n *\n * For example a 2xx response will give you a `.ok` of __true__\n * whereas 5xx will be __false__ and `.error` will be __true__. The\n * `.clientError` and `.serverError` are also available to be more\n * specific, and `.statusType` is the class of error ranging from 1..5\n * sometimes useful for mapping respond colors etc.\n *\n * \"sugar\" properties are also defined for common cases. Currently providing:\n *\n * - .noContent\n * - .badRequest\n * - .unauthorized\n * - .notAcceptable\n * - .notFound\n *\n * @param {Number} status\n * @api private\n */\n\nResponse.prototype.setStatusProperties = function(status){\n var type = status / 100 | 0;\n\n // status / class\n this.status = status;\n this.statusType = type;\n\n // basics\n this.info = 1 == type;\n this.ok = 2 == type;\n this.clientError = 4 == type;\n this.serverError = 5 == type;\n this.error = (4 == type || 5 == type)\n ? this.toError()\n : false;\n\n // sugar\n this.accepted = 202 == status;\n this.noContent = 204 == status || 1223 == status;\n this.badRequest = 400 == status;\n this.unauthorized = 401 == status;\n this.notAcceptable = 406 == status;\n this.notFound = 404 == status;\n this.forbidden = 403 == status;\n};\n\n/**\n * Return an `Error` representative of this response.\n *\n * @return {Error}\n * @api public\n */\n\nResponse.prototype.toError = function(){\n var req = this.req;\n var method = req.method;\n var url = req.url;\n\n var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';\n var err = new Error(msg);\n err.status = this.status;\n err.method = method;\n err.url = url;\n\n return err;\n};\n\n/**\n * Expose `Response`.\n */\n\nrequest.Response = Response;\n\n/**\n * Initialize a new `Request` with the given `method` and `url`.\n *\n * @param {String} method\n * @param {String} url\n * @api public\n */\n\nfunction Request(method, url) {\n var self = this;\n Emitter.call(this);\n this._query = this._query || [];\n this.method = method;\n this.url = url;\n this.header = {};\n this._header = {};\n this.on('end', function(){\n var res = new Response(self);\n if ('HEAD' == method) res.text = null;\n self.callback(null, res);\n });\n}\n\n/**\n * Mixin `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Allow for extension\n */\n\nRequest.prototype.use = function(fn) {\n fn(this);\n return this;\n}\n\n/**\n * Set timeout to `ms`.\n *\n * @param {Number} ms\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.timeout = function(ms){\n this._timeout = ms;\n return this;\n};\n\n/**\n * Clear previous timeout.\n *\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.clearTimeout = function(){\n this._timeout = 0;\n clearTimeout(this._timer);\n return this;\n};\n\n/**\n * Abort the request, and clear potential timeout.\n *\n * @return {Request}\n * @api public\n */\n\nRequest.prototype.abort = function(){\n if (this.aborted) return;\n this.aborted = true;\n this.xhr.abort();\n this.clearTimeout();\n this.emit('abort');\n return this;\n};\n\n/**\n * Set header `field` to `val`, or multiple fields with one object.\n *\n * Examples:\n *\n * req.get('/')\n * .set('Accept', 'application/json')\n * .set('X-API-Key', 'foobar')\n * .end(callback);\n *\n * req.get('/')\n * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })\n * .end(callback);\n *\n * @param {String|Object} field\n * @param {String} val\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.set = function(field, val){\n if (isObject(field)) {\n for (var key in field) {\n this.set(key, field[key]);\n }\n return this;\n }\n this._header[field.toLowerCase()] = val;\n this.header[field] = val;\n return this;\n};\n\n/**\n * Get case-insensitive header `field` value.\n *\n * @param {String} field\n * @return {String}\n * @api private\n */\n\nRequest.prototype.getHeader = function(field){\n return this._header[field.toLowerCase()];\n};\n\n/**\n * Set Content-Type to `type`, mapping values from `request.types`.\n *\n * Examples:\n *\n * superagent.types.xml = 'application/xml';\n *\n * request.post('/')\n * .type('xml')\n * .send(xmlstring)\n * .end(callback);\n *\n * request.post('/')\n * .type('application/xml')\n * .send(xmlstring)\n * .end(callback);\n *\n * @param {String} type\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.type = function(type){\n this.set('Content-Type', request.types[type] || type);\n return this;\n};\n\n/**\n * Set Accept to `type`, mapping values from `request.types`.\n *\n * Examples:\n *\n * superagent.types.json = 'application/json';\n *\n * request.get('/agent')\n * .accept('json')\n * .end(callback);\n *\n * request.get('/agent')\n * .accept('application/json')\n * .end(callback);\n *\n * @param {String} accept\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.accept = function(type){\n this.set('Accept', request.types[type] || type);\n return this;\n};\n\n/**\n * Set Authorization field value with `user` and `pass`.\n *\n * @param {String} user\n * @param {String} pass\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.auth = function(user, pass){\n var str = btoa(user + ':' + pass);\n this.set('Authorization', 'Basic ' + str);\n return this;\n};\n\n/**\n* Add query-string `val`.\n*\n* Examples:\n*\n* request.get('/shoes')\n* .query('size=10')\n* .query({ color: 'blue' })\n*\n* @param {Object|String} val\n* @return {Request} for chaining\n* @api public\n*/\n\nRequest.prototype.query = function(val){\n if ('string' != typeof val) val = serialize(val);\n if (val) this._query.push(val);\n return this;\n};\n\n/**\n * Write the field `name` and `val` for \"multipart/form-data\"\n * request bodies.\n *\n * ``` js\n * request.post('/upload')\n * .field('foo', 'bar')\n * .end(callback);\n * ```\n *\n * @param {String} name\n * @param {String|Blob|File} val\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.field = function(name, val){\n if (!this._formData) this._formData = new FormData();\n this._formData.append(name, val);\n return this;\n};\n\n/**\n * Queue the given `file` as an attachment to the specified `field`,\n * with optional `filename`.\n *\n * ``` js\n * request.post('/upload')\n * .attach(new Blob(['hey!'], { type: \"text/html\"}))\n * .end(callback);\n * ```\n *\n * @param {String} field\n * @param {Blob|File} file\n * @param {String} filename\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.attach = function(field, file, filename){\n if (!this._formData) this._formData = new FormData();\n this._formData.append(field, file, filename);\n return this;\n};\n\n/**\n * Send `data`, defaulting the `.type()` to \"json\" when\n * an object is given.\n *\n * Examples:\n *\n * // querystring\n * request.get('/search')\n * .end(callback)\n *\n * // multiple data \"writes\"\n * request.get('/search')\n * .send({ search: 'query' })\n * .send({ range: '1..5' })\n * .send({ order: 'desc' })\n * .end(callback)\n *\n * // manual json\n * request.post('/user')\n * .type('json')\n * .send('{\"name\":\"tj\"})\n * .end(callback)\n *\n * // auto json\n * request.post('/user')\n * .send({ name: 'tj' })\n * .end(callback)\n *\n * // manual x-www-form-urlencoded\n * request.post('/user')\n * .type('form')\n * .send('name=tj')\n * .end(callback)\n *\n * // auto x-www-form-urlencoded\n * request.post('/user')\n * .type('form')\n * .send({ name: 'tj' })\n * .end(callback)\n *\n * // defaults to x-www-form-urlencoded\n * request.post('/user')\n * .send('name=tobi')\n * .send('species=ferret')\n * .end(callback)\n *\n * @param {String|Object} data\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.send = function(data){\n var obj = isObject(data);\n var type = this.getHeader('Content-Type');\n\n // merge\n if (obj && isObject(this._data)) {\n for (var key in data) {\n this._data[key] = data[key];\n }\n } else if ('string' == typeof data) {\n if (!type) this.type('form');\n type = this.getHeader('Content-Type');\n if ('application/x-www-form-urlencoded' == type) {\n this._data = this._data\n ? this._data + '&' + data\n : data;\n } else {\n this._data = (this._data || '') + data;\n }\n } else {\n this._data = data;\n }\n\n if (!obj) return this;\n if (!type) this.type('json');\n return this;\n};\n\n/**\n * Invoke the callback with `err` and `res`\n * and handle arity check.\n *\n * @param {Error} err\n * @param {Response} res\n * @api private\n */\n\nRequest.prototype.callback = function(err, res){\n var fn = this._callback;\n if (2 == fn.length) return fn(err, res);\n if (err) return this.emit('error', err);\n fn(res);\n};\n\n/**\n * Invoke callback with x-domain error.\n *\n * @api private\n */\n\nRequest.prototype.crossDomainError = function(){\n var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');\n err.crossDomain = true;\n this.callback(err);\n};\n\n/**\n * Invoke callback with timeout error.\n *\n * @api private\n */\n\nRequest.prototype.timeoutError = function(){\n var timeout = this._timeout;\n var err = new Error('timeout of ' + timeout + 'ms exceeded');\n err.timeout = timeout;\n this.callback(err);\n};\n\n/**\n * Enable transmission of cookies with x-domain requests.\n *\n * Note that for this to work the origin must not be\n * using \"Access-Control-Allow-Origin\" with a wildcard,\n * and also must set \"Access-Control-Allow-Credentials\"\n * to \"true\".\n *\n * @api public\n */\n\nRequest.prototype.withCredentials = function(){\n this._withCredentials = true;\n return this;\n};\n\n/**\n * Initiate request, invoking callback `fn(res)`\n * with an instanceof `Response`.\n *\n * @param {Function} fn\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.end = function(fn){\n var self = this;\n var xhr = this.xhr = getXHR();\n var query = this._query.join('&');\n var timeout = this._timeout;\n var data = this._formData || this._data;\n\n // store callback\n this._callback = fn || noop;\n\n // state change\n xhr.onreadystatechange = function(){\n if (4 != xhr.readyState) return;\n if (0 == xhr.status) {\n if (self.aborted) return self.timeoutError();\n return self.crossDomainError();\n }\n self.emit('end');\n };\n\n // progress\n if (xhr.upload) {\n xhr.upload.onprogress = function(e){\n e.percent = e.loaded / e.total * 100;\n self.emit('progress', e);\n };\n }\n\n // timeout\n if (timeout && !this._timer) {\n this._timer = setTimeout(function(){\n self.abort();\n }, timeout);\n }\n\n // querystring\n if (query) {\n query = request.serializeObject(query);\n this.url += ~this.url.indexOf('?')\n ? '&' + query\n : '?' + query;\n }\n\n // initiate request\n xhr.open(this.method, this.url, true);\n\n // CORS\n if (this._withCredentials) xhr.withCredentials = true;\n\n // body\n if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {\n // serialize stuff\n var serialize = request.serialize[this.getHeader('Content-Type')];\n if (serialize) data = serialize(data);\n }\n\n // set header fields\n for (var field in this.header) {\n if (null == this.header[field]) continue;\n xhr.setRequestHeader(field, this.header[field]);\n }\n\n // send stuff\n this.emit('request', this);\n xhr.send(data);\n return this;\n};\n\n/**\n * Expose `Request`.\n */\n\nrequest.Request = Request;\n\n/**\n * Issue a request:\n *\n * Examples:\n *\n * request('GET', '/users').end(callback)\n * request('/users').end(callback)\n * request('/users', callback)\n *\n * @param {String} method\n * @param {String|Function} url or callback\n * @return {Request}\n * @api public\n */\n\nfunction request(method, url) {\n // callback\n if ('function' == typeof url) {\n return new Request('GET', method).end(url);\n }\n\n // url first\n if (1 == arguments.length) {\n return new Request('GET', method);\n }\n\n return new Request(method, url);\n}\n\n/**\n * GET `url` with optional callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed|Function} data or fn\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.get = function(url, data, fn){\n var req = request('GET', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.query(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * HEAD `url` with optional callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed|Function} data or fn\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.head = function(url, data, fn){\n var req = request('HEAD', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * DELETE `url` with optional callback `fn(res)`.\n *\n * @param {String} url\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.del = function(url, fn){\n var req = request('DELETE', url);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * PATCH `url` with optional `data` and callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed} data\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.patch = function(url, data, fn){\n var req = request('PATCH', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * POST `url` with optional `data` and callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed} data\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.post = function(url, data, fn){\n var req = request('POST', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * PUT `url` with optional `data` and callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed|Function} data or fn\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.put = function(url, data, fn){\n var req = request('PUT', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * Expose `request`.\n */\n\nmodule.exports = request;\n\n\n// WEBPACK FOOTER\n// module.id = 49\n// module.readableIdentifier = ./~/superagent/lib/client.js\n//@ sourceURL=webpack-module:///./~/superagent/lib/client.js"); /***/ }, /* 50 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {// Original code adapted from Robert Kieffer.\n// details at https://github.com/broofa/node-uuid\n\n\n(function() {\n var _global = this;\n\n var mathRNG, whatwgRNG;\n\n // NOTE: Math.random() does not guarantee \"cryptographic quality\"\n mathRNG = function(size) {\n var bytes = new Buffer(size);\n var r;\n\n for (var i = 0, r; i < size; i++) {\n if ((i & 0x03) == 0) r = Math.random() * 0x100000000;\n bytes[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return bytes;\n }\n\n if (_global.crypto && crypto.getRandomValues) {\n whatwgRNG = function(size) {\n var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array\n crypto.getRandomValues(bytes);\n return bytes;\n }\n }\n\n module.exports = whatwgRNG || mathRNG;\n\n}())\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 50\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/rng.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/rng.js"); + eval("'use strict';\n\nexports.decode = exports.parse = __webpack_require__(58);\nexports.encode = exports.stringify = __webpack_require__(59);\n\n\n// WEBPACK FOOTER\n// module.id = 50\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/querystring-es3/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/querystring-es3/index.js"); /***/ }, /* 51 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(66)\n\nvar md5 = toConstructor(__webpack_require__(59))\nvar rmd160 = toConstructor(__webpack_require__(70))\n\nfunction toConstructor (fn) {\n return function () {\n var buffers = []\n var m= {\n update: function (data, enc) {\n if(!Buffer.isBuffer(data)) data = new Buffer(data, enc)\n buffers.push(data)\n return this\n },\n digest: function (enc) {\n var buf = Buffer.concat(buffers)\n var r = fn(buf)\n buffers = null\n return enc ? r.toString(enc) : r\n }\n }\n return m\n }\n}\n\nmodule.exports = function (alg) {\n if('md5' === alg) return new md5()\n if('rmd160' === alg) return new rmd160()\n return createHash(alg)\n}\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 51\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/create-hash.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/create-hash.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {// Original code adapted from Robert Kieffer.\n// details at https://github.com/broofa/node-uuid\n\n\n(function() {\n var _global = this;\n\n var mathRNG, whatwgRNG;\n\n // NOTE: Math.random() does not guarantee \"cryptographic quality\"\n mathRNG = function(size) {\n var bytes = new Buffer(size);\n var r;\n\n for (var i = 0, r; i < size; i++) {\n if ((i & 0x03) == 0) r = Math.random() * 0x100000000;\n bytes[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return bytes;\n }\n\n if (_global.crypto && crypto.getRandomValues) {\n whatwgRNG = function(size) {\n var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array\n crypto.getRandomValues(bytes);\n return bytes;\n }\n }\n\n module.exports = whatwgRNG || mathRNG;\n\n}())\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 51\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/rng.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/rng.js"); /***/ }, /* 52 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(51)\n\nvar blocksize = 64\nvar zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)\n\nmodule.exports = Hmac\n\nfunction Hmac (alg, key) {\n if(!(this instanceof Hmac)) return new Hmac(alg, key)\n this._opad = opad\n this._alg = alg\n\n key = this._key = !Buffer.isBuffer(key) ? new Buffer(key) : key\n\n if(key.length > blocksize) {\n key = createHash(alg).update(key).digest()\n } else if(key.length < blocksize) {\n key = Buffer.concat([key, zeroBuffer], blocksize)\n }\n\n var ipad = this._ipad = new Buffer(blocksize)\n var opad = this._opad = new Buffer(blocksize)\n\n for(var i = 0; i < blocksize; i++) {\n ipad[i] = key[i] ^ 0x36\n opad[i] = key[i] ^ 0x5C\n }\n\n this._hash = createHash(alg).update(ipad)\n}\n\nHmac.prototype.update = function (data, enc) {\n this._hash.update(data, enc)\n return this\n}\n\nHmac.prototype.digest = function (enc) {\n var h = this._hash.digest()\n return createHash(this._alg).update(this._opad).update(h).digest(enc)\n}\n\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 52\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/create-hmac.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/create-hmac.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(68)\n\nvar md5 = toConstructor(__webpack_require__(60))\nvar rmd160 = toConstructor(__webpack_require__(70))\n\nfunction toConstructor (fn) {\n return function () {\n var buffers = []\n var m= {\n update: function (data, enc) {\n if(!Buffer.isBuffer(data)) data = new Buffer(data, enc)\n buffers.push(data)\n return this\n },\n digest: function (enc) {\n var buf = Buffer.concat(buffers)\n var r = fn(buf)\n buffers = null\n return enc ? r.toString(enc) : r\n }\n }\n return m\n }\n}\n\nmodule.exports = function (alg) {\n if('md5' === alg) return new md5()\n if('rmd160' === alg) return new rmd160()\n return createHash(alg)\n}\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 52\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/create-hash.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/create-hash.js"); /***/ }, /* 53 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {// JavaScript PBKDF2 Implementation\n// Based on http://git.io/qsv2zw\n// Licensed under LGPL v3\n// Copyright (c) 2013 jduncanator\n\nvar blocksize = 64\nvar zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)\n\nmodule.exports = function (createHmac, exports) {\n exports = exports || {}\n\n exports.pbkdf2 = function(password, salt, iterations, keylen, cb) {\n if('function' !== typeof cb)\n throw new Error('No callback provided to pbkdf2');\n setTimeout(function () {\n cb(null, exports.pbkdf2Sync(password, salt, iterations, keylen))\n })\n }\n\n exports.pbkdf2Sync = function(key, salt, iterations, keylen) {\n if('number' !== typeof iterations)\n throw new TypeError('Iterations not a number')\n if(iterations < 0)\n throw new TypeError('Bad iterations')\n if('number' !== typeof keylen)\n throw new TypeError('Key length not a number')\n if(keylen < 0)\n throw new TypeError('Bad key length')\n\n //stretch key to the correct length that hmac wants it,\n //otherwise this will happen every time hmac is called\n //twice per iteration.\n var key = !Buffer.isBuffer(key) ? new Buffer(key) : key\n\n if(key.length > blocksize) {\n key = createHash(alg).update(key).digest()\n } else if(key.length < blocksize) {\n key = Buffer.concat([key, zeroBuffer], blocksize)\n }\n\n var HMAC;\n var cplen, p = 0, i = 1, itmp = new Buffer(4), digtmp;\n var out = new Buffer(keylen);\n out.fill(0);\n while(keylen) {\n if(keylen > 20)\n cplen = 20;\n else\n cplen = keylen;\n\n /* We are unlikely to ever use more than 256 blocks (5120 bits!)\n * but just in case...\n */\n itmp[0] = (i >> 24) & 0xff;\n itmp[1] = (i >> 16) & 0xff;\n itmp[2] = (i >> 8) & 0xff;\n itmp[3] = i & 0xff;\n\n HMAC = createHmac('sha1', key);\n HMAC.update(salt)\n HMAC.update(itmp);\n digtmp = HMAC.digest();\n digtmp.copy(out, p, 0, cplen);\n\n for(var j = 1; j < iterations; j++) {\n HMAC = createHmac('sha1', key);\n HMAC.update(digtmp);\n digtmp = HMAC.digest();\n for(var k = 0; k < cplen; k++) {\n out[k] ^= digtmp[k];\n }\n }\n keylen -= cplen;\n i++;\n p += cplen;\n }\n\n return out;\n }\n\n return exports\n}\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 53\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/pbkdf2.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/pbkdf2.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(52)\n\nvar blocksize = 64\nvar zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)\n\nmodule.exports = Hmac\n\nfunction Hmac (alg, key) {\n if(!(this instanceof Hmac)) return new Hmac(alg, key)\n this._opad = opad\n this._alg = alg\n\n key = this._key = !Buffer.isBuffer(key) ? new Buffer(key) : key\n\n if(key.length > blocksize) {\n key = createHash(alg).update(key).digest()\n } else if(key.length < blocksize) {\n key = Buffer.concat([key, zeroBuffer], blocksize)\n }\n\n var ipad = this._ipad = new Buffer(blocksize)\n var opad = this._opad = new Buffer(blocksize)\n\n for(var i = 0; i < blocksize; i++) {\n ipad[i] = key[i] ^ 0x36\n opad[i] = key[i] ^ 0x5C\n }\n\n this._hash = createHash(alg).update(ipad)\n}\n\nHmac.prototype.update = function (data, enc) {\n this._hash.update(data, enc)\n return this\n}\n\nHmac.prototype.digest = function (enc) {\n var h = this._hash.digest()\n return createHash(this._alg).update(this._opad).update(h).digest(enc)\n}\n\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 53\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/create-hmac.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/create-hmac.js"); /***/ }, /* 54 */ /***/ function(module, exports, __webpack_require__) { - eval("/**\n * Module dependencies.\n */\n\nvar Emitter = __webpack_require__(68);\nvar reduce = __webpack_require__(69);\n\n/**\n * Root reference for iframes.\n */\n\nvar root = 'undefined' == typeof window\n ? this\n : window;\n\n/**\n * Noop.\n */\n\nfunction noop(){};\n\n/**\n * Check if `obj` is a host object,\n * we don't want to serialize these :)\n *\n * TODO: future proof, move to compoent land\n *\n * @param {Object} obj\n * @return {Boolean}\n * @api private\n */\n\nfunction isHost(obj) {\n var str = {}.toString.call(obj);\n\n switch (str) {\n case '[object File]':\n case '[object Blob]':\n case '[object FormData]':\n return true;\n default:\n return false;\n }\n}\n\n/**\n * Determine XHR.\n */\n\nfunction getXHR() {\n if (root.XMLHttpRequest\n && ('file:' != root.location.protocol || !root.ActiveXObject)) {\n return new XMLHttpRequest;\n } else {\n try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}\n try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}\n try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}\n try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}\n }\n return false;\n}\n\n/**\n * Removes leading and trailing whitespace, added to support IE.\n *\n * @param {String} s\n * @return {String}\n * @api private\n */\n\nvar trim = ''.trim\n ? function(s) { return s.trim(); }\n : function(s) { return s.replace(/(^\\s*|\\s*$)/g, ''); };\n\n/**\n * Check if `obj` is an object.\n *\n * @param {Object} obj\n * @return {Boolean}\n * @api private\n */\n\nfunction isObject(obj) {\n return obj === Object(obj);\n}\n\n/**\n * Serialize the given `obj`.\n *\n * @param {Object} obj\n * @return {String}\n * @api private\n */\n\nfunction serialize(obj) {\n if (!isObject(obj)) return obj;\n var pairs = [];\n for (var key in obj) {\n if (null != obj[key]) {\n pairs.push(encodeURIComponent(key)\n + '=' + encodeURIComponent(obj[key]));\n }\n }\n return pairs.join('&');\n}\n\n/**\n * Expose serialization method.\n */\n\n request.serializeObject = serialize;\n\n /**\n * Parse the given x-www-form-urlencoded `str`.\n *\n * @param {String} str\n * @return {Object}\n * @api private\n */\n\nfunction parseString(str) {\n var obj = {};\n var pairs = str.split('&');\n var parts;\n var pair;\n\n for (var i = 0, len = pairs.length; i < len; ++i) {\n pair = pairs[i];\n parts = pair.split('=');\n obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);\n }\n\n return obj;\n}\n\n/**\n * Expose parser.\n */\n\nrequest.parseString = parseString;\n\n/**\n * Default MIME type map.\n *\n * superagent.types.xml = 'application/xml';\n *\n */\n\nrequest.types = {\n html: 'text/html',\n json: 'application/json',\n xml: 'application/xml',\n urlencoded: 'application/x-www-form-urlencoded',\n 'form': 'application/x-www-form-urlencoded',\n 'form-data': 'application/x-www-form-urlencoded'\n};\n\n/**\n * Default serialization map.\n *\n * superagent.serialize['application/xml'] = function(obj){\n * return 'generated xml here';\n * };\n *\n */\n\n request.serialize = {\n 'application/x-www-form-urlencoded': serialize,\n 'application/json': JSON.stringify\n };\n\n /**\n * Default parsers.\n *\n * superagent.parse['application/xml'] = function(str){\n * return { object parsed from str };\n * };\n *\n */\n\nrequest.parse = {\n 'application/x-www-form-urlencoded': parseString,\n 'application/json': JSON.parse\n};\n\n/**\n * Parse the given header `str` into\n * an object containing the mapped fields.\n *\n * @param {String} str\n * @return {Object}\n * @api private\n */\n\nfunction parseHeader(str) {\n var lines = str.split(/\\r?\\n/);\n var fields = {};\n var index;\n var line;\n var field;\n var val;\n\n lines.pop(); // trailing CRLF\n\n for (var i = 0, len = lines.length; i < len; ++i) {\n line = lines[i];\n index = line.indexOf(':');\n field = line.slice(0, index).toLowerCase();\n val = trim(line.slice(index + 1));\n fields[field] = val;\n }\n\n return fields;\n}\n\n/**\n * Return the mime type for the given `str`.\n *\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nfunction type(str){\n return str.split(/ *; */).shift();\n};\n\n/**\n * Return header field parameters.\n *\n * @param {String} str\n * @return {Object}\n * @api private\n */\n\nfunction params(str){\n return reduce(str.split(/ *; */), function(obj, str){\n var parts = str.split(/ *= */)\n , key = parts.shift()\n , val = parts.shift();\n\n if (key && val) obj[key] = val;\n return obj;\n }, {});\n};\n\n/**\n * Initialize a new `Response` with the given `xhr`.\n *\n * - set flags (.ok, .error, etc)\n * - parse header\n *\n * Examples:\n *\n * Aliasing `superagent` as `request` is nice:\n *\n * request = superagent;\n *\n * We can use the promise-like API, or pass callbacks:\n *\n * request.get('/').end(function(res){});\n * request.get('/', function(res){});\n *\n * Sending data can be chained:\n *\n * request\n * .post('/user')\n * .send({ name: 'tj' })\n * .end(function(res){});\n *\n * Or passed to `.send()`:\n *\n * request\n * .post('/user')\n * .send({ name: 'tj' }, function(res){});\n *\n * Or passed to `.post()`:\n *\n * request\n * .post('/user', { name: 'tj' })\n * .end(function(res){});\n *\n * Or further reduced to a single call for simple cases:\n *\n * request\n * .post('/user', { name: 'tj' }, function(res){});\n *\n * @param {XMLHTTPRequest} xhr\n * @param {Object} options\n * @api private\n */\n\nfunction Response(req, options) {\n options = options || {};\n this.req = req;\n this.xhr = this.req.xhr;\n this.text = this.xhr.responseText;\n this.setStatusProperties(this.xhr.status);\n this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());\n // getAllResponseHeaders sometimes falsely returns \"\" for CORS requests, but\n // getResponseHeader still works. so we get content-type even if getting\n // other headers fails.\n this.header['content-type'] = this.xhr.getResponseHeader('content-type');\n this.setHeaderProperties(this.header);\n this.body = this.req.method != 'HEAD'\n ? this.parseBody(this.text)\n : null;\n}\n\n/**\n * Get case-insensitive `field` value.\n *\n * @param {String} field\n * @return {String}\n * @api public\n */\n\nResponse.prototype.get = function(field){\n return this.header[field.toLowerCase()];\n};\n\n/**\n * Set header related properties:\n *\n * - `.type` the content type without params\n *\n * A response of \"Content-Type: text/plain; charset=utf-8\"\n * will provide you with a `.type` of \"text/plain\".\n *\n * @param {Object} header\n * @api private\n */\n\nResponse.prototype.setHeaderProperties = function(header){\n // content-type\n var ct = this.header['content-type'] || '';\n this.type = type(ct);\n\n // params\n var obj = params(ct);\n for (var key in obj) this[key] = obj[key];\n};\n\n/**\n * Parse the given body `str`.\n *\n * Used for auto-parsing of bodies. Parsers\n * are defined on the `superagent.parse` object.\n *\n * @param {String} str\n * @return {Mixed}\n * @api private\n */\n\nResponse.prototype.parseBody = function(str){\n var parse = request.parse[this.type];\n return parse\n ? parse(str)\n : null;\n};\n\n/**\n * Set flags such as `.ok` based on `status`.\n *\n * For example a 2xx response will give you a `.ok` of __true__\n * whereas 5xx will be __false__ and `.error` will be __true__. The\n * `.clientError` and `.serverError` are also available to be more\n * specific, and `.statusType` is the class of error ranging from 1..5\n * sometimes useful for mapping respond colors etc.\n *\n * \"sugar\" properties are also defined for common cases. Currently providing:\n *\n * - .noContent\n * - .badRequest\n * - .unauthorized\n * - .notAcceptable\n * - .notFound\n *\n * @param {Number} status\n * @api private\n */\n\nResponse.prototype.setStatusProperties = function(status){\n var type = status / 100 | 0;\n\n // status / class\n this.status = status;\n this.statusType = type;\n\n // basics\n this.info = 1 == type;\n this.ok = 2 == type;\n this.clientError = 4 == type;\n this.serverError = 5 == type;\n this.error = (4 == type || 5 == type)\n ? this.toError()\n : false;\n\n // sugar\n this.accepted = 202 == status;\n this.noContent = 204 == status || 1223 == status;\n this.badRequest = 400 == status;\n this.unauthorized = 401 == status;\n this.notAcceptable = 406 == status;\n this.notFound = 404 == status;\n this.forbidden = 403 == status;\n};\n\n/**\n * Return an `Error` representative of this response.\n *\n * @return {Error}\n * @api public\n */\n\nResponse.prototype.toError = function(){\n var req = this.req;\n var method = req.method;\n var url = req.url;\n\n var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';\n var err = new Error(msg);\n err.status = this.status;\n err.method = method;\n err.url = url;\n\n return err;\n};\n\n/**\n * Expose `Response`.\n */\n\nrequest.Response = Response;\n\n/**\n * Initialize a new `Request` with the given `method` and `url`.\n *\n * @param {String} method\n * @param {String} url\n * @api public\n */\n\nfunction Request(method, url) {\n var self = this;\n Emitter.call(this);\n this._query = this._query || [];\n this.method = method;\n this.url = url;\n this.header = {};\n this._header = {};\n this.on('end', function(){\n var res = new Response(self);\n if ('HEAD' == method) res.text = null;\n self.callback(null, res);\n });\n}\n\n/**\n * Mixin `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Allow for extension\n */\n\nRequest.prototype.use = function(fn) {\n fn(this);\n return this;\n}\n\n/**\n * Set timeout to `ms`.\n *\n * @param {Number} ms\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.timeout = function(ms){\n this._timeout = ms;\n return this;\n};\n\n/**\n * Clear previous timeout.\n *\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.clearTimeout = function(){\n this._timeout = 0;\n clearTimeout(this._timer);\n return this;\n};\n\n/**\n * Abort the request, and clear potential timeout.\n *\n * @return {Request}\n * @api public\n */\n\nRequest.prototype.abort = function(){\n if (this.aborted) return;\n this.aborted = true;\n this.xhr.abort();\n this.clearTimeout();\n this.emit('abort');\n return this;\n};\n\n/**\n * Set header `field` to `val`, or multiple fields with one object.\n *\n * Examples:\n *\n * req.get('/')\n * .set('Accept', 'application/json')\n * .set('X-API-Key', 'foobar')\n * .end(callback);\n *\n * req.get('/')\n * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })\n * .end(callback);\n *\n * @param {String|Object} field\n * @param {String} val\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.set = function(field, val){\n if (isObject(field)) {\n for (var key in field) {\n this.set(key, field[key]);\n }\n return this;\n }\n this._header[field.toLowerCase()] = val;\n this.header[field] = val;\n return this;\n};\n\n/**\n * Get case-insensitive header `field` value.\n *\n * @param {String} field\n * @return {String}\n * @api private\n */\n\nRequest.prototype.getHeader = function(field){\n return this._header[field.toLowerCase()];\n};\n\n/**\n * Set Content-Type to `type`, mapping values from `request.types`.\n *\n * Examples:\n *\n * superagent.types.xml = 'application/xml';\n *\n * request.post('/')\n * .type('xml')\n * .send(xmlstring)\n * .end(callback);\n *\n * request.post('/')\n * .type('application/xml')\n * .send(xmlstring)\n * .end(callback);\n *\n * @param {String} type\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.type = function(type){\n this.set('Content-Type', request.types[type] || type);\n return this;\n};\n\n/**\n * Set Accept to `type`, mapping values from `request.types`.\n *\n * Examples:\n *\n * superagent.types.json = 'application/json';\n *\n * request.get('/agent')\n * .accept('json')\n * .end(callback);\n *\n * request.get('/agent')\n * .accept('application/json')\n * .end(callback);\n *\n * @param {String} accept\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.accept = function(type){\n this.set('Accept', request.types[type] || type);\n return this;\n};\n\n/**\n * Set Authorization field value with `user` and `pass`.\n *\n * @param {String} user\n * @param {String} pass\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.auth = function(user, pass){\n var str = btoa(user + ':' + pass);\n this.set('Authorization', 'Basic ' + str);\n return this;\n};\n\n/**\n* Add query-string `val`.\n*\n* Examples:\n*\n* request.get('/shoes')\n* .query('size=10')\n* .query({ color: 'blue' })\n*\n* @param {Object|String} val\n* @return {Request} for chaining\n* @api public\n*/\n\nRequest.prototype.query = function(val){\n if ('string' != typeof val) val = serialize(val);\n if (val) this._query.push(val);\n return this;\n};\n\n/**\n * Write the field `name` and `val` for \"multipart/form-data\"\n * request bodies.\n *\n * ``` js\n * request.post('/upload')\n * .field('foo', 'bar')\n * .end(callback);\n * ```\n *\n * @param {String} name\n * @param {String|Blob|File} val\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.field = function(name, val){\n if (!this._formData) this._formData = new FormData();\n this._formData.append(name, val);\n return this;\n};\n\n/**\n * Queue the given `file` as an attachment to the specified `field`,\n * with optional `filename`.\n *\n * ``` js\n * request.post('/upload')\n * .attach(new Blob(['hey!'], { type: \"text/html\"}))\n * .end(callback);\n * ```\n *\n * @param {String} field\n * @param {Blob|File} file\n * @param {String} filename\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.attach = function(field, file, filename){\n if (!this._formData) this._formData = new FormData();\n this._formData.append(field, file, filename);\n return this;\n};\n\n/**\n * Send `data`, defaulting the `.type()` to \"json\" when\n * an object is given.\n *\n * Examples:\n *\n * // querystring\n * request.get('/search')\n * .end(callback)\n *\n * // multiple data \"writes\"\n * request.get('/search')\n * .send({ search: 'query' })\n * .send({ range: '1..5' })\n * .send({ order: 'desc' })\n * .end(callback)\n *\n * // manual json\n * request.post('/user')\n * .type('json')\n * .send('{\"name\":\"tj\"})\n * .end(callback)\n *\n * // auto json\n * request.post('/user')\n * .send({ name: 'tj' })\n * .end(callback)\n *\n * // manual x-www-form-urlencoded\n * request.post('/user')\n * .type('form')\n * .send('name=tj')\n * .end(callback)\n *\n * // auto x-www-form-urlencoded\n * request.post('/user')\n * .type('form')\n * .send({ name: 'tj' })\n * .end(callback)\n *\n * // defaults to x-www-form-urlencoded\n * request.post('/user')\n * .send('name=tobi')\n * .send('species=ferret')\n * .end(callback)\n *\n * @param {String|Object} data\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.send = function(data){\n var obj = isObject(data);\n var type = this.getHeader('Content-Type');\n\n // merge\n if (obj && isObject(this._data)) {\n for (var key in data) {\n this._data[key] = data[key];\n }\n } else if ('string' == typeof data) {\n if (!type) this.type('form');\n type = this.getHeader('Content-Type');\n if ('application/x-www-form-urlencoded' == type) {\n this._data = this._data\n ? this._data + '&' + data\n : data;\n } else {\n this._data = (this._data || '') + data;\n }\n } else {\n this._data = data;\n }\n\n if (!obj) return this;\n if (!type) this.type('json');\n return this;\n};\n\n/**\n * Invoke the callback with `err` and `res`\n * and handle arity check.\n *\n * @param {Error} err\n * @param {Response} res\n * @api private\n */\n\nRequest.prototype.callback = function(err, res){\n var fn = this._callback;\n if (2 == fn.length) return fn(err, res);\n if (err) return this.emit('error', err);\n fn(res);\n};\n\n/**\n * Invoke callback with x-domain error.\n *\n * @api private\n */\n\nRequest.prototype.crossDomainError = function(){\n var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');\n err.crossDomain = true;\n this.callback(err);\n};\n\n/**\n * Invoke callback with timeout error.\n *\n * @api private\n */\n\nRequest.prototype.timeoutError = function(){\n var timeout = this._timeout;\n var err = new Error('timeout of ' + timeout + 'ms exceeded');\n err.timeout = timeout;\n this.callback(err);\n};\n\n/**\n * Enable transmission of cookies with x-domain requests.\n *\n * Note that for this to work the origin must not be\n * using \"Access-Control-Allow-Origin\" with a wildcard,\n * and also must set \"Access-Control-Allow-Credentials\"\n * to \"true\".\n *\n * @api public\n */\n\nRequest.prototype.withCredentials = function(){\n this._withCredentials = true;\n return this;\n};\n\n/**\n * Initiate request, invoking callback `fn(res)`\n * with an instanceof `Response`.\n *\n * @param {Function} fn\n * @return {Request} for chaining\n * @api public\n */\n\nRequest.prototype.end = function(fn){\n var self = this;\n var xhr = this.xhr = getXHR();\n var query = this._query.join('&');\n var timeout = this._timeout;\n var data = this._formData || this._data;\n\n // store callback\n this._callback = fn || noop;\n\n // state change\n xhr.onreadystatechange = function(){\n if (4 != xhr.readyState) return;\n if (0 == xhr.status) {\n if (self.aborted) return self.timeoutError();\n return self.crossDomainError();\n }\n self.emit('end');\n };\n\n // progress\n if (xhr.upload) {\n xhr.upload.onprogress = function(e){\n e.percent = e.loaded / e.total * 100;\n self.emit('progress', e);\n };\n }\n\n // timeout\n if (timeout && !this._timer) {\n this._timer = setTimeout(function(){\n self.abort();\n }, timeout);\n }\n\n // querystring\n if (query) {\n query = request.serializeObject(query);\n this.url += ~this.url.indexOf('?')\n ? '&' + query\n : '?' + query;\n }\n\n // initiate request\n xhr.open(this.method, this.url, true);\n\n // CORS\n if (this._withCredentials) xhr.withCredentials = true;\n\n // body\n if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {\n // serialize stuff\n var serialize = request.serialize[this.getHeader('Content-Type')];\n if (serialize) data = serialize(data);\n }\n\n // set header fields\n for (var field in this.header) {\n if (null == this.header[field]) continue;\n xhr.setRequestHeader(field, this.header[field]);\n }\n\n // send stuff\n this.emit('request', this);\n xhr.send(data);\n return this;\n};\n\n/**\n * Expose `Request`.\n */\n\nrequest.Request = Request;\n\n/**\n * Issue a request:\n *\n * Examples:\n *\n * request('GET', '/users').end(callback)\n * request('/users').end(callback)\n * request('/users', callback)\n *\n * @param {String} method\n * @param {String|Function} url or callback\n * @return {Request}\n * @api public\n */\n\nfunction request(method, url) {\n // callback\n if ('function' == typeof url) {\n return new Request('GET', method).end(url);\n }\n\n // url first\n if (1 == arguments.length) {\n return new Request('GET', method);\n }\n\n return new Request(method, url);\n}\n\n/**\n * GET `url` with optional callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed|Function} data or fn\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.get = function(url, data, fn){\n var req = request('GET', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.query(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * HEAD `url` with optional callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed|Function} data or fn\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.head = function(url, data, fn){\n var req = request('HEAD', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * DELETE `url` with optional callback `fn(res)`.\n *\n * @param {String} url\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.del = function(url, fn){\n var req = request('DELETE', url);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * PATCH `url` with optional `data` and callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed} data\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.patch = function(url, data, fn){\n var req = request('PATCH', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * POST `url` with optional `data` and callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed} data\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.post = function(url, data, fn){\n var req = request('POST', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * PUT `url` with optional `data` and callback `fn(res)`.\n *\n * @param {String} url\n * @param {Mixed|Function} data or fn\n * @param {Function} fn\n * @return {Request}\n * @api public\n */\n\nrequest.put = function(url, data, fn){\n var req = request('PUT', url);\n if ('function' == typeof data) fn = data, data = null;\n if (data) req.send(data);\n if (fn) req.end(fn);\n return req;\n};\n\n/**\n * Expose `request`.\n */\n\nmodule.exports = request;\n\n\n// WEBPACK FOOTER\n// module.id = 54\n// module.readableIdentifier = ./~/superagent/lib/client.js\n//@ sourceURL=webpack-module:///./~/superagent/lib/client.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {// JavaScript PBKDF2 Implementation\n// Based on http://git.io/qsv2zw\n// Licensed under LGPL v3\n// Copyright (c) 2013 jduncanator\n\nvar blocksize = 64\nvar zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0)\n\nmodule.exports = function (createHmac, exports) {\n exports = exports || {}\n\n exports.pbkdf2 = function(password, salt, iterations, keylen, cb) {\n if('function' !== typeof cb)\n throw new Error('No callback provided to pbkdf2');\n setTimeout(function () {\n cb(null, exports.pbkdf2Sync(password, salt, iterations, keylen))\n })\n }\n\n exports.pbkdf2Sync = function(key, salt, iterations, keylen) {\n if('number' !== typeof iterations)\n throw new TypeError('Iterations not a number')\n if(iterations < 0)\n throw new TypeError('Bad iterations')\n if('number' !== typeof keylen)\n throw new TypeError('Key length not a number')\n if(keylen < 0)\n throw new TypeError('Bad key length')\n\n //stretch key to the correct length that hmac wants it,\n //otherwise this will happen every time hmac is called\n //twice per iteration.\n var key = !Buffer.isBuffer(key) ? new Buffer(key) : key\n\n if(key.length > blocksize) {\n key = createHash(alg).update(key).digest()\n } else if(key.length < blocksize) {\n key = Buffer.concat([key, zeroBuffer], blocksize)\n }\n\n var HMAC;\n var cplen, p = 0, i = 1, itmp = new Buffer(4), digtmp;\n var out = new Buffer(keylen);\n out.fill(0);\n while(keylen) {\n if(keylen > 20)\n cplen = 20;\n else\n cplen = keylen;\n\n /* We are unlikely to ever use more than 256 blocks (5120 bits!)\n * but just in case...\n */\n itmp[0] = (i >> 24) & 0xff;\n itmp[1] = (i >> 16) & 0xff;\n itmp[2] = (i >> 8) & 0xff;\n itmp[3] = i & 0xff;\n\n HMAC = createHmac('sha1', key);\n HMAC.update(salt)\n HMAC.update(itmp);\n digtmp = HMAC.digest();\n digtmp.copy(out, p, 0, cplen);\n\n for(var j = 1; j < iterations; j++) {\n HMAC = createHmac('sha1', key);\n HMAC.update(digtmp);\n digtmp = HMAC.digest();\n for(var k = 0; k < cplen; k++) {\n out[k] ^= digtmp[k];\n }\n }\n keylen -= cplen;\n i++;\n p += cplen;\n }\n\n return out;\n }\n\n return exports\n}\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 54\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/pbkdf2.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/pbkdf2.js"); /***/ }, /* 55 */ @@ -388,25 +388,25 @@ var ripple = /* 57 */ /***/ function(module, exports, __webpack_require__) { - eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\n// If obj.hasOwnProperty has been overridden, then calling\n// obj.hasOwnProperty(prop) will break.\n// See: https://github.com/joyent/node/issues/1707\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nmodule.exports = function(qs, sep, eq, options) {\n sep = sep || '&';\n eq = eq || '=';\n var obj = {};\n\n if (typeof qs !== 'string' || qs.length === 0) {\n return obj;\n }\n\n var regexp = /\\+/g;\n qs = qs.split(sep);\n\n var maxKeys = 1000;\n if (options && typeof options.maxKeys === 'number') {\n maxKeys = options.maxKeys;\n }\n\n var len = qs.length;\n // maxKeys <= 0 means that we should not limit keys count\n if (maxKeys > 0 && len > maxKeys) {\n len = maxKeys;\n }\n\n for (var i = 0; i < len; ++i) {\n var x = qs[i].replace(regexp, '%20'),\n idx = x.indexOf(eq),\n kstr, vstr, k, v;\n\n if (idx >= 0) {\n kstr = x.substr(0, idx);\n vstr = x.substr(idx + 1);\n } else {\n kstr = x;\n vstr = '';\n }\n\n k = decodeURIComponent(kstr);\n v = decodeURIComponent(vstr);\n\n if (!hasOwnProperty(obj, k)) {\n obj[k] = v;\n } else if (isArray(obj[k])) {\n obj[k].push(v);\n } else {\n obj[k] = [obj[k], v];\n }\n }\n\n return obj;\n};\n\nvar isArray = Array.isArray || function (xs) {\n return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\n\n// WEBPACK FOOTER\n// module.id = 57\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/querystring-es3/decode.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/querystring-es3/decode.js"); + eval("exports.read = function(buffer, offset, isLE, mLen, nBytes) {\n var e, m,\n eLen = nBytes * 8 - mLen - 1,\n eMax = (1 << eLen) - 1,\n eBias = eMax >> 1,\n nBits = -7,\n i = isLE ? (nBytes - 1) : 0,\n d = isLE ? -1 : 1,\n s = buffer[offset + i];\n\n i += d;\n\n e = s & ((1 << (-nBits)) - 1);\n s >>= (-nBits);\n nBits += eLen;\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);\n\n m = e & ((1 << (-nBits)) - 1);\n e >>= (-nBits);\n nBits += mLen;\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);\n\n if (e === 0) {\n e = 1 - eBias;\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity);\n } else {\n m = m + Math.pow(2, mLen);\n e = e - eBias;\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen);\n};\n\nexports.write = function(buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c,\n eLen = nBytes * 8 - mLen - 1,\n eMax = (1 << eLen) - 1,\n eBias = eMax >> 1,\n rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),\n i = isLE ? 0 : (nBytes - 1),\n d = isLE ? 1 : -1,\n s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;\n\n value = Math.abs(value);\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0;\n e = eMax;\n } else {\n e = Math.floor(Math.log(value) / Math.LN2);\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--;\n c *= 2;\n }\n if (e + eBias >= 1) {\n value += rt / c;\n } else {\n value += rt * Math.pow(2, 1 - eBias);\n }\n if (value * c >= 2) {\n e++;\n c /= 2;\n }\n\n if (e + eBias >= eMax) {\n m = 0;\n e = eMax;\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen);\n e = e + eBias;\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);\n e = 0;\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);\n\n e = (e << mLen) | m;\n eLen += mLen;\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);\n\n buffer[offset + i - d] |= s * 128;\n};\n\n\n// WEBPACK FOOTER\n// module.id = 57\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/buffer/~/ieee754/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/buffer/~/ieee754/index.js"); /***/ }, /* 58 */ /***/ function(module, exports, __webpack_require__) { - eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar stringifyPrimitive = function(v) {\n switch (typeof v) {\n case 'string':\n return v;\n\n case 'boolean':\n return v ? 'true' : 'false';\n\n case 'number':\n return isFinite(v) ? v : '';\n\n default:\n return '';\n }\n};\n\nmodule.exports = function(obj, sep, eq, name) {\n sep = sep || '&';\n eq = eq || '=';\n if (obj === null) {\n obj = undefined;\n }\n\n if (typeof obj === 'object') {\n return map(objectKeys(obj), function(k) {\n var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;\n if (isArray(obj[k])) {\n return map(obj[k], function(v) {\n return ks + encodeURIComponent(stringifyPrimitive(v));\n }).join(sep);\n } else {\n return ks + encodeURIComponent(stringifyPrimitive(obj[k]));\n }\n }).join(sep);\n\n }\n\n if (!name) return '';\n return encodeURIComponent(stringifyPrimitive(name)) + eq +\n encodeURIComponent(stringifyPrimitive(obj));\n};\n\nvar isArray = Array.isArray || function (xs) {\n return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\nfunction map (xs, f) {\n if (xs.map) return xs.map(f);\n var res = [];\n for (var i = 0; i < xs.length; i++) {\n res.push(f(xs[i], i));\n }\n return res;\n}\n\nvar objectKeys = Object.keys || function (obj) {\n var res = [];\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);\n }\n return res;\n};\n\n\n// WEBPACK FOOTER\n// module.id = 58\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/querystring-es3/encode.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/querystring-es3/encode.js"); + eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\n// If obj.hasOwnProperty has been overridden, then calling\n// obj.hasOwnProperty(prop) will break.\n// See: https://github.com/joyent/node/issues/1707\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nmodule.exports = function(qs, sep, eq, options) {\n sep = sep || '&';\n eq = eq || '=';\n var obj = {};\n\n if (typeof qs !== 'string' || qs.length === 0) {\n return obj;\n }\n\n var regexp = /\\+/g;\n qs = qs.split(sep);\n\n var maxKeys = 1000;\n if (options && typeof options.maxKeys === 'number') {\n maxKeys = options.maxKeys;\n }\n\n var len = qs.length;\n // maxKeys <= 0 means that we should not limit keys count\n if (maxKeys > 0 && len > maxKeys) {\n len = maxKeys;\n }\n\n for (var i = 0; i < len; ++i) {\n var x = qs[i].replace(regexp, '%20'),\n idx = x.indexOf(eq),\n kstr, vstr, k, v;\n\n if (idx >= 0) {\n kstr = x.substr(0, idx);\n vstr = x.substr(idx + 1);\n } else {\n kstr = x;\n vstr = '';\n }\n\n k = decodeURIComponent(kstr);\n v = decodeURIComponent(vstr);\n\n if (!hasOwnProperty(obj, k)) {\n obj[k] = v;\n } else if (isArray(obj[k])) {\n obj[k].push(v);\n } else {\n obj[k] = [obj[k], v];\n }\n }\n\n return obj;\n};\n\nvar isArray = Array.isArray || function (xs) {\n return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\n\n// WEBPACK FOOTER\n// module.id = 58\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/querystring-es3/decode.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/querystring-es3/decode.js"); /***/ }, /* 59 */ /***/ function(module, exports, __webpack_require__) { - eval("/*\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n */\n\nvar helpers = __webpack_require__(67);\n\n/*\n * Calculate the MD5 of an array of little-endian words, and a bit length\n */\nfunction core_md5(x, len)\n{\n /* append padding */\n x[len >> 5] |= 0x80 << ((len) % 32);\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n\n for(var i = 0; i < x.length; i += 16)\n {\n var olda = a;\n var oldb = b;\n var oldc = c;\n var oldd = d;\n\n a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);\n d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);\n c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);\n b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);\n a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);\n d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);\n c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);\n b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);\n a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);\n d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);\n c = md5_ff(c, d, a, b, x[i+10], 17, -42063);\n b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);\n a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);\n d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);\n c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);\n b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);\n\n a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);\n d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);\n c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);\n b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);\n a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);\n d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);\n c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);\n b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);\n a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);\n d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);\n c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);\n b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);\n a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);\n d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);\n c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);\n b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);\n\n a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);\n d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);\n c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);\n b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);\n a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);\n d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);\n c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);\n b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);\n a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);\n d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);\n c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);\n b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);\n a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);\n d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);\n c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);\n b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);\n\n a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);\n d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);\n c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);\n b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);\n a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);\n d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);\n c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);\n b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);\n a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);\n d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);\n c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);\n b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);\n a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);\n d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);\n c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);\n b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);\n\n a = safe_add(a, olda);\n b = safe_add(b, oldb);\n c = safe_add(c, oldc);\n d = safe_add(d, oldd);\n }\n return Array(a, b, c, d);\n\n}\n\n/*\n * These functions implement the four basic operations the algorithm uses.\n */\nfunction md5_cmn(q, a, b, x, s, t)\n{\n return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);\n}\nfunction md5_ff(a, b, c, d, x, s, t)\n{\n return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\n}\nfunction md5_gg(a, b, c, d, x, s, t)\n{\n return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\n}\nfunction md5_hh(a, b, c, d, x, s, t)\n{\n return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n}\nfunction md5_ii(a, b, c, d, x, s, t)\n{\n return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\n}\n\n/*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\nfunction safe_add(x, y)\n{\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xFFFF);\n}\n\n/*\n * Bitwise rotate a 32-bit number to the left.\n */\nfunction bit_rol(num, cnt)\n{\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\nmodule.exports = function md5(buf) {\n return helpers.hash(buf, core_md5, 16);\n};\n\n\n// WEBPACK FOOTER\n// module.id = 59\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/md5.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/md5.js"); + eval("// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar stringifyPrimitive = function(v) {\n switch (typeof v) {\n case 'string':\n return v;\n\n case 'boolean':\n return v ? 'true' : 'false';\n\n case 'number':\n return isFinite(v) ? v : '';\n\n default:\n return '';\n }\n};\n\nmodule.exports = function(obj, sep, eq, name) {\n sep = sep || '&';\n eq = eq || '=';\n if (obj === null) {\n obj = undefined;\n }\n\n if (typeof obj === 'object') {\n return map(objectKeys(obj), function(k) {\n var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;\n if (isArray(obj[k])) {\n return map(obj[k], function(v) {\n return ks + encodeURIComponent(stringifyPrimitive(v));\n }).join(sep);\n } else {\n return ks + encodeURIComponent(stringifyPrimitive(obj[k]));\n }\n }).join(sep);\n\n }\n\n if (!name) return '';\n return encodeURIComponent(stringifyPrimitive(name)) + eq +\n encodeURIComponent(stringifyPrimitive(obj));\n};\n\nvar isArray = Array.isArray || function (xs) {\n return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\nfunction map (xs, f) {\n if (xs.map) return xs.map(f);\n var res = [];\n for (var i = 0; i < xs.length; i++) {\n res.push(f(xs[i], i));\n }\n return res;\n}\n\nvar objectKeys = Object.keys || function (obj) {\n var res = [];\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);\n }\n return res;\n};\n\n\n// WEBPACK FOOTER\n// module.id = 59\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/querystring-es3/encode.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/querystring-es3/encode.js"); /***/ }, /* 60 */ /***/ function(module, exports, __webpack_require__) { - eval("exports.read = function(buffer, offset, isLE, mLen, nBytes) {\n var e, m,\n eLen = nBytes * 8 - mLen - 1,\n eMax = (1 << eLen) - 1,\n eBias = eMax >> 1,\n nBits = -7,\n i = isLE ? (nBytes - 1) : 0,\n d = isLE ? -1 : 1,\n s = buffer[offset + i];\n\n i += d;\n\n e = s & ((1 << (-nBits)) - 1);\n s >>= (-nBits);\n nBits += eLen;\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);\n\n m = e & ((1 << (-nBits)) - 1);\n e >>= (-nBits);\n nBits += mLen;\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);\n\n if (e === 0) {\n e = 1 - eBias;\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity);\n } else {\n m = m + Math.pow(2, mLen);\n e = e - eBias;\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen);\n};\n\nexports.write = function(buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c,\n eLen = nBytes * 8 - mLen - 1,\n eMax = (1 << eLen) - 1,\n eBias = eMax >> 1,\n rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),\n i = isLE ? 0 : (nBytes - 1),\n d = isLE ? 1 : -1,\n s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;\n\n value = Math.abs(value);\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0;\n e = eMax;\n } else {\n e = Math.floor(Math.log(value) / Math.LN2);\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--;\n c *= 2;\n }\n if (e + eBias >= 1) {\n value += rt / c;\n } else {\n value += rt * Math.pow(2, 1 - eBias);\n }\n if (value * c >= 2) {\n e++;\n c /= 2;\n }\n\n if (e + eBias >= eMax) {\n m = 0;\n e = eMax;\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen);\n e = e + eBias;\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);\n e = 0;\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);\n\n e = (e << mLen) | m;\n eLen += mLen;\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);\n\n buffer[offset + i - d] |= s * 128;\n};\n\n\n// WEBPACK FOOTER\n// module.id = 60\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/buffer/~/ieee754/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/buffer/~/ieee754/index.js"); + eval("/*\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n */\n\nvar helpers = __webpack_require__(69);\n\n/*\n * Calculate the MD5 of an array of little-endian words, and a bit length\n */\nfunction core_md5(x, len)\n{\n /* append padding */\n x[len >> 5] |= 0x80 << ((len) % 32);\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n\n for(var i = 0; i < x.length; i += 16)\n {\n var olda = a;\n var oldb = b;\n var oldc = c;\n var oldd = d;\n\n a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);\n d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);\n c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);\n b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);\n a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);\n d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);\n c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);\n b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);\n a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);\n d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);\n c = md5_ff(c, d, a, b, x[i+10], 17, -42063);\n b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);\n a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);\n d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);\n c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);\n b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);\n\n a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);\n d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);\n c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);\n b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);\n a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);\n d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);\n c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);\n b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);\n a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);\n d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);\n c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);\n b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);\n a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);\n d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);\n c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);\n b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);\n\n a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);\n d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);\n c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);\n b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);\n a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);\n d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);\n c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);\n b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);\n a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);\n d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);\n c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);\n b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);\n a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);\n d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);\n c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);\n b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);\n\n a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);\n d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);\n c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);\n b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);\n a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);\n d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);\n c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);\n b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);\n a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);\n d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);\n c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);\n b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);\n a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);\n d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);\n c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);\n b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);\n\n a = safe_add(a, olda);\n b = safe_add(b, oldb);\n c = safe_add(c, oldc);\n d = safe_add(d, oldd);\n }\n return Array(a, b, c, d);\n\n}\n\n/*\n * These functions implement the four basic operations the algorithm uses.\n */\nfunction md5_cmn(q, a, b, x, s, t)\n{\n return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);\n}\nfunction md5_ff(a, b, c, d, x, s, t)\n{\n return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\n}\nfunction md5_gg(a, b, c, d, x, s, t)\n{\n return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\n}\nfunction md5_hh(a, b, c, d, x, s, t)\n{\n return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n}\nfunction md5_ii(a, b, c, d, x, s, t)\n{\n return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\n}\n\n/*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\nfunction safe_add(x, y)\n{\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xFFFF);\n}\n\n/*\n * Bitwise rotate a 32-bit number to the left.\n */\nfunction bit_rol(num, cnt)\n{\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\nmodule.exports = function md5(buf) {\n return helpers.hash(buf, core_md5, 16);\n};\n\n\n// WEBPACK FOOTER\n// module.id = 60\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/md5.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/md5.js"); /***/ }, /* 61 */ @@ -442,25 +442,25 @@ var ripple = /* 66 */ /***/ function(module, exports, __webpack_require__) { - eval("var exports = module.exports = function (alg) {\n var Alg = exports[alg]\n if(!Alg) throw new Error(alg + ' is not supported (we accept pull requests)')\n return new Alg()\n}\n\nvar Buffer = __webpack_require__(79).Buffer\nvar Hash = __webpack_require__(72)(Buffer)\n\nexports.sha =\nexports.sha1 = __webpack_require__(73)(Buffer, Hash)\nexports.sha256 = __webpack_require__(74)(Buffer, Hash)\n\n\n// WEBPACK FOOTER\n// module.id = 66\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/~/sha.js/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/~/sha.js/index.js"); + eval("\n/**\n * Reduce `arr` with `fn`.\n *\n * @param {Array} arr\n * @param {Function} fn\n * @param {Mixed} initial\n *\n * TODO: combatible error handling?\n */\n\nmodule.exports = function(arr, fn, initial){ \n var idx = 0;\n var len = arr.length;\n var curr = arguments.length == 3\n ? initial\n : arr[idx++];\n\n while (idx < len) {\n curr = fn.call(null, curr, arr[idx], ++idx, arr);\n }\n \n return curr;\n};\n\n// WEBPACK FOOTER\n// module.id = 66\n// module.readableIdentifier = ./~/superagent/~/reduce-component/index.js\n//@ sourceURL=webpack-module:///./~/superagent/~/reduce-component/index.js"); /***/ }, /* 67 */ /***/ function(module, exports, __webpack_require__) { - eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var intSize = 4;\nvar zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);\nvar chrsz = 8;\n\nfunction toArray(buf, bigEndian) {\n if ((buf.length % intSize) !== 0) {\n var len = buf.length + (intSize - (buf.length % intSize));\n buf = Buffer.concat([buf, zeroBuffer], len);\n }\n\n var arr = [];\n var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;\n for (var i = 0; i < buf.length; i += intSize) {\n arr.push(fn.call(buf, i));\n }\n return arr;\n}\n\nfunction toBuffer(arr, size, bigEndian) {\n var buf = new Buffer(size);\n var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;\n for (var i = 0; i < arr.length; i++) {\n fn.call(buf, arr[i], i * 4, true);\n }\n return buf;\n}\n\nfunction hash(buf, fn, hashSize, bigEndian) {\n if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);\n var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);\n return toBuffer(arr, hashSize, bigEndian);\n}\n\nmodule.exports = { hash: hash };\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 67\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/helpers.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/helpers.js"); + eval("\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n for (var key in Emitter.prototype) {\n obj[key] = Emitter.prototype[key];\n }\n return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n (this._callbacks[event] = this._callbacks[event] || [])\n .push(fn);\n return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n var self = this;\n this._callbacks = this._callbacks || {};\n\n function on() {\n self.off(event, on);\n fn.apply(this, arguments);\n }\n\n on.fn = fn;\n this.on(event, on);\n return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n\n // all\n if (0 == arguments.length) {\n this._callbacks = {};\n return this;\n }\n\n // specific event\n var callbacks = this._callbacks[event];\n if (!callbacks) return this;\n\n // remove all handlers\n if (1 == arguments.length) {\n delete this._callbacks[event];\n return this;\n }\n\n // remove specific handler\n var cb;\n for (var i = 0; i < callbacks.length; i++) {\n cb = callbacks[i];\n if (cb === fn || cb.fn === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n this._callbacks = this._callbacks || {};\n var args = [].slice.call(arguments, 1)\n , callbacks = this._callbacks[event];\n\n if (callbacks) {\n callbacks = callbacks.slice(0);\n for (var i = 0, len = callbacks.length; i < len; ++i) {\n callbacks[i].apply(this, args);\n }\n }\n\n return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n this._callbacks = this._callbacks || {};\n return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n return !! this.listeners(event).length;\n};\n\n\n// WEBPACK FOOTER\n// module.id = 67\n// module.readableIdentifier = ./~/superagent/~/component-emitter/index.js\n//@ sourceURL=webpack-module:///./~/superagent/~/component-emitter/index.js"); /***/ }, /* 68 */ /***/ function(module, exports, __webpack_require__) { - eval("\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n for (var key in Emitter.prototype) {\n obj[key] = Emitter.prototype[key];\n }\n return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n (this._callbacks[event] = this._callbacks[event] || [])\n .push(fn);\n return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n var self = this;\n this._callbacks = this._callbacks || {};\n\n function on() {\n self.off(event, on);\n fn.apply(this, arguments);\n }\n\n on.fn = fn;\n this.on(event, on);\n return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n this._callbacks = this._callbacks || {};\n\n // all\n if (0 == arguments.length) {\n this._callbacks = {};\n return this;\n }\n\n // specific event\n var callbacks = this._callbacks[event];\n if (!callbacks) return this;\n\n // remove all handlers\n if (1 == arguments.length) {\n delete this._callbacks[event];\n return this;\n }\n\n // remove specific handler\n var cb;\n for (var i = 0; i < callbacks.length; i++) {\n cb = callbacks[i];\n if (cb === fn || cb.fn === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n this._callbacks = this._callbacks || {};\n var args = [].slice.call(arguments, 1)\n , callbacks = this._callbacks[event];\n\n if (callbacks) {\n callbacks = callbacks.slice(0);\n for (var i = 0, len = callbacks.length; i < len; ++i) {\n callbacks[i].apply(this, args);\n }\n }\n\n return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n this._callbacks = this._callbacks || {};\n return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n return !! this.listeners(event).length;\n};\n\n\n// WEBPACK FOOTER\n// module.id = 68\n// module.readableIdentifier = ./~/superagent/~/component-emitter/index.js\n//@ sourceURL=webpack-module:///./~/superagent/~/component-emitter/index.js"); + eval("var exports = module.exports = function (alg) {\n var Alg = exports[alg]\n if(!Alg) throw new Error(alg + ' is not supported (we accept pull requests)')\n return new Alg()\n}\n\nvar Buffer = __webpack_require__(79).Buffer\nvar Hash = __webpack_require__(72)(Buffer)\n\nexports.sha =\nexports.sha1 = __webpack_require__(73)(Buffer, Hash)\nexports.sha256 = __webpack_require__(74)(Buffer, Hash)\n\n\n// WEBPACK FOOTER\n// module.id = 68\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/~/sha.js/index.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/~/sha.js/index.js"); /***/ }, /* 69 */ /***/ function(module, exports, __webpack_require__) { - eval("\n/**\n * Reduce `arr` with `fn`.\n *\n * @param {Array} arr\n * @param {Function} fn\n * @param {Mixed} initial\n *\n * TODO: combatible error handling?\n */\n\nmodule.exports = function(arr, fn, initial){ \n var idx = 0;\n var len = arr.length;\n var curr = arguments.length == 3\n ? initial\n : arr[idx++];\n\n while (idx < len) {\n curr = fn.call(null, curr, arr[idx], ++idx, arr);\n }\n \n return curr;\n};\n\n// WEBPACK FOOTER\n// module.id = 69\n// module.readableIdentifier = ./~/superagent/~/reduce-component/index.js\n//@ sourceURL=webpack-module:///./~/superagent/~/reduce-component/index.js"); + eval("/* WEBPACK VAR INJECTION */(function(Buffer) {var intSize = 4;\nvar zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);\nvar chrsz = 8;\n\nfunction toArray(buf, bigEndian) {\n if ((buf.length % intSize) !== 0) {\n var len = buf.length + (intSize - (buf.length % intSize));\n buf = Buffer.concat([buf, zeroBuffer], len);\n }\n\n var arr = [];\n var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;\n for (var i = 0; i < buf.length; i += intSize) {\n arr.push(fn.call(buf, i));\n }\n return arr;\n}\n\nfunction toBuffer(arr, size, bigEndian) {\n var buf = new Buffer(size);\n var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;\n for (var i = 0; i < arr.length; i++) {\n fn.call(buf, arr[i], i * 4, true);\n }\n return buf;\n}\n\nfunction hash(buf, fn, hashSize, bigEndian) {\n if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);\n var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);\n return toBuffer(arr, hashSize, bigEndian);\n}\n\nmodule.exports = { hash: hash };\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(40).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 69\n// module.readableIdentifier = (webpack)/~/node-libs-browser/~/crypto-browserify/helpers.js\n//@ sourceURL=webpack-module:///(webpack)/~/node-libs-browser/~/crypto-browserify/helpers.js"); /***/ }, /* 70 */ diff --git a/package.json b/package.json index 4bc8a956e..1056084ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ripple-client", - "version": "1.0.4", + "version": "1.0.5", "description": "Client for the Ripple payment network", "author": { "name": "Ripple Labs, Inc.", diff --git a/src/js/services/authinfo.js b/src/js/services/authinfo.js index 449292356..9c0f2cc58 100644 --- a/src/js/services/authinfo.js +++ b/src/js/services/authinfo.js @@ -1,3 +1,4 @@ + /** * AUTH INFO * @@ -47,7 +48,7 @@ module.factory('rpAuthInfo', ['$rootScope', 'rpRippleTxt', '$http', }, error: function () { $scope.$apply(function() { - callback(new Error("Authentication info server unreachable")); + callback(new Error("Cannot connect to our login system, please try again later or contact support@ripple.com.")); }); }, success: function (data) { diff --git a/src/js/services/books.js b/src/js/services/books.js index 600381b37..f8e3e50ca 100644 --- a/src/js/services/books.js +++ b/src/js/services/books.js @@ -42,13 +42,13 @@ function(net, $q, $scope, $filter, $id) { if (d.TakerGets.value) { d.TakerGets.value = d.taker_gets_funded; } else { - d.TakerGets = d.taker_gets_funded; + d.TakerGets = parseInt(Number(d.taker_gets_funded), 10); } if (d.TakerPays.value) { d.TakerPays.value = d.taker_pays_funded; } else { - d.TakerPays = d.taker_pays_funded; + d.TakerPays = parseInt(Number(d.taker_pays_funded), 10); } d.TakerGets = Amount.from_json(d.TakerGets);