diff --git a/deps/js/ripple.js b/deps/js/ripple.js index 2591c7c5b..0fac183cf 100644 --- a/deps/js/ripple.js +++ b/deps/js/ripple.js @@ -56,7 +56,7 @@ var ripple = /***/ 1: /***/ function(module, exports, 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//\n\n// npm\nvar EventEmitter = require(27).EventEmitter;\nvar util = require(28);\n\nvar Request = require(14).Request;\nvar Server = require(10).Server;\nvar Amount = require(2).Amount;\nvar Currency = require(3).Currency;\nvar UInt160 = require(15).UInt160;\nvar Transaction = require(5).Transaction;\nvar Account = require(16).Account;\nvar Meta = require(6).Meta;\nvar OrderBook = require(17).OrderBook;\nvar PathFind = require(18).PathFind;\nvar RippleError = require(19).RippleError;\n\nvar utils = require(9);\nvar config = require(12);\nvar sjcl = require(11);\n\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\n { \n host: \n , port: \n , secure: \n }\n\n Events:\n 'connect'\n 'connected' (DEPRECATED)\n 'disconnect'\n 'disconnected' (DEPRECATED)\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\n this.trusted = opts.trusted;\n this.local_sequence = opts.local_sequence; // Locally track sequence numbers\n this.local_fee = opts.local_fee; // Locally set fees\n this.local_signing = (typeof opts.local_signing === 'undefined') ? true : Boolean(opts.local_signing);\n this.fee_cushion = (typeof opts.fee_cushion === 'undefined') ? 1.5 : Number(opts.fee_cushion);\n this.max_fee = (typeof opts.max_fee === 'undefined') ? Infinity : Number(opts.max_fee);\n this.id = 0;\n this.trace = Boolean(opts.trace);\n this._server_fatal = false; // True, if we know server exited.\n this._ledger_current_index = void(0);\n this._ledger_hash = void(0);\n this._ledger_time = void(0);\n this._stand_alone = void(0);\n this._testnet = void(0);\n this._transaction_subs = 0;\n this.online_target = false;\n this._online_state = 'closed'; // 'open', 'closed', 'connecting', 'closing'\n this.state = 'offline'; // 'online', 'offline'\n this.retry_timer = void(0);\n this.retry = void(0);\n\n this._load_base = 256;\n this._load_factor = 256;\n this._fee_ref = 10;\n this._fee_base = 10;\n this._reserve_base = void(0);\n this._reserve_inc = void(0);\n this._connection_count = 0;\n this._connected = false;\n this._connection_offset = 1000 * (Number(opts.connection_offset) || 5);\n\n this._last_tx = null;\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 this.accounts = {\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\n // account : { seq : __ }\n };\n\n // Account objects by AccountId.\n this._accounts = { };\n\n // OrderBook objects\n this._books = { };\n\n // Secrets that we know about.\n this.secrets = {\n // Secrets can be set by calling set_secret(account, secret).\n\n // account : secret\n };\n\n // Cache for various ledgers.\n // XXX Clear when ledger advances.\n this.ledgers = {\n current : {\n account_root : {}\n }\n };\n\n // Fallback for previous API\n if (!opts.hasOwnProperty('servers')) {\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 var pool = Number(server.pool) || 1;\n while (pool--) { self.add_server(server); };\n });\n\n // This is used to remove Node EventEmitter warnings\n var maxListeners = opts.maxListeners || opts.max_listeners || 0;\n this._servers.concat(this).forEach(function(emitter) {\n emitter.setMaxListeners(maxListeners);\n });\n\n function listener_added(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 function listener_removed(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('newListener', listener_added);\n this.on('removeListener', listener_removed);\n}\n\nutil.inherits(Remote, EventEmitter);\n\n// Flags for ledger entries. In support of account_root().\nRemote.flags = {\n account_root : {\n PasswordSpent: 0x00010000,\n RequireDestTag: 0x00020000,\n RequireAuth: 0x00040000,\n DisallowXRP: 0x00080000\n }\n};\n\nfunction isTemMalformed(engine_result_code) {\n return (engine_result_code >= -299 && engine_result_code < 199);\n};\n\nfunction isTefFailure(engine_result_code) {\n return (engine_result_code >= -299 && engine_result_code < 199);\n};\n\nRemote.from_config = function (obj, trace) {\n var serverConfig = typeof obj === 'string' ? config.servers[obj] : obj;\n\n var remote = new Remote(serverConfig, trace);\n\n function initialize_account(account) {\n var accountInfo = config.accounts[account];\n if (typeof accountInfo === 'object') {\n if (accountInfo.secret) {\n // Index by nickname ...\n remote.set_secret(account, accountInfo.secret);\n // ... and by account ID\n remote.set_secret(accountInfo.account, accountInfo.secret);\n }\n }\n }\n\n if (typeof config.accounts === 'object') {\n for (var account in config.accounts) {\n initialize_account(account);\n }\n }\n\n return remote;\n};\n\nRemote.create_remote = function(options, callback) {\n var remote = Remote.from_config(options);\n remote.connect(callback);\n return remote;\n};\n\nRemote.prototype.add_server = function (opts) {\n var self = this;\n\n var server = new Server(this, {\n host : opts.host || opts.websocket_ip,\n port : opts.port || opts.websocket_port,\n secure : opts.secure || opts.websocket_ssl\n });\n\n function server_message(data) {\n self._handle_message(data, server);\n }\n\n function server_connect() {\n self._connection_count++;\n self._set_state('online');\n if (opts.primary || !self._primary_server) {\n self._set_primary_server(server);\n }\n if (self._connection_count === self._servers.length) {\n self.emit('ready');\n }\n }\n\n function server_disconnect() {\n self._connection_count--;\n if (!self._connection_count) {\n self._set_state('offline');\n }\n }\n\n server.on('message', server_message);\n server.on('connect', server_connect);\n server.on('disconnect', server_disconnect);\n\n this._servers.push(server);\n\n return this;\n};\n\n// Inform remote that the remote server is not comming back.\nRemote.prototype.server_fatal = function () {\n this._server_fatal = true;\n};\n\n// Set the emitted state: 'online' or 'offline'\nRemote.prototype._set_state = function (state) {\n this._trace('remote: set_state: %s', state);\n\n if (this.state !== state) {\n this.state = state;\n\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\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\nRemote.prototype.set_trace = function (trace) {\n this.trace = trace === void(0) || trace;\n return this;\n};\n\nRemote.prototype._trace = function() {\n if (this.trace) {\n utils.logObject.apply(utils, arguments);\n }\n};\n\n/**\n * Connect to the Ripple network.\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 ;(function nextServer(i) {\n var server = self._servers[i];\n server.connect();\n server._sid = ++i;\n\n if (i < self._servers.length) {\n setTimeout(function() {\n nextServer(i);\n }, self._connection_offset);\n }\n })(0);\n\n return this;\n};\n\n/**\n * Disconnect from the Ripple network.\n */\nRemote.prototype.disconnect = function (online) {\n if (!this._servers.length) {\n throw new Error('No servers available, not disconnecting');\n }\n\n this._servers.forEach(function(server) {\n server.disconnect();\n });\n\n this._set_state('offline');\n\n return this;\n};\n\n// It is possible for messages to be dispatched after the connection is closed.\nRemote.prototype._handle_message = function (message, server) {\n var self = this;\n\n try { message = JSON.parse(message); } catch(e) { }\n\n var unexpected = typeof message !== 'object' || typeof message.type !== 'string';\n\n if (unexpected) {\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 'response':\n // Handled by the server that sent the request\n break;\n\n case 'ledgerClosed':\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\n this._ledger_time = message.ledger_time;\n this._ledger_hash = message.ledger_hash;\n this._ledger_current_index = message.ledger_index + 1;\n\n this.emit('ledger_closed', message, server);\n break;\n\n case 'transaction':\n // To get these events, just subscribe to them. A subscribes and\n // unsubscribes will be added as needed.\n // XXX If not trusted, need proof.\n\n // De-duplicate transactions that are immediately following each other\n // XXX Should have a cache of n txs so we can dedup out of order txs\n if (this._last_tx === message.transaction.hash) {\n break;\n }\n\n this._last_tx = message.transaction.hash;\n\n this._trace('remote: tx: %s', message);\n\n // Process metadata\n message.mmeta = new Meta(message.meta);\n\n // Pass the event on to any related Account objects\n message.mmeta.getAffectedAccounts().forEach(function(account) {\n account = self._accounts[account];\n if (account) {\n account.notifyTx(message);\n }\n });\n\n // Pass the event on to any related OrderBooks\n message.mmeta.getAffectedBooks().forEach(function(book) {\n book = self._books[book];\n if (book) {\n book.notifyTx(message);\n }\n });\n\n this.emit('transaction', message);\n this.emit('transaction_all', message);\n break;\n\n case 'path_find':\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 break;\n case 'serverStatus':\n self.emit('server_status', message);\n\n var load_changed = message.hasOwnProperty('load_base')\n && message.hasOwnProperty('load_factor')\n && (message.load_base !== self._load_base || message.load_factor !== self._load_factor)\n ;\n\n if (load_changed) {\n self._load_base = message.load_base;\n self._load_factor = message.load_factor;\n self.emit('load', { 'load_base' : self._load_base, 'load_factor' : self.load_factor });\n }\n break;\n\n // All other messages\n default:\n this._trace('remote: ' + message.type + ': %s', message);\n this.emit('net_' + message.type, message);\n break;\n }\n};\n\nRemote.prototype.ledger_hash = function () {\n return this._ledger_hash;\n};\n\nRemote.prototype._set_primary_server = 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\nRemote.prototype._server_is_available = function (server) {\n return server && server._connected;\n};\n\nRemote.prototype._next_server = function () {\n var result = null;\n\n for (var i=0; i request: what to send, consumed.\nRemote.prototype.request = function (request) {\n if (!this._servers.length) {\n request.emit('error', new Error('No servers available'));\n } else if (!this._connected) {\n this.once('connect', this.request.bind(this, request));\n } else if (request.server === null) {\n this.emit('error', new Error('Server does not exist'));\n } else {\n var server = request.server || this._get_server();\n if (server) {\n server.request(request);\n } else {\n request.emit('error', new Error('No servers available'));\n }\n }\n};\n\nRemote.prototype.request_server_info = function(callback) {\n return new Request(this, 'server_info').callback(callback);\n};\n\n// XXX This is a bad command. Some varients don't scale.\n// XXX Require the server to be trusted.\nRemote.prototype.request_ledger = function (ledger, opts, callback) {\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'ledger');\n\n if (ledger) {\n // DEPRECATED: use .ledger_hash() or .ledger_index()\n console.log('request_ledger: ledger parameter is deprecated');\n request.message.ledger = ledger;\n }\n\n var props = [\n 'full'\n , 'expand'\n , 'transactions'\n , 'accounts' \n ];\n\n switch (typeof opts) {\n case 'object':\n for (var key in opts) {\n if (~props.indexOf(key)) {\n request.message[key] = true;\n }\n }\n break;\n\n case 'function':\n callback = opts;\n opts = void(0);\n break;\n\n default:\n //DEPRECATED\n console.log('request_ledger: full parameter is deprecated');\n request.message.full = true;\n break;\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// Only for unit testing.\nRemote.prototype.request_ledger_hash = function (callback) {\n //utils.assert(this.trusted); // If not trusted, need to check proof.\n\n return new Request(this, 'ledger_closed').callback(callback);\n};\n\n// .ledger()\n// .ledger_index()\nRemote.prototype.request_ledger_header = function (callback) {\n return new Request(this, 'ledger_header').callback(callback);\n};\n\n// Get the current proposed ledger entry. May be closed (and revised) at any time (even before returning).\n// Only for unit testing.\nRemote.prototype.request_ledger_current = function (callback) {\n return new Request(this, 'ledger_current').callback(callback);\n};\n\n// --> type : the type of ledger entry.\n// .ledger()\n// .ledger_index()\n// .offer_id()\nRemote.prototype.request_ledger_entry = function (type, callback) {\n //utils.assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.\n\n var self = this;\n var request = new Request(this, 'ledger_entry');\n\n // Transparent caching. When .request() is invoked, look in the Remote object for the result.\n // If not found, listen, cache result, and emit it.\n //\n // Transparent caching:\n if (type === 'account_root') {\n request.request_default = request.request;\n\n request.request = function () { // Intercept default request.\n var bDefault = true;\n // .self = Remote\n // this = Request\n\n // console.log('request_ledger_entry: caught');\n\n //if (self._ledger_hash) {\n // A specific ledger is requested.\n // XXX Add caching.\n // else if (req.ledger_index)\n // else if ('ripple_state' === request.type) // YYY Could be cached per ledger.\n //} \n \n if (!self._ledger_hash && type === 'account_root') {\n var cache = self.ledgers.current.account_root;\n\n if (!cache) {\n cache = self.ledgers.current.account_root = {};\n }\n\n var node = self.ledgers.current.account_root[request.message.account_root];\n\n if (node) {\n // Emulate fetch of ledger entry.\n // console.log('request_ledger_entry: emulating');\n // YYY Missing lots of fields.\n request.emit('success', { node: node });\n bDefault = false;\n } else { // Was not cached.\n // XXX Only allow with trusted mode. Must sync response with advance.\n switch (type) {\n case 'account_root':\n request.on('success', function (message) {\n // Cache node.\n // console.log('request_ledger_entry: caching');\n self.ledgers.current.account_root[message.node.Account] = message.node;\n });\n break;\n\n default:\n // This type not cached.\n // console.log('request_ledger_entry: non-cached type');\n }\n }\n }\n\n if (bDefault) {\n // console.log('request_ledger_entry: invoking');\n request.request_default();\n }\n };\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// .accounts(accounts, realtime)\nRemote.prototype.request_subscribe = function (streams, callback) {\n var request = new Request(this, 'subscribe');\n\n if (streams) {\n request.message.streams = Array.isArray(streams) ? streams : [ streams ];\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// .accounts(accounts, realtime)\nRemote.prototype.request_unsubscribe = function (streams, callback) {\n var request = new Request(this, 'unsubscribe');\n\n if (streams) {\n request.message.streams = Array.isArray(streams) ? streams : [ streams ];\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// .ledger_choose()\n// .ledger_hash()\n// .ledger_index()\nRemote.prototype.request_transaction = \nRemote.prototype.request_transaction_entry = function (tx_hash, ledger_hash, callback) {\n //utils.assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.\n var request = new Request(this, 'transaction_entry');\n\n request.tx_hash(tx_hash);\n\n switch (typeof ledger_hash) {\n case 'string':\n request.ledger_hash(ledger_hash);\n break;\n default:\n request.ledger_index('validated');\n callback = ledger_hash;\n }\n \n request.callback(callback);\n\n return request;\n};\n\n// DEPRECATED: use request_transaction_entry\nRemote.prototype.request_tx = function (hash, callback) {\n var request = new Request(this, 'tx');\n request.message.transaction = hash;\n request.callback(callback);\n return request;\n};\n\nRemote.prototype.request_account_info = function (accountID, callback) {\n var request = new Request(this, 'account_info');\n request.message.ident = UInt160.json_rewrite(accountID); // DEPRECATED\n request.message.account = UInt160.json_rewrite(accountID);\n request.callback(callback);\n return request;\n};\n\n// --> account_index: sub_account index (optional)\n// --> current: true, for the current ledger.\nRemote.prototype.request_account_lines = function (accountID, account_index, current, callback) {\n // XXX Does this require the server to be trusted?\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'account_lines');\n\n request.message.account = UInt160.json_rewrite(accountID);\n\n if (account_index) {\n request.message.index = account_index;\n }\n\n request.ledger_choose(current);\n request.callback(callback);\n\n return request;\n};\n\n// --> account_index: sub_account index (optional)\n// --> current: true, for the current ledger.\nRemote.prototype.request_account_offers = function (accountID, account_index, current, callback) {\n var request = new Request(this, 'account_offers');\n\n request.message.account = UInt160.json_rewrite(accountID);\n\n if (account_index) {\n request.message.index = account_index;\n }\n\n request.ledger_choose(current);\n request.callback(callback);\n\n return request;\n};\n\n\n/*\n account: account,\n ledger_index_min: ledger_index, // optional, defaults to -1 if ledger_index_max is specified.\n ledger_index_max: ledger_index, // optional, defaults to -1 if ledger_index_min is specified.\n binary: boolean, // optional, defaults to false\n count: boolean, // optional, defaults to false\n descending: boolean, // optional, defaults to false\n offset: integer, // optional, defaults to 0\n limit: integer // optional\n*/\n\nRemote.prototype.request_account_tx = function (obj, callback) {\n // XXX Does this require the server to be trusted?\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'account_tx');\n\n request.message.account = obj.account;\n\n var props = [\n 'ledger_index_min'\n , 'ledger_index_max'\n , 'binary'\n , 'count'\n , 'descending'\n , 'offset'\n , 'limit'\n ];\n\n for (var key in obj) {\n if (~props.indexOf(key)) {\n request.message[key] = obj[key];\n }\n }\n\n request.callback(callback);\n\n return request;\n};\n\n/**\n * Request the overall transaction history.\n *\n * Returns a list of transactions that happened recently on the network. The\n * default number of transactions to be returned is 20.\n */\nRemote.prototype.request_tx_history = function (start, callback) {\n // XXX Does this require the server to be trusted?\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'tx_history');\n\n request.message.start = start;\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_book_offers = function (gets, pays, taker, callback) {\n var request = new Request(this, 'book_offers');\n\n request.message.taker_gets = {\n currency: Currency.json_rewrite(gets.currency)\n };\n\n if (request.message.taker_gets.currency !== 'XRP') {\n request.message.taker_gets.issuer = UInt160.json_rewrite(gets.issuer);\n }\n\n request.message.taker_pays = {\n currency: Currency.json_rewrite(pays.currency)\n };\n\n if (request.message.taker_pays.currency !== 'XRP') {\n request.message.taker_pays.issuer = UInt160.json_rewrite(pays.issuer);\n }\n\n request.message.taker = taker ? taker : UInt160.ACCOUNT_ONE;\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_wallet_accounts = function (seed, callback) {\n utils.assert(this.trusted); // Don't send secrets.\n var request = new Request(this, 'wallet_accounts');\n request.message.seed = seed;\n return request.callback(callback);\n};\n\nRemote.prototype.request_sign = function (secret, tx_json, callback) {\n utils.assert(this.trusted); // Don't send secrets.\n var request = new Request(this, 'sign');\n request.message.secret = secret;\n request.message.tx_json = tx_json;\n request.callback(callback);\n return request;\n};\n\n// Submit a transaction.\nRemote.prototype.request_submit = function (callback) {\n return new Request(this, 'submit').callback(callback);\n};\n\n//\n// Higher level functions.\n//\n\n/**\n * Create a subscribe request with current subscriptions.\n *\n * Other classes can add their own subscriptions to this request by listening to\n * the server_subscribe event.\n *\n * This function will create and return the request, but not submit it.\n */\nRemote.prototype._server_prepare_subscribe = function (callback) {\n var self = this;\n\n var feeds = [ 'ledger', 'server' ];\n\n if (this._transaction_subs) {\n feeds.push('transactions');\n }\n\n var request = this.request_subscribe(feeds);\n\n request.once('success', function (message) {\n self._stand_alone = !!message.stand_alone;\n self._testnet = !!message.testnet;\n\n if (typeof message.random === 'string') {\n var rand = message.random.match(/[0-9A-F]{8}/ig);\n while (rand && rand.length) {\n sjcl.random.addEntropy(parseInt(rand.pop(), 16));\n }\n self.emit('random', utils.hexToArray(message.random));\n }\n\n if (message.ledger_hash && message.ledger_index) {\n self._ledger_time = message.ledger_time;\n self._ledger_hash = message.ledger_hash;\n self._ledger_current_index = message.ledger_index+1;\n self.emit('ledger_closed', message);\n }\n\n // FIXME Use this to estimate fee.\n // XXX When we have multiple server support, most of this should be tracked\n // by the Server objects and then aggregated/interpreted by Remote.\n self._load_base = message.load_base || 256;\n self._load_factor = message.load_factor || 256;\n self._fee_ref = message.fee_ref;\n self._fee_base = message.fee_base;\n self._reserve_base = message.reserve_base;\n self._reserve_inc = message.reserve_inc;\n\n self.emit('subscribed');\n });\n\n request.on('error', function (err) {\n // XXX We need a better global error handling\n console.log(err);\n });\n\n self.emit('prepare_subscribe', request);\n\n request.callback(callback);\n\n // XXX Could give error events, maybe even time out.\n\n return request;\n};\n\n// For unit testing: ask the remote to accept the current ledger.\n// - To be notified when the ledger is accepted, server_subscribe() then listen to 'ledger_hash' events.\n// A good way to be notified of the result of this is:\n// remote.once('ledger_closed', function (ledger_closed, ledger_index) { ... } );\nRemote.prototype.ledger_accept = function (callback) {\n if (this._stand_alone) {\n var request = new Request(this, 'ledger_accept');\n request.request();\n request.callback(callback);\n } else {\n this.emit('error', { error : 'notStandAlone' });\n }\n return this;\n};\n\n// Return a request to refresh the account balance.\nRemote.prototype.request_account_balance = function (account, current, callback) {\n var request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n request.once('success', function (message) {\n request.emit('account_balance', Amount.from_json(message.node.Balance));\n });\n request.callback(callback, 'account_balance');\n return request;\n};\n\n// Return a request to return the account flags.\nRemote.prototype.request_account_flags = function (account, current, callback) {\n var request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n request.on('success', function (message) {\n request.emit('account_flags', message.node.Flags);\n });\n request.callback(callback, 'account_flags');\n return request;\n};\n\n// Return a request to emit the owner count.\nRemote.prototype.request_owner_count = function (account, current, callback) {\n var request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n request.on('success', function (message) {\n request.emit('owner_count', message.node.OwnerCount);\n });\n request.callback(callback, 'owner_count');\n return request;\n};\n\nRemote.prototype.get_account =\nRemote.prototype.account = function (accountId) {\n var accountId = UInt160.json_rewrite(accountId);\n var account = this._accounts[accountId];\n\n if (!account) {\n account = new Account(this, accountId);\n if (account.is_valid()) {\n this._accounts[accountId] = account;\n }\n }\n\n return account;\n};\n\nRemote.prototype.path_find = function (src_account, dst_account, dst_amount, src_currencies) {\n var path_find = new PathFind(this, src_account, dst_account, dst_amount, src_currencies);\n\n if (this._cur_path_find) {\n this._cur_path_find.notify_superceded();\n }\n\n path_find.create();\n\n this._cur_path_find = path_find;\n\n return path_find;\n};\n\nRemote.prototype.book = function (currency_gets, issuer_gets, currency_pays, issuer_pays) {\n var gets = currency_gets + (currency_gets === 'XRP' ? '' : ('/' + issuer_gets));\n var pays = currency_pays + (currency_pays === 'XRP' ? '' : ('/' + issuer_pays));\n var key = gets + ':' + pays;\n var book;\n\n if (!this._books.hasOwnProperty(key)) {\n book = new OrderBook(this, currency_gets, issuer_gets, currency_pays, issuer_pays);\n if (book.is_valid()) {\n this._books[key] = book;\n }\n }\n\n return book;\n};\n\n// Return the next account sequence if possible.\n// <-- undefined or Sequence\nRemote.prototype.account_seq = function (account, advance) {\n var account = UInt160.json_rewrite(account);\n var account_info = this.accounts[account];\n var seq;\n\n if (account_info && account_info.seq) {\n seq = account_info.seq;\n account_info.seq += { ADVANCE: 1, REWIND: -1 }[advance.toUpperCase()] || 0;\n }\n\n return seq;\n};\n\nRemote.prototype.set_account_seq = function (account, seq) {\n var account = UInt160.json_rewrite(account);\n\n if (!this.accounts.hasOwnProperty(account)) {\n this.accounts[account] = { };\n }\n\n this.accounts[account].seq = seq;\n}\n\n// Return a request to refresh accounts[account].seq.\nRemote.prototype.account_seq_cache = function (account, current, callback) {\n var self = this;\n\n if (!this.accounts.hasOwnProperty(account)) {\n this.accounts[account] = { };\n }\n\n var account_info = this.accounts[account];\n var request = account_info.caching_seq_request;\n\n if (!request) {\n // console.log('starting: %s', account);\n request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n\n function account_root_success(message) {\n delete account_info.caching_seq_request;\n\n var seq = message.node.Sequence;\n account_info.seq = seq;\n\n // console.log('caching: %s %d', account, seq);\n // If the caller also waits for 'success', they might run before this.\n request.emit('success_account_seq_cache', message);\n }\n\n function account_root_error(message) {\n // console.log('error: %s', account);\n delete account_info.caching_seq_request;\n\n request.emit('error_account_seq_cache', message);\n }\n\n request.once('success', account_root_success);\n request.once('error', account_root_error);\n\n account_info.caching_seq_request = request;\n }\n\n request.callback(callback, 'success_account_seq_cache', 'error_account_seq_cache');\n\n return request;\n};\n\n// Mark an account's root node as dirty.\nRemote.prototype.dirty_account_root = function (account) {\n var account = UInt160.json_rewrite(account);\n delete this.ledgers.current.account_root[account];\n};\n\n// Store a secret - allows the Remote to automatically fill out auth information.\nRemote.prototype.set_secret = function (account, secret) {\n this.secrets[account] = secret;\n};\n\n\n// Return a request to get a ripple balance.\n//\n// --> account: String\n// --> issuer: String\n// --> currency: String\n// --> current: bool : true = current ledger\n//\n// If does not exist: emit('error', 'error' : 'remoteError', 'remote' : { 'error' : 'entryNotFound' })\nRemote.prototype.request_ripple_balance = function (account, issuer, currency, current, callback) {\n var request = this.request_ledger_entry('ripple_state'); // YYY Could be cached per ledger.\n\n request.ripple_state(account, issuer, currency);\n request.ledger_choose(current);\n request.once('success', function(message) {\n var node = message.node;\n var lowLimit = Amount.from_json(node.LowLimit);\n var highLimit = Amount.from_json(node.HighLimit);\n // The amount the low account holds of issuer.\n var balance = Amount.from_json(node.Balance);\n // accountHigh implies: for account: balance is negated, highLimit is the limit set by account.\n var accountHigh = UInt160.from_json(account).equals(highLimit.issuer());\n\n request.emit('ripple_state', {\n account_balance : ( accountHigh ? balance.negate() : balance.clone()).parse_issuer(account),\n peer_balance : (!accountHigh ? balance.negate() : balance.clone()).parse_issuer(issuer),\n\n account_limit : ( accountHigh ? highLimit : lowLimit).clone().parse_issuer(issuer),\n peer_limit : (!accountHigh ? highLimit : lowLimit).clone().parse_issuer(account),\n\n account_quality_in : ( accountHigh ? node.HighQualityIn : node.LowQualityIn),\n peer_quality_in : (!accountHigh ? node.HighQualityIn : node.LowQualityIn),\n\n account_quality_out : ( accountHigh ? node.HighQualityOut : node.LowQualityOut),\n peer_quality_out : (!accountHigh ? node.HighQualityOut : node.LowQualityOut),\n });\n });\n\n request.callback(callback, 'ripple_state');\n\n return request;\n};\n\nfunction prepare_currencies(ci) {\n var ci_new = { };\n\n if (ci.hasOwnProperty('issuer')) {\n ci_new.issuer = UInt160.json_rewrite(ci.issuer);\n }\n\n if (ci.hasOwnProperty('currency')) {\n ci_new.currency = Currency.json_rewrite(ci.currency);\n }\n\n return ci_new;\n}\n\nRemote.prototype.request_ripple_path_find = function (src_account, dst_account, dst_amount, src_currencies, callback) {\n var request = new Request(this, 'ripple_path_find');\n\n request.message.source_account = UInt160.json_rewrite(src_account);\n request.message.destination_account = UInt160.json_rewrite(dst_account);\n request.message.destination_amount = Amount.json_rewrite(dst_amount);\n\n if (src_currencies) {\n request.message.source_currencies = src_currencies.map(prepare_currencies);\n }\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_path_find_create = function (src_account, dst_account, dst_amount, src_currencies, callback) {\n var request = new Request(this, 'path_find');\n\n request.message.subcommand = 'create';\n request.message.source_account = UInt160.json_rewrite(src_account);\n request.message.destination_account = UInt160.json_rewrite(dst_account);\n request.message.destination_amount = Amount.json_rewrite(dst_amount);\n\n if (src_currencies) {\n request.message.source_currencies = src_currencies.map(prepare_currencies);\n }\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_path_find_close = function () {\n var request = new Request(this, 'path_find');\n request.message.subcommand = 'close';\n return request;\n};\n\nRemote.prototype.request_unl_list = function (callback) {\n return new Request(this, 'unl_list').callback(callback);\n};\n\nRemote.prototype.request_unl_add = function (addr, comment, callback) {\n var request = new Request(this, 'unl_add');\n\n request.message.node = addr;\n\n if (comment) {\n request.message.comment = note;\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// --> node: | \nRemote.prototype.request_unl_delete = function (node, callback) {\n var request = new Request(this, 'unl_delete');\n request.message.node = node;\n request.callback(callback);\n return request;\n};\n\nRemote.prototype.request_peers = function (callback) {\n return new Request(this, 'peers').callback(callback);\n};\n\nRemote.prototype.request_connect = function (ip, port, callback) {\n var request = new Request(this, 'connect');\n\n request.message.ip = ip;\n\n if (port) {\n request.message.port = port;\n }\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.transaction = function (source, destination, amount, callback) {\n var tx = new Transaction(this);\n\n if (arguments.length >= 3) {\n tx = tx.payment(source, destination, amount);\n if (typeof callback === 'function') {\n tx.submit(callback);\n }\n }\n\n return tx;\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 * @return {Amount} Final fee in XRP for specified number of fee units.\n */\nRemote.prototype.fee_tx = function (units) {\n var fee_unit = this.fee_tx_unit();\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 */\nRemote.prototype.fee_tx_unit = 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 */\nRemote.prototype.reserve = function (owner_count) {\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 = owner_count || 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\nRemote.prototype.ping = function(host, callback) {\n var request = new Request(this, 'ping');\n\n switch (typeof host) {\n case 'function':\n callback = host;\n break;\n case 'string':\n var server = null;\n for (var i=0, s; s=this._servers[i]; i++) {\n if (s._host === host) {\n server = s;\n break;\n }\n }\n request.set_server(server);\n break;\n }\n\n var then = Date.now();\n\n request.once('success', function() {\n request.emit('pong', Date.now() - then);\n });\n \n request.callback(callback, 'pong');\n\n return request;\n};\n\nexports.Remote = Remote;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 1\n// module.readableIdentifier = ./src/js/ripple/remote.js\n//@ sourceURL=webpack-module:///./src/js/ripple/remote.js"); + 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//\n\n// npm\nvar EventEmitter = require(27).EventEmitter;\nvar util = require(28);\n\nvar Request = require(14).Request;\nvar Server = require(10).Server;\nvar Amount = require(2).Amount;\nvar Currency = require(3).Currency;\nvar UInt160 = require(15).UInt160;\nvar Transaction = require(5).Transaction;\nvar Account = require(16).Account;\nvar Meta = require(6).Meta;\nvar OrderBook = require(17).OrderBook;\nvar PathFind = require(18).PathFind;\nvar RippleError = require(19).RippleError;\n\nvar utils = require(9);\nvar config = require(12);\nvar sjcl = require(11);\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\n { \n host: \n , port: \n , secure: \n }\n\n Events:\n 'connect'\n 'connected' (DEPRECATED)\n 'disconnect'\n 'disconnected' (DEPRECATED)\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\n this.trusted = Boolean(opts.trusted);\n this.local_sequence = Boolean(opts.local_sequence); // Locally track sequence numbers\n this.local_fee = (typeof opts.local_fee === 'undefined') ? true : Boolean(opts.local_fee); // Locally set fees\n this.local_signing = (typeof opts.local_signing === 'undefined') ? true : Boolean(opts.local_signing);\n this.fee_cushion = (typeof opts.fee_cushion === 'undefined') ? 1.5 : Number(opts.fee_cushion);\n this.max_fee = (typeof opts.max_fee === 'undefined') ? Infinity : Number(opts.max_fee);\n this.id = 0;\n this.trace = Boolean(opts.trace);\n this._server_fatal = false; // True, if we know server exited.\n this._ledger_current_index = void(0);\n this._ledger_hash = void(0);\n this._ledger_time = void(0);\n this._stand_alone = void(0);\n this._testnet = void(0);\n this._transaction_subs = 0;\n this.online_target = false;\n this._online_state = 'closed'; // 'open', 'closed', 'connecting', 'closing'\n this.state = 'offline'; // 'online', 'offline'\n this.retry_timer = void(0);\n this.retry = void(0);\n\n this._load_base = 256;\n this._load_factor = 256;\n this._fee_ref = 10;\n this._fee_base = 10;\n this._reserve_base = void(0);\n this._reserve_inc = void(0);\n this._connection_count = 0;\n this._connected = false;\n this._connection_offset = 1000 * (Number(opts.connection_offset) || 5);\n this._submission_timeout = 1000 * (Number(opts.submission_timeout) || 10);\n\n this._last_tx = null;\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 this.accounts = {\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\n // account : { seq : __ }\n };\n\n // Account objects by AccountId.\n this._accounts = { };\n\n // OrderBook objects\n this._books = { };\n\n // Secrets that we know about.\n this.secrets = {\n // Secrets can be set by calling set_secret(account, secret).\n\n // account : secret\n };\n\n // Cache for various ledgers.\n // XXX Clear when ledger advances.\n this.ledgers = {\n current : {\n account_root : {}\n }\n };\n\n // Fallback for previous API\n if (!opts.hasOwnProperty('servers')) {\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 var pool = Number(server.pool) || 1;\n while (pool--) { self.add_server(server); };\n });\n\n // This is used to remove Node EventEmitter warnings\n var maxListeners = opts.maxListeners || opts.max_listeners || 0;\n this._servers.concat(this).forEach(function(emitter) {\n emitter.setMaxListeners(maxListeners);\n });\n\n function listener_added(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 function listener_removed(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('newListener', listener_added);\n this.on('removeListener', listener_removed);\n}\n\nutil.inherits(Remote, EventEmitter);\n\n// Flags for ledger entries. In support of account_root().\nRemote.flags = {\n account_root : {\n PasswordSpent: 0x00010000,\n RequireDestTag: 0x00020000,\n RequireAuth: 0x00040000,\n DisallowXRP: 0x00080000\n }\n};\n\nfunction isTemMalformed(engine_result_code) {\n return (engine_result_code >= -299 && engine_result_code < 199);\n};\n\nfunction isTefFailure(engine_result_code) {\n return (engine_result_code >= -299 && engine_result_code < 199);\n};\n\nRemote.from_config = function (obj, trace) {\n var serverConfig = typeof obj === 'string' ? config.servers[obj] : obj;\n\n var remote = new Remote(serverConfig, trace);\n\n function initialize_account(account) {\n var accountInfo = config.accounts[account];\n if (typeof accountInfo === 'object') {\n if (accountInfo.secret) {\n // Index by nickname ...\n remote.set_secret(account, accountInfo.secret);\n // ... and by account ID\n remote.set_secret(accountInfo.account, accountInfo.secret);\n }\n }\n }\n\n if (typeof config.accounts === 'object') {\n for (var account in config.accounts) {\n initialize_account(account);\n }\n }\n\n return remote;\n};\n\nRemote.create_remote = function(options, callback) {\n var remote = Remote.from_config(options);\n remote.connect(callback);\n return remote;\n};\n\nRemote.prototype.add_server = function (opts) {\n var self = this;\n\n var server = new Server(this, {\n host : opts.host || opts.websocket_ip,\n port : opts.port || opts.websocket_port,\n secure : opts.secure || opts.websocket_ssl\n });\n\n function server_message(data) {\n self._handle_message(data, server);\n }\n\n function server_connect() {\n self._connection_count++;\n self._set_state('online');\n if (opts.primary || !self._primary_server) {\n self._set_primary_server(server);\n }\n if (self._connection_count === self._servers.length) {\n self.emit('ready');\n }\n }\n\n function server_disconnect() {\n self._connection_count--;\n if (!self._connection_count) {\n self._set_state('offline');\n }\n }\n\n server.on('message', server_message);\n server.on('connect', server_connect);\n server.on('disconnect', server_disconnect);\n\n this._servers.push(server);\n\n return this;\n};\n\n// Inform remote that the remote server is not comming back.\nRemote.prototype.server_fatal = function () {\n this._server_fatal = true;\n};\n\n// Set the emitted state: 'online' or 'offline'\nRemote.prototype._set_state = function (state) {\n this._trace('remote: set_state: %s', state);\n\n if (this.state !== state) {\n this.state = state;\n\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\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\nRemote.prototype.set_trace = function (trace) {\n this.trace = trace === void(0) || trace;\n return this;\n};\n\nRemote.prototype._trace = function() {\n if (this.trace) {\n utils.logObject.apply(utils, arguments);\n }\n};\n\n/**\n * Connect to the Ripple network.\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 ;(function nextServer(i) {\n var server = self._servers[i];\n server.connect();\n server._sid = ++i;\n\n if (i < self._servers.length) {\n setTimeout(function() {\n nextServer(i);\n }, self._connection_offset);\n }\n })(0);\n\n return this;\n};\n\n/**\n * Disconnect from the Ripple network.\n */\nRemote.prototype.disconnect = function (online) {\n if (!this._servers.length) {\n throw new Error('No servers available, not disconnecting');\n }\n\n this._servers.forEach(function(server) {\n server.disconnect();\n });\n\n this._set_state('offline');\n\n return this;\n};\n\n// It is possible for messages to be dispatched after the connection is closed.\nRemote.prototype._handle_message = function (message, server) {\n var self = this;\n\n try { message = JSON.parse(message); } catch(e) { }\n\n var unexpected = typeof message !== 'object' || typeof message.type !== 'string';\n\n if (unexpected) {\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 'response':\n // Handled by the server that sent the request\n break;\n\n case 'ledgerClosed':\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\n this._ledger_time = message.ledger_time;\n this._ledger_hash = message.ledger_hash;\n this._ledger_current_index = message.ledger_index + 1;\n\n this.emit('ledger_closed', message, server);\n break;\n\n case 'transaction':\n // To get these events, just subscribe to them. A subscribes and\n // unsubscribes will be added as needed.\n // XXX If not trusted, need proof.\n\n // De-duplicate transactions that are immediately following each other\n // XXX Should have a cache of n txs so we can dedup out of order txs\n if (this._last_tx === message.transaction.hash) {\n break;\n }\n\n this._last_tx = message.transaction.hash;\n\n this._trace('remote: tx: %s', message);\n\n // Process metadata\n message.mmeta = new Meta(message.meta);\n\n // Pass the event on to any related Account objects\n message.mmeta.getAffectedAccounts().forEach(function(account) {\n account = self._accounts[account];\n if (account) {\n account.notifyTx(message);\n }\n });\n\n // Pass the event on to any related OrderBooks\n message.mmeta.getAffectedBooks().forEach(function(book) {\n book = self._books[book];\n if (book) {\n book.notifyTx(message);\n }\n });\n\n this.emit('transaction', message);\n this.emit('transaction_all', message);\n break;\n\n case 'path_find':\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 break;\n case 'serverStatus':\n self.emit('server_status', message);\n\n var load_changed = message.hasOwnProperty('load_base')\n && message.hasOwnProperty('load_factor')\n && (message.load_base !== self._load_base || message.load_factor !== self._load_factor)\n ;\n\n if (load_changed) {\n self._load_base = message.load_base;\n self._load_factor = message.load_factor;\n var obj = {\n load_base: self._load_base,\n load_factor: self._load_factor,\n fee_units: self.fee_tx_unit()\n }\n self.emit('load', obj);\n self.emit('load_changed', obj);\n }\n break;\n\n // All other messages\n default:\n this._trace('remote: ' + message.type + ': %s', message);\n this.emit('net_' + message.type, message);\n break;\n }\n};\n\nRemote.prototype.ledger_hash = function () {\n return this._ledger_hash;\n};\n\nRemote.prototype._set_primary_server = 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\nRemote.prototype._server_is_available = function (server) {\n return server && server._connected;\n};\n\nRemote.prototype._next_server = function () {\n var result = null;\n\n for (var i=0; i request: what to send, consumed.\nRemote.prototype.request = function (request) {\n if (!this._servers.length) {\n request.emit('error', new Error('No servers available'));\n } else if (!this._connected) {\n this.once('connect', this.request.bind(this, request));\n } else if (request.server === null) {\n this.emit('error', new Error('Server does not exist'));\n } else {\n var server = request.server || this._get_server();\n if (server) {\n server.request(request);\n } else {\n request.emit('error', new Error('No servers available'));\n }\n }\n};\n\nRemote.prototype.request_server_info = function(callback) {\n return new Request(this, 'server_info').callback(callback);\n};\n\n// XXX This is a bad command. Some varients don't scale.\n// XXX Require the server to be trusted.\nRemote.prototype.request_ledger = function (ledger, opts, callback) {\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'ledger');\n\n if (ledger) {\n // DEPRECATED: use .ledger_hash() or .ledger_index()\n console.log('request_ledger: ledger parameter is deprecated');\n request.message.ledger = ledger;\n }\n\n var props = [\n 'full'\n , 'expand'\n , 'transactions'\n , 'accounts'\n ];\n\n switch (typeof opts) {\n case 'object':\n for (var key in opts) {\n if (~props.indexOf(key)) {\n request.message[key] = true;\n }\n }\n break;\n\n case 'function':\n callback = opts;\n opts = void(0);\n break;\n\n default:\n //DEPRECATED\n console.log('request_ledger: full parameter is deprecated');\n request.message.full = true;\n break;\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// Only for unit testing.\nRemote.prototype.request_ledger_hash = function (callback) {\n //utils.assert(this.trusted); // If not trusted, need to check proof.\n\n return new Request(this, 'ledger_closed').callback(callback);\n};\n\n// .ledger()\n// .ledger_index()\nRemote.prototype.request_ledger_header = function (callback) {\n return new Request(this, 'ledger_header').callback(callback);\n};\n\n// Get the current proposed ledger entry. May be closed (and revised) at any time (even before returning).\n// Only for unit testing.\nRemote.prototype.request_ledger_current = function (callback) {\n return new Request(this, 'ledger_current').callback(callback);\n};\n\n// --> type : the type of ledger entry.\n// .ledger()\n// .ledger_index()\n// .offer_id()\nRemote.prototype.request_ledger_entry = function (type, callback) {\n //utils.assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.\n\n var self = this;\n var request = new Request(this, 'ledger_entry');\n\n // Transparent caching. When .request() is invoked, look in the Remote object for the result.\n // If not found, listen, cache result, and emit it.\n //\n // Transparent caching:\n if (type === 'account_root') {\n request.request_default = request.request;\n\n request.request = function () { // Intercept default request.\n var bDefault = true;\n // .self = Remote\n // this = Request\n\n // console.log('request_ledger_entry: caught');\n\n //if (self._ledger_hash) {\n // A specific ledger is requested.\n // XXX Add caching.\n // else if (req.ledger_index)\n // else if ('ripple_state' === request.type) // YYY Could be cached per ledger.\n //} \n \n if (!self._ledger_hash && type === 'account_root') {\n var cache = self.ledgers.current.account_root;\n\n if (!cache) {\n cache = self.ledgers.current.account_root = {};\n }\n\n var node = self.ledgers.current.account_root[request.message.account_root];\n\n if (node) {\n // Emulate fetch of ledger entry.\n // console.log('request_ledger_entry: emulating');\n // YYY Missing lots of fields.\n request.emit('success', { node: node });\n bDefault = false;\n } else { // Was not cached.\n // XXX Only allow with trusted mode. Must sync response with advance.\n switch (type) {\n case 'account_root':\n request.on('success', function (message) {\n // Cache node.\n // console.log('request_ledger_entry: caching');\n self.ledgers.current.account_root[message.node.Account] = message.node;\n });\n break;\n\n default:\n // This type not cached.\n // console.log('request_ledger_entry: non-cached type');\n }\n }\n }\n\n if (bDefault) {\n // console.log('request_ledger_entry: invoking');\n request.request_default();\n }\n };\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// .accounts(accounts, realtime)\nRemote.prototype.request_subscribe = function (streams, callback) {\n var request = new Request(this, 'subscribe');\n\n if (streams) {\n request.message.streams = Array.isArray(streams) ? streams : [ streams ];\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// .accounts(accounts, realtime)\nRemote.prototype.request_unsubscribe = function (streams, callback) {\n var request = new Request(this, 'unsubscribe');\n\n if (streams) {\n request.message.streams = Array.isArray(streams) ? streams : [ streams ];\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// .ledger_choose()\n// .ledger_hash()\n// .ledger_index()\nRemote.prototype.request_transaction = \nRemote.prototype.request_transaction_entry = function (hash, ledger_hash, callback) {\n //utils.assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.\n var request = new Request(this, 'transaction_entry');\n\n request.tx_hash(hash);\n\n switch (typeof ledger_hash) {\n case 'string':\n request.ledger_hash(ledger_hash);\n break;\n default:\n request.ledger_index('validated');\n callback = ledger_hash;\n }\n \n request.callback(callback);\n\n return request;\n};\n\n// DEPRECATED: use request_transaction_entry\nRemote.prototype.request_tx = function (hash, callback) {\n var request = new Request(this, 'tx');\n request.message.transaction = hash;\n request.callback(callback);\n return request;\n};\n\nRemote.prototype.request_account_info = function (accountID, callback) {\n var request = new Request(this, 'account_info');\n request.message.ident = UInt160.json_rewrite(accountID); // DEPRECATED\n request.message.account = UInt160.json_rewrite(accountID);\n request.callback(callback);\n return request;\n};\n\n// --> account_index: sub_account index (optional)\n// --> current: true, for the current ledger.\nRemote.prototype.request_account_lines = function (accountID, account_index, current, callback) {\n // XXX Does this require the server to be trusted?\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'account_lines');\n\n request.message.account = UInt160.json_rewrite(accountID);\n\n if (account_index) {\n request.message.index = account_index;\n }\n\n request.ledger_choose(current);\n request.callback(callback);\n\n return request;\n};\n\n// --> account_index: sub_account index (optional)\n// --> current: true, for the current ledger.\nRemote.prototype.request_account_offers = function (accountID, account_index, current, callback) {\n var request = new Request(this, 'account_offers');\n\n request.message.account = UInt160.json_rewrite(accountID);\n\n if (account_index) {\n request.message.index = account_index;\n }\n\n request.ledger_choose(current);\n request.callback(callback);\n\n return request;\n};\n\n\n/*\n account: account,\n ledger_index_min: ledger_index, // optional, defaults to -1 if ledger_index_max is specified.\n ledger_index_max: ledger_index, // optional, defaults to -1 if ledger_index_min is specified.\n binary: boolean, // optional, defaults to false\n count: boolean, // optional, defaults to false\n descending: boolean, // optional, defaults to false\n offset: integer, // optional, defaults to 0\n limit: integer // optional\n*/\n\nRemote.prototype.request_account_tx = function (obj, callback) {\n // XXX Does this require the server to be trusted?\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'account_tx');\n\n var request_fields = [\n 'account'\n , 'ledger_index_min' //earliest\n , 'ledger_index_max' //latest\n , 'binary' //false\n , 'count' //false\n , 'descending' //false\n , 'offset' //0\n , 'limit'\n\n //extended account_tx\n , 'forward' //false\n , 'marker'\n ];\n\n for (var key in obj) {\n if (~request_fields.indexOf(key)) {\n request.message[key] = obj[key];\n }\n }\n\n request.callback(callback);\n\n return request;\n};\n\n/**\n * Request the overall transaction history.\n *\n * Returns a list of transactions that happened recently on the network. The\n * default number of transactions to be returned is 20.\n */\nRemote.prototype.request_tx_history = function (start, callback) {\n // XXX Does this require the server to be trusted?\n //utils.assert(this.trusted);\n\n var request = new Request(this, 'tx_history');\n\n request.message.start = start;\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_book_offers = function (gets, pays, taker, callback) {\n var request = new Request(this, 'book_offers');\n\n request.message.taker_gets = {\n currency: Currency.json_rewrite(gets.currency)\n };\n\n if (request.message.taker_gets.currency !== 'XRP') {\n request.message.taker_gets.issuer = UInt160.json_rewrite(gets.issuer);\n }\n\n request.message.taker_pays = {\n currency: Currency.json_rewrite(pays.currency)\n };\n\n if (request.message.taker_pays.currency !== 'XRP') {\n request.message.taker_pays.issuer = UInt160.json_rewrite(pays.issuer);\n }\n\n request.message.taker = taker ? taker : UInt160.ACCOUNT_ONE;\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_wallet_accounts = function (seed, callback) {\n utils.assert(this.trusted); // Don't send secrets.\n var request = new Request(this, 'wallet_accounts');\n request.message.seed = seed;\n return request.callback(callback);\n};\n\nRemote.prototype.request_sign = function (secret, tx_json, callback) {\n utils.assert(this.trusted); // Don't send secrets.\n var request = new Request(this, 'sign');\n request.message.secret = secret;\n request.message.tx_json = tx_json;\n request.callback(callback);\n return request;\n};\n\n// Submit a transaction.\nRemote.prototype.request_submit = function (callback) {\n return new Request(this, 'submit').callback(callback);\n};\n\n//\n// Higher level functions.\n//\n\n/**\n * Create a subscribe request with current subscriptions.\n *\n * Other classes can add their own subscriptions to this request by listening to\n * the server_subscribe event.\n *\n * This function will create and return the request, but not submit it.\n */\nRemote.prototype._server_prepare_subscribe = function (callback) {\n var self = this;\n\n var feeds = [ 'ledger', 'server' ];\n\n if (this._transaction_subs) {\n feeds.push('transactions');\n }\n\n var request = this.request_subscribe(feeds);\n\n request.once('success', function (message) {\n self._stand_alone = !!message.stand_alone;\n self._testnet = !!message.testnet;\n\n if (typeof message.random === 'string') {\n var rand = message.random.match(/[0-9A-F]{8}/ig);\n while (rand && rand.length) {\n sjcl.random.addEntropy(parseInt(rand.pop(), 16));\n }\n self.emit('random', utils.hexToArray(message.random));\n }\n\n if (message.ledger_hash && message.ledger_index) {\n self._ledger_time = message.ledger_time;\n self._ledger_hash = message.ledger_hash;\n self._ledger_current_index = message.ledger_index+1;\n self.emit('ledger_closed', message);\n }\n\n // FIXME Use this to estimate fee.\n // XXX When we have multiple server support, most of this should be tracked\n // by the Server objects and then aggregated/interpreted by Remote.\n self._load_base = message.load_base || 256;\n self._load_factor = message.load_factor || 256;\n self._fee_ref = message.fee_ref;\n self._fee_base = message.fee_base;\n self._reserve_base = message.reserve_base;\n self._reserve_inc = message.reserve_inc;\n\n self.emit('subscribed');\n });\n\n request.on('error', function (err) {\n // XXX We need a better global error handling\n console.log(err);\n });\n\n self.emit('prepare_subscribe', request);\n\n request.callback(callback);\n\n // XXX Could give error events, maybe even time out.\n\n return request;\n};\n\n// For unit testing: ask the remote to accept the current ledger.\n// - To be notified when the ledger is accepted, server_subscribe() then listen to 'ledger_hash' events.\n// A good way to be notified of the result of this is:\n// remote.once('ledger_closed', function (ledger_closed, ledger_index) { ... } );\nRemote.prototype.ledger_accept = function (callback) {\n if (this._stand_alone) {\n var request = new Request(this, 'ledger_accept');\n request.request();\n request.callback(callback);\n } else {\n this.emit('error', { error : 'notStandAlone' });\n }\n return this;\n};\n\n// Return a request to refresh the account balance.\nRemote.prototype.request_account_balance = function (account, ledger, callback) {\n var request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(ledger);\n request.once('success', function (message) {\n request.emit('account_balance', Amount.from_json(message.node.Balance));\n });\n request.callback(callback, 'account_balance');\n return request;\n};\n\n// Return a request to return the account flags.\nRemote.prototype.request_account_flags = function (account, current, callback) {\n var request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n request.on('success', function (message) {\n request.emit('account_flags', message.node.Flags);\n });\n request.callback(callback, 'account_flags');\n return request;\n};\n\n// Return a request to emit the owner count.\nRemote.prototype.request_owner_count = function (account, current, callback) {\n var request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n request.on('success', function (message) {\n request.emit('owner_count', message.node.OwnerCount);\n });\n request.callback(callback, 'owner_count');\n return request;\n};\n\nRemote.prototype.get_account =\nRemote.prototype.account = function (accountId) {\n var accountId = UInt160.json_rewrite(accountId);\n var account = this._accounts[accountId];\n\n if (!account) {\n account = new Account(this, accountId);\n if (account.is_valid()) {\n this._accounts[accountId] = account;\n }\n }\n\n return account;\n};\n\nRemote.prototype.path_find = function (src_account, dst_account, dst_amount, src_currencies) {\n var path_find = new PathFind(this, src_account, dst_account, dst_amount, src_currencies);\n\n if (this._cur_path_find) {\n this._cur_path_find.notify_superceded();\n }\n\n path_find.create();\n\n this._cur_path_find = path_find;\n\n return path_find;\n};\n\nRemote.prototype.book = function (currency_gets, issuer_gets, currency_pays, issuer_pays) {\n var gets = currency_gets + (currency_gets === 'XRP' ? '' : ('/' + issuer_gets));\n var pays = currency_pays + (currency_pays === 'XRP' ? '' : ('/' + issuer_pays));\n var key = gets + ':' + pays;\n var book;\n\n if (!this._books.hasOwnProperty(key)) {\n book = new OrderBook(this, currency_gets, issuer_gets, currency_pays, issuer_pays);\n if (book.is_valid()) {\n this._books[key] = book;\n }\n }\n\n return this._books[key];\n};\n\n// Return the next account sequence if possible.\n// <-- undefined or Sequence\nRemote.prototype.account_seq = function (account, advance) {\n var account = UInt160.json_rewrite(account);\n var account_info = this.accounts[account];\n var seq;\n\n if (account_info && account_info.seq) {\n seq = account_info.seq;\n account_info.seq += { ADVANCE: 1, REWIND: -1 }[advance.toUpperCase()] || 0;\n }\n\n return seq;\n};\n\nRemote.prototype.set_account_seq = function (account, seq) {\n var account = UInt160.json_rewrite(account);\n\n if (!this.accounts.hasOwnProperty(account)) {\n this.accounts[account] = { };\n }\n\n this.accounts[account].seq = seq;\n}\n\n// Return a request to refresh accounts[account].seq.\nRemote.prototype.account_seq_cache = function (account, current, callback) {\n var self = this;\n\n if (!this.accounts.hasOwnProperty(account)) {\n this.accounts[account] = { };\n }\n\n var account_info = this.accounts[account];\n var request = account_info.caching_seq_request;\n\n if (!request) {\n // console.log('starting: %s', account);\n request = this.request_ledger_entry('account_root');\n request.account_root(account);\n request.ledger_choose(current);\n\n function account_root_success(message) {\n delete account_info.caching_seq_request;\n\n var seq = message.node.Sequence;\n account_info.seq = seq;\n\n // console.log('caching: %s %d', account, seq);\n // If the caller also waits for 'success', they might run before this.\n request.emit('success_account_seq_cache', message);\n }\n\n function account_root_error(message) {\n // console.log('error: %s', account);\n delete account_info.caching_seq_request;\n\n request.emit('error_account_seq_cache', message);\n }\n\n request.once('success', account_root_success);\n request.once('error', account_root_error);\n\n account_info.caching_seq_request = request;\n }\n\n request.callback(callback, 'success_account_seq_cache', 'error_account_seq_cache');\n\n return request;\n};\n\n// Mark an account's root node as dirty.\nRemote.prototype.dirty_account_root = function (account) {\n var account = UInt160.json_rewrite(account);\n delete this.ledgers.current.account_root[account];\n};\n\n// Store a secret - allows the Remote to automatically fill out auth information.\nRemote.prototype.set_secret = function (account, secret) {\n this.secrets[account] = secret;\n};\n\n\n// Return a request to get a ripple balance.\n//\n// --> account: String\n// --> issuer: String\n// --> currency: String\n// --> current: bool : true = current ledger\n//\n// If does not exist: emit('error', 'error' : 'remoteError', 'remote' : { 'error' : 'entryNotFound' })\nRemote.prototype.request_ripple_balance = function (account, issuer, currency, current, callback) {\n var request = this.request_ledger_entry('ripple_state'); // YYY Could be cached per ledger.\n\n request.ripple_state(account, issuer, currency);\n request.ledger_choose(current);\n request.once('success', function(message) {\n var node = message.node;\n var lowLimit = Amount.from_json(node.LowLimit);\n var highLimit = Amount.from_json(node.HighLimit);\n // The amount the low account holds of issuer.\n var balance = Amount.from_json(node.Balance);\n // accountHigh implies: for account: balance is negated, highLimit is the limit set by account.\n var accountHigh = UInt160.from_json(account).equals(highLimit.issuer());\n\n request.emit('ripple_state', {\n account_balance : ( accountHigh ? balance.negate() : balance.clone()).parse_issuer(account),\n peer_balance : (!accountHigh ? balance.negate() : balance.clone()).parse_issuer(issuer),\n\n account_limit : ( accountHigh ? highLimit : lowLimit).clone().parse_issuer(issuer),\n peer_limit : (!accountHigh ? highLimit : lowLimit).clone().parse_issuer(account),\n\n account_quality_in : ( accountHigh ? node.HighQualityIn : node.LowQualityIn),\n peer_quality_in : (!accountHigh ? node.HighQualityIn : node.LowQualityIn),\n\n account_quality_out : ( accountHigh ? node.HighQualityOut : node.LowQualityOut),\n peer_quality_out : (!accountHigh ? node.HighQualityOut : node.LowQualityOut),\n });\n });\n\n request.callback(callback, 'ripple_state');\n\n return request;\n};\n\nfunction prepare_currencies(ci) {\n var ci_new = { };\n\n if (ci.hasOwnProperty('issuer')) {\n ci_new.issuer = UInt160.json_rewrite(ci.issuer);\n }\n\n if (ci.hasOwnProperty('currency')) {\n ci_new.currency = Currency.json_rewrite(ci.currency);\n }\n\n return ci_new;\n}\n\nRemote.prototype.request_ripple_path_find = function (src_account, dst_account, dst_amount, src_currencies, callback) {\n var request = new Request(this, 'ripple_path_find');\n\n request.message.source_account = UInt160.json_rewrite(src_account);\n request.message.destination_account = UInt160.json_rewrite(dst_account);\n request.message.destination_amount = Amount.json_rewrite(dst_amount);\n\n if (src_currencies) {\n request.message.source_currencies = src_currencies.map(prepare_currencies);\n }\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_path_find_create = function (src_account, dst_account, dst_amount, src_currencies, callback) {\n var request = new Request(this, 'path_find');\n\n request.message.subcommand = 'create';\n request.message.source_account = UInt160.json_rewrite(src_account);\n request.message.destination_account = UInt160.json_rewrite(dst_account);\n request.message.destination_amount = Amount.json_rewrite(dst_amount);\n\n if (src_currencies) {\n request.message.source_currencies = src_currencies.map(prepare_currencies);\n }\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.request_path_find_close = function () {\n var request = new Request(this, 'path_find');\n request.message.subcommand = 'close';\n return request;\n};\n\nRemote.prototype.request_unl_list = function (callback) {\n return new Request(this, 'unl_list').callback(callback);\n};\n\nRemote.prototype.request_unl_add = function (addr, comment, callback) {\n var request = new Request(this, 'unl_add');\n\n request.message.node = addr;\n\n if (comment) {\n request.message.comment = note;\n }\n\n request.callback(callback);\n\n return request;\n};\n\n// --> node: | \nRemote.prototype.request_unl_delete = function (node, callback) {\n var request = new Request(this, 'unl_delete');\n request.message.node = node;\n request.callback(callback);\n return request;\n};\n\nRemote.prototype.request_peers = function (callback) {\n return new Request(this, 'peers').callback(callback);\n};\n\nRemote.prototype.request_connect = function (ip, port, callback) {\n var request = new Request(this, 'connect');\n\n request.message.ip = ip;\n\n if (port) {\n request.message.port = port;\n }\n\n request.callback(callback);\n\n return request;\n};\n\nRemote.prototype.transaction = function (source, destination, amount, callback) {\n var tx = new Transaction(this);\n\n if (arguments.length >= 3) {\n tx = tx.payment(source, destination, amount);\n if (typeof callback === 'function') {\n tx.submit(callback);\n }\n }\n\n return tx;\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 * @return {Amount} Final fee in XRP for specified number of fee units.\n */\nRemote.prototype.fee_tx = function (units) {\n var fee_unit = this.fee_tx_unit();\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 */\nRemote.prototype.fee_tx_unit = 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 */\nRemote.prototype.reserve = function (owner_count) {\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 = owner_count || 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\nRemote.prototype.ping = function(host, callback) {\n var request = new Request(this, 'ping');\n\n switch (typeof host) {\n case 'function':\n callback = host;\n break;\n case 'string':\n request.set_server(host);\n break;\n }\n\n var then = Date.now();\n\n request.once('success', function() {\n request.emit('pong', Date.now() - then);\n });\n\n request.callback(callback, 'pong');\n\n return request;\n};\n\nexports.Remote = Remote;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 1\n// module.readableIdentifier = ./src/js/ripple/remote.js\n//@ sourceURL=webpack-module:///./src/js/ripple/remote.js"); /***/ }, @@ -70,7 +70,7 @@ var ripple = /***/ 3: /***/ function(module, exports, require) { - eval("\n//\n// Currency support\n//\n\n// XXX Internal form should be UInt160.\nvar Currency = 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\n// Given \"USD\" return the json.\nCurrency.json_rewrite = function (j) {\n return Currency.from_json(j).to_json();\n};\n\nCurrency.from_json = function (j) {\n if (j instanceof Currency) {\n return j.clone();\n } else {\n return new Currency().parse_json(j);\n }\n};\n\nCurrency.from_bytes = function (j) {\n if (j instanceof Currency) {\n return j.clone();\n } else {\n return new Currency().parse_bytes(j);\n }\n};\n\nCurrency.is_valid = function (j) {\n return Currency.from_json(j).is_valid();\n};\n\nCurrency.prototype.clone = function() {\n return this.copyTo(new Currency());\n};\n\n// Returns copy.\nCurrency.prototype.copyTo = function (d) {\n d._value = this._value;\n\n return d;\n};\n\nCurrency.prototype.equals = function (d) {\n return ('string' !== typeof this._value && isNaN(this._value))\n || ('string' !== typeof d._value && isNaN(d._value)) ? false : this._value === d._value;\n};\n\n// this._value = NaN on error.\nCurrency.prototype.parse_json = function (j) {\n if (j instanceof Currency) {\n this._value = j;\n } else if ('string' === typeof j) {\n if (j === \"\" || j === \"0\" || j === \"XRP\") {\n // XRP is never allowed as a Currency object\n this._value = 0;\n } else if (j.length === 3) {\n this._value = j;\n } else {\n this._value = NaN;\n }\n } else if ('number' === typeof j) {\n // XXX This is a hack\n this._value = j;\n } else if ('string' != typeof j || 3 !== j.length) {\n this._value = NaN;\n } else {\n this._value = j;\n }\n\n return this;\n};\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 for (var i=0; i<20; i++) {\n isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || byte_array[0]===0)\n }\n if (isZeroExceptInStandardPositions) {\n var currencyCode = String.fromCharCode(byte_array[12]) + String.fromCharCode(byte_array[13]) + String.fromCharCode(byte_array[14]);\n if (/^[A-Z]{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\nCurrency.prototype.is_native = function () {\n return !isNaN(this._value) && !this._value;\n};\n\nCurrency.prototype.is_valid = function () {\n return 'string' === typeof this._value || !isNaN(this._value);\n};\n\nCurrency.prototype.to_json = function () {\n return this._value ? this._value : \"XRP\";\n};\n\nCurrency.prototype.to_human = function () {\n return this._value ? this._value : \"XRP\";\n};\n\nexports.Currency = Currency;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 3\n// module.readableIdentifier = ./src/js/ripple/currency.js\n//@ sourceURL=webpack-module:///./src/js/ripple/currency.js"); + eval("\n//\n// Currency support\n//\n\n// XXX Internal form should be UInt160.\nvar Currency = 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\n// Given \"USD\" return the json.\nCurrency.json_rewrite = function (j) {\n return Currency.from_json(j).to_json();\n};\n\nCurrency.from_json = function (j) {\n if (j instanceof Currency) {\n return j.clone();\n } else {\n return new Currency().parse_json(j);\n }\n};\n\nCurrency.from_bytes = function (j) {\n if (j instanceof Currency) {\n return j.clone();\n } else {\n return new Currency().parse_bytes(j);\n }\n};\n\nCurrency.is_valid = function (j) {\n return Currency.from_json(j).is_valid();\n};\n\nCurrency.prototype.clone = function() {\n return this.copyTo(new Currency());\n};\n\n// Returns copy.\nCurrency.prototype.copyTo = function (d) {\n d._value = this._value;\n\n return d;\n};\n\nCurrency.prototype.equals = function (d) {\n return ('string' !== typeof this._value && isNaN(this._value))\n || ('string' !== typeof d._value && isNaN(d._value)) ? false : this._value === d._value;\n};\n\n// this._value = NaN on error.\nCurrency.prototype.parse_json = function (j) {\n if (j instanceof Currency) {\n this._value = j;\n } else if ('string' === typeof j) {\n if (j === \"\" || j === \"0\" || j === \"XRP\") {\n // XRP is never allowed as a Currency object\n this._value = 0;\n } else if (j.length === 3) {\n this._value = j;\n } else {\n this._value = NaN;\n }\n } else if ('number' === typeof j) {\n // XXX This is a hack\n this._value = j;\n } else if ('string' != typeof j || 3 !== j.length) {\n this._value = NaN;\n } else {\n this._value = j;\n }\n\n return this;\n};\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 for (var i=0; i<20; i++) {\n isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || byte_array[0]===0)\n }\n if (isZeroExceptInStandardPositions) {\n var currencyCode = String.fromCharCode(byte_array[12]) + String.fromCharCode(byte_array[13]) + 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\nCurrency.prototype.is_native = function () {\n return !isNaN(this._value) && !this._value;\n};\n\nCurrency.prototype.is_valid = function () {\n return 'string' === typeof this._value || !isNaN(this._value);\n};\n\nCurrency.prototype.to_json = function () {\n return this._value ? this._value : \"XRP\";\n};\n\nCurrency.prototype.to_human = function () {\n return this._value ? this._value : \"XRP\";\n};\n\nexports.Currency = Currency;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 3\n// module.readableIdentifier = ./src/js/ripple/currency.js\n//@ sourceURL=webpack-module:///./src/js/ripple/currency.js"); /***/ }, @@ -84,7 +84,7 @@ var ripple = /***/ 5: /***/ function(module, exports, require) { - 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 correct as incorrect.\n// - it may not communicate with the rest of the network.\n// - may or may not forward.\n//\n\nvar EventEmitter = require(27).EventEmitter;\nvar util = require(28);\n\nvar sjcl = require(11);\n\nvar Amount = require(2).Amount;\nvar Currency = require(2).Currency;\nvar UInt160 = require(2).UInt160;\nvar Seed = require(21).Seed;\nvar SerializedObject = require(7).SerializedObject;\nvar RippleError = require(19).RippleError;\n\nvar config = require(12);\n\n// A class to implement transactions.\n// - Collects parameters\n// - Allow event listeners to be attached to determine the outcome.\nfunction Transaction(remote) {\n EventEmitter.call(this);\n\n var self = this;\n\n this.remote = remote;\n this._secret = void(0);\n this._build_path = false;\n\n // Transaction data.\n this.tx_json = { Flags: 0 };\n\n this.hash = void(0);\n\n // ledger_current_index was this when transaction was submited.\n this.submit_index = void(0); \n\n // Under construction.\n this.state = void(0); \n\n this.finalized = false;\n this._previous_signing_hash = void(0);\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 AccountSet: {\n RequireDestTag: 0x00010000,\n OptionalDestTag: 0x00020000,\n RequireAuth: 0x00040000,\n OptionalAuth: 0x00080000,\n DisallowXRP: 0x00100000,\n AllowXRP: 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\nTransaction.formats = require(8).tx;\n\nTransaction.HASH_SIGN = 0x53545800;\nTransaction.HASH_SIGN_TESTNET = 0x73747800;\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.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.set_state = function (state) {\n if (this.state !== state) {\n this.state = state;\n this.emit('state', state);\n }\n};\n\n/**\n * TODO\n * Actually do this right\n */\n\nTransaction.prototype.get_fee = function() {\n return Transaction.fees['default'].to_json();\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 */\nTransaction.prototype.complete = function () {\n var tx_json = this.tx_json;\n\n if (typeof tx_json.Fee === 'undefined') {\n if (this.remote.local_fee || !this.remote.trusted) {\n this.tx_json.Fee = this.remote.fee_tx(this.fee_units()).to_json();\n }\n }\n\n if (typeof tx_json.SigningPubKey === 'undefined' && (!this.remote || this.remote.local_signing)) {\n var seed = Seed.from_json(this._secret);\n var key = seed.get_key(this.tx_json.Account);\n tx_json.SigningPubKey = key.to_hex_pub();\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.signing_hash = function () {\n var prefix = Transaction[config.testnet ? 'HASH_SIGN_TESTNET' : 'HASH_SIGN'];\n return SerializedObject.from_json(this.tx_json).signing_hash(prefix);\n};\n\nTransaction.prototype.sign = function () {\n var seed = Seed.from_json(this._secret);\n var hash = this.signing_hash();\n\n var previously_signed = this.tx_json.TxnSignature \n && hash === this._previous_signing_hash;\n\n if (previously_signed) return;\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};\n\n//\n// Set options for Transactions\n//\n\n// --> 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.build_path = 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.destination_tag = function (tag) {\n if (tag !== void(0)) {\n this.tx_json.DestinationTag = tag;\n }\n return this;\n}\n\nTransaction._path_rewrite = function (path) {\n var props = [\n 'account'\n , 'issuer'\n , 'currency'\n ]\n\n var path_new = path.map(function(node) {\n var node_new = { };\n\n for (var prop in node) {\n if (~props.indexOf(prop)) {\n node_new[prop] = UInt160.json_rewrite(node[prop]);\n }\n }\n\n return node_new;\n });\n\n return path_new;\n}\n\nTransaction.prototype.path_add = function (path) {\n this.tx_json.Paths = this.tx_json.Paths || [];\n this.tx_json.Paths.push(Transaction._path_rewrite(path));\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\nTransaction.prototype.paths = function (paths) {\n for (var i=0, l=paths.length; i rate: In billionths.\nTransaction.prototype.transfer_rate = 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.set_flags = function (flags) {\n if (flags) {\n var transaction_flags = Transaction.flags[this.tx_json.TransactionType];\n\n // We plan to not define this field on new Transaction.\n if (this.tx_json.Flags === void(0)) {\n this.tx_json.Flags = 0;\n }\n\n var flag_set = Array.isArray(flags) ? flags : [ flags ];\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.offer_create = function (src, taker_pays, taker_gets, expiration, cancel_sequence) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\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 (this.remote.local_fee) {\n //this.tx_json.Fee = Transaction.fees.offer.to_json();\n }\n\n if (expiration) {\n this.tx_json.Expiration = expiration instanceof Date\n ? expiration.getTime()\n : Number(expiration);\n }\n\n if (cancel_sequence) {\n this.tx_json.OfferSequence = Number(cancel_sequence);\n }\n\n return this;\n};\n\nTransaction.prototype.password_fund = function (src, dst) {\n if (!UInt160.is_valid(dst)) {\n throw new Error('Destination address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'PasswordFund';\n this.tx_json.Destination = UInt160.json_rewrite(dst);\n return this;\n}\n\nTransaction.prototype.password_set = function (src, authorized_key, generator, public_key, signature) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'PasswordSet';\n this.tx_json.RegularKey = authorized_key;\n this.tx_json.Generator = generator;\n this.tx_json.PublicKey = public_key;\n this.tx_json.Signature = signature;\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, deliver_amount) {\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._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'Payment';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.Amount = Amount.json_rewrite(deliver_amount);\n this.tx_json.Destination = UInt160.json_rewrite(dst);\n\n return this;\n}\n\nTransaction.prototype.ripple_line_set = function (src, limit, quality_in, quality_out) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'TrustSet';\n this.tx_json.Account = UInt160.json_rewrite(src);\n\n // Allow limit of 0 through.\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\nTransaction.prototype.wallet_add = function (src, amount, authorized_key, public_key, signature) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'WalletAdd';\n this.tx_json.Amount = Amount.json_rewrite(amount);\n this.tx_json.RegularKey = authorized_key;\n this.tx_json.PublicKey = public_key;\n this.tx_json.Signature = signature;\n return this;\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 */\nTransaction.prototype.fee_units = function () {\n return Transaction.fee_units['default'];\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 submission_error(error, message) {\n if (!(error instanceof RippleError)) {\n error = new RippleError(error, message);\n }\n self.callback(error);\n }\n\n function submission_success(message) {\n self.callback(null, message);\n }\n\n this.once('error', submission_error);\n this.once('success', submission_success);\n\n var account = this.tx_json.Account;\n\n if (typeof account !== 'string') {\n this.emit('error', new RippleError('tejInvalidAccount', 'Account is unspecified'));\n } else {\n // YYY Might check paths for invalid accounts.\n this.remote.get_account(account).submit(this);\n }\n\n return this;\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 correct as incorrect.\n// - it may not communicate with the rest of the network.\n// - may or may not forward.\n//\n\nvar EventEmitter = require(27).EventEmitter;\nvar util = require(28);\n\nvar sjcl = require(11);\n\nvar Amount = require(2).Amount;\nvar Currency = require(2).Currency;\nvar UInt160 = require(2).UInt160;\nvar Seed = require(21).Seed;\nvar SerializedObject = require(7).SerializedObject;\nvar RippleError = require(19).RippleError;\n\nvar config = require(12);\n\n// A class to implement transactions.\n// - Collects parameters\n// - Allow event listeners to be attached to determine the outcome.\nfunction Transaction(remote) {\n EventEmitter.call(this);\n\n var self = this;\n\n this.remote = remote;\n this._secret = void(0);\n this._build_path = false;\n\n // Transaction data.\n this.tx_json = { Flags: 0 };\n\n this.hash = void(0);\n\n // ledger_current_index was this when transaction was submited.\n this.submit_index = void(0);\n\n // Under construction.\n this.state = void(0);\n\n this.finalized = false;\n this._previous_signing_hash = void(0);\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 AccountSet: {\n RequireDestTag: 0x00010000,\n OptionalDestTag: 0x00020000,\n RequireAuth: 0x00040000,\n OptionalAuth: 0x00080000,\n DisallowXRP: 0x00100000,\n AllowXRP: 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\nTransaction.formats = require(8).tx;\n\nTransaction.HASH_SIGN = 0x53545800;\nTransaction.HASH_SIGN_TESTNET = 0x73747800;\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.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.set_state = function (state) {\n if (this.state !== state) {\n this.state = state;\n this.emit('state', state);\n }\n};\n\n/**\n * TODO\n * Actually do this right\n */\n\nTransaction.prototype.get_fee = function() {\n return Transaction.fees['default'].to_json();\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 */\nTransaction.prototype.complete = function () {\n if (this.remote && typeof this.tx_json.Fee === 'undefined') {\n if (this.remote.local_fee || !this.remote.trusted) {\n this.tx_json.Fee = this.remote.fee_tx(this.fee_units()).to_json();\n }\n }\n\n if (typeof this.tx_json.SigningPubKey === 'undefined' && (!this.remote || this.remote.local_signing)) {\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 }\n\n return this.tx_json;\n};\n\nTransaction.prototype.serialize = function () {\n return SerializedObject.from_json(this.tx_json);\n};\n\nTransaction.prototype.signing_hash = function () {\n var prefix = Transaction[config.testnet ? 'HASH_SIGN_TESTNET' : 'HASH_SIGN'];\n return SerializedObject.from_json(this.tx_json).signing_hash(prefix);\n};\n\nTransaction.prototype.sign = function () {\n var seed = Seed.from_json(this._secret);\n var hash = this.signing_hash();\n\n var previously_signed = this.tx_json.TxnSignature\n && hash === this._previous_signing_hash;\n\n if (previously_signed) return;\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};\n\n//\n// Set options for Transactions\n//\n\n// --> 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.build_path = 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.destination_tag = function (tag) {\n if (tag !== void(0)) {\n this.tx_json.DestinationTag = tag;\n }\n return this;\n}\n\nTransaction._path_rewrite = function (path) {\n var path_new = path.map(function(node) {\n var node_new = { };\n\n if (node.hasOwnProperty('account')) {\n node_new.account = UInt160.json_rewrite(node.account);\n }\n\n if (node.hasOwnProperty('issuer')) {\n node_new.issuer = UInt160.json_rewrite(node.issuer);\n }\n\n if (node.hasOwnProperty('currency')) {\n node_new.currency = Currency.json_rewrite(node.currency);\n }\n\n return node_new;\n });\n\n return path_new;\n}\n\nTransaction.prototype.path_add = function (path) {\n this.tx_json.Paths = this.tx_json.Paths || [];\n this.tx_json.Paths.push(Transaction._path_rewrite(path));\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\nTransaction.prototype.paths = function (paths) {\n for (var i=0, l=paths.length; i rate: In billionths.\nTransaction.prototype.transfer_rate = 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.set_flags = function (flags) {\n if (flags) {\n var transaction_flags = Transaction.flags[this.tx_json.TransactionType];\n\n // We plan to not define this field on new Transaction.\n if (this.tx_json.Flags === void(0)) {\n this.tx_json.Flags = 0;\n }\n\n var flag_set = Array.isArray(flags) ? flags : [ flags ];\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.offer_create = function (src, taker_pays, taker_gets, expiration, cancel_sequence) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\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 (this.remote.local_fee) {\n //this.tx_json.Fee = Transaction.fees.offer.to_json();\n }\n\n if (expiration) {\n this.tx_json.Expiration = expiration instanceof Date\n ? expiration.getTime()\n : Number(expiration);\n }\n\n if (cancel_sequence) {\n this.tx_json.OfferSequence = Number(cancel_sequence);\n }\n\n return this;\n};\n\nTransaction.prototype.password_fund = function (src, dst) {\n if (!UInt160.is_valid(dst)) {\n throw new Error('Destination address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'PasswordFund';\n this.tx_json.Destination = UInt160.json_rewrite(dst);\n return this;\n}\n\nTransaction.prototype.password_set = function (src, authorized_key, generator, public_key, signature) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'PasswordSet';\n this.tx_json.RegularKey = authorized_key;\n this.tx_json.Generator = generator;\n this.tx_json.PublicKey = public_key;\n this.tx_json.Signature = signature;\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, deliver_amount) {\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._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'Payment';\n this.tx_json.Account = UInt160.json_rewrite(src);\n this.tx_json.Amount = Amount.json_rewrite(deliver_amount);\n this.tx_json.Destination = UInt160.json_rewrite(dst);\n\n return this;\n}\n\nTransaction.prototype.ripple_line_set = function (src, limit, quality_in, quality_out) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'TrustSet';\n this.tx_json.Account = UInt160.json_rewrite(src);\n\n // Allow limit of 0 through.\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\nTransaction.prototype.wallet_add = function (src, amount, authorized_key, public_key, signature) {\n if (!UInt160.is_valid(src)) {\n throw new Error('Source address invalid');\n }\n\n this._secret = this._account_secret(src);\n this.tx_json.TransactionType = 'WalletAdd';\n this.tx_json.Amount = Amount.json_rewrite(amount);\n this.tx_json.RegularKey = authorized_key;\n this.tx_json.PublicKey = public_key;\n this.tx_json.Signature = signature;\n return this;\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 */\nTransaction.prototype.fee_units = function () {\n return Transaction.fee_units['default'];\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 submission_error(error, message) {\n if (!(error instanceof RippleError)) {\n error = new RippleError(error, message);\n }\n self.callback(error);\n }\n\n function submission_success(message) {\n self.callback(null, message);\n }\n\n this.on('error', function(){});\n this.once('error', submission_error);\n this.once('success', submission_success);\n\n var account = this.tx_json.Account;\n\n if (typeof account !== 'string') {\n this.emit('error', new RippleError('tejInvalidAccount', 'Account is unspecified'));\n } else {\n // YYY Might check paths for invalid accounts.\n this.remote.get_account(account).submit(this);\n }\n\n return this;\n};\n\nTransaction.prototype.abort = function(callback) {\n if (!this.finalized) {\n var callback = typeof callback === 'function' ? callback : function(){};\n this.once('final', callback);\n this.emit('abort');\n }\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"); /***/ }, @@ -98,7 +98,7 @@ var ripple = /***/ 7: /***/ function(module, exports, require) { - eval("/* WEBPACK VAR INJECTION */(function(require, Buffer) {var binformat = require(8),\n sjcl = require(11),\n extend = require(29),\n stypes = require(22);\n\nvar UInt256 = require(23).UInt256;\n\nvar SerializedObject = function (buf) {\n if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {\n this.buffer = buf;\n } else if (\"string\" === typeof buf) {\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 var typedef;\n var so = new SerializedObject();\n\n // Create a copy of the object so we don't modify it\n obj = extend({}, obj);\n\n if (\"number\" === typeof obj.TransactionType) {\n obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType);\n\n if (!obj.TransactionType) {\n throw new Error(\"Transaction type ID is invalid.\");\n }\n }\n\n if (\"string\" === typeof obj.TransactionType) {\n typedef = binformat.tx[obj.TransactionType].slice();\n\n obj.TransactionType = typedef.shift();\n } else if (\"undefined\" !== typeof obj.LedgerEntryType) {\n // XXX: TODO\n throw new Error(\"Ledger entry binary format not yet implemented.\");\n } else throw new Error(\"Object to be serialized must contain either \" +\n \"TransactionType or LedgerEntryType.\");\n\n so.serialize(typedef, obj);\n\n return so;\n};\n\nSerializedObject.prototype.append = function (bytes) {\n this.buffer = this.buffer.concat(bytes);\n this.pointer += bytes.length;\n};\n\nSerializedObject.prototype.resetPointer = function () {\n this.pointer = 0;\n};\n\n/*\nSerializedObject.prototype.read = function (numberOfBytes) {\n var start = this.pointer;\n var end = start+numberOfBytes;\n if (end > this.buffer.length) {\n\tthrow new Error(\"There aren't that many bytes left to read.\");\n } else {\n\tvar result = this.buffer.slice(start,end);\n\tthis.pointer = end;\n\treturn result;\n }\n};\n*/\n\nvar readOrPeek = function (advance) {\n return function(numberOfBytes) {\n\t var start = this.pointer;\n\t var end = start+numberOfBytes;\n\t if (end > this.buffer.length) {\n\t\tthrow new Error(\"There aren't that many bytes left.\");\n\t } else {\n\t\tvar result = this.buffer.slice(start,end);\n\t\tif (advance) {this.pointer = end;}\n\t\treturn result;\n\t }\n }\n}\nSerializedObject.prototype.read = readOrPeek(true);\nSerializedObject.prototype.peek = readOrPeek(false);\n\n\nSerializedObject.prototype.to_bits = function ()\n{\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\n\n\n\nvar TRANSACTION_TYPES = {\n\t0:\"Payment\",\n\t3:\"AccountSet\",\n\t5:\"SetRegularKey\",\n\t7:\"OfferCreate\",\n\t8:\"OfferCancel\",\n\t9:\"Contract\",\n\t10:\"RemoveContract\",\n\t20:\"TrustSet\",\n\t100:\"EnableFeature\",\n\t101:\"SetFee\"\n};\n\nSerializedObject.prototype.to_json = function() {\n\tvar old_pointer = this.pointer;\n\tthis.resetPointer();\n\tvar output = \"{\";\n\twhile (true) {\n\t\tvar key_and_value = stypes.parse_whatever(this);\n\t\tvar key = key_and_value[0];\n\t\tvar value = key_and_value[1];\n\t\toutput += (\"\\\"\" + key + \"\\\":\" + jsonify_structure(value,key));\n\t\toutput += \",\";\n\t\tif (this.pointer == this.buffer.length) {\n\t\t\tbreak;\n\t\t} else if (this.pointer > this.buffer.length) {\n\t\t\tconsole.log(\"WARNING: Buffer length exceeded during SerializedObject.to_json\");\n\t\t\tbreak;\n\t\t}\n\t}\n\toutput = output.slice(0,-1);\n\toutput += \"}\";\n\tthis.pointer = old_pointer;\n\toutput = JSON.parse(output);\n\treturn output;\n}\n\nfunction jsonify_structure(thing,field_name) {\n\tvar output;\n\tvar typeof_thing = typeof thing;\n\tif (typeof_thing === \"number\") { //Special codes\n\t\tif (field_name) {\n\t\t\tif (field_name === \"LedgerEntryType\") {\n\t\t\t\toutput = thing; //TODO: Do we have special codes for LedgerEntryType?\n\t\t\t} else if (field_name === \"TransactionType\") {\n\t\t\t\toutput = \"\\\"\"+TRANSACTION_TYPES[thing]+\"\\\"\" || thing;\n\t\t\t} else {\n\t\t\t\toutput = thing;\n\t\t\t}\n\t\t} else {\n\t\t\toutput = thing;\n\t\t}\n\t} else if (typeof_thing === \"boolean\") {\n\t\toutput = thing;\n\t} else if (typeof_thing === \"string\") {\n\t\toutput = \"\\\"\" + thing + \"\\\"\";\n\t} else if ( \"function\" === typeof thing.to_json ) {\n\t\toutput = JSON.stringify(thing.to_json());\n\t} else if (Array.isArray(thing)) {\n\t\t//console.log(\"here2\");\n\t\t//iterate over array []\n\t\toutput = \"[\";\n\t\tfor (var i=0; i< thing.length; i++) {\n\t\t\toutput += jsonify_structure(thing[i]);\n\t\t\toutput += \",\";\n\t\t}\n\t\toutput = output.slice(0,-1);\n\t\toutput += \"]\";\n\t} else {\n\t\t//console.log(\"here1\", thing);\n\t\t//iterate over object {}\n\t\toutput = \"{\";\n\t\tvar keys = Object.keys(thing);\n\t\t//console.log(keys);\n\t\tfor (var i=0; i 0xf) buffer.push(type_id & 0xff);\n else buffer[0] += (type_id & 0xf) << 4;\n\n if (field_id > 0xf) buffer.push(field_id & 0xff);\n else buffer[0] += field_id & 0xf;\n\n return buffer;\n};\n\nfunction sort_field_compare(a, b) {\n // Sort by type id first, then by field id\n return a[3].id !== b[3].id ?\n a[3].id - b[3].id :\n a[2] - b[2];\n};\nSerializedObject._sort_typedef = function (typedef) {\n return typedef.sort(sort_field_compare);\n};\n\nSerializedObject.lookup_type_tx = function (id) {\n for (var i in binformat.tx) {\n if (!binformat.tx.hasOwnProperty(i)) continue;\n\n if (binformat.tx[i][0] === id) {\n return i;\n }\n }\n\n return null;\n};\n\n\nexports.SerializedObject = SerializedObject;\n\n/* WEBPACK VAR INJECTION */}(require, require(24).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 7\n// module.readableIdentifier = ./src/js/ripple/serializedobject.js\n//@ sourceURL=webpack-module:///./src/js/ripple/serializedobject.js"); + eval("/* WEBPACK VAR INJECTION */(function(require, Buffer) {var binformat = require(8),\n sjcl = require(11),\n extend = require(29),\n stypes = require(22);\n\nvar UInt256 = require(23).UInt256;\n\nvar SerializedObject = function (buf) {\n if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {\n this.buffer = buf;\n } else if (\"string\" === typeof buf) {\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 var typedef;\n var so = new SerializedObject();\n\n // Create a copy of the object so we don't modify it\n obj = extend({}, obj);\n\n if (\"number\" === typeof obj.TransactionType) {\n obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType);\n\n if (!obj.TransactionType) {\n throw new Error(\"Transaction type ID is invalid.\");\n }\n }\n\n if (\"string\" === typeof obj.TransactionType) {\n typedef = binformat.tx[obj.TransactionType].slice();\n\n obj.TransactionType = typedef.shift();\n } else if (\"undefined\" !== typeof obj.LedgerEntryType) {\n // XXX: TODO\n throw new Error(\"Ledger entry binary format not yet implemented.\");\n } else throw new Error(\"Object to be serialized must contain either \" +\n \"TransactionType or LedgerEntryType.\");\n\n so.serialize(typedef, obj);\n\n return so;\n};\n\nSerializedObject.prototype.append = function (bytes) {\n this.buffer = this.buffer.concat(bytes);\n this.pointer += bytes.length;\n};\n\nSerializedObject.prototype.resetPointer = function () {\n this.pointer = 0;\n};\n\n\nvar readOrPeek = function (advance) {\n return function(numberOfBytes) {\n\t var start = this.pointer;\n\t var end = start+numberOfBytes;\n\t if (end > this.buffer.length) {\n\t\tthrow new Error(\"There aren't that many bytes left.\");\n\t } else {\n\t\tvar result = this.buffer.slice(start,end);\n\t\tif (advance) {this.pointer = end;}\n\t\treturn result;\n\t }\n }\n}\nSerializedObject.prototype.read = readOrPeek(true);\nSerializedObject.prototype.peek = readOrPeek(false);\n\n\nSerializedObject.prototype.to_bits = function ()\n{\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\n\n\n\nvar TRANSACTION_TYPES = {\n\t0:\"Payment\",\n\t3:\"AccountSet\",\n\t5:\"SetRegularKey\",\n\t7:\"OfferCreate\",\n\t8:\"OfferCancel\",\n\t9:\"Contract\",\n\t10:\"RemoveContract\",\n\t20:\"TrustSet\",\n\t100:\"EnableFeature\",\n\t101:\"SetFee\"\n};\n\nvar LEDGER_ENTRY_TYPES = {\n\t97:\"AccountRoot\",\n\t99:\"Contract\",\n\t100:\"DirectoryNode\",\n\t102:\"Features\",\n\t103:\"GeneratorMap\",\n\t104:\"LedgerHashes\",\n\t110:\"Nickname\",\n\t111:\"Offer\",\n\t114:\"RippleState\",\n\t115:\"FeeSettings\"\n};\n\nvar TRANSACTION_RESULTS = {\n 0 :\"tesSUCCESS\",\n\t100:\"tecCLAIM\",\n\t101:\"tecPATH_PARTIAL\",\n\t102:\"tecUNFUNDED_ADD\",\n\t103:\"tecUNFUNDED_OFFER\",\n\t104:\"tecUNFUNDED_PAYMENT\",\n\t105:\"tecFAILED_PROCESSING\",\n\t121:\"tecDIR_FULL\",\n\t122:\"tecINSUF_RESERVE_LINE\",\n\t123:\"tecINSUF_RESERVE_OFFER\",\n\t124:\"tecNO_DST\",\n\t125:\"tecNO_DST_INSUF_XRP\",\n\t126:\"tecNO_LINE_INSUF_RESERVE\",\n\t127:\"tecNO_LINE_REDUNDANT\",\n\t128:\"tecPATH_DRY\",\n\t129:\"tecUNFUNDED\", // Deprecated, old ambiguous unfunded.\n\t130:\"tecMASTER_DISABLED\",\n\t131:\"tecNO_REGULAR_KEY\",\n\t132:\"tecOWNERS\"\n};\n\n\n\n\n\nSerializedObject.prototype.to_json = function() {\n\tvar old_pointer = this.pointer;\n\tthis.resetPointer();\n\tvar output = {};\n\twhile (true) {\n\t\tvar key_and_value = stypes.parse_whatever(this);\n\t\tvar key = key_and_value[0];\n\t\tvar value = key_and_value[1];\n\t\toutput[key] = jsonify_structure(value,key);\n\t\tif (this.pointer == this.buffer.length) {\n\t\t\tbreak;\n\t\t} else if (this.pointer > this.buffer.length) {\n\t\t\tconsole.log(\"WARNING: Buffer length exceeded during SerializedObject.to_json\");\n\t\t\tbreak;\n\t\t}\n\t}\n\tthis.pointer = old_pointer;\n\treturn output;\n}\n\nfunction jsonify_structure(thing,field_name) {\n\tvar output;\n\tvar typeof_thing = typeof thing;\n\tif (\"number\" === typeof thing) { //Special codes\n\t\tif (field_name) {\n\t\t\tif (field_name === \"LedgerEntryType\") {\n\t\t\t\toutput = LEDGER_ENTRY_TYPES[thing] || thing;\n\t\t\t} else if (field_name === \"TransactionResult\") {\n\t\t\t\toutput = TRANSACTION_RESULTS[thing] || thing;\n\t\t\t} else if (field_name === \"TransactionType\") {\n\t\t\t\toutput = TRANSACTION_TYPES[thing] || thing;\n\t\t\t} else {\n\t\t\t\toutput = thing;\n\t\t\t}\n\t\t} else {\n\t\t\toutput = thing;\n\t\t}\n\t} else if (\"object\" === typeof thing &&\n \"function\" === typeof thing.to_json) {\n\t\toutput = thing.to_json();\n\t} else if (Array.isArray(thing)) {\n\t\t//console.log(\"here2\");\n\t\t//iterate over array []\n\t\toutput = [];\n\t\tfor (var i=0; i< thing.length; i++) {\n\t\t\toutput.push(jsonify_structure(thing[i]));\n\t\t}\n\t} else if (\"object\" === typeof thing) {\n\t\t//console.log(\"here1\", thing);\n\t\t//iterate over object {}\n\t\toutput = {};\n\t\tvar keys = Object.keys(thing);\n\t\tfor (var i=0; i 0xf) buffer.push(type_id & 0xff);\n else buffer[0] += (type_id & 0xf) << 4;\n\n if (field_id > 0xf) buffer.push(field_id & 0xff);\n else buffer[0] += field_id & 0xf;\n\n return buffer;\n};\n\nfunction sort_field_compare(a, b) {\n // Sort by type id first, then by field id\n return a[3].id !== b[3].id ?\n a[3].id - b[3].id :\n a[2] - b[2];\n};\nSerializedObject._sort_typedef = function (typedef) {\n return typedef.sort(sort_field_compare);\n};\n\nSerializedObject.lookup_type_tx = function (id) {\n for (var i in binformat.tx) {\n if (!binformat.tx.hasOwnProperty(i)) continue;\n\n if (binformat.tx[i][0] === id) {\n return i;\n }\n }\n\n return null;\n};\n\n\nexports.SerializedObject = SerializedObject;\n\n/* WEBPACK VAR INJECTION */}(require, require(24).Buffer))\n\n// WEBPACK FOOTER\n// module.id = 7\n// module.readableIdentifier = ./src/js/ripple/serializedobject.js\n//@ sourceURL=webpack-module:///./src/js/ripple/serializedobject.js"); /***/ }, @@ -147,21 +147,21 @@ var ripple = /***/ 14: /***/ function(module, exports, require) { - eval("var EventEmitter = require(27).EventEmitter;\nvar util = require(28);\nvar UInt160 = require(15).UInt160;\nvar Currency = require(3).Currency;\nvar Transaction = require(5).Transaction;\nvar Account = require(16).Account;\nvar Meta = require(6).Meta;\nvar OrderBook = require(17).OrderBook;\nvar RippleError = require(19).RippleError;\n\n// Request events emitted:\n// 'success' : Request successful.\n// 'error' : Request failed.\n// 'remoteError'\n// 'remoteUnexpected'\n// 'remoteDisconnected'\nfunction Request(remote, command) {\n EventEmitter.call(this);\n\n this.remote = remote;\n this.requested = false;\n this.message = {\n command : command,\n id : void(0)\n };\n};\n\nutil.inherits(Request, EventEmitter);\n\n// Send the request to a remote.\nRequest.prototype.request = function (remote) {\n if (!this.requested) {\n this.requested = true;\n this.remote.request(this);\n this.emit('request', remote);\n }\n};\n\nRequest.prototype.callback = function(callback, successEvent, errorEvent) {\n if (callback && typeof callback === 'function') {\n function request_success(message) {\n callback.call(this, null, message);\n }\n\n function request_error(error) {\n if (!(error instanceof RippleError)) {\n error = new RippleError(error);\n }\n callback.call(this, error);\n }\n\n this.once(successEvent || 'success', request_success);\n this.once(errorEvent || 'error' , request_error);\n this.request();\n }\n\n return this;\n};\n\nRequest.prototype.timeout = function(duration, callback) {\n var self = this;\n\n if (!this.requested) {\n function requested() {\n self.timeout(duration, callback);\n }\n this.once('request', requested);\n return;\n }\n\n var emit = this.emit;\n var timed_out = false;\n\n var timeout = setTimeout(function() {\n timed_out = true;\n if (typeof callback === 'function') callback();\n emit.call(self, 'timeout');\n }, duration);\n\n this.emit = function() {\n if (!timed_out) {\n clearTimeout(timeout);\n emit.apply(self, arguments);\n }\n };\n\n return this;\n};\n\nRequest.prototype.set_server = function(server) {\n this.server = server;\n};\n\nRequest.prototype.build_path = function (build) {\n if (build) {\n this.message.build_path = true;\n }\n return this;\n};\n\nRequest.prototype.ledger_choose = function (current) {\n if (current) {\n this.message.ledger_index = this.remote._ledger_current_index;\n } else {\n this.message.ledger_hash = this.remote._ledger_hash;\n }\n return this;\n};\n\n// Set the ledger for a request.\n// - ledger_entry\n// - transaction_entry\nRequest.prototype.ledger_hash = function (hash) {\n this.message.ledger_hash = hash;\n return this;\n};\n\n// Set the ledger_index for a request.\n// - ledger_entry\nRequest.prototype.ledger_index = function (ledger_index) {\n this.message.ledger_index = ledger_index;\n return this;\n};\n\nRequest.prototype.ledger_select = function (ledger_spec) {\n switch (ledger_spec) {\n case 'current':\n case 'closed':\n case 'verified':\n this.message.ledger_index = ledger_spec;\n break;\n\n default:\n // XXX Better test needed\n if (Number(ledger_spec)) {\n this.message.ledger_index = ledger_spec;\n } else {\n this.message.ledger_hash = ledger_spec;\n }\n break;\n }\n\n return this;\n};\n\nRequest.prototype.account_root = function (account) {\n this.message.account_root = UInt160.json_rewrite(account);\n return this;\n};\n\nRequest.prototype.index = function (hash) {\n this.message.index = hash;\n return this;\n};\n\n// Provide the information id an offer.\n// --> account\n// --> seq : sequence number of transaction creating offer (integer)\nRequest.prototype.offer_id = function (account, seq) {\n this.message.offer = {\n account: UInt160.json_rewrite(account),\n seq: seq\n };\n return this;\n};\n\n// --> index : ledger entry index.\nRequest.prototype.offer_index = function (index) {\n this.message.offer = index;\n return this;\n};\n\nRequest.prototype.secret = function (secret) {\n if (secret) {\n this.message.secret = secret;\n }\n return this;\n};\n\nRequest.prototype.tx_hash = function (hash) {\n this.message.tx_hash = hash;\n return this;\n};\n\nRequest.prototype.tx_json = function (json) {\n this.message.tx_json = json;\n return this;\n};\n\nRequest.prototype.tx_blob = function (json) {\n this.message.tx_blob = json;\n return this;\n};\n\nRequest.prototype.ripple_state = function (account, issuer, currency) {\n this.message.ripple_state = {\n currency : currency,\n accounts : [\n UInt160.json_rewrite(account),\n UInt160.json_rewrite(issuer)\n ]\n };\n return this;\n};\n\nRequest.prototype.accounts = function (accounts, realtime) {\n if (!Array.isArray(accounts)) {\n accounts = [ accounts ];\n }\n\n // Process accounts parameters\n var processedAccounts = accounts.map(function(account) {\n return UInt160.json_rewrite(account);\n });\n \n if (realtime) {\n this.message.rt_accounts = processedAccounts;\n } else {\n this.message.accounts = processedAccounts;\n }\n\n return this;\n};\n\nRequest.prototype.rt_accounts = function (accounts) {\n return this.accounts(accounts, true);\n};\n\nRequest.prototype.books = function (books, snapshot) {\n var processedBooks = [ ];\n\n for (var i = 0, l = books.length; i < l; i++) {\n var book = books[i];\n var json = { };\n\n function processSide(side) {\n if (!book[side]) {\n throw new Error('Missing ' + side);\n }\n\n var obj = json[side] = {\n currency: Currency.json_rewrite(book[side].currency)\n };\n \n if (obj.currency !== 'XRP') {\n obj.issuer = UInt160.json_rewrite(book[side].issuer);\n }\n }\n\n processSide('taker_gets');\n processSide('taker_pays');\n\n if (snapshot) {\n json.snapshot = true;\n }\n\n if (book.both) {\n json.both = true; \n }\n\n processedBooks.push(json);\n }\n\n this.message.books = processedBooks;\n\n return this;\n};\n\nexports.Request = Request;\n\n\n// WEBPACK FOOTER\n// module.id = 14\n// module.readableIdentifier = ./src/js/ripple/request.js\n//@ sourceURL=webpack-module:///./src/js/ripple/request.js"); + eval("var EventEmitter = require(27).EventEmitter;\nvar util = require(28);\nvar UInt160 = require(15).UInt160;\nvar Currency = require(3).Currency;\nvar Transaction = require(5).Transaction;\nvar Account = require(16).Account;\nvar Meta = require(6).Meta;\nvar OrderBook = require(17).OrderBook;\nvar RippleError = require(19).RippleError;\n\n// Request events emitted:\n// 'success' : Request successful.\n// 'error' : Request failed.\n// 'remoteError'\n// 'remoteUnexpected'\n// 'remoteDisconnected'\nfunction Request(remote, command) {\n EventEmitter.call(this);\n\n this.remote = remote;\n this.requested = false;\n this.message = {\n command : command,\n id : void(0)\n };\n};\n\nutil.inherits(Request, EventEmitter);\n\n// Send the request to a remote.\nRequest.prototype.request = function (remote) {\n if (!this.requested) {\n this.requested = true;\n this.remote.request(this);\n this.emit('request', remote);\n }\n};\n\nRequest.prototype.callback = function(callback, successEvent, errorEvent) {\n if (callback && typeof callback === 'function') {\n var self = this;\n\n function request_success(message) {\n callback.call(self, null, message);\n }\n\n function request_error(error) {\n if (!(error instanceof RippleError)) {\n error = new RippleError(error);\n }\n callback.call(self, error);\n }\n\n this.once(successEvent || 'success', request_success);\n this.once(errorEvent || 'error' , request_error);\n this.request();\n }\n\n return this;\n};\n\nRequest.prototype.timeout = function(duration, callback) {\n var self = this;\n\n if (!this.requested) {\n function requested() {\n self.timeout(duration, callback);\n }\n this.once('request', requested);\n return;\n }\n\n var emit = this.emit;\n var timed_out = false;\n\n var timeout = setTimeout(function() {\n timed_out = true;\n if (typeof callback === 'function') callback();\n emit.call(self, 'timeout');\n }, duration);\n\n this.emit = function() {\n if (!timed_out) {\n clearTimeout(timeout);\n emit.apply(self, arguments);\n }\n };\n\n return this;\n};\n\nRequest.prototype.set_server = function(server) {\n var selected = null;\n\n switch (typeof server) {\n case 'object':\n selected = server;\n break;\n case 'string':\n for (var i=0, s; s=this.remote._servers[i]; i++) {\n if (s._host === server) {\n selected = s;\n break;\n }\n }\n break;\n };\n\n this.server = selected;\n};\n\nRequest.prototype.build_path = function (build) {\n if (build) {\n this.message.build_path = true;\n }\n return this;\n};\n\nRequest.prototype.ledger_choose = function (current) {\n if (current) {\n this.message.ledger_index = this.remote._ledger_current_index;\n } else {\n this.message.ledger_hash = this.remote._ledger_hash;\n }\n return this;\n};\n\n// Set the ledger for a request.\n// - ledger_entry\n// - transaction_entry\nRequest.prototype.ledger_hash = function (hash) {\n this.message.ledger_hash = hash;\n return this;\n};\n\n// Set the ledger_index for a request.\n// - ledger_entry\nRequest.prototype.ledger_index = function (ledger_index) {\n this.message.ledger_index = ledger_index;\n return this;\n};\n\nRequest.prototype.ledger_select = function (ledger_spec) {\n switch (ledger_spec) {\n case 'current':\n case 'closed':\n case 'verified':\n this.message.ledger_index = ledger_spec;\n break;\n\n default:\n // XXX Better test needed\n if (Number(ledger_spec)) {\n this.message.ledger_index = ledger_spec;\n } else {\n this.message.ledger_hash = ledger_spec;\n }\n break;\n }\n\n return this;\n};\n\nRequest.prototype.account_root = function (account) {\n this.message.account_root = UInt160.json_rewrite(account);\n return this;\n};\n\nRequest.prototype.index = function (hash) {\n this.message.index = hash;\n return this;\n};\n\n// Provide the information id an offer.\n// --> account\n// --> seq : sequence number of transaction creating offer (integer)\nRequest.prototype.offer_id = function (account, seq) {\n this.message.offer = {\n account: UInt160.json_rewrite(account),\n seq: seq\n };\n return this;\n};\n\n// --> index : ledger entry index.\nRequest.prototype.offer_index = function (index) {\n this.message.offer = index;\n return this;\n};\n\nRequest.prototype.secret = function (secret) {\n if (secret) {\n this.message.secret = secret;\n }\n return this;\n};\n\nRequest.prototype.tx_hash = function (hash) {\n this.message.tx_hash = hash;\n return this;\n};\n\nRequest.prototype.tx_json = function (json) {\n this.message.tx_json = json;\n return this;\n};\n\nRequest.prototype.tx_blob = function (json) {\n this.message.tx_blob = json;\n return this;\n};\n\nRequest.prototype.ripple_state = function (account, issuer, currency) {\n this.message.ripple_state = {\n currency : currency,\n accounts : [\n UInt160.json_rewrite(account),\n UInt160.json_rewrite(issuer)\n ]\n };\n return this;\n};\n\nRequest.prototype.accounts = function (accounts, realtime) {\n if (!Array.isArray(accounts)) {\n accounts = [ accounts ];\n }\n\n // Process accounts parameters\n var processedAccounts = accounts.map(function(account) {\n return UInt160.json_rewrite(account);\n });\n\n if (realtime) {\n this.message.rt_accounts = processedAccounts;\n } else {\n this.message.accounts = processedAccounts;\n }\n\n return this;\n};\n\nRequest.prototype.rt_accounts = function (accounts) {\n return this.accounts(accounts, true);\n};\n\nRequest.prototype.books = function (books, snapshot) {\n var processedBooks = [ ];\n\n for (var i = 0, l = books.length; i < l; i++) {\n var book = books[i];\n var json = { };\n\n function processSide(side) {\n if (!book[side]) {\n throw new Error('Missing ' + side);\n }\n\n var obj = json[side] = {\n currency: Currency.json_rewrite(book[side].currency)\n };\n if (obj.currency !== 'XRP') {\n obj.issuer = UInt160.json_rewrite(book[side].issuer);\n }\n }\n\n processSide('taker_gets');\n processSide('taker_pays');\n\n if (snapshot) {\n json.snapshot = true;\n }\n\n if (book.both) {\n json.both = true;\n }\n\n processedBooks.push(json);\n }\n\n this.message.books = processedBooks;\n\n return this;\n};\n\nexports.Request = Request;\n\n\n// WEBPACK FOOTER\n// module.id = 14\n// module.readableIdentifier = ./src/js/ripple/request.js\n//@ sourceURL=webpack-module:///./src/js/ripple/request.js"); /***/ }, /***/ 15: /***/ function(module, exports, require) { - eval("var sjcl = require(11);\nvar utils = require(9);\nvar config = require(12);\nvar jsbn = require(20);\nvar extend = require(29);\n\nvar BigInteger = jsbn.BigInteger;\nvar nbi = jsbn.nbi;\n\nvar UInt = require(30).UInt;\nvar Base = require(4).Base;\n\n//\n// UInt160 support\n//\n\nvar UInt160 = extend(function () {\n // Internal form: NaN or BigInteger\n this._value = NaN;\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\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 this._value = new BigInteger(String(j));\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 } else {\n this._value = NaN;\n }\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 var opts = opts || {};\n var output = NaN;\n\n if (this._value instanceof BigInteger) {\n output = Base.encode_check(Base.VER_ACCOUNT_ID, this.to_bytes());\n if (opts.gateways && output in opts.gateways) {\n output = opts.gateways[output];\n }\n }\n \n return output;\n};\n\nexports.UInt160 = UInt160;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 15\n// module.readableIdentifier = ./src/js/ripple/uint160.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint160.js"); + eval("var sjcl = require(11);\nvar utils = require(9);\nvar config = require(12);\nvar jsbn = require(20);\nvar extend = require(29);\n\nvar BigInteger = jsbn.BigInteger;\nvar nbi = jsbn.nbi;\n\nvar UInt = require(31).UInt;\nvar Base = require(4).Base;\n\n//\n// UInt160 support\n//\n\nvar UInt160 = extend(function () {\n // Internal form: NaN or BigInteger\n this._value = NaN;\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\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 this._value = new BigInteger(String(j));\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 } else {\n this._value = NaN;\n }\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 var opts = opts || {};\n var output = NaN;\n\n if (this._value instanceof BigInteger) {\n output = Base.encode_check(Base.VER_ACCOUNT_ID, this.to_bytes());\n if (opts.gateways && output in opts.gateways) {\n output = opts.gateways[output];\n }\n }\n \n return output;\n};\n\nexports.UInt160 = UInt160;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 15\n// module.readableIdentifier = ./src/js/ripple/uint160.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint160.js"); /***/ }, /***/ 16: /***/ function(module, exports, require) { - eval("// Routines for working with an account.\n//\n// You should not instantiate this class yourself, instead use Remote#account.\n//\n// Events:\n// wallet_clean\t: True, iff the wallet has been updated.\n// wallet_dirty\t: True, iff the wallet needs to be updated.\n// balance\t\t: The current stamp balance.\n// balance_proposed\n//\n\n// var network = require(\"./network.js\");\n\nvar EventEmitter = require(27).EventEmitter;\nvar util = require(28);\nvar extend = require(29);\n\nvar Amount = require(2).Amount;\nvar UInt160 = require(15).UInt160;\nvar TransactionManager = require(31).TransactionManager;\n\n\nfunction Account(remote, account) {\n EventEmitter.call(this);\n\n var self = this;\n\n this._tx_manager = null;\n this._remote = remote;\n this._account = UInt160.from_json(account);\n this._account_id = this._account.to_json();\n this._subs = 0;\n\n // Ledger entry object\n // Important: This must never be overwritten, only extend()-ed\n this._entry = { };\n\n function listener_added(type, listener) {\n if (~Account.subscribe_events.indexOf(type)) {\n if (!self._subs && self._remote._connected) {\n self._remote.request_subscribe()\n .accounts(self._account_id)\n .request();\n }\n self._subs += 1;\n }\n }\n\n function listener_removed(type, listener) {\n if (~Account.subscribe_events.indexOf(type)) {\n self._subs -= 1;\n if (!self._subs && self._remote._connected) {\n self._remote.request_unsubscribe()\n .accounts(self._account_id)\n .request();\n }\n }\n }\n\n this.on('newListener', listener_added);\n this.on('removeListener', listener_removed);\n\n function prepare_subscribe(request) {\n if (self._account.is_valid() && self._subs) {\n request.accounts(self._account_id);\n }\n }\n\n this._remote.on('prepare_subscribe', prepare_subscribe);\n\n function handle_transaction(transaction) {\n var changed = false;\n\n transaction.mmeta.each(function(an) {\n var isAccountRoot = an.entryType === 'AccountRoot' \n && an.fields.Account === self._account_id;\n if (isAccountRoot) {\n extend(self._entry, an.fieldsNew, an.fieldsFinal);\n changed = true;\n }\n });\n\n if (changed) {\n self.emit('entry', self._entry);\n }\n }\n\n this.on('transaction', handle_transaction);\n\n return this;\n};\n\nutil.inherits(Account, EventEmitter);\n\n/**\n * List of events that require a remote subscription to the account.\n */\nAccount.subscribe_events = [ 'transaction', 'entry' ];\n\nAccount.prototype.to_json = function () {\n return this._account.to_json();\n};\n\n/**\n * Whether the AccountId is valid.\n *\n * Note: This does not tell you whether the account exists in the ledger.\n */\nAccount.prototype.is_valid = function () {\n return this._account.is_valid();\n};\n\nAccount.prototype.get_info = function(callback) {\n var callback = typeof callback === 'function' ? callback : function(){};\n this._remote.request_account_info(this._account_id, callback);\n};\n\n/**\n * Retrieve the current AccountRoot entry.\n *\n * To keep up-to-date with changes to the AccountRoot entry, subscribe to the\n * \"entry\" event.\n *\n * @param {function (err, entry)} callback Called with the result\n */\nAccount.prototype.entry = function (callback) {\n var self = this;\n var callback = typeof callback === 'function' ? callback : function(){};\n\n this.get_info(function account_info(err, info) {\n if (err) {\n callback(err);\n } else {\n extend(self._entry, info.account_data);\n self.emit('entry', self._entry);\n callback(null, info);\n }\n });\n\n return this;\n};\n\nAccount.prototype.get_next_sequence = function(callback) {\n var callback = typeof callback === 'function' ? callback : function(){};\n\n this.get_info(function account_info(err, info) {\n if (err) {\n callback(err);\n } else {\n callback(null, info.account_data.Sequence); \n }\n });\n\n return this;\n};\n\n/**\n * Retrieve this account's Ripple trust lines.\n *\n * To keep up-to-date with changes to the AccountRoot entry, subscribe to the\n * \"lines\" event. (Not yet implemented.)\n *\n * @param {function (err, lines)} callback Called with the result\n */\nAccount.prototype.lines = function (callback)\n{\n var self = this;\n\n self._remote.request_account_lines(this._account_id)\n .on('success', function (e) {\n self._lines = e.lines;\n self.emit('lines', self._lines);\n\n if (\"function\" === typeof callback) {\n callback(null, e);\n }\n })\n .on('error', function (e) {\n callback(e);\n })\n .request();\n\n return this;\n};\n\n/**\n * Notify object of a relevant transaction.\n *\n * This is only meant to be called by the Remote class. You should never have to\n * call this yourself.\n */\nAccount.prototype.notifyTx = function (message) {\n // Only trigger the event if the account object is actually\n // subscribed - this prevents some weird phantom events from\n // occurring.\n if (this._subs) {\n this.emit('transaction', message);\n }\n};\n\nAccount.prototype.submit = function(tx) {\n if (!this._tx_manager) {\n this._tx_manager = new TransactionManager(this);\n }\n this._tx_manager.submit(tx);\n};\n\nexports.Account = Account;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 16\n// module.readableIdentifier = ./src/js/ripple/account.js\n//@ sourceURL=webpack-module:///./src/js/ripple/account.js"); + eval("// Routines for working with an account.\n//\n// You should not instantiate this class yourself, instead use Remote#account.\n//\n// Events:\n// wallet_clean\t: True, iff the wallet has been updated.\n// wallet_dirty\t: True, iff the wallet needs to be updated.\n// balance\t\t: The current stamp balance.\n// balance_proposed\n//\n\n// var network = require(\"./network.js\");\n\nvar EventEmitter = require(27).EventEmitter;\nvar util = require(28);\nvar extend = require(29);\n\nvar Amount = require(2).Amount;\nvar UInt160 = require(15).UInt160;\nvar TransactionManager = require(30).TransactionManager;\n\n\nfunction Account(remote, account) {\n EventEmitter.call(this);\n\n var self = this;\n\n this._remote = remote;\n this._account = UInt160.from_json(account);\n this._account_id = this._account.to_json();\n this._subs = 0;\n\n // Ledger entry object\n // Important: This must never be overwritten, only extend()-ed\n this._entry = { };\n\n function listener_added(type, listener) {\n if (~Account.subscribe_events.indexOf(type)) {\n if (!self._subs && self._remote._connected) {\n self._remote.request_subscribe()\n .accounts(self._account_id)\n .request();\n }\n self._subs += 1;\n }\n }\n\n function listener_removed(type, listener) {\n if (~Account.subscribe_events.indexOf(type)) {\n self._subs -= 1;\n if (!self._subs && self._remote._connected) {\n self._remote.request_unsubscribe()\n .accounts(self._account_id)\n .request();\n }\n }\n }\n\n this.on('newListener', listener_added);\n this.on('removeListener', listener_removed);\n\n function prepare_subscribe(request) {\n if (self._account.is_valid() && self._subs) {\n request.accounts(self._account_id);\n }\n }\n\n this._remote.on('prepare_subscribe', prepare_subscribe);\n\n function handle_transaction(transaction) {\n var changed = false;\n\n transaction.mmeta.each(function(an) {\n var isAccountRoot = an.entryType === 'AccountRoot' \n && an.fields.Account === self._account_id;\n if (isAccountRoot) {\n extend(self._entry, an.fieldsNew, an.fieldsFinal);\n changed = true;\n }\n });\n\n if (changed) {\n self.emit('entry', self._entry);\n }\n }\n\n this.on('transaction', handle_transaction);\n\n return this;\n};\n\nutil.inherits(Account, EventEmitter);\n\n/**\n * List of events that require a remote subscription to the account.\n */\nAccount.subscribe_events = [ 'transaction', 'entry' ];\n\nAccount.prototype.to_json = function () {\n return this._account.to_json();\n};\n\n/**\n * Whether the AccountId is valid.\n *\n * Note: This does not tell you whether the account exists in the ledger.\n */\nAccount.prototype.is_valid = function () {\n return this._account.is_valid();\n};\n\nAccount.prototype.get_info = function(callback) {\n var callback = typeof callback === 'function' ? callback : function(){};\n var request = this._remote.request_account_info(this._account_id, callback);\n return request;\n};\n\n/**\n * Retrieve the current AccountRoot entry.\n *\n * To keep up-to-date with changes to the AccountRoot entry, subscribe to the\n * \"entry\" event.\n *\n * @param {function (err, entry)} callback Called with the result\n */\nAccount.prototype.entry = function (callback) {\n var self = this;\n var callback = typeof callback === 'function' ? callback : function(){};\n\n this.get_info(function account_info(err, info) {\n if (err) {\n callback(err);\n } else {\n extend(self._entry, info.account_data);\n self.emit('entry', self._entry);\n callback(null, info);\n }\n });\n\n return this;\n};\n\nAccount.prototype.get_next_sequence = function(callback) {\n var callback = typeof callback === 'function' ? callback : function(){};\n\n this.get_info(function account_info(err, info) {\n if (err) {\n callback(err);\n } else {\n callback(null, info.account_data.Sequence); \n }\n });\n\n return this;\n};\n\n/**\n * Retrieve this account's Ripple trust lines.\n *\n * To keep up-to-date with changes to the AccountRoot entry, subscribe to the\n * \"lines\" event. (Not yet implemented.)\n *\n * @param {function (err, lines)} callback Called with the result\n */\nAccount.prototype.lines = function (callback) {\n var self = this;\n var callback = typeof callback === 'function' ? callback : function(){};\n\n function account_lines(err, res) {\n if (err) {\n callback(err);\n } else {\n self._lines = res.lines;\n self.emit('lines', self._lines);\n callback(null, res);\n }\n }\n\n this._remote.request_account_lines(this._account_id, account_lines);\n\n return this;\n};\n\n/**\n * Notify object of a relevant transaction.\n *\n * This is only meant to be called by the Remote class. You should never have to\n * call this yourself.\n */\nAccount.prototype.notifyTx = function (message) {\n // Only trigger the event if the account object is actually\n // subscribed - this prevents some weird phantom events from\n // occurring.\n if (this._subs) {\n this.emit('transaction', message);\n var account = message.transaction.Account;\n if (!account) return;\n if (account === this._account_id) {\n this.emit('transaction-outbound', message);\n } else {\n this.emit('transaction-inbound', message);\n }\n }\n};\n\nAccount.prototype.submit = function(tx) {\n if (!this._tx_manager) {\n this._tx_manager = new TransactionManager(this);\n }\n this._tx_manager.submit(tx);\n};\n\nexports.Account = Account;\n\n// vim:sw=2:sts=2:ts=8:et\n\n\n// WEBPACK FOOTER\n// module.id = 16\n// module.readableIdentifier = ./src/js/ripple/account.js\n//@ sourceURL=webpack-module:///./src/js/ripple/account.js"); /***/ }, @@ -175,14 +175,14 @@ var ripple = /***/ 18: /***/ function(module, exports, require) { - eval("var EventEmitter = require(27).EventEmitter;\nvar util = require(28);\n\nvar Amount = require(2).Amount;\n\nvar extend = require(29);\n\n/**\n * Represents a persistent path finding request.\n *\n * Only one path find request is allowed per connection, so when another path\n * find request is triggered it will supercede the existing one, making it emit\n * the 'end' and 'superceded' events.\n */\nvar PathFind = function (remote, src_account, dst_account,\n dst_amount, src_currencies)\n{\n EventEmitter.call(this);\n\n this.remote = remote;\n\n this.src_account = src_account;\n this.dst_account = dst_account;\n this.dst_amount = dst_amount;\n this.src_currencies = src_currencies;\n};\n\nutil.inherits(PathFind, EventEmitter);\n\n/**\n * Submits a path_find_create request to the network.\n *\n * This starts a path find request, superceding all previous path finds.\n *\n * This will be called automatically by Remote when this object is instantiated,\n * so you should only have to call it if the path find was closed or superceded\n * and you wish to restart it.\n */\nPathFind.prototype.create = function ()\n{\n var self = this;\n\n var req = this.remote.request_path_find_create(this.src_account,\n this.dst_account,\n this.dst_amount,\n this.src_currencies,\n handleInitialPath);\n\n function handleInitialPath(err, msg) {\n if (err) {\n self.emit('error', err);\n return;\n }\n self.notify_update(msg);\n }\n\n req.request();\n};\n\nPathFind.prototype.close = function ()\n{\n this.remote.request_path_find_close().request();\n this.emit('end');\n this.emit('close');\n};\n\nPathFind.prototype.notify_update = function (message)\n{\n var src_account = message.source_account;\n var dst_account = message.destination_account;\n var dst_amount = Amount.from_json(message.destination_amount);\n\n // Only pass the event along if this path find response matches what we were\n // looking for.\n if (this.src_account === src_account &&\n this.dst_account === dst_account &&\n this.dst_amount.equals(dst_amount)) {\n this.emit('update', message);\n }\n};\n\nPathFind.prototype.notify_superceded = function ()\n{\n this.emit('end');\n this.emit('superceded');\n};\n\nexports.PathFind = PathFind;\n\n\n// WEBPACK FOOTER\n// module.id = 18\n// module.readableIdentifier = ./src/js/ripple/pathfind.js\n//@ sourceURL=webpack-module:///./src/js/ripple/pathfind.js"); + eval("var EventEmitter = require(27).EventEmitter;\nvar util = require(28);\n\nvar Amount = require(2).Amount;\n\nvar extend = require(29);\n\n/**\n * Represents a persistent path finding request.\n *\n * Only one path find request is allowed per connection, so when another path\n * find request is triggered it will supercede the existing one, making it emit\n * the 'end' and 'superceded' events.\n */\nvar PathFind = function (remote, src_account, dst_account,\n dst_amount, src_currencies)\n{\n EventEmitter.call(this);\n\n this.remote = remote;\n\n this.src_account = src_account;\n this.dst_account = dst_account;\n this.dst_amount = dst_amount;\n this.src_currencies = src_currencies;\n};\n\nutil.inherits(PathFind, EventEmitter);\n\n/**\n * Submits a path_find_create request to the network.\n *\n * This starts a path find request, superceding all previous path finds.\n *\n * This will be called automatically by Remote when this object is instantiated,\n * so you should only have to call it if the path find was closed or superceded\n * and you wish to restart it.\n */\nPathFind.prototype.create = function ()\n{\n var self = this;\n\n var req = this.remote.request_path_find_create(this.src_account,\n this.dst_account,\n this.dst_amount,\n this.src_currencies,\n handleInitialPath);\n\n function handleInitialPath(err, msg) {\n if (err) {\n self.emit('error', err);\n return;\n }\n self.notify_update(msg);\n }\n\n // XXX We should add ourselves to prepare_subscribe or a similar mechanism so\n // that we can resubscribe after a reconnection.\n\n req.request();\n};\n\nPathFind.prototype.close = function ()\n{\n this.remote.request_path_find_close().request();\n this.emit('end');\n this.emit('close');\n};\n\nPathFind.prototype.notify_update = function (message)\n{\n var src_account = message.source_account;\n var dst_account = message.destination_account;\n var dst_amount = Amount.from_json(message.destination_amount);\n\n // Only pass the event along if this path find response matches what we were\n // looking for.\n if (this.src_account === src_account &&\n this.dst_account === dst_account &&\n this.dst_amount.equals(dst_amount)) {\n this.emit('update', message);\n }\n};\n\nPathFind.prototype.notify_superceded = function ()\n{\n // XXX If we're set to re-subscribe whenever we connect to a new server, then\n // we should cancel that behavior here. See PathFind#create.\n\n this.emit('end');\n this.emit('superceded');\n};\n\nexports.PathFind = PathFind;\n\n\n// WEBPACK FOOTER\n// module.id = 18\n// module.readableIdentifier = ./src/js/ripple/pathfind.js\n//@ sourceURL=webpack-module:///./src/js/ripple/pathfind.js"); /***/ }, /***/ 19: /***/ function(module, exports, require) { - eval("var util = require(28);\nvar extend = require(29);\n\nfunction RippleError(code, message) {\n if (typeof code === 'object') {\n extend(this, code);\n } else {\n this.result = code;\n this.message = message;\n this.result_message = message;\n }\n\n this.message = this.result_message || 'Error';\n\n Error.captureStackTrace(this, code || this);\n}\n\nutil.inherits(RippleError, Error);\n\nRippleError.prototype.name = 'RippleError';\n\nexports.RippleError = RippleError;\n\n\n// WEBPACK FOOTER\n// module.id = 19\n// module.readableIdentifier = ./src/js/ripple/rippleerror.js\n//@ sourceURL=webpack-module:///./src/js/ripple/rippleerror.js"); + eval("var util = require(28);\nvar extend = require(29);\n\nfunction RippleError(code, message) {\n switch (typeof code) {\n case 'object':\n extend(this, code);\n break;\n case 'string':\n this.result = code;\n this.result_message = message;\n break;\n }\n\n this.result = this.result || this.error || 'Error';\n this.result_message = this.result_message || this.error_message || 'Error';\n this.message = this.result_message;\n\n Error.captureStackTrace(this, code || this);\n}\n\nutil.inherits(RippleError, Error);\n\nRippleError.prototype.name = 'RippleError';\n\nexports.RippleError = RippleError;\n\n\n// WEBPACK FOOTER\n// module.id = 19\n// module.readableIdentifier = ./src/js/ripple/rippleerror.js\n//@ sourceURL=webpack-module:///./src/js/ripple/rippleerror.js"); /***/ }, @@ -196,21 +196,21 @@ var ripple = /***/ 21: /***/ function(module, exports, require) { - eval("//\n// Seed support\n//\n\nvar sjcl = require(11);\nvar utils = require(9);\nvar jsbn = require(20);\nvar extend = require(29);\n\nvar BigInteger = jsbn.BigInteger;\n\nvar Base = require(4).Base,\n UInt = require(30).UInt,\n UInt256 = require(23).UInt256,\n KeyPair = require(32).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 ('string' === typeof j) {\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 (\"string\" !== typeof j) {\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 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\nSeed.prototype.get_key = function (account_id) {\n if (!this.is_valid()) {\n throw new Error(\"Cannot generate keys from invalid seed!\");\n }\n // XXX Should loop over keys until we find the right one\n\n var curve = this._curve;\n\n var seq = 0;\n\n var private_gen, public_gen, i = 0;\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 i = 0;\n do {\n sec = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(append_int(public_gen.toBytesCompressed(), seq), i)));\n i++;\n } while (!curve.r.greaterEquals(sec));\n\n sec = sec.add(private_gen).mod(curve.r);\n\n return KeyPair.from_bn_secret(sec);\n};\n\nexports.Seed = Seed;\n\n\n// WEBPACK FOOTER\n// module.id = 21\n// module.readableIdentifier = ./src/js/ripple/seed.js\n//@ sourceURL=webpack-module:///./src/js/ripple/seed.js"); + eval("//\n// Seed support\n//\n\nvar sjcl = require(11);\nvar utils = require(9);\nvar jsbn = require(20);\nvar extend = require(29);\n\nvar BigInteger = jsbn.BigInteger;\n\nvar Base = require(4).Base,\n UInt = require(31).UInt,\n UInt256 = require(23).UInt256,\n KeyPair = require(32).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 ('string' === typeof j) {\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 (\"string\" !== typeof j) {\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 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\nSeed.prototype.get_key = function (account_id) {\n if (!this.is_valid()) {\n throw new Error(\"Cannot generate keys from invalid seed!\");\n }\n // XXX Should loop over keys until we find the right one\n\n var curve = this._curve;\n\n var seq = 0;\n\n var private_gen, public_gen, i = 0;\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 i = 0;\n do {\n sec = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(append_int(public_gen.toBytesCompressed(), seq), i)));\n i++;\n } while (!curve.r.greaterEquals(sec));\n\n sec = sec.add(private_gen).mod(curve.r);\n\n return KeyPair.from_bn_secret(sec);\n};\n\nexports.Seed = Seed;\n\n\n// WEBPACK FOOTER\n// module.id = 21\n// module.readableIdentifier = ./src/js/ripple/seed.js\n//@ sourceURL=webpack-module:///./src/js/ripple/seed.js"); /***/ }, /***/ 22: /***/ function(module, exports, require) { - 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 extend = require(29),\n utils = require(9),\n sjcl = require(11);\n\nvar amount = require(2),\n UInt128 = require(33).UInt128,\n UInt160 = require(15).UInt160,\n UInt256 = require(23).UInt256,\n Amount = amount.Amount,\n Currency= amount.Currency;\n\n// Shortcuts\nvar hex = sjcl.codec.hex,\n bytes = sjcl.codec.bytes;\n\nvar jsbn = require(20);\nvar BigInteger = jsbn.BigInteger;\n\n\nvar SerializedType = function (methods) {\n extend(this, methods);\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\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 if (val <= 192) {\n so.append([val]);\n } else if (val <= 12,480) {\n val -= 193;\n so.append([193 + (val >>> 8), val & 0xff]);\n } else if (val <= 918744) {\n val -= 12481;\n so.append([\n 241 + (val >>> 16),\n val >>> 8 & 0xff,\n val & 0xff\n ]);\n } else 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 if (b1 <= 192) {\n return b1;\n } else if (b1 <= 240) {\n b2 = so.read(1)[0];\n return 193 + (b1-193)*256 + b2;\n } else if (b1 <= 254) {\n b2 = so.read(1)[0];\n b3 = so.read(1)[0];\n return 12481 + (b1-241)*65536 + b2*256 + b3\n }\n else {\n throw new Error(\"Invalid varint length indicator\");\n }\n};\n\n\n\n\n\n// In the following, we assume that the inputs are in the proper range. Is this correct?\n\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 (\"number\" !== typeof val) {\n throw new Error(\"Integer is not a number\");\n }\n if (val < 0 || val >= (Math.pow(256, bytes))) {\n throw new Error(\"Integer out of bounds\");\n }\n var newBytes = [];\n for (var i=0; i>> (i*8) & 0xff);\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 for (var i = 0; i 16) {\n throw new Error(\"Int64 is too large\");\n }\n while (hex.length < 16) {\n hex = \"0\" + hex;\n }\n return serialize_hex(so, hex, true); //noLength = true\n },\n parse: function (so) {\n var hi = readAndSum(so, 4);\n var lo = readAndSum(so, 4);\n\n var result = new BigInteger(\"\"+hi);\n result.shiftLeft(32);\n result.add(lo);\n return result;\n }\n});\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\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\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\n// Internal\nvar STCurrency = new SerializedType({\n serialize: function (so, val) {\n var currency = val.to_json();\n if (\"XRP\" === currency) {\n serialize_hex(so, UInt160.HEX_ZERO, true);\n } else if (\"string\" === typeof currency && currency.length === 3) {\n var currencyCode = currency.toUpperCase(),\n currencyData = utils.arraySet(20, 0);\n\n if (!/^[A-Z]{3}$/.test(currencyCode) || currencyCode === \"XRP\" ) {\n throw new Error('Invalid currency code');\n }\n\n currencyData[12] = currencyCode.charCodeAt(0) & 0xff;\n currencyData[13] = currencyCode.charCodeAt(1) & 0xff;\n currencyData[14] = currencyCode.charCodeAt(2) & 0xff;\n\n so.append(currencyData);\n } else {\n throw new Error('Tried to serialize invalid/unimplemented currency type.');\n }\n },\n parse: function (so) {\n var currency = Currency.from_bytes(so.read(20));\n if (!currency.is_valid()) {\n throw new Error(\"Invalid currency\");\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 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 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 if (!amount.is_negative()) valueBytes[0] |= 0x40;\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()) hi |= 1 << 30;\n\n // Next eight bits: offset/exponent\n hi |= ((97 + amount._offset) & 0xff) << 22;\n\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);\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 for (var i=1; i<8; i++) {\n is_zero = is_zero && !value_bytes[i];\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\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\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\nvar STVL = exports.VariableLength = new SerializedType({\n serialize: function (so, val) {\n if (\"string\" === typeof val) serialize_hex(so, val);\n else throw new Error(\"Unknown datatype.\");\n },\n parse: function (so) {\n var len = this.parse_varint(so);\n return convert_bytes_to_hex(so.read(len));\n }\n});\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\t//console.log(\"KKKKKKKKKKK\",len);\n if (len !== 20) {\n throw new Error(\"Non-standard-length account ID\");\n }\n var result = UInt160.from_bytes(so.read(len));\n if (false && !result.is_valid()) {\n throw new Error(\"Invalid Account\");\n }\n return result;\n }\n});\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 // XXX\n for (var i = 0, l = val.length; i < l; i++) {\n // Boundary\n if (i) STInt8.serialize(so, this.typeBoundary);\n\n for (var j = 0, l2 = val[i].length; j < l2; j++) {\n var entry = val[i][j];\n\t\t//if (entry.hasOwnProperty(\"_value\")) {entry = entry._value;}\n var type = 0;\n\n if (entry.account) type |= this.typeAccount;\n if (entry.currency) type |= this.typeCurrency;\n if (entry.issuer) type |= this.typeIssuer;\n\n STInt8.serialize(so, type);\n\n if (entry.account) {\n so.append(UInt160.from_json(entry.account).to_bytes());\n }\n if (entry.currency) {\n var currency = Currency.from_json(entry.currency);\n STCurrency.serialize(so, currency);\n }\n if (entry.issuer) {\n so.append(UInt160.from_json(entry.issuer).to_bytes());\n }\n }\n }\n STInt8.serialize(so, this.typeEnd);\n },\n parse: function (so) {\n // XXX\n\t// should return a list of lists:\n\t/*\n\t[\n\t\t[entry, entry],\n\t\t[entry, entry, entry]\n\t\t[entry]\n\t\t[]\n\t]\n\t\n\teach entry has one or more of the following attributes: amount, currency, issuer.\n\t*/\n\t\n\tvar path_list = [];\n\tvar current_path = [];\n\t\n\twhile (true) { //TODO: try/catch this loop, and catch when we run out of data without reaching the end of the data structure.\n\t\tvar tag_byte = so.read(1)[0];\n\t\t//Now determine: is this an end, boundary, or entry-begin-tag?\n\t\t//console.log(\"Tag byte:\", tag_byte);\n\t\tif (tag_byte == this.typeEnd) { //We're done.\n\t\t\t//console.log(\"End.\");\n\t\t\tif (current_path) { //close the current path, if there is one,\n\t\t\t\tpath_list.push(current_path);\n\t\t\t}\n\t\t\tbreak; //and conclude.\n\t\t} else if (tag_byte == this.typeBoundary) {\n\t\t\t//console.log(\"Boundary\");\n\t\t\tif (current_path) { //close the current path, if there is one,\n\t\t\t\tpath_list.push(current_path);\n\t\t\t}\n\t\t\tcurrent_path = []; //and start a new one.\n\t\t} else {\n\t\t\t//It's an entry-begin tag.\n\t\t\t//console.log(\"It's an entry-begin tag.\");\n\t\t\tvar entry = {};\n\t\t\tif (tag_byte & this.typeAccount) {\n\t\t\t\t//console.log(\"entry.account\");\n\t\t\t\t/*var bta = so.read(20);\n\t\t\t\tconsole.log(\"BTA:\", bta);*/\n\t\t\t\tentry.account = STHash160.parse(so);\n\t\t\t}\n\t\t\tif (tag_byte & this.typeCurrency) {\n\t\t\t\t//console.log(\"entry.currency\");\n\t\t\t\tentry.currency = STCurrency.parse(so)\n\t\t\t}\n\t\t\tif (tag_byte & this.typeIssuer) {\n\t\t\t\t//console.log(\"entry.issuer\");\n\t\t\t\tentry.issuer = STHash160.parse(so); //should know to use Base58?\n\t\t\t\t//console.log(\"DONE WITH ISSUER!\");\n\t\t\t}\n\t\t\tif (entry.account || entry.currency || entry.issuer) {\n\t\t\t\tcurrent_path.push(entry);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid path entry\"); //It must have at least something in it.\n\t\t\t}\n\t\t}\n\t}\n\treturn path_list;\n }\n});\n\nvar STVector256 = exports.Vector256 = new SerializedType({\n serialize: function (so, val) { //Assume val is an array of STHash256 objects.\n var length_as_varint = SerializedType.serialize_varint(so, val.length);\n\tfor (var i = 0; i= 16) {\n\t\tSTInt8.serialize(so, type_bits)\n\t}\n\tif (field_bits >= 16) {\n\t\tSTInt8.serialize(so, field_bits)\n\t}\n\tvar serialized_object_type = TYPES_MAP[type_bits];\n\t//do something with val[keys] and val[keys[i]];\n\tserialized_object_type.serialize(so, value);\n}\n\n\n//What should this helper function be attached to?\n//Take the serialized object, figure out what type/field it is, and return the parsing of that.\nvar parse_whatever = exports.parse_whatever = function(so) {\n\tvar tag_byte = so.read(1)[0];\n\tvar type_bits = tag_byte >> 4;\n\tvar field_bits = tag_byte & 0x0f;\n\tvar type;\n\tvar field_name;\n\tif (type_bits === 0) {\n\t\ttype_bits = so.read(1)[0];\n\t}\n\ttype = TYPES_MAP[type_bits];\n\tif (\"undefined\" === typeof type) {\n\t\tthrow Error(\"Unknown type\");\n\t} else {\n\t\tif (field_bits === 0) {\n\t\t\tfield_name = FIELDS_MAP[type_bits][so.read(1)[0]];\n\t\t} else {\n\t\t\tfield_name = FIELDS_MAP[type_bits][field_bits];\n\t\t}\n\t\tif (\"undefined\" === typeof field_name) {\n\t\t\tthrow Error(\"Unknown field \"+tag_byte);\n\t\t} else {\n\t\t\treturn [field_name, type.parse(so)]; //key, value\n\t\t}\n\t}\n}\n\n\n\nvar STObject = exports.Object = new SerializedType({\n serialize: function (so, val) {\n var keys = Object.keys(val);\n\tfor (var i=0; i= 16) {\n\t\t\tSTInt8.serialize(so, type_bits)\n\t\t}\n\t\tif (field_bits >= 16) {\n\t\t\tSTInt8.serialize(so, field_bits)\n\t\t}\n\t\tvar serialized_object_type = TYPES_MAP[type_bits];\n\t\t//do something with val[keys] and val[keys[i]];\n\t\tserialized_object_type.serialize(so, val[keys[i]]);\n\t\t*/\n\t}\n\tSTInt8.serialize(so, 0xe1); //Object ending marker\n },\n parse: function (so) {\n\t//console.log(\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\", so.buffer, so.pointer);\n var output = {};\n\twhile (true) {\n\t\tif (so.peek(1)[0] === 0xe1) { //ending marker\n\t\t\tso.read(1);\n\t\t\tbreak;\n\t\t} else {\n\t\t\t//console.log(\"WTF M8\");\n\t\t\tvar key_and_value = parse_whatever(so);\n\t\t\toutput[key_and_value[0]] = key_and_value[1];\n\t\t\t//console.log(\"BBBBBBBBBBBBB\", key_and_value, output);\n\t\t}\n\t}\n\treturn output;\n }\n});\n\nvar STArray = exports.Array = new SerializedType({\n serialize: function (so, val) { \n for (var i=0; i>> 8), val & 0xff]);\n } else if (val <= 918744) {\n val -= 12481;\n so.append([\n 241 + (val >>> 16),\n val >>> 8 & 0xff,\n val & 0xff\n ]);\n } else 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 if (b1 <= 192) {\n return b1;\n } else if (b1 <= 240) {\n b2 = so.read(1)[0];\n return 193 + (b1-193)*256 + b2;\n } else if (b1 <= 254) {\n b2 = so.read(1)[0];\n b3 = so.read(1)[0];\n return 12481 + (b1-241)*65536 + b2*256 + b3\n }\n else {\n throw new Error(\"Invalid varint length indicator\");\n }\n};\n\n\n\n\n\n// In the following, we assume that the inputs are in the proper range. Is this correct?\n\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 (\"number\" !== typeof val) {\n throw new Error(\"Integer is not a number\");\n }\n if (val < 0 || val >= (Math.pow(256, bytes))) {\n throw new Error(\"Integer out of bounds\");\n }\n var newBytes = [];\n for (var i=0; i>> (i*8) & 0xff);\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 for (var i = 0; i 16) {\n throw new Error(\"Int64 is too large\");\n }\n while (hex.length < 16) {\n hex = \"0\" + hex;\n }\n return serialize_hex(so, hex, true); //noLength = true\n },\n parse: function (so) {\n var hi = readAndSum(so, 4);\n var lo = readAndSum(so, 4);\n\n var result = new BigInteger(\"\"+hi);\n result.shiftLeft(32);\n result.add(lo);\n return result;\n }\n});\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\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\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\n// Internal\nvar STCurrency = new SerializedType({\n serialize: function (so, val) {\n var currency = val.to_json();\n if (\"XRP\" === currency) {\n serialize_hex(so, UInt160.HEX_ZERO, true);\n } else if (\"string\" === typeof currency && currency.length === 3) {\n var currencyCode = currency.toUpperCase(),\n currencyData = utils.arraySet(20, 0);\n\n if (!/^[A-Z]{3}$/.test(currencyCode) || currencyCode === \"XRP\" ) {\n throw new Error('Invalid currency code');\n }\n\n currencyData[12] = currencyCode.charCodeAt(0) & 0xff;\n currencyData[13] = currencyCode.charCodeAt(1) & 0xff;\n currencyData[14] = currencyCode.charCodeAt(2) & 0xff;\n\n so.append(currencyData);\n } else {\n throw new Error('Tried to serialize invalid/unimplemented currency type.');\n }\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 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 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 if (!amount.is_negative()) valueBytes[0] |= 0x40;\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()) hi |= 1 << 30;\n\n // Next eight bits: offset/exponent\n hi |= ((97 + amount._offset) & 0xff) << 22;\n\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);\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 for (var i=1; i<8; i++) {\n is_zero = is_zero && !value_bytes[i];\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\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\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\nvar STVL = exports.VariableLength = new SerializedType({\n serialize: function (so, val) {\n if (\"string\" === typeof val) serialize_hex(so, val);\n else throw new Error(\"Unknown datatype.\");\n },\n parse: function (so) {\n var len = this.parse_varint(so);\n return convert_bytes_to_hex(so.read(len));\n }\n});\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\t//console.log(\"KKKKKKKKKKK\",len);\n if (len !== 20) {\n throw new Error(\"Non-standard-length account ID\");\n }\n var result = UInt160.from_bytes(so.read(len));\n if (false && !result.is_valid()) {\n throw new Error(\"Invalid Account\");\n }\n return result;\n }\n});\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 // XXX\n for (var i = 0, l = val.length; i < l; i++) {\n // Boundary\n if (i) STInt8.serialize(so, this.typeBoundary);\n\n for (var j = 0, l2 = val[i].length; j < l2; j++) {\n var entry = val[i][j];\n\t\t//if (entry.hasOwnProperty(\"_value\")) {entry = entry._value;}\n var type = 0;\n\n if (entry.account) type |= this.typeAccount;\n if (entry.currency) type |= this.typeCurrency;\n if (entry.issuer) type |= this.typeIssuer;\n\n STInt8.serialize(so, type);\n\n if (entry.account) {\n so.append(UInt160.from_json(entry.account).to_bytes());\n }\n if (entry.currency) {\n var currency = Currency.from_json(entry.currency);\n STCurrency.serialize(so, currency);\n }\n if (entry.issuer) {\n so.append(UInt160.from_json(entry.issuer).to_bytes());\n }\n }\n }\n STInt8.serialize(so, this.typeEnd);\n },\n parse: function (so) {\n // XXX\n\t// should return a list of lists:\n\t/*\n\t[\n\t\t[entry, entry],\n\t\t[entry, entry, entry]\n\t\t[entry]\n\t\t[]\n\t]\n\t\n\teach entry has one or more of the following attributes: amount, currency, issuer.\n\t*/\n\t\n\tvar path_list = [];\n\tvar current_path = [];\n\t\n\twhile (true) { //TODO: try/catch this loop, and catch when we run out of data without reaching the end of the data structure.\n\t\tvar tag_byte = so.read(1)[0];\n\t\t//Now determine: is this an end, boundary, or entry-begin-tag?\n\t\t//console.log(\"Tag byte:\", tag_byte);\n\t\tif (tag_byte == this.typeEnd) { //We're done.\n\t\t\t//console.log(\"End.\");\n\t\t\tif (current_path) { //close the current path, if there is one,\n\t\t\t\tpath_list.push(current_path);\n\t\t\t}\n\t\t\tbreak; //and conclude.\n\t\t} else if (tag_byte == this.typeBoundary) {\n\t\t\t//console.log(\"Boundary\");\n\t\t\tif (current_path) { //close the current path, if there is one,\n\t\t\t\tpath_list.push(current_path);\n\t\t\t}\n\t\t\tcurrent_path = []; //and start a new one.\n\t\t} else {\n\t\t\t//It's an entry-begin tag.\n\t\t\t//console.log(\"It's an entry-begin tag.\");\n\t\t\tvar entry = {};\n\t\t\tif (tag_byte & this.typeAccount) {\n\t\t\t\t//console.log(\"entry.account\");\n\t\t\t\t/*var bta = so.read(20);\n\t\t\t\tconsole.log(\"BTA:\", bta);*/\n\t\t\t\tentry.account = STHash160.parse(so);\n\t\t\t}\n\t\t\tif (tag_byte & this.typeCurrency) {\n\t\t\t\t//console.log(\"entry.currency\");\n\t\t\t\tentry.currency = STCurrency.parse(so)\n\t\t\t}\n\t\t\tif (tag_byte & this.typeIssuer) {\n\t\t\t\t//console.log(\"entry.issuer\");\n\t\t\t\tentry.issuer = STHash160.parse(so); //should know to use Base58?\n\t\t\t\t//console.log(\"DONE WITH ISSUER!\");\n\t\t\t}\n\t\t\tif (entry.account || entry.currency || entry.issuer) {\n\t\t\t\tcurrent_path.push(entry);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid path entry\"); //It must have at least something in it.\n\t\t\t}\n\t\t}\n\t}\n\treturn path_list;\n }\n});\n\nvar STVector256 = exports.Vector256 = new SerializedType({\n serialize: function (so, val) { //Assume val is an array of STHash256 objects.\n var length_as_varint = SerializedType.serialize_varint(so, val.length);\n\tfor (var i = 0; i= 16) {\n\t\tSTInt8.serialize(so, type_bits)\n\t}\n\tif (field_bits >= 16) {\n\t\tSTInt8.serialize(so, field_bits)\n\t}\n\tvar serialized_object_type = TYPES_MAP[type_bits];\n\t//do something with val[keys] and val[keys[i]];\n\tserialized_object_type.serialize(so, value);\n}\n\n\n//What should this helper function be attached to?\n//Take the serialized object, figure out what type/field it is, and return the parsing of that.\nvar parse_whatever = exports.parse_whatever = function(so) {\n\tvar tag_byte = so.read(1)[0];\n\tvar type_bits = tag_byte >> 4;\n\tvar field_bits = tag_byte & 0x0f;\n\tvar type;\n\tvar field_name;\n\tif (type_bits === 0) {\n\t\ttype_bits = so.read(1)[0];\n\t}\n\ttype = TYPES_MAP[type_bits];\n\tif (\"undefined\" === typeof type) {\n\t\tthrow Error(\"Unknown type\");\n\t} else {\n\t\tif (field_bits === 0) {\n\t\t\tfield_name = FIELDS_MAP[type_bits][so.read(1)[0]];\n\t\t} else {\n\t\t\tfield_name = FIELDS_MAP[type_bits][field_bits];\n\t\t}\n\t\tif (\"undefined\" === typeof field_name) {\n\t\t\tthrow Error(\"Unknown field \"+tag_byte);\n\t\t} else {\n\t\t\treturn [field_name, type.parse(so)]; //key, value\n\t\t}\n\t}\n}\n\n\n\nvar STObject = exports.Object = new SerializedType({\n serialize: function (so, val) {\n var keys = Object.keys(val);\n\tfor (var i=0; i= 16) {\n\t\t\tSTInt8.serialize(so, type_bits)\n\t\t}\n\t\tif (field_bits >= 16) {\n\t\t\tSTInt8.serialize(so, field_bits)\n\t\t}\n\t\tvar serialized_object_type = TYPES_MAP[type_bits];\n\t\t//do something with val[keys] and val[keys[i]];\n\t\tserialized_object_type.serialize(so, val[keys[i]]);\n\t\t*/\n\t}\n\tSTInt8.serialize(so, 0xe1); //Object ending marker\n },\n parse: function (so) {\n\t//console.log(\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\", so.buffer, so.pointer);\n var output = {};\n\twhile (true) {\n\t\tif (so.peek(1)[0] === 0xe1) { //ending marker\n\t\t\tso.read(1);\n\t\t\tbreak;\n\t\t} else {\n\t\t\t//console.log(\"WTF M8\");\n\t\t\tvar key_and_value = parse_whatever(so);\n\t\t\toutput[key_and_value[0]] = key_and_value[1];\n\t\t\t//console.log(\"BBBBBBBBBBBBB\", key_and_value, output);\n\t\t}\n\t}\n\treturn output;\n }\n});\n\nvar STArray = exports.Array = new SerializedType({\n serialize: function (so, val) { \n for (var i=0; i 5) {\n tx.emit('error', new RippleError('tejAttemptsExceeded'));\n return;\n }\n\n var submit_request = remote.request_submit();\n\n if (remote.local_signing) {\n tx.sign();\n submit_request.tx_blob(tx.serialize().to_hex());\n } else {\n submit_request.secret(tx._secret);\n submit_request.build_path(tx._build_path);\n submit_request.tx_json(tx.tx_json);\n }\n\n function transaction_proposed(message) {\n tx.hash = message.tx_json.hash;\n tx.set_state('client_proposed');\n tx.emit('proposed', {\n tx_json: message.tx_json,\n engine_result: message.engine_result,\n engine_result_code: message.engine_result_code,\n engine_result_message: message.engine_result_message,\n // If server is honest, don't expect a final if rejected.\n rejected: tx.isRejected(message.engine_result_code),\n });\n }\n\n function transaction_failed(message) {\n function transaction_requested(err, res) {\n if (self._is_not_found(err)) {\n self._resubmit(1);\n } else {\n //XX\n tx.emit('error', new RippleError(message));\n }\n }\n\n self.remote.request_tx(tx.hash, transaction_requested);\n }\n\n function transaction_retry(message) {\n switch (message.engine_result) {\n case 'terPRE_SEQ':\n self._resubmit(1);\n break;\n default:\n submission_error(new RippleError(message));\n }\n }\n\n function submission_error(error) {\n if (self._is_too_busy(error)) {\n self._resubmit(1);\n } else {\n //Decrement sequence\n self._next_sequence--;\n tx.set_state('remoteError');\n tx.emit('submitted', error);\n tx.emit('error', new RippleError(error));\n }\n }\n\n function submission_success(message) {\n if (!tx.hash) {\n tx.hash = message.tx_json.hash;\n }\n\n message.result = message.engine_result || '';\n\n tx.emit('submitted', message);\n\n switch (message.result.slice(0, 3)) {\n case 'tec':\n tx.emit('error', message);\n break;\n case 'tes':\n transaction_proposed(message);\n break;\n case 'tef':\n //tefPAST_SEQ\n transaction_failed(message);\n break;\n case 'ter':\n transaction_retry(message);\n break;\n default:\n submission_error(message);\n }\n }\n\n submit_request.once('success', submission_success);\n submit_request.once('error', submission_error);\n submit_request.request();\n\n submit_request.timeout(this._submission_timeout, function() {\n tx.emit('timeout');\n if (self.remote._connected) {\n self._resubmit(1);\n }\n });\n\n tx.set_state('client_submitted');\n tx.attempts++;\n\n return submit_request;\n};\n\nTransactionManager.prototype._is_remote_error = function(error) {\n return error && typeof error === 'object'\n && error.error === 'remoteError'\n && typeof error.remote === 'object'\n};\n\nTransactionManager.prototype._is_not_found = function(error) {\n return this._is_remote_error(error) && /^(txnNotFound|transactionNotFound)$/.test(error.remote.error);\n};\n\nTransactionManager.prototype._is_too_busy = function(error) {\n return this._is_remote_error(error) && error.remote.error === 'tooBusy';\n};\n\n/**\n * Entry point for TransactionManager submission\n *\n * @param {Object} tx\n */\n\nTransactionManager.prototype.submit = function(tx) {\n var self = this;\n\n // If sequence number is not yet known, defer until it is.\n if (!this._next_sequence) {\n function resubmit_transaction() {\n self.submit(tx);\n }\n this.once('sequence_loaded', resubmit_transaction);\n return;\n }\n\n tx.tx_json.Sequence = this._next_sequence++;\n tx.submit_index = this.remote._ledger_current_index;\n tx.last_ledger = void(0);\n tx.attempts = 0;\n tx.complete();\n\n function finalize(message) {\n if (!tx.finalized) {\n //XX\n self._pending.removeSequence(tx.tx_json.Sequence);\n tx.finalized = true;\n tx.emit('final', message);\n }\n }\n\n tx.on('error', finalize);\n tx.once('success', finalize);\n tx.once('abort', function() {\n tx.emit('error', new RippleError('tejAbort', 'Transaction aborted'));\n });\n\n var fee = Number(tx.tx_json.Fee);\n var remote = this.remote;\n\n if (!tx._secret && !tx.tx_json.TxnSignature) {\n tx.emit('error', new RippleError('tejSecretUnknown', 'Missing secret'));\n } else if (!remote.trusted && !remote.local_signing) {\n tx.emit('error', new RippleError('tejServerUntrusted', 'Attempt to give secret to untrusted server'));\n } else if (fee && fee > this._max_fee) {\n tx.emit('error', new RippleError('tejMaxFeeExceeded', 'Max fee exceeded'));\n } else {\n this._pending.push(tx);\n this._request(tx);\n }\n};\n\nexports.TransactionManager = TransactionManager;\n\n\n// WEBPACK FOOTER\n// module.id = 30\n// module.readableIdentifier = ./src/js/ripple/transactionmanager.js\n//@ sourceURL=webpack-module:///./src/js/ripple/transactionmanager.js"); /***/ }, /***/ 31: /***/ function(module, exports, require) { - eval("var util = require(28);\nvar EventEmitter = require(27).EventEmitter;\nvar RippleError = require(19).RippleError;\nvar Queue = require(42).TransactionQueue;\n\n/**\n * @constructor TransactionManager\n * @param {Object} account\n */\n\nfunction TransactionManager(account) {\n EventEmitter.call(this);\n\n var self = this;\n\n this.account = account;\n this.remote = account._remote;\n this._timeout = void(0);\n this._resubmitting = false;\n this._pending = new Queue;\n this._next_sequence = void(0);\n this._cache = { };\n\n //XX Fee units\n this._max_fee = Number(this.remote.max_fee) || Infinity;\n\n function remote_disconnected() {\n function remote_reconnected() {\n self._resubmit();\n };\n self.remote.once('connect', remote_reconnected);\n };\n\n this.remote.on('disconnect', remote_disconnected);\n\n function sequence_loaded(err, sequence) {\n self._next_sequence = sequence;\n self.emit('sequence_loaded', sequence);\n };\n\n this.account.get_next_sequence(sequence_loaded);\n\n function cache_transaction(message) {\n var transaction = {\n ledger_hash: message.ledger_hash,\n ledger_index: message.ledger_index,\n metadata: message.meta,\n tx_json: message.transaction\n }\n\n transaction.tx_json.ledger_index = transaction.ledger_index;\n transaction.tx_json.inLedger = transaction.ledger_index;\n\n self._cache[message.transaction.Sequence] = transaction;\n }\n\n this.account.on('transaction', cache_transaction);\n};\n\nutil.inherits(TransactionManager, EventEmitter);\n\n// request_tx presents transactions in\n// a format slightly different from \n// request_transaction_entry\nfunction rewrite_transaction(tx) {\n try {\n var result = {\n ledger_index: tx.ledger_index,\n metadata: tx.meta,\n tx_json: { \n Account: tx.Account,\n Amount: tx.Amount,\n Destination: tx.Destination,\n Fee: tx.Fee,\n Flags: tx.Flags,\n Sequence: tx.Sequence,\n SigningPubKey: tx.SigningPubKey,\n TransactionType: tx.TransactionType,\n hash: tx.hash\n }\n }\n } catch(exception) {\n }\n return result || { };\n};\n\nTransactionManager.prototype._resubmit = function() {\n var self = this;\n\n function resubmit(pending, index) {\n if (pending.finalized) {\n // Transaction has been finalized, nothing to do\n return;\n } \n\n var sequence = pending.tx_json.Sequence;\n var cached = self._cache[sequence];\n\n pending.emit('resubmit');\n\n if (cached) {\n // Transaction was received while waiting for\n // resubmission\n pending.emit('success', cached);\n delete self._cache[sequence];\n } else if (pending.hash) {\n // Transaction was successfully submitted, and\n // its hash discovered, but not validated\n\n function pending_check(err, res) {\n if (self._is_not_found(err)) {\n self._request(pending);\n } else {\n pending.emit('success', rewrite_transaction(res));\n }\n }\n\n self.remote.request_tx(pending.hash, pending_check);\n } else {\n self._request(pending);\n }\n }\n\n this._wait_ledgers(3, function() {\n self._pending.forEach(resubmit);\n });\n}\n\nTransactionManager.prototype._wait_ledgers = function(ledgers, callback) {\n var self = this;\n var closes = 0;\n\n function ledger_closed() {\n if (++closes === ledgers) {\n callback();\n self.remote.removeListener('ledger_closed', ledger_closed);\n }\n }\n\n this.remote.on('ledger_closed', ledger_closed);\n}\n\nTransactionManager.prototype._request = function(tx) {\n var self = this;\n var remote = this.remote;\n\n if (!tx._secret && !tx.tx_json.TxnSignature) {\n tx.emit('error', new RippleError('tejSecretUnknown', 'Missing secret'));\n return;\n } \n \n if (!remote.trusted && !remote.local_signing) {\n tx.emit('error', new RippleError('tejServerUntrusted', 'Attempt to give secret to untrusted server'));\n return;\n }\n\n function finalize(message) {\n if (!tx.finalized) {\n tx.finalized = true;\n tx.emit('final', message);\n self._pending.removeSequence(tx.tx_json.Sequence);\n }\n }\n\n tx.once('error', finalize);\n tx.once('success', finalize);\n\n // Listen for 'ledger closed' events to verify\n // that the transaction is discovered in the\n // ledger before considering the transaction\n // successful\n this._detect_ledger_entry(tx);\n\n var submit_request = remote.request_submit();\n\n if (remote.local_signing) {\n tx.sign();\n submit_request.tx_blob(tx.serialize().to_hex());\n } else {\n submit_request.secret(tx._secret);\n submit_request.build_path(tx._build_path);\n submit_request.tx_json(tx.tx_json);\n }\n\n tx.submit_index = remote._ledger_current_index;\n\n function transaction_proposed(message) {\n tx.hash = message.tx_json.hash;\n tx.set_state('client_proposed');\n tx.emit('proposed', {\n tx_json: message.tx_json,\n\n result: message.engine_result,\n engine_result: message.engine_result,\n\n result_code: message.engine_result_code,\n engine_result_code: message.engine_result_code,\n\n result_message: message.engine_result_message,\n engine_result_message: message.engine_result_message,\n\n // If server is honest, don't expect a final if rejected.\n rejected: tx.isRejected(message.engine_result_code),\n });\n }\n\n function transaction_failed(message) {\n if (!tx.hash) tx.hash = message.tx_json.hash;\n\n function transaction_requested(err, res) {\n if (self._is_not_found(err)) {\n self._resubmit();\n } else {\n tx.emit('error', new RippleError(message));\n self._pending.removeSequence(tx.tx_json.Sequence);\n }\n }\n\n self.remote.request_tx(tx.hash, transaction_requested);\n }\n\n function submission_error(err) {\n tx.set_state('remoteError');\n tx.emit('error', new RippleError(err));\n }\n\n function submission_success(message) {\n var engine_result = message.engine_result || '';\n\n tx.hash = message.tx_json.hash;\n\n switch (engine_result.slice(0, 3)) {\n case 'tef':\n //tefPAST_SEQ\n transaction_failed(message);\n break;\n case 'tes':\n transaction_proposed(message);\n break;\n default:\n submission_error(message);\n }\n }\n\n submit_request.once('success', submission_success);\n submit_request.once('error', submission_error);\n submit_request.request();\n\n submit_request.timeout(1000 * 10, function() {\n if (self.remote._connected) {\n self._resubmit();\n }\n });\n\n tx.set_state('client_submitted');\n tx.emit('submitted');\n\n return submit_request;\n};\n\nTransactionManager.prototype._is_not_found = function(error) {\n var not_found_re = /^(txnNotFound|transactionNotFound)$/;\n return error && typeof error === 'object'\n && error.error === 'remoteError'\n && typeof error.remote === 'object'\n && not_found_re.test(error.remote.error);\n};\n\nTransactionManager.prototype._detect_ledger_entry = function(tx) {\n var self = this;\n var remote = this.remote;\n var checked_ledgers = { };\n\n function entry_callback(err, message) {\n if (typeof message !== 'object') return;\n\n var ledger_hash = message.ledger_hash;\n var ledger_index = message.ledger_index;\n\n if (tx.finalized || checked_ledgers[ledger_hash]) {\n // Transaction submission has already erred or\n // this ledger has already been checked for \n // transaction\n return;\n }\n\n checked_ledgers[ledger_hash] = true;\n\n if (self._is_not_found(err)) {\n var dif = ledger_index - tx.submit_index;\n if (dif >= 8) {\n // Lost\n tx.emit('error', message);\n tx.emit('lost', message);\n } else if (dif >= 4) {\n // Missing\n tx.set_state('client_missing');\n tx.emit('missing', message);\n } else {\n // Pending\n tx.emit('pending', message);\n }\n } else {\n // Transaction was found in the ledger, \n // consider this transaction successful\n if (message.metadata) {\n tx.set_state(message.metadata.TransactionResult);\n }\n tx.emit('success', message);\n }\n }\n\n function ledger_closed(message) {\n if (!tx.finalized && !checked_ledgers[message.ledger_hash]) {\n remote.request_transaction_entry(tx.hash, message.ledger_hash, entry_callback);\n }\n }\n\n function transaction_proposed() {\n // Check the ledger for transaction entry\n remote.addListener('ledger_closed', ledger_closed);\n }\n\n function transaction_finalized() {\n // Stop checking the ledger\n remote.removeListener('ledger_closed', ledger_closed);\n tx.removeListener('proposed', transaction_proposed);\n }\n\n tx.once('proposed', transaction_proposed);\n tx.once('final', transaction_finalized);\n tx.once('resubmit', transaction_finalized);\n};\n\n/**\n * @param {Object} tx\n */\n\nTransactionManager.prototype.submit = function(tx) {\n // If sequence number is not yet known, defer until it is.\n var self = this;\n\n if (!this._next_sequence) {\n function resubmit_transaction() {\n self.submit(tx); \n }\n this.once('sequence_loaded', resubmit_transaction);\n return;\n }\n\n tx.tx_json.Sequence = this._next_sequence++;\n tx.complete();\n\n this._pending.push(tx);\n\n var fee = tx.tx_json.Fee;\n\n if (fee === void(0) || fee <= this._max_fee) {\n this._request(tx);\n }\n};\n\nexports.TransactionManager = TransactionManager;\n\n\n// WEBPACK FOOTER\n// module.id = 31\n// module.readableIdentifier = ./src/js/ripple/transactionmanager.js\n//@ sourceURL=webpack-module:///./src/js/ripple/transactionmanager.js"); + eval("\nvar sjcl = require(11);\nvar utils = require(9);\nvar config = require(12);\nvar jsbn = require(20);\n\nvar BigInteger = jsbn.BigInteger;\nvar nbi = jsbn.nbi;\n\nvar Base = require(4).Base;\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\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\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 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// 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 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 = nbi();\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\n break;\n\n default:\n if ('string' !== typeof j) {\n\t this._value = NaN;\n }\n else if (j[0] === \"r\") {\n\t this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);\n }\n else if (this.constructor.width === j.length) {\n\t this._value = new BigInteger(utils.stringToArray(j), 256);\n }\n else if ((this.constructor.width*2) === j.length) {\n\t // XXX Check char set!\n\t this._value = new BigInteger(j, 16);\n }\n else {\n\t this._value = NaN;\n }\n }\n\n return this;\n};\n\nUInt.prototype.parse_hex = function (j) {\n if ('string' === typeof j &&\n j.length === (this.constructor.width * 2)) {\n this._value = new BigInteger(j, 16);\n } else {\n this._value = NaN;\n }\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 return this;\n};\n\n\nUInt.prototype.parse_bytes = function (j) {\n if (!Array.isArray(j) || j.length !== this.constructor.width) {\n\tthis._value = NaN;\n } else {\n\t this._value = new BigInteger(j, 256);\n }\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 &&\n j.bitLength() <= this.constructor.width * 8) {\n var bytes = sjcl.codec.bytes.fromBits(j.toBits());\n\t this._value = new BigInteger(bytes, 256);\n } else {\n this._value = NaN;\n }\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 var bytes = this._value.toByteArray();\n bytes = bytes.map(function (b) { return (b+256) % 256; });\n var target = this.constructor.width;\n\n // XXX Make sure only trim off leading zeros.\n bytes = bytes.slice(-target);\n while (bytes.length < target) bytes.unshift(0);\n\n return bytes;\n};\n\nUInt.prototype.to_hex = function () {\n if (!(this._value instanceof BigInteger))\n return null;\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 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 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 = 31\n// module.readableIdentifier = ./src/js/ripple/uint.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint.js"); /***/ }, @@ -280,7 +280,7 @@ var ripple = /***/ 33: /***/ function(module, exports, require) { - eval("\nvar sjcl = require(11);\nvar utils = require(9);\nvar config = require(12);\nvar jsbn = require(20);\nvar extend = require(29);\n\nvar BigInteger = jsbn.BigInteger;\nvar nbi = jsbn.nbi;\n\nvar UInt = require(30).UInt,\n Base = require(4).Base;\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 = 33\n// module.readableIdentifier = ./src/js/ripple/uint128.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint128.js"); + eval("\nvar sjcl = require(11);\nvar utils = require(9);\nvar config = require(12);\nvar jsbn = require(20);\nvar extend = require(29);\n\nvar BigInteger = jsbn.BigInteger;\nvar nbi = jsbn.nbi;\n\nvar UInt = require(31).UInt,\n Base = require(4).Base;\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 = 33\n// module.readableIdentifier = ./src/js/ripple/uint128.js\n//@ sourceURL=webpack-module:///./src/js/ripple/uint128.js"); /***/ }, @@ -343,7 +343,7 @@ var ripple = /***/ 42: /***/ function(module, exports, require) { - eval("\nfunction TransactionQueue() {\n this._queue = [ ];\n}\n\nTransactionQueue.prototype.length = function() {\n return this._queue.length;\n};\n\nTransactionQueue.prototype.push = function(o) {\n return this._queue.push(o);\n};\n\nTransactionQueue.prototype.hasHash = function(hash) {\n return this.indexOf('hash', hash) !== -1;\n};\n\nTransactionQueue.prototype.hasSequence = function(sequence) {\n return this.indexOf('sequence', sequence) !== -1;\n};\n\nTransactionQueue.prototype.indexOf = function(prop, val) {\n var index = -1;\n for (var i=0, tx; tx=this._queue[i]; i++) {\n if (tx[prop] === val) {\n index = i;\n break;\n }\n }\n return index;\n};\n\nTransactionQueue.prototype.removeSequence = function(sequence) {\n var result = [ ];\n for (var i=0, tx; tx=this._queue[i]; i++) {\n if (!tx.tx_json) continue;\n if (tx.tx_json.Sequence !== sequence) \n result.push(tx);\n }\n this._queue = result;\n};\n\nTransactionQueue.prototype.removeHash = function(hash) {\n var result = [ ];\n for (var i=0, tx; tx=this._queue[i]; i++) {\n if (!tx.tx_json) continue;\n if (tx.hash !== hash)\n result.push(tx);\n }\n this._queue = result;\n};\n\nTransactionQueue.prototype.forEach = function(fn) {\n for (var i=0, tx; tx=this._queue[i]; i++) {\n fn(tx, i);\n }\n};\n\nexports.TransactionQueue = TransactionQueue;\n\n\n// WEBPACK FOOTER\n// module.id = 42\n// module.readableIdentifier = ./src/js/ripple/transactionqueue.js\n//@ sourceURL=webpack-module:///./src/js/ripple/transactionqueue.js"); + eval("\nfunction TransactionQueue() {\n var self = this;\n\n this._queue = [ ];\n\n Object.defineProperty(this, '_length', {\n get: function() { return self._queue.length }\n });\n}\n\nTransactionQueue.prototype.length = function() {\n return this._queue.length;\n};\n\nTransactionQueue.prototype.indexOf = function(prop, val) {\n var index = -1;\n for (var i=0, tx; tx=this._queue[i]; i++) {\n if (tx[prop] === val) {\n index = i;\n break;\n }\n }\n return index;\n};\n\nTransactionQueue.prototype.hasHash = function(hash) {\n return this.indexOf('hash', hash) !== -1;\n};\n\nTransactionQueue.prototype.get = function(prop, val) {\n var index = this.indexOf(prop, val);\n return index > -1 ? this._queue[index] : false;\n};\n\nTransactionQueue.prototype.removeSequence = function(sequence) {\n var result = [ ];\n for (var i=0, tx; tx=this._queue[i]; i++) {\n if (!tx.tx_json) continue;\n if (tx.tx_json.Sequence !== sequence) result.push(tx);\n }\n this._queue = result;\n};\n\nTransactionQueue.prototype.removeHash = function(hash) {\n var result = [ ];\n for (var i=0, tx; tx=this._queue[i]; i++) {\n if (!tx.tx_json) continue;\n if (tx.hash !== hash) result.push(tx);\n }\n this._queue = result;\n};\n\nTransactionQueue.prototype.forEach = function() {\n Array.prototype.forEach.apply(this._queue, arguments);\n};\n\nTransactionQueue.prototype.push = function() {\n Array.prototype.push.apply(this._queue, arguments);\n};\n\nexports.TransactionQueue = TransactionQueue;\n\n\n// WEBPACK FOOTER\n// module.id = 42\n// module.readableIdentifier = ./src/js/ripple/transactionqueue.js\n//@ sourceURL=webpack-module:///./src/js/ripple/transactionqueue.js"); /***/ }, diff --git a/livereload.js b/livereload.js new file mode 100644 index 000000000..edb280265 --- /dev/null +++ b/livereload.js @@ -0,0 +1,1055 @@ +(function() { +var __customevents = {}, __protocol = {}, __connector = {}, __timer = {}, __options = {}, __reloader = {}, __livereload = {}, __less = {}, __startup = {}; + +// customevents +var CustomEvents; +CustomEvents = { + bind: function(element, eventName, handler) { + if (element.addEventListener) { + return element.addEventListener(eventName, handler, false); + } else if (element.attachEvent) { + element[eventName] = 1; + return element.attachEvent('onpropertychange', function(event) { + if (event.propertyName === eventName) { + return handler(); + } + }); + } else { + throw new Error("Attempt to attach custom event " + eventName + " to something which isn't a DOMElement"); + } + }, + fire: function(element, eventName) { + var event; + if (element.addEventListener) { + event = document.createEvent('HTMLEvents'); + event.initEvent(eventName, true, true); + return document.dispatchEvent(event); + } else if (element.attachEvent) { + if (element[eventName]) { + return element[eventName]++; + } + } else { + throw new Error("Attempt to fire custom event " + eventName + " on something which isn't a DOMElement"); + } + } +}; +__customevents.bind = CustomEvents.bind; +__customevents.fire = CustomEvents.fire; + +// protocol +var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError; +var __indexOf = Array.prototype.indexOf || function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (this[i] === item) return i; + } + return -1; +}; +__protocol.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6'; +__protocol.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7'; +__protocol.ProtocolError = ProtocolError = (function() { + function ProtocolError(reason, data) { + this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\"."; + } + return ProtocolError; +})(); +__protocol.Parser = Parser = (function() { + function Parser(handlers) { + this.handlers = handlers; + this.reset(); + } + Parser.prototype.reset = function() { + return this.protocol = null; + }; + Parser.prototype.process = function(data) { + var command, message, options, _ref; + try { + if (!(this.protocol != null)) { + if (data.match(/^!!ver:([\d.]+)$/)) { + this.protocol = 6; + } else if (message = this._parseMessage(data, ['hello'])) { + if (!message.protocols.length) { + throw new ProtocolError("no protocols specified in handshake message"); + } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) { + this.protocol = 7; + } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) { + this.protocol = 6; + } else { + throw new ProtocolError("no supported protocols found"); + } + } + return this.handlers.connected(this.protocol); + } else if (this.protocol === 6) { + message = JSON.parse(data); + if (!message.length) { + throw new ProtocolError("protocol 6 messages must be arrays"); + } + command = message[0], options = message[1]; + if (command !== 'refresh') { + throw new ProtocolError("unknown protocol 6 command"); + } + return this.handlers.message({ + command: 'reload', + path: options.path, + liveCSS: (_ref = options.apply_css_live) != null ? _ref : true + }); + } else { + message = this._parseMessage(data, ['reload', 'alert']); + return this.handlers.message(message); + } + } catch (e) { + if (e instanceof ProtocolError) { + return this.handlers.error(e); + } else { + throw e; + } + } + }; + Parser.prototype._parseMessage = function(data, validCommands) { + var message, _ref; + try { + message = JSON.parse(data); + } catch (e) { + throw new ProtocolError('unparsable JSON', data); + } + if (!message.command) { + throw new ProtocolError('missing "command" key', data); + } + if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) { + throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data); + } + return message; + }; + return Parser; +})(); + +// connector +// Generated by CoffeeScript 1.3.3 +var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref; + +_ref = __protocol, Parser = _ref.Parser, PROTOCOL_6 = _ref.PROTOCOL_6, PROTOCOL_7 = _ref.PROTOCOL_7; + +Version = '2.0.8'; + +__connector.Connector = Connector = (function() { + + function Connector(options, WebSocket, Timer, handlers) { + var _this = this; + this.options = options; + this.WebSocket = WebSocket; + this.Timer = Timer; + this.handlers = handlers; + this._uri = "ws://" + this.options.host + ":" + this.options.port + "/livereload"; + this._nextDelay = this.options.mindelay; + this._connectionDesired = false; + this.protocol = 0; + this.protocolParser = new Parser({ + connected: function(protocol) { + _this.protocol = protocol; + _this._handshakeTimeout.stop(); + _this._nextDelay = _this.options.mindelay; + _this._disconnectionReason = 'broken'; + return _this.handlers.connected(protocol); + }, + error: function(e) { + _this.handlers.error(e); + return _this._closeOnError(); + }, + message: function(message) { + return _this.handlers.message(message); + } + }); + this._handshakeTimeout = new Timer(function() { + if (!_this._isSocketConnected()) { + return; + } + _this._disconnectionReason = 'handshake-timeout'; + return _this.socket.close(); + }); + this._reconnectTimer = new Timer(function() { + if (!_this._connectionDesired) { + return; + } + return _this.connect(); + }); + this.connect(); + } + + Connector.prototype._isSocketConnected = function() { + return this.socket && this.socket.readyState === this.WebSocket.OPEN; + }; + + Connector.prototype.connect = function() { + var _this = this; + this._connectionDesired = true; + if (this._isSocketConnected()) { + return; + } + this._reconnectTimer.stop(); + this._disconnectionReason = 'cannot-connect'; + this.protocolParser.reset(); + this.handlers.connecting(); + this.socket = new this.WebSocket(this._uri); + this.socket.onopen = function(e) { + return _this._onopen(e); + }; + this.socket.onclose = function(e) { + return _this._onclose(e); + }; + this.socket.onmessage = function(e) { + return _this._onmessage(e); + }; + return this.socket.onerror = function(e) { + return _this._onerror(e); + }; + }; + + Connector.prototype.disconnect = function() { + this._connectionDesired = false; + this._reconnectTimer.stop(); + if (!this._isSocketConnected()) { + return; + } + this._disconnectionReason = 'manual'; + return this.socket.close(); + }; + + Connector.prototype._scheduleReconnection = function() { + if (!this._connectionDesired) { + return; + } + if (!this._reconnectTimer.running) { + this._reconnectTimer.start(this._nextDelay); + return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2); + } + }; + + Connector.prototype.sendCommand = function(command) { + if (this.protocol == null) { + return; + } + return this._sendCommand(command); + }; + + Connector.prototype._sendCommand = function(command) { + return this.socket.send(JSON.stringify(command)); + }; + + Connector.prototype._closeOnError = function() { + this._handshakeTimeout.stop(); + this._disconnectionReason = 'error'; + return this.socket.close(); + }; + + Connector.prototype._onopen = function(e) { + var hello; + this.handlers.socketConnected(); + this._disconnectionReason = 'handshake-failed'; + hello = { + command: 'hello', + protocols: [PROTOCOL_6, PROTOCOL_7] + }; + hello.ver = Version; + if (this.options.ext) { + hello.ext = this.options.ext; + } + if (this.options.extver) { + hello.extver = this.options.extver; + } + if (this.options.snipver) { + hello.snipver = this.options.snipver; + } + this._sendCommand(hello); + return this._handshakeTimeout.start(this.options.handshake_timeout); + }; + + Connector.prototype._onclose = function(e) { + this.protocol = 0; + this.handlers.disconnected(this._disconnectionReason, this._nextDelay); + return this._scheduleReconnection(); + }; + + Connector.prototype._onerror = function(e) {}; + + Connector.prototype._onmessage = function(e) { + return this.protocolParser.process(e.data); + }; + + return Connector; + +})(); + +// timer +var Timer; +var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; +__timer.Timer = Timer = (function() { + function Timer(func) { + this.func = func; + this.running = false; + this.id = null; + this._handler = __bind(function() { + this.running = false; + this.id = null; + return this.func(); + }, this); + } + Timer.prototype.start = function(timeout) { + if (this.running) { + clearTimeout(this.id); + } + this.id = setTimeout(this._handler, timeout); + return this.running = true; + }; + Timer.prototype.stop = function() { + if (this.running) { + clearTimeout(this.id); + this.running = false; + return this.id = null; + } + }; + return Timer; +})(); +Timer.start = function(timeout, func) { + return setTimeout(func, timeout); +}; + +// options +var Options; +__options.Options = Options = (function() { + function Options() { + this.host = null; + this.port = 35729; + this.snipver = null; + this.ext = null; + this.extver = null; + this.mindelay = 1000; + this.maxdelay = 60000; + this.handshake_timeout = 5000; + } + Options.prototype.set = function(name, value) { + switch (typeof this[name]) { + case 'undefined': + break; + case 'number': + return this[name] = +value; + default: + return this[name] = value; + } + }; + return Options; +})(); +Options.extract = function(document) { + var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len2, _ref, _ref2; + _ref = document.getElementsByTagName('script'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + element = _ref[_i]; + if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) { + options = new Options(); + if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) { + options.host = mm[1]; + if (mm[2]) { + options.port = parseInt(mm[2], 10); + } + } + if (m[2]) { + _ref2 = m[2].split('&'); + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + pair = _ref2[_j]; + if ((keyAndValue = pair.split('=')).length > 1) { + options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('=')); + } + } + } + return options; + } + } + return null; +}; + +// reloader +// Generated by CoffeeScript 1.3.1 +(function() { + var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl; + + splitUrl = function(url) { + var hash, index, params; + if ((index = url.indexOf('#')) >= 0) { + hash = url.slice(index); + url = url.slice(0, index); + } else { + hash = ''; + } + if ((index = url.indexOf('?')) >= 0) { + params = url.slice(index); + url = url.slice(0, index); + } else { + params = ''; + } + return { + url: url, + params: params, + hash: hash + }; + }; + + pathFromUrl = function(url) { + var path; + url = splitUrl(url).url; + if (url.indexOf('file://') === 0) { + path = url.replace(/^file:\/\/(localhost)?/, ''); + } else { + path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/'); + } + return decodeURIComponent(path); + }; + + pickBestMatch = function(path, objects, pathFunc) { + var bestMatch, object, score, _i, _len; + bestMatch = { + score: 0 + }; + for (_i = 0, _len = objects.length; _i < _len; _i++) { + object = objects[_i]; + score = numberOfMatchingSegments(path, pathFunc(object)); + if (score > bestMatch.score) { + bestMatch = { + object: object, + score: score + }; + } + } + if (bestMatch.score > 0) { + return bestMatch; + } else { + return null; + } + }; + + numberOfMatchingSegments = function(path1, path2) { + var comps1, comps2, eqCount, len; + path1 = path1.replace(/^\/+/, '').toLowerCase(); + path2 = path2.replace(/^\/+/, '').toLowerCase(); + if (path1 === path2) { + return 10000; + } + comps1 = path1.split('/').reverse(); + comps2 = path2.split('/').reverse(); + len = Math.min(comps1.length, comps2.length); + eqCount = 0; + while (eqCount < len && comps1[eqCount] === comps2[eqCount]) { + ++eqCount; + } + return eqCount; + }; + + pathsMatch = function(path1, path2) { + return numberOfMatchingSegments(path1, path2) > 0; + }; + + IMAGE_STYLES = [ + { + selector: 'background', + styleNames: ['backgroundImage'] + }, { + selector: 'border', + styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage'] + } + ]; + + __reloader.Reloader = Reloader = (function() { + + Reloader.name = 'Reloader'; + + function Reloader(window, console, Timer) { + this.window = window; + this.console = console; + this.Timer = Timer; + this.document = this.window.document; + this.importCacheWaitPeriod = 200; + this.plugins = []; + } + + Reloader.prototype.addPlugin = function(plugin) { + return this.plugins.push(plugin); + }; + + Reloader.prototype.analyze = function(callback) { + return results; + }; + + Reloader.prototype.reload = function(path, options) { + var plugin, _base, _i, _len, _ref; + this.options = options; + if ((_base = this.options).stylesheetReloadTimeout == null) { + _base.stylesheetReloadTimeout = 15000; + } + _ref = this.plugins; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + plugin = _ref[_i]; + if (plugin.reload && plugin.reload(path, options)) { + return; + } + } + if (options.liveCSS) { + if (path.match(/\.css$/i)) { + if (this.reloadStylesheet(path)) { + return; + } + } + } + if (options.liveImg) { + if (path.match(/\.(jpe?g|png|gif)$/i)) { + this.reloadImages(path); + return; + } + } + return this.reloadPage(); + }; + + Reloader.prototype.reloadPage = function() { + return this.window.document.location.reload(); + }; + + Reloader.prototype.reloadImages = function(path) { + var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results; + expando = this.generateUniqueString(); + _ref = this.document.images; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + img = _ref[_i]; + if (pathsMatch(path, pathFromUrl(img.src))) { + img.src = this.generateCacheBustUrl(img.src, expando); + } + } + if (this.document.querySelectorAll) { + for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) { + _ref1 = IMAGE_STYLES[_j], selector = _ref1.selector, styleNames = _ref1.styleNames; + _ref2 = this.document.querySelectorAll("[style*=" + selector + "]"); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + img = _ref2[_k]; + this.reloadStyleImages(img.style, styleNames, path, expando); + } + } + } + if (this.document.styleSheets) { + _ref3 = this.document.styleSheets; + _results = []; + for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { + styleSheet = _ref3[_l]; + _results.push(this.reloadStylesheetImages(styleSheet, path, expando)); + } + return _results; + } + }; + + Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) { + var rule, rules, styleNames, _i, _j, _len, _len1; + try { + rules = styleSheet != null ? styleSheet.cssRules : void 0; + } catch (e) { + + } + if (!rules) { + return; + } + for (_i = 0, _len = rules.length; _i < _len; _i++) { + rule = rules[_i]; + switch (rule.type) { + case CSSRule.IMPORT_RULE: + this.reloadStylesheetImages(rule.styleSheet, path, expando); + break; + case CSSRule.STYLE_RULE: + for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) { + styleNames = IMAGE_STYLES[_j].styleNames; + this.reloadStyleImages(rule.style, styleNames, path, expando); + } + break; + case CSSRule.MEDIA_RULE: + this.reloadStylesheetImages(rule, path, expando); + } + } + }; + + Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) { + var newValue, styleName, value, _i, _len, + _this = this; + for (_i = 0, _len = styleNames.length; _i < _len; _i++) { + styleName = styleNames[_i]; + value = style[styleName]; + if (typeof value === 'string') { + newValue = value.replace(/\burl\s*\(([^)]*)\)/, function(match, src) { + if (pathsMatch(path, pathFromUrl(src))) { + return "url(" + (_this.generateCacheBustUrl(src, expando)) + ")"; + } else { + return match; + } + }); + if (newValue !== value) { + style[styleName] = newValue; + } + } + } + }; + + Reloader.prototype.reloadStylesheet = function(path) { + var imported, link, links, match, style, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, + _this = this; + links = (function() { + var _i, _len, _ref, _results; + _ref = this.document.getElementsByTagName('link'); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + link = _ref[_i]; + if (link.rel === 'stylesheet' && !link.__LiveReload_pendingRemoval) { + _results.push(link); + } + } + return _results; + }).call(this); + imported = []; + _ref = this.document.getElementsByTagName('style'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + style = _ref[_i]; + if (style.sheet) { + this.collectImportedStylesheets(style, style.sheet, imported); + } + } + for (_j = 0, _len1 = links.length; _j < _len1; _j++) { + link = links[_j]; + this.collectImportedStylesheets(link, link.sheet, imported); + } + if (this.window.StyleFix && this.document.querySelectorAll) { + _ref1 = this.document.querySelectorAll('style[data-href]'); + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + style = _ref1[_k]; + links.push(style); + } + } + this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets"); + match = pickBestMatch(path, links.concat(imported), function(l) { + return pathFromUrl(_this.linkHref(l)); + }); + if (match) { + if (match.object.rule) { + this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href); + this.reattachImportedRule(match.object); + } else { + this.console.log("LiveReload is reloading stylesheet: " + (this.linkHref(match.object))); + this.reattachStylesheetLink(match.object); + } + } else { + this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one"); + for (_l = 0, _len3 = links.length; _l < _len3; _l++) { + link = links[_l]; + this.reattachStylesheetLink(link); + } + } + return true; + }; + + Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) { + var index, rule, rules, _i, _len; + try { + rules = styleSheet != null ? styleSheet.cssRules : void 0; + } catch (e) { + + } + if (rules && rules.length) { + for (index = _i = 0, _len = rules.length; _i < _len; index = ++_i) { + rule = rules[index]; + switch (rule.type) { + case CSSRule.CHARSET_RULE: + continue; + case CSSRule.IMPORT_RULE: + result.push({ + link: link, + rule: rule, + index: index, + href: rule.href + }); + this.collectImportedStylesheets(link, rule.styleSheet, result); + break; + default: + break; + } + } + } + }; + + Reloader.prototype.waitUntilCssLoads = function(clone, func) { + var callbackExecuted, executeCallback, poll, + _this = this; + callbackExecuted = false; + executeCallback = function() { + if (callbackExecuted) { + return; + } + callbackExecuted = true; + return func(); + }; + clone.onload = function() { + console.log("onload!"); + _this.knownToSupportCssOnLoad = true; + return executeCallback(); + }; + if (!this.knownToSupportCssOnLoad) { + (poll = function() { + if (clone.sheet) { + console.log("polling!"); + return executeCallback(); + } else { + return _this.Timer.start(50, poll); + } + })(); + } + return this.Timer.start(this.options.stylesheetReloadTimeout, executeCallback); + }; + + Reloader.prototype.linkHref = function(link) { + return link.href || link.getAttribute('data-href'); + }; + + Reloader.prototype.reattachStylesheetLink = function(link) { + var clone, parent, + _this = this; + if (link.__LiveReload_pendingRemoval) { + return; + } + link.__LiveReload_pendingRemoval = true; + if (link.tagName === 'STYLE') { + clone = this.document.createElement('link'); + clone.rel = 'stylesheet'; + clone.media = link.media; + clone.disabled = link.disabled; + } else { + clone = link.cloneNode(false); + } + clone.href = this.generateCacheBustUrl(this.linkHref(link)); + parent = link.parentNode; + if (parent.lastChild === link) { + parent.appendChild(clone); + } else { + parent.insertBefore(clone, link.nextSibling); + } + return this.waitUntilCssLoads(clone, function() { + var additionalWaitingTime; + if (/AppleWebKit/.test(navigator.userAgent)) { + additionalWaitingTime = 5; + } else { + additionalWaitingTime = 200; + } + return _this.Timer.start(additionalWaitingTime, function() { + var _ref; + if (!link.parentNode) { + return; + } + link.parentNode.removeChild(link); + clone.onreadystatechange = null; + return (_ref = _this.window.StyleFix) != null ? _ref.link(clone) : void 0; + }); + }); + }; + + Reloader.prototype.reattachImportedRule = function(_arg) { + var href, index, link, media, newRule, parent, rule, tempLink, + _this = this; + rule = _arg.rule, index = _arg.index, link = _arg.link; + parent = rule.parentStyleSheet; + href = this.generateCacheBustUrl(rule.href); + media = rule.media.length ? [].join.call(rule.media, ', ') : ''; + newRule = "@import url(\"" + href + "\") " + media + ";"; + rule.__LiveReload_newHref = href; + tempLink = this.document.createElement("link"); + tempLink.rel = 'stylesheet'; + tempLink.href = href; + tempLink.__LiveReload_pendingRemoval = true; + if (link.parentNode) { + link.parentNode.insertBefore(tempLink, link); + } + return this.Timer.start(this.importCacheWaitPeriod, function() { + if (tempLink.parentNode) { + tempLink.parentNode.removeChild(tempLink); + } + if (rule.__LiveReload_newHref !== href) { + return; + } + parent.insertRule(newRule, index); + parent.deleteRule(index + 1); + rule = parent.cssRules[index]; + rule.__LiveReload_newHref = href; + return _this.Timer.start(_this.importCacheWaitPeriod, function() { + if (rule.__LiveReload_newHref !== href) { + return; + } + parent.insertRule(newRule, index); + return parent.deleteRule(index + 1); + }); + }); + }; + + Reloader.prototype.generateUniqueString = function() { + return 'livereload=' + Date.now(); + }; + + Reloader.prototype.generateCacheBustUrl = function(url, expando) { + var hash, oldParams, params, _ref; + if (expando == null) { + expando = this.generateUniqueString(); + } + _ref = splitUrl(url), url = _ref.url, hash = _ref.hash, oldParams = _ref.params; + if (this.options.overrideURL) { + if (url.indexOf(this.options.serverURL) < 0) { + url = this.options.serverURL + this.options.overrideURL + "?url=" + encodeURIComponent(url); + } + } + params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) { + return "" + sep + expando; + }); + if (params === oldParams) { + if (oldParams.length === 0) { + params = "?" + expando; + } else { + params = "" + oldParams + "&" + expando; + } + } + return url + params + hash; + }; + + return Reloader; + + })(); + +}).call(this); + +// livereload +var Connector, LiveReload, Options, Reloader, Timer; + +Connector = __connector.Connector; + +Timer = __timer.Timer; + +Options = __options.Options; + +Reloader = __reloader.Reloader; + +__livereload.LiveReload = LiveReload = (function() { + + function LiveReload(window) { + var _this = this; + this.window = window; + this.listeners = {}; + this.plugins = []; + this.pluginIdentifiers = {}; + this.console = this.window.location.href.match(/LR-verbose/) && this.window.console && this.window.console.log && this.window.console.error ? this.window.console : { + log: function() {}, + error: function() {} + }; + if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) { + console.error("LiveReload disabled because the browser does not seem to support web sockets"); + return; + } + if (!(this.options = Options.extract(this.window.document))) { + console.error("LiveReload disabled because it could not find its own