<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow strict-local
 * @emails oncall+draft_js
 */

'use strict';

const Immutable = require('immutable');
const insertIntoList = require('insertIntoList');
const invariant = require('invariant');

const {Repeat} = Immutable;

import type CharacterMetadata from 'CharacterMetadata';
import type ContentState from 'ContentState';
import type SelectionState from 'SelectionState';

function insertTextIntoContentState(
  contentState: ContentState,
  selectionState: SelectionState,
  text: string,
  characterMetadata: CharacterMetadata,
): ContentState {
  invariant(
    selectionState.isCollapsed(),
    '`insertText` should only be called with a collapsed range.',
  );

  let len: ?number = null;
  if (text != null) {
    len = text.length;
  }

  if (len == null || len === 0) {
    return contentState;
  }

  const blockMap = contentState.getBlockMap();
  const key = selectionState.getStartKey();
  const offset = selectionState.getStartOffset();
  const block = blockMap.get(key);
  const blockText = block.getText();

  const newBlock = block.merge({
    text:
      blockText.slice(0, offset) +
      text +
      blockText.slice(offset, block.getLength()),
    characterList: insertIntoList(
      block.getCharacterList(),
      Repeat(characterMetadata, len).toList(),
      offset,
    ),
  });

  const newOffset = offset + len;

  return contentState.merge({
    blockMap: blockMap.set(key, newBlock),
    selectionAfter: selectionState.merge({
      anchorOffset: newOffset,
      focusOffset: newOffset,
    }),
  });
}

module.exports = insertTextIntoContentState;
<commit_msg>Autofix ESLint Rule fb-www/order-requires: html/shared/draft-js/model/transaction<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow strict-local
 * @emails oncall+draft_js
 */

'use strict';

import type CharacterMetadata from 'CharacterMetadata';
import type ContentState from 'ContentState';
import type SelectionState from 'SelectionState';

const Immutable = require('immutable');
const insertIntoList = require('insertIntoList');
const invariant = require('invariant');

const {Repeat} = Immutable;

function insertTextIntoContentState(
  contentState: ContentState,
  selectionState: SelectionState,
  text: string,
  characterMetadata: CharacterMetadata,
): ContentState {
  invariant(
    selectionState.isCollapsed(),
    '`insertText` should only be called with a collapsed range.',
  );

  let len: ?number = null;
  if (text != null) {
    len = text.length;
  }

  if (len == null || len === 0) {
    return contentState;
  }

  const blockMap = contentState.getBlockMap();
  const key = selectionState.getStartKey();
  const offset = selectionState.getStartOffset();
  const block = blockMap.get(key);
  const blockText = block.getText();

  const newBlock = block.merge({
    text:
      blockText.slice(0, offset) +
      text +
      blockText.slice(offset, block.getLength()),
    characterList: insertIntoList(
      block.getCharacterList(),
      Repeat(characterMetadata, len).toList(),
      offset,
    ),
  });

  const newOffset = offset + len;

  return contentState.merge({
    blockMap: blockMap.set(key, newBlock),
    selectionAfter: selectionState.merge({
      anchorOffset: newOffset,
      focusOffset: newOffset,
    }),
  });
}

module.exports = insertTextIntoContentState;
<|endoftext|>


<commit_before>/*!
 * fullnode.js - full node for bcoin
 * Copyright (c) 2014-2015, Fedor Indutny (MIT License)
 * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
 * https://github.com/bcoin-org/bcoin
 */

'use strict';

var constants = require('../protocol/constants');
var utils = require('../utils/utils');
var co = require('../utils/co');
var Node = require('./node');
var Chain = require('../chain/chain');
var Fees = require('../mempool/fees');
var Mempool = require('../mempool/mempool');
var Pool = require('../net/pool');
var Miner = require('../miner/miner');
var WalletDB = require('../wallet/walletdb');
var HTTPServer;

try {
  HTTPServer = require('../http/server');
} catch (e) {
  ;
}

/**
 * Create a fullnode complete with a chain,
 * mempool, miner, wallet, etc.
 * @exports Fullnode
 * @extends Node
 * @constructor
 * @param {Object?} options
 * @param {Boolean?} options.limitFree
 * @param {Number?} options.limitFreeRelay
 * @param {Boolean?} options.requireStandard
 * @param {Boolean?} options.rejectInsaneFees
 * @param {Boolean?} options.replaceByFee
 * @param {Boolean?} options.selfish
 * @param {Base58Address?} options.payoutAddress
 * @param {String?} options.coinbaseFlags
 * @param {Buffer?} options.sslKey
 * @param {Buffer?} options.sslCert
 * @param {Number?} options.httpPort
 * @param {String?} options.httpHost
 * @param {Object?} options.wallet - Primary {@link Wallet} options.
 * @property {Boolean} loaded
 * @property {Chain} chain
 * @property {PolicyEstimator} fees
 * @property {Mempool} mempool
 * @property {Pool} pool
 * @property {Miner} miner
 * @property {WalletDB} walletdb
 * @property {HTTPServer} http
 * @emits Fullnode#block
 * @emits Fullnode#tx
 * @emits Fullnode#alert
 * @emits Fullnode#error
 */

function Fullnode(options) {
  if (!(this instanceof Fullnode))
    return new Fullnode(options);

  Node.call(this, options);

  // Instantiate blockchain.
  this.chain = new Chain({
    network: this.network,
    logger: this.logger,
    db: this.options.db,
    location: this.location('chain'),
    preload: false,
    spv: false,
    witness: this.options.witness,
    prune: this.options.prune,
    useCheckpoints: this.options.useCheckpoints,
    coinCache: this.options.coinCache,
    indexTX: this.options.indexTX,
    indexAddress: this.options.indexAddress,
    maxFiles: this.options.maxFiles
  });

  // Fee estimation.
  this.fees = new Fees(
    constants.tx.MIN_RELAY,
    this.network,
    this.logger);

  // Mempool needs access to the chain.
  this.mempool = new Mempool({
    network: this.network,
    logger: this.logger,
    chain: this.chain,
    fees: this.fees,
    limitFree: this.options.limitFree,
    limitFreeRelay: this.options.limitFreeRelay,
    requireStandard: this.options.requireStandard,
    rejectInsaneFees: this.options.rejectInsaneFees,
    replaceByFee: this.options.replaceByFee,
    indexAddress: this.options.indexAddress
  });

  // Pool needs access to the chain and mempool.
  this.pool = new Pool({
    network: this.network,
    logger: this.logger,
    chain: this.chain,
    mempool: this.mempool,
    witness: this.options.witness,
    selfish: this.options.selfish,
    headers: this.options.headers,
    compact: this.options.compact,
    bip151: this.options.bip151,
    bip150: this.options.bip150,
    authPeers: this.options.authPeers,
    knownPeers: this.options.knownPeers,
    identityKey: this.options.identityKey,
    maxPeers: this.options.maxPeers,
    maxLeeches: this.options.maxLeeches,
    proxyServer: this.options.proxyServer,
    preferredSeed: this.options.preferredSeed,
    ignoreDiscovery: this.options.ignoreDiscovery,
    port: this.options.port,
    listen: this.options.listen,
    spv: false
  });

  // Miner needs access to the chain and mempool.
  this.miner = new Miner({
    network: this.network,
    logger: this.logger,
    chain: this.chain,
    mempool: this.mempool,
    fees: this.fees,
    address: this.options.payoutAddress,
    coinbaseFlags: this.options.coinbaseFlags
  });

  // Wallet database needs access to fees.
  this.walletdb = new WalletDB({
    network: this.network,
    logger: this.logger,
    fees: this.fees,
    db: this.options.db,
    location: this.location('walletdb'),
    witness: this.options.witness,
    useCheckpoints: this.options.useCheckpoints,
    maxFiles: this.options.maxFiles,
    resolution: true,
    verify: false
  });

  // HTTP needs access to the node.
  if (!utils.isBrowser) {
    this.http = new HTTPServer({
      network: this.network,
      logger: this.logger,
      node: this,
      key: this.options.sslKey,
      cert: this.options.sslCert,
      port: this.options.httpPort || this.network.rpcPort,
      host: this.options.httpHost || '0.0.0.0',
      apiKey: this.options.apiKey,
      serviceKey: this.options.serviceKey,
      walletAuth: this.options.walletAuth,
      noAuth: this.options.noAuth
    });
  }

  this._init();
}

utils.inherits(Fullnode, Node);

/**
 * Initialize the node.
 * @private
 */

Fullnode.prototype._init = function _init() {
  var self = this;
  var onError = this._error.bind(this);

  // Bind to errors
  this.chain.on('error', onError);
  this.mempool.on('error', onError);
  this.pool.on('error', onError);
  this.miner.on('error', onError);
  this.walletdb.on('error', onError);

  if (this.http)
    this.http.on('error', onError);

  this.pool.on('alert', function(alert) {
    self.emit('alert', alert);
  });

  this.mempool.on('tx', function(tx) {
    self.emit('tx', tx);
    self.walletdb.addTX(tx).catch(onError);
    self.miner.notifyEntry();
  });

  this.chain.on('block', function(block) {
    self.emit('block', block);
  });

  this.chain.on('connect', function(entry, block) {
    self.walletdb.addBlock(entry, block.txs).catch(onError);

    if (self.chain.synced)
      self.mempool.addBlock(block).catch(onError);
  });

  this.chain.on('disconnect', function(entry, block) {
    self.walletdb.removeBlock(entry).catch(onError);

    if (self.chain.synced)
      self.mempool.removeBlock(block).catch(onError);
  });

  this.miner.on('block', function(block) {
    self.broadcast(block.toInv()).catch(onError);
  });

  this.walletdb.on('send', function(tx) {
    self.sendTX(tx).catch(onError);
  });
};

/**
 * Open the node and all its child objects,
 * wait for the database to load.
 * @alias Fullnode#open
 * @returns {Promise}
 */

Fullnode.prototype._open = co(function* open() {
  yield this.chain.open();
  yield this.mempool.open();
  yield this.miner.open();
  yield this.pool.open();
  yield this.walletdb.open();

  // Ensure primary wallet.
  yield this.openWallet();

  // Rescan for any missed transactions.
  yield this.rescan();

  // Rebroadcast pending transactions.
  yield this.resend();

  if (this.http)
    yield this.http.open();

  this.logger.info('Node is loaded.');
});

/**
 * Close the node, wait for the database to close.
 * @alias Fullnode#close
 * @returns {Promise}
 */

Fullnode.prototype._close = co(function* close() {
  if (this.http)
    yield this.http.close();

  yield this.wallet.destroy();

  this.wallet = null;

  yield this.walletdb.close();
  yield this.pool.close();
  yield this.miner.close();
  yield this.mempool.close();
  yield this.chain.close();

  this.logger.info('Node is closed.');
});

/**
 * Rescan for any missed transactions.
 * @returns {Promise}
 */

Fullnode.prototype.rescan = function rescan() {
  if (this.options.noScan) {
    return this.walletdb.setTip(
      this.chain.tip.hash,
      this.chain.height);
  }

  // Always rescan to make sure we didn't
  // miss anything: there is no atomicity
  // between the chaindb and walletdb.
  return this.scan();
};

