text: ;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
      var BigNumber = require('bignumber.js');
      /*
       json_parse.js
       2012-06-20
  
       Public Domain.
  
       NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  
       This file creates a json_parse function.
  
       json_parse(text, reviver)
       This method parses a JSON text to produce an object or array.
       It can throw a SyntaxError exception.
  
       The optional reviver parameter is a function that can filter and
       transform the results. It receives each of the keys and values,
       and its return value is used instead of the original value.
       If it returns what it received, then the structure is not modified.
       If it returns undefined then the member is deleted.
  
       Example:
  
       // Parse the text. Values that look like ISO date strings will
       // be converted to Date objects.
  
       myData = json_parse(text, function (key, value) {
       var a;
       if (typeof value === 'string') {
       a =
       /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
       if (a) {
       return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
       +a[5], +a[6]));
       }
       }
       return value;
       });
  
       This is a reference implementation. You are free to copy, modify, or
       redistribute.
  
       This code should be minified before deployment.
       See http://javascript.crockford.com/jsmin.html
  
       USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
       NOT CONTROL.
       */
  
      /*members "", "\"", "\/", "\\", at, b, call, charAt, f, fromCharCode,
       hasOwnProperty, message, n, name, prototype, push, r, t, text
       */
  
      var json_parse = (function () {
          "use strict";
  
  // This is a function that can parse a JSON text, producing a JavaScript
  // data structure. It is a simple, recursive descent parser. It does not use
  // eval or regular expressions, so it can be used as a model for implementing
  // a JSON parser in other languages.
  
  // We are defining the function inside of another function to avoid creating
  // global variables.
  
          var at,     // The index of the current character
              ch,     // The current character
              escapee = {
                  '"':  '"',
                  '\\': '\\',
                  '/':  '/',
                  b:    '\b',
                  f:    '\f',
                  n:    '\n',
                  r:    '\r',
                  t:    '\t'
              },
              text,
  
              error = function (m) {
  
  // Call error when something is wrong.
  
                  throw {
                      name:    'SyntaxError',
                      message: m,
                      at:      at,
                      text:    text
                  };
              },
  
              next = function (c) {
  
  // If a c parameter is provided, verify that it matches the current character.
  
                  if (c && c !== ch) {
                      error("Expected '" + c + "' instead of '" + ch + "'");
                  }
  
  // Get the next character. When there are no more characters,
  // return the empty string.
  
                  ch = text.charAt(at);
                  at += 1;
                  return ch;
              },
  
              number = function () {
  // Parse a number value.
  
                  var number,
                      string = '';
  
                  if (ch === '-') {
                      string = '-';
                      next('-');
                  }
                  while (ch >= '0' && ch <= '9') {
                      string += ch;
                      next();
                  }
                  if (ch === '.') {
                      string += '.';
                      while (next() && ch >= '0' && ch <= '9') {
                          string += ch;
                      }
                  }
                  if (ch === 'e' || ch === 'E') {
                      string += ch;
                      next();
                      if (ch === '-' || ch === '+') {
                          string += ch;
                          next();
                      }
                      while (ch >= '0' && ch <= '9') {
                          string += ch;
                          next();
                      }
                  }
                  number = +string;
                  if (!isFinite(number)) {
                      error("Bad number");
                  } else {
                      if (number > 9007199254740992 || number < -9007199254740992)
                          return new BigNumber(string);
                      return number;
                  }
              },
  
              string = function () {
  
  // Parse a string value.
  
                  var hex,
                      i,
                      string = '',
                      uffff;
  
  // When parsing for string values, we must look for " and \ characters.
  
                  if (ch === '"') {
                      while (next()) {
                          if (ch === '"') {
                              next();
                              return string;
                          }
                          if (ch === '\\') {
                              next();
                              if (ch === 'u') {
                                  uffff = 0;
                                  for (i = 0; i < 4; i += 1) {
                                      hex = parseInt(next(), 16);
                                      if (!isFinite(hex)) {
                                          break;
                                      }
                                      uffff = uffff * 16 + hex;
                                  }
                                  string += String.fromCharCode(uffff);
                              } else if (typeof escapee[ch] === 'string') {
                                  string += escapee[ch];
                              } else {
                                  break;
                              }
                          } else {
                              string += ch;
                          }
                      }
                  }
                  error("Bad string");
              },
  
              white = function () {
  
  // Skip whitespace.
  
                  while (ch && ch <= ' ') {
                      next();
                  }
              },
  
              word = function () {
  
  // true, false, or null.
  
                  switch (ch) {
                      case 't':
                          next('t');
                          next('r');
                          next('u');
                          next('e');
                          return true;
                      case 'f':
                          next('f');
                          next('a');
                          next('l');
                          next('s');
                          next('e');
                          return false;
                      case 'n':
                          next('n');
                          next('u');
                          next('l');
                          next('l');
                          return null;
                  }
                  error("Unexpected '" + ch + "'");
              },
  
              value,  // Place holder for the value function.
  
              array = function () {
  
  // Parse an array value.
  
                  var array = [];
  
                  if (ch === '[') {
                      next('[');
                      white();
                      if (ch === ']') {
                          next(']');
                          return array;   // empty array
                      }
                      while (ch) {
                          array.push(value());
                          white();
                          if (ch === ']') {
                              next(']');
                              return array;
                          }
                          next(',');
                          white();
                      }
                  }
                  error("Bad array");
              },
  
              object = function () {
  
  // Parse an object value.
  
                  var key,
                      object = {};
  
                  if (ch === '{') {
                      next('{');
                      white();
                      if (ch === '}') {
                          next('}');
                          return object;   // empty object
                      }
                      while (ch) {
                          key = string();
                          white();
                          next(':');
                          if (Object.hasOwnProperty.call(object, key)) {
                              error('Duplicate key "' + key + '"');
                          }
                          object[key] = value();
                          white();
                          if (ch === '}') {
                              next('}');
                              return object;
                          }
                          next(',');
                          white();
                      }
                  }
                  error("Bad object");
              };
  
          value = function () {
  
  // Parse a JSON value. It could be an object, an array, a string, a number,
  // or a word.
  
              white();
              switch (ch) {
                  case '{':
                      return object();
                  case '[':
                      return array();
                  case '"':
                      return string();
                  case '-':
                      return number();
                  default:
                      return ch >= '0' && ch <= '9' ? number() : word();
              }
          };
  
  // Return the json_parse function. It will have access to all of the above
  // functions and variables.
  
          return function (source, reviver) {
              var result;
  
              text = source;
              at = 0;
              ch = ' ';
              result = value();
              white();
              if (ch) {
                  error("Syntax error");
              }
  
  // If there is a reviver function, we recursively walk the new structure,
  // passing each name/value pair to the reviver function for possible
  // transformation, starting with a temporary root object that holds the result
  // in an empty key. If there is not a reviver function, we simply return the
  // result.
  
              return typeof reviver === 'function'
                  ? (function walk(holder, key) {
                  var k, v, value = holder[key];
                  if (value && typeof value === 'object') {
                      for (k in value) {
                          if (Object.prototype.hasOwnProperty.call(value, k)) {
                              v = walk(value, k);
                              if (v !== undefined) {
                                  value[k] = v;
                              } else {
                                  delete value[k];
                              }
                          }
                      }
                  }
                  return reviver.call(holder, key, value);
              }({'': result}, ''))
                  : result;
          };
      }());
  
      json_stringify = require('./stringify.js').stringify;
  
      module.exports = {
          parse: json_parse,
          stringify: json_stringify
      };
  
  },{"./stringify.js":3,"bignumber.js":2}],2:[function(require,module,exports){
      /* bignumber.js v1.1.1 https://github.com/MikeMcl/bignumber.js/LICENCE */
      ;(function ( global ) {
          'use strict';
  
          /*
           bignumber.js v1.1.1
           A JavaScript library for arbitrary-precision arithmetic.
           https://github.com/MikeMcl/bignumber.js
           Copyright (c) 2012 Michael Mclaughlin <M8ch88l@gmail.com>
           MIT Expat Licence
           */
  
          /*********************************** DEFAULTS ************************************/
  
          /*
           * The default values below must be integers within the stated ranges (inclusive).
           * Most of these values can be changed programmatically using BigNumber.config().
           */
  
          /*
           * The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP,
           * MAX_EXP, and the argument to toFixed, toPrecision and toExponential, beyond
           * which an exception is thrown (if ERRORS is true).
           */
          var MAX = 1E9,                                   // 0 to 1e+9
  
          // Limit of magnitude of exponent argument to toPower.
              MAX_POWER = 1E6,                             // 1 to 1e+6
  
          // The maximum number of decimal places for operations involving division.
              DECIMAL_PLACES = 20,                         // 0 to MAX
  
          /*
           * The rounding mode used when rounding to the above decimal places, and when
           * using toFixed, toPrecision and toExponential, and round (default value).
           * UP         0 Away from zero.
           * DOWN       1 Towards zero.
           * CEIL       2 Towards +Infinity.
           * FLOOR      3 Towards -Infinity.
           * HALF_UP    4 Towards nearest neighbour. If equidistant, up.
           * HALF_DOWN  5 Towards nearest neighbour. If equidistant, down.
           * HALF_EVEN  6 Towards nearest neighbour. If equidistant, towards even neighbour.
           * HALF_CEIL  7 Towards nearest neighbour. If equidistant, towards +Infinity.
           * HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
           */
              ROUNDING_MODE = 4,                           // 0 to 8
  
          // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]
  
          // The exponent value at and beneath which toString returns exponential notation.
          // Number type: -7
              TO_EXP_NEG = -7,                             // 0 to -MAX
  
          // The exponent value at and above which toString returns exponential notation.
          // Number type: 21
              TO_EXP_POS = 21,                             // 0 to MAX
  
          // RANGE : [MIN_EXP, MAX_EXP]
  
          // The minimum exponent value, beneath which underflow to zero occurs.
          // Number type: -324  (5e-324)
              MIN_EXP = -MAX,                              // -1 to -MAX
  
          // The maximum exponent value, above which overflow to Infinity occurs.
          // Number type:  308  (1.7976931348623157e+308)
              MAX_EXP = MAX,                               // 1 to MAX
  
          // Whether BigNumber Errors are ever thrown.
          // CHANGE parseInt to parseFloat if changing ERRORS to false.
              ERRORS = true,                               // true or false
              parse = parseInt,                            // parseInt or parseFloat
  
          /***********************************************************************************/
  
              P = BigNumber.prototype,
              DIGITS = '0123456789abcdefghijklmnopqrstuvwxyz',
              outOfRange,
              id = 0,
              isValid = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
              trim = String.prototype.trim || function () {return this.replace(/^\s+|\s+$/g, '')},
              ONE = BigNumber(1);
  
  
          // CONSTRUCTOR
  
  
          /*
           * The exported function.
           * Create and return a new instance of a BigNumber object.
           *
           * n {number|string|BigNumber} A numeric value.
           * [b] {number} The base of n. Integer, 2 to 36 inclusive.
           */
          function BigNumber( n, b ) {
              var e, i, isNum, digits, valid, orig,
                  x = this;
  
              // Enable constructor usage without new.
              if ( !(x instanceof BigNumber) ) {
                  return new BigNumber( n, b )
              }
  
              // Duplicate.
              if ( n instanceof BigNumber ) {
                  id = 0;
  
                  // e is undefined.
                  if ( b !== e ) {
                      n += ''
                  } else {
                      x['s'] = n['s'];
                      x['e'] = n['e'];
                      x['c'] = ( n = n['c'] ) ? n.slice() : n;
                      return
                  }
              }
  
              // If number, check if minus zero.
              if ( typeof n != 'string' ) {
                  n = ( isNum = typeof n == 'number' ||
                      Object.prototype.toString.call(n) == '[object Number]' ) &&
                  n === 0 && 1 / n < 0 ? '-0' : n + ''
              }
  
              orig = n;
  
              if ( b === e && isValid.test(n) ) {
  
                  // Determine sign.
                  x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1
  
                  // Either n is not a valid BigNumber or a base has been specified.
              } else {
  
                  // Enable exponential notation to be used with base 10 argument.
                  // Ensure return value is rounded to DECIMAL_PLACES as with other bases.
                  if ( b == 10 ) {
  
                      return setMode( n, DECIMAL_PLACES, ROUNDING_MODE )
                  }
  
                  n = trim.call(n).replace( /^\+(?!-)/, '' );
  
                  x['s'] = n.charAt(0) == '-' ? ( n = n.replace( /^-(?!-)/, '' ), -1 ) : 1;
  
                  if ( b != null ) {
  
                      if ( ( b == (b | 0) || !ERRORS ) &&
                          !( outOfRange = !( b >= 2 && b <= 36 ) ) ) {
  
                          digits = '[' + DIGITS.slice( 0, b = b | 0 ) + ']+';
  
                          // Before non-decimal number validity test and base conversion
                          // remove the `.` from e.g. '1.', and replace e.g. '.1' with '0.1'.
                          n = n.replace( /\.$/, '' ).replace( /^\./, '0.' );
  
                          // Any number in exponential form will fail due to the e+/-.
                          if ( valid = new RegExp(
                                  '^' + digits + '(?:\\.' + digits + ')?$', 'i' ).test(n) ) {
  
                              if ( isNum ) {
  
                                  if ( n.replace( /^0\.0*|\./, '' ).length > 15 ) {
  
                                      // 'new BigNumber() number type has more than 15 significant digits: {n}'
                                      ifExceptionsThrow( orig, 0 )
                                  }
  
                                  // Prevent later check for length on converted number.
                                  isNum = !isNum
                              }
                              n = convert( n, 10, b, x['s'] )
  
                          } else if ( n != 'Infinity' && n != 'NaN' ) {
  
                              // 'new BigNumber() not a base {b} number: {n}'
                              ifExceptionsThrow( orig, 1, b );
                              n = 'NaN'
                          }
                      } else {
  
                          // 'new BigNumber() base not an integer: {b}'
                          // 'new BigNumber() base out of range: {b}'
                          ifExceptionsThrow( b, 2 );
  
                          // Ignore base.
                          valid = isValid.test(n)
                      }
                  } else {
                      valid = isValid.test(n)
                  }
  
                  if ( !valid ) {
  
                      // Infinity/NaN
                      x['c'] = x['e'] = null;
  
                      // NaN
                      if ( n != 'Infinity' ) {
  
                          // No exception on NaN.
                          if ( n != 'NaN' ) {
  
                              // 'new BigNumber() not a number: {n}'
                              ifExceptionsThrow( orig, 3 )
                          }
                          x['s'] = null
                      }
                      id = 0;
  
                      return
                  }
              }
  
              // Decimal point?
              if ( ( e = n.indexOf('.') ) > -1 ) {
                  n = n.replace( '.', '' )
              }
  
              // Exponential form?
              if ( ( i = n.search( /e/i ) ) > 0 ) {
  
                  // Determine exponent.
                  if ( e < 0 ) {
                      e = i
                  }
                  e += +n.slice( i + 1 );
                  n = n.substring( 0, i )
  
              } else if ( e < 0 ) {
  
                  // Integer.
                  e = n.length
              }
  
              // Determine leading zeros.
              for ( i = 0; n.charAt(i) == '0'; i++ ) {
              }
  
              b = n.length;
  
              // Disallow numbers with over 15 significant digits if number type.
              if ( isNum && b > 15 && n.slice(i).length > 15 ) {
  
                  // 'new BigNumber() number type has more than 15 significant digits: {n}'
                  ifExceptionsThrow( orig, 0 )
              }
              id = 0;
  
              // Overflow?
              if ( ( e -= i + 1 ) > MAX_EXP ) {
  
                  // Infinity.
                  x['c'] = x['e'] = null
  
                  // Zero or underflow?
              } else if ( i == b || e < MIN_EXP ) {
  
                  // Zero.
                  x['c'] = [ x['e'] = 0 ]
              } else {
  
                  // Determine trailing zeros.
                  for ( ; n.charAt(--b) == '0'; ) {
                  }
  
                  x['e'] = e;
                  x['c'] = [];
  
                  // Convert string to array of digits (without leading and trailing zeros).
                  for ( e = 0; i <= b; x['c'][e++] = +n.charAt(i++) ) {
                  }
              }
          }
  
  
          // CONSTRUCTOR PROPERTIES/METHODS
  
  
          BigNumber['ROUND_UP'] = 0;
          BigNumber['ROUND_DOWN'] = 1;
          BigNumber['ROUND_CEIL'] = 2;
          BigNumber['ROUND_FLOOR'] = 3;
          BigNumber['ROUND_HALF_UP'] = 4;
          BigNumber['ROUND_HALF_DOWN'] = 5;
          BigNumber['ROUND_HALF_EVEN'] = 6;
          BigNumber['ROUND_HALF_CEIL'] = 7;
          BigNumber['ROUND_HALF_FLOOR'] = 8;
  
  
          /*
           * Configure infrequently-changing library-wide settings.
           *
           * Accept an object or an argument list, with one or many of the following
           * properties or parameters respectively:
           * [ DECIMAL_PLACES [, ROUNDING_MODE [, EXPONENTIAL_AT [, RANGE [, ERRORS ]]]]]
           *
           * E.g.
           * BigNumber.config(20, 4) is equivalent to
           * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })
           * Ignore properties/parameters set to null or undefined.
           *
           * Return an object with the properties current values.
           */
          BigNumber['config'] = function () {
              var v, p,
                  i = 0,
                  r = {},
                  a = arguments,
                  o = a[0],
                  c = 'config',
                  inRange = function ( n, lo, hi ) {
                      return !( ( outOfRange = n < lo || n > hi ) ||
                      parse(n) != n && n !== 0 )
                  },
                  has = o && typeof o == 'object'
                      ? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null}
                      : function () {if ( a.length > i ) return ( v = a[i++] ) != null};
  
              // [DECIMAL_PLACES] {number} Integer, 0 to MAX inclusive.
              if ( has( p = 'DECIMAL_PLACES' ) ) {
  
                  if ( inRange( v, 0, MAX ) ) {
                      DECIMAL_PLACES = v | 0
                  } else {
  
                      // 'config() DECIMAL_PLACES not an integer: {v}'
                      // 'config() DECIMAL_PLACES out of range: {v}'
                      ifExceptionsThrow( v, p, c )
                  }
              }
              r[p] = DECIMAL_PLACES;
  
              // [ROUNDING_MODE] {number} Integer, 0 to 8 inclusive.
              if ( has( p = 'ROUNDING_MODE' ) ) {
  
                  if ( inRange( v, 0, 8 ) ) {
                      ROUNDING_MODE = v | 0
                  } else {
  
                      // 'config() ROUNDING_MODE not an integer: {v}'
                      // 'config() ROUNDING_MODE out of range: {v}'
                      ifExceptionsThrow( v, p, c )
                  }
              }
              r[p] = ROUNDING_MODE;
  
              /*
               * [EXPONENTIAL_AT] {number|number[]} Integer, -MAX to MAX inclusive or
               * [ integer -MAX to 0 inclusive, 0 to MAX inclusive ].
               */
              if ( has( p = 'EXPONENTIAL_AT' ) ) {
  
                  if ( inRange( v, -MAX, MAX ) ) {
                      TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) )
                  } else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) &&
                      inRange( v[1], 0, MAX ) ) {
                      TO_EXP_NEG = ~~v[0], TO_EXP_POS = ~~v[1]
                  } else {
  
                      // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}'
                      // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}'
                      ifExceptionsThrow( v, p, c, 1 )
                  }
              }
              r[p] = [ TO_EXP_NEG, TO_EXP_POS ];
  
              /*
               * [RANGE][ {number|number[]} Non-zero integer, -MAX to MAX inclusive or
               * [ integer -MAX to -1 inclusive, integer 1 to MAX inclusive ].
               */
              if ( has( p = 'RANGE' ) ) {
  
                  if ( inRange( v, -MAX, MAX ) && ~~v ) {
                      MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) )
                  } else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) &&
                      inRange( v[1], 1, MAX ) ) {
                      MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]
                  } else {
  
                      // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}'
                      // 'config() RANGE out of range or not [negative, positive: {v}'
                      ifExceptionsThrow( v, p, c, 1, 1 )
                  }
              }
              r[p] = [ MIN_EXP, MAX_EXP ];
  
              // [ERRORS] {boolean|number} true, false, 1 or 0.
              if ( has( p = 'ERRORS' ) ) {
  
                  if ( v === !!v || v === 1 || v === 0 ) {
                      parse = ( outOfRange = id = 0, ERRORS = !!v )
                          ? parseInt
                          : parseFloat
                  } else {
  
                      // 'config() ERRORS not a boolean or binary digit: {v}'
                      ifExceptionsThrow( v, p, c, 0, 0, 1 )
                  }
              }
              r[p] = ERRORS;
  
              return r
          };
  
  
          // PRIVATE FUNCTIONS
  
  
          // Assemble error messages. Throw BigNumber Errors.
          function ifExceptionsThrow( arg, i, j, isArray, isRange, isErrors) {
              if ( ERRORS ) {
                  var method = ['new BigNumber', 'cmp', 'div', 'eq', 'gt', 'gte', 'lt',
                              'lte', 'minus', 'mod', 'plus', 'times', 'toFr'
                          ][ id ? id < 0 ? -id : id : 1 / id < 0 ? 1 : 0 ] + '()',
                      error = outOfRange ? ' out of range' : ' not a' +
                      ( isRange ? ' non-zero' : 'n' ) + ' integer';
  
                  error = ( [
                          method + ' number type has more than 15 significant digits',
                          method + ' not a base ' + j + ' number',
                          method + ' base' + error,
                          method + ' not a number' ][i] ||
                      j + '() ' + i + ( isErrors
                          ? ' not a boolean or binary digit'
                          : error + ( isArray
                          ? ' or not [' + ( outOfRange
                          ? ' negative, positive'
                          : ' integer, integer' ) + ' ]'
                          : '' ) ) ) + ': ' + arg;
  
                  outOfRange = id = 0;
                  throw {
                      name : 'BigNumber Error',
                      message : error,
                      toString : function () {return this.name + ': ' + this.message}
                  }
              }
          }
  
  
          /*
           * Convert a numeric string of baseIn to a numeric string of baseOut.
           */
          function convert( nStr, baseOut, baseIn, sign ) {
              var e, dvs, dvd, nArr, fracArr, fracBN;
  
              // Convert string of base bIn to an array of numbers of baseOut.
              // Eg. strToArr('255', 10) where baseOut is 16, returns [15, 15].
              // Eg. strToArr('ff', 16)  where baseOut is 10, returns [2, 5, 5].
              function strToArr( str, bIn ) {
                  var j,
                      i = 0,
                      strL = str.length,
                      arrL,
                      arr = [0];
  
                  for ( bIn = bIn || baseIn; i < strL; i++ ) {
  
                      for ( arrL = arr.length, j = 0; j < arrL; arr[j] *= bIn, j++ ) {
                      }
  
                      for ( arr[0] += DIGITS.indexOf( str.charAt(i) ), j = 0;
                            j < arr.length;
                            j++ ) {
  
                          if ( arr[j] > baseOut - 1 ) {
  
                              if ( arr[j + 1] == null ) {
                                  arr[j + 1] = 0
                              }
                              arr[j + 1] += arr[j] / baseOut ^ 0;
                              arr[j] %= baseOut
                          }
                      }
                  }
  
                  return arr.reverse()
              }
  
              // Convert array to string.
              // E.g. arrToStr( [9, 10, 11] ) becomes '9ab' (in bases above 11).
              function arrToStr( arr ) {
                  var i = 0,
                      arrL = arr.length,
                      str = '';
  
                  for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) {
                  }
  
                  return str
              }
  
              nStr = nStr.toLowerCase();
  
              /*
               * If non-integer convert integer part and fraction part separately.
               * Convert the fraction part as if it is an integer than use division to
               * reduce it down again to a value less than one.
               */
              if ( ( e = nStr.indexOf( '.' ) ) > -1 ) {
  
                  /*
                   * Calculate the power to which to raise the base to get the number
                   * to divide the fraction part by after it has been converted as an
                   * integer to the required base.
                   */
                  e = nStr.length - e - 1;
  
                  // Use toFixed to avoid possible exponential notation.
                  dvs = strToArr( new BigNumber(baseIn)['pow'](e)['toF'](), 10 );
  
                  nArr = nStr.split('.');
  
                  // Convert the base of the fraction part (as integer).
                  dvd = strToArr( nArr[1] );
  
                  // Convert the base of the integer part.
                  nArr = strToArr( nArr[0] );
  
                  // Result will be a BigNumber with a value less than 1.
                  fracBN = divide( dvd, dvs, dvd.length - dvs.length, sign, baseOut,
                      // Is least significant digit of integer part an odd number?
                      nArr[nArr.length - 1] & 1 );
  
                  fracArr = fracBN['c'];
  
                  // e can be <= 0  ( if e == 0, fracArr is [0] or [1] ).
                  if ( e = fracBN['e'] ) {
  
                      // Append zeros according to the exponent of the result.
                      for ( ; ++e; fracArr.unshift(0) ) {
                      }
  
                      // Append the fraction part to the converted integer part.
                      nStr = arrToStr(nArr) + '.' + arrToStr(fracArr)
  
                      // fracArr is [1].
                      // Fraction digits rounded up, so increment last digit of integer part.
                  } else if ( fracArr[0] ) {
  
                      if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) {
                          ++nArr[e];
                          nStr = arrToStr(nArr)
                      } else {
                          nStr = new BigNumber( arrToStr(nArr),
                              baseOut )['plus'](ONE)['toS'](baseOut)
                      }
  
                      // fracArr is [0]. No fraction digits.
                  } else {
                      nStr = arrToStr(nArr)
                  }
              } else {
  
                  // Simple integer. Convert base.
                  nStr = arrToStr( strToArr(nStr) )
              }
  
              return nStr
          }
  
  
          // Perform division in the specified base. Called by div and convert.
          function divide( dvd, dvs, exp, s, base, isOdd ) {
              var dvsL, dvsT, next, cmp, remI,
                  dvsZ = dvs.slice(),
                  dvdI = dvsL = dvs.length,
                  dvdL = dvd.length,
                  rem = dvd.slice( 0, dvsL ),
                  remL = rem.length,
                  quo = new BigNumber(ONE),
                  qc = quo['c'] = [],
                  qi = 0,
                  dig = DECIMAL_PLACES + ( quo['e'] = exp ) + 1;
  
              quo['s'] = s;
              s = dig < 0 ? 0 : dig;
  
              // Add zeros to make remainder as long as divisor.
              for ( ; remL++ < dvsL; rem.push(0) ) {
              }
  
              // Create version of divisor with leading zero.
              dvsZ.unshift(0);
  
              do {
  
                  // 'next' is how many times the divisor goes into the current remainder.
                  for ( next = 0; next < base; next++ ) {
  
                      // Compare divisor and remainder.
                      if ( dvsL != ( remL = rem.length ) ) {
                          cmp = dvsL > remL ? 1 : -1
                      } else {
                          for ( remI = -1, cmp = 0; ++remI < dvsL; ) {
  
                              if ( dvs[remI] != rem[remI] ) {
                                  cmp = dvs[remI] > rem[remI] ? 1 : -1;
                                  break
                              }
                          }
                      }
  
                      // Subtract divisor from remainder (if divisor < remainder).
                      if ( cmp < 0 ) {
  
                          // Remainder cannot be more than one digit longer than divisor.
                          // Equalise lengths using divisor with extra leading zero?
                          for ( dvsT = remL == dvsL ? dvs : dvsZ; remL; ) {
  
                              if ( rem[--remL] < dvsT[remL] ) {
  
                                  for ( remI = remL;
                                        remI && !rem[--remI];
                                        rem[remI] = base - 1 ) {
                                  }
                                  --rem[remI];
                                  rem[remL] += base
                              }
                              rem[remL] -= dvsT[remL]
                          }
                          for ( ; !rem[0]; rem.shift() ) {
                          }
                      } else {
                          break
                      }
                  }
  
                  // Add the 'next' digit to the result array.
                  qc[qi++] = cmp ? next : ++next;
  
                  // Update the remainder.
                  rem[0] && cmp
                      ? ( rem[remL] = dvd[dvdI] || 0 )
                      : ( rem = [ dvd[dvdI] ] )
  
              } while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- );
  
              // Leading zero? Do not remove if result is simply zero (qi == 1).
              if ( !qc[0] && qi != 1 ) {
  
                  // There can't be more than one zero.
                  --quo['e'];
                  qc.shift()
              }
  
              // Round?
              if ( qi > dig ) {
                  rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null )
              }
  
              // Overflow?
              if ( quo['e'] > MAX_EXP ) {
  
                  // Infinity.
                  quo['c'] = quo['e'] = null
  
                  // Underflow?
              } else if ( quo['e'] < MIN_EXP ) {
  
                  // Zero.
                  quo['c'] = [quo['e'] = 0]
              }
  
              return quo
          }
  
  
          /*
           * Return a string representing the value of BigNumber n in normal or
           * exponential notation rounded to the specified decimal places or
           * significant digits.
           * Called by toString, toExponential (exp 1), toFixed, and toPrecision (exp 2).
           * d is the index (with the value in normal notation) of the digit that may be
           * rounded up.
           */
          function format( n, d, exp ) {
  
              // Initially, i is the number of decimal places required.
              var i = d - (n = new BigNumber(n))['e'],
                  c = n['c'];
  
              // +-Infinity or NaN?
              if ( !c ) {
                  return n['toS']()
              }
  
              // Round?
              if ( c.length > ++d ) {
                  rnd( n, i, 10 )
              }
  
              // Recalculate d if toFixed as n['e'] may have changed if value rounded up.
              i = c[0] == 0 ? i + 1 : exp ? d : n['e'] + i + 1;
  
              // Append zeros?
              for ( ; c.length < i; c.push(0) ) {
              }
              i = n['e'];
  
              /*
               * toPrecision returns exponential notation if the number of significant
               * digits specified is less than the number of digits necessary to
               * represent the integer part of the value in normal notation.
               */
              return exp == 1 || exp == 2 && ( --d < i || i <= TO_EXP_NEG )
  
                  // Exponential notation.
                  ? ( n['s'] < 0 && c[0] ? '-' : '' ) + ( c.length > 1
                  ? ( c.splice( 1, 0, '.' ), c.join('') )
                  : c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i
  
                  // Normal notation.
                  : n['toS']()
          }
  
  
          // Round if necessary.
          // Called by divide, format, setMode and sqrt.
          function rnd( x, dp, base, isOdd, r ) {
              var xc = x['c'],
                  isNeg = x['s'] < 0,
                  half = base / 2,
                  i = x['e'] + dp + 1,
  
              // 'next' is the digit after the digit that may be rounded up.
                  next = xc[i],
  
              /*
               * 'more' is whether there are digits after 'next'.
               * E.g.
               * 0.005 (e = -3) to be rounded to 0 decimal places (dp = 0) gives i = -2
               * The 'next' digit is zero, and there ARE 'more' digits after it.
               * 0.5 (e = -1) dp = 0 gives i = 0
               * The 'next' digit is 5 and there are no 'more' digits after it.
               */
                  more = r || i < 0 || xc[i + 1] != null;
  
              r = ROUNDING_MODE < 4
                  ? ( next != null || more ) &&
              ( ROUNDING_MODE == 0 ||
              ROUNDING_MODE == 2 && !isNeg ||
              ROUNDING_MODE == 3 && isNeg )
                  : next > half || next == half &&
              ( ROUNDING_MODE == 4 || more ||
  
              /*
               * isOdd is used in base conversion and refers to the least significant
               * digit of the integer part of the value to be converted. The fraction
               * part is rounded by this method separately from the integer part.
               */
              ROUNDING_MODE == 6 && ( xc[i - 1] & 1 || !dp && isOdd ) ||
              ROUNDING_MODE == 7 && !isNeg ||
              ROUNDING_MODE == 8 && isNeg );
  
              if ( i < 1 || !xc[0] ) {
                  xc.length = 0;
                  xc.push(0);
  
                  if ( r ) {
  
                      // 1, 0.1, 0.01, 0.001, 0.0001 etc.
                      xc[0] = 1;
                      x['e'] = -dp
                  } else {
  
                      // Zero.
                      x['e'] = 0
                  }
  
                  return x
              }
  
              // Remove any digits after the required decimal places.
              xc.length = i--;
  
              // Round up?
              if ( r ) {
  
                  // Rounding up may mean the previous digit has to be rounded up and so on.
                  for ( --base; ++xc[i] > base; ) {
                      xc[i] = 0;
  
                      if ( !i-- ) {
                          ++x['e'];
                          xc.unshift(1)
                      }
                  }
              }
  
              // Remove trailing zeros.
              for ( i = xc.length; !xc[--i]; xc.pop() ) {
              }
  
              return x
          }
  
  
          // Round after setting the appropriate rounding mode.
          // Handles ceil, floor and round.
          function setMode( x, dp, rm ) {
              var r = ROUNDING_MODE;
  
              ROUNDING_MODE = rm;
              x = new BigNumber(x);
              x['c'] && rnd( x, dp, 10 );
              ROUNDING_MODE = r;
  
              return x
          }
  
  
          // PROTOTYPE/INSTANCE METHODS
  
  
          /*
           * Return a new BigNumber whose value is the absolute value of this BigNumber.
           */
          P['abs'] = P['absoluteValue'] = function () {
              var x = new BigNumber(this);
  
              if ( x['s'] < 0 ) {
                  x['s'] = 1
              }
  
              return x
          };
  
  
          /*
           * Return a new BigNumber whose value is the value of this BigNumber
           * rounded to a whole number in the direction of Infinity.
           */
          P['ceil'] = function () {
              return setMode( this, 0, 2 )
          };
  
  
          /*
           * Return
           * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b),
           * -1 if the value of this BigNumber is less than the value of BigNumber(y, b),
           * 0 if they have the same value,
           * or null if the value of either is NaN.
           */
          P['comparedTo'] = P['cmp'] = function ( y, b ) {
              var a,
                  x = this,
                  xc = x['c'],
                  yc = ( id = -id, y = new BigNumber( y, b ) )['c'],
                  i = x['s'],
                  j = y['s'],
                  k = x['e'],
                  l = y['e'];
  
              // Either NaN?
              if ( !i || !j ) {
                  return null
              }
  
              a = xc && !xc[0], b = yc && !yc[0];
  
              // Either zero?
              if ( a || b ) {
                  return a ? b ? 0 : -j : i
              }
  
              // Signs differ?
              if ( i != j ) {
                  return i
              }
  
              // Either Infinity?
              if ( a = i < 0, b = k == l, !xc || !yc ) {
                  return b ? 0 : !xc ^ a ? 1 : -1
              }
  
              // Compare exponents.
              if ( !b ) {
                  return k > l ^ a ? 1 : -1
              }
  
              // Compare digit by digit.
              for ( i = -1,
                        j = ( k = xc.length ) < ( l = yc.length ) ? k : l;
                    ++i < j; ) {
  
                  if ( xc[i] != yc[i] ) {
                      return xc[i] > yc[i] ^ a ? 1 : -1
                  }
              }
              // Compare lengths.
              return k == l ? 0 : k > l ^ a ? 1 : -1
          };
  
  
          /*
           *  n / 0 = I
           *  n / N = N
           *  n / I = 0
           *  0 / n = 0
           *  0 / 0 = N
           *  0 / N = N
           *  0 / I = 0
           *  N / n = N
           *  N / 0 = N
           *  N / N = N
           *  N / I = N
           *  I / n = I
           *  I / 0 = I
           *  I / N = N
           *  I / I = N
           *
           * Return a new BigNumber whose value is the value of this BigNumber
           * divided by the value of BigNumber(y, b), rounded according to
           * DECIMAL_PLACES and ROUNDING_MODE.
           */
          P['dividedBy'] = P['div'] = function ( y, b ) {
              var xc = this['c'],
                  xe = this['e'],
                  xs = this['s'],
                  yc = ( id = 2, y = new BigNumber( y, b ) )['c'],
                  ye = y['e'],
                  ys = y['s'],
                  s = xs == ys ? 1 : -1;
  
              // Either NaN/Infinity/0?
              return !xe && ( !xc || !xc[0] ) || !ye && ( !yc || !yc[0] )
  
                  // Either NaN?
                  ? new BigNumber( !xs || !ys ||
  
              // Both 0 or both Infinity?
              ( xc ? yc && xc[0] == yc[0] : !yc )
  
                  // Return NaN.
                  ? NaN
  
                  // x is 0 or y is Infinity?
                  : xc && xc[0] == 0 || !yc
  
                  // Return +-0.
                  ? s * 0
  
                  // y is 0. Return +-Infinity.
                  : s / 0 )
  
                  : divide( xc, yc, xe - ye, s, 10 )
          };
  
  
          /*
           * Return true if the value of this BigNumber is equal to the value of
           * BigNumber(n, b), otherwise returns false.
           */
          P['equals'] = P['eq'] = function ( n, b ) {
              id = 3;
              return this['cmp']( n, b ) === 0
          };
  
  
          /*
           * Return a new BigNumber whose value is the value of this BigNumber
           * rounded to a whole number in the direction of -Infinity.
           */
          P['floor'] = function () {
              return setMode( this, 0, 3 )
          };
  
  
          /*
           * Return true if the value of this BigNumber is greater than the value of
           * BigNumber(n, b), otherwise returns false.
           */
          P['greaterThan'] = P['gt'] = function ( n, b ) {
              id = 4;
              return this['cmp']( n, b ) > 0
          };
  
  
          /*
           * Return true if the value of this BigNumber is greater than or equal to
           * the value of BigNumber(n, b), otherwise returns false.
           */
          P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) {
              id = 5;
              return ( b = this['cmp']( n, b ) ) == 1 || b === 0
          };
  
  
          /*
           * Return true if the value of this BigNumber is a finite number, otherwise
           * returns false.
           */
          P['isFinite'] = P['isF'] = function () {
              return !!this['c']
          };
  
  
          /*
           * Return true if the value of this BigNumber is NaN, otherwise returns
           * false.
           */
          P['isNaN'] = function () {
              return !this['s']
          };
  
  
          /*
           * Return true if the value of this BigNumber is negative, otherwise
           * returns false.
           */
          P['isNegative'] = P['isNeg'] = function () {
              return this['s'] < 0
          };
  
  
          /*
           * Return true if the value of this BigNumber is 0 or -0, otherwise returns
           * false.
           */
          P['isZero'] = P['isZ'] = function () {
              return !!this['c'] && this['c'][0] == 0
          };
  
  
          /*
           * Return true if the value of this BigNumber is less than the value of
           * BigNumber(n, b), otherwise returns false.
           */
          P['lessThan'] = P['lt'] = function ( n, b ) {
              id = 6;
              return this['cmp']( n, b ) < 0
          };
  
  
          /*
           * Return true if the value of this BigNumber is less than or equal to the
           * value of BigNumber(n, b), otherwise returns false.
           */
          P['lessThanOrEqualTo'] = P['lte'] = function ( n, b ) {
              id = 7;
              return ( b = this['cmp']( n, b ) ) == -1 || b === 0
          };
  
  
          /*
           *  n - 0 = n
           *  n - N = N
           *  n - I = -I
           *  0 - n = -n
           *  0 - 0 = 0
           *  0 - N = N
           *  0 - I = -I
           *  N - n = N
           *  N - 0 = N
           *  N - N = N
           *  N - I = N
           *  I - n = I
           *  I - 0 = I
           *  I - N = N
           *  I - I = N
           *
           * Return a new BigNumber whose value is the value of this BigNumber minus
           * the value of BigNumber(y, b).
           */
          P['minus'] = function ( y, b ) {
              var d, i, j, xLTy,
                  x = this,
                  a = x['s'];
  
              b = ( id = 8, y = new BigNumber( y, b ) )['s'];
  
              // Either NaN?
              if ( !a || !b ) {
                  return new BigNumber(NaN)
              }
  
              // Signs differ?
              if ( a != b ) {
                  return y['s'] = -b, x['plus'](y)
              }
  
              var xc = x['c'],
                  xe = x['e'],
                  yc = y['c'],
                  ye = y['e'];
  
              if ( !xe || !ye ) {
  
                  // Either Infinity?
                  if ( !xc || !yc ) {
                      return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN )
                  }
  
                  // Either zero?
                  if ( !xc[0] || !yc[0] ) {
  
                      // y is non-zero?
                      return yc[0]
                          ? ( y['s'] = -b, y )
  
                          // x is non-zero?
                          : new BigNumber( xc[0]
                          ? x
  
                          // Both are zero.
                          : 0 )
                  }
              }
  
              // Determine which is the bigger number.
              // Prepend zeros to equalise exponents.
              if ( xc = xc.slice(), a = xe - ye ) {
                  d = ( xLTy = a < 0 ) ? ( a = -a, xc ) : ( ye = xe, yc );
  
                  for ( d.reverse(), b = a; b--; d.push(0) ) {
                  }
                  d.reverse()
              } else {
  
                  // Exponents equal. Check digit by digit.
                  j = ( ( xLTy = xc.length < yc.length ) ? xc : yc ).length;
  
                  for ( a = b = 0; b < j; b++ ) {
  
                      if ( xc[b] != yc[b] ) {
                          xLTy = xc[b] < yc[b];
                          break
                      }
                  }
              }
  
              // x < y? Point xc to the array of the bigger number.
              if ( xLTy ) {
                  d = xc, xc = yc, yc = d;
                  y['s'] = -y['s']
              }
  
              /*
               * Append zeros to xc if shorter. No need to add zeros to yc if shorter
               * as subtraction only needs to start at yc.length.
               */
              if ( ( b = -( ( j = xc.length ) - yc.length ) ) > 0 ) {
  
                  for ( ; b--; xc[j++] = 0 ) {
                  }
              }
  
              // Subtract yc from xc.
              for ( b = yc.length; b > a; ){
  
                  if ( xc[--b] < yc[b] ) {
  
                      for ( i = b; i && !xc[--i]; xc[i] = 9 ) {
                      }
                      --xc[i];
                      xc[b] += 10
                  }
                  xc[b] -= yc[b]
              }
  
              // Remove trailing zeros.
              for ( ; xc[--j] == 0; xc.pop() ) {
              }
  
              // Remove leading zeros and adjust exponent accordingly.
              for ( ; xc[0] == 0; xc.shift(), --ye ) {
              }
  
              /*
               * No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity
               * when neither x or y are Infinity.
               */
  
              // Underflow?
              if ( ye < MIN_EXP || !xc[0] ) {
  
                  // Result must be zero.
                  xc = [ye = 0]
              }
  
              return y['c'] = xc, y['e'] = ye, y
          };
  
  
          /*
           *   n % 0 =  N
           *   n % N =  N
           *   0 % n =  0
           *  -0 % n = -0
           *   0 % 0 =  N
           *   0 % N =  N
           *   N % n =  N
           *   N % 0 =  N
           *   N % N =  N
           *
           * Return a new BigNumber whose value is the value of this BigNumber modulo
           * the value of BigNumber(y, b).
           */
          P['modulo'] = P['mod'] = function ( y, b ) {
              var x = this,
                  xc = x['c'],
                  yc = ( id = 9, y = new BigNumber( y, b ) )['c'],
                  i = x['s'],
                  j = y['s'];
  
              // Is x or y NaN, or y zero?
              b = !i || !j || yc && !yc[0];
  
              if ( b || xc && !xc[0] ) {
                  return new BigNumber( b ? NaN : x )
              }
  
              x['s'] = y['s'] = 1;
              b = y['cmp'](x) == 1;
              x['s'] = i, y['s'] = j;
  
              return b
                  ? new BigNumber(x)
                  : ( i = DECIMAL_PLACES, j = ROUNDING_MODE,
                  DECIMAL_PLACES = 0, ROUNDING_MODE = 1,
                  x = x['div'](y),
                  DECIMAL_PLACES = i, ROUNDING_MODE = j,
                  this['minus']( x['times'](y) ) )
          };
  
  
          /*
           * Return a new BigNumber whose value is the value of this BigNumber
           * negated, i.e. multiplied by -1.
           */
          P['negated'] = P['neg'] = function () {
              var x = new BigNumber(this);
  
              return x['s'] = -x['s'] || null, x
          };
  
  
          /*
           *  n + 0 = n
           *  n + N = N
           *  n + I = I
           *  0 + n = n
           *  0 + 0 = 0
           *  0 + N = N
           *  0 + I = I
           *  N + n = N
           *  N + 0 = N
           *  N + N = N
           *  N + I = N
           *  I + n = I
           *  I + 0 = I
           *  I + N = N
           *  I + I = I
           *
           * Return a new BigNumber whose value is the value of this BigNumber plus
           * the value of BigNumber(y, b).
           */
          P['plus'] = function ( y, b ) {
              var d,
                  x = this,
                  a = x['s'];
  
              b = ( id = 10, y = new BigNumber( y, b ) )['s'];
  
              // Either NaN?
              if ( !a || !b ) {
                  return new BigNumber(NaN)
              }
  
              // Signs differ?
              if ( a != b ) {
                  return y['s'] = -b, x['minus'](y)
              }
  
              var xe = x['e'],
                  xc = x['c'],
                  ye = y['e'],
                  yc = y['c'];
  
              if ( !xe || !ye ) {
  
                  // Either Infinity?
                  if ( !xc || !yc ) {
  
                      // Return +-Infinity.
                      return new BigNumber( a / 0 )
                  }
  
                  // Either zero?
                  if ( !xc[0] || !yc[0] ) {
  
                      // y is non-zero?
                      return yc[0]
                          ? y
                          : new BigNumber( xc[0]
  
                          // x is non-zero?
                          ? x
  
                          // Both are zero. Return zero.
                          : a * 0 )
                  }
              }
  
              // Prepend zeros to equalise exponents.
              // Note: Faster to use reverse then do unshifts.
              if ( xc = xc.slice(), a = xe - ye ) {
                  d = a > 0 ? ( ye = xe, yc ) : ( a = -a, xc );
  
                  for ( d.reverse(); a--; d.push(0) ) {
                  }
                  d.reverse()
              }
  
              // Point xc to the longer array.
              if ( xc.length - yc.length < 0 ) {
                  d = yc, yc = xc, xc = d
              }
  
              /*
               * Only start adding at yc.length - 1 as the
               * further digits of xc can be left as they are.
               */
              for ( a = yc.length, b = 0; a;
                    b = ( xc[--a] = xc[a] + yc[a] + b ) / 10 ^ 0, xc[a] %= 10 ) {
              }
  
              // No need to check for zero, as +x + +y != 0 && -x + -y != 0
  
              if ( b ) {
                  xc.unshift(b);
  
                  // Overflow? (MAX_EXP + 1 possible)
                  if ( ++ye > MAX_EXP ) {
  
                      // Infinity.
                      xc = ye = null
                  }
              }
  
              // Remove trailing zeros.
              for ( a = xc.length; xc[--a] == 0; xc.pop() ) {
              }
  
              return y['c'] = xc, y['e'] = ye, y
          };
  
  
          /*
           * Return a BigNumber whose value is the value of this BigNumber raised to
           * the power e. If e is negative round according to DECIMAL_PLACES and
           * ROUNDING_MODE.
           *
           * e {number} Integer, -MAX_POWER to MAX_POWER inclusive.
           */
          P['toPower'] = P['pow'] = function ( e ) {
  
              // e to integer, avoiding NaN or Infinity becoming 0.
              var i = e * 0 == 0 ? e | 0 : e,
                  x = new BigNumber(this),
                  y = new BigNumber(ONE);
  
              // Use Math.pow?
              // Pass +-Infinity for out of range exponents.
              if ( ( ( ( outOfRange = e < -MAX_POWER || e > MAX_POWER ) &&
                  (i = e * 1 / 0) ) ||
  
                  /*
                   * Any exponent that fails the parse becomes NaN.
                   *
                   * Include 'e !== 0' because on Opera -0 == parseFloat(-0) is false,
                   * despite -0 === parseFloat(-0) && -0 == parseFloat('-0') is true.
                   */
                  parse(e) != e && e !== 0 && !(i = NaN) ) &&
  
                  // 'pow() exponent not an integer: {e}'
                  // 'pow() exponent out of range: {e}'
                  !ifExceptionsThrow( e, 'exponent', 'pow' ) ||
  
                  // Pass zero to Math.pow, as any value to the power zero is 1.
                  !i ) {
  
                  // i is +-Infinity, NaN or 0.
                  return new BigNumber( Math.pow( x['toS'](), i ) )
              }
  
              for ( i = i < 0 ? -i : i; ; ) {
  
                  if ( i & 1 ) {
                      y = y['times'](x)
                  }
                  i >>= 1;
  
                  if ( !i ) {
                      break
                  }
                  x = x['times'](x)
              }
  
              return e < 0 ? ONE['div'](y) : y
          };
  
  
          /*
           * Return a new BigNumber whose value is the value of this BigNumber
           * rounded to a maximum of dp decimal places using rounding mode rm, or to
           * 0 and ROUNDING_MODE respectively if omitted.
           *
           * [dp] {number} Integer, 0 to MAX inclusive.
           * [rm] {number} Integer, 0 to 8 inclusive.
           */
          P['round'] = function ( dp, rm ) {
  
              dp = dp == null || ( ( ( outOfRange = dp < 0 || dp > MAX ) ||
              parse(dp) != dp ) &&
  
              // 'round() decimal places out of range: {dp}'
              // 'round() decimal places not an integer: {dp}'
              !ifExceptionsThrow( dp, 'decimal places', 'round' ) )
                  ? 0
                  : dp | 0;
  
              rm = rm == null || ( ( ( outOfRange = rm < 0 || rm > 8 ) ||
  
              // Include '&& rm !== 0' because with Opera -0 == parseFloat(-0) is false.
              parse(rm) != rm && rm !== 0 ) &&
  
              // 'round() mode not an integer: {rm}'
              // 'round() mode out of range: {rm}'
              !ifExceptionsThrow( rm, 'mode', 'round' ) )
                  ? ROUNDING_MODE
                  : rm | 0;
  
              return setMode( this, dp, rm )
          };
  
  
          /*
           *  sqrt(-n) =  N
           *  sqrt( N) =  N
           *  sqrt(-I) =  N
           *  sqrt( I) =  I
           *  sqrt( 0) =  0
           *  sqrt(-0) = -0
           *
           * Return a new BigNumber whose value is the square root of the value of
           * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE.
           */
          P['squareRoot'] = P['sqrt'] = function () {
              var estimate, r, approx,
                  x = this,
                  xc = x['c'],
                  i = x['s'],
                  e = x['e'],
                  half = new BigNumber('0.5');
  
              // Negative/NaN/Infinity/zero?
              if ( i !== 1 || !xc || !xc[0] ) {
                  return new BigNumber( !i || i < 0 && ( !xc || xc[0] )
                      ? NaN
                      : xc ? x : 1 / 0 )
              }
  
              // Estimate.
              i = Math.sqrt( x['toS']() );
  
              // Math.sqrt underflow/overflow?
              // Pass x to Math.sqrt as integer, then adjust the exponent of the result.
              if ( i == 0 || i == 1 / 0 ) {
                  estimate = xc.join('');
  
                  if ( !( estimate.length + e & 1 ) ) {
                      estimate += '0'
                  }
  
                  r = new BigNumber( Math.sqrt(estimate).toString() );
                  r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 )
              } else {
                  r = new BigNumber( i.toString() )
              }
  
              i = r['e'] + ( DECIMAL_PLACES += 4 );
  
              // Newton-Raphson loop.
              do {
                  approx = r;
                  r = half['times']( approx['plus']( x['div'](approx) ) )
              } while ( approx['c'].slice( 0, i ).join('') !==
              r['c'].slice( 0, i ).join('') );
  
              rnd( r, DECIMAL_PLACES -= 4, 10 );
  
              return r
          };
  
  
          /*
           *  n * 0 = 0
           *  n * N = N
           *  n * I = I
           *  0 * n = 0
           *  0 * 0 = 0
           *  0 * N = N
           *  0 * I = N
           *  N * n = N
           *  N * 0 = N
           *  N * N = N
           *  N * I = N
           *  I * n = I
           *  I * 0 = N
           *  I * N = N
           *  I * I = I
           *
           * Return a new BigNumber whose value is the value of this BigNumber times
           * the value of BigNumber(y, b).
           */
          P['times'] = function ( y, b ) {
              var c,
                  x = this,
                  xc = x['c'],
                  yc = ( id = 11, y = new BigNumber( y, b ) )['c'],
                  i = x['e'],
                  j = y['e'],
                  a = x['s'];
  
              y['s'] = a == ( b = y['s'] ) ? 1 : -1;
  
              // Either NaN/Infinity/0?
              if ( !i && ( !xc || !xc[0] ) || !j && ( !yc || !yc[0] ) ) {
  
                  // Either NaN?
                  return new BigNumber( !a || !b ||
  
                  // x is 0 and y is Infinity  or  y is 0 and x is Infinity?
                  xc && !xc[0] && !yc || yc && !yc[0] && !xc
  
                      // Return NaN.
                      ? NaN
  
                      // Either Infinity?
                      : !xc || !yc
  
                      // Return +-Infinity.
                      ? y['s'] / 0
  
                      // x or y is 0. Return +-0.
                      : y['s'] * 0 )
              }
              y['e'] = i + j;
  
              if ( ( a = xc.length ) < ( b = yc.length ) ) {
                  c = xc, xc = yc, yc = c, j = a, a = b, b = j
              }
  
              for ( j = a + b, c = []; j--; c.push(0) ) {
              }
  
              // Multiply!
              for ( i = b - 1; i > -1; i-- ) {
  
                  for ( b = 0, j = a + i;
                        j > i;
                        b = c[j] + yc[i] * xc[j - i - 1] + b,
                            c[j--] = b % 10 | 0,
                            b = b / 10 | 0 ) {
                  }
  
                  if ( b ) {
                      c[j] = ( c[j] + b ) % 10
                  }
              }
  
              b && ++y['e'];
  
              // Remove any leading zero.
              !c[0] && c.shift();
  
              // Remove trailing zeros.
              for ( j = c.length; !c[--j]; c.pop() ) {
              }
  
              // No zero check needed as only x * 0 == 0 etc.
  
              // Overflow?
              y['c'] = y['e'] > MAX_EXP
  
                  // Infinity.
                  ? ( y['e'] = null )
  
                  // Underflow?
                  : y['e'] < MIN_EXP
  
                  // Zero.
                  ? [ y['e'] = 0 ]
  
                  // Neither.
                  : c;
  
              return y
          };
  
  
          /*
           * Return a string representing the value of this BigNumber in exponential
           * notation to dp fixed decimal places and rounded using ROUNDING_MODE if
           * necessary.
           *
           * [dp] {number} Integer, 0 to MAX inclusive.
           */
          P['toExponential'] = P['toE'] = function ( dp ) {
  
              return format( this,
                  ( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) ||
  
                  /*
                   * Include '&& dp !== 0' because with Opera -0 == parseFloat(-0) is
                   * false, despite -0 == parseFloat('-0') && 0 == -0 being true.
                   */
                  parse(dp) != dp && dp !== 0 ) &&
  
                  // 'toE() decimal places not an integer: {dp}'
                  // 'toE() decimal places out of range: {dp}'
                  !ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c']
                      ? this['c'].length - 1
                      : dp | 0, 1 )
          };
  
  
          /*
           * Return a string representing the value of this BigNumber in normal
           * notation to dp fixed decimal places and rounded using ROUNDING_MODE if
           * necessary.
           *
           * Note: as with JavaScript's number type, (-0).toFixed(0) is '0',
           * but e.g. (-0.00001).toFixed(0) is '-0'.
           *
           * [dp] {number} Integer, 0 to MAX inclusive.
           */
          P['toFixed'] = P['toF'] = function ( dp ) {
              var n, str, d,
                  x = this;
  
              if ( !( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) ||
                  parse(dp) != dp && dp !== 0 ) &&
  
                  // 'toF() decimal places not an integer: {dp}'
                  // 'toF() decimal places out of range: {dp}'
                  !ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) {
                  d = x['e'] + ( dp | 0 )
              }
  
              n = TO_EXP_NEG, dp = TO_EXP_POS;
              TO_EXP_NEG = -( TO_EXP_POS = 1 / 0 );
  
              // Note: str is initially undefined.
              if ( d == str ) {
                  str = x['toS']()
              } else {
                  str = format( x, d );
  
                  // (-0).toFixed() is '0', but (-0.1).toFixed() is '-0'.
                  // (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
                  if ( x['s'] < 0 && x['c'] ) {
  
                      // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString.
                      if ( !x['c'][0] ) {
                          str = str.replace(/^-/, '')
  
                          // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign.
                      } else if ( str.indexOf('-') < 0 ) {
                          str = '-' + str
                      }
                  }
              }
              TO_EXP_NEG = n, TO_EXP_POS = dp;
  
              return str
          };
  
  
          /*
           * Return a string array representing the value of this BigNumber as a
           * simple fraction with an integer numerator and an integer denominator.
           * The denominator will be a positive non-zero value less than or equal to
           * the specified maximum denominator. If a maximum denominator is not
           * specified, the denominator will be the lowest value necessary to
           * represent the number exactly.
           *
           * [maxD] {number|string|BigNumber} Integer >= 1 and < Infinity.
           */
          P['toFraction'] = P['toFr'] = function ( maxD ) {
              var q, frac, n0, d0, d2, n, e,
                  n1 = d0 = new BigNumber(ONE),
                  d1 = n0 = new BigNumber('0'),
                  x = this,
                  xc = x['c'],
                  exp = MAX_EXP,
                  dp = DECIMAL_PLACES,
                  rm = ROUNDING_MODE,
                  d = new BigNumber(ONE);
  
              // NaN, Infinity.
              if ( !xc ) {
                  return x['toS']()
              }
  
              e = d['e'] = xc.length - x['e'] - 1;
  
              // If max denominator is undefined or null...
              if ( maxD == null ||
  
                  // or NaN...
                  ( !( id = 12, n = new BigNumber(maxD) )['s'] ||
  
                  // or less than 1, or Infinity...
                  ( outOfRange = n['cmp'](n1) < 0 || !n['c'] ) ||
  
                  // or not an integer...
                  ( ERRORS && n['e'] < n['c'].length - 1 ) ) &&
  
                  // 'toFr() max denominator not an integer: {maxD}'
                  // 'toFr() max denominator out of range: {maxD}'
                  !ifExceptionsThrow( maxD, 'max denominator', 'toFr' ) ||
  
                  // or greater than the maxD needed to specify the value exactly...
                  ( maxD = n )['cmp'](d) > 0 ) {
  
                  // d is e.g. 10, 100, 1000, 10000... , n1 is 1.
                  maxD = e > 0 ? d : n1
              }
  
              MAX_EXP = 1 / 0;
              n = new BigNumber( xc.join('') );
  
              for ( DECIMAL_PLACES = 0, ROUNDING_MODE = 1; ; )  {
                  q = n['div'](d);
                  d2 = d0['plus']( q['times'](d1) );
  
                  if ( d2['cmp'](maxD) == 1 ) {
                      break
                  }
  
                  d0 = d1, d1 = d2;
  
                  n1 = n0['plus']( q['times']( d2 = n1 ) );
                  n0 = d2;
  
                  d = n['minus']( q['times']( d2 = d ) );
                  n = d2
              }
  
              d2 = maxD['minus'](d0)['div'](d1);
              n0 = n0['plus']( d2['times'](n1) );
              d0 = d0['plus']( d2['times'](d1) );
  
              n0['s'] = n1['s'] = x['s'];
  
              DECIMAL_PLACES = e * 2;
              ROUNDING_MODE = rm;
  
              // Determine which fraction is closer to x, n0 / d0 or n1 / d1?
              frac = n1['div'](d1)['minus'](x)['abs']()['cmp'](
                  n0['div'](d0)['minus'](x)['abs']() ) < 1
                  ? [ n1['toS'](), d1['toS']() ]
                  : [ n0['toS'](), d0['toS']() ];
  
              return MAX_EXP = exp, DECIMAL_PLACES = dp, frac
          };
  
  
          /*
           * Return a string representing the value of this BigNumber to sd significant
           * digits and rounded using ROUNDING_MODE if necessary.
           * If sd is less than the number of digits necessary to represent the integer
           * part of the value in normal notation, then use exponential notation.
           *
           * sd {number} Integer, 1 to MAX inclusive.
           */
          P['toPrecision'] = P['toP'] = function ( sd ) {
  
              /*
               * ERRORS true: Throw if sd not undefined, null or an integer in range.
               * ERRORS false: Ignore sd if not a number or not in range.
               * Truncate non-integers.
               */
              return sd == null || ( ( ( outOfRange = sd < 1 || sd > MAX ) ||
              parse(sd) != sd ) &&
  
              // 'toP() precision not an integer: {sd}'
              // 'toP() precision out of range: {sd}'
              !ifExceptionsThrow( sd, 'precision', 'toP' ) )
                  ? this['toS']()
                  : format( this, --sd | 0, 2 )
          };
  
  
          /*
           * Return a string representing the value of this BigNumber in base b, or
           * base 10 if b is omitted. If a base is specified, including base 10,
           * round according to DECIMAL_PLACES and ROUNDING_MODE.
           * If a base is not specified, and this BigNumber has a positive exponent
           * that is equal to or greater than TO_EXP_POS, or a negative exponent equal
           * to or less than TO_EXP_NEG, return exponential notation.
           *
           * [b] {number} Integer, 2 to 36 inclusive.
           */
          P['toString'] = P['toS'] = function ( b ) {
              var u, str, strL,
                  x = this,
                  xe = x['e'];
  
              // Infinity or NaN?
              if ( xe === null ) {
                  str = x['s'] ? 'Infinity' : 'NaN'
  
                  // Exponential format?
              } else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) {
                  return format( x, x['c'].length - 1, 1 )
              } else {
                  str = x['c'].join('');
  
                  // Negative exponent?
                  if ( xe < 0 ) {
  
                      // Prepend zeros.
                      for ( ; ++xe; str = '0' + str ) {
                      }
                      str = '0.' + str
  
                      // Positive exponent?
                  } else if ( strL = str.length, xe > 0 ) {
  
                      if ( ++xe > strL ) {
  
                          // Append zeros.
                          for ( xe -= strL; xe-- ; str += '0' ) {
                          }
                      } else if ( xe < strL ) {
                          str = str.slice( 0, xe ) + '.' + str.slice(xe)
                      }
  
                      // Exponent zero.
                  } else {
                      if ( u = str.charAt(0), strL > 1 ) {
                          str = u + '.' + str.slice(1)
  
                          // Avoid '-0'
                      } else if ( u == '0' ) {
                          return u
                      }
                  }
  
                  if ( b != null ) {
  
                      if ( !( outOfRange = !( b >= 2 && b <= 36 ) ) &&
                          ( b == (b | 0) || !ERRORS ) ) {
                          str = convert( str, b | 0, 10, x['s'] );
  
                          // Avoid '-0'
                          if ( str == '0' ) {
                              return str
                          }
                      } else {
  
                          // 'toS() base not an integer: {b}'
                          // 'toS() base out of range: {b}'
                          ifExceptionsThrow( b, 'base', 'toS' )
                      }
                  }
  
              }
  
              return x['s'] < 0 ? '-' + str : str
          };
  
  
          /*
           * Return as toString, but do not accept a base argument.
           */
          P['valueOf'] = function () {
              return this['toS']()
          };
  
  
          // Add aliases for BigDecimal methods.
          //P['add'] = P['plus'];
          //P['subtract'] = P['minus'];
          //P['multiply'] = P['times'];
          //P['divide'] = P['div'];
          //P['remainder'] = P['mod'];
          //P['compareTo'] = P['cmp'];
          //P['negate'] = P['neg'];
  
  
          // EXPORT
  
  
          // Node and other CommonJS-like environments that support module.exports.
          if ( typeof module !== 'undefined' && module.exports ) {
              module.exports = BigNumber
  
              //AMD.
          } else if ( typeof define == 'function' && define.amd ) {
              define( function () {
                  return BigNumber
              })
  
              //Browser.
          } else {
              global['BigNumber'] = BigNumber
          }
  
      })( this );
  
  
  },{}],3:[function(require,module,exports){
      var BigNumber = require('bignumber.js');
  
      /*
       json2.js
       2013-05-26
  
       Public Domain.
  
       NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  
       See http://www.JSON.org/js.html
  
  
       This code should be minified before deployment.
       See http://javascript.crockford.com/jsmin.html
  
       USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
       NOT CONTROL.
  
  
       This file creates a global JSON object containing two methods: stringify
       and parse.
  
       JSON.stringify(value, replacer, space)
       value       any JavaScript value, usually an object or array.
  
       replacer    an optional parameter that determines how object
       values are stringified for objects. It can be a
       function or an array of strings.
  
       space       an optional parameter that specifies the indentation
       of nested structures. If it is omitted, the text will
       be packed without extra whitespace. If it is a number,
       it will specify the number of spaces to indent at each
       level. If it is a string (such as '\t' or '&nbsp;'),
       it contains the characters used to indent at each level.
  
       This method produces a JSON text from a JavaScript value.
  
       When an object value is found, if the object contains a toJSON
       method, its toJSON method will be called and the result will be
       stringified. A toJSON method does not serialize: it returns the
       value represented by the name/value pair that should be serialized,
       or undefined if nothing should be serialized. The toJSON method
       will be passed the key associated with the value, and this will be
       bound to the value
  
       For example, this would serialize Dates as ISO strings.
  
       Date.prototype.toJSON = function (key) {
       function f(n) {
       // Format integers to have at least two digits.
       return n < 10 ? '0' + n : n;
       }
  
       return this.getUTCFullYear()   + '-' +
       f(this.getUTCMonth() + 1) + '-' +
       f(this.getUTCDate())      + 'T' +
       f(this.getUTCHours())     + ':' +
       f(this.getUTCMinutes())   + ':' +
       f(this.getUTCSeconds())   + 'Z';
       };
  
       You can provide an optional replacer method. It will be passed the
       key and value of each member, with this bound to the containing
       object. The value that is returned from your method will be
       serialized. If your method returns undefined, then the member will
       be excluded from the serialization.
  
       If the replacer parameter is an array of strings, then it will be
       used to select the members to be serialized. It filters the results
       such that only members with keys listed in the replacer array are
       stringified.
  
       Values that do not have JSON representations, such as undefined or
       functions, will not be serialized. Such values in objects will be
       dropped; in arrays they will be replaced with null. You can use
       a replacer function to replace those with JSON values.
       JSON.stringify(undefined) returns undefined.
  
       The optional space parameter produces a stringification of the
       value that is filled with line breaks and indentation to make it
       easier to read.
  
       If the space parameter is a non-empty string, then that string will
       be used for indentation. If the space parameter is a number, then
       the indentation will be that many spaces.
  
       Example:
  
       text = JSON.stringify(['e', {pluribus: 'unum'}]);
       // text is '["e",{"pluribus":"unum"}]'
  
  
       text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
       // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
  
       text = JSON.stringify([new Date()], function (key, value) {
       return this[key] instanceof Date ?
       'Date(' + this[key] + ')' : value;
       });
       // text is '["Date(---current time---)"]'
  
  
       JSON.parse(text, reviver)
       This method parses a JSON text to produce an object or array.
       It can throw a SyntaxError exception.
  
       The optional reviver parameter is a function that can filter and
       transform the results. It receives each of the keys and values,
       and its return value is used instead of the original value.
       If it returns what it received, then the structure is not modified.
       If it returns undefined then the member is deleted.
  
       Example:
  
       // Parse the text. Values that look like ISO date strings will
       // be converted to Date objects.
  
       myData = JSON.parse(text, function (key, value) {
       var a;
       if (typeof value === 'string') {
       a =
       /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
       if (a) {
       return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
       +a[5], +a[6]));
       }
       }
       return value;
       });
  
       myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
       var d;
       if (typeof value === 'string' &&
       value.slice(0, 5) === 'Date(' &&
       value.slice(-1) === ')') {
       d = new Date(value.slice(5, -1));
       if (d) {
       return d;
       }
       }
       return value;
       });
  
  
       This is a reference implementation. You are free to copy, modify, or
       redistribute.
       */
  
      /*jslint evil: true, regexp: true */
  
      /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
       call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
       getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
       lastIndex, length, parse, prototype, push, replace, slice, stringify,
       test, toJSON, toString, valueOf
       */
  
  
  // Create a JSON object only if one does not already exist. We create the
  // methods in a closure to avoid creating global variables.
  
      var JSON = module.exports;
  
      (function () {
          'use strict';
  
          function f(n) {
              // Format integers to have at least two digits.
              return n < 10 ? '0' + n : n;
          }
  
          var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
              escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
              gap,
              indent,
              meta = {    // table of character substitutions
                  '\b': '\\b',
                  '\t': '\\t',
                  '\n': '\\n',
                  '\f': '\\f',
                  '\r': '\\r',
                  '"' : '\\"',
                  '\\': '\\\\'
              },
              rep;
  
  
          function quote(string) {
  
  // If the string contains no control characters, no quote characters, and no
  // backslash characters, then we can safely slap some quotes around it.
  // Otherwise we must also replace the offending characters with safe escape
  // sequences.
  
              escapable.lastIndex = 0;
              return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
                  var c = meta[a];
                  return typeof c === 'string'
                      ? c
                      : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
              }) + '"' : '"' + string + '"';
          }
  
  
          function str(key, holder) {
  
  // Produce a string from holder[key].
  
              var i,          // The loop counter.
                  k,          // The member key.
                  v,          // The member value.
                  length,
                  mind = gap,
                  partial,
                  value = holder[key];
  
  // If the value has a toJSON method, call it to obtain a replacement value.
  
              if (value && typeof value === 'object' &&
                  typeof value.toJSON === 'function') {
                  value = value.toJSON(key);
              }
  
  // If we were called with a replacer function, then call the replacer to
  // obtain a replacement value.
  
              if (typeof rep === 'function') {
                  value = rep.call(holder, key, value);
              }
  
  // What happens next depends on the value's type.
  
              switch (typeof value) {
                  case 'string':
                      return quote(value);
  
                  case 'number':
  
  // JSON numbers must be finite. Encode non-finite numbers as null.
  
                      return isFinite(value) ? String(value) : 'null';
  
                  case 'boolean':
                  case 'null':
  
  // If the value is a boolean or null, convert it to a string. Note:
  // typeof null does not produce 'null'. The case is included here in
  // the remote chance that this gets fixed someday.
  
                      return String(value);
  
  // If the type is 'object', we might be dealing with an object or an array or
  // null.
  
                  case 'object':
  
  // Due to a specification blunder in ECMAScript, typeof null is 'object',
  // so watch out for that case.
  
                      if (!value) {
                          return 'null';
                      }
  
                      if (value instanceof BigNumber)
                          return value.toString();
  
  // Make an array to hold the partial results of stringifying this object value.
  
                      gap += indent;
                      partial = [];
  
  // Is the value an array?
  
                      if (Object.prototype.toString.apply(value) === '[object Array]') {
  
  // The value is an array. Stringify every element. Use null as a placeholder
  // for non-JSON values.
  
                          length = value.length;
                          for (i = 0; i < length; i += 1) {
                              partial[i] = str(i, value) || 'null';
                          }
  
  // Join all of the elements together, separated with commas, and wrap them in
  // brackets.
  
                          v = partial.length === 0
                              ? '[]'
                              : gap
                              ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
                              : '[' + partial.join(',') + ']';
                          gap = mind;
                          return v;
                      }
  
  // If the replacer is an array, use it to select the members to be stringified.
  
                      if (rep && typeof rep === 'object') {
                          length = rep.length;
                          for (i = 0; i < length; i += 1) {
                              if (typeof rep[i] === 'string') {
                                  k = rep[i];
                                  v = str(k, value);
                                  if (v) {
                                      partial.push(quote(k) + (gap ? ': ' : ':') + v);
                                  }
                              }
                          }
                      } else {
  
  // Otherwise, iterate through all of the keys in the object.
  
                          for (k in value) {
                              if (Object.prototype.hasOwnProperty.call(value, k)) {
                                  v = str(k, value);
                                  if (v) {
                                      partial.push(quote(k) + (gap ? ': ' : ':') + v);
                                  }
                              }
                          }
                      }
  
  // Join all of the member texts together, separated with commas,
  // and wrap them in braces.
  
                      v = partial.length === 0
                          ? '{}'
                          : gap
                          ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
                          : '{' + partial.join(',') + '}';
                      gap = mind;
                      return v;
              }
          }
  
  // If the JSON object does not yet have a stringify method, give it one.
  
          if (typeof JSON.stringify !== 'function') {
              JSON.stringify = function (value, replacer, space) {
  
  // The stringify method takes a value and an optional replacer, and an optional
  // space parameter, and returns a JSON text. The replacer can be a function
  // that can replace values, or an array of strings that will select the keys.
  // A default replacer method can be provided. Use of the space parameter can
  // produce text that is more easily readable.
  
                  var i;
                  gap = '';
                  indent = '';
  
  // If the space parameter is a number, make an indent string containing that
  // many spaces.
  
                  if (typeof space === 'number') {
                      for (i = 0; i < space; i += 1) {
                          indent += ' ';
                      }
  
  // If the space parameter is a string, it will be used as the indent string.
  
                  } else if (typeof space === 'string') {
                      indent = space;
                  }
  
  // If there is a replacer, it must be a function or an array.
  // Otherwise, throw an error.
  
                  rep = replacer;
                  if (replacer && typeof replacer !== 'function' &&
                      (typeof replacer !== 'object' ||
                      typeof replacer.length !== 'number')) {
                      throw new Error('JSON.stringify');
                  }
  
  // Make a fake root object containing our value under the key of ''.
  // Return the result of stringifying the value.
  
                  return str('', {'': value});
              };
          }
      }());
  
  },{"bignumber.js":2}],4:[function(require,module,exports){
      window.JSONbig = require('./index.js');
  },{"./index.js":1}]},{},[4])
  ;