/**
 * Rescan for any missed transactions.
 * @param {Number} height
 * @returns {Promise}
 */

Fullnode.prototype.scan = function scan(height) {
  return this.walletdb.rescan(this.chain.db, height);
};

/**
 * Broadcast a transaction (note that this will _not_ be verified
 * by the mempool - use with care, lest you get banned from
 * bitcoind nodes).
 * @param {TX|Block} item
 * @returns {Promise}
 */

Fullnode.prototype.broadcast = function broadcast(item, callback) {
  return this.pool.broadcast(item, callback);
};

/**
 * Verify a transaction, add it to the mempool, and broadcast.
 * Safer than {@link Fullnode#broadcast}.
 * @example
 * node.sendTX(tx, callback);
 * node.sendTX(tx, true, callback);
 * @param {TX} tx
 */

Fullnode.prototype.sendTX = co(function* sendTX(tx) {
  try {
    yield this.mempool.addTX(tx);
  } catch (err) {
    if (err.type === 'VerifyError') {
      this._error(err);
      this.logger.warning('Verification failed for tx: %s.', tx.rhash);
      this.logger.warning('Attempting to broadcast anyway...');
      yield this.pool.broadcast(tx);
      return;
    }
    throw err;
  }

  if (!this.options.selfish)
    tx = tx.toInv();

  yield this.pool.broadcast(tx);
});

/**
 * Listen on a server socket on
 * the p2p network (accepts leech peers).
 */

Fullnode.prototype.listen = function listen() {
  return this.pool.listen();
};

/**
 * Connect to the network.
 */

Fullnode.prototype.connect = function connect() {
  return this.pool.connect();
};

/**
 * Start the blockchain sync.
 */

Fullnode.prototype.startSync = function startSync() {
  return this.pool.startSync();
};

/**
 * Stop syncing the blockchain.
 */

Fullnode.prototype.stopSync = function stopSync() {
  return this.pool.stopSync();
};

/**
 * Retrieve a block from the chain database.
 * @param {Hash} hash
 * @returns {Promise} - Returns {@link Block}.
 */

Fullnode.prototype.getBlock = function getBlock(hash) {
  return this.chain.db.getBlock(hash);
};

/**
 * Retrieve a block from the chain database, filled with coins.
 * @param {Hash} hash
 * @returns {Promise} - Returns {@link Block}.
 */

Fullnode.prototype.getFullBlock = function getFullBlock(hash) {
  return this.chain.db.getFullBlock(hash);
};

/**
 * Retrieve a coin from the mempool or chain database.
 * Takes into account spent coins in the mempool.
 * @param {Hash} hash
 * @param {Number} index
 * @returns {Promise} - Returns {@link Coin}.
 */

Fullnode.prototype.getCoin = function getCoin(hash, index) {
  var coin = this.mempool.getCoin(hash, index);

  if (coin)
    return Promise.resolve(coin);

  if (this.mempool.isSpent(hash, index))
    return Promise.resolve();

  return this.chain.db.getCoin(hash, index);
};

/**
 * Get coins that pertain to an address from the mempool or chain database.
 * Takes into account spent coins in the mempool.
 * @param {Address} addresses
 * @returns {Promise} - Returns {@link Coin}[].
 */

Fullnode.prototype.getCoinsByAddress = co(function* getCoinsByAddress(addresses) {
  var coins = this.mempool.getCoinsByAddress(addresses);
  var i, blockCoins, coin, spent;

  blockCoins = yield this.chain.db.getCoinsByAddress(addresses);

  for (i = 0; i < blockCoins.length; i++) {
    coin = blockCoins[i];
    spent = this.mempool.isSpent(coin.hash, coin.index);

    if (!spent)
      coins.push(coin);
  }

  return coins;
});

/**
 * Retrieve transactions pertaining to an
 * address from the mempool or chain database.
 * @param {Address} addresses
 * @returns {Promise} - Returns {@link TX}[].
 */

Fullnode.prototype.getTXByAddress = co(function* getTXByAddress(addresses) {
  var mempool = this.mempool.getTXByAddress(addresses);
  var txs = yield this.chain.db.getTXByAddress(addresses);
  return mempool.concat(txs);
});

/**
 * Retrieve a transaction from the mempool or chain database.
 * @param {Hash} hash
 * @returns {Promise} - Returns {@link TX}.
 */

Fullnode.prototype.getTX = function getTX(hash) {
  var tx = this.mempool.getTX(hash);

  if (tx)
    return Promise.resolve(tx);

  return this.chain.db.getTX(hash);
};

/**
 * Test whether the mempool or chain contains a transaction.
 * @param {Hash} hash
 * @returns {Promise} - Returns Boolean.
 */

Fullnode.prototype.hasTX = function hasTX(hash) {
  if (this.mempool.hasTX(hash))
    return Promise.resolve(true);

  return this.chain.db.hasTX(hash);
};

/**
 * Check whether a coin has been spent.
 * @param {Hash} hash
 * @param {Number} index
 * @returns {Promise} - Returns Boolean.
 */

Fullnode.prototype.isSpent = function isSpent(hash, index) {
  if (this.mempool.isSpent(hash, index))
    return Promise.resolve(true);

  return this.chain.db.isSpent(hash, index);
};

/**
 * Fill a transaction with coins from the mempool
 * and chain database (unspent only).
 * @param {TX} tx
 * @returns {Promise} - Returns {@link TX}.
 */

Fullnode.prototype.fillCoins = function fillCoins(tx) {
  return this.mempool.fillAllCoins(tx);
};

/**
 * Fill a transaction with all historical coins
 * from the mempool and chain database.
 * @param {TX} tx
 * @returns {Promise} - Returns {@link TX}.
 */

Fullnode.prototype.fillHistory = function fillHistory(tx) {
  return this.mempool.fillAllHistory(tx);
};

/**
 * Return bitcoinj-style confidence for a transaction.
 * @param {Hash|TX} tx
 * @returns {Promise} - Returns {@link Confidence}.
 */

Fullnode.prototype.getConfidence = function getConfidence(tx) {
  return this.mempool.getConfidence(tx);
};

/*
 * Expose
 */

module.exports = Fullnode;
<commit_msg>fullnode: no resolution for walletdb.<commit_after>/*!
 * fullnode.js - full node for bcoin
 * Copyright (c) 2014-2015, Fedor Indutny (MIT License)
 * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
 * https://github.com/bcoin-org/bcoin
 */

'use strict';

var constants = require('../protocol/constants');
var utils = require('../utils/utils');
var co = require('../utils/co');
var Node = require('./node');
var Chain = require('../chain/chain');
var Fees = require('../mempool/fees');
var Mempool = require('../mempool/mempool');
var Pool = require('../net/pool');
var Miner = require('../miner/miner');
var WalletDB = require('../wallet/walletdb');
var HTTPServer;

try {
  HTTPServer = require('../http/server');
} catch (e) {
  ;
}

/**
 * Create a fullnode complete with a chain,
 * mempool, miner, wallet, etc.
 * @exports Fullnode
 * @extends Node
 * @constructor
 * @param {Object?} options
 * @param {Boolean?} options.limitFree
 * @param {Number?} options.limitFreeRelay
 * @param {Boolean?} options.requireStandard
 * @param {Boolean?} options.rejectInsaneFees
 * @param {Boolean?} options.replaceByFee
 * @param {Boolean?} options.selfish
 * @param {Base58Address?} options.payoutAddress
 * @param {String?} options.coinbaseFlags
 * @param {Buffer?} options.sslKey
 * @param {Buffer?} options.sslCert
 * @param {Number?} options.httpPort
 * @param {String?} options.httpHost
 * @param {Object?} options.wallet - Primary {@link Wallet} options.
 * @property {Boolean} loaded
 * @property {Chain} chain
 * @property {PolicyEstimator} fees
 * @property {Mempool} mempool
 * @property {Pool} pool
 * @property {Miner} miner
 * @property {WalletDB} walletdb
 * @property {HTTPServer} http
 * @emits Fullnode#block
 * @emits Fullnode#tx
 * @emits Fullnode#alert
 * @emits Fullnode#error
 */

function Fullnode(options) {
  if (!(this instanceof Fullnode))
    return new Fullnode(options);

  Node.call(this, options);

  // Instantiate blockchain.
  this.chain = new Chain({
    network: this.network,
    logger: this.logger,
    db: this.options.db,
    location: this.location('chain'),
    preload: false,
    spv: false,
    witness: this.options.witness,
    prune: this.options.prune,
    useCheckpoints: this.options.useCheckpoints,
    coinCache: this.options.coinCache,
    indexTX: this.options.indexTX,
    indexAddress: this.options.indexAddress,
    maxFiles: this.options.maxFiles
  });

  // Fee estimation.
  this.fees = new Fees(
    constants.tx.MIN_RELAY,
    this.network,
    this.logger);

  // Mempool needs access to the chain.
  this.mempool = new Mempool({
    network: this.network,
    logger: this.logger,
    chain: this.chain,
    fees: this.fees,
    limitFree: this.options.limitFree,
    limitFreeRelay: this.options.limitFreeRelay,
    requireStandard: this.options.requireStandard,
    rejectInsaneFees: this.options.rejectInsaneFees,
    replaceByFee: this.options.replaceByFee,
    indexAddress: this.options.indexAddress
  });

  // Pool needs access to the chain and mempool.
  this.pool = new Pool({
    network: this.network,
    logger: this.logger,
    chain: this.chain,
    mempool: this.mempool,
    witness: this.options.witness,
    selfish: this.options.selfish,
    headers: this.options.headers,
    compact: this.options.compact,
    bip151: this.options.bip151,
    bip150: this.options.bip150,
    authPeers: this.options.authPeers,
    knownPeers: this.options.knownPeers,
    identityKey: this.options.identityKey,
    maxPeers: this.options.maxPeers,
    maxLeeches: this.options.maxLeeches,
    proxyServer: this.options.proxyServer,
    preferredSeed: this.options.preferredSeed,
    ignoreDiscovery: this.options.ignoreDiscovery,
    port: this.options.port,
    listen: this.options.listen,
    spv: false
  });

  // Miner needs access to the chain and mempool.
  this.miner = new Miner({
    network: this.network,
    logger: this.logger,
    chain: this.chain,
    mempool: this.mempool,
    fees: this.fees,
    address: this.options.payoutAddress,
    coinbaseFlags: this.options.coinbaseFlags
  });

  // Wallet database needs access to fees.
  this.walletdb = new WalletDB({
    network: this.network,
    logger: this.logger,
    fees: this.fees,
    db: this.options.db,
    location: this.location('walletdb'),
    witness: this.options.witness,
    useCheckpoints: this.options.useCheckpoints,
    maxFiles: this.options.maxFiles,
    resolution: false,
    verify: false
  });

  // HTTP needs access to the node.
  if (!utils.isBrowser) {
    this.http = new HTTPServer({
      network: this.network,
      logger: this.logger,
      node: this,
      key: this.options.sslKey,
      cert: this.options.sslCert,
      port: this.options.httpPort || this.network.rpcPort,
      host: this.options.httpHost || '0.0.0.0',
      apiKey: this.options.apiKey,
      serviceKey: this.options.serviceKey,
      walletAuth: this.options.walletAuth,
      noAuth: this.options.noAuth
    });
  }

  this._init();
}

utils.inherits(Fullnode, Node);

/**
 * Initialize the node.
 * @private
 */

Fullnode.prototype._init = function _init() {
  var self = this;
  var onError = this._error.bind(this);

  // Bind to errors
  this.chain.on('error', onError);
  this.mempool.on('error', onError);
  this.pool.on('error', onError);
  this.miner.on('error', onError);
  this.walletdb.on('error', onError);

  if (this.http)
    this.http.on('error', onError);

  this.pool.on('alert', function(alert) {
    self.emit('alert', alert);
  });

  this.mempool.on('tx', function(tx) {
    self.emit('tx', tx);
    self.walletdb.addTX(tx).catch(onError);
    self.miner.notifyEntry();
  });

  this.chain.on('block', function(block) {
    self.emit('block', block);
  });

  this.chain.on('connect', function(entry, block) {
    self.walletdb.addBlock(entry, block.txs).catch(onError);

    if (self.chain.synced)
      self.mempool.addBlock(block).catch(onError);
  });

  this.chain.on('disconnect', function(entry, block) {
    self.walletdb.removeBlock(entry).catch(onError);

    if (self.chain.synced)
      self.mempool.removeBlock(block).catch(onError);
  });

  this.miner.on('block', function(block) {
    self.broadcast(block.toInv()).catch(onError);
  });

  this.walletdb.on('send', function(tx) {
    self.sendTX(tx).catch(onError);
  });
};

/**
 * Open the node and all its child objects,
 * wait for the database to load.
 * @alias Fullnode#open
 * @returns {Promise}
 */

Fullnode.prototype._open = co(function* open() {
  yield this.chain.open();
  yield this.mempool.open();
  yield this.miner.open();
  yield this.pool.open();
  yield this.walletdb.open();

  // Ensure primary wallet.
  yield this.openWallet();

  // Rescan for any missed transactions.
  yield this.rescan();

  // Rebroadcast pending transactions.
  yield this.resend();

  if (this.http)
    yield this.http.open();

  this.logger.info('Node is loaded.');
});

/**
 * Close the node, wait for the database to close.
 * @alias Fullnode#close
 * @returns {Promise}
 */

Fullnode.prototype._close = co(function* close() {
  if (this.http)
    yield this.http.close();

  yield this.wallet.destroy();

  this.wallet = null;

  yield this.walletdb.close();
  yield this.pool.close();
  yield this.miner.close();
  yield this.mempool.close();
  yield this.chain.close();

  this.logger.info('Node is closed.');
});

/**
 * Rescan for any missed transactions.
 * @returns {Promise}
 */

Fullnode.prototype.rescan = function rescan() {
  if (this.options.noScan) {
    return this.walletdb.setTip(
      this.chain.tip.hash,
      this.chain.height);
  }

  // Always rescan to make sure we didn't
  // miss anything: there is no atomicity
  // between the chaindb and walletdb.
  return this.scan();
};

/**
 * Rescan for any missed transactions.
 * @param {Number} height
 * @returns {Promise}
 */

Fullnode.prototype.scan = function scan(height) {
  return this.walletdb.rescan(this.chain.db, height);
};

/**
 * Broadcast a transaction (note that this will _not_ be verified
 * by the mempool - use with care, lest you get banned from
 * bitcoind nodes).
 * @param {TX|Block} item
 * @returns {Promise}
 */

Fullnode.prototype.broadcast = function broadcast(item, callback) {
  return this.pool.broadcast(item, callback);
};

/**
 * Verify a transaction, add it to the mempool, and broadcast.
 * Safer than {@link Fullnode#broadcast}.
 * @example
 * node.sendTX(tx, callback);
 * node.sendTX(tx, true, callback);
 * @param {TX} tx
 */

Fullnode.prototype.sendTX = co(function* sendTX(tx) {
  try {
    yield this.mempool.addTX(tx);
  } catch (err) {
    if (err.type === 'VerifyError') {
      this._error(err);
      this.logger.warning('Verification failed for tx: %s.', tx.rhash);
      this.logger.warning('Attempting to broadcast anyway...');
      yield this.pool.broadcast(tx);
      return;
    }
    throw err;
  }

  if (!this.options.selfish)
    tx = tx.toInv();

  yield this.pool.broadcast(tx);
});

/**
 * Listen on a server socket on
 * the p2p network (accepts leech peers).
 */

Fullnode.prototype.listen = function listen() {
  return this.pool.listen();
};

/**
 * Connect to the network.
 */

Fullnode.prototype.connect = function connect() {
  return this.pool.connect();
};

/**
 * Start the blockchain sync.
 */

Fullnode.prototype.startSync = function startSync() {
  return this.pool.startSync();
};

/**
 * Stop syncing the blockchain.
 */

Fullnode.prototype.stopSync = function stopSync() {
  return this.pool.stopSync();
};

/**
 * Retrieve a block from the chain database.
 * @param {Hash} hash
 * @returns {Promise} - Returns {@link Block}.
 */

Fullnode.prototype.getBlock = function getBlock(hash) {
  return this.chain.db.getBlock(hash);
};

/**
 * Retrieve a block from the chain database, filled with coins.
 * @param {Hash} hash
 * @returns {Promise} - Returns {@link Block}.
 */

Fullnode.prototype.getFullBlock = function getFullBlock(hash) {
  return this.chain.db.getFullBlock(hash);
};

/**
 * Retrieve a coin from the mempool or chain database.
 * Takes into account spent coins in the mempool.
 * @param {Hash} hash
 * @param {Number} index
 * @returns {Promise} - Returns {@link Coin}.
 */

Fullnode.prototype.getCoin = function getCoin(hash, index) {
  var coin = this.mempool.getCoin(hash, index);

  if (coin)
    return Promise.resolve(coin);

  if (this.mempool.isSpent(hash, index))
    return Promise.resolve();

  return this.chain.db.getCoin(hash, index);
};

/**
 * Get coins that pertain to an address from the mempool or chain database.
 * Takes into account spent coins in the mempool.
 * @param {Address} addresses
 * @returns {Promise} - Returns {@link Coin}[].
 */

Fullnode.prototype.getCoinsByAddress = co(function* getCoinsByAddress(addresses) {
  var coins = this.mempool.getCoinsByAddress(addresses);
  var i, blockCoins, coin, spent;

  blockCoins = yield this.chain.db.getCoinsByAddress(addresses);

  for (i = 0; i < blockCoins.length; i++) {
    coin = blockCoins[i];
    spent = this.mempool.isSpent(coin.hash, coin.index);

    if (!spent)
      coins.push(coin);
  }

  return coins;
});

/**
 * Retrieve transactions pertaining to an
 * address from the mempool or chain database.
 * @param {Address} addresses
 * @returns {Promise} - Returns {@link TX}[].
 */

Fullnode.prototype.getTXByAddress = co(function* getTXByAddress(addresses) {
  var mempool = this.mempool.getTXByAddress(addresses);
  var txs = yield this.chain.db.getTXByAddress(addresses);
  return mempool.concat(txs);
});

/**
 * Retrieve a transaction from the mempool or chain database.
 * @param {Hash} hash
 * @returns {Promise} - Returns {@link TX}.
 */

Fullnode.prototype.getTX = function getTX(hash) {
  var tx = this.mempool.getTX(hash);

  if (tx)
    return Promise.resolve(tx);

  return this.chain.db.getTX(hash);
};

/**
 * Test whether the mempool or chain contains a transaction.
 * @param {Hash} hash
 * @returns {Promise} - Returns Boolean.
 */

Fullnode.prototype.hasTX = function hasTX(hash) {
  if (this.mempool.hasTX(hash))
    return Promise.resolve(true);

  return this.chain.db.hasTX(hash);
};

/**
 * Check whether a coin has been spent.
 * @param {Hash} hash
 * @param {Number} index
 * @returns {Promise} - Returns Boolean.
 */

Fullnode.prototype.isSpent = function isSpent(hash, index) {
  if (this.mempool.isSpent(hash, index))
    return Promise.resolve(true);

  return this.chain.db.isSpent(hash, index);
};

/**
 * Fill a transaction with coins from the mempool
 * and chain database (unspent only).
 * @param {TX} tx
 * @returns {Promise} - Returns {@link TX}.
 */

Fullnode.prototype.fillCoins = function fillCoins(tx) {
  return this.mempool.fillAllCoins(tx);
};

/**
 * Fill a transaction with all historical coins
 * from the mempool and chain database.
 * @param {TX} tx
 * @returns {Promise} - Returns {@link TX}.
 */

Fullnode.prototype.fillHistory = function fillHistory(tx) {
  return this.mempool.fillAllHistory(tx);
};

/**
 * Return bitcoinj-style confidence for a transaction.
 * @param {Hash|TX} tx
 * @returns {Promise} - Returns {@link Confidence}.
 */

Fullnode.prototype.getConfidence = function getConfidence(tx) {
  return this.mempool.getConfidence(tx);
};

/*
 * Expose
 */

module.exports = Fullnode;
<|endoftext|>


<commit_before>import {
  getBufferFromHex,
  getSignTransactionObject,
  sanitizeHex,
  calculateChainIdFromV,
  eip1559Params
} from './helpers';
import {
  hashPersonalMessage,
  publicToAddress,
  bufferToHex,
  ecsign,
  isValidPrivate,
  isValidPublic,
  privateToPublic
} from 'ethereumjs-util';
import toBuffer from '@/core/helpers/toBuffer';
import commonGenerator from '@/core/helpers/commonGenerator';
import { Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx';
import { toChecksumAddress } from '@/core/helpers/addressUtils';
import store from '@/core/store';
class WalletInterface {
  constructor(key, isPub = false, identifier, nick, keystore) {
    this.nickname = nick !== null && nick !== '' ? nick : '';
    this.keystore = keystore !== null && keystore !== '' ? keystore : '';
    this.identifier = identifier;
    if (!isPub) {
      const _privKey = Buffer.isBuffer(key)
        ? key
        : getBufferFromHex(sanitizeHex(key));
      console.log(_privKey);
      if (_privKey.length !== 32) {
        throw new Error(
          'Private key does not satisfy the curve requirements (ie. it is invalid)'
        );
      } else {
        try {
          if (!isValidPrivate(_privKey))
            throw new Error(
              'Private key does not satisfy the curve requirements (ie. it is invalid)'
            );
        } catch (e) {
          throw new Error(
            'Private key does not satisfy the curve requirements (ie. it is invalid)'
          );
        }
      }
      this.privateKey = _privKey;
      this.publicKey = privateToPublic(_privKey);
      this.isPubOnly = false;
    } else {
      const _pubKey = Buffer.isBuffer(key) ? key : getBufferFromHex(key);
      if (_pubKey.length !== 20) {
        try {
          if (!isValidPublic(_pubKey, true))
            throw new Error('Invalid public key');
        } catch (e) {
          throw new Error('Invalid public key');
        }
      }
      if (_pubKey.length === 20) this.isAddress = true;
      this.publicKey = _pubKey;
      this.isPubOnly = true;
    }
    this.meta = {
      name: keystore ? 'Key store' : 'Private Key',
      img: {
        type: 'mew-icon',
        value: keystore ? 'keystore' : 'privateKey'
      }
    };
  }
  getPrivateKey() {
    if (this.isPubOnly) throw new Error('public key only wallet');
    return this.privateKey;
  }

  getPrivateKeyString() {
    if (this.isPubOnly) throw new Error('public key only wallet');
    return bufferToHex(this.getPrivateKey());
  }

  getNickname() {
    if (this.nickname === '') return '';
    return this.nickname;
  }

  getKeystore() {
    if (this.keystore === '') return '';
    return this.keystore;
  }

  getPublicKey() {
    if (this.isAddress) throw new Error('Address only wallet');
    return this.publicKey;
  }

  getPublicKeyString() {
    return bufferToHex(this.getPublicKey());
  }

  getAddress() {
    if (this.isAddress) return this.publicKey;
    return publicToAddress(this.publicKey, true);
  }

  getAddressString() {
    return bufferToHex(this.getAddress());
  }

  getChecksumAddressString() {
    return toChecksumAddress(this.getAddressString());
  }
  signTransaction(txParams, signer) {
    if (this.isPubOnly && typeof signer !== 'function')
      throw new Error('public key only wallets needs a signer');
    if (!this.isPubOnly) {
      return new Promise(resolve => {
        let tx = Transaction.fromTxData(txParams, {
          common: commonGenerator(store.getters['global/network'])
        });
        if (store.getters['global/isEIP1559SupportedNetwork']) {
          const feeMarket = store.getters['global/gasFeeMarketInfo'];
          const _txParams = Object.assign(
            eip1559Params(txParams.gasPrice, feeMarket),
            txParams
          );
          delete _txParams.gasPrice;
          tx = FeeMarketEIP1559Transaction.fromTxData(_txParams, {
            common: commonGenerator(store.getters['global/network'])
          });
        }
        const networkId = tx.common.chainId();
        tx = tx.sign(this.privateKey);
        const signedChainId = tx.chainId
          ? parseInt(tx.chainId.toString())
          : calculateChainIdFromV(tx.v);
        if (signedChainId !== networkId)
          throw new Error(
            'Invalid networkId signature returned. Expected: ' +
              networkId +
              ', Got: ' +
              signedChainId,
            'InvalidNetworkId'
          );
        resolve(getSignTransactionObject(tx));
      });
    }
    return signer(txParams);
  }
  signMessage(msg, signer) {
    if (this.isPubOnly && typeof signer !== 'function')
      throw new Error('public key only wallets needs a signer');
    return new Promise((resolve, reject) => {
      if (!this.isPubOnly) {
        const msgHash = hashPersonalMessage(toBuffer(msg));
        const signed = ecsign(msgHash, this.privateKey);
        resolve(
          Buffer.concat([
            Buffer.from(signed.r),
            Buffer.from(signed.s),
            Buffer.from([signed.v])
          ])
        );
      } else {
        signer(msg).then(resolve).catch(reject);
      }
    });
  }
}
export default WalletInterface;
<commit_msg>lint: 🗃 remove console log<commit_after>import {
  getBufferFromHex,
  getSignTransactionObject,
  sanitizeHex,
  calculateChainIdFromV,
  eip1559Params
} from './helpers';
import {
  hashPersonalMessage,
  publicToAddress,
  bufferToHex,
  ecsign,
  isValidPrivate,
  isValidPublic,
  privateToPublic
} from 'ethereumjs-util';
import toBuffer from '@/core/helpers/toBuffer';
import commonGenerator from '@/core/helpers/commonGenerator';
import { Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx';
import { toChecksumAddress } from '@/core/helpers/addressUtils';
import store from '@/core/store';
class WalletInterface {
  constructor(key, isPub = false, identifier, nick, keystore) {
    this.nickname = nick !== null && nick !== '' ? nick : '';
    this.keystore = keystore !== null && keystore !== '' ? keystore : '';
    this.identifier = identifier;
    if (!isPub) {
      const _privKey = Buffer.isBuffer(key)
        ? key
        : getBufferFromHex(sanitizeHex(key));
      if (_privKey.length !== 32) {
        throw new Error(
          'Private key does not satisfy the curve requirements (ie. it is invalid)'
        );
      } else {
        try {
          if (!isValidPrivate(_privKey))
            throw new Error(
              'Private key does not satisfy the curve requirements (ie. it is invalid)'
            );
        } catch (e) {
          throw new Error(
            'Private key does not satisfy the curve requirements (ie. it is invalid)'
          );
        }
      }
      this.privateKey = _privKey;
      this.publicKey = privateToPublic(_privKey);
      this.isPubOnly = false;
    } else {
      const _pubKey = Buffer.isBuffer(key) ? key : getBufferFromHex(key);
      if (_pubKey.length !== 20) {
        try {
          if (!isValidPublic(_pubKey, true))
            throw new Error('Invalid public key');
        } catch (e) {
          throw new Error('Invalid public key');
        }
      }
      if (_pubKey.length === 20) this.isAddress = true;
      this.publicKey = _pubKey;
      this.isPubOnly = true;
    }
    this.meta = {
      name: keystore ? 'Key store' : 'Private Key',
      img: {
        type: 'mew-icon',
        value: keystore ? 'keystore' : 'privateKey'
      }
    };
  }
  getPrivateKey() {
    if (this.isPubOnly) throw new Error('public key only wallet');
    return this.privateKey;
  }

  getPrivateKeyString() {
    if (this.isPubOnly) throw new Error('public key only wallet');
    return bufferToHex(this.getPrivateKey());
  }

  getNickname() {
    if (this.nickname === '') return '';
    return this.nickname;
  }

  getKeystore() {
    if (this.keystore === '') return '';
    return this.keystore;
  }

  getPublicKey() {
    if (this.isAddress) throw new Error('Address only wallet');
    return this.publicKey;
  }

  getPublicKeyString() {
    return bufferToHex(this.getPublicKey());
  }

  getAddress() {
    if (this.isAddress) return this.publicKey;
    return publicToAddress(this.publicKey, true);
  }

  getAddressString() {
    return bufferToHex(this.getAddress());
  }

  getChecksumAddressString() {
    return toChecksumAddress(this.getAddressString());
  }
  signTransaction(txParams, signer) {
    if (this.isPubOnly && typeof signer !== 'function')
      throw new Error('public key only wallets needs a signer');
    if (!this.isPubOnly) {
      return new Promise(resolve => {
        let tx = Transaction.fromTxData(txParams, {
          common: commonGenerator(store.getters['global/network'])
        });
        if (store.getters['global/isEIP1559SupportedNetwork']) {
          const feeMarket = store.getters['global/gasFeeMarketInfo'];
          const _txParams = Object.assign(
            eip1559Params(txParams.gasPrice, feeMarket),
            txParams
          );
          delete _txParams.gasPrice;
          tx = FeeMarketEIP1559Transaction.fromTxData(_txParams, {
            common: commonGenerator(store.getters['global/network'])
          });
        }
        const networkId = tx.common.chainId();
        tx = tx.sign(this.privateKey);
        const signedChainId = tx.chainId
          ? parseInt(tx.chainId.toString())
          : calculateChainIdFromV(tx.v);
        if (signedChainId !== networkId)
          throw new Error(
            'Invalid networkId signature returned. Expected: ' +
              networkId +
              ', Got: ' +
              signedChainId,
            'InvalidNetworkId'
          );
        resolve(getSignTransactionObject(tx));
      });
    }
    return signer(txParams);
  }
  signMessage(msg, signer) {
    if (this.isPubOnly && typeof signer !== 'function')
      throw new Error('public key only wallets needs a signer');
    return new Promise((resolve, reject) => {
      if (!this.isPubOnly) {
        const msgHash = hashPersonalMessage(toBuffer(msg));
        const signed = ecsign(msgHash, this.privateKey);
        resolve(
          Buffer.concat([
            Buffer.from(signed.r),
            Buffer.from(signed.s),
            Buffer.from([signed.v])
          ])
        );
      } else {
        signer(msg).then(resolve).catch(reject);
      }
    });
  }
}
export default WalletInterface;
<|endoftext|>


<commit_before>module.exports = function(window, options) {
  window.navigator = {
    userAgent: options.userAgent
  };
};
<commit_msg>Provide user agent failover value<commit_after>module.exports = function(window, options) {
  window.navigator = {
    userAgent: options.userAgent || ''
  };
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { View, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { Container, Content, Text, Left, Right, Body, Card, CardItem, ListItem, Separator } from 'native-base';
import { getPlatformValue } from '../utils';

const { height, width } = Dimensions.get('window');

export default class Points extends Component {

  constructor() {
    super();
    this.state = {
      CurrentPoints: 0,
    };
  }

  componentDidMount() {
    this.setPoints();
  }

  async setPoints() {
    try {
      const ref = this.props.Firebase.database().ref();
      const user = this.props.Firebase.auth().currentUser;
      const uid = user.uid;
      const userPointsRef = ref.child('userReadable/userPoints').child(uid);

      userPointsRef.once('value').then((snap) => {
        const points = snap.val().points;
        return points;
      })
      .then((points) => {
        this.setState({ CurrentPoints: points });
      });
    } catch (e) {
      console.log(e);
    }
  }

  _getBoard() {
    const ref = this.props.Firebase.database().ref();
    const userRef = ref.child('userPoints');
    const leaderBoard = [];

    userRef.orderByChild('points').once('value').then((snap) => {
      snap.forEach((snapshot) => {
        leaderBoard.push([snapshot.val().displayName, snapshot.val().points]);
      });
      return Promise.all(leaderBoard);
    })
      .then((leaderBoard) => {
        const newleaderBoard = leaderBoard.reverse();
        return newleaderBoard;
      })
      .then((newleaderBoard) => {
        const ranks = Object.keys(newleaderBoard);
        ranks.forEach((ranked) => {
          const name = newleaderBoard[ranked][0];
          const rank = +ranked + 1;
          console.log(name, `| Rank ${rank}`);
        });
      });
  }

  render() {
    return (
      <Container style={{ backgroundColor: 'black' }}>
        <View style={styles.header}>
          <TouchableOpacity>
            <Icon
              name="bars"
              size={30}
              color="white"
              onPress={this.props.sideMenu}
            />
          </TouchableOpacity>
          <Text
            style={{
              fontSize: 25,
              textAlign: 'center',
              width: 250,
              color: 'white',
              fontWeight: '300',
              marginBottom: 5,
            }}
          >
            POINTS
          </Text>
          <Icon name="diamond" size={20} color="#ffc107" />
        </View>
        <Card style={{ backgroundColor: 'black', borderWidth: 0 }}>
          <CardItem header style={{ backgroundColor: 'black', margin: 0 }}>
            <Text style={{ fontFamily: 'OpenSans', fontSize: 100, color: '#bdbdbd', fontFamily: 'OpenSans', fontWeight: '100' }}>{this.state.CurrentPoints}</Text>
            <Text style={{ fontFamily: 'OpenSans', color: '#ffc107' }}>Total Pts</Text>
          </CardItem>
          <CardItem footer style={{ borderTopWidth: 1, borderBottomWidth: 1, borderColor: '#ffc107', backgroundColor: '#212121', height: height * 0.197 }}>
            <Text style={{ fontFamily: 'OpenSans', color: '#bdbdbd', borderBottomWidth: 1, borderTopWidth: 1, borderColor: '#ffc107', fontSize: 25 }}>Todays Points</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white', fontSize: 40 }}>20 <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Pts</Text></Text>
            </Right>
          </CardItem>
        </Card>
        <Content>
          <ListItem>
            <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>+2 Pts</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Checking In</Text>
            </Right>
          </ListItem>
          <ListItem>
            <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>+10 Pts</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Under Budget</Text>
            </Right>
          </ListItem>
          <ListItem>
            <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>+5 Pts</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>New Goal</Text>
            </Right>
          </ListItem>
          <Separator bordered style={{ borderTopWidth: 1, borderBottomWidth: 1, borderColor: '#ffc107', backgroundColor: '#212121' }}>
            <Text style={{ fontFamily: 'OpenSans', fontSize: 20, textAlign: 'center', color: '#bdbdbd' }}>Ranking</Text>
          </Separator>
          <ListItem icon>
            <Left>
              <Icon name="certificate" />
            </Left>
            <Body>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Local Rank</Text>
            </Body>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>5 th</Text>
            </Right>
          </ListItem>
          <ListItem icon>
            <Left>
              <Icon name="certificate" color="#ffc107" />
            </Left>
            <Body>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>World Rank</Text>
            </Body>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>105 th</Text>
            </Right>
          </ListItem>
        </Content>
      </Container>
    );
  }
}

const styles = StyleSheet.create({
  totalPoints: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 60,
  },
  red: {
    color: 'red',
  },
  headline: {
    fontWeight: 'bold',
    fontSize: 18,
    marginTop: 0,
    width: 200,
    textAlign: 'center',
    backgroundColor: 'yellow',
  },
  header: {
    paddingTop: getPlatformValue('android', 25, 20),
    flex: 0,
    flexDirection: 'row',
    height: 60,
    backgroundColor: 'black',
    justifyContent: 'space-around',
    alignItems: 'center',
    borderBottomWidth: 1,
    borderColor: '#424242',
  },
});
<commit_msg>User is now given a local rank based on amount of total points amongst all users that is displayed on points page.<commit_after>import React, { Component } from 'react';
import { View, StyleSheet, TouchableOpacity, Dimensions } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { Container, Content, Text, Left, Right, Body, Card, CardItem, ListItem, Separator } from 'native-base';
import { getPlatformValue } from '../utils';

const { height, width } = Dimensions.get('window');

export default class Points extends Component {

  constructor() {
    super();
    this.state = {
      userRank: 0,
      CurrentPoints: 0,
    };
  }

  componentDidMount() {
    this.setPoints();
    this._getBoard();
  }

  async setPoints() {
    try {
      const ref = this.props.Firebase.database().ref();
      const user = this.props.Firebase.auth().currentUser;
      const uid = user.uid;
      const userPointsRef = ref.child('userReadable/userPoints').child(uid);

      userPointsRef.once('value').then((snap) => {
        const points = snap.val().points;
        return points;
      })
      .then((points) => {
        this.setState({ CurrentPoints: points });
      });
    } catch (e) {
      console.log(e);
    }
  }

  async _getBoard() {
    try {
      const ref = this.props.Firebase.database().ref();
      const user = this.props.Firebase.auth().currentUser;
      const userRankingRef = ref.child('userReadable/userPoints');
      const leaderBoard = [];

      userRankingRef.orderByChild('points').once('value').then((snap) => {
        snap.forEach((snapshot) => {
          leaderBoard.push([snapshot.val().displayName, snapshot.val().points]);
        });
        return Promise.all(leaderBoard);
      })
      .then((leaderBoard) => {
        const newleaderBoard = leaderBoard.reverse();
        return newleaderBoard;
      })
      .then((newleaderBoard) => {
        const rankings = [];
        const ranks = Object.keys(newleaderBoard);
        ranks.forEach((ranked) => {
          const name = newleaderBoard[ranked][0];
          const rank = +ranked + 1;
          rankings.push([name, `${rank}`]);
        });
        return rankings;
      })
      .then((rankings) => {
        rankings.forEach((Rank) => {
          if (Rank[0] === user.displayName) {
            this.setState({ userRank: Rank[1] });
          }
        });
      });
    } catch (e) {
      console.log(e);
    }
  }

  render() {
    return (
      <Container style={{ backgroundColor: 'black' }}>
        <View style={styles.header}>
          <TouchableOpacity>
            <Icon
              name="bars"
              size={30}
              color="white"
              onPress={this.props.sideMenu}
            />
          </TouchableOpacity>
          <Text
            style={{
              fontSize: 25,
              textAlign: 'center',
              width: 250,
              color: 'white',
              fontWeight: '300',
              marginBottom: 5,
            }}
          >
            POINTS
          </Text>
          <Icon name="diamond" size={20} color="#ffc107" />
        </View>
        <Card style={{ backgroundColor: 'black', borderWidth: 0 }}>
          <CardItem header style={{ backgroundColor: 'black', margin: 0 }}>
            <Text style={{ fontFamily: 'OpenSans', fontSize: 100, color: '#bdbdbd', fontFamily: 'OpenSans', fontWeight: '100' }}>{this.state.CurrentPoints}</Text>
            <Text style={{ fontFamily: 'OpenSans', color: '#ffc107' }}>Total Pts</Text>
          </CardItem>
          <CardItem footer style={{ borderTopWidth: 1, borderBottomWidth: 1, borderColor: '#ffc107', backgroundColor: '#212121', height: height * 0.197 }}>
            <Text style={{ fontFamily: 'OpenSans', color: '#bdbdbd', borderBottomWidth: 1, borderTopWidth: 1, borderColor: '#ffc107', fontSize: 25 }}>Todays Points</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white', fontSize: 40 }}>20 <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Pts</Text></Text>
            </Right>
          </CardItem>
        </Card>
        <Content>
          <ListItem>
            <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>+2 Pts</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Checking In</Text>
            </Right>
          </ListItem>
          <ListItem>
            <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>+10 Pts</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Under Budget</Text>
            </Right>
          </ListItem>
          <ListItem>
            <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>+5 Pts</Text>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>New Goal</Text>
            </Right>
          </ListItem>
          <Separator bordered style={{ borderTopWidth: 1, borderBottomWidth: 1, borderColor: '#ffc107', backgroundColor: '#212121' }}>
            <Text style={{ fontFamily: 'OpenSans', fontSize: 20, textAlign: 'center', color: '#bdbdbd' }}>Ranking</Text>
          </Separator>
          <ListItem icon>
            <Left>
              <Icon name="certificate" />
            </Left>
            <Body>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>Local Rank</Text>
            </Body>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}> {this.state.userRank}th </Text>
            </Right>
          </ListItem>
          <ListItem icon>
            <Left>
              <Icon name="certificate" color="#ffc107" />
            </Left>
            <Body>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>World Rank</Text>
            </Body>
            <Right>
              <Text style={{ fontFamily: 'OpenSans', color: 'white' }}>105 th</Text>
            </Right>
          </ListItem>
        </Content>
      </Container>
    );
  }
}

const styles = StyleSheet.create({
  totalPoints: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 60,
  },
  red: {
    color: 'red',
  },
  headline: {
    fontWeight: 'bold',
    fontSize: 18,
    marginTop: 0,
    width: 200,
    textAlign: 'center',
    backgroundColor: 'yellow',
  },
  header: {
    paddingTop: getPlatformValue('android', 25, 20),
    flex: 0,
    flexDirection: 'row',
    height: 60,
    backgroundColor: 'black',
    justifyContent: 'space-around',
    alignItems: 'center',
    borderBottomWidth: 1,
    borderColor: '#424242',
  },
});
<|endoftext|>


<commit_before>var _ = require('lodash');
var AWS = require('aws-sdk');
var events = require('events');
var moment = require('moment');
var dateRange = require('moment-range');
var path = require('path');
var async = require('async');
var util = require('util');

var Uploader = require('s3-streaming-upload').Uploader;

var ReadableStream = require('./readable-stream');

function DynamoBackup(options) {
    options = options || {};
    this.excludedTables = options.excludedTables || [];
    this.includedTables = options.includedTables;
    this.readPercentage = options.readPercentage || .25;
    this.backupPath = options.backupPath;
    this.bucket = options.bucket;
    this.stopOnFailure = options.stopOnFailure || false;
    this.base64Binary = options.base64Binary || false;
    this.saveDataPipelineFormat = options.saveDataPipelineFormat || false;
    this.awsAccessKey = options.awsAccessKey || process.env.AWS_ACCESS_KEY_ID;
    this.awsSecretKey = options.awsSecretKey || process.env.AWS_SECRET_ACCESS_KEY;
    this.awsRegion = options.awsRegion || process.env.AWS_DEFAULT_REGION || 'us-east-1';
    this.debug = Boolean(options.debug);

    AWS.config.update({
        accessKeyId: this.awsAccessKey,
        secretAccessKey: this.secretAccessKey,
        region: this.awsRegion
    });
}

util.inherits(DynamoBackup, events.EventEmitter);

DynamoBackup.prototype.listTables = function (callback) {
    var self = this;
    self._fetchTables(null, [], callback);
}

DynamoBackup.prototype.backupTable = function (tableName, backupPath, callback) {
    var self = this;
    var stream = new ReadableStream();

    if (callback === undefined) {
        callback = backupPath;
        backupPath = self._getBackupPath();
    }

    var upload = new Uploader({
        accessKey: self.awsAccessKey,
        secretKey: self.awsSecretKey,
        region: self.awsRegion,
        bucket: self.bucket,
        objectName: path.join(backupPath, tableName + '.json'),
        stream: stream,
        debug: self.debug
    });

    var startTime = moment.utc();
    self.emit('start-backup', tableName, startTime);
    upload.send(function (err) {
        if (err) {
            self.emit('error', {
                table: tableName,
                err: err
            });
        }
        var endTime = moment.utc();
        var backupDuration = new dateRange(startTime, endTime);
        self.emit('end-backup', tableName, backupDuration);
        return callback(err);
    });

    self._copyTable(
        tableName,
        function (items) {
            items.forEach(function (item) {
                if (self.base64Binary) {
                    _.each(item, function (value, key) {
                        if (value && value.B) {
                            value.B = new Buffer(value.B).toString('base64');
                        }
                    });
                }

                if (self.saveDataPipelineFormat) {
                    stream.append(self._formatForDataPipeline(item));
                } else {
                    stream.append(JSON.stringify(item));
                }
                stream.append('\n');
            });
        },
        function (err) {
            stream.end();
            if (err) {
                self.emit('error', {
                    table: tableName,
                    err: err
                });
            }
        }
        );
}

DynamoBackup.prototype.backupAllTables = function (callback) {
    var self = this;
    var backupPath = self._getBackupPath();

    self.listTables(function (err, tables) {
        if (err) {
            return callback(err);
        }
        var includedTables = self.includedTables || tables;
        tables = _.difference(tables, self.excludedTables);
        tables = _.intersection(tables, includedTables);

        async.each(tables,
            function (tableName, done) {
                self.backupTable(tableName, backupPath, function (err) {
                    if (err) {
                        if (self.stopOnFailure) {
                            return done(err);
                        }
                    }
                    done();
                })
            },
            callback
            );
    });
}

DynamoBackup.prototype._getBackupPath = function () {
    var self = this;
    var now = moment.utc();
    return self.backupPath || ('DynamoDB-backup-' + now.format('YYYY-MM-DD-HH-mm-ss'));
}

DynamoBackup.prototype._copyTable = function (tableName, itemsReceived, callback) {
    var self = this;
    var ddb = new AWS.DynamoDB();
    ddb.describeTable({ TableName: tableName }, function (err, data) {
        if (err) {
            return callback(err);
        }

        var readPercentage = self.readPercentage;
        var limit = Math.max((data.Table.ProvisionedThroughput.ReadCapacityUnits * readPercentage) | 0, 1);

        self._streamItems(tableName, null, limit, itemsReceived, callback);
    });
}

DynamoBackup.prototype._streamItems = function fetchItems(tableName, startKey, limit, itemsReceived, callback) {
    var self = this;
    var ddb = new AWS.DynamoDB();
    var params = {
        Limit: limit,
        ReturnConsumedCapacity: 'NONE',
        TableName: tableName
    };
    if (startKey) {
        params.ExclusiveStartKey = startKey;
    }
    ddb.scan(params, function (err, data) {
        if (err) {
            return callback(err);
        }

        if (data.Items.length > 0) {
            itemsReceived(data.Items);
        }

        if (!data.LastEvaluatedKey || _.keys(data.LastEvaluatedKey).length === 0) {
            return callback();
        }
        self._streamItems(tableName, data.LastEvaluatedKey, limit, itemsReceived, callback);
    });
}

DynamoBackup.prototype._fetchTables = function (lastTable, tables, callback) {
    var self = this;
    var ddb = new AWS.DynamoDB();
    var params = {};
    if (lastTable) {
        params.ExclusiveStartTableName = lastTable;
    }
    ddb.listTables(params, function (err, data) {
        if (err) {
            return callback(err, null);
        }
        tables = tables.concat(data.TableNames);
        if (data.LastEvaluatedTableName) {
            self._fetchTables(data.LastEvaluatedTableName, tables, callback);
        } else {
            callback(null, tables);
        }
    });
};

/**
 * AWS Data Pipeline import requires that each key in the Attribute list
 * be lower-cased and for sets start with a lower-case character followed
 * by an 'S'.
 *
 * Go through each attribute and create a new entry with the correct case
 */
DynamoBackup.prototype._formatForDataPipeline = function (item) {
    var self = this;
    _.each(item, function (value, key) {
        //value will be of the form: {S: 'xxx'}. Convert the key
        _.each(value, function (v, k) {
            var dataPipelineValueKey = self._getDataPipelineAttributeValueKey(k);
            value[dataPipelineValueKey] = v;
            value[k] = undefined;
        });
    });
    return JSON.stringify(item);
};

DynamoBackup.prototype._getDataPipelineAttributeValueKey = function (type) {
    switch (type) {
        case 'S':
        case 'N':
        case 'B':
        case 'M':
        case 'L':
        case 'NULL':
        case 'BOOL':
            return type.toLowerCase();
        case 'SS':
            return 'sS';
        case 'NS':
            return 'nS';
        case 'BS':
            return 'bS';
        default:
            throw new Error('Unknown AttributeValue key: ' + type);
    }
}

module.exports = DynamoBackup;<commit_msg>fixed access issue from lambda via IAM role temp creds<commit_after>var _ = require('lodash');
var AWS = require('aws-sdk');
var events = require('events');
var moment = require('moment');
var dateRange = require('moment-range');
var path = require('path');
var async = require('async');
var util = require('util');

var Uploader = require('s3-streaming-upload').Uploader;

var ReadableStream = require('./readable-stream');

function DynamoBackup(options) {
    options = options || {};
    this.excludedTables = options.excludedTables || [];
    this.includedTables = options.includedTables;
    this.readPercentage = options.readPercentage || .25;
    this.backupPath = options.backupPath;
    this.bucket = options.bucket;
    this.stopOnFailure = options.stopOnFailure || false;
    this.base64Binary = options.base64Binary || false;
    this.saveDataPipelineFormat = options.saveDataPipelineFormat || false;
    this.awsAccessKey = options.awsAccessKey || process.env.AWS_ACCESS_KEY_ID;
    this.awsSecretKey = options.awsSecretKey || process.env.AWS_SECRET_ACCESS_KEY;
    this.awsRegion = options.awsRegion || process.env.AWS_DEFAULT_REGION || 'us-east-1';
    this.debug = Boolean(options.debug);

    // ensure that temporary credentials from IAM role don't get
    // passed in as user access key without session token
    if (this.awsAccessKey !== undefined &&
        this.awsAccessKey.lastIndexOf('AKIA', 0) === 0) {
        AWS.config.update({
            accessKeyId: this.awsAccessKey,
            secretAccessKey: this.secretAccessKey,
            region: this.awsRegion
        });
    }
}

util.inherits(DynamoBackup, events.EventEmitter);

DynamoBackup.prototype.listTables = function (callback) {
    var self = this;
    self._fetchTables(null, [], callback);
}

DynamoBackup.prototype.backupTable = function (tableName, backupPath, callback) {
    var self = this;
    var stream = new ReadableStream();

    if (callback === undefined) {
        callback = backupPath;
        backupPath = self._getBackupPath();
    }

    var uploaderParams = {
        bucket: self.bucket,
        objectName: path.join(backupPath, tableName + '.json'),
        stream: stream,
        debug: self.debug
    }

    if (self.awsAccessKey !== undefined &&
        self.awsAccessKey.lastIndexOf('AKIA', 0) === 0) {
        uploaderParams.accessKey = self.awsAccessKey;
        uploaderParams.secretKey = self.awsSecretKey;
        uploaderParams.region = self.awsRegion;
    }

    var upload = new Uploader(uploaderParams);

    var startTime = moment.utc();
    self.emit('start-backup', tableName, startTime);
    upload.send(function (err) {
        if (err) {
            self.emit('error', {
                table: tableName,
                err: err
            });
        }
        var endTime = moment.utc();
        var backupDuration = new dateRange(startTime, endTime);
        self.emit('end-backup', tableName, backupDuration);
        return callback(err);
    });

    self._copyTable(
        tableName,
        function (items) {
            items.forEach(function (item) {
                if (self.base64Binary) {
                    _.each(item, function (value, key) {
                        if (value && value.B) {
                            value.B = new Buffer(value.B).toString('base64');
                        }
                    });
                }

                if (self.saveDataPipelineFormat) {
                    stream.append(self._formatForDataPipeline(item));
                } else {
                    stream.append(JSON.stringify(item));
                }
                stream.append('\n');
            });
        },
        function (err) {
            stream.end();
            if (err) {
                self.emit('error', {
                    table: tableName,
                    err: err
                });
            }
        }
        );
}

DynamoBackup.prototype.backupAllTables = function (callback) {
    var self = this;
    var backupPath = self._getBackupPath();

    self.listTables(function (err, tables) {
        if (err) {
            return callback(err);
        }
        var includedTables = self.includedTables || tables;
        tables = _.difference(tables, self.excludedTables);
        tables = _.intersection(tables, includedTables);

        async.each(tables,
            function (tableName, done) {
                self.backupTable(tableName, backupPath, function (err) {
                    if (err) {
                        if (self.stopOnFailure) {
                            return done(err);
                        }
                    }
                    done();
                })
            },
            callback
            );
    });
}

DynamoBackup.prototype._getBackupPath = function () {
    var self = this;
    var now = moment.utc();
    return self.backupPath || ('DynamoDB-backup-' + now.format('YYYY-MM-DD-HH-mm-ss'));
}

DynamoBackup.prototype._copyTable = function (tableName, itemsReceived, callback) {
    var self = this;
    var ddb = new AWS.DynamoDB();
    ddb.describeTable({ TableName: tableName }, function (err, data) {
        if (err) {
            return callback(err);
        }

        var readPercentage = self.readPercentage;
        var limit = Math.max((data.Table.ProvisionedThroughput.ReadCapacityUnits * readPercentage) | 0, 1);

        self._streamItems(tableName, null, limit, itemsReceived, callback);
    });
}

DynamoBackup.prototype._streamItems = function fetchItems(tableName, startKey, limit, itemsReceived, callback) {
    var self = this;
    var ddb = new AWS.DynamoDB();
    var params = {
        Limit: limit,
        ReturnConsumedCapacity: 'NONE',
        TableName: tableName
    };
    if (startKey) {
        params.ExclusiveStartKey = startKey;
    }
    ddb.scan(params, function (err, data) {
        if (err) {
            return callback(err);
        }

        if (data.Items.length > 0) {
            itemsReceived(data.Items);
        }

        if (!data.LastEvaluatedKey || _.keys(data.LastEvaluatedKey).length === 0) {
            return callback();
        }
        self._streamItems(tableName, data.LastEvaluatedKey, limit, itemsReceived, callback);
    });
}

DynamoBackup.prototype._fetchTables = function (lastTable, tables, callback) {
    var self = this;
    var ddb = new AWS.DynamoDB();
    var params = {};
    if (lastTable) {
        params.ExclusiveStartTableName = lastTable;
    }
    ddb.listTables(params, function (err, data) {
        if (err) {
            return callback(err, null);
        }
        tables = tables.concat(data.TableNames);
        if (data.LastEvaluatedTableName) {
            self._fetchTables(data.LastEvaluatedTableName, tables, callback);
        } else {
            callback(null, tables);
        }
    });
};

/**
 * AWS Data Pipeline import requires that each key in the Attribute list
 * be lower-cased and for sets start with a lower-case character followed
 * by an 'S'.
 *
 * Go through each attribute and create a new entry with the correct case
 */
DynamoBackup.prototype._formatForDataPipeline = function (item) {
    var self = this;
    _.each(item, function (value, key) {
        //value will be of the form: {S: 'xxx'}. Convert the key
        _.each(value, function (v, k) {
            var dataPipelineValueKey = self._getDataPipelineAttributeValueKey(k);
            value[dataPipelineValueKey] = v;
            value[k] = undefined;
        });
    });
    return JSON.stringify(item);
};

DynamoBackup.prototype._getDataPipelineAttributeValueKey = function (type) {
    switch (type) {
        case 'S':
        case 'N':
        case 'B':
        case 'M':
        case 'L':
        case 'NULL':
        case 'BOOL':
            return type.toLowerCase();
        case 'SS':
            return 'sS';
        case 'NS':
            return 'nS';
        case 'BS':
            return 'bS';
        default:
            throw new Error('Unknown AttributeValue key: ' + type);
    }
}

module.exports = DynamoBackup;<|endoftext|>


<commit_before>const controller = require("./controller");
const escodegen = require("escodegen");
const esprima = require("esprima");
const fs = require("fs");
const iconv = require("iconv-lite");
const path = require("path");
const {VM} = require("vm2");
const argv = require("./argv.js");

const filename = process.argv[2];

console.log(`Analyzing ${filename}`);
const sample_buffer = fs.readFileSync(filename);
let encoding;
if (argv.encoding) {
	console.log("Using argv encoding");
	encoding = argv.encoding;
} else {
	console.log("Using detected encoding");
	encoding = require("jschardet").detect(sample_buffer).encoding;
	if (encoding === null) encoding = "utf8";
	console.log(`The file seems to be encoded with ${encoding}.`);
}
const sample_source = iconv.decode(sample_buffer, encoding);
let code = fs.readFileSync(path.join(__dirname, "patch.js"), "utf8") + sample_source;

if (code.match("<job") || code.match("<script")) { // The sample may actually be a .wsf, which is <job><script>..</script><script>..</script></job>.
	code = code.replace(/<\??\/?\w+( .*)*\??>/g, ""); // XML tags
	code = code.replace(/<!\[CDATA\[/g, "");
	code = code.replace(/\]\]>/g, "");
}

function rewrite(code) {
	if (code.match("@cc_on")) {
		if (!argv["no-cc_on-rewrite"]) {
			console.log("Replacing @cc_on statements (use --no-cc_on-rewrite to skip)...")
			code = code.replace(/\/\*@cc_on/g, "");
			code = code.replace(/@\*\//g, "");
		} else {
			console.log(
				`The code appears to contain conditional compilation statements.
If you run into unexpected results, try uncommenting lines that look like

    /*@cc_on
    <JavaScript code>
    @*/

`
			);
		}
	}

	if (!argv["no-rewrite"]) {
		console.log("Rewriting code...");
		if (argv["dumb-concat-simplify"]) {
			console.log("Applying dumb concat simplification (remove --dumb-concat-simplify to skip)...")
			code = code.replace(/'[ \r\n]*\+[ \r\n]*'/gm, "");
			code = code.replace(/"[ \r\n]*\+[ \r\n]*"/gm, "");
		}

		if (!argv["no-rewrite-prototype"]) {
			console.log("Replacing `function A.prototype.B()` (use --no-rewrite-prototype to skip)...")
			// Replace `function X.prototype.y()` with `X.prototype.y = function()`
			code = code.replace(/function (\w+)\.prototype\.(\w+)/gm, "$1.prototype.$2 = function");
			console.log(code);
		}

		let tree;
		try {
			tree = esprima.parse(code);
		} catch (e) {
			console.log(e);
			console.log("");
			if (filename.match(/jse$/)) {
				console.log(
					`This appears to be a JSE (JScript.Encode) file.
Please compile the decoder and decode it first:

cc decoder.c -o decoder
./decoder ${filename} ${filename.replace(/jse$/, "js")}

`
				);
			} else {
				console.log(
					`This doesn't seem to be a JavaScript/WScript file.
If this is a JSE file (JScript.Encode), compile
decoder.c and run it on the file, like this:

cc decoder.c -o decoder
./decoder ${filename} ${filename}.js

`
				);
			}
			process.exit(-1);
			return;
		}

		if (!argv["no-concat-simplify"]) {
			console.log("Simplifying concatenations (use --no-concat-simplify to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "BinaryExpression") return;
				if (val.operator !== "+") return;
				if (val.left.type !== "Literal") return;
				if (val.right.type !== "Literal") return;
				const result = val.left.value + val.right.value;
				return {
					type: "Literal",
					value: result,
					raw: JSON.stringify(result),
				};
			});
		}

		if (argv["function-rewrite"]) {
			console.log("Rewriting functions (remove --function-rewrite to skip)...")
			traverse(tree, function(key, val) {
				if (key !== "callee") return;
				if (val.autogenerated) return;
				switch (val.type) {
					case "MemberExpression":
						return require("./patches/this.js")(val.object, val);
					default:
						return require("./patches/nothis.js")(val);
				}
			});
		}

		if (!argv["no-typeof-rewrite"]) {
			console.log("Rewriting typeof calls (use --no-typeof-rewrite to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "UnaryExpression") return;
				if (val.operator !== "typeof") return;
				if (val.autogenerated) return;
				return require("./patches/typeof.js")(val.argument);
			});
		}

		if (!argv["no-eval-rewrite"]) {
			console.log("Rewriting eval calls (use --no-eval-rewrite to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "CallExpression") return;
				if (val.callee.type !== "Identifier") return;
				if (val.callee.name !== "eval") return;
				return require("./patches/eval.js")(val.arguments);
			});
		}

		if (!argv["no-catch-rewrite"]) { // JScript quirk
			console.log("Rewriting try/catch statements (use --no-catch-rewrite to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "TryStatement") return;
				if (!val.handler) return;
				if (val.autogenerated) return;
				return require("./patches/catch.js")(val);
			});
		}

		// Replace (a !== b) with (false)
		if (argv["experimental-neq"]) {
			console.log("Rewriting `a !== b` (remove --experimental-neq to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "BinaryExpression") return;
				if (val.operator !== "!=" && val.operator !== "!==") return;
				return {
					type: "Literal",
					value: false,
					raw: "false",
				};
			});
		}
		// console.log(JSON.stringify(tree, null, "\t"));
		code = escodegen.generate(tree);

		// The modifications may have resulted in more concatenations, eg. "a" + ("foo", "b") + "c" -> "a" + "b" + "c"
		if (argv["dumb-concat-simplify"]) {
			console.log("Simplifying dumb concatenations (remove --dumb-concat-simplify to skip)...")
			code = code.replace(/'[ \r\n]*\+[ \r\n]*'/gm, "");
			code = code.replace(/"[ \r\n]*\+[ \r\n]*"/gm, "");
		}

		console.log("Rewritten successfully.")
	}
	console.log(code);
	return code;
}
code = rewrite(code);
controller.logJS(code);

Array.prototype.Count = function() {
	return this.length;
};

const sandbox = {
	ActiveXObject,
	alert: (x) => {},
	console: {
		log: (x) => console.log(JSON.stringify(x)),
	},
	Enumerator: require("./emulator/Enumerator"),
	GetObject: require("./emulator/WMI").GetObject,
	JSON,
	location: new Proxy({
		href: "http://www.foobar.com/",
		protocol: "http:",
		host: "www.foobar.com",
		hostname: "www.foobar.com",
	}, {
		get: function(target, name) {
			switch (name) {
				case Symbol.toPrimitive:
					return () => "http://www.foobar.com/";
				default:
					return target[name.toLowerCase()];
			}
		},
	}),
	parse: (x) => {},
	rewrite: (code) => rewrite(controller.logJS(code)),
	ScriptEngine: () => {
		const type = "JScript"; // or "JavaScript", or "VBScript"
		console.log(`Notice: emulating a ${type} engine (in ScriptEngine)`);
		return type;
	},
	_typeof: (x) => x.typeof ? x.typeof : typeof x,
	WScript: new Proxy({}, {
		get: function(target, name) {
			if (typeof name === "string") name = name.toLowerCase();
			switch (name) {
				case Symbol.toPrimitive:
					return () => "Windows Script Host";
				case "tostring":
					return "Windows Script Host";

				case "arguments":
					return new Proxy((n) => `${n}th argument`, {
						get: function(target, name) {
							switch (name) {
								case "Unnamed":
									return [];
								case "length":
									return 0;
								case "ShowUsage":
									return {
										typeof: "unknown",
									};
								case "Named":
									return [];
								default:
									return new Proxy(
										target[name],
										{
											get: (target, name) => name.toLowerCase() === "typeof" ? "unknown" : target[name],
										}
									);
							}
						},
					});
				case "createobject":
					return ActiveXObject;
				case "echo":
					if (argv["no-echo"])
						return () => {};
					return (x) => {
						console.log("Script wrote:", x);
						console.log("Add flag --no-echo to disable this.");
					};
				case "path":
					return "C:\\TestFolder\\";
				case "sleep":
					// return x => console.log(`Sleeping for ${x} ms...`)
					return (x) => {};
				case "stdin":
					return new Proxy({
						atendofstream: {
							typeof: "unknown",
						},
						line: 1,
						writeline: (text) => {
							if (argv["no-echo"]) return;
							console.log("Script wrote:", text);
							console.log("Add flag --no-echo to disable this.");
						},
					}, {
						get: function(target, name) {
							name = name.toLowerCase();
							if (!(name in target))
								controller.kill(`WScript.StdIn.${name} not implemented!`);
							return target[name];
						},
					});
				case "quit":
					return () => {};
				case "scriptfullname":
					return "(ScriptFullName)";
				case "scriptname":
					return "sample.js";
				default:
					controller.kill(`WScript.${name} not implemented!`);
			}
		},
	}),
	WSH: "Windows Script Host",
};

const vm = new VM({
	timeout: (argv.timeout || 10) * 1000,
	sandbox,
});

vm.run(code);

function ActiveXObject(name) {
	console.log(`New ActiveXObject: ${name}`);
	name = name.toLowerCase();
	if (name.match("winhttprequest"))
		return require("./emulator/XMLHTTP")();
	if (name.match("xmlhttp"))
		return require("./emulator/XMLHTTP")();
	if (name.match("dom")) {
		return {
			createElement: require("./emulator/DOM"),
			load: (filename) => {
				// console.log(`Loading ${filename} in a virtual DOM environment...`);
			},
		};
	}

	switch (name) {
		case "adodb.stream":
			return require("./emulator/ADODBStream")();
		case "adodb.recordset":
			return require("./emulator/ADODBRecordSet")();
		case "scriptcontrol":
			return require("./emulator/ScriptControl")();
		case "scripting.filesystemobject":
			return require("./emulator/FileSystemObject")();
		case "scripting.dictionary":
			return require("./emulator/Dictionary")();
		case "shell.application":
			return require("./emulator/ShellApplication")();
		case "wscript.network":
			return require("./emulator/WScriptNetwork")();
		case "wscript.shell":
			return require("./emulator/WScriptShell")();
		case "wbemscripting.swbemlocator":
			return require("./emulator/WBEMScriptingSWBEMLocator")();
		default:
			controller.kill(`Unknown ActiveXObject ${name}`);
			break;
	}
}

function traverse(obj, func) {
	const keys = Object.keys(obj);
	for (let i = 0; i < keys.length; i++) {
		const key = keys[i];
		const replacement = func.apply(this, [key, obj[key]]);
		if (replacement) obj[key] = replacement;
		if (obj.autogenerated) continue;
		if (obj[key] !== null && typeof obj[key] === "object")
			traverse(obj[key], func);
	}
}
<commit_msg>Fix XML parsing code (possibly for the last time?)<commit_after>const controller = require("./controller");
const escodegen = require("escodegen");
const esprima = require("esprima");
const fs = require("fs");
const iconv = require("iconv-lite");
const path = require("path");
const {VM} = require("vm2");
const argv = require("./argv.js");

const filename = process.argv[2];

console.log(`Analyzing ${filename}`);
const sample_buffer = fs.readFileSync(filename);
let encoding;
if (argv.encoding) {
	console.log("Using argv encoding");
	encoding = argv.encoding;
} else {
	console.log("Using detected encoding");
	encoding = require("jschardet").detect(sample_buffer).encoding;
	if (encoding === null) encoding = "utf8";
	console.log(`The file seems to be encoded with ${encoding}.`);
}
const sample_source = iconv.decode(sample_buffer, encoding);
let code = fs.readFileSync(path.join(__dirname, "patch.js"), "utf8") + sample_source;

if (code.match("<job") || code.match("<script")) { // The sample may actually be a .wsf, which is <job><script>..</script><script>..</script></job>.
	code = code.replace(/<\??\/?\w+( [\w=\"\']*)*\??>/g, ""); // XML tags
	code = code.replace(/<!\[CDATA\[/g, "");
	code = code.replace(/\]\]>/g, "");
}

function rewrite(code) {
	if (code.match("@cc_on")) {
		if (!argv["no-cc_on-rewrite"]) {
			console.log("Replacing @cc_on statements (use --no-cc_on-rewrite to skip)...")
			code = code.replace(/\/\*@cc_on/g, "");
			code = code.replace(/@\*\//g, "");
		} else {
			console.log(
				`The code appears to contain conditional compilation statements.
If you run into unexpected results, try uncommenting lines that look like

    /*@cc_on
    <JavaScript code>
    @*/

`
			);
		}
	}

	if (!argv["no-rewrite"]) {
		console.log("Rewriting code...");
		if (argv["dumb-concat-simplify"]) {
			console.log("Applying dumb concat simplification (remove --dumb-concat-simplify to skip)...")
			code = code.replace(/'[ \r\n]*\+[ \r\n]*'/gm, "");
			code = code.replace(/"[ \r\n]*\+[ \r\n]*"/gm, "");
		}

		if (!argv["no-rewrite-prototype"]) {
			console.log("Replacing `function A.prototype.B()` (use --no-rewrite-prototype to skip)...")
			// Replace `function X.prototype.y()` with `X.prototype.y = function()`
			code = code.replace(/function (\w+)\.prototype\.(\w+)/gm, "$1.prototype.$2 = function");
			console.log(code);
		}

		let tree;
		try {
			tree = esprima.parse(code);
		} catch (e) {
			console.log(e);
			console.log("");
			if (filename.match(/jse$/)) {
				console.log(
					`This appears to be a JSE (JScript.Encode) file.
Please compile the decoder and decode it first:

cc decoder.c -o decoder
./decoder ${filename} ${filename.replace(/jse$/, "js")}

`
				);
			} else {
				console.log(
					`This doesn't seem to be a JavaScript/WScript file.
If this is a JSE file (JScript.Encode), compile
decoder.c and run it on the file, like this:

cc decoder.c -o decoder
./decoder ${filename} ${filename}.js

`
				);
			}
			process.exit(-1);
			return;
		}

		if (!argv["no-concat-simplify"]) {
			console.log("Simplifying concatenations (use --no-concat-simplify to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "BinaryExpression") return;
				if (val.operator !== "+") return;
				if (val.left.type !== "Literal") return;
				if (val.right.type !== "Literal") return;
				const result = val.left.value + val.right.value;
				return {
					type: "Literal",
					value: result,
					raw: JSON.stringify(result),
				};
			});
		}

		if (argv["function-rewrite"]) {
			console.log("Rewriting functions (remove --function-rewrite to skip)...")
			traverse(tree, function(key, val) {
				if (key !== "callee") return;
				if (val.autogenerated) return;
				switch (val.type) {
					case "MemberExpression":
						return require("./patches/this.js")(val.object, val);
					default:
						return require("./patches/nothis.js")(val);
				}
			});
		}

		if (!argv["no-typeof-rewrite"]) {
			console.log("Rewriting typeof calls (use --no-typeof-rewrite to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "UnaryExpression") return;
				if (val.operator !== "typeof") return;
				if (val.autogenerated) return;
				return require("./patches/typeof.js")(val.argument);
			});
		}

		if (!argv["no-eval-rewrite"]) {
			console.log("Rewriting eval calls (use --no-eval-rewrite to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "CallExpression") return;
				if (val.callee.type !== "Identifier") return;
				if (val.callee.name !== "eval") return;
				return require("./patches/eval.js")(val.arguments);
			});
		}

		if (!argv["no-catch-rewrite"]) { // JScript quirk
			console.log("Rewriting try/catch statements (use --no-catch-rewrite to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "TryStatement") return;
				if (!val.handler) return;
				if (val.autogenerated) return;
				return require("./patches/catch.js")(val);
			});
		}

		// Replace (a !== b) with (false)
		if (argv["experimental-neq"]) {
			console.log("Rewriting `a !== b` (remove --experimental-neq to skip)...");
			traverse(tree, function(key, val) {
				if (!val) return;
				if (val.type !== "BinaryExpression") return;
				if (val.operator !== "!=" && val.operator !== "!==") return;
				return {
					type: "Literal",
					value: false,
					raw: "false",
				};
			});
		}
		// console.log(JSON.stringify(tree, null, "\t"));
		code = escodegen.generate(tree);

		// The modifications may have resulted in more concatenations, eg. "a" + ("foo", "b") + "c" -> "a" + "b" + "c"
		if (argv["dumb-concat-simplify"]) {
			console.log("Simplifying dumb concatenations (remove --dumb-concat-simplify to skip)...")
			code = code.replace(/'[ \r\n]*\+[ \r\n]*'/gm, "");
			code = code.replace(/"[ \r\n]*\+[ \r\n]*"/gm, "");
		}

		console.log("Rewritten successfully.")
	}
	console.log(code);
	return code;
}
code = rewrite(code);
controller.logJS(code);

Array.prototype.Count = function() {
	return this.length;
};

const sandbox = {
	ActiveXObject,
	alert: (x) => {},
	console: {
		log: (x) => console.log(JSON.stringify(x)),
	},
	Enumerator: require("./emulator/Enumerator"),
	GetObject: require("./emulator/WMI").GetObject,
	JSON,
	location: new Proxy({
		href: "http://www.foobar.com/",
		protocol: "http:",
		host: "www.foobar.com",
		hostname: "www.foobar.com",
	}, {
		get: function(target, name) {
			switch (name) {
				case Symbol.toPrimitive:
					return () => "http://www.foobar.com/";
				default:
					return target[name.toLowerCase()];
			}
		},
	}),
	parse: (x) => {},
	rewrite: (code) => rewrite(controller.logJS(code)),
	ScriptEngine: () => {
		const type = "JScript"; // or "JavaScript", or "VBScript"
		console.log(`Notice: emulating a ${type} engine (in ScriptEngine)`);
		return type;
	},
	_typeof: (x) => x.typeof ? x.typeof : typeof x,
	WScript: new Proxy({}, {
		get: function(target, name) {
			if (typeof name === "string") name = name.toLowerCase();
			switch (name) {
				case Symbol.toPrimitive:
					return () => "Windows Script Host";
				case "tostring":
					return "Windows Script Host";

				case "arguments":
					return new Proxy((n) => `${n}th argument`, {
						get: function(target, name) {
							switch (name) {
								case "Unnamed":
									return [];
								case "length":
									return 0;
								case "ShowUsage":
									return {
										typeof: "unknown",
									};
								case "Named":
									return [];
								default:
									return new Proxy(
										target[name],
										{
											get: (target, name) => name.toLowerCase() === "typeof" ? "unknown" : target[name],
										}
									);
							}
						},
					});
				case "createobject":
					return ActiveXObject;
				case "echo":
					if (argv["no-echo"])
						return () => {};
					return (x) => {
						console.log("Script wrote:", x);
						console.log("Add flag --no-echo to disable this.");
					};
				case "path":
					return "C:\\TestFolder\\";
				case "sleep":
					// return x => console.log(`Sleeping for ${x} ms...`)
					return (x) => {};
				case "stdin":
					return new Proxy({
						atendofstream: {
							typeof: "unknown",
						},
						line: 1,
						writeline: (text) => {
							if (argv["no-echo"]) return;
							console.log("Script wrote:", text);
							console.log("Add flag --no-echo to disable this.");
						},
					}, {
						get: function(target, name) {
							name = name.toLowerCase();
							if (!(name in target))
								controller.kill(`WScript.StdIn.${name} not implemented!`);
							return target[name];
						},
					});
				case "quit":
					return () => {};
				case "scriptfullname":
					return "(ScriptFullName)";
				case "scriptname":
					return "sample.js";
				default:
					controller.kill(`WScript.${name} not implemented!`);
			}
		},
	}),
	WSH: "Windows Script Host",
};

const vm = new VM({
	timeout: (argv.timeout || 10) * 1000,
	sandbox,
});

vm.run(code);

function ActiveXObject(name) {
	console.log(`New ActiveXObject: ${name}`);
	name = name.toLowerCase();
	if (name.match("winhttprequest"))
		return require("./emulator/XMLHTTP")();
	if (name.match("xmlhttp"))
		return require("./emulator/XMLHTTP")();
	if (name.match("dom")) {
		return {
			createElement: require("./emulator/DOM"),
			load: (filename) => {
				// console.log(`Loading ${filename} in a virtual DOM environment...`);
			},
		};
	}

	switch (name) {
		case "adodb.stream":
			return require("./emulator/ADODBStream")();
		case "adodb.recordset":
			return require("./emulator/ADODBRecordSet")();
		case "scriptcontrol":
			return require("./emulator/ScriptControl")();
		case "scripting.filesystemobject":
			return require("./emulator/FileSystemObject")();
		case "scripting.dictionary":
			return require("./emulator/Dictionary")();
		case "shell.application":
			return require("./emulator/ShellApplication")();
		case "wscript.network":
			return require("./emulator/WScriptNetwork")();
		case "wscript.shell":
			return require("./emulator/WScriptShell")();
		case "wbemscripting.swbemlocator":
			return require("./emulator/WBEMScriptingSWBEMLocator")();
		default:
			controller.kill(`Unknown ActiveXObject ${name}`);
			break;
	}
}

function traverse(obj, func) {
	const keys = Object.keys(obj);
	for (let i = 0; i < keys.length; i++) {
		const key = keys[i];
		const replacement = func.apply(this, [key, obj[key]]);
		if (replacement) obj[key] = replacement;
		if (obj.autogenerated) continue;
		if (obj[key] !== null && typeof obj[key] === "object")
			traverse(obj[key], func);
	}
}
<|endoftext|>