mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-27 15:15:50 +00:00
47370 lines
1.3 MiB
47370 lines
1.3 MiB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
(function (Buffer){
|
|
|
|
const codec = require('ripple-binary-codec');
|
|
const addressCodec = require('ripple-address-codec');
|
|
const keyCodec = require('ripple-keypairs');
|
|
|
|
const TOML_PATH = "/.well-known/xrp-ledger.toml";
|
|
|
|
|
|
|
|
//Get the domain and public key from the manifest
|
|
function parseManifest(){
|
|
const manhex = $('#manifest').val()
|
|
|
|
//TODO: throw errors when manifest is malformed or keys are not present
|
|
let man = codec.decode(manhex);
|
|
let buff = new Buffer(man['PublicKey'], 'hex').toJSON().data
|
|
|
|
let domain = hex_to_ascii(man['Domain']);
|
|
let publicKey = addressCodec.encodeNodePublic(buff);
|
|
let publicKeyHex = man['PublicKey'];
|
|
|
|
let message = "[domain-attestation-blob:"+domain+":"+publicKey+"]";
|
|
let attestation = "A59AB577E14A7BEC053752FBFE78C3DED6DCEC81A7C41DF1931BC61742BB4FAEAA0D4F1C1EAE5BC74F6D68A3B26C8A223EA2492A5BD18D51F8AC7F4A97DFBE0C";
|
|
|
|
var verify = keyCodec.verify(ascii_to_hexa(message),attestation,publicKeyHex)
|
|
|
|
//TODO: Go to the domain, check that this public key is there, and check the attestation.
|
|
console.log(domain);
|
|
console.log(publicKey);
|
|
console.log(verify);
|
|
|
|
}
|
|
|
|
function hex_to_ascii(str1)
|
|
{
|
|
var hex = str1.toString();
|
|
var str = '';
|
|
for (var n = 0; n < hex.length; n += 2) {
|
|
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
|
|
}
|
|
return str;
|
|
}
|
|
|
|
function ascii_to_hexa(str)
|
|
{
|
|
var arr1 = [];
|
|
for (var n = 0, l = str.length; n < l; n ++)
|
|
{
|
|
var hex = Number(str.charCodeAt(n)).toString(16);
|
|
arr1.push(hex);
|
|
}
|
|
return arr1.join('');
|
|
}
|
|
|
|
//message: [domain-attestation-blob:mayurbhandary.com]
|
|
|
|
|
|
//TODO: Obtain manifest through form submission
|
|
//attestation="A59AB577E14A7BEC053752FBFE78C3DED6DCEC81A7C41DF1931BC61742BB4FAEAA0D4F1C1EAE5BC74F6D68A3B26C8A223EA2492A5BD18D51F8AC7F4A97DFBE0C"
|
|
//manifest: 24000000017121EDFCADB465692E663A6081B8AE60A5CAA7FC9519B6140B9C9FFDE313A7044CEDC3732103A951D1D042B128BC3253E261719277CBEE7966207C55299DDF9DE08ACCF81C67764730450221009AB0D13B5F333BFA75098F5E8C81638E133D9585973E56E22C9202D4F13E12FE02207B48B2C49B734D78E23AD0C51C98E21F78813D711E465C88A4FBEA37263552A477116D617975726268616E646172792E636F6D7012401EB58B0BACE2E8BBE07D9A2A0FA82BAB21B236DE23FB81F44816921730300038598F4144B85A72206065F1F05563A84997F15A345058CCB07B3D63702F2D760C'
|
|
|
|
//parseManifest('24000000017121EDFCADB465692E663A6081B8AE60A5CAA7FC9519B6140B9C9FFDE313A7044CEDC3732103A951D1D042B128BC3253E261719277CBEE7966207C55299DDF9DE08ACCF81C67764730450221009AB0D13B5F333BFA75098F5E8C81638E133D9585973E56E22C9202D4F13E12FE02207B48B2C49B734D78E23AD0C51C98E21F78813D711E465C88A4FBEA37263552A477116D617975726268616E646172792E636F6D7012401EB58B0BACE2E8BBE07D9A2A0FA82BAB21B236DE23FB81F44816921730300038598F4144B85A72206065F1F05563A84997F15A345058CCB07B3D63702F2D760C');
|
|
|
|
|
|
|
|
function handle_submit(event) {
|
|
event.preventDefault();
|
|
|
|
$('.result-title').show()
|
|
$('#result').show()
|
|
$('#log').empty()
|
|
|
|
parseManifest();
|
|
}
|
|
|
|
$(document).ready(() => {
|
|
$('#manifest-entry').submit(handle_submit)
|
|
})
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"buffer":100,"ripple-address-codec":44,"ripple-binary-codec":54,"ripple-keypairs":81}],2:[function(require,module,exports){
|
|
(function (module, exports) {
|
|
'use strict';
|
|
|
|
// Utils
|
|
function assert (val, msg) {
|
|
if (!val) throw new Error(msg || 'Assertion failed');
|
|
}
|
|
|
|
// Could use `inherits` module, but don't want to move from single file
|
|
// architecture yet.
|
|
function inherits (ctor, superCtor) {
|
|
ctor.super_ = superCtor;
|
|
var TempCtor = function () {};
|
|
TempCtor.prototype = superCtor.prototype;
|
|
ctor.prototype = new TempCtor();
|
|
ctor.prototype.constructor = ctor;
|
|
}
|
|
|
|
// BN
|
|
|
|
function BN (number, base, endian) {
|
|
if (BN.isBN(number)) {
|
|
return number;
|
|
}
|
|
|
|
this.negative = 0;
|
|
this.words = null;
|
|
this.length = 0;
|
|
|
|
// Reduction context
|
|
this.red = null;
|
|
|
|
if (number !== null) {
|
|
if (base === 'le' || base === 'be') {
|
|
endian = base;
|
|
base = 10;
|
|
}
|
|
|
|
this._init(number || 0, base || 10, endian || 'be');
|
|
}
|
|
}
|
|
if (typeof module === 'object') {
|
|
module.exports = BN;
|
|
} else {
|
|
exports.BN = BN;
|
|
}
|
|
|
|
BN.BN = BN;
|
|
BN.wordSize = 26;
|
|
|
|
var Buffer;
|
|
try {
|
|
Buffer = require('buffer').Buffer;
|
|
} catch (e) {
|
|
}
|
|
|
|
BN.isBN = function isBN (num) {
|
|
if (num instanceof BN) {
|
|
return true;
|
|
}
|
|
|
|
return num !== null && typeof num === 'object' &&
|
|
num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
|
|
};
|
|
|
|
BN.max = function max (left, right) {
|
|
if (left.cmp(right) > 0) return left;
|
|
return right;
|
|
};
|
|
|
|
BN.min = function min (left, right) {
|
|
if (left.cmp(right) < 0) return left;
|
|
return right;
|
|
};
|
|
|
|
BN.prototype._init = function init (number, base, endian) {
|
|
if (typeof number === 'number') {
|
|
return this._initNumber(number, base, endian);
|
|
}
|
|
|
|
if (typeof number === 'object') {
|
|
return this._initArray(number, base, endian);
|
|
}
|
|
|
|
if (base === 'hex') {
|
|
base = 16;
|
|
}
|
|
assert(base === (base | 0) && base >= 2 && base <= 36);
|
|
|
|
number = number.toString().replace(/\s+/g, '');
|
|
var start = 0;
|
|
if (number[0] === '-') {
|
|
start++;
|
|
}
|
|
|
|
if (base === 16) {
|
|
this._parseHex(number, start);
|
|
} else {
|
|
this._parseBase(number, base, start);
|
|
}
|
|
|
|
if (number[0] === '-') {
|
|
this.negative = 1;
|
|
}
|
|
|
|
this._strip();
|
|
|
|
if (endian !== 'le') return;
|
|
|
|
this._initArray(this.toArray(), base, endian);
|
|
};
|
|
|
|
BN.prototype._initNumber = function _initNumber (number, base, endian) {
|
|
if (number < 0) {
|
|
this.negative = 1;
|
|
number = -number;
|
|
}
|
|
if (number < 0x4000000) {
|
|
this.words = [number & 0x3ffffff];
|
|
this.length = 1;
|
|
} else if (number < 0x10000000000000) {
|
|
this.words = [
|
|
number & 0x3ffffff,
|
|
(number / 0x4000000) & 0x3ffffff
|
|
];
|
|
this.length = 2;
|
|
} else {
|
|
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
|
this.words = [
|
|
number & 0x3ffffff,
|
|
(number / 0x4000000) & 0x3ffffff,
|
|
1
|
|
];
|
|
this.length = 3;
|
|
}
|
|
|
|
if (endian !== 'le') return;
|
|
|
|
// Reverse the bytes
|
|
this._initArray(this.toArray(), base, endian);
|
|
};
|
|
|
|
BN.prototype._initArray = function _initArray (number, base, endian) {
|
|
// Perhaps a Uint8Array
|
|
assert(typeof number.length === 'number');
|
|
if (number.length <= 0) {
|
|
this.words = [0];
|
|
this.length = 1;
|
|
return this;
|
|
}
|
|
|
|
this.length = Math.ceil(number.length / 3);
|
|
this.words = new Array(this.length);
|
|
for (var i = 0; i < this.length; i++) {
|
|
this.words[i] = 0;
|
|
}
|
|
|
|
var j, w;
|
|
var off = 0;
|
|
if (endian === 'be') {
|
|
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
|
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
|
off += 24;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
j++;
|
|
}
|
|
}
|
|
} else if (endian === 'le') {
|
|
for (i = 0, j = 0; i < number.length; i += 3) {
|
|
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
|
off += 24;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
return this._strip();
|
|
};
|
|
|
|
function parseHex (str, start, end) {
|
|
var r = 0;
|
|
var len = Math.min(str.length, end);
|
|
var z = 0;
|
|
for (var i = start; i < len; i++) {
|
|
var c = str.charCodeAt(i) - 48;
|
|
|
|
r <<= 4;
|
|
|
|
var b;
|
|
|
|
// 'a' - 'f'
|
|
if (c >= 49 && c <= 54) {
|
|
b = c - 49 + 0xa;
|
|
|
|
// 'A' - 'F'
|
|
} else if (c >= 17 && c <= 22) {
|
|
b = c - 17 + 0xa;
|
|
|
|
// '0' - '9'
|
|
} else {
|
|
b = c;
|
|
}
|
|
|
|
r |= b;
|
|
z |= b;
|
|
}
|
|
|
|
assert(!(z & 0xf0), 'Invalid character in ' + str);
|
|
return r;
|
|
}
|
|
|
|
BN.prototype._parseHex = function _parseHex (number, start) {
|
|
// Create possibly bigger array to ensure that it fits the number
|
|
this.length = Math.ceil((number.length - start) / 6);
|
|
this.words = new Array(this.length);
|
|
for (var i = 0; i < this.length; i++) {
|
|
this.words[i] = 0;
|
|
}
|
|
|
|
var j, w;
|
|
// Scan 24-bit chunks and add them to the number
|
|
var off = 0;
|
|
for (i = number.length - 6, j = 0; i >= start; i -= 6) {
|
|
w = parseHex(number, i, i + 6);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
|
|
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
|
off += 24;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
j++;
|
|
}
|
|
}
|
|
if (i + 6 !== start) {
|
|
w = parseHex(number, start, i + 6);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
|
}
|
|
this._strip();
|
|
};
|
|
|
|
function parseBase (str, start, end, mul) {
|
|
var r = 0;
|
|
var b = 0;
|
|
var len = Math.min(str.length, end);
|
|
for (var i = start; i < len; i++) {
|
|
var c = str.charCodeAt(i) - 48;
|
|
|
|
r *= mul;
|
|
|
|
// 'a'
|
|
if (c >= 49) {
|
|
b = c - 49 + 0xa;
|
|
|
|
// 'A'
|
|
} else if (c >= 17) {
|
|
b = c - 17 + 0xa;
|
|
|
|
// '0' - '9'
|
|
} else {
|
|
b = c;
|
|
}
|
|
assert(c >= 0 && b < mul, 'Invalid character');
|
|
r += b;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
BN.prototype._parseBase = function _parseBase (number, base, start) {
|
|
// Initialize as zero
|
|
this.words = [0];
|
|
this.length = 1;
|
|
|
|
// Find length of limb in base
|
|
for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
|
|
limbLen++;
|
|
}
|
|
limbLen--;
|
|
limbPow = (limbPow / base) | 0;
|
|
|
|
var total = number.length - start;
|
|
var mod = total % limbLen;
|
|
var end = Math.min(total, total - mod) + start;
|
|
|
|
var word = 0;
|
|
for (var i = start; i < end; i += limbLen) {
|
|
word = parseBase(number, i, i + limbLen, base);
|
|
|
|
this.imuln(limbPow);
|
|
if (this.words[0] + word < 0x4000000) {
|
|
this.words[0] += word;
|
|
} else {
|
|
this._iaddn(word);
|
|
}
|
|
}
|
|
|
|
if (mod !== 0) {
|
|
var pow = 1;
|
|
word = parseBase(number, i, number.length, base);
|
|
|
|
for (i = 0; i < mod; i++) {
|
|
pow *= base;
|
|
}
|
|
|
|
this.imuln(pow);
|
|
if (this.words[0] + word < 0x4000000) {
|
|
this.words[0] += word;
|
|
} else {
|
|
this._iaddn(word);
|
|
}
|
|
}
|
|
};
|
|
|
|
BN.prototype.copy = function copy (dest) {
|
|
dest.words = new Array(this.length);
|
|
for (var i = 0; i < this.length; i++) {
|
|
dest.words[i] = this.words[i];
|
|
}
|
|
dest.length = this.length;
|
|
dest.negative = this.negative;
|
|
dest.red = this.red;
|
|
};
|
|
|
|
function move (dest, src) {
|
|
dest.words = src.words;
|
|
dest.length = src.length;
|
|
dest.negative = src.negative;
|
|
dest.red = src.red;
|
|
}
|
|
|
|
BN.prototype._move = function _move (dest) {
|
|
move(dest, this);
|
|
};
|
|
|
|
BN.prototype.clone = function clone () {
|
|
var r = new BN(null);
|
|
this.copy(r);
|
|
return r;
|
|
};
|
|
|
|
BN.prototype._expand = function _expand (size) {
|
|
while (this.length < size) {
|
|
this.words[this.length++] = 0;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
// Remove leading `0` from `this`
|
|
BN.prototype._strip = function strip () {
|
|
while (this.length > 1 && this.words[this.length - 1] === 0) {
|
|
this.length--;
|
|
}
|
|
return this._normSign();
|
|
};
|
|
|
|
BN.prototype._normSign = function _normSign () {
|
|
// -0 = 0
|
|
if (this.length === 1 && this.words[0] === 0) {
|
|
this.negative = 0;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
// Check Symbol.for because not everywhere where Symbol defined
|
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
|
|
if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') {
|
|
BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect;
|
|
} else {
|
|
BN.prototype.inspect = inspect;
|
|
}
|
|
|
|
function inspect () {
|
|
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
|
|
}
|
|
|
|
/*
|
|
|
|
var zeros = [];
|
|
var groupSizes = [];
|
|
var groupBases = [];
|
|
|
|
var s = '';
|
|
var i = -1;
|
|
while (++i < BN.wordSize) {
|
|
zeros[i] = s;
|
|
s += '0';
|
|
}
|
|
groupSizes[0] = 0;
|
|
groupSizes[1] = 0;
|
|
groupBases[0] = 0;
|
|
groupBases[1] = 0;
|
|
var base = 2 - 1;
|
|
while (++base < 36 + 1) {
|
|
var groupSize = 0;
|
|
var groupBase = 1;
|
|
while (groupBase < (1 << BN.wordSize) / base) {
|
|
groupBase *= base;
|
|
groupSize += 1;
|
|
}
|
|
groupSizes[base] = groupSize;
|
|
groupBases[base] = groupBase;
|
|
}
|
|
|
|
*/
|
|
|
|
var zeros = [
|
|
'',
|
|
'0',
|
|
'00',
|
|
'000',
|
|
'0000',
|
|
'00000',
|
|
'000000',
|
|
'0000000',
|
|
'00000000',
|
|
'000000000',
|
|
'0000000000',
|
|
'00000000000',
|
|
'000000000000',
|
|
'0000000000000',
|
|
'00000000000000',
|
|
'000000000000000',
|
|
'0000000000000000',
|
|
'00000000000000000',
|
|
'000000000000000000',
|
|
'0000000000000000000',
|
|
'00000000000000000000',
|
|
'000000000000000000000',
|
|
'0000000000000000000000',
|
|
'00000000000000000000000',
|
|
'000000000000000000000000',
|
|
'0000000000000000000000000'
|
|
];
|
|
|
|
var groupSizes = [
|
|
0, 0,
|
|
25, 16, 12, 11, 10, 9, 8,
|
|
8, 7, 7, 7, 7, 6, 6,
|
|
6, 6, 6, 6, 6, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5
|
|
];
|
|
|
|
var groupBases = [
|
|
0, 0,
|
|
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
|
|
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
|
|
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
|
|
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
|
|
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
|
|
];
|
|
|
|
BN.prototype.toString = function toString (base, padding) {
|
|
base = base || 10;
|
|
padding = padding | 0 || 1;
|
|
|
|
var out;
|
|
if (base === 16 || base === 'hex') {
|
|
out = '';
|
|
var off = 0;
|
|
var carry = 0;
|
|
for (var i = 0; i < this.length; i++) {
|
|
var w = this.words[i];
|
|
var word = (((w << off) | carry) & 0xffffff).toString(16);
|
|
carry = (w >>> (24 - off)) & 0xffffff;
|
|
if (carry !== 0 || i !== this.length - 1) {
|
|
out = zeros[6 - word.length] + word + out;
|
|
} else {
|
|
out = word + out;
|
|
}
|
|
off += 2;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
i--;
|
|
}
|
|
}
|
|
if (carry !== 0) {
|
|
out = carry.toString(16) + out;
|
|
}
|
|
while (out.length % padding !== 0) {
|
|
out = '0' + out;
|
|
}
|
|
if (this.negative !== 0) {
|
|
out = '-' + out;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
if (base === (base | 0) && base >= 2 && base <= 36) {
|
|
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
|
|
var groupSize = groupSizes[base];
|
|
// var groupBase = Math.pow(base, groupSize);
|
|
var groupBase = groupBases[base];
|
|
out = '';
|
|
var c = this.clone();
|
|
c.negative = 0;
|
|
while (!c.isZero()) {
|
|
var r = c.modrn(groupBase).toString(base);
|
|
c = c.idivn(groupBase);
|
|
|
|
if (!c.isZero()) {
|
|
out = zeros[groupSize - r.length] + r + out;
|
|
} else {
|
|
out = r + out;
|
|
}
|
|
}
|
|
if (this.isZero()) {
|
|
out = '0' + out;
|
|
}
|
|
while (out.length % padding !== 0) {
|
|
out = '0' + out;
|
|
}
|
|
if (this.negative !== 0) {
|
|
out = '-' + out;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
assert(false, 'Base should be between 2 and 36');
|
|
};
|
|
|
|
BN.prototype.toNumber = function toNumber () {
|
|
var ret = this.words[0];
|
|
if (this.length === 2) {
|
|
ret += this.words[1] * 0x4000000;
|
|
} else if (this.length === 3 && this.words[2] === 0x01) {
|
|
// NOTE: at this stage it is known that the top bit is set
|
|
ret += 0x10000000000000 + (this.words[1] * 0x4000000);
|
|
} else if (this.length > 2) {
|
|
assert(false, 'Number can only safely store up to 53 bits');
|
|
}
|
|
return (this.negative !== 0) ? -ret : ret;
|
|
};
|
|
|
|
BN.prototype.toJSON = function toJSON () {
|
|
return this.toString(16, 2);
|
|
};
|
|
|
|
if (Buffer) {
|
|
BN.prototype.toBuffer = function toBuffer (endian, length) {
|
|
return this.toArrayLike(Buffer, endian, length);
|
|
};
|
|
}
|
|
|
|
BN.prototype.toArray = function toArray (endian, length) {
|
|
return this.toArrayLike(Array, endian, length);
|
|
};
|
|
|
|
var allocate = function allocate (ArrayType, size) {
|
|
if (ArrayType.allocUnsafe) {
|
|
return ArrayType.allocUnsafe(size);
|
|
}
|
|
return new ArrayType(size);
|
|
};
|
|
|
|
BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
|
|
this._strip();
|
|
|
|
var byteLength = this.byteLength();
|
|
var reqLength = length || Math.max(1, byteLength);
|
|
assert(byteLength <= reqLength, 'byte array longer than desired length');
|
|
assert(reqLength > 0, 'Requested array length <= 0');
|
|
|
|
var res = allocate(ArrayType, reqLength);
|
|
var postfix = endian === 'le' ? 'LE' : 'BE';
|
|
this['_toArrayLike' + postfix](res, byteLength);
|
|
return res;
|
|
};
|
|
|
|
BN.prototype._toArrayLikeLE = function _toArrayLikeLE (res, byteLength) {
|
|
var position = 0;
|
|
var carry = 0;
|
|
|
|
for (var i = 0, shift = 0; i < this.length; i++) {
|
|
var word = (this.words[i] << shift) | carry;
|
|
|
|
res[position++] = word & 0xff;
|
|
if (position < res.length) {
|
|
res[position++] = (word >> 8) & 0xff;
|
|
}
|
|
if (position < res.length) {
|
|
res[position++] = (word >> 16) & 0xff;
|
|
}
|
|
|
|
if (shift === 6) {
|
|
if (position < res.length) {
|
|
res[position++] = (word >> 24) & 0xff;
|
|
}
|
|
carry = 0;
|
|
shift = 0;
|
|
} else {
|
|
carry = word >>> 24;
|
|
shift += 2;
|
|
}
|
|
}
|
|
|
|
if (position < res.length) {
|
|
res[position++] = carry;
|
|
|
|
while (position < res.length) {
|
|
res[position++] = 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
BN.prototype._toArrayLikeBE = function _toArrayLikeBE (res, byteLength) {
|
|
var position = res.length - 1;
|
|
var carry = 0;
|
|
|
|
for (var i = 0, shift = 0; i < this.length; i++) {
|
|
var word = (this.words[i] << shift) | carry;
|
|
|
|
res[position--] = word & 0xff;
|
|
if (position >= 0) {
|
|
res[position--] = (word >> 8) & 0xff;
|
|
}
|
|
if (position >= 0) {
|
|
res[position--] = (word >> 16) & 0xff;
|
|
}
|
|
|
|
if (shift === 6) {
|
|
if (position >= 0) {
|
|
res[position--] = (word >> 24) & 0xff;
|
|
}
|
|
carry = 0;
|
|
shift = 0;
|
|
} else {
|
|
carry = word >>> 24;
|
|
shift += 2;
|
|
}
|
|
}
|
|
|
|
if (position >= 0) {
|
|
res[position--] = carry;
|
|
|
|
while (position >= 0) {
|
|
res[position--] = 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
if (Math.clz32) {
|
|
BN.prototype._countBits = function _countBits (w) {
|
|
return 32 - Math.clz32(w);
|
|
};
|
|
} else {
|
|
BN.prototype._countBits = function _countBits (w) {
|
|
var t = w;
|
|
var r = 0;
|
|
if (t >= 0x1000) {
|
|
r += 13;
|
|
t >>>= 13;
|
|
}
|
|
if (t >= 0x40) {
|
|
r += 7;
|
|
t >>>= 7;
|
|
}
|
|
if (t >= 0x8) {
|
|
r += 4;
|
|
t >>>= 4;
|
|
}
|
|
if (t >= 0x02) {
|
|
r += 2;
|
|
t >>>= 2;
|
|
}
|
|
return r + t;
|
|
};
|
|
}
|
|
|
|
BN.prototype._zeroBits = function _zeroBits (w) {
|
|
// Short-cut
|
|
if (w === 0) return 26;
|
|
|
|
var t = w;
|
|
var r = 0;
|
|
if ((t & 0x1fff) === 0) {
|
|
r += 13;
|
|
t >>>= 13;
|
|
}
|
|
if ((t & 0x7f) === 0) {
|
|
r += 7;
|
|
t >>>= 7;
|
|
}
|
|
if ((t & 0xf) === 0) {
|
|
r += 4;
|
|
t >>>= 4;
|
|
}
|
|
if ((t & 0x3) === 0) {
|
|
r += 2;
|
|
t >>>= 2;
|
|
}
|
|
if ((t & 0x1) === 0) {
|
|
r++;
|
|
}
|
|
return r;
|
|
};
|
|
|
|
// Return number of used bits in a BN
|
|
BN.prototype.bitLength = function bitLength () {
|
|
var w = this.words[this.length - 1];
|
|
var hi = this._countBits(w);
|
|
return (this.length - 1) * 26 + hi;
|
|
};
|
|
|
|
function toBitArray (num) {
|
|
var w = new Array(num.bitLength());
|
|
|
|
for (var bit = 0; bit < w.length; bit++) {
|
|
var off = (bit / 26) | 0;
|
|
var wbit = bit % 26;
|
|
|
|
w[bit] = (num.words[off] >>> wbit) & 0x01;
|
|
}
|
|
|
|
return w;
|
|
}
|
|
|
|
// Number of trailing zero bits
|
|
BN.prototype.zeroBits = function zeroBits () {
|
|
if (this.isZero()) return 0;
|
|
|
|
var r = 0;
|
|
for (var i = 0; i < this.length; i++) {
|
|
var b = this._zeroBits(this.words[i]);
|
|
r += b;
|
|
if (b !== 26) break;
|
|
}
|
|
return r;
|
|
};
|
|
|
|
BN.prototype.byteLength = function byteLength () {
|
|
return Math.ceil(this.bitLength() / 8);
|
|
};
|
|
|
|
BN.prototype.toTwos = function toTwos (width) {
|
|
if (this.negative !== 0) {
|
|
return this.abs().inotn(width).iaddn(1);
|
|
}
|
|
return this.clone();
|
|
};
|
|
|
|
BN.prototype.fromTwos = function fromTwos (width) {
|
|
if (this.testn(width - 1)) {
|
|
return this.notn(width).iaddn(1).ineg();
|
|
}
|
|
return this.clone();
|
|
};
|
|
|
|
BN.prototype.isNeg = function isNeg () {
|
|
return this.negative !== 0;
|
|
};
|
|
|
|
// Return negative clone of `this`
|
|
BN.prototype.neg = function neg () {
|
|
return this.clone().ineg();
|
|
};
|
|
|
|
BN.prototype.ineg = function ineg () {
|
|
if (!this.isZero()) {
|
|
this.negative ^= 1;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
// Or `num` with `this` in-place
|
|
BN.prototype.iuor = function iuor (num) {
|
|
while (this.length < num.length) {
|
|
this.words[this.length++] = 0;
|
|
}
|
|
|
|
for (var i = 0; i < num.length; i++) {
|
|
this.words[i] = this.words[i] | num.words[i];
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.ior = function ior (num) {
|
|
assert((this.negative | num.negative) === 0);
|
|
return this.iuor(num);
|
|
};
|
|
|
|
// Or `num` with `this`
|
|
BN.prototype.or = function or (num) {
|
|
if (this.length > num.length) return this.clone().ior(num);
|
|
return num.clone().ior(this);
|
|
};
|
|
|
|
BN.prototype.uor = function uor (num) {
|
|
if (this.length > num.length) return this.clone().iuor(num);
|
|
return num.clone().iuor(this);
|
|
};
|
|
|
|
// And `num` with `this` in-place
|
|
BN.prototype.iuand = function iuand (num) {
|
|
// b = min-length(num, this)
|
|
var b;
|
|
if (this.length > num.length) {
|
|
b = num;
|
|
} else {
|
|
b = this;
|
|
}
|
|
|
|
for (var i = 0; i < b.length; i++) {
|
|
this.words[i] = this.words[i] & num.words[i];
|
|
}
|
|
|
|
this.length = b.length;
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.iand = function iand (num) {
|
|
assert((this.negative | num.negative) === 0);
|
|
return this.iuand(num);
|
|
};
|
|
|
|
// And `num` with `this`
|
|
BN.prototype.and = function and (num) {
|
|
if (this.length > num.length) return this.clone().iand(num);
|
|
return num.clone().iand(this);
|
|
};
|
|
|
|
BN.prototype.uand = function uand (num) {
|
|
if (this.length > num.length) return this.clone().iuand(num);
|
|
return num.clone().iuand(this);
|
|
};
|
|
|
|
// Xor `num` with `this` in-place
|
|
BN.prototype.iuxor = function iuxor (num) {
|
|
// a.length > b.length
|
|
var a;
|
|
var b;
|
|
if (this.length > num.length) {
|
|
a = this;
|
|
b = num;
|
|
} else {
|
|
a = num;
|
|
b = this;
|
|
}
|
|
|
|
for (var i = 0; i < b.length; i++) {
|
|
this.words[i] = a.words[i] ^ b.words[i];
|
|
}
|
|
|
|
if (this !== a) {
|
|
for (; i < a.length; i++) {
|
|
this.words[i] = a.words[i];
|
|
}
|
|
}
|
|
|
|
this.length = a.length;
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.ixor = function ixor (num) {
|
|
assert((this.negative | num.negative) === 0);
|
|
return this.iuxor(num);
|
|
};
|
|
|
|
// Xor `num` with `this`
|
|
BN.prototype.xor = function xor (num) {
|
|
if (this.length > num.length) return this.clone().ixor(num);
|
|
return num.clone().ixor(this);
|
|
};
|
|
|
|
BN.prototype.uxor = function uxor (num) {
|
|
if (this.length > num.length) return this.clone().iuxor(num);
|
|
return num.clone().iuxor(this);
|
|
};
|
|
|
|
// Not ``this`` with ``width`` bitwidth
|
|
BN.prototype.inotn = function inotn (width) {
|
|
assert(typeof width === 'number' && width >= 0);
|
|
|
|
var bytesNeeded = Math.ceil(width / 26) | 0;
|
|
var bitsLeft = width % 26;
|
|
|
|
// Extend the buffer with leading zeroes
|
|
this._expand(bytesNeeded);
|
|
|
|
if (bitsLeft > 0) {
|
|
bytesNeeded--;
|
|
}
|
|
|
|
// Handle complete words
|
|
for (var i = 0; i < bytesNeeded; i++) {
|
|
this.words[i] = ~this.words[i] & 0x3ffffff;
|
|
}
|
|
|
|
// Handle the residue
|
|
if (bitsLeft > 0) {
|
|
this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
|
|
}
|
|
|
|
// And remove leading zeroes
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.notn = function notn (width) {
|
|
return this.clone().inotn(width);
|
|
};
|
|
|
|
// Set `bit` of `this`
|
|
BN.prototype.setn = function setn (bit, val) {
|
|
assert(typeof bit === 'number' && bit >= 0);
|
|
|
|
var off = (bit / 26) | 0;
|
|
var wbit = bit % 26;
|
|
|
|
this._expand(off + 1);
|
|
|
|
if (val) {
|
|
this.words[off] = this.words[off] | (1 << wbit);
|
|
} else {
|
|
this.words[off] = this.words[off] & ~(1 << wbit);
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
// Add `num` to `this` in-place
|
|
BN.prototype.iadd = function iadd (num) {
|
|
var r;
|
|
|
|
// negative + positive
|
|
if (this.negative !== 0 && num.negative === 0) {
|
|
this.negative = 0;
|
|
r = this.isub(num);
|
|
this.negative ^= 1;
|
|
return this._normSign();
|
|
|
|
// positive + negative
|
|
} else if (this.negative === 0 && num.negative !== 0) {
|
|
num.negative = 0;
|
|
r = this.isub(num);
|
|
num.negative = 1;
|
|
return r._normSign();
|
|
}
|
|
|
|
// a.length > b.length
|
|
var a, b;
|
|
if (this.length > num.length) {
|
|
a = this;
|
|
b = num;
|
|
} else {
|
|
a = num;
|
|
b = this;
|
|
}
|
|
|
|
var carry = 0;
|
|
for (var i = 0; i < b.length; i++) {
|
|
r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
|
|
this.words[i] = r & 0x3ffffff;
|
|
carry = r >>> 26;
|
|
}
|
|
for (; carry !== 0 && i < a.length; i++) {
|
|
r = (a.words[i] | 0) + carry;
|
|
this.words[i] = r & 0x3ffffff;
|
|
carry = r >>> 26;
|
|
}
|
|
|
|
this.length = a.length;
|
|
if (carry !== 0) {
|
|
this.words[this.length] = carry;
|
|
this.length++;
|
|
// Copy the rest of the words
|
|
} else if (a !== this) {
|
|
for (; i < a.length; i++) {
|
|
this.words[i] = a.words[i];
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
// Add `num` to `this`
|
|
BN.prototype.add = function add (num) {
|
|
var res;
|
|
if (num.negative !== 0 && this.negative === 0) {
|
|
num.negative = 0;
|
|
res = this.sub(num);
|
|
num.negative ^= 1;
|
|
return res;
|
|
} else if (num.negative === 0 && this.negative !== 0) {
|
|
this.negative = 0;
|
|
res = num.sub(this);
|
|
this.negative = 1;
|
|
return res;
|
|
}
|
|
|
|
if (this.length > num.length) return this.clone().iadd(num);
|
|
|
|
return num.clone().iadd(this);
|
|
};
|
|
|
|
// Subtract `num` from `this` in-place
|
|
BN.prototype.isub = function isub (num) {
|
|
// this - (-num) = this + num
|
|
if (num.negative !== 0) {
|
|
num.negative = 0;
|
|
var r = this.iadd(num);
|
|
num.negative = 1;
|
|
return r._normSign();
|
|
|
|
// -this - num = -(this + num)
|
|
} else if (this.negative !== 0) {
|
|
this.negative = 0;
|
|
this.iadd(num);
|
|
this.negative = 1;
|
|
return this._normSign();
|
|
}
|
|
|
|
// At this point both numbers are positive
|
|
var cmp = this.cmp(num);
|
|
|
|
// Optimization - zeroify
|
|
if (cmp === 0) {
|
|
this.negative = 0;
|
|
this.length = 1;
|
|
this.words[0] = 0;
|
|
return this;
|
|
}
|
|
|
|
// a > b
|
|
var a, b;
|
|
if (cmp > 0) {
|
|
a = this;
|
|
b = num;
|
|
} else {
|
|
a = num;
|
|
b = this;
|
|
}
|
|
|
|
var carry = 0;
|
|
for (var i = 0; i < b.length; i++) {
|
|
r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
|
|
carry = r >> 26;
|
|
this.words[i] = r & 0x3ffffff;
|
|
}
|
|
for (; carry !== 0 && i < a.length; i++) {
|
|
r = (a.words[i] | 0) + carry;
|
|
carry = r >> 26;
|
|
this.words[i] = r & 0x3ffffff;
|
|
}
|
|
|
|
// Copy rest of the words
|
|
if (carry === 0 && i < a.length && a !== this) {
|
|
for (; i < a.length; i++) {
|
|
this.words[i] = a.words[i];
|
|
}
|
|
}
|
|
|
|
this.length = Math.max(this.length, i);
|
|
|
|
if (a !== this) {
|
|
this.negative = 1;
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
// Subtract `num` from `this`
|
|
BN.prototype.sub = function sub (num) {
|
|
return this.clone().isub(num);
|
|
};
|
|
|
|
function smallMulTo (self, num, out) {
|
|
out.negative = num.negative ^ self.negative;
|
|
var len = (self.length + num.length) | 0;
|
|
out.length = len;
|
|
len = (len - 1) | 0;
|
|
|
|
// Peel one iteration (compiler can't do it, because of code complexity)
|
|
var a = self.words[0] | 0;
|
|
var b = num.words[0] | 0;
|
|
var r = a * b;
|
|
|
|
var lo = r & 0x3ffffff;
|
|
var carry = (r / 0x4000000) | 0;
|
|
out.words[0] = lo;
|
|
|
|
for (var k = 1; k < len; k++) {
|
|
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
|
// note that ncarry could be >= 0x3ffffff
|
|
var ncarry = carry >>> 26;
|
|
var rword = carry & 0x3ffffff;
|
|
var maxJ = Math.min(k, num.length - 1);
|
|
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
|
var i = (k - j) | 0;
|
|
a = self.words[i] | 0;
|
|
b = num.words[j] | 0;
|
|
r = a * b + rword;
|
|
ncarry += (r / 0x4000000) | 0;
|
|
rword = r & 0x3ffffff;
|
|
}
|
|
out.words[k] = rword | 0;
|
|
carry = ncarry | 0;
|
|
}
|
|
if (carry !== 0) {
|
|
out.words[k] = carry | 0;
|
|
} else {
|
|
out.length--;
|
|
}
|
|
|
|
return out._strip();
|
|
}
|
|
|
|
// TODO(indutny): it may be reasonable to omit it for users who don't need
|
|
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
|
|
// multiplication (like elliptic secp256k1).
|
|
var comb10MulTo = function comb10MulTo (self, num, out) {
|
|
var a = self.words;
|
|
var b = num.words;
|
|
var o = out.words;
|
|
var c = 0;
|
|
var lo;
|
|
var mid;
|
|
var hi;
|
|
var a0 = a[0] | 0;
|
|
var al0 = a0 & 0x1fff;
|
|
var ah0 = a0 >>> 13;
|
|
var a1 = a[1] | 0;
|
|
var al1 = a1 & 0x1fff;
|
|
var ah1 = a1 >>> 13;
|
|
var a2 = a[2] | 0;
|
|
var al2 = a2 & 0x1fff;
|
|
var ah2 = a2 >>> 13;
|
|
var a3 = a[3] | 0;
|
|
var al3 = a3 & 0x1fff;
|
|
var ah3 = a3 >>> 13;
|
|
var a4 = a[4] | 0;
|
|
var al4 = a4 & 0x1fff;
|
|
var ah4 = a4 >>> 13;
|
|
var a5 = a[5] | 0;
|
|
var al5 = a5 & 0x1fff;
|
|
var ah5 = a5 >>> 13;
|
|
var a6 = a[6] | 0;
|
|
var al6 = a6 & 0x1fff;
|
|
var ah6 = a6 >>> 13;
|
|
var a7 = a[7] | 0;
|
|
var al7 = a7 & 0x1fff;
|
|
var ah7 = a7 >>> 13;
|
|
var a8 = a[8] | 0;
|
|
var al8 = a8 & 0x1fff;
|
|
var ah8 = a8 >>> 13;
|
|
var a9 = a[9] | 0;
|
|
var al9 = a9 & 0x1fff;
|
|
var ah9 = a9 >>> 13;
|
|
var b0 = b[0] | 0;
|
|
var bl0 = b0 & 0x1fff;
|
|
var bh0 = b0 >>> 13;
|
|
var b1 = b[1] | 0;
|
|
var bl1 = b1 & 0x1fff;
|
|
var bh1 = b1 >>> 13;
|
|
var b2 = b[2] | 0;
|
|
var bl2 = b2 & 0x1fff;
|
|
var bh2 = b2 >>> 13;
|
|
var b3 = b[3] | 0;
|
|
var bl3 = b3 & 0x1fff;
|
|
var bh3 = b3 >>> 13;
|
|
var b4 = b[4] | 0;
|
|
var bl4 = b4 & 0x1fff;
|
|
var bh4 = b4 >>> 13;
|
|
var b5 = b[5] | 0;
|
|
var bl5 = b5 & 0x1fff;
|
|
var bh5 = b5 >>> 13;
|
|
var b6 = b[6] | 0;
|
|
var bl6 = b6 & 0x1fff;
|
|
var bh6 = b6 >>> 13;
|
|
var b7 = b[7] | 0;
|
|
var bl7 = b7 & 0x1fff;
|
|
var bh7 = b7 >>> 13;
|
|
var b8 = b[8] | 0;
|
|
var bl8 = b8 & 0x1fff;
|
|
var bh8 = b8 >>> 13;
|
|
var b9 = b[9] | 0;
|
|
var bl9 = b9 & 0x1fff;
|
|
var bh9 = b9 >>> 13;
|
|
|
|
out.negative = self.negative ^ num.negative;
|
|
out.length = 19;
|
|
/* k = 0 */
|
|
lo = Math.imul(al0, bl0);
|
|
mid = Math.imul(al0, bh0);
|
|
mid = (mid + Math.imul(ah0, bl0)) | 0;
|
|
hi = Math.imul(ah0, bh0);
|
|
var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
|
|
w0 &= 0x3ffffff;
|
|
/* k = 1 */
|
|
lo = Math.imul(al1, bl0);
|
|
mid = Math.imul(al1, bh0);
|
|
mid = (mid + Math.imul(ah1, bl0)) | 0;
|
|
hi = Math.imul(ah1, bh0);
|
|
lo = (lo + Math.imul(al0, bl1)) | 0;
|
|
mid = (mid + Math.imul(al0, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh1)) | 0;
|
|
var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
|
|
w1 &= 0x3ffffff;
|
|
/* k = 2 */
|
|
lo = Math.imul(al2, bl0);
|
|
mid = Math.imul(al2, bh0);
|
|
mid = (mid + Math.imul(ah2, bl0)) | 0;
|
|
hi = Math.imul(ah2, bh0);
|
|
lo = (lo + Math.imul(al1, bl1)) | 0;
|
|
mid = (mid + Math.imul(al1, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh1)) | 0;
|
|
lo = (lo + Math.imul(al0, bl2)) | 0;
|
|
mid = (mid + Math.imul(al0, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh2)) | 0;
|
|
var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
|
|
w2 &= 0x3ffffff;
|
|
/* k = 3 */
|
|
lo = Math.imul(al3, bl0);
|
|
mid = Math.imul(al3, bh0);
|
|
mid = (mid + Math.imul(ah3, bl0)) | 0;
|
|
hi = Math.imul(ah3, bh0);
|
|
lo = (lo + Math.imul(al2, bl1)) | 0;
|
|
mid = (mid + Math.imul(al2, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh1)) | 0;
|
|
lo = (lo + Math.imul(al1, bl2)) | 0;
|
|
mid = (mid + Math.imul(al1, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh2)) | 0;
|
|
lo = (lo + Math.imul(al0, bl3)) | 0;
|
|
mid = (mid + Math.imul(al0, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh3)) | 0;
|
|
var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
|
|
w3 &= 0x3ffffff;
|
|
/* k = 4 */
|
|
lo = Math.imul(al4, bl0);
|
|
mid = Math.imul(al4, bh0);
|
|
mid = (mid + Math.imul(ah4, bl0)) | 0;
|
|
hi = Math.imul(ah4, bh0);
|
|
lo = (lo + Math.imul(al3, bl1)) | 0;
|
|
mid = (mid + Math.imul(al3, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh1)) | 0;
|
|
lo = (lo + Math.imul(al2, bl2)) | 0;
|
|
mid = (mid + Math.imul(al2, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh2)) | 0;
|
|
lo = (lo + Math.imul(al1, bl3)) | 0;
|
|
mid = (mid + Math.imul(al1, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh3)) | 0;
|
|
lo = (lo + Math.imul(al0, bl4)) | 0;
|
|
mid = (mid + Math.imul(al0, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh4)) | 0;
|
|
var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
|
|
w4 &= 0x3ffffff;
|
|
/* k = 5 */
|
|
lo = Math.imul(al5, bl0);
|
|
mid = Math.imul(al5, bh0);
|
|
mid = (mid + Math.imul(ah5, bl0)) | 0;
|
|
hi = Math.imul(ah5, bh0);
|
|
lo = (lo + Math.imul(al4, bl1)) | 0;
|
|
mid = (mid + Math.imul(al4, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh1)) | 0;
|
|
lo = (lo + Math.imul(al3, bl2)) | 0;
|
|
mid = (mid + Math.imul(al3, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh2)) | 0;
|
|
lo = (lo + Math.imul(al2, bl3)) | 0;
|
|
mid = (mid + Math.imul(al2, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh3)) | 0;
|
|
lo = (lo + Math.imul(al1, bl4)) | 0;
|
|
mid = (mid + Math.imul(al1, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh4)) | 0;
|
|
lo = (lo + Math.imul(al0, bl5)) | 0;
|
|
mid = (mid + Math.imul(al0, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh5)) | 0;
|
|
var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
|
|
w5 &= 0x3ffffff;
|
|
/* k = 6 */
|
|
lo = Math.imul(al6, bl0);
|
|
mid = Math.imul(al6, bh0);
|
|
mid = (mid + Math.imul(ah6, bl0)) | 0;
|
|
hi = Math.imul(ah6, bh0);
|
|
lo = (lo + Math.imul(al5, bl1)) | 0;
|
|
mid = (mid + Math.imul(al5, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh1)) | 0;
|
|
lo = (lo + Math.imul(al4, bl2)) | 0;
|
|
mid = (mid + Math.imul(al4, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh2)) | 0;
|
|
lo = (lo + Math.imul(al3, bl3)) | 0;
|
|
mid = (mid + Math.imul(al3, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh3)) | 0;
|
|
lo = (lo + Math.imul(al2, bl4)) | 0;
|
|
mid = (mid + Math.imul(al2, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh4)) | 0;
|
|
lo = (lo + Math.imul(al1, bl5)) | 0;
|
|
mid = (mid + Math.imul(al1, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh5)) | 0;
|
|
lo = (lo + Math.imul(al0, bl6)) | 0;
|
|
mid = (mid + Math.imul(al0, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh6)) | 0;
|
|
var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
|
|
w6 &= 0x3ffffff;
|
|
/* k = 7 */
|
|
lo = Math.imul(al7, bl0);
|
|
mid = Math.imul(al7, bh0);
|
|
mid = (mid + Math.imul(ah7, bl0)) | 0;
|
|
hi = Math.imul(ah7, bh0);
|
|
lo = (lo + Math.imul(al6, bl1)) | 0;
|
|
mid = (mid + Math.imul(al6, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh1)) | 0;
|
|
lo = (lo + Math.imul(al5, bl2)) | 0;
|
|
mid = (mid + Math.imul(al5, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh2)) | 0;
|
|
lo = (lo + Math.imul(al4, bl3)) | 0;
|
|
mid = (mid + Math.imul(al4, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh3)) | 0;
|
|
lo = (lo + Math.imul(al3, bl4)) | 0;
|
|
mid = (mid + Math.imul(al3, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh4)) | 0;
|
|
lo = (lo + Math.imul(al2, bl5)) | 0;
|
|
mid = (mid + Math.imul(al2, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh5)) | 0;
|
|
lo = (lo + Math.imul(al1, bl6)) | 0;
|
|
mid = (mid + Math.imul(al1, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh6)) | 0;
|
|
lo = (lo + Math.imul(al0, bl7)) | 0;
|
|
mid = (mid + Math.imul(al0, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh7)) | 0;
|
|
var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
|
|
w7 &= 0x3ffffff;
|
|
/* k = 8 */
|
|
lo = Math.imul(al8, bl0);
|
|
mid = Math.imul(al8, bh0);
|
|
mid = (mid + Math.imul(ah8, bl0)) | 0;
|
|
hi = Math.imul(ah8, bh0);
|
|
lo = (lo + Math.imul(al7, bl1)) | 0;
|
|
mid = (mid + Math.imul(al7, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh1)) | 0;
|
|
lo = (lo + Math.imul(al6, bl2)) | 0;
|
|
mid = (mid + Math.imul(al6, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh2)) | 0;
|
|
lo = (lo + Math.imul(al5, bl3)) | 0;
|
|
mid = (mid + Math.imul(al5, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh3)) | 0;
|
|
lo = (lo + Math.imul(al4, bl4)) | 0;
|
|
mid = (mid + Math.imul(al4, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh4)) | 0;
|
|
lo = (lo + Math.imul(al3, bl5)) | 0;
|
|
mid = (mid + Math.imul(al3, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh5)) | 0;
|
|
lo = (lo + Math.imul(al2, bl6)) | 0;
|
|
mid = (mid + Math.imul(al2, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh6)) | 0;
|
|
lo = (lo + Math.imul(al1, bl7)) | 0;
|
|
mid = (mid + Math.imul(al1, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh7)) | 0;
|
|
lo = (lo + Math.imul(al0, bl8)) | 0;
|
|
mid = (mid + Math.imul(al0, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh8)) | 0;
|
|
var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
|
|
w8 &= 0x3ffffff;
|
|
/* k = 9 */
|
|
lo = Math.imul(al9, bl0);
|
|
mid = Math.imul(al9, bh0);
|
|
mid = (mid + Math.imul(ah9, bl0)) | 0;
|
|
hi = Math.imul(ah9, bh0);
|
|
lo = (lo + Math.imul(al8, bl1)) | 0;
|
|
mid = (mid + Math.imul(al8, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh1)) | 0;
|
|
lo = (lo + Math.imul(al7, bl2)) | 0;
|
|
mid = (mid + Math.imul(al7, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh2)) | 0;
|
|
lo = (lo + Math.imul(al6, bl3)) | 0;
|
|
mid = (mid + Math.imul(al6, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh3)) | 0;
|
|
lo = (lo + Math.imul(al5, bl4)) | 0;
|
|
mid = (mid + Math.imul(al5, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh4)) | 0;
|
|
lo = (lo + Math.imul(al4, bl5)) | 0;
|
|
mid = (mid + Math.imul(al4, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh5)) | 0;
|
|
lo = (lo + Math.imul(al3, bl6)) | 0;
|
|
mid = (mid + Math.imul(al3, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh6)) | 0;
|
|
lo = (lo + Math.imul(al2, bl7)) | 0;
|
|
mid = (mid + Math.imul(al2, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh7)) | 0;
|
|
lo = (lo + Math.imul(al1, bl8)) | 0;
|
|
mid = (mid + Math.imul(al1, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh8)) | 0;
|
|
lo = (lo + Math.imul(al0, bl9)) | 0;
|
|
mid = (mid + Math.imul(al0, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh9)) | 0;
|
|
var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
|
|
w9 &= 0x3ffffff;
|
|
/* k = 10 */
|
|
lo = Math.imul(al9, bl1);
|
|
mid = Math.imul(al9, bh1);
|
|
mid = (mid + Math.imul(ah9, bl1)) | 0;
|
|
hi = Math.imul(ah9, bh1);
|
|
lo = (lo + Math.imul(al8, bl2)) | 0;
|
|
mid = (mid + Math.imul(al8, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh2)) | 0;
|
|
lo = (lo + Math.imul(al7, bl3)) | 0;
|
|
mid = (mid + Math.imul(al7, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh3)) | 0;
|
|
lo = (lo + Math.imul(al6, bl4)) | 0;
|
|
mid = (mid + Math.imul(al6, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh4)) | 0;
|
|
lo = (lo + Math.imul(al5, bl5)) | 0;
|
|
mid = (mid + Math.imul(al5, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh5)) | 0;
|
|
lo = (lo + Math.imul(al4, bl6)) | 0;
|
|
mid = (mid + Math.imul(al4, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh6)) | 0;
|
|
lo = (lo + Math.imul(al3, bl7)) | 0;
|
|
mid = (mid + Math.imul(al3, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh7)) | 0;
|
|
lo = (lo + Math.imul(al2, bl8)) | 0;
|
|
mid = (mid + Math.imul(al2, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh8)) | 0;
|
|
lo = (lo + Math.imul(al1, bl9)) | 0;
|
|
mid = (mid + Math.imul(al1, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh9)) | 0;
|
|
var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
|
|
w10 &= 0x3ffffff;
|
|
/* k = 11 */
|
|
lo = Math.imul(al9, bl2);
|
|
mid = Math.imul(al9, bh2);
|
|
mid = (mid + Math.imul(ah9, bl2)) | 0;
|
|
hi = Math.imul(ah9, bh2);
|
|
lo = (lo + Math.imul(al8, bl3)) | 0;
|
|
mid = (mid + Math.imul(al8, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh3)) | 0;
|
|
lo = (lo + Math.imul(al7, bl4)) | 0;
|
|
mid = (mid + Math.imul(al7, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh4)) | 0;
|
|
lo = (lo + Math.imul(al6, bl5)) | 0;
|
|
mid = (mid + Math.imul(al6, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh5)) | 0;
|
|
lo = (lo + Math.imul(al5, bl6)) | 0;
|
|
mid = (mid + Math.imul(al5, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh6)) | 0;
|
|
lo = (lo + Math.imul(al4, bl7)) | 0;
|
|
mid = (mid + Math.imul(al4, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh7)) | 0;
|
|
lo = (lo + Math.imul(al3, bl8)) | 0;
|
|
mid = (mid + Math.imul(al3, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh8)) | 0;
|
|
lo = (lo + Math.imul(al2, bl9)) | 0;
|
|
mid = (mid + Math.imul(al2, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh9)) | 0;
|
|
var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
|
|
w11 &= 0x3ffffff;
|
|
/* k = 12 */
|
|
lo = Math.imul(al9, bl3);
|
|
mid = Math.imul(al9, bh3);
|
|
mid = (mid + Math.imul(ah9, bl3)) | 0;
|
|
hi = Math.imul(ah9, bh3);
|
|
lo = (lo + Math.imul(al8, bl4)) | 0;
|
|
mid = (mid + Math.imul(al8, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh4)) | 0;
|
|
lo = (lo + Math.imul(al7, bl5)) | 0;
|
|
mid = (mid + Math.imul(al7, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh5)) | 0;
|
|
lo = (lo + Math.imul(al6, bl6)) | 0;
|
|
mid = (mid + Math.imul(al6, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh6)) | 0;
|
|
lo = (lo + Math.imul(al5, bl7)) | 0;
|
|
mid = (mid + Math.imul(al5, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh7)) | 0;
|
|
lo = (lo + Math.imul(al4, bl8)) | 0;
|
|
mid = (mid + Math.imul(al4, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh8)) | 0;
|
|
lo = (lo + Math.imul(al3, bl9)) | 0;
|
|
mid = (mid + Math.imul(al3, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh9)) | 0;
|
|
var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
|
|
w12 &= 0x3ffffff;
|
|
/* k = 13 */
|
|
lo = Math.imul(al9, bl4);
|
|
mid = Math.imul(al9, bh4);
|
|
mid = (mid + Math.imul(ah9, bl4)) | 0;
|
|
hi = Math.imul(ah9, bh4);
|
|
lo = (lo + Math.imul(al8, bl5)) | 0;
|
|
mid = (mid + Math.imul(al8, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh5)) | 0;
|
|
lo = (lo + Math.imul(al7, bl6)) | 0;
|
|
mid = (mid + Math.imul(al7, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh6)) | 0;
|
|
lo = (lo + Math.imul(al6, bl7)) | 0;
|
|
mid = (mid + Math.imul(al6, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh7)) | 0;
|
|
lo = (lo + Math.imul(al5, bl8)) | 0;
|
|
mid = (mid + Math.imul(al5, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh8)) | 0;
|
|
lo = (lo + Math.imul(al4, bl9)) | 0;
|
|
mid = (mid + Math.imul(al4, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh9)) | 0;
|
|
var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
|
|
w13 &= 0x3ffffff;
|
|
/* k = 14 */
|
|
lo = Math.imul(al9, bl5);
|
|
mid = Math.imul(al9, bh5);
|
|
mid = (mid + Math.imul(ah9, bl5)) | 0;
|
|
hi = Math.imul(ah9, bh5);
|
|
lo = (lo + Math.imul(al8, bl6)) | 0;
|
|
mid = (mid + Math.imul(al8, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh6)) | 0;
|
|
lo = (lo + Math.imul(al7, bl7)) | 0;
|
|
mid = (mid + Math.imul(al7, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh7)) | 0;
|
|
lo = (lo + Math.imul(al6, bl8)) | 0;
|
|
mid = (mid + Math.imul(al6, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh8)) | 0;
|
|
lo = (lo + Math.imul(al5, bl9)) | 0;
|
|
mid = (mid + Math.imul(al5, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh9)) | 0;
|
|
var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
|
|
w14 &= 0x3ffffff;
|
|
/* k = 15 */
|
|
lo = Math.imul(al9, bl6);
|
|
mid = Math.imul(al9, bh6);
|
|
mid = (mid + Math.imul(ah9, bl6)) | 0;
|
|
hi = Math.imul(ah9, bh6);
|
|
lo = (lo + Math.imul(al8, bl7)) | 0;
|
|
mid = (mid + Math.imul(al8, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh7)) | 0;
|
|
lo = (lo + Math.imul(al7, bl8)) | 0;
|
|
mid = (mid + Math.imul(al7, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh8)) | 0;
|
|
lo = (lo + Math.imul(al6, bl9)) | 0;
|
|
mid = (mid + Math.imul(al6, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh9)) | 0;
|
|
var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
|
|
w15 &= 0x3ffffff;
|
|
/* k = 16 */
|
|
lo = Math.imul(al9, bl7);
|
|
mid = Math.imul(al9, bh7);
|
|
mid = (mid + Math.imul(ah9, bl7)) | 0;
|
|
hi = Math.imul(ah9, bh7);
|
|
lo = (lo + Math.imul(al8, bl8)) | 0;
|
|
mid = (mid + Math.imul(al8, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh8)) | 0;
|
|
lo = (lo + Math.imul(al7, bl9)) | 0;
|
|
mid = (mid + Math.imul(al7, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh9)) | 0;
|
|
var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
|
|
w16 &= 0x3ffffff;
|
|
/* k = 17 */
|
|
lo = Math.imul(al9, bl8);
|
|
mid = Math.imul(al9, bh8);
|
|
mid = (mid + Math.imul(ah9, bl8)) | 0;
|
|
hi = Math.imul(ah9, bh8);
|
|
lo = (lo + Math.imul(al8, bl9)) | 0;
|
|
mid = (mid + Math.imul(al8, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh9)) | 0;
|
|
var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
|
|
w17 &= 0x3ffffff;
|
|
/* k = 18 */
|
|
lo = Math.imul(al9, bl9);
|
|
mid = Math.imul(al9, bh9);
|
|
mid = (mid + Math.imul(ah9, bl9)) | 0;
|
|
hi = Math.imul(ah9, bh9);
|
|
var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
|
|
w18 &= 0x3ffffff;
|
|
o[0] = w0;
|
|
o[1] = w1;
|
|
o[2] = w2;
|
|
o[3] = w3;
|
|
o[4] = w4;
|
|
o[5] = w5;
|
|
o[6] = w6;
|
|
o[7] = w7;
|
|
o[8] = w8;
|
|
o[9] = w9;
|
|
o[10] = w10;
|
|
o[11] = w11;
|
|
o[12] = w12;
|
|
o[13] = w13;
|
|
o[14] = w14;
|
|
o[15] = w15;
|
|
o[16] = w16;
|
|
o[17] = w17;
|
|
o[18] = w18;
|
|
if (c !== 0) {
|
|
o[19] = c;
|
|
out.length++;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
// Polyfill comb
|
|
if (!Math.imul) {
|
|
comb10MulTo = smallMulTo;
|
|
}
|
|
|
|
function bigMulTo (self, num, out) {
|
|
out.negative = num.negative ^ self.negative;
|
|
out.length = self.length + num.length;
|
|
|
|
var carry = 0;
|
|
var hncarry = 0;
|
|
for (var k = 0; k < out.length - 1; k++) {
|
|
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
|
// note that ncarry could be >= 0x3ffffff
|
|
var ncarry = hncarry;
|
|
hncarry = 0;
|
|
var rword = carry & 0x3ffffff;
|
|
var maxJ = Math.min(k, num.length - 1);
|
|
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
|
var i = k - j;
|
|
var a = self.words[i] | 0;
|
|
var b = num.words[j] | 0;
|
|
var r = a * b;
|
|
|
|
var lo = r & 0x3ffffff;
|
|
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
|
|
lo = (lo + rword) | 0;
|
|
rword = lo & 0x3ffffff;
|
|
ncarry = (ncarry + (lo >>> 26)) | 0;
|
|
|
|
hncarry += ncarry >>> 26;
|
|
ncarry &= 0x3ffffff;
|
|
}
|
|
out.words[k] = rword;
|
|
carry = ncarry;
|
|
ncarry = hncarry;
|
|
}
|
|
if (carry !== 0) {
|
|
out.words[k] = carry;
|
|
} else {
|
|
out.length--;
|
|
}
|
|
|
|
return out._strip();
|
|
}
|
|
|
|
function jumboMulTo (self, num, out) {
|
|
// Temporary disable, see https://github.com/indutny/bn.js/issues/211
|
|
// var fftm = new FFTM();
|
|
// return fftm.mulp(self, num, out);
|
|
return bigMulTo(self, num, out);
|
|
}
|
|
|
|
BN.prototype.mulTo = function mulTo (num, out) {
|
|
var res;
|
|
var len = this.length + num.length;
|
|
if (this.length === 10 && num.length === 10) {
|
|
res = comb10MulTo(this, num, out);
|
|
} else if (len < 63) {
|
|
res = smallMulTo(this, num, out);
|
|
} else if (len < 1024) {
|
|
res = bigMulTo(this, num, out);
|
|
} else {
|
|
res = jumboMulTo(this, num, out);
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
// Cooley-Tukey algorithm for FFT
|
|
// slightly revisited to rely on looping instead of recursion
|
|
|
|
function FFTM (x, y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
|
|
FFTM.prototype.makeRBT = function makeRBT (N) {
|
|
var t = new Array(N);
|
|
var l = BN.prototype._countBits(N) - 1;
|
|
for (var i = 0; i < N; i++) {
|
|
t[i] = this.revBin(i, l, N);
|
|
}
|
|
|
|
return t;
|
|
};
|
|
|
|
// Returns binary-reversed representation of `x`
|
|
FFTM.prototype.revBin = function revBin (x, l, N) {
|
|
if (x === 0 || x === N - 1) return x;
|
|
|
|
var rb = 0;
|
|
for (var i = 0; i < l; i++) {
|
|
rb |= (x & 1) << (l - i - 1);
|
|
x >>= 1;
|
|
}
|
|
|
|
return rb;
|
|
};
|
|
|
|
// Performs "tweedling" phase, therefore 'emulating'
|
|
// behaviour of the recursive algorithm
|
|
FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
|
|
for (var i = 0; i < N; i++) {
|
|
rtws[i] = rws[rbt[i]];
|
|
itws[i] = iws[rbt[i]];
|
|
}
|
|
};
|
|
|
|
FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
|
|
this.permute(rbt, rws, iws, rtws, itws, N);
|
|
|
|
for (var s = 1; s < N; s <<= 1) {
|
|
var l = s << 1;
|
|
|
|
var rtwdf = Math.cos(2 * Math.PI / l);
|
|
var itwdf = Math.sin(2 * Math.PI / l);
|
|
|
|
for (var p = 0; p < N; p += l) {
|
|
var rtwdf_ = rtwdf;
|
|
var itwdf_ = itwdf;
|
|
|
|
for (var j = 0; j < s; j++) {
|
|
var re = rtws[p + j];
|
|
var ie = itws[p + j];
|
|
|
|
var ro = rtws[p + j + s];
|
|
var io = itws[p + j + s];
|
|
|
|
var rx = rtwdf_ * ro - itwdf_ * io;
|
|
|
|
io = rtwdf_ * io + itwdf_ * ro;
|
|
ro = rx;
|
|
|
|
rtws[p + j] = re + ro;
|
|
itws[p + j] = ie + io;
|
|
|
|
rtws[p + j + s] = re - ro;
|
|
itws[p + j + s] = ie - io;
|
|
|
|
/* jshint maxdepth : false */
|
|
if (j !== l) {
|
|
rx = rtwdf * rtwdf_ - itwdf * itwdf_;
|
|
|
|
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
|
|
rtwdf_ = rx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
|
|
var N = Math.max(m, n) | 1;
|
|
var odd = N & 1;
|
|
var i = 0;
|
|
for (N = N / 2 | 0; N; N = N >>> 1) {
|
|
i++;
|
|
}
|
|
|
|
return 1 << i + 1 + odd;
|
|
};
|
|
|
|
FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
|
|
if (N <= 1) return;
|
|
|
|
for (var i = 0; i < N / 2; i++) {
|
|
var t = rws[i];
|
|
|
|
rws[i] = rws[N - i - 1];
|
|
rws[N - i - 1] = t;
|
|
|
|
t = iws[i];
|
|
|
|
iws[i] = -iws[N - i - 1];
|
|
iws[N - i - 1] = -t;
|
|
}
|
|
};
|
|
|
|
FFTM.prototype.normalize13b = function normalize13b (ws, N) {
|
|
var carry = 0;
|
|
for (var i = 0; i < N / 2; i++) {
|
|
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
|
|
Math.round(ws[2 * i] / N) +
|
|
carry;
|
|
|
|
ws[i] = w & 0x3ffffff;
|
|
|
|
if (w < 0x4000000) {
|
|
carry = 0;
|
|
} else {
|
|
carry = w / 0x4000000 | 0;
|
|
}
|
|
}
|
|
|
|
return ws;
|
|
};
|
|
|
|
FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
|
|
var carry = 0;
|
|
for (var i = 0; i < len; i++) {
|
|
carry = carry + (ws[i] | 0);
|
|
|
|
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
|
|
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
|
|
}
|
|
|
|
// Pad with zeroes
|
|
for (i = 2 * len; i < N; ++i) {
|
|
rws[i] = 0;
|
|
}
|
|
|
|
assert(carry === 0);
|
|
assert((carry & ~0x1fff) === 0);
|
|
};
|
|
|
|
FFTM.prototype.stub = function stub (N) {
|
|
var ph = new Array(N);
|
|
for (var i = 0; i < N; i++) {
|
|
ph[i] = 0;
|
|
}
|
|
|
|
return ph;
|
|
};
|
|
|
|
FFTM.prototype.mulp = function mulp (x, y, out) {
|
|
var N = 2 * this.guessLen13b(x.length, y.length);
|
|
|
|
var rbt = this.makeRBT(N);
|
|
|
|
var _ = this.stub(N);
|
|
|
|
var rws = new Array(N);
|
|
var rwst = new Array(N);
|
|
var iwst = new Array(N);
|
|
|
|
var nrws = new Array(N);
|
|
var nrwst = new Array(N);
|
|
var niwst = new Array(N);
|
|
|
|
var rmws = out.words;
|
|
rmws.length = N;
|
|
|
|
this.convert13b(x.words, x.length, rws, N);
|
|
this.convert13b(y.words, y.length, nrws, N);
|
|
|
|
this.transform(rws, _, rwst, iwst, N, rbt);
|
|
this.transform(nrws, _, nrwst, niwst, N, rbt);
|
|
|
|
for (var i = 0; i < N; i++) {
|
|
var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
|
|
iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
|
|
rwst[i] = rx;
|
|
}
|
|
|
|
this.conjugate(rwst, iwst, N);
|
|
this.transform(rwst, iwst, rmws, _, N, rbt);
|
|
this.conjugate(rmws, _, N);
|
|
this.normalize13b(rmws, N);
|
|
|
|
out.negative = x.negative ^ y.negative;
|
|
out.length = x.length + y.length;
|
|
return out._strip();
|
|
};
|
|
|
|
// Multiply `this` by `num`
|
|
BN.prototype.mul = function mul (num) {
|
|
var out = new BN(null);
|
|
out.words = new Array(this.length + num.length);
|
|
return this.mulTo(num, out);
|
|
};
|
|
|
|
// Multiply employing FFT
|
|
BN.prototype.mulf = function mulf (num) {
|
|
var out = new BN(null);
|
|
out.words = new Array(this.length + num.length);
|
|
return jumboMulTo(this, num, out);
|
|
};
|
|
|
|
// In-place Multiplication
|
|
BN.prototype.imul = function imul (num) {
|
|
return this.clone().mulTo(num, this);
|
|
};
|
|
|
|
BN.prototype.imuln = function imuln (num) {
|
|
var isNegNum = num < 0;
|
|
if (isNegNum) num = -num;
|
|
|
|
assert(typeof num === 'number');
|
|
assert(num < 0x4000000);
|
|
|
|
// Carry
|
|
var carry = 0;
|
|
for (var i = 0; i < this.length; i++) {
|
|
var w = (this.words[i] | 0) * num;
|
|
var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
|
|
carry >>= 26;
|
|
carry += (w / 0x4000000) | 0;
|
|
// NOTE: lo is 27bit maximum
|
|
carry += lo >>> 26;
|
|
this.words[i] = lo & 0x3ffffff;
|
|
}
|
|
|
|
if (carry !== 0) {
|
|
this.words[i] = carry;
|
|
this.length++;
|
|
}
|
|
|
|
return isNegNum ? this.ineg() : this;
|
|
};
|
|
|
|
BN.prototype.muln = function muln (num) {
|
|
return this.clone().imuln(num);
|
|
};
|
|
|
|
// `this` * `this`
|
|
BN.prototype.sqr = function sqr () {
|
|
return this.mul(this);
|
|
};
|
|
|
|
// `this` * `this` in-place
|
|
BN.prototype.isqr = function isqr () {
|
|
return this.imul(this.clone());
|
|
};
|
|
|
|
// Math.pow(`this`, `num`)
|
|
BN.prototype.pow = function pow (num) {
|
|
var w = toBitArray(num);
|
|
if (w.length === 0) return new BN(1);
|
|
|
|
// Skip leading zeroes
|
|
var res = this;
|
|
for (var i = 0; i < w.length; i++, res = res.sqr()) {
|
|
if (w[i] !== 0) break;
|
|
}
|
|
|
|
if (++i < w.length) {
|
|
for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
|
|
if (w[i] === 0) continue;
|
|
|
|
res = res.mul(q);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
// Shift-left in-place
|
|
BN.prototype.iushln = function iushln (bits) {
|
|
assert(typeof bits === 'number' && bits >= 0);
|
|
var r = bits % 26;
|
|
var s = (bits - r) / 26;
|
|
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
|
|
var i;
|
|
|
|
if (r !== 0) {
|
|
var carry = 0;
|
|
|
|
for (i = 0; i < this.length; i++) {
|
|
var newCarry = this.words[i] & carryMask;
|
|
var c = ((this.words[i] | 0) - newCarry) << r;
|
|
this.words[i] = c | carry;
|
|
carry = newCarry >>> (26 - r);
|
|
}
|
|
|
|
if (carry) {
|
|
this.words[i] = carry;
|
|
this.length++;
|
|
}
|
|
}
|
|
|
|
if (s !== 0) {
|
|
for (i = this.length - 1; i >= 0; i--) {
|
|
this.words[i + s] = this.words[i];
|
|
}
|
|
|
|
for (i = 0; i < s; i++) {
|
|
this.words[i] = 0;
|
|
}
|
|
|
|
this.length += s;
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.ishln = function ishln (bits) {
|
|
// TODO(indutny): implement me
|
|
assert(this.negative === 0);
|
|
return this.iushln(bits);
|
|
};
|
|
|
|
// Shift-right in-place
|
|
// NOTE: `hint` is a lowest bit before trailing zeroes
|
|
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
|
BN.prototype.iushrn = function iushrn (bits, hint, extended) {
|
|
assert(typeof bits === 'number' && bits >= 0);
|
|
var h;
|
|
if (hint) {
|
|
h = (hint - (hint % 26)) / 26;
|
|
} else {
|
|
h = 0;
|
|
}
|
|
|
|
var r = bits % 26;
|
|
var s = Math.min((bits - r) / 26, this.length);
|
|
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
|
var maskedWords = extended;
|
|
|
|
h -= s;
|
|
h = Math.max(0, h);
|
|
|
|
// Extended mode, copy masked part
|
|
if (maskedWords) {
|
|
for (var i = 0; i < s; i++) {
|
|
maskedWords.words[i] = this.words[i];
|
|
}
|
|
maskedWords.length = s;
|
|
}
|
|
|
|
if (s === 0) {
|
|
// No-op, we should not move anything at all
|
|
} else if (this.length > s) {
|
|
this.length -= s;
|
|
for (i = 0; i < this.length; i++) {
|
|
this.words[i] = this.words[i + s];
|
|
}
|
|
} else {
|
|
this.words[0] = 0;
|
|
this.length = 1;
|
|
}
|
|
|
|
var carry = 0;
|
|
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
|
|
var word = this.words[i] | 0;
|
|
this.words[i] = (carry << (26 - r)) | (word >>> r);
|
|
carry = word & mask;
|
|
}
|
|
|
|
// Push carried bits as a mask
|
|
if (maskedWords && carry !== 0) {
|
|
maskedWords.words[maskedWords.length++] = carry;
|
|
}
|
|
|
|
if (this.length === 0) {
|
|
this.words[0] = 0;
|
|
this.length = 1;
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.ishrn = function ishrn (bits, hint, extended) {
|
|
// TODO(indutny): implement me
|
|
assert(this.negative === 0);
|
|
return this.iushrn(bits, hint, extended);
|
|
};
|
|
|
|
// Shift-left
|
|
BN.prototype.shln = function shln (bits) {
|
|
return this.clone().ishln(bits);
|
|
};
|
|
|
|
BN.prototype.ushln = function ushln (bits) {
|
|
return this.clone().iushln(bits);
|
|
};
|
|
|
|
// Shift-right
|
|
BN.prototype.shrn = function shrn (bits) {
|
|
return this.clone().ishrn(bits);
|
|
};
|
|
|
|
BN.prototype.ushrn = function ushrn (bits) {
|
|
return this.clone().iushrn(bits);
|
|
};
|
|
|
|
// Test if n bit is set
|
|
BN.prototype.testn = function testn (bit) {
|
|
assert(typeof bit === 'number' && bit >= 0);
|
|
var r = bit % 26;
|
|
var s = (bit - r) / 26;
|
|
var q = 1 << r;
|
|
|
|
// Fast case: bit is much higher than all existing words
|
|
if (this.length <= s) return false;
|
|
|
|
// Check bit and return
|
|
var w = this.words[s];
|
|
|
|
return !!(w & q);
|
|
};
|
|
|
|
// Return only lowers bits of number (in-place)
|
|
BN.prototype.imaskn = function imaskn (bits) {
|
|
assert(typeof bits === 'number' && bits >= 0);
|
|
var r = bits % 26;
|
|
var s = (bits - r) / 26;
|
|
|
|
assert(this.negative === 0, 'imaskn works only with positive numbers');
|
|
|
|
if (this.length <= s) {
|
|
return this;
|
|
}
|
|
|
|
if (r !== 0) {
|
|
s++;
|
|
}
|
|
this.length = Math.min(s, this.length);
|
|
|
|
if (r !== 0) {
|
|
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
|
this.words[this.length - 1] &= mask;
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
// Return only lowers bits of number
|
|
BN.prototype.maskn = function maskn (bits) {
|
|
return this.clone().imaskn(bits);
|
|
};
|
|
|
|
// Add plain number `num` to `this`
|
|
BN.prototype.iaddn = function iaddn (num) {
|
|
assert(typeof num === 'number');
|
|
assert(num < 0x4000000);
|
|
if (num < 0) return this.isubn(-num);
|
|
|
|
// Possible sign change
|
|
if (this.negative !== 0) {
|
|
if (this.length === 1 && (this.words[0] | 0) <= num) {
|
|
this.words[0] = num - (this.words[0] | 0);
|
|
this.negative = 0;
|
|
return this;
|
|
}
|
|
|
|
this.negative = 0;
|
|
this.isubn(num);
|
|
this.negative = 1;
|
|
return this;
|
|
}
|
|
|
|
// Add without checks
|
|
return this._iaddn(num);
|
|
};
|
|
|
|
BN.prototype._iaddn = function _iaddn (num) {
|
|
this.words[0] += num;
|
|
|
|
// Carry
|
|
for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
|
|
this.words[i] -= 0x4000000;
|
|
if (i === this.length - 1) {
|
|
this.words[i + 1] = 1;
|
|
} else {
|
|
this.words[i + 1]++;
|
|
}
|
|
}
|
|
this.length = Math.max(this.length, i + 1);
|
|
|
|
return this;
|
|
};
|
|
|
|
// Subtract plain number `num` from `this`
|
|
BN.prototype.isubn = function isubn (num) {
|
|
assert(typeof num === 'number');
|
|
assert(num < 0x4000000);
|
|
if (num < 0) return this.iaddn(-num);
|
|
|
|
if (this.negative !== 0) {
|
|
this.negative = 0;
|
|
this.iaddn(num);
|
|
this.negative = 1;
|
|
return this;
|
|
}
|
|
|
|
this.words[0] -= num;
|
|
|
|
if (this.length === 1 && this.words[0] < 0) {
|
|
this.words[0] = -this.words[0];
|
|
this.negative = 1;
|
|
} else {
|
|
// Carry
|
|
for (var i = 0; i < this.length && this.words[i] < 0; i++) {
|
|
this.words[i] += 0x4000000;
|
|
this.words[i + 1] -= 1;
|
|
}
|
|
}
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype.addn = function addn (num) {
|
|
return this.clone().iaddn(num);
|
|
};
|
|
|
|
BN.prototype.subn = function subn (num) {
|
|
return this.clone().isubn(num);
|
|
};
|
|
|
|
BN.prototype.iabs = function iabs () {
|
|
this.negative = 0;
|
|
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.abs = function abs () {
|
|
return this.clone().iabs();
|
|
};
|
|
|
|
BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
|
|
var len = num.length + shift;
|
|
var i;
|
|
|
|
this._expand(len);
|
|
|
|
var w;
|
|
var carry = 0;
|
|
for (i = 0; i < num.length; i++) {
|
|
w = (this.words[i + shift] | 0) + carry;
|
|
var right = (num.words[i] | 0) * mul;
|
|
w -= right & 0x3ffffff;
|
|
carry = (w >> 26) - ((right / 0x4000000) | 0);
|
|
this.words[i + shift] = w & 0x3ffffff;
|
|
}
|
|
for (; i < this.length - shift; i++) {
|
|
w = (this.words[i + shift] | 0) + carry;
|
|
carry = w >> 26;
|
|
this.words[i + shift] = w & 0x3ffffff;
|
|
}
|
|
|
|
if (carry === 0) return this._strip();
|
|
|
|
// Subtraction overflow
|
|
assert(carry === -1);
|
|
carry = 0;
|
|
for (i = 0; i < this.length; i++) {
|
|
w = -(this.words[i] | 0) + carry;
|
|
carry = w >> 26;
|
|
this.words[i] = w & 0x3ffffff;
|
|
}
|
|
this.negative = 1;
|
|
|
|
return this._strip();
|
|
};
|
|
|
|
BN.prototype._wordDiv = function _wordDiv (num, mode) {
|
|
var shift = this.length - num.length;
|
|
|
|
var a = this.clone();
|
|
var b = num;
|
|
|
|
// Normalize
|
|
var bhi = b.words[b.length - 1] | 0;
|
|
var bhiBits = this._countBits(bhi);
|
|
shift = 26 - bhiBits;
|
|
if (shift !== 0) {
|
|
b = b.ushln(shift);
|
|
a.iushln(shift);
|
|
bhi = b.words[b.length - 1] | 0;
|
|
}
|
|
|
|
// Initialize quotient
|
|
var m = a.length - b.length;
|
|
var q;
|
|
|
|
if (mode !== 'mod') {
|
|
q = new BN(null);
|
|
q.length = m + 1;
|
|
q.words = new Array(q.length);
|
|
for (var i = 0; i < q.length; i++) {
|
|
q.words[i] = 0;
|
|
}
|
|
}
|
|
|
|
var diff = a.clone()._ishlnsubmul(b, 1, m);
|
|
if (diff.negative === 0) {
|
|
a = diff;
|
|
if (q) {
|
|
q.words[m] = 1;
|
|
}
|
|
}
|
|
|
|
for (var j = m - 1; j >= 0; j--) {
|
|
var qj = (a.words[b.length + j] | 0) * 0x4000000 +
|
|
(a.words[b.length + j - 1] | 0);
|
|
|
|
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
|
// (0x7ffffff)
|
|
qj = Math.min((qj / bhi) | 0, 0x3ffffff);
|
|
|
|
a._ishlnsubmul(b, qj, j);
|
|
while (a.negative !== 0) {
|
|
qj--;
|
|
a.negative = 0;
|
|
a._ishlnsubmul(b, 1, j);
|
|
if (!a.isZero()) {
|
|
a.negative ^= 1;
|
|
}
|
|
}
|
|
if (q) {
|
|
q.words[j] = qj;
|
|
}
|
|
}
|
|
if (q) {
|
|
q._strip();
|
|
}
|
|
a._strip();
|
|
|
|
// Denormalize
|
|
if (mode !== 'div' && shift !== 0) {
|
|
a.iushrn(shift);
|
|
}
|
|
|
|
return {
|
|
div: q || null,
|
|
mod: a
|
|
};
|
|
};
|
|
|
|
// NOTE: 1) `mode` can be set to `mod` to request mod only,
|
|
// to `div` to request div only, or be absent to
|
|
// request both div & mod
|
|
// 2) `positive` is true if unsigned mod is requested
|
|
BN.prototype.divmod = function divmod (num, mode, positive) {
|
|
assert(!num.isZero());
|
|
|
|
if (this.isZero()) {
|
|
return {
|
|
div: new BN(0),
|
|
mod: new BN(0)
|
|
};
|
|
}
|
|
|
|
var div, mod, res;
|
|
if (this.negative !== 0 && num.negative === 0) {
|
|
res = this.neg().divmod(num, mode);
|
|
|
|
if (mode !== 'mod') {
|
|
div = res.div.neg();
|
|
}
|
|
|
|
if (mode !== 'div') {
|
|
mod = res.mod.neg();
|
|
if (positive && mod.negative !== 0) {
|
|
mod.iadd(num);
|
|
}
|
|
}
|
|
|
|
return {
|
|
div: div,
|
|
mod: mod
|
|
};
|
|
}
|
|
|
|
if (this.negative === 0 && num.negative !== 0) {
|
|
res = this.divmod(num.neg(), mode);
|
|
|
|
if (mode !== 'mod') {
|
|
div = res.div.neg();
|
|
}
|
|
|
|
return {
|
|
div: div,
|
|
mod: res.mod
|
|
};
|
|
}
|
|
|
|
if ((this.negative & num.negative) !== 0) {
|
|
res = this.neg().divmod(num.neg(), mode);
|
|
|
|
if (mode !== 'div') {
|
|
mod = res.mod.neg();
|
|
if (positive && mod.negative !== 0) {
|
|
mod.isub(num);
|
|
}
|
|
}
|
|
|
|
return {
|
|
div: res.div,
|
|
mod: mod
|
|
};
|
|
}
|
|
|
|
// Both numbers are positive at this point
|
|
|
|
// Strip both numbers to approximate shift value
|
|
if (num.length > this.length || this.cmp(num) < 0) {
|
|
return {
|
|
div: new BN(0),
|
|
mod: this
|
|
};
|
|
}
|
|
|
|
// Very short reduction
|
|
if (num.length === 1) {
|
|
if (mode === 'div') {
|
|
return {
|
|
div: this.divn(num.words[0]),
|
|
mod: null
|
|
};
|
|
}
|
|
|
|
if (mode === 'mod') {
|
|
return {
|
|
div: null,
|
|
mod: new BN(this.modrn(num.words[0]))
|
|
};
|
|
}
|
|
|
|
return {
|
|
div: this.divn(num.words[0]),
|
|
mod: new BN(this.modrn(num.words[0]))
|
|
};
|
|
}
|
|
|
|
return this._wordDiv(num, mode);
|
|
};
|
|
|
|
// Find `this` / `num`
|
|
BN.prototype.div = function div (num) {
|
|
return this.divmod(num, 'div', false).div;
|
|
};
|
|
|
|
// Find `this` % `num`
|
|
BN.prototype.mod = function mod (num) {
|
|
return this.divmod(num, 'mod', false).mod;
|
|
};
|
|
|
|
BN.prototype.umod = function umod (num) {
|
|
return this.divmod(num, 'mod', true).mod;
|
|
};
|
|
|
|
// Find Round(`this` / `num`)
|
|
BN.prototype.divRound = function divRound (num) {
|
|
var dm = this.divmod(num);
|
|
|
|
// Fast case - exact division
|
|
if (dm.mod.isZero()) return dm.div;
|
|
|
|
var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
|
|
|
|
var half = num.ushrn(1);
|
|
var r2 = num.andln(1);
|
|
var cmp = mod.cmp(half);
|
|
|
|
// Round down
|
|
if (cmp < 0 || (r2 === 1 && cmp === 0)) return dm.div;
|
|
|
|
// Round up
|
|
return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
|
|
};
|
|
|
|
BN.prototype.modrn = function modrn (num) {
|
|
var isNegNum = num < 0;
|
|
if (isNegNum) num = -num;
|
|
|
|
assert(num <= 0x3ffffff);
|
|
var p = (1 << 26) % num;
|
|
|
|
var acc = 0;
|
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
acc = (p * acc + (this.words[i] | 0)) % num;
|
|
}
|
|
|
|
return isNegNum ? -acc : acc;
|
|
};
|
|
|
|
// WARNING: DEPRECATED
|
|
BN.prototype.modn = function modn (num) {
|
|
return this.modrn(num);
|
|
};
|
|
|
|
// In-place division by number
|
|
BN.prototype.idivn = function idivn (num) {
|
|
var isNegNum = num < 0;
|
|
if (isNegNum) num = -num;
|
|
|
|
assert(num <= 0x3ffffff);
|
|
|
|
var carry = 0;
|
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
var w = (this.words[i] | 0) + carry * 0x4000000;
|
|
this.words[i] = (w / num) | 0;
|
|
carry = w % num;
|
|
}
|
|
|
|
this._strip();
|
|
return isNegNum ? this.ineg() : this;
|
|
};
|
|
|
|
BN.prototype.divn = function divn (num) {
|
|
return this.clone().idivn(num);
|
|
};
|
|
|
|
BN.prototype.egcd = function egcd (p) {
|
|
assert(p.negative === 0);
|
|
assert(!p.isZero());
|
|
|
|
var x = this;
|
|
var y = p.clone();
|
|
|
|
if (x.negative !== 0) {
|
|
x = x.umod(p);
|
|
} else {
|
|
x = x.clone();
|
|
}
|
|
|
|
// A * x + B * y = x
|
|
var A = new BN(1);
|
|
var B = new BN(0);
|
|
|
|
// C * x + D * y = y
|
|
var C = new BN(0);
|
|
var D = new BN(1);
|
|
|
|
var g = 0;
|
|
|
|
while (x.isEven() && y.isEven()) {
|
|
x.iushrn(1);
|
|
y.iushrn(1);
|
|
++g;
|
|
}
|
|
|
|
var yp = y.clone();
|
|
var xp = x.clone();
|
|
|
|
while (!x.isZero()) {
|
|
for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
|
if (i > 0) {
|
|
x.iushrn(i);
|
|
while (i-- > 0) {
|
|
if (A.isOdd() || B.isOdd()) {
|
|
A.iadd(yp);
|
|
B.isub(xp);
|
|
}
|
|
|
|
A.iushrn(1);
|
|
B.iushrn(1);
|
|
}
|
|
}
|
|
|
|
for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
|
if (j > 0) {
|
|
y.iushrn(j);
|
|
while (j-- > 0) {
|
|
if (C.isOdd() || D.isOdd()) {
|
|
C.iadd(yp);
|
|
D.isub(xp);
|
|
}
|
|
|
|
C.iushrn(1);
|
|
D.iushrn(1);
|
|
}
|
|
}
|
|
|
|
if (x.cmp(y) >= 0) {
|
|
x.isub(y);
|
|
A.isub(C);
|
|
B.isub(D);
|
|
} else {
|
|
y.isub(x);
|
|
C.isub(A);
|
|
D.isub(B);
|
|
}
|
|
}
|
|
|
|
return {
|
|
a: C,
|
|
b: D,
|
|
gcd: y.iushln(g)
|
|
};
|
|
};
|
|
|
|
// This is reduced incarnation of the binary EEA
|
|
// above, designated to invert members of the
|
|
// _prime_ fields F(p) at a maximal speed
|
|
BN.prototype._invmp = function _invmp (p) {
|
|
assert(p.negative === 0);
|
|
assert(!p.isZero());
|
|
|
|
var a = this;
|
|
var b = p.clone();
|
|
|
|
if (a.negative !== 0) {
|
|
a = a.umod(p);
|
|
} else {
|
|
a = a.clone();
|
|
}
|
|
|
|
var x1 = new BN(1);
|
|
var x2 = new BN(0);
|
|
|
|
var delta = b.clone();
|
|
|
|
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
|
|
for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
|
if (i > 0) {
|
|
a.iushrn(i);
|
|
while (i-- > 0) {
|
|
if (x1.isOdd()) {
|
|
x1.iadd(delta);
|
|
}
|
|
|
|
x1.iushrn(1);
|
|
}
|
|
}
|
|
|
|
for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
|
if (j > 0) {
|
|
b.iushrn(j);
|
|
while (j-- > 0) {
|
|
if (x2.isOdd()) {
|
|
x2.iadd(delta);
|
|
}
|
|
|
|
x2.iushrn(1);
|
|
}
|
|
}
|
|
|
|
if (a.cmp(b) >= 0) {
|
|
a.isub(b);
|
|
x1.isub(x2);
|
|
} else {
|
|
b.isub(a);
|
|
x2.isub(x1);
|
|
}
|
|
}
|
|
|
|
var res;
|
|
if (a.cmpn(1) === 0) {
|
|
res = x1;
|
|
} else {
|
|
res = x2;
|
|
}
|
|
|
|
if (res.cmpn(0) < 0) {
|
|
res.iadd(p);
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
BN.prototype.gcd = function gcd (num) {
|
|
if (this.isZero()) return num.abs();
|
|
if (num.isZero()) return this.abs();
|
|
|
|
var a = this.clone();
|
|
var b = num.clone();
|
|
a.negative = 0;
|
|
b.negative = 0;
|
|
|
|
// Remove common factor of two
|
|
for (var shift = 0; a.isEven() && b.isEven(); shift++) {
|
|
a.iushrn(1);
|
|
b.iushrn(1);
|
|
}
|
|
|
|
do {
|
|
while (a.isEven()) {
|
|
a.iushrn(1);
|
|
}
|
|
while (b.isEven()) {
|
|
b.iushrn(1);
|
|
}
|
|
|
|
var r = a.cmp(b);
|
|
if (r < 0) {
|
|
// Swap `a` and `b` to make `a` always bigger than `b`
|
|
var t = a;
|
|
a = b;
|
|
b = t;
|
|
} else if (r === 0 || b.cmpn(1) === 0) {
|
|
break;
|
|
}
|
|
|
|
a.isub(b);
|
|
} while (true);
|
|
|
|
return b.iushln(shift);
|
|
};
|
|
|
|
// Invert number in the field F(num)
|
|
BN.prototype.invm = function invm (num) {
|
|
return this.egcd(num).a.umod(num);
|
|
};
|
|
|
|
BN.prototype.isEven = function isEven () {
|
|
return (this.words[0] & 1) === 0;
|
|
};
|
|
|
|
BN.prototype.isOdd = function isOdd () {
|
|
return (this.words[0] & 1) === 1;
|
|
};
|
|
|
|
// And first word and num
|
|
BN.prototype.andln = function andln (num) {
|
|
return this.words[0] & num;
|
|
};
|
|
|
|
// Increment at the bit position in-line
|
|
BN.prototype.bincn = function bincn (bit) {
|
|
assert(typeof bit === 'number');
|
|
var r = bit % 26;
|
|
var s = (bit - r) / 26;
|
|
var q = 1 << r;
|
|
|
|
// Fast case: bit is much higher than all existing words
|
|
if (this.length <= s) {
|
|
this._expand(s + 1);
|
|
this.words[s] |= q;
|
|
return this;
|
|
}
|
|
|
|
// Add bit and propagate, if needed
|
|
var carry = q;
|
|
for (var i = s; carry !== 0 && i < this.length; i++) {
|
|
var w = this.words[i] | 0;
|
|
w += carry;
|
|
carry = w >>> 26;
|
|
w &= 0x3ffffff;
|
|
this.words[i] = w;
|
|
}
|
|
if (carry !== 0) {
|
|
this.words[i] = carry;
|
|
this.length++;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.isZero = function isZero () {
|
|
return this.length === 1 && this.words[0] === 0;
|
|
};
|
|
|
|
BN.prototype.cmpn = function cmpn (num) {
|
|
var negative = num < 0;
|
|
|
|
if (this.negative !== 0 && !negative) return -1;
|
|
if (this.negative === 0 && negative) return 1;
|
|
|
|
this._strip();
|
|
|
|
var res;
|
|
if (this.length > 1) {
|
|
res = 1;
|
|
} else {
|
|
if (negative) {
|
|
num = -num;
|
|
}
|
|
|
|
assert(num <= 0x3ffffff, 'Number is too big');
|
|
|
|
var w = this.words[0] | 0;
|
|
res = w === num ? 0 : w < num ? -1 : 1;
|
|
}
|
|
if (this.negative !== 0) return -res | 0;
|
|
return res;
|
|
};
|
|
|
|
// Compare two numbers and return:
|
|
// 1 - if `this` > `num`
|
|
// 0 - if `this` == `num`
|
|
// -1 - if `this` < `num`
|
|
BN.prototype.cmp = function cmp (num) {
|
|
if (this.negative !== 0 && num.negative === 0) return -1;
|
|
if (this.negative === 0 && num.negative !== 0) return 1;
|
|
|
|
var res = this.ucmp(num);
|
|
if (this.negative !== 0) return -res | 0;
|
|
return res;
|
|
};
|
|
|
|
// Unsigned comparison
|
|
BN.prototype.ucmp = function ucmp (num) {
|
|
// At this point both numbers have the same sign
|
|
if (this.length > num.length) return 1;
|
|
if (this.length < num.length) return -1;
|
|
|
|
var res = 0;
|
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
var a = this.words[i] | 0;
|
|
var b = num.words[i] | 0;
|
|
|
|
if (a === b) continue;
|
|
if (a < b) {
|
|
res = -1;
|
|
} else if (a > b) {
|
|
res = 1;
|
|
}
|
|
break;
|
|
}
|
|
return res;
|
|
};
|
|
|
|
BN.prototype.gtn = function gtn (num) {
|
|
return this.cmpn(num) === 1;
|
|
};
|
|
|
|
BN.prototype.gt = function gt (num) {
|
|
return this.cmp(num) === 1;
|
|
};
|
|
|
|
BN.prototype.gten = function gten (num) {
|
|
return this.cmpn(num) >= 0;
|
|
};
|
|
|
|
BN.prototype.gte = function gte (num) {
|
|
return this.cmp(num) >= 0;
|
|
};
|
|
|
|
BN.prototype.ltn = function ltn (num) {
|
|
return this.cmpn(num) === -1;
|
|
};
|
|
|
|
BN.prototype.lt = function lt (num) {
|
|
return this.cmp(num) === -1;
|
|
};
|
|
|
|
BN.prototype.lten = function lten (num) {
|
|
return this.cmpn(num) <= 0;
|
|
};
|
|
|
|
BN.prototype.lte = function lte (num) {
|
|
return this.cmp(num) <= 0;
|
|
};
|
|
|
|
BN.prototype.eqn = function eqn (num) {
|
|
return this.cmpn(num) === 0;
|
|
};
|
|
|
|
BN.prototype.eq = function eq (num) {
|
|
return this.cmp(num) === 0;
|
|
};
|
|
|
|
//
|
|
// A reduce context, could be using montgomery or something better, depending
|
|
// on the `m` itself.
|
|
//
|
|
BN.red = function red (num) {
|
|
return new Red(num);
|
|
};
|
|
|
|
BN.prototype.toRed = function toRed (ctx) {
|
|
assert(!this.red, 'Already a number in reduction context');
|
|
assert(this.negative === 0, 'red works only with positives');
|
|
return ctx.convertTo(this)._forceRed(ctx);
|
|
};
|
|
|
|
BN.prototype.fromRed = function fromRed () {
|
|
assert(this.red, 'fromRed works only with numbers in reduction context');
|
|
return this.red.convertFrom(this);
|
|
};
|
|
|
|
BN.prototype._forceRed = function _forceRed (ctx) {
|
|
this.red = ctx;
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.forceRed = function forceRed (ctx) {
|
|
assert(!this.red, 'Already a number in reduction context');
|
|
return this._forceRed(ctx);
|
|
};
|
|
|
|
BN.prototype.redAdd = function redAdd (num) {
|
|
assert(this.red, 'redAdd works only with red numbers');
|
|
return this.red.add(this, num);
|
|
};
|
|
|
|
BN.prototype.redIAdd = function redIAdd (num) {
|
|
assert(this.red, 'redIAdd works only with red numbers');
|
|
return this.red.iadd(this, num);
|
|
};
|
|
|
|
BN.prototype.redSub = function redSub (num) {
|
|
assert(this.red, 'redSub works only with red numbers');
|
|
return this.red.sub(this, num);
|
|
};
|
|
|
|
BN.prototype.redISub = function redISub (num) {
|
|
assert(this.red, 'redISub works only with red numbers');
|
|
return this.red.isub(this, num);
|
|
};
|
|
|
|
BN.prototype.redShl = function redShl (num) {
|
|
assert(this.red, 'redShl works only with red numbers');
|
|
return this.red.shl(this, num);
|
|
};
|
|
|
|
BN.prototype.redMul = function redMul (num) {
|
|
assert(this.red, 'redMul works only with red numbers');
|
|
this.red._verify2(this, num);
|
|
return this.red.mul(this, num);
|
|
};
|
|
|
|
BN.prototype.redIMul = function redIMul (num) {
|
|
assert(this.red, 'redMul works only with red numbers');
|
|
this.red._verify2(this, num);
|
|
return this.red.imul(this, num);
|
|
};
|
|
|
|
BN.prototype.redSqr = function redSqr () {
|
|
assert(this.red, 'redSqr works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.sqr(this);
|
|
};
|
|
|
|
BN.prototype.redISqr = function redISqr () {
|
|
assert(this.red, 'redISqr works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.isqr(this);
|
|
};
|
|
|
|
// Square root over p
|
|
BN.prototype.redSqrt = function redSqrt () {
|
|
assert(this.red, 'redSqrt works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.sqrt(this);
|
|
};
|
|
|
|
BN.prototype.redInvm = function redInvm () {
|
|
assert(this.red, 'redInvm works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.invm(this);
|
|
};
|
|
|
|
// Return negative clone of `this` % `red modulo`
|
|
BN.prototype.redNeg = function redNeg () {
|
|
assert(this.red, 'redNeg works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.neg(this);
|
|
};
|
|
|
|
BN.prototype.redPow = function redPow (num) {
|
|
assert(this.red && !num.red, 'redPow(normalNum)');
|
|
this.red._verify1(this);
|
|
return this.red.pow(this, num);
|
|
};
|
|
|
|
// Prime numbers with efficient reduction
|
|
var primes = {
|
|
k256: null,
|
|
p224: null,
|
|
p192: null,
|
|
p25519: null
|
|
};
|
|
|
|
// Pseudo-Mersenne prime
|
|
function MPrime (name, p) {
|
|
// P = 2 ^ N - K
|
|
this.name = name;
|
|
this.p = new BN(p, 16);
|
|
this.n = this.p.bitLength();
|
|
this.k = new BN(1).iushln(this.n).isub(this.p);
|
|
|
|
this.tmp = this._tmp();
|
|
}
|
|
|
|
MPrime.prototype._tmp = function _tmp () {
|
|
var tmp = new BN(null);
|
|
tmp.words = new Array(Math.ceil(this.n / 13));
|
|
return tmp;
|
|
};
|
|
|
|
MPrime.prototype.ireduce = function ireduce (num) {
|
|
// Assumes that `num` is less than `P^2`
|
|
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
|
|
var r = num;
|
|
var rlen;
|
|
|
|
do {
|
|
this.split(r, this.tmp);
|
|
r = this.imulK(r);
|
|
r = r.iadd(this.tmp);
|
|
rlen = r.bitLength();
|
|
} while (rlen > this.n);
|
|
|
|
var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
|
|
if (cmp === 0) {
|
|
r.words[0] = 0;
|
|
r.length = 1;
|
|
} else if (cmp > 0) {
|
|
r.isub(this.p);
|
|
} else {
|
|
r._strip();
|
|
}
|
|
|
|
return r;
|
|
};
|
|
|
|
MPrime.prototype.split = function split (input, out) {
|
|
input.iushrn(this.n, 0, out);
|
|
};
|
|
|
|
MPrime.prototype.imulK = function imulK (num) {
|
|
return num.imul(this.k);
|
|
};
|
|
|
|
function K256 () {
|
|
MPrime.call(
|
|
this,
|
|
'k256',
|
|
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
|
|
}
|
|
inherits(K256, MPrime);
|
|
|
|
K256.prototype.split = function split (input, output) {
|
|
// 256 = 9 * 26 + 22
|
|
var mask = 0x3fffff;
|
|
|
|
var outLen = Math.min(input.length, 9);
|
|
for (var i = 0; i < outLen; i++) {
|
|
output.words[i] = input.words[i];
|
|
}
|
|
output.length = outLen;
|
|
|
|
if (input.length <= 9) {
|
|
input.words[0] = 0;
|
|
input.length = 1;
|
|
return;
|
|
}
|
|
|
|
// Shift by 9 limbs
|
|
var prev = input.words[9];
|
|
output.words[output.length++] = prev & mask;
|
|
|
|
for (i = 10; i < input.length; i++) {
|
|
var next = input.words[i] | 0;
|
|
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
|
|
prev = next;
|
|
}
|
|
prev >>>= 22;
|
|
input.words[i - 10] = prev;
|
|
if (prev === 0 && input.length > 10) {
|
|
input.length -= 10;
|
|
} else {
|
|
input.length -= 9;
|
|
}
|
|
};
|
|
|
|
K256.prototype.imulK = function imulK (num) {
|
|
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
|
|
num.words[num.length] = 0;
|
|
num.words[num.length + 1] = 0;
|
|
num.length += 2;
|
|
|
|
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
|
|
var lo = 0;
|
|
for (var i = 0; i < num.length; i++) {
|
|
var w = num.words[i] | 0;
|
|
lo += w * 0x3d1;
|
|
num.words[i] = lo & 0x3ffffff;
|
|
lo = w * 0x40 + ((lo / 0x4000000) | 0);
|
|
}
|
|
|
|
// Fast length reduction
|
|
if (num.words[num.length - 1] === 0) {
|
|
num.length--;
|
|
if (num.words[num.length - 1] === 0) {
|
|
num.length--;
|
|
}
|
|
}
|
|
return num;
|
|
};
|
|
|
|
function P224 () {
|
|
MPrime.call(
|
|
this,
|
|
'p224',
|
|
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
|
|
}
|
|
inherits(P224, MPrime);
|
|
|
|
function P192 () {
|
|
MPrime.call(
|
|
this,
|
|
'p192',
|
|
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
|
|
}
|
|
inherits(P192, MPrime);
|
|
|
|
function P25519 () {
|
|
// 2 ^ 255 - 19
|
|
MPrime.call(
|
|
this,
|
|
'25519',
|
|
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
|
|
}
|
|
inherits(P25519, MPrime);
|
|
|
|
P25519.prototype.imulK = function imulK (num) {
|
|
// K = 0x13
|
|
var carry = 0;
|
|
for (var i = 0; i < num.length; i++) {
|
|
var hi = (num.words[i] | 0) * 0x13 + carry;
|
|
var lo = hi & 0x3ffffff;
|
|
hi >>>= 26;
|
|
|
|
num.words[i] = lo;
|
|
carry = hi;
|
|
}
|
|
if (carry !== 0) {
|
|
num.words[num.length++] = carry;
|
|
}
|
|
return num;
|
|
};
|
|
|
|
// Exported mostly for testing purposes, use plain name instead
|
|
BN._prime = function prime (name) {
|
|
// Cached version of prime
|
|
if (primes[name]) return primes[name];
|
|
|
|
var prime;
|
|
if (name === 'k256') {
|
|
prime = new K256();
|
|
} else if (name === 'p224') {
|
|
prime = new P224();
|
|
} else if (name === 'p192') {
|
|
prime = new P192();
|
|
} else if (name === 'p25519') {
|
|
prime = new P25519();
|
|
} else {
|
|
throw new Error('Unknown prime ' + name);
|
|
}
|
|
primes[name] = prime;
|
|
|
|
return prime;
|
|
};
|
|
|
|
//
|
|
// Base reduction engine
|
|
//
|
|
function Red (m) {
|
|
if (typeof m === 'string') {
|
|
var prime = BN._prime(m);
|
|
this.m = prime.p;
|
|
this.prime = prime;
|
|
} else {
|
|
assert(m.gtn(1), 'modulus must be greater than 1');
|
|
this.m = m;
|
|
this.prime = null;
|
|
}
|
|
}
|
|
|
|
Red.prototype._verify1 = function _verify1 (a) {
|
|
assert(a.negative === 0, 'red works only with positives');
|
|
assert(a.red, 'red works only with red numbers');
|
|
};
|
|
|
|
Red.prototype._verify2 = function _verify2 (a, b) {
|
|
assert((a.negative | b.negative) === 0, 'red works only with positives');
|
|
assert(a.red && a.red === b.red,
|
|
'red works only with red numbers');
|
|
};
|
|
|
|
Red.prototype.imod = function imod (a) {
|
|
if (this.prime) return this.prime.ireduce(a)._forceRed(this);
|
|
|
|
move(a, a.umod(this.m)._forceRed(this));
|
|
return a;
|
|
};
|
|
|
|
Red.prototype.neg = function neg (a) {
|
|
if (a.isZero()) {
|
|
return a.clone();
|
|
}
|
|
|
|
return this.m.sub(a)._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.add = function add (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.add(b);
|
|
if (res.cmp(this.m) >= 0) {
|
|
res.isub(this.m);
|
|
}
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.iadd = function iadd (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.iadd(b);
|
|
if (res.cmp(this.m) >= 0) {
|
|
res.isub(this.m);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
Red.prototype.sub = function sub (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.sub(b);
|
|
if (res.cmpn(0) < 0) {
|
|
res.iadd(this.m);
|
|
}
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.isub = function isub (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.isub(b);
|
|
if (res.cmpn(0) < 0) {
|
|
res.iadd(this.m);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
Red.prototype.shl = function shl (a, num) {
|
|
this._verify1(a);
|
|
return this.imod(a.ushln(num));
|
|
};
|
|
|
|
Red.prototype.imul = function imul (a, b) {
|
|
this._verify2(a, b);
|
|
return this.imod(a.imul(b));
|
|
};
|
|
|
|
Red.prototype.mul = function mul (a, b) {
|
|
this._verify2(a, b);
|
|
return this.imod(a.mul(b));
|
|
};
|
|
|
|
Red.prototype.isqr = function isqr (a) {
|
|
return this.imul(a, a.clone());
|
|
};
|
|
|
|
Red.prototype.sqr = function sqr (a) {
|
|
return this.mul(a, a);
|
|
};
|
|
|
|
Red.prototype.sqrt = function sqrt (a) {
|
|
if (a.isZero()) return a.clone();
|
|
|
|
var mod3 = this.m.andln(3);
|
|
assert(mod3 % 2 === 1);
|
|
|
|
// Fast case
|
|
if (mod3 === 3) {
|
|
var pow = this.m.add(new BN(1)).iushrn(2);
|
|
return this.pow(a, pow);
|
|
}
|
|
|
|
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
|
|
//
|
|
// Find Q and S, that Q * 2 ^ S = (P - 1)
|
|
var q = this.m.subn(1);
|
|
var s = 0;
|
|
while (!q.isZero() && q.andln(1) === 0) {
|
|
s++;
|
|
q.iushrn(1);
|
|
}
|
|
assert(!q.isZero());
|
|
|
|
var one = new BN(1).toRed(this);
|
|
var nOne = one.redNeg();
|
|
|
|
// Find quadratic non-residue
|
|
// NOTE: Max is such because of generalized Riemann hypothesis.
|
|
var lpow = this.m.subn(1).iushrn(1);
|
|
var z = this.m.bitLength();
|
|
z = new BN(2 * z * z).toRed(this);
|
|
|
|
while (this.pow(z, lpow).cmp(nOne) !== 0) {
|
|
z.redIAdd(nOne);
|
|
}
|
|
|
|
var c = this.pow(z, q);
|
|
var r = this.pow(a, q.addn(1).iushrn(1));
|
|
var t = this.pow(a, q);
|
|
var m = s;
|
|
while (t.cmp(one) !== 0) {
|
|
var tmp = t;
|
|
for (var i = 0; tmp.cmp(one) !== 0; i++) {
|
|
tmp = tmp.redSqr();
|
|
}
|
|
assert(i < m);
|
|
var b = this.pow(c, new BN(1).iushln(m - i - 1));
|
|
|
|
r = r.redMul(b);
|
|
c = b.redSqr();
|
|
t = t.redMul(c);
|
|
m = i;
|
|
}
|
|
|
|
return r;
|
|
};
|
|
|
|
Red.prototype.invm = function invm (a) {
|
|
var inv = a._invmp(this.m);
|
|
if (inv.negative !== 0) {
|
|
inv.negative = 0;
|
|
return this.imod(inv).redNeg();
|
|
} else {
|
|
return this.imod(inv);
|
|
}
|
|
};
|
|
|
|
Red.prototype.pow = function pow (a, num) {
|
|
if (num.isZero()) return new BN(1).toRed(this);
|
|
if (num.cmpn(1) === 0) return a.clone();
|
|
|
|
var windowSize = 4;
|
|
var wnd = new Array(1 << windowSize);
|
|
wnd[0] = new BN(1).toRed(this);
|
|
wnd[1] = a;
|
|
for (var i = 2; i < wnd.length; i++) {
|
|
wnd[i] = this.mul(wnd[i - 1], a);
|
|
}
|
|
|
|
var res = wnd[0];
|
|
var current = 0;
|
|
var currentLen = 0;
|
|
var start = num.bitLength() % 26;
|
|
if (start === 0) {
|
|
start = 26;
|
|
}
|
|
|
|
for (i = num.length - 1; i >= 0; i--) {
|
|
var word = num.words[i];
|
|
for (var j = start - 1; j >= 0; j--) {
|
|
var bit = (word >> j) & 1;
|
|
if (res !== wnd[0]) {
|
|
res = this.sqr(res);
|
|
}
|
|
|
|
if (bit === 0 && current === 0) {
|
|
currentLen = 0;
|
|
continue;
|
|
}
|
|
|
|
current <<= 1;
|
|
current |= bit;
|
|
currentLen++;
|
|
if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
|
|
|
|
res = this.mul(res, wnd[current]);
|
|
currentLen = 0;
|
|
current = 0;
|
|
}
|
|
start = 26;
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
Red.prototype.convertTo = function convertTo (num) {
|
|
var r = num.umod(this.m);
|
|
|
|
return r === num ? r.clone() : r;
|
|
};
|
|
|
|
Red.prototype.convertFrom = function convertFrom (num) {
|
|
var res = num.clone();
|
|
res.red = null;
|
|
return res;
|
|
};
|
|
|
|
//
|
|
// Montgomery method engine
|
|
//
|
|
|
|
BN.mont = function mont (num) {
|
|
return new Mont(num);
|
|
};
|
|
|
|
function Mont (m) {
|
|
Red.call(this, m);
|
|
|
|
this.shift = this.m.bitLength();
|
|
if (this.shift % 26 !== 0) {
|
|
this.shift += 26 - (this.shift % 26);
|
|
}
|
|
|
|
this.r = new BN(1).iushln(this.shift);
|
|
this.r2 = this.imod(this.r.sqr());
|
|
this.rinv = this.r._invmp(this.m);
|
|
|
|
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
|
|
this.minv = this.minv.umod(this.r);
|
|
this.minv = this.r.sub(this.minv);
|
|
}
|
|
inherits(Mont, Red);
|
|
|
|
Mont.prototype.convertTo = function convertTo (num) {
|
|
return this.imod(num.ushln(this.shift));
|
|
};
|
|
|
|
Mont.prototype.convertFrom = function convertFrom (num) {
|
|
var r = this.imod(num.mul(this.rinv));
|
|
r.red = null;
|
|
return r;
|
|
};
|
|
|
|
Mont.prototype.imul = function imul (a, b) {
|
|
if (a.isZero() || b.isZero()) {
|
|
a.words[0] = 0;
|
|
a.length = 1;
|
|
return a;
|
|
}
|
|
|
|
var t = a.imul(b);
|
|
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
|
var u = t.isub(c).iushrn(this.shift);
|
|
var res = u;
|
|
|
|
if (u.cmp(this.m) >= 0) {
|
|
res = u.isub(this.m);
|
|
} else if (u.cmpn(0) < 0) {
|
|
res = u.iadd(this.m);
|
|
}
|
|
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Mont.prototype.mul = function mul (a, b) {
|
|
if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
|
|
|
|
var t = a.mul(b);
|
|
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
|
var u = t.isub(c).iushrn(this.shift);
|
|
var res = u;
|
|
if (u.cmp(this.m) >= 0) {
|
|
res = u.isub(this.m);
|
|
} else if (u.cmpn(0) < 0) {
|
|
res = u.iadd(this.m);
|
|
}
|
|
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Mont.prototype.invm = function invm (a) {
|
|
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
|
|
var res = this.imod(a._invmp(this.m).mul(this.r2));
|
|
return res._forceRed(this);
|
|
};
|
|
})(typeof module === 'undefined' || module, this);
|
|
|
|
},{"buffer":99}],3:[function(require,module,exports){
|
|
var r;
|
|
|
|
module.exports = function rand(len) {
|
|
if (!r)
|
|
r = new Rand(null);
|
|
|
|
return r.generate(len);
|
|
};
|
|
|
|
function Rand(rand) {
|
|
this.rand = rand;
|
|
}
|
|
module.exports.Rand = Rand;
|
|
|
|
Rand.prototype.generate = function generate(len) {
|
|
return this._rand(len);
|
|
};
|
|
|
|
// Emulate crypto API using randy
|
|
Rand.prototype._rand = function _rand(n) {
|
|
if (this.rand.getBytes)
|
|
return this.rand.getBytes(n);
|
|
|
|
var res = new Uint8Array(n);
|
|
for (var i = 0; i < res.length; i++)
|
|
res[i] = this.rand.getByte();
|
|
return res;
|
|
};
|
|
|
|
if (typeof self === 'object') {
|
|
if (self.crypto && self.crypto.getRandomValues) {
|
|
// Modern browsers
|
|
Rand.prototype._rand = function _rand(n) {
|
|
var arr = new Uint8Array(n);
|
|
self.crypto.getRandomValues(arr);
|
|
return arr;
|
|
};
|
|
} else if (self.msCrypto && self.msCrypto.getRandomValues) {
|
|
// IE
|
|
Rand.prototype._rand = function _rand(n) {
|
|
var arr = new Uint8Array(n);
|
|
self.msCrypto.getRandomValues(arr);
|
|
return arr;
|
|
};
|
|
|
|
// Safari's WebWorkers do not have `crypto`
|
|
} else if (typeof window === 'object') {
|
|
// Old junk
|
|
Rand.prototype._rand = function() {
|
|
throw new Error('Not implemented yet');
|
|
};
|
|
}
|
|
} else {
|
|
// Node.js or Web worker with no crypto support
|
|
try {
|
|
var crypto = require('crypto');
|
|
if (typeof crypto.randomBytes !== 'function')
|
|
throw new Error('Not supported');
|
|
|
|
Rand.prototype._rand = function _rand(n) {
|
|
return crypto.randomBytes(n);
|
|
};
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
},{"crypto":99}],4:[function(require,module,exports){
|
|
var Buffer = require('safe-buffer').Buffer
|
|
var Transform = require('stream').Transform
|
|
var StringDecoder = require('string_decoder').StringDecoder
|
|
var inherits = require('inherits')
|
|
|
|
function CipherBase (hashMode) {
|
|
Transform.call(this)
|
|
this.hashMode = typeof hashMode === 'string'
|
|
if (this.hashMode) {
|
|
this[hashMode] = this._finalOrDigest
|
|
} else {
|
|
this.final = this._finalOrDigest
|
|
}
|
|
if (this._final) {
|
|
this.__final = this._final
|
|
this._final = null
|
|
}
|
|
this._decoder = null
|
|
this._encoding = null
|
|
}
|
|
inherits(CipherBase, Transform)
|
|
|
|
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
|
|
if (typeof data === 'string') {
|
|
data = Buffer.from(data, inputEnc)
|
|
}
|
|
|
|
var outData = this._update(data)
|
|
if (this.hashMode) return this
|
|
|
|
if (outputEnc) {
|
|
outData = this._toString(outData, outputEnc)
|
|
}
|
|
|
|
return outData
|
|
}
|
|
|
|
CipherBase.prototype.setAutoPadding = function () {}
|
|
CipherBase.prototype.getAuthTag = function () {
|
|
throw new Error('trying to get auth tag in unsupported state')
|
|
}
|
|
|
|
CipherBase.prototype.setAuthTag = function () {
|
|
throw new Error('trying to set auth tag in unsupported state')
|
|
}
|
|
|
|
CipherBase.prototype.setAAD = function () {
|
|
throw new Error('trying to set aad in unsupported state')
|
|
}
|
|
|
|
CipherBase.prototype._transform = function (data, _, next) {
|
|
var err
|
|
try {
|
|
if (this.hashMode) {
|
|
this._update(data)
|
|
} else {
|
|
this.push(this._update(data))
|
|
}
|
|
} catch (e) {
|
|
err = e
|
|
} finally {
|
|
next(err)
|
|
}
|
|
}
|
|
CipherBase.prototype._flush = function (done) {
|
|
var err
|
|
try {
|
|
this.push(this.__final())
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
|
|
done(err)
|
|
}
|
|
CipherBase.prototype._finalOrDigest = function (outputEnc) {
|
|
var outData = this.__final() || Buffer.alloc(0)
|
|
if (outputEnc) {
|
|
outData = this._toString(outData, outputEnc, true)
|
|
}
|
|
return outData
|
|
}
|
|
|
|
CipherBase.prototype._toString = function (value, enc, fin) {
|
|
if (!this._decoder) {
|
|
this._decoder = new StringDecoder(enc)
|
|
this._encoding = enc
|
|
}
|
|
|
|
if (this._encoding !== enc) throw new Error('can\'t switch encodings')
|
|
|
|
var out = this._decoder.write(value)
|
|
if (fin) {
|
|
out += this._decoder.end()
|
|
}
|
|
|
|
return out
|
|
}
|
|
|
|
module.exports = CipherBase
|
|
|
|
},{"inherits":38,"safe-buffer":85,"stream":126,"string_decoder":127}],5:[function(require,module,exports){
|
|
'use strict'
|
|
var inherits = require('inherits')
|
|
var MD5 = require('md5.js')
|
|
var RIPEMD160 = require('ripemd160')
|
|
var sha = require('sha.js')
|
|
var Base = require('cipher-base')
|
|
|
|
function Hash (hash) {
|
|
Base.call(this, 'digest')
|
|
|
|
this._hash = hash
|
|
}
|
|
|
|
inherits(Hash, Base)
|
|
|
|
Hash.prototype._update = function (data) {
|
|
this._hash.update(data)
|
|
}
|
|
|
|
Hash.prototype._final = function () {
|
|
return this._hash.digest()
|
|
}
|
|
|
|
module.exports = function createHash (alg) {
|
|
alg = alg.toLowerCase()
|
|
if (alg === 'md5') return new MD5()
|
|
if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160()
|
|
|
|
return new Hash(sha(alg))
|
|
}
|
|
|
|
},{"cipher-base":4,"inherits":38,"md5.js":40,"ripemd160":43,"sha.js":87}],6:[function(require,module,exports){
|
|
;(function (globalScope) {
|
|
'use strict';
|
|
|
|
|
|
/*
|
|
* decimal.js v10.2.0
|
|
* An arbitrary-precision Decimal type for JavaScript.
|
|
* https://github.com/MikeMcl/decimal.js
|
|
* Copyright (c) 2019 Michael Mclaughlin <M8ch88l@gmail.com>
|
|
* MIT Licence
|
|
*/
|
|
|
|
|
|
// ----------------------------------- EDITABLE DEFAULTS ------------------------------------ //
|
|
|
|
|
|
// The maximum exponent magnitude.
|
|
// The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`.
|
|
var EXP_LIMIT = 9e15, // 0 to 9e15
|
|
|
|
// The limit on the value of `precision`, and on the value of the first argument to
|
|
// `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`.
|
|
MAX_DIGITS = 1e9, // 0 to 1e9
|
|
|
|
// Base conversion alphabet.
|
|
NUMERALS = '0123456789abcdef',
|
|
|
|
// The natural logarithm of 10 (1025 digits).
|
|
LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058',
|
|
|
|
// Pi (1025 digits).
|
|
PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789',
|
|
|
|
|
|
// The initial configuration properties of the Decimal constructor.
|
|
DEFAULTS = {
|
|
|
|
// These values must be integers within the stated ranges (inclusive).
|
|
// Most of these values can be changed at run-time using the `Decimal.config` method.
|
|
|
|
// The maximum number of significant digits of the result of a calculation or base conversion.
|
|
// E.g. `Decimal.config({ precision: 20 });`
|
|
precision: 20, // 1 to MAX_DIGITS
|
|
|
|
// The rounding mode used when rounding to `precision`.
|
|
//
|
|
// ROUND_UP 0 Away from zero.
|
|
// ROUND_DOWN 1 Towards zero.
|
|
// ROUND_CEIL 2 Towards +Infinity.
|
|
// ROUND_FLOOR 3 Towards -Infinity.
|
|
// ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up.
|
|
// ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.
|
|
// ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.
|
|
// ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.
|
|
// ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
|
|
//
|
|
// E.g.
|
|
// `Decimal.rounding = 4;`
|
|
// `Decimal.rounding = Decimal.ROUND_HALF_UP;`
|
|
rounding: 4, // 0 to 8
|
|
|
|
// The modulo mode used when calculating the modulus: a mod n.
|
|
// The quotient (q = a / n) is calculated according to the corresponding rounding mode.
|
|
// The remainder (r) is calculated as: r = a - n * q.
|
|
//
|
|
// UP 0 The remainder is positive if the dividend is negative, else is negative.
|
|
// DOWN 1 The remainder has the same sign as the dividend (JavaScript %).
|
|
// FLOOR 3 The remainder has the same sign as the divisor (Python %).
|
|
// HALF_EVEN 6 The IEEE 754 remainder function.
|
|
// EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive.
|
|
//
|
|
// Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian
|
|
// division (9) are commonly used for the modulus operation. The other rounding modes can also
|
|
// be used, but they may not give useful results.
|
|
modulo: 1, // 0 to 9
|
|
|
|
// The exponent value at and beneath which `toString` returns exponential notation.
|
|
// JavaScript numbers: -7
|
|
toExpNeg: -7, // 0 to -EXP_LIMIT
|
|
|
|
// The exponent value at and above which `toString` returns exponential notation.
|
|
// JavaScript numbers: 21
|
|
toExpPos: 21, // 0 to EXP_LIMIT
|
|
|
|
// The minimum exponent value, beneath which underflow to zero occurs.
|
|
// JavaScript numbers: -324 (5e-324)
|
|
minE: -EXP_LIMIT, // -1 to -EXP_LIMIT
|
|
|
|
// The maximum exponent value, above which overflow to Infinity occurs.
|
|
// JavaScript numbers: 308 (1.7976931348623157e+308)
|
|
maxE: EXP_LIMIT, // 1 to EXP_LIMIT
|
|
|
|
// Whether to use cryptographically-secure random number generation, if available.
|
|
crypto: false // true/false
|
|
},
|
|
|
|
|
|
// ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- //
|
|
|
|
|
|
Decimal, inexact, noConflict, quadrant,
|
|
external = true,
|
|
|
|
decimalError = '[DecimalError] ',
|
|
invalidArgument = decimalError + 'Invalid argument: ',
|
|
precisionLimitExceeded = decimalError + 'Precision limit exceeded',
|
|
cryptoUnavailable = decimalError + 'crypto unavailable',
|
|
|
|
mathfloor = Math.floor,
|
|
mathpow = Math.pow,
|
|
|
|
isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i,
|
|
isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i,
|
|
isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i,
|
|
isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
|
|
|
|
BASE = 1e7,
|
|
LOG_BASE = 7,
|
|
MAX_SAFE_INTEGER = 9007199254740991,
|
|
|
|
LN10_PRECISION = LN10.length - 1,
|
|
PI_PRECISION = PI.length - 1,
|
|
|
|
// Decimal.prototype object
|
|
P = { name: '[object Decimal]' };
|
|
|
|
|
|
// Decimal prototype methods
|
|
|
|
|
|
/*
|
|
* absoluteValue abs
|
|
* ceil
|
|
* comparedTo cmp
|
|
* cosine cos
|
|
* cubeRoot cbrt
|
|
* decimalPlaces dp
|
|
* dividedBy div
|
|
* dividedToIntegerBy divToInt
|
|
* equals eq
|
|
* floor
|
|
* greaterThan gt
|
|
* greaterThanOrEqualTo gte
|
|
* hyperbolicCosine cosh
|
|
* hyperbolicSine sinh
|
|
* hyperbolicTangent tanh
|
|
* inverseCosine acos
|
|
* inverseHyperbolicCosine acosh
|
|
* inverseHyperbolicSine asinh
|
|
* inverseHyperbolicTangent atanh
|
|
* inverseSine asin
|
|
* inverseTangent atan
|
|
* isFinite
|
|
* isInteger isInt
|
|
* isNaN
|
|
* isNegative isNeg
|
|
* isPositive isPos
|
|
* isZero
|
|
* lessThan lt
|
|
* lessThanOrEqualTo lte
|
|
* logarithm log
|
|
* [maximum] [max]
|
|
* [minimum] [min]
|
|
* minus sub
|
|
* modulo mod
|
|
* naturalExponential exp
|
|
* naturalLogarithm ln
|
|
* negated neg
|
|
* plus add
|
|
* precision sd
|
|
* round
|
|
* sine sin
|
|
* squareRoot sqrt
|
|
* tangent tan
|
|
* times mul
|
|
* toBinary
|
|
* toDecimalPlaces toDP
|
|
* toExponential
|
|
* toFixed
|
|
* toFraction
|
|
* toHexadecimal toHex
|
|
* toNearest
|
|
* toNumber
|
|
* toOctal
|
|
* toPower pow
|
|
* toPrecision
|
|
* toSignificantDigits toSD
|
|
* toString
|
|
* truncated trunc
|
|
* valueOf toJSON
|
|
*/
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the absolute value of this Decimal.
|
|
*
|
|
*/
|
|
P.absoluteValue = P.abs = function () {
|
|
var x = new this.constructor(this);
|
|
if (x.s < 0) x.s = 1;
|
|
return finalise(x);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the
|
|
* direction of positive Infinity.
|
|
*
|
|
*/
|
|
P.ceil = function () {
|
|
return finalise(new this.constructor(this), this.e + 1, 2);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return
|
|
* 1 if the value of this Decimal is greater than the value of `y`,
|
|
* -1 if the value of this Decimal is less than the value of `y`,
|
|
* 0 if they have the same value,
|
|
* NaN if the value of either Decimal is NaN.
|
|
*
|
|
*/
|
|
P.comparedTo = P.cmp = function (y) {
|
|
var i, j, xdL, ydL,
|
|
x = this,
|
|
xd = x.d,
|
|
yd = (y = new x.constructor(y)).d,
|
|
xs = x.s,
|
|
ys = y.s;
|
|
|
|
// Either NaN or ±Infinity?
|
|
if (!xd || !yd) {
|
|
return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1;
|
|
}
|
|
|
|
// Either zero?
|
|
if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0;
|
|
|
|
// Signs differ?
|
|
if (xs !== ys) return xs;
|
|
|
|
// Compare exponents.
|
|
if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1;
|
|
|
|
xdL = xd.length;
|
|
ydL = yd.length;
|
|
|
|
// Compare digit by digit.
|
|
for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) {
|
|
if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1;
|
|
}
|
|
|
|
// Compare lengths.
|
|
return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the cosine of the value in radians of this Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-1, 1]
|
|
*
|
|
* cos(0) = 1
|
|
* cos(-0) = 1
|
|
* cos(Infinity) = NaN
|
|
* cos(-Infinity) = NaN
|
|
* cos(NaN) = NaN
|
|
*
|
|
*/
|
|
P.cosine = P.cos = function () {
|
|
var pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.d) return new Ctor(NaN);
|
|
|
|
// cos(0) = cos(-0) = 1
|
|
if (!x.d[0]) return new Ctor(1);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE;
|
|
Ctor.rounding = 1;
|
|
|
|
x = cosine(Ctor, toLessThanHalfPi(Ctor, x));
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true);
|
|
};
|
|
|
|
|
|
/*
|
|
*
|
|
* Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to
|
|
* `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* cbrt(0) = 0
|
|
* cbrt(-0) = -0
|
|
* cbrt(1) = 1
|
|
* cbrt(-1) = -1
|
|
* cbrt(N) = N
|
|
* cbrt(-I) = -I
|
|
* cbrt(I) = I
|
|
*
|
|
* Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3))
|
|
*
|
|
*/
|
|
P.cubeRoot = P.cbrt = function () {
|
|
var e, m, n, r, rep, s, sd, t, t3, t3plusx,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite() || x.isZero()) return new Ctor(x);
|
|
external = false;
|
|
|
|
// Initial estimate.
|
|
s = x.s * mathpow(x.s * x, 1 / 3);
|
|
|
|
// Math.cbrt underflow/overflow?
|
|
// Pass x to Math.pow as integer, then adjust the exponent of the result.
|
|
if (!s || Math.abs(s) == 1 / 0) {
|
|
n = digitsToString(x.d);
|
|
e = x.e;
|
|
|
|
// Adjust n exponent so it is a multiple of 3 away from x exponent.
|
|
if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00');
|
|
s = mathpow(n, 1 / 3);
|
|
|
|
// Rarely, e may be one less than the result exponent value.
|
|
e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2));
|
|
|
|
if (s == 1 / 0) {
|
|
n = '5e' + e;
|
|
} else {
|
|
n = s.toExponential();
|
|
n = n.slice(0, n.indexOf('e') + 1) + e;
|
|
}
|
|
|
|
r = new Ctor(n);
|
|
r.s = x.s;
|
|
} else {
|
|
r = new Ctor(s.toString());
|
|
}
|
|
|
|
sd = (e = Ctor.precision) + 3;
|
|
|
|
// Halley's method.
|
|
// TODO? Compare Newton's method.
|
|
for (;;) {
|
|
t = r;
|
|
t3 = t.times(t).times(t);
|
|
t3plusx = t3.plus(x);
|
|
r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1);
|
|
|
|
// TODO? Replace with for-loop and checkRoundingDigits.
|
|
if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) {
|
|
n = n.slice(sd - 3, sd + 1);
|
|
|
|
// The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999
|
|
// , i.e. approaching a rounding boundary, continue the iteration.
|
|
if (n == '9999' || !rep && n == '4999') {
|
|
|
|
// On the first iteration only, check to see if rounding up gives the exact result as the
|
|
// nines may infinitely repeat.
|
|
if (!rep) {
|
|
finalise(t, e + 1, 0);
|
|
|
|
if (t.times(t).times(t).eq(x)) {
|
|
r = t;
|
|
break;
|
|
}
|
|
}
|
|
|
|
sd += 4;
|
|
rep = 1;
|
|
} else {
|
|
|
|
// If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result.
|
|
// If not, then there are further digits and m will be truthy.
|
|
if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
|
|
|
|
// Truncate to the first rounding digit.
|
|
finalise(r, e + 1, 1);
|
|
m = !r.times(r).times(r).eq(x);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
external = true;
|
|
|
|
return finalise(r, e, Ctor.rounding, m);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return the number of decimal places of the value of this Decimal.
|
|
*
|
|
*/
|
|
P.decimalPlaces = P.dp = function () {
|
|
var w,
|
|
d = this.d,
|
|
n = NaN;
|
|
|
|
if (d) {
|
|
w = d.length - 1;
|
|
n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE;
|
|
|
|
// Subtract the number of trailing zeros of the last word.
|
|
w = d[w];
|
|
if (w) for (; w % 10 == 0; w /= 10) n--;
|
|
if (n < 0) n = 0;
|
|
}
|
|
|
|
return n;
|
|
};
|
|
|
|
|
|
/*
|
|
* 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 Decimal whose value is the value of this Decimal divided by `y`, rounded to
|
|
* `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.dividedBy = P.div = function (y) {
|
|
return divide(this, new this.constructor(y));
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the integer part of dividing the value of this Decimal
|
|
* by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.dividedToIntegerBy = P.divToInt = function (y) {
|
|
var x = this,
|
|
Ctor = x.constructor;
|
|
return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is equal to the value of `y`, otherwise return false.
|
|
*
|
|
*/
|
|
P.equals = P.eq = function (y) {
|
|
return this.cmp(y) === 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the
|
|
* direction of negative Infinity.
|
|
*
|
|
*/
|
|
P.floor = function () {
|
|
return finalise(new this.constructor(this), this.e + 1, 3);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is greater than the value of `y`, otherwise return
|
|
* false.
|
|
*
|
|
*/
|
|
P.greaterThan = P.gt = function (y) {
|
|
return this.cmp(y) > 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is greater than or equal to the value of `y`,
|
|
* otherwise return false.
|
|
*
|
|
*/
|
|
P.greaterThanOrEqualTo = P.gte = function (y) {
|
|
var k = this.cmp(y);
|
|
return k == 1 || k === 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this
|
|
* Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [1, Infinity]
|
|
*
|
|
* cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ...
|
|
*
|
|
* cosh(0) = 1
|
|
* cosh(-0) = 1
|
|
* cosh(Infinity) = Infinity
|
|
* cosh(-Infinity) = Infinity
|
|
* cosh(NaN) = NaN
|
|
*
|
|
* x time taken (ms) result
|
|
* 1000 9 9.8503555700852349694e+433
|
|
* 10000 25 4.4034091128314607936e+4342
|
|
* 100000 171 1.4033316802130615897e+43429
|
|
* 1000000 3817 1.5166076984010437725e+434294
|
|
* 10000000 abandoned after 2 minute wait
|
|
*
|
|
* TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x))
|
|
*
|
|
*/
|
|
P.hyperbolicCosine = P.cosh = function () {
|
|
var k, n, pr, rm, len,
|
|
x = this,
|
|
Ctor = x.constructor,
|
|
one = new Ctor(1);
|
|
|
|
if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN);
|
|
if (x.isZero()) return one;
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + Math.max(x.e, x.sd()) + 4;
|
|
Ctor.rounding = 1;
|
|
len = x.d.length;
|
|
|
|
// Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1
|
|
// i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4))
|
|
|
|
// Estimate the optimum number of times to use the argument reduction.
|
|
// TODO? Estimation reused from cosine() and may not be optimal here.
|
|
if (len < 32) {
|
|
k = Math.ceil(len / 3);
|
|
n = (1 / tinyPow(4, k)).toString();
|
|
} else {
|
|
k = 16;
|
|
n = '2.3283064365386962890625e-10';
|
|
}
|
|
|
|
x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true);
|
|
|
|
// Reverse argument reduction
|
|
var cosh2_x,
|
|
i = k,
|
|
d8 = new Ctor(8);
|
|
for (; i--;) {
|
|
cosh2_x = x.times(x);
|
|
x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8))));
|
|
}
|
|
|
|
return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the hyperbolic sine of the value in radians of this
|
|
* Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-Infinity, Infinity]
|
|
*
|
|
* sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ...
|
|
*
|
|
* sinh(0) = 0
|
|
* sinh(-0) = -0
|
|
* sinh(Infinity) = Infinity
|
|
* sinh(-Infinity) = -Infinity
|
|
* sinh(NaN) = NaN
|
|
*
|
|
* x time taken (ms)
|
|
* 10 2 ms
|
|
* 100 5 ms
|
|
* 1000 14 ms
|
|
* 10000 82 ms
|
|
* 100000 886 ms 1.4033316802130615897e+43429
|
|
* 200000 2613 ms
|
|
* 300000 5407 ms
|
|
* 400000 8824 ms
|
|
* 500000 13026 ms 8.7080643612718084129e+217146
|
|
* 1000000 48543 ms
|
|
*
|
|
* TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x))
|
|
*
|
|
*/
|
|
P.hyperbolicSine = P.sinh = function () {
|
|
var k, pr, rm, len,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite() || x.isZero()) return new Ctor(x);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + Math.max(x.e, x.sd()) + 4;
|
|
Ctor.rounding = 1;
|
|
len = x.d.length;
|
|
|
|
if (len < 3) {
|
|
x = taylorSeries(Ctor, 2, x, x, true);
|
|
} else {
|
|
|
|
// Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x))
|
|
// i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3))
|
|
// 3 multiplications and 1 addition
|
|
|
|
// Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x)))
|
|
// i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5)))
|
|
// 4 multiplications and 2 additions
|
|
|
|
// Estimate the optimum number of times to use the argument reduction.
|
|
k = 1.4 * Math.sqrt(len);
|
|
k = k > 16 ? 16 : k | 0;
|
|
|
|
x = x.times(1 / tinyPow(5, k));
|
|
x = taylorSeries(Ctor, 2, x, x, true);
|
|
|
|
// Reverse argument reduction
|
|
var sinh2_x,
|
|
d5 = new Ctor(5),
|
|
d16 = new Ctor(16),
|
|
d20 = new Ctor(20);
|
|
for (; k--;) {
|
|
sinh2_x = x.times(x);
|
|
x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20))));
|
|
}
|
|
}
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return finalise(x, pr, rm, true);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this
|
|
* Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-1, 1]
|
|
*
|
|
* tanh(x) = sinh(x) / cosh(x)
|
|
*
|
|
* tanh(0) = 0
|
|
* tanh(-0) = -0
|
|
* tanh(Infinity) = 1
|
|
* tanh(-Infinity) = -1
|
|
* tanh(NaN) = NaN
|
|
*
|
|
*/
|
|
P.hyperbolicTangent = P.tanh = function () {
|
|
var pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite()) return new Ctor(x.s);
|
|
if (x.isZero()) return new Ctor(x);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + 7;
|
|
Ctor.rounding = 1;
|
|
|
|
return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of
|
|
* this Decimal.
|
|
*
|
|
* Domain: [-1, 1]
|
|
* Range: [0, pi]
|
|
*
|
|
* acos(x) = pi/2 - asin(x)
|
|
*
|
|
* acos(0) = pi/2
|
|
* acos(-0) = pi/2
|
|
* acos(1) = 0
|
|
* acos(-1) = pi
|
|
* acos(1/2) = pi/3
|
|
* acos(-1/2) = 2*pi/3
|
|
* acos(|x| > 1) = NaN
|
|
* acos(NaN) = NaN
|
|
*
|
|
*/
|
|
P.inverseCosine = P.acos = function () {
|
|
var halfPi,
|
|
x = this,
|
|
Ctor = x.constructor,
|
|
k = x.abs().cmp(1),
|
|
pr = Ctor.precision,
|
|
rm = Ctor.rounding;
|
|
|
|
if (k !== -1) {
|
|
return k === 0
|
|
// |x| is 1
|
|
? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0)
|
|
// |x| > 1 or x is NaN
|
|
: new Ctor(NaN);
|
|
}
|
|
|
|
if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5);
|
|
|
|
// TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3
|
|
|
|
Ctor.precision = pr + 6;
|
|
Ctor.rounding = 1;
|
|
|
|
x = x.asin();
|
|
halfPi = getPi(Ctor, pr + 4, rm).times(0.5);
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return halfPi.minus(x);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the
|
|
* value of this Decimal.
|
|
*
|
|
* Domain: [1, Infinity]
|
|
* Range: [0, Infinity]
|
|
*
|
|
* acosh(x) = ln(x + sqrt(x^2 - 1))
|
|
*
|
|
* acosh(x < 1) = NaN
|
|
* acosh(NaN) = NaN
|
|
* acosh(Infinity) = Infinity
|
|
* acosh(-Infinity) = NaN
|
|
* acosh(0) = NaN
|
|
* acosh(-0) = NaN
|
|
* acosh(1) = 0
|
|
* acosh(-1) = NaN
|
|
*
|
|
*/
|
|
P.inverseHyperbolicCosine = P.acosh = function () {
|
|
var pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN);
|
|
if (!x.isFinite()) return new Ctor(x);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4;
|
|
Ctor.rounding = 1;
|
|
external = false;
|
|
|
|
x = x.times(x).minus(1).sqrt().plus(x);
|
|
|
|
external = true;
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return x.ln();
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value
|
|
* of this Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-Infinity, Infinity]
|
|
*
|
|
* asinh(x) = ln(x + sqrt(x^2 + 1))
|
|
*
|
|
* asinh(NaN) = NaN
|
|
* asinh(Infinity) = Infinity
|
|
* asinh(-Infinity) = -Infinity
|
|
* asinh(0) = 0
|
|
* asinh(-0) = -0
|
|
*
|
|
*/
|
|
P.inverseHyperbolicSine = P.asinh = function () {
|
|
var pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite() || x.isZero()) return new Ctor(x);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6;
|
|
Ctor.rounding = 1;
|
|
external = false;
|
|
|
|
x = x.times(x).plus(1).sqrt().plus(x);
|
|
|
|
external = true;
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return x.ln();
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the
|
|
* value of this Decimal.
|
|
*
|
|
* Domain: [-1, 1]
|
|
* Range: [-Infinity, Infinity]
|
|
*
|
|
* atanh(x) = 0.5 * ln((1 + x) / (1 - x))
|
|
*
|
|
* atanh(|x| > 1) = NaN
|
|
* atanh(NaN) = NaN
|
|
* atanh(Infinity) = NaN
|
|
* atanh(-Infinity) = NaN
|
|
* atanh(0) = 0
|
|
* atanh(-0) = -0
|
|
* atanh(1) = Infinity
|
|
* atanh(-1) = -Infinity
|
|
*
|
|
*/
|
|
P.inverseHyperbolicTangent = P.atanh = function () {
|
|
var pr, rm, wpr, xsd,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite()) return new Ctor(NaN);
|
|
if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
xsd = x.sd();
|
|
|
|
if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true);
|
|
|
|
Ctor.precision = wpr = xsd - x.e;
|
|
|
|
x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1);
|
|
|
|
Ctor.precision = pr + 4;
|
|
Ctor.rounding = 1;
|
|
|
|
x = x.ln();
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return x.times(0.5);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this
|
|
* Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-pi/2, pi/2]
|
|
*
|
|
* asin(x) = 2*atan(x/(1 + sqrt(1 - x^2)))
|
|
*
|
|
* asin(0) = 0
|
|
* asin(-0) = -0
|
|
* asin(1/2) = pi/6
|
|
* asin(-1/2) = -pi/6
|
|
* asin(1) = pi/2
|
|
* asin(-1) = -pi/2
|
|
* asin(|x| > 1) = NaN
|
|
* asin(NaN) = NaN
|
|
*
|
|
* TODO? Compare performance of Taylor series.
|
|
*
|
|
*/
|
|
P.inverseSine = P.asin = function () {
|
|
var halfPi, k,
|
|
pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (x.isZero()) return new Ctor(x);
|
|
|
|
k = x.abs().cmp(1);
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
|
|
if (k !== -1) {
|
|
|
|
// |x| is 1
|
|
if (k === 0) {
|
|
halfPi = getPi(Ctor, pr + 4, rm).times(0.5);
|
|
halfPi.s = x.s;
|
|
return halfPi;
|
|
}
|
|
|
|
// |x| > 1 or x is NaN
|
|
return new Ctor(NaN);
|
|
}
|
|
|
|
// TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6
|
|
|
|
Ctor.precision = pr + 6;
|
|
Ctor.rounding = 1;
|
|
|
|
x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan();
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return x.times(2);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value
|
|
* of this Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-pi/2, pi/2]
|
|
*
|
|
* atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ...
|
|
*
|
|
* atan(0) = 0
|
|
* atan(-0) = -0
|
|
* atan(1) = pi/4
|
|
* atan(-1) = -pi/4
|
|
* atan(Infinity) = pi/2
|
|
* atan(-Infinity) = -pi/2
|
|
* atan(NaN) = NaN
|
|
*
|
|
*/
|
|
P.inverseTangent = P.atan = function () {
|
|
var i, j, k, n, px, t, r, wpr, x2,
|
|
x = this,
|
|
Ctor = x.constructor,
|
|
pr = Ctor.precision,
|
|
rm = Ctor.rounding;
|
|
|
|
if (!x.isFinite()) {
|
|
if (!x.s) return new Ctor(NaN);
|
|
if (pr + 4 <= PI_PRECISION) {
|
|
r = getPi(Ctor, pr + 4, rm).times(0.5);
|
|
r.s = x.s;
|
|
return r;
|
|
}
|
|
} else if (x.isZero()) {
|
|
return new Ctor(x);
|
|
} else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) {
|
|
r = getPi(Ctor, pr + 4, rm).times(0.25);
|
|
r.s = x.s;
|
|
return r;
|
|
}
|
|
|
|
Ctor.precision = wpr = pr + 10;
|
|
Ctor.rounding = 1;
|
|
|
|
// TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x);
|
|
|
|
// Argument reduction
|
|
// Ensure |x| < 0.42
|
|
// atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2)))
|
|
|
|
k = Math.min(28, wpr / LOG_BASE + 2 | 0);
|
|
|
|
for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1));
|
|
|
|
external = false;
|
|
|
|
j = Math.ceil(wpr / LOG_BASE);
|
|
n = 1;
|
|
x2 = x.times(x);
|
|
r = new Ctor(x);
|
|
px = x;
|
|
|
|
// atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ...
|
|
for (; i !== -1;) {
|
|
px = px.times(x2);
|
|
t = r.minus(px.div(n += 2));
|
|
|
|
px = px.times(x2);
|
|
r = t.plus(px.div(n += 2));
|
|
|
|
if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;);
|
|
}
|
|
|
|
if (k) r = r.times(2 << (k - 1));
|
|
|
|
external = true;
|
|
|
|
return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is a finite number, otherwise return false.
|
|
*
|
|
*/
|
|
P.isFinite = function () {
|
|
return !!this.d;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is an integer, otherwise return false.
|
|
*
|
|
*/
|
|
P.isInteger = P.isInt = function () {
|
|
return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is NaN, otherwise return false.
|
|
*
|
|
*/
|
|
P.isNaN = function () {
|
|
return !this.s;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is negative, otherwise return false.
|
|
*
|
|
*/
|
|
P.isNegative = P.isNeg = function () {
|
|
return this.s < 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is positive, otherwise return false.
|
|
*
|
|
*/
|
|
P.isPositive = P.isPos = function () {
|
|
return this.s > 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is 0 or -0, otherwise return false.
|
|
*
|
|
*/
|
|
P.isZero = function () {
|
|
return !!this.d && this.d[0] === 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is less than `y`, otherwise return false.
|
|
*
|
|
*/
|
|
P.lessThan = P.lt = function (y) {
|
|
return this.cmp(y) < 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return true if the value of this Decimal is less than or equal to `y`, otherwise return false.
|
|
*
|
|
*/
|
|
P.lessThanOrEqualTo = P.lte = function (y) {
|
|
return this.cmp(y) < 1;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return the logarithm of the value of this Decimal to the specified base, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* If no base is specified, return log[10](arg).
|
|
*
|
|
* log[base](arg) = ln(arg) / ln(base)
|
|
*
|
|
* The result will always be correctly rounded if the base of the log is 10, and 'almost always'
|
|
* otherwise:
|
|
*
|
|
* Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen
|
|
* rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error
|
|
* between the result and the correctly rounded result will be one ulp (unit in the last place).
|
|
*
|
|
* log[-b](a) = NaN
|
|
* log[0](a) = NaN
|
|
* log[1](a) = NaN
|
|
* log[NaN](a) = NaN
|
|
* log[Infinity](a) = NaN
|
|
* log[b](0) = -Infinity
|
|
* log[b](-0) = -Infinity
|
|
* log[b](-a) = NaN
|
|
* log[b](1) = 0
|
|
* log[b](Infinity) = Infinity
|
|
* log[b](NaN) = NaN
|
|
*
|
|
* [base] {number|string|Decimal} The base of the logarithm.
|
|
*
|
|
*/
|
|
P.logarithm = P.log = function (base) {
|
|
var isBase10, d, denominator, k, inf, num, sd, r,
|
|
arg = this,
|
|
Ctor = arg.constructor,
|
|
pr = Ctor.precision,
|
|
rm = Ctor.rounding,
|
|
guard = 5;
|
|
|
|
// Default base is 10.
|
|
if (base == null) {
|
|
base = new Ctor(10);
|
|
isBase10 = true;
|
|
} else {
|
|
base = new Ctor(base);
|
|
d = base.d;
|
|
|
|
// Return NaN if base is negative, or non-finite, or is 0 or 1.
|
|
if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN);
|
|
|
|
isBase10 = base.eq(10);
|
|
}
|
|
|
|
d = arg.d;
|
|
|
|
// Is arg negative, non-finite, 0 or 1?
|
|
if (arg.s < 0 || !d || !d[0] || arg.eq(1)) {
|
|
return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0);
|
|
}
|
|
|
|
// The result will have a non-terminating decimal expansion if base is 10 and arg is not an
|
|
// integer power of 10.
|
|
if (isBase10) {
|
|
if (d.length > 1) {
|
|
inf = true;
|
|
} else {
|
|
for (k = d[0]; k % 10 === 0;) k /= 10;
|
|
inf = k !== 1;
|
|
}
|
|
}
|
|
|
|
external = false;
|
|
sd = pr + guard;
|
|
num = naturalLogarithm(arg, sd);
|
|
denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd);
|
|
|
|
// The result will have 5 rounding digits.
|
|
r = divide(num, denominator, sd, 1);
|
|
|
|
// If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000,
|
|
// calculate 10 further digits.
|
|
//
|
|
// If the result is known to have an infinite decimal expansion, repeat this until it is clear
|
|
// that the result is above or below the boundary. Otherwise, if after calculating the 10
|
|
// further digits, the last 14 are nines, round up and assume the result is exact.
|
|
// Also assume the result is exact if the last 14 are zero.
|
|
//
|
|
// Example of a result that will be incorrectly rounded:
|
|
// log[1048576](4503599627370502) = 2.60000000000000009610279511444746...
|
|
// The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it
|
|
// will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so
|
|
// the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal
|
|
// place is still 2.6.
|
|
if (checkRoundingDigits(r.d, k = pr, rm)) {
|
|
|
|
do {
|
|
sd += 10;
|
|
num = naturalLogarithm(arg, sd);
|
|
denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd);
|
|
r = divide(num, denominator, sd, 1);
|
|
|
|
if (!inf) {
|
|
|
|
// Check for 14 nines from the 2nd rounding digit, as the first may be 4.
|
|
if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) {
|
|
r = finalise(r, pr + 1, 0);
|
|
}
|
|
|
|
break;
|
|
}
|
|
} while (checkRoundingDigits(r.d, k += 10, rm));
|
|
}
|
|
|
|
external = true;
|
|
|
|
return finalise(r, pr, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal.
|
|
*
|
|
* arguments {number|string|Decimal}
|
|
*
|
|
P.max = function () {
|
|
Array.prototype.push.call(arguments, this);
|
|
return maxOrMin(this.constructor, arguments, 'lt');
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal.
|
|
*
|
|
* arguments {number|string|Decimal}
|
|
*
|
|
P.min = function () {
|
|
Array.prototype.push.call(arguments, this);
|
|
return maxOrMin(this.constructor, arguments, 'gt');
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
* 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 Decimal whose value is the value of this Decimal minus `y`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.minus = P.sub = function (y) {
|
|
var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
y = new Ctor(y);
|
|
|
|
// If either is not finite...
|
|
if (!x.d || !y.d) {
|
|
|
|
// Return NaN if either is NaN.
|
|
if (!x.s || !y.s) y = new Ctor(NaN);
|
|
|
|
// Return y negated if x is finite and y is ±Infinity.
|
|
else if (x.d) y.s = -y.s;
|
|
|
|
// Return x if y is finite and x is ±Infinity.
|
|
// Return x if both are ±Infinity with different signs.
|
|
// Return NaN if both are ±Infinity with the same sign.
|
|
else y = new Ctor(y.d || x.s !== y.s ? x : NaN);
|
|
|
|
return y;
|
|
}
|
|
|
|
// If signs differ...
|
|
if (x.s != y.s) {
|
|
y.s = -y.s;
|
|
return x.plus(y);
|
|
}
|
|
|
|
xd = x.d;
|
|
yd = y.d;
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
|
|
// If either is zero...
|
|
if (!xd[0] || !yd[0]) {
|
|
|
|
// Return y negated if x is zero and y is non-zero.
|
|
if (yd[0]) y.s = -y.s;
|
|
|
|
// Return x if y is zero and x is non-zero.
|
|
else if (xd[0]) y = new Ctor(x);
|
|
|
|
// Return zero if both are zero.
|
|
// From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity.
|
|
else return new Ctor(rm === 3 ? -0 : 0);
|
|
|
|
return external ? finalise(y, pr, rm) : y;
|
|
}
|
|
|
|
// x and y are finite, non-zero numbers with the same sign.
|
|
|
|
// Calculate base 1e7 exponents.
|
|
e = mathfloor(y.e / LOG_BASE);
|
|
xe = mathfloor(x.e / LOG_BASE);
|
|
|
|
xd = xd.slice();
|
|
k = xe - e;
|
|
|
|
// If base 1e7 exponents differ...
|
|
if (k) {
|
|
xLTy = k < 0;
|
|
|
|
if (xLTy) {
|
|
d = xd;
|
|
k = -k;
|
|
len = yd.length;
|
|
} else {
|
|
d = yd;
|
|
e = xe;
|
|
len = xd.length;
|
|
}
|
|
|
|
// Numbers with massively different exponents would result in a very high number of
|
|
// zeros needing to be prepended, but this can be avoided while still ensuring correct
|
|
// rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`.
|
|
i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2;
|
|
|
|
if (k > i) {
|
|
k = i;
|
|
d.length = 1;
|
|
}
|
|
|
|
// Prepend zeros to equalise exponents.
|
|
d.reverse();
|
|
for (i = k; i--;) d.push(0);
|
|
d.reverse();
|
|
|
|
// Base 1e7 exponents equal.
|
|
} else {
|
|
|
|
// Check digits to determine which is the bigger number.
|
|
|
|
i = xd.length;
|
|
len = yd.length;
|
|
xLTy = i < len;
|
|
if (xLTy) len = i;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
if (xd[i] != yd[i]) {
|
|
xLTy = xd[i] < yd[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
k = 0;
|
|
}
|
|
|
|
if (xLTy) {
|
|
d = xd;
|
|
xd = yd;
|
|
yd = d;
|
|
y.s = -y.s;
|
|
}
|
|
|
|
len = xd.length;
|
|
|
|
// Append zeros to `xd` if shorter.
|
|
// Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length.
|
|
for (i = yd.length - len; i > 0; --i) xd[len++] = 0;
|
|
|
|
// Subtract yd from xd.
|
|
for (i = yd.length; i > k;) {
|
|
|
|
if (xd[--i] < yd[i]) {
|
|
for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1;
|
|
--xd[j];
|
|
xd[i] += BASE;
|
|
}
|
|
|
|
xd[i] -= yd[i];
|
|
}
|
|
|
|
// Remove trailing zeros.
|
|
for (; xd[--len] === 0;) xd.pop();
|
|
|
|
// Remove leading zeros and adjust exponent accordingly.
|
|
for (; xd[0] === 0; xd.shift()) --e;
|
|
|
|
// Zero?
|
|
if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0);
|
|
|
|
y.d = xd;
|
|
y.e = getBase10Exponent(xd, e);
|
|
|
|
return external ? finalise(y, pr, rm) : y;
|
|
};
|
|
|
|
|
|
/*
|
|
* n % 0 = N
|
|
* n % N = N
|
|
* n % I = n
|
|
* 0 % n = 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 = N
|
|
* I % 0 = N
|
|
* I % N = N
|
|
* I % I = N
|
|
*
|
|
* Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to
|
|
* `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* The result depends on the modulo mode.
|
|
*
|
|
*/
|
|
P.modulo = P.mod = function (y) {
|
|
var q,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
y = new Ctor(y);
|
|
|
|
// Return NaN if x is ±Infinity or NaN, or y is NaN or ±0.
|
|
if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN);
|
|
|
|
// Return x if y is ±Infinity or x is ±0.
|
|
if (!y.d || x.d && !x.d[0]) {
|
|
return finalise(new Ctor(x), Ctor.precision, Ctor.rounding);
|
|
}
|
|
|
|
// Prevent rounding of intermediate calculations.
|
|
external = false;
|
|
|
|
if (Ctor.modulo == 9) {
|
|
|
|
// Euclidian division: q = sign(y) * floor(x / abs(y))
|
|
// result = x - q * y where 0 <= result < abs(y)
|
|
q = divide(x, y.abs(), 0, 3, 1);
|
|
q.s *= y.s;
|
|
} else {
|
|
q = divide(x, y, 0, Ctor.modulo, 1);
|
|
}
|
|
|
|
q = q.times(y);
|
|
|
|
external = true;
|
|
|
|
return x.minus(q);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the natural exponential of the value of this Decimal,
|
|
* i.e. the base e raised to the power the value of this Decimal, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.naturalExponential = P.exp = function () {
|
|
return naturalExponential(this);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the natural logarithm of the value of this Decimal,
|
|
* rounded to `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.naturalLogarithm = P.ln = function () {
|
|
return naturalLogarithm(this);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by
|
|
* -1.
|
|
*
|
|
*/
|
|
P.negated = P.neg = function () {
|
|
var x = new this.constructor(this);
|
|
x.s = -x.s;
|
|
return finalise(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 Decimal whose value is the value of this Decimal plus `y`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.plus = P.add = function (y) {
|
|
var carry, d, e, i, k, len, pr, rm, xd, yd,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
y = new Ctor(y);
|
|
|
|
// If either is not finite...
|
|
if (!x.d || !y.d) {
|
|
|
|
// Return NaN if either is NaN.
|
|
if (!x.s || !y.s) y = new Ctor(NaN);
|
|
|
|
// Return x if y is finite and x is ±Infinity.
|
|
// Return x if both are ±Infinity with the same sign.
|
|
// Return NaN if both are ±Infinity with different signs.
|
|
// Return y if x is finite and y is ±Infinity.
|
|
else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN);
|
|
|
|
return y;
|
|
}
|
|
|
|
// If signs differ...
|
|
if (x.s != y.s) {
|
|
y.s = -y.s;
|
|
return x.minus(y);
|
|
}
|
|
|
|
xd = x.d;
|
|
yd = y.d;
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
|
|
// If either is zero...
|
|
if (!xd[0] || !yd[0]) {
|
|
|
|
// Return x if y is zero.
|
|
// Return y if y is non-zero.
|
|
if (!yd[0]) y = new Ctor(x);
|
|
|
|
return external ? finalise(y, pr, rm) : y;
|
|
}
|
|
|
|
// x and y are finite, non-zero numbers with the same sign.
|
|
|
|
// Calculate base 1e7 exponents.
|
|
k = mathfloor(x.e / LOG_BASE);
|
|
e = mathfloor(y.e / LOG_BASE);
|
|
|
|
xd = xd.slice();
|
|
i = k - e;
|
|
|
|
// If base 1e7 exponents differ...
|
|
if (i) {
|
|
|
|
if (i < 0) {
|
|
d = xd;
|
|
i = -i;
|
|
len = yd.length;
|
|
} else {
|
|
d = yd;
|
|
e = k;
|
|
len = xd.length;
|
|
}
|
|
|
|
// Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1.
|
|
k = Math.ceil(pr / LOG_BASE);
|
|
len = k > len ? k + 1 : len + 1;
|
|
|
|
if (i > len) {
|
|
i = len;
|
|
d.length = 1;
|
|
}
|
|
|
|
// Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts.
|
|
d.reverse();
|
|
for (; i--;) d.push(0);
|
|
d.reverse();
|
|
}
|
|
|
|
len = xd.length;
|
|
i = yd.length;
|
|
|
|
// If yd is longer than xd, swap xd and yd so xd points to the longer array.
|
|
if (len - i < 0) {
|
|
i = len;
|
|
d = yd;
|
|
yd = xd;
|
|
xd = d;
|
|
}
|
|
|
|
// Only start adding at yd.length - 1 as the further digits of xd can be left as they are.
|
|
for (carry = 0; i;) {
|
|
carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0;
|
|
xd[i] %= BASE;
|
|
}
|
|
|
|
if (carry) {
|
|
xd.unshift(carry);
|
|
++e;
|
|
}
|
|
|
|
// Remove trailing zeros.
|
|
// No need to check for zero, as +x + +y != 0 && -x + -y != 0
|
|
for (len = xd.length; xd[--len] == 0;) xd.pop();
|
|
|
|
y.d = xd;
|
|
y.e = getBase10Exponent(xd, e);
|
|
|
|
return external ? finalise(y, pr, rm) : y;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return the number of significant digits of the value of this Decimal.
|
|
*
|
|
* [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
|
|
*
|
|
*/
|
|
P.precision = P.sd = function (z) {
|
|
var k,
|
|
x = this;
|
|
|
|
if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z);
|
|
|
|
if (x.d) {
|
|
k = getPrecision(x.d);
|
|
if (z && x.e + 1 > k) k = x.e + 1;
|
|
} else {
|
|
k = NaN;
|
|
}
|
|
|
|
return k;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal rounded to a whole number using
|
|
* rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.round = function () {
|
|
var x = this,
|
|
Ctor = x.constructor;
|
|
|
|
return finalise(new Ctor(x), x.e + 1, Ctor.rounding);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the sine of the value in radians of this Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-1, 1]
|
|
*
|
|
* sin(x) = x - x^3/3! + x^5/5! - ...
|
|
*
|
|
* sin(0) = 0
|
|
* sin(-0) = -0
|
|
* sin(Infinity) = NaN
|
|
* sin(-Infinity) = NaN
|
|
* sin(NaN) = NaN
|
|
*
|
|
*/
|
|
P.sine = P.sin = function () {
|
|
var pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite()) return new Ctor(NaN);
|
|
if (x.isZero()) return new Ctor(x);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE;
|
|
Ctor.rounding = 1;
|
|
|
|
x = sine(Ctor, toLessThanHalfPi(Ctor, x));
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the square root of this Decimal, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* sqrt(-n) = N
|
|
* sqrt(N) = N
|
|
* sqrt(-I) = N
|
|
* sqrt(I) = I
|
|
* sqrt(0) = 0
|
|
* sqrt(-0) = -0
|
|
*
|
|
*/
|
|
P.squareRoot = P.sqrt = function () {
|
|
var m, n, sd, r, rep, t,
|
|
x = this,
|
|
d = x.d,
|
|
e = x.e,
|
|
s = x.s,
|
|
Ctor = x.constructor;
|
|
|
|
// Negative/NaN/Infinity/zero?
|
|
if (s !== 1 || !d || !d[0]) {
|
|
return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0);
|
|
}
|
|
|
|
external = false;
|
|
|
|
// Initial estimate.
|
|
s = Math.sqrt(+x);
|
|
|
|
// Math.sqrt underflow/overflow?
|
|
// Pass x to Math.sqrt as integer, then adjust the exponent of the result.
|
|
if (s == 0 || s == 1 / 0) {
|
|
n = digitsToString(d);
|
|
|
|
if ((n.length + e) % 2 == 0) n += '0';
|
|
s = Math.sqrt(n);
|
|
e = mathfloor((e + 1) / 2) - (e < 0 || e % 2);
|
|
|
|
if (s == 1 / 0) {
|
|
n = '1e' + e;
|
|
} else {
|
|
n = s.toExponential();
|
|
n = n.slice(0, n.indexOf('e') + 1) + e;
|
|
}
|
|
|
|
r = new Ctor(n);
|
|
} else {
|
|
r = new Ctor(s.toString());
|
|
}
|
|
|
|
sd = (e = Ctor.precision) + 3;
|
|
|
|
// Newton-Raphson iteration.
|
|
for (;;) {
|
|
t = r;
|
|
r = t.plus(divide(x, t, sd + 2, 1)).times(0.5);
|
|
|
|
// TODO? Replace with for-loop and checkRoundingDigits.
|
|
if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) {
|
|
n = n.slice(sd - 3, sd + 1);
|
|
|
|
// The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or
|
|
// 4999, i.e. approaching a rounding boundary, continue the iteration.
|
|
if (n == '9999' || !rep && n == '4999') {
|
|
|
|
// On the first iteration only, check to see if rounding up gives the exact result as the
|
|
// nines may infinitely repeat.
|
|
if (!rep) {
|
|
finalise(t, e + 1, 0);
|
|
|
|
if (t.times(t).eq(x)) {
|
|
r = t;
|
|
break;
|
|
}
|
|
}
|
|
|
|
sd += 4;
|
|
rep = 1;
|
|
} else {
|
|
|
|
// If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result.
|
|
// If not, then there are further digits and m will be truthy.
|
|
if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
|
|
|
|
// Truncate to the first rounding digit.
|
|
finalise(r, e + 1, 1);
|
|
m = !r.times(r).eq(x);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
external = true;
|
|
|
|
return finalise(r, e, Ctor.rounding, m);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the tangent of the value in radians of this Decimal.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-Infinity, Infinity]
|
|
*
|
|
* tan(0) = 0
|
|
* tan(-0) = -0
|
|
* tan(Infinity) = NaN
|
|
* tan(-Infinity) = NaN
|
|
* tan(NaN) = NaN
|
|
*
|
|
*/
|
|
P.tangent = P.tan = function () {
|
|
var pr, rm,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (!x.isFinite()) return new Ctor(NaN);
|
|
if (x.isZero()) return new Ctor(x);
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
Ctor.precision = pr + 10;
|
|
Ctor.rounding = 1;
|
|
|
|
x = x.sin();
|
|
x.s = 1;
|
|
x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0);
|
|
|
|
Ctor.precision = pr;
|
|
Ctor.rounding = rm;
|
|
|
|
return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true);
|
|
};
|
|
|
|
|
|
/*
|
|
* 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 Decimal whose value is this Decimal times `y`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
*/
|
|
P.times = P.mul = function (y) {
|
|
var carry, e, i, k, r, rL, t, xdL, ydL,
|
|
x = this,
|
|
Ctor = x.constructor,
|
|
xd = x.d,
|
|
yd = (y = new Ctor(y)).d;
|
|
|
|
y.s *= x.s;
|
|
|
|
// If either is NaN, ±Infinity or ±0...
|
|
if (!xd || !xd[0] || !yd || !yd[0]) {
|
|
|
|
return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd
|
|
|
|
// Return NaN if either is NaN.
|
|
// Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity.
|
|
? NaN
|
|
|
|
// Return ±Infinity if either is ±Infinity.
|
|
// Return ±0 if either is ±0.
|
|
: !xd || !yd ? y.s / 0 : y.s * 0);
|
|
}
|
|
|
|
e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE);
|
|
xdL = xd.length;
|
|
ydL = yd.length;
|
|
|
|
// Ensure xd points to the longer array.
|
|
if (xdL < ydL) {
|
|
r = xd;
|
|
xd = yd;
|
|
yd = r;
|
|
rL = xdL;
|
|
xdL = ydL;
|
|
ydL = rL;
|
|
}
|
|
|
|
// Initialise the result array with zeros.
|
|
r = [];
|
|
rL = xdL + ydL;
|
|
for (i = rL; i--;) r.push(0);
|
|
|
|
// Multiply!
|
|
for (i = ydL; --i >= 0;) {
|
|
carry = 0;
|
|
for (k = xdL + i; k > i;) {
|
|
t = r[k] + yd[i] * xd[k - i - 1] + carry;
|
|
r[k--] = t % BASE | 0;
|
|
carry = t / BASE | 0;
|
|
}
|
|
|
|
r[k] = (r[k] + carry) % BASE | 0;
|
|
}
|
|
|
|
// Remove trailing zeros.
|
|
for (; !r[--rL];) r.pop();
|
|
|
|
if (carry) ++e;
|
|
else r.shift();
|
|
|
|
y.d = r;
|
|
y.e = getBase10Exponent(r, e);
|
|
|
|
return external ? finalise(y, Ctor.precision, Ctor.rounding) : y;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal in base 2, round to `sd` significant
|
|
* digits using rounding mode `rm`.
|
|
*
|
|
* If the optional `sd` argument is present then return binary exponential notation.
|
|
*
|
|
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
*/
|
|
P.toBinary = function (sd, rm) {
|
|
return toStringBinary(this, 2, sd, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp`
|
|
* decimal places using rounding mode `rm` or `rounding` if `rm` is omitted.
|
|
*
|
|
* If `dp` is omitted, return a new Decimal whose value is the value of this Decimal.
|
|
*
|
|
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
*/
|
|
P.toDecimalPlaces = P.toDP = function (dp, rm) {
|
|
var x = this,
|
|
Ctor = x.constructor;
|
|
|
|
x = new Ctor(x);
|
|
if (dp === void 0) return x;
|
|
|
|
checkInt32(dp, 0, MAX_DIGITS);
|
|
|
|
if (rm === void 0) rm = Ctor.rounding;
|
|
else checkInt32(rm, 0, 8);
|
|
|
|
return finalise(x, dp + x.e + 1, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal in exponential notation rounded to
|
|
* `dp` fixed decimal places using rounding mode `rounding`.
|
|
*
|
|
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
*/
|
|
P.toExponential = function (dp, rm) {
|
|
var str,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (dp === void 0) {
|
|
str = finiteToString(x, true);
|
|
} else {
|
|
checkInt32(dp, 0, MAX_DIGITS);
|
|
|
|
if (rm === void 0) rm = Ctor.rounding;
|
|
else checkInt32(rm, 0, 8);
|
|
|
|
x = finalise(new Ctor(x), dp + 1, rm);
|
|
str = finiteToString(x, true, dp + 1);
|
|
}
|
|
|
|
return x.isNeg() && !x.isZero() ? '-' + str : str;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal in normal (fixed-point) notation to
|
|
* `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is
|
|
* omitted.
|
|
*
|
|
* As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
|
|
*
|
|
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
* (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.
|
|
* (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
|
|
* (-0).toFixed(3) is '0.000'.
|
|
* (-0.5).toFixed(0) is '-0'.
|
|
*
|
|
*/
|
|
P.toFixed = function (dp, rm) {
|
|
var str, y,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (dp === void 0) {
|
|
str = finiteToString(x);
|
|
} else {
|
|
checkInt32(dp, 0, MAX_DIGITS);
|
|
|
|
if (rm === void 0) rm = Ctor.rounding;
|
|
else checkInt32(rm, 0, 8);
|
|
|
|
y = finalise(new Ctor(x), dp + x.e + 1, rm);
|
|
str = finiteToString(y, false, dp + y.e + 1);
|
|
}
|
|
|
|
// To determine whether to add the minus sign look at the value before it was rounded,
|
|
// i.e. look at `x` rather than `y`.
|
|
return x.isNeg() && !x.isZero() ? '-' + str : str;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return an array representing the value of this Decimal 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|Decimal} Maximum denominator. Integer >= 1 and < Infinity.
|
|
*
|
|
*/
|
|
P.toFraction = function (maxD) {
|
|
var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r,
|
|
x = this,
|
|
xd = x.d,
|
|
Ctor = x.constructor;
|
|
|
|
if (!xd) return new Ctor(x);
|
|
|
|
n1 = d0 = new Ctor(1);
|
|
d1 = n0 = new Ctor(0);
|
|
|
|
d = new Ctor(d1);
|
|
e = d.e = getPrecision(xd) - x.e - 1;
|
|
k = e % LOG_BASE;
|
|
d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k);
|
|
|
|
if (maxD == null) {
|
|
|
|
// d is 10**e, the minimum max-denominator needed.
|
|
maxD = e > 0 ? d : n1;
|
|
} else {
|
|
n = new Ctor(maxD);
|
|
if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n);
|
|
maxD = n.gt(d) ? (e > 0 ? d : n1) : n;
|
|
}
|
|
|
|
external = false;
|
|
n = new Ctor(digitsToString(xd));
|
|
pr = Ctor.precision;
|
|
Ctor.precision = e = xd.length * LOG_BASE * 2;
|
|
|
|
for (;;) {
|
|
q = divide(n, d, 0, 1, 1);
|
|
d2 = d0.plus(q.times(d1));
|
|
if (d2.cmp(maxD) == 1) break;
|
|
d0 = d1;
|
|
d1 = d2;
|
|
d2 = n1;
|
|
n1 = n0.plus(q.times(d2));
|
|
n0 = d2;
|
|
d2 = d;
|
|
d = n.minus(q.times(d2));
|
|
n = d2;
|
|
}
|
|
|
|
d2 = divide(maxD.minus(d0), d1, 0, 1, 1);
|
|
n0 = n0.plus(d2.times(n1));
|
|
d0 = d0.plus(d2.times(d1));
|
|
n0.s = n1.s = x.s;
|
|
|
|
// Determine which fraction is closer to x, n0/d0 or n1/d1?
|
|
r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1
|
|
? [n1, d1] : [n0, d0];
|
|
|
|
Ctor.precision = pr;
|
|
external = true;
|
|
|
|
return r;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal in base 16, round to `sd` significant
|
|
* digits using rounding mode `rm`.
|
|
*
|
|
* If the optional `sd` argument is present then return binary exponential notation.
|
|
*
|
|
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
*/
|
|
P.toHexadecimal = P.toHex = function (sd, rm) {
|
|
return toStringBinary(this, 16, sd, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Returns a new Decimal whose value is the nearest multiple of `y` in the direction of rounding
|
|
* mode `rm`, or `Decimal.rounding` if `rm` is omitted, to the value of this Decimal.
|
|
*
|
|
* The return value will always have the same sign as this Decimal, unless either this Decimal
|
|
* or `y` is NaN, in which case the return value will be also be NaN.
|
|
*
|
|
* The return value is not affected by the value of `precision`.
|
|
*
|
|
* y {number|string|Decimal} The magnitude to round to a multiple of.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
* 'toNearest() rounding mode not an integer: {rm}'
|
|
* 'toNearest() rounding mode out of range: {rm}'
|
|
*
|
|
*/
|
|
P.toNearest = function (y, rm) {
|
|
var x = this,
|
|
Ctor = x.constructor;
|
|
|
|
x = new Ctor(x);
|
|
|
|
if (y == null) {
|
|
|
|
// If x is not finite, return x.
|
|
if (!x.d) return x;
|
|
|
|
y = new Ctor(1);
|
|
rm = Ctor.rounding;
|
|
} else {
|
|
y = new Ctor(y);
|
|
if (rm === void 0) {
|
|
rm = Ctor.rounding;
|
|
} else {
|
|
checkInt32(rm, 0, 8);
|
|
}
|
|
|
|
// If x is not finite, return x if y is not NaN, else NaN.
|
|
if (!x.d) return y.s ? x : y;
|
|
|
|
// If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN.
|
|
if (!y.d) {
|
|
if (y.s) y.s = x.s;
|
|
return y;
|
|
}
|
|
}
|
|
|
|
// If y is not zero, calculate the nearest multiple of y to x.
|
|
if (y.d[0]) {
|
|
external = false;
|
|
x = divide(x, y, 0, rm, 1).times(y);
|
|
external = true;
|
|
finalise(x);
|
|
|
|
// If y is zero, return zero with the sign of x.
|
|
} else {
|
|
y.s = x.s;
|
|
x = y;
|
|
}
|
|
|
|
return x;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return the value of this Decimal converted to a number primitive.
|
|
* Zero keeps its sign.
|
|
*
|
|
*/
|
|
P.toNumber = function () {
|
|
return +this;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal in base 8, round to `sd` significant
|
|
* digits using rounding mode `rm`.
|
|
*
|
|
* If the optional `sd` argument is present then return binary exponential notation.
|
|
*
|
|
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
*/
|
|
P.toOctal = function (sd, rm) {
|
|
return toStringBinary(this, 8, sd, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded
|
|
* to `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* ECMAScript compliant.
|
|
*
|
|
* pow(x, NaN) = NaN
|
|
* pow(x, ±0) = 1
|
|
|
|
* pow(NaN, non-zero) = NaN
|
|
* pow(abs(x) > 1, +Infinity) = +Infinity
|
|
* pow(abs(x) > 1, -Infinity) = +0
|
|
* pow(abs(x) == 1, ±Infinity) = NaN
|
|
* pow(abs(x) < 1, +Infinity) = +0
|
|
* pow(abs(x) < 1, -Infinity) = +Infinity
|
|
* pow(+Infinity, y > 0) = +Infinity
|
|
* pow(+Infinity, y < 0) = +0
|
|
* pow(-Infinity, odd integer > 0) = -Infinity
|
|
* pow(-Infinity, even integer > 0) = +Infinity
|
|
* pow(-Infinity, odd integer < 0) = -0
|
|
* pow(-Infinity, even integer < 0) = +0
|
|
* pow(+0, y > 0) = +0
|
|
* pow(+0, y < 0) = +Infinity
|
|
* pow(-0, odd integer > 0) = -0
|
|
* pow(-0, even integer > 0) = +0
|
|
* pow(-0, odd integer < 0) = -Infinity
|
|
* pow(-0, even integer < 0) = +Infinity
|
|
* pow(finite x < 0, finite non-integer) = NaN
|
|
*
|
|
* For non-integer or very large exponents pow(x, y) is calculated using
|
|
*
|
|
* x^y = exp(y*ln(x))
|
|
*
|
|
* Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the
|
|
* probability of an incorrectly rounded result
|
|
* P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14
|
|
* i.e. 1 in 250,000,000,000,000
|
|
*
|
|
* If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place).
|
|
*
|
|
* y {number|string|Decimal} The power to which to raise this Decimal.
|
|
*
|
|
*/
|
|
P.toPower = P.pow = function (y) {
|
|
var e, k, pr, r, rm, s,
|
|
x = this,
|
|
Ctor = x.constructor,
|
|
yn = +(y = new Ctor(y));
|
|
|
|
// Either ±Infinity, NaN or ±0?
|
|
if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn));
|
|
|
|
x = new Ctor(x);
|
|
|
|
if (x.eq(1)) return x;
|
|
|
|
pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
|
|
if (y.eq(1)) return finalise(x, pr, rm);
|
|
|
|
// y exponent
|
|
e = mathfloor(y.e / LOG_BASE);
|
|
|
|
// If y is a small integer use the 'exponentiation by squaring' algorithm.
|
|
if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) {
|
|
r = intPow(Ctor, x, k, pr);
|
|
return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm);
|
|
}
|
|
|
|
s = x.s;
|
|
|
|
// if x is negative
|
|
if (s < 0) {
|
|
|
|
// if y is not an integer
|
|
if (e < y.d.length - 1) return new Ctor(NaN);
|
|
|
|
// Result is positive if x is negative and the last digit of integer y is even.
|
|
if ((y.d[e] & 1) == 0) s = 1;
|
|
|
|
// if x.eq(-1)
|
|
if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) {
|
|
x.s = s;
|
|
return x;
|
|
}
|
|
}
|
|
|
|
// Estimate result exponent.
|
|
// x^y = 10^e, where e = y * log10(x)
|
|
// log10(x) = log10(x_significand) + x_exponent
|
|
// log10(x_significand) = ln(x_significand) / ln(10)
|
|
k = mathpow(+x, yn);
|
|
e = k == 0 || !isFinite(k)
|
|
? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1))
|
|
: new Ctor(k + '').e;
|
|
|
|
// Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1.
|
|
|
|
// Overflow/underflow?
|
|
if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0);
|
|
|
|
external = false;
|
|
Ctor.rounding = x.s = 1;
|
|
|
|
// Estimate the extra guard digits needed to ensure five correct rounding digits from
|
|
// naturalLogarithm(x). Example of failure without these extra digits (precision: 10):
|
|
// new Decimal(2.32456).pow('2087987436534566.46411')
|
|
// should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815
|
|
k = Math.min(12, (e + '').length);
|
|
|
|
// r = x^y = exp(y*ln(x))
|
|
r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr);
|
|
|
|
// r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40)
|
|
if (r.d) {
|
|
|
|
// Truncate to the required precision plus five rounding digits.
|
|
r = finalise(r, pr + 5, 1);
|
|
|
|
// If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate
|
|
// the result.
|
|
if (checkRoundingDigits(r.d, pr, rm)) {
|
|
e = pr + 10;
|
|
|
|
// Truncate to the increased precision plus five rounding digits.
|
|
r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1);
|
|
|
|
// Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9).
|
|
if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) {
|
|
r = finalise(r, pr + 1, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
r.s = s;
|
|
external = true;
|
|
Ctor.rounding = rm;
|
|
|
|
return finalise(r, pr, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal rounded to `sd` significant digits
|
|
* using rounding mode `rounding`.
|
|
*
|
|
* Return exponential notation if `sd` is less than the number of digits necessary to represent
|
|
* the integer part of the value in normal notation.
|
|
*
|
|
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
*/
|
|
P.toPrecision = function (sd, rm) {
|
|
var str,
|
|
x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (sd === void 0) {
|
|
str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos);
|
|
} else {
|
|
checkInt32(sd, 1, MAX_DIGITS);
|
|
|
|
if (rm === void 0) rm = Ctor.rounding;
|
|
else checkInt32(rm, 0, 8);
|
|
|
|
x = finalise(new Ctor(x), sd, rm);
|
|
str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd);
|
|
}
|
|
|
|
return x.isNeg() && !x.isZero() ? '-' + str : str;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd`
|
|
* significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if
|
|
* omitted.
|
|
*
|
|
* [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
|
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
|
*
|
|
* 'toSD() digits out of range: {sd}'
|
|
* 'toSD() digits not an integer: {sd}'
|
|
* 'toSD() rounding mode not an integer: {rm}'
|
|
* 'toSD() rounding mode out of range: {rm}'
|
|
*
|
|
*/
|
|
P.toSignificantDigits = P.toSD = function (sd, rm) {
|
|
var x = this,
|
|
Ctor = x.constructor;
|
|
|
|
if (sd === void 0) {
|
|
sd = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
} else {
|
|
checkInt32(sd, 1, MAX_DIGITS);
|
|
|
|
if (rm === void 0) rm = Ctor.rounding;
|
|
else checkInt32(rm, 0, 8);
|
|
}
|
|
|
|
return finalise(new Ctor(x), sd, rm);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal.
|
|
*
|
|
* Return exponential notation if this Decimal has a positive exponent equal to or greater than
|
|
* `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
|
|
*
|
|
*/
|
|
P.toString = function () {
|
|
var x = this,
|
|
Ctor = x.constructor,
|
|
str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos);
|
|
|
|
return x.isNeg() && !x.isZero() ? '-' + str : str;
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of this Decimal truncated to a whole number.
|
|
*
|
|
*/
|
|
P.truncated = P.trunc = function () {
|
|
return finalise(new this.constructor(this), this.e + 1, 1);
|
|
};
|
|
|
|
|
|
/*
|
|
* Return a string representing the value of this Decimal.
|
|
* Unlike `toString`, negative zero will include the minus sign.
|
|
*
|
|
*/
|
|
P.valueOf = P.toJSON = function () {
|
|
var x = this,
|
|
Ctor = x.constructor,
|
|
str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos);
|
|
|
|
return x.isNeg() ? '-' + str : str;
|
|
};
|
|
|
|
|
|
/*
|
|
// Add aliases to match BigDecimal method names.
|
|
// 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;
|
|
*/
|
|
|
|
|
|
// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.
|
|
|
|
|
|
/*
|
|
* digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower,
|
|
* finiteToString, naturalExponential, naturalLogarithm
|
|
* checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest,
|
|
* P.toPrecision, P.toSignificantDigits, toStringBinary, random
|
|
* checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm
|
|
* convertBase toStringBinary, parseOther
|
|
* cos P.cos
|
|
* divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy,
|
|
* P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction,
|
|
* P.toNearest, toStringBinary, naturalExponential, naturalLogarithm,
|
|
* taylorSeries, atan2, parseOther
|
|
* finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh,
|
|
* P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus,
|
|
* P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot,
|
|
* P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed,
|
|
* P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits,
|
|
* P.truncated, divide, getLn10, getPi, naturalExponential,
|
|
* naturalLogarithm, ceil, floor, round, trunc
|
|
* finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf,
|
|
* toStringBinary
|
|
* getBase10Exponent P.minus, P.plus, P.times, parseOther
|
|
* getLn10 P.logarithm, naturalLogarithm
|
|
* getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2
|
|
* getPrecision P.precision, P.toFraction
|
|
* getZeroString digitsToString, finiteToString
|
|
* intPow P.toPower, parseOther
|
|
* isOdd toLessThanHalfPi
|
|
* maxOrMin max, min
|
|
* naturalExponential P.naturalExponential, P.toPower
|
|
* naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm,
|
|
* P.toPower, naturalExponential
|
|
* nonFiniteToString finiteToString, toStringBinary
|
|
* parseDecimal Decimal
|
|
* parseOther Decimal
|
|
* sin P.sin
|
|
* taylorSeries P.cosh, P.sinh, cos, sin
|
|
* toLessThanHalfPi P.cos, P.sin
|
|
* toStringBinary P.toBinary, P.toHexadecimal, P.toOctal
|
|
* truncate intPow
|
|
*
|
|
* Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi,
|
|
* naturalLogarithm, config, parseOther, random, Decimal
|
|
*/
|
|
|
|
|
|
function digitsToString(d) {
|
|
var i, k, ws,
|
|
indexOfLastWord = d.length - 1,
|
|
str = '',
|
|
w = d[0];
|
|
|
|
if (indexOfLastWord > 0) {
|
|
str += w;
|
|
for (i = 1; i < indexOfLastWord; i++) {
|
|
ws = d[i] + '';
|
|
k = LOG_BASE - ws.length;
|
|
if (k) str += getZeroString(k);
|
|
str += ws;
|
|
}
|
|
|
|
w = d[i];
|
|
ws = w + '';
|
|
k = LOG_BASE - ws.length;
|
|
if (k) str += getZeroString(k);
|
|
} else if (w === 0) {
|
|
return '0';
|
|
}
|
|
|
|
// Remove trailing zeros of last w.
|
|
for (; w % 10 === 0;) w /= 10;
|
|
|
|
return str + w;
|
|
}
|
|
|
|
|
|
function checkInt32(i, min, max) {
|
|
if (i !== ~~i || i < min || i > max) {
|
|
throw Error(invalidArgument + i);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Check 5 rounding digits if `repeating` is null, 4 otherwise.
|
|
* `repeating == null` if caller is `log` or `pow`,
|
|
* `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`.
|
|
*/
|
|
function checkRoundingDigits(d, i, rm, repeating) {
|
|
var di, k, r, rd;
|
|
|
|
// Get the length of the first word of the array d.
|
|
for (k = d[0]; k >= 10; k /= 10) --i;
|
|
|
|
// Is the rounding digit in the first word of d?
|
|
if (--i < 0) {
|
|
i += LOG_BASE;
|
|
di = 0;
|
|
} else {
|
|
di = Math.ceil((i + 1) / LOG_BASE);
|
|
i %= LOG_BASE;
|
|
}
|
|
|
|
// i is the index (0 - 6) of the rounding digit.
|
|
// E.g. if within the word 3487563 the first rounding digit is 5,
|
|
// then i = 4, k = 1000, rd = 3487563 % 1000 = 563
|
|
k = mathpow(10, LOG_BASE - i);
|
|
rd = d[di] % k | 0;
|
|
|
|
if (repeating == null) {
|
|
if (i < 3) {
|
|
if (i == 0) rd = rd / 100 | 0;
|
|
else if (i == 1) rd = rd / 10 | 0;
|
|
r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0;
|
|
} else {
|
|
r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) &&
|
|
(d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 ||
|
|
(rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0;
|
|
}
|
|
} else {
|
|
if (i < 4) {
|
|
if (i == 0) rd = rd / 1000 | 0;
|
|
else if (i == 1) rd = rd / 100 | 0;
|
|
else if (i == 2) rd = rd / 10 | 0;
|
|
r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999;
|
|
} else {
|
|
r = ((repeating || rm < 4) && rd + 1 == k ||
|
|
(!repeating && rm > 3) && rd + 1 == k / 2) &&
|
|
(d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1;
|
|
}
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
|
|
// Convert string of `baseIn` to an array of numbers of `baseOut`.
|
|
// Eg. convertBase('255', 10, 16) returns [15, 15].
|
|
// Eg. convertBase('ff', 16, 10) returns [2, 5, 5].
|
|
function convertBase(str, baseIn, baseOut) {
|
|
var j,
|
|
arr = [0],
|
|
arrL,
|
|
i = 0,
|
|
strL = str.length;
|
|
|
|
for (; i < strL;) {
|
|
for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn;
|
|
arr[0] += NUMERALS.indexOf(str.charAt(i++));
|
|
for (j = 0; j < arr.length; j++) {
|
|
if (arr[j] > baseOut - 1) {
|
|
if (arr[j + 1] === void 0) arr[j + 1] = 0;
|
|
arr[j + 1] += arr[j] / baseOut | 0;
|
|
arr[j] %= baseOut;
|
|
}
|
|
}
|
|
}
|
|
|
|
return arr.reverse();
|
|
}
|
|
|
|
|
|
/*
|
|
* cos(x) = 1 - x^2/2! + x^4/4! - ...
|
|
* |x| < pi/2
|
|
*
|
|
*/
|
|
function cosine(Ctor, x) {
|
|
var k, y,
|
|
len = x.d.length;
|
|
|
|
// Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1
|
|
// i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1
|
|
|
|
// Estimate the optimum number of times to use the argument reduction.
|
|
if (len < 32) {
|
|
k = Math.ceil(len / 3);
|
|
y = (1 / tinyPow(4, k)).toString();
|
|
} else {
|
|
k = 16;
|
|
y = '2.3283064365386962890625e-10';
|
|
}
|
|
|
|
Ctor.precision += k;
|
|
|
|
x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1));
|
|
|
|
// Reverse argument reduction
|
|
for (var i = k; i--;) {
|
|
var cos2x = x.times(x);
|
|
x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1);
|
|
}
|
|
|
|
Ctor.precision -= k;
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
/*
|
|
* Perform division in the specified base.
|
|
*/
|
|
var divide = (function () {
|
|
|
|
// Assumes non-zero x and k, and hence non-zero result.
|
|
function multiplyInteger(x, k, base) {
|
|
var temp,
|
|
carry = 0,
|
|
i = x.length;
|
|
|
|
for (x = x.slice(); i--;) {
|
|
temp = x[i] * k + carry;
|
|
x[i] = temp % base | 0;
|
|
carry = temp / base | 0;
|
|
}
|
|
|
|
if (carry) x.unshift(carry);
|
|
|
|
return x;
|
|
}
|
|
|
|
function compare(a, b, aL, bL) {
|
|
var i, r;
|
|
|
|
if (aL != bL) {
|
|
r = aL > bL ? 1 : -1;
|
|
} else {
|
|
for (i = r = 0; i < aL; i++) {
|
|
if (a[i] != b[i]) {
|
|
r = a[i] > b[i] ? 1 : -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
function subtract(a, b, aL, base) {
|
|
var i = 0;
|
|
|
|
// Subtract b from a.
|
|
for (; aL--;) {
|
|
a[aL] -= i;
|
|
i = a[aL] < b[aL] ? 1 : 0;
|
|
a[aL] = i * base + a[aL] - b[aL];
|
|
}
|
|
|
|
// Remove leading zeros.
|
|
for (; !a[0] && a.length > 1;) a.shift();
|
|
}
|
|
|
|
return function (x, y, pr, rm, dp, base) {
|
|
var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0,
|
|
yL, yz,
|
|
Ctor = x.constructor,
|
|
sign = x.s == y.s ? 1 : -1,
|
|
xd = x.d,
|
|
yd = y.d;
|
|
|
|
// Either NaN, Infinity or 0?
|
|
if (!xd || !xd[0] || !yd || !yd[0]) {
|
|
|
|
return new Ctor(// Return NaN if either NaN, or both Infinity or 0.
|
|
!x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN :
|
|
|
|
// Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0.
|
|
xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0);
|
|
}
|
|
|
|
if (base) {
|
|
logBase = 1;
|
|
e = x.e - y.e;
|
|
} else {
|
|
base = BASE;
|
|
logBase = LOG_BASE;
|
|
e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase);
|
|
}
|
|
|
|
yL = yd.length;
|
|
xL = xd.length;
|
|
q = new Ctor(sign);
|
|
qd = q.d = [];
|
|
|
|
// Result exponent may be one less than e.
|
|
// The digit array of a Decimal from toStringBinary may have trailing zeros.
|
|
for (i = 0; yd[i] == (xd[i] || 0); i++);
|
|
|
|
if (yd[i] > (xd[i] || 0)) e--;
|
|
|
|
if (pr == null) {
|
|
sd = pr = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
} else if (dp) {
|
|
sd = pr + (x.e - y.e) + 1;
|
|
} else {
|
|
sd = pr;
|
|
}
|
|
|
|
if (sd < 0) {
|
|
qd.push(1);
|
|
more = true;
|
|
} else {
|
|
|
|
// Convert precision in number of base 10 digits to base 1e7 digits.
|
|
sd = sd / logBase + 2 | 0;
|
|
i = 0;
|
|
|
|
// divisor < 1e7
|
|
if (yL == 1) {
|
|
k = 0;
|
|
yd = yd[0];
|
|
sd++;
|
|
|
|
// k is the carry.
|
|
for (; (i < xL || k) && sd--; i++) {
|
|
t = k * base + (xd[i] || 0);
|
|
qd[i] = t / yd | 0;
|
|
k = t % yd | 0;
|
|
}
|
|
|
|
more = k || i < xL;
|
|
|
|
// divisor >= 1e7
|
|
} else {
|
|
|
|
// Normalise xd and yd so highest order digit of yd is >= base/2
|
|
k = base / (yd[0] + 1) | 0;
|
|
|
|
if (k > 1) {
|
|
yd = multiplyInteger(yd, k, base);
|
|
xd = multiplyInteger(xd, k, base);
|
|
yL = yd.length;
|
|
xL = xd.length;
|
|
}
|
|
|
|
xi = yL;
|
|
rem = xd.slice(0, yL);
|
|
remL = rem.length;
|
|
|
|
// Add zeros to make remainder as long as divisor.
|
|
for (; remL < yL;) rem[remL++] = 0;
|
|
|
|
yz = yd.slice();
|
|
yz.unshift(0);
|
|
yd0 = yd[0];
|
|
|
|
if (yd[1] >= base / 2) ++yd0;
|
|
|
|
do {
|
|
k = 0;
|
|
|
|
// Compare divisor and remainder.
|
|
cmp = compare(yd, rem, yL, remL);
|
|
|
|
// If divisor < remainder.
|
|
if (cmp < 0) {
|
|
|
|
// Calculate trial digit, k.
|
|
rem0 = rem[0];
|
|
if (yL != remL) rem0 = rem0 * base + (rem[1] || 0);
|
|
|
|
// k will be how many times the divisor goes into the current remainder.
|
|
k = rem0 / yd0 | 0;
|
|
|
|
// Algorithm:
|
|
// 1. product = divisor * trial digit (k)
|
|
// 2. if product > remainder: product -= divisor, k--
|
|
// 3. remainder -= product
|
|
// 4. if product was < remainder at 2:
|
|
// 5. compare new remainder and divisor
|
|
// 6. If remainder > divisor: remainder -= divisor, k++
|
|
|
|
if (k > 1) {
|
|
if (k >= base) k = base - 1;
|
|
|
|
// product = divisor * trial digit.
|
|
prod = multiplyInteger(yd, k, base);
|
|
prodL = prod.length;
|
|
remL = rem.length;
|
|
|
|
// Compare product and remainder.
|
|
cmp = compare(prod, rem, prodL, remL);
|
|
|
|
// product > remainder.
|
|
if (cmp == 1) {
|
|
k--;
|
|
|
|
// Subtract divisor from product.
|
|
subtract(prod, yL < prodL ? yz : yd, prodL, base);
|
|
}
|
|
} else {
|
|
|
|
// cmp is -1.
|
|
// If k is 0, there is no need to compare yd and rem again below, so change cmp to 1
|
|
// to avoid it. If k is 1 there is a need to compare yd and rem again below.
|
|
if (k == 0) cmp = k = 1;
|
|
prod = yd.slice();
|
|
}
|
|
|
|
prodL = prod.length;
|
|
if (prodL < remL) prod.unshift(0);
|
|
|
|
// Subtract product from remainder.
|
|
subtract(rem, prod, remL, base);
|
|
|
|
// If product was < previous remainder.
|
|
if (cmp == -1) {
|
|
remL = rem.length;
|
|
|
|
// Compare divisor and new remainder.
|
|
cmp = compare(yd, rem, yL, remL);
|
|
|
|
// If divisor < new remainder, subtract divisor from remainder.
|
|
if (cmp < 1) {
|
|
k++;
|
|
|
|
// Subtract divisor from remainder.
|
|
subtract(rem, yL < remL ? yz : yd, remL, base);
|
|
}
|
|
}
|
|
|
|
remL = rem.length;
|
|
} else if (cmp === 0) {
|
|
k++;
|
|
rem = [0];
|
|
} // if cmp === 1, k will be 0
|
|
|
|
// Add the next digit, k, to the result array.
|
|
qd[i++] = k;
|
|
|
|
// Update the remainder.
|
|
if (cmp && rem[0]) {
|
|
rem[remL++] = xd[xi] || 0;
|
|
} else {
|
|
rem = [xd[xi]];
|
|
remL = 1;
|
|
}
|
|
|
|
} while ((xi++ < xL || rem[0] !== void 0) && sd--);
|
|
|
|
more = rem[0] !== void 0;
|
|
}
|
|
|
|
// Leading zero?
|
|
if (!qd[0]) qd.shift();
|
|
}
|
|
|
|
// logBase is 1 when divide is being used for base conversion.
|
|
if (logBase == 1) {
|
|
q.e = e;
|
|
inexact = more;
|
|
} else {
|
|
|
|
// To calculate q.e, first get the number of digits of qd[0].
|
|
for (i = 1, k = qd[0]; k >= 10; k /= 10) i++;
|
|
q.e = i + e * logBase - 1;
|
|
|
|
finalise(q, dp ? pr + q.e + 1 : pr, rm, more);
|
|
}
|
|
|
|
return q;
|
|
};
|
|
})();
|
|
|
|
|
|
/*
|
|
* Round `x` to `sd` significant digits using rounding mode `rm`.
|
|
* Check for over/under-flow.
|
|
*/
|
|
function finalise(x, sd, rm, isTruncated) {
|
|
var digits, i, j, k, rd, roundUp, w, xd, xdi,
|
|
Ctor = x.constructor;
|
|
|
|
// Don't round if sd is null or undefined.
|
|
out: if (sd != null) {
|
|
xd = x.d;
|
|
|
|
// Infinity/NaN.
|
|
if (!xd) return x;
|
|
|
|
// rd: the rounding digit, i.e. the digit after the digit that may be rounded up.
|
|
// w: the word of xd containing rd, a base 1e7 number.
|
|
// xdi: the index of w within xd.
|
|
// digits: the number of digits of w.
|
|
// i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if
|
|
// they had leading zeros)
|
|
// j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero).
|
|
|
|
// Get the length of the first word of the digits array xd.
|
|
for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++;
|
|
i = sd - digits;
|
|
|
|
// Is the rounding digit in the first word of xd?
|
|
if (i < 0) {
|
|
i += LOG_BASE;
|
|
j = sd;
|
|
w = xd[xdi = 0];
|
|
|
|
// Get the rounding digit at index j of w.
|
|
rd = w / mathpow(10, digits - j - 1) % 10 | 0;
|
|
} else {
|
|
xdi = Math.ceil((i + 1) / LOG_BASE);
|
|
k = xd.length;
|
|
if (xdi >= k) {
|
|
if (isTruncated) {
|
|
|
|
// Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`.
|
|
for (; k++ <= xdi;) xd.push(0);
|
|
w = rd = 0;
|
|
digits = 1;
|
|
i %= LOG_BASE;
|
|
j = i - LOG_BASE + 1;
|
|
} else {
|
|
break out;
|
|
}
|
|
} else {
|
|
w = k = xd[xdi];
|
|
|
|
// Get the number of digits of w.
|
|
for (digits = 1; k >= 10; k /= 10) digits++;
|
|
|
|
// Get the index of rd within w.
|
|
i %= LOG_BASE;
|
|
|
|
// Get the index of rd within w, adjusted for leading zeros.
|
|
// The number of leading zeros of w is given by LOG_BASE - digits.
|
|
j = i - LOG_BASE + digits;
|
|
|
|
// Get the rounding digit at index j of w.
|
|
rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0;
|
|
}
|
|
}
|
|
|
|
// Are there any non-zero digits after the rounding digit?
|
|
isTruncated = isTruncated || sd < 0 ||
|
|
xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1));
|
|
|
|
// The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right
|
|
// of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression
|
|
// will give 714.
|
|
|
|
roundUp = rm < 4
|
|
? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
|
|
: rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 &&
|
|
|
|
// Check whether the digit to the left of the rounding digit is odd.
|
|
((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 ||
|
|
rm == (x.s < 0 ? 8 : 7));
|
|
|
|
if (sd < 1 || !xd[0]) {
|
|
xd.length = 0;
|
|
if (roundUp) {
|
|
|
|
// Convert sd to decimal places.
|
|
sd -= x.e + 1;
|
|
|
|
// 1, 0.1, 0.01, 0.001, 0.0001 etc.
|
|
xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE);
|
|
x.e = -sd || 0;
|
|
} else {
|
|
|
|
// Zero.
|
|
xd[0] = x.e = 0;
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
// Remove excess digits.
|
|
if (i == 0) {
|
|
xd.length = xdi;
|
|
k = 1;
|
|
xdi--;
|
|
} else {
|
|
xd.length = xdi + 1;
|
|
k = mathpow(10, LOG_BASE - i);
|
|
|
|
// E.g. 56700 becomes 56000 if 7 is the rounding digit.
|
|
// j > 0 means i > number of leading zeros of w.
|
|
xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0;
|
|
}
|
|
|
|
if (roundUp) {
|
|
for (;;) {
|
|
|
|
// Is the digit to be rounded up in the first word of xd?
|
|
if (xdi == 0) {
|
|
|
|
// i will be the length of xd[0] before k is added.
|
|
for (i = 1, j = xd[0]; j >= 10; j /= 10) i++;
|
|
j = xd[0] += k;
|
|
for (k = 1; j >= 10; j /= 10) k++;
|
|
|
|
// if i != k the length has increased.
|
|
if (i != k) {
|
|
x.e++;
|
|
if (xd[0] == BASE) xd[0] = 1;
|
|
}
|
|
|
|
break;
|
|
} else {
|
|
xd[xdi] += k;
|
|
if (xd[xdi] != BASE) break;
|
|
xd[xdi--] = 0;
|
|
k = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove trailing zeros.
|
|
for (i = xd.length; xd[--i] === 0;) xd.pop();
|
|
}
|
|
|
|
if (external) {
|
|
|
|
// Overflow?
|
|
if (x.e > Ctor.maxE) {
|
|
|
|
// Infinity.
|
|
x.d = null;
|
|
x.e = NaN;
|
|
|
|
// Underflow?
|
|
} else if (x.e < Ctor.minE) {
|
|
|
|
// Zero.
|
|
x.e = 0;
|
|
x.d = [0];
|
|
// Ctor.underflow = true;
|
|
} // else Ctor.underflow = false;
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
function finiteToString(x, isExp, sd) {
|
|
if (!x.isFinite()) return nonFiniteToString(x);
|
|
var k,
|
|
e = x.e,
|
|
str = digitsToString(x.d),
|
|
len = str.length;
|
|
|
|
if (isExp) {
|
|
if (sd && (k = sd - len) > 0) {
|
|
str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k);
|
|
} else if (len > 1) {
|
|
str = str.charAt(0) + '.' + str.slice(1);
|
|
}
|
|
|
|
str = str + (x.e < 0 ? 'e' : 'e+') + x.e;
|
|
} else if (e < 0) {
|
|
str = '0.' + getZeroString(-e - 1) + str;
|
|
if (sd && (k = sd - len) > 0) str += getZeroString(k);
|
|
} else if (e >= len) {
|
|
str += getZeroString(e + 1 - len);
|
|
if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k);
|
|
} else {
|
|
if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k);
|
|
if (sd && (k = sd - len) > 0) {
|
|
if (e + 1 === len) str += '.';
|
|
str += getZeroString(k);
|
|
}
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
|
|
// Calculate the base 10 exponent from the base 1e7 exponent.
|
|
function getBase10Exponent(digits, e) {
|
|
var w = digits[0];
|
|
|
|
// Add the number of digits of the first word of the digits array.
|
|
for ( e *= LOG_BASE; w >= 10; w /= 10) e++;
|
|
return e;
|
|
}
|
|
|
|
|
|
function getLn10(Ctor, sd, pr) {
|
|
if (sd > LN10_PRECISION) {
|
|
|
|
// Reset global state in case the exception is caught.
|
|
external = true;
|
|
if (pr) Ctor.precision = pr;
|
|
throw Error(precisionLimitExceeded);
|
|
}
|
|
return finalise(new Ctor(LN10), sd, 1, true);
|
|
}
|
|
|
|
|
|
function getPi(Ctor, sd, rm) {
|
|
if (sd > PI_PRECISION) throw Error(precisionLimitExceeded);
|
|
return finalise(new Ctor(PI), sd, rm, true);
|
|
}
|
|
|
|
|
|
function getPrecision(digits) {
|
|
var w = digits.length - 1,
|
|
len = w * LOG_BASE + 1;
|
|
|
|
w = digits[w];
|
|
|
|
// If non-zero...
|
|
if (w) {
|
|
|
|
// Subtract the number of trailing zeros of the last word.
|
|
for (; w % 10 == 0; w /= 10) len--;
|
|
|
|
// Add the number of digits of the first word.
|
|
for (w = digits[0]; w >= 10; w /= 10) len++;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
|
|
function getZeroString(k) {
|
|
var zs = '';
|
|
for (; k--;) zs += '0';
|
|
return zs;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an
|
|
* integer of type number.
|
|
*
|
|
* Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`.
|
|
*
|
|
*/
|
|
function intPow(Ctor, x, n, pr) {
|
|
var isTruncated,
|
|
r = new Ctor(1),
|
|
|
|
// Max n of 9007199254740991 takes 53 loop iterations.
|
|
// Maximum digits array length; leaves [28, 34] guard digits.
|
|
k = Math.ceil(pr / LOG_BASE + 4);
|
|
|
|
external = false;
|
|
|
|
for (;;) {
|
|
if (n % 2) {
|
|
r = r.times(x);
|
|
if (truncate(r.d, k)) isTruncated = true;
|
|
}
|
|
|
|
n = mathfloor(n / 2);
|
|
if (n === 0) {
|
|
|
|
// To ensure correct rounding when r.d is truncated, increment the last word if it is zero.
|
|
n = r.d.length - 1;
|
|
if (isTruncated && r.d[n] === 0) ++r.d[n];
|
|
break;
|
|
}
|
|
|
|
x = x.times(x);
|
|
truncate(x.d, k);
|
|
}
|
|
|
|
external = true;
|
|
|
|
return r;
|
|
}
|
|
|
|
|
|
function isOdd(n) {
|
|
return n.d[n.d.length - 1] & 1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Handle `max` and `min`. `ltgt` is 'lt' or 'gt'.
|
|
*/
|
|
function maxOrMin(Ctor, args, ltgt) {
|
|
var y,
|
|
x = new Ctor(args[0]),
|
|
i = 0;
|
|
|
|
for (; ++i < args.length;) {
|
|
y = new Ctor(args[i]);
|
|
if (!y.s) {
|
|
x = y;
|
|
break;
|
|
} else if (x[ltgt](y)) {
|
|
x = y;
|
|
}
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant
|
|
* digits.
|
|
*
|
|
* Taylor/Maclaurin series.
|
|
*
|
|
* exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ...
|
|
*
|
|
* Argument reduction:
|
|
* Repeat x = x / 32, k += 5, until |x| < 0.1
|
|
* exp(x) = exp(x / 2^k)^(2^k)
|
|
*
|
|
* Previously, the argument was initially reduced by
|
|
* exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10)
|
|
* to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was
|
|
* found to be slower than just dividing repeatedly by 32 as above.
|
|
*
|
|
* Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000
|
|
* Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000
|
|
* (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324)
|
|
*
|
|
* exp(Infinity) = Infinity
|
|
* exp(-Infinity) = 0
|
|
* exp(NaN) = NaN
|
|
* exp(±0) = 1
|
|
*
|
|
* exp(x) is non-terminating for any finite, non-zero x.
|
|
*
|
|
* The result will always be correctly rounded.
|
|
*
|
|
*/
|
|
function naturalExponential(x, sd) {
|
|
var denominator, guard, j, pow, sum, t, wpr,
|
|
rep = 0,
|
|
i = 0,
|
|
k = 0,
|
|
Ctor = x.constructor,
|
|
rm = Ctor.rounding,
|
|
pr = Ctor.precision;
|
|
|
|
// 0/NaN/Infinity?
|
|
if (!x.d || !x.d[0] || x.e > 17) {
|
|
|
|
return new Ctor(x.d
|
|
? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0
|
|
: x.s ? x.s < 0 ? 0 : x : 0 / 0);
|
|
}
|
|
|
|
if (sd == null) {
|
|
external = false;
|
|
wpr = pr;
|
|
} else {
|
|
wpr = sd;
|
|
}
|
|
|
|
t = new Ctor(0.03125);
|
|
|
|
// while abs(x) >= 0.1
|
|
while (x.e > -2) {
|
|
|
|
// x = x / 2^5
|
|
x = x.times(t);
|
|
k += 5;
|
|
}
|
|
|
|
// Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision
|
|
// necessary to ensure the first 4 rounding digits are correct.
|
|
guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0;
|
|
wpr += guard;
|
|
denominator = pow = sum = new Ctor(1);
|
|
Ctor.precision = wpr;
|
|
|
|
for (;;) {
|
|
pow = finalise(pow.times(x), wpr, 1);
|
|
denominator = denominator.times(++i);
|
|
t = sum.plus(divide(pow, denominator, wpr, 1));
|
|
|
|
if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
|
|
j = k;
|
|
while (j--) sum = finalise(sum.times(sum), wpr, 1);
|
|
|
|
// Check to see if the first 4 rounding digits are [49]999.
|
|
// If so, repeat the summation with a higher precision, otherwise
|
|
// e.g. with precision: 18, rounding: 1
|
|
// exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123)
|
|
// `wpr - guard` is the index of first rounding digit.
|
|
if (sd == null) {
|
|
|
|
if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) {
|
|
Ctor.precision = wpr += 10;
|
|
denominator = pow = t = new Ctor(1);
|
|
i = 0;
|
|
rep++;
|
|
} else {
|
|
return finalise(sum, Ctor.precision = pr, rm, external = true);
|
|
}
|
|
} else {
|
|
Ctor.precision = pr;
|
|
return sum;
|
|
}
|
|
}
|
|
|
|
sum = t;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant
|
|
* digits.
|
|
*
|
|
* ln(-n) = NaN
|
|
* ln(0) = -Infinity
|
|
* ln(-0) = -Infinity
|
|
* ln(1) = 0
|
|
* ln(Infinity) = Infinity
|
|
* ln(-Infinity) = NaN
|
|
* ln(NaN) = NaN
|
|
*
|
|
* ln(n) (n != 1) is non-terminating.
|
|
*
|
|
*/
|
|
function naturalLogarithm(y, sd) {
|
|
var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2,
|
|
n = 1,
|
|
guard = 10,
|
|
x = y,
|
|
xd = x.d,
|
|
Ctor = x.constructor,
|
|
rm = Ctor.rounding,
|
|
pr = Ctor.precision;
|
|
|
|
// Is x negative or Infinity, NaN, 0 or 1?
|
|
if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) {
|
|
return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x);
|
|
}
|
|
|
|
if (sd == null) {
|
|
external = false;
|
|
wpr = pr;
|
|
} else {
|
|
wpr = sd;
|
|
}
|
|
|
|
Ctor.precision = wpr += guard;
|
|
c = digitsToString(xd);
|
|
c0 = c.charAt(0);
|
|
|
|
if (Math.abs(e = x.e) < 1.5e15) {
|
|
|
|
// Argument reduction.
|
|
// The series converges faster the closer the argument is to 1, so using
|
|
// ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b
|
|
// multiply the argument by itself until the leading digits of the significand are 7, 8, 9,
|
|
// 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can
|
|
// later be divided by this number, then separate out the power of 10 using
|
|
// ln(a*10^b) = ln(a) + b*ln(10).
|
|
|
|
// max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14).
|
|
//while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) {
|
|
// max n is 6 (gives 0.7 - 1.3)
|
|
while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) {
|
|
x = x.times(y);
|
|
c = digitsToString(x.d);
|
|
c0 = c.charAt(0);
|
|
n++;
|
|
}
|
|
|
|
e = x.e;
|
|
|
|
if (c0 > 1) {
|
|
x = new Ctor('0.' + c);
|
|
e++;
|
|
} else {
|
|
x = new Ctor(c0 + '.' + c.slice(1));
|
|
}
|
|
} else {
|
|
|
|
// The argument reduction method above may result in overflow if the argument y is a massive
|
|
// number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this
|
|
// function using ln(x*10^e) = ln(x) + e*ln(10).
|
|
t = getLn10(Ctor, wpr + 2, pr).times(e + '');
|
|
x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t);
|
|
Ctor.precision = pr;
|
|
|
|
return sd == null ? finalise(x, pr, rm, external = true) : x;
|
|
}
|
|
|
|
// x1 is x reduced to a value near 1.
|
|
x1 = x;
|
|
|
|
// Taylor series.
|
|
// ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...)
|
|
// where x = (y - 1)/(y + 1) (|x| < 1)
|
|
sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1);
|
|
x2 = finalise(x.times(x), wpr, 1);
|
|
denominator = 3;
|
|
|
|
for (;;) {
|
|
numerator = finalise(numerator.times(x2), wpr, 1);
|
|
t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1));
|
|
|
|
if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
|
|
sum = sum.times(2);
|
|
|
|
// Reverse the argument reduction. Check that e is not 0 because, besides preventing an
|
|
// unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0.
|
|
if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + ''));
|
|
sum = divide(sum, new Ctor(n), wpr, 1);
|
|
|
|
// Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has
|
|
// been repeated previously) and the first 4 rounding digits 9999?
|
|
// If so, restart the summation with a higher precision, otherwise
|
|
// e.g. with precision: 12, rounding: 1
|
|
// ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463.
|
|
// `wpr - guard` is the index of first rounding digit.
|
|
if (sd == null) {
|
|
if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) {
|
|
Ctor.precision = wpr += guard;
|
|
t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1);
|
|
x2 = finalise(x.times(x), wpr, 1);
|
|
denominator = rep = 1;
|
|
} else {
|
|
return finalise(sum, Ctor.precision = pr, rm, external = true);
|
|
}
|
|
} else {
|
|
Ctor.precision = pr;
|
|
return sum;
|
|
}
|
|
}
|
|
|
|
sum = t;
|
|
denominator += 2;
|
|
}
|
|
}
|
|
|
|
|
|
// ±Infinity, NaN.
|
|
function nonFiniteToString(x) {
|
|
// Unsigned.
|
|
return String(x.s * x.s / 0);
|
|
}
|
|
|
|
|
|
/*
|
|
* Parse the value of a new Decimal `x` from string `str`.
|
|
*/
|
|
function parseDecimal(x, str) {
|
|
var e, i, len;
|
|
|
|
// Decimal point?
|
|
if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
|
|
|
|
// Exponential form?
|
|
if ((i = str.search(/e/i)) > 0) {
|
|
|
|
// Determine exponent.
|
|
if (e < 0) e = i;
|
|
e += +str.slice(i + 1);
|
|
str = str.substring(0, i);
|
|
} else if (e < 0) {
|
|
|
|
// Integer.
|
|
e = str.length;
|
|
}
|
|
|
|
// Determine leading zeros.
|
|
for (i = 0; str.charCodeAt(i) === 48; i++);
|
|
|
|
// Determine trailing zeros.
|
|
for (len = str.length; str.charCodeAt(len - 1) === 48; --len);
|
|
str = str.slice(i, len);
|
|
|
|
if (str) {
|
|
len -= i;
|
|
x.e = e = e - i - 1;
|
|
x.d = [];
|
|
|
|
// Transform base
|
|
|
|
// e is the base 10 exponent.
|
|
// i is where to slice str to get the first word of the digits array.
|
|
i = (e + 1) % LOG_BASE;
|
|
if (e < 0) i += LOG_BASE;
|
|
|
|
if (i < len) {
|
|
if (i) x.d.push(+str.slice(0, i));
|
|
for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE));
|
|
str = str.slice(i);
|
|
i = LOG_BASE - str.length;
|
|
} else {
|
|
i -= len;
|
|
}
|
|
|
|
for (; i--;) str += '0';
|
|
x.d.push(+str);
|
|
|
|
if (external) {
|
|
|
|
// Overflow?
|
|
if (x.e > x.constructor.maxE) {
|
|
|
|
// Infinity.
|
|
x.d = null;
|
|
x.e = NaN;
|
|
|
|
// Underflow?
|
|
} else if (x.e < x.constructor.minE) {
|
|
|
|
// Zero.
|
|
x.e = 0;
|
|
x.d = [0];
|
|
// x.constructor.underflow = true;
|
|
} // else x.constructor.underflow = false;
|
|
}
|
|
} else {
|
|
|
|
// Zero.
|
|
x.e = 0;
|
|
x.d = [0];
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
/*
|
|
* Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value.
|
|
*/
|
|
function parseOther(x, str) {
|
|
var base, Ctor, divisor, i, isFloat, len, p, xd, xe;
|
|
|
|
if (str === 'Infinity' || str === 'NaN') {
|
|
if (!+str) x.s = NaN;
|
|
x.e = NaN;
|
|
x.d = null;
|
|
return x;
|
|
}
|
|
|
|
if (isHex.test(str)) {
|
|
base = 16;
|
|
str = str.toLowerCase();
|
|
} else if (isBinary.test(str)) {
|
|
base = 2;
|
|
} else if (isOctal.test(str)) {
|
|
base = 8;
|
|
} else {
|
|
throw Error(invalidArgument + str);
|
|
}
|
|
|
|
// Is there a binary exponent part?
|
|
i = str.search(/p/i);
|
|
|
|
if (i > 0) {
|
|
p = +str.slice(i + 1);
|
|
str = str.substring(2, i);
|
|
} else {
|
|
str = str.slice(2);
|
|
}
|
|
|
|
// Convert `str` as an integer then divide the result by `base` raised to a power such that the
|
|
// fraction part will be restored.
|
|
i = str.indexOf('.');
|
|
isFloat = i >= 0;
|
|
Ctor = x.constructor;
|
|
|
|
if (isFloat) {
|
|
str = str.replace('.', '');
|
|
len = str.length;
|
|
i = len - i;
|
|
|
|
// log[10](16) = 1.2041... , log[10](88) = 1.9444....
|
|
divisor = intPow(Ctor, new Ctor(base), i, i * 2);
|
|
}
|
|
|
|
xd = convertBase(str, base, BASE);
|
|
xe = xd.length - 1;
|
|
|
|
// Remove trailing zeros.
|
|
for (i = xe; xd[i] === 0; --i) xd.pop();
|
|
if (i < 0) return new Ctor(x.s * 0);
|
|
x.e = getBase10Exponent(xd, xe);
|
|
x.d = xd;
|
|
external = false;
|
|
|
|
// At what precision to perform the division to ensure exact conversion?
|
|
// maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount)
|
|
// log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412
|
|
// E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits.
|
|
// maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount
|
|
// Therefore using 4 * the number of digits of str will always be enough.
|
|
if (isFloat) x = divide(x, divisor, len * 4);
|
|
|
|
// Multiply by the binary exponent part if present.
|
|
if (p) x = x.times(Math.abs(p) < 54 ? mathpow(2, p) : Decimal.pow(2, p));
|
|
external = true;
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
/*
|
|
* sin(x) = x - x^3/3! + x^5/5! - ...
|
|
* |x| < pi/2
|
|
*
|
|
*/
|
|
function sine(Ctor, x) {
|
|
var k,
|
|
len = x.d.length;
|
|
|
|
if (len < 3) return taylorSeries(Ctor, 2, x, x);
|
|
|
|
// Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x)
|
|
// i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5)
|
|
// and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20))
|
|
|
|
// Estimate the optimum number of times to use the argument reduction.
|
|
k = 1.4 * Math.sqrt(len);
|
|
k = k > 16 ? 16 : k | 0;
|
|
|
|
x = x.times(1 / tinyPow(5, k));
|
|
x = taylorSeries(Ctor, 2, x, x);
|
|
|
|
// Reverse argument reduction
|
|
var sin2_x,
|
|
d5 = new Ctor(5),
|
|
d16 = new Ctor(16),
|
|
d20 = new Ctor(20);
|
|
for (; k--;) {
|
|
sin2_x = x.times(x);
|
|
x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20))));
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
// Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`.
|
|
function taylorSeries(Ctor, n, x, y, isHyperbolic) {
|
|
var j, t, u, x2,
|
|
i = 1,
|
|
pr = Ctor.precision,
|
|
k = Math.ceil(pr / LOG_BASE);
|
|
|
|
external = false;
|
|
x2 = x.times(x);
|
|
u = new Ctor(y);
|
|
|
|
for (;;) {
|
|
t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1);
|
|
u = isHyperbolic ? y.plus(t) : y.minus(t);
|
|
y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1);
|
|
t = u.plus(y);
|
|
|
|
if (t.d[k] !== void 0) {
|
|
for (j = k; t.d[j] === u.d[j] && j--;);
|
|
if (j == -1) break;
|
|
}
|
|
|
|
j = u;
|
|
u = y;
|
|
y = t;
|
|
t = j;
|
|
i++;
|
|
}
|
|
|
|
external = true;
|
|
t.d.length = k + 1;
|
|
|
|
return t;
|
|
}
|
|
|
|
|
|
// Exponent e must be positive and non-zero.
|
|
function tinyPow(b, e) {
|
|
var n = b;
|
|
while (--e) n *= b;
|
|
return n;
|
|
}
|
|
|
|
|
|
// Return the absolute value of `x` reduced to less than or equal to half pi.
|
|
function toLessThanHalfPi(Ctor, x) {
|
|
var t,
|
|
isNeg = x.s < 0,
|
|
pi = getPi(Ctor, Ctor.precision, 1),
|
|
halfPi = pi.times(0.5);
|
|
|
|
x = x.abs();
|
|
|
|
if (x.lte(halfPi)) {
|
|
quadrant = isNeg ? 4 : 1;
|
|
return x;
|
|
}
|
|
|
|
t = x.divToInt(pi);
|
|
|
|
if (t.isZero()) {
|
|
quadrant = isNeg ? 3 : 2;
|
|
} else {
|
|
x = x.minus(t.times(pi));
|
|
|
|
// 0 <= x < pi
|
|
if (x.lte(halfPi)) {
|
|
quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1);
|
|
return x;
|
|
}
|
|
|
|
quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2);
|
|
}
|
|
|
|
return x.minus(pi).abs();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return the value of Decimal `x` as a string in base `baseOut`.
|
|
*
|
|
* If the optional `sd` argument is present include a binary exponent suffix.
|
|
*/
|
|
function toStringBinary(x, baseOut, sd, rm) {
|
|
var base, e, i, k, len, roundUp, str, xd, y,
|
|
Ctor = x.constructor,
|
|
isExp = sd !== void 0;
|
|
|
|
if (isExp) {
|
|
checkInt32(sd, 1, MAX_DIGITS);
|
|
if (rm === void 0) rm = Ctor.rounding;
|
|
else checkInt32(rm, 0, 8);
|
|
} else {
|
|
sd = Ctor.precision;
|
|
rm = Ctor.rounding;
|
|
}
|
|
|
|
if (!x.isFinite()) {
|
|
str = nonFiniteToString(x);
|
|
} else {
|
|
str = finiteToString(x);
|
|
i = str.indexOf('.');
|
|
|
|
// Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required:
|
|
// maxBinaryExponent = floor((decimalExponent + 1) * log[2](10))
|
|
// minBinaryExponent = floor(decimalExponent * log[2](10))
|
|
// log[2](10) = 3.321928094887362347870319429489390175864
|
|
|
|
if (isExp) {
|
|
base = 2;
|
|
if (baseOut == 16) {
|
|
sd = sd * 4 - 3;
|
|
} else if (baseOut == 8) {
|
|
sd = sd * 3 - 2;
|
|
}
|
|
} else {
|
|
base = baseOut;
|
|
}
|
|
|
|
// Convert the number as an integer then divide the result by its base raised to a power such
|
|
// that the fraction part will be restored.
|
|
|
|
// Non-integer.
|
|
if (i >= 0) {
|
|
str = str.replace('.', '');
|
|
y = new Ctor(1);
|
|
y.e = str.length - i;
|
|
y.d = convertBase(finiteToString(y), 10, base);
|
|
y.e = y.d.length;
|
|
}
|
|
|
|
xd = convertBase(str, 10, base);
|
|
e = len = xd.length;
|
|
|
|
// Remove trailing zeros.
|
|
for (; xd[--len] == 0;) xd.pop();
|
|
|
|
if (!xd[0]) {
|
|
str = isExp ? '0p+0' : '0';
|
|
} else {
|
|
if (i < 0) {
|
|
e--;
|
|
} else {
|
|
x = new Ctor(x);
|
|
x.d = xd;
|
|
x.e = e;
|
|
x = divide(x, y, sd, rm, 0, base);
|
|
xd = x.d;
|
|
e = x.e;
|
|
roundUp = inexact;
|
|
}
|
|
|
|
// The rounding digit, i.e. the digit after the digit that may be rounded up.
|
|
i = xd[sd];
|
|
k = base / 2;
|
|
roundUp = roundUp || xd[sd + 1] !== void 0;
|
|
|
|
roundUp = rm < 4
|
|
? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2))
|
|
: i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 ||
|
|
rm === (x.s < 0 ? 8 : 7));
|
|
|
|
xd.length = sd;
|
|
|
|
if (roundUp) {
|
|
|
|
// Rounding up may mean the previous digit has to be rounded up and so on.
|
|
for (; ++xd[--sd] > base - 1;) {
|
|
xd[sd] = 0;
|
|
if (!sd) {
|
|
++e;
|
|
xd.unshift(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Determine trailing zeros.
|
|
for (len = xd.length; !xd[len - 1]; --len);
|
|
|
|
// E.g. [4, 11, 15] becomes 4bf.
|
|
for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]);
|
|
|
|
// Add binary exponent suffix?
|
|
if (isExp) {
|
|
if (len > 1) {
|
|
if (baseOut == 16 || baseOut == 8) {
|
|
i = baseOut == 16 ? 4 : 3;
|
|
for (--len; len % i; len++) str += '0';
|
|
xd = convertBase(str, base, baseOut);
|
|
for (len = xd.length; !xd[len - 1]; --len);
|
|
|
|
// xd[0] will always be be 1
|
|
for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]);
|
|
} else {
|
|
str = str.charAt(0) + '.' + str.slice(1);
|
|
}
|
|
}
|
|
|
|
str = str + (e < 0 ? 'p' : 'p+') + e;
|
|
} else if (e < 0) {
|
|
for (; ++e;) str = '0' + str;
|
|
str = '0.' + str;
|
|
} else {
|
|
if (++e > len) for (e -= len; e-- ;) str += '0';
|
|
else if (e < len) str = str.slice(0, e) + '.' + str.slice(e);
|
|
}
|
|
}
|
|
|
|
str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str;
|
|
}
|
|
|
|
return x.s < 0 ? '-' + str : str;
|
|
}
|
|
|
|
|
|
// Does not strip trailing zeros.
|
|
function truncate(arr, len) {
|
|
if (arr.length > len) {
|
|
arr.length = len;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
// Decimal methods
|
|
|
|
|
|
/*
|
|
* abs
|
|
* acos
|
|
* acosh
|
|
* add
|
|
* asin
|
|
* asinh
|
|
* atan
|
|
* atanh
|
|
* atan2
|
|
* cbrt
|
|
* ceil
|
|
* clone
|
|
* config
|
|
* cos
|
|
* cosh
|
|
* div
|
|
* exp
|
|
* floor
|
|
* hypot
|
|
* ln
|
|
* log
|
|
* log2
|
|
* log10
|
|
* max
|
|
* min
|
|
* mod
|
|
* mul
|
|
* pow
|
|
* random
|
|
* round
|
|
* set
|
|
* sign
|
|
* sin
|
|
* sinh
|
|
* sqrt
|
|
* sub
|
|
* tan
|
|
* tanh
|
|
* trunc
|
|
*/
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the absolute value of `x`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function abs(x) {
|
|
return new this(x).abs();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arccosine in radians of `x`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function acos(x) {
|
|
return new this(x).acos();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to
|
|
* `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function acosh(x) {
|
|
return new this(x).acosh();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
* y {number|string|Decimal}
|
|
*
|
|
*/
|
|
function add(x, y) {
|
|
return new this(x).plus(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function asin(x) {
|
|
return new this(x).asin();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to
|
|
* `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function asinh(x) {
|
|
return new this(x).asinh();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function atan(x) {
|
|
return new this(x).atan();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to
|
|
* `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function atanh(x) {
|
|
return new this(x).atanh();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi
|
|
* (inclusive), rounded to `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* Domain: [-Infinity, Infinity]
|
|
* Range: [-pi, pi]
|
|
*
|
|
* y {number|string|Decimal} The y-coordinate.
|
|
* x {number|string|Decimal} The x-coordinate.
|
|
*
|
|
* atan2(±0, -0) = ±pi
|
|
* atan2(±0, +0) = ±0
|
|
* atan2(±0, -x) = ±pi for x > 0
|
|
* atan2(±0, x) = ±0 for x > 0
|
|
* atan2(-y, ±0) = -pi/2 for y > 0
|
|
* atan2(y, ±0) = pi/2 for y > 0
|
|
* atan2(±y, -Infinity) = ±pi for finite y > 0
|
|
* atan2(±y, +Infinity) = ±0 for finite y > 0
|
|
* atan2(±Infinity, x) = ±pi/2 for finite x
|
|
* atan2(±Infinity, -Infinity) = ±3*pi/4
|
|
* atan2(±Infinity, +Infinity) = ±pi/4
|
|
* atan2(NaN, x) = NaN
|
|
* atan2(y, NaN) = NaN
|
|
*
|
|
*/
|
|
function atan2(y, x) {
|
|
y = new this(y);
|
|
x = new this(x);
|
|
var r,
|
|
pr = this.precision,
|
|
rm = this.rounding,
|
|
wpr = pr + 4;
|
|
|
|
// Either NaN
|
|
if (!y.s || !x.s) {
|
|
r = new this(NaN);
|
|
|
|
// Both ±Infinity
|
|
} else if (!y.d && !x.d) {
|
|
r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75);
|
|
r.s = y.s;
|
|
|
|
// x is ±Infinity or y is ±0
|
|
} else if (!x.d || y.isZero()) {
|
|
r = x.s < 0 ? getPi(this, pr, rm) : new this(0);
|
|
r.s = y.s;
|
|
|
|
// y is ±Infinity or x is ±0
|
|
} else if (!y.d || x.isZero()) {
|
|
r = getPi(this, wpr, 1).times(0.5);
|
|
r.s = y.s;
|
|
|
|
// Both non-zero and finite
|
|
} else if (x.s < 0) {
|
|
this.precision = wpr;
|
|
this.rounding = 1;
|
|
r = this.atan(divide(y, x, wpr, 1));
|
|
x = getPi(this, wpr, 1);
|
|
this.precision = pr;
|
|
this.rounding = rm;
|
|
r = y.s < 0 ? r.minus(x) : r.plus(x);
|
|
} else {
|
|
r = this.atan(divide(y, x, wpr, 1));
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function cbrt(x) {
|
|
return new this(x).cbrt();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function ceil(x) {
|
|
return finalise(x = new this(x), x.e + 1, 2);
|
|
}
|
|
|
|
|
|
/*
|
|
* Configure global settings for a Decimal constructor.
|
|
*
|
|
* `obj` is an object with one or more of the following properties,
|
|
*
|
|
* precision {number}
|
|
* rounding {number}
|
|
* toExpNeg {number}
|
|
* toExpPos {number}
|
|
* maxE {number}
|
|
* minE {number}
|
|
* modulo {number}
|
|
* crypto {boolean|number}
|
|
* defaults {true}
|
|
*
|
|
* E.g. Decimal.config({ precision: 20, rounding: 4 })
|
|
*
|
|
*/
|
|
function config(obj) {
|
|
if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected');
|
|
var i, p, v,
|
|
useDefaults = obj.defaults === true,
|
|
ps = [
|
|
'precision', 1, MAX_DIGITS,
|
|
'rounding', 0, 8,
|
|
'toExpNeg', -EXP_LIMIT, 0,
|
|
'toExpPos', 0, EXP_LIMIT,
|
|
'maxE', 0, EXP_LIMIT,
|
|
'minE', -EXP_LIMIT, 0,
|
|
'modulo', 0, 9
|
|
];
|
|
|
|
for (i = 0; i < ps.length; i += 3) {
|
|
if (p = ps[i], useDefaults) this[p] = DEFAULTS[p];
|
|
if ((v = obj[p]) !== void 0) {
|
|
if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v;
|
|
else throw Error(invalidArgument + p + ': ' + v);
|
|
}
|
|
}
|
|
|
|
if (p = 'crypto', useDefaults) this[p] = DEFAULTS[p];
|
|
if ((v = obj[p]) !== void 0) {
|
|
if (v === true || v === false || v === 0 || v === 1) {
|
|
if (v) {
|
|
if (typeof crypto != 'undefined' && crypto &&
|
|
(crypto.getRandomValues || crypto.randomBytes)) {
|
|
this[p] = true;
|
|
} else {
|
|
throw Error(cryptoUnavailable);
|
|
}
|
|
} else {
|
|
this[p] = false;
|
|
}
|
|
} else {
|
|
throw Error(invalidArgument + p + ': ' + v);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function cos(x) {
|
|
return new this(x).cos();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function cosh(x) {
|
|
return new this(x).cosh();
|
|
}
|
|
|
|
|
|
/*
|
|
* Create and return a Decimal constructor with the same configuration properties as this Decimal
|
|
* constructor.
|
|
*
|
|
*/
|
|
function clone(obj) {
|
|
var i, p, ps;
|
|
|
|
/*
|
|
* The Decimal constructor and exported function.
|
|
* Return a new Decimal instance.
|
|
*
|
|
* v {number|string|Decimal} A numeric value.
|
|
*
|
|
*/
|
|
function Decimal(v) {
|
|
var e, i, t,
|
|
x = this;
|
|
|
|
// Decimal called without new.
|
|
if (!(x instanceof Decimal)) return new Decimal(v);
|
|
|
|
// Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor
|
|
// which points to Object.
|
|
x.constructor = Decimal;
|
|
|
|
// Duplicate.
|
|
if (v instanceof Decimal) {
|
|
x.s = v.s;
|
|
|
|
if (external) {
|
|
if (!v.d || v.e > Decimal.maxE) {
|
|
|
|
// Infinity.
|
|
x.e = NaN;
|
|
x.d = null;
|
|
} else if (v.e < Decimal.minE) {
|
|
|
|
// Zero.
|
|
x.e = 0;
|
|
x.d = [0];
|
|
} else {
|
|
x.e = v.e;
|
|
x.d = v.d.slice();
|
|
}
|
|
} else {
|
|
x.e = v.e;
|
|
x.d = v.d ? v.d.slice() : v.d;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
t = typeof v;
|
|
|
|
if (t === 'number') {
|
|
if (v === 0) {
|
|
x.s = 1 / v < 0 ? -1 : 1;
|
|
x.e = 0;
|
|
x.d = [0];
|
|
return;
|
|
}
|
|
|
|
if (v < 0) {
|
|
v = -v;
|
|
x.s = -1;
|
|
} else {
|
|
x.s = 1;
|
|
}
|
|
|
|
// Fast path for small integers.
|
|
if (v === ~~v && v < 1e7) {
|
|
for (e = 0, i = v; i >= 10; i /= 10) e++;
|
|
|
|
if (external) {
|
|
if (e > Decimal.maxE) {
|
|
x.e = NaN;
|
|
x.d = null;
|
|
} else if (e < Decimal.minE) {
|
|
x.e = 0;
|
|
x.d = [0];
|
|
} else {
|
|
x.e = e;
|
|
x.d = [v];
|
|
}
|
|
} else {
|
|
x.e = e;
|
|
x.d = [v];
|
|
}
|
|
|
|
return;
|
|
|
|
// Infinity, NaN.
|
|
} else if (v * 0 !== 0) {
|
|
if (!v) x.s = NaN;
|
|
x.e = NaN;
|
|
x.d = null;
|
|
return;
|
|
}
|
|
|
|
return parseDecimal(x, v.toString());
|
|
|
|
} else if (t !== 'string') {
|
|
throw Error(invalidArgument + v);
|
|
}
|
|
|
|
// Minus sign?
|
|
if ((i = v.charCodeAt(0)) === 45) {
|
|
v = v.slice(1);
|
|
x.s = -1;
|
|
} else {
|
|
// Plus sign?
|
|
if (i === 43) v = v.slice(1);
|
|
x.s = 1;
|
|
}
|
|
|
|
return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v);
|
|
}
|
|
|
|
Decimal.prototype = P;
|
|
|
|
Decimal.ROUND_UP = 0;
|
|
Decimal.ROUND_DOWN = 1;
|
|
Decimal.ROUND_CEIL = 2;
|
|
Decimal.ROUND_FLOOR = 3;
|
|
Decimal.ROUND_HALF_UP = 4;
|
|
Decimal.ROUND_HALF_DOWN = 5;
|
|
Decimal.ROUND_HALF_EVEN = 6;
|
|
Decimal.ROUND_HALF_CEIL = 7;
|
|
Decimal.ROUND_HALF_FLOOR = 8;
|
|
Decimal.EUCLID = 9;
|
|
|
|
Decimal.config = Decimal.set = config;
|
|
Decimal.clone = clone;
|
|
Decimal.isDecimal = isDecimalInstance;
|
|
|
|
Decimal.abs = abs;
|
|
Decimal.acos = acos;
|
|
Decimal.acosh = acosh; // ES6
|
|
Decimal.add = add;
|
|
Decimal.asin = asin;
|
|
Decimal.asinh = asinh; // ES6
|
|
Decimal.atan = atan;
|
|
Decimal.atanh = atanh; // ES6
|
|
Decimal.atan2 = atan2;
|
|
Decimal.cbrt = cbrt; // ES6
|
|
Decimal.ceil = ceil;
|
|
Decimal.cos = cos;
|
|
Decimal.cosh = cosh; // ES6
|
|
Decimal.div = div;
|
|
Decimal.exp = exp;
|
|
Decimal.floor = floor;
|
|
Decimal.hypot = hypot; // ES6
|
|
Decimal.ln = ln;
|
|
Decimal.log = log;
|
|
Decimal.log10 = log10; // ES6
|
|
Decimal.log2 = log2; // ES6
|
|
Decimal.max = max;
|
|
Decimal.min = min;
|
|
Decimal.mod = mod;
|
|
Decimal.mul = mul;
|
|
Decimal.pow = pow;
|
|
Decimal.random = random;
|
|
Decimal.round = round;
|
|
Decimal.sign = sign; // ES6
|
|
Decimal.sin = sin;
|
|
Decimal.sinh = sinh; // ES6
|
|
Decimal.sqrt = sqrt;
|
|
Decimal.sub = sub;
|
|
Decimal.tan = tan;
|
|
Decimal.tanh = tanh; // ES6
|
|
Decimal.trunc = trunc; // ES6
|
|
|
|
if (obj === void 0) obj = {};
|
|
if (obj) {
|
|
if (obj.defaults !== true) {
|
|
ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto'];
|
|
for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p];
|
|
}
|
|
}
|
|
|
|
Decimal.config(obj);
|
|
|
|
return Decimal;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
* y {number|string|Decimal}
|
|
*
|
|
*/
|
|
function div(x, y) {
|
|
return new this(x).div(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} The power to which to raise the base of the natural log.
|
|
*
|
|
*/
|
|
function exp(x) {
|
|
return new this(x).exp();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function floor(x) {
|
|
return finalise(x = new this(x), x.e + 1, 3);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the square root of the sum of the squares of the arguments,
|
|
* rounded to `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* hypot(a, b, ...) = sqrt(a^2 + b^2 + ...)
|
|
*
|
|
* arguments {number|string|Decimal}
|
|
*
|
|
*/
|
|
function hypot() {
|
|
var i, n,
|
|
t = new this(0);
|
|
|
|
external = false;
|
|
|
|
for (i = 0; i < arguments.length;) {
|
|
n = new this(arguments[i++]);
|
|
if (!n.d) {
|
|
if (n.s) {
|
|
external = true;
|
|
return new this(1 / 0);
|
|
}
|
|
t = n;
|
|
} else if (t.d) {
|
|
t = t.plus(n.times(n));
|
|
}
|
|
}
|
|
|
|
external = true;
|
|
|
|
return t.sqrt();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return true if object is a Decimal instance (where Decimal is any Decimal constructor),
|
|
* otherwise return false.
|
|
*
|
|
*/
|
|
function isDecimalInstance(obj) {
|
|
return obj instanceof Decimal || obj && obj.name === '[object Decimal]' || false;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function ln(x) {
|
|
return new this(x).ln();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base
|
|
* is specified, rounded to `precision` significant digits using rounding mode `rounding`.
|
|
*
|
|
* log[y](x)
|
|
*
|
|
* x {number|string|Decimal} The argument of the logarithm.
|
|
* y {number|string|Decimal} The base of the logarithm.
|
|
*
|
|
*/
|
|
function log(x, y) {
|
|
return new this(x).log(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function log2(x) {
|
|
return new this(x).log(2);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function log10(x) {
|
|
return new this(x).log(10);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the maximum of the arguments.
|
|
*
|
|
* arguments {number|string|Decimal}
|
|
*
|
|
*/
|
|
function max() {
|
|
return maxOrMin(this, arguments, 'lt');
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the minimum of the arguments.
|
|
*
|
|
* arguments {number|string|Decimal}
|
|
*
|
|
*/
|
|
function min() {
|
|
return maxOrMin(this, arguments, 'gt');
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits
|
|
* using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
* y {number|string|Decimal}
|
|
*
|
|
*/
|
|
function mod(x, y) {
|
|
return new this(x).mod(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
* y {number|string|Decimal}
|
|
*
|
|
*/
|
|
function mul(x, y) {
|
|
return new this(x).mul(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} The base.
|
|
* y {number|string|Decimal} The exponent.
|
|
*
|
|
*/
|
|
function pow(x, y) {
|
|
return new this(x).pow(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with
|
|
* `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros
|
|
* are produced).
|
|
*
|
|
* [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive.
|
|
*
|
|
*/
|
|
function random(sd) {
|
|
var d, e, k, n,
|
|
i = 0,
|
|
r = new this(1),
|
|
rd = [];
|
|
|
|
if (sd === void 0) sd = this.precision;
|
|
else checkInt32(sd, 1, MAX_DIGITS);
|
|
|
|
k = Math.ceil(sd / LOG_BASE);
|
|
|
|
if (!this.crypto) {
|
|
for (; i < k;) rd[i++] = Math.random() * 1e7 | 0;
|
|
|
|
// Browsers supporting crypto.getRandomValues.
|
|
} else if (crypto.getRandomValues) {
|
|
d = crypto.getRandomValues(new Uint32Array(k));
|
|
|
|
for (; i < k;) {
|
|
n = d[i];
|
|
|
|
// 0 <= n < 4294967296
|
|
// Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865).
|
|
if (n >= 4.29e9) {
|
|
d[i] = crypto.getRandomValues(new Uint32Array(1))[0];
|
|
} else {
|
|
|
|
// 0 <= n <= 4289999999
|
|
// 0 <= (n % 1e7) <= 9999999
|
|
rd[i++] = n % 1e7;
|
|
}
|
|
}
|
|
|
|
// Node.js supporting crypto.randomBytes.
|
|
} else if (crypto.randomBytes) {
|
|
|
|
// buffer
|
|
d = crypto.randomBytes(k *= 4);
|
|
|
|
for (; i < k;) {
|
|
|
|
// 0 <= n < 2147483648
|
|
n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24);
|
|
|
|
// Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286).
|
|
if (n >= 2.14e9) {
|
|
crypto.randomBytes(4).copy(d, i);
|
|
} else {
|
|
|
|
// 0 <= n <= 2139999999
|
|
// 0 <= (n % 1e7) <= 9999999
|
|
rd.push(n % 1e7);
|
|
i += 4;
|
|
}
|
|
}
|
|
|
|
i = k / 4;
|
|
} else {
|
|
throw Error(cryptoUnavailable);
|
|
}
|
|
|
|
k = rd[--i];
|
|
sd %= LOG_BASE;
|
|
|
|
// Convert trailing digits to zeros according to sd.
|
|
if (k && sd) {
|
|
n = mathpow(10, LOG_BASE - sd);
|
|
rd[i] = (k / n | 0) * n;
|
|
}
|
|
|
|
// Remove trailing words which are zero.
|
|
for (; rd[i] === 0; i--) rd.pop();
|
|
|
|
// Zero?
|
|
if (i < 0) {
|
|
e = 0;
|
|
rd = [0];
|
|
} else {
|
|
e = -1;
|
|
|
|
// Remove leading words which are zero and adjust exponent accordingly.
|
|
for (; rd[0] === 0; e -= LOG_BASE) rd.shift();
|
|
|
|
// Count the digits of the first word of rd to determine leading zeros.
|
|
for (k = 1, n = rd[0]; n >= 10; n /= 10) k++;
|
|
|
|
// Adjust the exponent for leading zeros of the first word of rd.
|
|
if (k < LOG_BASE) e -= LOG_BASE - k;
|
|
}
|
|
|
|
r.e = e;
|
|
r.d = rd;
|
|
|
|
return r;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`.
|
|
*
|
|
* To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL).
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function round(x) {
|
|
return finalise(x = new this(x), x.e + 1, this.rounding);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return
|
|
* 1 if x > 0,
|
|
* -1 if x < 0,
|
|
* 0 if x is 0,
|
|
* -0 if x is -0,
|
|
* NaN otherwise
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function sign(x) {
|
|
x = new this(x);
|
|
return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits
|
|
* using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function sin(x) {
|
|
return new this(x).sin();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function sinh(x) {
|
|
return new this(x).sinh();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function sqrt(x) {
|
|
return new this(x).sqrt();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits
|
|
* using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal}
|
|
* y {number|string|Decimal}
|
|
*
|
|
*/
|
|
function sub(x, y) {
|
|
return new this(x).sub(y);
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant
|
|
* digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function tan(x) {
|
|
return new this(x).tan();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision`
|
|
* significant digits using rounding mode `rounding`.
|
|
*
|
|
* x {number|string|Decimal} A value in radians.
|
|
*
|
|
*/
|
|
function tanh(x) {
|
|
return new this(x).tanh();
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a new Decimal whose value is `x` truncated to an integer.
|
|
*
|
|
* x {number|string|Decimal}
|
|
*
|
|
*/
|
|
function trunc(x) {
|
|
return finalise(x = new this(x), x.e + 1, 1);
|
|
}
|
|
|
|
|
|
// Create and configure initial Decimal constructor.
|
|
Decimal = clone(DEFAULTS);
|
|
|
|
Decimal['default'] = Decimal.Decimal = Decimal;
|
|
|
|
// Create the internal constants from their string values.
|
|
LN10 = new Decimal(LN10);
|
|
PI = new Decimal(PI);
|
|
|
|
|
|
// Export.
|
|
|
|
|
|
// AMD.
|
|
if (typeof define == 'function' && define.amd) {
|
|
define(function () {
|
|
return Decimal;
|
|
});
|
|
|
|
// Node and other environments that support module.exports.
|
|
} else if (typeof module != 'undefined' && module.exports) {
|
|
if (typeof Symbol == 'function' && typeof Symbol.iterator == 'symbol') {
|
|
P[Symbol.for('nodejs.util.inspect.custom')] = P.toString;
|
|
P[Symbol.toStringTag] = 'Decimal';
|
|
}
|
|
|
|
module.exports = Decimal;
|
|
|
|
// Browser.
|
|
} else {
|
|
if (!globalScope) {
|
|
globalScope = typeof self != 'undefined' && self && self.self == self ? self : window;
|
|
}
|
|
|
|
noConflict = globalScope.Decimal;
|
|
Decimal.noConflict = function () {
|
|
globalScope.Decimal = noConflict;
|
|
return Decimal;
|
|
};
|
|
|
|
globalScope.Decimal = Decimal;
|
|
}
|
|
})(this);
|
|
|
|
},{}],7:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var elliptic = exports;
|
|
|
|
elliptic.version = require('../package.json').version;
|
|
elliptic.utils = require('./elliptic/utils');
|
|
elliptic.rand = require('brorand');
|
|
elliptic.curve = require('./elliptic/curve');
|
|
elliptic.curves = require('./elliptic/curves');
|
|
|
|
// Protocols
|
|
elliptic.ec = require('./elliptic/ec');
|
|
elliptic.eddsa = require('./elliptic/eddsa');
|
|
|
|
},{"../package.json":23,"./elliptic/curve":10,"./elliptic/curves":13,"./elliptic/ec":14,"./elliptic/eddsa":17,"./elliptic/utils":21,"brorand":3}],8:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var BN = require('bn.js');
|
|
var utils = require('../utils');
|
|
var getNAF = utils.getNAF;
|
|
var getJSF = utils.getJSF;
|
|
var assert = utils.assert;
|
|
|
|
function BaseCurve(type, conf) {
|
|
this.type = type;
|
|
this.p = new BN(conf.p, 16);
|
|
|
|
// Use Montgomery, when there is no fast reduction for the prime
|
|
this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
|
|
|
|
// Useful for many curves
|
|
this.zero = new BN(0).toRed(this.red);
|
|
this.one = new BN(1).toRed(this.red);
|
|
this.two = new BN(2).toRed(this.red);
|
|
|
|
// Curve configuration, optional
|
|
this.n = conf.n && new BN(conf.n, 16);
|
|
this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
|
|
|
|
// Temporary arrays
|
|
this._wnafT1 = new Array(4);
|
|
this._wnafT2 = new Array(4);
|
|
this._wnafT3 = new Array(4);
|
|
this._wnafT4 = new Array(4);
|
|
|
|
this._bitLength = this.n ? this.n.bitLength() : 0;
|
|
|
|
// Generalized Greg Maxwell's trick
|
|
var adjustCount = this.n && this.p.div(this.n);
|
|
if (!adjustCount || adjustCount.cmpn(100) > 0) {
|
|
this.redN = null;
|
|
} else {
|
|
this._maxwellTrick = true;
|
|
this.redN = this.n.toRed(this.red);
|
|
}
|
|
}
|
|
module.exports = BaseCurve;
|
|
|
|
BaseCurve.prototype.point = function point() {
|
|
throw new Error('Not implemented');
|
|
};
|
|
|
|
BaseCurve.prototype.validate = function validate() {
|
|
throw new Error('Not implemented');
|
|
};
|
|
|
|
BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
|
|
assert(p.precomputed);
|
|
var doubles = p._getDoubles();
|
|
|
|
var naf = getNAF(k, 1, this._bitLength);
|
|
var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
|
|
I /= 3;
|
|
|
|
// Translate into more windowed form
|
|
var repr = [];
|
|
for (var j = 0; j < naf.length; j += doubles.step) {
|
|
var nafW = 0;
|
|
for (var k = j + doubles.step - 1; k >= j; k--)
|
|
nafW = (nafW << 1) + naf[k];
|
|
repr.push(nafW);
|
|
}
|
|
|
|
var a = this.jpoint(null, null, null);
|
|
var b = this.jpoint(null, null, null);
|
|
for (var i = I; i > 0; i--) {
|
|
for (var j = 0; j < repr.length; j++) {
|
|
var nafW = repr[j];
|
|
if (nafW === i)
|
|
b = b.mixedAdd(doubles.points[j]);
|
|
else if (nafW === -i)
|
|
b = b.mixedAdd(doubles.points[j].neg());
|
|
}
|
|
a = a.add(b);
|
|
}
|
|
return a.toP();
|
|
};
|
|
|
|
BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
|
|
var w = 4;
|
|
|
|
// Precompute window
|
|
var nafPoints = p._getNAFPoints(w);
|
|
w = nafPoints.wnd;
|
|
var wnd = nafPoints.points;
|
|
|
|
// Get NAF form
|
|
var naf = getNAF(k, w, this._bitLength);
|
|
|
|
// Add `this`*(N+1) for every w-NAF index
|
|
var acc = this.jpoint(null, null, null);
|
|
for (var i = naf.length - 1; i >= 0; i--) {
|
|
// Count zeroes
|
|
for (var k = 0; i >= 0 && naf[i] === 0; i--)
|
|
k++;
|
|
if (i >= 0)
|
|
k++;
|
|
acc = acc.dblp(k);
|
|
|
|
if (i < 0)
|
|
break;
|
|
var z = naf[i];
|
|
assert(z !== 0);
|
|
if (p.type === 'affine') {
|
|
// J +- P
|
|
if (z > 0)
|
|
acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
|
|
else
|
|
acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
|
|
} else {
|
|
// J +- J
|
|
if (z > 0)
|
|
acc = acc.add(wnd[(z - 1) >> 1]);
|
|
else
|
|
acc = acc.add(wnd[(-z - 1) >> 1].neg());
|
|
}
|
|
}
|
|
return p.type === 'affine' ? acc.toP() : acc;
|
|
};
|
|
|
|
BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
|
|
points,
|
|
coeffs,
|
|
len,
|
|
jacobianResult) {
|
|
var wndWidth = this._wnafT1;
|
|
var wnd = this._wnafT2;
|
|
var naf = this._wnafT3;
|
|
|
|
// Fill all arrays
|
|
var max = 0;
|
|
for (var i = 0; i < len; i++) {
|
|
var p = points[i];
|
|
var nafPoints = p._getNAFPoints(defW);
|
|
wndWidth[i] = nafPoints.wnd;
|
|
wnd[i] = nafPoints.points;
|
|
}
|
|
|
|
// Comb small window NAFs
|
|
for (var i = len - 1; i >= 1; i -= 2) {
|
|
var a = i - 1;
|
|
var b = i;
|
|
if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
|
|
naf[a] = getNAF(coeffs[a], wndWidth[a], this._bitLength);
|
|
naf[b] = getNAF(coeffs[b], wndWidth[b], this._bitLength);
|
|
max = Math.max(naf[a].length, max);
|
|
max = Math.max(naf[b].length, max);
|
|
continue;
|
|
}
|
|
|
|
var comb = [
|
|
points[a], /* 1 */
|
|
null, /* 3 */
|
|
null, /* 5 */
|
|
points[b] /* 7 */
|
|
];
|
|
|
|
// Try to avoid Projective points, if possible
|
|
if (points[a].y.cmp(points[b].y) === 0) {
|
|
comb[1] = points[a].add(points[b]);
|
|
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
|
} else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
|
|
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
|
comb[2] = points[a].add(points[b].neg());
|
|
} else {
|
|
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
|
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
|
}
|
|
|
|
var index = [
|
|
-3, /* -1 -1 */
|
|
-1, /* -1 0 */
|
|
-5, /* -1 1 */
|
|
-7, /* 0 -1 */
|
|
0, /* 0 0 */
|
|
7, /* 0 1 */
|
|
5, /* 1 -1 */
|
|
1, /* 1 0 */
|
|
3 /* 1 1 */
|
|
];
|
|
|
|
var jsf = getJSF(coeffs[a], coeffs[b]);
|
|
max = Math.max(jsf[0].length, max);
|
|
naf[a] = new Array(max);
|
|
naf[b] = new Array(max);
|
|
for (var j = 0; j < max; j++) {
|
|
var ja = jsf[0][j] | 0;
|
|
var jb = jsf[1][j] | 0;
|
|
|
|
naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
|
|
naf[b][j] = 0;
|
|
wnd[a] = comb;
|
|
}
|
|
}
|
|
|
|
var acc = this.jpoint(null, null, null);
|
|
var tmp = this._wnafT4;
|
|
for (var i = max; i >= 0; i--) {
|
|
var k = 0;
|
|
|
|
while (i >= 0) {
|
|
var zero = true;
|
|
for (var j = 0; j < len; j++) {
|
|
tmp[j] = naf[j][i] | 0;
|
|
if (tmp[j] !== 0)
|
|
zero = false;
|
|
}
|
|
if (!zero)
|
|
break;
|
|
k++;
|
|
i--;
|
|
}
|
|
if (i >= 0)
|
|
k++;
|
|
acc = acc.dblp(k);
|
|
if (i < 0)
|
|
break;
|
|
|
|
for (var j = 0; j < len; j++) {
|
|
var z = tmp[j];
|
|
var p;
|
|
if (z === 0)
|
|
continue;
|
|
else if (z > 0)
|
|
p = wnd[j][(z - 1) >> 1];
|
|
else if (z < 0)
|
|
p = wnd[j][(-z - 1) >> 1].neg();
|
|
|
|
if (p.type === 'affine')
|
|
acc = acc.mixedAdd(p);
|
|
else
|
|
acc = acc.add(p);
|
|
}
|
|
}
|
|
// Zeroify references
|
|
for (var i = 0; i < len; i++)
|
|
wnd[i] = null;
|
|
|
|
if (jacobianResult)
|
|
return acc;
|
|
else
|
|
return acc.toP();
|
|
};
|
|
|
|
function BasePoint(curve, type) {
|
|
this.curve = curve;
|
|
this.type = type;
|
|
this.precomputed = null;
|
|
}
|
|
BaseCurve.BasePoint = BasePoint;
|
|
|
|
BasePoint.prototype.eq = function eq(/*other*/) {
|
|
throw new Error('Not implemented');
|
|
};
|
|
|
|
BasePoint.prototype.validate = function validate() {
|
|
return this.curve.validate(this);
|
|
};
|
|
|
|
BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
|
bytes = utils.toArray(bytes, enc);
|
|
|
|
var len = this.p.byteLength();
|
|
|
|
// uncompressed, hybrid-odd, hybrid-even
|
|
if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
|
|
bytes.length - 1 === 2 * len) {
|
|
if (bytes[0] === 0x06)
|
|
assert(bytes[bytes.length - 1] % 2 === 0);
|
|
else if (bytes[0] === 0x07)
|
|
assert(bytes[bytes.length - 1] % 2 === 1);
|
|
|
|
var res = this.point(bytes.slice(1, 1 + len),
|
|
bytes.slice(1 + len, 1 + 2 * len));
|
|
|
|
return res;
|
|
} else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
|
bytes.length - 1 === len) {
|
|
return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
|
|
}
|
|
throw new Error('Unknown point format');
|
|
};
|
|
|
|
BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
|
|
return this.encode(enc, true);
|
|
};
|
|
|
|
BasePoint.prototype._encode = function _encode(compact) {
|
|
var len = this.curve.p.byteLength();
|
|
var x = this.getX().toArray('be', len);
|
|
|
|
if (compact)
|
|
return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
|
|
|
|
return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
|
|
};
|
|
|
|
BasePoint.prototype.encode = function encode(enc, compact) {
|
|
return utils.encode(this._encode(compact), enc);
|
|
};
|
|
|
|
BasePoint.prototype.precompute = function precompute(power) {
|
|
if (this.precomputed)
|
|
return this;
|
|
|
|
var precomputed = {
|
|
doubles: null,
|
|
naf: null,
|
|
beta: null
|
|
};
|
|
precomputed.naf = this._getNAFPoints(8);
|
|
precomputed.doubles = this._getDoubles(4, power);
|
|
precomputed.beta = this._getBeta();
|
|
this.precomputed = precomputed;
|
|
|
|
return this;
|
|
};
|
|
|
|
BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
|
|
if (!this.precomputed)
|
|
return false;
|
|
|
|
var doubles = this.precomputed.doubles;
|
|
if (!doubles)
|
|
return false;
|
|
|
|
return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
|
|
};
|
|
|
|
BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
|
|
if (this.precomputed && this.precomputed.doubles)
|
|
return this.precomputed.doubles;
|
|
|
|
var doubles = [ this ];
|
|
var acc = this;
|
|
for (var i = 0; i < power; i += step) {
|
|
for (var j = 0; j < step; j++)
|
|
acc = acc.dbl();
|
|
doubles.push(acc);
|
|
}
|
|
return {
|
|
step: step,
|
|
points: doubles
|
|
};
|
|
};
|
|
|
|
BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
|
|
if (this.precomputed && this.precomputed.naf)
|
|
return this.precomputed.naf;
|
|
|
|
var res = [ this ];
|
|
var max = (1 << wnd) - 1;
|
|
var dbl = max === 1 ? null : this.dbl();
|
|
for (var i = 1; i < max; i++)
|
|
res[i] = res[i - 1].add(dbl);
|
|
return {
|
|
wnd: wnd,
|
|
points: res
|
|
};
|
|
};
|
|
|
|
BasePoint.prototype._getBeta = function _getBeta() {
|
|
return null;
|
|
};
|
|
|
|
BasePoint.prototype.dblp = function dblp(k) {
|
|
var r = this;
|
|
for (var i = 0; i < k; i++)
|
|
r = r.dbl();
|
|
return r;
|
|
};
|
|
|
|
},{"../utils":21,"bn.js":22}],9:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var BN = require('bn.js');
|
|
var inherits = require('inherits');
|
|
var Base = require('./base');
|
|
|
|
var assert = utils.assert;
|
|
|
|
function EdwardsCurve(conf) {
|
|
// NOTE: Important as we are creating point in Base.call()
|
|
this.twisted = (conf.a | 0) !== 1;
|
|
this.mOneA = this.twisted && (conf.a | 0) === -1;
|
|
this.extended = this.mOneA;
|
|
|
|
Base.call(this, 'edwards', conf);
|
|
|
|
this.a = new BN(conf.a, 16).umod(this.red.m);
|
|
this.a = this.a.toRed(this.red);
|
|
this.c = new BN(conf.c, 16).toRed(this.red);
|
|
this.c2 = this.c.redSqr();
|
|
this.d = new BN(conf.d, 16).toRed(this.red);
|
|
this.dd = this.d.redAdd(this.d);
|
|
|
|
assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
|
|
this.oneC = (conf.c | 0) === 1;
|
|
}
|
|
inherits(EdwardsCurve, Base);
|
|
module.exports = EdwardsCurve;
|
|
|
|
EdwardsCurve.prototype._mulA = function _mulA(num) {
|
|
if (this.mOneA)
|
|
return num.redNeg();
|
|
else
|
|
return this.a.redMul(num);
|
|
};
|
|
|
|
EdwardsCurve.prototype._mulC = function _mulC(num) {
|
|
if (this.oneC)
|
|
return num;
|
|
else
|
|
return this.c.redMul(num);
|
|
};
|
|
|
|
// Just for compatibility with Short curve
|
|
EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
|
|
return this.point(x, y, z, t);
|
|
};
|
|
|
|
EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
|
x = new BN(x, 16);
|
|
if (!x.red)
|
|
x = x.toRed(this.red);
|
|
|
|
var x2 = x.redSqr();
|
|
var rhs = this.c2.redSub(this.a.redMul(x2));
|
|
var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
|
|
|
|
var y2 = rhs.redMul(lhs.redInvm());
|
|
var y = y2.redSqrt();
|
|
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
|
throw new Error('invalid point');
|
|
|
|
var isOdd = y.fromRed().isOdd();
|
|
if (odd && !isOdd || !odd && isOdd)
|
|
y = y.redNeg();
|
|
|
|
return this.point(x, y);
|
|
};
|
|
|
|
EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
|
|
y = new BN(y, 16);
|
|
if (!y.red)
|
|
y = y.toRed(this.red);
|
|
|
|
// x^2 = (y^2 - c^2) / (c^2 d y^2 - a)
|
|
var y2 = y.redSqr();
|
|
var lhs = y2.redSub(this.c2);
|
|
var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);
|
|
var x2 = lhs.redMul(rhs.redInvm());
|
|
|
|
if (x2.cmp(this.zero) === 0) {
|
|
if (odd)
|
|
throw new Error('invalid point');
|
|
else
|
|
return this.point(this.zero, y);
|
|
}
|
|
|
|
var x = x2.redSqrt();
|
|
if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
|
|
throw new Error('invalid point');
|
|
|
|
if (x.fromRed().isOdd() !== odd)
|
|
x = x.redNeg();
|
|
|
|
return this.point(x, y);
|
|
};
|
|
|
|
EdwardsCurve.prototype.validate = function validate(point) {
|
|
if (point.isInfinity())
|
|
return true;
|
|
|
|
// Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
|
|
point.normalize();
|
|
|
|
var x2 = point.x.redSqr();
|
|
var y2 = point.y.redSqr();
|
|
var lhs = x2.redMul(this.a).redAdd(y2);
|
|
var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
|
|
|
|
return lhs.cmp(rhs) === 0;
|
|
};
|
|
|
|
function Point(curve, x, y, z, t) {
|
|
Base.BasePoint.call(this, curve, 'projective');
|
|
if (x === null && y === null && z === null) {
|
|
this.x = this.curve.zero;
|
|
this.y = this.curve.one;
|
|
this.z = this.curve.one;
|
|
this.t = this.curve.zero;
|
|
this.zOne = true;
|
|
} else {
|
|
this.x = new BN(x, 16);
|
|
this.y = new BN(y, 16);
|
|
this.z = z ? new BN(z, 16) : this.curve.one;
|
|
this.t = t && new BN(t, 16);
|
|
if (!this.x.red)
|
|
this.x = this.x.toRed(this.curve.red);
|
|
if (!this.y.red)
|
|
this.y = this.y.toRed(this.curve.red);
|
|
if (!this.z.red)
|
|
this.z = this.z.toRed(this.curve.red);
|
|
if (this.t && !this.t.red)
|
|
this.t = this.t.toRed(this.curve.red);
|
|
this.zOne = this.z === this.curve.one;
|
|
|
|
// Use extended coordinates
|
|
if (this.curve.extended && !this.t) {
|
|
this.t = this.x.redMul(this.y);
|
|
if (!this.zOne)
|
|
this.t = this.t.redMul(this.z.redInvm());
|
|
}
|
|
}
|
|
}
|
|
inherits(Point, Base.BasePoint);
|
|
|
|
EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
|
|
return Point.fromJSON(this, obj);
|
|
};
|
|
|
|
EdwardsCurve.prototype.point = function point(x, y, z, t) {
|
|
return new Point(this, x, y, z, t);
|
|
};
|
|
|
|
Point.fromJSON = function fromJSON(curve, obj) {
|
|
return new Point(curve, obj[0], obj[1], obj[2]);
|
|
};
|
|
|
|
Point.prototype.inspect = function inspect() {
|
|
if (this.isInfinity())
|
|
return '<EC Point Infinity>';
|
|
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
|
' y: ' + this.y.fromRed().toString(16, 2) +
|
|
' z: ' + this.z.fromRed().toString(16, 2) + '>';
|
|
};
|
|
|
|
Point.prototype.isInfinity = function isInfinity() {
|
|
// XXX This code assumes that zero is always zero in red
|
|
return this.x.cmpn(0) === 0 &&
|
|
(this.y.cmp(this.z) === 0 ||
|
|
(this.zOne && this.y.cmp(this.curve.c) === 0));
|
|
};
|
|
|
|
Point.prototype._extDbl = function _extDbl() {
|
|
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
|
// #doubling-dbl-2008-hwcd
|
|
// 4M + 4S
|
|
|
|
// A = X1^2
|
|
var a = this.x.redSqr();
|
|
// B = Y1^2
|
|
var b = this.y.redSqr();
|
|
// C = 2 * Z1^2
|
|
var c = this.z.redSqr();
|
|
c = c.redIAdd(c);
|
|
// D = a * A
|
|
var d = this.curve._mulA(a);
|
|
// E = (X1 + Y1)^2 - A - B
|
|
var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
|
|
// G = D + B
|
|
var g = d.redAdd(b);
|
|
// F = G - C
|
|
var f = g.redSub(c);
|
|
// H = D - B
|
|
var h = d.redSub(b);
|
|
// X3 = E * F
|
|
var nx = e.redMul(f);
|
|
// Y3 = G * H
|
|
var ny = g.redMul(h);
|
|
// T3 = E * H
|
|
var nt = e.redMul(h);
|
|
// Z3 = F * G
|
|
var nz = f.redMul(g);
|
|
return this.curve.point(nx, ny, nz, nt);
|
|
};
|
|
|
|
Point.prototype._projDbl = function _projDbl() {
|
|
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
|
// #doubling-dbl-2008-bbjlp
|
|
// #doubling-dbl-2007-bl
|
|
// and others
|
|
// Generally 3M + 4S or 2M + 4S
|
|
|
|
// B = (X1 + Y1)^2
|
|
var b = this.x.redAdd(this.y).redSqr();
|
|
// C = X1^2
|
|
var c = this.x.redSqr();
|
|
// D = Y1^2
|
|
var d = this.y.redSqr();
|
|
|
|
var nx;
|
|
var ny;
|
|
var nz;
|
|
if (this.curve.twisted) {
|
|
// E = a * C
|
|
var e = this.curve._mulA(c);
|
|
// F = E + D
|
|
var f = e.redAdd(d);
|
|
if (this.zOne) {
|
|
// X3 = (B - C - D) * (F - 2)
|
|
nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
|
|
// Y3 = F * (E - D)
|
|
ny = f.redMul(e.redSub(d));
|
|
// Z3 = F^2 - 2 * F
|
|
nz = f.redSqr().redSub(f).redSub(f);
|
|
} else {
|
|
// H = Z1^2
|
|
var h = this.z.redSqr();
|
|
// J = F - 2 * H
|
|
var j = f.redSub(h).redISub(h);
|
|
// X3 = (B-C-D)*J
|
|
nx = b.redSub(c).redISub(d).redMul(j);
|
|
// Y3 = F * (E - D)
|
|
ny = f.redMul(e.redSub(d));
|
|
// Z3 = F * J
|
|
nz = f.redMul(j);
|
|
}
|
|
} else {
|
|
// E = C + D
|
|
var e = c.redAdd(d);
|
|
// H = (c * Z1)^2
|
|
var h = this.curve._mulC(this.z).redSqr();
|
|
// J = E - 2 * H
|
|
var j = e.redSub(h).redSub(h);
|
|
// X3 = c * (B - E) * J
|
|
nx = this.curve._mulC(b.redISub(e)).redMul(j);
|
|
// Y3 = c * E * (C - D)
|
|
ny = this.curve._mulC(e).redMul(c.redISub(d));
|
|
// Z3 = E * J
|
|
nz = e.redMul(j);
|
|
}
|
|
return this.curve.point(nx, ny, nz);
|
|
};
|
|
|
|
Point.prototype.dbl = function dbl() {
|
|
if (this.isInfinity())
|
|
return this;
|
|
|
|
// Double in extended coordinates
|
|
if (this.curve.extended)
|
|
return this._extDbl();
|
|
else
|
|
return this._projDbl();
|
|
};
|
|
|
|
Point.prototype._extAdd = function _extAdd(p) {
|
|
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
|
// #addition-add-2008-hwcd-3
|
|
// 8M
|
|
|
|
// A = (Y1 - X1) * (Y2 - X2)
|
|
var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
|
|
// B = (Y1 + X1) * (Y2 + X2)
|
|
var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
|
|
// C = T1 * k * T2
|
|
var c = this.t.redMul(this.curve.dd).redMul(p.t);
|
|
// D = Z1 * 2 * Z2
|
|
var d = this.z.redMul(p.z.redAdd(p.z));
|
|
// E = B - A
|
|
var e = b.redSub(a);
|
|
// F = D - C
|
|
var f = d.redSub(c);
|
|
// G = D + C
|
|
var g = d.redAdd(c);
|
|
// H = B + A
|
|
var h = b.redAdd(a);
|
|
// X3 = E * F
|
|
var nx = e.redMul(f);
|
|
// Y3 = G * H
|
|
var ny = g.redMul(h);
|
|
// T3 = E * H
|
|
var nt = e.redMul(h);
|
|
// Z3 = F * G
|
|
var nz = f.redMul(g);
|
|
return this.curve.point(nx, ny, nz, nt);
|
|
};
|
|
|
|
Point.prototype._projAdd = function _projAdd(p) {
|
|
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
|
// #addition-add-2008-bbjlp
|
|
// #addition-add-2007-bl
|
|
// 10M + 1S
|
|
|
|
// A = Z1 * Z2
|
|
var a = this.z.redMul(p.z);
|
|
// B = A^2
|
|
var b = a.redSqr();
|
|
// C = X1 * X2
|
|
var c = this.x.redMul(p.x);
|
|
// D = Y1 * Y2
|
|
var d = this.y.redMul(p.y);
|
|
// E = d * C * D
|
|
var e = this.curve.d.redMul(c).redMul(d);
|
|
// F = B - E
|
|
var f = b.redSub(e);
|
|
// G = B + E
|
|
var g = b.redAdd(e);
|
|
// X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
|
|
var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
|
|
var nx = a.redMul(f).redMul(tmp);
|
|
var ny;
|
|
var nz;
|
|
if (this.curve.twisted) {
|
|
// Y3 = A * G * (D - a * C)
|
|
ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
|
|
// Z3 = F * G
|
|
nz = f.redMul(g);
|
|
} else {
|
|
// Y3 = A * G * (D - C)
|
|
ny = a.redMul(g).redMul(d.redSub(c));
|
|
// Z3 = c * F * G
|
|
nz = this.curve._mulC(f).redMul(g);
|
|
}
|
|
return this.curve.point(nx, ny, nz);
|
|
};
|
|
|
|
Point.prototype.add = function add(p) {
|
|
if (this.isInfinity())
|
|
return p;
|
|
if (p.isInfinity())
|
|
return this;
|
|
|
|
if (this.curve.extended)
|
|
return this._extAdd(p);
|
|
else
|
|
return this._projAdd(p);
|
|
};
|
|
|
|
Point.prototype.mul = function mul(k) {
|
|
if (this._hasDoubles(k))
|
|
return this.curve._fixedNafMul(this, k);
|
|
else
|
|
return this.curve._wnafMul(this, k);
|
|
};
|
|
|
|
Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
|
|
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
|
|
};
|
|
|
|
Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
|
|
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
|
|
};
|
|
|
|
Point.prototype.normalize = function normalize() {
|
|
if (this.zOne)
|
|
return this;
|
|
|
|
// Normalize coordinates
|
|
var zi = this.z.redInvm();
|
|
this.x = this.x.redMul(zi);
|
|
this.y = this.y.redMul(zi);
|
|
if (this.t)
|
|
this.t = this.t.redMul(zi);
|
|
this.z = this.curve.one;
|
|
this.zOne = true;
|
|
return this;
|
|
};
|
|
|
|
Point.prototype.neg = function neg() {
|
|
return this.curve.point(this.x.redNeg(),
|
|
this.y,
|
|
this.z,
|
|
this.t && this.t.redNeg());
|
|
};
|
|
|
|
Point.prototype.getX = function getX() {
|
|
this.normalize();
|
|
return this.x.fromRed();
|
|
};
|
|
|
|
Point.prototype.getY = function getY() {
|
|
this.normalize();
|
|
return this.y.fromRed();
|
|
};
|
|
|
|
Point.prototype.eq = function eq(other) {
|
|
return this === other ||
|
|
this.getX().cmp(other.getX()) === 0 &&
|
|
this.getY().cmp(other.getY()) === 0;
|
|
};
|
|
|
|
Point.prototype.eqXToP = function eqXToP(x) {
|
|
var rx = x.toRed(this.curve.red).redMul(this.z);
|
|
if (this.x.cmp(rx) === 0)
|
|
return true;
|
|
|
|
var xc = x.clone();
|
|
var t = this.curve.redN.redMul(this.z);
|
|
for (;;) {
|
|
xc.iadd(this.curve.n);
|
|
if (xc.cmp(this.curve.p) >= 0)
|
|
return false;
|
|
|
|
rx.redIAdd(t);
|
|
if (this.x.cmp(rx) === 0)
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// Compatibility with BaseCurve
|
|
Point.prototype.toP = Point.prototype.normalize;
|
|
Point.prototype.mixedAdd = Point.prototype.add;
|
|
|
|
},{"../utils":21,"./base":8,"bn.js":22,"inherits":38}],10:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var curve = exports;
|
|
|
|
curve.base = require('./base');
|
|
curve.short = require('./short');
|
|
curve.mont = require('./mont');
|
|
curve.edwards = require('./edwards');
|
|
|
|
},{"./base":8,"./edwards":9,"./mont":11,"./short":12}],11:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var BN = require('bn.js');
|
|
var inherits = require('inherits');
|
|
var Base = require('./base');
|
|
|
|
var utils = require('../utils');
|
|
|
|
function MontCurve(conf) {
|
|
Base.call(this, 'mont', conf);
|
|
|
|
this.a = new BN(conf.a, 16).toRed(this.red);
|
|
this.b = new BN(conf.b, 16).toRed(this.red);
|
|
this.i4 = new BN(4).toRed(this.red).redInvm();
|
|
this.two = new BN(2).toRed(this.red);
|
|
this.a24 = this.i4.redMul(this.a.redAdd(this.two));
|
|
}
|
|
inherits(MontCurve, Base);
|
|
module.exports = MontCurve;
|
|
|
|
MontCurve.prototype.validate = function validate(point) {
|
|
var x = point.normalize().x;
|
|
var x2 = x.redSqr();
|
|
var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
|
|
var y = rhs.redSqrt();
|
|
|
|
return y.redSqr().cmp(rhs) === 0;
|
|
};
|
|
|
|
function Point(curve, x, z) {
|
|
Base.BasePoint.call(this, curve, 'projective');
|
|
if (x === null && z === null) {
|
|
this.x = this.curve.one;
|
|
this.z = this.curve.zero;
|
|
} else {
|
|
this.x = new BN(x, 16);
|
|
this.z = new BN(z, 16);
|
|
if (!this.x.red)
|
|
this.x = this.x.toRed(this.curve.red);
|
|
if (!this.z.red)
|
|
this.z = this.z.toRed(this.curve.red);
|
|
}
|
|
}
|
|
inherits(Point, Base.BasePoint);
|
|
|
|
MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
|
return this.point(utils.toArray(bytes, enc), 1);
|
|
};
|
|
|
|
MontCurve.prototype.point = function point(x, z) {
|
|
return new Point(this, x, z);
|
|
};
|
|
|
|
MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
|
|
return Point.fromJSON(this, obj);
|
|
};
|
|
|
|
Point.prototype.precompute = function precompute() {
|
|
// No-op
|
|
};
|
|
|
|
Point.prototype._encode = function _encode() {
|
|
return this.getX().toArray('be', this.curve.p.byteLength());
|
|
};
|
|
|
|
Point.fromJSON = function fromJSON(curve, obj) {
|
|
return new Point(curve, obj[0], obj[1] || curve.one);
|
|
};
|
|
|
|
Point.prototype.inspect = function inspect() {
|
|
if (this.isInfinity())
|
|
return '<EC Point Infinity>';
|
|
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
|
' z: ' + this.z.fromRed().toString(16, 2) + '>';
|
|
};
|
|
|
|
Point.prototype.isInfinity = function isInfinity() {
|
|
// XXX This code assumes that zero is always zero in red
|
|
return this.z.cmpn(0) === 0;
|
|
};
|
|
|
|
Point.prototype.dbl = function dbl() {
|
|
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
|
|
// 2M + 2S + 4A
|
|
|
|
// A = X1 + Z1
|
|
var a = this.x.redAdd(this.z);
|
|
// AA = A^2
|
|
var aa = a.redSqr();
|
|
// B = X1 - Z1
|
|
var b = this.x.redSub(this.z);
|
|
// BB = B^2
|
|
var bb = b.redSqr();
|
|
// C = AA - BB
|
|
var c = aa.redSub(bb);
|
|
// X3 = AA * BB
|
|
var nx = aa.redMul(bb);
|
|
// Z3 = C * (BB + A24 * C)
|
|
var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
|
|
return this.curve.point(nx, nz);
|
|
};
|
|
|
|
Point.prototype.add = function add() {
|
|
throw new Error('Not supported on Montgomery curve');
|
|
};
|
|
|
|
Point.prototype.diffAdd = function diffAdd(p, diff) {
|
|
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
|
|
// 4M + 2S + 6A
|
|
|
|
// A = X2 + Z2
|
|
var a = this.x.redAdd(this.z);
|
|
// B = X2 - Z2
|
|
var b = this.x.redSub(this.z);
|
|
// C = X3 + Z3
|
|
var c = p.x.redAdd(p.z);
|
|
// D = X3 - Z3
|
|
var d = p.x.redSub(p.z);
|
|
// DA = D * A
|
|
var da = d.redMul(a);
|
|
// CB = C * B
|
|
var cb = c.redMul(b);
|
|
// X5 = Z1 * (DA + CB)^2
|
|
var nx = diff.z.redMul(da.redAdd(cb).redSqr());
|
|
// Z5 = X1 * (DA - CB)^2
|
|
var nz = diff.x.redMul(da.redISub(cb).redSqr());
|
|
return this.curve.point(nx, nz);
|
|
};
|
|
|
|
Point.prototype.mul = function mul(k) {
|
|
var t = k.clone();
|
|
var a = this; // (N / 2) * Q + Q
|
|
var b = this.curve.point(null, null); // (N / 2) * Q
|
|
var c = this; // Q
|
|
|
|
for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
|
|
bits.push(t.andln(1));
|
|
|
|
for (var i = bits.length - 1; i >= 0; i--) {
|
|
if (bits[i] === 0) {
|
|
// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
|
|
a = a.diffAdd(b, c);
|
|
// N * Q = 2 * ((N / 2) * Q + Q))
|
|
b = b.dbl();
|
|
} else {
|
|
// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
|
|
b = a.diffAdd(b, c);
|
|
// N * Q + Q = 2 * ((N / 2) * Q + Q)
|
|
a = a.dbl();
|
|
}
|
|
}
|
|
return b;
|
|
};
|
|
|
|
Point.prototype.mulAdd = function mulAdd() {
|
|
throw new Error('Not supported on Montgomery curve');
|
|
};
|
|
|
|
Point.prototype.jumlAdd = function jumlAdd() {
|
|
throw new Error('Not supported on Montgomery curve');
|
|
};
|
|
|
|
Point.prototype.eq = function eq(other) {
|
|
return this.getX().cmp(other.getX()) === 0;
|
|
};
|
|
|
|
Point.prototype.normalize = function normalize() {
|
|
this.x = this.x.redMul(this.z.redInvm());
|
|
this.z = this.curve.one;
|
|
return this;
|
|
};
|
|
|
|
Point.prototype.getX = function getX() {
|
|
// Normalize coordinates
|
|
this.normalize();
|
|
|
|
return this.x.fromRed();
|
|
};
|
|
|
|
},{"../utils":21,"./base":8,"bn.js":22,"inherits":38}],12:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var BN = require('bn.js');
|
|
var inherits = require('inherits');
|
|
var Base = require('./base');
|
|
|
|
var assert = utils.assert;
|
|
|
|
function ShortCurve(conf) {
|
|
Base.call(this, 'short', conf);
|
|
|
|
this.a = new BN(conf.a, 16).toRed(this.red);
|
|
this.b = new BN(conf.b, 16).toRed(this.red);
|
|
this.tinv = this.two.redInvm();
|
|
|
|
this.zeroA = this.a.fromRed().cmpn(0) === 0;
|
|
this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
|
|
|
|
// If the curve is endomorphic, precalculate beta and lambda
|
|
this.endo = this._getEndomorphism(conf);
|
|
this._endoWnafT1 = new Array(4);
|
|
this._endoWnafT2 = new Array(4);
|
|
}
|
|
inherits(ShortCurve, Base);
|
|
module.exports = ShortCurve;
|
|
|
|
ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
|
|
// No efficient endomorphism
|
|
if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
|
|
return;
|
|
|
|
// Compute beta and lambda, that lambda * P = (beta * Px; Py)
|
|
var beta;
|
|
var lambda;
|
|
if (conf.beta) {
|
|
beta = new BN(conf.beta, 16).toRed(this.red);
|
|
} else {
|
|
var betas = this._getEndoRoots(this.p);
|
|
// Choose the smallest beta
|
|
beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
|
|
beta = beta.toRed(this.red);
|
|
}
|
|
if (conf.lambda) {
|
|
lambda = new BN(conf.lambda, 16);
|
|
} else {
|
|
// Choose the lambda that is matching selected beta
|
|
var lambdas = this._getEndoRoots(this.n);
|
|
if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
|
|
lambda = lambdas[0];
|
|
} else {
|
|
lambda = lambdas[1];
|
|
assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
|
|
}
|
|
}
|
|
|
|
// Get basis vectors, used for balanced length-two representation
|
|
var basis;
|
|
if (conf.basis) {
|
|
basis = conf.basis.map(function(vec) {
|
|
return {
|
|
a: new BN(vec.a, 16),
|
|
b: new BN(vec.b, 16)
|
|
};
|
|
});
|
|
} else {
|
|
basis = this._getEndoBasis(lambda);
|
|
}
|
|
|
|
return {
|
|
beta: beta,
|
|
lambda: lambda,
|
|
basis: basis
|
|
};
|
|
};
|
|
|
|
ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
|
|
// Find roots of for x^2 + x + 1 in F
|
|
// Root = (-1 +- Sqrt(-3)) / 2
|
|
//
|
|
var red = num === this.p ? this.red : BN.mont(num);
|
|
var tinv = new BN(2).toRed(red).redInvm();
|
|
var ntinv = tinv.redNeg();
|
|
|
|
var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
|
|
|
|
var l1 = ntinv.redAdd(s).fromRed();
|
|
var l2 = ntinv.redSub(s).fromRed();
|
|
return [ l1, l2 ];
|
|
};
|
|
|
|
ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
|
|
// aprxSqrt >= sqrt(this.n)
|
|
var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
|
|
|
|
// 3.74
|
|
// Run EGCD, until r(L + 1) < aprxSqrt
|
|
var u = lambda;
|
|
var v = this.n.clone();
|
|
var x1 = new BN(1);
|
|
var y1 = new BN(0);
|
|
var x2 = new BN(0);
|
|
var y2 = new BN(1);
|
|
|
|
// NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
|
|
var a0;
|
|
var b0;
|
|
// First vector
|
|
var a1;
|
|
var b1;
|
|
// Second vector
|
|
var a2;
|
|
var b2;
|
|
|
|
var prevR;
|
|
var i = 0;
|
|
var r;
|
|
var x;
|
|
while (u.cmpn(0) !== 0) {
|
|
var q = v.div(u);
|
|
r = v.sub(q.mul(u));
|
|
x = x2.sub(q.mul(x1));
|
|
var y = y2.sub(q.mul(y1));
|
|
|
|
if (!a1 && r.cmp(aprxSqrt) < 0) {
|
|
a0 = prevR.neg();
|
|
b0 = x1;
|
|
a1 = r.neg();
|
|
b1 = x;
|
|
} else if (a1 && ++i === 2) {
|
|
break;
|
|
}
|
|
prevR = r;
|
|
|
|
v = u;
|
|
u = r;
|
|
x2 = x1;
|
|
x1 = x;
|
|
y2 = y1;
|
|
y1 = y;
|
|
}
|
|
a2 = r.neg();
|
|
b2 = x;
|
|
|
|
var len1 = a1.sqr().add(b1.sqr());
|
|
var len2 = a2.sqr().add(b2.sqr());
|
|
if (len2.cmp(len1) >= 0) {
|
|
a2 = a0;
|
|
b2 = b0;
|
|
}
|
|
|
|
// Normalize signs
|
|
if (a1.negative) {
|
|
a1 = a1.neg();
|
|
b1 = b1.neg();
|
|
}
|
|
if (a2.negative) {
|
|
a2 = a2.neg();
|
|
b2 = b2.neg();
|
|
}
|
|
|
|
return [
|
|
{ a: a1, b: b1 },
|
|
{ a: a2, b: b2 }
|
|
];
|
|
};
|
|
|
|
ShortCurve.prototype._endoSplit = function _endoSplit(k) {
|
|
var basis = this.endo.basis;
|
|
var v1 = basis[0];
|
|
var v2 = basis[1];
|
|
|
|
var c1 = v2.b.mul(k).divRound(this.n);
|
|
var c2 = v1.b.neg().mul(k).divRound(this.n);
|
|
|
|
var p1 = c1.mul(v1.a);
|
|
var p2 = c2.mul(v2.a);
|
|
var q1 = c1.mul(v1.b);
|
|
var q2 = c2.mul(v2.b);
|
|
|
|
// Calculate answer
|
|
var k1 = k.sub(p1).sub(p2);
|
|
var k2 = q1.add(q2).neg();
|
|
return { k1: k1, k2: k2 };
|
|
};
|
|
|
|
ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
|
x = new BN(x, 16);
|
|
if (!x.red)
|
|
x = x.toRed(this.red);
|
|
|
|
var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
|
|
var y = y2.redSqrt();
|
|
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
|
throw new Error('invalid point');
|
|
|
|
// XXX Is there any way to tell if the number is odd without converting it
|
|
// to non-red form?
|
|
var isOdd = y.fromRed().isOdd();
|
|
if (odd && !isOdd || !odd && isOdd)
|
|
y = y.redNeg();
|
|
|
|
return this.point(x, y);
|
|
};
|
|
|
|
ShortCurve.prototype.validate = function validate(point) {
|
|
if (point.inf)
|
|
return true;
|
|
|
|
var x = point.x;
|
|
var y = point.y;
|
|
|
|
var ax = this.a.redMul(x);
|
|
var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
|
|
return y.redSqr().redISub(rhs).cmpn(0) === 0;
|
|
};
|
|
|
|
ShortCurve.prototype._endoWnafMulAdd =
|
|
function _endoWnafMulAdd(points, coeffs, jacobianResult) {
|
|
var npoints = this._endoWnafT1;
|
|
var ncoeffs = this._endoWnafT2;
|
|
for (var i = 0; i < points.length; i++) {
|
|
var split = this._endoSplit(coeffs[i]);
|
|
var p = points[i];
|
|
var beta = p._getBeta();
|
|
|
|
if (split.k1.negative) {
|
|
split.k1.ineg();
|
|
p = p.neg(true);
|
|
}
|
|
if (split.k2.negative) {
|
|
split.k2.ineg();
|
|
beta = beta.neg(true);
|
|
}
|
|
|
|
npoints[i * 2] = p;
|
|
npoints[i * 2 + 1] = beta;
|
|
ncoeffs[i * 2] = split.k1;
|
|
ncoeffs[i * 2 + 1] = split.k2;
|
|
}
|
|
var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
|
|
|
|
// Clean-up references to points and coefficients
|
|
for (var j = 0; j < i * 2; j++) {
|
|
npoints[j] = null;
|
|
ncoeffs[j] = null;
|
|
}
|
|
return res;
|
|
};
|
|
|
|
function Point(curve, x, y, isRed) {
|
|
Base.BasePoint.call(this, curve, 'affine');
|
|
if (x === null && y === null) {
|
|
this.x = null;
|
|
this.y = null;
|
|
this.inf = true;
|
|
} else {
|
|
this.x = new BN(x, 16);
|
|
this.y = new BN(y, 16);
|
|
// Force redgomery representation when loading from JSON
|
|
if (isRed) {
|
|
this.x.forceRed(this.curve.red);
|
|
this.y.forceRed(this.curve.red);
|
|
}
|
|
if (!this.x.red)
|
|
this.x = this.x.toRed(this.curve.red);
|
|
if (!this.y.red)
|
|
this.y = this.y.toRed(this.curve.red);
|
|
this.inf = false;
|
|
}
|
|
}
|
|
inherits(Point, Base.BasePoint);
|
|
|
|
ShortCurve.prototype.point = function point(x, y, isRed) {
|
|
return new Point(this, x, y, isRed);
|
|
};
|
|
|
|
ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
|
|
return Point.fromJSON(this, obj, red);
|
|
};
|
|
|
|
Point.prototype._getBeta = function _getBeta() {
|
|
if (!this.curve.endo)
|
|
return;
|
|
|
|
var pre = this.precomputed;
|
|
if (pre && pre.beta)
|
|
return pre.beta;
|
|
|
|
var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
|
|
if (pre) {
|
|
var curve = this.curve;
|
|
var endoMul = function(p) {
|
|
return curve.point(p.x.redMul(curve.endo.beta), p.y);
|
|
};
|
|
pre.beta = beta;
|
|
beta.precomputed = {
|
|
beta: null,
|
|
naf: pre.naf && {
|
|
wnd: pre.naf.wnd,
|
|
points: pre.naf.points.map(endoMul)
|
|
},
|
|
doubles: pre.doubles && {
|
|
step: pre.doubles.step,
|
|
points: pre.doubles.points.map(endoMul)
|
|
}
|
|
};
|
|
}
|
|
return beta;
|
|
};
|
|
|
|
Point.prototype.toJSON = function toJSON() {
|
|
if (!this.precomputed)
|
|
return [ this.x, this.y ];
|
|
|
|
return [ this.x, this.y, this.precomputed && {
|
|
doubles: this.precomputed.doubles && {
|
|
step: this.precomputed.doubles.step,
|
|
points: this.precomputed.doubles.points.slice(1)
|
|
},
|
|
naf: this.precomputed.naf && {
|
|
wnd: this.precomputed.naf.wnd,
|
|
points: this.precomputed.naf.points.slice(1)
|
|
}
|
|
} ];
|
|
};
|
|
|
|
Point.fromJSON = function fromJSON(curve, obj, red) {
|
|
if (typeof obj === 'string')
|
|
obj = JSON.parse(obj);
|
|
var res = curve.point(obj[0], obj[1], red);
|
|
if (!obj[2])
|
|
return res;
|
|
|
|
function obj2point(obj) {
|
|
return curve.point(obj[0], obj[1], red);
|
|
}
|
|
|
|
var pre = obj[2];
|
|
res.precomputed = {
|
|
beta: null,
|
|
doubles: pre.doubles && {
|
|
step: pre.doubles.step,
|
|
points: [ res ].concat(pre.doubles.points.map(obj2point))
|
|
},
|
|
naf: pre.naf && {
|
|
wnd: pre.naf.wnd,
|
|
points: [ res ].concat(pre.naf.points.map(obj2point))
|
|
}
|
|
};
|
|
return res;
|
|
};
|
|
|
|
Point.prototype.inspect = function inspect() {
|
|
if (this.isInfinity())
|
|
return '<EC Point Infinity>';
|
|
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
|
' y: ' + this.y.fromRed().toString(16, 2) + '>';
|
|
};
|
|
|
|
Point.prototype.isInfinity = function isInfinity() {
|
|
return this.inf;
|
|
};
|
|
|
|
Point.prototype.add = function add(p) {
|
|
// O + P = P
|
|
if (this.inf)
|
|
return p;
|
|
|
|
// P + O = P
|
|
if (p.inf)
|
|
return this;
|
|
|
|
// P + P = 2P
|
|
if (this.eq(p))
|
|
return this.dbl();
|
|
|
|
// P + (-P) = O
|
|
if (this.neg().eq(p))
|
|
return this.curve.point(null, null);
|
|
|
|
// P + Q = O
|
|
if (this.x.cmp(p.x) === 0)
|
|
return this.curve.point(null, null);
|
|
|
|
var c = this.y.redSub(p.y);
|
|
if (c.cmpn(0) !== 0)
|
|
c = c.redMul(this.x.redSub(p.x).redInvm());
|
|
var nx = c.redSqr().redISub(this.x).redISub(p.x);
|
|
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
|
return this.curve.point(nx, ny);
|
|
};
|
|
|
|
Point.prototype.dbl = function dbl() {
|
|
if (this.inf)
|
|
return this;
|
|
|
|
// 2P = O
|
|
var ys1 = this.y.redAdd(this.y);
|
|
if (ys1.cmpn(0) === 0)
|
|
return this.curve.point(null, null);
|
|
|
|
var a = this.curve.a;
|
|
|
|
var x2 = this.x.redSqr();
|
|
var dyinv = ys1.redInvm();
|
|
var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
|
|
|
|
var nx = c.redSqr().redISub(this.x.redAdd(this.x));
|
|
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
|
return this.curve.point(nx, ny);
|
|
};
|
|
|
|
Point.prototype.getX = function getX() {
|
|
return this.x.fromRed();
|
|
};
|
|
|
|
Point.prototype.getY = function getY() {
|
|
return this.y.fromRed();
|
|
};
|
|
|
|
Point.prototype.mul = function mul(k) {
|
|
k = new BN(k, 16);
|
|
if (this.isInfinity())
|
|
return this;
|
|
else if (this._hasDoubles(k))
|
|
return this.curve._fixedNafMul(this, k);
|
|
else if (this.curve.endo)
|
|
return this.curve._endoWnafMulAdd([ this ], [ k ]);
|
|
else
|
|
return this.curve._wnafMul(this, k);
|
|
};
|
|
|
|
Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
|
|
var points = [ this, p2 ];
|
|
var coeffs = [ k1, k2 ];
|
|
if (this.curve.endo)
|
|
return this.curve._endoWnafMulAdd(points, coeffs);
|
|
else
|
|
return this.curve._wnafMulAdd(1, points, coeffs, 2);
|
|
};
|
|
|
|
Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
|
|
var points = [ this, p2 ];
|
|
var coeffs = [ k1, k2 ];
|
|
if (this.curve.endo)
|
|
return this.curve._endoWnafMulAdd(points, coeffs, true);
|
|
else
|
|
return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
|
|
};
|
|
|
|
Point.prototype.eq = function eq(p) {
|
|
return this === p ||
|
|
this.inf === p.inf &&
|
|
(this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
|
|
};
|
|
|
|
Point.prototype.neg = function neg(_precompute) {
|
|
if (this.inf)
|
|
return this;
|
|
|
|
var res = this.curve.point(this.x, this.y.redNeg());
|
|
if (_precompute && this.precomputed) {
|
|
var pre = this.precomputed;
|
|
var negate = function(p) {
|
|
return p.neg();
|
|
};
|
|
res.precomputed = {
|
|
naf: pre.naf && {
|
|
wnd: pre.naf.wnd,
|
|
points: pre.naf.points.map(negate)
|
|
},
|
|
doubles: pre.doubles && {
|
|
step: pre.doubles.step,
|
|
points: pre.doubles.points.map(negate)
|
|
}
|
|
};
|
|
}
|
|
return res;
|
|
};
|
|
|
|
Point.prototype.toJ = function toJ() {
|
|
if (this.inf)
|
|
return this.curve.jpoint(null, null, null);
|
|
|
|
var res = this.curve.jpoint(this.x, this.y, this.curve.one);
|
|
return res;
|
|
};
|
|
|
|
function JPoint(curve, x, y, z) {
|
|
Base.BasePoint.call(this, curve, 'jacobian');
|
|
if (x === null && y === null && z === null) {
|
|
this.x = this.curve.one;
|
|
this.y = this.curve.one;
|
|
this.z = new BN(0);
|
|
} else {
|
|
this.x = new BN(x, 16);
|
|
this.y = new BN(y, 16);
|
|
this.z = new BN(z, 16);
|
|
}
|
|
if (!this.x.red)
|
|
this.x = this.x.toRed(this.curve.red);
|
|
if (!this.y.red)
|
|
this.y = this.y.toRed(this.curve.red);
|
|
if (!this.z.red)
|
|
this.z = this.z.toRed(this.curve.red);
|
|
|
|
this.zOne = this.z === this.curve.one;
|
|
}
|
|
inherits(JPoint, Base.BasePoint);
|
|
|
|
ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
|
|
return new JPoint(this, x, y, z);
|
|
};
|
|
|
|
JPoint.prototype.toP = function toP() {
|
|
if (this.isInfinity())
|
|
return this.curve.point(null, null);
|
|
|
|
var zinv = this.z.redInvm();
|
|
var zinv2 = zinv.redSqr();
|
|
var ax = this.x.redMul(zinv2);
|
|
var ay = this.y.redMul(zinv2).redMul(zinv);
|
|
|
|
return this.curve.point(ax, ay);
|
|
};
|
|
|
|
JPoint.prototype.neg = function neg() {
|
|
return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
|
|
};
|
|
|
|
JPoint.prototype.add = function add(p) {
|
|
// O + P = P
|
|
if (this.isInfinity())
|
|
return p;
|
|
|
|
// P + O = P
|
|
if (p.isInfinity())
|
|
return this;
|
|
|
|
// 12M + 4S + 7A
|
|
var pz2 = p.z.redSqr();
|
|
var z2 = this.z.redSqr();
|
|
var u1 = this.x.redMul(pz2);
|
|
var u2 = p.x.redMul(z2);
|
|
var s1 = this.y.redMul(pz2.redMul(p.z));
|
|
var s2 = p.y.redMul(z2.redMul(this.z));
|
|
|
|
var h = u1.redSub(u2);
|
|
var r = s1.redSub(s2);
|
|
if (h.cmpn(0) === 0) {
|
|
if (r.cmpn(0) !== 0)
|
|
return this.curve.jpoint(null, null, null);
|
|
else
|
|
return this.dbl();
|
|
}
|
|
|
|
var h2 = h.redSqr();
|
|
var h3 = h2.redMul(h);
|
|
var v = u1.redMul(h2);
|
|
|
|
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
|
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
|
var nz = this.z.redMul(p.z).redMul(h);
|
|
|
|
return this.curve.jpoint(nx, ny, nz);
|
|
};
|
|
|
|
JPoint.prototype.mixedAdd = function mixedAdd(p) {
|
|
// O + P = P
|
|
if (this.isInfinity())
|
|
return p.toJ();
|
|
|
|
// P + O = P
|
|
if (p.isInfinity())
|
|
return this;
|
|
|
|
// 8M + 3S + 7A
|
|
var z2 = this.z.redSqr();
|
|
var u1 = this.x;
|
|
var u2 = p.x.redMul(z2);
|
|
var s1 = this.y;
|
|
var s2 = p.y.redMul(z2).redMul(this.z);
|
|
|
|
var h = u1.redSub(u2);
|
|
var r = s1.redSub(s2);
|
|
if (h.cmpn(0) === 0) {
|
|
if (r.cmpn(0) !== 0)
|
|
return this.curve.jpoint(null, null, null);
|
|
else
|
|
return this.dbl();
|
|
}
|
|
|
|
var h2 = h.redSqr();
|
|
var h3 = h2.redMul(h);
|
|
var v = u1.redMul(h2);
|
|
|
|
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
|
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
|
var nz = this.z.redMul(h);
|
|
|
|
return this.curve.jpoint(nx, ny, nz);
|
|
};
|
|
|
|
JPoint.prototype.dblp = function dblp(pow) {
|
|
if (pow === 0)
|
|
return this;
|
|
if (this.isInfinity())
|
|
return this;
|
|
if (!pow)
|
|
return this.dbl();
|
|
|
|
if (this.curve.zeroA || this.curve.threeA) {
|
|
var r = this;
|
|
for (var i = 0; i < pow; i++)
|
|
r = r.dbl();
|
|
return r;
|
|
}
|
|
|
|
// 1M + 2S + 1A + N * (4S + 5M + 8A)
|
|
// N = 1 => 6M + 6S + 9A
|
|
var a = this.curve.a;
|
|
var tinv = this.curve.tinv;
|
|
|
|
var jx = this.x;
|
|
var jy = this.y;
|
|
var jz = this.z;
|
|
var jz4 = jz.redSqr().redSqr();
|
|
|
|
// Reuse results
|
|
var jyd = jy.redAdd(jy);
|
|
for (var i = 0; i < pow; i++) {
|
|
var jx2 = jx.redSqr();
|
|
var jyd2 = jyd.redSqr();
|
|
var jyd4 = jyd2.redSqr();
|
|
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
|
|
|
var t1 = jx.redMul(jyd2);
|
|
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
|
var t2 = t1.redISub(nx);
|
|
var dny = c.redMul(t2);
|
|
dny = dny.redIAdd(dny).redISub(jyd4);
|
|
var nz = jyd.redMul(jz);
|
|
if (i + 1 < pow)
|
|
jz4 = jz4.redMul(jyd4);
|
|
|
|
jx = nx;
|
|
jz = nz;
|
|
jyd = dny;
|
|
}
|
|
|
|
return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
|
|
};
|
|
|
|
JPoint.prototype.dbl = function dbl() {
|
|
if (this.isInfinity())
|
|
return this;
|
|
|
|
if (this.curve.zeroA)
|
|
return this._zeroDbl();
|
|
else if (this.curve.threeA)
|
|
return this._threeDbl();
|
|
else
|
|
return this._dbl();
|
|
};
|
|
|
|
JPoint.prototype._zeroDbl = function _zeroDbl() {
|
|
var nx;
|
|
var ny;
|
|
var nz;
|
|
// Z = 1
|
|
if (this.zOne) {
|
|
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
|
// #doubling-mdbl-2007-bl
|
|
// 1M + 5S + 14A
|
|
|
|
// XX = X1^2
|
|
var xx = this.x.redSqr();
|
|
// YY = Y1^2
|
|
var yy = this.y.redSqr();
|
|
// YYYY = YY^2
|
|
var yyyy = yy.redSqr();
|
|
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
|
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
|
s = s.redIAdd(s);
|
|
// M = 3 * XX + a; a = 0
|
|
var m = xx.redAdd(xx).redIAdd(xx);
|
|
// T = M ^ 2 - 2*S
|
|
var t = m.redSqr().redISub(s).redISub(s);
|
|
|
|
// 8 * YYYY
|
|
var yyyy8 = yyyy.redIAdd(yyyy);
|
|
yyyy8 = yyyy8.redIAdd(yyyy8);
|
|
yyyy8 = yyyy8.redIAdd(yyyy8);
|
|
|
|
// X3 = T
|
|
nx = t;
|
|
// Y3 = M * (S - T) - 8 * YYYY
|
|
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
|
// Z3 = 2*Y1
|
|
nz = this.y.redAdd(this.y);
|
|
} else {
|
|
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
|
// #doubling-dbl-2009-l
|
|
// 2M + 5S + 13A
|
|
|
|
// A = X1^2
|
|
var a = this.x.redSqr();
|
|
// B = Y1^2
|
|
var b = this.y.redSqr();
|
|
// C = B^2
|
|
var c = b.redSqr();
|
|
// D = 2 * ((X1 + B)^2 - A - C)
|
|
var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
|
|
d = d.redIAdd(d);
|
|
// E = 3 * A
|
|
var e = a.redAdd(a).redIAdd(a);
|
|
// F = E^2
|
|
var f = e.redSqr();
|
|
|
|
// 8 * C
|
|
var c8 = c.redIAdd(c);
|
|
c8 = c8.redIAdd(c8);
|
|
c8 = c8.redIAdd(c8);
|
|
|
|
// X3 = F - 2 * D
|
|
nx = f.redISub(d).redISub(d);
|
|
// Y3 = E * (D - X3) - 8 * C
|
|
ny = e.redMul(d.redISub(nx)).redISub(c8);
|
|
// Z3 = 2 * Y1 * Z1
|
|
nz = this.y.redMul(this.z);
|
|
nz = nz.redIAdd(nz);
|
|
}
|
|
|
|
return this.curve.jpoint(nx, ny, nz);
|
|
};
|
|
|
|
JPoint.prototype._threeDbl = function _threeDbl() {
|
|
var nx;
|
|
var ny;
|
|
var nz;
|
|
// Z = 1
|
|
if (this.zOne) {
|
|
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
|
|
// #doubling-mdbl-2007-bl
|
|
// 1M + 5S + 15A
|
|
|
|
// XX = X1^2
|
|
var xx = this.x.redSqr();
|
|
// YY = Y1^2
|
|
var yy = this.y.redSqr();
|
|
// YYYY = YY^2
|
|
var yyyy = yy.redSqr();
|
|
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
|
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
|
s = s.redIAdd(s);
|
|
// M = 3 * XX + a
|
|
var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
|
|
// T = M^2 - 2 * S
|
|
var t = m.redSqr().redISub(s).redISub(s);
|
|
// X3 = T
|
|
nx = t;
|
|
// Y3 = M * (S - T) - 8 * YYYY
|
|
var yyyy8 = yyyy.redIAdd(yyyy);
|
|
yyyy8 = yyyy8.redIAdd(yyyy8);
|
|
yyyy8 = yyyy8.redIAdd(yyyy8);
|
|
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
|
// Z3 = 2 * Y1
|
|
nz = this.y.redAdd(this.y);
|
|
} else {
|
|
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
|
|
// 3M + 5S
|
|
|
|
// delta = Z1^2
|
|
var delta = this.z.redSqr();
|
|
// gamma = Y1^2
|
|
var gamma = this.y.redSqr();
|
|
// beta = X1 * gamma
|
|
var beta = this.x.redMul(gamma);
|
|
// alpha = 3 * (X1 - delta) * (X1 + delta)
|
|
var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
|
|
alpha = alpha.redAdd(alpha).redIAdd(alpha);
|
|
// X3 = alpha^2 - 8 * beta
|
|
var beta4 = beta.redIAdd(beta);
|
|
beta4 = beta4.redIAdd(beta4);
|
|
var beta8 = beta4.redAdd(beta4);
|
|
nx = alpha.redSqr().redISub(beta8);
|
|
// Z3 = (Y1 + Z1)^2 - gamma - delta
|
|
nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
|
|
// Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
|
|
var ggamma8 = gamma.redSqr();
|
|
ggamma8 = ggamma8.redIAdd(ggamma8);
|
|
ggamma8 = ggamma8.redIAdd(ggamma8);
|
|
ggamma8 = ggamma8.redIAdd(ggamma8);
|
|
ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
|
|
}
|
|
|
|
return this.curve.jpoint(nx, ny, nz);
|
|
};
|
|
|
|
JPoint.prototype._dbl = function _dbl() {
|
|
var a = this.curve.a;
|
|
|
|
// 4M + 6S + 10A
|
|
var jx = this.x;
|
|
var jy = this.y;
|
|
var jz = this.z;
|
|
var jz4 = jz.redSqr().redSqr();
|
|
|
|
var jx2 = jx.redSqr();
|
|
var jy2 = jy.redSqr();
|
|
|
|
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
|
|
|
var jxd4 = jx.redAdd(jx);
|
|
jxd4 = jxd4.redIAdd(jxd4);
|
|
var t1 = jxd4.redMul(jy2);
|
|
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
|
var t2 = t1.redISub(nx);
|
|
|
|
var jyd8 = jy2.redSqr();
|
|
jyd8 = jyd8.redIAdd(jyd8);
|
|
jyd8 = jyd8.redIAdd(jyd8);
|
|
jyd8 = jyd8.redIAdd(jyd8);
|
|
var ny = c.redMul(t2).redISub(jyd8);
|
|
var nz = jy.redAdd(jy).redMul(jz);
|
|
|
|
return this.curve.jpoint(nx, ny, nz);
|
|
};
|
|
|
|
JPoint.prototype.trpl = function trpl() {
|
|
if (!this.curve.zeroA)
|
|
return this.dbl().add(this);
|
|
|
|
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
|
|
// 5M + 10S + ...
|
|
|
|
// XX = X1^2
|
|
var xx = this.x.redSqr();
|
|
// YY = Y1^2
|
|
var yy = this.y.redSqr();
|
|
// ZZ = Z1^2
|
|
var zz = this.z.redSqr();
|
|
// YYYY = YY^2
|
|
var yyyy = yy.redSqr();
|
|
// M = 3 * XX + a * ZZ2; a = 0
|
|
var m = xx.redAdd(xx).redIAdd(xx);
|
|
// MM = M^2
|
|
var mm = m.redSqr();
|
|
// E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
|
|
var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
|
e = e.redIAdd(e);
|
|
e = e.redAdd(e).redIAdd(e);
|
|
e = e.redISub(mm);
|
|
// EE = E^2
|
|
var ee = e.redSqr();
|
|
// T = 16*YYYY
|
|
var t = yyyy.redIAdd(yyyy);
|
|
t = t.redIAdd(t);
|
|
t = t.redIAdd(t);
|
|
t = t.redIAdd(t);
|
|
// U = (M + E)^2 - MM - EE - T
|
|
var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
|
|
// X3 = 4 * (X1 * EE - 4 * YY * U)
|
|
var yyu4 = yy.redMul(u);
|
|
yyu4 = yyu4.redIAdd(yyu4);
|
|
yyu4 = yyu4.redIAdd(yyu4);
|
|
var nx = this.x.redMul(ee).redISub(yyu4);
|
|
nx = nx.redIAdd(nx);
|
|
nx = nx.redIAdd(nx);
|
|
// Y3 = 8 * Y1 * (U * (T - U) - E * EE)
|
|
var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
|
|
ny = ny.redIAdd(ny);
|
|
ny = ny.redIAdd(ny);
|
|
ny = ny.redIAdd(ny);
|
|
// Z3 = (Z1 + E)^2 - ZZ - EE
|
|
var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
|
|
|
|
return this.curve.jpoint(nx, ny, nz);
|
|
};
|
|
|
|
JPoint.prototype.mul = function mul(k, kbase) {
|
|
k = new BN(k, kbase);
|
|
|
|
return this.curve._wnafMul(this, k);
|
|
};
|
|
|
|
JPoint.prototype.eq = function eq(p) {
|
|
if (p.type === 'affine')
|
|
return this.eq(p.toJ());
|
|
|
|
if (this === p)
|
|
return true;
|
|
|
|
// x1 * z2^2 == x2 * z1^2
|
|
var z2 = this.z.redSqr();
|
|
var pz2 = p.z.redSqr();
|
|
if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
|
|
return false;
|
|
|
|
// y1 * z2^3 == y2 * z1^3
|
|
var z3 = z2.redMul(this.z);
|
|
var pz3 = pz2.redMul(p.z);
|
|
return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
|
|
};
|
|
|
|
JPoint.prototype.eqXToP = function eqXToP(x) {
|
|
var zs = this.z.redSqr();
|
|
var rx = x.toRed(this.curve.red).redMul(zs);
|
|
if (this.x.cmp(rx) === 0)
|
|
return true;
|
|
|
|
var xc = x.clone();
|
|
var t = this.curve.redN.redMul(zs);
|
|
for (;;) {
|
|
xc.iadd(this.curve.n);
|
|
if (xc.cmp(this.curve.p) >= 0)
|
|
return false;
|
|
|
|
rx.redIAdd(t);
|
|
if (this.x.cmp(rx) === 0)
|
|
return true;
|
|
}
|
|
};
|
|
|
|
JPoint.prototype.inspect = function inspect() {
|
|
if (this.isInfinity())
|
|
return '<EC JPoint Infinity>';
|
|
return '<EC JPoint x: ' + this.x.toString(16, 2) +
|
|
' y: ' + this.y.toString(16, 2) +
|
|
' z: ' + this.z.toString(16, 2) + '>';
|
|
};
|
|
|
|
JPoint.prototype.isInfinity = function isInfinity() {
|
|
// XXX This code assumes that zero is always zero in red
|
|
return this.z.cmpn(0) === 0;
|
|
};
|
|
|
|
},{"../utils":21,"./base":8,"bn.js":22,"inherits":38}],13:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var curves = exports;
|
|
|
|
var hash = require('hash.js');
|
|
var curve = require('./curve');
|
|
var utils = require('./utils');
|
|
|
|
var assert = utils.assert;
|
|
|
|
function PresetCurve(options) {
|
|
if (options.type === 'short')
|
|
this.curve = new curve.short(options);
|
|
else if (options.type === 'edwards')
|
|
this.curve = new curve.edwards(options);
|
|
else
|
|
this.curve = new curve.mont(options);
|
|
this.g = this.curve.g;
|
|
this.n = this.curve.n;
|
|
this.hash = options.hash;
|
|
|
|
assert(this.g.validate(), 'Invalid curve');
|
|
assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
|
|
}
|
|
curves.PresetCurve = PresetCurve;
|
|
|
|
function defineCurve(name, options) {
|
|
Object.defineProperty(curves, name, {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: function() {
|
|
var curve = new PresetCurve(options);
|
|
Object.defineProperty(curves, name, {
|
|
configurable: true,
|
|
enumerable: true,
|
|
value: curve
|
|
});
|
|
return curve;
|
|
}
|
|
});
|
|
}
|
|
|
|
defineCurve('p192', {
|
|
type: 'short',
|
|
prime: 'p192',
|
|
p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
|
|
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
|
|
b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
|
|
n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
|
|
hash: hash.sha256,
|
|
gRed: false,
|
|
g: [
|
|
'188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
|
|
'07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
|
|
]
|
|
});
|
|
|
|
defineCurve('p224', {
|
|
type: 'short',
|
|
prime: 'p224',
|
|
p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
|
|
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
|
|
b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
|
|
n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
|
|
hash: hash.sha256,
|
|
gRed: false,
|
|
g: [
|
|
'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
|
|
'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
|
|
]
|
|
});
|
|
|
|
defineCurve('p256', {
|
|
type: 'short',
|
|
prime: null,
|
|
p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
|
|
a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
|
|
b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
|
|
n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
|
|
hash: hash.sha256,
|
|
gRed: false,
|
|
g: [
|
|
'6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
|
|
'4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
|
|
]
|
|
});
|
|
|
|
defineCurve('p384', {
|
|
type: 'short',
|
|
prime: null,
|
|
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'fffffffe ffffffff 00000000 00000000 ffffffff',
|
|
a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'fffffffe ffffffff 00000000 00000000 fffffffc',
|
|
b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
|
|
'5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
|
|
n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
|
|
'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
|
|
hash: hash.sha384,
|
|
gRed: false,
|
|
g: [
|
|
'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
|
|
'5502f25d bf55296c 3a545e38 72760ab7',
|
|
'3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
|
|
'0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
|
|
]
|
|
});
|
|
|
|
defineCurve('p521', {
|
|
type: 'short',
|
|
prime: null,
|
|
p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'ffffffff ffffffff ffffffff ffffffff ffffffff',
|
|
a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'ffffffff ffffffff ffffffff ffffffff fffffffc',
|
|
b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
|
|
'99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
|
|
'3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
|
|
n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
|
'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
|
|
'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
|
|
hash: hash.sha512,
|
|
gRed: false,
|
|
g: [
|
|
'000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
|
|
'053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
|
|
'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
|
|
'00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
|
|
'579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
|
|
'3fad0761 353c7086 a272c240 88be9476 9fd16650'
|
|
]
|
|
});
|
|
|
|
defineCurve('curve25519', {
|
|
type: 'mont',
|
|
prime: 'p25519',
|
|
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
|
|
a: '76d06',
|
|
b: '1',
|
|
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
|
|
hash: hash.sha256,
|
|
gRed: false,
|
|
g: [
|
|
'9'
|
|
]
|
|
});
|
|
|
|
defineCurve('ed25519', {
|
|
type: 'edwards',
|
|
prime: 'p25519',
|
|
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
|
|
a: '-1',
|
|
c: '1',
|
|
// -121665 * (121666^(-1)) (mod P)
|
|
d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
|
|
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
|
|
hash: hash.sha256,
|
|
gRed: false,
|
|
g: [
|
|
'216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
|
|
|
|
// 4/5
|
|
'6666666666666666666666666666666666666666666666666666666666666658'
|
|
]
|
|
});
|
|
|
|
var pre;
|
|
try {
|
|
pre = require('./precomputed/secp256k1');
|
|
} catch (e) {
|
|
pre = undefined;
|
|
}
|
|
|
|
defineCurve('secp256k1', {
|
|
type: 'short',
|
|
prime: 'k256',
|
|
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
|
|
a: '0',
|
|
b: '7',
|
|
n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
|
|
h: '1',
|
|
hash: hash.sha256,
|
|
|
|
// Precomputed endomorphism
|
|
beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
|
|
lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
|
|
basis: [
|
|
{
|
|
a: '3086d221a7d46bcde86c90e49284eb15',
|
|
b: '-e4437ed6010e88286f547fa90abfe4c3'
|
|
},
|
|
{
|
|
a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
|
|
b: '3086d221a7d46bcde86c90e49284eb15'
|
|
}
|
|
],
|
|
|
|
gRed: false,
|
|
g: [
|
|
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
|
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
|
|
pre
|
|
]
|
|
});
|
|
|
|
},{"./curve":10,"./precomputed/secp256k1":20,"./utils":21,"hash.js":25}],14:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var BN = require('bn.js');
|
|
var HmacDRBG = require('hmac-drbg');
|
|
var utils = require('../utils');
|
|
var curves = require('../curves');
|
|
var rand = require('brorand');
|
|
var assert = utils.assert;
|
|
|
|
var KeyPair = require('./key');
|
|
var Signature = require('./signature');
|
|
|
|
function EC(options) {
|
|
if (!(this instanceof EC))
|
|
return new EC(options);
|
|
|
|
// Shortcut `elliptic.ec(curve-name)`
|
|
if (typeof options === 'string') {
|
|
assert(curves.hasOwnProperty(options), 'Unknown curve ' + options);
|
|
|
|
options = curves[options];
|
|
}
|
|
|
|
// Shortcut for `elliptic.ec(elliptic.curves.curveName)`
|
|
if (options instanceof curves.PresetCurve)
|
|
options = { curve: options };
|
|
|
|
this.curve = options.curve.curve;
|
|
this.n = this.curve.n;
|
|
this.nh = this.n.ushrn(1);
|
|
this.g = this.curve.g;
|
|
|
|
// Point on curve
|
|
this.g = options.curve.g;
|
|
this.g.precompute(options.curve.n.bitLength() + 1);
|
|
|
|
// Hash for function for DRBG
|
|
this.hash = options.hash || options.curve.hash;
|
|
}
|
|
module.exports = EC;
|
|
|
|
EC.prototype.keyPair = function keyPair(options) {
|
|
return new KeyPair(this, options);
|
|
};
|
|
|
|
EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
|
|
return KeyPair.fromPrivate(this, priv, enc);
|
|
};
|
|
|
|
EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
|
|
return KeyPair.fromPublic(this, pub, enc);
|
|
};
|
|
|
|
EC.prototype.genKeyPair = function genKeyPair(options) {
|
|
if (!options)
|
|
options = {};
|
|
|
|
// Instantiate Hmac_DRBG
|
|
var drbg = new HmacDRBG({
|
|
hash: this.hash,
|
|
pers: options.pers,
|
|
persEnc: options.persEnc || 'utf8',
|
|
entropy: options.entropy || rand(this.hash.hmacStrength),
|
|
entropyEnc: options.entropy && options.entropyEnc || 'utf8',
|
|
nonce: this.n.toArray()
|
|
});
|
|
|
|
var bytes = this.n.byteLength();
|
|
var ns2 = this.n.sub(new BN(2));
|
|
do {
|
|
var priv = new BN(drbg.generate(bytes));
|
|
if (priv.cmp(ns2) > 0)
|
|
continue;
|
|
|
|
priv.iaddn(1);
|
|
return this.keyFromPrivate(priv);
|
|
} while (true);
|
|
};
|
|
|
|
EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
|
|
var delta = msg.byteLength() * 8 - this.n.bitLength();
|
|
if (delta > 0)
|
|
msg = msg.ushrn(delta);
|
|
if (!truncOnly && msg.cmp(this.n) >= 0)
|
|
return msg.sub(this.n);
|
|
else
|
|
return msg;
|
|
};
|
|
|
|
EC.prototype.sign = function sign(msg, key, enc, options) {
|
|
if (typeof enc === 'object') {
|
|
options = enc;
|
|
enc = null;
|
|
}
|
|
if (!options)
|
|
options = {};
|
|
|
|
key = this.keyFromPrivate(key, enc);
|
|
msg = this._truncateToN(new BN(msg, 16));
|
|
|
|
// Zero-extend key to provide enough entropy
|
|
var bytes = this.n.byteLength();
|
|
var bkey = key.getPrivate().toArray('be', bytes);
|
|
|
|
// Zero-extend nonce to have the same byte size as N
|
|
var nonce = msg.toArray('be', bytes);
|
|
|
|
// Instantiate Hmac_DRBG
|
|
var drbg = new HmacDRBG({
|
|
hash: this.hash,
|
|
entropy: bkey,
|
|
nonce: nonce,
|
|
pers: options.pers,
|
|
persEnc: options.persEnc || 'utf8'
|
|
});
|
|
|
|
// Number of bytes to generate
|
|
var ns1 = this.n.sub(new BN(1));
|
|
|
|
for (var iter = 0; true; iter++) {
|
|
var k = options.k ?
|
|
options.k(iter) :
|
|
new BN(drbg.generate(this.n.byteLength()));
|
|
k = this._truncateToN(k, true);
|
|
if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
|
|
continue;
|
|
|
|
var kp = this.g.mul(k);
|
|
if (kp.isInfinity())
|
|
continue;
|
|
|
|
var kpX = kp.getX();
|
|
var r = kpX.umod(this.n);
|
|
if (r.cmpn(0) === 0)
|
|
continue;
|
|
|
|
var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
|
|
s = s.umod(this.n);
|
|
if (s.cmpn(0) === 0)
|
|
continue;
|
|
|
|
var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
|
|
(kpX.cmp(r) !== 0 ? 2 : 0);
|
|
|
|
// Use complement of `s`, if it is > `n / 2`
|
|
if (options.canonical && s.cmp(this.nh) > 0) {
|
|
s = this.n.sub(s);
|
|
recoveryParam ^= 1;
|
|
}
|
|
|
|
return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
|
|
}
|
|
};
|
|
|
|
EC.prototype.verify = function verify(msg, signature, key, enc) {
|
|
msg = this._truncateToN(new BN(msg, 16));
|
|
key = this.keyFromPublic(key, enc);
|
|
signature = new Signature(signature, 'hex');
|
|
|
|
// Perform primitive values validation
|
|
var r = signature.r;
|
|
var s = signature.s;
|
|
if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
|
|
return false;
|
|
if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
|
|
return false;
|
|
|
|
// Validate signature
|
|
var sinv = s.invm(this.n);
|
|
var u1 = sinv.mul(msg).umod(this.n);
|
|
var u2 = sinv.mul(r).umod(this.n);
|
|
|
|
if (!this.curve._maxwellTrick) {
|
|
var p = this.g.mulAdd(u1, key.getPublic(), u2);
|
|
if (p.isInfinity())
|
|
return false;
|
|
|
|
return p.getX().umod(this.n).cmp(r) === 0;
|
|
}
|
|
|
|
// NOTE: Greg Maxwell's trick, inspired by:
|
|
// https://git.io/vad3K
|
|
|
|
var p = this.g.jmulAdd(u1, key.getPublic(), u2);
|
|
if (p.isInfinity())
|
|
return false;
|
|
|
|
// Compare `p.x` of Jacobian point with `r`,
|
|
// this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
|
|
// inverse of `p.z^2`
|
|
return p.eqXToP(r);
|
|
};
|
|
|
|
EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
|
|
assert((3 & j) === j, 'The recovery param is more than two bits');
|
|
signature = new Signature(signature, enc);
|
|
|
|
var n = this.n;
|
|
var e = new BN(msg);
|
|
var r = signature.r;
|
|
var s = signature.s;
|
|
|
|
// A set LSB signifies that the y-coordinate is odd
|
|
var isYOdd = j & 1;
|
|
var isSecondKey = j >> 1;
|
|
if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
|
|
throw new Error('Unable to find sencond key candinate');
|
|
|
|
// 1.1. Let x = r + jn.
|
|
if (isSecondKey)
|
|
r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
|
|
else
|
|
r = this.curve.pointFromX(r, isYOdd);
|
|
|
|
var rInv = signature.r.invm(n);
|
|
var s1 = n.sub(e).mul(rInv).umod(n);
|
|
var s2 = s.mul(rInv).umod(n);
|
|
|
|
// 1.6.1 Compute Q = r^-1 (sR - eG)
|
|
// Q = r^-1 (sR + -eG)
|
|
return this.g.mulAdd(s1, r, s2);
|
|
};
|
|
|
|
EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
|
|
signature = new Signature(signature, enc);
|
|
if (signature.recoveryParam !== null)
|
|
return signature.recoveryParam;
|
|
|
|
for (var i = 0; i < 4; i++) {
|
|
var Qprime;
|
|
try {
|
|
Qprime = this.recoverPubKey(e, signature, i);
|
|
} catch (e) {
|
|
continue;
|
|
}
|
|
|
|
if (Qprime.eq(Q))
|
|
return i;
|
|
}
|
|
throw new Error('Unable to find valid recovery factor');
|
|
};
|
|
|
|
},{"../curves":13,"../utils":21,"./key":15,"./signature":16,"bn.js":22,"brorand":3,"hmac-drbg":37}],15:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var BN = require('bn.js');
|
|
var utils = require('../utils');
|
|
var assert = utils.assert;
|
|
|
|
function KeyPair(ec, options) {
|
|
this.ec = ec;
|
|
this.priv = null;
|
|
this.pub = null;
|
|
|
|
// KeyPair(ec, { priv: ..., pub: ... })
|
|
if (options.priv)
|
|
this._importPrivate(options.priv, options.privEnc);
|
|
if (options.pub)
|
|
this._importPublic(options.pub, options.pubEnc);
|
|
}
|
|
module.exports = KeyPair;
|
|
|
|
KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
|
|
if (pub instanceof KeyPair)
|
|
return pub;
|
|
|
|
return new KeyPair(ec, {
|
|
pub: pub,
|
|
pubEnc: enc
|
|
});
|
|
};
|
|
|
|
KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
|
|
if (priv instanceof KeyPair)
|
|
return priv;
|
|
|
|
return new KeyPair(ec, {
|
|
priv: priv,
|
|
privEnc: enc
|
|
});
|
|
};
|
|
|
|
KeyPair.prototype.validate = function validate() {
|
|
var pub = this.getPublic();
|
|
|
|
if (pub.isInfinity())
|
|
return { result: false, reason: 'Invalid public key' };
|
|
if (!pub.validate())
|
|
return { result: false, reason: 'Public key is not a point' };
|
|
if (!pub.mul(this.ec.curve.n).isInfinity())
|
|
return { result: false, reason: 'Public key * N != O' };
|
|
|
|
return { result: true, reason: null };
|
|
};
|
|
|
|
KeyPair.prototype.getPublic = function getPublic(compact, enc) {
|
|
// compact is optional argument
|
|
if (typeof compact === 'string') {
|
|
enc = compact;
|
|
compact = null;
|
|
}
|
|
|
|
if (!this.pub)
|
|
this.pub = this.ec.g.mul(this.priv);
|
|
|
|
if (!enc)
|
|
return this.pub;
|
|
|
|
return this.pub.encode(enc, compact);
|
|
};
|
|
|
|
KeyPair.prototype.getPrivate = function getPrivate(enc) {
|
|
if (enc === 'hex')
|
|
return this.priv.toString(16, 2);
|
|
else
|
|
return this.priv;
|
|
};
|
|
|
|
KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
|
|
this.priv = new BN(key, enc || 16);
|
|
|
|
// Ensure that the priv won't be bigger than n, otherwise we may fail
|
|
// in fixed multiplication method
|
|
this.priv = this.priv.umod(this.ec.curve.n);
|
|
};
|
|
|
|
KeyPair.prototype._importPublic = function _importPublic(key, enc) {
|
|
if (key.x || key.y) {
|
|
// Montgomery points only have an `x` coordinate.
|
|
// Weierstrass/Edwards points on the other hand have both `x` and
|
|
// `y` coordinates.
|
|
if (this.ec.curve.type === 'mont') {
|
|
assert(key.x, 'Need x coordinate');
|
|
} else if (this.ec.curve.type === 'short' ||
|
|
this.ec.curve.type === 'edwards') {
|
|
assert(key.x && key.y, 'Need both x and y coordinate');
|
|
}
|
|
this.pub = this.ec.curve.point(key.x, key.y);
|
|
return;
|
|
}
|
|
this.pub = this.ec.curve.decodePoint(key, enc);
|
|
};
|
|
|
|
// ECDH
|
|
KeyPair.prototype.derive = function derive(pub) {
|
|
return pub.mul(this.priv).getX();
|
|
};
|
|
|
|
// ECDSA
|
|
KeyPair.prototype.sign = function sign(msg, enc, options) {
|
|
return this.ec.sign(msg, this, enc, options);
|
|
};
|
|
|
|
KeyPair.prototype.verify = function verify(msg, signature) {
|
|
return this.ec.verify(msg, signature, this);
|
|
};
|
|
|
|
KeyPair.prototype.inspect = function inspect() {
|
|
return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
|
|
' pub: ' + (this.pub && this.pub.inspect()) + ' >';
|
|
};
|
|
|
|
},{"../utils":21,"bn.js":22}],16:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var BN = require('bn.js');
|
|
|
|
var utils = require('../utils');
|
|
var assert = utils.assert;
|
|
|
|
function Signature(options, enc) {
|
|
if (options instanceof Signature)
|
|
return options;
|
|
|
|
if (this._importDER(options, enc))
|
|
return;
|
|
|
|
assert(options.r && options.s, 'Signature without r or s');
|
|
this.r = new BN(options.r, 16);
|
|
this.s = new BN(options.s, 16);
|
|
if (options.recoveryParam === undefined)
|
|
this.recoveryParam = null;
|
|
else
|
|
this.recoveryParam = options.recoveryParam;
|
|
}
|
|
module.exports = Signature;
|
|
|
|
function Position() {
|
|
this.place = 0;
|
|
}
|
|
|
|
function getLength(buf, p) {
|
|
var initial = buf[p.place++];
|
|
if (!(initial & 0x80)) {
|
|
return initial;
|
|
}
|
|
var octetLen = initial & 0xf;
|
|
var val = 0;
|
|
for (var i = 0, off = p.place; i < octetLen; i++, off++) {
|
|
val <<= 8;
|
|
val |= buf[off];
|
|
}
|
|
p.place = off;
|
|
return val;
|
|
}
|
|
|
|
function rmPadding(buf) {
|
|
var i = 0;
|
|
var len = buf.length - 1;
|
|
while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
|
|
i++;
|
|
}
|
|
if (i === 0) {
|
|
return buf;
|
|
}
|
|
return buf.slice(i);
|
|
}
|
|
|
|
Signature.prototype._importDER = function _importDER(data, enc) {
|
|
data = utils.toArray(data, enc);
|
|
var p = new Position();
|
|
if (data[p.place++] !== 0x30) {
|
|
return false;
|
|
}
|
|
var len = getLength(data, p);
|
|
if ((len + p.place) !== data.length) {
|
|
return false;
|
|
}
|
|
if (data[p.place++] !== 0x02) {
|
|
return false;
|
|
}
|
|
var rlen = getLength(data, p);
|
|
var r = data.slice(p.place, rlen + p.place);
|
|
p.place += rlen;
|
|
if (data[p.place++] !== 0x02) {
|
|
return false;
|
|
}
|
|
var slen = getLength(data, p);
|
|
if (data.length !== slen + p.place) {
|
|
return false;
|
|
}
|
|
var s = data.slice(p.place, slen + p.place);
|
|
if (r[0] === 0 && (r[1] & 0x80)) {
|
|
r = r.slice(1);
|
|
}
|
|
if (s[0] === 0 && (s[1] & 0x80)) {
|
|
s = s.slice(1);
|
|
}
|
|
|
|
this.r = new BN(r);
|
|
this.s = new BN(s);
|
|
this.recoveryParam = null;
|
|
|
|
return true;
|
|
};
|
|
|
|
function constructLength(arr, len) {
|
|
if (len < 0x80) {
|
|
arr.push(len);
|
|
return;
|
|
}
|
|
var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
|
|
arr.push(octets | 0x80);
|
|
while (--octets) {
|
|
arr.push((len >>> (octets << 3)) & 0xff);
|
|
}
|
|
arr.push(len);
|
|
}
|
|
|
|
Signature.prototype.toDER = function toDER(enc) {
|
|
var r = this.r.toArray();
|
|
var s = this.s.toArray();
|
|
|
|
// Pad values
|
|
if (r[0] & 0x80)
|
|
r = [ 0 ].concat(r);
|
|
// Pad values
|
|
if (s[0] & 0x80)
|
|
s = [ 0 ].concat(s);
|
|
|
|
r = rmPadding(r);
|
|
s = rmPadding(s);
|
|
|
|
while (!s[0] && !(s[1] & 0x80)) {
|
|
s = s.slice(1);
|
|
}
|
|
var arr = [ 0x02 ];
|
|
constructLength(arr, r.length);
|
|
arr = arr.concat(r);
|
|
arr.push(0x02);
|
|
constructLength(arr, s.length);
|
|
var backHalf = arr.concat(s);
|
|
var res = [ 0x30 ];
|
|
constructLength(res, backHalf.length);
|
|
res = res.concat(backHalf);
|
|
return utils.encode(res, enc);
|
|
};
|
|
|
|
},{"../utils":21,"bn.js":22}],17:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var hash = require('hash.js');
|
|
var curves = require('../curves');
|
|
var utils = require('../utils');
|
|
var assert = utils.assert;
|
|
var parseBytes = utils.parseBytes;
|
|
var KeyPair = require('./key');
|
|
var Signature = require('./signature');
|
|
|
|
function EDDSA(curve) {
|
|
assert(curve === 'ed25519', 'only tested with ed25519 so far');
|
|
|
|
if (!(this instanceof EDDSA))
|
|
return new EDDSA(curve);
|
|
|
|
var curve = curves[curve].curve;
|
|
this.curve = curve;
|
|
this.g = curve.g;
|
|
this.g.precompute(curve.n.bitLength() + 1);
|
|
|
|
this.pointClass = curve.point().constructor;
|
|
this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
|
|
this.hash = hash.sha512;
|
|
}
|
|
|
|
module.exports = EDDSA;
|
|
|
|
/**
|
|
* @param {Array|String} message - message bytes
|
|
* @param {Array|String|KeyPair} secret - secret bytes or a keypair
|
|
* @returns {Signature} - signature
|
|
*/
|
|
EDDSA.prototype.sign = function sign(message, secret) {
|
|
message = parseBytes(message);
|
|
var key = this.keyFromSecret(secret);
|
|
var r = this.hashInt(key.messagePrefix(), message);
|
|
var R = this.g.mul(r);
|
|
var Rencoded = this.encodePoint(R);
|
|
var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
|
|
.mul(key.priv());
|
|
var S = r.add(s_).umod(this.curve.n);
|
|
return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
|
|
};
|
|
|
|
/**
|
|
* @param {Array} message - message bytes
|
|
* @param {Array|String|Signature} sig - sig bytes
|
|
* @param {Array|String|Point|KeyPair} pub - public key
|
|
* @returns {Boolean} - true if public key matches sig of message
|
|
*/
|
|
EDDSA.prototype.verify = function verify(message, sig, pub) {
|
|
message = parseBytes(message);
|
|
sig = this.makeSignature(sig);
|
|
var key = this.keyFromPublic(pub);
|
|
var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
|
|
var SG = this.g.mul(sig.S());
|
|
var RplusAh = sig.R().add(key.pub().mul(h));
|
|
return RplusAh.eq(SG);
|
|
};
|
|
|
|
EDDSA.prototype.hashInt = function hashInt() {
|
|
var hash = this.hash();
|
|
for (var i = 0; i < arguments.length; i++)
|
|
hash.update(arguments[i]);
|
|
return utils.intFromLE(hash.digest()).umod(this.curve.n);
|
|
};
|
|
|
|
EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
|
|
return KeyPair.fromPublic(this, pub);
|
|
};
|
|
|
|
EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
|
|
return KeyPair.fromSecret(this, secret);
|
|
};
|
|
|
|
EDDSA.prototype.makeSignature = function makeSignature(sig) {
|
|
if (sig instanceof Signature)
|
|
return sig;
|
|
return new Signature(this, sig);
|
|
};
|
|
|
|
/**
|
|
* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
|
|
*
|
|
* EDDSA defines methods for encoding and decoding points and integers. These are
|
|
* helper convenience methods, that pass along to utility functions implied
|
|
* parameters.
|
|
*
|
|
*/
|
|
EDDSA.prototype.encodePoint = function encodePoint(point) {
|
|
var enc = point.getY().toArray('le', this.encodingLength);
|
|
enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
|
|
return enc;
|
|
};
|
|
|
|
EDDSA.prototype.decodePoint = function decodePoint(bytes) {
|
|
bytes = utils.parseBytes(bytes);
|
|
|
|
var lastIx = bytes.length - 1;
|
|
var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
|
|
var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
|
|
|
|
var y = utils.intFromLE(normed);
|
|
return this.curve.pointFromY(y, xIsOdd);
|
|
};
|
|
|
|
EDDSA.prototype.encodeInt = function encodeInt(num) {
|
|
return num.toArray('le', this.encodingLength);
|
|
};
|
|
|
|
EDDSA.prototype.decodeInt = function decodeInt(bytes) {
|
|
return utils.intFromLE(bytes);
|
|
};
|
|
|
|
EDDSA.prototype.isPoint = function isPoint(val) {
|
|
return val instanceof this.pointClass;
|
|
};
|
|
|
|
},{"../curves":13,"../utils":21,"./key":18,"./signature":19,"hash.js":25}],18:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var assert = utils.assert;
|
|
var parseBytes = utils.parseBytes;
|
|
var cachedProperty = utils.cachedProperty;
|
|
|
|
/**
|
|
* @param {EDDSA} eddsa - instance
|
|
* @param {Object} params - public/private key parameters
|
|
*
|
|
* @param {Array<Byte>} [params.secret] - secret seed bytes
|
|
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
|
|
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
|
|
*
|
|
*/
|
|
function KeyPair(eddsa, params) {
|
|
this.eddsa = eddsa;
|
|
this._secret = parseBytes(params.secret);
|
|
if (eddsa.isPoint(params.pub))
|
|
this._pub = params.pub;
|
|
else
|
|
this._pubBytes = parseBytes(params.pub);
|
|
}
|
|
|
|
KeyPair.fromPublic = function fromPublic(eddsa, pub) {
|
|
if (pub instanceof KeyPair)
|
|
return pub;
|
|
return new KeyPair(eddsa, { pub: pub });
|
|
};
|
|
|
|
KeyPair.fromSecret = function fromSecret(eddsa, secret) {
|
|
if (secret instanceof KeyPair)
|
|
return secret;
|
|
return new KeyPair(eddsa, { secret: secret });
|
|
};
|
|
|
|
KeyPair.prototype.secret = function secret() {
|
|
return this._secret;
|
|
};
|
|
|
|
cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
|
|
return this.eddsa.encodePoint(this.pub());
|
|
});
|
|
|
|
cachedProperty(KeyPair, 'pub', function pub() {
|
|
if (this._pubBytes)
|
|
return this.eddsa.decodePoint(this._pubBytes);
|
|
return this.eddsa.g.mul(this.priv());
|
|
});
|
|
|
|
cachedProperty(KeyPair, 'privBytes', function privBytes() {
|
|
var eddsa = this.eddsa;
|
|
var hash = this.hash();
|
|
var lastIx = eddsa.encodingLength - 1;
|
|
|
|
var a = hash.slice(0, eddsa.encodingLength);
|
|
a[0] &= 248;
|
|
a[lastIx] &= 127;
|
|
a[lastIx] |= 64;
|
|
|
|
return a;
|
|
});
|
|
|
|
cachedProperty(KeyPair, 'priv', function priv() {
|
|
return this.eddsa.decodeInt(this.privBytes());
|
|
});
|
|
|
|
cachedProperty(KeyPair, 'hash', function hash() {
|
|
return this.eddsa.hash().update(this.secret()).digest();
|
|
});
|
|
|
|
cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
|
|
return this.hash().slice(this.eddsa.encodingLength);
|
|
});
|
|
|
|
KeyPair.prototype.sign = function sign(message) {
|
|
assert(this._secret, 'KeyPair can only verify');
|
|
return this.eddsa.sign(message, this);
|
|
};
|
|
|
|
KeyPair.prototype.verify = function verify(message, sig) {
|
|
return this.eddsa.verify(message, sig, this);
|
|
};
|
|
|
|
KeyPair.prototype.getSecret = function getSecret(enc) {
|
|
assert(this._secret, 'KeyPair is public only');
|
|
return utils.encode(this.secret(), enc);
|
|
};
|
|
|
|
KeyPair.prototype.getPublic = function getPublic(enc) {
|
|
return utils.encode(this.pubBytes(), enc);
|
|
};
|
|
|
|
module.exports = KeyPair;
|
|
|
|
},{"../utils":21}],19:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var BN = require('bn.js');
|
|
var utils = require('../utils');
|
|
var assert = utils.assert;
|
|
var cachedProperty = utils.cachedProperty;
|
|
var parseBytes = utils.parseBytes;
|
|
|
|
/**
|
|
* @param {EDDSA} eddsa - eddsa instance
|
|
* @param {Array<Bytes>|Object} sig -
|
|
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
|
|
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
|
|
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
|
|
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
|
|
*/
|
|
function Signature(eddsa, sig) {
|
|
this.eddsa = eddsa;
|
|
|
|
if (typeof sig !== 'object')
|
|
sig = parseBytes(sig);
|
|
|
|
if (Array.isArray(sig)) {
|
|
sig = {
|
|
R: sig.slice(0, eddsa.encodingLength),
|
|
S: sig.slice(eddsa.encodingLength)
|
|
};
|
|
}
|
|
|
|
assert(sig.R && sig.S, 'Signature without R or S');
|
|
|
|
if (eddsa.isPoint(sig.R))
|
|
this._R = sig.R;
|
|
if (sig.S instanceof BN)
|
|
this._S = sig.S;
|
|
|
|
this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
|
|
this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
|
|
}
|
|
|
|
cachedProperty(Signature, 'S', function S() {
|
|
return this.eddsa.decodeInt(this.Sencoded());
|
|
});
|
|
|
|
cachedProperty(Signature, 'R', function R() {
|
|
return this.eddsa.decodePoint(this.Rencoded());
|
|
});
|
|
|
|
cachedProperty(Signature, 'Rencoded', function Rencoded() {
|
|
return this.eddsa.encodePoint(this.R());
|
|
});
|
|
|
|
cachedProperty(Signature, 'Sencoded', function Sencoded() {
|
|
return this.eddsa.encodeInt(this.S());
|
|
});
|
|
|
|
Signature.prototype.toBytes = function toBytes() {
|
|
return this.Rencoded().concat(this.Sencoded());
|
|
};
|
|
|
|
Signature.prototype.toHex = function toHex() {
|
|
return utils.encode(this.toBytes(), 'hex').toUpperCase();
|
|
};
|
|
|
|
module.exports = Signature;
|
|
|
|
},{"../utils":21,"bn.js":22}],20:[function(require,module,exports){
|
|
module.exports = {
|
|
doubles: {
|
|
step: 4,
|
|
points: [
|
|
[
|
|
'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
|
|
'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
|
|
],
|
|
[
|
|
'8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
|
|
'11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
|
|
],
|
|
[
|
|
'175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
|
|
'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
|
|
],
|
|
[
|
|
'363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
|
|
'4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
|
|
],
|
|
[
|
|
'8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
|
|
'4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
|
|
],
|
|
[
|
|
'723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
|
|
'96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
|
|
],
|
|
[
|
|
'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
|
|
'5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
|
|
],
|
|
[
|
|
'100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
|
|
'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
|
|
],
|
|
[
|
|
'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
|
|
'9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
|
|
],
|
|
[
|
|
'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
|
|
'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
|
|
],
|
|
[
|
|
'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
|
|
'9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
|
|
],
|
|
[
|
|
'53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
|
|
'5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
|
|
],
|
|
[
|
|
'8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
|
|
'10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
|
|
],
|
|
[
|
|
'385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
|
|
'283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
|
|
],
|
|
[
|
|
'6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
|
|
'7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
|
|
],
|
|
[
|
|
'3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
|
|
'56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
|
|
],
|
|
[
|
|
'85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
|
|
'7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
|
|
],
|
|
[
|
|
'948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
|
|
'53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
|
|
],
|
|
[
|
|
'6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
|
|
'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
|
|
],
|
|
[
|
|
'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
|
|
'4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
|
|
],
|
|
[
|
|
'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
|
|
'7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
|
|
],
|
|
[
|
|
'213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
|
|
'4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
|
|
],
|
|
[
|
|
'4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
|
|
'17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
|
|
],
|
|
[
|
|
'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
|
|
'6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
|
|
],
|
|
[
|
|
'76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
|
|
'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
|
|
],
|
|
[
|
|
'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
|
|
'893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
|
|
],
|
|
[
|
|
'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
|
|
'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
|
|
],
|
|
[
|
|
'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
|
|
'2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
|
|
],
|
|
[
|
|
'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
|
|
'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
|
|
],
|
|
[
|
|
'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
|
|
'7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
|
|
],
|
|
[
|
|
'90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
|
|
'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
|
|
],
|
|
[
|
|
'8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
|
|
'662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
|
|
],
|
|
[
|
|
'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
|
|
'1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
|
|
],
|
|
[
|
|
'8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
|
|
'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
|
|
],
|
|
[
|
|
'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
|
|
'2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
|
|
],
|
|
[
|
|
'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
|
|
'67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
|
|
],
|
|
[
|
|
'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
|
|
'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
|
|
],
|
|
[
|
|
'324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
|
|
'648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
|
|
],
|
|
[
|
|
'4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
|
|
'35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
|
|
],
|
|
[
|
|
'9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
|
|
'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
|
|
],
|
|
[
|
|
'6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
|
|
'9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
|
|
],
|
|
[
|
|
'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
|
|
'40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
|
|
],
|
|
[
|
|
'7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
|
|
'34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
|
|
],
|
|
[
|
|
'928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
|
|
'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
|
|
],
|
|
[
|
|
'85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
|
|
'1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
|
|
],
|
|
[
|
|
'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
|
|
'493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
|
|
],
|
|
[
|
|
'827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
|
|
'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
|
|
],
|
|
[
|
|
'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
|
|
'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
|
|
],
|
|
[
|
|
'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
|
|
'4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
|
|
],
|
|
[
|
|
'1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
|
|
'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
|
|
],
|
|
[
|
|
'146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
|
|
'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
|
|
],
|
|
[
|
|
'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
|
|
'6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
|
|
],
|
|
[
|
|
'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
|
|
'8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
|
|
],
|
|
[
|
|
'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
|
|
'7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
|
|
],
|
|
[
|
|
'174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
|
|
'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
|
|
],
|
|
[
|
|
'959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
|
|
'2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
|
|
],
|
|
[
|
|
'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
|
|
'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
|
|
],
|
|
[
|
|
'64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
|
|
'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
|
|
],
|
|
[
|
|
'8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
|
|
'38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
|
|
],
|
|
[
|
|
'13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
|
|
'69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
|
|
],
|
|
[
|
|
'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
|
|
'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
|
|
],
|
|
[
|
|
'8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
|
|
'40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
|
|
],
|
|
[
|
|
'8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
|
|
'620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
|
|
],
|
|
[
|
|
'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
|
|
'7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
|
|
],
|
|
[
|
|
'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
|
|
'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
|
|
]
|
|
]
|
|
},
|
|
naf: {
|
|
wnd: 7,
|
|
points: [
|
|
[
|
|
'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
|
|
'388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
|
|
],
|
|
[
|
|
'2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
|
|
'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
|
|
],
|
|
[
|
|
'5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
|
|
'6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
|
|
],
|
|
[
|
|
'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
|
|
'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
|
|
],
|
|
[
|
|
'774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
|
|
'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
|
|
],
|
|
[
|
|
'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
|
|
'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
|
|
],
|
|
[
|
|
'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
|
|
'581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
|
|
],
|
|
[
|
|
'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
|
|
'4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
|
|
],
|
|
[
|
|
'2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
|
|
'85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
|
|
],
|
|
[
|
|
'352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
|
|
'321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
|
|
],
|
|
[
|
|
'2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
|
|
'2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
|
|
],
|
|
[
|
|
'9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
|
|
'73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
|
|
],
|
|
[
|
|
'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
|
|
'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
|
|
],
|
|
[
|
|
'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
|
|
'2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
|
|
],
|
|
[
|
|
'6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
|
|
'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
|
|
],
|
|
[
|
|
'1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
|
|
'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
|
|
],
|
|
[
|
|
'605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
|
|
'2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
|
|
],
|
|
[
|
|
'62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
|
|
'80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
|
|
],
|
|
[
|
|
'80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
|
|
'1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
|
|
],
|
|
[
|
|
'7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
|
|
'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
|
|
],
|
|
[
|
|
'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
|
|
'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
|
|
],
|
|
[
|
|
'49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
|
|
'758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
|
|
],
|
|
[
|
|
'77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
|
|
'958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
|
|
],
|
|
[
|
|
'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
|
|
'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
|
|
],
|
|
[
|
|
'463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
|
|
'5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
|
|
],
|
|
[
|
|
'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
|
|
'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
|
|
],
|
|
[
|
|
'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
|
|
'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
|
|
],
|
|
[
|
|
'2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
|
|
'4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
|
|
],
|
|
[
|
|
'7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
|
|
'91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
|
|
],
|
|
[
|
|
'754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
|
|
'673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
|
|
],
|
|
[
|
|
'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
|
|
'59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
|
|
],
|
|
[
|
|
'186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
|
|
'3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
|
|
],
|
|
[
|
|
'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
|
|
'55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
|
|
],
|
|
[
|
|
'5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
|
|
'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
|
|
],
|
|
[
|
|
'290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
|
|
'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
|
|
],
|
|
[
|
|
'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
|
|
'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
|
|
],
|
|
[
|
|
'766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
|
|
'744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
|
|
],
|
|
[
|
|
'59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
|
|
'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
|
|
],
|
|
[
|
|
'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
|
|
'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
|
|
],
|
|
[
|
|
'7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
|
|
'30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
|
|
],
|
|
[
|
|
'948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
|
|
'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
|
|
],
|
|
[
|
|
'7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
|
|
'100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
|
|
],
|
|
[
|
|
'3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
|
|
'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
|
|
],
|
|
[
|
|
'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
|
|
'8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
|
|
],
|
|
[
|
|
'1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
|
|
'68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
|
|
],
|
|
[
|
|
'733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
|
|
'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
|
|
],
|
|
[
|
|
'15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
|
|
'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
|
|
],
|
|
[
|
|
'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
|
|
'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
|
|
],
|
|
[
|
|
'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
|
|
'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
|
|
],
|
|
[
|
|
'311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
|
|
'66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
|
|
],
|
|
[
|
|
'34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
|
|
'9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
|
|
],
|
|
[
|
|
'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
|
|
'4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
|
|
],
|
|
[
|
|
'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
|
|
'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
|
|
],
|
|
[
|
|
'32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
|
|
'5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
|
|
],
|
|
[
|
|
'7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
|
|
'8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
|
|
],
|
|
[
|
|
'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
|
|
'8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
|
|
],
|
|
[
|
|
'16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
|
|
'5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
|
|
],
|
|
[
|
|
'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
|
|
'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
|
|
],
|
|
[
|
|
'78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
|
|
'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
|
|
],
|
|
[
|
|
'494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
|
|
'42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
|
|
],
|
|
[
|
|
'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
|
|
'204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
|
|
],
|
|
[
|
|
'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
|
|
'4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
|
|
],
|
|
[
|
|
'841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
|
|
'73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
|
|
],
|
|
[
|
|
'5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
|
|
'39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
|
|
],
|
|
[
|
|
'36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
|
|
'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
|
|
],
|
|
[
|
|
'336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
|
|
'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
|
|
],
|
|
[
|
|
'8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
|
|
'6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
|
|
],
|
|
[
|
|
'1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
|
|
'60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
|
|
],
|
|
[
|
|
'85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
|
|
'3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
|
|
],
|
|
[
|
|
'29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
|
|
'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
|
|
],
|
|
[
|
|
'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
|
|
'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
|
|
],
|
|
[
|
|
'4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
|
|
'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
|
|
],
|
|
[
|
|
'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
|
|
'6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
|
|
],
|
|
[
|
|
'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
|
|
'322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
|
|
],
|
|
[
|
|
'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
|
|
'6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
|
|
],
|
|
[
|
|
'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
|
|
'2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
|
|
],
|
|
[
|
|
'591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
|
|
'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
|
|
],
|
|
[
|
|
'11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
|
|
'998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
|
|
],
|
|
[
|
|
'3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
|
|
'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
|
|
],
|
|
[
|
|
'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
|
|
'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
|
|
],
|
|
[
|
|
'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
|
|
'6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
|
|
],
|
|
[
|
|
'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
|
|
'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
|
|
],
|
|
[
|
|
'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
|
|
'21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
|
|
],
|
|
[
|
|
'347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
|
|
'60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
|
|
],
|
|
[
|
|
'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
|
|
'49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
|
|
],
|
|
[
|
|
'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
|
|
'5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
|
|
],
|
|
[
|
|
'4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
|
|
'7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
|
|
],
|
|
[
|
|
'3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
|
|
'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
|
|
],
|
|
[
|
|
'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
|
|
'8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
|
|
],
|
|
[
|
|
'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
|
|
'39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
|
|
],
|
|
[
|
|
'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
|
|
'62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
|
|
],
|
|
[
|
|
'48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
|
|
'25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
|
|
],
|
|
[
|
|
'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
|
|
'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
|
|
],
|
|
[
|
|
'6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
|
|
'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
|
|
],
|
|
[
|
|
'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
|
|
'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
|
|
],
|
|
[
|
|
'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
|
|
'6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
|
|
],
|
|
[
|
|
'13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
|
|
'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
|
|
],
|
|
[
|
|
'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
|
|
'1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
|
|
],
|
|
[
|
|
'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
|
|
'5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
|
|
],
|
|
[
|
|
'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
|
|
'438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
|
|
],
|
|
[
|
|
'8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
|
|
'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
|
|
],
|
|
[
|
|
'52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
|
|
'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
|
|
],
|
|
[
|
|
'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
|
|
'6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
|
|
],
|
|
[
|
|
'7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
|
|
'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
|
|
],
|
|
[
|
|
'5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
|
|
'9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
|
|
],
|
|
[
|
|
'32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
|
|
'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
|
|
],
|
|
[
|
|
'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
|
|
'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
|
|
],
|
|
[
|
|
'8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
|
|
'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
|
|
],
|
|
[
|
|
'4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
|
|
'67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
|
|
],
|
|
[
|
|
'3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
|
|
'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
|
|
],
|
|
[
|
|
'674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
|
|
'299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
|
|
],
|
|
[
|
|
'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
|
|
'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
|
|
],
|
|
[
|
|
'30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
|
|
'462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
|
|
],
|
|
[
|
|
'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
|
|
'62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
|
|
],
|
|
[
|
|
'93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
|
|
'7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
|
|
],
|
|
[
|
|
'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
|
|
'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
|
|
],
|
|
[
|
|
'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
|
|
'4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
|
|
],
|
|
[
|
|
'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
|
|
'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
|
|
],
|
|
[
|
|
'463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
|
|
'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
|
|
],
|
|
[
|
|
'7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
|
|
'603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
|
|
],
|
|
[
|
|
'74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
|
|
'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
|
|
],
|
|
[
|
|
'30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
|
|
'553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
|
|
],
|
|
[
|
|
'9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
|
|
'712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
|
|
],
|
|
[
|
|
'176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
|
|
'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
|
|
],
|
|
[
|
|
'75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
|
|
'9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
|
|
],
|
|
[
|
|
'809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
|
|
'9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
|
|
],
|
|
[
|
|
'1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
|
|
'4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
|
|
]
|
|
]
|
|
}
|
|
};
|
|
|
|
},{}],21:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = exports;
|
|
var BN = require('bn.js');
|
|
var minAssert = require('minimalistic-assert');
|
|
var minUtils = require('minimalistic-crypto-utils');
|
|
|
|
utils.assert = minAssert;
|
|
utils.toArray = minUtils.toArray;
|
|
utils.zero2 = minUtils.zero2;
|
|
utils.toHex = minUtils.toHex;
|
|
utils.encode = minUtils.encode;
|
|
|
|
// Represent num in a w-NAF form
|
|
function getNAF(num, w, bits) {
|
|
var naf = new Array(Math.max(num.bitLength(), bits) + 1);
|
|
naf.fill(0);
|
|
|
|
var ws = 1 << (w + 1);
|
|
var k = num.clone();
|
|
|
|
for (var i = 0; i < naf.length; i++) {
|
|
var z;
|
|
var mod = k.andln(ws - 1);
|
|
if (k.isOdd()) {
|
|
if (mod > (ws >> 1) - 1)
|
|
z = (ws >> 1) - mod;
|
|
else
|
|
z = mod;
|
|
k.isubn(z);
|
|
} else {
|
|
z = 0;
|
|
}
|
|
|
|
naf[i] = z;
|
|
k.iushrn(1);
|
|
}
|
|
|
|
return naf;
|
|
}
|
|
utils.getNAF = getNAF;
|
|
|
|
// Represent k1, k2 in a Joint Sparse Form
|
|
function getJSF(k1, k2) {
|
|
var jsf = [
|
|
[],
|
|
[]
|
|
];
|
|
|
|
k1 = k1.clone();
|
|
k2 = k2.clone();
|
|
var d1 = 0;
|
|
var d2 = 0;
|
|
while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
|
|
|
|
// First phase
|
|
var m14 = (k1.andln(3) + d1) & 3;
|
|
var m24 = (k2.andln(3) + d2) & 3;
|
|
if (m14 === 3)
|
|
m14 = -1;
|
|
if (m24 === 3)
|
|
m24 = -1;
|
|
var u1;
|
|
if ((m14 & 1) === 0) {
|
|
u1 = 0;
|
|
} else {
|
|
var m8 = (k1.andln(7) + d1) & 7;
|
|
if ((m8 === 3 || m8 === 5) && m24 === 2)
|
|
u1 = -m14;
|
|
else
|
|
u1 = m14;
|
|
}
|
|
jsf[0].push(u1);
|
|
|
|
var u2;
|
|
if ((m24 & 1) === 0) {
|
|
u2 = 0;
|
|
} else {
|
|
var m8 = (k2.andln(7) + d2) & 7;
|
|
if ((m8 === 3 || m8 === 5) && m14 === 2)
|
|
u2 = -m24;
|
|
else
|
|
u2 = m24;
|
|
}
|
|
jsf[1].push(u2);
|
|
|
|
// Second phase
|
|
if (2 * d1 === u1 + 1)
|
|
d1 = 1 - d1;
|
|
if (2 * d2 === u2 + 1)
|
|
d2 = 1 - d2;
|
|
k1.iushrn(1);
|
|
k2.iushrn(1);
|
|
}
|
|
|
|
return jsf;
|
|
}
|
|
utils.getJSF = getJSF;
|
|
|
|
function cachedProperty(obj, name, computer) {
|
|
var key = '_' + name;
|
|
obj.prototype[name] = function cachedProperty() {
|
|
return this[key] !== undefined ? this[key] :
|
|
this[key] = computer.call(this);
|
|
};
|
|
}
|
|
utils.cachedProperty = cachedProperty;
|
|
|
|
function parseBytes(bytes) {
|
|
return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
|
|
bytes;
|
|
}
|
|
utils.parseBytes = parseBytes;
|
|
|
|
function intFromLE(bytes) {
|
|
return new BN(bytes, 'hex', 'le');
|
|
}
|
|
utils.intFromLE = intFromLE;
|
|
|
|
|
|
},{"bn.js":22,"minimalistic-assert":41,"minimalistic-crypto-utils":42}],22:[function(require,module,exports){
|
|
(function (module, exports) {
|
|
'use strict';
|
|
|
|
// Utils
|
|
function assert (val, msg) {
|
|
if (!val) throw new Error(msg || 'Assertion failed');
|
|
}
|
|
|
|
// Could use `inherits` module, but don't want to move from single file
|
|
// architecture yet.
|
|
function inherits (ctor, superCtor) {
|
|
ctor.super_ = superCtor;
|
|
var TempCtor = function () {};
|
|
TempCtor.prototype = superCtor.prototype;
|
|
ctor.prototype = new TempCtor();
|
|
ctor.prototype.constructor = ctor;
|
|
}
|
|
|
|
// BN
|
|
|
|
function BN (number, base, endian) {
|
|
if (BN.isBN(number)) {
|
|
return number;
|
|
}
|
|
|
|
this.negative = 0;
|
|
this.words = null;
|
|
this.length = 0;
|
|
|
|
// Reduction context
|
|
this.red = null;
|
|
|
|
if (number !== null) {
|
|
if (base === 'le' || base === 'be') {
|
|
endian = base;
|
|
base = 10;
|
|
}
|
|
|
|
this._init(number || 0, base || 10, endian || 'be');
|
|
}
|
|
}
|
|
if (typeof module === 'object') {
|
|
module.exports = BN;
|
|
} else {
|
|
exports.BN = BN;
|
|
}
|
|
|
|
BN.BN = BN;
|
|
BN.wordSize = 26;
|
|
|
|
var Buffer;
|
|
try {
|
|
Buffer = require('buffer').Buffer;
|
|
} catch (e) {
|
|
}
|
|
|
|
BN.isBN = function isBN (num) {
|
|
if (num instanceof BN) {
|
|
return true;
|
|
}
|
|
|
|
return num !== null && typeof num === 'object' &&
|
|
num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
|
|
};
|
|
|
|
BN.max = function max (left, right) {
|
|
if (left.cmp(right) > 0) return left;
|
|
return right;
|
|
};
|
|
|
|
BN.min = function min (left, right) {
|
|
if (left.cmp(right) < 0) return left;
|
|
return right;
|
|
};
|
|
|
|
BN.prototype._init = function init (number, base, endian) {
|
|
if (typeof number === 'number') {
|
|
return this._initNumber(number, base, endian);
|
|
}
|
|
|
|
if (typeof number === 'object') {
|
|
return this._initArray(number, base, endian);
|
|
}
|
|
|
|
if (base === 'hex') {
|
|
base = 16;
|
|
}
|
|
assert(base === (base | 0) && base >= 2 && base <= 36);
|
|
|
|
number = number.toString().replace(/\s+/g, '');
|
|
var start = 0;
|
|
if (number[0] === '-') {
|
|
start++;
|
|
}
|
|
|
|
if (base === 16) {
|
|
this._parseHex(number, start);
|
|
} else {
|
|
this._parseBase(number, base, start);
|
|
}
|
|
|
|
if (number[0] === '-') {
|
|
this.negative = 1;
|
|
}
|
|
|
|
this.strip();
|
|
|
|
if (endian !== 'le') return;
|
|
|
|
this._initArray(this.toArray(), base, endian);
|
|
};
|
|
|
|
BN.prototype._initNumber = function _initNumber (number, base, endian) {
|
|
if (number < 0) {
|
|
this.negative = 1;
|
|
number = -number;
|
|
}
|
|
if (number < 0x4000000) {
|
|
this.words = [ number & 0x3ffffff ];
|
|
this.length = 1;
|
|
} else if (number < 0x10000000000000) {
|
|
this.words = [
|
|
number & 0x3ffffff,
|
|
(number / 0x4000000) & 0x3ffffff
|
|
];
|
|
this.length = 2;
|
|
} else {
|
|
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
|
this.words = [
|
|
number & 0x3ffffff,
|
|
(number / 0x4000000) & 0x3ffffff,
|
|
1
|
|
];
|
|
this.length = 3;
|
|
}
|
|
|
|
if (endian !== 'le') return;
|
|
|
|
// Reverse the bytes
|
|
this._initArray(this.toArray(), base, endian);
|
|
};
|
|
|
|
BN.prototype._initArray = function _initArray (number, base, endian) {
|
|
// Perhaps a Uint8Array
|
|
assert(typeof number.length === 'number');
|
|
if (number.length <= 0) {
|
|
this.words = [ 0 ];
|
|
this.length = 1;
|
|
return this;
|
|
}
|
|
|
|
this.length = Math.ceil(number.length / 3);
|
|
this.words = new Array(this.length);
|
|
for (var i = 0; i < this.length; i++) {
|
|
this.words[i] = 0;
|
|
}
|
|
|
|
var j, w;
|
|
var off = 0;
|
|
if (endian === 'be') {
|
|
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
|
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
|
off += 24;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
j++;
|
|
}
|
|
}
|
|
} else if (endian === 'le') {
|
|
for (i = 0, j = 0; i < number.length; i += 3) {
|
|
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
|
off += 24;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
return this.strip();
|
|
};
|
|
|
|
function parseHex (str, start, end) {
|
|
var r = 0;
|
|
var len = Math.min(str.length, end);
|
|
for (var i = start; i < len; i++) {
|
|
var c = str.charCodeAt(i) - 48;
|
|
|
|
r <<= 4;
|
|
|
|
// 'a' - 'f'
|
|
if (c >= 49 && c <= 54) {
|
|
r |= c - 49 + 0xa;
|
|
|
|
// 'A' - 'F'
|
|
} else if (c >= 17 && c <= 22) {
|
|
r |= c - 17 + 0xa;
|
|
|
|
// '0' - '9'
|
|
} else {
|
|
r |= c & 0xf;
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
BN.prototype._parseHex = function _parseHex (number, start) {
|
|
// Create possibly bigger array to ensure that it fits the number
|
|
this.length = Math.ceil((number.length - start) / 6);
|
|
this.words = new Array(this.length);
|
|
for (var i = 0; i < this.length; i++) {
|
|
this.words[i] = 0;
|
|
}
|
|
|
|
var j, w;
|
|
// Scan 24-bit chunks and add them to the number
|
|
var off = 0;
|
|
for (i = number.length - 6, j = 0; i >= start; i -= 6) {
|
|
w = parseHex(number, i, i + 6);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
|
|
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
|
off += 24;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
j++;
|
|
}
|
|
}
|
|
if (i + 6 !== start) {
|
|
w = parseHex(number, start, i + 6);
|
|
this.words[j] |= (w << off) & 0x3ffffff;
|
|
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
|
}
|
|
this.strip();
|
|
};
|
|
|
|
function parseBase (str, start, end, mul) {
|
|
var r = 0;
|
|
var len = Math.min(str.length, end);
|
|
for (var i = start; i < len; i++) {
|
|
var c = str.charCodeAt(i) - 48;
|
|
|
|
r *= mul;
|
|
|
|
// 'a'
|
|
if (c >= 49) {
|
|
r += c - 49 + 0xa;
|
|
|
|
// 'A'
|
|
} else if (c >= 17) {
|
|
r += c - 17 + 0xa;
|
|
|
|
// '0' - '9'
|
|
} else {
|
|
r += c;
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
BN.prototype._parseBase = function _parseBase (number, base, start) {
|
|
// Initialize as zero
|
|
this.words = [ 0 ];
|
|
this.length = 1;
|
|
|
|
// Find length of limb in base
|
|
for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
|
|
limbLen++;
|
|
}
|
|
limbLen--;
|
|
limbPow = (limbPow / base) | 0;
|
|
|
|
var total = number.length - start;
|
|
var mod = total % limbLen;
|
|
var end = Math.min(total, total - mod) + start;
|
|
|
|
var word = 0;
|
|
for (var i = start; i < end; i += limbLen) {
|
|
word = parseBase(number, i, i + limbLen, base);
|
|
|
|
this.imuln(limbPow);
|
|
if (this.words[0] + word < 0x4000000) {
|
|
this.words[0] += word;
|
|
} else {
|
|
this._iaddn(word);
|
|
}
|
|
}
|
|
|
|
if (mod !== 0) {
|
|
var pow = 1;
|
|
word = parseBase(number, i, number.length, base);
|
|
|
|
for (i = 0; i < mod; i++) {
|
|
pow *= base;
|
|
}
|
|
|
|
this.imuln(pow);
|
|
if (this.words[0] + word < 0x4000000) {
|
|
this.words[0] += word;
|
|
} else {
|
|
this._iaddn(word);
|
|
}
|
|
}
|
|
};
|
|
|
|
BN.prototype.copy = function copy (dest) {
|
|
dest.words = new Array(this.length);
|
|
for (var i = 0; i < this.length; i++) {
|
|
dest.words[i] = this.words[i];
|
|
}
|
|
dest.length = this.length;
|
|
dest.negative = this.negative;
|
|
dest.red = this.red;
|
|
};
|
|
|
|
BN.prototype.clone = function clone () {
|
|
var r = new BN(null);
|
|
this.copy(r);
|
|
return r;
|
|
};
|
|
|
|
BN.prototype._expand = function _expand (size) {
|
|
while (this.length < size) {
|
|
this.words[this.length++] = 0;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
// Remove leading `0` from `this`
|
|
BN.prototype.strip = function strip () {
|
|
while (this.length > 1 && this.words[this.length - 1] === 0) {
|
|
this.length--;
|
|
}
|
|
return this._normSign();
|
|
};
|
|
|
|
BN.prototype._normSign = function _normSign () {
|
|
// -0 = 0
|
|
if (this.length === 1 && this.words[0] === 0) {
|
|
this.negative = 0;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.inspect = function inspect () {
|
|
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
|
|
};
|
|
|
|
/*
|
|
|
|
var zeros = [];
|
|
var groupSizes = [];
|
|
var groupBases = [];
|
|
|
|
var s = '';
|
|
var i = -1;
|
|
while (++i < BN.wordSize) {
|
|
zeros[i] = s;
|
|
s += '0';
|
|
}
|
|
groupSizes[0] = 0;
|
|
groupSizes[1] = 0;
|
|
groupBases[0] = 0;
|
|
groupBases[1] = 0;
|
|
var base = 2 - 1;
|
|
while (++base < 36 + 1) {
|
|
var groupSize = 0;
|
|
var groupBase = 1;
|
|
while (groupBase < (1 << BN.wordSize) / base) {
|
|
groupBase *= base;
|
|
groupSize += 1;
|
|
}
|
|
groupSizes[base] = groupSize;
|
|
groupBases[base] = groupBase;
|
|
}
|
|
|
|
*/
|
|
|
|
var zeros = [
|
|
'',
|
|
'0',
|
|
'00',
|
|
'000',
|
|
'0000',
|
|
'00000',
|
|
'000000',
|
|
'0000000',
|
|
'00000000',
|
|
'000000000',
|
|
'0000000000',
|
|
'00000000000',
|
|
'000000000000',
|
|
'0000000000000',
|
|
'00000000000000',
|
|
'000000000000000',
|
|
'0000000000000000',
|
|
'00000000000000000',
|
|
'000000000000000000',
|
|
'0000000000000000000',
|
|
'00000000000000000000',
|
|
'000000000000000000000',
|
|
'0000000000000000000000',
|
|
'00000000000000000000000',
|
|
'000000000000000000000000',
|
|
'0000000000000000000000000'
|
|
];
|
|
|
|
var groupSizes = [
|
|
0, 0,
|
|
25, 16, 12, 11, 10, 9, 8,
|
|
8, 7, 7, 7, 7, 6, 6,
|
|
6, 6, 6, 6, 6, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5
|
|
];
|
|
|
|
var groupBases = [
|
|
0, 0,
|
|
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
|
|
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
|
|
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
|
|
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
|
|
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
|
|
];
|
|
|
|
BN.prototype.toString = function toString (base, padding) {
|
|
base = base || 10;
|
|
padding = padding | 0 || 1;
|
|
|
|
var out;
|
|
if (base === 16 || base === 'hex') {
|
|
out = '';
|
|
var off = 0;
|
|
var carry = 0;
|
|
for (var i = 0; i < this.length; i++) {
|
|
var w = this.words[i];
|
|
var word = (((w << off) | carry) & 0xffffff).toString(16);
|
|
carry = (w >>> (24 - off)) & 0xffffff;
|
|
if (carry !== 0 || i !== this.length - 1) {
|
|
out = zeros[6 - word.length] + word + out;
|
|
} else {
|
|
out = word + out;
|
|
}
|
|
off += 2;
|
|
if (off >= 26) {
|
|
off -= 26;
|
|
i--;
|
|
}
|
|
}
|
|
if (carry !== 0) {
|
|
out = carry.toString(16) + out;
|
|
}
|
|
while (out.length % padding !== 0) {
|
|
out = '0' + out;
|
|
}
|
|
if (this.negative !== 0) {
|
|
out = '-' + out;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
if (base === (base | 0) && base >= 2 && base <= 36) {
|
|
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
|
|
var groupSize = groupSizes[base];
|
|
// var groupBase = Math.pow(base, groupSize);
|
|
var groupBase = groupBases[base];
|
|
out = '';
|
|
var c = this.clone();
|
|
c.negative = 0;
|
|
while (!c.isZero()) {
|
|
var r = c.modn(groupBase).toString(base);
|
|
c = c.idivn(groupBase);
|
|
|
|
if (!c.isZero()) {
|
|
out = zeros[groupSize - r.length] + r + out;
|
|
} else {
|
|
out = r + out;
|
|
}
|
|
}
|
|
if (this.isZero()) {
|
|
out = '0' + out;
|
|
}
|
|
while (out.length % padding !== 0) {
|
|
out = '0' + out;
|
|
}
|
|
if (this.negative !== 0) {
|
|
out = '-' + out;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
assert(false, 'Base should be between 2 and 36');
|
|
};
|
|
|
|
BN.prototype.toNumber = function toNumber () {
|
|
var ret = this.words[0];
|
|
if (this.length === 2) {
|
|
ret += this.words[1] * 0x4000000;
|
|
} else if (this.length === 3 && this.words[2] === 0x01) {
|
|
// NOTE: at this stage it is known that the top bit is set
|
|
ret += 0x10000000000000 + (this.words[1] * 0x4000000);
|
|
} else if (this.length > 2) {
|
|
assert(false, 'Number can only safely store up to 53 bits');
|
|
}
|
|
return (this.negative !== 0) ? -ret : ret;
|
|
};
|
|
|
|
BN.prototype.toJSON = function toJSON () {
|
|
return this.toString(16);
|
|
};
|
|
|
|
BN.prototype.toBuffer = function toBuffer (endian, length) {
|
|
assert(typeof Buffer !== 'undefined');
|
|
return this.toArrayLike(Buffer, endian, length);
|
|
};
|
|
|
|
BN.prototype.toArray = function toArray (endian, length) {
|
|
return this.toArrayLike(Array, endian, length);
|
|
};
|
|
|
|
BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
|
|
var byteLength = this.byteLength();
|
|
var reqLength = length || Math.max(1, byteLength);
|
|
assert(byteLength <= reqLength, 'byte array longer than desired length');
|
|
assert(reqLength > 0, 'Requested array length <= 0');
|
|
|
|
this.strip();
|
|
var littleEndian = endian === 'le';
|
|
var res = new ArrayType(reqLength);
|
|
|
|
var b, i;
|
|
var q = this.clone();
|
|
if (!littleEndian) {
|
|
// Assume big-endian
|
|
for (i = 0; i < reqLength - byteLength; i++) {
|
|
res[i] = 0;
|
|
}
|
|
|
|
for (i = 0; !q.isZero(); i++) {
|
|
b = q.andln(0xff);
|
|
q.iushrn(8);
|
|
|
|
res[reqLength - i - 1] = b;
|
|
}
|
|
} else {
|
|
for (i = 0; !q.isZero(); i++) {
|
|
b = q.andln(0xff);
|
|
q.iushrn(8);
|
|
|
|
res[i] = b;
|
|
}
|
|
|
|
for (; i < reqLength; i++) {
|
|
res[i] = 0;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
if (Math.clz32) {
|
|
BN.prototype._countBits = function _countBits (w) {
|
|
return 32 - Math.clz32(w);
|
|
};
|
|
} else {
|
|
BN.prototype._countBits = function _countBits (w) {
|
|
var t = w;
|
|
var r = 0;
|
|
if (t >= 0x1000) {
|
|
r += 13;
|
|
t >>>= 13;
|
|
}
|
|
if (t >= 0x40) {
|
|
r += 7;
|
|
t >>>= 7;
|
|
}
|
|
if (t >= 0x8) {
|
|
r += 4;
|
|
t >>>= 4;
|
|
}
|
|
if (t >= 0x02) {
|
|
r += 2;
|
|
t >>>= 2;
|
|
}
|
|
return r + t;
|
|
};
|
|
}
|
|
|
|
BN.prototype._zeroBits = function _zeroBits (w) {
|
|
// Short-cut
|
|
if (w === 0) return 26;
|
|
|
|
var t = w;
|
|
var r = 0;
|
|
if ((t & 0x1fff) === 0) {
|
|
r += 13;
|
|
t >>>= 13;
|
|
}
|
|
if ((t & 0x7f) === 0) {
|
|
r += 7;
|
|
t >>>= 7;
|
|
}
|
|
if ((t & 0xf) === 0) {
|
|
r += 4;
|
|
t >>>= 4;
|
|
}
|
|
if ((t & 0x3) === 0) {
|
|
r += 2;
|
|
t >>>= 2;
|
|
}
|
|
if ((t & 0x1) === 0) {
|
|
r++;
|
|
}
|
|
return r;
|
|
};
|
|
|
|
// Return number of used bits in a BN
|
|
BN.prototype.bitLength = function bitLength () {
|
|
var w = this.words[this.length - 1];
|
|
var hi = this._countBits(w);
|
|
return (this.length - 1) * 26 + hi;
|
|
};
|
|
|
|
function toBitArray (num) {
|
|
var w = new Array(num.bitLength());
|
|
|
|
for (var bit = 0; bit < w.length; bit++) {
|
|
var off = (bit / 26) | 0;
|
|
var wbit = bit % 26;
|
|
|
|
w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
|
|
}
|
|
|
|
return w;
|
|
}
|
|
|
|
// Number of trailing zero bits
|
|
BN.prototype.zeroBits = function zeroBits () {
|
|
if (this.isZero()) return 0;
|
|
|
|
var r = 0;
|
|
for (var i = 0; i < this.length; i++) {
|
|
var b = this._zeroBits(this.words[i]);
|
|
r += b;
|
|
if (b !== 26) break;
|
|
}
|
|
return r;
|
|
};
|
|
|
|
BN.prototype.byteLength = function byteLength () {
|
|
return Math.ceil(this.bitLength() / 8);
|
|
};
|
|
|
|
BN.prototype.toTwos = function toTwos (width) {
|
|
if (this.negative !== 0) {
|
|
return this.abs().inotn(width).iaddn(1);
|
|
}
|
|
return this.clone();
|
|
};
|
|
|
|
BN.prototype.fromTwos = function fromTwos (width) {
|
|
if (this.testn(width - 1)) {
|
|
return this.notn(width).iaddn(1).ineg();
|
|
}
|
|
return this.clone();
|
|
};
|
|
|
|
BN.prototype.isNeg = function isNeg () {
|
|
return this.negative !== 0;
|
|
};
|
|
|
|
// Return negative clone of `this`
|
|
BN.prototype.neg = function neg () {
|
|
return this.clone().ineg();
|
|
};
|
|
|
|
BN.prototype.ineg = function ineg () {
|
|
if (!this.isZero()) {
|
|
this.negative ^= 1;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
// Or `num` with `this` in-place
|
|
BN.prototype.iuor = function iuor (num) {
|
|
while (this.length < num.length) {
|
|
this.words[this.length++] = 0;
|
|
}
|
|
|
|
for (var i = 0; i < num.length; i++) {
|
|
this.words[i] = this.words[i] | num.words[i];
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.ior = function ior (num) {
|
|
assert((this.negative | num.negative) === 0);
|
|
return this.iuor(num);
|
|
};
|
|
|
|
// Or `num` with `this`
|
|
BN.prototype.or = function or (num) {
|
|
if (this.length > num.length) return this.clone().ior(num);
|
|
return num.clone().ior(this);
|
|
};
|
|
|
|
BN.prototype.uor = function uor (num) {
|
|
if (this.length > num.length) return this.clone().iuor(num);
|
|
return num.clone().iuor(this);
|
|
};
|
|
|
|
// And `num` with `this` in-place
|
|
BN.prototype.iuand = function iuand (num) {
|
|
// b = min-length(num, this)
|
|
var b;
|
|
if (this.length > num.length) {
|
|
b = num;
|
|
} else {
|
|
b = this;
|
|
}
|
|
|
|
for (var i = 0; i < b.length; i++) {
|
|
this.words[i] = this.words[i] & num.words[i];
|
|
}
|
|
|
|
this.length = b.length;
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.iand = function iand (num) {
|
|
assert((this.negative | num.negative) === 0);
|
|
return this.iuand(num);
|
|
};
|
|
|
|
// And `num` with `this`
|
|
BN.prototype.and = function and (num) {
|
|
if (this.length > num.length) return this.clone().iand(num);
|
|
return num.clone().iand(this);
|
|
};
|
|
|
|
BN.prototype.uand = function uand (num) {
|
|
if (this.length > num.length) return this.clone().iuand(num);
|
|
return num.clone().iuand(this);
|
|
};
|
|
|
|
// Xor `num` with `this` in-place
|
|
BN.prototype.iuxor = function iuxor (num) {
|
|
// a.length > b.length
|
|
var a;
|
|
var b;
|
|
if (this.length > num.length) {
|
|
a = this;
|
|
b = num;
|
|
} else {
|
|
a = num;
|
|
b = this;
|
|
}
|
|
|
|
for (var i = 0; i < b.length; i++) {
|
|
this.words[i] = a.words[i] ^ b.words[i];
|
|
}
|
|
|
|
if (this !== a) {
|
|
for (; i < a.length; i++) {
|
|
this.words[i] = a.words[i];
|
|
}
|
|
}
|
|
|
|
this.length = a.length;
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.ixor = function ixor (num) {
|
|
assert((this.negative | num.negative) === 0);
|
|
return this.iuxor(num);
|
|
};
|
|
|
|
// Xor `num` with `this`
|
|
BN.prototype.xor = function xor (num) {
|
|
if (this.length > num.length) return this.clone().ixor(num);
|
|
return num.clone().ixor(this);
|
|
};
|
|
|
|
BN.prototype.uxor = function uxor (num) {
|
|
if (this.length > num.length) return this.clone().iuxor(num);
|
|
return num.clone().iuxor(this);
|
|
};
|
|
|
|
// Not ``this`` with ``width`` bitwidth
|
|
BN.prototype.inotn = function inotn (width) {
|
|
assert(typeof width === 'number' && width >= 0);
|
|
|
|
var bytesNeeded = Math.ceil(width / 26) | 0;
|
|
var bitsLeft = width % 26;
|
|
|
|
// Extend the buffer with leading zeroes
|
|
this._expand(bytesNeeded);
|
|
|
|
if (bitsLeft > 0) {
|
|
bytesNeeded--;
|
|
}
|
|
|
|
// Handle complete words
|
|
for (var i = 0; i < bytesNeeded; i++) {
|
|
this.words[i] = ~this.words[i] & 0x3ffffff;
|
|
}
|
|
|
|
// Handle the residue
|
|
if (bitsLeft > 0) {
|
|
this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
|
|
}
|
|
|
|
// And remove leading zeroes
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.notn = function notn (width) {
|
|
return this.clone().inotn(width);
|
|
};
|
|
|
|
// Set `bit` of `this`
|
|
BN.prototype.setn = function setn (bit, val) {
|
|
assert(typeof bit === 'number' && bit >= 0);
|
|
|
|
var off = (bit / 26) | 0;
|
|
var wbit = bit % 26;
|
|
|
|
this._expand(off + 1);
|
|
|
|
if (val) {
|
|
this.words[off] = this.words[off] | (1 << wbit);
|
|
} else {
|
|
this.words[off] = this.words[off] & ~(1 << wbit);
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
// Add `num` to `this` in-place
|
|
BN.prototype.iadd = function iadd (num) {
|
|
var r;
|
|
|
|
// negative + positive
|
|
if (this.negative !== 0 && num.negative === 0) {
|
|
this.negative = 0;
|
|
r = this.isub(num);
|
|
this.negative ^= 1;
|
|
return this._normSign();
|
|
|
|
// positive + negative
|
|
} else if (this.negative === 0 && num.negative !== 0) {
|
|
num.negative = 0;
|
|
r = this.isub(num);
|
|
num.negative = 1;
|
|
return r._normSign();
|
|
}
|
|
|
|
// a.length > b.length
|
|
var a, b;
|
|
if (this.length > num.length) {
|
|
a = this;
|
|
b = num;
|
|
} else {
|
|
a = num;
|
|
b = this;
|
|
}
|
|
|
|
var carry = 0;
|
|
for (var i = 0; i < b.length; i++) {
|
|
r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
|
|
this.words[i] = r & 0x3ffffff;
|
|
carry = r >>> 26;
|
|
}
|
|
for (; carry !== 0 && i < a.length; i++) {
|
|
r = (a.words[i] | 0) + carry;
|
|
this.words[i] = r & 0x3ffffff;
|
|
carry = r >>> 26;
|
|
}
|
|
|
|
this.length = a.length;
|
|
if (carry !== 0) {
|
|
this.words[this.length] = carry;
|
|
this.length++;
|
|
// Copy the rest of the words
|
|
} else if (a !== this) {
|
|
for (; i < a.length; i++) {
|
|
this.words[i] = a.words[i];
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
// Add `num` to `this`
|
|
BN.prototype.add = function add (num) {
|
|
var res;
|
|
if (num.negative !== 0 && this.negative === 0) {
|
|
num.negative = 0;
|
|
res = this.sub(num);
|
|
num.negative ^= 1;
|
|
return res;
|
|
} else if (num.negative === 0 && this.negative !== 0) {
|
|
this.negative = 0;
|
|
res = num.sub(this);
|
|
this.negative = 1;
|
|
return res;
|
|
}
|
|
|
|
if (this.length > num.length) return this.clone().iadd(num);
|
|
|
|
return num.clone().iadd(this);
|
|
};
|
|
|
|
// Subtract `num` from `this` in-place
|
|
BN.prototype.isub = function isub (num) {
|
|
// this - (-num) = this + num
|
|
if (num.negative !== 0) {
|
|
num.negative = 0;
|
|
var r = this.iadd(num);
|
|
num.negative = 1;
|
|
return r._normSign();
|
|
|
|
// -this - num = -(this + num)
|
|
} else if (this.negative !== 0) {
|
|
this.negative = 0;
|
|
this.iadd(num);
|
|
this.negative = 1;
|
|
return this._normSign();
|
|
}
|
|
|
|
// At this point both numbers are positive
|
|
var cmp = this.cmp(num);
|
|
|
|
// Optimization - zeroify
|
|
if (cmp === 0) {
|
|
this.negative = 0;
|
|
this.length = 1;
|
|
this.words[0] = 0;
|
|
return this;
|
|
}
|
|
|
|
// a > b
|
|
var a, b;
|
|
if (cmp > 0) {
|
|
a = this;
|
|
b = num;
|
|
} else {
|
|
a = num;
|
|
b = this;
|
|
}
|
|
|
|
var carry = 0;
|
|
for (var i = 0; i < b.length; i++) {
|
|
r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
|
|
carry = r >> 26;
|
|
this.words[i] = r & 0x3ffffff;
|
|
}
|
|
for (; carry !== 0 && i < a.length; i++) {
|
|
r = (a.words[i] | 0) + carry;
|
|
carry = r >> 26;
|
|
this.words[i] = r & 0x3ffffff;
|
|
}
|
|
|
|
// Copy rest of the words
|
|
if (carry === 0 && i < a.length && a !== this) {
|
|
for (; i < a.length; i++) {
|
|
this.words[i] = a.words[i];
|
|
}
|
|
}
|
|
|
|
this.length = Math.max(this.length, i);
|
|
|
|
if (a !== this) {
|
|
this.negative = 1;
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
// Subtract `num` from `this`
|
|
BN.prototype.sub = function sub (num) {
|
|
return this.clone().isub(num);
|
|
};
|
|
|
|
function smallMulTo (self, num, out) {
|
|
out.negative = num.negative ^ self.negative;
|
|
var len = (self.length + num.length) | 0;
|
|
out.length = len;
|
|
len = (len - 1) | 0;
|
|
|
|
// Peel one iteration (compiler can't do it, because of code complexity)
|
|
var a = self.words[0] | 0;
|
|
var b = num.words[0] | 0;
|
|
var r = a * b;
|
|
|
|
var lo = r & 0x3ffffff;
|
|
var carry = (r / 0x4000000) | 0;
|
|
out.words[0] = lo;
|
|
|
|
for (var k = 1; k < len; k++) {
|
|
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
|
// note that ncarry could be >= 0x3ffffff
|
|
var ncarry = carry >>> 26;
|
|
var rword = carry & 0x3ffffff;
|
|
var maxJ = Math.min(k, num.length - 1);
|
|
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
|
var i = (k - j) | 0;
|
|
a = self.words[i] | 0;
|
|
b = num.words[j] | 0;
|
|
r = a * b + rword;
|
|
ncarry += (r / 0x4000000) | 0;
|
|
rword = r & 0x3ffffff;
|
|
}
|
|
out.words[k] = rword | 0;
|
|
carry = ncarry | 0;
|
|
}
|
|
if (carry !== 0) {
|
|
out.words[k] = carry | 0;
|
|
} else {
|
|
out.length--;
|
|
}
|
|
|
|
return out.strip();
|
|
}
|
|
|
|
// TODO(indutny): it may be reasonable to omit it for users who don't need
|
|
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
|
|
// multiplication (like elliptic secp256k1).
|
|
var comb10MulTo = function comb10MulTo (self, num, out) {
|
|
var a = self.words;
|
|
var b = num.words;
|
|
var o = out.words;
|
|
var c = 0;
|
|
var lo;
|
|
var mid;
|
|
var hi;
|
|
var a0 = a[0] | 0;
|
|
var al0 = a0 & 0x1fff;
|
|
var ah0 = a0 >>> 13;
|
|
var a1 = a[1] | 0;
|
|
var al1 = a1 & 0x1fff;
|
|
var ah1 = a1 >>> 13;
|
|
var a2 = a[2] | 0;
|
|
var al2 = a2 & 0x1fff;
|
|
var ah2 = a2 >>> 13;
|
|
var a3 = a[3] | 0;
|
|
var al3 = a3 & 0x1fff;
|
|
var ah3 = a3 >>> 13;
|
|
var a4 = a[4] | 0;
|
|
var al4 = a4 & 0x1fff;
|
|
var ah4 = a4 >>> 13;
|
|
var a5 = a[5] | 0;
|
|
var al5 = a5 & 0x1fff;
|
|
var ah5 = a5 >>> 13;
|
|
var a6 = a[6] | 0;
|
|
var al6 = a6 & 0x1fff;
|
|
var ah6 = a6 >>> 13;
|
|
var a7 = a[7] | 0;
|
|
var al7 = a7 & 0x1fff;
|
|
var ah7 = a7 >>> 13;
|
|
var a8 = a[8] | 0;
|
|
var al8 = a8 & 0x1fff;
|
|
var ah8 = a8 >>> 13;
|
|
var a9 = a[9] | 0;
|
|
var al9 = a9 & 0x1fff;
|
|
var ah9 = a9 >>> 13;
|
|
var b0 = b[0] | 0;
|
|
var bl0 = b0 & 0x1fff;
|
|
var bh0 = b0 >>> 13;
|
|
var b1 = b[1] | 0;
|
|
var bl1 = b1 & 0x1fff;
|
|
var bh1 = b1 >>> 13;
|
|
var b2 = b[2] | 0;
|
|
var bl2 = b2 & 0x1fff;
|
|
var bh2 = b2 >>> 13;
|
|
var b3 = b[3] | 0;
|
|
var bl3 = b3 & 0x1fff;
|
|
var bh3 = b3 >>> 13;
|
|
var b4 = b[4] | 0;
|
|
var bl4 = b4 & 0x1fff;
|
|
var bh4 = b4 >>> 13;
|
|
var b5 = b[5] | 0;
|
|
var bl5 = b5 & 0x1fff;
|
|
var bh5 = b5 >>> 13;
|
|
var b6 = b[6] | 0;
|
|
var bl6 = b6 & 0x1fff;
|
|
var bh6 = b6 >>> 13;
|
|
var b7 = b[7] | 0;
|
|
var bl7 = b7 & 0x1fff;
|
|
var bh7 = b7 >>> 13;
|
|
var b8 = b[8] | 0;
|
|
var bl8 = b8 & 0x1fff;
|
|
var bh8 = b8 >>> 13;
|
|
var b9 = b[9] | 0;
|
|
var bl9 = b9 & 0x1fff;
|
|
var bh9 = b9 >>> 13;
|
|
|
|
out.negative = self.negative ^ num.negative;
|
|
out.length = 19;
|
|
/* k = 0 */
|
|
lo = Math.imul(al0, bl0);
|
|
mid = Math.imul(al0, bh0);
|
|
mid = (mid + Math.imul(ah0, bl0)) | 0;
|
|
hi = Math.imul(ah0, bh0);
|
|
var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
|
|
w0 &= 0x3ffffff;
|
|
/* k = 1 */
|
|
lo = Math.imul(al1, bl0);
|
|
mid = Math.imul(al1, bh0);
|
|
mid = (mid + Math.imul(ah1, bl0)) | 0;
|
|
hi = Math.imul(ah1, bh0);
|
|
lo = (lo + Math.imul(al0, bl1)) | 0;
|
|
mid = (mid + Math.imul(al0, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh1)) | 0;
|
|
var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
|
|
w1 &= 0x3ffffff;
|
|
/* k = 2 */
|
|
lo = Math.imul(al2, bl0);
|
|
mid = Math.imul(al2, bh0);
|
|
mid = (mid + Math.imul(ah2, bl0)) | 0;
|
|
hi = Math.imul(ah2, bh0);
|
|
lo = (lo + Math.imul(al1, bl1)) | 0;
|
|
mid = (mid + Math.imul(al1, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh1)) | 0;
|
|
lo = (lo + Math.imul(al0, bl2)) | 0;
|
|
mid = (mid + Math.imul(al0, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh2)) | 0;
|
|
var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
|
|
w2 &= 0x3ffffff;
|
|
/* k = 3 */
|
|
lo = Math.imul(al3, bl0);
|
|
mid = Math.imul(al3, bh0);
|
|
mid = (mid + Math.imul(ah3, bl0)) | 0;
|
|
hi = Math.imul(ah3, bh0);
|
|
lo = (lo + Math.imul(al2, bl1)) | 0;
|
|
mid = (mid + Math.imul(al2, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh1)) | 0;
|
|
lo = (lo + Math.imul(al1, bl2)) | 0;
|
|
mid = (mid + Math.imul(al1, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh2)) | 0;
|
|
lo = (lo + Math.imul(al0, bl3)) | 0;
|
|
mid = (mid + Math.imul(al0, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh3)) | 0;
|
|
var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
|
|
w3 &= 0x3ffffff;
|
|
/* k = 4 */
|
|
lo = Math.imul(al4, bl0);
|
|
mid = Math.imul(al4, bh0);
|
|
mid = (mid + Math.imul(ah4, bl0)) | 0;
|
|
hi = Math.imul(ah4, bh0);
|
|
lo = (lo + Math.imul(al3, bl1)) | 0;
|
|
mid = (mid + Math.imul(al3, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh1)) | 0;
|
|
lo = (lo + Math.imul(al2, bl2)) | 0;
|
|
mid = (mid + Math.imul(al2, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh2)) | 0;
|
|
lo = (lo + Math.imul(al1, bl3)) | 0;
|
|
mid = (mid + Math.imul(al1, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh3)) | 0;
|
|
lo = (lo + Math.imul(al0, bl4)) | 0;
|
|
mid = (mid + Math.imul(al0, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh4)) | 0;
|
|
var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
|
|
w4 &= 0x3ffffff;
|
|
/* k = 5 */
|
|
lo = Math.imul(al5, bl0);
|
|
mid = Math.imul(al5, bh0);
|
|
mid = (mid + Math.imul(ah5, bl0)) | 0;
|
|
hi = Math.imul(ah5, bh0);
|
|
lo = (lo + Math.imul(al4, bl1)) | 0;
|
|
mid = (mid + Math.imul(al4, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh1)) | 0;
|
|
lo = (lo + Math.imul(al3, bl2)) | 0;
|
|
mid = (mid + Math.imul(al3, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh2)) | 0;
|
|
lo = (lo + Math.imul(al2, bl3)) | 0;
|
|
mid = (mid + Math.imul(al2, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh3)) | 0;
|
|
lo = (lo + Math.imul(al1, bl4)) | 0;
|
|
mid = (mid + Math.imul(al1, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh4)) | 0;
|
|
lo = (lo + Math.imul(al0, bl5)) | 0;
|
|
mid = (mid + Math.imul(al0, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh5)) | 0;
|
|
var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
|
|
w5 &= 0x3ffffff;
|
|
/* k = 6 */
|
|
lo = Math.imul(al6, bl0);
|
|
mid = Math.imul(al6, bh0);
|
|
mid = (mid + Math.imul(ah6, bl0)) | 0;
|
|
hi = Math.imul(ah6, bh0);
|
|
lo = (lo + Math.imul(al5, bl1)) | 0;
|
|
mid = (mid + Math.imul(al5, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh1)) | 0;
|
|
lo = (lo + Math.imul(al4, bl2)) | 0;
|
|
mid = (mid + Math.imul(al4, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh2)) | 0;
|
|
lo = (lo + Math.imul(al3, bl3)) | 0;
|
|
mid = (mid + Math.imul(al3, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh3)) | 0;
|
|
lo = (lo + Math.imul(al2, bl4)) | 0;
|
|
mid = (mid + Math.imul(al2, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh4)) | 0;
|
|
lo = (lo + Math.imul(al1, bl5)) | 0;
|
|
mid = (mid + Math.imul(al1, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh5)) | 0;
|
|
lo = (lo + Math.imul(al0, bl6)) | 0;
|
|
mid = (mid + Math.imul(al0, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh6)) | 0;
|
|
var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
|
|
w6 &= 0x3ffffff;
|
|
/* k = 7 */
|
|
lo = Math.imul(al7, bl0);
|
|
mid = Math.imul(al7, bh0);
|
|
mid = (mid + Math.imul(ah7, bl0)) | 0;
|
|
hi = Math.imul(ah7, bh0);
|
|
lo = (lo + Math.imul(al6, bl1)) | 0;
|
|
mid = (mid + Math.imul(al6, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh1)) | 0;
|
|
lo = (lo + Math.imul(al5, bl2)) | 0;
|
|
mid = (mid + Math.imul(al5, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh2)) | 0;
|
|
lo = (lo + Math.imul(al4, bl3)) | 0;
|
|
mid = (mid + Math.imul(al4, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh3)) | 0;
|
|
lo = (lo + Math.imul(al3, bl4)) | 0;
|
|
mid = (mid + Math.imul(al3, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh4)) | 0;
|
|
lo = (lo + Math.imul(al2, bl5)) | 0;
|
|
mid = (mid + Math.imul(al2, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh5)) | 0;
|
|
lo = (lo + Math.imul(al1, bl6)) | 0;
|
|
mid = (mid + Math.imul(al1, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh6)) | 0;
|
|
lo = (lo + Math.imul(al0, bl7)) | 0;
|
|
mid = (mid + Math.imul(al0, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh7)) | 0;
|
|
var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
|
|
w7 &= 0x3ffffff;
|
|
/* k = 8 */
|
|
lo = Math.imul(al8, bl0);
|
|
mid = Math.imul(al8, bh0);
|
|
mid = (mid + Math.imul(ah8, bl0)) | 0;
|
|
hi = Math.imul(ah8, bh0);
|
|
lo = (lo + Math.imul(al7, bl1)) | 0;
|
|
mid = (mid + Math.imul(al7, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh1)) | 0;
|
|
lo = (lo + Math.imul(al6, bl2)) | 0;
|
|
mid = (mid + Math.imul(al6, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh2)) | 0;
|
|
lo = (lo + Math.imul(al5, bl3)) | 0;
|
|
mid = (mid + Math.imul(al5, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh3)) | 0;
|
|
lo = (lo + Math.imul(al4, bl4)) | 0;
|
|
mid = (mid + Math.imul(al4, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh4)) | 0;
|
|
lo = (lo + Math.imul(al3, bl5)) | 0;
|
|
mid = (mid + Math.imul(al3, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh5)) | 0;
|
|
lo = (lo + Math.imul(al2, bl6)) | 0;
|
|
mid = (mid + Math.imul(al2, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh6)) | 0;
|
|
lo = (lo + Math.imul(al1, bl7)) | 0;
|
|
mid = (mid + Math.imul(al1, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh7)) | 0;
|
|
lo = (lo + Math.imul(al0, bl8)) | 0;
|
|
mid = (mid + Math.imul(al0, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh8)) | 0;
|
|
var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
|
|
w8 &= 0x3ffffff;
|
|
/* k = 9 */
|
|
lo = Math.imul(al9, bl0);
|
|
mid = Math.imul(al9, bh0);
|
|
mid = (mid + Math.imul(ah9, bl0)) | 0;
|
|
hi = Math.imul(ah9, bh0);
|
|
lo = (lo + Math.imul(al8, bl1)) | 0;
|
|
mid = (mid + Math.imul(al8, bh1)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl1)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh1)) | 0;
|
|
lo = (lo + Math.imul(al7, bl2)) | 0;
|
|
mid = (mid + Math.imul(al7, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh2)) | 0;
|
|
lo = (lo + Math.imul(al6, bl3)) | 0;
|
|
mid = (mid + Math.imul(al6, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh3)) | 0;
|
|
lo = (lo + Math.imul(al5, bl4)) | 0;
|
|
mid = (mid + Math.imul(al5, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh4)) | 0;
|
|
lo = (lo + Math.imul(al4, bl5)) | 0;
|
|
mid = (mid + Math.imul(al4, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh5)) | 0;
|
|
lo = (lo + Math.imul(al3, bl6)) | 0;
|
|
mid = (mid + Math.imul(al3, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh6)) | 0;
|
|
lo = (lo + Math.imul(al2, bl7)) | 0;
|
|
mid = (mid + Math.imul(al2, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh7)) | 0;
|
|
lo = (lo + Math.imul(al1, bl8)) | 0;
|
|
mid = (mid + Math.imul(al1, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh8)) | 0;
|
|
lo = (lo + Math.imul(al0, bl9)) | 0;
|
|
mid = (mid + Math.imul(al0, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah0, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah0, bh9)) | 0;
|
|
var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
|
|
w9 &= 0x3ffffff;
|
|
/* k = 10 */
|
|
lo = Math.imul(al9, bl1);
|
|
mid = Math.imul(al9, bh1);
|
|
mid = (mid + Math.imul(ah9, bl1)) | 0;
|
|
hi = Math.imul(ah9, bh1);
|
|
lo = (lo + Math.imul(al8, bl2)) | 0;
|
|
mid = (mid + Math.imul(al8, bh2)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl2)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh2)) | 0;
|
|
lo = (lo + Math.imul(al7, bl3)) | 0;
|
|
mid = (mid + Math.imul(al7, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh3)) | 0;
|
|
lo = (lo + Math.imul(al6, bl4)) | 0;
|
|
mid = (mid + Math.imul(al6, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh4)) | 0;
|
|
lo = (lo + Math.imul(al5, bl5)) | 0;
|
|
mid = (mid + Math.imul(al5, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh5)) | 0;
|
|
lo = (lo + Math.imul(al4, bl6)) | 0;
|
|
mid = (mid + Math.imul(al4, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh6)) | 0;
|
|
lo = (lo + Math.imul(al3, bl7)) | 0;
|
|
mid = (mid + Math.imul(al3, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh7)) | 0;
|
|
lo = (lo + Math.imul(al2, bl8)) | 0;
|
|
mid = (mid + Math.imul(al2, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh8)) | 0;
|
|
lo = (lo + Math.imul(al1, bl9)) | 0;
|
|
mid = (mid + Math.imul(al1, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah1, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah1, bh9)) | 0;
|
|
var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
|
|
w10 &= 0x3ffffff;
|
|
/* k = 11 */
|
|
lo = Math.imul(al9, bl2);
|
|
mid = Math.imul(al9, bh2);
|
|
mid = (mid + Math.imul(ah9, bl2)) | 0;
|
|
hi = Math.imul(ah9, bh2);
|
|
lo = (lo + Math.imul(al8, bl3)) | 0;
|
|
mid = (mid + Math.imul(al8, bh3)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl3)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh3)) | 0;
|
|
lo = (lo + Math.imul(al7, bl4)) | 0;
|
|
mid = (mid + Math.imul(al7, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh4)) | 0;
|
|
lo = (lo + Math.imul(al6, bl5)) | 0;
|
|
mid = (mid + Math.imul(al6, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh5)) | 0;
|
|
lo = (lo + Math.imul(al5, bl6)) | 0;
|
|
mid = (mid + Math.imul(al5, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh6)) | 0;
|
|
lo = (lo + Math.imul(al4, bl7)) | 0;
|
|
mid = (mid + Math.imul(al4, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh7)) | 0;
|
|
lo = (lo + Math.imul(al3, bl8)) | 0;
|
|
mid = (mid + Math.imul(al3, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh8)) | 0;
|
|
lo = (lo + Math.imul(al2, bl9)) | 0;
|
|
mid = (mid + Math.imul(al2, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah2, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah2, bh9)) | 0;
|
|
var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
|
|
w11 &= 0x3ffffff;
|
|
/* k = 12 */
|
|
lo = Math.imul(al9, bl3);
|
|
mid = Math.imul(al9, bh3);
|
|
mid = (mid + Math.imul(ah9, bl3)) | 0;
|
|
hi = Math.imul(ah9, bh3);
|
|
lo = (lo + Math.imul(al8, bl4)) | 0;
|
|
mid = (mid + Math.imul(al8, bh4)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl4)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh4)) | 0;
|
|
lo = (lo + Math.imul(al7, bl5)) | 0;
|
|
mid = (mid + Math.imul(al7, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh5)) | 0;
|
|
lo = (lo + Math.imul(al6, bl6)) | 0;
|
|
mid = (mid + Math.imul(al6, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh6)) | 0;
|
|
lo = (lo + Math.imul(al5, bl7)) | 0;
|
|
mid = (mid + Math.imul(al5, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh7)) | 0;
|
|
lo = (lo + Math.imul(al4, bl8)) | 0;
|
|
mid = (mid + Math.imul(al4, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh8)) | 0;
|
|
lo = (lo + Math.imul(al3, bl9)) | 0;
|
|
mid = (mid + Math.imul(al3, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah3, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah3, bh9)) | 0;
|
|
var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
|
|
w12 &= 0x3ffffff;
|
|
/* k = 13 */
|
|
lo = Math.imul(al9, bl4);
|
|
mid = Math.imul(al9, bh4);
|
|
mid = (mid + Math.imul(ah9, bl4)) | 0;
|
|
hi = Math.imul(ah9, bh4);
|
|
lo = (lo + Math.imul(al8, bl5)) | 0;
|
|
mid = (mid + Math.imul(al8, bh5)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl5)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh5)) | 0;
|
|
lo = (lo + Math.imul(al7, bl6)) | 0;
|
|
mid = (mid + Math.imul(al7, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh6)) | 0;
|
|
lo = (lo + Math.imul(al6, bl7)) | 0;
|
|
mid = (mid + Math.imul(al6, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh7)) | 0;
|
|
lo = (lo + Math.imul(al5, bl8)) | 0;
|
|
mid = (mid + Math.imul(al5, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh8)) | 0;
|
|
lo = (lo + Math.imul(al4, bl9)) | 0;
|
|
mid = (mid + Math.imul(al4, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah4, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah4, bh9)) | 0;
|
|
var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
|
|
w13 &= 0x3ffffff;
|
|
/* k = 14 */
|
|
lo = Math.imul(al9, bl5);
|
|
mid = Math.imul(al9, bh5);
|
|
mid = (mid + Math.imul(ah9, bl5)) | 0;
|
|
hi = Math.imul(ah9, bh5);
|
|
lo = (lo + Math.imul(al8, bl6)) | 0;
|
|
mid = (mid + Math.imul(al8, bh6)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl6)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh6)) | 0;
|
|
lo = (lo + Math.imul(al7, bl7)) | 0;
|
|
mid = (mid + Math.imul(al7, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh7)) | 0;
|
|
lo = (lo + Math.imul(al6, bl8)) | 0;
|
|
mid = (mid + Math.imul(al6, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh8)) | 0;
|
|
lo = (lo + Math.imul(al5, bl9)) | 0;
|
|
mid = (mid + Math.imul(al5, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah5, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah5, bh9)) | 0;
|
|
var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
|
|
w14 &= 0x3ffffff;
|
|
/* k = 15 */
|
|
lo = Math.imul(al9, bl6);
|
|
mid = Math.imul(al9, bh6);
|
|
mid = (mid + Math.imul(ah9, bl6)) | 0;
|
|
hi = Math.imul(ah9, bh6);
|
|
lo = (lo + Math.imul(al8, bl7)) | 0;
|
|
mid = (mid + Math.imul(al8, bh7)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl7)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh7)) | 0;
|
|
lo = (lo + Math.imul(al7, bl8)) | 0;
|
|
mid = (mid + Math.imul(al7, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh8)) | 0;
|
|
lo = (lo + Math.imul(al6, bl9)) | 0;
|
|
mid = (mid + Math.imul(al6, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah6, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah6, bh9)) | 0;
|
|
var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
|
|
w15 &= 0x3ffffff;
|
|
/* k = 16 */
|
|
lo = Math.imul(al9, bl7);
|
|
mid = Math.imul(al9, bh7);
|
|
mid = (mid + Math.imul(ah9, bl7)) | 0;
|
|
hi = Math.imul(ah9, bh7);
|
|
lo = (lo + Math.imul(al8, bl8)) | 0;
|
|
mid = (mid + Math.imul(al8, bh8)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl8)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh8)) | 0;
|
|
lo = (lo + Math.imul(al7, bl9)) | 0;
|
|
mid = (mid + Math.imul(al7, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah7, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah7, bh9)) | 0;
|
|
var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
|
|
w16 &= 0x3ffffff;
|
|
/* k = 17 */
|
|
lo = Math.imul(al9, bl8);
|
|
mid = Math.imul(al9, bh8);
|
|
mid = (mid + Math.imul(ah9, bl8)) | 0;
|
|
hi = Math.imul(ah9, bh8);
|
|
lo = (lo + Math.imul(al8, bl9)) | 0;
|
|
mid = (mid + Math.imul(al8, bh9)) | 0;
|
|
mid = (mid + Math.imul(ah8, bl9)) | 0;
|
|
hi = (hi + Math.imul(ah8, bh9)) | 0;
|
|
var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
|
|
w17 &= 0x3ffffff;
|
|
/* k = 18 */
|
|
lo = Math.imul(al9, bl9);
|
|
mid = Math.imul(al9, bh9);
|
|
mid = (mid + Math.imul(ah9, bl9)) | 0;
|
|
hi = Math.imul(ah9, bh9);
|
|
var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
|
c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
|
|
w18 &= 0x3ffffff;
|
|
o[0] = w0;
|
|
o[1] = w1;
|
|
o[2] = w2;
|
|
o[3] = w3;
|
|
o[4] = w4;
|
|
o[5] = w5;
|
|
o[6] = w6;
|
|
o[7] = w7;
|
|
o[8] = w8;
|
|
o[9] = w9;
|
|
o[10] = w10;
|
|
o[11] = w11;
|
|
o[12] = w12;
|
|
o[13] = w13;
|
|
o[14] = w14;
|
|
o[15] = w15;
|
|
o[16] = w16;
|
|
o[17] = w17;
|
|
o[18] = w18;
|
|
if (c !== 0) {
|
|
o[19] = c;
|
|
out.length++;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
// Polyfill comb
|
|
if (!Math.imul) {
|
|
comb10MulTo = smallMulTo;
|
|
}
|
|
|
|
function bigMulTo (self, num, out) {
|
|
out.negative = num.negative ^ self.negative;
|
|
out.length = self.length + num.length;
|
|
|
|
var carry = 0;
|
|
var hncarry = 0;
|
|
for (var k = 0; k < out.length - 1; k++) {
|
|
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
|
// note that ncarry could be >= 0x3ffffff
|
|
var ncarry = hncarry;
|
|
hncarry = 0;
|
|
var rword = carry & 0x3ffffff;
|
|
var maxJ = Math.min(k, num.length - 1);
|
|
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
|
var i = k - j;
|
|
var a = self.words[i] | 0;
|
|
var b = num.words[j] | 0;
|
|
var r = a * b;
|
|
|
|
var lo = r & 0x3ffffff;
|
|
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
|
|
lo = (lo + rword) | 0;
|
|
rword = lo & 0x3ffffff;
|
|
ncarry = (ncarry + (lo >>> 26)) | 0;
|
|
|
|
hncarry += ncarry >>> 26;
|
|
ncarry &= 0x3ffffff;
|
|
}
|
|
out.words[k] = rword;
|
|
carry = ncarry;
|
|
ncarry = hncarry;
|
|
}
|
|
if (carry !== 0) {
|
|
out.words[k] = carry;
|
|
} else {
|
|
out.length--;
|
|
}
|
|
|
|
return out.strip();
|
|
}
|
|
|
|
function jumboMulTo (self, num, out) {
|
|
var fftm = new FFTM();
|
|
return fftm.mulp(self, num, out);
|
|
}
|
|
|
|
BN.prototype.mulTo = function mulTo (num, out) {
|
|
var res;
|
|
var len = this.length + num.length;
|
|
if (this.length === 10 && num.length === 10) {
|
|
res = comb10MulTo(this, num, out);
|
|
} else if (len < 63) {
|
|
res = smallMulTo(this, num, out);
|
|
} else if (len < 1024) {
|
|
res = bigMulTo(this, num, out);
|
|
} else {
|
|
res = jumboMulTo(this, num, out);
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
// Cooley-Tukey algorithm for FFT
|
|
// slightly revisited to rely on looping instead of recursion
|
|
|
|
function FFTM (x, y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
|
|
FFTM.prototype.makeRBT = function makeRBT (N) {
|
|
var t = new Array(N);
|
|
var l = BN.prototype._countBits(N) - 1;
|
|
for (var i = 0; i < N; i++) {
|
|
t[i] = this.revBin(i, l, N);
|
|
}
|
|
|
|
return t;
|
|
};
|
|
|
|
// Returns binary-reversed representation of `x`
|
|
FFTM.prototype.revBin = function revBin (x, l, N) {
|
|
if (x === 0 || x === N - 1) return x;
|
|
|
|
var rb = 0;
|
|
for (var i = 0; i < l; i++) {
|
|
rb |= (x & 1) << (l - i - 1);
|
|
x >>= 1;
|
|
}
|
|
|
|
return rb;
|
|
};
|
|
|
|
// Performs "tweedling" phase, therefore 'emulating'
|
|
// behaviour of the recursive algorithm
|
|
FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
|
|
for (var i = 0; i < N; i++) {
|
|
rtws[i] = rws[rbt[i]];
|
|
itws[i] = iws[rbt[i]];
|
|
}
|
|
};
|
|
|
|
FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
|
|
this.permute(rbt, rws, iws, rtws, itws, N);
|
|
|
|
for (var s = 1; s < N; s <<= 1) {
|
|
var l = s << 1;
|
|
|
|
var rtwdf = Math.cos(2 * Math.PI / l);
|
|
var itwdf = Math.sin(2 * Math.PI / l);
|
|
|
|
for (var p = 0; p < N; p += l) {
|
|
var rtwdf_ = rtwdf;
|
|
var itwdf_ = itwdf;
|
|
|
|
for (var j = 0; j < s; j++) {
|
|
var re = rtws[p + j];
|
|
var ie = itws[p + j];
|
|
|
|
var ro = rtws[p + j + s];
|
|
var io = itws[p + j + s];
|
|
|
|
var rx = rtwdf_ * ro - itwdf_ * io;
|
|
|
|
io = rtwdf_ * io + itwdf_ * ro;
|
|
ro = rx;
|
|
|
|
rtws[p + j] = re + ro;
|
|
itws[p + j] = ie + io;
|
|
|
|
rtws[p + j + s] = re - ro;
|
|
itws[p + j + s] = ie - io;
|
|
|
|
/* jshint maxdepth : false */
|
|
if (j !== l) {
|
|
rx = rtwdf * rtwdf_ - itwdf * itwdf_;
|
|
|
|
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
|
|
rtwdf_ = rx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
|
|
var N = Math.max(m, n) | 1;
|
|
var odd = N & 1;
|
|
var i = 0;
|
|
for (N = N / 2 | 0; N; N = N >>> 1) {
|
|
i++;
|
|
}
|
|
|
|
return 1 << i + 1 + odd;
|
|
};
|
|
|
|
FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
|
|
if (N <= 1) return;
|
|
|
|
for (var i = 0; i < N / 2; i++) {
|
|
var t = rws[i];
|
|
|
|
rws[i] = rws[N - i - 1];
|
|
rws[N - i - 1] = t;
|
|
|
|
t = iws[i];
|
|
|
|
iws[i] = -iws[N - i - 1];
|
|
iws[N - i - 1] = -t;
|
|
}
|
|
};
|
|
|
|
FFTM.prototype.normalize13b = function normalize13b (ws, N) {
|
|
var carry = 0;
|
|
for (var i = 0; i < N / 2; i++) {
|
|
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
|
|
Math.round(ws[2 * i] / N) +
|
|
carry;
|
|
|
|
ws[i] = w & 0x3ffffff;
|
|
|
|
if (w < 0x4000000) {
|
|
carry = 0;
|
|
} else {
|
|
carry = w / 0x4000000 | 0;
|
|
}
|
|
}
|
|
|
|
return ws;
|
|
};
|
|
|
|
FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
|
|
var carry = 0;
|
|
for (var i = 0; i < len; i++) {
|
|
carry = carry + (ws[i] | 0);
|
|
|
|
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
|
|
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
|
|
}
|
|
|
|
// Pad with zeroes
|
|
for (i = 2 * len; i < N; ++i) {
|
|
rws[i] = 0;
|
|
}
|
|
|
|
assert(carry === 0);
|
|
assert((carry & ~0x1fff) === 0);
|
|
};
|
|
|
|
FFTM.prototype.stub = function stub (N) {
|
|
var ph = new Array(N);
|
|
for (var i = 0; i < N; i++) {
|
|
ph[i] = 0;
|
|
}
|
|
|
|
return ph;
|
|
};
|
|
|
|
FFTM.prototype.mulp = function mulp (x, y, out) {
|
|
var N = 2 * this.guessLen13b(x.length, y.length);
|
|
|
|
var rbt = this.makeRBT(N);
|
|
|
|
var _ = this.stub(N);
|
|
|
|
var rws = new Array(N);
|
|
var rwst = new Array(N);
|
|
var iwst = new Array(N);
|
|
|
|
var nrws = new Array(N);
|
|
var nrwst = new Array(N);
|
|
var niwst = new Array(N);
|
|
|
|
var rmws = out.words;
|
|
rmws.length = N;
|
|
|
|
this.convert13b(x.words, x.length, rws, N);
|
|
this.convert13b(y.words, y.length, nrws, N);
|
|
|
|
this.transform(rws, _, rwst, iwst, N, rbt);
|
|
this.transform(nrws, _, nrwst, niwst, N, rbt);
|
|
|
|
for (var i = 0; i < N; i++) {
|
|
var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
|
|
iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
|
|
rwst[i] = rx;
|
|
}
|
|
|
|
this.conjugate(rwst, iwst, N);
|
|
this.transform(rwst, iwst, rmws, _, N, rbt);
|
|
this.conjugate(rmws, _, N);
|
|
this.normalize13b(rmws, N);
|
|
|
|
out.negative = x.negative ^ y.negative;
|
|
out.length = x.length + y.length;
|
|
return out.strip();
|
|
};
|
|
|
|
// Multiply `this` by `num`
|
|
BN.prototype.mul = function mul (num) {
|
|
var out = new BN(null);
|
|
out.words = new Array(this.length + num.length);
|
|
return this.mulTo(num, out);
|
|
};
|
|
|
|
// Multiply employing FFT
|
|
BN.prototype.mulf = function mulf (num) {
|
|
var out = new BN(null);
|
|
out.words = new Array(this.length + num.length);
|
|
return jumboMulTo(this, num, out);
|
|
};
|
|
|
|
// In-place Multiplication
|
|
BN.prototype.imul = function imul (num) {
|
|
return this.clone().mulTo(num, this);
|
|
};
|
|
|
|
BN.prototype.imuln = function imuln (num) {
|
|
assert(typeof num === 'number');
|
|
assert(num < 0x4000000);
|
|
|
|
// Carry
|
|
var carry = 0;
|
|
for (var i = 0; i < this.length; i++) {
|
|
var w = (this.words[i] | 0) * num;
|
|
var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
|
|
carry >>= 26;
|
|
carry += (w / 0x4000000) | 0;
|
|
// NOTE: lo is 27bit maximum
|
|
carry += lo >>> 26;
|
|
this.words[i] = lo & 0x3ffffff;
|
|
}
|
|
|
|
if (carry !== 0) {
|
|
this.words[i] = carry;
|
|
this.length++;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.muln = function muln (num) {
|
|
return this.clone().imuln(num);
|
|
};
|
|
|
|
// `this` * `this`
|
|
BN.prototype.sqr = function sqr () {
|
|
return this.mul(this);
|
|
};
|
|
|
|
// `this` * `this` in-place
|
|
BN.prototype.isqr = function isqr () {
|
|
return this.imul(this.clone());
|
|
};
|
|
|
|
// Math.pow(`this`, `num`)
|
|
BN.prototype.pow = function pow (num) {
|
|
var w = toBitArray(num);
|
|
if (w.length === 0) return new BN(1);
|
|
|
|
// Skip leading zeroes
|
|
var res = this;
|
|
for (var i = 0; i < w.length; i++, res = res.sqr()) {
|
|
if (w[i] !== 0) break;
|
|
}
|
|
|
|
if (++i < w.length) {
|
|
for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
|
|
if (w[i] === 0) continue;
|
|
|
|
res = res.mul(q);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
// Shift-left in-place
|
|
BN.prototype.iushln = function iushln (bits) {
|
|
assert(typeof bits === 'number' && bits >= 0);
|
|
var r = bits % 26;
|
|
var s = (bits - r) / 26;
|
|
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
|
|
var i;
|
|
|
|
if (r !== 0) {
|
|
var carry = 0;
|
|
|
|
for (i = 0; i < this.length; i++) {
|
|
var newCarry = this.words[i] & carryMask;
|
|
var c = ((this.words[i] | 0) - newCarry) << r;
|
|
this.words[i] = c | carry;
|
|
carry = newCarry >>> (26 - r);
|
|
}
|
|
|
|
if (carry) {
|
|
this.words[i] = carry;
|
|
this.length++;
|
|
}
|
|
}
|
|
|
|
if (s !== 0) {
|
|
for (i = this.length - 1; i >= 0; i--) {
|
|
this.words[i + s] = this.words[i];
|
|
}
|
|
|
|
for (i = 0; i < s; i++) {
|
|
this.words[i] = 0;
|
|
}
|
|
|
|
this.length += s;
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.ishln = function ishln (bits) {
|
|
// TODO(indutny): implement me
|
|
assert(this.negative === 0);
|
|
return this.iushln(bits);
|
|
};
|
|
|
|
// Shift-right in-place
|
|
// NOTE: `hint` is a lowest bit before trailing zeroes
|
|
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
|
BN.prototype.iushrn = function iushrn (bits, hint, extended) {
|
|
assert(typeof bits === 'number' && bits >= 0);
|
|
var h;
|
|
if (hint) {
|
|
h = (hint - (hint % 26)) / 26;
|
|
} else {
|
|
h = 0;
|
|
}
|
|
|
|
var r = bits % 26;
|
|
var s = Math.min((bits - r) / 26, this.length);
|
|
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
|
var maskedWords = extended;
|
|
|
|
h -= s;
|
|
h = Math.max(0, h);
|
|
|
|
// Extended mode, copy masked part
|
|
if (maskedWords) {
|
|
for (var i = 0; i < s; i++) {
|
|
maskedWords.words[i] = this.words[i];
|
|
}
|
|
maskedWords.length = s;
|
|
}
|
|
|
|
if (s === 0) {
|
|
// No-op, we should not move anything at all
|
|
} else if (this.length > s) {
|
|
this.length -= s;
|
|
for (i = 0; i < this.length; i++) {
|
|
this.words[i] = this.words[i + s];
|
|
}
|
|
} else {
|
|
this.words[0] = 0;
|
|
this.length = 1;
|
|
}
|
|
|
|
var carry = 0;
|
|
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
|
|
var word = this.words[i] | 0;
|
|
this.words[i] = (carry << (26 - r)) | (word >>> r);
|
|
carry = word & mask;
|
|
}
|
|
|
|
// Push carried bits as a mask
|
|
if (maskedWords && carry !== 0) {
|
|
maskedWords.words[maskedWords.length++] = carry;
|
|
}
|
|
|
|
if (this.length === 0) {
|
|
this.words[0] = 0;
|
|
this.length = 1;
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.ishrn = function ishrn (bits, hint, extended) {
|
|
// TODO(indutny): implement me
|
|
assert(this.negative === 0);
|
|
return this.iushrn(bits, hint, extended);
|
|
};
|
|
|
|
// Shift-left
|
|
BN.prototype.shln = function shln (bits) {
|
|
return this.clone().ishln(bits);
|
|
};
|
|
|
|
BN.prototype.ushln = function ushln (bits) {
|
|
return this.clone().iushln(bits);
|
|
};
|
|
|
|
// Shift-right
|
|
BN.prototype.shrn = function shrn (bits) {
|
|
return this.clone().ishrn(bits);
|
|
};
|
|
|
|
BN.prototype.ushrn = function ushrn (bits) {
|
|
return this.clone().iushrn(bits);
|
|
};
|
|
|
|
// Test if n bit is set
|
|
BN.prototype.testn = function testn (bit) {
|
|
assert(typeof bit === 'number' && bit >= 0);
|
|
var r = bit % 26;
|
|
var s = (bit - r) / 26;
|
|
var q = 1 << r;
|
|
|
|
// Fast case: bit is much higher than all existing words
|
|
if (this.length <= s) return false;
|
|
|
|
// Check bit and return
|
|
var w = this.words[s];
|
|
|
|
return !!(w & q);
|
|
};
|
|
|
|
// Return only lowers bits of number (in-place)
|
|
BN.prototype.imaskn = function imaskn (bits) {
|
|
assert(typeof bits === 'number' && bits >= 0);
|
|
var r = bits % 26;
|
|
var s = (bits - r) / 26;
|
|
|
|
assert(this.negative === 0, 'imaskn works only with positive numbers');
|
|
|
|
if (this.length <= s) {
|
|
return this;
|
|
}
|
|
|
|
if (r !== 0) {
|
|
s++;
|
|
}
|
|
this.length = Math.min(s, this.length);
|
|
|
|
if (r !== 0) {
|
|
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
|
this.words[this.length - 1] &= mask;
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
// Return only lowers bits of number
|
|
BN.prototype.maskn = function maskn (bits) {
|
|
return this.clone().imaskn(bits);
|
|
};
|
|
|
|
// Add plain number `num` to `this`
|
|
BN.prototype.iaddn = function iaddn (num) {
|
|
assert(typeof num === 'number');
|
|
assert(num < 0x4000000);
|
|
if (num < 0) return this.isubn(-num);
|
|
|
|
// Possible sign change
|
|
if (this.negative !== 0) {
|
|
if (this.length === 1 && (this.words[0] | 0) < num) {
|
|
this.words[0] = num - (this.words[0] | 0);
|
|
this.negative = 0;
|
|
return this;
|
|
}
|
|
|
|
this.negative = 0;
|
|
this.isubn(num);
|
|
this.negative = 1;
|
|
return this;
|
|
}
|
|
|
|
// Add without checks
|
|
return this._iaddn(num);
|
|
};
|
|
|
|
BN.prototype._iaddn = function _iaddn (num) {
|
|
this.words[0] += num;
|
|
|
|
// Carry
|
|
for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
|
|
this.words[i] -= 0x4000000;
|
|
if (i === this.length - 1) {
|
|
this.words[i + 1] = 1;
|
|
} else {
|
|
this.words[i + 1]++;
|
|
}
|
|
}
|
|
this.length = Math.max(this.length, i + 1);
|
|
|
|
return this;
|
|
};
|
|
|
|
// Subtract plain number `num` from `this`
|
|
BN.prototype.isubn = function isubn (num) {
|
|
assert(typeof num === 'number');
|
|
assert(num < 0x4000000);
|
|
if (num < 0) return this.iaddn(-num);
|
|
|
|
if (this.negative !== 0) {
|
|
this.negative = 0;
|
|
this.iaddn(num);
|
|
this.negative = 1;
|
|
return this;
|
|
}
|
|
|
|
this.words[0] -= num;
|
|
|
|
if (this.length === 1 && this.words[0] < 0) {
|
|
this.words[0] = -this.words[0];
|
|
this.negative = 1;
|
|
} else {
|
|
// Carry
|
|
for (var i = 0; i < this.length && this.words[i] < 0; i++) {
|
|
this.words[i] += 0x4000000;
|
|
this.words[i + 1] -= 1;
|
|
}
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.addn = function addn (num) {
|
|
return this.clone().iaddn(num);
|
|
};
|
|
|
|
BN.prototype.subn = function subn (num) {
|
|
return this.clone().isubn(num);
|
|
};
|
|
|
|
BN.prototype.iabs = function iabs () {
|
|
this.negative = 0;
|
|
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.abs = function abs () {
|
|
return this.clone().iabs();
|
|
};
|
|
|
|
BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
|
|
var len = num.length + shift;
|
|
var i;
|
|
|
|
this._expand(len);
|
|
|
|
var w;
|
|
var carry = 0;
|
|
for (i = 0; i < num.length; i++) {
|
|
w = (this.words[i + shift] | 0) + carry;
|
|
var right = (num.words[i] | 0) * mul;
|
|
w -= right & 0x3ffffff;
|
|
carry = (w >> 26) - ((right / 0x4000000) | 0);
|
|
this.words[i + shift] = w & 0x3ffffff;
|
|
}
|
|
for (; i < this.length - shift; i++) {
|
|
w = (this.words[i + shift] | 0) + carry;
|
|
carry = w >> 26;
|
|
this.words[i + shift] = w & 0x3ffffff;
|
|
}
|
|
|
|
if (carry === 0) return this.strip();
|
|
|
|
// Subtraction overflow
|
|
assert(carry === -1);
|
|
carry = 0;
|
|
for (i = 0; i < this.length; i++) {
|
|
w = -(this.words[i] | 0) + carry;
|
|
carry = w >> 26;
|
|
this.words[i] = w & 0x3ffffff;
|
|
}
|
|
this.negative = 1;
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype._wordDiv = function _wordDiv (num, mode) {
|
|
var shift = this.length - num.length;
|
|
|
|
var a = this.clone();
|
|
var b = num;
|
|
|
|
// Normalize
|
|
var bhi = b.words[b.length - 1] | 0;
|
|
var bhiBits = this._countBits(bhi);
|
|
shift = 26 - bhiBits;
|
|
if (shift !== 0) {
|
|
b = b.ushln(shift);
|
|
a.iushln(shift);
|
|
bhi = b.words[b.length - 1] | 0;
|
|
}
|
|
|
|
// Initialize quotient
|
|
var m = a.length - b.length;
|
|
var q;
|
|
|
|
if (mode !== 'mod') {
|
|
q = new BN(null);
|
|
q.length = m + 1;
|
|
q.words = new Array(q.length);
|
|
for (var i = 0; i < q.length; i++) {
|
|
q.words[i] = 0;
|
|
}
|
|
}
|
|
|
|
var diff = a.clone()._ishlnsubmul(b, 1, m);
|
|
if (diff.negative === 0) {
|
|
a = diff;
|
|
if (q) {
|
|
q.words[m] = 1;
|
|
}
|
|
}
|
|
|
|
for (var j = m - 1; j >= 0; j--) {
|
|
var qj = (a.words[b.length + j] | 0) * 0x4000000 +
|
|
(a.words[b.length + j - 1] | 0);
|
|
|
|
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
|
// (0x7ffffff)
|
|
qj = Math.min((qj / bhi) | 0, 0x3ffffff);
|
|
|
|
a._ishlnsubmul(b, qj, j);
|
|
while (a.negative !== 0) {
|
|
qj--;
|
|
a.negative = 0;
|
|
a._ishlnsubmul(b, 1, j);
|
|
if (!a.isZero()) {
|
|
a.negative ^= 1;
|
|
}
|
|
}
|
|
if (q) {
|
|
q.words[j] = qj;
|
|
}
|
|
}
|
|
if (q) {
|
|
q.strip();
|
|
}
|
|
a.strip();
|
|
|
|
// Denormalize
|
|
if (mode !== 'div' && shift !== 0) {
|
|
a.iushrn(shift);
|
|
}
|
|
|
|
return {
|
|
div: q || null,
|
|
mod: a
|
|
};
|
|
};
|
|
|
|
// NOTE: 1) `mode` can be set to `mod` to request mod only,
|
|
// to `div` to request div only, or be absent to
|
|
// request both div & mod
|
|
// 2) `positive` is true if unsigned mod is requested
|
|
BN.prototype.divmod = function divmod (num, mode, positive) {
|
|
assert(!num.isZero());
|
|
|
|
if (this.isZero()) {
|
|
return {
|
|
div: new BN(0),
|
|
mod: new BN(0)
|
|
};
|
|
}
|
|
|
|
var div, mod, res;
|
|
if (this.negative !== 0 && num.negative === 0) {
|
|
res = this.neg().divmod(num, mode);
|
|
|
|
if (mode !== 'mod') {
|
|
div = res.div.neg();
|
|
}
|
|
|
|
if (mode !== 'div') {
|
|
mod = res.mod.neg();
|
|
if (positive && mod.negative !== 0) {
|
|
mod.iadd(num);
|
|
}
|
|
}
|
|
|
|
return {
|
|
div: div,
|
|
mod: mod
|
|
};
|
|
}
|
|
|
|
if (this.negative === 0 && num.negative !== 0) {
|
|
res = this.divmod(num.neg(), mode);
|
|
|
|
if (mode !== 'mod') {
|
|
div = res.div.neg();
|
|
}
|
|
|
|
return {
|
|
div: div,
|
|
mod: res.mod
|
|
};
|
|
}
|
|
|
|
if ((this.negative & num.negative) !== 0) {
|
|
res = this.neg().divmod(num.neg(), mode);
|
|
|
|
if (mode !== 'div') {
|
|
mod = res.mod.neg();
|
|
if (positive && mod.negative !== 0) {
|
|
mod.isub(num);
|
|
}
|
|
}
|
|
|
|
return {
|
|
div: res.div,
|
|
mod: mod
|
|
};
|
|
}
|
|
|
|
// Both numbers are positive at this point
|
|
|
|
// Strip both numbers to approximate shift value
|
|
if (num.length > this.length || this.cmp(num) < 0) {
|
|
return {
|
|
div: new BN(0),
|
|
mod: this
|
|
};
|
|
}
|
|
|
|
// Very short reduction
|
|
if (num.length === 1) {
|
|
if (mode === 'div') {
|
|
return {
|
|
div: this.divn(num.words[0]),
|
|
mod: null
|
|
};
|
|
}
|
|
|
|
if (mode === 'mod') {
|
|
return {
|
|
div: null,
|
|
mod: new BN(this.modn(num.words[0]))
|
|
};
|
|
}
|
|
|
|
return {
|
|
div: this.divn(num.words[0]),
|
|
mod: new BN(this.modn(num.words[0]))
|
|
};
|
|
}
|
|
|
|
return this._wordDiv(num, mode);
|
|
};
|
|
|
|
// Find `this` / `num`
|
|
BN.prototype.div = function div (num) {
|
|
return this.divmod(num, 'div', false).div;
|
|
};
|
|
|
|
// Find `this` % `num`
|
|
BN.prototype.mod = function mod (num) {
|
|
return this.divmod(num, 'mod', false).mod;
|
|
};
|
|
|
|
BN.prototype.umod = function umod (num) {
|
|
return this.divmod(num, 'mod', true).mod;
|
|
};
|
|
|
|
// Find Round(`this` / `num`)
|
|
BN.prototype.divRound = function divRound (num) {
|
|
var dm = this.divmod(num);
|
|
|
|
// Fast case - exact division
|
|
if (dm.mod.isZero()) return dm.div;
|
|
|
|
var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
|
|
|
|
var half = num.ushrn(1);
|
|
var r2 = num.andln(1);
|
|
var cmp = mod.cmp(half);
|
|
|
|
// Round down
|
|
if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
|
|
|
|
// Round up
|
|
return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
|
|
};
|
|
|
|
BN.prototype.modn = function modn (num) {
|
|
assert(num <= 0x3ffffff);
|
|
var p = (1 << 26) % num;
|
|
|
|
var acc = 0;
|
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
acc = (p * acc + (this.words[i] | 0)) % num;
|
|
}
|
|
|
|
return acc;
|
|
};
|
|
|
|
// In-place division by number
|
|
BN.prototype.idivn = function idivn (num) {
|
|
assert(num <= 0x3ffffff);
|
|
|
|
var carry = 0;
|
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
var w = (this.words[i] | 0) + carry * 0x4000000;
|
|
this.words[i] = (w / num) | 0;
|
|
carry = w % num;
|
|
}
|
|
|
|
return this.strip();
|
|
};
|
|
|
|
BN.prototype.divn = function divn (num) {
|
|
return this.clone().idivn(num);
|
|
};
|
|
|
|
BN.prototype.egcd = function egcd (p) {
|
|
assert(p.negative === 0);
|
|
assert(!p.isZero());
|
|
|
|
var x = this;
|
|
var y = p.clone();
|
|
|
|
if (x.negative !== 0) {
|
|
x = x.umod(p);
|
|
} else {
|
|
x = x.clone();
|
|
}
|
|
|
|
// A * x + B * y = x
|
|
var A = new BN(1);
|
|
var B = new BN(0);
|
|
|
|
// C * x + D * y = y
|
|
var C = new BN(0);
|
|
var D = new BN(1);
|
|
|
|
var g = 0;
|
|
|
|
while (x.isEven() && y.isEven()) {
|
|
x.iushrn(1);
|
|
y.iushrn(1);
|
|
++g;
|
|
}
|
|
|
|
var yp = y.clone();
|
|
var xp = x.clone();
|
|
|
|
while (!x.isZero()) {
|
|
for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
|
if (i > 0) {
|
|
x.iushrn(i);
|
|
while (i-- > 0) {
|
|
if (A.isOdd() || B.isOdd()) {
|
|
A.iadd(yp);
|
|
B.isub(xp);
|
|
}
|
|
|
|
A.iushrn(1);
|
|
B.iushrn(1);
|
|
}
|
|
}
|
|
|
|
for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
|
if (j > 0) {
|
|
y.iushrn(j);
|
|
while (j-- > 0) {
|
|
if (C.isOdd() || D.isOdd()) {
|
|
C.iadd(yp);
|
|
D.isub(xp);
|
|
}
|
|
|
|
C.iushrn(1);
|
|
D.iushrn(1);
|
|
}
|
|
}
|
|
|
|
if (x.cmp(y) >= 0) {
|
|
x.isub(y);
|
|
A.isub(C);
|
|
B.isub(D);
|
|
} else {
|
|
y.isub(x);
|
|
C.isub(A);
|
|
D.isub(B);
|
|
}
|
|
}
|
|
|
|
return {
|
|
a: C,
|
|
b: D,
|
|
gcd: y.iushln(g)
|
|
};
|
|
};
|
|
|
|
// This is reduced incarnation of the binary EEA
|
|
// above, designated to invert members of the
|
|
// _prime_ fields F(p) at a maximal speed
|
|
BN.prototype._invmp = function _invmp (p) {
|
|
assert(p.negative === 0);
|
|
assert(!p.isZero());
|
|
|
|
var a = this;
|
|
var b = p.clone();
|
|
|
|
if (a.negative !== 0) {
|
|
a = a.umod(p);
|
|
} else {
|
|
a = a.clone();
|
|
}
|
|
|
|
var x1 = new BN(1);
|
|
var x2 = new BN(0);
|
|
|
|
var delta = b.clone();
|
|
|
|
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
|
|
for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
|
if (i > 0) {
|
|
a.iushrn(i);
|
|
while (i-- > 0) {
|
|
if (x1.isOdd()) {
|
|
x1.iadd(delta);
|
|
}
|
|
|
|
x1.iushrn(1);
|
|
}
|
|
}
|
|
|
|
for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
|
if (j > 0) {
|
|
b.iushrn(j);
|
|
while (j-- > 0) {
|
|
if (x2.isOdd()) {
|
|
x2.iadd(delta);
|
|
}
|
|
|
|
x2.iushrn(1);
|
|
}
|
|
}
|
|
|
|
if (a.cmp(b) >= 0) {
|
|
a.isub(b);
|
|
x1.isub(x2);
|
|
} else {
|
|
b.isub(a);
|
|
x2.isub(x1);
|
|
}
|
|
}
|
|
|
|
var res;
|
|
if (a.cmpn(1) === 0) {
|
|
res = x1;
|
|
} else {
|
|
res = x2;
|
|
}
|
|
|
|
if (res.cmpn(0) < 0) {
|
|
res.iadd(p);
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
BN.prototype.gcd = function gcd (num) {
|
|
if (this.isZero()) return num.abs();
|
|
if (num.isZero()) return this.abs();
|
|
|
|
var a = this.clone();
|
|
var b = num.clone();
|
|
a.negative = 0;
|
|
b.negative = 0;
|
|
|
|
// Remove common factor of two
|
|
for (var shift = 0; a.isEven() && b.isEven(); shift++) {
|
|
a.iushrn(1);
|
|
b.iushrn(1);
|
|
}
|
|
|
|
do {
|
|
while (a.isEven()) {
|
|
a.iushrn(1);
|
|
}
|
|
while (b.isEven()) {
|
|
b.iushrn(1);
|
|
}
|
|
|
|
var r = a.cmp(b);
|
|
if (r < 0) {
|
|
// Swap `a` and `b` to make `a` always bigger than `b`
|
|
var t = a;
|
|
a = b;
|
|
b = t;
|
|
} else if (r === 0 || b.cmpn(1) === 0) {
|
|
break;
|
|
}
|
|
|
|
a.isub(b);
|
|
} while (true);
|
|
|
|
return b.iushln(shift);
|
|
};
|
|
|
|
// Invert number in the field F(num)
|
|
BN.prototype.invm = function invm (num) {
|
|
return this.egcd(num).a.umod(num);
|
|
};
|
|
|
|
BN.prototype.isEven = function isEven () {
|
|
return (this.words[0] & 1) === 0;
|
|
};
|
|
|
|
BN.prototype.isOdd = function isOdd () {
|
|
return (this.words[0] & 1) === 1;
|
|
};
|
|
|
|
// And first word and num
|
|
BN.prototype.andln = function andln (num) {
|
|
return this.words[0] & num;
|
|
};
|
|
|
|
// Increment at the bit position in-line
|
|
BN.prototype.bincn = function bincn (bit) {
|
|
assert(typeof bit === 'number');
|
|
var r = bit % 26;
|
|
var s = (bit - r) / 26;
|
|
var q = 1 << r;
|
|
|
|
// Fast case: bit is much higher than all existing words
|
|
if (this.length <= s) {
|
|
this._expand(s + 1);
|
|
this.words[s] |= q;
|
|
return this;
|
|
}
|
|
|
|
// Add bit and propagate, if needed
|
|
var carry = q;
|
|
for (var i = s; carry !== 0 && i < this.length; i++) {
|
|
var w = this.words[i] | 0;
|
|
w += carry;
|
|
carry = w >>> 26;
|
|
w &= 0x3ffffff;
|
|
this.words[i] = w;
|
|
}
|
|
if (carry !== 0) {
|
|
this.words[i] = carry;
|
|
this.length++;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.isZero = function isZero () {
|
|
return this.length === 1 && this.words[0] === 0;
|
|
};
|
|
|
|
BN.prototype.cmpn = function cmpn (num) {
|
|
var negative = num < 0;
|
|
|
|
if (this.negative !== 0 && !negative) return -1;
|
|
if (this.negative === 0 && negative) return 1;
|
|
|
|
this.strip();
|
|
|
|
var res;
|
|
if (this.length > 1) {
|
|
res = 1;
|
|
} else {
|
|
if (negative) {
|
|
num = -num;
|
|
}
|
|
|
|
assert(num <= 0x3ffffff, 'Number is too big');
|
|
|
|
var w = this.words[0] | 0;
|
|
res = w === num ? 0 : w < num ? -1 : 1;
|
|
}
|
|
if (this.negative !== 0) return -res | 0;
|
|
return res;
|
|
};
|
|
|
|
// Compare two numbers and return:
|
|
// 1 - if `this` > `num`
|
|
// 0 - if `this` == `num`
|
|
// -1 - if `this` < `num`
|
|
BN.prototype.cmp = function cmp (num) {
|
|
if (this.negative !== 0 && num.negative === 0) return -1;
|
|
if (this.negative === 0 && num.negative !== 0) return 1;
|
|
|
|
var res = this.ucmp(num);
|
|
if (this.negative !== 0) return -res | 0;
|
|
return res;
|
|
};
|
|
|
|
// Unsigned comparison
|
|
BN.prototype.ucmp = function ucmp (num) {
|
|
// At this point both numbers have the same sign
|
|
if (this.length > num.length) return 1;
|
|
if (this.length < num.length) return -1;
|
|
|
|
var res = 0;
|
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
var a = this.words[i] | 0;
|
|
var b = num.words[i] | 0;
|
|
|
|
if (a === b) continue;
|
|
if (a < b) {
|
|
res = -1;
|
|
} else if (a > b) {
|
|
res = 1;
|
|
}
|
|
break;
|
|
}
|
|
return res;
|
|
};
|
|
|
|
BN.prototype.gtn = function gtn (num) {
|
|
return this.cmpn(num) === 1;
|
|
};
|
|
|
|
BN.prototype.gt = function gt (num) {
|
|
return this.cmp(num) === 1;
|
|
};
|
|
|
|
BN.prototype.gten = function gten (num) {
|
|
return this.cmpn(num) >= 0;
|
|
};
|
|
|
|
BN.prototype.gte = function gte (num) {
|
|
return this.cmp(num) >= 0;
|
|
};
|
|
|
|
BN.prototype.ltn = function ltn (num) {
|
|
return this.cmpn(num) === -1;
|
|
};
|
|
|
|
BN.prototype.lt = function lt (num) {
|
|
return this.cmp(num) === -1;
|
|
};
|
|
|
|
BN.prototype.lten = function lten (num) {
|
|
return this.cmpn(num) <= 0;
|
|
};
|
|
|
|
BN.prototype.lte = function lte (num) {
|
|
return this.cmp(num) <= 0;
|
|
};
|
|
|
|
BN.prototype.eqn = function eqn (num) {
|
|
return this.cmpn(num) === 0;
|
|
};
|
|
|
|
BN.prototype.eq = function eq (num) {
|
|
return this.cmp(num) === 0;
|
|
};
|
|
|
|
//
|
|
// A reduce context, could be using montgomery or something better, depending
|
|
// on the `m` itself.
|
|
//
|
|
BN.red = function red (num) {
|
|
return new Red(num);
|
|
};
|
|
|
|
BN.prototype.toRed = function toRed (ctx) {
|
|
assert(!this.red, 'Already a number in reduction context');
|
|
assert(this.negative === 0, 'red works only with positives');
|
|
return ctx.convertTo(this)._forceRed(ctx);
|
|
};
|
|
|
|
BN.prototype.fromRed = function fromRed () {
|
|
assert(this.red, 'fromRed works only with numbers in reduction context');
|
|
return this.red.convertFrom(this);
|
|
};
|
|
|
|
BN.prototype._forceRed = function _forceRed (ctx) {
|
|
this.red = ctx;
|
|
return this;
|
|
};
|
|
|
|
BN.prototype.forceRed = function forceRed (ctx) {
|
|
assert(!this.red, 'Already a number in reduction context');
|
|
return this._forceRed(ctx);
|
|
};
|
|
|
|
BN.prototype.redAdd = function redAdd (num) {
|
|
assert(this.red, 'redAdd works only with red numbers');
|
|
return this.red.add(this, num);
|
|
};
|
|
|
|
BN.prototype.redIAdd = function redIAdd (num) {
|
|
assert(this.red, 'redIAdd works only with red numbers');
|
|
return this.red.iadd(this, num);
|
|
};
|
|
|
|
BN.prototype.redSub = function redSub (num) {
|
|
assert(this.red, 'redSub works only with red numbers');
|
|
return this.red.sub(this, num);
|
|
};
|
|
|
|
BN.prototype.redISub = function redISub (num) {
|
|
assert(this.red, 'redISub works only with red numbers');
|
|
return this.red.isub(this, num);
|
|
};
|
|
|
|
BN.prototype.redShl = function redShl (num) {
|
|
assert(this.red, 'redShl works only with red numbers');
|
|
return this.red.shl(this, num);
|
|
};
|
|
|
|
BN.prototype.redMul = function redMul (num) {
|
|
assert(this.red, 'redMul works only with red numbers');
|
|
this.red._verify2(this, num);
|
|
return this.red.mul(this, num);
|
|
};
|
|
|
|
BN.prototype.redIMul = function redIMul (num) {
|
|
assert(this.red, 'redMul works only with red numbers');
|
|
this.red._verify2(this, num);
|
|
return this.red.imul(this, num);
|
|
};
|
|
|
|
BN.prototype.redSqr = function redSqr () {
|
|
assert(this.red, 'redSqr works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.sqr(this);
|
|
};
|
|
|
|
BN.prototype.redISqr = function redISqr () {
|
|
assert(this.red, 'redISqr works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.isqr(this);
|
|
};
|
|
|
|
// Square root over p
|
|
BN.prototype.redSqrt = function redSqrt () {
|
|
assert(this.red, 'redSqrt works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.sqrt(this);
|
|
};
|
|
|
|
BN.prototype.redInvm = function redInvm () {
|
|
assert(this.red, 'redInvm works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.invm(this);
|
|
};
|
|
|
|
// Return negative clone of `this` % `red modulo`
|
|
BN.prototype.redNeg = function redNeg () {
|
|
assert(this.red, 'redNeg works only with red numbers');
|
|
this.red._verify1(this);
|
|
return this.red.neg(this);
|
|
};
|
|
|
|
BN.prototype.redPow = function redPow (num) {
|
|
assert(this.red && !num.red, 'redPow(normalNum)');
|
|
this.red._verify1(this);
|
|
return this.red.pow(this, num);
|
|
};
|
|
|
|
// Prime numbers with efficient reduction
|
|
var primes = {
|
|
k256: null,
|
|
p224: null,
|
|
p192: null,
|
|
p25519: null
|
|
};
|
|
|
|
// Pseudo-Mersenne prime
|
|
function MPrime (name, p) {
|
|
// P = 2 ^ N - K
|
|
this.name = name;
|
|
this.p = new BN(p, 16);
|
|
this.n = this.p.bitLength();
|
|
this.k = new BN(1).iushln(this.n).isub(this.p);
|
|
|
|
this.tmp = this._tmp();
|
|
}
|
|
|
|
MPrime.prototype._tmp = function _tmp () {
|
|
var tmp = new BN(null);
|
|
tmp.words = new Array(Math.ceil(this.n / 13));
|
|
return tmp;
|
|
};
|
|
|
|
MPrime.prototype.ireduce = function ireduce (num) {
|
|
// Assumes that `num` is less than `P^2`
|
|
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
|
|
var r = num;
|
|
var rlen;
|
|
|
|
do {
|
|
this.split(r, this.tmp);
|
|
r = this.imulK(r);
|
|
r = r.iadd(this.tmp);
|
|
rlen = r.bitLength();
|
|
} while (rlen > this.n);
|
|
|
|
var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
|
|
if (cmp === 0) {
|
|
r.words[0] = 0;
|
|
r.length = 1;
|
|
} else if (cmp > 0) {
|
|
r.isub(this.p);
|
|
} else {
|
|
r.strip();
|
|
}
|
|
|
|
return r;
|
|
};
|
|
|
|
MPrime.prototype.split = function split (input, out) {
|
|
input.iushrn(this.n, 0, out);
|
|
};
|
|
|
|
MPrime.prototype.imulK = function imulK (num) {
|
|
return num.imul(this.k);
|
|
};
|
|
|
|
function K256 () {
|
|
MPrime.call(
|
|
this,
|
|
'k256',
|
|
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
|
|
}
|
|
inherits(K256, MPrime);
|
|
|
|
K256.prototype.split = function split (input, output) {
|
|
// 256 = 9 * 26 + 22
|
|
var mask = 0x3fffff;
|
|
|
|
var outLen = Math.min(input.length, 9);
|
|
for (var i = 0; i < outLen; i++) {
|
|
output.words[i] = input.words[i];
|
|
}
|
|
output.length = outLen;
|
|
|
|
if (input.length <= 9) {
|
|
input.words[0] = 0;
|
|
input.length = 1;
|
|
return;
|
|
}
|
|
|
|
// Shift by 9 limbs
|
|
var prev = input.words[9];
|
|
output.words[output.length++] = prev & mask;
|
|
|
|
for (i = 10; i < input.length; i++) {
|
|
var next = input.words[i] | 0;
|
|
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
|
|
prev = next;
|
|
}
|
|
prev >>>= 22;
|
|
input.words[i - 10] = prev;
|
|
if (prev === 0 && input.length > 10) {
|
|
input.length -= 10;
|
|
} else {
|
|
input.length -= 9;
|
|
}
|
|
};
|
|
|
|
K256.prototype.imulK = function imulK (num) {
|
|
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
|
|
num.words[num.length] = 0;
|
|
num.words[num.length + 1] = 0;
|
|
num.length += 2;
|
|
|
|
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
|
|
var lo = 0;
|
|
for (var i = 0; i < num.length; i++) {
|
|
var w = num.words[i] | 0;
|
|
lo += w * 0x3d1;
|
|
num.words[i] = lo & 0x3ffffff;
|
|
lo = w * 0x40 + ((lo / 0x4000000) | 0);
|
|
}
|
|
|
|
// Fast length reduction
|
|
if (num.words[num.length - 1] === 0) {
|
|
num.length--;
|
|
if (num.words[num.length - 1] === 0) {
|
|
num.length--;
|
|
}
|
|
}
|
|
return num;
|
|
};
|
|
|
|
function P224 () {
|
|
MPrime.call(
|
|
this,
|
|
'p224',
|
|
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
|
|
}
|
|
inherits(P224, MPrime);
|
|
|
|
function P192 () {
|
|
MPrime.call(
|
|
this,
|
|
'p192',
|
|
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
|
|
}
|
|
inherits(P192, MPrime);
|
|
|
|
function P25519 () {
|
|
// 2 ^ 255 - 19
|
|
MPrime.call(
|
|
this,
|
|
'25519',
|
|
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
|
|
}
|
|
inherits(P25519, MPrime);
|
|
|
|
P25519.prototype.imulK = function imulK (num) {
|
|
// K = 0x13
|
|
var carry = 0;
|
|
for (var i = 0; i < num.length; i++) {
|
|
var hi = (num.words[i] | 0) * 0x13 + carry;
|
|
var lo = hi & 0x3ffffff;
|
|
hi >>>= 26;
|
|
|
|
num.words[i] = lo;
|
|
carry = hi;
|
|
}
|
|
if (carry !== 0) {
|
|
num.words[num.length++] = carry;
|
|
}
|
|
return num;
|
|
};
|
|
|
|
// Exported mostly for testing purposes, use plain name instead
|
|
BN._prime = function prime (name) {
|
|
// Cached version of prime
|
|
if (primes[name]) return primes[name];
|
|
|
|
var prime;
|
|
if (name === 'k256') {
|
|
prime = new K256();
|
|
} else if (name === 'p224') {
|
|
prime = new P224();
|
|
} else if (name === 'p192') {
|
|
prime = new P192();
|
|
} else if (name === 'p25519') {
|
|
prime = new P25519();
|
|
} else {
|
|
throw new Error('Unknown prime ' + name);
|
|
}
|
|
primes[name] = prime;
|
|
|
|
return prime;
|
|
};
|
|
|
|
//
|
|
// Base reduction engine
|
|
//
|
|
function Red (m) {
|
|
if (typeof m === 'string') {
|
|
var prime = BN._prime(m);
|
|
this.m = prime.p;
|
|
this.prime = prime;
|
|
} else {
|
|
assert(m.gtn(1), 'modulus must be greater than 1');
|
|
this.m = m;
|
|
this.prime = null;
|
|
}
|
|
}
|
|
|
|
Red.prototype._verify1 = function _verify1 (a) {
|
|
assert(a.negative === 0, 'red works only with positives');
|
|
assert(a.red, 'red works only with red numbers');
|
|
};
|
|
|
|
Red.prototype._verify2 = function _verify2 (a, b) {
|
|
assert((a.negative | b.negative) === 0, 'red works only with positives');
|
|
assert(a.red && a.red === b.red,
|
|
'red works only with red numbers');
|
|
};
|
|
|
|
Red.prototype.imod = function imod (a) {
|
|
if (this.prime) return this.prime.ireduce(a)._forceRed(this);
|
|
return a.umod(this.m)._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.neg = function neg (a) {
|
|
if (a.isZero()) {
|
|
return a.clone();
|
|
}
|
|
|
|
return this.m.sub(a)._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.add = function add (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.add(b);
|
|
if (res.cmp(this.m) >= 0) {
|
|
res.isub(this.m);
|
|
}
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.iadd = function iadd (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.iadd(b);
|
|
if (res.cmp(this.m) >= 0) {
|
|
res.isub(this.m);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
Red.prototype.sub = function sub (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.sub(b);
|
|
if (res.cmpn(0) < 0) {
|
|
res.iadd(this.m);
|
|
}
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Red.prototype.isub = function isub (a, b) {
|
|
this._verify2(a, b);
|
|
|
|
var res = a.isub(b);
|
|
if (res.cmpn(0) < 0) {
|
|
res.iadd(this.m);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
Red.prototype.shl = function shl (a, num) {
|
|
this._verify1(a);
|
|
return this.imod(a.ushln(num));
|
|
};
|
|
|
|
Red.prototype.imul = function imul (a, b) {
|
|
this._verify2(a, b);
|
|
return this.imod(a.imul(b));
|
|
};
|
|
|
|
Red.prototype.mul = function mul (a, b) {
|
|
this._verify2(a, b);
|
|
return this.imod(a.mul(b));
|
|
};
|
|
|
|
Red.prototype.isqr = function isqr (a) {
|
|
return this.imul(a, a.clone());
|
|
};
|
|
|
|
Red.prototype.sqr = function sqr (a) {
|
|
return this.mul(a, a);
|
|
};
|
|
|
|
Red.prototype.sqrt = function sqrt (a) {
|
|
if (a.isZero()) return a.clone();
|
|
|
|
var mod3 = this.m.andln(3);
|
|
assert(mod3 % 2 === 1);
|
|
|
|
// Fast case
|
|
if (mod3 === 3) {
|
|
var pow = this.m.add(new BN(1)).iushrn(2);
|
|
return this.pow(a, pow);
|
|
}
|
|
|
|
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
|
|
//
|
|
// Find Q and S, that Q * 2 ^ S = (P - 1)
|
|
var q = this.m.subn(1);
|
|
var s = 0;
|
|
while (!q.isZero() && q.andln(1) === 0) {
|
|
s++;
|
|
q.iushrn(1);
|
|
}
|
|
assert(!q.isZero());
|
|
|
|
var one = new BN(1).toRed(this);
|
|
var nOne = one.redNeg();
|
|
|
|
// Find quadratic non-residue
|
|
// NOTE: Max is such because of generalized Riemann hypothesis.
|
|
var lpow = this.m.subn(1).iushrn(1);
|
|
var z = this.m.bitLength();
|
|
z = new BN(2 * z * z).toRed(this);
|
|
|
|
while (this.pow(z, lpow).cmp(nOne) !== 0) {
|
|
z.redIAdd(nOne);
|
|
}
|
|
|
|
var c = this.pow(z, q);
|
|
var r = this.pow(a, q.addn(1).iushrn(1));
|
|
var t = this.pow(a, q);
|
|
var m = s;
|
|
while (t.cmp(one) !== 0) {
|
|
var tmp = t;
|
|
for (var i = 0; tmp.cmp(one) !== 0; i++) {
|
|
tmp = tmp.redSqr();
|
|
}
|
|
assert(i < m);
|
|
var b = this.pow(c, new BN(1).iushln(m - i - 1));
|
|
|
|
r = r.redMul(b);
|
|
c = b.redSqr();
|
|
t = t.redMul(c);
|
|
m = i;
|
|
}
|
|
|
|
return r;
|
|
};
|
|
|
|
Red.prototype.invm = function invm (a) {
|
|
var inv = a._invmp(this.m);
|
|
if (inv.negative !== 0) {
|
|
inv.negative = 0;
|
|
return this.imod(inv).redNeg();
|
|
} else {
|
|
return this.imod(inv);
|
|
}
|
|
};
|
|
|
|
Red.prototype.pow = function pow (a, num) {
|
|
if (num.isZero()) return new BN(1).toRed(this);
|
|
if (num.cmpn(1) === 0) return a.clone();
|
|
|
|
var windowSize = 4;
|
|
var wnd = new Array(1 << windowSize);
|
|
wnd[0] = new BN(1).toRed(this);
|
|
wnd[1] = a;
|
|
for (var i = 2; i < wnd.length; i++) {
|
|
wnd[i] = this.mul(wnd[i - 1], a);
|
|
}
|
|
|
|
var res = wnd[0];
|
|
var current = 0;
|
|
var currentLen = 0;
|
|
var start = num.bitLength() % 26;
|
|
if (start === 0) {
|
|
start = 26;
|
|
}
|
|
|
|
for (i = num.length - 1; i >= 0; i--) {
|
|
var word = num.words[i];
|
|
for (var j = start - 1; j >= 0; j--) {
|
|
var bit = (word >> j) & 1;
|
|
if (res !== wnd[0]) {
|
|
res = this.sqr(res);
|
|
}
|
|
|
|
if (bit === 0 && current === 0) {
|
|
currentLen = 0;
|
|
continue;
|
|
}
|
|
|
|
current <<= 1;
|
|
current |= bit;
|
|
currentLen++;
|
|
if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
|
|
|
|
res = this.mul(res, wnd[current]);
|
|
currentLen = 0;
|
|
current = 0;
|
|
}
|
|
start = 26;
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
Red.prototype.convertTo = function convertTo (num) {
|
|
var r = num.umod(this.m);
|
|
|
|
return r === num ? r.clone() : r;
|
|
};
|
|
|
|
Red.prototype.convertFrom = function convertFrom (num) {
|
|
var res = num.clone();
|
|
res.red = null;
|
|
return res;
|
|
};
|
|
|
|
//
|
|
// Montgomery method engine
|
|
//
|
|
|
|
BN.mont = function mont (num) {
|
|
return new Mont(num);
|
|
};
|
|
|
|
function Mont (m) {
|
|
Red.call(this, m);
|
|
|
|
this.shift = this.m.bitLength();
|
|
if (this.shift % 26 !== 0) {
|
|
this.shift += 26 - (this.shift % 26);
|
|
}
|
|
|
|
this.r = new BN(1).iushln(this.shift);
|
|
this.r2 = this.imod(this.r.sqr());
|
|
this.rinv = this.r._invmp(this.m);
|
|
|
|
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
|
|
this.minv = this.minv.umod(this.r);
|
|
this.minv = this.r.sub(this.minv);
|
|
}
|
|
inherits(Mont, Red);
|
|
|
|
Mont.prototype.convertTo = function convertTo (num) {
|
|
return this.imod(num.ushln(this.shift));
|
|
};
|
|
|
|
Mont.prototype.convertFrom = function convertFrom (num) {
|
|
var r = this.imod(num.mul(this.rinv));
|
|
r.red = null;
|
|
return r;
|
|
};
|
|
|
|
Mont.prototype.imul = function imul (a, b) {
|
|
if (a.isZero() || b.isZero()) {
|
|
a.words[0] = 0;
|
|
a.length = 1;
|
|
return a;
|
|
}
|
|
|
|
var t = a.imul(b);
|
|
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
|
var u = t.isub(c).iushrn(this.shift);
|
|
var res = u;
|
|
|
|
if (u.cmp(this.m) >= 0) {
|
|
res = u.isub(this.m);
|
|
} else if (u.cmpn(0) < 0) {
|
|
res = u.iadd(this.m);
|
|
}
|
|
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Mont.prototype.mul = function mul (a, b) {
|
|
if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
|
|
|
|
var t = a.mul(b);
|
|
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
|
var u = t.isub(c).iushrn(this.shift);
|
|
var res = u;
|
|
if (u.cmp(this.m) >= 0) {
|
|
res = u.isub(this.m);
|
|
} else if (u.cmpn(0) < 0) {
|
|
res = u.iadd(this.m);
|
|
}
|
|
|
|
return res._forceRed(this);
|
|
};
|
|
|
|
Mont.prototype.invm = function invm (a) {
|
|
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
|
|
var res = this.imod(a._invmp(this.m).mul(this.r2));
|
|
return res._forceRed(this);
|
|
};
|
|
})(typeof module === 'undefined' || module, this);
|
|
|
|
},{"buffer":99}],23:[function(require,module,exports){
|
|
module.exports={
|
|
"_from": "elliptic@^6.5.2",
|
|
"_id": "elliptic@6.5.2",
|
|
"_inBundle": false,
|
|
"_integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
|
|
"_location": "/elliptic",
|
|
"_phantomChildren": {},
|
|
"_requested": {
|
|
"type": "range",
|
|
"registry": true,
|
|
"raw": "elliptic@^6.5.2",
|
|
"name": "elliptic",
|
|
"escapedName": "elliptic",
|
|
"rawSpec": "^6.5.2",
|
|
"saveSpec": null,
|
|
"fetchSpec": "^6.5.2"
|
|
},
|
|
"_requiredBy": [
|
|
"/ripple-keypairs"
|
|
],
|
|
"_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
|
|
"_shasum": "05c5678d7173c049d8ca433552224a495d0e3762",
|
|
"_spec": "elliptic@^6.5.2",
|
|
"_where": "/Users/mbhandary/node_modules/ripple-keypairs",
|
|
"author": {
|
|
"name": "Fedor Indutny",
|
|
"email": "fedor@indutny.com"
|
|
},
|
|
"bugs": {
|
|
"url": "https://github.com/indutny/elliptic/issues"
|
|
},
|
|
"bundleDependencies": false,
|
|
"dependencies": {
|
|
"bn.js": "^4.4.0",
|
|
"brorand": "^1.0.1",
|
|
"hash.js": "^1.0.0",
|
|
"hmac-drbg": "^1.0.0",
|
|
"inherits": "^2.0.1",
|
|
"minimalistic-assert": "^1.0.0",
|
|
"minimalistic-crypto-utils": "^1.0.0"
|
|
},
|
|
"deprecated": false,
|
|
"description": "EC cryptography",
|
|
"devDependencies": {
|
|
"brfs": "^1.4.3",
|
|
"coveralls": "^3.0.8",
|
|
"grunt": "^1.0.4",
|
|
"grunt-browserify": "^5.0.0",
|
|
"grunt-cli": "^1.2.0",
|
|
"grunt-contrib-connect": "^1.0.0",
|
|
"grunt-contrib-copy": "^1.0.0",
|
|
"grunt-contrib-uglify": "^1.0.1",
|
|
"grunt-mocha-istanbul": "^3.0.1",
|
|
"grunt-saucelabs": "^9.0.1",
|
|
"istanbul": "^0.4.2",
|
|
"jscs": "^3.0.7",
|
|
"jshint": "^2.10.3",
|
|
"mocha": "^6.2.2"
|
|
},
|
|
"files": [
|
|
"lib"
|
|
],
|
|
"homepage": "https://github.com/indutny/elliptic",
|
|
"keywords": [
|
|
"EC",
|
|
"Elliptic",
|
|
"curve",
|
|
"Cryptography"
|
|
],
|
|
"license": "MIT",
|
|
"main": "lib/elliptic.js",
|
|
"name": "elliptic",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "git+ssh://git@github.com/indutny/elliptic.git"
|
|
},
|
|
"scripts": {
|
|
"jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
|
|
"jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
|
|
"lint": "npm run jscs && npm run jshint",
|
|
"test": "npm run lint && npm run unit",
|
|
"unit": "istanbul test _mocha --reporter=spec test/index.js",
|
|
"version": "grunt dist && git add dist/"
|
|
},
|
|
"version": "6.5.2"
|
|
}
|
|
|
|
},{}],24:[function(require,module,exports){
|
|
'use strict'
|
|
var Buffer = require('safe-buffer').Buffer
|
|
var Transform = require('stream').Transform
|
|
var inherits = require('inherits')
|
|
|
|
function throwIfNotStringOrBuffer (val, prefix) {
|
|
if (!Buffer.isBuffer(val) && typeof val !== 'string') {
|
|
throw new TypeError(prefix + ' must be a string or a buffer')
|
|
}
|
|
}
|
|
|
|
function HashBase (blockSize) {
|
|
Transform.call(this)
|
|
|
|
this._block = Buffer.allocUnsafe(blockSize)
|
|
this._blockSize = blockSize
|
|
this._blockOffset = 0
|
|
this._length = [0, 0, 0, 0]
|
|
|
|
this._finalized = false
|
|
}
|
|
|
|
inherits(HashBase, Transform)
|
|
|
|
HashBase.prototype._transform = function (chunk, encoding, callback) {
|
|
var error = null
|
|
try {
|
|
this.update(chunk, encoding)
|
|
} catch (err) {
|
|
error = err
|
|
}
|
|
|
|
callback(error)
|
|
}
|
|
|
|
HashBase.prototype._flush = function (callback) {
|
|
var error = null
|
|
try {
|
|
this.push(this.digest())
|
|
} catch (err) {
|
|
error = err
|
|
}
|
|
|
|
callback(error)
|
|
}
|
|
|
|
HashBase.prototype.update = function (data, encoding) {
|
|
throwIfNotStringOrBuffer(data, 'Data')
|
|
if (this._finalized) throw new Error('Digest already called')
|
|
if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding)
|
|
|
|
// consume data
|
|
var block = this._block
|
|
var offset = 0
|
|
while (this._blockOffset + data.length - offset >= this._blockSize) {
|
|
for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++]
|
|
this._update()
|
|
this._blockOffset = 0
|
|
}
|
|
while (offset < data.length) block[this._blockOffset++] = data[offset++]
|
|
|
|
// update length
|
|
for (var j = 0, carry = data.length * 8; carry > 0; ++j) {
|
|
this._length[j] += carry
|
|
carry = (this._length[j] / 0x0100000000) | 0
|
|
if (carry > 0) this._length[j] -= 0x0100000000 * carry
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
HashBase.prototype._update = function () {
|
|
throw new Error('_update is not implemented')
|
|
}
|
|
|
|
HashBase.prototype.digest = function (encoding) {
|
|
if (this._finalized) throw new Error('Digest already called')
|
|
this._finalized = true
|
|
|
|
var digest = this._digest()
|
|
if (encoding !== undefined) digest = digest.toString(encoding)
|
|
|
|
// reset state
|
|
this._block.fill(0)
|
|
this._blockOffset = 0
|
|
for (var i = 0; i < 4; ++i) this._length[i] = 0
|
|
|
|
return digest
|
|
}
|
|
|
|
HashBase.prototype._digest = function () {
|
|
throw new Error('_digest is not implemented')
|
|
}
|
|
|
|
module.exports = HashBase
|
|
|
|
},{"inherits":38,"safe-buffer":85,"stream":126}],25:[function(require,module,exports){
|
|
var hash = exports;
|
|
|
|
hash.utils = require('./hash/utils');
|
|
hash.common = require('./hash/common');
|
|
hash.sha = require('./hash/sha');
|
|
hash.ripemd = require('./hash/ripemd');
|
|
hash.hmac = require('./hash/hmac');
|
|
|
|
// Proxy hash functions to the main object
|
|
hash.sha1 = hash.sha.sha1;
|
|
hash.sha256 = hash.sha.sha256;
|
|
hash.sha224 = hash.sha.sha224;
|
|
hash.sha384 = hash.sha.sha384;
|
|
hash.sha512 = hash.sha.sha512;
|
|
hash.ripemd160 = hash.ripemd.ripemd160;
|
|
|
|
},{"./hash/common":26,"./hash/hmac":27,"./hash/ripemd":28,"./hash/sha":29,"./hash/utils":36}],26:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./utils');
|
|
var assert = require('minimalistic-assert');
|
|
|
|
function BlockHash() {
|
|
this.pending = null;
|
|
this.pendingTotal = 0;
|
|
this.blockSize = this.constructor.blockSize;
|
|
this.outSize = this.constructor.outSize;
|
|
this.hmacStrength = this.constructor.hmacStrength;
|
|
this.padLength = this.constructor.padLength / 8;
|
|
this.endian = 'big';
|
|
|
|
this._delta8 = this.blockSize / 8;
|
|
this._delta32 = this.blockSize / 32;
|
|
}
|
|
exports.BlockHash = BlockHash;
|
|
|
|
BlockHash.prototype.update = function update(msg, enc) {
|
|
// Convert message to array, pad it, and join into 32bit blocks
|
|
msg = utils.toArray(msg, enc);
|
|
if (!this.pending)
|
|
this.pending = msg;
|
|
else
|
|
this.pending = this.pending.concat(msg);
|
|
this.pendingTotal += msg.length;
|
|
|
|
// Enough data, try updating
|
|
if (this.pending.length >= this._delta8) {
|
|
msg = this.pending;
|
|
|
|
// Process pending data in blocks
|
|
var r = msg.length % this._delta8;
|
|
this.pending = msg.slice(msg.length - r, msg.length);
|
|
if (this.pending.length === 0)
|
|
this.pending = null;
|
|
|
|
msg = utils.join32(msg, 0, msg.length - r, this.endian);
|
|
for (var i = 0; i < msg.length; i += this._delta32)
|
|
this._update(msg, i, i + this._delta32);
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
BlockHash.prototype.digest = function digest(enc) {
|
|
this.update(this._pad());
|
|
assert(this.pending === null);
|
|
|
|
return this._digest(enc);
|
|
};
|
|
|
|
BlockHash.prototype._pad = function pad() {
|
|
var len = this.pendingTotal;
|
|
var bytes = this._delta8;
|
|
var k = bytes - ((len + this.padLength) % bytes);
|
|
var res = new Array(k + this.padLength);
|
|
res[0] = 0x80;
|
|
for (var i = 1; i < k; i++)
|
|
res[i] = 0;
|
|
|
|
// Append length
|
|
len <<= 3;
|
|
if (this.endian === 'big') {
|
|
for (var t = 8; t < this.padLength; t++)
|
|
res[i++] = 0;
|
|
|
|
res[i++] = 0;
|
|
res[i++] = 0;
|
|
res[i++] = 0;
|
|
res[i++] = 0;
|
|
res[i++] = (len >>> 24) & 0xff;
|
|
res[i++] = (len >>> 16) & 0xff;
|
|
res[i++] = (len >>> 8) & 0xff;
|
|
res[i++] = len & 0xff;
|
|
} else {
|
|
res[i++] = len & 0xff;
|
|
res[i++] = (len >>> 8) & 0xff;
|
|
res[i++] = (len >>> 16) & 0xff;
|
|
res[i++] = (len >>> 24) & 0xff;
|
|
res[i++] = 0;
|
|
res[i++] = 0;
|
|
res[i++] = 0;
|
|
res[i++] = 0;
|
|
|
|
for (t = 8; t < this.padLength; t++)
|
|
res[i++] = 0;
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
},{"./utils":36,"minimalistic-assert":41}],27:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./utils');
|
|
var assert = require('minimalistic-assert');
|
|
|
|
function Hmac(hash, key, enc) {
|
|
if (!(this instanceof Hmac))
|
|
return new Hmac(hash, key, enc);
|
|
this.Hash = hash;
|
|
this.blockSize = hash.blockSize / 8;
|
|
this.outSize = hash.outSize / 8;
|
|
this.inner = null;
|
|
this.outer = null;
|
|
|
|
this._init(utils.toArray(key, enc));
|
|
}
|
|
module.exports = Hmac;
|
|
|
|
Hmac.prototype._init = function init(key) {
|
|
// Shorten key, if needed
|
|
if (key.length > this.blockSize)
|
|
key = new this.Hash().update(key).digest();
|
|
assert(key.length <= this.blockSize);
|
|
|
|
// Add padding to key
|
|
for (var i = key.length; i < this.blockSize; i++)
|
|
key.push(0);
|
|
|
|
for (i = 0; i < key.length; i++)
|
|
key[i] ^= 0x36;
|
|
this.inner = new this.Hash().update(key);
|
|
|
|
// 0x36 ^ 0x5c = 0x6a
|
|
for (i = 0; i < key.length; i++)
|
|
key[i] ^= 0x6a;
|
|
this.outer = new this.Hash().update(key);
|
|
};
|
|
|
|
Hmac.prototype.update = function update(msg, enc) {
|
|
this.inner.update(msg, enc);
|
|
return this;
|
|
};
|
|
|
|
Hmac.prototype.digest = function digest(enc) {
|
|
this.outer.update(this.inner.digest());
|
|
return this.outer.digest(enc);
|
|
};
|
|
|
|
},{"./utils":36,"minimalistic-assert":41}],28:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('./utils');
|
|
var common = require('./common');
|
|
|
|
var rotl32 = utils.rotl32;
|
|
var sum32 = utils.sum32;
|
|
var sum32_3 = utils.sum32_3;
|
|
var sum32_4 = utils.sum32_4;
|
|
var BlockHash = common.BlockHash;
|
|
|
|
function RIPEMD160() {
|
|
if (!(this instanceof RIPEMD160))
|
|
return new RIPEMD160();
|
|
|
|
BlockHash.call(this);
|
|
|
|
this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
|
|
this.endian = 'little';
|
|
}
|
|
utils.inherits(RIPEMD160, BlockHash);
|
|
exports.ripemd160 = RIPEMD160;
|
|
|
|
RIPEMD160.blockSize = 512;
|
|
RIPEMD160.outSize = 160;
|
|
RIPEMD160.hmacStrength = 192;
|
|
RIPEMD160.padLength = 64;
|
|
|
|
RIPEMD160.prototype._update = function update(msg, start) {
|
|
var A = this.h[0];
|
|
var B = this.h[1];
|
|
var C = this.h[2];
|
|
var D = this.h[3];
|
|
var E = this.h[4];
|
|
var Ah = A;
|
|
var Bh = B;
|
|
var Ch = C;
|
|
var Dh = D;
|
|
var Eh = E;
|
|
for (var j = 0; j < 80; j++) {
|
|
var T = sum32(
|
|
rotl32(
|
|
sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
|
|
s[j]),
|
|
E);
|
|
A = E;
|
|
E = D;
|
|
D = rotl32(C, 10);
|
|
C = B;
|
|
B = T;
|
|
T = sum32(
|
|
rotl32(
|
|
sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
|
|
sh[j]),
|
|
Eh);
|
|
Ah = Eh;
|
|
Eh = Dh;
|
|
Dh = rotl32(Ch, 10);
|
|
Ch = Bh;
|
|
Bh = T;
|
|
}
|
|
T = sum32_3(this.h[1], C, Dh);
|
|
this.h[1] = sum32_3(this.h[2], D, Eh);
|
|
this.h[2] = sum32_3(this.h[3], E, Ah);
|
|
this.h[3] = sum32_3(this.h[4], A, Bh);
|
|
this.h[4] = sum32_3(this.h[0], B, Ch);
|
|
this.h[0] = T;
|
|
};
|
|
|
|
RIPEMD160.prototype._digest = function digest(enc) {
|
|
if (enc === 'hex')
|
|
return utils.toHex32(this.h, 'little');
|
|
else
|
|
return utils.split32(this.h, 'little');
|
|
};
|
|
|
|
function f(j, x, y, z) {
|
|
if (j <= 15)
|
|
return x ^ y ^ z;
|
|
else if (j <= 31)
|
|
return (x & y) | ((~x) & z);
|
|
else if (j <= 47)
|
|
return (x | (~y)) ^ z;
|
|
else if (j <= 63)
|
|
return (x & z) | (y & (~z));
|
|
else
|
|
return x ^ (y | (~z));
|
|
}
|
|
|
|
function K(j) {
|
|
if (j <= 15)
|
|
return 0x00000000;
|
|
else if (j <= 31)
|
|
return 0x5a827999;
|
|
else if (j <= 47)
|
|
return 0x6ed9eba1;
|
|
else if (j <= 63)
|
|
return 0x8f1bbcdc;
|
|
else
|
|
return 0xa953fd4e;
|
|
}
|
|
|
|
function Kh(j) {
|
|
if (j <= 15)
|
|
return 0x50a28be6;
|
|
else if (j <= 31)
|
|
return 0x5c4dd124;
|
|
else if (j <= 47)
|
|
return 0x6d703ef3;
|
|
else if (j <= 63)
|
|
return 0x7a6d76e9;
|
|
else
|
|
return 0x00000000;
|
|
}
|
|
|
|
var r = [
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
|
|
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
|
|
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
|
|
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
|
];
|
|
|
|
var rh = [
|
|
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
|
|
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
|
|
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
|
|
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
|
|
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
|
];
|
|
|
|
var s = [
|
|
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
|
|
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
|
|
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
|
|
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
|
|
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
|
];
|
|
|
|
var sh = [
|
|
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
|
|
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
|
|
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
|
|
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
|
|
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
|
];
|
|
|
|
},{"./common":26,"./utils":36}],29:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
exports.sha1 = require('./sha/1');
|
|
exports.sha224 = require('./sha/224');
|
|
exports.sha256 = require('./sha/256');
|
|
exports.sha384 = require('./sha/384');
|
|
exports.sha512 = require('./sha/512');
|
|
|
|
},{"./sha/1":30,"./sha/224":31,"./sha/256":32,"./sha/384":33,"./sha/512":34}],30:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var common = require('../common');
|
|
var shaCommon = require('./common');
|
|
|
|
var rotl32 = utils.rotl32;
|
|
var sum32 = utils.sum32;
|
|
var sum32_5 = utils.sum32_5;
|
|
var ft_1 = shaCommon.ft_1;
|
|
var BlockHash = common.BlockHash;
|
|
|
|
var sha1_K = [
|
|
0x5A827999, 0x6ED9EBA1,
|
|
0x8F1BBCDC, 0xCA62C1D6
|
|
];
|
|
|
|
function SHA1() {
|
|
if (!(this instanceof SHA1))
|
|
return new SHA1();
|
|
|
|
BlockHash.call(this);
|
|
this.h = [
|
|
0x67452301, 0xefcdab89, 0x98badcfe,
|
|
0x10325476, 0xc3d2e1f0 ];
|
|
this.W = new Array(80);
|
|
}
|
|
|
|
utils.inherits(SHA1, BlockHash);
|
|
module.exports = SHA1;
|
|
|
|
SHA1.blockSize = 512;
|
|
SHA1.outSize = 160;
|
|
SHA1.hmacStrength = 80;
|
|
SHA1.padLength = 64;
|
|
|
|
SHA1.prototype._update = function _update(msg, start) {
|
|
var W = this.W;
|
|
|
|
for (var i = 0; i < 16; i++)
|
|
W[i] = msg[start + i];
|
|
|
|
for(; i < W.length; i++)
|
|
W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
|
|
|
|
var a = this.h[0];
|
|
var b = this.h[1];
|
|
var c = this.h[2];
|
|
var d = this.h[3];
|
|
var e = this.h[4];
|
|
|
|
for (i = 0; i < W.length; i++) {
|
|
var s = ~~(i / 20);
|
|
var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
|
|
e = d;
|
|
d = c;
|
|
c = rotl32(b, 30);
|
|
b = a;
|
|
a = t;
|
|
}
|
|
|
|
this.h[0] = sum32(this.h[0], a);
|
|
this.h[1] = sum32(this.h[1], b);
|
|
this.h[2] = sum32(this.h[2], c);
|
|
this.h[3] = sum32(this.h[3], d);
|
|
this.h[4] = sum32(this.h[4], e);
|
|
};
|
|
|
|
SHA1.prototype._digest = function digest(enc) {
|
|
if (enc === 'hex')
|
|
return utils.toHex32(this.h, 'big');
|
|
else
|
|
return utils.split32(this.h, 'big');
|
|
};
|
|
|
|
},{"../common":26,"../utils":36,"./common":35}],31:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var SHA256 = require('./256');
|
|
|
|
function SHA224() {
|
|
if (!(this instanceof SHA224))
|
|
return new SHA224();
|
|
|
|
SHA256.call(this);
|
|
this.h = [
|
|
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
|
|
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
|
|
}
|
|
utils.inherits(SHA224, SHA256);
|
|
module.exports = SHA224;
|
|
|
|
SHA224.blockSize = 512;
|
|
SHA224.outSize = 224;
|
|
SHA224.hmacStrength = 192;
|
|
SHA224.padLength = 64;
|
|
|
|
SHA224.prototype._digest = function digest(enc) {
|
|
// Just truncate output
|
|
if (enc === 'hex')
|
|
return utils.toHex32(this.h.slice(0, 7), 'big');
|
|
else
|
|
return utils.split32(this.h.slice(0, 7), 'big');
|
|
};
|
|
|
|
|
|
},{"../utils":36,"./256":32}],32:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var common = require('../common');
|
|
var shaCommon = require('./common');
|
|
var assert = require('minimalistic-assert');
|
|
|
|
var sum32 = utils.sum32;
|
|
var sum32_4 = utils.sum32_4;
|
|
var sum32_5 = utils.sum32_5;
|
|
var ch32 = shaCommon.ch32;
|
|
var maj32 = shaCommon.maj32;
|
|
var s0_256 = shaCommon.s0_256;
|
|
var s1_256 = shaCommon.s1_256;
|
|
var g0_256 = shaCommon.g0_256;
|
|
var g1_256 = shaCommon.g1_256;
|
|
|
|
var BlockHash = common.BlockHash;
|
|
|
|
var sha256_K = [
|
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
];
|
|
|
|
function SHA256() {
|
|
if (!(this instanceof SHA256))
|
|
return new SHA256();
|
|
|
|
BlockHash.call(this);
|
|
this.h = [
|
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
|
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
|
];
|
|
this.k = sha256_K;
|
|
this.W = new Array(64);
|
|
}
|
|
utils.inherits(SHA256, BlockHash);
|
|
module.exports = SHA256;
|
|
|
|
SHA256.blockSize = 512;
|
|
SHA256.outSize = 256;
|
|
SHA256.hmacStrength = 192;
|
|
SHA256.padLength = 64;
|
|
|
|
SHA256.prototype._update = function _update(msg, start) {
|
|
var W = this.W;
|
|
|
|
for (var i = 0; i < 16; i++)
|
|
W[i] = msg[start + i];
|
|
for (; i < W.length; i++)
|
|
W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
|
|
|
|
var a = this.h[0];
|
|
var b = this.h[1];
|
|
var c = this.h[2];
|
|
var d = this.h[3];
|
|
var e = this.h[4];
|
|
var f = this.h[5];
|
|
var g = this.h[6];
|
|
var h = this.h[7];
|
|
|
|
assert(this.k.length === W.length);
|
|
for (i = 0; i < W.length; i++) {
|
|
var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
|
|
var T2 = sum32(s0_256(a), maj32(a, b, c));
|
|
h = g;
|
|
g = f;
|
|
f = e;
|
|
e = sum32(d, T1);
|
|
d = c;
|
|
c = b;
|
|
b = a;
|
|
a = sum32(T1, T2);
|
|
}
|
|
|
|
this.h[0] = sum32(this.h[0], a);
|
|
this.h[1] = sum32(this.h[1], b);
|
|
this.h[2] = sum32(this.h[2], c);
|
|
this.h[3] = sum32(this.h[3], d);
|
|
this.h[4] = sum32(this.h[4], e);
|
|
this.h[5] = sum32(this.h[5], f);
|
|
this.h[6] = sum32(this.h[6], g);
|
|
this.h[7] = sum32(this.h[7], h);
|
|
};
|
|
|
|
SHA256.prototype._digest = function digest(enc) {
|
|
if (enc === 'hex')
|
|
return utils.toHex32(this.h, 'big');
|
|
else
|
|
return utils.split32(this.h, 'big');
|
|
};
|
|
|
|
},{"../common":26,"../utils":36,"./common":35,"minimalistic-assert":41}],33:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
|
|
var SHA512 = require('./512');
|
|
|
|
function SHA384() {
|
|
if (!(this instanceof SHA384))
|
|
return new SHA384();
|
|
|
|
SHA512.call(this);
|
|
this.h = [
|
|
0xcbbb9d5d, 0xc1059ed8,
|
|
0x629a292a, 0x367cd507,
|
|
0x9159015a, 0x3070dd17,
|
|
0x152fecd8, 0xf70e5939,
|
|
0x67332667, 0xffc00b31,
|
|
0x8eb44a87, 0x68581511,
|
|
0xdb0c2e0d, 0x64f98fa7,
|
|
0x47b5481d, 0xbefa4fa4 ];
|
|
}
|
|
utils.inherits(SHA384, SHA512);
|
|
module.exports = SHA384;
|
|
|
|
SHA384.blockSize = 1024;
|
|
SHA384.outSize = 384;
|
|
SHA384.hmacStrength = 192;
|
|
SHA384.padLength = 128;
|
|
|
|
SHA384.prototype._digest = function digest(enc) {
|
|
if (enc === 'hex')
|
|
return utils.toHex32(this.h.slice(0, 12), 'big');
|
|
else
|
|
return utils.split32(this.h.slice(0, 12), 'big');
|
|
};
|
|
|
|
},{"../utils":36,"./512":34}],34:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var common = require('../common');
|
|
var assert = require('minimalistic-assert');
|
|
|
|
var rotr64_hi = utils.rotr64_hi;
|
|
var rotr64_lo = utils.rotr64_lo;
|
|
var shr64_hi = utils.shr64_hi;
|
|
var shr64_lo = utils.shr64_lo;
|
|
var sum64 = utils.sum64;
|
|
var sum64_hi = utils.sum64_hi;
|
|
var sum64_lo = utils.sum64_lo;
|
|
var sum64_4_hi = utils.sum64_4_hi;
|
|
var sum64_4_lo = utils.sum64_4_lo;
|
|
var sum64_5_hi = utils.sum64_5_hi;
|
|
var sum64_5_lo = utils.sum64_5_lo;
|
|
|
|
var BlockHash = common.BlockHash;
|
|
|
|
var sha512_K = [
|
|
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
|
|
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
|
|
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
|
|
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
|
|
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
|
|
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
|
|
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
|
|
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
|
|
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
|
|
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
|
|
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
|
|
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
|
|
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
|
|
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
|
|
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
|
|
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
|
|
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
|
|
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
|
|
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
|
|
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
|
|
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
|
|
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
|
|
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
|
|
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
|
|
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
|
|
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
|
|
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
|
|
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
|
|
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
|
|
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
|
|
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
|
|
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
|
|
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
|
|
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
|
|
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
|
|
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
|
|
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
|
|
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
|
|
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
|
|
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
|
|
];
|
|
|
|
function SHA512() {
|
|
if (!(this instanceof SHA512))
|
|
return new SHA512();
|
|
|
|
BlockHash.call(this);
|
|
this.h = [
|
|
0x6a09e667, 0xf3bcc908,
|
|
0xbb67ae85, 0x84caa73b,
|
|
0x3c6ef372, 0xfe94f82b,
|
|
0xa54ff53a, 0x5f1d36f1,
|
|
0x510e527f, 0xade682d1,
|
|
0x9b05688c, 0x2b3e6c1f,
|
|
0x1f83d9ab, 0xfb41bd6b,
|
|
0x5be0cd19, 0x137e2179 ];
|
|
this.k = sha512_K;
|
|
this.W = new Array(160);
|
|
}
|
|
utils.inherits(SHA512, BlockHash);
|
|
module.exports = SHA512;
|
|
|
|
SHA512.blockSize = 1024;
|
|
SHA512.outSize = 512;
|
|
SHA512.hmacStrength = 192;
|
|
SHA512.padLength = 128;
|
|
|
|
SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
|
|
var W = this.W;
|
|
|
|
// 32 x 32bit words
|
|
for (var i = 0; i < 32; i++)
|
|
W[i] = msg[start + i];
|
|
for (; i < W.length; i += 2) {
|
|
var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
|
|
var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
|
|
var c1_hi = W[i - 14]; // i - 7
|
|
var c1_lo = W[i - 13];
|
|
var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
|
|
var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
|
|
var c3_hi = W[i - 32]; // i - 16
|
|
var c3_lo = W[i - 31];
|
|
|
|
W[i] = sum64_4_hi(
|
|
c0_hi, c0_lo,
|
|
c1_hi, c1_lo,
|
|
c2_hi, c2_lo,
|
|
c3_hi, c3_lo);
|
|
W[i + 1] = sum64_4_lo(
|
|
c0_hi, c0_lo,
|
|
c1_hi, c1_lo,
|
|
c2_hi, c2_lo,
|
|
c3_hi, c3_lo);
|
|
}
|
|
};
|
|
|
|
SHA512.prototype._update = function _update(msg, start) {
|
|
this._prepareBlock(msg, start);
|
|
|
|
var W = this.W;
|
|
|
|
var ah = this.h[0];
|
|
var al = this.h[1];
|
|
var bh = this.h[2];
|
|
var bl = this.h[3];
|
|
var ch = this.h[4];
|
|
var cl = this.h[5];
|
|
var dh = this.h[6];
|
|
var dl = this.h[7];
|
|
var eh = this.h[8];
|
|
var el = this.h[9];
|
|
var fh = this.h[10];
|
|
var fl = this.h[11];
|
|
var gh = this.h[12];
|
|
var gl = this.h[13];
|
|
var hh = this.h[14];
|
|
var hl = this.h[15];
|
|
|
|
assert(this.k.length === W.length);
|
|
for (var i = 0; i < W.length; i += 2) {
|
|
var c0_hi = hh;
|
|
var c0_lo = hl;
|
|
var c1_hi = s1_512_hi(eh, el);
|
|
var c1_lo = s1_512_lo(eh, el);
|
|
var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
|
|
var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
|
|
var c3_hi = this.k[i];
|
|
var c3_lo = this.k[i + 1];
|
|
var c4_hi = W[i];
|
|
var c4_lo = W[i + 1];
|
|
|
|
var T1_hi = sum64_5_hi(
|
|
c0_hi, c0_lo,
|
|
c1_hi, c1_lo,
|
|
c2_hi, c2_lo,
|
|
c3_hi, c3_lo,
|
|
c4_hi, c4_lo);
|
|
var T1_lo = sum64_5_lo(
|
|
c0_hi, c0_lo,
|
|
c1_hi, c1_lo,
|
|
c2_hi, c2_lo,
|
|
c3_hi, c3_lo,
|
|
c4_hi, c4_lo);
|
|
|
|
c0_hi = s0_512_hi(ah, al);
|
|
c0_lo = s0_512_lo(ah, al);
|
|
c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
|
|
c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
|
|
|
|
var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
|
|
var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
|
|
|
|
hh = gh;
|
|
hl = gl;
|
|
|
|
gh = fh;
|
|
gl = fl;
|
|
|
|
fh = eh;
|
|
fl = el;
|
|
|
|
eh = sum64_hi(dh, dl, T1_hi, T1_lo);
|
|
el = sum64_lo(dl, dl, T1_hi, T1_lo);
|
|
|
|
dh = ch;
|
|
dl = cl;
|
|
|
|
ch = bh;
|
|
cl = bl;
|
|
|
|
bh = ah;
|
|
bl = al;
|
|
|
|
ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
|
|
al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
|
|
}
|
|
|
|
sum64(this.h, 0, ah, al);
|
|
sum64(this.h, 2, bh, bl);
|
|
sum64(this.h, 4, ch, cl);
|
|
sum64(this.h, 6, dh, dl);
|
|
sum64(this.h, 8, eh, el);
|
|
sum64(this.h, 10, fh, fl);
|
|
sum64(this.h, 12, gh, gl);
|
|
sum64(this.h, 14, hh, hl);
|
|
};
|
|
|
|
SHA512.prototype._digest = function digest(enc) {
|
|
if (enc === 'hex')
|
|
return utils.toHex32(this.h, 'big');
|
|
else
|
|
return utils.split32(this.h, 'big');
|
|
};
|
|
|
|
function ch64_hi(xh, xl, yh, yl, zh) {
|
|
var r = (xh & yh) ^ ((~xh) & zh);
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function ch64_lo(xh, xl, yh, yl, zh, zl) {
|
|
var r = (xl & yl) ^ ((~xl) & zl);
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function maj64_hi(xh, xl, yh, yl, zh) {
|
|
var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function maj64_lo(xh, xl, yh, yl, zh, zl) {
|
|
var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function s0_512_hi(xh, xl) {
|
|
var c0_hi = rotr64_hi(xh, xl, 28);
|
|
var c1_hi = rotr64_hi(xl, xh, 2); // 34
|
|
var c2_hi = rotr64_hi(xl, xh, 7); // 39
|
|
|
|
var r = c0_hi ^ c1_hi ^ c2_hi;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function s0_512_lo(xh, xl) {
|
|
var c0_lo = rotr64_lo(xh, xl, 28);
|
|
var c1_lo = rotr64_lo(xl, xh, 2); // 34
|
|
var c2_lo = rotr64_lo(xl, xh, 7); // 39
|
|
|
|
var r = c0_lo ^ c1_lo ^ c2_lo;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function s1_512_hi(xh, xl) {
|
|
var c0_hi = rotr64_hi(xh, xl, 14);
|
|
var c1_hi = rotr64_hi(xh, xl, 18);
|
|
var c2_hi = rotr64_hi(xl, xh, 9); // 41
|
|
|
|
var r = c0_hi ^ c1_hi ^ c2_hi;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function s1_512_lo(xh, xl) {
|
|
var c0_lo = rotr64_lo(xh, xl, 14);
|
|
var c1_lo = rotr64_lo(xh, xl, 18);
|
|
var c2_lo = rotr64_lo(xl, xh, 9); // 41
|
|
|
|
var r = c0_lo ^ c1_lo ^ c2_lo;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function g0_512_hi(xh, xl) {
|
|
var c0_hi = rotr64_hi(xh, xl, 1);
|
|
var c1_hi = rotr64_hi(xh, xl, 8);
|
|
var c2_hi = shr64_hi(xh, xl, 7);
|
|
|
|
var r = c0_hi ^ c1_hi ^ c2_hi;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function g0_512_lo(xh, xl) {
|
|
var c0_lo = rotr64_lo(xh, xl, 1);
|
|
var c1_lo = rotr64_lo(xh, xl, 8);
|
|
var c2_lo = shr64_lo(xh, xl, 7);
|
|
|
|
var r = c0_lo ^ c1_lo ^ c2_lo;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function g1_512_hi(xh, xl) {
|
|
var c0_hi = rotr64_hi(xh, xl, 19);
|
|
var c1_hi = rotr64_hi(xl, xh, 29); // 61
|
|
var c2_hi = shr64_hi(xh, xl, 6);
|
|
|
|
var r = c0_hi ^ c1_hi ^ c2_hi;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
function g1_512_lo(xh, xl) {
|
|
var c0_lo = rotr64_lo(xh, xl, 19);
|
|
var c1_lo = rotr64_lo(xl, xh, 29); // 61
|
|
var c2_lo = shr64_lo(xh, xl, 6);
|
|
|
|
var r = c0_lo ^ c1_lo ^ c2_lo;
|
|
if (r < 0)
|
|
r += 0x100000000;
|
|
return r;
|
|
}
|
|
|
|
},{"../common":26,"../utils":36,"minimalistic-assert":41}],35:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = require('../utils');
|
|
var rotr32 = utils.rotr32;
|
|
|
|
function ft_1(s, x, y, z) {
|
|
if (s === 0)
|
|
return ch32(x, y, z);
|
|
if (s === 1 || s === 3)
|
|
return p32(x, y, z);
|
|
if (s === 2)
|
|
return maj32(x, y, z);
|
|
}
|
|
exports.ft_1 = ft_1;
|
|
|
|
function ch32(x, y, z) {
|
|
return (x & y) ^ ((~x) & z);
|
|
}
|
|
exports.ch32 = ch32;
|
|
|
|
function maj32(x, y, z) {
|
|
return (x & y) ^ (x & z) ^ (y & z);
|
|
}
|
|
exports.maj32 = maj32;
|
|
|
|
function p32(x, y, z) {
|
|
return x ^ y ^ z;
|
|
}
|
|
exports.p32 = p32;
|
|
|
|
function s0_256(x) {
|
|
return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
|
|
}
|
|
exports.s0_256 = s0_256;
|
|
|
|
function s1_256(x) {
|
|
return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
|
|
}
|
|
exports.s1_256 = s1_256;
|
|
|
|
function g0_256(x) {
|
|
return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
|
|
}
|
|
exports.g0_256 = g0_256;
|
|
|
|
function g1_256(x) {
|
|
return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
|
|
}
|
|
exports.g1_256 = g1_256;
|
|
|
|
},{"../utils":36}],36:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var assert = require('minimalistic-assert');
|
|
var inherits = require('inherits');
|
|
|
|
exports.inherits = inherits;
|
|
|
|
function isSurrogatePair(msg, i) {
|
|
if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {
|
|
return false;
|
|
}
|
|
if (i < 0 || i + 1 >= msg.length) {
|
|
return false;
|
|
}
|
|
return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;
|
|
}
|
|
|
|
function toArray(msg, enc) {
|
|
if (Array.isArray(msg))
|
|
return msg.slice();
|
|
if (!msg)
|
|
return [];
|
|
var res = [];
|
|
if (typeof msg === 'string') {
|
|
if (!enc) {
|
|
// Inspired by stringToUtf8ByteArray() in closure-library by Google
|
|
// https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143
|
|
// Apache License 2.0
|
|
// https://github.com/google/closure-library/blob/master/LICENSE
|
|
var p = 0;
|
|
for (var i = 0; i < msg.length; i++) {
|
|
var c = msg.charCodeAt(i);
|
|
if (c < 128) {
|
|
res[p++] = c;
|
|
} else if (c < 2048) {
|
|
res[p++] = (c >> 6) | 192;
|
|
res[p++] = (c & 63) | 128;
|
|
} else if (isSurrogatePair(msg, i)) {
|
|
c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);
|
|
res[p++] = (c >> 18) | 240;
|
|
res[p++] = ((c >> 12) & 63) | 128;
|
|
res[p++] = ((c >> 6) & 63) | 128;
|
|
res[p++] = (c & 63) | 128;
|
|
} else {
|
|
res[p++] = (c >> 12) | 224;
|
|
res[p++] = ((c >> 6) & 63) | 128;
|
|
res[p++] = (c & 63) | 128;
|
|
}
|
|
}
|
|
} else if (enc === 'hex') {
|
|
msg = msg.replace(/[^a-z0-9]+/ig, '');
|
|
if (msg.length % 2 !== 0)
|
|
msg = '0' + msg;
|
|
for (i = 0; i < msg.length; i += 2)
|
|
res.push(parseInt(msg[i] + msg[i + 1], 16));
|
|
}
|
|
} else {
|
|
for (i = 0; i < msg.length; i++)
|
|
res[i] = msg[i] | 0;
|
|
}
|
|
return res;
|
|
}
|
|
exports.toArray = toArray;
|
|
|
|
function toHex(msg) {
|
|
var res = '';
|
|
for (var i = 0; i < msg.length; i++)
|
|
res += zero2(msg[i].toString(16));
|
|
return res;
|
|
}
|
|
exports.toHex = toHex;
|
|
|
|
function htonl(w) {
|
|
var res = (w >>> 24) |
|
|
((w >>> 8) & 0xff00) |
|
|
((w << 8) & 0xff0000) |
|
|
((w & 0xff) << 24);
|
|
return res >>> 0;
|
|
}
|
|
exports.htonl = htonl;
|
|
|
|
function toHex32(msg, endian) {
|
|
var res = '';
|
|
for (var i = 0; i < msg.length; i++) {
|
|
var w = msg[i];
|
|
if (endian === 'little')
|
|
w = htonl(w);
|
|
res += zero8(w.toString(16));
|
|
}
|
|
return res;
|
|
}
|
|
exports.toHex32 = toHex32;
|
|
|
|
function zero2(word) {
|
|
if (word.length === 1)
|
|
return '0' + word;
|
|
else
|
|
return word;
|
|
}
|
|
exports.zero2 = zero2;
|
|
|
|
function zero8(word) {
|
|
if (word.length === 7)
|
|
return '0' + word;
|
|
else if (word.length === 6)
|
|
return '00' + word;
|
|
else if (word.length === 5)
|
|
return '000' + word;
|
|
else if (word.length === 4)
|
|
return '0000' + word;
|
|
else if (word.length === 3)
|
|
return '00000' + word;
|
|
else if (word.length === 2)
|
|
return '000000' + word;
|
|
else if (word.length === 1)
|
|
return '0000000' + word;
|
|
else
|
|
return word;
|
|
}
|
|
exports.zero8 = zero8;
|
|
|
|
function join32(msg, start, end, endian) {
|
|
var len = end - start;
|
|
assert(len % 4 === 0);
|
|
var res = new Array(len / 4);
|
|
for (var i = 0, k = start; i < res.length; i++, k += 4) {
|
|
var w;
|
|
if (endian === 'big')
|
|
w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
|
|
else
|
|
w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
|
|
res[i] = w >>> 0;
|
|
}
|
|
return res;
|
|
}
|
|
exports.join32 = join32;
|
|
|
|
function split32(msg, endian) {
|
|
var res = new Array(msg.length * 4);
|
|
for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
|
|
var m = msg[i];
|
|
if (endian === 'big') {
|
|
res[k] = m >>> 24;
|
|
res[k + 1] = (m >>> 16) & 0xff;
|
|
res[k + 2] = (m >>> 8) & 0xff;
|
|
res[k + 3] = m & 0xff;
|
|
} else {
|
|
res[k + 3] = m >>> 24;
|
|
res[k + 2] = (m >>> 16) & 0xff;
|
|
res[k + 1] = (m >>> 8) & 0xff;
|
|
res[k] = m & 0xff;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
exports.split32 = split32;
|
|
|
|
function rotr32(w, b) {
|
|
return (w >>> b) | (w << (32 - b));
|
|
}
|
|
exports.rotr32 = rotr32;
|
|
|
|
function rotl32(w, b) {
|
|
return (w << b) | (w >>> (32 - b));
|
|
}
|
|
exports.rotl32 = rotl32;
|
|
|
|
function sum32(a, b) {
|
|
return (a + b) >>> 0;
|
|
}
|
|
exports.sum32 = sum32;
|
|
|
|
function sum32_3(a, b, c) {
|
|
return (a + b + c) >>> 0;
|
|
}
|
|
exports.sum32_3 = sum32_3;
|
|
|
|
function sum32_4(a, b, c, d) {
|
|
return (a + b + c + d) >>> 0;
|
|
}
|
|
exports.sum32_4 = sum32_4;
|
|
|
|
function sum32_5(a, b, c, d, e) {
|
|
return (a + b + c + d + e) >>> 0;
|
|
}
|
|
exports.sum32_5 = sum32_5;
|
|
|
|
function sum64(buf, pos, ah, al) {
|
|
var bh = buf[pos];
|
|
var bl = buf[pos + 1];
|
|
|
|
var lo = (al + bl) >>> 0;
|
|
var hi = (lo < al ? 1 : 0) + ah + bh;
|
|
buf[pos] = hi >>> 0;
|
|
buf[pos + 1] = lo;
|
|
}
|
|
exports.sum64 = sum64;
|
|
|
|
function sum64_hi(ah, al, bh, bl) {
|
|
var lo = (al + bl) >>> 0;
|
|
var hi = (lo < al ? 1 : 0) + ah + bh;
|
|
return hi >>> 0;
|
|
}
|
|
exports.sum64_hi = sum64_hi;
|
|
|
|
function sum64_lo(ah, al, bh, bl) {
|
|
var lo = al + bl;
|
|
return lo >>> 0;
|
|
}
|
|
exports.sum64_lo = sum64_lo;
|
|
|
|
function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
|
|
var carry = 0;
|
|
var lo = al;
|
|
lo = (lo + bl) >>> 0;
|
|
carry += lo < al ? 1 : 0;
|
|
lo = (lo + cl) >>> 0;
|
|
carry += lo < cl ? 1 : 0;
|
|
lo = (lo + dl) >>> 0;
|
|
carry += lo < dl ? 1 : 0;
|
|
|
|
var hi = ah + bh + ch + dh + carry;
|
|
return hi >>> 0;
|
|
}
|
|
exports.sum64_4_hi = sum64_4_hi;
|
|
|
|
function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
|
|
var lo = al + bl + cl + dl;
|
|
return lo >>> 0;
|
|
}
|
|
exports.sum64_4_lo = sum64_4_lo;
|
|
|
|
function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
|
|
var carry = 0;
|
|
var lo = al;
|
|
lo = (lo + bl) >>> 0;
|
|
carry += lo < al ? 1 : 0;
|
|
lo = (lo + cl) >>> 0;
|
|
carry += lo < cl ? 1 : 0;
|
|
lo = (lo + dl) >>> 0;
|
|
carry += lo < dl ? 1 : 0;
|
|
lo = (lo + el) >>> 0;
|
|
carry += lo < el ? 1 : 0;
|
|
|
|
var hi = ah + bh + ch + dh + eh + carry;
|
|
return hi >>> 0;
|
|
}
|
|
exports.sum64_5_hi = sum64_5_hi;
|
|
|
|
function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
|
|
var lo = al + bl + cl + dl + el;
|
|
|
|
return lo >>> 0;
|
|
}
|
|
exports.sum64_5_lo = sum64_5_lo;
|
|
|
|
function rotr64_hi(ah, al, num) {
|
|
var r = (al << (32 - num)) | (ah >>> num);
|
|
return r >>> 0;
|
|
}
|
|
exports.rotr64_hi = rotr64_hi;
|
|
|
|
function rotr64_lo(ah, al, num) {
|
|
var r = (ah << (32 - num)) | (al >>> num);
|
|
return r >>> 0;
|
|
}
|
|
exports.rotr64_lo = rotr64_lo;
|
|
|
|
function shr64_hi(ah, al, num) {
|
|
return ah >>> num;
|
|
}
|
|
exports.shr64_hi = shr64_hi;
|
|
|
|
function shr64_lo(ah, al, num) {
|
|
var r = (ah << (32 - num)) | (al >>> num);
|
|
return r >>> 0;
|
|
}
|
|
exports.shr64_lo = shr64_lo;
|
|
|
|
},{"inherits":38,"minimalistic-assert":41}],37:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var hash = require('hash.js');
|
|
var utils = require('minimalistic-crypto-utils');
|
|
var assert = require('minimalistic-assert');
|
|
|
|
function HmacDRBG(options) {
|
|
if (!(this instanceof HmacDRBG))
|
|
return new HmacDRBG(options);
|
|
this.hash = options.hash;
|
|
this.predResist = !!options.predResist;
|
|
|
|
this.outLen = this.hash.outSize;
|
|
this.minEntropy = options.minEntropy || this.hash.hmacStrength;
|
|
|
|
this._reseed = null;
|
|
this.reseedInterval = null;
|
|
this.K = null;
|
|
this.V = null;
|
|
|
|
var entropy = utils.toArray(options.entropy, options.entropyEnc || 'hex');
|
|
var nonce = utils.toArray(options.nonce, options.nonceEnc || 'hex');
|
|
var pers = utils.toArray(options.pers, options.persEnc || 'hex');
|
|
assert(entropy.length >= (this.minEntropy / 8),
|
|
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
|
|
this._init(entropy, nonce, pers);
|
|
}
|
|
module.exports = HmacDRBG;
|
|
|
|
HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
|
|
var seed = entropy.concat(nonce).concat(pers);
|
|
|
|
this.K = new Array(this.outLen / 8);
|
|
this.V = new Array(this.outLen / 8);
|
|
for (var i = 0; i < this.V.length; i++) {
|
|
this.K[i] = 0x00;
|
|
this.V[i] = 0x01;
|
|
}
|
|
|
|
this._update(seed);
|
|
this._reseed = 1;
|
|
this.reseedInterval = 0x1000000000000; // 2^48
|
|
};
|
|
|
|
HmacDRBG.prototype._hmac = function hmac() {
|
|
return new hash.hmac(this.hash, this.K);
|
|
};
|
|
|
|
HmacDRBG.prototype._update = function update(seed) {
|
|
var kmac = this._hmac()
|
|
.update(this.V)
|
|
.update([ 0x00 ]);
|
|
if (seed)
|
|
kmac = kmac.update(seed);
|
|
this.K = kmac.digest();
|
|
this.V = this._hmac().update(this.V).digest();
|
|
if (!seed)
|
|
return;
|
|
|
|
this.K = this._hmac()
|
|
.update(this.V)
|
|
.update([ 0x01 ])
|
|
.update(seed)
|
|
.digest();
|
|
this.V = this._hmac().update(this.V).digest();
|
|
};
|
|
|
|
HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
|
|
// Optional entropy enc
|
|
if (typeof entropyEnc !== 'string') {
|
|
addEnc = add;
|
|
add = entropyEnc;
|
|
entropyEnc = null;
|
|
}
|
|
|
|
entropy = utils.toArray(entropy, entropyEnc);
|
|
add = utils.toArray(add, addEnc);
|
|
|
|
assert(entropy.length >= (this.minEntropy / 8),
|
|
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
|
|
|
|
this._update(entropy.concat(add || []));
|
|
this._reseed = 1;
|
|
};
|
|
|
|
HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
|
|
if (this._reseed > this.reseedInterval)
|
|
throw new Error('Reseed is required');
|
|
|
|
// Optional encoding
|
|
if (typeof enc !== 'string') {
|
|
addEnc = add;
|
|
add = enc;
|
|
enc = null;
|
|
}
|
|
|
|
// Optional additional data
|
|
if (add) {
|
|
add = utils.toArray(add, addEnc || 'hex');
|
|
this._update(add);
|
|
}
|
|
|
|
var temp = [];
|
|
while (temp.length < len) {
|
|
this.V = this._hmac().update(this.V).digest();
|
|
temp = temp.concat(this.V);
|
|
}
|
|
|
|
var res = temp.slice(0, len);
|
|
this._update(add);
|
|
this._reseed++;
|
|
return utils.encode(res, enc);
|
|
};
|
|
|
|
},{"hash.js":25,"minimalistic-assert":41,"minimalistic-crypto-utils":42}],38:[function(require,module,exports){
|
|
if (typeof Object.create === 'function') {
|
|
// implementation from standard node.js 'util' module
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
if (superCtor) {
|
|
ctor.super_ = superCtor
|
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|
constructor: {
|
|
value: ctor,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
})
|
|
}
|
|
};
|
|
} else {
|
|
// old school shim for old browsers
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
if (superCtor) {
|
|
ctor.super_ = superCtor
|
|
var TempCtor = function () {}
|
|
TempCtor.prototype = superCtor.prototype
|
|
ctor.prototype = new TempCtor()
|
|
ctor.prototype.constructor = ctor
|
|
}
|
|
}
|
|
}
|
|
|
|
},{}],39:[function(require,module,exports){
|
|
(function (global){
|
|
/**
|
|
* @license
|
|
* Lodash <https://lodash.com/>
|
|
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
* Released under MIT license <https://lodash.com/license>
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
*/
|
|
;(function() {
|
|
|
|
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
|
|
var undefined;
|
|
|
|
/** Used as the semantic version number. */
|
|
var VERSION = '4.17.15';
|
|
|
|
/** Used as the size to enable large array optimizations. */
|
|
var LARGE_ARRAY_SIZE = 200;
|
|
|
|
/** Error message constants. */
|
|
var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
|
|
FUNC_ERROR_TEXT = 'Expected a function';
|
|
|
|
/** Used to stand-in for `undefined` hash values. */
|
|
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|
|
|
/** Used as the maximum memoize cache size. */
|
|
var MAX_MEMOIZE_SIZE = 500;
|
|
|
|
/** Used as the internal argument placeholder. */
|
|
var PLACEHOLDER = '__lodash_placeholder__';
|
|
|
|
/** Used to compose bitmasks for cloning. */
|
|
var CLONE_DEEP_FLAG = 1,
|
|
CLONE_FLAT_FLAG = 2,
|
|
CLONE_SYMBOLS_FLAG = 4;
|
|
|
|
/** Used to compose bitmasks for value comparisons. */
|
|
var COMPARE_PARTIAL_FLAG = 1,
|
|
COMPARE_UNORDERED_FLAG = 2;
|
|
|
|
/** Used to compose bitmasks for function metadata. */
|
|
var WRAP_BIND_FLAG = 1,
|
|
WRAP_BIND_KEY_FLAG = 2,
|
|
WRAP_CURRY_BOUND_FLAG = 4,
|
|
WRAP_CURRY_FLAG = 8,
|
|
WRAP_CURRY_RIGHT_FLAG = 16,
|
|
WRAP_PARTIAL_FLAG = 32,
|
|
WRAP_PARTIAL_RIGHT_FLAG = 64,
|
|
WRAP_ARY_FLAG = 128,
|
|
WRAP_REARG_FLAG = 256,
|
|
WRAP_FLIP_FLAG = 512;
|
|
|
|
/** Used as default options for `_.truncate`. */
|
|
var DEFAULT_TRUNC_LENGTH = 30,
|
|
DEFAULT_TRUNC_OMISSION = '...';
|
|
|
|
/** Used to detect hot functions by number of calls within a span of milliseconds. */
|
|
var HOT_COUNT = 800,
|
|
HOT_SPAN = 16;
|
|
|
|
/** Used to indicate the type of lazy iteratees. */
|
|
var LAZY_FILTER_FLAG = 1,
|
|
LAZY_MAP_FLAG = 2,
|
|
LAZY_WHILE_FLAG = 3;
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var INFINITY = 1 / 0,
|
|
MAX_SAFE_INTEGER = 9007199254740991,
|
|
MAX_INTEGER = 1.7976931348623157e+308,
|
|
NAN = 0 / 0;
|
|
|
|
/** Used as references for the maximum length and index of an array. */
|
|
var MAX_ARRAY_LENGTH = 4294967295,
|
|
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
|
|
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
|
|
|
|
/** Used to associate wrap methods with their bit flags. */
|
|
var wrapFlags = [
|
|
['ary', WRAP_ARY_FLAG],
|
|
['bind', WRAP_BIND_FLAG],
|
|
['bindKey', WRAP_BIND_KEY_FLAG],
|
|
['curry', WRAP_CURRY_FLAG],
|
|
['curryRight', WRAP_CURRY_RIGHT_FLAG],
|
|
['flip', WRAP_FLIP_FLAG],
|
|
['partial', WRAP_PARTIAL_FLAG],
|
|
['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
|
|
['rearg', WRAP_REARG_FLAG]
|
|
];
|
|
|
|
/** `Object#toString` result references. */
|
|
var argsTag = '[object Arguments]',
|
|
arrayTag = '[object Array]',
|
|
asyncTag = '[object AsyncFunction]',
|
|
boolTag = '[object Boolean]',
|
|
dateTag = '[object Date]',
|
|
domExcTag = '[object DOMException]',
|
|
errorTag = '[object Error]',
|
|
funcTag = '[object Function]',
|
|
genTag = '[object GeneratorFunction]',
|
|
mapTag = '[object Map]',
|
|
numberTag = '[object Number]',
|
|
nullTag = '[object Null]',
|
|
objectTag = '[object Object]',
|
|
promiseTag = '[object Promise]',
|
|
proxyTag = '[object Proxy]',
|
|
regexpTag = '[object RegExp]',
|
|
setTag = '[object Set]',
|
|
stringTag = '[object String]',
|
|
symbolTag = '[object Symbol]',
|
|
undefinedTag = '[object Undefined]',
|
|
weakMapTag = '[object WeakMap]',
|
|
weakSetTag = '[object WeakSet]';
|
|
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|
dataViewTag = '[object DataView]',
|
|
float32Tag = '[object Float32Array]',
|
|
float64Tag = '[object Float64Array]',
|
|
int8Tag = '[object Int8Array]',
|
|
int16Tag = '[object Int16Array]',
|
|
int32Tag = '[object Int32Array]',
|
|
uint8Tag = '[object Uint8Array]',
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
uint16Tag = '[object Uint16Array]',
|
|
uint32Tag = '[object Uint32Array]';
|
|
|
|
/** Used to match empty string literals in compiled template source. */
|
|
var reEmptyStringLeading = /\b__p \+= '';/g,
|
|
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
|
|
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
|
|
|
|
/** Used to match HTML entities and HTML characters. */
|
|
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
|
|
reUnescapedHtml = /[&<>"']/g,
|
|
reHasEscapedHtml = RegExp(reEscapedHtml.source),
|
|
reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
|
|
|
|
/** Used to match template delimiters. */
|
|
var reEscape = /<%-([\s\S]+?)%>/g,
|
|
reEvaluate = /<%([\s\S]+?)%>/g,
|
|
reInterpolate = /<%=([\s\S]+?)%>/g;
|
|
|
|
/** Used to match property names within property paths. */
|
|
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
|
|
reIsPlainProp = /^\w*$/,
|
|
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
|
|
|
|
/**
|
|
* Used to match `RegExp`
|
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|
*/
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
|
|
reHasRegExpChar = RegExp(reRegExpChar.source);
|
|
|
|
/** Used to match leading and trailing whitespace. */
|
|
var reTrim = /^\s+|\s+$/g,
|
|
reTrimStart = /^\s+/,
|
|
reTrimEnd = /\s+$/;
|
|
|
|
/** Used to match wrap detail comments. */
|
|
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
|
|
reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
|
|
reSplitDetails = /,? & /;
|
|
|
|
/** Used to match words composed of alphanumeric characters. */
|
|
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
|
|
/** Used to match backslashes in property paths. */
|
|
var reEscapeChar = /\\(\\)?/g;
|
|
|
|
/**
|
|
* Used to match
|
|
* [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
|
|
*/
|
|
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
|
|
|
|
/** Used to match `RegExp` flags from their coerced string values. */
|
|
var reFlags = /\w*$/;
|
|
|
|
/** Used to detect bad signed hexadecimal string values. */
|
|
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
|
|
/** Used to detect binary string values. */
|
|
var reIsBinary = /^0b[01]+$/i;
|
|
|
|
/** Used to detect host constructors (Safari). */
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
/** Used to detect octal string values. */
|
|
var reIsOctal = /^0o[0-7]+$/i;
|
|
|
|
/** Used to detect unsigned integer values. */
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
|
|
/** Used to match Latin Unicode letters (excluding mathematical operators). */
|
|
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
|
|
|
|
/** Used to ensure capturing order of template delimiters. */
|
|
var reNoMatch = /($^)/;
|
|
|
|
/** Used to match unescaped characters in compiled string literals. */
|
|
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
|
|
|
|
/** Used to compose unicode character classes. */
|
|
var rsAstralRange = '\\ud800-\\udfff',
|
|
rsComboMarksRange = '\\u0300-\\u036f',
|
|
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
|
|
rsComboSymbolsRange = '\\u20d0-\\u20ff',
|
|
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
|
|
rsDingbatRange = '\\u2700-\\u27bf',
|
|
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
|
|
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
|
|
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
|
|
rsPunctuationRange = '\\u2000-\\u206f',
|
|
rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
|
|
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
|
|
rsVarRange = '\\ufe0e\\ufe0f',
|
|
rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
|
|
|
|
/** Used to compose unicode capture groups. */
|
|
var rsApos = "['\u2019]",
|
|
rsAstral = '[' + rsAstralRange + ']',
|
|
rsBreak = '[' + rsBreakRange + ']',
|
|
rsCombo = '[' + rsComboRange + ']',
|
|
rsDigits = '\\d+',
|
|
rsDingbat = '[' + rsDingbatRange + ']',
|
|
rsLower = '[' + rsLowerRange + ']',
|
|
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
|
|
rsFitz = '\\ud83c[\\udffb-\\udfff]',
|
|
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
|
|
rsNonAstral = '[^' + rsAstralRange + ']',
|
|
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
|
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
|
rsUpper = '[' + rsUpperRange + ']',
|
|
rsZWJ = '\\u200d';
|
|
|
|
/** Used to compose unicode regexes. */
|
|
var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
|
|
rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
|
|
rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
|
|
rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
|
|
reOptMod = rsModifier + '?',
|
|
rsOptVar = '[' + rsVarRange + ']?',
|
|
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
|
|
rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
|
|
rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
|
|
rsSeq = rsOptVar + reOptMod + rsOptJoin,
|
|
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
|
|
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
|
|
|
|
/** Used to match apostrophes. */
|
|
var reApos = RegExp(rsApos, 'g');
|
|
|
|
/**
|
|
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
|
|
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
|
|
*/
|
|
var reComboMark = RegExp(rsCombo, 'g');
|
|
|
|
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
|
|
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
|
|
|
|
/** Used to match complex or compound words. */
|
|
var reUnicodeWord = RegExp([
|
|
rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
|
|
rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
|
|
rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
|
|
rsUpper + '+' + rsOptContrUpper,
|
|
rsOrdUpper,
|
|
rsOrdLower,
|
|
rsDigits,
|
|
rsEmoji
|
|
].join('|'), 'g');
|
|
|
|
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
|
|
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
|
|
|
|
/** Used to detect strings that need a more robust regexp to match words. */
|
|
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
|
|
|
|
/** Used to assign default `context` object properties. */
|
|
var contextProps = [
|
|
'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
|
|
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
|
|
'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
|
|
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
|
|
'_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
|
|
];
|
|
|
|
/** Used to make template sourceURLs easier to identify. */
|
|
var templateCounter = -1;
|
|
|
|
/** Used to identify `toStringTag` values of typed arrays. */
|
|
var typedArrayTags = {};
|
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
typedArrayTags[uint32Tag] = true;
|
|
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
|
|
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
|
|
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
|
|
typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
|
|
typedArrayTags[setTag] = typedArrayTags[stringTag] =
|
|
typedArrayTags[weakMapTag] = false;
|
|
|
|
/** Used to identify `toStringTag` values supported by `_.clone`. */
|
|
var cloneableTags = {};
|
|
cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
|
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
|
|
cloneableTags[boolTag] = cloneableTags[dateTag] =
|
|
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
|
|
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
|
|
cloneableTags[int32Tag] = cloneableTags[mapTag] =
|
|
cloneableTags[numberTag] = cloneableTags[objectTag] =
|
|
cloneableTags[regexpTag] = cloneableTags[setTag] =
|
|
cloneableTags[stringTag] = cloneableTags[symbolTag] =
|
|
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
|
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
|
|
cloneableTags[errorTag] = cloneableTags[funcTag] =
|
|
cloneableTags[weakMapTag] = false;
|
|
|
|
/** Used to map Latin Unicode letters to basic Latin letters. */
|
|
var deburredLetters = {
|
|
// Latin-1 Supplement block.
|
|
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
|
|
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
|
|
'\xc7': 'C', '\xe7': 'c',
|
|
'\xd0': 'D', '\xf0': 'd',
|
|
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
|
|
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
|
|
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
|
|
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
|
|
'\xd1': 'N', '\xf1': 'n',
|
|
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
|
|
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
|
|
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
|
|
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
|
|
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
|
|
'\xc6': 'Ae', '\xe6': 'ae',
|
|
'\xde': 'Th', '\xfe': 'th',
|
|
'\xdf': 'ss',
|
|
// Latin Extended-A block.
|
|
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
|
|
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
|
|
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
|
|
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
|
|
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
|
|
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
|
|
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
|
|
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
|
|
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
|
|
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
|
|
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
|
|
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
|
|
'\u0134': 'J', '\u0135': 'j',
|
|
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
|
|
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
|
|
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
|
|
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
|
|
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
|
|
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
|
|
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
|
|
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
|
|
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
|
|
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
|
|
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
|
|
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
|
|
'\u0163': 't', '\u0165': 't', '\u0167': 't',
|
|
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
|
|
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
|
|
'\u0174': 'W', '\u0175': 'w',
|
|
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
|
|
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
|
|
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
|
|
'\u0132': 'IJ', '\u0133': 'ij',
|
|
'\u0152': 'Oe', '\u0153': 'oe',
|
|
'\u0149': "'n", '\u017f': 's'
|
|
};
|
|
|
|
/** Used to map characters to HTML entities. */
|
|
var htmlEscapes = {
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
"'": '''
|
|
};
|
|
|
|
/** Used to map HTML entities to characters. */
|
|
var htmlUnescapes = {
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
''': "'"
|
|
};
|
|
|
|
/** Used to escape characters for inclusion in compiled string literals. */
|
|
var stringEscapes = {
|
|
'\\': '\\',
|
|
"'": "'",
|
|
'\n': 'n',
|
|
'\r': 'r',
|
|
'\u2028': 'u2028',
|
|
'\u2029': 'u2029'
|
|
};
|
|
|
|
/** Built-in method references without a dependency on `root`. */
|
|
var freeParseFloat = parseFloat,
|
|
freeParseInt = parseInt;
|
|
|
|
/** Detect free variable `global` from Node.js. */
|
|
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
|
|
|
|
/** Detect free variable `self`. */
|
|
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
|
|
/** Used as a reference to the global object. */
|
|
var root = freeGlobal || freeSelf || Function('return this')();
|
|
|
|
/** Detect free variable `exports`. */
|
|
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
|
|
/** Detect free variable `module`. */
|
|
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
|
|
|
|
/** Detect the popular CommonJS extension `module.exports`. */
|
|
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
|
|
/** Detect free variable `process` from Node.js. */
|
|
var freeProcess = moduleExports && freeGlobal.process;
|
|
|
|
/** Used to access faster Node.js helpers. */
|
|
var nodeUtil = (function() {
|
|
try {
|
|
// Use `util.types` for Node.js 10+.
|
|
var types = freeModule && freeModule.require && freeModule.require('util').types;
|
|
|
|
if (types) {
|
|
return types;
|
|
}
|
|
|
|
// Legacy `process.binding('util')` for Node.js < 10.
|
|
return freeProcess && freeProcess.binding && freeProcess.binding('util');
|
|
} catch (e) {}
|
|
}());
|
|
|
|
/* Node.js helper references. */
|
|
var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
|
|
nodeIsDate = nodeUtil && nodeUtil.isDate,
|
|
nodeIsMap = nodeUtil && nodeUtil.isMap,
|
|
nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
|
|
nodeIsSet = nodeUtil && nodeUtil.isSet,
|
|
nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* A faster alternative to `Function#apply`, this function invokes `func`
|
|
* with the `this` binding of `thisArg` and the arguments of `args`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to invoke.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {Array} args The arguments to invoke `func` with.
|
|
* @returns {*} Returns the result of `func`.
|
|
*/
|
|
function apply(func, thisArg, args) {
|
|
switch (args.length) {
|
|
case 0: return func.call(thisArg);
|
|
case 1: return func.call(thisArg, args[0]);
|
|
case 2: return func.call(thisArg, args[0], args[1]);
|
|
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
|
}
|
|
return func.apply(thisArg, args);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseAggregator` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} setter The function to set `accumulator` values.
|
|
* @param {Function} iteratee The iteratee to transform keys.
|
|
* @param {Object} accumulator The initial aggregated object.
|
|
* @returns {Function} Returns `accumulator`.
|
|
*/
|
|
function arrayAggregator(array, setter, iteratee, accumulator) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
setter(accumulator, value, iteratee(value), array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.forEach` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEach(array, iteratee) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (iteratee(array[index], index, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.forEachRight` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEachRight(array, iteratee) {
|
|
var length = array == null ? 0 : array.length;
|
|
|
|
while (length--) {
|
|
if (iteratee(array[length], length, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.every` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
|
* else `false`.
|
|
*/
|
|
function arrayEvery(array, predicate) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (!predicate(array[index], index, array)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.filter` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
*/
|
|
function arrayFilter(array, predicate) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (predicate(value, index, array)) {
|
|
result[resIndex++] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.includes` for arrays without support for
|
|
* specifying an index to search from.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to inspect.
|
|
* @param {*} target The value to search for.
|
|
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
|
*/
|
|
function arrayIncludes(array, value) {
|
|
var length = array == null ? 0 : array.length;
|
|
return !!length && baseIndexOf(array, value, 0) > -1;
|
|
}
|
|
|
|
/**
|
|
* This function is like `arrayIncludes` except that it accepts a comparator.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to inspect.
|
|
* @param {*} target The value to search for.
|
|
* @param {Function} comparator The comparator invoked per element.
|
|
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
|
*/
|
|
function arrayIncludesWith(array, value, comparator) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (comparator(value, array[index])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.map` for arrays without support for iteratee
|
|
* shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
*/
|
|
function arrayMap(array, iteratee) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length,
|
|
result = Array(length);
|
|
|
|
while (++index < length) {
|
|
result[index] = iteratee(array[index], index, array);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Appends the elements of `values` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to append.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayPush(array, values) {
|
|
var index = -1,
|
|
length = values.length,
|
|
offset = array.length;
|
|
|
|
while (++index < length) {
|
|
array[offset + index] = values[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.reduce` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
|
* the initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
if (initAccum && length) {
|
|
accumulator = array[++index];
|
|
}
|
|
while (++index < length) {
|
|
accumulator = iteratee(accumulator, array[index], index, array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.reduceRight` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @param {boolean} [initAccum] Specify using the last element of `array` as
|
|
* the initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (initAccum && length) {
|
|
accumulator = array[--length];
|
|
}
|
|
while (length--) {
|
|
accumulator = iteratee(accumulator, array[length], length, array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.some` for arrays without support for iteratee
|
|
* shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
* else `false`.
|
|
*/
|
|
function arraySome(array, predicate) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (predicate(array[index], index, array)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Gets the size of an ASCII `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string inspect.
|
|
* @returns {number} Returns the string size.
|
|
*/
|
|
var asciiSize = baseProperty('length');
|
|
|
|
/**
|
|
* Converts an ASCII `string` to an array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function asciiToArray(string) {
|
|
return string.split('');
|
|
}
|
|
|
|
/**
|
|
* Splits an ASCII `string` into an array of its words.
|
|
*
|
|
* @private
|
|
* @param {string} The string to inspect.
|
|
* @returns {Array} Returns the words of `string`.
|
|
*/
|
|
function asciiWords(string) {
|
|
return string.match(reAsciiWord) || [];
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.findKey` and `_.findLastKey`,
|
|
* without support for iteratee shorthands, which iterates over `collection`
|
|
* using `eachFunc`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to inspect.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {Function} eachFunc The function to iterate over `collection`.
|
|
* @returns {*} Returns the found element or its key, else `undefined`.
|
|
*/
|
|
function baseFindKey(collection, predicate, eachFunc) {
|
|
var result;
|
|
eachFunc(collection, function(value, key, collection) {
|
|
if (predicate(value, key, collection)) {
|
|
result = key;
|
|
return false;
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.findIndex` and `_.findLastIndex` without
|
|
* support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseFindIndex(array, predicate, fromIndex, fromRight) {
|
|
var length = array.length,
|
|
index = fromIndex + (fromRight ? 1 : -1);
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
if (predicate(array[index], index, array)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.indexOf` without `fromIndex` bounds checks.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseIndexOf(array, value, fromIndex) {
|
|
return value === value
|
|
? strictIndexOf(array, value, fromIndex)
|
|
: baseFindIndex(array, baseIsNaN, fromIndex);
|
|
}
|
|
|
|
/**
|
|
* This function is like `baseIndexOf` except that it accepts a comparator.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @param {Function} comparator The comparator invoked per element.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseIndexOfWith(array, value, fromIndex, comparator) {
|
|
var index = fromIndex - 1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (comparator(array[index], value)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isNaN` without support for number objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
|
*/
|
|
function baseIsNaN(value) {
|
|
return value !== value;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.mean` and `_.meanBy` without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {number} Returns the mean.
|
|
*/
|
|
function baseMean(array, iteratee) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? (baseSum(array, iteratee) / length) : NAN;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.property` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {Function} Returns the new accessor function.
|
|
*/
|
|
function baseProperty(key) {
|
|
return function(object) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.propertyOf` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Function} Returns the new accessor function.
|
|
*/
|
|
function basePropertyOf(object) {
|
|
return function(key) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.reduce` and `_.reduceRight`, without support
|
|
* for iteratee shorthands, which iterates over `collection` using `eachFunc`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} accumulator The initial value.
|
|
* @param {boolean} initAccum Specify using the first or last element of
|
|
* `collection` as the initial value.
|
|
* @param {Function} eachFunc The function to iterate over `collection`.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
|
|
eachFunc(collection, function(value, index, collection) {
|
|
accumulator = initAccum
|
|
? (initAccum = false, value)
|
|
: iteratee(accumulator, value, index, collection);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortBy` which uses `comparer` to define the
|
|
* sort order of `array` and replaces criteria objects with their corresponding
|
|
* values.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to sort.
|
|
* @param {Function} comparer The function to define sort order.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function baseSortBy(array, comparer) {
|
|
var length = array.length;
|
|
|
|
array.sort(comparer);
|
|
while (length--) {
|
|
array[length] = array[length].value;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sum` and `_.sumBy` without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {number} Returns the sum.
|
|
*/
|
|
function baseSum(array, iteratee) {
|
|
var result,
|
|
index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
var current = iteratee(array[index]);
|
|
if (current !== undefined) {
|
|
result = result === undefined ? current : (result + current);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|
* or max array length checks.
|
|
*
|
|
* @private
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the array of results.
|
|
*/
|
|
function baseTimes(n, iteratee) {
|
|
var index = -1,
|
|
result = Array(n);
|
|
|
|
while (++index < n) {
|
|
result[index] = iteratee(index);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
|
|
* of key-value pairs for `object` corresponding to the property names of `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array} props The property names to get values for.
|
|
* @returns {Object} Returns the key-value pairs.
|
|
*/
|
|
function baseToPairs(object, props) {
|
|
return arrayMap(props, function(key) {
|
|
return [key, object[key]];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.unary` without support for storing metadata.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to cap arguments for.
|
|
* @returns {Function} Returns the new capped function.
|
|
*/
|
|
function baseUnary(func) {
|
|
return function(value) {
|
|
return func(value);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.values` and `_.valuesIn` which creates an
|
|
* array of `object` property values corresponding to the property names
|
|
* of `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array} props The property names to get values for.
|
|
* @returns {Object} Returns the array of property values.
|
|
*/
|
|
function baseValues(object, props) {
|
|
return arrayMap(props, function(key) {
|
|
return object[key];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Checks if a `cache` value for `key` exists.
|
|
*
|
|
* @private
|
|
* @param {Object} cache The cache to query.
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function cacheHas(cache, key) {
|
|
return cache.has(key);
|
|
}
|
|
|
|
/**
|
|
* Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
|
|
* that is not found in the character symbols.
|
|
*
|
|
* @private
|
|
* @param {Array} strSymbols The string symbols to inspect.
|
|
* @param {Array} chrSymbols The character symbols to find.
|
|
* @returns {number} Returns the index of the first unmatched string symbol.
|
|
*/
|
|
function charsStartIndex(strSymbols, chrSymbols) {
|
|
var index = -1,
|
|
length = strSymbols.length;
|
|
|
|
while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
|
|
* that is not found in the character symbols.
|
|
*
|
|
* @private
|
|
* @param {Array} strSymbols The string symbols to inspect.
|
|
* @param {Array} chrSymbols The character symbols to find.
|
|
* @returns {number} Returns the index of the last unmatched string symbol.
|
|
*/
|
|
function charsEndIndex(strSymbols, chrSymbols) {
|
|
var index = strSymbols.length;
|
|
|
|
while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of `placeholder` occurrences in `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} placeholder The placeholder to search for.
|
|
* @returns {number} Returns the placeholder count.
|
|
*/
|
|
function countHolders(array, placeholder) {
|
|
var length = array.length,
|
|
result = 0;
|
|
|
|
while (length--) {
|
|
if (array[length] === placeholder) {
|
|
++result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
|
|
* letters to basic Latin letters.
|
|
*
|
|
* @private
|
|
* @param {string} letter The matched letter to deburr.
|
|
* @returns {string} Returns the deburred letter.
|
|
*/
|
|
var deburrLetter = basePropertyOf(deburredLetters);
|
|
|
|
/**
|
|
* Used by `_.escape` to convert characters to HTML entities.
|
|
*
|
|
* @private
|
|
* @param {string} chr The matched character to escape.
|
|
* @returns {string} Returns the escaped character.
|
|
*/
|
|
var escapeHtmlChar = basePropertyOf(htmlEscapes);
|
|
|
|
/**
|
|
* Used by `_.template` to escape characters for inclusion in compiled string literals.
|
|
*
|
|
* @private
|
|
* @param {string} chr The matched character to escape.
|
|
* @returns {string} Returns the escaped character.
|
|
*/
|
|
function escapeStringChar(chr) {
|
|
return '\\' + stringEscapes[chr];
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {*} Returns the property value.
|
|
*/
|
|
function getValue(object, key) {
|
|
return object == null ? undefined : object[key];
|
|
}
|
|
|
|
/**
|
|
* Checks if `string` contains Unicode symbols.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
|
|
*/
|
|
function hasUnicode(string) {
|
|
return reHasUnicode.test(string);
|
|
}
|
|
|
|
/**
|
|
* Checks if `string` contains a word composed of Unicode symbols.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {boolean} Returns `true` if a word is found, else `false`.
|
|
*/
|
|
function hasUnicodeWord(string) {
|
|
return reHasUnicodeWord.test(string);
|
|
}
|
|
|
|
/**
|
|
* Converts `iterator` to an array.
|
|
*
|
|
* @private
|
|
* @param {Object} iterator The iterator to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function iteratorToArray(iterator) {
|
|
var data,
|
|
result = [];
|
|
|
|
while (!(data = iterator.next()).done) {
|
|
result.push(data.value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `map` to its key-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to convert.
|
|
* @returns {Array} Returns the key-value pairs.
|
|
*/
|
|
function mapToArray(map) {
|
|
var index = -1,
|
|
result = Array(map.size);
|
|
|
|
map.forEach(function(value, key) {
|
|
result[++index] = [key, value];
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a unary function that invokes `func` with its argument transformed.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {Function} transform The argument transform.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function overArg(func, transform) {
|
|
return function(arg) {
|
|
return func(transform(arg));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Replaces all `placeholder` elements in `array` with an internal placeholder
|
|
* and returns an array of their indexes.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {*} placeholder The placeholder to replace.
|
|
* @returns {Array} Returns the new array of placeholder indexes.
|
|
*/
|
|
function replaceHolders(array, placeholder) {
|
|
var index = -1,
|
|
length = array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (value === placeholder || value === PLACEHOLDER) {
|
|
array[index] = PLACEHOLDER;
|
|
result[resIndex++] = index;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `set` to an array of its values.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to convert.
|
|
* @returns {Array} Returns the values.
|
|
*/
|
|
function setToArray(set) {
|
|
var index = -1,
|
|
result = Array(set.size);
|
|
|
|
set.forEach(function(value) {
|
|
result[++index] = value;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `set` to its value-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to convert.
|
|
* @returns {Array} Returns the value-value pairs.
|
|
*/
|
|
function setToPairs(set) {
|
|
var index = -1,
|
|
result = Array(set.size);
|
|
|
|
set.forEach(function(value) {
|
|
result[++index] = [value, value];
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.indexOf` which performs strict equality
|
|
* comparisons of values, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function strictIndexOf(array, value, fromIndex) {
|
|
var index = fromIndex - 1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.lastIndexOf` which performs strict equality
|
|
* comparisons of values, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function strictLastIndexOf(array, value, fromIndex) {
|
|
var index = fromIndex + 1;
|
|
while (index--) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of symbols in `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {number} Returns the string size.
|
|
*/
|
|
function stringSize(string) {
|
|
return hasUnicode(string)
|
|
? unicodeSize(string)
|
|
: asciiSize(string);
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to an array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function stringToArray(string) {
|
|
return hasUnicode(string)
|
|
? unicodeToArray(string)
|
|
: asciiToArray(string);
|
|
}
|
|
|
|
/**
|
|
* Used by `_.unescape` to convert HTML entities to characters.
|
|
*
|
|
* @private
|
|
* @param {string} chr The matched character to unescape.
|
|
* @returns {string} Returns the unescaped character.
|
|
*/
|
|
var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
|
|
|
|
/**
|
|
* Gets the size of a Unicode `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string inspect.
|
|
* @returns {number} Returns the string size.
|
|
*/
|
|
function unicodeSize(string) {
|
|
var result = reUnicode.lastIndex = 0;
|
|
while (reUnicode.test(string)) {
|
|
++result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts a Unicode `string` to an array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function unicodeToArray(string) {
|
|
return string.match(reUnicode) || [];
|
|
}
|
|
|
|
/**
|
|
* Splits a Unicode `string` into an array of its words.
|
|
*
|
|
* @private
|
|
* @param {string} The string to inspect.
|
|
* @returns {Array} Returns the words of `string`.
|
|
*/
|
|
function unicodeWords(string) {
|
|
return string.match(reUnicodeWord) || [];
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Create a new pristine `lodash` function using the `context` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category Util
|
|
* @param {Object} [context=root] The context object.
|
|
* @returns {Function} Returns a new `lodash` function.
|
|
* @example
|
|
*
|
|
* _.mixin({ 'foo': _.constant('foo') });
|
|
*
|
|
* var lodash = _.runInContext();
|
|
* lodash.mixin({ 'bar': lodash.constant('bar') });
|
|
*
|
|
* _.isFunction(_.foo);
|
|
* // => true
|
|
* _.isFunction(_.bar);
|
|
* // => false
|
|
*
|
|
* lodash.isFunction(lodash.foo);
|
|
* // => false
|
|
* lodash.isFunction(lodash.bar);
|
|
* // => true
|
|
*
|
|
* // Create a suped-up `defer` in Node.js.
|
|
* var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
|
|
*/
|
|
var runInContext = (function runInContext(context) {
|
|
context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
|
|
|
|
/** Built-in constructor references. */
|
|
var Array = context.Array,
|
|
Date = context.Date,
|
|
Error = context.Error,
|
|
Function = context.Function,
|
|
Math = context.Math,
|
|
Object = context.Object,
|
|
RegExp = context.RegExp,
|
|
String = context.String,
|
|
TypeError = context.TypeError;
|
|
|
|
/** Used for built-in method references. */
|
|
var arrayProto = Array.prototype,
|
|
funcProto = Function.prototype,
|
|
objectProto = Object.prototype;
|
|
|
|
/** Used to detect overreaching core-js shims. */
|
|
var coreJsData = context['__core-js_shared__'];
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var funcToString = funcProto.toString;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Used to generate unique IDs. */
|
|
var idCounter = 0;
|
|
|
|
/** Used to detect methods masquerading as native. */
|
|
var maskSrcKey = (function() {
|
|
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|
}());
|
|
|
|
/**
|
|
* Used to resolve the
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var nativeObjectToString = objectProto.toString;
|
|
|
|
/** Used to infer the `Object` constructor. */
|
|
var objectCtorString = funcToString.call(Object);
|
|
|
|
/** Used to restore the original `_` reference in `_.noConflict`. */
|
|
var oldDash = root._;
|
|
|
|
/** Used to detect if a method is native. */
|
|
var reIsNative = RegExp('^' +
|
|
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
);
|
|
|
|
/** Built-in value references. */
|
|
var Buffer = moduleExports ? context.Buffer : undefined,
|
|
Symbol = context.Symbol,
|
|
Uint8Array = context.Uint8Array,
|
|
allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
|
|
getPrototype = overArg(Object.getPrototypeOf, Object),
|
|
objectCreate = Object.create,
|
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
|
splice = arrayProto.splice,
|
|
spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
|
|
symIterator = Symbol ? Symbol.iterator : undefined,
|
|
symToStringTag = Symbol ? Symbol.toStringTag : undefined;
|
|
|
|
var defineProperty = (function() {
|
|
try {
|
|
var func = getNative(Object, 'defineProperty');
|
|
func({}, '', {});
|
|
return func;
|
|
} catch (e) {}
|
|
}());
|
|
|
|
/** Mocked built-ins. */
|
|
var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
|
|
ctxNow = Date && Date.now !== root.Date.now && Date.now,
|
|
ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
|
|
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
var nativeCeil = Math.ceil,
|
|
nativeFloor = Math.floor,
|
|
nativeGetSymbols = Object.getOwnPropertySymbols,
|
|
nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
|
|
nativeIsFinite = context.isFinite,
|
|
nativeJoin = arrayProto.join,
|
|
nativeKeys = overArg(Object.keys, Object),
|
|
nativeMax = Math.max,
|
|
nativeMin = Math.min,
|
|
nativeNow = Date.now,
|
|
nativeParseInt = context.parseInt,
|
|
nativeRandom = Math.random,
|
|
nativeReverse = arrayProto.reverse;
|
|
|
|
/* Built-in method references that are verified to be native. */
|
|
var DataView = getNative(context, 'DataView'),
|
|
Map = getNative(context, 'Map'),
|
|
Promise = getNative(context, 'Promise'),
|
|
Set = getNative(context, 'Set'),
|
|
WeakMap = getNative(context, 'WeakMap'),
|
|
nativeCreate = getNative(Object, 'create');
|
|
|
|
/** Used to store function metadata. */
|
|
var metaMap = WeakMap && new WeakMap;
|
|
|
|
/** Used to lookup unminified function names. */
|
|
var realNames = {};
|
|
|
|
/** Used to detect maps, sets, and weakmaps. */
|
|
var dataViewCtorString = toSource(DataView),
|
|
mapCtorString = toSource(Map),
|
|
promiseCtorString = toSource(Promise),
|
|
setCtorString = toSource(Set),
|
|
weakMapCtorString = toSource(WeakMap);
|
|
|
|
/** Used to convert symbols to primitives and strings. */
|
|
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
|
|
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a `lodash` object which wraps `value` to enable implicit method
|
|
* chain sequences. Methods that operate on and return arrays, collections,
|
|
* and functions can be chained together. Methods that retrieve a single value
|
|
* or may return a primitive value will automatically end the chain sequence
|
|
* and return the unwrapped value. Otherwise, the value must be unwrapped
|
|
* with `_#value`.
|
|
*
|
|
* Explicit chain sequences, which must be unwrapped with `_#value`, may be
|
|
* enabled using `_.chain`.
|
|
*
|
|
* The execution of chained methods is lazy, that is, it's deferred until
|
|
* `_#value` is implicitly or explicitly called.
|
|
*
|
|
* Lazy evaluation allows several methods to support shortcut fusion.
|
|
* Shortcut fusion is an optimization to merge iteratee calls; this avoids
|
|
* the creation of intermediate arrays and can greatly reduce the number of
|
|
* iteratee executions. Sections of a chain sequence qualify for shortcut
|
|
* fusion if the section is applied to an array and iteratees accept only
|
|
* one argument. The heuristic for whether a section qualifies for shortcut
|
|
* fusion is subject to change.
|
|
*
|
|
* Chaining is supported in custom builds as long as the `_#value` method is
|
|
* directly or indirectly included in the build.
|
|
*
|
|
* In addition to lodash methods, wrappers have `Array` and `String` methods.
|
|
*
|
|
* The wrapper `Array` methods are:
|
|
* `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
|
|
*
|
|
* The wrapper `String` methods are:
|
|
* `replace` and `split`
|
|
*
|
|
* The wrapper methods that support shortcut fusion are:
|
|
* `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
|
|
* `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
|
|
* `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
|
|
*
|
|
* The chainable wrapper methods are:
|
|
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
|
|
* `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
|
|
* `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
|
|
* `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
|
|
* `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
|
|
* `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
|
|
* `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
|
|
* `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
|
|
* `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
|
|
* `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
|
|
* `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
|
|
* `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
|
|
* `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
|
|
* `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
|
|
* `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
|
|
* `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
|
|
* `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
|
|
* `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
|
|
* `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
|
|
* `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
|
|
* `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
|
|
* `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
|
|
* `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
|
|
* `zipObject`, `zipObjectDeep`, and `zipWith`
|
|
*
|
|
* The wrapper methods that are **not** chainable by default are:
|
|
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
|
|
* `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
|
|
* `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
|
|
* `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
|
|
* `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
|
|
* `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
|
|
* `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
|
|
* `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
|
|
* `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
|
|
* `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
|
|
* `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
|
|
* `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
|
|
* `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
|
|
* `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
|
|
* `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
|
|
* `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
|
|
* `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
|
|
* `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
|
|
* `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
|
|
* `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
|
|
* `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
|
|
* `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
|
|
* `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
|
|
* `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
|
|
* `upperFirst`, `value`, and `words`
|
|
*
|
|
* @name _
|
|
* @constructor
|
|
* @category Seq
|
|
* @param {*} value The value to wrap in a `lodash` instance.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var wrapped = _([1, 2, 3]);
|
|
*
|
|
* // Returns an unwrapped value.
|
|
* wrapped.reduce(_.add);
|
|
* // => 6
|
|
*
|
|
* // Returns a wrapped value.
|
|
* var squares = wrapped.map(square);
|
|
*
|
|
* _.isArray(squares);
|
|
* // => false
|
|
*
|
|
* _.isArray(squares.value());
|
|
* // => true
|
|
*/
|
|
function lodash(value) {
|
|
if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
|
|
if (value instanceof LodashWrapper) {
|
|
return value;
|
|
}
|
|
if (hasOwnProperty.call(value, '__wrapped__')) {
|
|
return wrapperClone(value);
|
|
}
|
|
}
|
|
return new LodashWrapper(value);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.create` without support for assigning
|
|
* properties to the created object.
|
|
*
|
|
* @private
|
|
* @param {Object} proto The object to inherit from.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
var baseCreate = (function() {
|
|
function object() {}
|
|
return function(proto) {
|
|
if (!isObject(proto)) {
|
|
return {};
|
|
}
|
|
if (objectCreate) {
|
|
return objectCreate(proto);
|
|
}
|
|
object.prototype = proto;
|
|
var result = new object;
|
|
object.prototype = undefined;
|
|
return result;
|
|
};
|
|
}());
|
|
|
|
/**
|
|
* The function whose prototype chain sequence wrappers inherit from.
|
|
*
|
|
* @private
|
|
*/
|
|
function baseLodash() {
|
|
// No operation performed.
|
|
}
|
|
|
|
/**
|
|
* The base constructor for creating `lodash` wrapper objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to wrap.
|
|
* @param {boolean} [chainAll] Enable explicit method chain sequences.
|
|
*/
|
|
function LodashWrapper(value, chainAll) {
|
|
this.__wrapped__ = value;
|
|
this.__actions__ = [];
|
|
this.__chain__ = !!chainAll;
|
|
this.__index__ = 0;
|
|
this.__values__ = undefined;
|
|
}
|
|
|
|
/**
|
|
* By default, the template delimiters used by lodash are like those in
|
|
* embedded Ruby (ERB) as well as ES2015 template strings. Change the
|
|
* following template settings to use alternative delimiters.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @type {Object}
|
|
*/
|
|
lodash.templateSettings = {
|
|
|
|
/**
|
|
* Used to detect `data` property values to be HTML-escaped.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {RegExp}
|
|
*/
|
|
'escape': reEscape,
|
|
|
|
/**
|
|
* Used to detect code to be evaluated.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {RegExp}
|
|
*/
|
|
'evaluate': reEvaluate,
|
|
|
|
/**
|
|
* Used to detect `data` property values to inject.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {RegExp}
|
|
*/
|
|
'interpolate': reInterpolate,
|
|
|
|
/**
|
|
* Used to reference the data object in the template text.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {string}
|
|
*/
|
|
'variable': '',
|
|
|
|
/**
|
|
* Used to import variables into the compiled template.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {Object}
|
|
*/
|
|
'imports': {
|
|
|
|
/**
|
|
* A reference to the `lodash` function.
|
|
*
|
|
* @memberOf _.templateSettings.imports
|
|
* @type {Function}
|
|
*/
|
|
'_': lodash
|
|
}
|
|
};
|
|
|
|
// Ensure wrappers are instances of `baseLodash`.
|
|
lodash.prototype = baseLodash.prototype;
|
|
lodash.prototype.constructor = lodash;
|
|
|
|
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
|
|
LodashWrapper.prototype.constructor = LodashWrapper;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {*} value The value to wrap.
|
|
*/
|
|
function LazyWrapper(value) {
|
|
this.__wrapped__ = value;
|
|
this.__actions__ = [];
|
|
this.__dir__ = 1;
|
|
this.__filtered__ = false;
|
|
this.__iteratees__ = [];
|
|
this.__takeCount__ = MAX_ARRAY_LENGTH;
|
|
this.__views__ = [];
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of the lazy wrapper object.
|
|
*
|
|
* @private
|
|
* @name clone
|
|
* @memberOf LazyWrapper
|
|
* @returns {Object} Returns the cloned `LazyWrapper` object.
|
|
*/
|
|
function lazyClone() {
|
|
var result = new LazyWrapper(this.__wrapped__);
|
|
result.__actions__ = copyArray(this.__actions__);
|
|
result.__dir__ = this.__dir__;
|
|
result.__filtered__ = this.__filtered__;
|
|
result.__iteratees__ = copyArray(this.__iteratees__);
|
|
result.__takeCount__ = this.__takeCount__;
|
|
result.__views__ = copyArray(this.__views__);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reverses the direction of lazy iteration.
|
|
*
|
|
* @private
|
|
* @name reverse
|
|
* @memberOf LazyWrapper
|
|
* @returns {Object} Returns the new reversed `LazyWrapper` object.
|
|
*/
|
|
function lazyReverse() {
|
|
if (this.__filtered__) {
|
|
var result = new LazyWrapper(this);
|
|
result.__dir__ = -1;
|
|
result.__filtered__ = true;
|
|
} else {
|
|
result = this.clone();
|
|
result.__dir__ *= -1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extracts the unwrapped value from its lazy wrapper.
|
|
*
|
|
* @private
|
|
* @name value
|
|
* @memberOf LazyWrapper
|
|
* @returns {*} Returns the unwrapped value.
|
|
*/
|
|
function lazyValue() {
|
|
var array = this.__wrapped__.value(),
|
|
dir = this.__dir__,
|
|
isArr = isArray(array),
|
|
isRight = dir < 0,
|
|
arrLength = isArr ? array.length : 0,
|
|
view = getView(0, arrLength, this.__views__),
|
|
start = view.start,
|
|
end = view.end,
|
|
length = end - start,
|
|
index = isRight ? end : (start - 1),
|
|
iteratees = this.__iteratees__,
|
|
iterLength = iteratees.length,
|
|
resIndex = 0,
|
|
takeCount = nativeMin(length, this.__takeCount__);
|
|
|
|
if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
|
|
return baseWrapperValue(array, this.__actions__);
|
|
}
|
|
var result = [];
|
|
|
|
outer:
|
|
while (length-- && resIndex < takeCount) {
|
|
index += dir;
|
|
|
|
var iterIndex = -1,
|
|
value = array[index];
|
|
|
|
while (++iterIndex < iterLength) {
|
|
var data = iteratees[iterIndex],
|
|
iteratee = data.iteratee,
|
|
type = data.type,
|
|
computed = iteratee(value);
|
|
|
|
if (type == LAZY_MAP_FLAG) {
|
|
value = computed;
|
|
} else if (!computed) {
|
|
if (type == LAZY_FILTER_FLAG) {
|
|
continue outer;
|
|
} else {
|
|
break outer;
|
|
}
|
|
}
|
|
}
|
|
result[resIndex++] = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Ensure `LazyWrapper` is an instance of `baseLodash`.
|
|
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
|
|
LazyWrapper.prototype.constructor = LazyWrapper;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a hash object.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function Hash(entries) {
|
|
var index = -1,
|
|
length = entries == null ? 0 : entries.length;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = entries[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the hash.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf Hash
|
|
*/
|
|
function hashClear() {
|
|
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
|
this.size = 0;
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the hash.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf Hash
|
|
* @param {Object} hash The hash to modify.
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function hashDelete(key) {
|
|
var result = this.has(key) && delete this.__data__[key];
|
|
this.size -= result ? 1 : 0;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the hash value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf Hash
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function hashGet(key) {
|
|
var data = this.__data__;
|
|
if (nativeCreate) {
|
|
var result = data[key];
|
|
return result === HASH_UNDEFINED ? undefined : result;
|
|
}
|
|
return hasOwnProperty.call(data, key) ? data[key] : undefined;
|
|
}
|
|
|
|
/**
|
|
* Checks if a hash value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf Hash
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function hashHas(key) {
|
|
var data = this.__data__;
|
|
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
|
|
}
|
|
|
|
/**
|
|
* Sets the hash `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf Hash
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the hash instance.
|
|
*/
|
|
function hashSet(key, value) {
|
|
var data = this.__data__;
|
|
this.size += this.has(key) ? 0 : 1;
|
|
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `Hash`.
|
|
Hash.prototype.clear = hashClear;
|
|
Hash.prototype['delete'] = hashDelete;
|
|
Hash.prototype.get = hashGet;
|
|
Hash.prototype.has = hashHas;
|
|
Hash.prototype.set = hashSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an list cache object.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function ListCache(entries) {
|
|
var index = -1,
|
|
length = entries == null ? 0 : entries.length;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = entries[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the list cache.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf ListCache
|
|
*/
|
|
function listCacheClear() {
|
|
this.__data__ = [];
|
|
this.size = 0;
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the list cache.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function listCacheDelete(key) {
|
|
var data = this.__data__,
|
|
index = assocIndexOf(data, key);
|
|
|
|
if (index < 0) {
|
|
return false;
|
|
}
|
|
var lastIndex = data.length - 1;
|
|
if (index == lastIndex) {
|
|
data.pop();
|
|
} else {
|
|
splice.call(data, index, 1);
|
|
}
|
|
--this.size;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Gets the list cache value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function listCacheGet(key) {
|
|
var data = this.__data__,
|
|
index = assocIndexOf(data, key);
|
|
|
|
return index < 0 ? undefined : data[index][1];
|
|
}
|
|
|
|
/**
|
|
* Checks if a list cache value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function listCacheHas(key) {
|
|
return assocIndexOf(this.__data__, key) > -1;
|
|
}
|
|
|
|
/**
|
|
* Sets the list cache `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the list cache instance.
|
|
*/
|
|
function listCacheSet(key, value) {
|
|
var data = this.__data__,
|
|
index = assocIndexOf(data, key);
|
|
|
|
if (index < 0) {
|
|
++this.size;
|
|
data.push([key, value]);
|
|
} else {
|
|
data[index][1] = value;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `ListCache`.
|
|
ListCache.prototype.clear = listCacheClear;
|
|
ListCache.prototype['delete'] = listCacheDelete;
|
|
ListCache.prototype.get = listCacheGet;
|
|
ListCache.prototype.has = listCacheHas;
|
|
ListCache.prototype.set = listCacheSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a map cache object to store key-value pairs.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function MapCache(entries) {
|
|
var index = -1,
|
|
length = entries == null ? 0 : entries.length;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = entries[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the map.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf MapCache
|
|
*/
|
|
function mapCacheClear() {
|
|
this.size = 0;
|
|
this.__data__ = {
|
|
'hash': new Hash,
|
|
'map': new (Map || ListCache),
|
|
'string': new Hash
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the map.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function mapCacheDelete(key) {
|
|
var result = getMapData(this, key)['delete'](key);
|
|
this.size -= result ? 1 : 0;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the map value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function mapCacheGet(key) {
|
|
return getMapData(this, key).get(key);
|
|
}
|
|
|
|
/**
|
|
* Checks if a map value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function mapCacheHas(key) {
|
|
return getMapData(this, key).has(key);
|
|
}
|
|
|
|
/**
|
|
* Sets the map `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the map cache instance.
|
|
*/
|
|
function mapCacheSet(key, value) {
|
|
var data = getMapData(this, key),
|
|
size = data.size;
|
|
|
|
data.set(key, value);
|
|
this.size += data.size == size ? 0 : 1;
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `MapCache`.
|
|
MapCache.prototype.clear = mapCacheClear;
|
|
MapCache.prototype['delete'] = mapCacheDelete;
|
|
MapCache.prototype.get = mapCacheGet;
|
|
MapCache.prototype.has = mapCacheHas;
|
|
MapCache.prototype.set = mapCacheSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
*
|
|
* Creates an array cache object to store unique values.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [values] The values to cache.
|
|
*/
|
|
function SetCache(values) {
|
|
var index = -1,
|
|
length = values == null ? 0 : values.length;
|
|
|
|
this.__data__ = new MapCache;
|
|
while (++index < length) {
|
|
this.add(values[index]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds `value` to the array cache.
|
|
*
|
|
* @private
|
|
* @name add
|
|
* @memberOf SetCache
|
|
* @alias push
|
|
* @param {*} value The value to cache.
|
|
* @returns {Object} Returns the cache instance.
|
|
*/
|
|
function setCacheAdd(value) {
|
|
this.__data__.set(value, HASH_UNDEFINED);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is in the array cache.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf SetCache
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns `true` if `value` is found, else `false`.
|
|
*/
|
|
function setCacheHas(value) {
|
|
return this.__data__.has(value);
|
|
}
|
|
|
|
// Add methods to `SetCache`.
|
|
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
|
|
SetCache.prototype.has = setCacheHas;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a stack cache object to store key-value pairs.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function Stack(entries) {
|
|
var data = this.__data__ = new ListCache(entries);
|
|
this.size = data.size;
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the stack.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf Stack
|
|
*/
|
|
function stackClear() {
|
|
this.__data__ = new ListCache;
|
|
this.size = 0;
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the stack.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function stackDelete(key) {
|
|
var data = this.__data__,
|
|
result = data['delete'](key);
|
|
|
|
this.size = data.size;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the stack value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function stackGet(key) {
|
|
return this.__data__.get(key);
|
|
}
|
|
|
|
/**
|
|
* Checks if a stack value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function stackHas(key) {
|
|
return this.__data__.has(key);
|
|
}
|
|
|
|
/**
|
|
* Sets the stack `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the stack cache instance.
|
|
*/
|
|
function stackSet(key, value) {
|
|
var data = this.__data__;
|
|
if (data instanceof ListCache) {
|
|
var pairs = data.__data__;
|
|
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|
pairs.push([key, value]);
|
|
this.size = ++data.size;
|
|
return this;
|
|
}
|
|
data = this.__data__ = new MapCache(pairs);
|
|
}
|
|
data.set(key, value);
|
|
this.size = data.size;
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `Stack`.
|
|
Stack.prototype.clear = stackClear;
|
|
Stack.prototype['delete'] = stackDelete;
|
|
Stack.prototype.get = stackGet;
|
|
Stack.prototype.has = stackHas;
|
|
Stack.prototype.set = stackSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @param {boolean} inherited Specify returning inherited property names.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function arrayLikeKeys(value, inherited) {
|
|
var isArr = isArray(value),
|
|
isArg = !isArr && isArguments(value),
|
|
isBuff = !isArr && !isArg && isBuffer(value),
|
|
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
|
|
skipIndexes = isArr || isArg || isBuff || isType,
|
|
result = skipIndexes ? baseTimes(value.length, String) : [],
|
|
length = result.length;
|
|
|
|
for (var key in value) {
|
|
if ((inherited || hasOwnProperty.call(value, key)) &&
|
|
!(skipIndexes && (
|
|
// Safari 9 has enumerable `arguments.length` in strict mode.
|
|
key == 'length' ||
|
|
// Node.js 0.10 has enumerable non-index properties on buffers.
|
|
(isBuff && (key == 'offset' || key == 'parent')) ||
|
|
// PhantomJS 2 has enumerable non-index properties on typed arrays.
|
|
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
|
|
// Skip index properties.
|
|
isIndex(key, length)
|
|
))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.sample` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to sample.
|
|
* @returns {*} Returns the random element.
|
|
*/
|
|
function arraySample(array) {
|
|
var length = array.length;
|
|
return length ? array[baseRandom(0, length - 1)] : undefined;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.sampleSize` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to sample.
|
|
* @param {number} n The number of elements to sample.
|
|
* @returns {Array} Returns the random elements.
|
|
*/
|
|
function arraySampleSize(array, n) {
|
|
return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.shuffle` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to shuffle.
|
|
* @returns {Array} Returns the new shuffled array.
|
|
*/
|
|
function arrayShuffle(array) {
|
|
return shuffleSelf(copyArray(array));
|
|
}
|
|
|
|
/**
|
|
* This function is like `assignValue` except that it doesn't assign
|
|
* `undefined` values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function assignMergeValue(object, key, value) {
|
|
if ((value !== undefined && !eq(object[key], value)) ||
|
|
(value === undefined && !(key in object))) {
|
|
baseAssignValue(object, key, value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function assignValue(object, key, value) {
|
|
var objValue = object[key];
|
|
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
|
|
(value === undefined && !(key in object))) {
|
|
baseAssignValue(object, key, value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} key The key to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function assocIndexOf(array, key) {
|
|
var length = array.length;
|
|
while (length--) {
|
|
if (eq(array[length][0], key)) {
|
|
return length;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Aggregates elements of `collection` on `accumulator` with keys transformed
|
|
* by `iteratee` and values set by `setter`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} setter The function to set `accumulator` values.
|
|
* @param {Function} iteratee The iteratee to transform keys.
|
|
* @param {Object} accumulator The initial aggregated object.
|
|
* @returns {Function} Returns `accumulator`.
|
|
*/
|
|
function baseAggregator(collection, setter, iteratee, accumulator) {
|
|
baseEach(collection, function(value, key, collection) {
|
|
setter(accumulator, value, iteratee(value), collection);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.assign` without support for multiple sources
|
|
* or `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseAssign(object, source) {
|
|
return object && copyObject(source, keys(source), object);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.assignIn` without support for multiple sources
|
|
* or `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseAssignIn(object, source) {
|
|
return object && copyObject(source, keysIn(source), object);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `assignValue` and `assignMergeValue` without
|
|
* value checks.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function baseAssignValue(object, key, value) {
|
|
if (key == '__proto__' && defineProperty) {
|
|
defineProperty(object, key, {
|
|
'configurable': true,
|
|
'enumerable': true,
|
|
'value': value,
|
|
'writable': true
|
|
});
|
|
} else {
|
|
object[key] = value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.at` without support for individual paths.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {string[]} paths The property paths to pick.
|
|
* @returns {Array} Returns the picked elements.
|
|
*/
|
|
function baseAt(object, paths) {
|
|
var index = -1,
|
|
length = paths.length,
|
|
result = Array(length),
|
|
skip = object == null;
|
|
|
|
while (++index < length) {
|
|
result[index] = skip ? undefined : get(object, paths[index]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.clamp` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {number} number The number to clamp.
|
|
* @param {number} [lower] The lower bound.
|
|
* @param {number} upper The upper bound.
|
|
* @returns {number} Returns the clamped number.
|
|
*/
|
|
function baseClamp(number, lower, upper) {
|
|
if (number === number) {
|
|
if (upper !== undefined) {
|
|
number = number <= upper ? number : upper;
|
|
}
|
|
if (lower !== undefined) {
|
|
number = number >= lower ? number : lower;
|
|
}
|
|
}
|
|
return number;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
|
|
* traversed objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to clone.
|
|
* @param {boolean} bitmask The bitmask flags.
|
|
* 1 - Deep clone
|
|
* 2 - Flatten inherited properties
|
|
* 4 - Clone symbols
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @param {string} [key] The key of `value`.
|
|
* @param {Object} [object] The parent object of `value`.
|
|
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
|
|
* @returns {*} Returns the cloned value.
|
|
*/
|
|
function baseClone(value, bitmask, customizer, key, object, stack) {
|
|
var result,
|
|
isDeep = bitmask & CLONE_DEEP_FLAG,
|
|
isFlat = bitmask & CLONE_FLAT_FLAG,
|
|
isFull = bitmask & CLONE_SYMBOLS_FLAG;
|
|
|
|
if (customizer) {
|
|
result = object ? customizer(value, key, object, stack) : customizer(value);
|
|
}
|
|
if (result !== undefined) {
|
|
return result;
|
|
}
|
|
if (!isObject(value)) {
|
|
return value;
|
|
}
|
|
var isArr = isArray(value);
|
|
if (isArr) {
|
|
result = initCloneArray(value);
|
|
if (!isDeep) {
|
|
return copyArray(value, result);
|
|
}
|
|
} else {
|
|
var tag = getTag(value),
|
|
isFunc = tag == funcTag || tag == genTag;
|
|
|
|
if (isBuffer(value)) {
|
|
return cloneBuffer(value, isDeep);
|
|
}
|
|
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
|
result = (isFlat || isFunc) ? {} : initCloneObject(value);
|
|
if (!isDeep) {
|
|
return isFlat
|
|
? copySymbolsIn(value, baseAssignIn(result, value))
|
|
: copySymbols(value, baseAssign(result, value));
|
|
}
|
|
} else {
|
|
if (!cloneableTags[tag]) {
|
|
return object ? value : {};
|
|
}
|
|
result = initCloneByTag(value, tag, isDeep);
|
|
}
|
|
}
|
|
// Check for circular references and return its corresponding clone.
|
|
stack || (stack = new Stack);
|
|
var stacked = stack.get(value);
|
|
if (stacked) {
|
|
return stacked;
|
|
}
|
|
stack.set(value, result);
|
|
|
|
if (isSet(value)) {
|
|
value.forEach(function(subValue) {
|
|
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
|
|
});
|
|
} else if (isMap(value)) {
|
|
value.forEach(function(subValue, key) {
|
|
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
|
|
});
|
|
}
|
|
|
|
var keysFunc = isFull
|
|
? (isFlat ? getAllKeysIn : getAllKeys)
|
|
: (isFlat ? keysIn : keys);
|
|
|
|
var props = isArr ? undefined : keysFunc(value);
|
|
arrayEach(props || value, function(subValue, key) {
|
|
if (props) {
|
|
key = subValue;
|
|
subValue = value[key];
|
|
}
|
|
// Recursively populate clone (susceptible to call stack limits).
|
|
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.conforms` which doesn't clone `source`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function baseConforms(source) {
|
|
var props = keys(source);
|
|
return function(object) {
|
|
return baseConformsTo(object, source, props);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.conformsTo` which accepts `props` to check.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
|
*/
|
|
function baseConformsTo(object, source, props) {
|
|
var length = props.length;
|
|
if (object == null) {
|
|
return !length;
|
|
}
|
|
object = Object(object);
|
|
while (length--) {
|
|
var key = props[length],
|
|
predicate = source[key],
|
|
value = object[key];
|
|
|
|
if ((value === undefined && !(key in object)) || !predicate(value)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.delay` and `_.defer` which accepts `args`
|
|
* to provide to `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to delay.
|
|
* @param {number} wait The number of milliseconds to delay invocation.
|
|
* @param {Array} args The arguments to provide to `func`.
|
|
* @returns {number|Object} Returns the timer id or timeout object.
|
|
*/
|
|
function baseDelay(func, wait, args) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
return setTimeout(function() { func.apply(undefined, args); }, wait);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.difference` without support
|
|
* for excluding multiple arrays or iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Array} values The values to exclude.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
*/
|
|
function baseDifference(array, values, iteratee, comparator) {
|
|
var index = -1,
|
|
includes = arrayIncludes,
|
|
isCommon = true,
|
|
length = array.length,
|
|
result = [],
|
|
valuesLength = values.length;
|
|
|
|
if (!length) {
|
|
return result;
|
|
}
|
|
if (iteratee) {
|
|
values = arrayMap(values, baseUnary(iteratee));
|
|
}
|
|
if (comparator) {
|
|
includes = arrayIncludesWith;
|
|
isCommon = false;
|
|
}
|
|
else if (values.length >= LARGE_ARRAY_SIZE) {
|
|
includes = cacheHas;
|
|
isCommon = false;
|
|
values = new SetCache(values);
|
|
}
|
|
outer:
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
computed = iteratee == null ? value : iteratee(value);
|
|
|
|
value = (comparator || value !== 0) ? value : 0;
|
|
if (isCommon && computed === computed) {
|
|
var valuesIndex = valuesLength;
|
|
while (valuesIndex--) {
|
|
if (values[valuesIndex] === computed) {
|
|
continue outer;
|
|
}
|
|
}
|
|
result.push(value);
|
|
}
|
|
else if (!includes(values, computed, comparator)) {
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.forEach` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
*/
|
|
var baseEach = createBaseEach(baseForOwn);
|
|
|
|
/**
|
|
* The base implementation of `_.forEachRight` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
*/
|
|
var baseEachRight = createBaseEach(baseForOwnRight, true);
|
|
|
|
/**
|
|
* The base implementation of `_.every` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
|
* else `false`
|
|
*/
|
|
function baseEvery(collection, predicate) {
|
|
var result = true;
|
|
baseEach(collection, function(value, index, collection) {
|
|
result = !!predicate(value, index, collection);
|
|
return result;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.max` and `_.min` which accepts a
|
|
* `comparator` to determine the extremum value.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The iteratee invoked per iteration.
|
|
* @param {Function} comparator The comparator used to compare values.
|
|
* @returns {*} Returns the extremum value.
|
|
*/
|
|
function baseExtremum(array, iteratee, comparator) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
current = iteratee(value);
|
|
|
|
if (current != null && (computed === undefined
|
|
? (current === current && !isSymbol(current))
|
|
: comparator(current, computed)
|
|
)) {
|
|
var computed = current,
|
|
result = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.fill` without an iteratee call guard.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to fill.
|
|
* @param {*} value The value to fill `array` with.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function baseFill(array, value, start, end) {
|
|
var length = array.length;
|
|
|
|
start = toInteger(start);
|
|
if (start < 0) {
|
|
start = -start > length ? 0 : (length + start);
|
|
}
|
|
end = (end === undefined || end > length) ? length : toInteger(end);
|
|
if (end < 0) {
|
|
end += length;
|
|
}
|
|
end = start > end ? 0 : toLength(end);
|
|
while (start < end) {
|
|
array[start++] = value;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.filter` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
*/
|
|
function baseFilter(collection, predicate) {
|
|
var result = [];
|
|
baseEach(collection, function(value, index, collection) {
|
|
if (predicate(value, index, collection)) {
|
|
result.push(value);
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.flatten` with support for restricting flattening.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to flatten.
|
|
* @param {number} depth The maximum recursion depth.
|
|
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
|
|
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
|
|
* @param {Array} [result=[]] The initial result value.
|
|
* @returns {Array} Returns the new flattened array.
|
|
*/
|
|
function baseFlatten(array, depth, predicate, isStrict, result) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
predicate || (predicate = isFlattenable);
|
|
result || (result = []);
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (depth > 0 && predicate(value)) {
|
|
if (depth > 1) {
|
|
// Recursively flatten arrays (susceptible to call stack limits).
|
|
baseFlatten(value, depth - 1, predicate, isStrict, result);
|
|
} else {
|
|
arrayPush(result, value);
|
|
}
|
|
} else if (!isStrict) {
|
|
result[result.length] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `baseForOwn` which iterates over `object`
|
|
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseFor = createBaseFor();
|
|
|
|
/**
|
|
* This function is like `baseFor` except that it iterates over properties
|
|
* in the opposite order.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseForRight = createBaseFor(true);
|
|
|
|
/**
|
|
* The base implementation of `_.forOwn` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForOwn(object, iteratee) {
|
|
return object && baseFor(object, iteratee, keys);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.forOwnRight` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForOwnRight(object, iteratee) {
|
|
return object && baseForRight(object, iteratee, keys);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.functions` which creates an array of
|
|
* `object` function property names filtered from `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Array} props The property names to filter.
|
|
* @returns {Array} Returns the function names.
|
|
*/
|
|
function baseFunctions(object, props) {
|
|
return arrayFilter(props, function(key) {
|
|
return isFunction(object[key]);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.get` without support for default values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @returns {*} Returns the resolved value.
|
|
*/
|
|
function baseGet(object, path) {
|
|
path = castPath(path, object);
|
|
|
|
var index = 0,
|
|
length = path.length;
|
|
|
|
while (object != null && index < length) {
|
|
object = object[toKey(path[index++])];
|
|
}
|
|
return (index && index == length) ? object : undefined;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
|
|
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
|
|
* symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @param {Function} symbolsFunc The function to get the symbols of `object`.
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|
*/
|
|
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
|
|
var result = keysFunc(object);
|
|
return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `getTag` without fallbacks for buggy environments.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the `toStringTag`.
|
|
*/
|
|
function baseGetTag(value) {
|
|
if (value == null) {
|
|
return value === undefined ? undefinedTag : nullTag;
|
|
}
|
|
return (symToStringTag && symToStringTag in Object(value))
|
|
? getRawTag(value)
|
|
: objectToString(value);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.gt` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is greater than `other`,
|
|
* else `false`.
|
|
*/
|
|
function baseGt(value, other) {
|
|
return value > other;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.has` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {Array|string} key The key to check.
|
|
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
|
*/
|
|
function baseHas(object, key) {
|
|
return object != null && hasOwnProperty.call(object, key);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.hasIn` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {Array|string} key The key to check.
|
|
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
|
*/
|
|
function baseHasIn(object, key) {
|
|
return object != null && key in Object(object);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.inRange` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {number} number The number to check.
|
|
* @param {number} start The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
|
*/
|
|
function baseInRange(number, start, end) {
|
|
return number >= nativeMin(start, end) && number < nativeMax(start, end);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.intersection`, without support
|
|
* for iteratee shorthands, that accepts an array of arrays to inspect.
|
|
*
|
|
* @private
|
|
* @param {Array} arrays The arrays to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of shared values.
|
|
*/
|
|
function baseIntersection(arrays, iteratee, comparator) {
|
|
var includes = comparator ? arrayIncludesWith : arrayIncludes,
|
|
length = arrays[0].length,
|
|
othLength = arrays.length,
|
|
othIndex = othLength,
|
|
caches = Array(othLength),
|
|
maxLength = Infinity,
|
|
result = [];
|
|
|
|
while (othIndex--) {
|
|
var array = arrays[othIndex];
|
|
if (othIndex && iteratee) {
|
|
array = arrayMap(array, baseUnary(iteratee));
|
|
}
|
|
maxLength = nativeMin(array.length, maxLength);
|
|
caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
|
|
? new SetCache(othIndex && array)
|
|
: undefined;
|
|
}
|
|
array = arrays[0];
|
|
|
|
var index = -1,
|
|
seen = caches[0];
|
|
|
|
outer:
|
|
while (++index < length && result.length < maxLength) {
|
|
var value = array[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
value = (comparator || value !== 0) ? value : 0;
|
|
if (!(seen
|
|
? cacheHas(seen, computed)
|
|
: includes(result, computed, comparator)
|
|
)) {
|
|
othIndex = othLength;
|
|
while (--othIndex) {
|
|
var cache = caches[othIndex];
|
|
if (!(cache
|
|
? cacheHas(cache, computed)
|
|
: includes(arrays[othIndex], computed, comparator))
|
|
) {
|
|
continue outer;
|
|
}
|
|
}
|
|
if (seen) {
|
|
seen.push(computed);
|
|
}
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.invert` and `_.invertBy` which inverts
|
|
* `object` with values transformed by `iteratee` and set by `setter`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} setter The function to set `accumulator` values.
|
|
* @param {Function} iteratee The iteratee to transform values.
|
|
* @param {Object} accumulator The initial inverted object.
|
|
* @returns {Function} Returns `accumulator`.
|
|
*/
|
|
function baseInverter(object, setter, iteratee, accumulator) {
|
|
baseForOwn(object, function(value, key, object) {
|
|
setter(accumulator, iteratee(value), key, object);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.invoke` without support for individual
|
|
* method arguments.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the method to invoke.
|
|
* @param {Array} args The arguments to invoke the method with.
|
|
* @returns {*} Returns the result of the invoked method.
|
|
*/
|
|
function baseInvoke(object, path, args) {
|
|
path = castPath(path, object);
|
|
object = parent(object, path);
|
|
var func = object == null ? object : object[toKey(last(path))];
|
|
return func == null ? undefined : apply(func, object, args);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isArguments`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
*/
|
|
function baseIsArguments(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == argsTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isArrayBuffer` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
|
|
*/
|
|
function baseIsArrayBuffer(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isDate` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a date object, else `false`.
|
|
*/
|
|
function baseIsDate(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == dateTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isEqual` which supports partial comparisons
|
|
* and tracks traversed objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @param {boolean} bitmask The bitmask flags.
|
|
* 1 - Unordered comparison
|
|
* 2 - Partial comparison
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @param {Object} [stack] Tracks traversed `value` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
*/
|
|
function baseIsEqual(value, other, bitmask, customizer, stack) {
|
|
if (value === other) {
|
|
return true;
|
|
}
|
|
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
|
|
return value !== value && other !== other;
|
|
}
|
|
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
|
* deep comparisons and tracks traversed objects enabling objects with circular
|
|
* references to be compared.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
|
|
var objIsArr = isArray(object),
|
|
othIsArr = isArray(other),
|
|
objTag = objIsArr ? arrayTag : getTag(object),
|
|
othTag = othIsArr ? arrayTag : getTag(other);
|
|
|
|
objTag = objTag == argsTag ? objectTag : objTag;
|
|
othTag = othTag == argsTag ? objectTag : othTag;
|
|
|
|
var objIsObj = objTag == objectTag,
|
|
othIsObj = othTag == objectTag,
|
|
isSameTag = objTag == othTag;
|
|
|
|
if (isSameTag && isBuffer(object)) {
|
|
if (!isBuffer(other)) {
|
|
return false;
|
|
}
|
|
objIsArr = true;
|
|
objIsObj = false;
|
|
}
|
|
if (isSameTag && !objIsObj) {
|
|
stack || (stack = new Stack);
|
|
return (objIsArr || isTypedArray(object))
|
|
? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
|
|
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
|
|
}
|
|
if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
|
|
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
|
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
|
|
|
if (objIsWrapped || othIsWrapped) {
|
|
var objUnwrapped = objIsWrapped ? object.value() : object,
|
|
othUnwrapped = othIsWrapped ? other.value() : other;
|
|
|
|
stack || (stack = new Stack);
|
|
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
|
|
}
|
|
}
|
|
if (!isSameTag) {
|
|
return false;
|
|
}
|
|
stack || (stack = new Stack);
|
|
return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isMap` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
|
|
*/
|
|
function baseIsMap(value) {
|
|
return isObjectLike(value) && getTag(value) == mapTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isMatch` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property values to match.
|
|
* @param {Array} matchData The property names, values, and compare flags to match.
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
|
*/
|
|
function baseIsMatch(object, source, matchData, customizer) {
|
|
var index = matchData.length,
|
|
length = index,
|
|
noCustomizer = !customizer;
|
|
|
|
if (object == null) {
|
|
return !length;
|
|
}
|
|
object = Object(object);
|
|
while (index--) {
|
|
var data = matchData[index];
|
|
if ((noCustomizer && data[2])
|
|
? data[1] !== object[data[0]]
|
|
: !(data[0] in object)
|
|
) {
|
|
return false;
|
|
}
|
|
}
|
|
while (++index < length) {
|
|
data = matchData[index];
|
|
var key = data[0],
|
|
objValue = object[key],
|
|
srcValue = data[1];
|
|
|
|
if (noCustomizer && data[2]) {
|
|
if (objValue === undefined && !(key in object)) {
|
|
return false;
|
|
}
|
|
} else {
|
|
var stack = new Stack;
|
|
if (customizer) {
|
|
var result = customizer(objValue, srcValue, key, object, source, stack);
|
|
}
|
|
if (!(result === undefined
|
|
? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
|
|
: result
|
|
)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isNative` without bad shim checks.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
* else `false`.
|
|
*/
|
|
function baseIsNative(value) {
|
|
if (!isObject(value) || isMasked(value)) {
|
|
return false;
|
|
}
|
|
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
|
|
return pattern.test(toSource(value));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isRegExp` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
|
|
*/
|
|
function baseIsRegExp(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == regexpTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isSet` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
|
|
*/
|
|
function baseIsSet(value) {
|
|
return isObjectLike(value) && getTag(value) == setTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isTypedArray` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
*/
|
|
function baseIsTypedArray(value) {
|
|
return isObjectLike(value) &&
|
|
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.iteratee`.
|
|
*
|
|
* @private
|
|
* @param {*} [value=_.identity] The value to convert to an iteratee.
|
|
* @returns {Function} Returns the iteratee.
|
|
*/
|
|
function baseIteratee(value) {
|
|
// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
|
|
// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
|
|
if (typeof value == 'function') {
|
|
return value;
|
|
}
|
|
if (value == null) {
|
|
return identity;
|
|
}
|
|
if (typeof value == 'object') {
|
|
return isArray(value)
|
|
? baseMatchesProperty(value[0], value[1])
|
|
: baseMatches(value);
|
|
}
|
|
return property(value);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function baseKeys(object) {
|
|
if (!isPrototype(object)) {
|
|
return nativeKeys(object);
|
|
}
|
|
var result = [];
|
|
for (var key in Object(object)) {
|
|
if (hasOwnProperty.call(object, key) && key != 'constructor') {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function baseKeysIn(object) {
|
|
if (!isObject(object)) {
|
|
return nativeKeysIn(object);
|
|
}
|
|
var isProto = isPrototype(object),
|
|
result = [];
|
|
|
|
for (var key in object) {
|
|
if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.lt` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is less than `other`,
|
|
* else `false`.
|
|
*/
|
|
function baseLt(value, other) {
|
|
return value < other;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.map` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
*/
|
|
function baseMap(collection, iteratee) {
|
|
var index = -1,
|
|
result = isArrayLike(collection) ? Array(collection.length) : [];
|
|
|
|
baseEach(collection, function(value, key, collection) {
|
|
result[++index] = iteratee(value, key, collection);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.matches` which doesn't clone `source`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object of property values to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function baseMatches(source) {
|
|
var matchData = getMatchData(source);
|
|
if (matchData.length == 1 && matchData[0][2]) {
|
|
return matchesStrictComparable(matchData[0][0], matchData[0][1]);
|
|
}
|
|
return function(object) {
|
|
return object === source || baseIsMatch(object, source, matchData);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
|
|
*
|
|
* @private
|
|
* @param {string} path The path of the property to get.
|
|
* @param {*} srcValue The value to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function baseMatchesProperty(path, srcValue) {
|
|
if (isKey(path) && isStrictComparable(srcValue)) {
|
|
return matchesStrictComparable(toKey(path), srcValue);
|
|
}
|
|
return function(object) {
|
|
var objValue = get(object, path);
|
|
return (objValue === undefined && objValue === srcValue)
|
|
? hasIn(object, path)
|
|
: baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.merge` without support for multiple sources.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {number} srcIndex The index of `source`.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
* counterparts.
|
|
*/
|
|
function baseMerge(object, source, srcIndex, customizer, stack) {
|
|
if (object === source) {
|
|
return;
|
|
}
|
|
baseFor(source, function(srcValue, key) {
|
|
stack || (stack = new Stack);
|
|
if (isObject(srcValue)) {
|
|
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
|
|
}
|
|
else {
|
|
var newValue = customizer
|
|
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
|
|
: undefined;
|
|
|
|
if (newValue === undefined) {
|
|
newValue = srcValue;
|
|
}
|
|
assignMergeValue(object, key, newValue);
|
|
}
|
|
}, keysIn);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
* deep merges and tracks traversed objects enabling objects with circular
|
|
* references to be merged.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {string} key The key of the value to merge.
|
|
* @param {number} srcIndex The index of `source`.
|
|
* @param {Function} mergeFunc The function to merge values.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
* counterparts.
|
|
*/
|
|
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
|
var objValue = safeGet(object, key),
|
|
srcValue = safeGet(source, key),
|
|
stacked = stack.get(srcValue);
|
|
|
|
if (stacked) {
|
|
assignMergeValue(object, key, stacked);
|
|
return;
|
|
}
|
|
var newValue = customizer
|
|
? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
|
: undefined;
|
|
|
|
var isCommon = newValue === undefined;
|
|
|
|
if (isCommon) {
|
|
var isArr = isArray(srcValue),
|
|
isBuff = !isArr && isBuffer(srcValue),
|
|
isTyped = !isArr && !isBuff && isTypedArray(srcValue);
|
|
|
|
newValue = srcValue;
|
|
if (isArr || isBuff || isTyped) {
|
|
if (isArray(objValue)) {
|
|
newValue = objValue;
|
|
}
|
|
else if (isArrayLikeObject(objValue)) {
|
|
newValue = copyArray(objValue);
|
|
}
|
|
else if (isBuff) {
|
|
isCommon = false;
|
|
newValue = cloneBuffer(srcValue, true);
|
|
}
|
|
else if (isTyped) {
|
|
isCommon = false;
|
|
newValue = cloneTypedArray(srcValue, true);
|
|
}
|
|
else {
|
|
newValue = [];
|
|
}
|
|
}
|
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
newValue = objValue;
|
|
if (isArguments(objValue)) {
|
|
newValue = toPlainObject(objValue);
|
|
}
|
|
else if (!isObject(objValue) || isFunction(objValue)) {
|
|
newValue = initCloneObject(srcValue);
|
|
}
|
|
}
|
|
else {
|
|
isCommon = false;
|
|
}
|
|
}
|
|
if (isCommon) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
stack.set(srcValue, newValue);
|
|
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
|
stack['delete'](srcValue);
|
|
}
|
|
assignMergeValue(object, key, newValue);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.nth` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {number} n The index of the element to return.
|
|
* @returns {*} Returns the nth element of `array`.
|
|
*/
|
|
function baseNth(array, n) {
|
|
var length = array.length;
|
|
if (!length) {
|
|
return;
|
|
}
|
|
n += n < 0 ? length : 0;
|
|
return isIndex(n, length) ? array[n] : undefined;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.orderBy` without param guards.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
|
|
* @param {string[]} orders The sort orders of `iteratees`.
|
|
* @returns {Array} Returns the new sorted array.
|
|
*/
|
|
function baseOrderBy(collection, iteratees, orders) {
|
|
var index = -1;
|
|
iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
|
|
|
|
var result = baseMap(collection, function(value, key, collection) {
|
|
var criteria = arrayMap(iteratees, function(iteratee) {
|
|
return iteratee(value);
|
|
});
|
|
return { 'criteria': criteria, 'index': ++index, 'value': value };
|
|
});
|
|
|
|
return baseSortBy(result, function(object, other) {
|
|
return compareMultiple(object, other, orders);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pick` without support for individual
|
|
* property identifiers.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {string[]} paths The property paths to pick.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function basePick(object, paths) {
|
|
return basePickBy(object, paths, function(value, path) {
|
|
return hasIn(object, path);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pickBy` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {string[]} paths The property paths to pick.
|
|
* @param {Function} predicate The function invoked per property.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function basePickBy(object, paths, predicate) {
|
|
var index = -1,
|
|
length = paths.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var path = paths[index],
|
|
value = baseGet(object, path);
|
|
|
|
if (predicate(value, path)) {
|
|
baseSet(result, castPath(path, object), value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseProperty` which supports deep paths.
|
|
*
|
|
* @private
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @returns {Function} Returns the new accessor function.
|
|
*/
|
|
function basePropertyDeep(path) {
|
|
return function(object) {
|
|
return baseGet(object, path);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pullAllBy` without support for iteratee
|
|
* shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function basePullAll(array, values, iteratee, comparator) {
|
|
var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
|
|
index = -1,
|
|
length = values.length,
|
|
seen = array;
|
|
|
|
if (array === values) {
|
|
values = copyArray(values);
|
|
}
|
|
if (iteratee) {
|
|
seen = arrayMap(array, baseUnary(iteratee));
|
|
}
|
|
while (++index < length) {
|
|
var fromIndex = 0,
|
|
value = values[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
|
|
if (seen !== array) {
|
|
splice.call(seen, fromIndex, 1);
|
|
}
|
|
splice.call(array, fromIndex, 1);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pullAt` without support for individual
|
|
* indexes or capturing the removed elements.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {number[]} indexes The indexes of elements to remove.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function basePullAt(array, indexes) {
|
|
var length = array ? indexes.length : 0,
|
|
lastIndex = length - 1;
|
|
|
|
while (length--) {
|
|
var index = indexes[length];
|
|
if (length == lastIndex || index !== previous) {
|
|
var previous = index;
|
|
if (isIndex(index)) {
|
|
splice.call(array, index, 1);
|
|
} else {
|
|
baseUnset(array, index);
|
|
}
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.random` without support for returning
|
|
* floating-point numbers.
|
|
*
|
|
* @private
|
|
* @param {number} lower The lower bound.
|
|
* @param {number} upper The upper bound.
|
|
* @returns {number} Returns the random number.
|
|
*/
|
|
function baseRandom(lower, upper) {
|
|
return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.range` and `_.rangeRight` which doesn't
|
|
* coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {number} start The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @param {number} step The value to increment or decrement by.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Array} Returns the range of numbers.
|
|
*/
|
|
function baseRange(start, end, step, fromRight) {
|
|
var index = -1,
|
|
length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
|
|
result = Array(length);
|
|
|
|
while (length--) {
|
|
result[fromRight ? length : ++index] = start;
|
|
start += step;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.repeat` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to repeat.
|
|
* @param {number} n The number of times to repeat the string.
|
|
* @returns {string} Returns the repeated string.
|
|
*/
|
|
function baseRepeat(string, n) {
|
|
var result = '';
|
|
if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
|
|
return result;
|
|
}
|
|
// Leverage the exponentiation by squaring algorithm for a faster repeat.
|
|
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
|
|
do {
|
|
if (n % 2) {
|
|
result += string;
|
|
}
|
|
n = nativeFloor(n / 2);
|
|
if (n) {
|
|
string += string;
|
|
}
|
|
} while (n);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseRest(func, start) {
|
|
return setToString(overRest(func, start, identity), func + '');
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sample`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @returns {*} Returns the random element.
|
|
*/
|
|
function baseSample(collection) {
|
|
return arraySample(values(collection));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sampleSize` without param guards.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @param {number} n The number of elements to sample.
|
|
* @returns {Array} Returns the random elements.
|
|
*/
|
|
function baseSampleSize(collection, n) {
|
|
var array = values(collection);
|
|
return shuffleSelf(array, baseClamp(n, 0, array.length));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.set`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {*} value The value to set.
|
|
* @param {Function} [customizer] The function to customize path creation.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseSet(object, path, value, customizer) {
|
|
if (!isObject(object)) {
|
|
return object;
|
|
}
|
|
path = castPath(path, object);
|
|
|
|
var index = -1,
|
|
length = path.length,
|
|
lastIndex = length - 1,
|
|
nested = object;
|
|
|
|
while (nested != null && ++index < length) {
|
|
var key = toKey(path[index]),
|
|
newValue = value;
|
|
|
|
if (index != lastIndex) {
|
|
var objValue = nested[key];
|
|
newValue = customizer ? customizer(objValue, key, nested) : undefined;
|
|
if (newValue === undefined) {
|
|
newValue = isObject(objValue)
|
|
? objValue
|
|
: (isIndex(path[index + 1]) ? [] : {});
|
|
}
|
|
}
|
|
assignValue(nested, key, newValue);
|
|
nested = nested[key];
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `setData` without support for hot loop shorting.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to associate metadata with.
|
|
* @param {*} data The metadata.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var baseSetData = !metaMap ? identity : function(func, data) {
|
|
metaMap.set(func, data);
|
|
return func;
|
|
};
|
|
|
|
/**
|
|
* The base implementation of `setToString` without support for hot loop shorting.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to modify.
|
|
* @param {Function} string The `toString` result.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var baseSetToString = !defineProperty ? identity : function(func, string) {
|
|
return defineProperty(func, 'toString', {
|
|
'configurable': true,
|
|
'enumerable': false,
|
|
'value': constant(string),
|
|
'writable': true
|
|
});
|
|
};
|
|
|
|
/**
|
|
* The base implementation of `_.shuffle`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to shuffle.
|
|
* @returns {Array} Returns the new shuffled array.
|
|
*/
|
|
function baseShuffle(collection) {
|
|
return shuffleSelf(values(collection));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.slice` without an iteratee call guard.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to slice.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
*/
|
|
function baseSlice(array, start, end) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
if (start < 0) {
|
|
start = -start > length ? 0 : (length + start);
|
|
}
|
|
end = end > length ? length : end;
|
|
if (end < 0) {
|
|
end += length;
|
|
}
|
|
length = start > end ? 0 : ((end - start) >>> 0);
|
|
start >>>= 0;
|
|
|
|
var result = Array(length);
|
|
while (++index < length) {
|
|
result[index] = array[index + start];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.some` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
* else `false`.
|
|
*/
|
|
function baseSome(collection, predicate) {
|
|
var result;
|
|
|
|
baseEach(collection, function(value, index, collection) {
|
|
result = predicate(value, index, collection);
|
|
return !result;
|
|
});
|
|
return !!result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
|
|
* performs a binary search of `array` to determine the index at which `value`
|
|
* should be inserted into `array` in order to maintain its sort order.
|
|
*
|
|
* @private
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
*/
|
|
function baseSortedIndex(array, value, retHighest) {
|
|
var low = 0,
|
|
high = array == null ? low : array.length;
|
|
|
|
if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
|
|
while (low < high) {
|
|
var mid = (low + high) >>> 1,
|
|
computed = array[mid];
|
|
|
|
if (computed !== null && !isSymbol(computed) &&
|
|
(retHighest ? (computed <= value) : (computed < value))) {
|
|
low = mid + 1;
|
|
} else {
|
|
high = mid;
|
|
}
|
|
}
|
|
return high;
|
|
}
|
|
return baseSortedIndexBy(array, value, identity, retHighest);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
|
|
* which invokes `iteratee` for `value` and each element of `array` to compute
|
|
* their sort ranking. The iteratee is invoked with one argument; (value).
|
|
*
|
|
* @private
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {Function} iteratee The iteratee invoked per element.
|
|
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
*/
|
|
function baseSortedIndexBy(array, value, iteratee, retHighest) {
|
|
value = iteratee(value);
|
|
|
|
var low = 0,
|
|
high = array == null ? 0 : array.length,
|
|
valIsNaN = value !== value,
|
|
valIsNull = value === null,
|
|
valIsSymbol = isSymbol(value),
|
|
valIsUndefined = value === undefined;
|
|
|
|
while (low < high) {
|
|
var mid = nativeFloor((low + high) / 2),
|
|
computed = iteratee(array[mid]),
|
|
othIsDefined = computed !== undefined,
|
|
othIsNull = computed === null,
|
|
othIsReflexive = computed === computed,
|
|
othIsSymbol = isSymbol(computed);
|
|
|
|
if (valIsNaN) {
|
|
var setLow = retHighest || othIsReflexive;
|
|
} else if (valIsUndefined) {
|
|
setLow = othIsReflexive && (retHighest || othIsDefined);
|
|
} else if (valIsNull) {
|
|
setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
|
|
} else if (valIsSymbol) {
|
|
setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
|
|
} else if (othIsNull || othIsSymbol) {
|
|
setLow = false;
|
|
} else {
|
|
setLow = retHighest ? (computed <= value) : (computed < value);
|
|
}
|
|
if (setLow) {
|
|
low = mid + 1;
|
|
} else {
|
|
high = mid;
|
|
}
|
|
}
|
|
return nativeMin(high, MAX_ARRAY_INDEX);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
|
|
* support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
*/
|
|
function baseSortedUniq(array, iteratee) {
|
|
var index = -1,
|
|
length = array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
if (!index || !eq(computed, seen)) {
|
|
var seen = computed;
|
|
result[resIndex++] = value === 0 ? 0 : value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.toNumber` which doesn't ensure correct
|
|
* conversions of binary, hexadecimal, or octal string values.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {number} Returns the number.
|
|
*/
|
|
function baseToNumber(value) {
|
|
if (typeof value == 'number') {
|
|
return value;
|
|
}
|
|
if (isSymbol(value)) {
|
|
return NAN;
|
|
}
|
|
return +value;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.toString` which doesn't convert nullish
|
|
* values to empty strings.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {string} Returns the string.
|
|
*/
|
|
function baseToString(value) {
|
|
// Exit early for strings to avoid a performance hit in some environments.
|
|
if (typeof value == 'string') {
|
|
return value;
|
|
}
|
|
if (isArray(value)) {
|
|
// Recursively convert values (susceptible to call stack limits).
|
|
return arrayMap(value, baseToString) + '';
|
|
}
|
|
if (isSymbol(value)) {
|
|
return symbolToString ? symbolToString.call(value) : '';
|
|
}
|
|
var result = (value + '');
|
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
*/
|
|
function baseUniq(array, iteratee, comparator) {
|
|
var index = -1,
|
|
includes = arrayIncludes,
|
|
length = array.length,
|
|
isCommon = true,
|
|
result = [],
|
|
seen = result;
|
|
|
|
if (comparator) {
|
|
isCommon = false;
|
|
includes = arrayIncludesWith;
|
|
}
|
|
else if (length >= LARGE_ARRAY_SIZE) {
|
|
var set = iteratee ? null : createSet(array);
|
|
if (set) {
|
|
return setToArray(set);
|
|
}
|
|
isCommon = false;
|
|
includes = cacheHas;
|
|
seen = new SetCache;
|
|
}
|
|
else {
|
|
seen = iteratee ? [] : result;
|
|
}
|
|
outer:
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
value = (comparator || value !== 0) ? value : 0;
|
|
if (isCommon && computed === computed) {
|
|
var seenIndex = seen.length;
|
|
while (seenIndex--) {
|
|
if (seen[seenIndex] === computed) {
|
|
continue outer;
|
|
}
|
|
}
|
|
if (iteratee) {
|
|
seen.push(computed);
|
|
}
|
|
result.push(value);
|
|
}
|
|
else if (!includes(seen, computed, comparator)) {
|
|
if (seen !== result) {
|
|
seen.push(computed);
|
|
}
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.unset`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The property path to unset.
|
|
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
|
*/
|
|
function baseUnset(object, path) {
|
|
path = castPath(path, object);
|
|
object = parent(object, path);
|
|
return object == null || delete object[toKey(last(path))];
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.update`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to update.
|
|
* @param {Function} updater The function to produce the updated value.
|
|
* @param {Function} [customizer] The function to customize path creation.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseUpdate(object, path, updater, customizer) {
|
|
return baseSet(object, path, updater(baseGet(object, path)), customizer);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.dropWhile` and `_.takeWhile`
|
|
* without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {boolean} [isDrop] Specify dropping elements instead of taking them.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
*/
|
|
function baseWhile(array, predicate, isDrop, fromRight) {
|
|
var length = array.length,
|
|
index = fromRight ? length : -1;
|
|
|
|
while ((fromRight ? index-- : ++index < length) &&
|
|
predicate(array[index], index, array)) {}
|
|
|
|
return isDrop
|
|
? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
|
|
: baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `wrapperValue` which returns the result of
|
|
* performing a sequence of actions on the unwrapped `value`, where each
|
|
* successive action is supplied the return value of the previous.
|
|
*
|
|
* @private
|
|
* @param {*} value The unwrapped value.
|
|
* @param {Array} actions Actions to perform to resolve the unwrapped value.
|
|
* @returns {*} Returns the resolved value.
|
|
*/
|
|
function baseWrapperValue(value, actions) {
|
|
var result = value;
|
|
if (result instanceof LazyWrapper) {
|
|
result = result.value();
|
|
}
|
|
return arrayReduce(actions, function(result, action) {
|
|
return action.func.apply(action.thisArg, arrayPush([result], action.args));
|
|
}, result);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.xor`, without support for
|
|
* iteratee shorthands, that accepts an array of arrays to inspect.
|
|
*
|
|
* @private
|
|
* @param {Array} arrays The arrays to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of values.
|
|
*/
|
|
function baseXor(arrays, iteratee, comparator) {
|
|
var length = arrays.length;
|
|
if (length < 2) {
|
|
return length ? baseUniq(arrays[0]) : [];
|
|
}
|
|
var index = -1,
|
|
result = Array(length);
|
|
|
|
while (++index < length) {
|
|
var array = arrays[index],
|
|
othIndex = -1;
|
|
|
|
while (++othIndex < length) {
|
|
if (othIndex != index) {
|
|
result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
|
|
}
|
|
}
|
|
}
|
|
return baseUniq(baseFlatten(result, 1), iteratee, comparator);
|
|
}
|
|
|
|
/**
|
|
* This base implementation of `_.zipObject` which assigns values using `assignFunc`.
|
|
*
|
|
* @private
|
|
* @param {Array} props The property identifiers.
|
|
* @param {Array} values The property values.
|
|
* @param {Function} assignFunc The function to assign values.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function baseZipObject(props, values, assignFunc) {
|
|
var index = -1,
|
|
length = props.length,
|
|
valsLength = values.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var value = index < valsLength ? values[index] : undefined;
|
|
assignFunc(result, props[index], value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Casts `value` to an empty array if it's not an array like object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @returns {Array|Object} Returns the cast array-like object.
|
|
*/
|
|
function castArrayLikeObject(value) {
|
|
return isArrayLikeObject(value) ? value : [];
|
|
}
|
|
|
|
/**
|
|
* Casts `value` to `identity` if it's not a function.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @returns {Function} Returns cast function.
|
|
*/
|
|
function castFunction(value) {
|
|
return typeof value == 'function' ? value : identity;
|
|
}
|
|
|
|
/**
|
|
* Casts `value` to a path array if it's not one.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @param {Object} [object] The object to query keys on.
|
|
* @returns {Array} Returns the cast property path array.
|
|
*/
|
|
function castPath(value, object) {
|
|
if (isArray(value)) {
|
|
return value;
|
|
}
|
|
return isKey(value, object) ? [value] : stringToPath(toString(value));
|
|
}
|
|
|
|
/**
|
|
* A `baseRest` alias which can be replaced with `identity` by module
|
|
* replacement plugins.
|
|
*
|
|
* @private
|
|
* @type {Function}
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
var castRest = baseRest;
|
|
|
|
/**
|
|
* Casts `array` to a slice if it's needed.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {number} start The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns the cast slice.
|
|
*/
|
|
function castSlice(array, start, end) {
|
|
var length = array.length;
|
|
end = end === undefined ? length : end;
|
|
return (!start && end >= length) ? array : baseSlice(array, start, end);
|
|
}
|
|
|
|
/**
|
|
* A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
|
|
*
|
|
* @private
|
|
* @param {number|Object} id The timer id or timeout object of the timer to clear.
|
|
*/
|
|
var clearTimeout = ctxClearTimeout || function(id) {
|
|
return root.clearTimeout(id);
|
|
};
|
|
|
|
/**
|
|
* Creates a clone of `buffer`.
|
|
*
|
|
* @private
|
|
* @param {Buffer} buffer The buffer to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Buffer} Returns the cloned buffer.
|
|
*/
|
|
function cloneBuffer(buffer, isDeep) {
|
|
if (isDeep) {
|
|
return buffer.slice();
|
|
}
|
|
var length = buffer.length,
|
|
result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
|
|
|
|
buffer.copy(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `arrayBuffer`.
|
|
*
|
|
* @private
|
|
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
|
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
|
*/
|
|
function cloneArrayBuffer(arrayBuffer) {
|
|
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `dataView`.
|
|
*
|
|
* @private
|
|
* @param {Object} dataView The data view to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the cloned data view.
|
|
*/
|
|
function cloneDataView(dataView, isDeep) {
|
|
var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
|
|
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `regexp`.
|
|
*
|
|
* @private
|
|
* @param {Object} regexp The regexp to clone.
|
|
* @returns {Object} Returns the cloned regexp.
|
|
*/
|
|
function cloneRegExp(regexp) {
|
|
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
|
|
result.lastIndex = regexp.lastIndex;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of the `symbol` object.
|
|
*
|
|
* @private
|
|
* @param {Object} symbol The symbol object to clone.
|
|
* @returns {Object} Returns the cloned symbol object.
|
|
*/
|
|
function cloneSymbol(symbol) {
|
|
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `typedArray`.
|
|
*
|
|
* @private
|
|
* @param {Object} typedArray The typed array to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the cloned typed array.
|
|
*/
|
|
function cloneTypedArray(typedArray, isDeep) {
|
|
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
|
|
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
}
|
|
|
|
/**
|
|
* Compares values to sort them in ascending order.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {number} Returns the sort order indicator for `value`.
|
|
*/
|
|
function compareAscending(value, other) {
|
|
if (value !== other) {
|
|
var valIsDefined = value !== undefined,
|
|
valIsNull = value === null,
|
|
valIsReflexive = value === value,
|
|
valIsSymbol = isSymbol(value);
|
|
|
|
var othIsDefined = other !== undefined,
|
|
othIsNull = other === null,
|
|
othIsReflexive = other === other,
|
|
othIsSymbol = isSymbol(other);
|
|
|
|
if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
|
|
(valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
|
|
(valIsNull && othIsDefined && othIsReflexive) ||
|
|
(!valIsDefined && othIsReflexive) ||
|
|
!valIsReflexive) {
|
|
return 1;
|
|
}
|
|
if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
|
|
(othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
|
|
(othIsNull && valIsDefined && valIsReflexive) ||
|
|
(!othIsDefined && valIsReflexive) ||
|
|
!othIsReflexive) {
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.orderBy` to compare multiple properties of a value to another
|
|
* and stable sort them.
|
|
*
|
|
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
|
|
* specify an order of "desc" for descending or "asc" for ascending sort order
|
|
* of corresponding values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {boolean[]|string[]} orders The order to sort by for each property.
|
|
* @returns {number} Returns the sort order indicator for `object`.
|
|
*/
|
|
function compareMultiple(object, other, orders) {
|
|
var index = -1,
|
|
objCriteria = object.criteria,
|
|
othCriteria = other.criteria,
|
|
length = objCriteria.length,
|
|
ordersLength = orders.length;
|
|
|
|
while (++index < length) {
|
|
var result = compareAscending(objCriteria[index], othCriteria[index]);
|
|
if (result) {
|
|
if (index >= ordersLength) {
|
|
return result;
|
|
}
|
|
var order = orders[index];
|
|
return result * (order == 'desc' ? -1 : 1);
|
|
}
|
|
}
|
|
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
|
|
// that causes it, under certain circumstances, to provide the same value for
|
|
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
|
|
// for more details.
|
|
//
|
|
// This also ensures a stable sort in V8 and other engines.
|
|
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
|
|
return object.index - other.index;
|
|
}
|
|
|
|
/**
|
|
* Creates an array that is the composition of partially applied arguments,
|
|
* placeholders, and provided arguments into a single array of arguments.
|
|
*
|
|
* @private
|
|
* @param {Array} args The provided arguments.
|
|
* @param {Array} partials The arguments to prepend to those provided.
|
|
* @param {Array} holders The `partials` placeholder indexes.
|
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
|
* @returns {Array} Returns the new array of composed arguments.
|
|
*/
|
|
function composeArgs(args, partials, holders, isCurried) {
|
|
var argsIndex = -1,
|
|
argsLength = args.length,
|
|
holdersLength = holders.length,
|
|
leftIndex = -1,
|
|
leftLength = partials.length,
|
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
|
result = Array(leftLength + rangeLength),
|
|
isUncurried = !isCurried;
|
|
|
|
while (++leftIndex < leftLength) {
|
|
result[leftIndex] = partials[leftIndex];
|
|
}
|
|
while (++argsIndex < holdersLength) {
|
|
if (isUncurried || argsIndex < argsLength) {
|
|
result[holders[argsIndex]] = args[argsIndex];
|
|
}
|
|
}
|
|
while (rangeLength--) {
|
|
result[leftIndex++] = args[argsIndex++];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This function is like `composeArgs` except that the arguments composition
|
|
* is tailored for `_.partialRight`.
|
|
*
|
|
* @private
|
|
* @param {Array} args The provided arguments.
|
|
* @param {Array} partials The arguments to append to those provided.
|
|
* @param {Array} holders The `partials` placeholder indexes.
|
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
|
* @returns {Array} Returns the new array of composed arguments.
|
|
*/
|
|
function composeArgsRight(args, partials, holders, isCurried) {
|
|
var argsIndex = -1,
|
|
argsLength = args.length,
|
|
holdersIndex = -1,
|
|
holdersLength = holders.length,
|
|
rightIndex = -1,
|
|
rightLength = partials.length,
|
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
|
result = Array(rangeLength + rightLength),
|
|
isUncurried = !isCurried;
|
|
|
|
while (++argsIndex < rangeLength) {
|
|
result[argsIndex] = args[argsIndex];
|
|
}
|
|
var offset = argsIndex;
|
|
while (++rightIndex < rightLength) {
|
|
result[offset + rightIndex] = partials[rightIndex];
|
|
}
|
|
while (++holdersIndex < holdersLength) {
|
|
if (isUncurried || argsIndex < argsLength) {
|
|
result[offset + holders[holdersIndex]] = args[argsIndex++];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Copies the values of `source` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} source The array to copy values from.
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function copyArray(source, array) {
|
|
var index = -1,
|
|
length = source.length;
|
|
|
|
array || (array = Array(length));
|
|
while (++index < length) {
|
|
array[index] = source[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Copies properties of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy properties from.
|
|
* @param {Array} props The property identifiers to copy.
|
|
* @param {Object} [object={}] The object to copy properties to.
|
|
* @param {Function} [customizer] The function to customize copied values.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copyObject(source, props, object, customizer) {
|
|
var isNew = !object;
|
|
object || (object = {});
|
|
|
|
var index = -1,
|
|
length = props.length;
|
|
|
|
while (++index < length) {
|
|
var key = props[index];
|
|
|
|
var newValue = customizer
|
|
? customizer(object[key], source[key], key, object, source)
|
|
: undefined;
|
|
|
|
if (newValue === undefined) {
|
|
newValue = source[key];
|
|
}
|
|
if (isNew) {
|
|
baseAssignValue(object, key, newValue);
|
|
} else {
|
|
assignValue(object, key, newValue);
|
|
}
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* Copies own symbols of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy symbols from.
|
|
* @param {Object} [object={}] The object to copy symbols to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copySymbols(source, object) {
|
|
return copyObject(source, getSymbols(source), object);
|
|
}
|
|
|
|
/**
|
|
* Copies own and inherited symbols of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy symbols from.
|
|
* @param {Object} [object={}] The object to copy symbols to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copySymbolsIn(source, object) {
|
|
return copyObject(source, getSymbolsIn(source), object);
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.groupBy`.
|
|
*
|
|
* @private
|
|
* @param {Function} setter The function to set accumulator values.
|
|
* @param {Function} [initializer] The accumulator object initializer.
|
|
* @returns {Function} Returns the new aggregator function.
|
|
*/
|
|
function createAggregator(setter, initializer) {
|
|
return function(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayAggregator : baseAggregator,
|
|
accumulator = initializer ? initializer() : {};
|
|
|
|
return func(collection, setter, getIteratee(iteratee, 2), accumulator);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.assign`.
|
|
*
|
|
* @private
|
|
* @param {Function} assigner The function to assign values.
|
|
* @returns {Function} Returns the new assigner function.
|
|
*/
|
|
function createAssigner(assigner) {
|
|
return baseRest(function(object, sources) {
|
|
var index = -1,
|
|
length = sources.length,
|
|
customizer = length > 1 ? sources[length - 1] : undefined,
|
|
guard = length > 2 ? sources[2] : undefined;
|
|
|
|
customizer = (assigner.length > 3 && typeof customizer == 'function')
|
|
? (length--, customizer)
|
|
: undefined;
|
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
customizer = length < 3 ? undefined : customizer;
|
|
length = 1;
|
|
}
|
|
object = Object(object);
|
|
while (++index < length) {
|
|
var source = sources[index];
|
|
if (source) {
|
|
assigner(object, source, index, customizer);
|
|
}
|
|
}
|
|
return object;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a `baseEach` or `baseEachRight` function.
|
|
*
|
|
* @private
|
|
* @param {Function} eachFunc The function to iterate over a collection.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseEach(eachFunc, fromRight) {
|
|
return function(collection, iteratee) {
|
|
if (collection == null) {
|
|
return collection;
|
|
}
|
|
if (!isArrayLike(collection)) {
|
|
return eachFunc(collection, iteratee);
|
|
}
|
|
var length = collection.length,
|
|
index = fromRight ? length : -1,
|
|
iterable = Object(collection);
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
if (iteratee(iterable[index], index, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return collection;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseFor(fromRight) {
|
|
return function(object, iteratee, keysFunc) {
|
|
var index = -1,
|
|
iterable = Object(object),
|
|
props = keysFunc(object),
|
|
length = props.length;
|
|
|
|
while (length--) {
|
|
var key = props[fromRight ? length : ++index];
|
|
if (iteratee(iterable[key], key, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return object;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with the optional `this`
|
|
* binding of `thisArg`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createBind(func, bitmask, thisArg) {
|
|
var isBind = bitmask & WRAP_BIND_FLAG,
|
|
Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
return fn.apply(isBind ? thisArg : this, arguments);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.lowerFirst`.
|
|
*
|
|
* @private
|
|
* @param {string} methodName The name of the `String` case method to use.
|
|
* @returns {Function} Returns the new case function.
|
|
*/
|
|
function createCaseFirst(methodName) {
|
|
return function(string) {
|
|
string = toString(string);
|
|
|
|
var strSymbols = hasUnicode(string)
|
|
? stringToArray(string)
|
|
: undefined;
|
|
|
|
var chr = strSymbols
|
|
? strSymbols[0]
|
|
: string.charAt(0);
|
|
|
|
var trailing = strSymbols
|
|
? castSlice(strSymbols, 1).join('')
|
|
: string.slice(1);
|
|
|
|
return chr[methodName]() + trailing;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.camelCase`.
|
|
*
|
|
* @private
|
|
* @param {Function} callback The function to combine each word.
|
|
* @returns {Function} Returns the new compounder function.
|
|
*/
|
|
function createCompounder(callback) {
|
|
return function(string) {
|
|
return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that produces an instance of `Ctor` regardless of
|
|
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
|
|
*
|
|
* @private
|
|
* @param {Function} Ctor The constructor to wrap.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createCtor(Ctor) {
|
|
return function() {
|
|
// Use a `switch` statement to work with class constructors. See
|
|
// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
|
|
// for more details.
|
|
var args = arguments;
|
|
switch (args.length) {
|
|
case 0: return new Ctor;
|
|
case 1: return new Ctor(args[0]);
|
|
case 2: return new Ctor(args[0], args[1]);
|
|
case 3: return new Ctor(args[0], args[1], args[2]);
|
|
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
|
|
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
|
|
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
}
|
|
var thisBinding = baseCreate(Ctor.prototype),
|
|
result = Ctor.apply(thisBinding, args);
|
|
|
|
// Mimic the constructor's `return` behavior.
|
|
// See https://es5.github.io/#x13.2.2 for more details.
|
|
return isObject(result) ? result : thisBinding;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to enable currying.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {number} arity The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createCurry(func, bitmask, arity) {
|
|
var Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var length = arguments.length,
|
|
args = Array(length),
|
|
index = length,
|
|
placeholder = getHolder(wrapper);
|
|
|
|
while (index--) {
|
|
args[index] = arguments[index];
|
|
}
|
|
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
|
|
? []
|
|
: replaceHolders(args, placeholder);
|
|
|
|
length -= holders.length;
|
|
if (length < arity) {
|
|
return createRecurry(
|
|
func, bitmask, createHybrid, wrapper.placeholder, undefined,
|
|
args, holders, undefined, undefined, arity - length);
|
|
}
|
|
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
return apply(fn, this, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a `_.find` or `_.findLast` function.
|
|
*
|
|
* @private
|
|
* @param {Function} findIndexFunc The function to find the collection index.
|
|
* @returns {Function} Returns the new find function.
|
|
*/
|
|
function createFind(findIndexFunc) {
|
|
return function(collection, predicate, fromIndex) {
|
|
var iterable = Object(collection);
|
|
if (!isArrayLike(collection)) {
|
|
var iteratee = getIteratee(predicate, 3);
|
|
collection = keys(collection);
|
|
predicate = function(key) { return iteratee(iterable[key], key, iterable); };
|
|
}
|
|
var index = findIndexFunc(collection, predicate, fromIndex);
|
|
return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a `_.flow` or `_.flowRight` function.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new flow function.
|
|
*/
|
|
function createFlow(fromRight) {
|
|
return flatRest(function(funcs) {
|
|
var length = funcs.length,
|
|
index = length,
|
|
prereq = LodashWrapper.prototype.thru;
|
|
|
|
if (fromRight) {
|
|
funcs.reverse();
|
|
}
|
|
while (index--) {
|
|
var func = funcs[index];
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
|
|
var wrapper = new LodashWrapper([], true);
|
|
}
|
|
}
|
|
index = wrapper ? index : length;
|
|
while (++index < length) {
|
|
func = funcs[index];
|
|
|
|
var funcName = getFuncName(func),
|
|
data = funcName == 'wrapper' ? getData(func) : undefined;
|
|
|
|
if (data && isLaziable(data[0]) &&
|
|
data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
|
|
!data[4].length && data[9] == 1
|
|
) {
|
|
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
|
|
} else {
|
|
wrapper = (func.length == 1 && isLaziable(func))
|
|
? wrapper[funcName]()
|
|
: wrapper.thru(func);
|
|
}
|
|
}
|
|
return function() {
|
|
var args = arguments,
|
|
value = args[0];
|
|
|
|
if (wrapper && args.length == 1 && isArray(value)) {
|
|
return wrapper.plant(value).value();
|
|
}
|
|
var index = 0,
|
|
result = length ? funcs[index].apply(this, args) : value;
|
|
|
|
while (++index < length) {
|
|
result = funcs[index].call(this, result);
|
|
}
|
|
return result;
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with optional `this`
|
|
* binding of `thisArg`, partial application, and currying.
|
|
*
|
|
* @private
|
|
* @param {Function|string} func The function or method name to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [partialsRight] The arguments to append to those provided
|
|
* to the new function.
|
|
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
|
|
var isAry = bitmask & WRAP_ARY_FLAG,
|
|
isBind = bitmask & WRAP_BIND_FLAG,
|
|
isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
|
|
isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
|
|
isFlip = bitmask & WRAP_FLIP_FLAG,
|
|
Ctor = isBindKey ? undefined : createCtor(func);
|
|
|
|
function wrapper() {
|
|
var length = arguments.length,
|
|
args = Array(length),
|
|
index = length;
|
|
|
|
while (index--) {
|
|
args[index] = arguments[index];
|
|
}
|
|
if (isCurried) {
|
|
var placeholder = getHolder(wrapper),
|
|
holdersCount = countHolders(args, placeholder);
|
|
}
|
|
if (partials) {
|
|
args = composeArgs(args, partials, holders, isCurried);
|
|
}
|
|
if (partialsRight) {
|
|
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
|
|
}
|
|
length -= holdersCount;
|
|
if (isCurried && length < arity) {
|
|
var newHolders = replaceHolders(args, placeholder);
|
|
return createRecurry(
|
|
func, bitmask, createHybrid, wrapper.placeholder, thisArg,
|
|
args, newHolders, argPos, ary, arity - length
|
|
);
|
|
}
|
|
var thisBinding = isBind ? thisArg : this,
|
|
fn = isBindKey ? thisBinding[func] : func;
|
|
|
|
length = args.length;
|
|
if (argPos) {
|
|
args = reorder(args, argPos);
|
|
} else if (isFlip && length > 1) {
|
|
args.reverse();
|
|
}
|
|
if (isAry && ary < length) {
|
|
args.length = ary;
|
|
}
|
|
if (this && this !== root && this instanceof wrapper) {
|
|
fn = Ctor || createCtor(fn);
|
|
}
|
|
return fn.apply(thisBinding, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.invertBy`.
|
|
*
|
|
* @private
|
|
* @param {Function} setter The function to set accumulator values.
|
|
* @param {Function} toIteratee The function to resolve iteratees.
|
|
* @returns {Function} Returns the new inverter function.
|
|
*/
|
|
function createInverter(setter, toIteratee) {
|
|
return function(object, iteratee) {
|
|
return baseInverter(object, setter, toIteratee(iteratee), {});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a mathematical operation on two values.
|
|
*
|
|
* @private
|
|
* @param {Function} operator The function to perform the operation.
|
|
* @param {number} [defaultValue] The value used for `undefined` arguments.
|
|
* @returns {Function} Returns the new mathematical operation function.
|
|
*/
|
|
function createMathOperation(operator, defaultValue) {
|
|
return function(value, other) {
|
|
var result;
|
|
if (value === undefined && other === undefined) {
|
|
return defaultValue;
|
|
}
|
|
if (value !== undefined) {
|
|
result = value;
|
|
}
|
|
if (other !== undefined) {
|
|
if (result === undefined) {
|
|
return other;
|
|
}
|
|
if (typeof value == 'string' || typeof other == 'string') {
|
|
value = baseToString(value);
|
|
other = baseToString(other);
|
|
} else {
|
|
value = baseToNumber(value);
|
|
other = baseToNumber(other);
|
|
}
|
|
result = operator(value, other);
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.over`.
|
|
*
|
|
* @private
|
|
* @param {Function} arrayFunc The function to iterate over iteratees.
|
|
* @returns {Function} Returns the new over function.
|
|
*/
|
|
function createOver(arrayFunc) {
|
|
return flatRest(function(iteratees) {
|
|
iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
|
|
return baseRest(function(args) {
|
|
var thisArg = this;
|
|
return arrayFunc(iteratees, function(iteratee) {
|
|
return apply(iteratee, thisArg, args);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates the padding for `string` based on `length`. The `chars` string
|
|
* is truncated if the number of characters exceeds `length`.
|
|
*
|
|
* @private
|
|
* @param {number} length The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padding for `string`.
|
|
*/
|
|
function createPadding(length, chars) {
|
|
chars = chars === undefined ? ' ' : baseToString(chars);
|
|
|
|
var charsLength = chars.length;
|
|
if (charsLength < 2) {
|
|
return charsLength ? baseRepeat(chars, length) : chars;
|
|
}
|
|
var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
|
|
return hasUnicode(chars)
|
|
? castSlice(stringToArray(result), 0, length).join('')
|
|
: result.slice(0, length);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with the `this` binding
|
|
* of `thisArg` and `partials` prepended to the arguments it receives.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {Array} partials The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createPartial(func, bitmask, thisArg, partials) {
|
|
var isBind = bitmask & WRAP_BIND_FLAG,
|
|
Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var argsIndex = -1,
|
|
argsLength = arguments.length,
|
|
leftIndex = -1,
|
|
leftLength = partials.length,
|
|
args = Array(leftLength + argsLength),
|
|
fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
|
|
while (++leftIndex < leftLength) {
|
|
args[leftIndex] = partials[leftIndex];
|
|
}
|
|
while (argsLength--) {
|
|
args[leftIndex++] = arguments[++argsIndex];
|
|
}
|
|
return apply(fn, isBind ? thisArg : this, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a `_.range` or `_.rangeRight` function.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new range function.
|
|
*/
|
|
function createRange(fromRight) {
|
|
return function(start, end, step) {
|
|
if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
|
|
end = step = undefined;
|
|
}
|
|
// Ensure the sign of `-0` is preserved.
|
|
start = toFinite(start);
|
|
if (end === undefined) {
|
|
end = start;
|
|
start = 0;
|
|
} else {
|
|
end = toFinite(end);
|
|
}
|
|
step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
|
|
return baseRange(start, end, step, fromRight);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a relational operation on two values.
|
|
*
|
|
* @private
|
|
* @param {Function} operator The function to perform the operation.
|
|
* @returns {Function} Returns the new relational operation function.
|
|
*/
|
|
function createRelationalOperation(operator) {
|
|
return function(value, other) {
|
|
if (!(typeof value == 'string' && typeof other == 'string')) {
|
|
value = toNumber(value);
|
|
other = toNumber(other);
|
|
}
|
|
return operator(value, other);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to continue currying.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {Function} wrapFunc The function to create the `func` wrapper.
|
|
* @param {*} placeholder The placeholder value.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
|
|
var isCurry = bitmask & WRAP_CURRY_FLAG,
|
|
newHolders = isCurry ? holders : undefined,
|
|
newHoldersRight = isCurry ? undefined : holders,
|
|
newPartials = isCurry ? partials : undefined,
|
|
newPartialsRight = isCurry ? undefined : partials;
|
|
|
|
bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
|
|
bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
|
|
|
|
if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
|
|
bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
|
|
}
|
|
var newData = [
|
|
func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
|
|
newHoldersRight, argPos, ary, arity
|
|
];
|
|
|
|
var result = wrapFunc.apply(undefined, newData);
|
|
if (isLaziable(func)) {
|
|
setData(result, newData);
|
|
}
|
|
result.placeholder = placeholder;
|
|
return setWrapToString(result, func, bitmask);
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.round`.
|
|
*
|
|
* @private
|
|
* @param {string} methodName The name of the `Math` method to use when rounding.
|
|
* @returns {Function} Returns the new round function.
|
|
*/
|
|
function createRound(methodName) {
|
|
var func = Math[methodName];
|
|
return function(number, precision) {
|
|
number = toNumber(number);
|
|
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
|
|
if (precision && nativeIsFinite(number)) {
|
|
// Shift with exponential notation to avoid floating-point issues.
|
|
// See [MDN](https://mdn.io/round#Examples) for more details.
|
|
var pair = (toString(number) + 'e').split('e'),
|
|
value = func(pair[0] + 'e' + (+pair[1] + precision));
|
|
|
|
pair = (toString(value) + 'e').split('e');
|
|
return +(pair[0] + 'e' + (+pair[1] - precision));
|
|
}
|
|
return func(number);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a set object of `values`.
|
|
*
|
|
* @private
|
|
* @param {Array} values The values to add to the set.
|
|
* @returns {Object} Returns the new set.
|
|
*/
|
|
var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
|
|
return new Set(values);
|
|
};
|
|
|
|
/**
|
|
* Creates a `_.toPairs` or `_.toPairsIn` function.
|
|
*
|
|
* @private
|
|
* @param {Function} keysFunc The function to get the keys of a given object.
|
|
* @returns {Function} Returns the new pairs function.
|
|
*/
|
|
function createToPairs(keysFunc) {
|
|
return function(object) {
|
|
var tag = getTag(object);
|
|
if (tag == mapTag) {
|
|
return mapToArray(object);
|
|
}
|
|
if (tag == setTag) {
|
|
return setToPairs(object);
|
|
}
|
|
return baseToPairs(object, keysFunc(object));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that either curries or invokes `func` with optional
|
|
* `this` binding and partially applied arguments.
|
|
*
|
|
* @private
|
|
* @param {Function|string} func The function or method name to wrap.
|
|
* @param {number} bitmask The bitmask flags.
|
|
* 1 - `_.bind`
|
|
* 2 - `_.bindKey`
|
|
* 4 - `_.curry` or `_.curryRight` of a bound function
|
|
* 8 - `_.curry`
|
|
* 16 - `_.curryRight`
|
|
* 32 - `_.partial`
|
|
* 64 - `_.partialRight`
|
|
* 128 - `_.rearg`
|
|
* 256 - `_.ary`
|
|
* 512 - `_.flip`
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to be partially applied.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
|
|
var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
|
|
if (!isBindKey && typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
var length = partials ? partials.length : 0;
|
|
if (!length) {
|
|
bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
|
|
partials = holders = undefined;
|
|
}
|
|
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
|
|
arity = arity === undefined ? arity : toInteger(arity);
|
|
length -= holders ? holders.length : 0;
|
|
|
|
if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
|
|
var partialsRight = partials,
|
|
holdersRight = holders;
|
|
|
|
partials = holders = undefined;
|
|
}
|
|
var data = isBindKey ? undefined : getData(func);
|
|
|
|
var newData = [
|
|
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
|
|
argPos, ary, arity
|
|
];
|
|
|
|
if (data) {
|
|
mergeData(newData, data);
|
|
}
|
|
func = newData[0];
|
|
bitmask = newData[1];
|
|
thisArg = newData[2];
|
|
partials = newData[3];
|
|
holders = newData[4];
|
|
arity = newData[9] = newData[9] === undefined
|
|
? (isBindKey ? 0 : func.length)
|
|
: nativeMax(newData[9] - length, 0);
|
|
|
|
if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
|
|
bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
|
|
}
|
|
if (!bitmask || bitmask == WRAP_BIND_FLAG) {
|
|
var result = createBind(func, bitmask, thisArg);
|
|
} else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
|
|
result = createCurry(func, bitmask, arity);
|
|
} else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
|
|
result = createPartial(func, bitmask, thisArg, partials);
|
|
} else {
|
|
result = createHybrid.apply(undefined, newData);
|
|
}
|
|
var setter = data ? baseSetData : setData;
|
|
return setWrapToString(setter(result, newData), func, bitmask);
|
|
}
|
|
|
|
/**
|
|
* Used by `_.defaults` to customize its `_.assignIn` use to assign properties
|
|
* of source objects to the destination object for all destination properties
|
|
* that resolve to `undefined`.
|
|
*
|
|
* @private
|
|
* @param {*} objValue The destination value.
|
|
* @param {*} srcValue The source value.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {Object} object The parent object of `objValue`.
|
|
* @returns {*} Returns the value to assign.
|
|
*/
|
|
function customDefaultsAssignIn(objValue, srcValue, key, object) {
|
|
if (objValue === undefined ||
|
|
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
|
|
return srcValue;
|
|
}
|
|
return objValue;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
|
|
* objects into destination objects that are passed thru.
|
|
*
|
|
* @private
|
|
* @param {*} objValue The destination value.
|
|
* @param {*} srcValue The source value.
|
|
* @param {string} key The key of the property to merge.
|
|
* @param {Object} object The parent object of `objValue`.
|
|
* @param {Object} source The parent object of `srcValue`.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
* counterparts.
|
|
* @returns {*} Returns the value to assign.
|
|
*/
|
|
function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
|
|
if (isObject(objValue) && isObject(srcValue)) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
stack.set(srcValue, objValue);
|
|
baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
|
|
stack['delete'](srcValue);
|
|
}
|
|
return objValue;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
|
|
* objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @param {string} key The key of the property to inspect.
|
|
* @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
|
|
*/
|
|
function customOmitClone(value) {
|
|
return isPlainObject(value) ? undefined : value;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqualDeep` for arrays with support for
|
|
* partial deep comparisons.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to compare.
|
|
* @param {Array} other The other array to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} stack Tracks traversed `array` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
|
*/
|
|
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
|
arrLength = array.length,
|
|
othLength = other.length;
|
|
|
|
if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
|
|
return false;
|
|
}
|
|
// Assume cyclic values are equal.
|
|
var stacked = stack.get(array);
|
|
if (stacked && stack.get(other)) {
|
|
return stacked == other;
|
|
}
|
|
var index = -1,
|
|
result = true,
|
|
seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
|
|
|
|
stack.set(array, other);
|
|
stack.set(other, array);
|
|
|
|
// Ignore non-index properties.
|
|
while (++index < arrLength) {
|
|
var arrValue = array[index],
|
|
othValue = other[index];
|
|
|
|
if (customizer) {
|
|
var compared = isPartial
|
|
? customizer(othValue, arrValue, index, other, array, stack)
|
|
: customizer(arrValue, othValue, index, array, other, stack);
|
|
}
|
|
if (compared !== undefined) {
|
|
if (compared) {
|
|
continue;
|
|
}
|
|
result = false;
|
|
break;
|
|
}
|
|
// Recursively compare arrays (susceptible to call stack limits).
|
|
if (seen) {
|
|
if (!arraySome(other, function(othValue, othIndex) {
|
|
if (!cacheHas(seen, othIndex) &&
|
|
(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
|
|
return seen.push(othIndex);
|
|
}
|
|
})) {
|
|
result = false;
|
|
break;
|
|
}
|
|
} else if (!(
|
|
arrValue === othValue ||
|
|
equalFunc(arrValue, othValue, bitmask, customizer, stack)
|
|
)) {
|
|
result = false;
|
|
break;
|
|
}
|
|
}
|
|
stack['delete'](array);
|
|
stack['delete'](other);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqualDeep` for comparing objects of
|
|
* the same `toStringTag`.
|
|
*
|
|
* **Note:** This function only supports comparing values with tags of
|
|
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {string} tag The `toStringTag` of the objects to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
|
|
switch (tag) {
|
|
case dataViewTag:
|
|
if ((object.byteLength != other.byteLength) ||
|
|
(object.byteOffset != other.byteOffset)) {
|
|
return false;
|
|
}
|
|
object = object.buffer;
|
|
other = other.buffer;
|
|
|
|
case arrayBufferTag:
|
|
if ((object.byteLength != other.byteLength) ||
|
|
!equalFunc(new Uint8Array(object), new Uint8Array(other))) {
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
case boolTag:
|
|
case dateTag:
|
|
case numberTag:
|
|
// Coerce booleans to `1` or `0` and dates to milliseconds.
|
|
// Invalid dates are coerced to `NaN`.
|
|
return eq(+object, +other);
|
|
|
|
case errorTag:
|
|
return object.name == other.name && object.message == other.message;
|
|
|
|
case regexpTag:
|
|
case stringTag:
|
|
// Coerce regexes to strings and treat strings, primitives and objects,
|
|
// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
|
|
// for more details.
|
|
return object == (other + '');
|
|
|
|
case mapTag:
|
|
var convert = mapToArray;
|
|
|
|
case setTag:
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
|
|
convert || (convert = setToArray);
|
|
|
|
if (object.size != other.size && !isPartial) {
|
|
return false;
|
|
}
|
|
// Assume cyclic values are equal.
|
|
var stacked = stack.get(object);
|
|
if (stacked) {
|
|
return stacked == other;
|
|
}
|
|
bitmask |= COMPARE_UNORDERED_FLAG;
|
|
|
|
// Recursively compare objects (susceptible to call stack limits).
|
|
stack.set(object, other);
|
|
var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
|
|
stack['delete'](object);
|
|
return result;
|
|
|
|
case symbolTag:
|
|
if (symbolValueOf) {
|
|
return symbolValueOf.call(object) == symbolValueOf.call(other);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqualDeep` for objects with support for
|
|
* partial deep comparisons.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
|
objProps = getAllKeys(object),
|
|
objLength = objProps.length,
|
|
othProps = getAllKeys(other),
|
|
othLength = othProps.length;
|
|
|
|
if (objLength != othLength && !isPartial) {
|
|
return false;
|
|
}
|
|
var index = objLength;
|
|
while (index--) {
|
|
var key = objProps[index];
|
|
if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
|
|
return false;
|
|
}
|
|
}
|
|
// Assume cyclic values are equal.
|
|
var stacked = stack.get(object);
|
|
if (stacked && stack.get(other)) {
|
|
return stacked == other;
|
|
}
|
|
var result = true;
|
|
stack.set(object, other);
|
|
stack.set(other, object);
|
|
|
|
var skipCtor = isPartial;
|
|
while (++index < objLength) {
|
|
key = objProps[index];
|
|
var objValue = object[key],
|
|
othValue = other[key];
|
|
|
|
if (customizer) {
|
|
var compared = isPartial
|
|
? customizer(othValue, objValue, key, other, object, stack)
|
|
: customizer(objValue, othValue, key, object, other, stack);
|
|
}
|
|
// Recursively compare objects (susceptible to call stack limits).
|
|
if (!(compared === undefined
|
|
? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
|
|
: compared
|
|
)) {
|
|
result = false;
|
|
break;
|
|
}
|
|
skipCtor || (skipCtor = key == 'constructor');
|
|
}
|
|
if (result && !skipCtor) {
|
|
var objCtor = object.constructor,
|
|
othCtor = other.constructor;
|
|
|
|
// Non `Object` object instances with different constructors are not equal.
|
|
if (objCtor != othCtor &&
|
|
('constructor' in object && 'constructor' in other) &&
|
|
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
|
|
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
|
|
result = false;
|
|
}
|
|
}
|
|
stack['delete'](object);
|
|
stack['delete'](other);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseRest` which flattens the rest array.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function flatRest(func) {
|
|
return setToString(overRest(func, undefined, flatten), func + '');
|
|
}
|
|
|
|
/**
|
|
* Creates an array of own enumerable property names and symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|
*/
|
|
function getAllKeys(object) {
|
|
return baseGetAllKeys(object, keys, getSymbols);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of own and inherited enumerable property names and
|
|
* symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|
*/
|
|
function getAllKeysIn(object) {
|
|
return baseGetAllKeys(object, keysIn, getSymbolsIn);
|
|
}
|
|
|
|
/**
|
|
* Gets metadata for `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to query.
|
|
* @returns {*} Returns the metadata for `func`.
|
|
*/
|
|
var getData = !metaMap ? noop : function(func) {
|
|
return metaMap.get(func);
|
|
};
|
|
|
|
/**
|
|
* Gets the name of `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to query.
|
|
* @returns {string} Returns the function name.
|
|
*/
|
|
function getFuncName(func) {
|
|
var result = (func.name + ''),
|
|
array = realNames[result],
|
|
length = hasOwnProperty.call(realNames, result) ? array.length : 0;
|
|
|
|
while (length--) {
|
|
var data = array[length],
|
|
otherFunc = data.func;
|
|
if (otherFunc == null || otherFunc == func) {
|
|
return data.name;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the argument placeholder value for `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to inspect.
|
|
* @returns {*} Returns the placeholder value.
|
|
*/
|
|
function getHolder(func) {
|
|
var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
|
|
return object.placeholder;
|
|
}
|
|
|
|
/**
|
|
* Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
|
|
* this function returns the custom method, otherwise it returns `baseIteratee`.
|
|
* If arguments are provided, the chosen function is invoked with them and
|
|
* its result is returned.
|
|
*
|
|
* @private
|
|
* @param {*} [value] The value to convert to an iteratee.
|
|
* @param {number} [arity] The arity of the created iteratee.
|
|
* @returns {Function} Returns the chosen function or its result.
|
|
*/
|
|
function getIteratee() {
|
|
var result = lodash.iteratee || iteratee;
|
|
result = result === iteratee ? baseIteratee : result;
|
|
return arguments.length ? result(arguments[0], arguments[1]) : result;
|
|
}
|
|
|
|
/**
|
|
* Gets the data for `map`.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to query.
|
|
* @param {string} key The reference key.
|
|
* @returns {*} Returns the map data.
|
|
*/
|
|
function getMapData(map, key) {
|
|
var data = map.__data__;
|
|
return isKeyable(key)
|
|
? data[typeof key == 'string' ? 'string' : 'hash']
|
|
: data.map;
|
|
}
|
|
|
|
/**
|
|
* Gets the property names, values, and compare flags of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the match data of `object`.
|
|
*/
|
|
function getMatchData(object) {
|
|
var result = keys(object),
|
|
length = result.length;
|
|
|
|
while (length--) {
|
|
var key = result[length],
|
|
value = object[key];
|
|
|
|
result[length] = [key, value, isStrictComparable(value)];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the native function at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the method to get.
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
*/
|
|
function getNative(object, key) {
|
|
var value = getValue(object, key);
|
|
return baseIsNative(value) ? value : undefined;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the raw `toStringTag`.
|
|
*/
|
|
function getRawTag(value) {
|
|
var isOwn = hasOwnProperty.call(value, symToStringTag),
|
|
tag = value[symToStringTag];
|
|
|
|
try {
|
|
value[symToStringTag] = undefined;
|
|
var unmasked = true;
|
|
} catch (e) {}
|
|
|
|
var result = nativeObjectToString.call(value);
|
|
if (unmasked) {
|
|
if (isOwn) {
|
|
value[symToStringTag] = tag;
|
|
} else {
|
|
delete value[symToStringTag];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own enumerable symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of symbols.
|
|
*/
|
|
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
|
|
if (object == null) {
|
|
return [];
|
|
}
|
|
object = Object(object);
|
|
return arrayFilter(nativeGetSymbols(object), function(symbol) {
|
|
return propertyIsEnumerable.call(object, symbol);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of symbols.
|
|
*/
|
|
var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
|
|
var result = [];
|
|
while (object) {
|
|
arrayPush(result, getSymbols(object));
|
|
object = getPrototype(object);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Gets the `toStringTag` of `value`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the `toStringTag`.
|
|
*/
|
|
var getTag = baseGetTag;
|
|
|
|
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
|
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
|
|
(Map && getTag(new Map) != mapTag) ||
|
|
(Promise && getTag(Promise.resolve()) != promiseTag) ||
|
|
(Set && getTag(new Set) != setTag) ||
|
|
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
|
|
getTag = function(value) {
|
|
var result = baseGetTag(value),
|
|
Ctor = result == objectTag ? value.constructor : undefined,
|
|
ctorString = Ctor ? toSource(Ctor) : '';
|
|
|
|
if (ctorString) {
|
|
switch (ctorString) {
|
|
case dataViewCtorString: return dataViewTag;
|
|
case mapCtorString: return mapTag;
|
|
case promiseCtorString: return promiseTag;
|
|
case setCtorString: return setTag;
|
|
case weakMapCtorString: return weakMapTag;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Gets the view, applying any `transforms` to the `start` and `end` positions.
|
|
*
|
|
* @private
|
|
* @param {number} start The start of the view.
|
|
* @param {number} end The end of the view.
|
|
* @param {Array} transforms The transformations to apply to the view.
|
|
* @returns {Object} Returns an object containing the `start` and `end`
|
|
* positions of the view.
|
|
*/
|
|
function getView(start, end, transforms) {
|
|
var index = -1,
|
|
length = transforms.length;
|
|
|
|
while (++index < length) {
|
|
var data = transforms[index],
|
|
size = data.size;
|
|
|
|
switch (data.type) {
|
|
case 'drop': start += size; break;
|
|
case 'dropRight': end -= size; break;
|
|
case 'take': end = nativeMin(end, start + size); break;
|
|
case 'takeRight': start = nativeMax(start, end - size); break;
|
|
}
|
|
}
|
|
return { 'start': start, 'end': end };
|
|
}
|
|
|
|
/**
|
|
* Extracts wrapper details from the `source` body comment.
|
|
*
|
|
* @private
|
|
* @param {string} source The source to inspect.
|
|
* @returns {Array} Returns the wrapper details.
|
|
*/
|
|
function getWrapDetails(source) {
|
|
var match = source.match(reWrapDetails);
|
|
return match ? match[1].split(reSplitDetails) : [];
|
|
}
|
|
|
|
/**
|
|
* Checks if `path` exists on `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path to check.
|
|
* @param {Function} hasFunc The function to check properties.
|
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
|
*/
|
|
function hasPath(object, path, hasFunc) {
|
|
path = castPath(path, object);
|
|
|
|
var index = -1,
|
|
length = path.length,
|
|
result = false;
|
|
|
|
while (++index < length) {
|
|
var key = toKey(path[index]);
|
|
if (!(result = object != null && hasFunc(object, key))) {
|
|
break;
|
|
}
|
|
object = object[key];
|
|
}
|
|
if (result || ++index != length) {
|
|
return result;
|
|
}
|
|
length = object == null ? 0 : object.length;
|
|
return !!length && isLength(length) && isIndex(key, length) &&
|
|
(isArray(object) || isArguments(object));
|
|
}
|
|
|
|
/**
|
|
* Initializes an array clone.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to clone.
|
|
* @returns {Array} Returns the initialized clone.
|
|
*/
|
|
function initCloneArray(array) {
|
|
var length = array.length,
|
|
result = new array.constructor(length);
|
|
|
|
// Add properties assigned by `RegExp#exec`.
|
|
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
|
|
result.index = array.index;
|
|
result.input = array.input;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Initializes an object clone.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to clone.
|
|
* @returns {Object} Returns the initialized clone.
|
|
*/
|
|
function initCloneObject(object) {
|
|
return (typeof object.constructor == 'function' && !isPrototype(object))
|
|
? baseCreate(getPrototype(object))
|
|
: {};
|
|
}
|
|
|
|
/**
|
|
* Initializes an object clone based on its `toStringTag`.
|
|
*
|
|
* **Note:** This function only supports cloning values with tags of
|
|
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to clone.
|
|
* @param {string} tag The `toStringTag` of the object to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the initialized clone.
|
|
*/
|
|
function initCloneByTag(object, tag, isDeep) {
|
|
var Ctor = object.constructor;
|
|
switch (tag) {
|
|
case arrayBufferTag:
|
|
return cloneArrayBuffer(object);
|
|
|
|
case boolTag:
|
|
case dateTag:
|
|
return new Ctor(+object);
|
|
|
|
case dataViewTag:
|
|
return cloneDataView(object, isDeep);
|
|
|
|
case float32Tag: case float64Tag:
|
|
case int8Tag: case int16Tag: case int32Tag:
|
|
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
|
return cloneTypedArray(object, isDeep);
|
|
|
|
case mapTag:
|
|
return new Ctor;
|
|
|
|
case numberTag:
|
|
case stringTag:
|
|
return new Ctor(object);
|
|
|
|
case regexpTag:
|
|
return cloneRegExp(object);
|
|
|
|
case setTag:
|
|
return new Ctor;
|
|
|
|
case symbolTag:
|
|
return cloneSymbol(object);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inserts wrapper `details` in a comment at the top of the `source` body.
|
|
*
|
|
* @private
|
|
* @param {string} source The source to modify.
|
|
* @returns {Array} details The details to insert.
|
|
* @returns {string} Returns the modified source.
|
|
*/
|
|
function insertWrapDetails(source, details) {
|
|
var length = details.length;
|
|
if (!length) {
|
|
return source;
|
|
}
|
|
var lastIndex = length - 1;
|
|
details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
|
|
details = details.join(length > 2 ? ', ' : ' ');
|
|
return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a flattenable `arguments` object or array.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
|
|
*/
|
|
function isFlattenable(value) {
|
|
return isArray(value) || isArguments(value) ||
|
|
!!(spreadableSymbol && value && value[spreadableSymbol]);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like index.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
*/
|
|
function isIndex(value, length) {
|
|
var type = typeof value;
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|
|
|
return !!length &&
|
|
(type == 'number' ||
|
|
(type != 'symbol' && reIsUint.test(value))) &&
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|
}
|
|
|
|
/**
|
|
* Checks if the given arguments are from an iteratee call.
|
|
*
|
|
* @private
|
|
* @param {*} value The potential iteratee value argument.
|
|
* @param {*} index The potential iteratee index or key argument.
|
|
* @param {*} object The potential iteratee object argument.
|
|
* @returns {boolean} Returns `true` if the arguments are from an iteratee call,
|
|
* else `false`.
|
|
*/
|
|
function isIterateeCall(value, index, object) {
|
|
if (!isObject(object)) {
|
|
return false;
|
|
}
|
|
var type = typeof index;
|
|
if (type == 'number'
|
|
? (isArrayLike(object) && isIndex(index, object.length))
|
|
: (type == 'string' && index in object)
|
|
) {
|
|
return eq(object[index], value);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a property name and not a property path.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {Object} [object] The object to query keys on.
|
|
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
|
*/
|
|
function isKey(value, object) {
|
|
if (isArray(value)) {
|
|
return false;
|
|
}
|
|
var type = typeof value;
|
|
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
|
|
value == null || isSymbol(value)) {
|
|
return true;
|
|
}
|
|
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
|
|
(object != null && value in Object(object));
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is suitable for use as unique object key.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|
*/
|
|
function isKeyable(value) {
|
|
var type = typeof value;
|
|
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
|
? (value !== '__proto__')
|
|
: (value === null);
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` has a lazy counterpart.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to check.
|
|
* @returns {boolean} Returns `true` if `func` has a lazy counterpart,
|
|
* else `false`.
|
|
*/
|
|
function isLaziable(func) {
|
|
var funcName = getFuncName(func),
|
|
other = lodash[funcName];
|
|
|
|
if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
|
|
return false;
|
|
}
|
|
if (func === other) {
|
|
return true;
|
|
}
|
|
var data = getData(other);
|
|
return !!data && func === data[0];
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` has its source masked.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to check.
|
|
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|
*/
|
|
function isMasked(func) {
|
|
return !!maskSrcKey && (maskSrcKey in func);
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` is capable of being masked.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `func` is maskable, else `false`.
|
|
*/
|
|
var isMaskable = coreJsData ? isFunction : stubFalse;
|
|
|
|
/**
|
|
* Checks if `value` is likely a prototype object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|
*/
|
|
function isPrototype(value) {
|
|
var Ctor = value && value.constructor,
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
|
|
|
return value === proto;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` if suitable for strict
|
|
* equality comparisons, else `false`.
|
|
*/
|
|
function isStrictComparable(value) {
|
|
return value === value && !isObject(value);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `matchesProperty` for source values suitable
|
|
* for strict equality comparisons, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @param {*} srcValue The value to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function matchesStrictComparable(key, srcValue) {
|
|
return function(object) {
|
|
if (object == null) {
|
|
return false;
|
|
}
|
|
return object[key] === srcValue &&
|
|
(srcValue !== undefined || (key in Object(object)));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.memoize` which clears the memoized function's
|
|
* cache when it exceeds `MAX_MEMOIZE_SIZE`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to have its output memoized.
|
|
* @returns {Function} Returns the new memoized function.
|
|
*/
|
|
function memoizeCapped(func) {
|
|
var result = memoize(func, function(key) {
|
|
if (cache.size === MAX_MEMOIZE_SIZE) {
|
|
cache.clear();
|
|
}
|
|
return key;
|
|
});
|
|
|
|
var cache = result.cache;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Merges the function metadata of `source` into `data`.
|
|
*
|
|
* Merging metadata reduces the number of wrappers used to invoke a function.
|
|
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
|
|
* may be applied regardless of execution order. Methods like `_.ary` and
|
|
* `_.rearg` modify function arguments, making the order in which they are
|
|
* executed important, preventing the merging of metadata. However, we make
|
|
* an exception for a safe combined case where curried functions have `_.ary`
|
|
* and or `_.rearg` applied.
|
|
*
|
|
* @private
|
|
* @param {Array} data The destination metadata.
|
|
* @param {Array} source The source metadata.
|
|
* @returns {Array} Returns `data`.
|
|
*/
|
|
function mergeData(data, source) {
|
|
var bitmask = data[1],
|
|
srcBitmask = source[1],
|
|
newBitmask = bitmask | srcBitmask,
|
|
isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
|
|
|
|
var isCombo =
|
|
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
|
|
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
|
|
((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
|
|
|
|
// Exit early if metadata can't be merged.
|
|
if (!(isCommon || isCombo)) {
|
|
return data;
|
|
}
|
|
// Use source `thisArg` if available.
|
|
if (srcBitmask & WRAP_BIND_FLAG) {
|
|
data[2] = source[2];
|
|
// Set when currying a bound function.
|
|
newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
|
|
}
|
|
// Compose partial arguments.
|
|
var value = source[3];
|
|
if (value) {
|
|
var partials = data[3];
|
|
data[3] = partials ? composeArgs(partials, value, source[4]) : value;
|
|
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
|
|
}
|
|
// Compose partial right arguments.
|
|
value = source[5];
|
|
if (value) {
|
|
partials = data[5];
|
|
data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
|
|
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
|
|
}
|
|
// Use source `argPos` if available.
|
|
value = source[7];
|
|
if (value) {
|
|
data[7] = value;
|
|
}
|
|
// Use source `ary` if it's smaller.
|
|
if (srcBitmask & WRAP_ARY_FLAG) {
|
|
data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
|
|
}
|
|
// Use source `arity` if one is not provided.
|
|
if (data[9] == null) {
|
|
data[9] = source[9];
|
|
}
|
|
// Use source `func` and merge bitmasks.
|
|
data[0] = source[0];
|
|
data[1] = newBitmask;
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* This function is like
|
|
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|
* except that it includes inherited enumerable properties.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function nativeKeysIn(object) {
|
|
var result = [];
|
|
if (object != null) {
|
|
for (var key in Object(object)) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a string using `Object.prototype.toString`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to convert.
|
|
* @returns {string} Returns the converted string.
|
|
*/
|
|
function objectToString(value) {
|
|
return nativeObjectToString.call(value);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseRest` which transforms the rest array.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @param {Function} transform The rest array transform.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function overRest(func, start, transform) {
|
|
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
|
|
return function() {
|
|
var args = arguments,
|
|
index = -1,
|
|
length = nativeMax(args.length - start, 0),
|
|
array = Array(length);
|
|
|
|
while (++index < length) {
|
|
array[index] = args[start + index];
|
|
}
|
|
index = -1;
|
|
var otherArgs = Array(start + 1);
|
|
while (++index < start) {
|
|
otherArgs[index] = args[index];
|
|
}
|
|
otherArgs[start] = transform(array);
|
|
return apply(func, this, otherArgs);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Gets the parent value at `path` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array} path The path to get the parent value of.
|
|
* @returns {*} Returns the parent value.
|
|
*/
|
|
function parent(object, path) {
|
|
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
|
|
}
|
|
|
|
/**
|
|
* Reorder `array` according to the specified indexes where the element at
|
|
* the first index is assigned as the first element, the element at
|
|
* the second index is assigned as the second element, and so on.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to reorder.
|
|
* @param {Array} indexes The arranged array indexes.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function reorder(array, indexes) {
|
|
var arrLength = array.length,
|
|
length = nativeMin(indexes.length, arrLength),
|
|
oldArray = copyArray(array);
|
|
|
|
while (length--) {
|
|
var index = indexes[length];
|
|
array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {*} Returns the property value.
|
|
*/
|
|
function safeGet(object, key) {
|
|
if (key === 'constructor' && typeof object[key] === 'function') {
|
|
return;
|
|
}
|
|
|
|
if (key == '__proto__') {
|
|
return;
|
|
}
|
|
|
|
return object[key];
|
|
}
|
|
|
|
/**
|
|
* Sets metadata for `func`.
|
|
*
|
|
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short
|
|
* period of time, it will trip its breaker and transition to an identity
|
|
* function to avoid garbage collection pauses in V8. See
|
|
* [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
|
|
* for more details.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to associate metadata with.
|
|
* @param {*} data The metadata.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var setData = shortOut(baseSetData);
|
|
|
|
/**
|
|
* A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to delay.
|
|
* @param {number} wait The number of milliseconds to delay invocation.
|
|
* @returns {number|Object} Returns the timer id or timeout object.
|
|
*/
|
|
var setTimeout = ctxSetTimeout || function(func, wait) {
|
|
return root.setTimeout(func, wait);
|
|
};
|
|
|
|
/**
|
|
* Sets the `toString` method of `func` to return `string`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to modify.
|
|
* @param {Function} string The `toString` result.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var setToString = shortOut(baseSetToString);
|
|
|
|
/**
|
|
* Sets the `toString` method of `wrapper` to mimic the source of `reference`
|
|
* with wrapper details in a comment at the top of the source body.
|
|
*
|
|
* @private
|
|
* @param {Function} wrapper The function to modify.
|
|
* @param {Function} reference The reference function.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @returns {Function} Returns `wrapper`.
|
|
*/
|
|
function setWrapToString(wrapper, reference, bitmask) {
|
|
var source = (reference + '');
|
|
return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that'll short out and invoke `identity` instead
|
|
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
|
|
* milliseconds.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new shortable function.
|
|
*/
|
|
function shortOut(func) {
|
|
var count = 0,
|
|
lastCalled = 0;
|
|
|
|
return function() {
|
|
var stamp = nativeNow(),
|
|
remaining = HOT_SPAN - (stamp - lastCalled);
|
|
|
|
lastCalled = stamp;
|
|
if (remaining > 0) {
|
|
if (++count >= HOT_COUNT) {
|
|
return arguments[0];
|
|
}
|
|
} else {
|
|
count = 0;
|
|
}
|
|
return func.apply(undefined, arguments);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.shuffle` which mutates and sets the size of `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to shuffle.
|
|
* @param {number} [size=array.length] The size of `array`.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function shuffleSelf(array, size) {
|
|
var index = -1,
|
|
length = array.length,
|
|
lastIndex = length - 1;
|
|
|
|
size = size === undefined ? length : size;
|
|
while (++index < size) {
|
|
var rand = baseRandom(index, lastIndex),
|
|
value = array[rand];
|
|
|
|
array[rand] = array[index];
|
|
array[index] = value;
|
|
}
|
|
array.length = size;
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to a property path array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the property path array.
|
|
*/
|
|
var stringToPath = memoizeCapped(function(string) {
|
|
var result = [];
|
|
if (string.charCodeAt(0) === 46 /* . */) {
|
|
result.push('');
|
|
}
|
|
string.replace(rePropName, function(match, number, quote, subString) {
|
|
result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
|
|
});
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Converts `value` to a string key if it's not a string or symbol.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @returns {string|symbol} Returns the key.
|
|
*/
|
|
function toKey(value) {
|
|
if (typeof value == 'string' || isSymbol(value)) {
|
|
return value;
|
|
}
|
|
var result = (value + '');
|
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
|
}
|
|
|
|
/**
|
|
* Converts `func` to its source code.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to convert.
|
|
* @returns {string} Returns the source code.
|
|
*/
|
|
function toSource(func) {
|
|
if (func != null) {
|
|
try {
|
|
return funcToString.call(func);
|
|
} catch (e) {}
|
|
try {
|
|
return (func + '');
|
|
} catch (e) {}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Updates wrapper `details` based on `bitmask` flags.
|
|
*
|
|
* @private
|
|
* @returns {Array} details The details to modify.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @returns {Array} Returns `details`.
|
|
*/
|
|
function updateWrapDetails(details, bitmask) {
|
|
arrayEach(wrapFlags, function(pair) {
|
|
var value = '_.' + pair[0];
|
|
if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
|
|
details.push(value);
|
|
}
|
|
});
|
|
return details.sort();
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `wrapper`.
|
|
*
|
|
* @private
|
|
* @param {Object} wrapper The wrapper to clone.
|
|
* @returns {Object} Returns the cloned wrapper.
|
|
*/
|
|
function wrapperClone(wrapper) {
|
|
if (wrapper instanceof LazyWrapper) {
|
|
return wrapper.clone();
|
|
}
|
|
var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
|
|
result.__actions__ = copyArray(wrapper.__actions__);
|
|
result.__index__ = wrapper.__index__;
|
|
result.__values__ = wrapper.__values__;
|
|
return result;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an array of elements split into groups the length of `size`.
|
|
* If `array` can't be split evenly, the final chunk will be the remaining
|
|
* elements.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to process.
|
|
* @param {number} [size=1] The length of each chunk
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the new array of chunks.
|
|
* @example
|
|
*
|
|
* _.chunk(['a', 'b', 'c', 'd'], 2);
|
|
* // => [['a', 'b'], ['c', 'd']]
|
|
*
|
|
* _.chunk(['a', 'b', 'c', 'd'], 3);
|
|
* // => [['a', 'b', 'c'], ['d']]
|
|
*/
|
|
function chunk(array, size, guard) {
|
|
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
|
|
size = 1;
|
|
} else {
|
|
size = nativeMax(toInteger(size), 0);
|
|
}
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length || size < 1) {
|
|
return [];
|
|
}
|
|
var index = 0,
|
|
resIndex = 0,
|
|
result = Array(nativeCeil(length / size));
|
|
|
|
while (index < length) {
|
|
result[resIndex++] = baseSlice(array, index, (index += size));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an array with all falsey values removed. The values `false`, `null`,
|
|
* `0`, `""`, `undefined`, and `NaN` are falsey.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to compact.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* _.compact([0, 1, false, 2, '', 3]);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function compact(array) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (value) {
|
|
result[resIndex++] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a new array concatenating `array` with any additional arrays
|
|
* and/or values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to concatenate.
|
|
* @param {...*} [values] The values to concatenate.
|
|
* @returns {Array} Returns the new concatenated array.
|
|
* @example
|
|
*
|
|
* var array = [1];
|
|
* var other = _.concat(array, 2, [3], [[4]]);
|
|
*
|
|
* console.log(other);
|
|
* // => [1, 2, 3, [4]]
|
|
*
|
|
* console.log(array);
|
|
* // => [1]
|
|
*/
|
|
function concat() {
|
|
var length = arguments.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
var args = Array(length - 1),
|
|
array = arguments[0],
|
|
index = length;
|
|
|
|
while (index--) {
|
|
args[index - 1] = arguments[index];
|
|
}
|
|
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of `array` values not included in the other given arrays
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons. The order and references of result values are
|
|
* determined by the first array.
|
|
*
|
|
* **Note:** Unlike `_.pullAll`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...Array} [values] The values to exclude.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @see _.without, _.xor
|
|
* @example
|
|
*
|
|
* _.difference([2, 1], [2, 3]);
|
|
* // => [1]
|
|
*/
|
|
var difference = baseRest(function(array, values) {
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.difference` except that it accepts `iteratee` which
|
|
* is invoked for each element of `array` and `values` to generate the criterion
|
|
* by which they're compared. The order and references of result values are
|
|
* determined by the first array. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* **Note:** Unlike `_.pullAllBy`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...Array} [values] The values to exclude.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
|
* // => [1.2]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
|
|
* // => [{ 'x': 2 }]
|
|
*/
|
|
var differenceBy = baseRest(function(array, values) {
|
|
var iteratee = last(values);
|
|
if (isArrayLikeObject(iteratee)) {
|
|
iteratee = undefined;
|
|
}
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.difference` except that it accepts `comparator`
|
|
* which is invoked to compare elements of `array` to `values`. The order and
|
|
* references of result values are determined by the first array. The comparator
|
|
* is invoked with two arguments: (arrVal, othVal).
|
|
*
|
|
* **Note:** Unlike `_.pullAllWith`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...Array} [values] The values to exclude.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
*
|
|
* _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
|
|
* // => [{ 'x': 2, 'y': 1 }]
|
|
*/
|
|
var differenceWith = baseRest(function(array, values) {
|
|
var comparator = last(values);
|
|
if (isArrayLikeObject(comparator)) {
|
|
comparator = undefined;
|
|
}
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements dropped from the beginning.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.5.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to drop.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.drop([1, 2, 3]);
|
|
* // => [2, 3]
|
|
*
|
|
* _.drop([1, 2, 3], 2);
|
|
* // => [3]
|
|
*
|
|
* _.drop([1, 2, 3], 5);
|
|
* // => []
|
|
*
|
|
* _.drop([1, 2, 3], 0);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function drop(array, n, guard) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
return baseSlice(array, n < 0 ? 0 : n, length);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements dropped from the end.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to drop.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.dropRight([1, 2, 3]);
|
|
* // => [1, 2]
|
|
*
|
|
* _.dropRight([1, 2, 3], 2);
|
|
* // => [1]
|
|
*
|
|
* _.dropRight([1, 2, 3], 5);
|
|
* // => []
|
|
*
|
|
* _.dropRight([1, 2, 3], 0);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function dropRight(array, n, guard) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
n = length - n;
|
|
return baseSlice(array, 0, n < 0 ? 0 : n);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` excluding elements dropped from the end.
|
|
* Elements are dropped until `predicate` returns falsey. The predicate is
|
|
* invoked with three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': false }
|
|
* ];
|
|
*
|
|
* _.dropRightWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
|
|
* // => objects for ['barney', 'fred']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.dropRightWhile(users, ['active', false]);
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.dropRightWhile(users, 'active');
|
|
* // => objects for ['barney', 'fred', 'pebbles']
|
|
*/
|
|
function dropRightWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3), true, true)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` excluding elements dropped from the beginning.
|
|
* Elements are dropped until `predicate` returns falsey. The predicate is
|
|
* invoked with three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': false },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': true }
|
|
* ];
|
|
*
|
|
* _.dropWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['pebbles']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.dropWhile(users, { 'user': 'barney', 'active': false });
|
|
* // => objects for ['fred', 'pebbles']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.dropWhile(users, ['active', false]);
|
|
* // => objects for ['pebbles']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.dropWhile(users, 'active');
|
|
* // => objects for ['barney', 'fred', 'pebbles']
|
|
*/
|
|
function dropWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3), true)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Fills elements of `array` with `value` from `start` up to, but not
|
|
* including, `end`.
|
|
*
|
|
* **Note:** This method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Array
|
|
* @param {Array} array The array to fill.
|
|
* @param {*} value The value to fill `array` with.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3];
|
|
*
|
|
* _.fill(array, 'a');
|
|
* console.log(array);
|
|
* // => ['a', 'a', 'a']
|
|
*
|
|
* _.fill(Array(3), 2);
|
|
* // => [2, 2, 2]
|
|
*
|
|
* _.fill([4, 6, 8, 10], '*', 1, 3);
|
|
* // => [4, '*', '*', 10]
|
|
*/
|
|
function fill(array, value, start, end) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
|
|
start = 0;
|
|
end = length;
|
|
}
|
|
return baseFill(array, value, start, end);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.find` except that it returns the index of the first
|
|
* element `predicate` returns truthy for instead of the element itself.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @returns {number} Returns the index of the found element, else `-1`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': false },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': true }
|
|
* ];
|
|
*
|
|
* _.findIndex(users, function(o) { return o.user == 'barney'; });
|
|
* // => 0
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findIndex(users, { 'user': 'fred', 'active': false });
|
|
* // => 1
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findIndex(users, ['active', false]);
|
|
* // => 0
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findIndex(users, 'active');
|
|
* // => 2
|
|
*/
|
|
function findIndex(array, predicate, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = fromIndex == null ? 0 : toInteger(fromIndex);
|
|
if (index < 0) {
|
|
index = nativeMax(length + index, 0);
|
|
}
|
|
return baseFindIndex(array, getIteratee(predicate, 3), index);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.findIndex` except that it iterates over elements
|
|
* of `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=array.length-1] The index to search from.
|
|
* @returns {number} Returns the index of the found element, else `-1`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': false }
|
|
* ];
|
|
*
|
|
* _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
|
|
* // => 2
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findLastIndex(users, { 'user': 'barney', 'active': true });
|
|
* // => 0
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findLastIndex(users, ['active', false]);
|
|
* // => 2
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findLastIndex(users, 'active');
|
|
* // => 0
|
|
*/
|
|
function findLastIndex(array, predicate, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = length - 1;
|
|
if (fromIndex !== undefined) {
|
|
index = toInteger(fromIndex);
|
|
index = fromIndex < 0
|
|
? nativeMax(length + index, 0)
|
|
: nativeMin(index, length - 1);
|
|
}
|
|
return baseFindIndex(array, getIteratee(predicate, 3), index, true);
|
|
}
|
|
|
|
/**
|
|
* Flattens `array` a single level deep.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to flatten.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* _.flatten([1, [2, [3, [4]], 5]]);
|
|
* // => [1, 2, [3, [4]], 5]
|
|
*/
|
|
function flatten(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseFlatten(array, 1) : [];
|
|
}
|
|
|
|
/**
|
|
* Recursively flattens `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to flatten.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* _.flattenDeep([1, [2, [3, [4]], 5]]);
|
|
* // => [1, 2, 3, 4, 5]
|
|
*/
|
|
function flattenDeep(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseFlatten(array, INFINITY) : [];
|
|
}
|
|
|
|
/**
|
|
* Recursively flatten `array` up to `depth` times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.4.0
|
|
* @category Array
|
|
* @param {Array} array The array to flatten.
|
|
* @param {number} [depth=1] The maximum recursion depth.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* var array = [1, [2, [3, [4]], 5]];
|
|
*
|
|
* _.flattenDepth(array, 1);
|
|
* // => [1, 2, [3, [4]], 5]
|
|
*
|
|
* _.flattenDepth(array, 2);
|
|
* // => [1, 2, 3, [4], 5]
|
|
*/
|
|
function flattenDepth(array, depth) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
depth = depth === undefined ? 1 : toInteger(depth);
|
|
return baseFlatten(array, depth);
|
|
}
|
|
|
|
/**
|
|
* The inverse of `_.toPairs`; this method returns an object composed
|
|
* from key-value `pairs`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} pairs The key-value pairs.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* _.fromPairs([['a', 1], ['b', 2]]);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
function fromPairs(pairs) {
|
|
var index = -1,
|
|
length = pairs == null ? 0 : pairs.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var pair = pairs[index];
|
|
result[pair[0]] = pair[1];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the first element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @alias first
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {*} Returns the first element of `array`.
|
|
* @example
|
|
*
|
|
* _.head([1, 2, 3]);
|
|
* // => 1
|
|
*
|
|
* _.head([]);
|
|
* // => undefined
|
|
*/
|
|
function head(array) {
|
|
return (array && array.length) ? array[0] : undefined;
|
|
}
|
|
|
|
/**
|
|
* Gets the index at which the first occurrence of `value` is found in `array`
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons. If `fromIndex` is negative, it's used as the
|
|
* offset from the end of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.indexOf([1, 2, 1, 2], 2);
|
|
* // => 1
|
|
*
|
|
* // Search from the `fromIndex`.
|
|
* _.indexOf([1, 2, 1, 2], 2, 2);
|
|
* // => 3
|
|
*/
|
|
function indexOf(array, value, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = fromIndex == null ? 0 : toInteger(fromIndex);
|
|
if (index < 0) {
|
|
index = nativeMax(length + index, 0);
|
|
}
|
|
return baseIndexOf(array, value, index);
|
|
}
|
|
|
|
/**
|
|
* Gets all but the last element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.initial([1, 2, 3]);
|
|
* // => [1, 2]
|
|
*/
|
|
function initial(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseSlice(array, 0, -1) : [];
|
|
}
|
|
|
|
/**
|
|
* Creates an array of unique values that are included in all given arrays
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons. The order and references of result values are
|
|
* determined by the first array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @returns {Array} Returns the new array of intersecting values.
|
|
* @example
|
|
*
|
|
* _.intersection([2, 1], [2, 3]);
|
|
* // => [2]
|
|
*/
|
|
var intersection = baseRest(function(arrays) {
|
|
var mapped = arrayMap(arrays, castArrayLikeObject);
|
|
return (mapped.length && mapped[0] === arrays[0])
|
|
? baseIntersection(mapped)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.intersection` except that it accepts `iteratee`
|
|
* which is invoked for each element of each `arrays` to generate the criterion
|
|
* by which they're compared. The order and references of result values are
|
|
* determined by the first array. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of intersecting values.
|
|
* @example
|
|
*
|
|
* _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
|
* // => [2.1]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 1 }]
|
|
*/
|
|
var intersectionBy = baseRest(function(arrays) {
|
|
var iteratee = last(arrays),
|
|
mapped = arrayMap(arrays, castArrayLikeObject);
|
|
|
|
if (iteratee === last(mapped)) {
|
|
iteratee = undefined;
|
|
} else {
|
|
mapped.pop();
|
|
}
|
|
return (mapped.length && mapped[0] === arrays[0])
|
|
? baseIntersection(mapped, getIteratee(iteratee, 2))
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.intersection` except that it accepts `comparator`
|
|
* which is invoked to compare elements of `arrays`. The order and references
|
|
* of result values are determined by the first array. The comparator is
|
|
* invoked with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of intersecting values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.intersectionWith(objects, others, _.isEqual);
|
|
* // => [{ 'x': 1, 'y': 2 }]
|
|
*/
|
|
var intersectionWith = baseRest(function(arrays) {
|
|
var comparator = last(arrays),
|
|
mapped = arrayMap(arrays, castArrayLikeObject);
|
|
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
if (comparator) {
|
|
mapped.pop();
|
|
}
|
|
return (mapped.length && mapped[0] === arrays[0])
|
|
? baseIntersection(mapped, undefined, comparator)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* Converts all elements in `array` into a string separated by `separator`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to convert.
|
|
* @param {string} [separator=','] The element separator.
|
|
* @returns {string} Returns the joined string.
|
|
* @example
|
|
*
|
|
* _.join(['a', 'b', 'c'], '~');
|
|
* // => 'a~b~c'
|
|
*/
|
|
function join(array, separator) {
|
|
return array == null ? '' : nativeJoin.call(array, separator);
|
|
}
|
|
|
|
/**
|
|
* Gets the last element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {*} Returns the last element of `array`.
|
|
* @example
|
|
*
|
|
* _.last([1, 2, 3]);
|
|
* // => 3
|
|
*/
|
|
function last(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? array[length - 1] : undefined;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.indexOf` except that it iterates over elements of
|
|
* `array` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} [fromIndex=array.length-1] The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.lastIndexOf([1, 2, 1, 2], 2);
|
|
* // => 3
|
|
*
|
|
* // Search from the `fromIndex`.
|
|
* _.lastIndexOf([1, 2, 1, 2], 2, 2);
|
|
* // => 1
|
|
*/
|
|
function lastIndexOf(array, value, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = length;
|
|
if (fromIndex !== undefined) {
|
|
index = toInteger(fromIndex);
|
|
index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
|
|
}
|
|
return value === value
|
|
? strictLastIndexOf(array, value, index)
|
|
: baseFindIndex(array, baseIsNaN, index, true);
|
|
}
|
|
|
|
/**
|
|
* Gets the element at index `n` of `array`. If `n` is negative, the nth
|
|
* element from the end is returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.11.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=0] The index of the element to return.
|
|
* @returns {*} Returns the nth element of `array`.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'd'];
|
|
*
|
|
* _.nth(array, 1);
|
|
* // => 'b'
|
|
*
|
|
* _.nth(array, -2);
|
|
* // => 'c';
|
|
*/
|
|
function nth(array, n) {
|
|
return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
|
|
}
|
|
|
|
/**
|
|
* Removes all given values from `array` using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
|
|
* to remove elements from an array by predicate.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {...*} [values] The values to remove.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
|
|
*
|
|
* _.pull(array, 'a', 'c');
|
|
* console.log(array);
|
|
* // => ['b', 'b']
|
|
*/
|
|
var pull = baseRest(pullAll);
|
|
|
|
/**
|
|
* This method is like `_.pull` except that it accepts an array of values to remove.
|
|
*
|
|
* **Note:** Unlike `_.difference`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
|
|
*
|
|
* _.pullAll(array, ['a', 'c']);
|
|
* console.log(array);
|
|
* // => ['b', 'b']
|
|
*/
|
|
function pullAll(array, values) {
|
|
return (array && array.length && values && values.length)
|
|
? basePullAll(array, values)
|
|
: array;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.pullAll` except that it accepts `iteratee` which is
|
|
* invoked for each element of `array` and `values` to generate the criterion
|
|
* by which they're compared. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* **Note:** Unlike `_.differenceBy`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
|
|
*
|
|
* _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
|
|
* console.log(array);
|
|
* // => [{ 'x': 2 }]
|
|
*/
|
|
function pullAllBy(array, values, iteratee) {
|
|
return (array && array.length && values && values.length)
|
|
? basePullAll(array, values, getIteratee(iteratee, 2))
|
|
: array;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.pullAll` except that it accepts `comparator` which
|
|
* is invoked to compare elements of `array` to `values`. The comparator is
|
|
* invoked with two arguments: (arrVal, othVal).
|
|
*
|
|
* **Note:** Unlike `_.differenceWith`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.6.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
|
|
*
|
|
* _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
|
|
* console.log(array);
|
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
|
|
*/
|
|
function pullAllWith(array, values, comparator) {
|
|
return (array && array.length && values && values.length)
|
|
? basePullAll(array, values, undefined, comparator)
|
|
: array;
|
|
}
|
|
|
|
/**
|
|
* Removes elements from `array` corresponding to `indexes` and returns an
|
|
* array of removed elements.
|
|
*
|
|
* **Note:** Unlike `_.at`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {...(number|number[])} [indexes] The indexes of elements to remove.
|
|
* @returns {Array} Returns the new array of removed elements.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'd'];
|
|
* var pulled = _.pullAt(array, [1, 3]);
|
|
*
|
|
* console.log(array);
|
|
* // => ['a', 'c']
|
|
*
|
|
* console.log(pulled);
|
|
* // => ['b', 'd']
|
|
*/
|
|
var pullAt = flatRest(function(array, indexes) {
|
|
var length = array == null ? 0 : array.length,
|
|
result = baseAt(array, indexes);
|
|
|
|
basePullAt(array, arrayMap(indexes, function(index) {
|
|
return isIndex(index, length) ? +index : index;
|
|
}).sort(compareAscending));
|
|
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Removes all elements from `array` that `predicate` returns truthy for
|
|
* and returns an array of the removed elements. The predicate is invoked
|
|
* with three arguments: (value, index, array).
|
|
*
|
|
* **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
|
|
* to pull elements from an array by value.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new array of removed elements.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3, 4];
|
|
* var evens = _.remove(array, function(n) {
|
|
* return n % 2 == 0;
|
|
* });
|
|
*
|
|
* console.log(array);
|
|
* // => [1, 3]
|
|
*
|
|
* console.log(evens);
|
|
* // => [2, 4]
|
|
*/
|
|
function remove(array, predicate) {
|
|
var result = [];
|
|
if (!(array && array.length)) {
|
|
return result;
|
|
}
|
|
var index = -1,
|
|
indexes = [],
|
|
length = array.length;
|
|
|
|
predicate = getIteratee(predicate, 3);
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (predicate(value, index, array)) {
|
|
result.push(value);
|
|
indexes.push(index);
|
|
}
|
|
}
|
|
basePullAt(array, indexes);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reverses `array` so that the first element becomes the last, the second
|
|
* element becomes the second to last, and so on.
|
|
*
|
|
* **Note:** This method mutates `array` and is based on
|
|
* [`Array#reverse`](https://mdn.io/Array/reverse).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3];
|
|
*
|
|
* _.reverse(array);
|
|
* // => [3, 2, 1]
|
|
*
|
|
* console.log(array);
|
|
* // => [3, 2, 1]
|
|
*/
|
|
function reverse(array) {
|
|
return array == null ? array : nativeReverse.call(array);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` from `start` up to, but not including, `end`.
|
|
*
|
|
* **Note:** This method is used instead of
|
|
* [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
|
|
* returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to slice.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
*/
|
|
function slice(array, start, end) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
|
|
start = 0;
|
|
end = length;
|
|
}
|
|
else {
|
|
start = start == null ? 0 : toInteger(start);
|
|
end = end === undefined ? length : toInteger(end);
|
|
}
|
|
return baseSlice(array, start, end);
|
|
}
|
|
|
|
/**
|
|
* Uses a binary search to determine the lowest index at which `value`
|
|
* should be inserted into `array` in order to maintain its sort order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* _.sortedIndex([30, 50], 40);
|
|
* // => 1
|
|
*/
|
|
function sortedIndex(array, value) {
|
|
return baseSortedIndex(array, value);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortedIndex` except that it accepts `iteratee`
|
|
* which is invoked for `value` and each element of `array` to compute their
|
|
* sort ranking. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 4 }, { 'x': 5 }];
|
|
*
|
|
* _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
|
|
* // => 0
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.sortedIndexBy(objects, { 'x': 4 }, 'x');
|
|
* // => 0
|
|
*/
|
|
function sortedIndexBy(array, value, iteratee) {
|
|
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.indexOf` except that it performs a binary
|
|
* search on a sorted `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.sortedIndexOf([4, 5, 5, 5, 6], 5);
|
|
* // => 1
|
|
*/
|
|
function sortedIndexOf(array, value) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (length) {
|
|
var index = baseSortedIndex(array, value);
|
|
if (index < length && eq(array[index], value)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortedIndex` except that it returns the highest
|
|
* index at which `value` should be inserted into `array` in order to
|
|
* maintain its sort order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* _.sortedLastIndex([4, 5, 5, 5, 6], 5);
|
|
* // => 4
|
|
*/
|
|
function sortedLastIndex(array, value) {
|
|
return baseSortedIndex(array, value, true);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortedLastIndex` except that it accepts `iteratee`
|
|
* which is invoked for `value` and each element of `array` to compute their
|
|
* sort ranking. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 4 }, { 'x': 5 }];
|
|
*
|
|
* _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
|
|
* // => 1
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
|
|
* // => 1
|
|
*/
|
|
function sortedLastIndexBy(array, value, iteratee) {
|
|
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.lastIndexOf` except that it performs a binary
|
|
* search on a sorted `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
|
|
* // => 3
|
|
*/
|
|
function sortedLastIndexOf(array, value) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (length) {
|
|
var index = baseSortedIndex(array, value, true) - 1;
|
|
if (eq(array[index], value)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniq` except that it's designed and optimized
|
|
* for sorted arrays.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.sortedUniq([1, 1, 2]);
|
|
* // => [1, 2]
|
|
*/
|
|
function sortedUniq(array) {
|
|
return (array && array.length)
|
|
? baseSortedUniq(array)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniqBy` except that it's designed and optimized
|
|
* for sorted arrays.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
|
|
* // => [1.1, 2.3]
|
|
*/
|
|
function sortedUniqBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseSortedUniq(array, getIteratee(iteratee, 2))
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Gets all but the first element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.tail([1, 2, 3]);
|
|
* // => [2, 3]
|
|
*/
|
|
function tail(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseSlice(array, 1, length) : [];
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements taken from the beginning.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to take.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.take([1, 2, 3]);
|
|
* // => [1]
|
|
*
|
|
* _.take([1, 2, 3], 2);
|
|
* // => [1, 2]
|
|
*
|
|
* _.take([1, 2, 3], 5);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* _.take([1, 2, 3], 0);
|
|
* // => []
|
|
*/
|
|
function take(array, n, guard) {
|
|
if (!(array && array.length)) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
return baseSlice(array, 0, n < 0 ? 0 : n);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements taken from the end.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to take.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.takeRight([1, 2, 3]);
|
|
* // => [3]
|
|
*
|
|
* _.takeRight([1, 2, 3], 2);
|
|
* // => [2, 3]
|
|
*
|
|
* _.takeRight([1, 2, 3], 5);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* _.takeRight([1, 2, 3], 0);
|
|
* // => []
|
|
*/
|
|
function takeRight(array, n, guard) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
n = length - n;
|
|
return baseSlice(array, n < 0 ? 0 : n, length);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with elements taken from the end. Elements are
|
|
* taken until `predicate` returns falsey. The predicate is invoked with
|
|
* three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': false }
|
|
* ];
|
|
*
|
|
* _.takeRightWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['fred', 'pebbles']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
|
|
* // => objects for ['pebbles']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.takeRightWhile(users, ['active', false]);
|
|
* // => objects for ['fred', 'pebbles']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.takeRightWhile(users, 'active');
|
|
* // => []
|
|
*/
|
|
function takeRightWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3), false, true)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with elements taken from the beginning. Elements
|
|
* are taken until `predicate` returns falsey. The predicate is invoked with
|
|
* three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': false },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': true }
|
|
* ];
|
|
*
|
|
* _.takeWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['barney', 'fred']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.takeWhile(users, { 'user': 'barney', 'active': false });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.takeWhile(users, ['active', false]);
|
|
* // => objects for ['barney', 'fred']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.takeWhile(users, 'active');
|
|
* // => []
|
|
*/
|
|
function takeWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3))
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Creates an array of unique values, in order, from all given arrays using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @returns {Array} Returns the new array of combined values.
|
|
* @example
|
|
*
|
|
* _.union([2], [1, 2]);
|
|
* // => [2, 1]
|
|
*/
|
|
var union = baseRest(function(arrays) {
|
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.union` except that it accepts `iteratee` which is
|
|
* invoked for each element of each `arrays` to generate the criterion by
|
|
* which uniqueness is computed. Result values are chosen from the first
|
|
* array in which the value occurs. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of combined values.
|
|
* @example
|
|
*
|
|
* _.unionBy([2.1], [1.2, 2.3], Math.floor);
|
|
* // => [2.1, 1.2]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 1 }, { 'x': 2 }]
|
|
*/
|
|
var unionBy = baseRest(function(arrays) {
|
|
var iteratee = last(arrays);
|
|
if (isArrayLikeObject(iteratee)) {
|
|
iteratee = undefined;
|
|
}
|
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.union` except that it accepts `comparator` which
|
|
* is invoked to compare elements of `arrays`. Result values are chosen from
|
|
* the first array in which the value occurs. The comparator is invoked
|
|
* with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of combined values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.unionWith(objects, others, _.isEqual);
|
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
|
|
*/
|
|
var unionWith = baseRest(function(arrays) {
|
|
var comparator = last(arrays);
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
|
|
});
|
|
|
|
/**
|
|
* Creates a duplicate-free version of an array, using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons, in which only the first occurrence of each element
|
|
* is kept. The order of result values is determined by the order they occur
|
|
* in the array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.uniq([2, 1, 2]);
|
|
* // => [2, 1]
|
|
*/
|
|
function uniq(array) {
|
|
return (array && array.length) ? baseUniq(array) : [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniq` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the criterion by which
|
|
* uniqueness is computed. The order of result values is determined by the
|
|
* order they occur in the array. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.uniqBy([2.1, 1.2, 2.3], Math.floor);
|
|
* // => [2.1, 1.2]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 1 }, { 'x': 2 }]
|
|
*/
|
|
function uniqBy(array, iteratee) {
|
|
return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniq` except that it accepts `comparator` which
|
|
* is invoked to compare elements of `array`. The order of result values is
|
|
* determined by the order they occur in the array.The comparator is invoked
|
|
* with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.uniqWith(objects, _.isEqual);
|
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
|
|
*/
|
|
function uniqWith(array, comparator) {
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.zip` except that it accepts an array of grouped
|
|
* elements and creates an array regrouping the elements to their pre-zip
|
|
* configuration.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.2.0
|
|
* @category Array
|
|
* @param {Array} array The array of grouped elements to process.
|
|
* @returns {Array} Returns the new array of regrouped elements.
|
|
* @example
|
|
*
|
|
* var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
|
|
* // => [['a', 1, true], ['b', 2, false]]
|
|
*
|
|
* _.unzip(zipped);
|
|
* // => [['a', 'b'], [1, 2], [true, false]]
|
|
*/
|
|
function unzip(array) {
|
|
if (!(array && array.length)) {
|
|
return [];
|
|
}
|
|
var length = 0;
|
|
array = arrayFilter(array, function(group) {
|
|
if (isArrayLikeObject(group)) {
|
|
length = nativeMax(group.length, length);
|
|
return true;
|
|
}
|
|
});
|
|
return baseTimes(length, function(index) {
|
|
return arrayMap(array, baseProperty(index));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.unzip` except that it accepts `iteratee` to specify
|
|
* how regrouped values should be combined. The iteratee is invoked with the
|
|
* elements of each group: (...group).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.8.0
|
|
* @category Array
|
|
* @param {Array} array The array of grouped elements to process.
|
|
* @param {Function} [iteratee=_.identity] The function to combine
|
|
* regrouped values.
|
|
* @returns {Array} Returns the new array of regrouped elements.
|
|
* @example
|
|
*
|
|
* var zipped = _.zip([1, 2], [10, 20], [100, 200]);
|
|
* // => [[1, 10, 100], [2, 20, 200]]
|
|
*
|
|
* _.unzipWith(zipped, _.add);
|
|
* // => [3, 30, 300]
|
|
*/
|
|
function unzipWith(array, iteratee) {
|
|
if (!(array && array.length)) {
|
|
return [];
|
|
}
|
|
var result = unzip(array);
|
|
if (iteratee == null) {
|
|
return result;
|
|
}
|
|
return arrayMap(result, function(group) {
|
|
return apply(iteratee, undefined, group);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates an array excluding all given values using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* **Note:** Unlike `_.pull`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...*} [values] The values to exclude.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @see _.difference, _.xor
|
|
* @example
|
|
*
|
|
* _.without([2, 1, 2, 3], 1, 2);
|
|
* // => [3]
|
|
*/
|
|
var without = baseRest(function(array, values) {
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, values)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* Creates an array of unique values that is the
|
|
* [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
|
|
* of the given arrays. The order of result values is determined by the order
|
|
* they occur in the arrays.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @see _.difference, _.without
|
|
* @example
|
|
*
|
|
* _.xor([2, 1], [2, 3]);
|
|
* // => [1, 3]
|
|
*/
|
|
var xor = baseRest(function(arrays) {
|
|
return baseXor(arrayFilter(arrays, isArrayLikeObject));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.xor` except that it accepts `iteratee` which is
|
|
* invoked for each element of each `arrays` to generate the criterion by
|
|
* which by which they're compared. The order of result values is determined
|
|
* by the order they occur in the arrays. The iteratee is invoked with one
|
|
* argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
|
* // => [1.2, 3.4]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 2 }]
|
|
*/
|
|
var xorBy = baseRest(function(arrays) {
|
|
var iteratee = last(arrays);
|
|
if (isArrayLikeObject(iteratee)) {
|
|
iteratee = undefined;
|
|
}
|
|
return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.xor` except that it accepts `comparator` which is
|
|
* invoked to compare elements of `arrays`. The order of result values is
|
|
* determined by the order they occur in the arrays. The comparator is invoked
|
|
* with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.xorWith(objects, others, _.isEqual);
|
|
* // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
|
|
*/
|
|
var xorWith = baseRest(function(arrays) {
|
|
var comparator = last(arrays);
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
|
|
});
|
|
|
|
/**
|
|
* Creates an array of grouped elements, the first of which contains the
|
|
* first elements of the given arrays, the second of which contains the
|
|
* second elements of the given arrays, and so on.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to process.
|
|
* @returns {Array} Returns the new array of grouped elements.
|
|
* @example
|
|
*
|
|
* _.zip(['a', 'b'], [1, 2], [true, false]);
|
|
* // => [['a', 1, true], ['b', 2, false]]
|
|
*/
|
|
var zip = baseRest(unzip);
|
|
|
|
/**
|
|
* This method is like `_.fromPairs` except that it accepts two arrays,
|
|
* one of property identifiers and one of corresponding values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.4.0
|
|
* @category Array
|
|
* @param {Array} [props=[]] The property identifiers.
|
|
* @param {Array} [values=[]] The property values.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* _.zipObject(['a', 'b'], [1, 2]);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
function zipObject(props, values) {
|
|
return baseZipObject(props || [], values || [], assignValue);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.zipObject` except that it supports property paths.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.1.0
|
|
* @category Array
|
|
* @param {Array} [props=[]] The property identifiers.
|
|
* @param {Array} [values=[]] The property values.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
|
|
* // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
|
|
*/
|
|
function zipObjectDeep(props, values) {
|
|
return baseZipObject(props || [], values || [], baseSet);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.zip` except that it accepts `iteratee` to specify
|
|
* how grouped values should be combined. The iteratee is invoked with the
|
|
* elements of each group: (...group).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.8.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to process.
|
|
* @param {Function} [iteratee=_.identity] The function to combine
|
|
* grouped values.
|
|
* @returns {Array} Returns the new array of grouped elements.
|
|
* @example
|
|
*
|
|
* _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
|
|
* return a + b + c;
|
|
* });
|
|
* // => [111, 222]
|
|
*/
|
|
var zipWith = baseRest(function(arrays) {
|
|
var length = arrays.length,
|
|
iteratee = length > 1 ? arrays[length - 1] : undefined;
|
|
|
|
iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
|
|
return unzipWith(arrays, iteratee);
|
|
});
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a `lodash` wrapper instance that wraps `value` with explicit method
|
|
* chain sequences enabled. The result of such sequences must be unwrapped
|
|
* with `_#value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.3.0
|
|
* @category Seq
|
|
* @param {*} value The value to wrap.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36 },
|
|
* { 'user': 'fred', 'age': 40 },
|
|
* { 'user': 'pebbles', 'age': 1 }
|
|
* ];
|
|
*
|
|
* var youngest = _
|
|
* .chain(users)
|
|
* .sortBy('age')
|
|
* .map(function(o) {
|
|
* return o.user + ' is ' + o.age;
|
|
* })
|
|
* .head()
|
|
* .value();
|
|
* // => 'pebbles is 1'
|
|
*/
|
|
function chain(value) {
|
|
var result = lodash(value);
|
|
result.__chain__ = true;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method invokes `interceptor` and returns `value`. The interceptor
|
|
* is invoked with one argument; (value). The purpose of this method is to
|
|
* "tap into" a method chain sequence in order to modify intermediate results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Seq
|
|
* @param {*} value The value to provide to `interceptor`.
|
|
* @param {Function} interceptor The function to invoke.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* _([1, 2, 3])
|
|
* .tap(function(array) {
|
|
* // Mutate input array.
|
|
* array.pop();
|
|
* })
|
|
* .reverse()
|
|
* .value();
|
|
* // => [2, 1]
|
|
*/
|
|
function tap(value, interceptor) {
|
|
interceptor(value);
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.tap` except that it returns the result of `interceptor`.
|
|
* The purpose of this method is to "pass thru" values replacing intermediate
|
|
* results in a method chain sequence.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Seq
|
|
* @param {*} value The value to provide to `interceptor`.
|
|
* @param {Function} interceptor The function to invoke.
|
|
* @returns {*} Returns the result of `interceptor`.
|
|
* @example
|
|
*
|
|
* _(' abc ')
|
|
* .chain()
|
|
* .trim()
|
|
* .thru(function(value) {
|
|
* return [value];
|
|
* })
|
|
* .value();
|
|
* // => ['abc']
|
|
*/
|
|
function thru(value, interceptor) {
|
|
return interceptor(value);
|
|
}
|
|
|
|
/**
|
|
* This method is the wrapper version of `_.at`.
|
|
*
|
|
* @name at
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Seq
|
|
* @param {...(string|string[])} [paths] The property paths to pick.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
|
|
*
|
|
* _(object).at(['a[0].b.c', 'a[1]']).value();
|
|
* // => [3, 4]
|
|
*/
|
|
var wrapperAt = flatRest(function(paths) {
|
|
var length = paths.length,
|
|
start = length ? paths[0] : 0,
|
|
value = this.__wrapped__,
|
|
interceptor = function(object) { return baseAt(object, paths); };
|
|
|
|
if (length > 1 || this.__actions__.length ||
|
|
!(value instanceof LazyWrapper) || !isIndex(start)) {
|
|
return this.thru(interceptor);
|
|
}
|
|
value = value.slice(start, +start + (length ? 1 : 0));
|
|
value.__actions__.push({
|
|
'func': thru,
|
|
'args': [interceptor],
|
|
'thisArg': undefined
|
|
});
|
|
return new LodashWrapper(value, this.__chain__).thru(function(array) {
|
|
if (length && !array.length) {
|
|
array.push(undefined);
|
|
}
|
|
return array;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
|
|
*
|
|
* @name chain
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36 },
|
|
* { 'user': 'fred', 'age': 40 }
|
|
* ];
|
|
*
|
|
* // A sequence without explicit chaining.
|
|
* _(users).head();
|
|
* // => { 'user': 'barney', 'age': 36 }
|
|
*
|
|
* // A sequence with explicit chaining.
|
|
* _(users)
|
|
* .chain()
|
|
* .head()
|
|
* .pick('user')
|
|
* .value();
|
|
* // => { 'user': 'barney' }
|
|
*/
|
|
function wrapperChain() {
|
|
return chain(this);
|
|
}
|
|
|
|
/**
|
|
* Executes the chain sequence and returns the wrapped result.
|
|
*
|
|
* @name commit
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var array = [1, 2];
|
|
* var wrapped = _(array).push(3);
|
|
*
|
|
* console.log(array);
|
|
* // => [1, 2]
|
|
*
|
|
* wrapped = wrapped.commit();
|
|
* console.log(array);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* wrapped.last();
|
|
* // => 3
|
|
*
|
|
* console.log(array);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function wrapperCommit() {
|
|
return new LodashWrapper(this.value(), this.__chain__);
|
|
}
|
|
|
|
/**
|
|
* Gets the next value on a wrapped object following the
|
|
* [iterator protocol](https://mdn.io/iteration_protocols#iterator).
|
|
*
|
|
* @name next
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the next iterator value.
|
|
* @example
|
|
*
|
|
* var wrapped = _([1, 2]);
|
|
*
|
|
* wrapped.next();
|
|
* // => { 'done': false, 'value': 1 }
|
|
*
|
|
* wrapped.next();
|
|
* // => { 'done': false, 'value': 2 }
|
|
*
|
|
* wrapped.next();
|
|
* // => { 'done': true, 'value': undefined }
|
|
*/
|
|
function wrapperNext() {
|
|
if (this.__values__ === undefined) {
|
|
this.__values__ = toArray(this.value());
|
|
}
|
|
var done = this.__index__ >= this.__values__.length,
|
|
value = done ? undefined : this.__values__[this.__index__++];
|
|
|
|
return { 'done': done, 'value': value };
|
|
}
|
|
|
|
/**
|
|
* Enables the wrapper to be iterable.
|
|
*
|
|
* @name Symbol.iterator
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the wrapper object.
|
|
* @example
|
|
*
|
|
* var wrapped = _([1, 2]);
|
|
*
|
|
* wrapped[Symbol.iterator]() === wrapped;
|
|
* // => true
|
|
*
|
|
* Array.from(wrapped);
|
|
* // => [1, 2]
|
|
*/
|
|
function wrapperToIterator() {
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of the chain sequence planting `value` as the wrapped value.
|
|
*
|
|
* @name plant
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Seq
|
|
* @param {*} value The value to plant.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var wrapped = _([1, 2]).map(square);
|
|
* var other = wrapped.plant([3, 4]);
|
|
*
|
|
* other.value();
|
|
* // => [9, 16]
|
|
*
|
|
* wrapped.value();
|
|
* // => [1, 4]
|
|
*/
|
|
function wrapperPlant(value) {
|
|
var result,
|
|
parent = this;
|
|
|
|
while (parent instanceof baseLodash) {
|
|
var clone = wrapperClone(parent);
|
|
clone.__index__ = 0;
|
|
clone.__values__ = undefined;
|
|
if (result) {
|
|
previous.__wrapped__ = clone;
|
|
} else {
|
|
result = clone;
|
|
}
|
|
var previous = clone;
|
|
parent = parent.__wrapped__;
|
|
}
|
|
previous.__wrapped__ = value;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method is the wrapper version of `_.reverse`.
|
|
*
|
|
* **Note:** This method mutates the wrapped array.
|
|
*
|
|
* @name reverse
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3];
|
|
*
|
|
* _(array).reverse().value()
|
|
* // => [3, 2, 1]
|
|
*
|
|
* console.log(array);
|
|
* // => [3, 2, 1]
|
|
*/
|
|
function wrapperReverse() {
|
|
var value = this.__wrapped__;
|
|
if (value instanceof LazyWrapper) {
|
|
var wrapped = value;
|
|
if (this.__actions__.length) {
|
|
wrapped = new LazyWrapper(this);
|
|
}
|
|
wrapped = wrapped.reverse();
|
|
wrapped.__actions__.push({
|
|
'func': thru,
|
|
'args': [reverse],
|
|
'thisArg': undefined
|
|
});
|
|
return new LodashWrapper(wrapped, this.__chain__);
|
|
}
|
|
return this.thru(reverse);
|
|
}
|
|
|
|
/**
|
|
* Executes the chain sequence to resolve the unwrapped value.
|
|
*
|
|
* @name value
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @alias toJSON, valueOf
|
|
* @category Seq
|
|
* @returns {*} Returns the resolved unwrapped value.
|
|
* @example
|
|
*
|
|
* _([1, 2, 3]).value();
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function wrapperValue() {
|
|
return baseWrapperValue(this.__wrapped__, this.__actions__);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an object composed of keys generated from the results of running
|
|
* each element of `collection` thru `iteratee`. The corresponding value of
|
|
* each key is the number of times the key was returned by `iteratee`. The
|
|
* iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.5.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
|
* @returns {Object} Returns the composed aggregate object.
|
|
* @example
|
|
*
|
|
* _.countBy([6.1, 4.2, 6.3], Math.floor);
|
|
* // => { '4': 1, '6': 2 }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.countBy(['one', 'two', 'three'], 'length');
|
|
* // => { '3': 2, '5': 1 }
|
|
*/
|
|
var countBy = createAggregator(function(result, value, key) {
|
|
if (hasOwnProperty.call(result, key)) {
|
|
++result[key];
|
|
} else {
|
|
baseAssignValue(result, key, 1);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Checks if `predicate` returns truthy for **all** elements of `collection`.
|
|
* Iteration is stopped once `predicate` returns falsey. The predicate is
|
|
* invoked with three arguments: (value, index|key, collection).
|
|
*
|
|
* **Note:** This method returns `true` for
|
|
* [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
|
|
* [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
|
|
* elements of empty collections.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.every([true, 1, null, 'yes'], Boolean);
|
|
* // => false
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': false },
|
|
* { 'user': 'fred', 'age': 40, 'active': false }
|
|
* ];
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.every(users, { 'user': 'barney', 'active': false });
|
|
* // => false
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.every(users, ['active', false]);
|
|
* // => true
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.every(users, 'active');
|
|
* // => false
|
|
*/
|
|
function every(collection, predicate, guard) {
|
|
var func = isArray(collection) ? arrayEvery : baseEvery;
|
|
if (guard && isIterateeCall(collection, predicate, guard)) {
|
|
predicate = undefined;
|
|
}
|
|
return func(collection, getIteratee(predicate, 3));
|
|
}
|
|
|
|
/**
|
|
* Iterates over elements of `collection`, returning an array of all elements
|
|
* `predicate` returns truthy for. The predicate is invoked with three
|
|
* arguments: (value, index|key, collection).
|
|
*
|
|
* **Note:** Unlike `_.remove`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
* @see _.reject
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': true },
|
|
* { 'user': 'fred', 'age': 40, 'active': false }
|
|
* ];
|
|
*
|
|
* _.filter(users, function(o) { return !o.active; });
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.filter(users, { 'age': 36, 'active': true });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.filter(users, ['active', false]);
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.filter(users, 'active');
|
|
* // => objects for ['barney']
|
|
*/
|
|
function filter(collection, predicate) {
|
|
var func = isArray(collection) ? arrayFilter : baseFilter;
|
|
return func(collection, getIteratee(predicate, 3));
|
|
}
|
|
|
|
/**
|
|
* Iterates over elements of `collection`, returning the first element
|
|
* `predicate` returns truthy for. The predicate is invoked with three
|
|
* arguments: (value, index|key, collection).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @returns {*} Returns the matched element, else `undefined`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': true },
|
|
* { 'user': 'fred', 'age': 40, 'active': false },
|
|
* { 'user': 'pebbles', 'age': 1, 'active': true }
|
|
* ];
|
|
*
|
|
* _.find(users, function(o) { return o.age < 40; });
|
|
* // => object for 'barney'
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.find(users, { 'age': 1, 'active': true });
|
|
* // => object for 'pebbles'
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.find(users, ['active', false]);
|
|
* // => object for 'fred'
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.find(users, 'active');
|
|
* // => object for 'barney'
|
|
*/
|
|
var find = createFind(findIndex);
|
|
|
|
/**
|
|
* This method is like `_.find` except that it iterates over elements of
|
|
* `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=collection.length-1] The index to search from.
|
|
* @returns {*} Returns the matched element, else `undefined`.
|
|
* @example
|
|
*
|
|
* _.findLast([1, 2, 3, 4], function(n) {
|
|
* return n % 2 == 1;
|
|
* });
|
|
* // => 3
|
|
*/
|
|
var findLast = createFind(findLastIndex);
|
|
|
|
/**
|
|
* Creates a flattened array of values by running each element in `collection`
|
|
* thru `iteratee` and flattening the mapped results. The iteratee is invoked
|
|
* with three arguments: (value, index|key, collection).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* function duplicate(n) {
|
|
* return [n, n];
|
|
* }
|
|
*
|
|
* _.flatMap([1, 2], duplicate);
|
|
* // => [1, 1, 2, 2]
|
|
*/
|
|
function flatMap(collection, iteratee) {
|
|
return baseFlatten(map(collection, iteratee), 1);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.flatMap` except that it recursively flattens the
|
|
* mapped results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* function duplicate(n) {
|
|
* return [[[n, n]]];
|
|
* }
|
|
*
|
|
* _.flatMapDeep([1, 2], duplicate);
|
|
* // => [1, 1, 2, 2]
|
|
*/
|
|
function flatMapDeep(collection, iteratee) {
|
|
return baseFlatten(map(collection, iteratee), INFINITY);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.flatMap` except that it recursively flattens the
|
|
* mapped results up to `depth` times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {number} [depth=1] The maximum recursion depth.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* function duplicate(n) {
|
|
* return [[[n, n]]];
|
|
* }
|
|
*
|
|
* _.flatMapDepth([1, 2], duplicate, 2);
|
|
* // => [[1, 1], [2, 2]]
|
|
*/
|
|
function flatMapDepth(collection, iteratee, depth) {
|
|
depth = depth === undefined ? 1 : toInteger(depth);
|
|
return baseFlatten(map(collection, iteratee), depth);
|
|
}
|
|
|
|
/**
|
|
* Iterates over elements of `collection` and invokes `iteratee` for each element.
|
|
* The iteratee is invoked with three arguments: (value, index|key, collection).
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
*
|
|
* **Note:** As with other "Collections" methods, objects with a "length"
|
|
* property are iterated like arrays. To avoid this behavior use `_.forIn`
|
|
* or `_.forOwn` for object iteration.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @alias each
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
* @see _.forEachRight
|
|
* @example
|
|
*
|
|
* _.forEach([1, 2], function(value) {
|
|
* console.log(value);
|
|
* });
|
|
* // => Logs `1` then `2`.
|
|
*
|
|
* _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
|
*/
|
|
function forEach(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayEach : baseEach;
|
|
return func(collection, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.forEach` except that it iterates over elements of
|
|
* `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @alias eachRight
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
* @see _.forEach
|
|
* @example
|
|
*
|
|
* _.forEachRight([1, 2], function(value) {
|
|
* console.log(value);
|
|
* });
|
|
* // => Logs `2` then `1`.
|
|
*/
|
|
function forEachRight(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayEachRight : baseEachRight;
|
|
return func(collection, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* Creates an object composed of keys generated from the results of running
|
|
* each element of `collection` thru `iteratee`. The order of grouped values
|
|
* is determined by the order they occur in `collection`. The corresponding
|
|
* value of each key is an array of elements responsible for generating the
|
|
* key. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
|
* @returns {Object} Returns the composed aggregate object.
|
|
* @example
|
|
*
|
|
* _.groupBy([6.1, 4.2, 6.3], Math.floor);
|
|
* // => { '4': [4.2], '6': [6.1, 6.3] }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.groupBy(['one', 'two', 'three'], 'length');
|
|
* // => { '3': ['one', 'two'], '5': ['three'] }
|
|
*/
|
|
var groupBy = createAggregator(function(result, value, key) {
|
|
if (hasOwnProperty.call(result, key)) {
|
|
result[key].push(value);
|
|
} else {
|
|
baseAssignValue(result, key, [value]);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Checks if `value` is in `collection`. If `collection` is a string, it's
|
|
* checked for a substring of `value`, otherwise
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* is used for equality comparisons. If `fromIndex` is negative, it's used as
|
|
* the offset from the end of `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object|string} collection The collection to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
|
|
* @returns {boolean} Returns `true` if `value` is found, else `false`.
|
|
* @example
|
|
*
|
|
* _.includes([1, 2, 3], 1);
|
|
* // => true
|
|
*
|
|
* _.includes([1, 2, 3], 1, 2);
|
|
* // => false
|
|
*
|
|
* _.includes({ 'a': 1, 'b': 2 }, 1);
|
|
* // => true
|
|
*
|
|
* _.includes('abcd', 'bc');
|
|
* // => true
|
|
*/
|
|
function includes(collection, value, fromIndex, guard) {
|
|
collection = isArrayLike(collection) ? collection : values(collection);
|
|
fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
|
|
|
|
var length = collection.length;
|
|
if (fromIndex < 0) {
|
|
fromIndex = nativeMax(length + fromIndex, 0);
|
|
}
|
|
return isString(collection)
|
|
? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
|
|
: (!!length && baseIndexOf(collection, value, fromIndex) > -1);
|
|
}
|
|
|
|
/**
|
|
* Invokes the method at `path` of each element in `collection`, returning
|
|
* an array of the results of each invoked method. Any additional arguments
|
|
* are provided to each invoked method. If `path` is a function, it's invoked
|
|
* for, and `this` bound to, each element in `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Array|Function|string} path The path of the method to invoke or
|
|
* the function invoked per iteration.
|
|
* @param {...*} [args] The arguments to invoke each method with.
|
|
* @returns {Array} Returns the array of results.
|
|
* @example
|
|
*
|
|
* _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
|
|
* // => [[1, 5, 7], [1, 2, 3]]
|
|
*
|
|
* _.invokeMap([123, 456], String.prototype.split, '');
|
|
* // => [['1', '2', '3'], ['4', '5', '6']]
|
|
*/
|
|
var invokeMap = baseRest(function(collection, path, args) {
|
|
var index = -1,
|
|
isFunc = typeof path == 'function',
|
|
result = isArrayLike(collection) ? Array(collection.length) : [];
|
|
|
|
baseEach(collection, function(value) {
|
|
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
|
|
});
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Creates an object composed of keys generated from the results of running
|
|
* each element of `collection` thru `iteratee`. The corresponding value of
|
|
* each key is the last element responsible for generating the key. The
|
|
* iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
|
* @returns {Object} Returns the composed aggregate object.
|
|
* @example
|
|
*
|
|
* var array = [
|
|
* { 'dir': 'left', 'code': 97 },
|
|
* { 'dir': 'right', 'code': 100 }
|
|
* ];
|
|
*
|
|
* _.keyBy(array, function(o) {
|
|
* return String.fromCharCode(o.code);
|
|
* });
|
|
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
|
|
*
|
|
* _.keyBy(array, 'dir');
|
|
* // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
|
|
*/
|
|
var keyBy = createAggregator(function(result, value, key) {
|
|
baseAssignValue(result, key, value);
|
|
});
|
|
|
|
/**
|
|
* Creates an array of values by running each element in `collection` thru
|
|
* `iteratee`. The iteratee is invoked with three arguments:
|
|
* (value, index|key, collection).
|
|
*
|
|
* Many lodash methods are guarded to work as iteratees for methods like
|
|
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
|
|
*
|
|
* The guarded methods are:
|
|
* `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
|
|
* `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
|
|
* `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
|
|
* `template`, `trim`, `trimEnd`, `trimStart`, and `words`
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* _.map([4, 8], square);
|
|
* // => [16, 64]
|
|
*
|
|
* _.map({ 'a': 4, 'b': 8 }, square);
|
|
* // => [16, 64] (iteration order is not guaranteed)
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney' },
|
|
* { 'user': 'fred' }
|
|
* ];
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.map(users, 'user');
|
|
* // => ['barney', 'fred']
|
|
*/
|
|
function map(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayMap : baseMap;
|
|
return func(collection, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortBy` except that it allows specifying the sort
|
|
* orders of the iteratees to sort by. If `orders` is unspecified, all values
|
|
* are sorted in ascending order. Otherwise, specify an order of "desc" for
|
|
* descending or "asc" for ascending sort order of corresponding values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
|
|
* The iteratees to sort by.
|
|
* @param {string[]} [orders] The sort orders of `iteratees`.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
|
|
* @returns {Array} Returns the new sorted array.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'fred', 'age': 48 },
|
|
* { 'user': 'barney', 'age': 34 },
|
|
* { 'user': 'fred', 'age': 40 },
|
|
* { 'user': 'barney', 'age': 36 }
|
|
* ];
|
|
*
|
|
* // Sort by `user` in ascending order and by `age` in descending order.
|
|
* _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
|
|
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
|
|
*/
|
|
function orderBy(collection, iteratees, orders, guard) {
|
|
if (collection == null) {
|
|
return [];
|
|
}
|
|
if (!isArray(iteratees)) {
|
|
iteratees = iteratees == null ? [] : [iteratees];
|
|
}
|
|
orders = guard ? undefined : orders;
|
|
if (!isArray(orders)) {
|
|
orders = orders == null ? [] : [orders];
|
|
}
|
|
return baseOrderBy(collection, iteratees, orders);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of elements split into two groups, the first of which
|
|
* contains elements `predicate` returns truthy for, the second of which
|
|
* contains elements `predicate` returns falsey for. The predicate is
|
|
* invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the array of grouped elements.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': false },
|
|
* { 'user': 'fred', 'age': 40, 'active': true },
|
|
* { 'user': 'pebbles', 'age': 1, 'active': false }
|
|
* ];
|
|
*
|
|
* _.partition(users, function(o) { return o.active; });
|
|
* // => objects for [['fred'], ['barney', 'pebbles']]
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.partition(users, { 'age': 1, 'active': false });
|
|
* // => objects for [['pebbles'], ['barney', 'fred']]
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.partition(users, ['active', false]);
|
|
* // => objects for [['barney', 'pebbles'], ['fred']]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.partition(users, 'active');
|
|
* // => objects for [['fred'], ['barney', 'pebbles']]
|
|
*/
|
|
var partition = createAggregator(function(result, value, key) {
|
|
result[key ? 0 : 1].push(value);
|
|
}, function() { return [[], []]; });
|
|
|
|
/**
|
|
* Reduces `collection` to a value which is the accumulated result of running
|
|
* each element in `collection` thru `iteratee`, where each successive
|
|
* invocation is supplied the return value of the previous. If `accumulator`
|
|
* is not given, the first element of `collection` is used as the initial
|
|
* value. The iteratee is invoked with four arguments:
|
|
* (accumulator, value, index|key, collection).
|
|
*
|
|
* Many lodash methods are guarded to work as iteratees for methods like
|
|
* `_.reduce`, `_.reduceRight`, and `_.transform`.
|
|
*
|
|
* The guarded methods are:
|
|
* `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
|
|
* and `sortBy`
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
* @see _.reduceRight
|
|
* @example
|
|
*
|
|
* _.reduce([1, 2], function(sum, n) {
|
|
* return sum + n;
|
|
* }, 0);
|
|
* // => 3
|
|
*
|
|
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
|
|
* (result[value] || (result[value] = [])).push(key);
|
|
* return result;
|
|
* }, {});
|
|
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
|
|
*/
|
|
function reduce(collection, iteratee, accumulator) {
|
|
var func = isArray(collection) ? arrayReduce : baseReduce,
|
|
initAccum = arguments.length < 3;
|
|
|
|
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.reduce` except that it iterates over elements of
|
|
* `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
* @see _.reduce
|
|
* @example
|
|
*
|
|
* var array = [[0, 1], [2, 3], [4, 5]];
|
|
*
|
|
* _.reduceRight(array, function(flattened, other) {
|
|
* return flattened.concat(other);
|
|
* }, []);
|
|
* // => [4, 5, 2, 3, 0, 1]
|
|
*/
|
|
function reduceRight(collection, iteratee, accumulator) {
|
|
var func = isArray(collection) ? arrayReduceRight : baseReduce,
|
|
initAccum = arguments.length < 3;
|
|
|
|
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
|
|
}
|
|
|
|
/**
|
|
* The opposite of `_.filter`; this method returns the elements of `collection`
|
|
* that `predicate` does **not** return truthy for.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
* @see _.filter
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': false },
|
|
* { 'user': 'fred', 'age': 40, 'active': true }
|
|
* ];
|
|
*
|
|
* _.reject(users, function(o) { return !o.active; });
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.reject(users, { 'age': 40, 'active': true });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.reject(users, ['active', false]);
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.reject(users, 'active');
|
|
* // => objects for ['barney']
|
|
*/
|
|
function reject(collection, predicate) {
|
|
var func = isArray(collection) ? arrayFilter : baseFilter;
|
|
return func(collection, negate(getIteratee(predicate, 3)));
|
|
}
|
|
|
|
/**
|
|
* Gets a random element from `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @returns {*} Returns the random element.
|
|
* @example
|
|
*
|
|
* _.sample([1, 2, 3, 4]);
|
|
* // => 2
|
|
*/
|
|
function sample(collection) {
|
|
var func = isArray(collection) ? arraySample : baseSample;
|
|
return func(collection);
|
|
}
|
|
|
|
/**
|
|
* Gets `n` random elements at unique keys from `collection` up to the
|
|
* size of `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @param {number} [n=1] The number of elements to sample.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the random elements.
|
|
* @example
|
|
*
|
|
* _.sampleSize([1, 2, 3], 2);
|
|
* // => [3, 1]
|
|
*
|
|
* _.sampleSize([1, 2, 3], 4);
|
|
* // => [2, 3, 1]
|
|
*/
|
|
function sampleSize(collection, n, guard) {
|
|
if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
|
|
n = 1;
|
|
} else {
|
|
n = toInteger(n);
|
|
}
|
|
var func = isArray(collection) ? arraySampleSize : baseSampleSize;
|
|
return func(collection, n);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of shuffled values, using a version of the
|
|
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to shuffle.
|
|
* @returns {Array} Returns the new shuffled array.
|
|
* @example
|
|
*
|
|
* _.shuffle([1, 2, 3, 4]);
|
|
* // => [4, 1, 3, 2]
|
|
*/
|
|
function shuffle(collection) {
|
|
var func = isArray(collection) ? arrayShuffle : baseShuffle;
|
|
return func(collection);
|
|
}
|
|
|
|
/**
|
|
* Gets the size of `collection` by returning its length for array-like
|
|
* values or the number of own enumerable string keyed properties for objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object|string} collection The collection to inspect.
|
|
* @returns {number} Returns the collection size.
|
|
* @example
|
|
*
|
|
* _.size([1, 2, 3]);
|
|
* // => 3
|
|
*
|
|
* _.size({ 'a': 1, 'b': 2 });
|
|
* // => 2
|
|
*
|
|
* _.size('pebbles');
|
|
* // => 7
|
|
*/
|
|
function size(collection) {
|
|
if (collection == null) {
|
|
return 0;
|
|
}
|
|
if (isArrayLike(collection)) {
|
|
return isString(collection) ? stringSize(collection) : collection.length;
|
|
}
|
|
var tag = getTag(collection);
|
|
if (tag == mapTag || tag == setTag) {
|
|
return collection.size;
|
|
}
|
|
return baseKeys(collection).length;
|
|
}
|
|
|
|
/**
|
|
* Checks if `predicate` returns truthy for **any** element of `collection`.
|
|
* Iteration is stopped once `predicate` returns truthy. The predicate is
|
|
* invoked with three arguments: (value, index|key, collection).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.some([null, 0, 'yes', false], Boolean);
|
|
* // => true
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false }
|
|
* ];
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.some(users, { 'user': 'barney', 'active': false });
|
|
* // => false
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.some(users, ['active', false]);
|
|
* // => true
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.some(users, 'active');
|
|
* // => true
|
|
*/
|
|
function some(collection, predicate, guard) {
|
|
var func = isArray(collection) ? arraySome : baseSome;
|
|
if (guard && isIterateeCall(collection, predicate, guard)) {
|
|
predicate = undefined;
|
|
}
|
|
return func(collection, getIteratee(predicate, 3));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of elements, sorted in ascending order by the results of
|
|
* running each element in a collection thru each iteratee. This method
|
|
* performs a stable sort, that is, it preserves the original sort order of
|
|
* equal elements. The iteratees are invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {...(Function|Function[])} [iteratees=[_.identity]]
|
|
* The iteratees to sort by.
|
|
* @returns {Array} Returns the new sorted array.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'fred', 'age': 48 },
|
|
* { 'user': 'barney', 'age': 36 },
|
|
* { 'user': 'fred', 'age': 40 },
|
|
* { 'user': 'barney', 'age': 34 }
|
|
* ];
|
|
*
|
|
* _.sortBy(users, [function(o) { return o.user; }]);
|
|
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
|
|
*
|
|
* _.sortBy(users, ['user', 'age']);
|
|
* // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
|
|
*/
|
|
var sortBy = baseRest(function(collection, iteratees) {
|
|
if (collection == null) {
|
|
return [];
|
|
}
|
|
var length = iteratees.length;
|
|
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
|
|
iteratees = [];
|
|
} else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
|
|
iteratees = [iteratees[0]];
|
|
}
|
|
return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
|
|
});
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Gets the timestamp of the number of milliseconds that have elapsed since
|
|
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Date
|
|
* @returns {number} Returns the timestamp.
|
|
* @example
|
|
*
|
|
* _.defer(function(stamp) {
|
|
* console.log(_.now() - stamp);
|
|
* }, _.now());
|
|
* // => Logs the number of milliseconds it took for the deferred invocation.
|
|
*/
|
|
var now = ctxNow || function() {
|
|
return root.Date.now();
|
|
};
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* The opposite of `_.before`; this method creates a function that invokes
|
|
* `func` once it's called `n` or more times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {number} n The number of calls before `func` is invoked.
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new restricted function.
|
|
* @example
|
|
*
|
|
* var saves = ['profile', 'settings'];
|
|
*
|
|
* var done = _.after(saves.length, function() {
|
|
* console.log('done saving!');
|
|
* });
|
|
*
|
|
* _.forEach(saves, function(type) {
|
|
* asyncSave({ 'type': type, 'complete': done });
|
|
* });
|
|
* // => Logs 'done saving!' after the two async saves have completed.
|
|
*/
|
|
function after(n, func) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
n = toInteger(n);
|
|
return function() {
|
|
if (--n < 1) {
|
|
return func.apply(this, arguments);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func`, with up to `n` arguments,
|
|
* ignoring any additional arguments.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to cap arguments for.
|
|
* @param {number} [n=func.length] The arity cap.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the new capped function.
|
|
* @example
|
|
*
|
|
* _.map(['6', '8', '10'], _.ary(parseInt, 1));
|
|
* // => [6, 8, 10]
|
|
*/
|
|
function ary(func, n, guard) {
|
|
n = guard ? undefined : n;
|
|
n = (func && n == null) ? func.length : n;
|
|
return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func`, with the `this` binding and arguments
|
|
* of the created function, while it's called less than `n` times. Subsequent
|
|
* calls to the created function return the result of the last `func` invocation.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {number} n The number of calls at which `func` is no longer invoked.
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new restricted function.
|
|
* @example
|
|
*
|
|
* jQuery(element).on('click', _.before(5, addContactToList));
|
|
* // => Allows adding up to 4 contacts to the list.
|
|
*/
|
|
function before(n, func) {
|
|
var result;
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
n = toInteger(n);
|
|
return function() {
|
|
if (--n > 0) {
|
|
result = func.apply(this, arguments);
|
|
}
|
|
if (n <= 1) {
|
|
func = undefined;
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of `thisArg`
|
|
* and `partials` prepended to the arguments it receives.
|
|
*
|
|
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
|
|
* may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
|
|
* property of bound functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to bind.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new bound function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, punctuation) {
|
|
* return greeting + ' ' + this.user + punctuation;
|
|
* }
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
*
|
|
* var bound = _.bind(greet, object, 'hi');
|
|
* bound('!');
|
|
* // => 'hi fred!'
|
|
*
|
|
* // Bound with placeholders.
|
|
* var bound = _.bind(greet, object, _, '!');
|
|
* bound('hi');
|
|
* // => 'hi fred!'
|
|
*/
|
|
var bind = baseRest(function(func, thisArg, partials) {
|
|
var bitmask = WRAP_BIND_FLAG;
|
|
if (partials.length) {
|
|
var holders = replaceHolders(partials, getHolder(bind));
|
|
bitmask |= WRAP_PARTIAL_FLAG;
|
|
}
|
|
return createWrap(func, bitmask, thisArg, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes the method at `object[key]` with `partials`
|
|
* prepended to the arguments it receives.
|
|
*
|
|
* This method differs from `_.bind` by allowing bound functions to reference
|
|
* methods that may be redefined or don't yet exist. See
|
|
* [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
|
|
* for more details.
|
|
*
|
|
* The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.10.0
|
|
* @category Function
|
|
* @param {Object} object The object to invoke the method on.
|
|
* @param {string} key The key of the method.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new bound function.
|
|
* @example
|
|
*
|
|
* var object = {
|
|
* 'user': 'fred',
|
|
* 'greet': function(greeting, punctuation) {
|
|
* return greeting + ' ' + this.user + punctuation;
|
|
* }
|
|
* };
|
|
*
|
|
* var bound = _.bindKey(object, 'greet', 'hi');
|
|
* bound('!');
|
|
* // => 'hi fred!'
|
|
*
|
|
* object.greet = function(greeting, punctuation) {
|
|
* return greeting + 'ya ' + this.user + punctuation;
|
|
* };
|
|
*
|
|
* bound('!');
|
|
* // => 'hiya fred!'
|
|
*
|
|
* // Bound with placeholders.
|
|
* var bound = _.bindKey(object, 'greet', _, '!');
|
|
* bound('hi');
|
|
* // => 'hiya fred!'
|
|
*/
|
|
var bindKey = baseRest(function(object, key, partials) {
|
|
var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
|
|
if (partials.length) {
|
|
var holders = replaceHolders(partials, getHolder(bindKey));
|
|
bitmask |= WRAP_PARTIAL_FLAG;
|
|
}
|
|
return createWrap(key, bitmask, object, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that accepts arguments of `func` and either invokes
|
|
* `func` returning its result, if at least `arity` number of arguments have
|
|
* been provided, or returns a function that accepts the remaining `func`
|
|
* arguments, and so on. The arity of `func` may be specified if `func.length`
|
|
* is not sufficient.
|
|
*
|
|
* The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
|
|
* may be used as a placeholder for provided arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of curried functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to curry.
|
|
* @param {number} [arity=func.length] The arity of `func`.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the new curried function.
|
|
* @example
|
|
*
|
|
* var abc = function(a, b, c) {
|
|
* return [a, b, c];
|
|
* };
|
|
*
|
|
* var curried = _.curry(abc);
|
|
*
|
|
* curried(1)(2)(3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(1, 2)(3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(1, 2, 3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* // Curried with placeholders.
|
|
* curried(1)(_, 3)(2);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function curry(func, arity, guard) {
|
|
arity = guard ? undefined : arity;
|
|
var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
|
|
result.placeholder = curry.placeholder;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.curry` except that arguments are applied to `func`
|
|
* in the manner of `_.partialRight` instead of `_.partial`.
|
|
*
|
|
* The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for provided arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of curried functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to curry.
|
|
* @param {number} [arity=func.length] The arity of `func`.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the new curried function.
|
|
* @example
|
|
*
|
|
* var abc = function(a, b, c) {
|
|
* return [a, b, c];
|
|
* };
|
|
*
|
|
* var curried = _.curryRight(abc);
|
|
*
|
|
* curried(3)(2)(1);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(2, 3)(1);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(1, 2, 3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* // Curried with placeholders.
|
|
* curried(3)(1, _)(2);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function curryRight(func, arity, guard) {
|
|
arity = guard ? undefined : arity;
|
|
var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
|
|
result.placeholder = curryRight.placeholder;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a debounced function that delays invoking `func` until after `wait`
|
|
* milliseconds have elapsed since the last time the debounced function was
|
|
* invoked. The debounced function comes with a `cancel` method to cancel
|
|
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
|
* Provide `options` to indicate whether `func` should be invoked on the
|
|
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
|
* with the last arguments provided to the debounced function. Subsequent
|
|
* calls to the debounced function return the result of the last `func`
|
|
* invocation.
|
|
*
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
* invoked on the trailing edge of the timeout only if the debounced function
|
|
* is invoked more than once during the `wait` timeout.
|
|
*
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
*
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
* for details over the differences between `_.debounce` and `_.throttle`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to debounce.
|
|
* @param {number} [wait=0] The number of milliseconds to delay.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {boolean} [options.leading=false]
|
|
* Specify invoking on the leading edge of the timeout.
|
|
* @param {number} [options.maxWait]
|
|
* The maximum time `func` is allowed to be delayed before it's invoked.
|
|
* @param {boolean} [options.trailing=true]
|
|
* Specify invoking on the trailing edge of the timeout.
|
|
* @returns {Function} Returns the new debounced function.
|
|
* @example
|
|
*
|
|
* // Avoid costly calculations while the window size is in flux.
|
|
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
|
*
|
|
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
|
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
|
* 'leading': true,
|
|
* 'trailing': false
|
|
* }));
|
|
*
|
|
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
|
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
|
* var source = new EventSource('/stream');
|
|
* jQuery(source).on('message', debounced);
|
|
*
|
|
* // Cancel the trailing debounced invocation.
|
|
* jQuery(window).on('popstate', debounced.cancel);
|
|
*/
|
|
function debounce(func, wait, options) {
|
|
var lastArgs,
|
|
lastThis,
|
|
maxWait,
|
|
result,
|
|
timerId,
|
|
lastCallTime,
|
|
lastInvokeTime = 0,
|
|
leading = false,
|
|
maxing = false,
|
|
trailing = true;
|
|
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
wait = toNumber(wait) || 0;
|
|
if (isObject(options)) {
|
|
leading = !!options.leading;
|
|
maxing = 'maxWait' in options;
|
|
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|
}
|
|
|
|
function invokeFunc(time) {
|
|
var args = lastArgs,
|
|
thisArg = lastThis;
|
|
|
|
lastArgs = lastThis = undefined;
|
|
lastInvokeTime = time;
|
|
result = func.apply(thisArg, args);
|
|
return result;
|
|
}
|
|
|
|
function leadingEdge(time) {
|
|
// Reset any `maxWait` timer.
|
|
lastInvokeTime = time;
|
|
// Start the timer for the trailing edge.
|
|
timerId = setTimeout(timerExpired, wait);
|
|
// Invoke the leading edge.
|
|
return leading ? invokeFunc(time) : result;
|
|
}
|
|
|
|
function remainingWait(time) {
|
|
var timeSinceLastCall = time - lastCallTime,
|
|
timeSinceLastInvoke = time - lastInvokeTime,
|
|
timeWaiting = wait - timeSinceLastCall;
|
|
|
|
return maxing
|
|
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
|
|
: timeWaiting;
|
|
}
|
|
|
|
function shouldInvoke(time) {
|
|
var timeSinceLastCall = time - lastCallTime,
|
|
timeSinceLastInvoke = time - lastInvokeTime;
|
|
|
|
// Either this is the first call, activity has stopped and we're at the
|
|
// trailing edge, the system time has gone backwards and we're treating
|
|
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
|
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
|
}
|
|
|
|
function timerExpired() {
|
|
var time = now();
|
|
if (shouldInvoke(time)) {
|
|
return trailingEdge(time);
|
|
}
|
|
// Restart the timer.
|
|
timerId = setTimeout(timerExpired, remainingWait(time));
|
|
}
|
|
|
|
function trailingEdge(time) {
|
|
timerId = undefined;
|
|
|
|
// Only invoke if we have `lastArgs` which means `func` has been
|
|
// debounced at least once.
|
|
if (trailing && lastArgs) {
|
|
return invokeFunc(time);
|
|
}
|
|
lastArgs = lastThis = undefined;
|
|
return result;
|
|
}
|
|
|
|
function cancel() {
|
|
if (timerId !== undefined) {
|
|
clearTimeout(timerId);
|
|
}
|
|
lastInvokeTime = 0;
|
|
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
|
}
|
|
|
|
function flush() {
|
|
return timerId === undefined ? result : trailingEdge(now());
|
|
}
|
|
|
|
function debounced() {
|
|
var time = now(),
|
|
isInvoking = shouldInvoke(time);
|
|
|
|
lastArgs = arguments;
|
|
lastThis = this;
|
|
lastCallTime = time;
|
|
|
|
if (isInvoking) {
|
|
if (timerId === undefined) {
|
|
return leadingEdge(lastCallTime);
|
|
}
|
|
if (maxing) {
|
|
// Handle invocations in a tight loop.
|
|
clearTimeout(timerId);
|
|
timerId = setTimeout(timerExpired, wait);
|
|
return invokeFunc(lastCallTime);
|
|
}
|
|
}
|
|
if (timerId === undefined) {
|
|
timerId = setTimeout(timerExpired, wait);
|
|
}
|
|
return result;
|
|
}
|
|
debounced.cancel = cancel;
|
|
debounced.flush = flush;
|
|
return debounced;
|
|
}
|
|
|
|
/**
|
|
* Defers invoking the `func` until the current call stack has cleared. Any
|
|
* additional arguments are provided to `func` when it's invoked.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to defer.
|
|
* @param {...*} [args] The arguments to invoke `func` with.
|
|
* @returns {number} Returns the timer id.
|
|
* @example
|
|
*
|
|
* _.defer(function(text) {
|
|
* console.log(text);
|
|
* }, 'deferred');
|
|
* // => Logs 'deferred' after one millisecond.
|
|
*/
|
|
var defer = baseRest(function(func, args) {
|
|
return baseDelay(func, 1, args);
|
|
});
|
|
|
|
/**
|
|
* Invokes `func` after `wait` milliseconds. Any additional arguments are
|
|
* provided to `func` when it's invoked.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to delay.
|
|
* @param {number} wait The number of milliseconds to delay invocation.
|
|
* @param {...*} [args] The arguments to invoke `func` with.
|
|
* @returns {number} Returns the timer id.
|
|
* @example
|
|
*
|
|
* _.delay(function(text) {
|
|
* console.log(text);
|
|
* }, 1000, 'later');
|
|
* // => Logs 'later' after one second.
|
|
*/
|
|
var delay = baseRest(function(func, wait, args) {
|
|
return baseDelay(func, toNumber(wait) || 0, args);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with arguments reversed.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to flip arguments for.
|
|
* @returns {Function} Returns the new flipped function.
|
|
* @example
|
|
*
|
|
* var flipped = _.flip(function() {
|
|
* return _.toArray(arguments);
|
|
* });
|
|
*
|
|
* flipped('a', 'b', 'c', 'd');
|
|
* // => ['d', 'c', 'b', 'a']
|
|
*/
|
|
function flip(func) {
|
|
return createWrap(func, WRAP_FLIP_FLAG);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that memoizes the result of `func`. If `resolver` is
|
|
* provided, it determines the cache key for storing the result based on the
|
|
* arguments provided to the memoized function. By default, the first argument
|
|
* provided to the memoized function is used as the map cache key. The `func`
|
|
* is invoked with the `this` binding of the memoized function.
|
|
*
|
|
* **Note:** The cache is exposed as the `cache` property on the memoized
|
|
* function. Its creation may be customized by replacing the `_.memoize.Cache`
|
|
* constructor with one whose instances implement the
|
|
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
|
|
* method interface of `clear`, `delete`, `get`, `has`, and `set`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to have its output memoized.
|
|
* @param {Function} [resolver] The function to resolve the cache key.
|
|
* @returns {Function} Returns the new memoized function.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2 };
|
|
* var other = { 'c': 3, 'd': 4 };
|
|
*
|
|
* var values = _.memoize(_.values);
|
|
* values(object);
|
|
* // => [1, 2]
|
|
*
|
|
* values(other);
|
|
* // => [3, 4]
|
|
*
|
|
* object.a = 2;
|
|
* values(object);
|
|
* // => [1, 2]
|
|
*
|
|
* // Modify the result cache.
|
|
* values.cache.set(object, ['a', 'b']);
|
|
* values(object);
|
|
* // => ['a', 'b']
|
|
*
|
|
* // Replace `_.memoize.Cache`.
|
|
* _.memoize.Cache = WeakMap;
|
|
*/
|
|
function memoize(func, resolver) {
|
|
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
var memoized = function() {
|
|
var args = arguments,
|
|
key = resolver ? resolver.apply(this, args) : args[0],
|
|
cache = memoized.cache;
|
|
|
|
if (cache.has(key)) {
|
|
return cache.get(key);
|
|
}
|
|
var result = func.apply(this, args);
|
|
memoized.cache = cache.set(key, result) || cache;
|
|
return result;
|
|
};
|
|
memoized.cache = new (memoize.Cache || MapCache);
|
|
return memoized;
|
|
}
|
|
|
|
// Expose `MapCache`.
|
|
memoize.Cache = MapCache;
|
|
|
|
/**
|
|
* Creates a function that negates the result of the predicate `func`. The
|
|
* `func` predicate is invoked with the `this` binding and arguments of the
|
|
* created function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} predicate The predicate to negate.
|
|
* @returns {Function} Returns the new negated function.
|
|
* @example
|
|
*
|
|
* function isEven(n) {
|
|
* return n % 2 == 0;
|
|
* }
|
|
*
|
|
* _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
|
|
* // => [1, 3, 5]
|
|
*/
|
|
function negate(predicate) {
|
|
if (typeof predicate != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
return function() {
|
|
var args = arguments;
|
|
switch (args.length) {
|
|
case 0: return !predicate.call(this);
|
|
case 1: return !predicate.call(this, args[0]);
|
|
case 2: return !predicate.call(this, args[0], args[1]);
|
|
case 3: return !predicate.call(this, args[0], args[1], args[2]);
|
|
}
|
|
return !predicate.apply(this, args);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that is restricted to invoking `func` once. Repeat calls
|
|
* to the function return the value of the first invocation. The `func` is
|
|
* invoked with the `this` binding and arguments of the created function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new restricted function.
|
|
* @example
|
|
*
|
|
* var initialize = _.once(createApplication);
|
|
* initialize();
|
|
* initialize();
|
|
* // => `createApplication` is invoked once
|
|
*/
|
|
function once(func) {
|
|
return before(2, func);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with its arguments transformed.
|
|
*
|
|
* @static
|
|
* @since 4.0.0
|
|
* @memberOf _
|
|
* @category Function
|
|
* @param {Function} func The function to wrap.
|
|
* @param {...(Function|Function[])} [transforms=[_.identity]]
|
|
* The argument transforms.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* function doubled(n) {
|
|
* return n * 2;
|
|
* }
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var func = _.overArgs(function(x, y) {
|
|
* return [x, y];
|
|
* }, [square, doubled]);
|
|
*
|
|
* func(9, 3);
|
|
* // => [81, 6]
|
|
*
|
|
* func(10, 5);
|
|
* // => [100, 10]
|
|
*/
|
|
var overArgs = castRest(function(func, transforms) {
|
|
transforms = (transforms.length == 1 && isArray(transforms[0]))
|
|
? arrayMap(transforms[0], baseUnary(getIteratee()))
|
|
: arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
|
|
|
|
var funcsLength = transforms.length;
|
|
return baseRest(function(args) {
|
|
var index = -1,
|
|
length = nativeMin(args.length, funcsLength);
|
|
|
|
while (++index < length) {
|
|
args[index] = transforms[index].call(this, args[index]);
|
|
}
|
|
return apply(func, this, args);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with `partials` prepended to the
|
|
* arguments it receives. This method is like `_.bind` except it does **not**
|
|
* alter the `this` binding.
|
|
*
|
|
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of partially
|
|
* applied functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.2.0
|
|
* @category Function
|
|
* @param {Function} func The function to partially apply arguments to.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new partially applied function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, name) {
|
|
* return greeting + ' ' + name;
|
|
* }
|
|
*
|
|
* var sayHelloTo = _.partial(greet, 'hello');
|
|
* sayHelloTo('fred');
|
|
* // => 'hello fred'
|
|
*
|
|
* // Partially applied with placeholders.
|
|
* var greetFred = _.partial(greet, _, 'fred');
|
|
* greetFred('hi');
|
|
* // => 'hi fred'
|
|
*/
|
|
var partial = baseRest(function(func, partials) {
|
|
var holders = replaceHolders(partials, getHolder(partial));
|
|
return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.partial` except that partially applied arguments
|
|
* are appended to the arguments it receives.
|
|
*
|
|
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of partially
|
|
* applied functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to partially apply arguments to.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new partially applied function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, name) {
|
|
* return greeting + ' ' + name;
|
|
* }
|
|
*
|
|
* var greetFred = _.partialRight(greet, 'fred');
|
|
* greetFred('hi');
|
|
* // => 'hi fred'
|
|
*
|
|
* // Partially applied with placeholders.
|
|
* var sayHelloTo = _.partialRight(greet, 'hello', _);
|
|
* sayHelloTo('fred');
|
|
* // => 'hello fred'
|
|
*/
|
|
var partialRight = baseRest(function(func, partials) {
|
|
var holders = replaceHolders(partials, getHolder(partialRight));
|
|
return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with arguments arranged according
|
|
* to the specified `indexes` where the argument value at the first index is
|
|
* provided as the first argument, the argument value at the second index is
|
|
* provided as the second argument, and so on.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to rearrange arguments for.
|
|
* @param {...(number|number[])} indexes The arranged argument indexes.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var rearged = _.rearg(function(a, b, c) {
|
|
* return [a, b, c];
|
|
* }, [2, 0, 1]);
|
|
*
|
|
* rearged('b', 'c', 'a')
|
|
* // => ['a', 'b', 'c']
|
|
*/
|
|
var rearg = flatRest(function(func, indexes) {
|
|
return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* created function and arguments from `start` and beyond provided as
|
|
* an array.
|
|
*
|
|
* **Note:** This method is based on the
|
|
* [rest parameter](https://mdn.io/rest_parameters).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.rest(function(what, names) {
|
|
* return what + ' ' + _.initial(names).join(', ') +
|
|
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
|
* });
|
|
*
|
|
* say('hello', 'fred', 'barney', 'pebbles');
|
|
* // => 'hello fred, barney, & pebbles'
|
|
*/
|
|
function rest(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = start === undefined ? start : toInteger(start);
|
|
return baseRest(func, start);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* create function and an array of arguments much like
|
|
* [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
|
|
*
|
|
* **Note:** This method is based on the
|
|
* [spread operator](https://mdn.io/spread_operator).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Function
|
|
* @param {Function} func The function to spread arguments over.
|
|
* @param {number} [start=0] The start position of the spread.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.spread(function(who, what) {
|
|
* return who + ' says ' + what;
|
|
* });
|
|
*
|
|
* say(['fred', 'hello']);
|
|
* // => 'fred says hello'
|
|
*
|
|
* var numbers = Promise.all([
|
|
* Promise.resolve(40),
|
|
* Promise.resolve(36)
|
|
* ]);
|
|
*
|
|
* numbers.then(_.spread(function(x, y) {
|
|
* return x + y;
|
|
* }));
|
|
* // => a Promise of 76
|
|
*/
|
|
function spread(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = start == null ? 0 : nativeMax(toInteger(start), 0);
|
|
return baseRest(function(args) {
|
|
var array = args[start],
|
|
otherArgs = castSlice(args, 0, start);
|
|
|
|
if (array) {
|
|
arrayPush(otherArgs, array);
|
|
}
|
|
return apply(func, this, otherArgs);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a throttled function that only invokes `func` at most once per
|
|
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
|
* method to cancel delayed `func` invocations and a `flush` method to
|
|
* immediately invoke them. Provide `options` to indicate whether `func`
|
|
* should be invoked on the leading and/or trailing edge of the `wait`
|
|
* timeout. The `func` is invoked with the last arguments provided to the
|
|
* throttled function. Subsequent calls to the throttled function return the
|
|
* result of the last `func` invocation.
|
|
*
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
* invoked on the trailing edge of the timeout only if the throttled function
|
|
* is invoked more than once during the `wait` timeout.
|
|
*
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
*
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
* for details over the differences between `_.throttle` and `_.debounce`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to throttle.
|
|
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {boolean} [options.leading=true]
|
|
* Specify invoking on the leading edge of the timeout.
|
|
* @param {boolean} [options.trailing=true]
|
|
* Specify invoking on the trailing edge of the timeout.
|
|
* @returns {Function} Returns the new throttled function.
|
|
* @example
|
|
*
|
|
* // Avoid excessively updating the position while scrolling.
|
|
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
|
|
*
|
|
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
|
|
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
|
|
* jQuery(element).on('click', throttled);
|
|
*
|
|
* // Cancel the trailing throttled invocation.
|
|
* jQuery(window).on('popstate', throttled.cancel);
|
|
*/
|
|
function throttle(func, wait, options) {
|
|
var leading = true,
|
|
trailing = true;
|
|
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
if (isObject(options)) {
|
|
leading = 'leading' in options ? !!options.leading : leading;
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|
}
|
|
return debounce(func, wait, {
|
|
'leading': leading,
|
|
'maxWait': wait,
|
|
'trailing': trailing
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that accepts up to one argument, ignoring any
|
|
* additional arguments.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to cap arguments for.
|
|
* @returns {Function} Returns the new capped function.
|
|
* @example
|
|
*
|
|
* _.map(['6', '8', '10'], _.unary(parseInt));
|
|
* // => [6, 8, 10]
|
|
*/
|
|
function unary(func) {
|
|
return ary(func, 1);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that provides `value` to `wrapper` as its first
|
|
* argument. Any additional arguments provided to the function are appended
|
|
* to those provided to the `wrapper`. The wrapper is invoked with the `this`
|
|
* binding of the created function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {*} value The value to wrap.
|
|
* @param {Function} [wrapper=identity] The wrapper function.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var p = _.wrap(_.escape, function(func, text) {
|
|
* return '<p>' + func(text) + '</p>';
|
|
* });
|
|
*
|
|
* p('fred, barney, & pebbles');
|
|
* // => '<p>fred, barney, & pebbles</p>'
|
|
*/
|
|
function wrap(value, wrapper) {
|
|
return partial(castFunction(wrapper), value);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Casts `value` as an array if it's not one.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.4.0
|
|
* @category Lang
|
|
* @param {*} value The value to inspect.
|
|
* @returns {Array} Returns the cast array.
|
|
* @example
|
|
*
|
|
* _.castArray(1);
|
|
* // => [1]
|
|
*
|
|
* _.castArray({ 'a': 1 });
|
|
* // => [{ 'a': 1 }]
|
|
*
|
|
* _.castArray('abc');
|
|
* // => ['abc']
|
|
*
|
|
* _.castArray(null);
|
|
* // => [null]
|
|
*
|
|
* _.castArray(undefined);
|
|
* // => [undefined]
|
|
*
|
|
* _.castArray();
|
|
* // => []
|
|
*
|
|
* var array = [1, 2, 3];
|
|
* console.log(_.castArray(array) === array);
|
|
* // => true
|
|
*/
|
|
function castArray() {
|
|
if (!arguments.length) {
|
|
return [];
|
|
}
|
|
var value = arguments[0];
|
|
return isArray(value) ? value : [value];
|
|
}
|
|
|
|
/**
|
|
* Creates a shallow clone of `value`.
|
|
*
|
|
* **Note:** This method is loosely based on the
|
|
* [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
|
|
* and supports cloning arrays, array buffers, booleans, date objects, maps,
|
|
* numbers, `Object` objects, regexes, sets, strings, symbols, and typed
|
|
* arrays. The own enumerable properties of `arguments` objects are cloned
|
|
* as plain objects. An empty object is returned for uncloneable values such
|
|
* as error objects, functions, DOM nodes, and WeakMaps.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to clone.
|
|
* @returns {*} Returns the cloned value.
|
|
* @see _.cloneDeep
|
|
* @example
|
|
*
|
|
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
|
*
|
|
* var shallow = _.clone(objects);
|
|
* console.log(shallow[0] === objects[0]);
|
|
* // => true
|
|
*/
|
|
function clone(value) {
|
|
return baseClone(value, CLONE_SYMBOLS_FLAG);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.clone` except that it accepts `customizer` which
|
|
* is invoked to produce the cloned value. If `customizer` returns `undefined`,
|
|
* cloning is handled by the method instead. The `customizer` is invoked with
|
|
* up to four arguments; (value [, index|key, object, stack]).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to clone.
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @returns {*} Returns the cloned value.
|
|
* @see _.cloneDeepWith
|
|
* @example
|
|
*
|
|
* function customizer(value) {
|
|
* if (_.isElement(value)) {
|
|
* return value.cloneNode(false);
|
|
* }
|
|
* }
|
|
*
|
|
* var el = _.cloneWith(document.body, customizer);
|
|
*
|
|
* console.log(el === document.body);
|
|
* // => false
|
|
* console.log(el.nodeName);
|
|
* // => 'BODY'
|
|
* console.log(el.childNodes.length);
|
|
* // => 0
|
|
*/
|
|
function cloneWith(value, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.clone` except that it recursively clones `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to recursively clone.
|
|
* @returns {*} Returns the deep cloned value.
|
|
* @see _.clone
|
|
* @example
|
|
*
|
|
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
|
*
|
|
* var deep = _.cloneDeep(objects);
|
|
* console.log(deep[0] === objects[0]);
|
|
* // => false
|
|
*/
|
|
function cloneDeep(value) {
|
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.cloneWith` except that it recursively clones `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to recursively clone.
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @returns {*} Returns the deep cloned value.
|
|
* @see _.cloneWith
|
|
* @example
|
|
*
|
|
* function customizer(value) {
|
|
* if (_.isElement(value)) {
|
|
* return value.cloneNode(true);
|
|
* }
|
|
* }
|
|
*
|
|
* var el = _.cloneDeepWith(document.body, customizer);
|
|
*
|
|
* console.log(el === document.body);
|
|
* // => false
|
|
* console.log(el.nodeName);
|
|
* // => 'BODY'
|
|
* console.log(el.childNodes.length);
|
|
* // => 20
|
|
*/
|
|
function cloneDeepWith(value, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
|
|
}
|
|
|
|
/**
|
|
* Checks if `object` conforms to `source` by invoking the predicate
|
|
* properties of `source` with the corresponding property values of `object`.
|
|
*
|
|
* **Note:** This method is equivalent to `_.conforms` when `source` is
|
|
* partially applied.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.14.0
|
|
* @category Lang
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2 };
|
|
*
|
|
* _.conformsTo(object, { 'b': function(n) { return n > 1; } });
|
|
* // => true
|
|
*
|
|
* _.conformsTo(object, { 'b': function(n) { return n > 2; } });
|
|
* // => false
|
|
*/
|
|
function conformsTo(object, source) {
|
|
return source == null || baseConformsTo(object, source, keys(source));
|
|
}
|
|
|
|
/**
|
|
* Performs a
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* comparison between two values to determine if they are equivalent.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
* var other = { 'a': 1 };
|
|
*
|
|
* _.eq(object, object);
|
|
* // => true
|
|
*
|
|
* _.eq(object, other);
|
|
* // => false
|
|
*
|
|
* _.eq('a', 'a');
|
|
* // => true
|
|
*
|
|
* _.eq('a', Object('a'));
|
|
* // => false
|
|
*
|
|
* _.eq(NaN, NaN);
|
|
* // => true
|
|
*/
|
|
function eq(value, other) {
|
|
return value === other || (value !== value && other !== other);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is greater than `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is greater than `other`,
|
|
* else `false`.
|
|
* @see _.lt
|
|
* @example
|
|
*
|
|
* _.gt(3, 1);
|
|
* // => true
|
|
*
|
|
* _.gt(3, 3);
|
|
* // => false
|
|
*
|
|
* _.gt(1, 3);
|
|
* // => false
|
|
*/
|
|
var gt = createRelationalOperation(baseGt);
|
|
|
|
/**
|
|
* Checks if `value` is greater than or equal to `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is greater than or equal to
|
|
* `other`, else `false`.
|
|
* @see _.lte
|
|
* @example
|
|
*
|
|
* _.gte(3, 1);
|
|
* // => true
|
|
*
|
|
* _.gte(3, 3);
|
|
* // => true
|
|
*
|
|
* _.gte(1, 3);
|
|
* // => false
|
|
*/
|
|
var gte = createRelationalOperation(function(value, other) {
|
|
return value >= other;
|
|
});
|
|
|
|
/**
|
|
* Checks if `value` is likely an `arguments` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.isArguments(function() { return arguments; }());
|
|
* // => true
|
|
*
|
|
* _.isArguments([1, 2, 3]);
|
|
* // => false
|
|
*/
|
|
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
|
return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
|
|
!propertyIsEnumerable.call(value, 'callee');
|
|
};
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `Array` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArray([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArray(document.body.children);
|
|
* // => false
|
|
*
|
|
* _.isArray('abc');
|
|
* // => false
|
|
*
|
|
* _.isArray(_.noop);
|
|
* // => false
|
|
*/
|
|
var isArray = Array.isArray;
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `ArrayBuffer` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayBuffer(new ArrayBuffer(2));
|
|
* // => true
|
|
*
|
|
* _.isArrayBuffer(new Array(2));
|
|
* // => false
|
|
*/
|
|
var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
|
|
|
|
/**
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArrayLike(document.body.children);
|
|
* // => true
|
|
*
|
|
* _.isArrayLike('abc');
|
|
* // => true
|
|
*
|
|
* _.isArrayLike(_.noop);
|
|
* // => false
|
|
*/
|
|
function isArrayLike(value) {
|
|
return value != null && isLength(value.length) && !isFunction(value);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|
* is an object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayLikeObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArrayLikeObject(document.body.children);
|
|
* // => true
|
|
*
|
|
* _.isArrayLikeObject('abc');
|
|
* // => false
|
|
*
|
|
* _.isArrayLikeObject(_.noop);
|
|
* // => false
|
|
*/
|
|
function isArrayLikeObject(value) {
|
|
return isObjectLike(value) && isArrayLike(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a boolean primitive or object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
|
|
* @example
|
|
*
|
|
* _.isBoolean(false);
|
|
* // => true
|
|
*
|
|
* _.isBoolean(null);
|
|
* // => false
|
|
*/
|
|
function isBoolean(value) {
|
|
return value === true || value === false ||
|
|
(isObjectLike(value) && baseGetTag(value) == boolTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a buffer.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isBuffer(new Buffer(2));
|
|
* // => true
|
|
*
|
|
* _.isBuffer(new Uint8Array(2));
|
|
* // => false
|
|
*/
|
|
var isBuffer = nativeIsBuffer || stubFalse;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Date` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a date object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isDate(new Date);
|
|
* // => true
|
|
*
|
|
* _.isDate('Mon April 23 2012');
|
|
* // => false
|
|
*/
|
|
var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
|
|
|
|
/**
|
|
* Checks if `value` is likely a DOM element.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
|
|
* @example
|
|
*
|
|
* _.isElement(document.body);
|
|
* // => true
|
|
*
|
|
* _.isElement('<body>');
|
|
* // => false
|
|
*/
|
|
function isElement(value) {
|
|
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is an empty object, collection, map, or set.
|
|
*
|
|
* Objects are considered empty if they have no own enumerable string keyed
|
|
* properties.
|
|
*
|
|
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
|
|
* jQuery-like collections are considered empty if they have a `length` of `0`.
|
|
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
|
|
* @example
|
|
*
|
|
* _.isEmpty(null);
|
|
* // => true
|
|
*
|
|
* _.isEmpty(true);
|
|
* // => true
|
|
*
|
|
* _.isEmpty(1);
|
|
* // => true
|
|
*
|
|
* _.isEmpty([1, 2, 3]);
|
|
* // => false
|
|
*
|
|
* _.isEmpty({ 'a': 1 });
|
|
* // => false
|
|
*/
|
|
function isEmpty(value) {
|
|
if (value == null) {
|
|
return true;
|
|
}
|
|
if (isArrayLike(value) &&
|
|
(isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
|
|
isBuffer(value) || isTypedArray(value) || isArguments(value))) {
|
|
return !value.length;
|
|
}
|
|
var tag = getTag(value);
|
|
if (tag == mapTag || tag == setTag) {
|
|
return !value.size;
|
|
}
|
|
if (isPrototype(value)) {
|
|
return !baseKeys(value).length;
|
|
}
|
|
for (var key in value) {
|
|
if (hasOwnProperty.call(value, key)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Performs a deep comparison between two values to determine if they are
|
|
* equivalent.
|
|
*
|
|
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
|
* date objects, error objects, maps, numbers, `Object` objects, regexes,
|
|
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
|
* by their own, not inherited, enumerable properties. Functions and DOM
|
|
* nodes are compared by strict equality, i.e. `===`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
* var other = { 'a': 1 };
|
|
*
|
|
* _.isEqual(object, other);
|
|
* // => true
|
|
*
|
|
* object === other;
|
|
* // => false
|
|
*/
|
|
function isEqual(value, other) {
|
|
return baseIsEqual(value, other);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.isEqual` except that it accepts `customizer` which
|
|
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
* are handled by the method instead. The `customizer` is invoked with up to
|
|
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* function isGreeting(value) {
|
|
* return /^h(?:i|ello)$/.test(value);
|
|
* }
|
|
*
|
|
* function customizer(objValue, othValue) {
|
|
* if (isGreeting(objValue) && isGreeting(othValue)) {
|
|
* return true;
|
|
* }
|
|
* }
|
|
*
|
|
* var array = ['hello', 'goodbye'];
|
|
* var other = ['hi', 'goodbye'];
|
|
*
|
|
* _.isEqualWith(array, other, customizer);
|
|
* // => true
|
|
*/
|
|
function isEqualWith(value, other, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
var result = customizer ? customizer(value, other) : undefined;
|
|
return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
|
|
* `SyntaxError`, `TypeError`, or `URIError` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isError(new Error);
|
|
* // => true
|
|
*
|
|
* _.isError(Error);
|
|
* // => false
|
|
*/
|
|
function isError(value) {
|
|
if (!isObjectLike(value)) {
|
|
return false;
|
|
}
|
|
var tag = baseGetTag(value);
|
|
return tag == errorTag || tag == domExcTag ||
|
|
(typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a finite primitive number.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isFinite`](https://mdn.io/Number/isFinite).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFinite(3);
|
|
* // => true
|
|
*
|
|
* _.isFinite(Number.MIN_VALUE);
|
|
* // => true
|
|
*
|
|
* _.isFinite(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isFinite('3');
|
|
* // => false
|
|
*/
|
|
function isFinite(value) {
|
|
return typeof value == 'number' && nativeIsFinite(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Function` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFunction(_);
|
|
* // => true
|
|
*
|
|
* _.isFunction(/abc/);
|
|
* // => false
|
|
*/
|
|
function isFunction(value) {
|
|
if (!isObject(value)) {
|
|
return false;
|
|
}
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
// in Safari 9 which returns 'object' for typed arrays and other constructors.
|
|
var tag = baseGetTag(value);
|
|
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is an integer.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isInteger`](https://mdn.io/Number/isInteger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an integer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isInteger(3);
|
|
* // => true
|
|
*
|
|
* _.isInteger(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isInteger(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isInteger('3');
|
|
* // => false
|
|
*/
|
|
function isInteger(value) {
|
|
return typeof value == 'number' && value == toInteger(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like length.
|
|
*
|
|
* **Note:** This method is loosely based on
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
* @example
|
|
*
|
|
* _.isLength(3);
|
|
* // => true
|
|
*
|
|
* _.isLength(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isLength(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isLength('3');
|
|
* // => false
|
|
*/
|
|
function isLength(value) {
|
|
return typeof value == 'number' &&
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is the
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObject({});
|
|
* // => true
|
|
*
|
|
* _.isObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObject(_.noop);
|
|
* // => true
|
|
*
|
|
* _.isObject(null);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
var type = typeof value;
|
|
return value != null && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
* and has a `typeof` result of "object".
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObjectLike({});
|
|
* // => true
|
|
*
|
|
* _.isObjectLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObjectLike(_.noop);
|
|
* // => false
|
|
*
|
|
* _.isObjectLike(null);
|
|
* // => false
|
|
*/
|
|
function isObjectLike(value) {
|
|
return value != null && typeof value == 'object';
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Map` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
|
|
* @example
|
|
*
|
|
* _.isMap(new Map);
|
|
* // => true
|
|
*
|
|
* _.isMap(new WeakMap);
|
|
* // => false
|
|
*/
|
|
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
|
|
|
|
/**
|
|
* Performs a partial deep comparison between `object` and `source` to
|
|
* determine if `object` contains equivalent property values.
|
|
*
|
|
* **Note:** This method is equivalent to `_.matches` when `source` is
|
|
* partially applied.
|
|
*
|
|
* Partial comparisons will match empty array and empty object `source`
|
|
* values against any array or object value, respectively. See `_.isEqual`
|
|
* for a list of supported value comparisons.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property values to match.
|
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2 };
|
|
*
|
|
* _.isMatch(object, { 'b': 2 });
|
|
* // => true
|
|
*
|
|
* _.isMatch(object, { 'b': 1 });
|
|
* // => false
|
|
*/
|
|
function isMatch(object, source) {
|
|
return object === source || baseIsMatch(object, source, getMatchData(source));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.isMatch` except that it accepts `customizer` which
|
|
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
* are handled by the method instead. The `customizer` is invoked with five
|
|
* arguments: (objValue, srcValue, index|key, object, source).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property values to match.
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
|
* @example
|
|
*
|
|
* function isGreeting(value) {
|
|
* return /^h(?:i|ello)$/.test(value);
|
|
* }
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* if (isGreeting(objValue) && isGreeting(srcValue)) {
|
|
* return true;
|
|
* }
|
|
* }
|
|
*
|
|
* var object = { 'greeting': 'hello' };
|
|
* var source = { 'greeting': 'hi' };
|
|
*
|
|
* _.isMatchWith(object, source, customizer);
|
|
* // => true
|
|
*/
|
|
function isMatchWith(object, source, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return baseIsMatch(object, source, getMatchData(source), customizer);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is `NaN`.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
|
|
* global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
|
|
* `undefined` and other non-number values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNaN(NaN);
|
|
* // => true
|
|
*
|
|
* _.isNaN(new Number(NaN));
|
|
* // => true
|
|
*
|
|
* isNaN(undefined);
|
|
* // => true
|
|
*
|
|
* _.isNaN(undefined);
|
|
* // => false
|
|
*/
|
|
function isNaN(value) {
|
|
// An `NaN` primitive is the only value that is not equal to itself.
|
|
// Perform the `toStringTag` check first to avoid errors with some
|
|
// ActiveX objects in IE.
|
|
return isNumber(value) && value != +value;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a pristine native function.
|
|
*
|
|
* **Note:** This method can't reliably detect native functions in the presence
|
|
* of the core-js package because core-js circumvents this kind of detection.
|
|
* Despite multiple requests, the core-js maintainer has made it clear: any
|
|
* attempt to fix the detection will be obstructed. As a result, we're left
|
|
* with little choice but to throw an error. Unfortunately, this also affects
|
|
* packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
|
|
* which rely on core-js.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.isNative(Array.prototype.push);
|
|
* // => true
|
|
*
|
|
* _.isNative(_);
|
|
* // => false
|
|
*/
|
|
function isNative(value) {
|
|
if (isMaskable(value)) {
|
|
throw new Error(CORE_ERROR_TEXT);
|
|
}
|
|
return baseIsNative(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is `null`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `null`, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNull(null);
|
|
* // => true
|
|
*
|
|
* _.isNull(void 0);
|
|
* // => false
|
|
*/
|
|
function isNull(value) {
|
|
return value === null;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is `null` or `undefined`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNil(null);
|
|
* // => true
|
|
*
|
|
* _.isNil(void 0);
|
|
* // => true
|
|
*
|
|
* _.isNil(NaN);
|
|
* // => false
|
|
*/
|
|
function isNil(value) {
|
|
return value == null;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Number` primitive or object.
|
|
*
|
|
* **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
|
|
* classified as numbers, use the `_.isFinite` method.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a number, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNumber(3);
|
|
* // => true
|
|
*
|
|
* _.isNumber(Number.MIN_VALUE);
|
|
* // => true
|
|
*
|
|
* _.isNumber(Infinity);
|
|
* // => true
|
|
*
|
|
* _.isNumber('3');
|
|
* // => false
|
|
*/
|
|
function isNumber(value) {
|
|
return typeof value == 'number' ||
|
|
(isObjectLike(value) && baseGetTag(value) == numberTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a plain object, that is, an object created by the
|
|
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.8.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* _.isPlainObject(new Foo);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject([1, 2, 3]);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
* // => true
|
|
*
|
|
* _.isPlainObject(Object.create(null));
|
|
* // => true
|
|
*/
|
|
function isPlainObject(value) {
|
|
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
|
return false;
|
|
}
|
|
var proto = getPrototype(value);
|
|
if (proto === null) {
|
|
return true;
|
|
}
|
|
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
|
|
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
funcToString.call(Ctor) == objectCtorString;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `RegExp` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
|
|
* @example
|
|
*
|
|
* _.isRegExp(/abc/);
|
|
* // => true
|
|
*
|
|
* _.isRegExp('/abc/');
|
|
* // => false
|
|
*/
|
|
var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
|
|
|
|
/**
|
|
* Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
|
|
* double precision number which isn't the result of a rounded unsafe integer.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSafeInteger(3);
|
|
* // => true
|
|
*
|
|
* _.isSafeInteger(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isSafeInteger(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isSafeInteger('3');
|
|
* // => false
|
|
*/
|
|
function isSafeInteger(value) {
|
|
return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Set` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSet(new Set);
|
|
* // => true
|
|
*
|
|
* _.isSet(new WeakSet);
|
|
* // => false
|
|
*/
|
|
var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `String` primitive or object.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
|
|
* @example
|
|
*
|
|
* _.isString('abc');
|
|
* // => true
|
|
*
|
|
* _.isString(1);
|
|
* // => false
|
|
*/
|
|
function isString(value) {
|
|
return typeof value == 'string' ||
|
|
(!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSymbol(Symbol.iterator);
|
|
* // => true
|
|
*
|
|
* _.isSymbol('abc');
|
|
* // => false
|
|
*/
|
|
function isSymbol(value) {
|
|
return typeof value == 'symbol' ||
|
|
(isObjectLike(value) && baseGetTag(value) == symbolTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a typed array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
* @example
|
|
*
|
|
* _.isTypedArray(new Uint8Array);
|
|
* // => true
|
|
*
|
|
* _.isTypedArray([]);
|
|
* // => false
|
|
*/
|
|
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|
|
|
/**
|
|
* Checks if `value` is `undefined`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
|
|
* @example
|
|
*
|
|
* _.isUndefined(void 0);
|
|
* // => true
|
|
*
|
|
* _.isUndefined(null);
|
|
* // => false
|
|
*/
|
|
function isUndefined(value) {
|
|
return value === undefined;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `WeakMap` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
|
|
* @example
|
|
*
|
|
* _.isWeakMap(new WeakMap);
|
|
* // => true
|
|
*
|
|
* _.isWeakMap(new Map);
|
|
* // => false
|
|
*/
|
|
function isWeakMap(value) {
|
|
return isObjectLike(value) && getTag(value) == weakMapTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `WeakSet` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
|
|
* @example
|
|
*
|
|
* _.isWeakSet(new WeakSet);
|
|
* // => true
|
|
*
|
|
* _.isWeakSet(new Set);
|
|
* // => false
|
|
*/
|
|
function isWeakSet(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == weakSetTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is less than `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is less than `other`,
|
|
* else `false`.
|
|
* @see _.gt
|
|
* @example
|
|
*
|
|
* _.lt(1, 3);
|
|
* // => true
|
|
*
|
|
* _.lt(3, 3);
|
|
* // => false
|
|
*
|
|
* _.lt(3, 1);
|
|
* // => false
|
|
*/
|
|
var lt = createRelationalOperation(baseLt);
|
|
|
|
/**
|
|
* Checks if `value` is less than or equal to `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is less than or equal to
|
|
* `other`, else `false`.
|
|
* @see _.gte
|
|
* @example
|
|
*
|
|
* _.lte(1, 3);
|
|
* // => true
|
|
*
|
|
* _.lte(3, 3);
|
|
* // => true
|
|
*
|
|
* _.lte(3, 1);
|
|
* // => false
|
|
*/
|
|
var lte = createRelationalOperation(function(value, other) {
|
|
return value <= other;
|
|
});
|
|
|
|
/**
|
|
* Converts `value` to an array.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
* @example
|
|
*
|
|
* _.toArray({ 'a': 1, 'b': 2 });
|
|
* // => [1, 2]
|
|
*
|
|
* _.toArray('abc');
|
|
* // => ['a', 'b', 'c']
|
|
*
|
|
* _.toArray(1);
|
|
* // => []
|
|
*
|
|
* _.toArray(null);
|
|
* // => []
|
|
*/
|
|
function toArray(value) {
|
|
if (!value) {
|
|
return [];
|
|
}
|
|
if (isArrayLike(value)) {
|
|
return isString(value) ? stringToArray(value) : copyArray(value);
|
|
}
|
|
if (symIterator && value[symIterator]) {
|
|
return iteratorToArray(value[symIterator]());
|
|
}
|
|
var tag = getTag(value),
|
|
func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
|
|
|
|
return func(value);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a finite number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.12.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted number.
|
|
* @example
|
|
*
|
|
* _.toFinite(3.2);
|
|
* // => 3.2
|
|
*
|
|
* _.toFinite(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toFinite(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toFinite('3.2');
|
|
* // => 3.2
|
|
*/
|
|
function toFinite(value) {
|
|
if (!value) {
|
|
return value === 0 ? value : 0;
|
|
}
|
|
value = toNumber(value);
|
|
if (value === INFINITY || value === -INFINITY) {
|
|
var sign = (value < 0 ? -1 : 1);
|
|
return sign * MAX_INTEGER;
|
|
}
|
|
return value === value ? value : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to an integer.
|
|
*
|
|
* **Note:** This method is loosely based on
|
|
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toInteger(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toInteger(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toInteger(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toInteger('3.2');
|
|
* // => 3
|
|
*/
|
|
function toInteger(value) {
|
|
var result = toFinite(value),
|
|
remainder = result % 1;
|
|
|
|
return result === result ? (remainder ? result - remainder : result) : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to an integer suitable for use as the length of an
|
|
* array-like object.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toLength(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toLength(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toLength(Infinity);
|
|
* // => 4294967295
|
|
*
|
|
* _.toLength('3.2');
|
|
* // => 3
|
|
*/
|
|
function toLength(value) {
|
|
return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to process.
|
|
* @returns {number} Returns the number.
|
|
* @example
|
|
*
|
|
* _.toNumber(3.2);
|
|
* // => 3.2
|
|
*
|
|
* _.toNumber(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toNumber(Infinity);
|
|
* // => Infinity
|
|
*
|
|
* _.toNumber('3.2');
|
|
* // => 3.2
|
|
*/
|
|
function toNumber(value) {
|
|
if (typeof value == 'number') {
|
|
return value;
|
|
}
|
|
if (isSymbol(value)) {
|
|
return NAN;
|
|
}
|
|
if (isObject(value)) {
|
|
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|
value = isObject(other) ? (other + '') : other;
|
|
}
|
|
if (typeof value != 'string') {
|
|
return value === 0 ? value : +value;
|
|
}
|
|
value = value.replace(reTrim, '');
|
|
var isBinary = reIsBinary.test(value);
|
|
return (isBinary || reIsOctal.test(value))
|
|
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
: (reIsBadHex.test(value) ? NAN : +value);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a plain object flattening inherited enumerable string
|
|
* keyed properties of `value` to own properties of the plain object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {Object} Returns the converted plain object.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.assign({ 'a': 1 }, new Foo);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*
|
|
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
|
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
|
*/
|
|
function toPlainObject(value) {
|
|
return copyObject(value, keysIn(value));
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a safe integer. A safe integer can be compared and
|
|
* represented correctly.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toSafeInteger(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toSafeInteger(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toSafeInteger(Infinity);
|
|
* // => 9007199254740991
|
|
*
|
|
* _.toSafeInteger('3.2');
|
|
* // => 3
|
|
*/
|
|
function toSafeInteger(value) {
|
|
return value
|
|
? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
|
|
: (value === 0 ? value : 0);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a string. An empty string is returned for `null`
|
|
* and `undefined` values. The sign of `-0` is preserved.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {string} Returns the converted string.
|
|
* @example
|
|
*
|
|
* _.toString(null);
|
|
* // => ''
|
|
*
|
|
* _.toString(-0);
|
|
* // => '-0'
|
|
*
|
|
* _.toString([1, 2, 3]);
|
|
* // => '1,2,3'
|
|
*/
|
|
function toString(value) {
|
|
return value == null ? '' : baseToString(value);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Assigns own enumerable string keyed properties of source objects to the
|
|
* destination object. Source objects are applied from left to right.
|
|
* Subsequent sources overwrite property assignments of previous sources.
|
|
*
|
|
* **Note:** This method mutates `object` and is loosely based on
|
|
* [`Object.assign`](https://mdn.io/Object/assign).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.10.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assignIn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* function Bar() {
|
|
* this.c = 3;
|
|
* }
|
|
*
|
|
* Foo.prototype.b = 2;
|
|
* Bar.prototype.d = 4;
|
|
*
|
|
* _.assign({ 'a': 0 }, new Foo, new Bar);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
var assign = createAssigner(function(object, source) {
|
|
if (isPrototype(source) || isArrayLike(source)) {
|
|
copyObject(source, keys(source), object);
|
|
return;
|
|
}
|
|
for (var key in source) {
|
|
if (hasOwnProperty.call(source, key)) {
|
|
assignValue(object, key, source[key]);
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it iterates over own and
|
|
* inherited source properties.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias extend
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assign
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* function Bar() {
|
|
* this.c = 3;
|
|
* }
|
|
*
|
|
* Foo.prototype.b = 2;
|
|
* Bar.prototype.d = 4;
|
|
*
|
|
* _.assignIn({ 'a': 0 }, new Foo, new Bar);
|
|
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
|
|
*/
|
|
var assignIn = createAssigner(function(object, source) {
|
|
copyObject(source, keysIn(source), object);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.assignIn` except that it accepts `customizer`
|
|
* which is invoked to produce the assigned values. If `customizer` returns
|
|
* `undefined`, assignment is handled by the method instead. The `customizer`
|
|
* is invoked with five arguments: (objValue, srcValue, key, object, source).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias extendWith
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} sources The source objects.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assignWith
|
|
* @example
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* return _.isUndefined(objValue) ? srcValue : objValue;
|
|
* }
|
|
*
|
|
* var defaults = _.partialRight(_.assignInWith, customizer);
|
|
*
|
|
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
|
|
copyObject(source, keysIn(source), object, customizer);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it accepts `customizer`
|
|
* which is invoked to produce the assigned values. If `customizer` returns
|
|
* `undefined`, assignment is handled by the method instead. The `customizer`
|
|
* is invoked with five arguments: (objValue, srcValue, key, object, source).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} sources The source objects.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assignInWith
|
|
* @example
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* return _.isUndefined(objValue) ? srcValue : objValue;
|
|
* }
|
|
*
|
|
* var defaults = _.partialRight(_.assignWith, customizer);
|
|
*
|
|
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
|
|
copyObject(source, keys(source), object, customizer);
|
|
});
|
|
|
|
/**
|
|
* Creates an array of values corresponding to `paths` of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {...(string|string[])} [paths] The property paths to pick.
|
|
* @returns {Array} Returns the picked values.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
|
|
*
|
|
* _.at(object, ['a[0].b.c', 'a[1]']);
|
|
* // => [3, 4]
|
|
*/
|
|
var at = flatRest(baseAt);
|
|
|
|
/**
|
|
* Creates an object that inherits from the `prototype` object. If a
|
|
* `properties` object is given, its own enumerable string keyed properties
|
|
* are assigned to the created object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.3.0
|
|
* @category Object
|
|
* @param {Object} prototype The object to inherit from.
|
|
* @param {Object} [properties] The properties to assign to the object.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* function Shape() {
|
|
* this.x = 0;
|
|
* this.y = 0;
|
|
* }
|
|
*
|
|
* function Circle() {
|
|
* Shape.call(this);
|
|
* }
|
|
*
|
|
* Circle.prototype = _.create(Shape.prototype, {
|
|
* 'constructor': Circle
|
|
* });
|
|
*
|
|
* var circle = new Circle;
|
|
* circle instanceof Circle;
|
|
* // => true
|
|
*
|
|
* circle instanceof Shape;
|
|
* // => true
|
|
*/
|
|
function create(prototype, properties) {
|
|
var result = baseCreate(prototype);
|
|
return properties == null ? result : baseAssign(result, properties);
|
|
}
|
|
|
|
/**
|
|
* Assigns own and inherited enumerable string keyed properties of source
|
|
* objects to the destination object for all destination properties that
|
|
* resolve to `undefined`. Source objects are applied from left to right.
|
|
* Once a property is set, additional values of the same property are ignored.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.defaultsDeep
|
|
* @example
|
|
*
|
|
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
var defaults = baseRest(function(object, sources) {
|
|
object = Object(object);
|
|
|
|
var index = -1;
|
|
var length = sources.length;
|
|
var guard = length > 2 ? sources[2] : undefined;
|
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
length = 1;
|
|
}
|
|
|
|
while (++index < length) {
|
|
var source = sources[index];
|
|
var props = keysIn(source);
|
|
var propsIndex = -1;
|
|
var propsLength = props.length;
|
|
|
|
while (++propsIndex < propsLength) {
|
|
var key = props[propsIndex];
|
|
var value = object[key];
|
|
|
|
if (value === undefined ||
|
|
(eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
|
|
object[key] = source[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
return object;
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.defaults` except that it recursively assigns
|
|
* default properties.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.defaults
|
|
* @example
|
|
*
|
|
* _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
|
|
* // => { 'a': { 'b': 2, 'c': 3 } }
|
|
*/
|
|
var defaultsDeep = baseRest(function(args) {
|
|
args.push(undefined, customDefaultsMerge);
|
|
return apply(mergeWith, undefined, args);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.find` except that it returns the key of the first
|
|
* element `predicate` returns truthy for instead of the element itself.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {string|undefined} Returns the key of the matched element,
|
|
* else `undefined`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'barney': { 'age': 36, 'active': true },
|
|
* 'fred': { 'age': 40, 'active': false },
|
|
* 'pebbles': { 'age': 1, 'active': true }
|
|
* };
|
|
*
|
|
* _.findKey(users, function(o) { return o.age < 40; });
|
|
* // => 'barney' (iteration order is not guaranteed)
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findKey(users, { 'age': 1, 'active': true });
|
|
* // => 'pebbles'
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findKey(users, ['active', false]);
|
|
* // => 'fred'
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findKey(users, 'active');
|
|
* // => 'barney'
|
|
*/
|
|
function findKey(object, predicate) {
|
|
return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.findKey` except that it iterates over elements of
|
|
* a collection in the opposite order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {string|undefined} Returns the key of the matched element,
|
|
* else `undefined`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'barney': { 'age': 36, 'active': true },
|
|
* 'fred': { 'age': 40, 'active': false },
|
|
* 'pebbles': { 'age': 1, 'active': true }
|
|
* };
|
|
*
|
|
* _.findLastKey(users, function(o) { return o.age < 40; });
|
|
* // => returns 'pebbles' assuming `_.findKey` returns 'barney'
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findLastKey(users, { 'age': 36, 'active': true });
|
|
* // => 'barney'
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findLastKey(users, ['active', false]);
|
|
* // => 'fred'
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findLastKey(users, 'active');
|
|
* // => 'pebbles'
|
|
*/
|
|
function findLastKey(object, predicate) {
|
|
return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
|
|
}
|
|
|
|
/**
|
|
* Iterates over own and inherited enumerable string keyed properties of an
|
|
* object and invokes `iteratee` for each property. The iteratee is invoked
|
|
* with three arguments: (value, key, object). Iteratee functions may exit
|
|
* iteration early by explicitly returning `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.3.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forInRight
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forIn(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
|
|
*/
|
|
function forIn(object, iteratee) {
|
|
return object == null
|
|
? object
|
|
: baseFor(object, getIteratee(iteratee, 3), keysIn);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.forIn` except that it iterates over properties of
|
|
* `object` in the opposite order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forIn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forInRight(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
|
|
*/
|
|
function forInRight(object, iteratee) {
|
|
return object == null
|
|
? object
|
|
: baseForRight(object, getIteratee(iteratee, 3), keysIn);
|
|
}
|
|
|
|
/**
|
|
* Iterates over own enumerable string keyed properties of an object and
|
|
* invokes `iteratee` for each property. The iteratee is invoked with three
|
|
* arguments: (value, key, object). Iteratee functions may exit iteration
|
|
* early by explicitly returning `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.3.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forOwnRight
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forOwn(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
|
*/
|
|
function forOwn(object, iteratee) {
|
|
return object && baseForOwn(object, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.forOwn` except that it iterates over properties of
|
|
* `object` in the opposite order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forOwn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forOwnRight(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
|
|
*/
|
|
function forOwnRight(object, iteratee) {
|
|
return object && baseForOwnRight(object, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of function property names from own enumerable properties
|
|
* of `object`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @returns {Array} Returns the function names.
|
|
* @see _.functionsIn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = _.constant('a');
|
|
* this.b = _.constant('b');
|
|
* }
|
|
*
|
|
* Foo.prototype.c = _.constant('c');
|
|
*
|
|
* _.functions(new Foo);
|
|
* // => ['a', 'b']
|
|
*/
|
|
function functions(object) {
|
|
return object == null ? [] : baseFunctions(object, keys(object));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of function property names from own and inherited
|
|
* enumerable properties of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @returns {Array} Returns the function names.
|
|
* @see _.functions
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = _.constant('a');
|
|
* this.b = _.constant('b');
|
|
* }
|
|
*
|
|
* Foo.prototype.c = _.constant('c');
|
|
*
|
|
* _.functionsIn(new Foo);
|
|
* // => ['a', 'b', 'c']
|
|
*/
|
|
function functionsIn(object) {
|
|
return object == null ? [] : baseFunctions(object, keysIn(object));
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `path` of `object`. If the resolved value is
|
|
* `undefined`, the `defaultValue` is returned in its place.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
|
|
* @returns {*} Returns the resolved value.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
*
|
|
* _.get(object, 'a[0].b.c');
|
|
* // => 3
|
|
*
|
|
* _.get(object, ['a', '0', 'b', 'c']);
|
|
* // => 3
|
|
*
|
|
* _.get(object, 'a.b.c', 'default');
|
|
* // => 'default'
|
|
*/
|
|
function get(object, path, defaultValue) {
|
|
var result = object == null ? undefined : baseGet(object, path);
|
|
return result === undefined ? defaultValue : result;
|
|
}
|
|
|
|
/**
|
|
* Checks if `path` is a direct property of `object`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path to check.
|
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': { 'b': 2 } };
|
|
* var other = _.create({ 'a': _.create({ 'b': 2 }) });
|
|
*
|
|
* _.has(object, 'a');
|
|
* // => true
|
|
*
|
|
* _.has(object, 'a.b');
|
|
* // => true
|
|
*
|
|
* _.has(object, ['a', 'b']);
|
|
* // => true
|
|
*
|
|
* _.has(other, 'a');
|
|
* // => false
|
|
*/
|
|
function has(object, path) {
|
|
return object != null && hasPath(object, path, baseHas);
|
|
}
|
|
|
|
/**
|
|
* Checks if `path` is a direct or inherited property of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path to check.
|
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
|
* @example
|
|
*
|
|
* var object = _.create({ 'a': _.create({ 'b': 2 }) });
|
|
*
|
|
* _.hasIn(object, 'a');
|
|
* // => true
|
|
*
|
|
* _.hasIn(object, 'a.b');
|
|
* // => true
|
|
*
|
|
* _.hasIn(object, ['a', 'b']);
|
|
* // => true
|
|
*
|
|
* _.hasIn(object, 'b');
|
|
* // => false
|
|
*/
|
|
function hasIn(object, path) {
|
|
return object != null && hasPath(object, path, baseHasIn);
|
|
}
|
|
|
|
/**
|
|
* Creates an object composed of the inverted keys and values of `object`.
|
|
* If `object` contains duplicate values, subsequent values overwrite
|
|
* property assignments of previous values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.7.0
|
|
* @category Object
|
|
* @param {Object} object The object to invert.
|
|
* @returns {Object} Returns the new inverted object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2, 'c': 1 };
|
|
*
|
|
* _.invert(object);
|
|
* // => { '1': 'c', '2': 'b' }
|
|
*/
|
|
var invert = createInverter(function(result, value, key) {
|
|
if (value != null &&
|
|
typeof value.toString != 'function') {
|
|
value = nativeObjectToString.call(value);
|
|
}
|
|
|
|
result[value] = key;
|
|
}, constant(identity));
|
|
|
|
/**
|
|
* This method is like `_.invert` except that the inverted object is generated
|
|
* from the results of running each element of `object` thru `iteratee`. The
|
|
* corresponding inverted value of each inverted key is an array of keys
|
|
* responsible for generating the inverted value. The iteratee is invoked
|
|
* with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.1.0
|
|
* @category Object
|
|
* @param {Object} object The object to invert.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Object} Returns the new inverted object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2, 'c': 1 };
|
|
*
|
|
* _.invertBy(object);
|
|
* // => { '1': ['a', 'c'], '2': ['b'] }
|
|
*
|
|
* _.invertBy(object, function(value) {
|
|
* return 'group' + value;
|
|
* });
|
|
* // => { 'group1': ['a', 'c'], 'group2': ['b'] }
|
|
*/
|
|
var invertBy = createInverter(function(result, value, key) {
|
|
if (value != null &&
|
|
typeof value.toString != 'function') {
|
|
value = nativeObjectToString.call(value);
|
|
}
|
|
|
|
if (hasOwnProperty.call(result, value)) {
|
|
result[value].push(key);
|
|
} else {
|
|
result[value] = [key];
|
|
}
|
|
}, getIteratee);
|
|
|
|
/**
|
|
* Invokes the method at `path` of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the method to invoke.
|
|
* @param {...*} [args] The arguments to invoke the method with.
|
|
* @returns {*} Returns the result of the invoked method.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
|
|
*
|
|
* _.invoke(object, 'a[0].b.c.slice', 1, 3);
|
|
* // => [2, 3]
|
|
*/
|
|
var invoke = baseRest(baseInvoke);
|
|
|
|
/**
|
|
* Creates an array of the own enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|
* for more details.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keys(new Foo);
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|
*
|
|
* _.keys('hi');
|
|
* // => ['0', '1']
|
|
*/
|
|
function keys(object) {
|
|
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keysIn(new Foo);
|
|
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
*/
|
|
function keysIn(object) {
|
|
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
|
|
}
|
|
|
|
/**
|
|
* The opposite of `_.mapValues`; this method creates an object with the
|
|
* same values as `object` and keys generated by running each own enumerable
|
|
* string keyed property of `object` thru `iteratee`. The iteratee is invoked
|
|
* with three arguments: (value, key, object).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.8.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns the new mapped object.
|
|
* @see _.mapValues
|
|
* @example
|
|
*
|
|
* _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
|
|
* return key + value;
|
|
* });
|
|
* // => { 'a1': 1, 'b2': 2 }
|
|
*/
|
|
function mapKeys(object, iteratee) {
|
|
var result = {};
|
|
iteratee = getIteratee(iteratee, 3);
|
|
|
|
baseForOwn(object, function(value, key, object) {
|
|
baseAssignValue(result, iteratee(value, key, object), value);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an object with the same keys as `object` and values generated
|
|
* by running each own enumerable string keyed property of `object` thru
|
|
* `iteratee`. The iteratee is invoked with three arguments:
|
|
* (value, key, object).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns the new mapped object.
|
|
* @see _.mapKeys
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'fred': { 'user': 'fred', 'age': 40 },
|
|
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
|
|
* };
|
|
*
|
|
* _.mapValues(users, function(o) { return o.age; });
|
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.mapValues(users, 'age');
|
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
*/
|
|
function mapValues(object, iteratee) {
|
|
var result = {};
|
|
iteratee = getIteratee(iteratee, 3);
|
|
|
|
baseForOwn(object, function(value, key, object) {
|
|
baseAssignValue(result, key, iteratee(value, key, object));
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it recursively merges own and
|
|
* inherited enumerable string keyed properties of source objects into the
|
|
* destination object. Source properties that resolve to `undefined` are
|
|
* skipped if a destination value exists. Array and plain object properties
|
|
* are merged recursively. Other objects and value types are overridden by
|
|
* assignment. Source objects are applied from left to right. Subsequent
|
|
* sources overwrite property assignments of previous sources.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.5.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = {
|
|
* 'a': [{ 'b': 2 }, { 'd': 4 }]
|
|
* };
|
|
*
|
|
* var other = {
|
|
* 'a': [{ 'c': 3 }, { 'e': 5 }]
|
|
* };
|
|
*
|
|
* _.merge(object, other);
|
|
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
|
|
*/
|
|
var merge = createAssigner(function(object, source, srcIndex) {
|
|
baseMerge(object, source, srcIndex);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.merge` except that it accepts `customizer` which
|
|
* is invoked to produce the merged values of the destination and source
|
|
* properties. If `customizer` returns `undefined`, merging is handled by the
|
|
* method instead. The `customizer` is invoked with six arguments:
|
|
* (objValue, srcValue, key, object, source, stack).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} sources The source objects.
|
|
* @param {Function} customizer The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* if (_.isArray(objValue)) {
|
|
* return objValue.concat(srcValue);
|
|
* }
|
|
* }
|
|
*
|
|
* var object = { 'a': [1], 'b': [2] };
|
|
* var other = { 'a': [3], 'b': [4] };
|
|
*
|
|
* _.mergeWith(object, other, customizer);
|
|
* // => { 'a': [1, 3], 'b': [2, 4] }
|
|
*/
|
|
var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
|
|
baseMerge(object, source, srcIndex, customizer);
|
|
});
|
|
|
|
/**
|
|
* The opposite of `_.pick`; this method creates an object composed of the
|
|
* own and inherited enumerable property paths of `object` that are not omitted.
|
|
*
|
|
* **Note:** This method is considerably slower than `_.pick`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {...(string|string[])} [paths] The property paths to omit.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.omit(object, ['a', 'c']);
|
|
* // => { 'b': '2' }
|
|
*/
|
|
var omit = flatRest(function(object, paths) {
|
|
var result = {};
|
|
if (object == null) {
|
|
return result;
|
|
}
|
|
var isDeep = false;
|
|
paths = arrayMap(paths, function(path) {
|
|
path = castPath(path, object);
|
|
isDeep || (isDeep = path.length > 1);
|
|
return path;
|
|
});
|
|
copyObject(object, getAllKeysIn(object), result);
|
|
if (isDeep) {
|
|
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
|
|
}
|
|
var length = paths.length;
|
|
while (length--) {
|
|
baseUnset(result, paths[length]);
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* The opposite of `_.pickBy`; this method creates an object composed of
|
|
* the own and inherited enumerable string keyed properties of `object` that
|
|
* `predicate` doesn't return truthy for. The predicate is invoked with two
|
|
* arguments: (value, key).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {Function} [predicate=_.identity] The function invoked per property.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.omitBy(object, _.isNumber);
|
|
* // => { 'b': '2' }
|
|
*/
|
|
function omitBy(object, predicate) {
|
|
return pickBy(object, negate(getIteratee(predicate)));
|
|
}
|
|
|
|
/**
|
|
* Creates an object composed of the picked `object` properties.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {...(string|string[])} [paths] The property paths to pick.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.pick(object, ['a', 'c']);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
var pick = flatRest(function(object, paths) {
|
|
return object == null ? {} : basePick(object, paths);
|
|
});
|
|
|
|
/**
|
|
* Creates an object composed of the `object` properties `predicate` returns
|
|
* truthy for. The predicate is invoked with two arguments: (value, key).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {Function} [predicate=_.identity] The function invoked per property.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.pickBy(object, _.isNumber);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
function pickBy(object, predicate) {
|
|
if (object == null) {
|
|
return {};
|
|
}
|
|
var props = arrayMap(getAllKeysIn(object), function(prop) {
|
|
return [prop];
|
|
});
|
|
predicate = getIteratee(predicate);
|
|
return basePickBy(object, props, function(value, path) {
|
|
return predicate(value, path[0]);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.get` except that if the resolved value is a
|
|
* function it's invoked with the `this` binding of its parent object and
|
|
* its result is returned.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the property to resolve.
|
|
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
|
|
* @returns {*} Returns the resolved value.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
|
|
*
|
|
* _.result(object, 'a[0].b.c1');
|
|
* // => 3
|
|
*
|
|
* _.result(object, 'a[0].b.c2');
|
|
* // => 4
|
|
*
|
|
* _.result(object, 'a[0].b.c3', 'default');
|
|
* // => 'default'
|
|
*
|
|
* _.result(object, 'a[0].b.c3', _.constant('default'));
|
|
* // => 'default'
|
|
*/
|
|
function result(object, path, defaultValue) {
|
|
path = castPath(path, object);
|
|
|
|
var index = -1,
|
|
length = path.length;
|
|
|
|
// Ensure the loop is entered when path is empty.
|
|
if (!length) {
|
|
length = 1;
|
|
object = undefined;
|
|
}
|
|
while (++index < length) {
|
|
var value = object == null ? undefined : object[toKey(path[index])];
|
|
if (value === undefined) {
|
|
index = length;
|
|
value = defaultValue;
|
|
}
|
|
object = isFunction(value) ? value.call(object) : value;
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
|
|
* it's created. Arrays are created for missing index properties while objects
|
|
* are created for all other missing properties. Use `_.setWith` to customize
|
|
* `path` creation.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
*
|
|
* _.set(object, 'a[0].b.c', 4);
|
|
* console.log(object.a[0].b.c);
|
|
* // => 4
|
|
*
|
|
* _.set(object, ['x', '0', 'y', 'z'], 5);
|
|
* console.log(object.x[0].y.z);
|
|
* // => 5
|
|
*/
|
|
function set(object, path, value) {
|
|
return object == null ? object : baseSet(object, path, value);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.set` except that it accepts `customizer` which is
|
|
* invoked to produce the objects of `path`. If `customizer` returns `undefined`
|
|
* path creation is handled by the method instead. The `customizer` is invoked
|
|
* with three arguments: (nsValue, key, nsObject).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {*} value The value to set.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = {};
|
|
*
|
|
* _.setWith(object, '[0][1]', 'a', Object);
|
|
* // => { '0': { '1': 'a' } }
|
|
*/
|
|
function setWith(object, path, value, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return object == null ? object : baseSet(object, path, value, customizer);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of own enumerable string keyed-value pairs for `object`
|
|
* which can be consumed by `_.fromPairs`. If `object` is a map or set, its
|
|
* entries are returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias entries
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the key-value pairs.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.toPairs(new Foo);
|
|
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
|
|
*/
|
|
var toPairs = createToPairs(keys);
|
|
|
|
/**
|
|
* Creates an array of own and inherited enumerable string keyed-value pairs
|
|
* for `object` which can be consumed by `_.fromPairs`. If `object` is a map
|
|
* or set, its entries are returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias entriesIn
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the key-value pairs.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.toPairsIn(new Foo);
|
|
* // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
|
|
*/
|
|
var toPairsIn = createToPairs(keysIn);
|
|
|
|
/**
|
|
* An alternative to `_.reduce`; this method transforms `object` to a new
|
|
* `accumulator` object which is the result of running each of its own
|
|
* enumerable string keyed properties thru `iteratee`, with each invocation
|
|
* potentially mutating the `accumulator` object. If `accumulator` is not
|
|
* provided, a new object with the same `[[Prototype]]` will be used. The
|
|
* iteratee is invoked with four arguments: (accumulator, value, key, object).
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.3.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {*} [accumulator] The custom accumulator value.
|
|
* @returns {*} Returns the accumulated value.
|
|
* @example
|
|
*
|
|
* _.transform([2, 3, 4], function(result, n) {
|
|
* result.push(n *= n);
|
|
* return n % 2 == 0;
|
|
* }, []);
|
|
* // => [4, 9]
|
|
*
|
|
* _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
|
|
* (result[value] || (result[value] = [])).push(key);
|
|
* }, {});
|
|
* // => { '1': ['a', 'c'], '2': ['b'] }
|
|
*/
|
|
function transform(object, iteratee, accumulator) {
|
|
var isArr = isArray(object),
|
|
isArrLike = isArr || isBuffer(object) || isTypedArray(object);
|
|
|
|
iteratee = getIteratee(iteratee, 4);
|
|
if (accumulator == null) {
|
|
var Ctor = object && object.constructor;
|
|
if (isArrLike) {
|
|
accumulator = isArr ? new Ctor : [];
|
|
}
|
|
else if (isObject(object)) {
|
|
accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
|
|
}
|
|
else {
|
|
accumulator = {};
|
|
}
|
|
}
|
|
(isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
|
|
return iteratee(accumulator, value, index, object);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* Removes the property at `path` of `object`.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to unset.
|
|
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 7 } }] };
|
|
* _.unset(object, 'a[0].b.c');
|
|
* // => true
|
|
*
|
|
* console.log(object);
|
|
* // => { 'a': [{ 'b': {} }] };
|
|
*
|
|
* _.unset(object, ['a', '0', 'b', 'c']);
|
|
* // => true
|
|
*
|
|
* console.log(object);
|
|
* // => { 'a': [{ 'b': {} }] };
|
|
*/
|
|
function unset(object, path) {
|
|
return object == null ? true : baseUnset(object, path);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.set` except that accepts `updater` to produce the
|
|
* value to set. Use `_.updateWith` to customize `path` creation. The `updater`
|
|
* is invoked with one argument: (value).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.6.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {Function} updater The function to produce the updated value.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
*
|
|
* _.update(object, 'a[0].b.c', function(n) { return n * n; });
|
|
* console.log(object.a[0].b.c);
|
|
* // => 9
|
|
*
|
|
* _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
|
|
* console.log(object.x[0].y.z);
|
|
* // => 0
|
|
*/
|
|
function update(object, path, updater) {
|
|
return object == null ? object : baseUpdate(object, path, castFunction(updater));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.update` except that it accepts `customizer` which is
|
|
* invoked to produce the objects of `path`. If `customizer` returns `undefined`
|
|
* path creation is handled by the method instead. The `customizer` is invoked
|
|
* with three arguments: (nsValue, key, nsObject).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.6.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {Function} updater The function to produce the updated value.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = {};
|
|
*
|
|
* _.updateWith(object, '[0][1]', _.constant('a'), Object);
|
|
* // => { '0': { '1': 'a' } }
|
|
*/
|
|
function updateWith(object, path, updater, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own enumerable string keyed property values of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property values.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.values(new Foo);
|
|
* // => [1, 2] (iteration order is not guaranteed)
|
|
*
|
|
* _.values('hi');
|
|
* // => ['h', 'i']
|
|
*/
|
|
function values(object) {
|
|
return object == null ? [] : baseValues(object, keys(object));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable string keyed property
|
|
* values of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property values.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.valuesIn(new Foo);
|
|
* // => [1, 2, 3] (iteration order is not guaranteed)
|
|
*/
|
|
function valuesIn(object) {
|
|
return object == null ? [] : baseValues(object, keysIn(object));
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Clamps `number` within the inclusive `lower` and `upper` bounds.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Number
|
|
* @param {number} number The number to clamp.
|
|
* @param {number} [lower] The lower bound.
|
|
* @param {number} upper The upper bound.
|
|
* @returns {number} Returns the clamped number.
|
|
* @example
|
|
*
|
|
* _.clamp(-10, -5, 5);
|
|
* // => -5
|
|
*
|
|
* _.clamp(10, -5, 5);
|
|
* // => 5
|
|
*/
|
|
function clamp(number, lower, upper) {
|
|
if (upper === undefined) {
|
|
upper = lower;
|
|
lower = undefined;
|
|
}
|
|
if (upper !== undefined) {
|
|
upper = toNumber(upper);
|
|
upper = upper === upper ? upper : 0;
|
|
}
|
|
if (lower !== undefined) {
|
|
lower = toNumber(lower);
|
|
lower = lower === lower ? lower : 0;
|
|
}
|
|
return baseClamp(toNumber(number), lower, upper);
|
|
}
|
|
|
|
/**
|
|
* Checks if `n` is between `start` and up to, but not including, `end`. If
|
|
* `end` is not specified, it's set to `start` with `start` then set to `0`.
|
|
* If `start` is greater than `end` the params are swapped to support
|
|
* negative ranges.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.3.0
|
|
* @category Number
|
|
* @param {number} number The number to check.
|
|
* @param {number} [start=0] The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
|
* @see _.range, _.rangeRight
|
|
* @example
|
|
*
|
|
* _.inRange(3, 2, 4);
|
|
* // => true
|
|
*
|
|
* _.inRange(4, 8);
|
|
* // => true
|
|
*
|
|
* _.inRange(4, 2);
|
|
* // => false
|
|
*
|
|
* _.inRange(2, 2);
|
|
* // => false
|
|
*
|
|
* _.inRange(1.2, 2);
|
|
* // => true
|
|
*
|
|
* _.inRange(5.2, 4);
|
|
* // => false
|
|
*
|
|
* _.inRange(-3, -2, -6);
|
|
* // => true
|
|
*/
|
|
function inRange(number, start, end) {
|
|
start = toFinite(start);
|
|
if (end === undefined) {
|
|
end = start;
|
|
start = 0;
|
|
} else {
|
|
end = toFinite(end);
|
|
}
|
|
number = toNumber(number);
|
|
return baseInRange(number, start, end);
|
|
}
|
|
|
|
/**
|
|
* Produces a random number between the inclusive `lower` and `upper` bounds.
|
|
* If only one argument is provided a number between `0` and the given number
|
|
* is returned. If `floating` is `true`, or either `lower` or `upper` are
|
|
* floats, a floating-point number is returned instead of an integer.
|
|
*
|
|
* **Note:** JavaScript follows the IEEE-754 standard for resolving
|
|
* floating-point values which can produce unexpected results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.7.0
|
|
* @category Number
|
|
* @param {number} [lower=0] The lower bound.
|
|
* @param {number} [upper=1] The upper bound.
|
|
* @param {boolean} [floating] Specify returning a floating-point number.
|
|
* @returns {number} Returns the random number.
|
|
* @example
|
|
*
|
|
* _.random(0, 5);
|
|
* // => an integer between 0 and 5
|
|
*
|
|
* _.random(5);
|
|
* // => also an integer between 0 and 5
|
|
*
|
|
* _.random(5, true);
|
|
* // => a floating-point number between 0 and 5
|
|
*
|
|
* _.random(1.2, 5.2);
|
|
* // => a floating-point number between 1.2 and 5.2
|
|
*/
|
|
function random(lower, upper, floating) {
|
|
if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
|
|
upper = floating = undefined;
|
|
}
|
|
if (floating === undefined) {
|
|
if (typeof upper == 'boolean') {
|
|
floating = upper;
|
|
upper = undefined;
|
|
}
|
|
else if (typeof lower == 'boolean') {
|
|
floating = lower;
|
|
lower = undefined;
|
|
}
|
|
}
|
|
if (lower === undefined && upper === undefined) {
|
|
lower = 0;
|
|
upper = 1;
|
|
}
|
|
else {
|
|
lower = toFinite(lower);
|
|
if (upper === undefined) {
|
|
upper = lower;
|
|
lower = 0;
|
|
} else {
|
|
upper = toFinite(upper);
|
|
}
|
|
}
|
|
if (lower > upper) {
|
|
var temp = lower;
|
|
lower = upper;
|
|
upper = temp;
|
|
}
|
|
if (floating || lower % 1 || upper % 1) {
|
|
var rand = nativeRandom();
|
|
return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
|
|
}
|
|
return baseRandom(lower, upper);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the camel cased string.
|
|
* @example
|
|
*
|
|
* _.camelCase('Foo Bar');
|
|
* // => 'fooBar'
|
|
*
|
|
* _.camelCase('--foo-bar--');
|
|
* // => 'fooBar'
|
|
*
|
|
* _.camelCase('__FOO_BAR__');
|
|
* // => 'fooBar'
|
|
*/
|
|
var camelCase = createCompounder(function(result, word, index) {
|
|
word = word.toLowerCase();
|
|
return result + (index ? capitalize(word) : word);
|
|
});
|
|
|
|
/**
|
|
* Converts the first character of `string` to upper case and the remaining
|
|
* to lower case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to capitalize.
|
|
* @returns {string} Returns the capitalized string.
|
|
* @example
|
|
*
|
|
* _.capitalize('FRED');
|
|
* // => 'Fred'
|
|
*/
|
|
function capitalize(string) {
|
|
return upperFirst(toString(string).toLowerCase());
|
|
}
|
|
|
|
/**
|
|
* Deburrs `string` by converting
|
|
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
|
|
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
|
|
* letters to basic Latin letters and removing
|
|
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to deburr.
|
|
* @returns {string} Returns the deburred string.
|
|
* @example
|
|
*
|
|
* _.deburr('déjà vu');
|
|
* // => 'deja vu'
|
|
*/
|
|
function deburr(string) {
|
|
string = toString(string);
|
|
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
|
|
}
|
|
|
|
/**
|
|
* Checks if `string` ends with the given target string.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {string} [target] The string to search for.
|
|
* @param {number} [position=string.length] The position to search up to.
|
|
* @returns {boolean} Returns `true` if `string` ends with `target`,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.endsWith('abc', 'c');
|
|
* // => true
|
|
*
|
|
* _.endsWith('abc', 'b');
|
|
* // => false
|
|
*
|
|
* _.endsWith('abc', 'b', 2);
|
|
* // => true
|
|
*/
|
|
function endsWith(string, target, position) {
|
|
string = toString(string);
|
|
target = baseToString(target);
|
|
|
|
var length = string.length;
|
|
position = position === undefined
|
|
? length
|
|
: baseClamp(toInteger(position), 0, length);
|
|
|
|
var end = position;
|
|
position -= target.length;
|
|
return position >= 0 && string.slice(position, end) == target;
|
|
}
|
|
|
|
/**
|
|
* Converts the characters "&", "<", ">", '"', and "'" in `string` to their
|
|
* corresponding HTML entities.
|
|
*
|
|
* **Note:** No other characters are escaped. To escape additional
|
|
* characters use a third-party library like [_he_](https://mths.be/he).
|
|
*
|
|
* Though the ">" character is escaped for symmetry, characters like
|
|
* ">" and "/" don't need escaping in HTML and have no special meaning
|
|
* unless they're part of a tag or unquoted attribute value. See
|
|
* [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
|
|
* (under "semi-related fun fact") for more details.
|
|
*
|
|
* When working with HTML you should always
|
|
* [quote attribute values](http://wonko.com/post/html-escaping) to reduce
|
|
* XSS vectors.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The string to escape.
|
|
* @returns {string} Returns the escaped string.
|
|
* @example
|
|
*
|
|
* _.escape('fred, barney, & pebbles');
|
|
* // => 'fred, barney, & pebbles'
|
|
*/
|
|
function escape(string) {
|
|
string = toString(string);
|
|
return (string && reHasUnescapedHtml.test(string))
|
|
? string.replace(reUnescapedHtml, escapeHtmlChar)
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
|
|
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to escape.
|
|
* @returns {string} Returns the escaped string.
|
|
* @example
|
|
*
|
|
* _.escapeRegExp('[lodash](https://lodash.com/)');
|
|
* // => '\[lodash\]\(https://lodash\.com/\)'
|
|
*/
|
|
function escapeRegExp(string) {
|
|
string = toString(string);
|
|
return (string && reHasRegExpChar.test(string))
|
|
? string.replace(reRegExpChar, '\\$&')
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to
|
|
* [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the kebab cased string.
|
|
* @example
|
|
*
|
|
* _.kebabCase('Foo Bar');
|
|
* // => 'foo-bar'
|
|
*
|
|
* _.kebabCase('fooBar');
|
|
* // => 'foo-bar'
|
|
*
|
|
* _.kebabCase('__FOO_BAR__');
|
|
* // => 'foo-bar'
|
|
*/
|
|
var kebabCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? '-' : '') + word.toLowerCase();
|
|
});
|
|
|
|
/**
|
|
* Converts `string`, as space separated words, to lower case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the lower cased string.
|
|
* @example
|
|
*
|
|
* _.lowerCase('--Foo-Bar--');
|
|
* // => 'foo bar'
|
|
*
|
|
* _.lowerCase('fooBar');
|
|
* // => 'foo bar'
|
|
*
|
|
* _.lowerCase('__FOO_BAR__');
|
|
* // => 'foo bar'
|
|
*/
|
|
var lowerCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? ' ' : '') + word.toLowerCase();
|
|
});
|
|
|
|
/**
|
|
* Converts the first character of `string` to lower case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the converted string.
|
|
* @example
|
|
*
|
|
* _.lowerFirst('Fred');
|
|
* // => 'fred'
|
|
*
|
|
* _.lowerFirst('FRED');
|
|
* // => 'fRED'
|
|
*/
|
|
var lowerFirst = createCaseFirst('toLowerCase');
|
|
|
|
/**
|
|
* Pads `string` on the left and right sides if it's shorter than `length`.
|
|
* Padding characters are truncated if they can't be evenly divided by `length`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to pad.
|
|
* @param {number} [length=0] The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padded string.
|
|
* @example
|
|
*
|
|
* _.pad('abc', 8);
|
|
* // => ' abc '
|
|
*
|
|
* _.pad('abc', 8, '_-');
|
|
* // => '_-abc_-_'
|
|
*
|
|
* _.pad('abc', 3);
|
|
* // => 'abc'
|
|
*/
|
|
function pad(string, length, chars) {
|
|
string = toString(string);
|
|
length = toInteger(length);
|
|
|
|
var strLength = length ? stringSize(string) : 0;
|
|
if (!length || strLength >= length) {
|
|
return string;
|
|
}
|
|
var mid = (length - strLength) / 2;
|
|
return (
|
|
createPadding(nativeFloor(mid), chars) +
|
|
string +
|
|
createPadding(nativeCeil(mid), chars)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Pads `string` on the right side if it's shorter than `length`. Padding
|
|
* characters are truncated if they exceed `length`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to pad.
|
|
* @param {number} [length=0] The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padded string.
|
|
* @example
|
|
*
|
|
* _.padEnd('abc', 6);
|
|
* // => 'abc '
|
|
*
|
|
* _.padEnd('abc', 6, '_-');
|
|
* // => 'abc_-_'
|
|
*
|
|
* _.padEnd('abc', 3);
|
|
* // => 'abc'
|
|
*/
|
|
function padEnd(string, length, chars) {
|
|
string = toString(string);
|
|
length = toInteger(length);
|
|
|
|
var strLength = length ? stringSize(string) : 0;
|
|
return (length && strLength < length)
|
|
? (string + createPadding(length - strLength, chars))
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Pads `string` on the left side if it's shorter than `length`. Padding
|
|
* characters are truncated if they exceed `length`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to pad.
|
|
* @param {number} [length=0] The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padded string.
|
|
* @example
|
|
*
|
|
* _.padStart('abc', 6);
|
|
* // => ' abc'
|
|
*
|
|
* _.padStart('abc', 6, '_-');
|
|
* // => '_-_abc'
|
|
*
|
|
* _.padStart('abc', 3);
|
|
* // => 'abc'
|
|
*/
|
|
function padStart(string, length, chars) {
|
|
string = toString(string);
|
|
length = toInteger(length);
|
|
|
|
var strLength = length ? stringSize(string) : 0;
|
|
return (length && strLength < length)
|
|
? (createPadding(length - strLength, chars) + string)
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to an integer of the specified radix. If `radix` is
|
|
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a
|
|
* hexadecimal, in which case a `radix` of `16` is used.
|
|
*
|
|
* **Note:** This method aligns with the
|
|
* [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category String
|
|
* @param {string} string The string to convert.
|
|
* @param {number} [radix=10] The radix to interpret `value` by.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.parseInt('08');
|
|
* // => 8
|
|
*
|
|
* _.map(['6', '08', '10'], _.parseInt);
|
|
* // => [6, 8, 10]
|
|
*/
|
|
function parseInt(string, radix, guard) {
|
|
if (guard || radix == null) {
|
|
radix = 0;
|
|
} else if (radix) {
|
|
radix = +radix;
|
|
}
|
|
return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
|
|
}
|
|
|
|
/**
|
|
* Repeats the given string `n` times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to repeat.
|
|
* @param {number} [n=1] The number of times to repeat the string.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the repeated string.
|
|
* @example
|
|
*
|
|
* _.repeat('*', 3);
|
|
* // => '***'
|
|
*
|
|
* _.repeat('abc', 2);
|
|
* // => 'abcabc'
|
|
*
|
|
* _.repeat('abc', 0);
|
|
* // => ''
|
|
*/
|
|
function repeat(string, n, guard) {
|
|
if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
|
|
n = 1;
|
|
} else {
|
|
n = toInteger(n);
|
|
}
|
|
return baseRepeat(toString(string), n);
|
|
}
|
|
|
|
/**
|
|
* Replaces matches for `pattern` in `string` with `replacement`.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`String#replace`](https://mdn.io/String/replace).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to modify.
|
|
* @param {RegExp|string} pattern The pattern to replace.
|
|
* @param {Function|string} replacement The match replacement.
|
|
* @returns {string} Returns the modified string.
|
|
* @example
|
|
*
|
|
* _.replace('Hi Fred', 'Fred', 'Barney');
|
|
* // => 'Hi Barney'
|
|
*/
|
|
function replace() {
|
|
var args = arguments,
|
|
string = toString(args[0]);
|
|
|
|
return args.length < 3 ? string : string.replace(args[1], args[2]);
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to
|
|
* [snake case](https://en.wikipedia.org/wiki/Snake_case).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the snake cased string.
|
|
* @example
|
|
*
|
|
* _.snakeCase('Foo Bar');
|
|
* // => 'foo_bar'
|
|
*
|
|
* _.snakeCase('fooBar');
|
|
* // => 'foo_bar'
|
|
*
|
|
* _.snakeCase('--FOO-BAR--');
|
|
* // => 'foo_bar'
|
|
*/
|
|
var snakeCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? '_' : '') + word.toLowerCase();
|
|
});
|
|
|
|
/**
|
|
* Splits `string` by `separator`.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`String#split`](https://mdn.io/String/split).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to split.
|
|
* @param {RegExp|string} separator The separator pattern to split by.
|
|
* @param {number} [limit] The length to truncate results to.
|
|
* @returns {Array} Returns the string segments.
|
|
* @example
|
|
*
|
|
* _.split('a-b-c', '-', 2);
|
|
* // => ['a', 'b']
|
|
*/
|
|
function split(string, separator, limit) {
|
|
if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
|
|
separator = limit = undefined;
|
|
}
|
|
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
|
|
if (!limit) {
|
|
return [];
|
|
}
|
|
string = toString(string);
|
|
if (string && (
|
|
typeof separator == 'string' ||
|
|
(separator != null && !isRegExp(separator))
|
|
)) {
|
|
separator = baseToString(separator);
|
|
if (!separator && hasUnicode(string)) {
|
|
return castSlice(stringToArray(string), 0, limit);
|
|
}
|
|
}
|
|
return string.split(separator, limit);
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to
|
|
* [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.1.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the start cased string.
|
|
* @example
|
|
*
|
|
* _.startCase('--foo-bar--');
|
|
* // => 'Foo Bar'
|
|
*
|
|
* _.startCase('fooBar');
|
|
* // => 'Foo Bar'
|
|
*
|
|
* _.startCase('__FOO_BAR__');
|
|
* // => 'FOO BAR'
|
|
*/
|
|
var startCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? ' ' : '') + upperFirst(word);
|
|
});
|
|
|
|
/**
|
|
* Checks if `string` starts with the given target string.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {string} [target] The string to search for.
|
|
* @param {number} [position=0] The position to search from.
|
|
* @returns {boolean} Returns `true` if `string` starts with `target`,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.startsWith('abc', 'a');
|
|
* // => true
|
|
*
|
|
* _.startsWith('abc', 'b');
|
|
* // => false
|
|
*
|
|
* _.startsWith('abc', 'b', 1);
|
|
* // => true
|
|
*/
|
|
function startsWith(string, target, position) {
|
|
string = toString(string);
|
|
position = position == null
|
|
? 0
|
|
: baseClamp(toInteger(position), 0, string.length);
|
|
|
|
target = baseToString(target);
|
|
return string.slice(position, position + target.length) == target;
|
|
}
|
|
|
|
/**
|
|
* Creates a compiled template function that can interpolate data properties
|
|
* in "interpolate" delimiters, HTML-escape interpolated data properties in
|
|
* "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
|
|
* properties may be accessed as free variables in the template. If a setting
|
|
* object is given, it takes precedence over `_.templateSettings` values.
|
|
*
|
|
* **Note:** In the development build `_.template` utilizes
|
|
* [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
|
|
* for easier debugging.
|
|
*
|
|
* For more information on precompiling templates see
|
|
* [lodash's custom builds documentation](https://lodash.com/custom-builds).
|
|
*
|
|
* For more information on Chrome extension sandboxes see
|
|
* [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The template string.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {RegExp} [options.escape=_.templateSettings.escape]
|
|
* The HTML "escape" delimiter.
|
|
* @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
|
|
* The "evaluate" delimiter.
|
|
* @param {Object} [options.imports=_.templateSettings.imports]
|
|
* An object to import into the template as free variables.
|
|
* @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
|
|
* The "interpolate" delimiter.
|
|
* @param {string} [options.sourceURL='lodash.templateSources[n]']
|
|
* The sourceURL of the compiled template.
|
|
* @param {string} [options.variable='obj']
|
|
* The data object variable name.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the compiled template function.
|
|
* @example
|
|
*
|
|
* // Use the "interpolate" delimiter to create a compiled template.
|
|
* var compiled = _.template('hello <%= user %>!');
|
|
* compiled({ 'user': 'fred' });
|
|
* // => 'hello fred!'
|
|
*
|
|
* // Use the HTML "escape" delimiter to escape data property values.
|
|
* var compiled = _.template('<b><%- value %></b>');
|
|
* compiled({ 'value': '<script>' });
|
|
* // => '<b><script></b>'
|
|
*
|
|
* // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
|
|
* var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
|
|
* compiled({ 'users': ['fred', 'barney'] });
|
|
* // => '<li>fred</li><li>barney</li>'
|
|
*
|
|
* // Use the internal `print` function in "evaluate" delimiters.
|
|
* var compiled = _.template('<% print("hello " + user); %>!');
|
|
* compiled({ 'user': 'barney' });
|
|
* // => 'hello barney!'
|
|
*
|
|
* // Use the ES template literal delimiter as an "interpolate" delimiter.
|
|
* // Disable support by replacing the "interpolate" delimiter.
|
|
* var compiled = _.template('hello ${ user }!');
|
|
* compiled({ 'user': 'pebbles' });
|
|
* // => 'hello pebbles!'
|
|
*
|
|
* // Use backslashes to treat delimiters as plain text.
|
|
* var compiled = _.template('<%= "\\<%- value %\\>" %>');
|
|
* compiled({ 'value': 'ignored' });
|
|
* // => '<%- value %>'
|
|
*
|
|
* // Use the `imports` option to import `jQuery` as `jq`.
|
|
* var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
|
|
* var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
|
|
* compiled({ 'users': ['fred', 'barney'] });
|
|
* // => '<li>fred</li><li>barney</li>'
|
|
*
|
|
* // Use the `sourceURL` option to specify a custom sourceURL for the template.
|
|
* var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
|
|
* compiled(data);
|
|
* // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
|
|
*
|
|
* // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
|
|
* var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
|
|
* compiled.source;
|
|
* // => function(data) {
|
|
* // var __t, __p = '';
|
|
* // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
|
|
* // return __p;
|
|
* // }
|
|
*
|
|
* // Use custom template delimiters.
|
|
* _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
|
* var compiled = _.template('hello {{ user }}!');
|
|
* compiled({ 'user': 'mustache' });
|
|
* // => 'hello mustache!'
|
|
*
|
|
* // Use the `source` property to inline compiled templates for meaningful
|
|
* // line numbers in error messages and stack traces.
|
|
* fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
|
|
* var JST = {\
|
|
* "main": ' + _.template(mainText).source + '\
|
|
* };\
|
|
* ');
|
|
*/
|
|
function template(string, options, guard) {
|
|
// Based on John Resig's `tmpl` implementation
|
|
// (http://ejohn.org/blog/javascript-micro-templating/)
|
|
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
|
|
var settings = lodash.templateSettings;
|
|
|
|
if (guard && isIterateeCall(string, options, guard)) {
|
|
options = undefined;
|
|
}
|
|
string = toString(string);
|
|
options = assignInWith({}, options, settings, customDefaultsAssignIn);
|
|
|
|
var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
|
|
importsKeys = keys(imports),
|
|
importsValues = baseValues(imports, importsKeys);
|
|
|
|
var isEscaping,
|
|
isEvaluating,
|
|
index = 0,
|
|
interpolate = options.interpolate || reNoMatch,
|
|
source = "__p += '";
|
|
|
|
// Compile the regexp to match each delimiter.
|
|
var reDelimiters = RegExp(
|
|
(options.escape || reNoMatch).source + '|' +
|
|
interpolate.source + '|' +
|
|
(interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
|
|
(options.evaluate || reNoMatch).source + '|$'
|
|
, 'g');
|
|
|
|
// Use a sourceURL for easier debugging.
|
|
// The sourceURL gets injected into the source that's eval-ed, so be careful
|
|
// with lookup (in case of e.g. prototype pollution), and strip newlines if any.
|
|
// A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection.
|
|
var sourceURL = '//# sourceURL=' +
|
|
(hasOwnProperty.call(options, 'sourceURL')
|
|
? (options.sourceURL + '').replace(/[\r\n]/g, ' ')
|
|
: ('lodash.templateSources[' + (++templateCounter) + ']')
|
|
) + '\n';
|
|
|
|
string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
|
|
interpolateValue || (interpolateValue = esTemplateValue);
|
|
|
|
// Escape characters that can't be included in string literals.
|
|
source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
|
|
|
|
// Replace delimiters with snippets.
|
|
if (escapeValue) {
|
|
isEscaping = true;
|
|
source += "' +\n__e(" + escapeValue + ") +\n'";
|
|
}
|
|
if (evaluateValue) {
|
|
isEvaluating = true;
|
|
source += "';\n" + evaluateValue + ";\n__p += '";
|
|
}
|
|
if (interpolateValue) {
|
|
source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
|
|
}
|
|
index = offset + match.length;
|
|
|
|
// The JS engine embedded in Adobe products needs `match` returned in
|
|
// order to produce the correct `offset` value.
|
|
return match;
|
|
});
|
|
|
|
source += "';\n";
|
|
|
|
// If `variable` is not specified wrap a with-statement around the generated
|
|
// code to add the data object to the top of the scope chain.
|
|
// Like with sourceURL, we take care to not check the option's prototype,
|
|
// as this configuration is a code injection vector.
|
|
var variable = hasOwnProperty.call(options, 'variable') && options.variable;
|
|
if (!variable) {
|
|
source = 'with (obj) {\n' + source + '\n}\n';
|
|
}
|
|
// Cleanup code by stripping empty strings.
|
|
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
|
|
.replace(reEmptyStringMiddle, '$1')
|
|
.replace(reEmptyStringTrailing, '$1;');
|
|
|
|
// Frame code as the function body.
|
|
source = 'function(' + (variable || 'obj') + ') {\n' +
|
|
(variable
|
|
? ''
|
|
: 'obj || (obj = {});\n'
|
|
) +
|
|
"var __t, __p = ''" +
|
|
(isEscaping
|
|
? ', __e = _.escape'
|
|
: ''
|
|
) +
|
|
(isEvaluating
|
|
? ', __j = Array.prototype.join;\n' +
|
|
"function print() { __p += __j.call(arguments, '') }\n"
|
|
: ';\n'
|
|
) +
|
|
source +
|
|
'return __p\n}';
|
|
|
|
var result = attempt(function() {
|
|
return Function(importsKeys, sourceURL + 'return ' + source)
|
|
.apply(undefined, importsValues);
|
|
});
|
|
|
|
// Provide the compiled function's source by its `toString` method or
|
|
// the `source` property as a convenience for inlining compiled templates.
|
|
result.source = source;
|
|
if (isError(result)) {
|
|
throw result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `string`, as a whole, to lower case just like
|
|
* [String#toLowerCase](https://mdn.io/toLowerCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the lower cased string.
|
|
* @example
|
|
*
|
|
* _.toLower('--Foo-Bar--');
|
|
* // => '--foo-bar--'
|
|
*
|
|
* _.toLower('fooBar');
|
|
* // => 'foobar'
|
|
*
|
|
* _.toLower('__FOO_BAR__');
|
|
* // => '__foo_bar__'
|
|
*/
|
|
function toLower(value) {
|
|
return toString(value).toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Converts `string`, as a whole, to upper case just like
|
|
* [String#toUpperCase](https://mdn.io/toUpperCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the upper cased string.
|
|
* @example
|
|
*
|
|
* _.toUpper('--foo-bar--');
|
|
* // => '--FOO-BAR--'
|
|
*
|
|
* _.toUpper('fooBar');
|
|
* // => 'FOOBAR'
|
|
*
|
|
* _.toUpper('__foo_bar__');
|
|
* // => '__FOO_BAR__'
|
|
*/
|
|
function toUpper(value) {
|
|
return toString(value).toUpperCase();
|
|
}
|
|
|
|
/**
|
|
* Removes leading and trailing whitespace or specified characters from `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to trim.
|
|
* @param {string} [chars=whitespace] The characters to trim.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the trimmed string.
|
|
* @example
|
|
*
|
|
* _.trim(' abc ');
|
|
* // => 'abc'
|
|
*
|
|
* _.trim('-_-abc-_-', '_-');
|
|
* // => 'abc'
|
|
*
|
|
* _.map([' foo ', ' bar '], _.trim);
|
|
* // => ['foo', 'bar']
|
|
*/
|
|
function trim(string, chars, guard) {
|
|
string = toString(string);
|
|
if (string && (guard || chars === undefined)) {
|
|
return string.replace(reTrim, '');
|
|
}
|
|
if (!string || !(chars = baseToString(chars))) {
|
|
return string;
|
|
}
|
|
var strSymbols = stringToArray(string),
|
|
chrSymbols = stringToArray(chars),
|
|
start = charsStartIndex(strSymbols, chrSymbols),
|
|
end = charsEndIndex(strSymbols, chrSymbols) + 1;
|
|
|
|
return castSlice(strSymbols, start, end).join('');
|
|
}
|
|
|
|
/**
|
|
* Removes trailing whitespace or specified characters from `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to trim.
|
|
* @param {string} [chars=whitespace] The characters to trim.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the trimmed string.
|
|
* @example
|
|
*
|
|
* _.trimEnd(' abc ');
|
|
* // => ' abc'
|
|
*
|
|
* _.trimEnd('-_-abc-_-', '_-');
|
|
* // => '-_-abc'
|
|
*/
|
|
function trimEnd(string, chars, guard) {
|
|
string = toString(string);
|
|
if (string && (guard || chars === undefined)) {
|
|
return string.replace(reTrimEnd, '');
|
|
}
|
|
if (!string || !(chars = baseToString(chars))) {
|
|
return string;
|
|
}
|
|
var strSymbols = stringToArray(string),
|
|
end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
|
|
|
|
return castSlice(strSymbols, 0, end).join('');
|
|
}
|
|
|
|
/**
|
|
* Removes leading whitespace or specified characters from `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to trim.
|
|
* @param {string} [chars=whitespace] The characters to trim.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the trimmed string.
|
|
* @example
|
|
*
|
|
* _.trimStart(' abc ');
|
|
* // => 'abc '
|
|
*
|
|
* _.trimStart('-_-abc-_-', '_-');
|
|
* // => 'abc-_-'
|
|
*/
|
|
function trimStart(string, chars, guard) {
|
|
string = toString(string);
|
|
if (string && (guard || chars === undefined)) {
|
|
return string.replace(reTrimStart, '');
|
|
}
|
|
if (!string || !(chars = baseToString(chars))) {
|
|
return string;
|
|
}
|
|
var strSymbols = stringToArray(string),
|
|
start = charsStartIndex(strSymbols, stringToArray(chars));
|
|
|
|
return castSlice(strSymbols, start).join('');
|
|
}
|
|
|
|
/**
|
|
* Truncates `string` if it's longer than the given maximum string length.
|
|
* The last characters of the truncated string are replaced with the omission
|
|
* string which defaults to "...".
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to truncate.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {number} [options.length=30] The maximum string length.
|
|
* @param {string} [options.omission='...'] The string to indicate text is omitted.
|
|
* @param {RegExp|string} [options.separator] The separator pattern to truncate to.
|
|
* @returns {string} Returns the truncated string.
|
|
* @example
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino');
|
|
* // => 'hi-diddly-ho there, neighbo...'
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino', {
|
|
* 'length': 24,
|
|
* 'separator': ' '
|
|
* });
|
|
* // => 'hi-diddly-ho there,...'
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino', {
|
|
* 'length': 24,
|
|
* 'separator': /,? +/
|
|
* });
|
|
* // => 'hi-diddly-ho there...'
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino', {
|
|
* 'omission': ' [...]'
|
|
* });
|
|
* // => 'hi-diddly-ho there, neig [...]'
|
|
*/
|
|
function truncate(string, options) {
|
|
var length = DEFAULT_TRUNC_LENGTH,
|
|
omission = DEFAULT_TRUNC_OMISSION;
|
|
|
|
if (isObject(options)) {
|
|
var separator = 'separator' in options ? options.separator : separator;
|
|
length = 'length' in options ? toInteger(options.length) : length;
|
|
omission = 'omission' in options ? baseToString(options.omission) : omission;
|
|
}
|
|
string = toString(string);
|
|
|
|
var strLength = string.length;
|
|
if (hasUnicode(string)) {
|
|
var strSymbols = stringToArray(string);
|
|
strLength = strSymbols.length;
|
|
}
|
|
if (length >= strLength) {
|
|
return string;
|
|
}
|
|
var end = length - stringSize(omission);
|
|
if (end < 1) {
|
|
return omission;
|
|
}
|
|
var result = strSymbols
|
|
? castSlice(strSymbols, 0, end).join('')
|
|
: string.slice(0, end);
|
|
|
|
if (separator === undefined) {
|
|
return result + omission;
|
|
}
|
|
if (strSymbols) {
|
|
end += (result.length - end);
|
|
}
|
|
if (isRegExp(separator)) {
|
|
if (string.slice(end).search(separator)) {
|
|
var match,
|
|
substring = result;
|
|
|
|
if (!separator.global) {
|
|
separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
|
|
}
|
|
separator.lastIndex = 0;
|
|
while ((match = separator.exec(substring))) {
|
|
var newEnd = match.index;
|
|
}
|
|
result = result.slice(0, newEnd === undefined ? end : newEnd);
|
|
}
|
|
} else if (string.indexOf(baseToString(separator), end) != end) {
|
|
var index = result.lastIndexOf(separator);
|
|
if (index > -1) {
|
|
result = result.slice(0, index);
|
|
}
|
|
}
|
|
return result + omission;
|
|
}
|
|
|
|
/**
|
|
* The inverse of `_.escape`; this method converts the HTML entities
|
|
* `&`, `<`, `>`, `"`, and `'` in `string` to
|
|
* their corresponding characters.
|
|
*
|
|
* **Note:** No other HTML entities are unescaped. To unescape additional
|
|
* HTML entities use a third-party library like [_he_](https://mths.be/he).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.6.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to unescape.
|
|
* @returns {string} Returns the unescaped string.
|
|
* @example
|
|
*
|
|
* _.unescape('fred, barney, & pebbles');
|
|
* // => 'fred, barney, & pebbles'
|
|
*/
|
|
function unescape(string) {
|
|
string = toString(string);
|
|
return (string && reHasEscapedHtml.test(string))
|
|
? string.replace(reEscapedHtml, unescapeHtmlChar)
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Converts `string`, as space separated words, to upper case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the upper cased string.
|
|
* @example
|
|
*
|
|
* _.upperCase('--foo-bar');
|
|
* // => 'FOO BAR'
|
|
*
|
|
* _.upperCase('fooBar');
|
|
* // => 'FOO BAR'
|
|
*
|
|
* _.upperCase('__foo_bar__');
|
|
* // => 'FOO BAR'
|
|
*/
|
|
var upperCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? ' ' : '') + word.toUpperCase();
|
|
});
|
|
|
|
/**
|
|
* Converts the first character of `string` to upper case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the converted string.
|
|
* @example
|
|
*
|
|
* _.upperFirst('fred');
|
|
* // => 'Fred'
|
|
*
|
|
* _.upperFirst('FRED');
|
|
* // => 'FRED'
|
|
*/
|
|
var upperFirst = createCaseFirst('toUpperCase');
|
|
|
|
/**
|
|
* Splits `string` into an array of its words.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {RegExp|string} [pattern] The pattern to match words.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the words of `string`.
|
|
* @example
|
|
*
|
|
* _.words('fred, barney, & pebbles');
|
|
* // => ['fred', 'barney', 'pebbles']
|
|
*
|
|
* _.words('fred, barney, & pebbles', /[^, ]+/g);
|
|
* // => ['fred', 'barney', '&', 'pebbles']
|
|
*/
|
|
function words(string, pattern, guard) {
|
|
string = toString(string);
|
|
pattern = guard ? undefined : pattern;
|
|
|
|
if (pattern === undefined) {
|
|
return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
|
|
}
|
|
return string.match(pattern) || [];
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Attempts to invoke `func`, returning either the result or the caught error
|
|
* object. Any additional arguments are provided to `func` when it's invoked.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {Function} func The function to attempt.
|
|
* @param {...*} [args] The arguments to invoke `func` with.
|
|
* @returns {*} Returns the `func` result or error object.
|
|
* @example
|
|
*
|
|
* // Avoid throwing errors for invalid selectors.
|
|
* var elements = _.attempt(function(selector) {
|
|
* return document.querySelectorAll(selector);
|
|
* }, '>_>');
|
|
*
|
|
* if (_.isError(elements)) {
|
|
* elements = [];
|
|
* }
|
|
*/
|
|
var attempt = baseRest(function(func, args) {
|
|
try {
|
|
return apply(func, undefined, args);
|
|
} catch (e) {
|
|
return isError(e) ? e : new Error(e);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Binds methods of an object to the object itself, overwriting the existing
|
|
* method.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of bound functions.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {Object} object The object to bind and assign the bound methods to.
|
|
* @param {...(string|string[])} methodNames The object method names to bind.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var view = {
|
|
* 'label': 'docs',
|
|
* 'click': function() {
|
|
* console.log('clicked ' + this.label);
|
|
* }
|
|
* };
|
|
*
|
|
* _.bindAll(view, ['click']);
|
|
* jQuery(element).on('click', view.click);
|
|
* // => Logs 'clicked docs' when clicked.
|
|
*/
|
|
var bindAll = flatRest(function(object, methodNames) {
|
|
arrayEach(methodNames, function(key) {
|
|
key = toKey(key);
|
|
baseAssignValue(object, key, bind(object[key], object));
|
|
});
|
|
return object;
|
|
});
|
|
|
|
/**
|
|
* Creates a function that iterates over `pairs` and invokes the corresponding
|
|
* function of the first predicate to return truthy. The predicate-function
|
|
* pairs are invoked with the `this` binding and arguments of the created
|
|
* function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {Array} pairs The predicate-function pairs.
|
|
* @returns {Function} Returns the new composite function.
|
|
* @example
|
|
*
|
|
* var func = _.cond([
|
|
* [_.matches({ 'a': 1 }), _.constant('matches A')],
|
|
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
|
|
* [_.stubTrue, _.constant('no match')]
|
|
* ]);
|
|
*
|
|
* func({ 'a': 1, 'b': 2 });
|
|
* // => 'matches A'
|
|
*
|
|
* func({ 'a': 0, 'b': 1 });
|
|
* // => 'matches B'
|
|
*
|
|
* func({ 'a': '1', 'b': '2' });
|
|
* // => 'no match'
|
|
*/
|
|
function cond(pairs) {
|
|
var length = pairs == null ? 0 : pairs.length,
|
|
toIteratee = getIteratee();
|
|
|
|
pairs = !length ? [] : arrayMap(pairs, function(pair) {
|
|
if (typeof pair[1] != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
return [toIteratee(pair[0]), pair[1]];
|
|
});
|
|
|
|
return baseRest(function(args) {
|
|
var index = -1;
|
|
while (++index < length) {
|
|
var pair = pairs[index];
|
|
if (apply(pair[0], this, args)) {
|
|
return apply(pair[1], this, args);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes the predicate properties of `source` with
|
|
* the corresponding property values of a given object, returning `true` if
|
|
* all predicates return truthy, else `false`.
|
|
*
|
|
* **Note:** The created function is equivalent to `_.conformsTo` with
|
|
* `source` partially applied.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {Function} Returns the new spec function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': 2, 'b': 1 },
|
|
* { 'a': 1, 'b': 2 }
|
|
* ];
|
|
*
|
|
* _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
|
|
* // => [{ 'a': 1, 'b': 2 }]
|
|
*/
|
|
function conforms(source) {
|
|
return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that returns `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Util
|
|
* @param {*} value The value to return from the new function.
|
|
* @returns {Function} Returns the new constant function.
|
|
* @example
|
|
*
|
|
* var objects = _.times(2, _.constant({ 'a': 1 }));
|
|
*
|
|
* console.log(objects);
|
|
* // => [{ 'a': 1 }, { 'a': 1 }]
|
|
*
|
|
* console.log(objects[0] === objects[1]);
|
|
* // => true
|
|
*/
|
|
function constant(value) {
|
|
return function() {
|
|
return value;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Checks `value` to determine whether a default value should be returned in
|
|
* its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
|
|
* or `undefined`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.14.0
|
|
* @category Util
|
|
* @param {*} value The value to check.
|
|
* @param {*} defaultValue The default value.
|
|
* @returns {*} Returns the resolved value.
|
|
* @example
|
|
*
|
|
* _.defaultTo(1, 10);
|
|
* // => 1
|
|
*
|
|
* _.defaultTo(undefined, 10);
|
|
* // => 10
|
|
*/
|
|
function defaultTo(value, defaultValue) {
|
|
return (value == null || value !== value) ? defaultValue : value;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that returns the result of invoking the given functions
|
|
* with the `this` binding of the created function, where each successive
|
|
* invocation is supplied the return value of the previous.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [funcs] The functions to invoke.
|
|
* @returns {Function} Returns the new composite function.
|
|
* @see _.flowRight
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var addSquare = _.flow([_.add, square]);
|
|
* addSquare(1, 2);
|
|
* // => 9
|
|
*/
|
|
var flow = createFlow();
|
|
|
|
/**
|
|
* This method is like `_.flow` except that it creates a function that
|
|
* invokes the given functions from right to left.
|
|
*
|
|
* @static
|
|
* @since 3.0.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [funcs] The functions to invoke.
|
|
* @returns {Function} Returns the new composite function.
|
|
* @see _.flow
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var addSquare = _.flowRight([square, _.add]);
|
|
* addSquare(1, 2);
|
|
* // => 9
|
|
*/
|
|
var flowRight = createFlow(true);
|
|
|
|
/**
|
|
* This method returns the first argument it receives.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {*} value Any value.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
*
|
|
* console.log(_.identity(object) === object);
|
|
* // => true
|
|
*/
|
|
function identity(value) {
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the arguments of the created
|
|
* function. If `func` is a property name, the created function returns the
|
|
* property value for a given element. If `func` is an array or object, the
|
|
* created function returns `true` for elements that contain the equivalent
|
|
* source properties, otherwise it returns `false`.
|
|
*
|
|
* @static
|
|
* @since 4.0.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {*} [func=_.identity] The value to convert to a callback.
|
|
* @returns {Function} Returns the callback.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': true },
|
|
* { 'user': 'fred', 'age': 40, 'active': false }
|
|
* ];
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
|
|
* // => [{ 'user': 'barney', 'age': 36, 'active': true }]
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.filter(users, _.iteratee(['user', 'fred']));
|
|
* // => [{ 'user': 'fred', 'age': 40 }]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.map(users, _.iteratee('user'));
|
|
* // => ['barney', 'fred']
|
|
*
|
|
* // Create custom iteratee shorthands.
|
|
* _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
|
|
* return !_.isRegExp(func) ? iteratee(func) : function(string) {
|
|
* return func.test(string);
|
|
* };
|
|
* });
|
|
*
|
|
* _.filter(['abc', 'def'], /ef/);
|
|
* // => ['def']
|
|
*/
|
|
function iteratee(func) {
|
|
return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a partial deep comparison between a given
|
|
* object and `source`, returning `true` if the given object has equivalent
|
|
* property values, else `false`.
|
|
*
|
|
* **Note:** The created function is equivalent to `_.isMatch` with `source`
|
|
* partially applied.
|
|
*
|
|
* Partial comparisons will match empty array and empty object `source`
|
|
* values against any array or object value, respectively. See `_.isEqual`
|
|
* for a list of supported value comparisons.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {Object} source The object of property values to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': 1, 'b': 2, 'c': 3 },
|
|
* { 'a': 4, 'b': 5, 'c': 6 }
|
|
* ];
|
|
*
|
|
* _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
|
|
* // => [{ 'a': 4, 'b': 5, 'c': 6 }]
|
|
*/
|
|
function matches(source) {
|
|
return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a partial deep comparison between the
|
|
* value at `path` of a given object to `srcValue`, returning `true` if the
|
|
* object value is equivalent, else `false`.
|
|
*
|
|
* **Note:** Partial comparisons will match empty array and empty object
|
|
* `srcValue` values against any array or object value, respectively. See
|
|
* `_.isEqual` for a list of supported value comparisons.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Util
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @param {*} srcValue The value to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': 1, 'b': 2, 'c': 3 },
|
|
* { 'a': 4, 'b': 5, 'c': 6 }
|
|
* ];
|
|
*
|
|
* _.find(objects, _.matchesProperty('a', 4));
|
|
* // => { 'a': 4, 'b': 5, 'c': 6 }
|
|
*/
|
|
function matchesProperty(path, srcValue) {
|
|
return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes the method at `path` of a given object.
|
|
* Any additional arguments are provided to the invoked method.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Util
|
|
* @param {Array|string} path The path of the method to invoke.
|
|
* @param {...*} [args] The arguments to invoke the method with.
|
|
* @returns {Function} Returns the new invoker function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': { 'b': _.constant(2) } },
|
|
* { 'a': { 'b': _.constant(1) } }
|
|
* ];
|
|
*
|
|
* _.map(objects, _.method('a.b'));
|
|
* // => [2, 1]
|
|
*
|
|
* _.map(objects, _.method(['a', 'b']));
|
|
* // => [2, 1]
|
|
*/
|
|
var method = baseRest(function(path, args) {
|
|
return function(object) {
|
|
return baseInvoke(object, path, args);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* The opposite of `_.method`; this method creates a function that invokes
|
|
* the method at a given path of `object`. Any additional arguments are
|
|
* provided to the invoked method.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Util
|
|
* @param {Object} object The object to query.
|
|
* @param {...*} [args] The arguments to invoke the method with.
|
|
* @returns {Function} Returns the new invoker function.
|
|
* @example
|
|
*
|
|
* var array = _.times(3, _.constant),
|
|
* object = { 'a': array, 'b': array, 'c': array };
|
|
*
|
|
* _.map(['a[2]', 'c[0]'], _.methodOf(object));
|
|
* // => [2, 0]
|
|
*
|
|
* _.map([['a', '2'], ['c', '0']], _.methodOf(object));
|
|
* // => [2, 0]
|
|
*/
|
|
var methodOf = baseRest(function(object, args) {
|
|
return function(path) {
|
|
return baseInvoke(object, path, args);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Adds all own enumerable string keyed function properties of a source
|
|
* object to the destination object. If `object` is a function, then methods
|
|
* are added to its prototype as well.
|
|
*
|
|
* **Note:** Use `_.runInContext` to create a pristine `lodash` function to
|
|
* avoid conflicts caused by modifying the original.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {Function|Object} [object=lodash] The destination object.
|
|
* @param {Object} source The object of functions to add.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {boolean} [options.chain=true] Specify whether mixins are chainable.
|
|
* @returns {Function|Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* function vowels(string) {
|
|
* return _.filter(string, function(v) {
|
|
* return /[aeiou]/i.test(v);
|
|
* });
|
|
* }
|
|
*
|
|
* _.mixin({ 'vowels': vowels });
|
|
* _.vowels('fred');
|
|
* // => ['e']
|
|
*
|
|
* _('fred').vowels().value();
|
|
* // => ['e']
|
|
*
|
|
* _.mixin({ 'vowels': vowels }, { 'chain': false });
|
|
* _('fred').vowels();
|
|
* // => ['e']
|
|
*/
|
|
function mixin(object, source, options) {
|
|
var props = keys(source),
|
|
methodNames = baseFunctions(source, props);
|
|
|
|
if (options == null &&
|
|
!(isObject(source) && (methodNames.length || !props.length))) {
|
|
options = source;
|
|
source = object;
|
|
object = this;
|
|
methodNames = baseFunctions(source, keys(source));
|
|
}
|
|
var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
|
|
isFunc = isFunction(object);
|
|
|
|
arrayEach(methodNames, function(methodName) {
|
|
var func = source[methodName];
|
|
object[methodName] = func;
|
|
if (isFunc) {
|
|
object.prototype[methodName] = function() {
|
|
var chainAll = this.__chain__;
|
|
if (chain || chainAll) {
|
|
var result = object(this.__wrapped__),
|
|
actions = result.__actions__ = copyArray(this.__actions__);
|
|
|
|
actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
|
|
result.__chain__ = chainAll;
|
|
return result;
|
|
}
|
|
return func.apply(object, arrayPush([this.value()], arguments));
|
|
};
|
|
}
|
|
});
|
|
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* Reverts the `_` variable to its previous value and returns a reference to
|
|
* the `lodash` function.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @returns {Function} Returns the `lodash` function.
|
|
* @example
|
|
*
|
|
* var lodash = _.noConflict();
|
|
*/
|
|
function noConflict() {
|
|
if (root._ === this) {
|
|
root._ = oldDash;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* This method returns `undefined`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.3.0
|
|
* @category Util
|
|
* @example
|
|
*
|
|
* _.times(2, _.noop);
|
|
* // => [undefined, undefined]
|
|
*/
|
|
function noop() {
|
|
// No operation performed.
|
|
}
|
|
|
|
/**
|
|
* Creates a function that gets the argument at index `n`. If `n` is negative,
|
|
* the nth argument from the end is returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {number} [n=0] The index of the argument to return.
|
|
* @returns {Function} Returns the new pass-thru function.
|
|
* @example
|
|
*
|
|
* var func = _.nthArg(1);
|
|
* func('a', 'b', 'c', 'd');
|
|
* // => 'b'
|
|
*
|
|
* var func = _.nthArg(-2);
|
|
* func('a', 'b', 'c', 'd');
|
|
* // => 'c'
|
|
*/
|
|
function nthArg(n) {
|
|
n = toInteger(n);
|
|
return baseRest(function(args) {
|
|
return baseNth(args, n);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `iteratees` with the arguments it receives
|
|
* and returns their results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [iteratees=[_.identity]]
|
|
* The iteratees to invoke.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var func = _.over([Math.max, Math.min]);
|
|
*
|
|
* func(1, 2, 3, 4);
|
|
* // => [4, 1]
|
|
*/
|
|
var over = createOver(arrayMap);
|
|
|
|
/**
|
|
* Creates a function that checks if **all** of the `predicates` return
|
|
* truthy when invoked with the arguments it receives.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [predicates=[_.identity]]
|
|
* The predicates to check.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var func = _.overEvery([Boolean, isFinite]);
|
|
*
|
|
* func('1');
|
|
* // => true
|
|
*
|
|
* func(null);
|
|
* // => false
|
|
*
|
|
* func(NaN);
|
|
* // => false
|
|
*/
|
|
var overEvery = createOver(arrayEvery);
|
|
|
|
/**
|
|
* Creates a function that checks if **any** of the `predicates` return
|
|
* truthy when invoked with the arguments it receives.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [predicates=[_.identity]]
|
|
* The predicates to check.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var func = _.overSome([Boolean, isFinite]);
|
|
*
|
|
* func('1');
|
|
* // => true
|
|
*
|
|
* func(null);
|
|
* // => true
|
|
*
|
|
* func(NaN);
|
|
* // => false
|
|
*/
|
|
var overSome = createOver(arraySome);
|
|
|
|
/**
|
|
* Creates a function that returns the value at `path` of a given object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Util
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @returns {Function} Returns the new accessor function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': { 'b': 2 } },
|
|
* { 'a': { 'b': 1 } }
|
|
* ];
|
|
*
|
|
* _.map(objects, _.property('a.b'));
|
|
* // => [2, 1]
|
|
*
|
|
* _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
|
|
* // => [1, 2]
|
|
*/
|
|
function property(path) {
|
|
return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
|
|
}
|
|
|
|
/**
|
|
* The opposite of `_.property`; this method creates a function that returns
|
|
* the value at a given path of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {Object} object The object to query.
|
|
* @returns {Function} Returns the new accessor function.
|
|
* @example
|
|
*
|
|
* var array = [0, 1, 2],
|
|
* object = { 'a': array, 'b': array, 'c': array };
|
|
*
|
|
* _.map(['a[2]', 'c[0]'], _.propertyOf(object));
|
|
* // => [2, 0]
|
|
*
|
|
* _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
|
|
* // => [2, 0]
|
|
*/
|
|
function propertyOf(object) {
|
|
return function(path) {
|
|
return object == null ? undefined : baseGet(object, path);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates an array of numbers (positive and/or negative) progressing from
|
|
* `start` up to, but not including, `end`. A step of `-1` is used if a negative
|
|
* `start` is specified without an `end` or `step`. If `end` is not specified,
|
|
* it's set to `start` with `start` then set to `0`.
|
|
*
|
|
* **Note:** JavaScript follows the IEEE-754 standard for resolving
|
|
* floating-point values which can produce unexpected results.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {number} [start=0] The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @param {number} [step=1] The value to increment or decrement by.
|
|
* @returns {Array} Returns the range of numbers.
|
|
* @see _.inRange, _.rangeRight
|
|
* @example
|
|
*
|
|
* _.range(4);
|
|
* // => [0, 1, 2, 3]
|
|
*
|
|
* _.range(-4);
|
|
* // => [0, -1, -2, -3]
|
|
*
|
|
* _.range(1, 5);
|
|
* // => [1, 2, 3, 4]
|
|
*
|
|
* _.range(0, 20, 5);
|
|
* // => [0, 5, 10, 15]
|
|
*
|
|
* _.range(0, -4, -1);
|
|
* // => [0, -1, -2, -3]
|
|
*
|
|
* _.range(1, 4, 0);
|
|
* // => [1, 1, 1]
|
|
*
|
|
* _.range(0);
|
|
* // => []
|
|
*/
|
|
var range = createRange();
|
|
|
|
/**
|
|
* This method is like `_.range` except that it populates values in
|
|
* descending order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {number} [start=0] The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @param {number} [step=1] The value to increment or decrement by.
|
|
* @returns {Array} Returns the range of numbers.
|
|
* @see _.inRange, _.range
|
|
* @example
|
|
*
|
|
* _.rangeRight(4);
|
|
* // => [3, 2, 1, 0]
|
|
*
|
|
* _.rangeRight(-4);
|
|
* // => [-3, -2, -1, 0]
|
|
*
|
|
* _.rangeRight(1, 5);
|
|
* // => [4, 3, 2, 1]
|
|
*
|
|
* _.rangeRight(0, 20, 5);
|
|
* // => [15, 10, 5, 0]
|
|
*
|
|
* _.rangeRight(0, -4, -1);
|
|
* // => [-3, -2, -1, 0]
|
|
*
|
|
* _.rangeRight(1, 4, 0);
|
|
* // => [1, 1, 1]
|
|
*
|
|
* _.rangeRight(0);
|
|
* // => []
|
|
*/
|
|
var rangeRight = createRange(true);
|
|
|
|
/**
|
|
* This method returns a new empty array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {Array} Returns the new empty array.
|
|
* @example
|
|
*
|
|
* var arrays = _.times(2, _.stubArray);
|
|
*
|
|
* console.log(arrays);
|
|
* // => [[], []]
|
|
*
|
|
* console.log(arrays[0] === arrays[1]);
|
|
* // => false
|
|
*/
|
|
function stubArray() {
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* This method returns `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {boolean} Returns `false`.
|
|
* @example
|
|
*
|
|
* _.times(2, _.stubFalse);
|
|
* // => [false, false]
|
|
*/
|
|
function stubFalse() {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* This method returns a new empty object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {Object} Returns the new empty object.
|
|
* @example
|
|
*
|
|
* var objects = _.times(2, _.stubObject);
|
|
*
|
|
* console.log(objects);
|
|
* // => [{}, {}]
|
|
*
|
|
* console.log(objects[0] === objects[1]);
|
|
* // => false
|
|
*/
|
|
function stubObject() {
|
|
return {};
|
|
}
|
|
|
|
/**
|
|
* This method returns an empty string.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {string} Returns the empty string.
|
|
* @example
|
|
*
|
|
* _.times(2, _.stubString);
|
|
* // => ['', '']
|
|
*/
|
|
function stubString() {
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* This method returns `true`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {boolean} Returns `true`.
|
|
* @example
|
|
*
|
|
* _.times(2, _.stubTrue);
|
|
* // => [true, true]
|
|
*/
|
|
function stubTrue() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Invokes the iteratee `n` times, returning an array of the results of
|
|
* each invocation. The iteratee is invoked with one argument; (index).
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the array of results.
|
|
* @example
|
|
*
|
|
* _.times(3, String);
|
|
* // => ['0', '1', '2']
|
|
*
|
|
* _.times(4, _.constant(0));
|
|
* // => [0, 0, 0, 0]
|
|
*/
|
|
function times(n, iteratee) {
|
|
n = toInteger(n);
|
|
if (n < 1 || n > MAX_SAFE_INTEGER) {
|
|
return [];
|
|
}
|
|
var index = MAX_ARRAY_LENGTH,
|
|
length = nativeMin(n, MAX_ARRAY_LENGTH);
|
|
|
|
iteratee = getIteratee(iteratee);
|
|
n -= MAX_ARRAY_LENGTH;
|
|
|
|
var result = baseTimes(length, iteratee);
|
|
while (++index < n) {
|
|
iteratee(index);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a property path array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {*} value The value to convert.
|
|
* @returns {Array} Returns the new property path array.
|
|
* @example
|
|
*
|
|
* _.toPath('a.b.c');
|
|
* // => ['a', 'b', 'c']
|
|
*
|
|
* _.toPath('a[0].b.c');
|
|
* // => ['a', '0', 'b', 'c']
|
|
*/
|
|
function toPath(value) {
|
|
if (isArray(value)) {
|
|
return arrayMap(value, toKey);
|
|
}
|
|
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
|
|
}
|
|
|
|
/**
|
|
* Generates a unique ID. If `prefix` is given, the ID is appended to it.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {string} [prefix=''] The value to prefix the ID with.
|
|
* @returns {string} Returns the unique ID.
|
|
* @example
|
|
*
|
|
* _.uniqueId('contact_');
|
|
* // => 'contact_104'
|
|
*
|
|
* _.uniqueId();
|
|
* // => '105'
|
|
*/
|
|
function uniqueId(prefix) {
|
|
var id = ++idCounter;
|
|
return toString(prefix) + id;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Adds two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.4.0
|
|
* @category Math
|
|
* @param {number} augend The first number in an addition.
|
|
* @param {number} addend The second number in an addition.
|
|
* @returns {number} Returns the total.
|
|
* @example
|
|
*
|
|
* _.add(6, 4);
|
|
* // => 10
|
|
*/
|
|
var add = createMathOperation(function(augend, addend) {
|
|
return augend + addend;
|
|
}, 0);
|
|
|
|
/**
|
|
* Computes `number` rounded up to `precision`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Math
|
|
* @param {number} number The number to round up.
|
|
* @param {number} [precision=0] The precision to round up to.
|
|
* @returns {number} Returns the rounded up number.
|
|
* @example
|
|
*
|
|
* _.ceil(4.006);
|
|
* // => 5
|
|
*
|
|
* _.ceil(6.004, 2);
|
|
* // => 6.01
|
|
*
|
|
* _.ceil(6040, -2);
|
|
* // => 6100
|
|
*/
|
|
var ceil = createRound('ceil');
|
|
|
|
/**
|
|
* Divide two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Math
|
|
* @param {number} dividend The first number in a division.
|
|
* @param {number} divisor The second number in a division.
|
|
* @returns {number} Returns the quotient.
|
|
* @example
|
|
*
|
|
* _.divide(6, 4);
|
|
* // => 1.5
|
|
*/
|
|
var divide = createMathOperation(function(dividend, divisor) {
|
|
return dividend / divisor;
|
|
}, 1);
|
|
|
|
/**
|
|
* Computes `number` rounded down to `precision`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Math
|
|
* @param {number} number The number to round down.
|
|
* @param {number} [precision=0] The precision to round down to.
|
|
* @returns {number} Returns the rounded down number.
|
|
* @example
|
|
*
|
|
* _.floor(4.006);
|
|
* // => 4
|
|
*
|
|
* _.floor(0.046, 2);
|
|
* // => 0.04
|
|
*
|
|
* _.floor(4060, -2);
|
|
* // => 4000
|
|
*/
|
|
var floor = createRound('floor');
|
|
|
|
/**
|
|
* Computes the maximum value of `array`. If `array` is empty or falsey,
|
|
* `undefined` is returned.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {*} Returns the maximum value.
|
|
* @example
|
|
*
|
|
* _.max([4, 2, 8, 6]);
|
|
* // => 8
|
|
*
|
|
* _.max([]);
|
|
* // => undefined
|
|
*/
|
|
function max(array) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, identity, baseGt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.max` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the criterion by which
|
|
* the value is ranked. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {*} Returns the maximum value.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 1 }, { 'n': 2 }];
|
|
*
|
|
* _.maxBy(objects, function(o) { return o.n; });
|
|
* // => { 'n': 2 }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.maxBy(objects, 'n');
|
|
* // => { 'n': 2 }
|
|
*/
|
|
function maxBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* Computes the mean of the values in `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {number} Returns the mean.
|
|
* @example
|
|
*
|
|
* _.mean([4, 2, 8, 6]);
|
|
* // => 5
|
|
*/
|
|
function mean(array) {
|
|
return baseMean(array, identity);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.mean` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the value to be averaged.
|
|
* The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the mean.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
|
|
*
|
|
* _.meanBy(objects, function(o) { return o.n; });
|
|
* // => 5
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.meanBy(objects, 'n');
|
|
* // => 5
|
|
*/
|
|
function meanBy(array, iteratee) {
|
|
return baseMean(array, getIteratee(iteratee, 2));
|
|
}
|
|
|
|
/**
|
|
* Computes the minimum value of `array`. If `array` is empty or falsey,
|
|
* `undefined` is returned.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {*} Returns the minimum value.
|
|
* @example
|
|
*
|
|
* _.min([4, 2, 8, 6]);
|
|
* // => 2
|
|
*
|
|
* _.min([]);
|
|
* // => undefined
|
|
*/
|
|
function min(array) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, identity, baseLt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.min` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the criterion by which
|
|
* the value is ranked. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {*} Returns the minimum value.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 1 }, { 'n': 2 }];
|
|
*
|
|
* _.minBy(objects, function(o) { return o.n; });
|
|
* // => { 'n': 1 }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.minBy(objects, 'n');
|
|
* // => { 'n': 1 }
|
|
*/
|
|
function minBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* Multiply two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Math
|
|
* @param {number} multiplier The first number in a multiplication.
|
|
* @param {number} multiplicand The second number in a multiplication.
|
|
* @returns {number} Returns the product.
|
|
* @example
|
|
*
|
|
* _.multiply(6, 4);
|
|
* // => 24
|
|
*/
|
|
var multiply = createMathOperation(function(multiplier, multiplicand) {
|
|
return multiplier * multiplicand;
|
|
}, 1);
|
|
|
|
/**
|
|
* Computes `number` rounded to `precision`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Math
|
|
* @param {number} number The number to round.
|
|
* @param {number} [precision=0] The precision to round to.
|
|
* @returns {number} Returns the rounded number.
|
|
* @example
|
|
*
|
|
* _.round(4.006);
|
|
* // => 4
|
|
*
|
|
* _.round(4.006, 2);
|
|
* // => 4.01
|
|
*
|
|
* _.round(4060, -2);
|
|
* // => 4100
|
|
*/
|
|
var round = createRound('round');
|
|
|
|
/**
|
|
* Subtract two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {number} minuend The first number in a subtraction.
|
|
* @param {number} subtrahend The second number in a subtraction.
|
|
* @returns {number} Returns the difference.
|
|
* @example
|
|
*
|
|
* _.subtract(6, 4);
|
|
* // => 2
|
|
*/
|
|
var subtract = createMathOperation(function(minuend, subtrahend) {
|
|
return minuend - subtrahend;
|
|
}, 0);
|
|
|
|
/**
|
|
* Computes the sum of the values in `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.4.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {number} Returns the sum.
|
|
* @example
|
|
*
|
|
* _.sum([4, 2, 8, 6]);
|
|
* // => 20
|
|
*/
|
|
function sum(array) {
|
|
return (array && array.length)
|
|
? baseSum(array, identity)
|
|
: 0;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sum` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the value to be summed.
|
|
* The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the sum.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
|
|
*
|
|
* _.sumBy(objects, function(o) { return o.n; });
|
|
* // => 20
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.sumBy(objects, 'n');
|
|
* // => 20
|
|
*/
|
|
function sumBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseSum(array, getIteratee(iteratee, 2))
|
|
: 0;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
// Add methods that return wrapped values in chain sequences.
|
|
lodash.after = after;
|
|
lodash.ary = ary;
|
|
lodash.assign = assign;
|
|
lodash.assignIn = assignIn;
|
|
lodash.assignInWith = assignInWith;
|
|
lodash.assignWith = assignWith;
|
|
lodash.at = at;
|
|
lodash.before = before;
|
|
lodash.bind = bind;
|
|
lodash.bindAll = bindAll;
|
|
lodash.bindKey = bindKey;
|
|
lodash.castArray = castArray;
|
|
lodash.chain = chain;
|
|
lodash.chunk = chunk;
|
|
lodash.compact = compact;
|
|
lodash.concat = concat;
|
|
lodash.cond = cond;
|
|
lodash.conforms = conforms;
|
|
lodash.constant = constant;
|
|
lodash.countBy = countBy;
|
|
lodash.create = create;
|
|
lodash.curry = curry;
|
|
lodash.curryRight = curryRight;
|
|
lodash.debounce = debounce;
|
|
lodash.defaults = defaults;
|
|
lodash.defaultsDeep = defaultsDeep;
|
|
lodash.defer = defer;
|
|
lodash.delay = delay;
|
|
lodash.difference = difference;
|
|
lodash.differenceBy = differenceBy;
|
|
lodash.differenceWith = differenceWith;
|
|
lodash.drop = drop;
|
|
lodash.dropRight = dropRight;
|
|
lodash.dropRightWhile = dropRightWhile;
|
|
lodash.dropWhile = dropWhile;
|
|
lodash.fill = fill;
|
|
lodash.filter = filter;
|
|
lodash.flatMap = flatMap;
|
|
lodash.flatMapDeep = flatMapDeep;
|
|
lodash.flatMapDepth = flatMapDepth;
|
|
lodash.flatten = flatten;
|
|
lodash.flattenDeep = flattenDeep;
|
|
lodash.flattenDepth = flattenDepth;
|
|
lodash.flip = flip;
|
|
lodash.flow = flow;
|
|
lodash.flowRight = flowRight;
|
|
lodash.fromPairs = fromPairs;
|
|
lodash.functions = functions;
|
|
lodash.functionsIn = functionsIn;
|
|
lodash.groupBy = groupBy;
|
|
lodash.initial = initial;
|
|
lodash.intersection = intersection;
|
|
lodash.intersectionBy = intersectionBy;
|
|
lodash.intersectionWith = intersectionWith;
|
|
lodash.invert = invert;
|
|
lodash.invertBy = invertBy;
|
|
lodash.invokeMap = invokeMap;
|
|
lodash.iteratee = iteratee;
|
|
lodash.keyBy = keyBy;
|
|
lodash.keys = keys;
|
|
lodash.keysIn = keysIn;
|
|
lodash.map = map;
|
|
lodash.mapKeys = mapKeys;
|
|
lodash.mapValues = mapValues;
|
|
lodash.matches = matches;
|
|
lodash.matchesProperty = matchesProperty;
|
|
lodash.memoize = memoize;
|
|
lodash.merge = merge;
|
|
lodash.mergeWith = mergeWith;
|
|
lodash.method = method;
|
|
lodash.methodOf = methodOf;
|
|
lodash.mixin = mixin;
|
|
lodash.negate = negate;
|
|
lodash.nthArg = nthArg;
|
|
lodash.omit = omit;
|
|
lodash.omitBy = omitBy;
|
|
lodash.once = once;
|
|
lodash.orderBy = orderBy;
|
|
lodash.over = over;
|
|
lodash.overArgs = overArgs;
|
|
lodash.overEvery = overEvery;
|
|
lodash.overSome = overSome;
|
|
lodash.partial = partial;
|
|
lodash.partialRight = partialRight;
|
|
lodash.partition = partition;
|
|
lodash.pick = pick;
|
|
lodash.pickBy = pickBy;
|
|
lodash.property = property;
|
|
lodash.propertyOf = propertyOf;
|
|
lodash.pull = pull;
|
|
lodash.pullAll = pullAll;
|
|
lodash.pullAllBy = pullAllBy;
|
|
lodash.pullAllWith = pullAllWith;
|
|
lodash.pullAt = pullAt;
|
|
lodash.range = range;
|
|
lodash.rangeRight = rangeRight;
|
|
lodash.rearg = rearg;
|
|
lodash.reject = reject;
|
|
lodash.remove = remove;
|
|
lodash.rest = rest;
|
|
lodash.reverse = reverse;
|
|
lodash.sampleSize = sampleSize;
|
|
lodash.set = set;
|
|
lodash.setWith = setWith;
|
|
lodash.shuffle = shuffle;
|
|
lodash.slice = slice;
|
|
lodash.sortBy = sortBy;
|
|
lodash.sortedUniq = sortedUniq;
|
|
lodash.sortedUniqBy = sortedUniqBy;
|
|
lodash.split = split;
|
|
lodash.spread = spread;
|
|
lodash.tail = tail;
|
|
lodash.take = take;
|
|
lodash.takeRight = takeRight;
|
|
lodash.takeRightWhile = takeRightWhile;
|
|
lodash.takeWhile = takeWhile;
|
|
lodash.tap = tap;
|
|
lodash.throttle = throttle;
|
|
lodash.thru = thru;
|
|
lodash.toArray = toArray;
|
|
lodash.toPairs = toPairs;
|
|
lodash.toPairsIn = toPairsIn;
|
|
lodash.toPath = toPath;
|
|
lodash.toPlainObject = toPlainObject;
|
|
lodash.transform = transform;
|
|
lodash.unary = unary;
|
|
lodash.union = union;
|
|
lodash.unionBy = unionBy;
|
|
lodash.unionWith = unionWith;
|
|
lodash.uniq = uniq;
|
|
lodash.uniqBy = uniqBy;
|
|
lodash.uniqWith = uniqWith;
|
|
lodash.unset = unset;
|
|
lodash.unzip = unzip;
|
|
lodash.unzipWith = unzipWith;
|
|
lodash.update = update;
|
|
lodash.updateWith = updateWith;
|
|
lodash.values = values;
|
|
lodash.valuesIn = valuesIn;
|
|
lodash.without = without;
|
|
lodash.words = words;
|
|
lodash.wrap = wrap;
|
|
lodash.xor = xor;
|
|
lodash.xorBy = xorBy;
|
|
lodash.xorWith = xorWith;
|
|
lodash.zip = zip;
|
|
lodash.zipObject = zipObject;
|
|
lodash.zipObjectDeep = zipObjectDeep;
|
|
lodash.zipWith = zipWith;
|
|
|
|
// Add aliases.
|
|
lodash.entries = toPairs;
|
|
lodash.entriesIn = toPairsIn;
|
|
lodash.extend = assignIn;
|
|
lodash.extendWith = assignInWith;
|
|
|
|
// Add methods to `lodash.prototype`.
|
|
mixin(lodash, lodash);
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
// Add methods that return unwrapped values in chain sequences.
|
|
lodash.add = add;
|
|
lodash.attempt = attempt;
|
|
lodash.camelCase = camelCase;
|
|
lodash.capitalize = capitalize;
|
|
lodash.ceil = ceil;
|
|
lodash.clamp = clamp;
|
|
lodash.clone = clone;
|
|
lodash.cloneDeep = cloneDeep;
|
|
lodash.cloneDeepWith = cloneDeepWith;
|
|
lodash.cloneWith = cloneWith;
|
|
lodash.conformsTo = conformsTo;
|
|
lodash.deburr = deburr;
|
|
lodash.defaultTo = defaultTo;
|
|
lodash.divide = divide;
|
|
lodash.endsWith = endsWith;
|
|
lodash.eq = eq;
|
|
lodash.escape = escape;
|
|
lodash.escapeRegExp = escapeRegExp;
|
|
lodash.every = every;
|
|
lodash.find = find;
|
|
lodash.findIndex = findIndex;
|
|
lodash.findKey = findKey;
|
|
lodash.findLast = findLast;
|
|
lodash.findLastIndex = findLastIndex;
|
|
lodash.findLastKey = findLastKey;
|
|
lodash.floor = floor;
|
|
lodash.forEach = forEach;
|
|
lodash.forEachRight = forEachRight;
|
|
lodash.forIn = forIn;
|
|
lodash.forInRight = forInRight;
|
|
lodash.forOwn = forOwn;
|
|
lodash.forOwnRight = forOwnRight;
|
|
lodash.get = get;
|
|
lodash.gt = gt;
|
|
lodash.gte = gte;
|
|
lodash.has = has;
|
|
lodash.hasIn = hasIn;
|
|
lodash.head = head;
|
|
lodash.identity = identity;
|
|
lodash.includes = includes;
|
|
lodash.indexOf = indexOf;
|
|
lodash.inRange = inRange;
|
|
lodash.invoke = invoke;
|
|
lodash.isArguments = isArguments;
|
|
lodash.isArray = isArray;
|
|
lodash.isArrayBuffer = isArrayBuffer;
|
|
lodash.isArrayLike = isArrayLike;
|
|
lodash.isArrayLikeObject = isArrayLikeObject;
|
|
lodash.isBoolean = isBoolean;
|
|
lodash.isBuffer = isBuffer;
|
|
lodash.isDate = isDate;
|
|
lodash.isElement = isElement;
|
|
lodash.isEmpty = isEmpty;
|
|
lodash.isEqual = isEqual;
|
|
lodash.isEqualWith = isEqualWith;
|
|
lodash.isError = isError;
|
|
lodash.isFinite = isFinite;
|
|
lodash.isFunction = isFunction;
|
|
lodash.isInteger = isInteger;
|
|
lodash.isLength = isLength;
|
|
lodash.isMap = isMap;
|
|
lodash.isMatch = isMatch;
|
|
lodash.isMatchWith = isMatchWith;
|
|
lodash.isNaN = isNaN;
|
|
lodash.isNative = isNative;
|
|
lodash.isNil = isNil;
|
|
lodash.isNull = isNull;
|
|
lodash.isNumber = isNumber;
|
|
lodash.isObject = isObject;
|
|
lodash.isObjectLike = isObjectLike;
|
|
lodash.isPlainObject = isPlainObject;
|
|
lodash.isRegExp = isRegExp;
|
|
lodash.isSafeInteger = isSafeInteger;
|
|
lodash.isSet = isSet;
|
|
lodash.isString = isString;
|
|
lodash.isSymbol = isSymbol;
|
|
lodash.isTypedArray = isTypedArray;
|
|
lodash.isUndefined = isUndefined;
|
|
lodash.isWeakMap = isWeakMap;
|
|
lodash.isWeakSet = isWeakSet;
|
|
lodash.join = join;
|
|
lodash.kebabCase = kebabCase;
|
|
lodash.last = last;
|
|
lodash.lastIndexOf = lastIndexOf;
|
|
lodash.lowerCase = lowerCase;
|
|
lodash.lowerFirst = lowerFirst;
|
|
lodash.lt = lt;
|
|
lodash.lte = lte;
|
|
lodash.max = max;
|
|
lodash.maxBy = maxBy;
|
|
lodash.mean = mean;
|
|
lodash.meanBy = meanBy;
|
|
lodash.min = min;
|
|
lodash.minBy = minBy;
|
|
lodash.stubArray = stubArray;
|
|
lodash.stubFalse = stubFalse;
|
|
lodash.stubObject = stubObject;
|
|
lodash.stubString = stubString;
|
|
lodash.stubTrue = stubTrue;
|
|
lodash.multiply = multiply;
|
|
lodash.nth = nth;
|
|
lodash.noConflict = noConflict;
|
|
lodash.noop = noop;
|
|
lodash.now = now;
|
|
lodash.pad = pad;
|
|
lodash.padEnd = padEnd;
|
|
lodash.padStart = padStart;
|
|
lodash.parseInt = parseInt;
|
|
lodash.random = random;
|
|
lodash.reduce = reduce;
|
|
lodash.reduceRight = reduceRight;
|
|
lodash.repeat = repeat;
|
|
lodash.replace = replace;
|
|
lodash.result = result;
|
|
lodash.round = round;
|
|
lodash.runInContext = runInContext;
|
|
lodash.sample = sample;
|
|
lodash.size = size;
|
|
lodash.snakeCase = snakeCase;
|
|
lodash.some = some;
|
|
lodash.sortedIndex = sortedIndex;
|
|
lodash.sortedIndexBy = sortedIndexBy;
|
|
lodash.sortedIndexOf = sortedIndexOf;
|
|
lodash.sortedLastIndex = sortedLastIndex;
|
|
lodash.sortedLastIndexBy = sortedLastIndexBy;
|
|
lodash.sortedLastIndexOf = sortedLastIndexOf;
|
|
lodash.startCase = startCase;
|
|
lodash.startsWith = startsWith;
|
|
lodash.subtract = subtract;
|
|
lodash.sum = sum;
|
|
lodash.sumBy = sumBy;
|
|
lodash.template = template;
|
|
lodash.times = times;
|
|
lodash.toFinite = toFinite;
|
|
lodash.toInteger = toInteger;
|
|
lodash.toLength = toLength;
|
|
lodash.toLower = toLower;
|
|
lodash.toNumber = toNumber;
|
|
lodash.toSafeInteger = toSafeInteger;
|
|
lodash.toString = toString;
|
|
lodash.toUpper = toUpper;
|
|
lodash.trim = trim;
|
|
lodash.trimEnd = trimEnd;
|
|
lodash.trimStart = trimStart;
|
|
lodash.truncate = truncate;
|
|
lodash.unescape = unescape;
|
|
lodash.uniqueId = uniqueId;
|
|
lodash.upperCase = upperCase;
|
|
lodash.upperFirst = upperFirst;
|
|
|
|
// Add aliases.
|
|
lodash.each = forEach;
|
|
lodash.eachRight = forEachRight;
|
|
lodash.first = head;
|
|
|
|
mixin(lodash, (function() {
|
|
var source = {};
|
|
baseForOwn(lodash, function(func, methodName) {
|
|
if (!hasOwnProperty.call(lodash.prototype, methodName)) {
|
|
source[methodName] = func;
|
|
}
|
|
});
|
|
return source;
|
|
}()), { 'chain': false });
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* The semantic version number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @type {string}
|
|
*/
|
|
lodash.VERSION = VERSION;
|
|
|
|
// Assign default placeholders.
|
|
arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
|
|
lodash[methodName].placeholder = lodash;
|
|
});
|
|
|
|
// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
|
|
arrayEach(['drop', 'take'], function(methodName, index) {
|
|
LazyWrapper.prototype[methodName] = function(n) {
|
|
n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
|
|
|
|
var result = (this.__filtered__ && !index)
|
|
? new LazyWrapper(this)
|
|
: this.clone();
|
|
|
|
if (result.__filtered__) {
|
|
result.__takeCount__ = nativeMin(n, result.__takeCount__);
|
|
} else {
|
|
result.__views__.push({
|
|
'size': nativeMin(n, MAX_ARRAY_LENGTH),
|
|
'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
|
|
});
|
|
}
|
|
return result;
|
|
};
|
|
|
|
LazyWrapper.prototype[methodName + 'Right'] = function(n) {
|
|
return this.reverse()[methodName](n).reverse();
|
|
};
|
|
});
|
|
|
|
// Add `LazyWrapper` methods that accept an `iteratee` value.
|
|
arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
|
|
var type = index + 1,
|
|
isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
|
|
|
|
LazyWrapper.prototype[methodName] = function(iteratee) {
|
|
var result = this.clone();
|
|
result.__iteratees__.push({
|
|
'iteratee': getIteratee(iteratee, 3),
|
|
'type': type
|
|
});
|
|
result.__filtered__ = result.__filtered__ || isFilter;
|
|
return result;
|
|
};
|
|
});
|
|
|
|
// Add `LazyWrapper` methods for `_.head` and `_.last`.
|
|
arrayEach(['head', 'last'], function(methodName, index) {
|
|
var takeName = 'take' + (index ? 'Right' : '');
|
|
|
|
LazyWrapper.prototype[methodName] = function() {
|
|
return this[takeName](1).value()[0];
|
|
};
|
|
});
|
|
|
|
// Add `LazyWrapper` methods for `_.initial` and `_.tail`.
|
|
arrayEach(['initial', 'tail'], function(methodName, index) {
|
|
var dropName = 'drop' + (index ? '' : 'Right');
|
|
|
|
LazyWrapper.prototype[methodName] = function() {
|
|
return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
|
|
};
|
|
});
|
|
|
|
LazyWrapper.prototype.compact = function() {
|
|
return this.filter(identity);
|
|
};
|
|
|
|
LazyWrapper.prototype.find = function(predicate) {
|
|
return this.filter(predicate).head();
|
|
};
|
|
|
|
LazyWrapper.prototype.findLast = function(predicate) {
|
|
return this.reverse().find(predicate);
|
|
};
|
|
|
|
LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
|
|
if (typeof path == 'function') {
|
|
return new LazyWrapper(this);
|
|
}
|
|
return this.map(function(value) {
|
|
return baseInvoke(value, path, args);
|
|
});
|
|
});
|
|
|
|
LazyWrapper.prototype.reject = function(predicate) {
|
|
return this.filter(negate(getIteratee(predicate)));
|
|
};
|
|
|
|
LazyWrapper.prototype.slice = function(start, end) {
|
|
start = toInteger(start);
|
|
|
|
var result = this;
|
|
if (result.__filtered__ && (start > 0 || end < 0)) {
|
|
return new LazyWrapper(result);
|
|
}
|
|
if (start < 0) {
|
|
result = result.takeRight(-start);
|
|
} else if (start) {
|
|
result = result.drop(start);
|
|
}
|
|
if (end !== undefined) {
|
|
end = toInteger(end);
|
|
result = end < 0 ? result.dropRight(-end) : result.take(end - start);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
LazyWrapper.prototype.takeRightWhile = function(predicate) {
|
|
return this.reverse().takeWhile(predicate).reverse();
|
|
};
|
|
|
|
LazyWrapper.prototype.toArray = function() {
|
|
return this.take(MAX_ARRAY_LENGTH);
|
|
};
|
|
|
|
// Add `LazyWrapper` methods to `lodash.prototype`.
|
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
|
var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
|
|
isTaker = /^(?:head|last)$/.test(methodName),
|
|
lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
|
|
retUnwrapped = isTaker || /^find/.test(methodName);
|
|
|
|
if (!lodashFunc) {
|
|
return;
|
|
}
|
|
lodash.prototype[methodName] = function() {
|
|
var value = this.__wrapped__,
|
|
args = isTaker ? [1] : arguments,
|
|
isLazy = value instanceof LazyWrapper,
|
|
iteratee = args[0],
|
|
useLazy = isLazy || isArray(value);
|
|
|
|
var interceptor = function(value) {
|
|
var result = lodashFunc.apply(lodash, arrayPush([value], args));
|
|
return (isTaker && chainAll) ? result[0] : result;
|
|
};
|
|
|
|
if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
|
|
// Avoid lazy use if the iteratee has a "length" value other than `1`.
|
|
isLazy = useLazy = false;
|
|
}
|
|
var chainAll = this.__chain__,
|
|
isHybrid = !!this.__actions__.length,
|
|
isUnwrapped = retUnwrapped && !chainAll,
|
|
onlyLazy = isLazy && !isHybrid;
|
|
|
|
if (!retUnwrapped && useLazy) {
|
|
value = onlyLazy ? value : new LazyWrapper(this);
|
|
var result = func.apply(value, args);
|
|
result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
|
|
return new LodashWrapper(result, chainAll);
|
|
}
|
|
if (isUnwrapped && onlyLazy) {
|
|
return func.apply(this, args);
|
|
}
|
|
result = this.thru(interceptor);
|
|
return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
|
|
};
|
|
});
|
|
|
|
// Add `Array` methods to `lodash.prototype`.
|
|
arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
|
|
var func = arrayProto[methodName],
|
|
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
|
|
retUnwrapped = /^(?:pop|shift)$/.test(methodName);
|
|
|
|
lodash.prototype[methodName] = function() {
|
|
var args = arguments;
|
|
if (retUnwrapped && !this.__chain__) {
|
|
var value = this.value();
|
|
return func.apply(isArray(value) ? value : [], args);
|
|
}
|
|
return this[chainName](function(value) {
|
|
return func.apply(isArray(value) ? value : [], args);
|
|
});
|
|
};
|
|
});
|
|
|
|
// Map minified method names to their real names.
|
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
|
var lodashFunc = lodash[methodName];
|
|
if (lodashFunc) {
|
|
var key = lodashFunc.name + '';
|
|
if (!hasOwnProperty.call(realNames, key)) {
|
|
realNames[key] = [];
|
|
}
|
|
realNames[key].push({ 'name': methodName, 'func': lodashFunc });
|
|
}
|
|
});
|
|
|
|
realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
|
|
'name': 'wrapper',
|
|
'func': undefined
|
|
}];
|
|
|
|
// Add methods to `LazyWrapper`.
|
|
LazyWrapper.prototype.clone = lazyClone;
|
|
LazyWrapper.prototype.reverse = lazyReverse;
|
|
LazyWrapper.prototype.value = lazyValue;
|
|
|
|
// Add chain sequence methods to the `lodash` wrapper.
|
|
lodash.prototype.at = wrapperAt;
|
|
lodash.prototype.chain = wrapperChain;
|
|
lodash.prototype.commit = wrapperCommit;
|
|
lodash.prototype.next = wrapperNext;
|
|
lodash.prototype.plant = wrapperPlant;
|
|
lodash.prototype.reverse = wrapperReverse;
|
|
lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
|
|
|
|
// Add lazy aliases.
|
|
lodash.prototype.first = lodash.prototype.head;
|
|
|
|
if (symIterator) {
|
|
lodash.prototype[symIterator] = wrapperToIterator;
|
|
}
|
|
return lodash;
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
// Export lodash.
|
|
var _ = runInContext();
|
|
|
|
// Some AMD build optimizers, like r.js, check for condition patterns like:
|
|
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
|
|
// Expose Lodash on the global object to prevent errors when Lodash is
|
|
// loaded by a script tag in the presence of an AMD loader.
|
|
// See http://requirejs.org/docs/errors.html#mismatch for more details.
|
|
// Use `_.noConflict` to remove Lodash from the global object.
|
|
root._ = _;
|
|
|
|
// Define as an anonymous module so, through path mapping, it can be
|
|
// referenced as the "underscore" module.
|
|
define(function() {
|
|
return _;
|
|
});
|
|
}
|
|
// Check for `exports` after `define` in case a build optimizer adds it.
|
|
else if (freeModule) {
|
|
// Export for Node.js.
|
|
(freeModule.exports = _)._ = _;
|
|
// Export for CommonJS support.
|
|
freeExports._ = _;
|
|
}
|
|
else {
|
|
// Export to the global object.
|
|
root._ = _;
|
|
}
|
|
}.call(this));
|
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{}],40:[function(require,module,exports){
|
|
'use strict'
|
|
var inherits = require('inherits')
|
|
var HashBase = require('hash-base')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var ARRAY16 = new Array(16)
|
|
|
|
function MD5 () {
|
|
HashBase.call(this, 64)
|
|
|
|
// state
|
|
this._a = 0x67452301
|
|
this._b = 0xefcdab89
|
|
this._c = 0x98badcfe
|
|
this._d = 0x10325476
|
|
}
|
|
|
|
inherits(MD5, HashBase)
|
|
|
|
MD5.prototype._update = function () {
|
|
var M = ARRAY16
|
|
for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4)
|
|
|
|
var a = this._a
|
|
var b = this._b
|
|
var c = this._c
|
|
var d = this._d
|
|
|
|
a = fnF(a, b, c, d, M[0], 0xd76aa478, 7)
|
|
d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12)
|
|
c = fnF(c, d, a, b, M[2], 0x242070db, 17)
|
|
b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22)
|
|
a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7)
|
|
d = fnF(d, a, b, c, M[5], 0x4787c62a, 12)
|
|
c = fnF(c, d, a, b, M[6], 0xa8304613, 17)
|
|
b = fnF(b, c, d, a, M[7], 0xfd469501, 22)
|
|
a = fnF(a, b, c, d, M[8], 0x698098d8, 7)
|
|
d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12)
|
|
c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17)
|
|
b = fnF(b, c, d, a, M[11], 0x895cd7be, 22)
|
|
a = fnF(a, b, c, d, M[12], 0x6b901122, 7)
|
|
d = fnF(d, a, b, c, M[13], 0xfd987193, 12)
|
|
c = fnF(c, d, a, b, M[14], 0xa679438e, 17)
|
|
b = fnF(b, c, d, a, M[15], 0x49b40821, 22)
|
|
|
|
a = fnG(a, b, c, d, M[1], 0xf61e2562, 5)
|
|
d = fnG(d, a, b, c, M[6], 0xc040b340, 9)
|
|
c = fnG(c, d, a, b, M[11], 0x265e5a51, 14)
|
|
b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20)
|
|
a = fnG(a, b, c, d, M[5], 0xd62f105d, 5)
|
|
d = fnG(d, a, b, c, M[10], 0x02441453, 9)
|
|
c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14)
|
|
b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20)
|
|
a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5)
|
|
d = fnG(d, a, b, c, M[14], 0xc33707d6, 9)
|
|
c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14)
|
|
b = fnG(b, c, d, a, M[8], 0x455a14ed, 20)
|
|
a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5)
|
|
d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9)
|
|
c = fnG(c, d, a, b, M[7], 0x676f02d9, 14)
|
|
b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20)
|
|
|
|
a = fnH(a, b, c, d, M[5], 0xfffa3942, 4)
|
|
d = fnH(d, a, b, c, M[8], 0x8771f681, 11)
|
|
c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16)
|
|
b = fnH(b, c, d, a, M[14], 0xfde5380c, 23)
|
|
a = fnH(a, b, c, d, M[1], 0xa4beea44, 4)
|
|
d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11)
|
|
c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16)
|
|
b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23)
|
|
a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4)
|
|
d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11)
|
|
c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16)
|
|
b = fnH(b, c, d, a, M[6], 0x04881d05, 23)
|
|
a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4)
|
|
d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11)
|
|
c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16)
|
|
b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23)
|
|
|
|
a = fnI(a, b, c, d, M[0], 0xf4292244, 6)
|
|
d = fnI(d, a, b, c, M[7], 0x432aff97, 10)
|
|
c = fnI(c, d, a, b, M[14], 0xab9423a7, 15)
|
|
b = fnI(b, c, d, a, M[5], 0xfc93a039, 21)
|
|
a = fnI(a, b, c, d, M[12], 0x655b59c3, 6)
|
|
d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10)
|
|
c = fnI(c, d, a, b, M[10], 0xffeff47d, 15)
|
|
b = fnI(b, c, d, a, M[1], 0x85845dd1, 21)
|
|
a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6)
|
|
d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10)
|
|
c = fnI(c, d, a, b, M[6], 0xa3014314, 15)
|
|
b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21)
|
|
a = fnI(a, b, c, d, M[4], 0xf7537e82, 6)
|
|
d = fnI(d, a, b, c, M[11], 0xbd3af235, 10)
|
|
c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15)
|
|
b = fnI(b, c, d, a, M[9], 0xeb86d391, 21)
|
|
|
|
this._a = (this._a + a) | 0
|
|
this._b = (this._b + b) | 0
|
|
this._c = (this._c + c) | 0
|
|
this._d = (this._d + d) | 0
|
|
}
|
|
|
|
MD5.prototype._digest = function () {
|
|
// create padding and handle blocks
|
|
this._block[this._blockOffset++] = 0x80
|
|
if (this._blockOffset > 56) {
|
|
this._block.fill(0, this._blockOffset, 64)
|
|
this._update()
|
|
this._blockOffset = 0
|
|
}
|
|
|
|
this._block.fill(0, this._blockOffset, 56)
|
|
this._block.writeUInt32LE(this._length[0], 56)
|
|
this._block.writeUInt32LE(this._length[1], 60)
|
|
this._update()
|
|
|
|
// produce result
|
|
var buffer = Buffer.allocUnsafe(16)
|
|
buffer.writeInt32LE(this._a, 0)
|
|
buffer.writeInt32LE(this._b, 4)
|
|
buffer.writeInt32LE(this._c, 8)
|
|
buffer.writeInt32LE(this._d, 12)
|
|
return buffer
|
|
}
|
|
|
|
function rotl (x, n) {
|
|
return (x << n) | (x >>> (32 - n))
|
|
}
|
|
|
|
function fnF (a, b, c, d, m, k, s) {
|
|
return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0
|
|
}
|
|
|
|
function fnG (a, b, c, d, m, k, s) {
|
|
return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0
|
|
}
|
|
|
|
function fnH (a, b, c, d, m, k, s) {
|
|
return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0
|
|
}
|
|
|
|
function fnI (a, b, c, d, m, k, s) {
|
|
return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0
|
|
}
|
|
|
|
module.exports = MD5
|
|
|
|
},{"hash-base":24,"inherits":38,"safe-buffer":85}],41:[function(require,module,exports){
|
|
module.exports = assert;
|
|
|
|
function assert(val, msg) {
|
|
if (!val)
|
|
throw new Error(msg || 'Assertion failed');
|
|
}
|
|
|
|
assert.equal = function assertEqual(l, r, msg) {
|
|
if (l != r)
|
|
throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
|
|
};
|
|
|
|
},{}],42:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
var utils = exports;
|
|
|
|
function toArray(msg, enc) {
|
|
if (Array.isArray(msg))
|
|
return msg.slice();
|
|
if (!msg)
|
|
return [];
|
|
var res = [];
|
|
if (typeof msg !== 'string') {
|
|
for (var i = 0; i < msg.length; i++)
|
|
res[i] = msg[i] | 0;
|
|
return res;
|
|
}
|
|
if (enc === 'hex') {
|
|
msg = msg.replace(/[^a-z0-9]+/ig, '');
|
|
if (msg.length % 2 !== 0)
|
|
msg = '0' + msg;
|
|
for (var i = 0; i < msg.length; i += 2)
|
|
res.push(parseInt(msg[i] + msg[i + 1], 16));
|
|
} else {
|
|
for (var i = 0; i < msg.length; i++) {
|
|
var c = msg.charCodeAt(i);
|
|
var hi = c >> 8;
|
|
var lo = c & 0xff;
|
|
if (hi)
|
|
res.push(hi, lo);
|
|
else
|
|
res.push(lo);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
utils.toArray = toArray;
|
|
|
|
function zero2(word) {
|
|
if (word.length === 1)
|
|
return '0' + word;
|
|
else
|
|
return word;
|
|
}
|
|
utils.zero2 = zero2;
|
|
|
|
function toHex(msg) {
|
|
var res = '';
|
|
for (var i = 0; i < msg.length; i++)
|
|
res += zero2(msg[i].toString(16));
|
|
return res;
|
|
}
|
|
utils.toHex = toHex;
|
|
|
|
utils.encode = function encode(arr, enc) {
|
|
if (enc === 'hex')
|
|
return toHex(arr);
|
|
else
|
|
return arr;
|
|
};
|
|
|
|
},{}],43:[function(require,module,exports){
|
|
'use strict'
|
|
var Buffer = require('buffer').Buffer
|
|
var inherits = require('inherits')
|
|
var HashBase = require('hash-base')
|
|
|
|
var ARRAY16 = new Array(16)
|
|
|
|
var zl = [
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
|
|
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
|
|
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
|
|
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
|
]
|
|
|
|
var zr = [
|
|
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
|
|
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
|
|
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
|
|
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
|
|
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
|
]
|
|
|
|
var sl = [
|
|
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
|
|
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
|
|
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
|
|
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
|
|
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
|
]
|
|
|
|
var sr = [
|
|
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
|
|
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
|
|
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
|
|
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
|
|
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
|
]
|
|
|
|
var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]
|
|
var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]
|
|
|
|
function RIPEMD160 () {
|
|
HashBase.call(this, 64)
|
|
|
|
// state
|
|
this._a = 0x67452301
|
|
this._b = 0xefcdab89
|
|
this._c = 0x98badcfe
|
|
this._d = 0x10325476
|
|
this._e = 0xc3d2e1f0
|
|
}
|
|
|
|
inherits(RIPEMD160, HashBase)
|
|
|
|
RIPEMD160.prototype._update = function () {
|
|
var words = ARRAY16
|
|
for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4)
|
|
|
|
var al = this._a | 0
|
|
var bl = this._b | 0
|
|
var cl = this._c | 0
|
|
var dl = this._d | 0
|
|
var el = this._e | 0
|
|
|
|
var ar = this._a | 0
|
|
var br = this._b | 0
|
|
var cr = this._c | 0
|
|
var dr = this._d | 0
|
|
var er = this._e | 0
|
|
|
|
// computation
|
|
for (var i = 0; i < 80; i += 1) {
|
|
var tl
|
|
var tr
|
|
if (i < 16) {
|
|
tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i])
|
|
tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i])
|
|
} else if (i < 32) {
|
|
tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i])
|
|
tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i])
|
|
} else if (i < 48) {
|
|
tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i])
|
|
tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i])
|
|
} else if (i < 64) {
|
|
tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i])
|
|
tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i])
|
|
} else { // if (i<80) {
|
|
tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i])
|
|
tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i])
|
|
}
|
|
|
|
al = el
|
|
el = dl
|
|
dl = rotl(cl, 10)
|
|
cl = bl
|
|
bl = tl
|
|
|
|
ar = er
|
|
er = dr
|
|
dr = rotl(cr, 10)
|
|
cr = br
|
|
br = tr
|
|
}
|
|
|
|
// update state
|
|
var t = (this._b + cl + dr) | 0
|
|
this._b = (this._c + dl + er) | 0
|
|
this._c = (this._d + el + ar) | 0
|
|
this._d = (this._e + al + br) | 0
|
|
this._e = (this._a + bl + cr) | 0
|
|
this._a = t
|
|
}
|
|
|
|
RIPEMD160.prototype._digest = function () {
|
|
// create padding and handle blocks
|
|
this._block[this._blockOffset++] = 0x80
|
|
if (this._blockOffset > 56) {
|
|
this._block.fill(0, this._blockOffset, 64)
|
|
this._update()
|
|
this._blockOffset = 0
|
|
}
|
|
|
|
this._block.fill(0, this._blockOffset, 56)
|
|
this._block.writeUInt32LE(this._length[0], 56)
|
|
this._block.writeUInt32LE(this._length[1], 60)
|
|
this._update()
|
|
|
|
// produce result
|
|
var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20)
|
|
buffer.writeInt32LE(this._a, 0)
|
|
buffer.writeInt32LE(this._b, 4)
|
|
buffer.writeInt32LE(this._c, 8)
|
|
buffer.writeInt32LE(this._d, 12)
|
|
buffer.writeInt32LE(this._e, 16)
|
|
return buffer
|
|
}
|
|
|
|
function rotl (x, n) {
|
|
return (x << n) | (x >>> (32 - n))
|
|
}
|
|
|
|
function fn1 (a, b, c, d, e, m, k, s) {
|
|
return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0
|
|
}
|
|
|
|
function fn2 (a, b, c, d, e, m, k, s) {
|
|
return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0
|
|
}
|
|
|
|
function fn3 (a, b, c, d, e, m, k, s) {
|
|
return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0
|
|
}
|
|
|
|
function fn4 (a, b, c, d, e, m, k, s) {
|
|
return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0
|
|
}
|
|
|
|
function fn5 (a, b, c, d, e, m, k, s) {
|
|
return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0
|
|
}
|
|
|
|
module.exports = RIPEMD160
|
|
|
|
},{"buffer":100,"hash-base":24,"inherits":38}],44:[function(require,module,exports){
|
|
(function (Buffer){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const xrp_codec_1 = require("./xrp-codec");
|
|
exports.codec = xrp_codec_1.codec;
|
|
exports.encodeSeed = xrp_codec_1.encodeSeed;
|
|
exports.decodeSeed = xrp_codec_1.decodeSeed;
|
|
exports.encodeAccountID = xrp_codec_1.encodeAccountID;
|
|
exports.decodeAccountID = xrp_codec_1.decodeAccountID;
|
|
exports.encodeNodePublic = xrp_codec_1.encodeNodePublic;
|
|
exports.decodeNodePublic = xrp_codec_1.decodeNodePublic;
|
|
exports.encodeAccountPublic = xrp_codec_1.encodeAccountPublic;
|
|
exports.decodeAccountPublic = xrp_codec_1.decodeAccountPublic;
|
|
exports.isValidClassicAddress = xrp_codec_1.isValidClassicAddress;
|
|
const assert = require("assert");
|
|
const PREFIX_BYTES = {
|
|
MAIN: Buffer.from([0x05, 0x44]),
|
|
TEST: Buffer.from([0x04, 0x93]) // 4, 147
|
|
};
|
|
function classicAddressToXAddress(classicAddress, tag, test) {
|
|
const accountId = xrp_codec_1.decodeAccountID(classicAddress);
|
|
return encodeXAddress(accountId, tag, test);
|
|
}
|
|
exports.classicAddressToXAddress = classicAddressToXAddress;
|
|
function encodeXAddress(accountId, tag, test) {
|
|
if (accountId.length !== 20) {
|
|
// RIPEMD160 is 160 bits = 20 bytes
|
|
throw new Error('Account ID must be 20 bytes');
|
|
}
|
|
const MAX_32_BIT_UNSIGNED_INT = 4294967295;
|
|
const flag = tag === false ? 0 : tag <= MAX_32_BIT_UNSIGNED_INT ? 1 : 2;
|
|
if (flag === 2) {
|
|
throw new Error('Invalid tag');
|
|
}
|
|
if (tag === false) {
|
|
tag = 0;
|
|
}
|
|
const bytes = Buffer.concat([
|
|
test ? PREFIX_BYTES.TEST : PREFIX_BYTES.MAIN,
|
|
accountId,
|
|
Buffer.from([
|
|
flag,
|
|
tag & 0xff,
|
|
(tag >> 8) & 0xff,
|
|
(tag >> 16) & 0xff,
|
|
(tag >> 24) & 0xff,
|
|
0, 0, 0, 0 // four zero bytes (reserved for 64-bit tags)
|
|
])
|
|
]);
|
|
const xAddress = xrp_codec_1.codec.encodeChecked(bytes);
|
|
return xAddress;
|
|
}
|
|
exports.encodeXAddress = encodeXAddress;
|
|
function xAddressToClassicAddress(xAddress) {
|
|
const { accountId, tag, test } = decodeXAddress(xAddress);
|
|
const classicAddress = xrp_codec_1.encodeAccountID(accountId);
|
|
return {
|
|
classicAddress,
|
|
tag,
|
|
test
|
|
};
|
|
}
|
|
exports.xAddressToClassicAddress = xAddressToClassicAddress;
|
|
function decodeXAddress(xAddress) {
|
|
const decoded = xrp_codec_1.codec.decodeChecked(xAddress);
|
|
const test = isBufferForTestAddress(decoded);
|
|
const accountId = decoded.slice(2, 22);
|
|
const tag = tagFromBuffer(decoded);
|
|
return {
|
|
accountId,
|
|
tag,
|
|
test
|
|
};
|
|
}
|
|
exports.decodeXAddress = decodeXAddress;
|
|
function isBufferForTestAddress(buf) {
|
|
const decodedPrefix = buf.slice(0, 2);
|
|
if (PREFIX_BYTES.MAIN.equals(decodedPrefix)) {
|
|
return false;
|
|
}
|
|
else if (PREFIX_BYTES.TEST.equals(decodedPrefix)) {
|
|
return true;
|
|
}
|
|
else {
|
|
throw new Error('Invalid X-address: bad prefix');
|
|
}
|
|
}
|
|
function tagFromBuffer(buf) {
|
|
const flag = buf[22];
|
|
if (flag >= 2) {
|
|
// No support for 64-bit tags at this time
|
|
throw new Error('Unsupported X-address');
|
|
}
|
|
if (flag === 1) {
|
|
// Little-endian to big-endian
|
|
return buf[23] + buf[24] * 0x100 + buf[25] * 0x10000 + buf[26] * 0x1000000;
|
|
}
|
|
assert.strictEqual(flag, 0, 'flag must be zero to indicate no tag');
|
|
assert.ok(Buffer.from('0000000000000000', 'hex').equals(buf.slice(23, 23 + 8)), 'remaining bytes must be zero');
|
|
return false;
|
|
}
|
|
function isValidXAddress(xAddress) {
|
|
try {
|
|
decodeXAddress(xAddress);
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
exports.isValidXAddress = isValidXAddress;
|
|
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"./xrp-codec":46,"assert":94,"buffer":100}],45:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
/**
|
|
* Check whether two sequences (e.g. arrays of numbers) are equal.
|
|
*
|
|
* @param arr1 One of the arrays to compare.
|
|
* @param arr2 The other array to compare.
|
|
*/
|
|
function seqEqual(arr1, arr2) {
|
|
if (arr1.length !== arr2.length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < arr1.length; i++) {
|
|
if (arr1[i] !== arr2[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
exports.seqEqual = seqEqual;
|
|
/**
|
|
* Check whether a value is a sequence (e.g. array of numbers).
|
|
*
|
|
* @param val The value to check.
|
|
*/
|
|
function isSequence(val) {
|
|
return val.length !== undefined;
|
|
}
|
|
/**
|
|
* Concatenate all `arguments` into a single array. Each argument can be either
|
|
* a single element or a sequence, which has a `length` property and supports
|
|
* element retrieval via sequence[ix].
|
|
*
|
|
* > concatArgs(1, [2, 3], Buffer.from([4,5]), new Uint8Array([6, 7]));
|
|
* [1,2,3,4,5,6,7]
|
|
*
|
|
* @returns {number[]} Array of concatenated arguments
|
|
*/
|
|
function concatArgs(...args) {
|
|
const ret = [];
|
|
args.forEach(function (arg) {
|
|
if (isSequence(arg)) {
|
|
for (let j = 0; j < arg.length; j++) {
|
|
ret.push(arg[j]);
|
|
}
|
|
}
|
|
else {
|
|
ret.push(arg);
|
|
}
|
|
});
|
|
return ret;
|
|
}
|
|
exports.concatArgs = concatArgs;
|
|
|
|
},{}],46:[function(require,module,exports){
|
|
(function (Buffer){
|
|
"use strict";
|
|
/**
|
|
* Codec class
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const baseCodec = require("base-x");
|
|
const utils_1 = require("./utils");
|
|
class Codec {
|
|
constructor(options) {
|
|
this.sha256 = options.sha256;
|
|
this.alphabet = options.alphabet;
|
|
this.codec = baseCodec(this.alphabet);
|
|
this.base = this.alphabet.length;
|
|
}
|
|
/**
|
|
* Encoder.
|
|
*
|
|
* @param bytes Buffer of data to encode.
|
|
* @param opts Options object including the version bytes and the expected length of the data to encode.
|
|
*/
|
|
encode(bytes, opts) {
|
|
const versions = opts.versions;
|
|
return this.encodeVersioned(bytes, versions, opts.expectedLength);
|
|
}
|
|
encodeVersioned(bytes, versions, expectedLength) {
|
|
if (expectedLength && bytes.length !== expectedLength) {
|
|
throw new Error('unexpected_payload_length: bytes.length does not match expectedLength.' +
|
|
' Ensure that the bytes are a Buffer.');
|
|
}
|
|
return this.encodeChecked(Buffer.from(utils_1.concatArgs(versions, bytes)));
|
|
}
|
|
encodeChecked(buffer) {
|
|
const check = this.sha256(this.sha256(buffer)).slice(0, 4);
|
|
return this.encodeRaw(Buffer.from(utils_1.concatArgs(buffer, check)));
|
|
}
|
|
encodeRaw(bytes) {
|
|
return this.codec.encode(bytes);
|
|
}
|
|
/**
|
|
* Decoder.
|
|
*
|
|
* @param base58string Base58Check-encoded string to decode.
|
|
* @param opts Options object including the version byte(s) and the expected length of the data after decoding.
|
|
*/
|
|
decode(base58string, opts) {
|
|
const versions = opts.versions;
|
|
const types = opts.versionTypes;
|
|
const withoutSum = this.decodeChecked(base58string);
|
|
if (versions.length > 1 && !opts.expectedLength) {
|
|
throw new Error('expectedLength is required because there are >= 2 possible versions');
|
|
}
|
|
const versionLengthGuess = typeof versions[0] === 'number' ? 1 : versions[0].length;
|
|
const payloadLength = opts.expectedLength || withoutSum.length - versionLengthGuess;
|
|
const versionBytes = withoutSum.slice(0, -payloadLength);
|
|
const payload = withoutSum.slice(-payloadLength);
|
|
for (let i = 0; i < versions.length; i++) {
|
|
const version = Array.isArray(versions[i]) ? versions[i] : [versions[i]];
|
|
if (utils_1.seqEqual(versionBytes, version)) {
|
|
return {
|
|
version,
|
|
bytes: payload,
|
|
type: types ? types[i] : null
|
|
};
|
|
}
|
|
}
|
|
throw new Error('version_invalid: version bytes do not match any of the provided version(s)');
|
|
}
|
|
decodeChecked(base58string) {
|
|
const buffer = this.decodeRaw(base58string);
|
|
if (buffer.length < 5) {
|
|
throw new Error('invalid_input_size: decoded data must have length >= 5');
|
|
}
|
|
if (!this.verifyCheckSum(buffer)) {
|
|
throw new Error('checksum_invalid');
|
|
}
|
|
return buffer.slice(0, -4);
|
|
}
|
|
decodeRaw(base58string) {
|
|
return this.codec.decode(base58string);
|
|
}
|
|
verifyCheckSum(bytes) {
|
|
const computed = this.sha256(this.sha256(bytes.slice(0, -4))).slice(0, 4);
|
|
const checksum = bytes.slice(-4);
|
|
return utils_1.seqEqual(computed, checksum);
|
|
}
|
|
}
|
|
/**
|
|
* XRP codec
|
|
*/
|
|
// Pure JavaScript hash functions in the browser, native hash functions in Node.js
|
|
const createHash = require('create-hash');
|
|
// base58 encodings: https://xrpl.org/base58-encodings.html
|
|
const ACCOUNT_ID = 0; // Account address (20 bytes)
|
|
const ACCOUNT_PUBLIC_KEY = 0x23; // Account public key (33 bytes)
|
|
const FAMILY_SEED = 0x21; // 33; Seed value (for secret keys) (16 bytes)
|
|
const NODE_PUBLIC = 0x1C; // 28; Validation public key (33 bytes)
|
|
const ED25519_SEED = [0x01, 0xE1, 0x4B]; // [1, 225, 75]
|
|
const codecOptions = {
|
|
sha256: function (bytes) {
|
|
return createHash('sha256').update(Buffer.from(bytes)).digest();
|
|
},
|
|
alphabet: 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
|
|
};
|
|
const codecWithXrpAlphabet = new Codec(codecOptions);
|
|
exports.codec = codecWithXrpAlphabet;
|
|
// entropy is a Buffer of size 16
|
|
// type is 'ed25519' or 'secp256k1'
|
|
function encodeSeed(entropy, type) {
|
|
if (entropy.length !== 16) {
|
|
throw new Error('entropy must have length 16');
|
|
}
|
|
const opts = {
|
|
expectedLength: 16,
|
|
// for secp256k1, use `FAMILY_SEED`
|
|
versions: type === 'ed25519' ? ED25519_SEED : [FAMILY_SEED]
|
|
};
|
|
// prefixes entropy with version bytes
|
|
return codecWithXrpAlphabet.encode(entropy, opts);
|
|
}
|
|
exports.encodeSeed = encodeSeed;
|
|
function decodeSeed(seed, opts = {
|
|
versionTypes: ['ed25519', 'secp256k1'],
|
|
versions: [ED25519_SEED, FAMILY_SEED],
|
|
expectedLength: 16
|
|
}) {
|
|
return codecWithXrpAlphabet.decode(seed, opts);
|
|
}
|
|
exports.decodeSeed = decodeSeed;
|
|
function encodeAccountID(bytes) {
|
|
const opts = { versions: [ACCOUNT_ID], expectedLength: 20 };
|
|
return codecWithXrpAlphabet.encode(bytes, opts);
|
|
}
|
|
exports.encodeAccountID = encodeAccountID;
|
|
exports.encodeAddress = encodeAccountID;
|
|
function decodeAccountID(accountId) {
|
|
const opts = { versions: [ACCOUNT_ID], expectedLength: 20 };
|
|
return codecWithXrpAlphabet.decode(accountId, opts).bytes;
|
|
}
|
|
exports.decodeAccountID = decodeAccountID;
|
|
exports.decodeAddress = decodeAccountID;
|
|
function decodeNodePublic(base58string) {
|
|
const opts = { versions: [NODE_PUBLIC], expectedLength: 33 };
|
|
return codecWithXrpAlphabet.decode(base58string, opts).bytes;
|
|
}
|
|
exports.decodeNodePublic = decodeNodePublic;
|
|
function encodeNodePublic(bytes) {
|
|
const opts = { versions: [NODE_PUBLIC], expectedLength: 33 };
|
|
return codecWithXrpAlphabet.encode(bytes, opts);
|
|
}
|
|
exports.encodeNodePublic = encodeNodePublic;
|
|
function encodeAccountPublic(bytes) {
|
|
const opts = { versions: [ACCOUNT_PUBLIC_KEY], expectedLength: 33 };
|
|
return codecWithXrpAlphabet.encode(bytes, opts);
|
|
}
|
|
exports.encodeAccountPublic = encodeAccountPublic;
|
|
function decodeAccountPublic(base58string) {
|
|
const opts = { versions: [ACCOUNT_PUBLIC_KEY], expectedLength: 33 };
|
|
return codecWithXrpAlphabet.decode(base58string, opts).bytes;
|
|
}
|
|
exports.decodeAccountPublic = decodeAccountPublic;
|
|
function isValidClassicAddress(address) {
|
|
try {
|
|
decodeAccountID(address);
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
exports.isValidClassicAddress = isValidClassicAddress;
|
|
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"./utils":45,"base-x":47,"buffer":100,"create-hash":5}],47:[function(require,module,exports){
|
|
'use strict'
|
|
// base-x encoding / decoding
|
|
// Copyright (c) 2018 base-x contributors
|
|
// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
|
// @ts-ignore
|
|
var _Buffer = require('safe-buffer').Buffer
|
|
function base (ALPHABET) {
|
|
if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }
|
|
var BASE_MAP = new Uint8Array(256)
|
|
BASE_MAP.fill(255)
|
|
for (var i = 0; i < ALPHABET.length; i++) {
|
|
var x = ALPHABET.charAt(i)
|
|
var xc = x.charCodeAt(0)
|
|
if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }
|
|
BASE_MAP[xc] = i
|
|
}
|
|
var BASE = ALPHABET.length
|
|
var LEADER = ALPHABET.charAt(0)
|
|
var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up
|
|
var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up
|
|
function encode (source) {
|
|
if (!_Buffer.isBuffer(source)) { throw new TypeError('Expected Buffer') }
|
|
if (source.length === 0) { return '' }
|
|
// Skip & count leading zeroes.
|
|
var zeroes = 0
|
|
var length = 0
|
|
var pbegin = 0
|
|
var pend = source.length
|
|
while (pbegin !== pend && source[pbegin] === 0) {
|
|
pbegin++
|
|
zeroes++
|
|
}
|
|
// Allocate enough space in big-endian base58 representation.
|
|
var size = ((pend - pbegin) * iFACTOR + 1) >>> 0
|
|
var b58 = new Uint8Array(size)
|
|
// Process the bytes.
|
|
while (pbegin !== pend) {
|
|
var carry = source[pbegin]
|
|
// Apply "b58 = b58 * 256 + ch".
|
|
var i = 0
|
|
for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {
|
|
carry += (256 * b58[it1]) >>> 0
|
|
b58[it1] = (carry % BASE) >>> 0
|
|
carry = (carry / BASE) >>> 0
|
|
}
|
|
if (carry !== 0) { throw new Error('Non-zero carry') }
|
|
length = i
|
|
pbegin++
|
|
}
|
|
// Skip leading zeroes in base58 result.
|
|
var it2 = size - length
|
|
while (it2 !== size && b58[it2] === 0) {
|
|
it2++
|
|
}
|
|
// Translate the result into a string.
|
|
var str = LEADER.repeat(zeroes)
|
|
for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }
|
|
return str
|
|
}
|
|
function decodeUnsafe (source) {
|
|
if (typeof source !== 'string') { throw new TypeError('Expected String') }
|
|
if (source.length === 0) { return _Buffer.alloc(0) }
|
|
var psz = 0
|
|
// Skip leading spaces.
|
|
if (source[psz] === ' ') { return }
|
|
// Skip and count leading '1's.
|
|
var zeroes = 0
|
|
var length = 0
|
|
while (source[psz] === LEADER) {
|
|
zeroes++
|
|
psz++
|
|
}
|
|
// Allocate enough space in big-endian base256 representation.
|
|
var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.
|
|
var b256 = new Uint8Array(size)
|
|
// Process the characters.
|
|
while (source[psz]) {
|
|
// Decode character
|
|
var carry = BASE_MAP[source.charCodeAt(psz)]
|
|
// Invalid character
|
|
if (carry === 255) { return }
|
|
var i = 0
|
|
for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {
|
|
carry += (BASE * b256[it3]) >>> 0
|
|
b256[it3] = (carry % 256) >>> 0
|
|
carry = (carry / 256) >>> 0
|
|
}
|
|
if (carry !== 0) { throw new Error('Non-zero carry') }
|
|
length = i
|
|
psz++
|
|
}
|
|
// Skip trailing spaces.
|
|
if (source[psz] === ' ') { return }
|
|
// Skip leading zeroes in b256.
|
|
var it4 = size - length
|
|
while (it4 !== size && b256[it4] === 0) {
|
|
it4++
|
|
}
|
|
var vch = _Buffer.allocUnsafe(zeroes + (size - it4))
|
|
vch.fill(0x00, 0, zeroes)
|
|
var j = zeroes
|
|
while (it4 !== size) {
|
|
vch[j++] = b256[it4++]
|
|
}
|
|
return vch
|
|
}
|
|
function decode (string) {
|
|
var buffer = decodeUnsafe(string)
|
|
if (buffer) { return buffer }
|
|
throw new Error('Non-base' + BASE + ' character')
|
|
}
|
|
return {
|
|
encode: encode,
|
|
decodeUnsafe: decodeUnsafe,
|
|
decode: decode
|
|
}
|
|
}
|
|
module.exports = base
|
|
|
|
},{"safe-buffer":85}],48:[function(require,module,exports){
|
|
'use strict'; /* eslint-disable func-style */
|
|
|
|
var BN = require('bn.js');
|
|
var types = require('./types');var _require =
|
|
require('./hash-prefixes'),HashPrefix = _require.HashPrefix;var _require2 =
|
|
require('./serdes/binary-parser'),BinaryParser = _require2.BinaryParser;var _require3 =
|
|
require('./serdes/binary-serializer'),BinarySerializer = _require3.BinarySerializer,BytesList = _require3.BytesList;var _require4 =
|
|
require('./utils/bytes-utils'),bytesToHex = _require4.bytesToHex,slice = _require4.slice,parseBytes = _require4.parseBytes;var _require5 =
|
|
|
|
require('./hashes'),sha512Half = _require5.sha512Half,transactionID = _require5.transactionID;
|
|
|
|
var makeParser = function makeParser(bytes) {return new BinaryParser(bytes);};
|
|
var readJSON = function readJSON(parser) {return parser.readType(types.STObject).toJSON();};
|
|
var binaryToJSON = function binaryToJSON(bytes) {return readJSON(makeParser(bytes));};
|
|
|
|
function serializeObject(object) {var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};var
|
|
prefix = opts.prefix,suffix = opts.suffix,_opts$signingFieldsOn = opts.signingFieldsOnly,signingFieldsOnly = _opts$signingFieldsOn === undefined ? false : _opts$signingFieldsOn;
|
|
var bytesList = new BytesList();
|
|
if (prefix) {
|
|
bytesList.put(prefix);
|
|
}
|
|
var filter = signingFieldsOnly ? function (f) {return f.isSigningField;} : undefined;
|
|
types.STObject.from(object).toBytesSink(bytesList, filter);
|
|
if (suffix) {
|
|
bytesList.put(suffix);
|
|
}
|
|
return bytesList.toBytes();
|
|
}
|
|
|
|
function signingData(tx) {var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : HashPrefix.transactionSig;
|
|
return serializeObject(tx, { prefix: prefix, signingFieldsOnly: true });
|
|
}
|
|
|
|
function signingClaimData(claim) {
|
|
var prefix = HashPrefix.paymentChannelClaim;
|
|
var channel = types.Hash256.from(claim.channel).toBytes();
|
|
var amount = new types.UInt64(new BN(claim.amount)).toBytes();
|
|
|
|
var bytesList = new BytesList();
|
|
|
|
bytesList.put(prefix);
|
|
bytesList.put(channel);
|
|
bytesList.put(amount);
|
|
return bytesList.toBytes();
|
|
}
|
|
|
|
function multiSigningData(tx, signingAccount) {
|
|
var prefix = HashPrefix.transactionMultiSig;
|
|
var suffix = types.AccountID.from(signingAccount).toBytes();
|
|
return serializeObject(tx, { prefix: prefix, suffix: suffix, signingFieldsOnly: true });
|
|
}
|
|
|
|
module.exports = {
|
|
BinaryParser: BinaryParser,
|
|
BinarySerializer: BinarySerializer,
|
|
BytesList: BytesList,
|
|
makeParser: makeParser,
|
|
serializeObject: serializeObject,
|
|
readJSON: readJSON,
|
|
bytesToHex: bytesToHex,
|
|
parseBytes: parseBytes,
|
|
multiSigningData: multiSigningData,
|
|
signingData: signingData,
|
|
signingClaimData: signingClaimData,
|
|
binaryToJSON: binaryToJSON,
|
|
sha512Half: sha512Half,
|
|
transactionID: transactionID,
|
|
slice: slice };
|
|
},{"./hash-prefixes":52,"./hashes":53,"./serdes/binary-parser":57,"./serdes/binary-serializer":58,"./types":68,"./utils/bytes-utils":79,"bn.js":2}],49:[function(require,module,exports){
|
|
'use strict';var _ = require('lodash');
|
|
var enums = require('./enums');var
|
|
Field = enums.Field;
|
|
var types = require('./types');
|
|
var binary = require('./binary');var _require =
|
|
require('./shamap'),ShaMap = _require.ShaMap;
|
|
var ledgerHashes = require('./ledger-hashes');
|
|
var hashes = require('./hashes');
|
|
var quality = require('./quality');var _require2 =
|
|
require('./hash-prefixes'),HashPrefix = _require2.HashPrefix;
|
|
|
|
|
|
module.exports = _.assign({
|
|
hashes: _.assign({}, hashes, ledgerHashes),
|
|
binary: binary,
|
|
enums: enums,
|
|
quality: quality,
|
|
Field: Field,
|
|
HashPrefix: HashPrefix,
|
|
ShaMap: ShaMap },
|
|
|
|
types);
|
|
},{"./binary":48,"./enums":51,"./hash-prefixes":52,"./hashes":53,"./ledger-hashes":55,"./quality":56,"./shamap":59,"./types":68,"lodash":39}],50:[function(require,module,exports){
|
|
module.exports={
|
|
"TYPES": {
|
|
"Validation": 10003,
|
|
"Done": -1,
|
|
"Hash128": 4,
|
|
"Blob": 7,
|
|
"AccountID": 8,
|
|
"Amount": 6,
|
|
"Hash256": 5,
|
|
"UInt8": 16,
|
|
"Vector256": 19,
|
|
"STObject": 14,
|
|
"Unknown": -2,
|
|
"Transaction": 10001,
|
|
"Hash160": 17,
|
|
"PathSet": 18,
|
|
"LedgerEntry": 10002,
|
|
"UInt16": 1,
|
|
"NotPresent": 0,
|
|
"UInt64": 3,
|
|
"UInt32": 2,
|
|
"STArray": 15
|
|
},
|
|
"LEDGER_ENTRY_TYPES": {
|
|
"Any": -3,
|
|
"Child": -2,
|
|
"Invalid": -1,
|
|
"AccountRoot": 97,
|
|
"DirectoryNode": 100,
|
|
"RippleState": 114,
|
|
"Ticket": 84,
|
|
"SignerList": 83,
|
|
"Offer": 111,
|
|
"LedgerHashes": 104,
|
|
"Amendments": 102,
|
|
"FeeSettings": 115,
|
|
"Escrow": 117,
|
|
"PayChannel": 120,
|
|
"DepositPreauth": 112,
|
|
"Check": 67,
|
|
"Nickname": 110,
|
|
"Contract": 99,
|
|
"GeneratorMap": 103
|
|
},
|
|
"FIELDS": [
|
|
[
|
|
"Generic",
|
|
{
|
|
"nth": 0,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Unknown"
|
|
}
|
|
],
|
|
[
|
|
"Invalid",
|
|
{
|
|
"nth": -1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Unknown"
|
|
}
|
|
],
|
|
[
|
|
"LedgerEntryType",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt16"
|
|
}
|
|
],
|
|
[
|
|
"TransactionType",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt16"
|
|
}
|
|
],
|
|
[
|
|
"SignerWeight",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt16"
|
|
}
|
|
],
|
|
[
|
|
"Flags",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"SourceTag",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"Sequence",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"PreviousTxnLgrSeq",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"LedgerSequence",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"CloseTime",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"ParentCloseTime",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"SigningTime",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"Expiration",
|
|
{
|
|
"nth": 10,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"TransferRate",
|
|
{
|
|
"nth": 11,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"WalletSize",
|
|
{
|
|
"nth": 12,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"OwnerCount",
|
|
{
|
|
"nth": 13,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"DestinationTag",
|
|
{
|
|
"nth": 14,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"HighQualityIn",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"HighQualityOut",
|
|
{
|
|
"nth": 17,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"LowQualityIn",
|
|
{
|
|
"nth": 18,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"LowQualityOut",
|
|
{
|
|
"nth": 19,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"QualityIn",
|
|
{
|
|
"nth": 20,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"QualityOut",
|
|
{
|
|
"nth": 21,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"StampEscrow",
|
|
{
|
|
"nth": 22,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"BondAmount",
|
|
{
|
|
"nth": 23,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"LoadFee",
|
|
{
|
|
"nth": 24,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"OfferSequence",
|
|
{
|
|
"nth": 25,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"FirstLedgerSequence",
|
|
{
|
|
"nth": 26,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"LastLedgerSequence",
|
|
{
|
|
"nth": 27,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"TransactionIndex",
|
|
{
|
|
"nth": 28,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"OperationLimit",
|
|
{
|
|
"nth": 29,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"ReferenceFeeUnits",
|
|
{
|
|
"nth": 30,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"ReserveBase",
|
|
{
|
|
"nth": 31,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"ReserveIncrement",
|
|
{
|
|
"nth": 32,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"SetFlag",
|
|
{
|
|
"nth": 33,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"ClearFlag",
|
|
{
|
|
"nth": 34,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"SignerQuorum",
|
|
{
|
|
"nth": 35,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"CancelAfter",
|
|
{
|
|
"nth": 36,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"FinishAfter",
|
|
{
|
|
"nth": 37,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"IndexNext",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"IndexPrevious",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"BookNode",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"OwnerNode",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"BaseFee",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"ExchangeRate",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"LowNode",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"HighNode",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
],
|
|
[
|
|
"EmailHash",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash128"
|
|
}
|
|
],
|
|
[
|
|
"LedgerHash",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"ParentHash",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"TransactionHash",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"AccountHash",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"PreviousTxnID",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"LedgerIndex",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"WalletLocator",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"RootIndex",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"AccountTxnID",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"BookDirectory",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"InvoiceID",
|
|
{
|
|
"nth": 17,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"Nickname",
|
|
{
|
|
"nth": 18,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"Amendment",
|
|
{
|
|
"nth": 19,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"TicketID",
|
|
{
|
|
"nth": 20,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"Digest",
|
|
{
|
|
"nth": 21,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"hash",
|
|
{
|
|
"nth": 257,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"index",
|
|
{
|
|
"nth": 258,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"Amount",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"Balance",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"LimitAmount",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"TakerPays",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"TakerGets",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"LowLimit",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"HighLimit",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"Fee",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"SendMax",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"DeliverMin",
|
|
{
|
|
"nth": 10,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"MinimumOffer",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"RippleEscrow",
|
|
{
|
|
"nth": 17,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"DeliveredAmount",
|
|
{
|
|
"nth": 18,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"taker_gets_funded",
|
|
{
|
|
"nth": 258,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"taker_pays_funded",
|
|
{
|
|
"nth": 259,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Amount"
|
|
}
|
|
],
|
|
[
|
|
"PublicKey",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"MessageKey",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"SigningPubKey",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"TxnSignature",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": false,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"Generator",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"Signature",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": false,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"Domain",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"FundCode",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"RemoveCode",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"ExpireCode",
|
|
{
|
|
"nth": 10,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"CreateCode",
|
|
{
|
|
"nth": 11,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"MemoType",
|
|
{
|
|
"nth": 12,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"MemoData",
|
|
{
|
|
"nth": 13,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"MemoFormat",
|
|
{
|
|
"nth": 14,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"Fulfillment",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"Condition",
|
|
{
|
|
"nth": 17,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"MasterSignature",
|
|
{
|
|
"nth": 18,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": false,
|
|
"type": "Blob"
|
|
}
|
|
],
|
|
[
|
|
"Account",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"Owner",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"Destination",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"Issuer",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"Authorize",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"Unauthorize",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"Target",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"RegularKey",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "AccountID"
|
|
}
|
|
],
|
|
[
|
|
"ObjectEndMarker",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"TransactionMetaData",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"CreatedNode",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"DeletedNode",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"ModifiedNode",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"PreviousFields",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"FinalFields",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"NewFields",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"TemplateEntry",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"Memo",
|
|
{
|
|
"nth": 10,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"SignerEntry",
|
|
{
|
|
"nth": 11,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"Signer",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"Majority",
|
|
{
|
|
"nth": 18,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STObject"
|
|
}
|
|
],
|
|
[
|
|
"ArrayEndMarker",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"Signers",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": false,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"SignerEntries",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"Template",
|
|
{
|
|
"nth": 5,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"Necessary",
|
|
{
|
|
"nth": 6,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"Sufficient",
|
|
{
|
|
"nth": 7,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"AffectedNodes",
|
|
{
|
|
"nth": 8,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"Memos",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"Majorities",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "STArray"
|
|
}
|
|
],
|
|
[
|
|
"CloseResolution",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt8"
|
|
}
|
|
],
|
|
[
|
|
"Method",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt8"
|
|
}
|
|
],
|
|
[
|
|
"TransactionResult",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt8"
|
|
}
|
|
],
|
|
[
|
|
"TakerPaysCurrency",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash160"
|
|
}
|
|
],
|
|
[
|
|
"TakerPaysIssuer",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash160"
|
|
}
|
|
],
|
|
[
|
|
"TakerGetsCurrency",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash160"
|
|
}
|
|
],
|
|
[
|
|
"TakerGetsIssuer",
|
|
{
|
|
"nth": 4,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash160"
|
|
}
|
|
],
|
|
[
|
|
"Paths",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "PathSet"
|
|
}
|
|
],
|
|
[
|
|
"Indexes",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Vector256"
|
|
}
|
|
],
|
|
[
|
|
"Hashes",
|
|
{
|
|
"nth": 2,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Vector256"
|
|
}
|
|
],
|
|
[
|
|
"Amendments",
|
|
{
|
|
"nth": 3,
|
|
"isVLEncoded": true,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Vector256"
|
|
}
|
|
],
|
|
[
|
|
"Transaction",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Transaction"
|
|
}
|
|
],
|
|
[
|
|
"LedgerEntry",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "LedgerEntry"
|
|
}
|
|
],
|
|
[
|
|
"Validation",
|
|
{
|
|
"nth": 1,
|
|
"isVLEncoded": false,
|
|
"isSerialized": false,
|
|
"isSigningField": false,
|
|
"type": "Validation"
|
|
}
|
|
],
|
|
[
|
|
"SignerListID",
|
|
{
|
|
"nth": 38,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"SettleDelay",
|
|
{
|
|
"nth": 39,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt32"
|
|
}
|
|
],
|
|
[
|
|
"Channel",
|
|
{
|
|
"nth": 22,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"ConsensusHash",
|
|
{
|
|
"nth": 23,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"CheckID",
|
|
{
|
|
"nth": 24,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "Hash256"
|
|
}
|
|
],
|
|
[
|
|
"TickSize",
|
|
{
|
|
"nth": 16,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt8"
|
|
}
|
|
],
|
|
[
|
|
"DestinationNode",
|
|
{
|
|
"nth": 9,
|
|
"isVLEncoded": false,
|
|
"isSerialized": true,
|
|
"isSigningField": true,
|
|
"type": "UInt64"
|
|
}
|
|
]
|
|
],
|
|
"TRANSACTION_RESULTS": {
|
|
"telLOCAL_ERROR": -399,
|
|
"telBAD_DOMAIN": -398,
|
|
"telBAD_PATH_COUNT": -397,
|
|
"telBAD_PUBLIC_KEY": -396,
|
|
"telFAILED_PROCESSING": -395,
|
|
"telINSUF_FEE_P": -394,
|
|
"telNO_DST_PARTIAL": -393,
|
|
"telCAN_NOT_QUEUE": -392,
|
|
"telCAN_NOT_QUEUE_BALANCE": -391,
|
|
"telCAN_NOT_QUEUE_BLOCKS": -390,
|
|
"telCAN_NOT_QUEUE_BLOCKED": -389,
|
|
"telCAN_NOT_QUEUE_FEE": -388,
|
|
"telCAN_NOT_QUEUE_FULL": -387,
|
|
|
|
"temMALFORMED": -299,
|
|
"temBAD_AMOUNT": -298,
|
|
"temBAD_CURRENCY": -297,
|
|
"temBAD_EXPIRATION": -296,
|
|
"temBAD_FEE": -295,
|
|
"temBAD_ISSUER": -294,
|
|
"temBAD_LIMIT": -293,
|
|
"temBAD_OFFER": -292,
|
|
"temBAD_PATH": -291,
|
|
"temBAD_PATH_LOOP": -290,
|
|
"temBAD_REGKEY": -289,
|
|
"temBAD_SEND_XRP_LIMIT": -288,
|
|
"temBAD_SEND_XRP_MAX": -287,
|
|
"temBAD_SEND_XRP_NO_DIRECT": -286,
|
|
"temBAD_SEND_XRP_PARTIAL": -285,
|
|
"temBAD_SEND_XRP_PATHS": -284,
|
|
"temBAD_SEQUENCE": -283,
|
|
"temBAD_SIGNATURE": -282,
|
|
"temBAD_SRC_ACCOUNT": -281,
|
|
"temBAD_TRANSFER_RATE": -280,
|
|
"temDST_IS_SRC": -279,
|
|
"temDST_NEEDED": -278,
|
|
"temINVALID": -277,
|
|
"temINVALID_FLAG": -276,
|
|
"temREDUNDANT": -275,
|
|
"temRIPPLE_EMPTY": -274,
|
|
"temDISABLED": -273,
|
|
"temBAD_SIGNER": -272,
|
|
"temBAD_QUORUM": -271,
|
|
"temBAD_WEIGHT": -270,
|
|
"temBAD_TICK_SIZE": -269,
|
|
"temINVALID_ACCOUNT_ID": -268,
|
|
"temCANNOT_PREAUTH_SELF": -267,
|
|
"temUNCERTAIN": -266,
|
|
"temUNKNOWN": -265,
|
|
|
|
"tefFAILURE": -199,
|
|
"tefALREADY": -198,
|
|
"tefBAD_ADD_AUTH": -197,
|
|
"tefBAD_AUTH": -196,
|
|
"tefBAD_LEDGER": -195,
|
|
"tefCREATED": -194,
|
|
"tefEXCEPTION": -193,
|
|
"tefINTERNAL": -192,
|
|
"tefNO_AUTH_REQUIRED": -191,
|
|
"tefPAST_SEQ": -190,
|
|
"tefWRONG_PRIOR": -189,
|
|
"tefMASTER_DISABLED": -188,
|
|
"tefMAX_LEDGER": -187,
|
|
"tefBAD_SIGNATURE": -186,
|
|
"tefBAD_QUORUM": -185,
|
|
"tefNOT_MULTI_SIGNING": -184,
|
|
"tefBAD_AUTH_MASTER": -183,
|
|
"tefINVARIANT_FAILED": -182,
|
|
"tefTOO_BIG": -181,
|
|
|
|
"terRETRY": -99,
|
|
"terFUNDS_SPENT": -98,
|
|
"terINSUF_FEE_B": -97,
|
|
"terNO_ACCOUNT": -96,
|
|
"terNO_AUTH": -95,
|
|
"terNO_LINE": -94,
|
|
"terOWNERS": -93,
|
|
"terPRE_SEQ": -92,
|
|
"terLAST": -91,
|
|
"terNO_RIPPLE": -90,
|
|
"terQUEUED": -89,
|
|
|
|
"tesSUCCESS": 0,
|
|
|
|
"tecCLAIM": 100,
|
|
"tecPATH_PARTIAL": 101,
|
|
"tecUNFUNDED_ADD": 102,
|
|
"tecUNFUNDED_OFFER": 103,
|
|
"tecUNFUNDED_PAYMENT": 104,
|
|
"tecFAILED_PROCESSING": 105,
|
|
"tecDIR_FULL": 121,
|
|
"tecINSUF_RESERVE_LINE": 122,
|
|
"tecINSUF_RESERVE_OFFER": 123,
|
|
"tecNO_DST": 124,
|
|
"tecNO_DST_INSUF_XRP": 125,
|
|
"tecNO_LINE_INSUF_RESERVE": 126,
|
|
"tecNO_LINE_REDUNDANT": 127,
|
|
"tecPATH_DRY": 128,
|
|
"tecUNFUNDED": 129,
|
|
"tecNO_ALTERNATIVE_KEY": 130,
|
|
"tecNO_REGULAR_KEY": 131,
|
|
"tecOWNERS": 132,
|
|
"tecNO_ISSUER": 133,
|
|
"tecNO_AUTH": 134,
|
|
"tecNO_LINE": 135,
|
|
"tecINSUFF_FEE": 136,
|
|
"tecFROZEN": 137,
|
|
"tecNO_TARGET": 138,
|
|
"tecNO_PERMISSION": 139,
|
|
"tecNO_ENTRY": 140,
|
|
"tecINSUFFICIENT_RESERVE": 141,
|
|
"tecNEED_MASTER_KEY": 142,
|
|
"tecDST_TAG_NEEDED": 143,
|
|
"tecINTERNAL": 144,
|
|
"tecOVERSIZE": 145,
|
|
"tecCRYPTOCONDITION_ERROR": 146,
|
|
"tecINVARIANT_FAILED": 147,
|
|
"tecEXPIRED": 148,
|
|
"tecDUPLICATE": 149,
|
|
"tecKILLED": 150,
|
|
"tecHAS_OBLIGATIONS": 151,
|
|
"tecTOO_SOON": 152
|
|
},
|
|
"TRANSACTION_TYPES": {
|
|
"Invalid": -1,
|
|
|
|
"Payment": 0,
|
|
"EscrowCreate": 1,
|
|
"EscrowFinish": 2,
|
|
"AccountSet": 3,
|
|
"EscrowCancel": 4,
|
|
"SetRegularKey": 5,
|
|
"NickNameSet": 6,
|
|
"OfferCreate": 7,
|
|
"OfferCancel": 8,
|
|
"Contract": 9,
|
|
"TicketCreate": 10,
|
|
"TicketCancel": 11,
|
|
"SignerListSet": 12,
|
|
"PaymentChannelCreate": 13,
|
|
"PaymentChannelFund": 14,
|
|
"PaymentChannelClaim": 15,
|
|
"CheckCreate": 16,
|
|
"CheckCash": 17,
|
|
"CheckCancel": 18,
|
|
"DepositPreauth": 19,
|
|
"TrustSet": 20,
|
|
"AccountDelete": 21,
|
|
|
|
"EnableAmendment": 100,
|
|
"SetFee": 101
|
|
}
|
|
}
|
|
|
|
},{}],51:[function(require,module,exports){
|
|
'use strict';var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();var assert = require('assert');
|
|
var _ = require('lodash');var _require =
|
|
require('./../utils/bytes-utils'),parseBytes = _require.parseBytes,serializeUIntN = _require.serializeUIntN;
|
|
var makeClass = require('./../utils/make-class');
|
|
var enums = require('./definitions.json');
|
|
|
|
function transformWith(func, obj) {
|
|
return _.transform(obj, func);
|
|
}
|
|
|
|
function biMap(obj, valueKey) {
|
|
return _.transform(obj, function (result, value, key) {
|
|
result[key] = value;
|
|
result[value[valueKey]] = value;
|
|
});
|
|
}
|
|
|
|
var EnumType = makeClass({
|
|
EnumType: function EnumType(definition) {
|
|
_.assign(this, definition);
|
|
// At minimum
|
|
assert(this.bytes instanceof Uint8Array);
|
|
assert(typeof this.ordinal === 'number');
|
|
assert(typeof this.name === 'string');
|
|
},
|
|
toString: function toString() {
|
|
return this.name;
|
|
},
|
|
toJSON: function toJSON() {
|
|
return this.name;
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
sink.put(this.bytes);
|
|
},
|
|
statics: {
|
|
ordinalByteWidth: 1,
|
|
fromParser: function fromParser(parser) {
|
|
return this.from(parser.readUIntN(this.ordinalByteWidth));
|
|
},
|
|
from: function from(val) {
|
|
var ret = val instanceof this ? val : this[val];
|
|
if (!ret) {
|
|
throw new Error(
|
|
val + ' is not a valid name or ordinal for ' + this.enumName);
|
|
}
|
|
return ret;
|
|
},
|
|
valuesByName: function valuesByName() {var _this = this;
|
|
return _.transform(this.initVals, function (result, ordinal, name) {
|
|
var bytes = serializeUIntN(ordinal, _this.ordinalByteWidth);
|
|
var type = new _this({ name: name, ordinal: ordinal, bytes: bytes });
|
|
result[name] = type;
|
|
});
|
|
},
|
|
init: function init() {
|
|
var mapped = this.valuesByName();
|
|
_.assign(this, biMap(mapped, 'ordinal'));
|
|
this.values = _.values(mapped);
|
|
return this;
|
|
} } });
|
|
|
|
|
|
|
|
function makeEnum(name, definition) {
|
|
return makeClass({
|
|
inherits: EnumType,
|
|
statics: _.assign(definition, { enumName: name }) });
|
|
|
|
}
|
|
|
|
function makeEnums(to, definition, name) {
|
|
to[name] = makeEnum(name, definition);
|
|
}
|
|
|
|
var Enums = transformWith(makeEnums, {
|
|
Type: {
|
|
initVals: enums.TYPES },
|
|
|
|
LedgerEntryType: {
|
|
initVals: enums.LEDGER_ENTRY_TYPES, ordinalByteWidth: 2 },
|
|
|
|
TransactionType: {
|
|
initVals: enums.TRANSACTION_TYPES, ordinalByteWidth: 2 },
|
|
|
|
TransactionResult: {
|
|
initVals: enums.TRANSACTION_RESULTS, ordinalByteWidth: 1 } });
|
|
|
|
|
|
|
|
Enums.Field = makeClass({
|
|
inherits: EnumType,
|
|
statics: {
|
|
enumName: 'Field',
|
|
initVals: enums.FIELDS,
|
|
valuesByName: function valuesByName() {var _this2 = this;
|
|
var fields = _.map(this.initVals, function (_ref) {var _ref2 = _slicedToArray(_ref, 2),name = _ref2[0],definition = _ref2[1];
|
|
var type = Enums.Type[definition.type];
|
|
var bytes = _this2.header(type.ordinal, definition.nth);
|
|
var ordinal = type.ordinal << 16 | definition.nth;
|
|
var extra = { ordinal: ordinal, name: name, type: type, bytes: bytes };
|
|
return new _this2(_.assign(definition, extra));
|
|
});
|
|
return _.keyBy(fields, 'name');
|
|
},
|
|
header: function header(type, nth) {
|
|
var name = nth;
|
|
var header = [];
|
|
var push = header.push.bind(header);
|
|
if (type < 16) {
|
|
if (name < 16) {
|
|
push(type << 4 | name);
|
|
} else {
|
|
push(type << 4, name);
|
|
}
|
|
} else if (name < 16) {
|
|
push(name, type);
|
|
} else {
|
|
push(0, type, name);
|
|
}
|
|
return parseBytes(header, Uint8Array);
|
|
} } });
|
|
|
|
|
|
|
|
module.exports = Enums;
|
|
},{"./../utils/bytes-utils":79,"./../utils/make-class":80,"./definitions.json":50,"assert":94,"lodash":39}],52:[function(require,module,exports){
|
|
'use strict';var _require = require('./utils/bytes-utils'),serializeUIntN = _require.serializeUIntN;
|
|
|
|
function bytes(uint32) {
|
|
return serializeUIntN(uint32, 4);
|
|
}
|
|
|
|
var HashPrefix = {
|
|
transactionID: bytes(0x54584E00),
|
|
// transaction plus metadata
|
|
transaction: bytes(0x534E4400),
|
|
// account state
|
|
accountStateEntry: bytes(0x4D4C4E00),
|
|
// inner node in tree
|
|
innerNode: bytes(0x4D494E00),
|
|
// ledger master data for signing
|
|
ledgerHeader: bytes(0x4C575200),
|
|
// inner transaction to sign
|
|
transactionSig: bytes(0x53545800),
|
|
// inner transaction to sign
|
|
transactionMultiSig: bytes(0x534D5400),
|
|
// validation for signing
|
|
validation: bytes(0x56414C00),
|
|
// proposal for signing
|
|
proposal: bytes(0x50525000),
|
|
// payment channel claim
|
|
paymentChannelClaim: bytes(0x434C4D00) };
|
|
|
|
|
|
module.exports = {
|
|
HashPrefix: HashPrefix };
|
|
},{"./utils/bytes-utils":79}],53:[function(require,module,exports){
|
|
(function (Buffer){
|
|
'use strict';var makeClass = require('./utils/make-class');var _require =
|
|
require('./hash-prefixes'),HashPrefix = _require.HashPrefix;var _require2 =
|
|
require('./types'),Hash256 = _require2.Hash256;var _require3 =
|
|
require('./utils/bytes-utils'),parseBytes = _require3.parseBytes;
|
|
var createHash = require('create-hash');
|
|
|
|
var Sha512Half = makeClass({
|
|
Sha512Half: function Sha512Half() {
|
|
this.hash = createHash('sha512');
|
|
},
|
|
statics: {
|
|
put: function put(bytes) {
|
|
return new this().put(bytes);
|
|
} },
|
|
|
|
put: function put(bytes) {
|
|
this.hash.update(parseBytes(bytes, Buffer));
|
|
return this;
|
|
},
|
|
finish256: function finish256() {
|
|
var bytes = this.hash.digest();
|
|
return bytes.slice(0, 32);
|
|
},
|
|
finish: function finish() {
|
|
return new Hash256(this.finish256());
|
|
} });
|
|
|
|
|
|
function sha512Half() {
|
|
var hash = new Sha512Half();for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {args[_key] = arguments[_key];}
|
|
args.forEach(function (a) {return hash.put(a);});
|
|
return parseBytes(hash.finish256(), Uint8Array);
|
|
}
|
|
|
|
function transactionID(serialized) {
|
|
return new Hash256(sha512Half(HashPrefix.transactionID, serialized));
|
|
}
|
|
|
|
module.exports = {
|
|
Sha512Half: Sha512Half,
|
|
sha512Half: sha512Half,
|
|
transactionID: transactionID };
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"./hash-prefixes":52,"./types":68,"./utils/bytes-utils":79,"./utils/make-class":80,"buffer":100,"create-hash":5}],54:[function(require,module,exports){
|
|
'use strict';var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;};var assert = require('assert');
|
|
var coreTypes = require('./coretypes');var
|
|
quality =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
coreTypes.quality,_coreTypes$binary = coreTypes.binary,bytesToHex = _coreTypes$binary.bytesToHex,signingData = _coreTypes$binary.signingData,signingClaimData = _coreTypes$binary.signingClaimData,multiSigningData = _coreTypes$binary.multiSigningData,binaryToJSON = _coreTypes$binary.binaryToJSON,serializeObject = _coreTypes$binary.serializeObject,BinaryParser = _coreTypes$binary.BinaryParser;
|
|
|
|
function decodeLedgerData(binary) {
|
|
assert(typeof binary === 'string', 'binary must be a hex string');
|
|
var parser = new BinaryParser(binary);
|
|
return {
|
|
ledger_index: parser.readUInt32(),
|
|
total_coins: parser.readType(coreTypes.UInt64).valueOf().toString(),
|
|
parent_hash: parser.readType(coreTypes.Hash256).toHex(),
|
|
transaction_hash: parser.readType(coreTypes.Hash256).toHex(),
|
|
account_hash: parser.readType(coreTypes.Hash256).toHex(),
|
|
parent_close_time: parser.readUInt32(),
|
|
close_time: parser.readUInt32(),
|
|
close_time_resolution: parser.readUInt8(),
|
|
close_flags: parser.readUInt8() };
|
|
|
|
}
|
|
|
|
function decode(binary) {
|
|
assert(typeof binary === 'string', 'binary must be a hex string');
|
|
return binaryToJSON(binary);
|
|
}
|
|
|
|
function encode(json) {
|
|
assert((typeof json === 'undefined' ? 'undefined' : _typeof(json)) === 'object');
|
|
return bytesToHex(serializeObject(json));
|
|
}
|
|
|
|
function encodeForSigning(json) {
|
|
assert((typeof json === 'undefined' ? 'undefined' : _typeof(json)) === 'object');
|
|
return bytesToHex(signingData(json));
|
|
}
|
|
|
|
function encodeForSigningClaim(json) {
|
|
assert((typeof json === 'undefined' ? 'undefined' : _typeof(json)) === 'object');
|
|
return bytesToHex(signingClaimData(json));
|
|
}
|
|
|
|
function encodeForMultisigning(json, signer) {
|
|
assert((typeof json === 'undefined' ? 'undefined' : _typeof(json)) === 'object');
|
|
assert.equal(json.SigningPubKey, '');
|
|
return bytesToHex(multiSigningData(json, signer));
|
|
}
|
|
|
|
function encodeQuality(value) {
|
|
assert(typeof value === 'string');
|
|
return bytesToHex(quality.encode(value));
|
|
}
|
|
|
|
function decodeQuality(value) {
|
|
assert(typeof value === 'string');
|
|
return quality.decode(value).toString();
|
|
}
|
|
|
|
module.exports = {
|
|
decode: decode,
|
|
encode: encode,
|
|
encodeForSigning: encodeForSigning,
|
|
encodeForSigningClaim: encodeForSigningClaim,
|
|
encodeForMultisigning: encodeForMultisigning,
|
|
encodeQuality: encodeQuality,
|
|
decodeQuality: decodeQuality,
|
|
decodeLedgerData: decodeLedgerData };
|
|
},{"./coretypes":49,"assert":94}],55:[function(require,module,exports){
|
|
'use strict';function _toConsumableArray(arr) {if (Array.isArray(arr)) {for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {arr2[i] = arr[i];}return arr2;} else {return Array.from(arr);}}var _ = require('lodash');
|
|
var BN = require('bn.js');
|
|
var assert = require('assert');
|
|
var types = require('./types');var
|
|
STObject = types.STObject,Hash256 = types.Hash256;var _require =
|
|
require('./shamap'),ShaMap = _require.ShaMap;var _require2 =
|
|
require('./hash-prefixes'),HashPrefix = _require2.HashPrefix;var _require3 =
|
|
require('./hashes'),Sha512Half = _require3.Sha512Half;var _require4 =
|
|
require('./binary'),BinarySerializer = _require4.BinarySerializer,serializeObject = _require4.serializeObject;
|
|
|
|
function computeHash(itemizer, itemsJson) {
|
|
var map = new ShaMap();
|
|
itemsJson.forEach(function (item) {return map.addItem.apply(map, _toConsumableArray(itemizer(item)));});
|
|
return map.hash();
|
|
}
|
|
|
|
function transactionItem(json) {
|
|
assert(json.hash);
|
|
var index = Hash256.from(json.hash);
|
|
var item = {
|
|
hashPrefix: function hashPrefix() {
|
|
return HashPrefix.transaction;
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
var serializer = new BinarySerializer(sink);
|
|
serializer.writeLengthEncoded(STObject.from(json));
|
|
serializer.writeLengthEncoded(STObject.from(json.metaData));
|
|
} };
|
|
|
|
return [index, item];
|
|
}
|
|
|
|
function entryItem(json) {
|
|
var index = Hash256.from(json.index);
|
|
var bytes = serializeObject(json);
|
|
var item = {
|
|
hashPrefix: function hashPrefix() {
|
|
return HashPrefix.accountStateEntry;
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
sink.put(bytes);
|
|
} };
|
|
|
|
return [index, item];
|
|
}
|
|
|
|
var transactionTreeHash = _.partial(computeHash, transactionItem);
|
|
var accountStateHash = _.partial(computeHash, entryItem);
|
|
|
|
function ledgerHash(header) {
|
|
var hash = new Sha512Half();
|
|
hash.put(HashPrefix.ledgerHeader);
|
|
assert(header.parent_close_time !== undefined);
|
|
assert(header.close_flags !== undefined);
|
|
|
|
types.UInt32.from(header.ledger_index).toBytesSink(hash);
|
|
types.UInt64.from(new BN(header.total_coins)).toBytesSink(hash);
|
|
types.Hash256.from(header.parent_hash).toBytesSink(hash);
|
|
types.Hash256.from(header.transaction_hash).toBytesSink(hash);
|
|
types.Hash256.from(header.account_hash).toBytesSink(hash);
|
|
types.UInt32.from(header.parent_close_time).toBytesSink(hash);
|
|
types.UInt32.from(header.close_time).toBytesSink(hash);
|
|
types.UInt8.from(header.close_time_resolution).toBytesSink(hash);
|
|
types.UInt8.from(header.close_flags).toBytesSink(hash);
|
|
return hash.finish();
|
|
}
|
|
|
|
module.exports = {
|
|
accountStateHash: accountStateHash,
|
|
transactionTreeHash: transactionTreeHash,
|
|
ledgerHash: ledgerHash };
|
|
},{"./binary":48,"./hash-prefixes":52,"./hashes":53,"./shamap":59,"./types":68,"assert":94,"bn.js":2,"lodash":39}],56:[function(require,module,exports){
|
|
'use strict';var Decimal = require('decimal.js');var _require =
|
|
require('./utils/bytes-utils'),bytesToHex = _require.bytesToHex,slice = _require.slice,parseBytes = _require.parseBytes;var _require2 =
|
|
require('./types'),UInt64 = _require2.UInt64;
|
|
var BN = require('bn.js');
|
|
|
|
module.exports = {
|
|
encode: function encode(arg) {
|
|
var quality = arg instanceof Decimal ? arg : new Decimal(arg);
|
|
var exponent = quality.e - 15;
|
|
var qualityString = quality.times('1e' + -exponent).abs().toString();
|
|
var bytes = new UInt64(new BN(qualityString)).toBytes();
|
|
bytes[0] = exponent + 100;
|
|
return bytes;
|
|
},
|
|
decode: function decode(arg) {
|
|
var bytes = slice(parseBytes(arg), -8);
|
|
var exponent = bytes[0] - 100;
|
|
var mantissa = new Decimal('0x' + bytesToHex(slice(bytes, 1)));
|
|
return mantissa.times('1e' + exponent);
|
|
} };
|
|
},{"./types":68,"./utils/bytes-utils":79,"bn.js":2,"decimal.js":6}],57:[function(require,module,exports){
|
|
'use strict';var assert = require('assert');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('../enums'),Field = _require.Field;var _require2 =
|
|
require('../utils/bytes-utils'),slice = _require2.slice,parseBytes = _require2.parseBytes;
|
|
|
|
var BinaryParser = makeClass({
|
|
BinaryParser: function BinaryParser(buf) {
|
|
this._buf = parseBytes(buf, Uint8Array);
|
|
this._length = this._buf.length;
|
|
this._cursor = 0;
|
|
},
|
|
skip: function skip(n) {
|
|
this._cursor += n;
|
|
},
|
|
read: function read(n) {var to = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Uint8Array;
|
|
var start = this._cursor;
|
|
var end = this._cursor + n;
|
|
assert(end <= this._buf.length);
|
|
this._cursor = end;
|
|
return slice(this._buf, start, end, to);
|
|
},
|
|
readUIntN: function readUIntN(n) {
|
|
return this.read(n, Array).reduce(function (a, b) {return a << 8 | b;}) >>> 0;
|
|
},
|
|
readUInt8: function readUInt8() {
|
|
return this._buf[this._cursor++];
|
|
},
|
|
readUInt16: function readUInt16() {
|
|
return this.readUIntN(2);
|
|
},
|
|
readUInt32: function readUInt32() {
|
|
return this.readUIntN(4);
|
|
},
|
|
pos: function pos() {
|
|
return this._cursor;
|
|
},
|
|
size: function size() {
|
|
return this._buf.length;
|
|
},
|
|
end: function end(customEnd) {
|
|
var cursor = this.pos();
|
|
return cursor >= this._length || customEnd !== null &&
|
|
cursor >= customEnd;
|
|
},
|
|
readVL: function readVL() {
|
|
return this.read(this.readVLLength());
|
|
},
|
|
readVLLength: function readVLLength() {
|
|
var b1 = this.readUInt8();
|
|
if (b1 <= 192) {
|
|
return b1;
|
|
} else if (b1 <= 240) {
|
|
var b2 = this.readUInt8();
|
|
return 193 + (b1 - 193) * 256 + b2;
|
|
} else if (b1 <= 254) {
|
|
var _b = this.readUInt8();
|
|
var b3 = this.readUInt8();
|
|
return 12481 + (b1 - 241) * 65536 + _b * 256 + b3;
|
|
}
|
|
throw new Error('Invalid varint length indicator');
|
|
},
|
|
readFieldOrdinal: function readFieldOrdinal() {
|
|
var tagByte = this.readUInt8();
|
|
var type = (tagByte & 0xF0) >>> 4 || this.readUInt8();
|
|
var nth = tagByte & 0x0F || this.readUInt8();
|
|
return type << 16 | nth;
|
|
},
|
|
readField: function readField() {
|
|
return Field.from(this.readFieldOrdinal());
|
|
},
|
|
readType: function readType(type) {
|
|
return type.fromParser(this);
|
|
},
|
|
typeForField: function typeForField(field) {
|
|
return field.associatedType;
|
|
},
|
|
readFieldValue: function readFieldValue(field) {
|
|
var kls = this.typeForField(field);
|
|
if (!kls) {
|
|
throw new Error('unsupported: (' + field.name + ', ' + field.type.name + ')');
|
|
}
|
|
var sizeHint = field.isVLEncoded ? this.readVLLength() : null;
|
|
var value = kls.fromParser(this, sizeHint);
|
|
if (value === undefined) {
|
|
throw new Error('fromParser for (' +
|
|
field.name + ', ' + field.type.name + ') -> undefined ');
|
|
}
|
|
return value;
|
|
},
|
|
readFieldAndValue: function readFieldAndValue() {
|
|
var field = this.readField();
|
|
return [field, this.readFieldValue(field)];
|
|
} });
|
|
|
|
|
|
|
|
module.exports = {
|
|
BinaryParser: BinaryParser };
|
|
},{"../enums":51,"../utils/bytes-utils":79,"../utils/make-class":80,"assert":94}],58:[function(require,module,exports){
|
|
'use strict';var assert = require('assert');var _require =
|
|
require('../utils/bytes-utils'),parseBytes = _require.parseBytes,bytesToHex = _require.bytesToHex;
|
|
var makeClass = require('../utils/make-class');var _require2 =
|
|
require('../enums'),Type = _require2.Type,Field = _require2.Field;
|
|
|
|
var BytesSink = {
|
|
put: function put() /* bytesSequence */{
|
|
// any hex string or any object with a `length` and where 0 <= [ix] <= 255
|
|
} };
|
|
|
|
|
|
var BytesList = makeClass({
|
|
implementing: BytesSink,
|
|
BytesList: function BytesList() {
|
|
this.arrays = [];
|
|
this.length = 0;
|
|
},
|
|
put: function put(bytesArg) {
|
|
var bytes = parseBytes(bytesArg, Uint8Array);
|
|
this.length += bytes.length;
|
|
this.arrays.push(bytes);
|
|
return this;
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
this.arrays.forEach(function (arr) {
|
|
sink.put(arr);
|
|
});
|
|
},
|
|
toBytes: function toBytes() {
|
|
var concatenated = new Uint8Array(this.length);
|
|
var pointer = 0;
|
|
this.arrays.forEach(function (arr) {
|
|
concatenated.set(arr, pointer);
|
|
pointer += arr.length;
|
|
});
|
|
return concatenated;
|
|
},
|
|
toHex: function toHex() {
|
|
return bytesToHex(this.toBytes());
|
|
} });
|
|
|
|
|
|
var BinarySerializer = makeClass({
|
|
BinarySerializer: function BinarySerializer(sink) {
|
|
this.sink = sink;
|
|
},
|
|
write: function write(value) {
|
|
value.toBytesSink(this.sink);
|
|
},
|
|
put: function put(bytes) {
|
|
this.sink.put(bytes);
|
|
},
|
|
writeType: function writeType(type, value) {
|
|
this.write(type.from(value));
|
|
},
|
|
writeBytesList: function writeBytesList(bl) {
|
|
bl.toBytesSink(this.sink);
|
|
},
|
|
encodeVL: function encodeVL(len) {
|
|
var length = len;
|
|
var lenBytes = new Uint8Array(4);
|
|
if (length <= 192) {
|
|
lenBytes[0] = length;
|
|
return lenBytes.subarray(0, 1);
|
|
} else if (length <= 12480) {
|
|
length -= 193;
|
|
lenBytes[0] = 193 + (length >>> 8);
|
|
lenBytes[1] = length & 0xff;
|
|
return lenBytes.subarray(0, 2);
|
|
} else if (length <= 918744) {
|
|
length -= 12481;
|
|
lenBytes[0] = 241 + (length >>> 16);
|
|
lenBytes[1] = length >> 8 & 0xff;
|
|
lenBytes[2] = length & 0xff;
|
|
return lenBytes.subarray(0, 3);
|
|
}
|
|
throw new Error('Overflow error');
|
|
},
|
|
writeFieldAndValue: function writeFieldAndValue(field, _value) {
|
|
var sink = this.sink;
|
|
var value = field.associatedType.from(_value);
|
|
assert(value.toBytesSink, field);
|
|
sink.put(field.bytes);
|
|
|
|
if (field.isVLEncoded) {
|
|
this.writeLengthEncoded(value);
|
|
} else {
|
|
value.toBytesSink(sink);
|
|
if (field.type === Type.STObject) {
|
|
sink.put(Field.ObjectEndMarker.bytes);
|
|
} else if (field.type === Type.STArray) {
|
|
sink.put(Field.ArrayEndMarker.bytes);
|
|
}
|
|
}
|
|
},
|
|
writeLengthEncoded: function writeLengthEncoded(value) {
|
|
var bytes = new BytesList();
|
|
value.toBytesSink(bytes);
|
|
this.put(this.encodeVL(bytes.length));
|
|
this.writeBytesList(bytes);
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
BytesList: BytesList,
|
|
BinarySerializer: BinarySerializer };
|
|
},{"../enums":51,"../utils/bytes-utils":79,"../utils/make-class":80,"assert":94}],59:[function(require,module,exports){
|
|
'use strict';var assert = require('assert');
|
|
var makeClass = require('./utils/make-class');var _require =
|
|
require('./types'),Hash256 = _require.Hash256;var _require2 =
|
|
require('./hash-prefixes'),HashPrefix = _require2.HashPrefix;var _require3 =
|
|
require('./hashes'),Hasher = _require3.Sha512Half;
|
|
|
|
var ShaMapNode = makeClass({
|
|
virtuals: {
|
|
hashPrefix: function hashPrefix() {},
|
|
isLeaf: function isLeaf() {},
|
|
isInner: function isInner() {} },
|
|
|
|
cached: {
|
|
hash: function hash() {
|
|
var hasher = Hasher.put(this.hashPrefix());
|
|
this.toBytesSink(hasher);
|
|
return hasher.finish();
|
|
} } });
|
|
|
|
|
|
|
|
var ShaMapLeaf = makeClass({
|
|
inherits: ShaMapNode,
|
|
ShaMapLeaf: function ShaMapLeaf(index, item) {
|
|
ShaMapNode.call(this);
|
|
this.index = index;
|
|
this.item = item;
|
|
},
|
|
isLeaf: function isLeaf() {
|
|
return true;
|
|
},
|
|
isInner: function isInner() {
|
|
return false;
|
|
},
|
|
hashPrefix: function hashPrefix() {
|
|
return this.item.hashPrefix();
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
this.item.toBytesSink(sink);
|
|
this.index.toBytesSink(sink);
|
|
} });
|
|
|
|
|
|
var $uper = ShaMapNode.prototype;
|
|
|
|
var ShaMapInner = makeClass({
|
|
inherits: ShaMapNode,
|
|
ShaMapInner: function ShaMapInner() {var depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
ShaMapNode.call(this);
|
|
this.depth = depth;
|
|
this.slotBits = 0;
|
|
this.branches = Array(16);
|
|
},
|
|
isInner: function isInner() {
|
|
return true;
|
|
},
|
|
isLeaf: function isLeaf() {
|
|
return false;
|
|
},
|
|
hashPrefix: function hashPrefix() {
|
|
return HashPrefix.innerNode;
|
|
},
|
|
setBranch: function setBranch(slot, branch) {
|
|
this.slotBits = this.slotBits | 1 << slot;
|
|
this.branches[slot] = branch;
|
|
},
|
|
empty: function empty() {
|
|
return this.slotBits === 0;
|
|
},
|
|
hash: function hash() {
|
|
if (this.empty()) {
|
|
return Hash256.ZERO_256;
|
|
}
|
|
return $uper.hash.call(this);
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
for (var i = 0; i < this.branches.length; i++) {
|
|
var branch = this.branches[i];
|
|
var hash = branch ? branch.hash() : Hash256.ZERO_256;
|
|
hash.toBytesSink(sink);
|
|
}
|
|
},
|
|
addItem: function addItem(index, item, leaf) {
|
|
assert(index instanceof Hash256);
|
|
var nibble = index.nibblet(this.depth);
|
|
var existing = this.branches[nibble];
|
|
if (!existing) {
|
|
this.setBranch(nibble, leaf || new ShaMapLeaf(index, item));
|
|
} else if (existing.isLeaf()) {
|
|
var newInner = new ShaMapInner(this.depth + 1);
|
|
newInner.addItem(existing.index, null, existing);
|
|
newInner.addItem(index, item, leaf);
|
|
this.setBranch(nibble, newInner);
|
|
} else if (existing.isInner()) {
|
|
existing.addItem(index, item, leaf);
|
|
} else {
|
|
assert(false);
|
|
}
|
|
} });
|
|
|
|
|
|
var ShaMap = makeClass({
|
|
inherits: ShaMapInner });
|
|
|
|
|
|
module.exports = {
|
|
ShaMap: ShaMap };
|
|
},{"./hash-prefixes":52,"./hashes":53,"./types":68,"./utils/make-class":80,"assert":94}],60:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('ripple-address-codec'),decodeAccountID = _require.decodeAccountID,encodeAccountID = _require.encodeAccountID;var _require2 =
|
|
require('./hash-160'),Hash160 = _require2.Hash160;
|
|
|
|
var AccountID = makeClass({
|
|
AccountID: function AccountID(bytes) {
|
|
Hash160.call(this, bytes);
|
|
},
|
|
inherits: Hash160,
|
|
statics: {
|
|
from: function from(value) {
|
|
return value instanceof this ? value :
|
|
/^r/.test(value) ? this.fromBase58(value) :
|
|
new this(value);
|
|
},
|
|
cache: {},
|
|
fromCache: function fromCache(base58) {
|
|
var cached = this.cache[base58];
|
|
if (!cached) {
|
|
cached = this.cache[base58] = this.fromBase58(base58);
|
|
}
|
|
return cached;
|
|
},
|
|
fromBase58: function fromBase58(value) {
|
|
var acc = new this(decodeAccountID(value));
|
|
acc._toBase58 = value;
|
|
return acc;
|
|
} },
|
|
|
|
toJSON: function toJSON() {
|
|
return this.toBase58();
|
|
},
|
|
cached: {
|
|
toBase58: function toBase58() {
|
|
return encodeAccountID(this._bytes);
|
|
} } });
|
|
|
|
|
|
|
|
module.exports = {
|
|
AccountID: AccountID };
|
|
},{"../utils/make-class":80,"./hash-160":65,"ripple-address-codec":44}],61:[function(require,module,exports){
|
|
'use strict';var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;};function _toConsumableArray(arr) {if (Array.isArray(arr)) {for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {arr2[i] = arr[i];}return arr2;} else {return Array.from(arr);}}var _ = require('lodash');
|
|
var assert = require('assert');
|
|
var BN = require('bn.js');
|
|
var Decimal = require('decimal.js');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('./serialized-type'),SerializedType = _require.SerializedType;var _require2 =
|
|
require('../utils/bytes-utils'),bytesToHex = _require2.bytesToHex;var _require3 =
|
|
require('./currency'),Currency = _require3.Currency;var _require4 =
|
|
require('./account-id'),AccountID = _require4.AccountID;var _require5 =
|
|
require('./uint-64'),UInt64 = _require5.UInt64;
|
|
|
|
var MIN_IOU_EXPONENT = -96;
|
|
var MAX_IOU_EXPONENT = 80;
|
|
var MAX_IOU_PRECISION = 16;
|
|
var MIN_IOU_MANTISSA = '1000' + '0000' + '0000' + '0000'; // 16 digits
|
|
var MAX_IOU_MANTISSA = '9999' + '9999' + '9999' + '9999'; // ..
|
|
var MAX_IOU = new Decimal(MAX_IOU_MANTISSA + 'e' + MAX_IOU_EXPONENT);
|
|
var MIN_IOU = new Decimal(MIN_IOU_MANTISSA + 'e' + MIN_IOU_EXPONENT);
|
|
var DROPS_PER_XRP = new Decimal('1e6');
|
|
var MAX_NETWORK_DROPS = new Decimal('1e17');
|
|
var MIN_XRP = new Decimal('1e-6');
|
|
var MAX_XRP = MAX_NETWORK_DROPS.dividedBy(DROPS_PER_XRP);
|
|
|
|
// Never use exponential form
|
|
Decimal.config({
|
|
toExpPos: MAX_IOU_EXPONENT + MAX_IOU_PRECISION,
|
|
toExpNeg: MIN_IOU_EXPONENT - MAX_IOU_PRECISION });
|
|
|
|
|
|
var AMOUNT_PARAMETERS_DESCRIPTION = '\nNative values must be described in drops, a million of which equal one XRP.\nThis must be an integer number, with the absolute value not exceeding ' +
|
|
|
|
|
|
MAX_NETWORK_DROPS + '\n\nIOU values must have a maximum precision of ' +
|
|
|
|
MAX_IOU_PRECISION + ' significant digits. They are serialized as\na canonicalised mantissa and exponent.\n\nThe valid range for a mantissa is between ' +
|
|
|
|
|
|
MIN_IOU_MANTISSA + ' and ' +
|
|
MAX_IOU_MANTISSA + '\nThe exponent must be >= ' +
|
|
MIN_IOU_EXPONENT + ' and <= ' + MAX_IOU_EXPONENT + '\n\nThus the largest serializable IOU value is:\n' +
|
|
|
|
|
|
MAX_IOU.toString() + '\n\nAnd the smallest:\n' +
|
|
|
|
|
|
MIN_IOU.toString() + '\n';
|
|
|
|
|
|
function isDefined(val) {
|
|
return !_.isUndefined(val);
|
|
}
|
|
|
|
function raiseIllegalAmountError(value) {
|
|
throw new Error(value.toString() + ' is an illegal amount\n' +
|
|
AMOUNT_PARAMETERS_DESCRIPTION);
|
|
}
|
|
|
|
var parsers = {
|
|
string: function string(str) {
|
|
// Using /^\d+$/ here fixes #31
|
|
if (!str.match(/^\d+$/)) {
|
|
raiseIllegalAmountError(str);
|
|
}
|
|
return [new Decimal(str).dividedBy(DROPS_PER_XRP), Currency.XRP];
|
|
},
|
|
object: function object(_object) {
|
|
assert(isDefined(_object.currency), 'currency must be defined');
|
|
assert(isDefined(_object.issuer), 'issuer must be defined');
|
|
return [new Decimal(_object.value),
|
|
Currency.from(_object.currency),
|
|
AccountID.from(_object.issuer)];
|
|
} };
|
|
|
|
|
|
var Amount = makeClass({
|
|
Amount: function Amount(value, currency, issuer) {var validate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
|
this.value = value || new Decimal('0');
|
|
this.currency = currency || Currency.XRP;
|
|
this.issuer = issuer || null;
|
|
if (validate) {
|
|
this.assertValueIsValid();
|
|
}
|
|
},
|
|
mixins: SerializedType,
|
|
statics: {
|
|
from: function from(value) {
|
|
if (value instanceof this) {
|
|
return value;
|
|
}
|
|
var parser = parsers[typeof value === 'undefined' ? 'undefined' : _typeof(value)];
|
|
if (parser) {
|
|
return new (Function.prototype.bind.apply(this, [null].concat(_toConsumableArray(parser(value)))))();
|
|
}
|
|
throw new Error('unsupported value: ' + value);
|
|
},
|
|
fromParser: function fromParser(parser) {
|
|
var mantissa = parser.read(8);
|
|
var b1 = mantissa[0];
|
|
var b2 = mantissa[1];
|
|
|
|
var isIOU = b1 & 0x80;
|
|
var isPositive = b1 & 0x40;
|
|
var sign = isPositive ? '' : '-';
|
|
|
|
if (isIOU) {
|
|
mantissa[0] = 0;
|
|
var currency = parser.readType(Currency);
|
|
var issuer = parser.readType(AccountID);
|
|
var exponent = ((b1 & 0x3F) << 2) + ((b2 & 0xff) >> 6) - 97;
|
|
mantissa[1] &= 0x3F;
|
|
// decimal.js won't accept e notation with hex
|
|
var value = new Decimal(sign + '0x' + bytesToHex(mantissa)).
|
|
times('1e' + exponent);
|
|
return new this(value, currency, issuer, false);
|
|
}
|
|
|
|
mantissa[0] &= 0x3F;
|
|
var drops = new Decimal(sign + '0x' + bytesToHex(mantissa));
|
|
var xrpValue = drops.dividedBy(DROPS_PER_XRP);
|
|
return new this(xrpValue, Currency.XRP, null, false);
|
|
} },
|
|
|
|
assertValueIsValid: function assertValueIsValid() {
|
|
// zero is always a valid amount value
|
|
if (!this.isZero()) {
|
|
if (this.isNative()) {
|
|
var abs = this.value.abs();
|
|
if (abs.lt(MIN_XRP) || abs.gt(MAX_XRP)) {
|
|
// value is in XRP scale, but show the value in canonical json form
|
|
raiseIllegalAmountError(this.value.times(DROPS_PER_XRP));
|
|
}
|
|
this.verifyNoDecimal(this.value); // This is a secondary fix for #31
|
|
} else {
|
|
var p = this.value.precision();
|
|
var e = this.exponent();
|
|
if (p > MAX_IOU_PRECISION ||
|
|
e > MAX_IOU_EXPONENT ||
|
|
e < MIN_IOU_EXPONENT) {
|
|
raiseIllegalAmountError(this.value);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
isNative: function isNative() {
|
|
return this.currency.isNative();
|
|
},
|
|
mantissa: function mantissa() {
|
|
// This is a tertiary fix for #31
|
|
var integerNumberString = this.verifyNoDecimal();
|
|
|
|
return new UInt64(
|
|
new BN(integerNumberString));
|
|
},
|
|
verifyNoDecimal: function verifyNoDecimal() {
|
|
var integerNumberString = this.value.
|
|
times('1e' + -this.exponent()).abs().toString();
|
|
// Ensure that the value (after being multiplied by the exponent)
|
|
// does not contain a decimal. From the bn.js README:
|
|
// "decimals are not supported in this library."
|
|
// eslint-disable-next-line max-len
|
|
// https://github.com/indutny/bn.js/blob/9cb459f044853b46615464eea1a3ddfc7006463b/README.md
|
|
if (integerNumberString.indexOf('.') !== -1) {
|
|
raiseIllegalAmountError(integerNumberString);
|
|
}
|
|
return integerNumberString;
|
|
},
|
|
isZero: function isZero() {
|
|
return this.value.isZero();
|
|
},
|
|
exponent: function exponent() {
|
|
return this.isNative() ? -6 : this.value.e - 15;
|
|
},
|
|
valueString: function valueString() {
|
|
return (this.isNative() ? this.value.times(DROPS_PER_XRP) : this.value).
|
|
toString();
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
var isNative = this.isNative();
|
|
var notNegative = !this.value.isNegative();
|
|
var mantissa = this.mantissa().toBytes();
|
|
|
|
if (isNative) {
|
|
mantissa[0] |= notNegative ? 0x40 : 0;
|
|
sink.put(mantissa);
|
|
} else {
|
|
mantissa[0] |= 0x80;
|
|
if (!this.isZero()) {
|
|
if (notNegative) {
|
|
mantissa[0] |= 0x40;
|
|
}
|
|
var exponent = this.value.e - 15;
|
|
var exponentByte = 97 + exponent;
|
|
mantissa[0] |= exponentByte >>> 2;
|
|
mantissa[1] |= (exponentByte & 0x03) << 6;
|
|
}
|
|
sink.put(mantissa);
|
|
this.currency.toBytesSink(sink);
|
|
this.issuer.toBytesSink(sink);
|
|
}
|
|
},
|
|
toJSON: function toJSON() {
|
|
var valueString = this.valueString();
|
|
if (this.isNative()) {
|
|
return valueString;
|
|
}
|
|
return {
|
|
value: valueString,
|
|
currency: this.currency.toJSON(),
|
|
issuer: this.issuer.toJSON() };
|
|
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
Amount: Amount };
|
|
},{"../utils/bytes-utils":79,"../utils/make-class":80,"./account-id":60,"./currency":63,"./serialized-type":70,"./uint-64":75,"assert":94,"bn.js":2,"decimal.js":6,"lodash":39}],62:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('../utils/bytes-utils'),parseBytes = _require.parseBytes;var _require2 =
|
|
require('./serialized-type'),SerializedType = _require2.SerializedType;
|
|
|
|
var Blob = makeClass({
|
|
mixins: SerializedType,
|
|
Blob: function Blob(bytes) {
|
|
if (bytes) {
|
|
this._bytes = parseBytes(bytes, Uint8Array);
|
|
} else {
|
|
this._bytes = new Uint8Array(0);
|
|
}
|
|
},
|
|
statics: {
|
|
fromParser: function fromParser(parser, hint) {
|
|
return new this(parser.read(hint));
|
|
},
|
|
from: function from(value) {
|
|
if (value instanceof this) {
|
|
return value;
|
|
}
|
|
return new this(value);
|
|
} } });
|
|
|
|
|
|
|
|
module.exports = {
|
|
Blob: Blob };
|
|
},{"../utils/bytes-utils":79,"../utils/make-class":80,"./serialized-type":70}],63:[function(require,module,exports){
|
|
'use strict';var _ = require('lodash');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('../utils/bytes-utils'),slice = _require.slice;var _require2 =
|
|
require('./hash-160'),Hash160 = _require2.Hash160;
|
|
var ISO_REGEX = /^[A-Z0-9]{3}$/;
|
|
var HEX_REGEX = /^[A-F0-9]{40}$/;
|
|
|
|
function isoToBytes(iso) {
|
|
var bytes = new Uint8Array(20);
|
|
if (iso !== 'XRP') {
|
|
var isoBytes = iso.split('').map(function (c) {return c.charCodeAt(0);});
|
|
bytes.set(isoBytes, 12);
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
function isISOCode(val) {
|
|
return val.length === 3; // ISO_REGEX.test(val);
|
|
}
|
|
|
|
function isHex(val) {
|
|
return HEX_REGEX.test(val);
|
|
}
|
|
|
|
function isStringRepr(val) {
|
|
return _.isString(val) && (isISOCode(val) || isHex(val));
|
|
}
|
|
|
|
function isBytesArray(val) {
|
|
return val.length === 20;
|
|
}
|
|
|
|
function isValidRepr(val) {
|
|
return isStringRepr(val) || isBytesArray(val);
|
|
}
|
|
|
|
function bytesFromRepr(val) {
|
|
if (isValidRepr(val)) {
|
|
// We assume at this point that we have an object with a length, either 3,
|
|
// 20 or 40.
|
|
return val.length === 3 ? isoToBytes(val) : val;
|
|
}
|
|
throw new Error('Unsupported Currency repr: ' + val);
|
|
}
|
|
|
|
var $uper = Hash160.prototype;
|
|
var Currency = makeClass({
|
|
inherits: Hash160,
|
|
getters: ['isNative', 'iso'],
|
|
statics: {
|
|
init: function init() {
|
|
this.XRP = new this(new Uint8Array(20));
|
|
},
|
|
from: function from(val) {
|
|
return val instanceof this ? val : new this(bytesFromRepr(val));
|
|
} },
|
|
|
|
Currency: function Currency(bytes) {
|
|
Hash160.call(this, bytes);
|
|
this.classify();
|
|
},
|
|
classify: function classify() {
|
|
// We only have a non null iso() property available if the currency can be
|
|
// losslessly represented by the 3 letter iso code. If none is available a
|
|
// hex encoding of the full 20 bytes is the canonical representation.
|
|
var onlyISO = true;
|
|
|
|
var bytes = this._bytes;
|
|
var code = slice(this._bytes, 12, 15, Array);
|
|
var iso = code.map(function (c) {return String.fromCharCode(c);}).join('');
|
|
|
|
for (var i = bytes.length - 1; i >= 0; i--) {
|
|
if (bytes[i] !== 0 && !(i === 12 || i === 13 || i === 14)) {
|
|
onlyISO = false;
|
|
break;
|
|
}
|
|
}
|
|
var lossLessISO = onlyISO && iso !== 'XRP' && ISO_REGEX.test(iso);
|
|
this._isNative = onlyISO && _.isEqual(code, [0, 0, 0]);
|
|
this._iso = this._isNative ? 'XRP' : lossLessISO ? iso : null;
|
|
},
|
|
toJSON: function toJSON() {
|
|
if (this.iso()) {
|
|
return this.iso();
|
|
}
|
|
return $uper.toJSON.call(this);
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
Currency: Currency };
|
|
},{"../utils/bytes-utils":79,"../utils/make-class":80,"./hash-160":65,"lodash":39}],64:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./hash'),Hash = _require.Hash;
|
|
|
|
var Hash128 = makeClass({
|
|
inherits: Hash,
|
|
statics: { width: 16 } });
|
|
|
|
|
|
module.exports = {
|
|
Hash128: Hash128 };
|
|
},{"../utils/make-class":80,"./hash":67}],65:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./hash'),Hash = _require.Hash;
|
|
|
|
var Hash160 = makeClass({
|
|
inherits: Hash,
|
|
statics: { width: 20 } });
|
|
|
|
|
|
module.exports = {
|
|
Hash160: Hash160 };
|
|
},{"../utils/make-class":80,"./hash":67}],66:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./hash'),Hash = _require.Hash;
|
|
|
|
var Hash256 = makeClass({
|
|
inherits: Hash,
|
|
statics: {
|
|
width: 32,
|
|
init: function init() {
|
|
this.ZERO_256 = new this(new Uint8Array(this.width));
|
|
} } });
|
|
|
|
|
|
|
|
module.exports = {
|
|
Hash256: Hash256 };
|
|
},{"../utils/make-class":80,"./hash":67}],67:[function(require,module,exports){
|
|
'use strict';var assert = require('assert');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('./serialized-type'),Comparable = _require.Comparable,SerializedType = _require.SerializedType;var _require2 =
|
|
require('../utils/bytes-utils'),compareBytes = _require2.compareBytes,parseBytes = _require2.parseBytes;
|
|
|
|
var Hash = makeClass({
|
|
Hash: function Hash(bytes) {
|
|
var width = this.constructor.width;
|
|
this._bytes = bytes ? parseBytes(bytes, Uint8Array) :
|
|
new Uint8Array(width);
|
|
assert.equal(this._bytes.length, width);
|
|
},
|
|
mixins: [Comparable, SerializedType],
|
|
statics: {
|
|
width: NaN,
|
|
from: function from(value) {
|
|
if (value instanceof this) {
|
|
return value;
|
|
}
|
|
return new this(parseBytes(value));
|
|
},
|
|
fromParser: function fromParser(parser, hint) {
|
|
return new this(parser.read(hint || this.width));
|
|
} },
|
|
|
|
compareTo: function compareTo(other) {
|
|
return compareBytes(this._bytes, this.constructor.from(other)._bytes);
|
|
},
|
|
toString: function toString() {
|
|
return this.toHex();
|
|
},
|
|
nibblet: function nibblet(depth) {
|
|
var byte_ix = depth > 0 ? depth / 2 | 0 : 0;
|
|
var b = this._bytes[byte_ix];
|
|
if (depth % 2 === 0) {
|
|
b = (b & 0xF0) >>> 4;
|
|
} else {
|
|
b = b & 0x0F;
|
|
}
|
|
return b;
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
Hash: Hash };
|
|
},{"../utils/bytes-utils":79,"../utils/make-class":80,"./serialized-type":70,"assert":94}],68:[function(require,module,exports){
|
|
'use strict';var enums = require('../enums');var
|
|
Field = enums.Field;var _require =
|
|
require('./account-id'),AccountID = _require.AccountID;var _require2 =
|
|
require('./amount'),Amount = _require2.Amount;var _require3 =
|
|
require('./blob'),Blob = _require3.Blob;var _require4 =
|
|
require('./currency'),Currency = _require4.Currency;var _require5 =
|
|
require('./hash-128'),Hash128 = _require5.Hash128;var _require6 =
|
|
require('./hash-160'),Hash160 = _require6.Hash160;var _require7 =
|
|
require('./hash-256'),Hash256 = _require7.Hash256;var _require8 =
|
|
require('./path-set'),PathSet = _require8.PathSet;var _require9 =
|
|
require('./st-array'),STArray = _require9.STArray;var _require10 =
|
|
require('./st-object'),STObject = _require10.STObject;var _require11 =
|
|
require('./uint-16'),UInt16 = _require11.UInt16;var _require12 =
|
|
require('./uint-32'),UInt32 = _require12.UInt32;var _require13 =
|
|
require('./uint-64'),UInt64 = _require13.UInt64;var _require14 =
|
|
require('./uint-8'),UInt8 = _require14.UInt8;var _require15 =
|
|
require('./vector-256'),Vector256 = _require15.Vector256;
|
|
|
|
var coreTypes = {
|
|
AccountID: AccountID,
|
|
Amount: Amount,
|
|
Blob: Blob,
|
|
Currency: Currency,
|
|
Hash128: Hash128,
|
|
Hash160: Hash160,
|
|
Hash256: Hash256,
|
|
PathSet: PathSet,
|
|
STArray: STArray,
|
|
STObject: STObject,
|
|
UInt8: UInt8,
|
|
UInt16: UInt16,
|
|
UInt32: UInt32,
|
|
UInt64: UInt64,
|
|
Vector256: Vector256 };
|
|
|
|
|
|
Field.values.forEach(function (field) {
|
|
field.associatedType = coreTypes[field.type];
|
|
});
|
|
|
|
Field.TransactionType.associatedType = enums.TransactionType;
|
|
Field.TransactionResult.associatedType = enums.TransactionResult;
|
|
Field.LedgerEntryType.associatedType = enums.LedgerEntryType;
|
|
|
|
module.exports = coreTypes;
|
|
},{"../enums":51,"./account-id":60,"./amount":61,"./blob":62,"./currency":63,"./hash-128":64,"./hash-160":65,"./hash-256":66,"./path-set":69,"./st-array":71,"./st-object":72,"./uint-16":73,"./uint-32":74,"./uint-64":75,"./uint-8":76,"./vector-256":78}],69:[function(require,module,exports){
|
|
'use strict'; /* eslint-disable no-unused-expressions */
|
|
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('./serialized-type'),SerializedType = _require.SerializedType,ensureArrayLikeIs = _require.ensureArrayLikeIs;var _require2 =
|
|
require('./currency'),Currency = _require2.Currency;var _require3 =
|
|
require('./account-id'),AccountID = _require3.AccountID;
|
|
|
|
var PATHSET_END_BYTE = 0x00;
|
|
var PATH_SEPARATOR_BYTE = 0xFF;
|
|
var TYPE_ACCOUNT = 0x01;
|
|
var TYPE_CURRENCY = 0x10;
|
|
var TYPE_ISSUER = 0x20;
|
|
|
|
var Hop = makeClass({
|
|
statics: {
|
|
from: function from(value) {
|
|
if (value instanceof this) {
|
|
return value;
|
|
}
|
|
var hop = new Hop();
|
|
value.issuer && (hop.issuer = AccountID.from(value.issuer));
|
|
value.account && (hop.account = AccountID.from(value.account));
|
|
value.currency && (hop.currency = Currency.from(value.currency));
|
|
return hop;
|
|
},
|
|
parse: function parse(parser, type) {
|
|
var hop = new Hop();
|
|
type & TYPE_ACCOUNT && (hop.account = AccountID.fromParser(parser));
|
|
type & TYPE_CURRENCY && (hop.currency = Currency.fromParser(parser));
|
|
type & TYPE_ISSUER && (hop.issuer = AccountID.fromParser(parser));
|
|
return hop;
|
|
} },
|
|
|
|
toJSON: function toJSON() {
|
|
var type = this.type();
|
|
var ret = {};
|
|
type & TYPE_ACCOUNT && (ret.account = this.account.toJSON());
|
|
type & TYPE_ISSUER && (ret.issuer = this.issuer.toJSON());
|
|
type & TYPE_CURRENCY && (ret.currency = this.currency.toJSON());
|
|
return ret;
|
|
},
|
|
type: function type() {
|
|
var type = 0;
|
|
this.issuer && (type += TYPE_ISSUER);
|
|
this.account && (type += TYPE_ACCOUNT);
|
|
this.currency && (type += TYPE_CURRENCY);
|
|
return type;
|
|
} });
|
|
|
|
|
|
var Path = makeClass({
|
|
inherits: Array,
|
|
statics: {
|
|
from: function from(value) {
|
|
return ensureArrayLikeIs(Path, value).withChildren(Hop);
|
|
} },
|
|
|
|
toJSON: function toJSON() {
|
|
return this.map(function (k) {return k.toJSON();});
|
|
} });
|
|
|
|
|
|
var PathSet = makeClass({
|
|
mixins: SerializedType,
|
|
inherits: Array,
|
|
statics: {
|
|
from: function from(value) {
|
|
return ensureArrayLikeIs(PathSet, value).withChildren(Path);
|
|
},
|
|
fromParser: function fromParser(parser) {
|
|
var pathSet = new this();
|
|
var path = void 0;
|
|
while (!parser.end()) {
|
|
var type = parser.readUInt8();
|
|
if (type === PATHSET_END_BYTE) {
|
|
break;
|
|
}
|
|
if (type === PATH_SEPARATOR_BYTE) {
|
|
path = null;
|
|
continue;
|
|
}
|
|
if (!path) {
|
|
path = new Path();
|
|
pathSet.push(path);
|
|
}
|
|
path.push(Hop.parse(parser, type));
|
|
}
|
|
return pathSet;
|
|
} },
|
|
|
|
toJSON: function toJSON() {
|
|
return this.map(function (k) {return k.toJSON();});
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
var n = 0;
|
|
this.forEach(function (path) {
|
|
if (n++ !== 0) {
|
|
sink.put([PATH_SEPARATOR_BYTE]);
|
|
}
|
|
path.forEach(function (hop) {
|
|
sink.put([hop.type()]);
|
|
hop.account && hop.account.toBytesSink(sink);
|
|
hop.currency && hop.currency.toBytesSink(sink);
|
|
hop.issuer && hop.issuer.toBytesSink(sink);
|
|
});
|
|
});
|
|
sink.put([PATHSET_END_BYTE]);
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
PathSet: PathSet };
|
|
},{"../utils/make-class":80,"./account-id":60,"./currency":63,"./serialized-type":70}],70:[function(require,module,exports){
|
|
'use strict';var _require = require('../utils/bytes-utils'),bytesToHex = _require.bytesToHex,slice = _require.slice;var _require2 =
|
|
require('../serdes/binary-serializer'),BytesList = _require2.BytesList;
|
|
|
|
var Comparable = {
|
|
lt: function lt(other) {
|
|
return this.compareTo(other) < 0;
|
|
},
|
|
eq: function eq(other) {
|
|
return this.compareTo(other) === 0;
|
|
},
|
|
gt: function gt(other) {
|
|
return this.compareTo(other) > 0;
|
|
},
|
|
gte: function gte(other) {
|
|
return this.compareTo(other) > -1;
|
|
},
|
|
lte: function lte(other) {
|
|
return this.compareTo(other) < 1;
|
|
} };
|
|
|
|
|
|
var SerializedType = {
|
|
toBytesSink: function toBytesSink(sink) {
|
|
sink.put(this._bytes);
|
|
},
|
|
toHex: function toHex() {
|
|
return bytesToHex(this.toBytes());
|
|
},
|
|
toBytes: function toBytes() {
|
|
if (this._bytes) {
|
|
return slice(this._bytes);
|
|
}
|
|
var bl = new BytesList();
|
|
this.toBytesSink(bl);
|
|
return bl.toBytes();
|
|
},
|
|
toJSON: function toJSON() {
|
|
return this.toHex();
|
|
},
|
|
toString: function toString() {
|
|
return this.toHex();
|
|
} };
|
|
|
|
|
|
function ensureArrayLikeIs(Type, arrayLike) {
|
|
return {
|
|
withChildren: function withChildren(Child) {
|
|
if (arrayLike instanceof Type) {
|
|
return arrayLike;
|
|
}
|
|
var obj = new Type();
|
|
for (var i = 0; i < arrayLike.length; i++) {
|
|
obj.push(Child.from(arrayLike[i]));
|
|
}
|
|
return obj;
|
|
} };
|
|
|
|
}
|
|
|
|
module.exports = {
|
|
ensureArrayLikeIs: ensureArrayLikeIs,
|
|
SerializedType: SerializedType,
|
|
Comparable: Comparable };
|
|
},{"../serdes/binary-serializer":58,"../utils/bytes-utils":79}],71:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./serialized-type'),ensureArrayLikeIs = _require.ensureArrayLikeIs,SerializedType = _require.SerializedType;var _require2 =
|
|
require('../enums'),Field = _require2.Field;var _require3 =
|
|
require('./st-object'),STObject = _require3.STObject;var
|
|
ArrayEndMarker = Field.ArrayEndMarker;
|
|
|
|
var STArray = makeClass({
|
|
mixins: SerializedType,
|
|
inherits: Array,
|
|
statics: {
|
|
fromParser: function fromParser(parser) {
|
|
var array = new STArray();
|
|
while (!parser.end()) {
|
|
var field = parser.readField();
|
|
if (field === ArrayEndMarker) {
|
|
break;
|
|
}
|
|
var outer = new STObject();
|
|
outer[field] = parser.readFieldValue(field);
|
|
array.push(outer);
|
|
}
|
|
return array;
|
|
},
|
|
from: function from(value) {
|
|
return ensureArrayLikeIs(STArray, value).withChildren(STObject);
|
|
} },
|
|
|
|
toJSON: function toJSON() {
|
|
return this.map(function (v) {return v.toJSON();});
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
this.forEach(function (so) {return so.toBytesSink(sink);});
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
STArray: STArray };
|
|
},{"../enums":51,"../utils/make-class":80,"./serialized-type":70,"./st-object":72}],72:[function(require,module,exports){
|
|
'use strict';var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;};var _ = require('lodash');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('../enums'),Field = _require.Field;var _require2 =
|
|
require('../serdes/binary-serializer'),BinarySerializer = _require2.BinarySerializer;var
|
|
ObjectEndMarker = Field.ObjectEndMarker;var _require3 =
|
|
require('./serialized-type'),SerializedType = _require3.SerializedType;
|
|
|
|
var STObject = makeClass({
|
|
mixins: SerializedType,
|
|
statics: {
|
|
fromParser: function fromParser(parser, hint) {
|
|
var end = typeof hint === 'number' ? parser.pos() + hint : null;
|
|
var so = new this();
|
|
while (!parser.end(end)) {
|
|
var field = parser.readField();
|
|
if (field === ObjectEndMarker) {
|
|
break;
|
|
}
|
|
so[field] = parser.readFieldValue(field);
|
|
}
|
|
return so;
|
|
},
|
|
from: function from(value) {
|
|
if (value instanceof this) {
|
|
return value;
|
|
}
|
|
if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
|
|
return _.transform(value, function (so, val, key) {
|
|
var field = Field[key];
|
|
if (field) {
|
|
so[field] = field.associatedType.from(val);
|
|
} else {
|
|
so[key] = val;
|
|
}
|
|
}, new this());
|
|
}
|
|
throw new Error(value + ' is unsupported');
|
|
} },
|
|
|
|
fieldKeys: function fieldKeys() {
|
|
return Object.keys(this).map(function (k) {return Field[k];}).filter(Boolean);
|
|
},
|
|
toJSON: function toJSON() {
|
|
// Otherwise seemingly result will have same prototype as `this`
|
|
var accumulator = {}; // of only `own` properties
|
|
return _.transform(this, function (result, value, key) {
|
|
result[key] = value && value.toJSON ? value.toJSON() : value;
|
|
}, accumulator);
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {var _this = this;var filter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {return true;};
|
|
var serializer = new BinarySerializer(sink);
|
|
var fields = this.fieldKeys();
|
|
var sorted = _.sortBy(fields, 'ordinal');
|
|
sorted.filter(filter).forEach(function (field) {
|
|
var value = _this[field];
|
|
if (!field.isSerialized) {
|
|
return;
|
|
}
|
|
serializer.writeFieldAndValue(field, value);
|
|
});
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
STObject: STObject };
|
|
},{"../enums":51,"../serdes/binary-serializer":58,"../utils/make-class":80,"./serialized-type":70,"lodash":39}],73:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./uint'),UInt = _require.UInt;
|
|
|
|
var UInt16 = makeClass({
|
|
inherits: UInt,
|
|
statics: { width: 2 } });
|
|
|
|
|
|
module.exports = {
|
|
UInt16: UInt16 };
|
|
},{"../utils/make-class":80,"./uint":77}],74:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./uint'),UInt = _require.UInt;
|
|
|
|
var UInt32 = makeClass({
|
|
inherits: UInt,
|
|
statics: { width: 4 } });
|
|
|
|
|
|
module.exports = {
|
|
UInt32: UInt32 };
|
|
},{"../utils/make-class":80,"./uint":77}],75:[function(require,module,exports){
|
|
'use strict';var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;};var assert = require('assert');
|
|
var BN = require('bn.js');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
|
|
require('../utils/bytes-utils'),bytesToHex = _require.bytesToHex,parseBytes = _require.parseBytes,serializeUIntN = _require.serializeUIntN;var _require2 =
|
|
require('./uint'),UInt = _require2.UInt;
|
|
|
|
var HEX_REGEX = /^[A-F0-9]{16}$/;
|
|
|
|
var UInt64 = makeClass({
|
|
inherits: UInt,
|
|
statics: { width: 8 },
|
|
UInt64: function UInt64() {var arg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
var argType = typeof arg === 'undefined' ? 'undefined' : _typeof(arg);
|
|
if (argType === 'number') {
|
|
assert(arg >= 0);
|
|
this._bytes = new Uint8Array(8);
|
|
this._bytes.set(serializeUIntN(arg, 4), 4);
|
|
} else if (arg instanceof BN) {
|
|
this._bytes = parseBytes(arg.toArray('be', 8), Uint8Array);
|
|
this._toBN = arg;
|
|
} else {
|
|
if (argType === 'string') {
|
|
if (!HEX_REGEX.test(arg)) {
|
|
throw new Error(arg + ' is not a valid UInt64 hex string');
|
|
}
|
|
}
|
|
this._bytes = parseBytes(arg, Uint8Array);
|
|
}
|
|
assert(this._bytes.length === 8);
|
|
},
|
|
toJSON: function toJSON() {
|
|
return bytesToHex(this._bytes);
|
|
},
|
|
valueOf: function valueOf() {
|
|
return this.toBN();
|
|
},
|
|
cached: {
|
|
toBN: function toBN() {
|
|
return new BN(this._bytes);
|
|
} },
|
|
|
|
toBytes: function toBytes() {
|
|
return this._bytes;
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
UInt64: UInt64 };
|
|
},{"../utils/bytes-utils":79,"../utils/make-class":80,"./uint":77,"assert":94,"bn.js":2}],76:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./uint'),UInt = _require.UInt;
|
|
|
|
var UInt8 = makeClass({
|
|
inherits: UInt,
|
|
statics: { width: 1 } });
|
|
|
|
|
|
module.exports = {
|
|
UInt8: UInt8 };
|
|
},{"../utils/make-class":80,"./uint":77}],77:[function(require,module,exports){
|
|
'use strict';var assert = require('assert');
|
|
var BN = require('bn.js');
|
|
var makeClass = require('../utils/make-class');var _require =
|
|
require('./serialized-type'),Comparable = _require.Comparable,SerializedType = _require.SerializedType;var _require2 =
|
|
require('../utils/bytes-utils'),serializeUIntN = _require2.serializeUIntN;
|
|
var MAX_VALUES = [0, 255, 65535, 16777215, 4294967295];
|
|
|
|
function signum(a, b) {
|
|
return a < b ? -1 : a === b ? 0 : 1;
|
|
}
|
|
|
|
var UInt = makeClass({
|
|
mixins: [Comparable, SerializedType],
|
|
UInt: function UInt() {var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
var max = MAX_VALUES[this.constructor.width];
|
|
if (val < 0 || !(val <= max)) {
|
|
throw new Error(val + ' not in range 0 <= $val <= ' + max);
|
|
}
|
|
this.val = val;
|
|
},
|
|
statics: {
|
|
width: 0,
|
|
fromParser: function fromParser(parser) {
|
|
var val = this.width > 4 ? parser.read(this.width) :
|
|
parser.readUIntN(this.width);
|
|
return new this(val);
|
|
},
|
|
from: function from(val) {
|
|
return val instanceof this ? val : new this(val);
|
|
} },
|
|
|
|
toJSON: function toJSON() {
|
|
return this.val;
|
|
},
|
|
valueOf: function valueOf() {
|
|
return this.val;
|
|
},
|
|
compareTo: function compareTo(other) {
|
|
var thisValue = this.valueOf();
|
|
var otherValue = other.valueOf();
|
|
if (thisValue instanceof BN) {
|
|
return otherValue instanceof BN ?
|
|
thisValue.cmp(otherValue) :
|
|
thisValue.cmpn(otherValue);
|
|
} else if (otherValue instanceof BN) {
|
|
return -other.compareTo(this);
|
|
}
|
|
assert(typeof otherValue === 'number');
|
|
return signum(thisValue, otherValue);
|
|
},
|
|
toBytesSink: function toBytesSink(sink) {
|
|
sink.put(this.toBytes());
|
|
},
|
|
toBytes: function toBytes() {
|
|
return serializeUIntN(this.val, this.constructor.width);
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
UInt: UInt };
|
|
},{"../utils/bytes-utils":79,"../utils/make-class":80,"./serialized-type":70,"assert":94,"bn.js":2}],78:[function(require,module,exports){
|
|
'use strict';var makeClass = require('../utils/make-class');var _require =
|
|
require('./hash-256'),Hash256 = _require.Hash256;var _require2 =
|
|
require('./serialized-type'),ensureArrayLikeIs = _require2.ensureArrayLikeIs,SerializedType = _require2.SerializedType;
|
|
|
|
var Vector256 = makeClass({
|
|
mixins: SerializedType,
|
|
inherits: Array,
|
|
statics: {
|
|
fromParser: function fromParser(parser, hint) {
|
|
var vector256 = new this();
|
|
var bytes = hint !== null ? hint : parser.size() - parser.pos();
|
|
var hashes = bytes / 32;
|
|
for (var i = 0; i < hashes; i++) {
|
|
vector256.push(Hash256.fromParser(parser));
|
|
}
|
|
return vector256;
|
|
},
|
|
from: function from(value) {
|
|
return ensureArrayLikeIs(Vector256, value).withChildren(Hash256);
|
|
} },
|
|
|
|
toBytesSink: function toBytesSink(sink) {
|
|
this.forEach(function (h) {return h.toBytesSink(sink);});
|
|
},
|
|
toJSON: function toJSON() {
|
|
return this.map(function (hash) {return hash.toJSON();});
|
|
} });
|
|
|
|
|
|
module.exports = {
|
|
Vector256: Vector256 };
|
|
},{"../utils/make-class":80,"./hash-256":66,"./serialized-type":70}],79:[function(require,module,exports){
|
|
'use strict';var assert = require('assert');
|
|
|
|
function signum(a, b) {
|
|
return a < b ? -1 : a === b ? 0 : 1;
|
|
}
|
|
|
|
var hexLookup = function () {
|
|
var res = {};
|
|
var reverse = res.reverse = new Array(256);
|
|
for (var i = 0; i < 16; i++) {
|
|
var char = i.toString(16).toUpperCase();
|
|
res[char] = i;
|
|
|
|
for (var j = 0; j < 16; j++) {
|
|
var char2 = j.toString(16).toUpperCase();
|
|
var byte = (i << 4) + j;
|
|
var byteHex = char + char2;
|
|
res[byteHex] = byte;
|
|
reverse[byte] = byteHex;
|
|
}
|
|
}
|
|
return res;
|
|
}();
|
|
|
|
var reverseHexLookup = hexLookup.reverse;
|
|
|
|
function bytesToHex(sequence) {
|
|
var buf = Array(sequence.length);
|
|
for (var i = sequence.length - 1; i >= 0; i--) {
|
|
buf[i] = reverseHexLookup[sequence[i]];
|
|
}
|
|
return buf.join('');
|
|
}
|
|
|
|
function byteForHex(hex) {
|
|
var byte = hexLookup[hex];
|
|
if (byte === undefined) {
|
|
throw new Error('`' + hex + '` is not a valid hex representation of a byte');
|
|
}
|
|
return byte;
|
|
}
|
|
|
|
function parseBytes(val) {var Output = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Array;
|
|
if (!val || val.length === undefined) {
|
|
throw new Error(val + ' is not a sequence');
|
|
}
|
|
|
|
if (typeof val === 'string') {
|
|
var start = val.length % 2;
|
|
var _res = new Output((val.length + start) / 2);
|
|
for (var i = val.length, to = _res.length - 1; to >= start; i -= 2, to--) {
|
|
_res[to] = byteForHex(val.slice(i - 2, i));
|
|
}
|
|
if (start === 1) {
|
|
_res[0] = byteForHex(val[0]);
|
|
}
|
|
return _res;
|
|
} else if (val instanceof Output) {
|
|
return val;
|
|
} else if (Output === Uint8Array) {
|
|
return new Output(val);
|
|
}
|
|
var res = new Output(val.length);
|
|
for (var _i = val.length - 1; _i >= 0; _i--) {
|
|
res[_i] = val[_i];
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function serializeUIntN(val, width) {
|
|
var newBytes = new Uint8Array(width);
|
|
var lastIx = width - 1;
|
|
for (var i = 0; i < width; i++) {
|
|
newBytes[lastIx - i] = val >>> i * 8 & 0xff;
|
|
}
|
|
return newBytes;
|
|
}
|
|
|
|
function compareBytes(a, b) {
|
|
assert(a.length === b.length);
|
|
for (var i = 0; i < a.length; i++) {
|
|
var cmp = signum(a[i], b[i]);
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
function slice(val) {var startIx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;var endIx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : val.length;var Output = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : val.constructor;
|
|
/* eslint-disable no-param-reassign*/
|
|
if (startIx < 0) {
|
|
startIx += val.length;
|
|
}
|
|
if (endIx < 0) {
|
|
endIx += val.length;
|
|
}
|
|
/* eslint-enable no-param-reassign*/
|
|
var len = endIx - startIx;
|
|
var res = new Output(len);
|
|
for (var i = endIx - 1; i >= startIx; i--) {
|
|
res[i - startIx] = val[i];
|
|
}
|
|
return res;
|
|
}
|
|
|
|
module.exports = {
|
|
parseBytes: parseBytes,
|
|
bytesToHex: bytesToHex,
|
|
slice: slice,
|
|
compareBytes: compareBytes,
|
|
serializeUIntN: serializeUIntN };
|
|
},{"assert":94}],80:[function(require,module,exports){
|
|
'use strict';var _ = require('lodash');
|
|
var inherits = require('inherits');
|
|
|
|
function forEach(obj, func) {
|
|
Object.keys(obj || {}).forEach(function (k) {
|
|
func(obj[k], k);
|
|
});
|
|
}
|
|
|
|
function ensureArray(val) {
|
|
return Array.isArray(val) ? val : [val];
|
|
}
|
|
|
|
module.exports = function makeClass(klass_, definition_) {
|
|
var definition = definition_ || klass_;
|
|
var klass = typeof klass_ === 'function' ? klass_ : null;
|
|
if (klass === null) {
|
|
for (var k in definition) {
|
|
if (k[0].match(/[A-Z]/)) {
|
|
klass = definition[k];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
var parent = definition.inherits;
|
|
if (parent) {
|
|
if (klass === null) {
|
|
klass = function klass() {
|
|
parent.apply(this, arguments);
|
|
};
|
|
}
|
|
inherits(klass, parent);
|
|
_.defaults(klass, parent);
|
|
}
|
|
if (klass === null) {
|
|
klass = function klass() {};
|
|
}
|
|
var proto = klass.prototype;
|
|
function addFunc(original, name, wrapper) {
|
|
proto[name] = wrapper || original;
|
|
}
|
|
(definition.getters || []).forEach(function (k) {
|
|
var key = '_' + k;
|
|
proto[k] = function () {
|
|
return this[key];
|
|
};
|
|
});
|
|
forEach(definition.virtuals, function (f, n) {
|
|
addFunc(f, n, function () {
|
|
throw new Error('unimplemented');
|
|
});
|
|
});
|
|
forEach(definition.methods, addFunc);
|
|
forEach(definition, function (f, n) {
|
|
if (_.isFunction(f) && f !== klass) {
|
|
addFunc(f, n);
|
|
}
|
|
});
|
|
_.assign(klass, definition.statics);
|
|
if (typeof klass.init === 'function') {
|
|
klass.init();
|
|
}
|
|
forEach(definition.cached, function (f, n) {
|
|
var key = '_' + n;
|
|
addFunc(f, n, function () {
|
|
var value = this[key];
|
|
if (value === undefined) {
|
|
value = this[key] = f.call(this);
|
|
}
|
|
return value;
|
|
});
|
|
});
|
|
if (definition.mixins) {
|
|
var mixins = {};
|
|
// Right-most in the list win
|
|
ensureArray(definition.mixins).reverse().forEach(function (o) {
|
|
_.defaults(mixins, o);
|
|
});
|
|
_.defaults(proto, mixins);
|
|
}
|
|
|
|
return klass;
|
|
};
|
|
},{"inherits":38,"lodash":39}],81:[function(require,module,exports){
|
|
(function (Buffer){
|
|
"use strict";
|
|
const assert = require("assert");
|
|
const brorand = require("brorand");
|
|
const hashjs = require("hash.js");
|
|
const elliptic = require("elliptic");
|
|
const addressCodec = require("ripple-address-codec");
|
|
const secp256k1_1 = require("./secp256k1");
|
|
const utils = require("./utils");
|
|
const Ed25519 = elliptic.eddsa('ed25519');
|
|
const Secp256k1 = elliptic.ec('secp256k1');
|
|
const { hexToBytes } = utils;
|
|
const { bytesToHex } = utils;
|
|
function generateSeed(options = {}) {
|
|
assert(!options.entropy || options.entropy.length >= 16, 'entropy too short');
|
|
const entropy = options.entropy ? options.entropy.slice(0, 16) : brorand(16);
|
|
const type = options.algorithm === 'ed25519' ? 'ed25519' : 'secp256k1';
|
|
return addressCodec.encodeSeed(entropy, type);
|
|
}
|
|
function hash(message) {
|
|
return hashjs
|
|
.sha512()
|
|
.update(message)
|
|
.digest()
|
|
.slice(0, 32);
|
|
}
|
|
const secp256k1 = {
|
|
deriveKeypair(entropy, options) {
|
|
const prefix = '00';
|
|
const privateKey = prefix +
|
|
secp256k1_1.derivePrivateKey(entropy, options)
|
|
.toString(16, 64)
|
|
.toUpperCase();
|
|
const publicKey = bytesToHex(Secp256k1.keyFromPrivate(privateKey.slice(2))
|
|
.getPublic()
|
|
.encodeCompressed());
|
|
return { privateKey, publicKey };
|
|
},
|
|
sign(message, privateKey) {
|
|
return bytesToHex(Secp256k1.sign(hash(message), hexToBytes(privateKey), {
|
|
canonical: true,
|
|
}).toDER());
|
|
},
|
|
verify(message, signature, publicKey) {
|
|
return Secp256k1.verify(hash(message), signature, hexToBytes(publicKey));
|
|
},
|
|
};
|
|
const ed25519 = {
|
|
deriveKeypair(entropy) {
|
|
const prefix = 'ED';
|
|
const rawPrivateKey = hash(entropy);
|
|
const privateKey = prefix + bytesToHex(rawPrivateKey);
|
|
const publicKey = prefix + bytesToHex(Ed25519.keyFromSecret(rawPrivateKey).pubBytes());
|
|
return { privateKey, publicKey };
|
|
},
|
|
sign(message, privateKey) {
|
|
// caution: Ed25519.sign interprets all strings as hex, stripping
|
|
// any non-hex characters without warning
|
|
assert(Array.isArray(message), 'message must be array of octets');
|
|
return bytesToHex(Ed25519.sign(message, hexToBytes(privateKey).slice(1)).toBytes());
|
|
},
|
|
verify(message, signature, publicKey) {
|
|
return Ed25519.verify(message, hexToBytes(signature), hexToBytes(publicKey).slice(1));
|
|
},
|
|
};
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
function select(algorithm) {
|
|
const methods = { 'ecdsa-secp256k1': secp256k1, ed25519 };
|
|
return methods[algorithm];
|
|
}
|
|
function deriveKeypair(seed, options) {
|
|
const decoded = addressCodec.decodeSeed(seed);
|
|
const algorithm = decoded.type === 'ed25519' ? 'ed25519' : 'ecdsa-secp256k1';
|
|
const method = select(algorithm);
|
|
const keypair = method.deriveKeypair(decoded.bytes, options);
|
|
const messageToVerify = hash('This test message should verify.');
|
|
const signature = method.sign(messageToVerify, keypair.privateKey);
|
|
/* istanbul ignore if */
|
|
if (method.verify(messageToVerify, signature, keypair.publicKey) !== true) {
|
|
throw new Error('derived keypair did not generate verifiable signature');
|
|
}
|
|
return keypair;
|
|
}
|
|
function getAlgorithmFromKey(key) {
|
|
const bytes = hexToBytes(key);
|
|
return bytes.length === 33 && bytes[0] === 0xed
|
|
? 'ed25519'
|
|
: 'ecdsa-secp256k1';
|
|
}
|
|
function sign(messageHex, privateKey) {
|
|
const algorithm = getAlgorithmFromKey(privateKey);
|
|
return select(algorithm).sign(hexToBytes(messageHex), privateKey);
|
|
}
|
|
function verify(messageHex, signature, publicKey) {
|
|
const algorithm = getAlgorithmFromKey(publicKey);
|
|
return select(algorithm).verify(hexToBytes(messageHex), signature, publicKey);
|
|
}
|
|
function deriveAddressFromBytes(publicKeyBytes) {
|
|
return addressCodec.encodeAccountID(utils.computePublicKeyHash(publicKeyBytes));
|
|
}
|
|
function deriveAddress(publicKey) {
|
|
return deriveAddressFromBytes(Buffer.from(hexToBytes(publicKey)));
|
|
}
|
|
function deriveNodeAddress(publicKey) {
|
|
const generatorBytes = addressCodec.decodeNodePublic(publicKey);
|
|
const accountPublicBytes = secp256k1_1.accountPublicFromPublicGenerator(generatorBytes);
|
|
return deriveAddressFromBytes(accountPublicBytes);
|
|
}
|
|
const { decodeSeed } = addressCodec;
|
|
module.exports = {
|
|
generateSeed,
|
|
deriveKeypair,
|
|
sign,
|
|
verify,
|
|
deriveAddress,
|
|
deriveNodeAddress,
|
|
decodeSeed,
|
|
};
|
|
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"./secp256k1":82,"./utils":84,"assert":94,"brorand":3,"buffer":100,"elliptic":7,"hash.js":25,"ripple-address-codec":44}],82:[function(require,module,exports){
|
|
"use strict";
|
|
/* eslint-disable */
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const elliptic = require("elliptic");
|
|
const sha512_1 = require("./sha512");
|
|
const secp256k1 = elliptic.ec('secp256k1');
|
|
function deriveScalar(bytes, discrim) {
|
|
const order = secp256k1.curve.n;
|
|
for (let i = 0; i <= 0xffffffff; i++) {
|
|
// We hash the bytes to find a 256 bit number, looping until we are sure it
|
|
// is less than the order of the curve.
|
|
const hasher = new sha512_1.default().add(bytes);
|
|
// If the optional discriminator index was passed in, update the hash.
|
|
if (discrim !== undefined) {
|
|
hasher.addU32(discrim);
|
|
}
|
|
hasher.addU32(i);
|
|
const key = hasher.first256BN();
|
|
/* istanbul ignore else */
|
|
if (key.cmpn(0) > 0 && key.cmp(order) < 0) {
|
|
return key;
|
|
}
|
|
}
|
|
/* This error is practically impossible to reach.
|
|
* The order of the curve describes the (finite) amount of points on the curve
|
|
* https://github.com/indutny/elliptic/blob/master/lib/elliptic/curves.js#L182
|
|
* How often will an (essentially) random number generated by Sha512 be larger than that?
|
|
* There's 2^32 chances (the for loop) to get a number smaller than the order,
|
|
* and it's rare that you'll even get past the first loop iteration.
|
|
* Note that in TypeScript we actually need the throw, otherwise the function signature would be BN | undefined
|
|
*/
|
|
/* istanbul ignore next */
|
|
throw new Error('impossible unicorn ;)');
|
|
}
|
|
/**
|
|
* @param {Array} seed - bytes
|
|
* @param {Object} [opts] - object
|
|
* @param {Number} [opts.accountIndex=0] - the account number to generate
|
|
* @param {Boolean} [opts.validator=false] - generate root key-pair,
|
|
* as used by validators.
|
|
* @return {bn.js} - 256 bit scalar value
|
|
*
|
|
*/
|
|
function derivePrivateKey(seed, opts = {}) {
|
|
const root = opts.validator;
|
|
const order = secp256k1.curve.n;
|
|
// This private generator represents the `root` private key, and is what's
|
|
// used by validators for signing when a keypair is generated from a seed.
|
|
const privateGen = deriveScalar(seed);
|
|
if (root) {
|
|
// As returned by validation_create for a given seed
|
|
return privateGen;
|
|
}
|
|
const publicGen = secp256k1.g.mul(privateGen);
|
|
// A seed can generate many keypairs as a function of the seed and a uint32.
|
|
// Almost everyone just uses the first account, `0`.
|
|
const accountIndex = opts.accountIndex || 0;
|
|
return deriveScalar(publicGen.encodeCompressed(), accountIndex)
|
|
.add(privateGen)
|
|
.mod(order);
|
|
}
|
|
exports.derivePrivateKey = derivePrivateKey;
|
|
function accountPublicFromPublicGenerator(publicGenBytes) {
|
|
const rootPubPoint = secp256k1.curve.decodePoint(publicGenBytes);
|
|
const scalar = deriveScalar(publicGenBytes, 0);
|
|
const point = secp256k1.g.mul(scalar);
|
|
const offset = rootPubPoint.add(point);
|
|
return offset.encodeCompressed();
|
|
}
|
|
exports.accountPublicFromPublicGenerator = accountPublicFromPublicGenerator;
|
|
|
|
},{"./sha512":83,"elliptic":7}],83:[function(require,module,exports){
|
|
"use strict";
|
|
/* eslint-disable */
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const hashjs = require("hash.js");
|
|
const BigNum = require("bn.js");
|
|
class Sha512 {
|
|
constructor() {
|
|
this.hash = hashjs.sha512();
|
|
}
|
|
add(bytes) {
|
|
this.hash.update(bytes);
|
|
return this;
|
|
}
|
|
addU32(i) {
|
|
return this.add([
|
|
(i >>> 24) & 0xff,
|
|
(i >>> 16) & 0xff,
|
|
(i >>> 8) & 0xff,
|
|
i & 0xff,
|
|
]);
|
|
}
|
|
finish() {
|
|
return this.hash.digest();
|
|
}
|
|
first256() {
|
|
return this.finish().slice(0, 32);
|
|
}
|
|
first256BN() {
|
|
return new BigNum(this.first256());
|
|
}
|
|
}
|
|
exports.default = Sha512;
|
|
|
|
},{"bn.js":2,"hash.js":25}],84:[function(require,module,exports){
|
|
(function (Buffer){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const assert = require("assert");
|
|
const hashjs = require("hash.js");
|
|
const BN = require("bn.js");
|
|
function bytesToHex(a) {
|
|
return a
|
|
.map((byteValue) => {
|
|
const hex = byteValue.toString(16).toUpperCase();
|
|
return hex.length > 1 ? hex : `0${hex}`;
|
|
})
|
|
.join('');
|
|
}
|
|
exports.bytesToHex = bytesToHex;
|
|
function hexToBytes(a) {
|
|
assert(a.length % 2 === 0);
|
|
return new BN(a, 16).toArray(null, a.length / 2);
|
|
}
|
|
exports.hexToBytes = hexToBytes;
|
|
function computePublicKeyHash(publicKeyBytes) {
|
|
const hash256 = hashjs
|
|
.sha256()
|
|
.update(publicKeyBytes)
|
|
.digest();
|
|
const hash160 = hashjs
|
|
.ripemd160()
|
|
.update(hash256)
|
|
.digest();
|
|
return Buffer.from(hash160);
|
|
}
|
|
exports.computePublicKeyHash = computePublicKeyHash;
|
|
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"assert":94,"bn.js":2,"buffer":100,"hash.js":25}],85:[function(require,module,exports){
|
|
/* eslint-disable node/no-deprecated-api */
|
|
var buffer = require('buffer')
|
|
var Buffer = buffer.Buffer
|
|
|
|
// alternative to using Object.keys for old browsers
|
|
function copyProps (src, dst) {
|
|
for (var key in src) {
|
|
dst[key] = src[key]
|
|
}
|
|
}
|
|
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
|
|
module.exports = buffer
|
|
} else {
|
|
// Copy properties from require('buffer')
|
|
copyProps(buffer, exports)
|
|
exports.Buffer = SafeBuffer
|
|
}
|
|
|
|
function SafeBuffer (arg, encodingOrOffset, length) {
|
|
return Buffer(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
SafeBuffer.prototype = Object.create(Buffer.prototype)
|
|
|
|
// Copy static methods from Buffer
|
|
copyProps(Buffer, SafeBuffer)
|
|
|
|
SafeBuffer.from = function (arg, encodingOrOffset, length) {
|
|
if (typeof arg === 'number') {
|
|
throw new TypeError('Argument must not be a number')
|
|
}
|
|
return Buffer(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
SafeBuffer.alloc = function (size, fill, encoding) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
var buf = Buffer(size)
|
|
if (fill !== undefined) {
|
|
if (typeof encoding === 'string') {
|
|
buf.fill(fill, encoding)
|
|
} else {
|
|
buf.fill(fill)
|
|
}
|
|
} else {
|
|
buf.fill(0)
|
|
}
|
|
return buf
|
|
}
|
|
|
|
SafeBuffer.allocUnsafe = function (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
return Buffer(size)
|
|
}
|
|
|
|
SafeBuffer.allocUnsafeSlow = function (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
return buffer.SlowBuffer(size)
|
|
}
|
|
|
|
},{"buffer":100}],86:[function(require,module,exports){
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
// prototype class for hash functions
|
|
function Hash (blockSize, finalSize) {
|
|
this._block = Buffer.alloc(blockSize)
|
|
this._finalSize = finalSize
|
|
this._blockSize = blockSize
|
|
this._len = 0
|
|
}
|
|
|
|
Hash.prototype.update = function (data, enc) {
|
|
if (typeof data === 'string') {
|
|
enc = enc || 'utf8'
|
|
data = Buffer.from(data, enc)
|
|
}
|
|
|
|
var block = this._block
|
|
var blockSize = this._blockSize
|
|
var length = data.length
|
|
var accum = this._len
|
|
|
|
for (var offset = 0; offset < length;) {
|
|
var assigned = accum % blockSize
|
|
var remainder = Math.min(length - offset, blockSize - assigned)
|
|
|
|
for (var i = 0; i < remainder; i++) {
|
|
block[assigned + i] = data[offset + i]
|
|
}
|
|
|
|
accum += remainder
|
|
offset += remainder
|
|
|
|
if ((accum % blockSize) === 0) {
|
|
this._update(block)
|
|
}
|
|
}
|
|
|
|
this._len += length
|
|
return this
|
|
}
|
|
|
|
Hash.prototype.digest = function (enc) {
|
|
var rem = this._len % this._blockSize
|
|
|
|
this._block[rem] = 0x80
|
|
|
|
// zero (rem + 1) trailing bits, where (rem + 1) is the smallest
|
|
// non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize
|
|
this._block.fill(0, rem + 1)
|
|
|
|
if (rem >= this._finalSize) {
|
|
this._update(this._block)
|
|
this._block.fill(0)
|
|
}
|
|
|
|
var bits = this._len * 8
|
|
|
|
// uint32
|
|
if (bits <= 0xffffffff) {
|
|
this._block.writeUInt32BE(bits, this._blockSize - 4)
|
|
|
|
// uint64
|
|
} else {
|
|
var lowBits = (bits & 0xffffffff) >>> 0
|
|
var highBits = (bits - lowBits) / 0x100000000
|
|
|
|
this._block.writeUInt32BE(highBits, this._blockSize - 8)
|
|
this._block.writeUInt32BE(lowBits, this._blockSize - 4)
|
|
}
|
|
|
|
this._update(this._block)
|
|
var hash = this._hash()
|
|
|
|
return enc ? hash.toString(enc) : hash
|
|
}
|
|
|
|
Hash.prototype._update = function () {
|
|
throw new Error('_update must be implemented by subclass')
|
|
}
|
|
|
|
module.exports = Hash
|
|
|
|
},{"safe-buffer":85}],87:[function(require,module,exports){
|
|
var exports = module.exports = function SHA (algorithm) {
|
|
algorithm = algorithm.toLowerCase()
|
|
|
|
var Algorithm = exports[algorithm]
|
|
if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')
|
|
|
|
return new Algorithm()
|
|
}
|
|
|
|
exports.sha = require('./sha')
|
|
exports.sha1 = require('./sha1')
|
|
exports.sha224 = require('./sha224')
|
|
exports.sha256 = require('./sha256')
|
|
exports.sha384 = require('./sha384')
|
|
exports.sha512 = require('./sha512')
|
|
|
|
},{"./sha":88,"./sha1":89,"./sha224":90,"./sha256":91,"./sha384":92,"./sha512":93}],88:[function(require,module,exports){
|
|
/*
|
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined
|
|
* in FIPS PUB 180-1
|
|
* This source code is derived from sha1.js of the same repository.
|
|
* The difference between SHA-0 and SHA-1 is just a bitwise rotate left
|
|
* operation was added.
|
|
*/
|
|
|
|
var inherits = require('inherits')
|
|
var Hash = require('./hash')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var K = [
|
|
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
|
|
]
|
|
|
|
var W = new Array(80)
|
|
|
|
function Sha () {
|
|
this.init()
|
|
this._w = W
|
|
|
|
Hash.call(this, 64, 56)
|
|
}
|
|
|
|
inherits(Sha, Hash)
|
|
|
|
Sha.prototype.init = function () {
|
|
this._a = 0x67452301
|
|
this._b = 0xefcdab89
|
|
this._c = 0x98badcfe
|
|
this._d = 0x10325476
|
|
this._e = 0xc3d2e1f0
|
|
|
|
return this
|
|
}
|
|
|
|
function rotl5 (num) {
|
|
return (num << 5) | (num >>> 27)
|
|
}
|
|
|
|
function rotl30 (num) {
|
|
return (num << 30) | (num >>> 2)
|
|
}
|
|
|
|
function ft (s, b, c, d) {
|
|
if (s === 0) return (b & c) | ((~b) & d)
|
|
if (s === 2) return (b & c) | (b & d) | (c & d)
|
|
return b ^ c ^ d
|
|
}
|
|
|
|
Sha.prototype._update = function (M) {
|
|
var W = this._w
|
|
|
|
var a = this._a | 0
|
|
var b = this._b | 0
|
|
var c = this._c | 0
|
|
var d = this._d | 0
|
|
var e = this._e | 0
|
|
|
|
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
|
|
for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
|
|
|
|
for (var j = 0; j < 80; ++j) {
|
|
var s = ~~(j / 20)
|
|
var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
|
|
|
|
e = d
|
|
d = c
|
|
c = rotl30(b)
|
|
b = a
|
|
a = t
|
|
}
|
|
|
|
this._a = (a + this._a) | 0
|
|
this._b = (b + this._b) | 0
|
|
this._c = (c + this._c) | 0
|
|
this._d = (d + this._d) | 0
|
|
this._e = (e + this._e) | 0
|
|
}
|
|
|
|
Sha.prototype._hash = function () {
|
|
var H = Buffer.allocUnsafe(20)
|
|
|
|
H.writeInt32BE(this._a | 0, 0)
|
|
H.writeInt32BE(this._b | 0, 4)
|
|
H.writeInt32BE(this._c | 0, 8)
|
|
H.writeInt32BE(this._d | 0, 12)
|
|
H.writeInt32BE(this._e | 0, 16)
|
|
|
|
return H
|
|
}
|
|
|
|
module.exports = Sha
|
|
|
|
},{"./hash":86,"inherits":38,"safe-buffer":85}],89:[function(require,module,exports){
|
|
/*
|
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
|
* in FIPS PUB 180-1
|
|
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
|
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
|
* Distributed under the BSD License
|
|
* See http://pajhome.org.uk/crypt/md5 for details.
|
|
*/
|
|
|
|
var inherits = require('inherits')
|
|
var Hash = require('./hash')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var K = [
|
|
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
|
|
]
|
|
|
|
var W = new Array(80)
|
|
|
|
function Sha1 () {
|
|
this.init()
|
|
this._w = W
|
|
|
|
Hash.call(this, 64, 56)
|
|
}
|
|
|
|
inherits(Sha1, Hash)
|
|
|
|
Sha1.prototype.init = function () {
|
|
this._a = 0x67452301
|
|
this._b = 0xefcdab89
|
|
this._c = 0x98badcfe
|
|
this._d = 0x10325476
|
|
this._e = 0xc3d2e1f0
|
|
|
|
return this
|
|
}
|
|
|
|
function rotl1 (num) {
|
|
return (num << 1) | (num >>> 31)
|
|
}
|
|
|
|
function rotl5 (num) {
|
|
return (num << 5) | (num >>> 27)
|
|
}
|
|
|
|
function rotl30 (num) {
|
|
return (num << 30) | (num >>> 2)
|
|
}
|
|
|
|
function ft (s, b, c, d) {
|
|
if (s === 0) return (b & c) | ((~b) & d)
|
|
if (s === 2) return (b & c) | (b & d) | (c & d)
|
|
return b ^ c ^ d
|
|
}
|
|
|
|
Sha1.prototype._update = function (M) {
|
|
var W = this._w
|
|
|
|
var a = this._a | 0
|
|
var b = this._b | 0
|
|
var c = this._c | 0
|
|
var d = this._d | 0
|
|
var e = this._e | 0
|
|
|
|
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
|
|
for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
|
|
|
|
for (var j = 0; j < 80; ++j) {
|
|
var s = ~~(j / 20)
|
|
var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
|
|
|
|
e = d
|
|
d = c
|
|
c = rotl30(b)
|
|
b = a
|
|
a = t
|
|
}
|
|
|
|
this._a = (a + this._a) | 0
|
|
this._b = (b + this._b) | 0
|
|
this._c = (c + this._c) | 0
|
|
this._d = (d + this._d) | 0
|
|
this._e = (e + this._e) | 0
|
|
}
|
|
|
|
Sha1.prototype._hash = function () {
|
|
var H = Buffer.allocUnsafe(20)
|
|
|
|
H.writeInt32BE(this._a | 0, 0)
|
|
H.writeInt32BE(this._b | 0, 4)
|
|
H.writeInt32BE(this._c | 0, 8)
|
|
H.writeInt32BE(this._d | 0, 12)
|
|
H.writeInt32BE(this._e | 0, 16)
|
|
|
|
return H
|
|
}
|
|
|
|
module.exports = Sha1
|
|
|
|
},{"./hash":86,"inherits":38,"safe-buffer":85}],90:[function(require,module,exports){
|
|
/**
|
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
|
|
* in FIPS 180-2
|
|
* Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
|
|
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
|
*
|
|
*/
|
|
|
|
var inherits = require('inherits')
|
|
var Sha256 = require('./sha256')
|
|
var Hash = require('./hash')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var W = new Array(64)
|
|
|
|
function Sha224 () {
|
|
this.init()
|
|
|
|
this._w = W // new Array(64)
|
|
|
|
Hash.call(this, 64, 56)
|
|
}
|
|
|
|
inherits(Sha224, Sha256)
|
|
|
|
Sha224.prototype.init = function () {
|
|
this._a = 0xc1059ed8
|
|
this._b = 0x367cd507
|
|
this._c = 0x3070dd17
|
|
this._d = 0xf70e5939
|
|
this._e = 0xffc00b31
|
|
this._f = 0x68581511
|
|
this._g = 0x64f98fa7
|
|
this._h = 0xbefa4fa4
|
|
|
|
return this
|
|
}
|
|
|
|
Sha224.prototype._hash = function () {
|
|
var H = Buffer.allocUnsafe(28)
|
|
|
|
H.writeInt32BE(this._a, 0)
|
|
H.writeInt32BE(this._b, 4)
|
|
H.writeInt32BE(this._c, 8)
|
|
H.writeInt32BE(this._d, 12)
|
|
H.writeInt32BE(this._e, 16)
|
|
H.writeInt32BE(this._f, 20)
|
|
H.writeInt32BE(this._g, 24)
|
|
|
|
return H
|
|
}
|
|
|
|
module.exports = Sha224
|
|
|
|
},{"./hash":86,"./sha256":91,"inherits":38,"safe-buffer":85}],91:[function(require,module,exports){
|
|
/**
|
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
|
|
* in FIPS 180-2
|
|
* Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
|
|
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
|
*
|
|
*/
|
|
|
|
var inherits = require('inherits')
|
|
var Hash = require('./hash')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var K = [
|
|
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
|
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
|
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
|
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
|
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
|
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
|
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
|
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
|
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
|
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
|
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
|
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
|
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
|
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
|
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
|
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
|
]
|
|
|
|
var W = new Array(64)
|
|
|
|
function Sha256 () {
|
|
this.init()
|
|
|
|
this._w = W // new Array(64)
|
|
|
|
Hash.call(this, 64, 56)
|
|
}
|
|
|
|
inherits(Sha256, Hash)
|
|
|
|
Sha256.prototype.init = function () {
|
|
this._a = 0x6a09e667
|
|
this._b = 0xbb67ae85
|
|
this._c = 0x3c6ef372
|
|
this._d = 0xa54ff53a
|
|
this._e = 0x510e527f
|
|
this._f = 0x9b05688c
|
|
this._g = 0x1f83d9ab
|
|
this._h = 0x5be0cd19
|
|
|
|
return this
|
|
}
|
|
|
|
function ch (x, y, z) {
|
|
return z ^ (x & (y ^ z))
|
|
}
|
|
|
|
function maj (x, y, z) {
|
|
return (x & y) | (z & (x | y))
|
|
}
|
|
|
|
function sigma0 (x) {
|
|
return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)
|
|
}
|
|
|
|
function sigma1 (x) {
|
|
return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)
|
|
}
|
|
|
|
function gamma0 (x) {
|
|
return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)
|
|
}
|
|
|
|
function gamma1 (x) {
|
|
return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)
|
|
}
|
|
|
|
Sha256.prototype._update = function (M) {
|
|
var W = this._w
|
|
|
|
var a = this._a | 0
|
|
var b = this._b | 0
|
|
var c = this._c | 0
|
|
var d = this._d | 0
|
|
var e = this._e | 0
|
|
var f = this._f | 0
|
|
var g = this._g | 0
|
|
var h = this._h | 0
|
|
|
|
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
|
|
for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0
|
|
|
|
for (var j = 0; j < 64; ++j) {
|
|
var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0
|
|
var T2 = (sigma0(a) + maj(a, b, c)) | 0
|
|
|
|
h = g
|
|
g = f
|
|
f = e
|
|
e = (d + T1) | 0
|
|
d = c
|
|
c = b
|
|
b = a
|
|
a = (T1 + T2) | 0
|
|
}
|
|
|
|
this._a = (a + this._a) | 0
|
|
this._b = (b + this._b) | 0
|
|
this._c = (c + this._c) | 0
|
|
this._d = (d + this._d) | 0
|
|
this._e = (e + this._e) | 0
|
|
this._f = (f + this._f) | 0
|
|
this._g = (g + this._g) | 0
|
|
this._h = (h + this._h) | 0
|
|
}
|
|
|
|
Sha256.prototype._hash = function () {
|
|
var H = Buffer.allocUnsafe(32)
|
|
|
|
H.writeInt32BE(this._a, 0)
|
|
H.writeInt32BE(this._b, 4)
|
|
H.writeInt32BE(this._c, 8)
|
|
H.writeInt32BE(this._d, 12)
|
|
H.writeInt32BE(this._e, 16)
|
|
H.writeInt32BE(this._f, 20)
|
|
H.writeInt32BE(this._g, 24)
|
|
H.writeInt32BE(this._h, 28)
|
|
|
|
return H
|
|
}
|
|
|
|
module.exports = Sha256
|
|
|
|
},{"./hash":86,"inherits":38,"safe-buffer":85}],92:[function(require,module,exports){
|
|
var inherits = require('inherits')
|
|
var SHA512 = require('./sha512')
|
|
var Hash = require('./hash')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var W = new Array(160)
|
|
|
|
function Sha384 () {
|
|
this.init()
|
|
this._w = W
|
|
|
|
Hash.call(this, 128, 112)
|
|
}
|
|
|
|
inherits(Sha384, SHA512)
|
|
|
|
Sha384.prototype.init = function () {
|
|
this._ah = 0xcbbb9d5d
|
|
this._bh = 0x629a292a
|
|
this._ch = 0x9159015a
|
|
this._dh = 0x152fecd8
|
|
this._eh = 0x67332667
|
|
this._fh = 0x8eb44a87
|
|
this._gh = 0xdb0c2e0d
|
|
this._hh = 0x47b5481d
|
|
|
|
this._al = 0xc1059ed8
|
|
this._bl = 0x367cd507
|
|
this._cl = 0x3070dd17
|
|
this._dl = 0xf70e5939
|
|
this._el = 0xffc00b31
|
|
this._fl = 0x68581511
|
|
this._gl = 0x64f98fa7
|
|
this._hl = 0xbefa4fa4
|
|
|
|
return this
|
|
}
|
|
|
|
Sha384.prototype._hash = function () {
|
|
var H = Buffer.allocUnsafe(48)
|
|
|
|
function writeInt64BE (h, l, offset) {
|
|
H.writeInt32BE(h, offset)
|
|
H.writeInt32BE(l, offset + 4)
|
|
}
|
|
|
|
writeInt64BE(this._ah, this._al, 0)
|
|
writeInt64BE(this._bh, this._bl, 8)
|
|
writeInt64BE(this._ch, this._cl, 16)
|
|
writeInt64BE(this._dh, this._dl, 24)
|
|
writeInt64BE(this._eh, this._el, 32)
|
|
writeInt64BE(this._fh, this._fl, 40)
|
|
|
|
return H
|
|
}
|
|
|
|
module.exports = Sha384
|
|
|
|
},{"./hash":86,"./sha512":93,"inherits":38,"safe-buffer":85}],93:[function(require,module,exports){
|
|
var inherits = require('inherits')
|
|
var Hash = require('./hash')
|
|
var Buffer = require('safe-buffer').Buffer
|
|
|
|
var K = [
|
|
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
|
|
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
|
|
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
|
|
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
|
|
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
|
|
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
|
|
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
|
|
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
|
|
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
|
|
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
|
|
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
|
|
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
|
|
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
|
|
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
|
|
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
|
|
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
|
|
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
|
|
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
|
|
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
|
|
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
|
|
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
|
|
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
|
|
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
|
|
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
|
|
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
|
|
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
|
|
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
|
|
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
|
|
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
|
|
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
|
|
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
|
|
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
|
|
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
|
|
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
|
|
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
|
|
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
|
|
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
|
|
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
|
|
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
|
|
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
|
|
]
|
|
|
|
var W = new Array(160)
|
|
|
|
function Sha512 () {
|
|
this.init()
|
|
this._w = W
|
|
|
|
Hash.call(this, 128, 112)
|
|
}
|
|
|
|
inherits(Sha512, Hash)
|
|
|
|
Sha512.prototype.init = function () {
|
|
this._ah = 0x6a09e667
|
|
this._bh = 0xbb67ae85
|
|
this._ch = 0x3c6ef372
|
|
this._dh = 0xa54ff53a
|
|
this._eh = 0x510e527f
|
|
this._fh = 0x9b05688c
|
|
this._gh = 0x1f83d9ab
|
|
this._hh = 0x5be0cd19
|
|
|
|
this._al = 0xf3bcc908
|
|
this._bl = 0x84caa73b
|
|
this._cl = 0xfe94f82b
|
|
this._dl = 0x5f1d36f1
|
|
this._el = 0xade682d1
|
|
this._fl = 0x2b3e6c1f
|
|
this._gl = 0xfb41bd6b
|
|
this._hl = 0x137e2179
|
|
|
|
return this
|
|
}
|
|
|
|
function Ch (x, y, z) {
|
|
return z ^ (x & (y ^ z))
|
|
}
|
|
|
|
function maj (x, y, z) {
|
|
return (x & y) | (z & (x | y))
|
|
}
|
|
|
|
function sigma0 (x, xl) {
|
|
return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)
|
|
}
|
|
|
|
function sigma1 (x, xl) {
|
|
return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)
|
|
}
|
|
|
|
function Gamma0 (x, xl) {
|
|
return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)
|
|
}
|
|
|
|
function Gamma0l (x, xl) {
|
|
return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)
|
|
}
|
|
|
|
function Gamma1 (x, xl) {
|
|
return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)
|
|
}
|
|
|
|
function Gamma1l (x, xl) {
|
|
return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)
|
|
}
|
|
|
|
function getCarry (a, b) {
|
|
return (a >>> 0) < (b >>> 0) ? 1 : 0
|
|
}
|
|
|
|
Sha512.prototype._update = function (M) {
|
|
var W = this._w
|
|
|
|
var ah = this._ah | 0
|
|
var bh = this._bh | 0
|
|
var ch = this._ch | 0
|
|
var dh = this._dh | 0
|
|
var eh = this._eh | 0
|
|
var fh = this._fh | 0
|
|
var gh = this._gh | 0
|
|
var hh = this._hh | 0
|
|
|
|
var al = this._al | 0
|
|
var bl = this._bl | 0
|
|
var cl = this._cl | 0
|
|
var dl = this._dl | 0
|
|
var el = this._el | 0
|
|
var fl = this._fl | 0
|
|
var gl = this._gl | 0
|
|
var hl = this._hl | 0
|
|
|
|
for (var i = 0; i < 32; i += 2) {
|
|
W[i] = M.readInt32BE(i * 4)
|
|
W[i + 1] = M.readInt32BE(i * 4 + 4)
|
|
}
|
|
for (; i < 160; i += 2) {
|
|
var xh = W[i - 15 * 2]
|
|
var xl = W[i - 15 * 2 + 1]
|
|
var gamma0 = Gamma0(xh, xl)
|
|
var gamma0l = Gamma0l(xl, xh)
|
|
|
|
xh = W[i - 2 * 2]
|
|
xl = W[i - 2 * 2 + 1]
|
|
var gamma1 = Gamma1(xh, xl)
|
|
var gamma1l = Gamma1l(xl, xh)
|
|
|
|
// W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
|
|
var Wi7h = W[i - 7 * 2]
|
|
var Wi7l = W[i - 7 * 2 + 1]
|
|
|
|
var Wi16h = W[i - 16 * 2]
|
|
var Wi16l = W[i - 16 * 2 + 1]
|
|
|
|
var Wil = (gamma0l + Wi7l) | 0
|
|
var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0
|
|
Wil = (Wil + gamma1l) | 0
|
|
Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0
|
|
Wil = (Wil + Wi16l) | 0
|
|
Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0
|
|
|
|
W[i] = Wih
|
|
W[i + 1] = Wil
|
|
}
|
|
|
|
for (var j = 0; j < 160; j += 2) {
|
|
Wih = W[j]
|
|
Wil = W[j + 1]
|
|
|
|
var majh = maj(ah, bh, ch)
|
|
var majl = maj(al, bl, cl)
|
|
|
|
var sigma0h = sigma0(ah, al)
|
|
var sigma0l = sigma0(al, ah)
|
|
var sigma1h = sigma1(eh, el)
|
|
var sigma1l = sigma1(el, eh)
|
|
|
|
// t1 = h + sigma1 + ch + K[j] + W[j]
|
|
var Kih = K[j]
|
|
var Kil = K[j + 1]
|
|
|
|
var chh = Ch(eh, fh, gh)
|
|
var chl = Ch(el, fl, gl)
|
|
|
|
var t1l = (hl + sigma1l) | 0
|
|
var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0
|
|
t1l = (t1l + chl) | 0
|
|
t1h = (t1h + chh + getCarry(t1l, chl)) | 0
|
|
t1l = (t1l + Kil) | 0
|
|
t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0
|
|
t1l = (t1l + Wil) | 0
|
|
t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0
|
|
|
|
// t2 = sigma0 + maj
|
|
var t2l = (sigma0l + majl) | 0
|
|
var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0
|
|
|
|
hh = gh
|
|
hl = gl
|
|
gh = fh
|
|
gl = fl
|
|
fh = eh
|
|
fl = el
|
|
el = (dl + t1l) | 0
|
|
eh = (dh + t1h + getCarry(el, dl)) | 0
|
|
dh = ch
|
|
dl = cl
|
|
ch = bh
|
|
cl = bl
|
|
bh = ah
|
|
bl = al
|
|
al = (t1l + t2l) | 0
|
|
ah = (t1h + t2h + getCarry(al, t1l)) | 0
|
|
}
|
|
|
|
this._al = (this._al + al) | 0
|
|
this._bl = (this._bl + bl) | 0
|
|
this._cl = (this._cl + cl) | 0
|
|
this._dl = (this._dl + dl) | 0
|
|
this._el = (this._el + el) | 0
|
|
this._fl = (this._fl + fl) | 0
|
|
this._gl = (this._gl + gl) | 0
|
|
this._hl = (this._hl + hl) | 0
|
|
|
|
this._ah = (this._ah + ah + getCarry(this._al, al)) | 0
|
|
this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0
|
|
this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0
|
|
this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0
|
|
this._eh = (this._eh + eh + getCarry(this._el, el)) | 0
|
|
this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0
|
|
this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0
|
|
this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0
|
|
}
|
|
|
|
Sha512.prototype._hash = function () {
|
|
var H = Buffer.allocUnsafe(64)
|
|
|
|
function writeInt64BE (h, l, offset) {
|
|
H.writeInt32BE(h, offset)
|
|
H.writeInt32BE(l, offset + 4)
|
|
}
|
|
|
|
writeInt64BE(this._ah, this._al, 0)
|
|
writeInt64BE(this._bh, this._bl, 8)
|
|
writeInt64BE(this._ch, this._cl, 16)
|
|
writeInt64BE(this._dh, this._dl, 24)
|
|
writeInt64BE(this._eh, this._el, 32)
|
|
writeInt64BE(this._fh, this._fl, 40)
|
|
writeInt64BE(this._gh, this._gl, 48)
|
|
writeInt64BE(this._hh, this._hl, 56)
|
|
|
|
return H
|
|
}
|
|
|
|
module.exports = Sha512
|
|
|
|
},{"./hash":86,"inherits":38,"safe-buffer":85}],94:[function(require,module,exports){
|
|
(function (global){
|
|
'use strict';
|
|
|
|
var objectAssign = require('object-assign');
|
|
|
|
// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
|
|
// original notice:
|
|
|
|
/*!
|
|
* The buffer module from node.js, for the browser.
|
|
*
|
|
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
|
* @license MIT
|
|
*/
|
|
function compare(a, b) {
|
|
if (a === b) {
|
|
return 0;
|
|
}
|
|
|
|
var x = a.length;
|
|
var y = b.length;
|
|
|
|
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
|
|
if (a[i] !== b[i]) {
|
|
x = a[i];
|
|
y = b[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (x < y) {
|
|
return -1;
|
|
}
|
|
if (y < x) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
function isBuffer(b) {
|
|
if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
|
|
return global.Buffer.isBuffer(b);
|
|
}
|
|
return !!(b != null && b._isBuffer);
|
|
}
|
|
|
|
// based on node assert, original notice:
|
|
// NB: The URL to the CommonJS spec is kept just for tradition.
|
|
// node-assert has evolved a lot since then, both in API and behavior.
|
|
|
|
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
|
//
|
|
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
|
//
|
|
// Originally from narwhal.js (http://narwhaljs.org)
|
|
// Copyright (c) 2009 Thomas Robinson <280north.com>
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the 'Software'), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
var util = require('util/');
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
var pSlice = Array.prototype.slice;
|
|
var functionsHaveNames = (function () {
|
|
return function foo() {}.name === 'foo';
|
|
}());
|
|
function pToString (obj) {
|
|
return Object.prototype.toString.call(obj);
|
|
}
|
|
function isView(arrbuf) {
|
|
if (isBuffer(arrbuf)) {
|
|
return false;
|
|
}
|
|
if (typeof global.ArrayBuffer !== 'function') {
|
|
return false;
|
|
}
|
|
if (typeof ArrayBuffer.isView === 'function') {
|
|
return ArrayBuffer.isView(arrbuf);
|
|
}
|
|
if (!arrbuf) {
|
|
return false;
|
|
}
|
|
if (arrbuf instanceof DataView) {
|
|
return true;
|
|
}
|
|
if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
// 1. The assert module provides functions that throw
|
|
// AssertionError's when particular conditions are not met. The
|
|
// assert module must conform to the following interface.
|
|
|
|
var assert = module.exports = ok;
|
|
|
|
// 2. The AssertionError is defined in assert.
|
|
// new assert.AssertionError({ message: message,
|
|
// actual: actual,
|
|
// expected: expected })
|
|
|
|
var regex = /\s*function\s+([^\(\s]*)\s*/;
|
|
// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
|
|
function getName(func) {
|
|
if (!util.isFunction(func)) {
|
|
return;
|
|
}
|
|
if (functionsHaveNames) {
|
|
return func.name;
|
|
}
|
|
var str = func.toString();
|
|
var match = str.match(regex);
|
|
return match && match[1];
|
|
}
|
|
assert.AssertionError = function AssertionError(options) {
|
|
this.name = 'AssertionError';
|
|
this.actual = options.actual;
|
|
this.expected = options.expected;
|
|
this.operator = options.operator;
|
|
if (options.message) {
|
|
this.message = options.message;
|
|
this.generatedMessage = false;
|
|
} else {
|
|
this.message = getMessage(this);
|
|
this.generatedMessage = true;
|
|
}
|
|
var stackStartFunction = options.stackStartFunction || fail;
|
|
if (Error.captureStackTrace) {
|
|
Error.captureStackTrace(this, stackStartFunction);
|
|
} else {
|
|
// non v8 browsers so we can have a stacktrace
|
|
var err = new Error();
|
|
if (err.stack) {
|
|
var out = err.stack;
|
|
|
|
// try to strip useless frames
|
|
var fn_name = getName(stackStartFunction);
|
|
var idx = out.indexOf('\n' + fn_name);
|
|
if (idx >= 0) {
|
|
// once we have located the function frame
|
|
// we need to strip out everything before it (and its line)
|
|
var next_line = out.indexOf('\n', idx + 1);
|
|
out = out.substring(next_line + 1);
|
|
}
|
|
|
|
this.stack = out;
|
|
}
|
|
}
|
|
};
|
|
|
|
// assert.AssertionError instanceof Error
|
|
util.inherits(assert.AssertionError, Error);
|
|
|
|
function truncate(s, n) {
|
|
if (typeof s === 'string') {
|
|
return s.length < n ? s : s.slice(0, n);
|
|
} else {
|
|
return s;
|
|
}
|
|
}
|
|
function inspect(something) {
|
|
if (functionsHaveNames || !util.isFunction(something)) {
|
|
return util.inspect(something);
|
|
}
|
|
var rawname = getName(something);
|
|
var name = rawname ? ': ' + rawname : '';
|
|
return '[Function' + name + ']';
|
|
}
|
|
function getMessage(self) {
|
|
return truncate(inspect(self.actual), 128) + ' ' +
|
|
self.operator + ' ' +
|
|
truncate(inspect(self.expected), 128);
|
|
}
|
|
|
|
// At present only the three keys mentioned above are used and
|
|
// understood by the spec. Implementations or sub modules can pass
|
|
// other keys to the AssertionError's constructor - they will be
|
|
// ignored.
|
|
|
|
// 3. All of the following functions must throw an AssertionError
|
|
// when a corresponding condition is not met, with a message that
|
|
// may be undefined if not provided. All assertion methods provide
|
|
// both the actual and expected values to the assertion error for
|
|
// display purposes.
|
|
|
|
function fail(actual, expected, message, operator, stackStartFunction) {
|
|
throw new assert.AssertionError({
|
|
message: message,
|
|
actual: actual,
|
|
expected: expected,
|
|
operator: operator,
|
|
stackStartFunction: stackStartFunction
|
|
});
|
|
}
|
|
|
|
// EXTENSION! allows for well behaved errors defined elsewhere.
|
|
assert.fail = fail;
|
|
|
|
// 4. Pure assertion tests whether a value is truthy, as determined
|
|
// by !!guard.
|
|
// assert.ok(guard, message_opt);
|
|
// This statement is equivalent to assert.equal(true, !!guard,
|
|
// message_opt);. To test strictly for the value true, use
|
|
// assert.strictEqual(true, guard, message_opt);.
|
|
|
|
function ok(value, message) {
|
|
if (!value) fail(value, true, message, '==', assert.ok);
|
|
}
|
|
assert.ok = ok;
|
|
|
|
// 5. The equality assertion tests shallow, coercive equality with
|
|
// ==.
|
|
// assert.equal(actual, expected, message_opt);
|
|
|
|
assert.equal = function equal(actual, expected, message) {
|
|
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
|
|
};
|
|
|
|
// 6. The non-equality assertion tests for whether two objects are not equal
|
|
// with != assert.notEqual(actual, expected, message_opt);
|
|
|
|
assert.notEqual = function notEqual(actual, expected, message) {
|
|
if (actual == expected) {
|
|
fail(actual, expected, message, '!=', assert.notEqual);
|
|
}
|
|
};
|
|
|
|
// 7. The equivalence assertion tests a deep equality relation.
|
|
// assert.deepEqual(actual, expected, message_opt);
|
|
|
|
assert.deepEqual = function deepEqual(actual, expected, message) {
|
|
if (!_deepEqual(actual, expected, false)) {
|
|
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
|
|
}
|
|
};
|
|
|
|
assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
|
|
if (!_deepEqual(actual, expected, true)) {
|
|
fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
|
|
}
|
|
};
|
|
|
|
function _deepEqual(actual, expected, strict, memos) {
|
|
// 7.1. All identical values are equivalent, as determined by ===.
|
|
if (actual === expected) {
|
|
return true;
|
|
} else if (isBuffer(actual) && isBuffer(expected)) {
|
|
return compare(actual, expected) === 0;
|
|
|
|
// 7.2. If the expected value is a Date object, the actual value is
|
|
// equivalent if it is also a Date object that refers to the same time.
|
|
} else if (util.isDate(actual) && util.isDate(expected)) {
|
|
return actual.getTime() === expected.getTime();
|
|
|
|
// 7.3 If the expected value is a RegExp object, the actual value is
|
|
// equivalent if it is also a RegExp object with the same source and
|
|
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
|
|
} else if (util.isRegExp(actual) && util.isRegExp(expected)) {
|
|
return actual.source === expected.source &&
|
|
actual.global === expected.global &&
|
|
actual.multiline === expected.multiline &&
|
|
actual.lastIndex === expected.lastIndex &&
|
|
actual.ignoreCase === expected.ignoreCase;
|
|
|
|
// 7.4. Other pairs that do not both pass typeof value == 'object',
|
|
// equivalence is determined by ==.
|
|
} else if ((actual === null || typeof actual !== 'object') &&
|
|
(expected === null || typeof expected !== 'object')) {
|
|
return strict ? actual === expected : actual == expected;
|
|
|
|
// If both values are instances of typed arrays, wrap their underlying
|
|
// ArrayBuffers in a Buffer each to increase performance
|
|
// This optimization requires the arrays to have the same type as checked by
|
|
// Object.prototype.toString (aka pToString). Never perform binary
|
|
// comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
|
|
// bit patterns are not identical.
|
|
} else if (isView(actual) && isView(expected) &&
|
|
pToString(actual) === pToString(expected) &&
|
|
!(actual instanceof Float32Array ||
|
|
actual instanceof Float64Array)) {
|
|
return compare(new Uint8Array(actual.buffer),
|
|
new Uint8Array(expected.buffer)) === 0;
|
|
|
|
// 7.5 For all other Object pairs, including Array objects, equivalence is
|
|
// determined by having the same number of owned properties (as verified
|
|
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
|
// (although not necessarily the same order), equivalent values for every
|
|
// corresponding key, and an identical 'prototype' property. Note: this
|
|
// accounts for both named and indexed properties on Arrays.
|
|
} else if (isBuffer(actual) !== isBuffer(expected)) {
|
|
return false;
|
|
} else {
|
|
memos = memos || {actual: [], expected: []};
|
|
|
|
var actualIndex = memos.actual.indexOf(actual);
|
|
if (actualIndex !== -1) {
|
|
if (actualIndex === memos.expected.indexOf(expected)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
memos.actual.push(actual);
|
|
memos.expected.push(expected);
|
|
|
|
return objEquiv(actual, expected, strict, memos);
|
|
}
|
|
}
|
|
|
|
function isArguments(object) {
|
|
return Object.prototype.toString.call(object) == '[object Arguments]';
|
|
}
|
|
|
|
function objEquiv(a, b, strict, actualVisitedObjects) {
|
|
if (a === null || a === undefined || b === null || b === undefined)
|
|
return false;
|
|
// if one is a primitive, the other must be same
|
|
if (util.isPrimitive(a) || util.isPrimitive(b))
|
|
return a === b;
|
|
if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
|
|
return false;
|
|
var aIsArgs = isArguments(a);
|
|
var bIsArgs = isArguments(b);
|
|
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
|
|
return false;
|
|
if (aIsArgs) {
|
|
a = pSlice.call(a);
|
|
b = pSlice.call(b);
|
|
return _deepEqual(a, b, strict);
|
|
}
|
|
var ka = objectKeys(a);
|
|
var kb = objectKeys(b);
|
|
var key, i;
|
|
// having the same number of owned properties (keys incorporates
|
|
// hasOwnProperty)
|
|
if (ka.length !== kb.length)
|
|
return false;
|
|
//the same set of keys (although not necessarily the same order),
|
|
ka.sort();
|
|
kb.sort();
|
|
//~~~cheap key test
|
|
for (i = ka.length - 1; i >= 0; i--) {
|
|
if (ka[i] !== kb[i])
|
|
return false;
|
|
}
|
|
//equivalent values for every corresponding key, and
|
|
//~~~possibly expensive deep test
|
|
for (i = ka.length - 1; i >= 0; i--) {
|
|
key = ka[i];
|
|
if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// 8. The non-equivalence assertion tests for any deep inequality.
|
|
// assert.notDeepEqual(actual, expected, message_opt);
|
|
|
|
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
|
|
if (_deepEqual(actual, expected, false)) {
|
|
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
|
|
}
|
|
};
|
|
|
|
assert.notDeepStrictEqual = notDeepStrictEqual;
|
|
function notDeepStrictEqual(actual, expected, message) {
|
|
if (_deepEqual(actual, expected, true)) {
|
|
fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
|
|
}
|
|
}
|
|
|
|
|
|
// 9. The strict equality assertion tests strict equality, as determined by ===.
|
|
// assert.strictEqual(actual, expected, message_opt);
|
|
|
|
assert.strictEqual = function strictEqual(actual, expected, message) {
|
|
if (actual !== expected) {
|
|
fail(actual, expected, message, '===', assert.strictEqual);
|
|
}
|
|
};
|
|
|
|
// 10. The strict non-equality assertion tests for strict inequality, as
|
|
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
|
|
|
|
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
|
if (actual === expected) {
|
|
fail(actual, expected, message, '!==', assert.notStrictEqual);
|
|
}
|
|
};
|
|
|
|
function expectedException(actual, expected) {
|
|
if (!actual || !expected) {
|
|
return false;
|
|
}
|
|
|
|
if (Object.prototype.toString.call(expected) == '[object RegExp]') {
|
|
return expected.test(actual);
|
|
}
|
|
|
|
try {
|
|
if (actual instanceof expected) {
|
|
return true;
|
|
}
|
|
} catch (e) {
|
|
// Ignore. The instanceof check doesn't work for arrow functions.
|
|
}
|
|
|
|
if (Error.isPrototypeOf(expected)) {
|
|
return false;
|
|
}
|
|
|
|
return expected.call({}, actual) === true;
|
|
}
|
|
|
|
function _tryBlock(block) {
|
|
var error;
|
|
try {
|
|
block();
|
|
} catch (e) {
|
|
error = e;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
function _throws(shouldThrow, block, expected, message) {
|
|
var actual;
|
|
|
|
if (typeof block !== 'function') {
|
|
throw new TypeError('"block" argument must be a function');
|
|
}
|
|
|
|
if (typeof expected === 'string') {
|
|
message = expected;
|
|
expected = null;
|
|
}
|
|
|
|
actual = _tryBlock(block);
|
|
|
|
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
|
|
(message ? ' ' + message : '.');
|
|
|
|
if (shouldThrow && !actual) {
|
|
fail(actual, expected, 'Missing expected exception' + message);
|
|
}
|
|
|
|
var userProvidedMessage = typeof message === 'string';
|
|
var isUnwantedException = !shouldThrow && util.isError(actual);
|
|
var isUnexpectedException = !shouldThrow && actual && !expected;
|
|
|
|
if ((isUnwantedException &&
|
|
userProvidedMessage &&
|
|
expectedException(actual, expected)) ||
|
|
isUnexpectedException) {
|
|
fail(actual, expected, 'Got unwanted exception' + message);
|
|
}
|
|
|
|
if ((shouldThrow && actual && expected &&
|
|
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
|
|
throw actual;
|
|
}
|
|
}
|
|
|
|
// 11. Expected to throw an error:
|
|
// assert.throws(block, Error_opt, message_opt);
|
|
|
|
assert.throws = function(block, /*optional*/error, /*optional*/message) {
|
|
_throws(true, block, error, message);
|
|
};
|
|
|
|
// EXTENSION! This is annoying to write outside this module.
|
|
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
|
|
_throws(false, block, error, message);
|
|
};
|
|
|
|
assert.ifError = function(err) { if (err) throw err; };
|
|
|
|
// Expose a strict only variant of assert
|
|
function strict(value, message) {
|
|
if (!value) fail(value, true, message, '==', strict);
|
|
}
|
|
assert.strict = objectAssign(strict, assert, {
|
|
equal: assert.strictEqual,
|
|
deepEqual: assert.deepStrictEqual,
|
|
notEqual: assert.notStrictEqual,
|
|
notDeepEqual: assert.notDeepStrictEqual
|
|
});
|
|
assert.strict.strict = assert.strict;
|
|
|
|
var objectKeys = Object.keys || function (obj) {
|
|
var keys = [];
|
|
for (var key in obj) {
|
|
if (hasOwn.call(obj, key)) keys.push(key);
|
|
}
|
|
return keys;
|
|
};
|
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{"object-assign":107,"util/":97}],95:[function(require,module,exports){
|
|
if (typeof Object.create === 'function') {
|
|
// implementation from standard node.js 'util' module
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
ctor.super_ = superCtor
|
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|
constructor: {
|
|
value: ctor,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
});
|
|
};
|
|
} else {
|
|
// old school shim for old browsers
|
|
module.exports = function inherits(ctor, superCtor) {
|
|
ctor.super_ = superCtor
|
|
var TempCtor = function () {}
|
|
TempCtor.prototype = superCtor.prototype
|
|
ctor.prototype = new TempCtor()
|
|
ctor.prototype.constructor = ctor
|
|
}
|
|
}
|
|
|
|
},{}],96:[function(require,module,exports){
|
|
module.exports = function isBuffer(arg) {
|
|
return arg && typeof arg === 'object'
|
|
&& typeof arg.copy === 'function'
|
|
&& typeof arg.fill === 'function'
|
|
&& typeof arg.readUInt8 === 'function';
|
|
}
|
|
},{}],97:[function(require,module,exports){
|
|
(function (process,global){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
var formatRegExp = /%[sdj%]/g;
|
|
exports.format = function(f) {
|
|
if (!isString(f)) {
|
|
var objects = [];
|
|
for (var i = 0; i < arguments.length; i++) {
|
|
objects.push(inspect(arguments[i]));
|
|
}
|
|
return objects.join(' ');
|
|
}
|
|
|
|
var i = 1;
|
|
var args = arguments;
|
|
var len = args.length;
|
|
var str = String(f).replace(formatRegExp, function(x) {
|
|
if (x === '%%') return '%';
|
|
if (i >= len) return x;
|
|
switch (x) {
|
|
case '%s': return String(args[i++]);
|
|
case '%d': return Number(args[i++]);
|
|
case '%j':
|
|
try {
|
|
return JSON.stringify(args[i++]);
|
|
} catch (_) {
|
|
return '[Circular]';
|
|
}
|
|
default:
|
|
return x;
|
|
}
|
|
});
|
|
for (var x = args[i]; i < len; x = args[++i]) {
|
|
if (isNull(x) || !isObject(x)) {
|
|
str += ' ' + x;
|
|
} else {
|
|
str += ' ' + inspect(x);
|
|
}
|
|
}
|
|
return str;
|
|
};
|
|
|
|
|
|
// Mark that a method should not be used.
|
|
// Returns a modified function which warns once by default.
|
|
// If --no-deprecation is set, then it is a no-op.
|
|
exports.deprecate = function(fn, msg) {
|
|
// Allow for deprecating things in the process of starting up.
|
|
if (isUndefined(global.process)) {
|
|
return function() {
|
|
return exports.deprecate(fn, msg).apply(this, arguments);
|
|
};
|
|
}
|
|
|
|
if (process.noDeprecation === true) {
|
|
return fn;
|
|
}
|
|
|
|
var warned = false;
|
|
function deprecated() {
|
|
if (!warned) {
|
|
if (process.throwDeprecation) {
|
|
throw new Error(msg);
|
|
} else if (process.traceDeprecation) {
|
|
console.trace(msg);
|
|
} else {
|
|
console.error(msg);
|
|
}
|
|
warned = true;
|
|
}
|
|
return fn.apply(this, arguments);
|
|
}
|
|
|
|
return deprecated;
|
|
};
|
|
|
|
|
|
var debugs = {};
|
|
var debugEnviron;
|
|
exports.debuglog = function(set) {
|
|
if (isUndefined(debugEnviron))
|
|
debugEnviron = process.env.NODE_DEBUG || '';
|
|
set = set.toUpperCase();
|
|
if (!debugs[set]) {
|
|
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
|
|
var pid = process.pid;
|
|
debugs[set] = function() {
|
|
var msg = exports.format.apply(exports, arguments);
|
|
console.error('%s %d: %s', set, pid, msg);
|
|
};
|
|
} else {
|
|
debugs[set] = function() {};
|
|
}
|
|
}
|
|
return debugs[set];
|
|
};
|
|
|
|
|
|
/**
|
|
* Echos the value of a value. Trys to print the value out
|
|
* in the best way possible given the different types.
|
|
*
|
|
* @param {Object} obj The object to print out.
|
|
* @param {Object} opts Optional options object that alters the output.
|
|
*/
|
|
/* legacy: obj, showHidden, depth, colors*/
|
|
function inspect(obj, opts) {
|
|
// default options
|
|
var ctx = {
|
|
seen: [],
|
|
stylize: stylizeNoColor
|
|
};
|
|
// legacy...
|
|
if (arguments.length >= 3) ctx.depth = arguments[2];
|
|
if (arguments.length >= 4) ctx.colors = arguments[3];
|
|
if (isBoolean(opts)) {
|
|
// legacy...
|
|
ctx.showHidden = opts;
|
|
} else if (opts) {
|
|
// got an "options" object
|
|
exports._extend(ctx, opts);
|
|
}
|
|
// set default options
|
|
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
|
if (isUndefined(ctx.depth)) ctx.depth = 2;
|
|
if (isUndefined(ctx.colors)) ctx.colors = false;
|
|
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
|
if (ctx.colors) ctx.stylize = stylizeWithColor;
|
|
return formatValue(ctx, obj, ctx.depth);
|
|
}
|
|
exports.inspect = inspect;
|
|
|
|
|
|
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
|
inspect.colors = {
|
|
'bold' : [1, 22],
|
|
'italic' : [3, 23],
|
|
'underline' : [4, 24],
|
|
'inverse' : [7, 27],
|
|
'white' : [37, 39],
|
|
'grey' : [90, 39],
|
|
'black' : [30, 39],
|
|
'blue' : [34, 39],
|
|
'cyan' : [36, 39],
|
|
'green' : [32, 39],
|
|
'magenta' : [35, 39],
|
|
'red' : [31, 39],
|
|
'yellow' : [33, 39]
|
|
};
|
|
|
|
// Don't use 'blue' not visible on cmd.exe
|
|
inspect.styles = {
|
|
'special': 'cyan',
|
|
'number': 'yellow',
|
|
'boolean': 'yellow',
|
|
'undefined': 'grey',
|
|
'null': 'bold',
|
|
'string': 'green',
|
|
'date': 'magenta',
|
|
// "name": intentionally not styling
|
|
'regexp': 'red'
|
|
};
|
|
|
|
|
|
function stylizeWithColor(str, styleType) {
|
|
var style = inspect.styles[styleType];
|
|
|
|
if (style) {
|
|
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
|
|
'\u001b[' + inspect.colors[style][1] + 'm';
|
|
} else {
|
|
return str;
|
|
}
|
|
}
|
|
|
|
|
|
function stylizeNoColor(str, styleType) {
|
|
return str;
|
|
}
|
|
|
|
|
|
function arrayToHash(array) {
|
|
var hash = {};
|
|
|
|
array.forEach(function(val, idx) {
|
|
hash[val] = true;
|
|
});
|
|
|
|
return hash;
|
|
}
|
|
|
|
|
|
function formatValue(ctx, value, recurseTimes) {
|
|
// Provide a hook for user-specified inspect functions.
|
|
// Check that value is an object with an inspect function on it
|
|
if (ctx.customInspect &&
|
|
value &&
|
|
isFunction(value.inspect) &&
|
|
// Filter out the util module, it's inspect function is special
|
|
value.inspect !== exports.inspect &&
|
|
// Also filter out any prototype objects using the circular check.
|
|
!(value.constructor && value.constructor.prototype === value)) {
|
|
var ret = value.inspect(recurseTimes, ctx);
|
|
if (!isString(ret)) {
|
|
ret = formatValue(ctx, ret, recurseTimes);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Primitive types cannot have properties
|
|
var primitive = formatPrimitive(ctx, value);
|
|
if (primitive) {
|
|
return primitive;
|
|
}
|
|
|
|
// Look up the keys of the object.
|
|
var keys = Object.keys(value);
|
|
var visibleKeys = arrayToHash(keys);
|
|
|
|
if (ctx.showHidden) {
|
|
keys = Object.getOwnPropertyNames(value);
|
|
}
|
|
|
|
// IE doesn't make error fields non-enumerable
|
|
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
|
if (isError(value)
|
|
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
|
|
return formatError(value);
|
|
}
|
|
|
|
// Some type of object without properties can be shortcutted.
|
|
if (keys.length === 0) {
|
|
if (isFunction(value)) {
|
|
var name = value.name ? ': ' + value.name : '';
|
|
return ctx.stylize('[Function' + name + ']', 'special');
|
|
}
|
|
if (isRegExp(value)) {
|
|
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
|
}
|
|
if (isDate(value)) {
|
|
return ctx.stylize(Date.prototype.toString.call(value), 'date');
|
|
}
|
|
if (isError(value)) {
|
|
return formatError(value);
|
|
}
|
|
}
|
|
|
|
var base = '', array = false, braces = ['{', '}'];
|
|
|
|
// Make Array say that they are Array
|
|
if (isArray(value)) {
|
|
array = true;
|
|
braces = ['[', ']'];
|
|
}
|
|
|
|
// Make functions say that they are functions
|
|
if (isFunction(value)) {
|
|
var n = value.name ? ': ' + value.name : '';
|
|
base = ' [Function' + n + ']';
|
|
}
|
|
|
|
// Make RegExps say that they are RegExps
|
|
if (isRegExp(value)) {
|
|
base = ' ' + RegExp.prototype.toString.call(value);
|
|
}
|
|
|
|
// Make dates with properties first say the date
|
|
if (isDate(value)) {
|
|
base = ' ' + Date.prototype.toUTCString.call(value);
|
|
}
|
|
|
|
// Make error with message first say the error
|
|
if (isError(value)) {
|
|
base = ' ' + formatError(value);
|
|
}
|
|
|
|
if (keys.length === 0 && (!array || value.length == 0)) {
|
|
return braces[0] + base + braces[1];
|
|
}
|
|
|
|
if (recurseTimes < 0) {
|
|
if (isRegExp(value)) {
|
|
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
|
} else {
|
|
return ctx.stylize('[Object]', 'special');
|
|
}
|
|
}
|
|
|
|
ctx.seen.push(value);
|
|
|
|
var output;
|
|
if (array) {
|
|
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
|
} else {
|
|
output = keys.map(function(key) {
|
|
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
|
});
|
|
}
|
|
|
|
ctx.seen.pop();
|
|
|
|
return reduceToSingleString(output, base, braces);
|
|
}
|
|
|
|
|
|
function formatPrimitive(ctx, value) {
|
|
if (isUndefined(value))
|
|
return ctx.stylize('undefined', 'undefined');
|
|
if (isString(value)) {
|
|
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
|
.replace(/'/g, "\\'")
|
|
.replace(/\\"/g, '"') + '\'';
|
|
return ctx.stylize(simple, 'string');
|
|
}
|
|
if (isNumber(value))
|
|
return ctx.stylize('' + value, 'number');
|
|
if (isBoolean(value))
|
|
return ctx.stylize('' + value, 'boolean');
|
|
// For some reason typeof null is "object", so special case here.
|
|
if (isNull(value))
|
|
return ctx.stylize('null', 'null');
|
|
}
|
|
|
|
|
|
function formatError(value) {
|
|
return '[' + Error.prototype.toString.call(value) + ']';
|
|
}
|
|
|
|
|
|
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
|
var output = [];
|
|
for (var i = 0, l = value.length; i < l; ++i) {
|
|
if (hasOwnProperty(value, String(i))) {
|
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
|
String(i), true));
|
|
} else {
|
|
output.push('');
|
|
}
|
|
}
|
|
keys.forEach(function(key) {
|
|
if (!key.match(/^\d+$/)) {
|
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
|
key, true));
|
|
}
|
|
});
|
|
return output;
|
|
}
|
|
|
|
|
|
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
|
var name, str, desc;
|
|
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
|
|
if (desc.get) {
|
|
if (desc.set) {
|
|
str = ctx.stylize('[Getter/Setter]', 'special');
|
|
} else {
|
|
str = ctx.stylize('[Getter]', 'special');
|
|
}
|
|
} else {
|
|
if (desc.set) {
|
|
str = ctx.stylize('[Setter]', 'special');
|
|
}
|
|
}
|
|
if (!hasOwnProperty(visibleKeys, key)) {
|
|
name = '[' + key + ']';
|
|
}
|
|
if (!str) {
|
|
if (ctx.seen.indexOf(desc.value) < 0) {
|
|
if (isNull(recurseTimes)) {
|
|
str = formatValue(ctx, desc.value, null);
|
|
} else {
|
|
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
|
}
|
|
if (str.indexOf('\n') > -1) {
|
|
if (array) {
|
|
str = str.split('\n').map(function(line) {
|
|
return ' ' + line;
|
|
}).join('\n').substr(2);
|
|
} else {
|
|
str = '\n' + str.split('\n').map(function(line) {
|
|
return ' ' + line;
|
|
}).join('\n');
|
|
}
|
|
}
|
|
} else {
|
|
str = ctx.stylize('[Circular]', 'special');
|
|
}
|
|
}
|
|
if (isUndefined(name)) {
|
|
if (array && key.match(/^\d+$/)) {
|
|
return str;
|
|
}
|
|
name = JSON.stringify('' + key);
|
|
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
|
name = name.substr(1, name.length - 2);
|
|
name = ctx.stylize(name, 'name');
|
|
} else {
|
|
name = name.replace(/'/g, "\\'")
|
|
.replace(/\\"/g, '"')
|
|
.replace(/(^"|"$)/g, "'");
|
|
name = ctx.stylize(name, 'string');
|
|
}
|
|
}
|
|
|
|
return name + ': ' + str;
|
|
}
|
|
|
|
|
|
function reduceToSingleString(output, base, braces) {
|
|
var numLinesEst = 0;
|
|
var length = output.reduce(function(prev, cur) {
|
|
numLinesEst++;
|
|
if (cur.indexOf('\n') >= 0) numLinesEst++;
|
|
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
|
|
}, 0);
|
|
|
|
if (length > 60) {
|
|
return braces[0] +
|
|
(base === '' ? '' : base + '\n ') +
|
|
' ' +
|
|
output.join(',\n ') +
|
|
' ' +
|
|
braces[1];
|
|
}
|
|
|
|
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
|
}
|
|
|
|
|
|
// NOTE: These type checking functions intentionally don't use `instanceof`
|
|
// because it is fragile and can be easily faked with `Object.create()`.
|
|
function isArray(ar) {
|
|
return Array.isArray(ar);
|
|
}
|
|
exports.isArray = isArray;
|
|
|
|
function isBoolean(arg) {
|
|
return typeof arg === 'boolean';
|
|
}
|
|
exports.isBoolean = isBoolean;
|
|
|
|
function isNull(arg) {
|
|
return arg === null;
|
|
}
|
|
exports.isNull = isNull;
|
|
|
|
function isNullOrUndefined(arg) {
|
|
return arg == null;
|
|
}
|
|
exports.isNullOrUndefined = isNullOrUndefined;
|
|
|
|
function isNumber(arg) {
|
|
return typeof arg === 'number';
|
|
}
|
|
exports.isNumber = isNumber;
|
|
|
|
function isString(arg) {
|
|
return typeof arg === 'string';
|
|
}
|
|
exports.isString = isString;
|
|
|
|
function isSymbol(arg) {
|
|
return typeof arg === 'symbol';
|
|
}
|
|
exports.isSymbol = isSymbol;
|
|
|
|
function isUndefined(arg) {
|
|
return arg === void 0;
|
|
}
|
|
exports.isUndefined = isUndefined;
|
|
|
|
function isRegExp(re) {
|
|
return isObject(re) && objectToString(re) === '[object RegExp]';
|
|
}
|
|
exports.isRegExp = isRegExp;
|
|
|
|
function isObject(arg) {
|
|
return typeof arg === 'object' && arg !== null;
|
|
}
|
|
exports.isObject = isObject;
|
|
|
|
function isDate(d) {
|
|
return isObject(d) && objectToString(d) === '[object Date]';
|
|
}
|
|
exports.isDate = isDate;
|
|
|
|
function isError(e) {
|
|
return isObject(e) &&
|
|
(objectToString(e) === '[object Error]' || e instanceof Error);
|
|
}
|
|
exports.isError = isError;
|
|
|
|
function isFunction(arg) {
|
|
return typeof arg === 'function';
|
|
}
|
|
exports.isFunction = isFunction;
|
|
|
|
function isPrimitive(arg) {
|
|
return arg === null ||
|
|
typeof arg === 'boolean' ||
|
|
typeof arg === 'number' ||
|
|
typeof arg === 'string' ||
|
|
typeof arg === 'symbol' || // ES6 symbol
|
|
typeof arg === 'undefined';
|
|
}
|
|
exports.isPrimitive = isPrimitive;
|
|
|
|
exports.isBuffer = require('./support/isBuffer');
|
|
|
|
function objectToString(o) {
|
|
return Object.prototype.toString.call(o);
|
|
}
|
|
|
|
|
|
function pad(n) {
|
|
return n < 10 ? '0' + n.toString(10) : n.toString(10);
|
|
}
|
|
|
|
|
|
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
|
|
'Oct', 'Nov', 'Dec'];
|
|
|
|
// 26 Feb 16:19:34
|
|
function timestamp() {
|
|
var d = new Date();
|
|
var time = [pad(d.getHours()),
|
|
pad(d.getMinutes()),
|
|
pad(d.getSeconds())].join(':');
|
|
return [d.getDate(), months[d.getMonth()], time].join(' ');
|
|
}
|
|
|
|
|
|
// log is just a thin wrapper to console.log that prepends a timestamp
|
|
exports.log = function() {
|
|
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
|
|
};
|
|
|
|
|
|
/**
|
|
* Inherit the prototype methods from one constructor into another.
|
|
*
|
|
* The Function.prototype.inherits from lang.js rewritten as a standalone
|
|
* function (not on Function.prototype). NOTE: If this file is to be loaded
|
|
* during bootstrapping this function needs to be rewritten using some native
|
|
* functions as prototype setup using normal JavaScript does not work as
|
|
* expected during bootstrapping (see mirror.js in r114903).
|
|
*
|
|
* @param {function} ctor Constructor function which needs to inherit the
|
|
* prototype.
|
|
* @param {function} superCtor Constructor function to inherit prototype from.
|
|
*/
|
|
exports.inherits = require('inherits');
|
|
|
|
exports._extend = function(origin, add) {
|
|
// Don't do anything if add isn't an object
|
|
if (!add || !isObject(add)) return origin;
|
|
|
|
var keys = Object.keys(add);
|
|
var i = keys.length;
|
|
while (i--) {
|
|
origin[keys[i]] = add[keys[i]];
|
|
}
|
|
return origin;
|
|
};
|
|
|
|
function hasOwnProperty(obj, prop) {
|
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
}
|
|
|
|
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{"./support/isBuffer":96,"_process":109,"inherits":95}],98:[function(require,module,exports){
|
|
'use strict'
|
|
|
|
exports.byteLength = byteLength
|
|
exports.toByteArray = toByteArray
|
|
exports.fromByteArray = fromByteArray
|
|
|
|
var lookup = []
|
|
var revLookup = []
|
|
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
|
|
|
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
for (var i = 0, len = code.length; i < len; ++i) {
|
|
lookup[i] = code[i]
|
|
revLookup[code.charCodeAt(i)] = i
|
|
}
|
|
|
|
// Support decoding URL-safe base64 strings, as Node.js does.
|
|
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
|
revLookup['-'.charCodeAt(0)] = 62
|
|
revLookup['_'.charCodeAt(0)] = 63
|
|
|
|
function getLens (b64) {
|
|
var len = b64.length
|
|
|
|
if (len % 4 > 0) {
|
|
throw new Error('Invalid string. Length must be a multiple of 4')
|
|
}
|
|
|
|
// Trim off extra bytes after placeholder bytes are found
|
|
// See: https://github.com/beatgammit/base64-js/issues/42
|
|
var validLen = b64.indexOf('=')
|
|
if (validLen === -1) validLen = len
|
|
|
|
var placeHoldersLen = validLen === len
|
|
? 0
|
|
: 4 - (validLen % 4)
|
|
|
|
return [validLen, placeHoldersLen]
|
|
}
|
|
|
|
// base64 is 4/3 + up to two characters of the original data
|
|
function byteLength (b64) {
|
|
var lens = getLens(b64)
|
|
var validLen = lens[0]
|
|
var placeHoldersLen = lens[1]
|
|
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
|
}
|
|
|
|
function _byteLength (b64, validLen, placeHoldersLen) {
|
|
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
|
}
|
|
|
|
function toByteArray (b64) {
|
|
var tmp
|
|
var lens = getLens(b64)
|
|
var validLen = lens[0]
|
|
var placeHoldersLen = lens[1]
|
|
|
|
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
|
|
|
|
var curByte = 0
|
|
|
|
// if there are placeholders, only get up to the last complete 4 chars
|
|
var len = placeHoldersLen > 0
|
|
? validLen - 4
|
|
: validLen
|
|
|
|
var i
|
|
for (i = 0; i < len; i += 4) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 18) |
|
|
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
|
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
|
revLookup[b64.charCodeAt(i + 3)]
|
|
arr[curByte++] = (tmp >> 16) & 0xFF
|
|
arr[curByte++] = (tmp >> 8) & 0xFF
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
if (placeHoldersLen === 2) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 2) |
|
|
(revLookup[b64.charCodeAt(i + 1)] >> 4)
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
if (placeHoldersLen === 1) {
|
|
tmp =
|
|
(revLookup[b64.charCodeAt(i)] << 10) |
|
|
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
|
(revLookup[b64.charCodeAt(i + 2)] >> 2)
|
|
arr[curByte++] = (tmp >> 8) & 0xFF
|
|
arr[curByte++] = tmp & 0xFF
|
|
}
|
|
|
|
return arr
|
|
}
|
|
|
|
function tripletToBase64 (num) {
|
|
return lookup[num >> 18 & 0x3F] +
|
|
lookup[num >> 12 & 0x3F] +
|
|
lookup[num >> 6 & 0x3F] +
|
|
lookup[num & 0x3F]
|
|
}
|
|
|
|
function encodeChunk (uint8, start, end) {
|
|
var tmp
|
|
var output = []
|
|
for (var i = start; i < end; i += 3) {
|
|
tmp =
|
|
((uint8[i] << 16) & 0xFF0000) +
|
|
((uint8[i + 1] << 8) & 0xFF00) +
|
|
(uint8[i + 2] & 0xFF)
|
|
output.push(tripletToBase64(tmp))
|
|
}
|
|
return output.join('')
|
|
}
|
|
|
|
function fromByteArray (uint8) {
|
|
var tmp
|
|
var len = uint8.length
|
|
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
|
|
var parts = []
|
|
var maxChunkLength = 16383 // must be multiple of 3
|
|
|
|
// go through the array every three bytes, we'll deal with trailing stuff later
|
|
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
|
parts.push(encodeChunk(
|
|
uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
|
|
))
|
|
}
|
|
|
|
// pad the end with zeros, but make sure to not forget the extra bytes
|
|
if (extraBytes === 1) {
|
|
tmp = uint8[len - 1]
|
|
parts.push(
|
|
lookup[tmp >> 2] +
|
|
lookup[(tmp << 4) & 0x3F] +
|
|
'=='
|
|
)
|
|
} else if (extraBytes === 2) {
|
|
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
|
|
parts.push(
|
|
lookup[tmp >> 10] +
|
|
lookup[(tmp >> 4) & 0x3F] +
|
|
lookup[(tmp << 2) & 0x3F] +
|
|
'='
|
|
)
|
|
}
|
|
|
|
return parts.join('')
|
|
}
|
|
|
|
},{}],99:[function(require,module,exports){
|
|
|
|
},{}],100:[function(require,module,exports){
|
|
(function (Buffer){
|
|
/*!
|
|
* The buffer module from node.js, for the browser.
|
|
*
|
|
* @author Feross Aboukhadijeh <https://feross.org>
|
|
* @license MIT
|
|
*/
|
|
/* eslint-disable no-proto */
|
|
|
|
'use strict'
|
|
|
|
var base64 = require('base64-js')
|
|
var ieee754 = require('ieee754')
|
|
var customInspectSymbol =
|
|
(typeof Symbol === 'function' && typeof Symbol.for === 'function')
|
|
? Symbol.for('nodejs.util.inspect.custom')
|
|
: null
|
|
|
|
exports.Buffer = Buffer
|
|
exports.SlowBuffer = SlowBuffer
|
|
exports.INSPECT_MAX_BYTES = 50
|
|
|
|
var K_MAX_LENGTH = 0x7fffffff
|
|
exports.kMaxLength = K_MAX_LENGTH
|
|
|
|
/**
|
|
* If `Buffer.TYPED_ARRAY_SUPPORT`:
|
|
* === true Use Uint8Array implementation (fastest)
|
|
* === false Print warning and recommend using `buffer` v4.x which has an Object
|
|
* implementation (most compatible, even IE6)
|
|
*
|
|
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
|
|
* Opera 11.6+, iOS 4.2+.
|
|
*
|
|
* We report that the browser does not support typed arrays if the are not subclassable
|
|
* using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
|
|
* (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
|
|
* for __proto__ and has a buggy typed array implementation.
|
|
*/
|
|
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
|
|
|
|
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
|
|
typeof console.error === 'function') {
|
|
console.error(
|
|
'This browser lacks typed array (Uint8Array) support which is required by ' +
|
|
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
|
|
)
|
|
}
|
|
|
|
function typedArraySupport () {
|
|
// Can typed array instances can be augmented?
|
|
try {
|
|
var arr = new Uint8Array(1)
|
|
var proto = { foo: function () { return 42 } }
|
|
Object.setPrototypeOf(proto, Uint8Array.prototype)
|
|
Object.setPrototypeOf(arr, proto)
|
|
return arr.foo() === 42
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(Buffer.prototype, 'parent', {
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!Buffer.isBuffer(this)) return undefined
|
|
return this.buffer
|
|
}
|
|
})
|
|
|
|
Object.defineProperty(Buffer.prototype, 'offset', {
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!Buffer.isBuffer(this)) return undefined
|
|
return this.byteOffset
|
|
}
|
|
})
|
|
|
|
function createBuffer (length) {
|
|
if (length > K_MAX_LENGTH) {
|
|
throw new RangeError('The value "' + length + '" is invalid for option "size"')
|
|
}
|
|
// Return an augmented `Uint8Array` instance
|
|
var buf = new Uint8Array(length)
|
|
Object.setPrototypeOf(buf, Buffer.prototype)
|
|
return buf
|
|
}
|
|
|
|
/**
|
|
* The Buffer constructor returns instances of `Uint8Array` that have their
|
|
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
|
|
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
|
|
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
|
|
* returns a single octet.
|
|
*
|
|
* The `Uint8Array` prototype remains unmodified.
|
|
*/
|
|
|
|
function Buffer (arg, encodingOrOffset, length) {
|
|
// Common case.
|
|
if (typeof arg === 'number') {
|
|
if (typeof encodingOrOffset === 'string') {
|
|
throw new TypeError(
|
|
'The "string" argument must be of type string. Received type number'
|
|
)
|
|
}
|
|
return allocUnsafe(arg)
|
|
}
|
|
return from(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
|
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
|
|
Buffer[Symbol.species] === Buffer) {
|
|
Object.defineProperty(Buffer, Symbol.species, {
|
|
value: null,
|
|
configurable: true,
|
|
enumerable: false,
|
|
writable: false
|
|
})
|
|
}
|
|
|
|
Buffer.poolSize = 8192 // not used by this implementation
|
|
|
|
function from (value, encodingOrOffset, length) {
|
|
if (typeof value === 'string') {
|
|
return fromString(value, encodingOrOffset)
|
|
}
|
|
|
|
if (ArrayBuffer.isView(value)) {
|
|
return fromArrayLike(value)
|
|
}
|
|
|
|
if (value == null) {
|
|
throw new TypeError(
|
|
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
|
'or Array-like Object. Received type ' + (typeof value)
|
|
)
|
|
}
|
|
|
|
if (isInstance(value, ArrayBuffer) ||
|
|
(value && isInstance(value.buffer, ArrayBuffer))) {
|
|
return fromArrayBuffer(value, encodingOrOffset, length)
|
|
}
|
|
|
|
if (typeof value === 'number') {
|
|
throw new TypeError(
|
|
'The "value" argument must not be of type number. Received type number'
|
|
)
|
|
}
|
|
|
|
var valueOf = value.valueOf && value.valueOf()
|
|
if (valueOf != null && valueOf !== value) {
|
|
return Buffer.from(valueOf, encodingOrOffset, length)
|
|
}
|
|
|
|
var b = fromObject(value)
|
|
if (b) return b
|
|
|
|
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
|
|
typeof value[Symbol.toPrimitive] === 'function') {
|
|
return Buffer.from(
|
|
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
|
|
)
|
|
}
|
|
|
|
throw new TypeError(
|
|
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
|
'or Array-like Object. Received type ' + (typeof value)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
|
|
* if value is a number.
|
|
* Buffer.from(str[, encoding])
|
|
* Buffer.from(array)
|
|
* Buffer.from(buffer)
|
|
* Buffer.from(arrayBuffer[, byteOffset[, length]])
|
|
**/
|
|
Buffer.from = function (value, encodingOrOffset, length) {
|
|
return from(value, encodingOrOffset, length)
|
|
}
|
|
|
|
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
|
|
// https://github.com/feross/buffer/pull/148
|
|
Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype)
|
|
Object.setPrototypeOf(Buffer, Uint8Array)
|
|
|
|
function assertSize (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('"size" argument must be of type number')
|
|
} else if (size < 0) {
|
|
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
|
}
|
|
}
|
|
|
|
function alloc (size, fill, encoding) {
|
|
assertSize(size)
|
|
if (size <= 0) {
|
|
return createBuffer(size)
|
|
}
|
|
if (fill !== undefined) {
|
|
// Only pay attention to encoding if it's a string. This
|
|
// prevents accidentally sending in a number that would
|
|
// be interpretted as a start offset.
|
|
return typeof encoding === 'string'
|
|
? createBuffer(size).fill(fill, encoding)
|
|
: createBuffer(size).fill(fill)
|
|
}
|
|
return createBuffer(size)
|
|
}
|
|
|
|
/**
|
|
* Creates a new filled Buffer instance.
|
|
* alloc(size[, fill[, encoding]])
|
|
**/
|
|
Buffer.alloc = function (size, fill, encoding) {
|
|
return alloc(size, fill, encoding)
|
|
}
|
|
|
|
function allocUnsafe (size) {
|
|
assertSize(size)
|
|
return createBuffer(size < 0 ? 0 : checked(size) | 0)
|
|
}
|
|
|
|
/**
|
|
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
|
|
* */
|
|
Buffer.allocUnsafe = function (size) {
|
|
return allocUnsafe(size)
|
|
}
|
|
/**
|
|
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
|
|
*/
|
|
Buffer.allocUnsafeSlow = function (size) {
|
|
return allocUnsafe(size)
|
|
}
|
|
|
|
function fromString (string, encoding) {
|
|
if (typeof encoding !== 'string' || encoding === '') {
|
|
encoding = 'utf8'
|
|
}
|
|
|
|
if (!Buffer.isEncoding(encoding)) {
|
|
throw new TypeError('Unknown encoding: ' + encoding)
|
|
}
|
|
|
|
var length = byteLength(string, encoding) | 0
|
|
var buf = createBuffer(length)
|
|
|
|
var actual = buf.write(string, encoding)
|
|
|
|
if (actual !== length) {
|
|
// Writing a hex string, for example, that contains invalid characters will
|
|
// cause everything after the first invalid character to be ignored. (e.g.
|
|
// 'abxxcd' will be treated as 'ab')
|
|
buf = buf.slice(0, actual)
|
|
}
|
|
|
|
return buf
|
|
}
|
|
|
|
function fromArrayLike (array) {
|
|
var length = array.length < 0 ? 0 : checked(array.length) | 0
|
|
var buf = createBuffer(length)
|
|
for (var i = 0; i < length; i += 1) {
|
|
buf[i] = array[i] & 255
|
|
}
|
|
return buf
|
|
}
|
|
|
|
function fromArrayBuffer (array, byteOffset, length) {
|
|
if (byteOffset < 0 || array.byteLength < byteOffset) {
|
|
throw new RangeError('"offset" is outside of buffer bounds')
|
|
}
|
|
|
|
if (array.byteLength < byteOffset + (length || 0)) {
|
|
throw new RangeError('"length" is outside of buffer bounds')
|
|
}
|
|
|
|
var buf
|
|
if (byteOffset === undefined && length === undefined) {
|
|
buf = new Uint8Array(array)
|
|
} else if (length === undefined) {
|
|
buf = new Uint8Array(array, byteOffset)
|
|
} else {
|
|
buf = new Uint8Array(array, byteOffset, length)
|
|
}
|
|
|
|
// Return an augmented `Uint8Array` instance
|
|
Object.setPrototypeOf(buf, Buffer.prototype)
|
|
|
|
return buf
|
|
}
|
|
|
|
function fromObject (obj) {
|
|
if (Buffer.isBuffer(obj)) {
|
|
var len = checked(obj.length) | 0
|
|
var buf = createBuffer(len)
|
|
|
|
if (buf.length === 0) {
|
|
return buf
|
|
}
|
|
|
|
obj.copy(buf, 0, 0, len)
|
|
return buf
|
|
}
|
|
|
|
if (obj.length !== undefined) {
|
|
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
|
|
return createBuffer(0)
|
|
}
|
|
return fromArrayLike(obj)
|
|
}
|
|
|
|
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
|
|
return fromArrayLike(obj.data)
|
|
}
|
|
}
|
|
|
|
function checked (length) {
|
|
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
|
|
// length is NaN (which is otherwise coerced to zero.)
|
|
if (length >= K_MAX_LENGTH) {
|
|
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
|
|
'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
|
|
}
|
|
return length | 0
|
|
}
|
|
|
|
function SlowBuffer (length) {
|
|
if (+length != length) { // eslint-disable-line eqeqeq
|
|
length = 0
|
|
}
|
|
return Buffer.alloc(+length)
|
|
}
|
|
|
|
Buffer.isBuffer = function isBuffer (b) {
|
|
return b != null && b._isBuffer === true &&
|
|
b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
|
|
}
|
|
|
|
Buffer.compare = function compare (a, b) {
|
|
if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
|
|
if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
|
|
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
|
|
throw new TypeError(
|
|
'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
|
|
)
|
|
}
|
|
|
|
if (a === b) return 0
|
|
|
|
var x = a.length
|
|
var y = b.length
|
|
|
|
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
|
|
if (a[i] !== b[i]) {
|
|
x = a[i]
|
|
y = b[i]
|
|
break
|
|
}
|
|
}
|
|
|
|
if (x < y) return -1
|
|
if (y < x) return 1
|
|
return 0
|
|
}
|
|
|
|
Buffer.isEncoding = function isEncoding (encoding) {
|
|
switch (String(encoding).toLowerCase()) {
|
|
case 'hex':
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
case 'ascii':
|
|
case 'latin1':
|
|
case 'binary':
|
|
case 'base64':
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
Buffer.concat = function concat (list, length) {
|
|
if (!Array.isArray(list)) {
|
|
throw new TypeError('"list" argument must be an Array of Buffers')
|
|
}
|
|
|
|
if (list.length === 0) {
|
|
return Buffer.alloc(0)
|
|
}
|
|
|
|
var i
|
|
if (length === undefined) {
|
|
length = 0
|
|
for (i = 0; i < list.length; ++i) {
|
|
length += list[i].length
|
|
}
|
|
}
|
|
|
|
var buffer = Buffer.allocUnsafe(length)
|
|
var pos = 0
|
|
for (i = 0; i < list.length; ++i) {
|
|
var buf = list[i]
|
|
if (isInstance(buf, Uint8Array)) {
|
|
buf = Buffer.from(buf)
|
|
}
|
|
if (!Buffer.isBuffer(buf)) {
|
|
throw new TypeError('"list" argument must be an Array of Buffers')
|
|
}
|
|
buf.copy(buffer, pos)
|
|
pos += buf.length
|
|
}
|
|
return buffer
|
|
}
|
|
|
|
function byteLength (string, encoding) {
|
|
if (Buffer.isBuffer(string)) {
|
|
return string.length
|
|
}
|
|
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
|
|
return string.byteLength
|
|
}
|
|
if (typeof string !== 'string') {
|
|
throw new TypeError(
|
|
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
|
|
'Received type ' + typeof string
|
|
)
|
|
}
|
|
|
|
var len = string.length
|
|
var mustMatch = (arguments.length > 2 && arguments[2] === true)
|
|
if (!mustMatch && len === 0) return 0
|
|
|
|
// Use a for loop to avoid recursion
|
|
var loweredCase = false
|
|
for (;;) {
|
|
switch (encoding) {
|
|
case 'ascii':
|
|
case 'latin1':
|
|
case 'binary':
|
|
return len
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return utf8ToBytes(string).length
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return len * 2
|
|
case 'hex':
|
|
return len >>> 1
|
|
case 'base64':
|
|
return base64ToBytes(string).length
|
|
default:
|
|
if (loweredCase) {
|
|
return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
|
|
}
|
|
encoding = ('' + encoding).toLowerCase()
|
|
loweredCase = true
|
|
}
|
|
}
|
|
}
|
|
Buffer.byteLength = byteLength
|
|
|
|
function slowToString (encoding, start, end) {
|
|
var loweredCase = false
|
|
|
|
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
|
|
// property of a typed array.
|
|
|
|
// This behaves neither like String nor Uint8Array in that we set start/end
|
|
// to their upper/lower bounds if the value passed is out of range.
|
|
// undefined is handled specially as per ECMA-262 6th Edition,
|
|
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
|
|
if (start === undefined || start < 0) {
|
|
start = 0
|
|
}
|
|
// Return early if start > this.length. Done here to prevent potential uint32
|
|
// coercion fail below.
|
|
if (start > this.length) {
|
|
return ''
|
|
}
|
|
|
|
if (end === undefined || end > this.length) {
|
|
end = this.length
|
|
}
|
|
|
|
if (end <= 0) {
|
|
return ''
|
|
}
|
|
|
|
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
|
|
end >>>= 0
|
|
start >>>= 0
|
|
|
|
if (end <= start) {
|
|
return ''
|
|
}
|
|
|
|
if (!encoding) encoding = 'utf8'
|
|
|
|
while (true) {
|
|
switch (encoding) {
|
|
case 'hex':
|
|
return hexSlice(this, start, end)
|
|
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return utf8Slice(this, start, end)
|
|
|
|
case 'ascii':
|
|
return asciiSlice(this, start, end)
|
|
|
|
case 'latin1':
|
|
case 'binary':
|
|
return latin1Slice(this, start, end)
|
|
|
|
case 'base64':
|
|
return base64Slice(this, start, end)
|
|
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return utf16leSlice(this, start, end)
|
|
|
|
default:
|
|
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
|
encoding = (encoding + '').toLowerCase()
|
|
loweredCase = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
|
|
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
|
|
// reliably in a browserify context because there could be multiple different
|
|
// copies of the 'buffer' package in use. This method works even for Buffer
|
|
// instances that were created from another copy of the `buffer` package.
|
|
// See: https://github.com/feross/buffer/issues/154
|
|
Buffer.prototype._isBuffer = true
|
|
|
|
function swap (b, n, m) {
|
|
var i = b[n]
|
|
b[n] = b[m]
|
|
b[m] = i
|
|
}
|
|
|
|
Buffer.prototype.swap16 = function swap16 () {
|
|
var len = this.length
|
|
if (len % 2 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 16-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 2) {
|
|
swap(this, i, i + 1)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.swap32 = function swap32 () {
|
|
var len = this.length
|
|
if (len % 4 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 32-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 4) {
|
|
swap(this, i, i + 3)
|
|
swap(this, i + 1, i + 2)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.swap64 = function swap64 () {
|
|
var len = this.length
|
|
if (len % 8 !== 0) {
|
|
throw new RangeError('Buffer size must be a multiple of 64-bits')
|
|
}
|
|
for (var i = 0; i < len; i += 8) {
|
|
swap(this, i, i + 7)
|
|
swap(this, i + 1, i + 6)
|
|
swap(this, i + 2, i + 5)
|
|
swap(this, i + 3, i + 4)
|
|
}
|
|
return this
|
|
}
|
|
|
|
Buffer.prototype.toString = function toString () {
|
|
var length = this.length
|
|
if (length === 0) return ''
|
|
if (arguments.length === 0) return utf8Slice(this, 0, length)
|
|
return slowToString.apply(this, arguments)
|
|
}
|
|
|
|
Buffer.prototype.toLocaleString = Buffer.prototype.toString
|
|
|
|
Buffer.prototype.equals = function equals (b) {
|
|
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
|
|
if (this === b) return true
|
|
return Buffer.compare(this, b) === 0
|
|
}
|
|
|
|
Buffer.prototype.inspect = function inspect () {
|
|
var str = ''
|
|
var max = exports.INSPECT_MAX_BYTES
|
|
str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
|
|
if (this.length > max) str += ' ... '
|
|
return '<Buffer ' + str + '>'
|
|
}
|
|
if (customInspectSymbol) {
|
|
Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect
|
|
}
|
|
|
|
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
|
|
if (isInstance(target, Uint8Array)) {
|
|
target = Buffer.from(target, target.offset, target.byteLength)
|
|
}
|
|
if (!Buffer.isBuffer(target)) {
|
|
throw new TypeError(
|
|
'The "target" argument must be one of type Buffer or Uint8Array. ' +
|
|
'Received type ' + (typeof target)
|
|
)
|
|
}
|
|
|
|
if (start === undefined) {
|
|
start = 0
|
|
}
|
|
if (end === undefined) {
|
|
end = target ? target.length : 0
|
|
}
|
|
if (thisStart === undefined) {
|
|
thisStart = 0
|
|
}
|
|
if (thisEnd === undefined) {
|
|
thisEnd = this.length
|
|
}
|
|
|
|
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
|
|
throw new RangeError('out of range index')
|
|
}
|
|
|
|
if (thisStart >= thisEnd && start >= end) {
|
|
return 0
|
|
}
|
|
if (thisStart >= thisEnd) {
|
|
return -1
|
|
}
|
|
if (start >= end) {
|
|
return 1
|
|
}
|
|
|
|
start >>>= 0
|
|
end >>>= 0
|
|
thisStart >>>= 0
|
|
thisEnd >>>= 0
|
|
|
|
if (this === target) return 0
|
|
|
|
var x = thisEnd - thisStart
|
|
var y = end - start
|
|
var len = Math.min(x, y)
|
|
|
|
var thisCopy = this.slice(thisStart, thisEnd)
|
|
var targetCopy = target.slice(start, end)
|
|
|
|
for (var i = 0; i < len; ++i) {
|
|
if (thisCopy[i] !== targetCopy[i]) {
|
|
x = thisCopy[i]
|
|
y = targetCopy[i]
|
|
break
|
|
}
|
|
}
|
|
|
|
if (x < y) return -1
|
|
if (y < x) return 1
|
|
return 0
|
|
}
|
|
|
|
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
|
|
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
|
|
//
|
|
// Arguments:
|
|
// - buffer - a Buffer to search
|
|
// - val - a string, Buffer, or number
|
|
// - byteOffset - an index into `buffer`; will be clamped to an int32
|
|
// - encoding - an optional encoding, relevant is val is a string
|
|
// - dir - true for indexOf, false for lastIndexOf
|
|
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
|
// Empty buffer means no match
|
|
if (buffer.length === 0) return -1
|
|
|
|
// Normalize byteOffset
|
|
if (typeof byteOffset === 'string') {
|
|
encoding = byteOffset
|
|
byteOffset = 0
|
|
} else if (byteOffset > 0x7fffffff) {
|
|
byteOffset = 0x7fffffff
|
|
} else if (byteOffset < -0x80000000) {
|
|
byteOffset = -0x80000000
|
|
}
|
|
byteOffset = +byteOffset // Coerce to Number.
|
|
if (numberIsNaN(byteOffset)) {
|
|
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
|
|
byteOffset = dir ? 0 : (buffer.length - 1)
|
|
}
|
|
|
|
// Normalize byteOffset: negative offsets start from the end of the buffer
|
|
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
|
|
if (byteOffset >= buffer.length) {
|
|
if (dir) return -1
|
|
else byteOffset = buffer.length - 1
|
|
} else if (byteOffset < 0) {
|
|
if (dir) byteOffset = 0
|
|
else return -1
|
|
}
|
|
|
|
// Normalize val
|
|
if (typeof val === 'string') {
|
|
val = Buffer.from(val, encoding)
|
|
}
|
|
|
|
// Finally, search either indexOf (if dir is true) or lastIndexOf
|
|
if (Buffer.isBuffer(val)) {
|
|
// Special case: looking for empty string/buffer always fails
|
|
if (val.length === 0) {
|
|
return -1
|
|
}
|
|
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
|
} else if (typeof val === 'number') {
|
|
val = val & 0xFF // Search for a byte value [0-255]
|
|
if (typeof Uint8Array.prototype.indexOf === 'function') {
|
|
if (dir) {
|
|
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
|
} else {
|
|
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
|
|
}
|
|
}
|
|
return arrayIndexOf(buffer, [val], byteOffset, encoding, dir)
|
|
}
|
|
|
|
throw new TypeError('val must be string, number or Buffer')
|
|
}
|
|
|
|
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
|
|
var indexSize = 1
|
|
var arrLength = arr.length
|
|
var valLength = val.length
|
|
|
|
if (encoding !== undefined) {
|
|
encoding = String(encoding).toLowerCase()
|
|
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
|
|
encoding === 'utf16le' || encoding === 'utf-16le') {
|
|
if (arr.length < 2 || val.length < 2) {
|
|
return -1
|
|
}
|
|
indexSize = 2
|
|
arrLength /= 2
|
|
valLength /= 2
|
|
byteOffset /= 2
|
|
}
|
|
}
|
|
|
|
function read (buf, i) {
|
|
if (indexSize === 1) {
|
|
return buf[i]
|
|
} else {
|
|
return buf.readUInt16BE(i * indexSize)
|
|
}
|
|
}
|
|
|
|
var i
|
|
if (dir) {
|
|
var foundIndex = -1
|
|
for (i = byteOffset; i < arrLength; i++) {
|
|
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
|
|
if (foundIndex === -1) foundIndex = i
|
|
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
|
|
} else {
|
|
if (foundIndex !== -1) i -= i - foundIndex
|
|
foundIndex = -1
|
|
}
|
|
}
|
|
} else {
|
|
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
|
|
for (i = byteOffset; i >= 0; i--) {
|
|
var found = true
|
|
for (var j = 0; j < valLength; j++) {
|
|
if (read(arr, i + j) !== read(val, j)) {
|
|
found = false
|
|
break
|
|
}
|
|
}
|
|
if (found) return i
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
|
|
return this.indexOf(val, byteOffset, encoding) !== -1
|
|
}
|
|
|
|
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
|
|
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
|
|
}
|
|
|
|
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
|
|
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
|
|
}
|
|
|
|
function hexWrite (buf, string, offset, length) {
|
|
offset = Number(offset) || 0
|
|
var remaining = buf.length - offset
|
|
if (!length) {
|
|
length = remaining
|
|
} else {
|
|
length = Number(length)
|
|
if (length > remaining) {
|
|
length = remaining
|
|
}
|
|
}
|
|
|
|
var strLen = string.length
|
|
|
|
if (length > strLen / 2) {
|
|
length = strLen / 2
|
|
}
|
|
for (var i = 0; i < length; ++i) {
|
|
var parsed = parseInt(string.substr(i * 2, 2), 16)
|
|
if (numberIsNaN(parsed)) return i
|
|
buf[offset + i] = parsed
|
|
}
|
|
return i
|
|
}
|
|
|
|
function utf8Write (buf, string, offset, length) {
|
|
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
|
|
}
|
|
|
|
function asciiWrite (buf, string, offset, length) {
|
|
return blitBuffer(asciiToBytes(string), buf, offset, length)
|
|
}
|
|
|
|
function latin1Write (buf, string, offset, length) {
|
|
return asciiWrite(buf, string, offset, length)
|
|
}
|
|
|
|
function base64Write (buf, string, offset, length) {
|
|
return blitBuffer(base64ToBytes(string), buf, offset, length)
|
|
}
|
|
|
|
function ucs2Write (buf, string, offset, length) {
|
|
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
|
|
}
|
|
|
|
Buffer.prototype.write = function write (string, offset, length, encoding) {
|
|
// Buffer#write(string)
|
|
if (offset === undefined) {
|
|
encoding = 'utf8'
|
|
length = this.length
|
|
offset = 0
|
|
// Buffer#write(string, encoding)
|
|
} else if (length === undefined && typeof offset === 'string') {
|
|
encoding = offset
|
|
length = this.length
|
|
offset = 0
|
|
// Buffer#write(string, offset[, length][, encoding])
|
|
} else if (isFinite(offset)) {
|
|
offset = offset >>> 0
|
|
if (isFinite(length)) {
|
|
length = length >>> 0
|
|
if (encoding === undefined) encoding = 'utf8'
|
|
} else {
|
|
encoding = length
|
|
length = undefined
|
|
}
|
|
} else {
|
|
throw new Error(
|
|
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
|
|
)
|
|
}
|
|
|
|
var remaining = this.length - offset
|
|
if (length === undefined || length > remaining) length = remaining
|
|
|
|
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
|
|
throw new RangeError('Attempt to write outside buffer bounds')
|
|
}
|
|
|
|
if (!encoding) encoding = 'utf8'
|
|
|
|
var loweredCase = false
|
|
for (;;) {
|
|
switch (encoding) {
|
|
case 'hex':
|
|
return hexWrite(this, string, offset, length)
|
|
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return utf8Write(this, string, offset, length)
|
|
|
|
case 'ascii':
|
|
return asciiWrite(this, string, offset, length)
|
|
|
|
case 'latin1':
|
|
case 'binary':
|
|
return latin1Write(this, string, offset, length)
|
|
|
|
case 'base64':
|
|
// Warning: maxLength not taken into account in base64Write
|
|
return base64Write(this, string, offset, length)
|
|
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return ucs2Write(this, string, offset, length)
|
|
|
|
default:
|
|
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
|
encoding = ('' + encoding).toLowerCase()
|
|
loweredCase = true
|
|
}
|
|
}
|
|
}
|
|
|
|
Buffer.prototype.toJSON = function toJSON () {
|
|
return {
|
|
type: 'Buffer',
|
|
data: Array.prototype.slice.call(this._arr || this, 0)
|
|
}
|
|
}
|
|
|
|
function base64Slice (buf, start, end) {
|
|
if (start === 0 && end === buf.length) {
|
|
return base64.fromByteArray(buf)
|
|
} else {
|
|
return base64.fromByteArray(buf.slice(start, end))
|
|
}
|
|
}
|
|
|
|
function utf8Slice (buf, start, end) {
|
|
end = Math.min(buf.length, end)
|
|
var res = []
|
|
|
|
var i = start
|
|
while (i < end) {
|
|
var firstByte = buf[i]
|
|
var codePoint = null
|
|
var bytesPerSequence = (firstByte > 0xEF) ? 4
|
|
: (firstByte > 0xDF) ? 3
|
|
: (firstByte > 0xBF) ? 2
|
|
: 1
|
|
|
|
if (i + bytesPerSequence <= end) {
|
|
var secondByte, thirdByte, fourthByte, tempCodePoint
|
|
|
|
switch (bytesPerSequence) {
|
|
case 1:
|
|
if (firstByte < 0x80) {
|
|
codePoint = firstByte
|
|
}
|
|
break
|
|
case 2:
|
|
secondByte = buf[i + 1]
|
|
if ((secondByte & 0xC0) === 0x80) {
|
|
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
|
|
if (tempCodePoint > 0x7F) {
|
|
codePoint = tempCodePoint
|
|
}
|
|
}
|
|
break
|
|
case 3:
|
|
secondByte = buf[i + 1]
|
|
thirdByte = buf[i + 2]
|
|
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
|
|
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
|
|
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
|
|
codePoint = tempCodePoint
|
|
}
|
|
}
|
|
break
|
|
case 4:
|
|
secondByte = buf[i + 1]
|
|
thirdByte = buf[i + 2]
|
|
fourthByte = buf[i + 3]
|
|
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
|
|
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
|
|
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
|
|
codePoint = tempCodePoint
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (codePoint === null) {
|
|
// we did not generate a valid codePoint so insert a
|
|
// replacement char (U+FFFD) and advance only 1 byte
|
|
codePoint = 0xFFFD
|
|
bytesPerSequence = 1
|
|
} else if (codePoint > 0xFFFF) {
|
|
// encode to utf16 (surrogate pair dance)
|
|
codePoint -= 0x10000
|
|
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
|
|
codePoint = 0xDC00 | codePoint & 0x3FF
|
|
}
|
|
|
|
res.push(codePoint)
|
|
i += bytesPerSequence
|
|
}
|
|
|
|
return decodeCodePointsArray(res)
|
|
}
|
|
|
|
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
|
|
// the lowest limit is Chrome, with 0x10000 args.
|
|
// We go 1 magnitude less, for safety
|
|
var MAX_ARGUMENTS_LENGTH = 0x1000
|
|
|
|
function decodeCodePointsArray (codePoints) {
|
|
var len = codePoints.length
|
|
if (len <= MAX_ARGUMENTS_LENGTH) {
|
|
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
|
|
}
|
|
|
|
// Decode in chunks to avoid "call stack size exceeded".
|
|
var res = ''
|
|
var i = 0
|
|
while (i < len) {
|
|
res += String.fromCharCode.apply(
|
|
String,
|
|
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
|
|
)
|
|
}
|
|
return res
|
|
}
|
|
|
|
function asciiSlice (buf, start, end) {
|
|
var ret = ''
|
|
end = Math.min(buf.length, end)
|
|
|
|
for (var i = start; i < end; ++i) {
|
|
ret += String.fromCharCode(buf[i] & 0x7F)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
function latin1Slice (buf, start, end) {
|
|
var ret = ''
|
|
end = Math.min(buf.length, end)
|
|
|
|
for (var i = start; i < end; ++i) {
|
|
ret += String.fromCharCode(buf[i])
|
|
}
|
|
return ret
|
|
}
|
|
|
|
function hexSlice (buf, start, end) {
|
|
var len = buf.length
|
|
|
|
if (!start || start < 0) start = 0
|
|
if (!end || end < 0 || end > len) end = len
|
|
|
|
var out = ''
|
|
for (var i = start; i < end; ++i) {
|
|
out += hexSliceLookupTable[buf[i]]
|
|
}
|
|
return out
|
|
}
|
|
|
|
function utf16leSlice (buf, start, end) {
|
|
var bytes = buf.slice(start, end)
|
|
var res = ''
|
|
for (var i = 0; i < bytes.length; i += 2) {
|
|
res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
|
|
}
|
|
return res
|
|
}
|
|
|
|
Buffer.prototype.slice = function slice (start, end) {
|
|
var len = this.length
|
|
start = ~~start
|
|
end = end === undefined ? len : ~~end
|
|
|
|
if (start < 0) {
|
|
start += len
|
|
if (start < 0) start = 0
|
|
} else if (start > len) {
|
|
start = len
|
|
}
|
|
|
|
if (end < 0) {
|
|
end += len
|
|
if (end < 0) end = 0
|
|
} else if (end > len) {
|
|
end = len
|
|
}
|
|
|
|
if (end < start) end = start
|
|
|
|
var newBuf = this.subarray(start, end)
|
|
// Return an augmented `Uint8Array` instance
|
|
Object.setPrototypeOf(newBuf, Buffer.prototype)
|
|
|
|
return newBuf
|
|
}
|
|
|
|
/*
|
|
* Need to make sure that buffer isn't trying to write out of bounds.
|
|
*/
|
|
function checkOffset (offset, ext, length) {
|
|
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
|
|
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
|
|
}
|
|
|
|
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
|
|
|
var val = this[offset]
|
|
var mul = 1
|
|
var i = 0
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
val += this[offset + i] * mul
|
|
}
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) {
|
|
checkOffset(offset, byteLength, this.length)
|
|
}
|
|
|
|
var val = this[offset + --byteLength]
|
|
var mul = 1
|
|
while (byteLength > 0 && (mul *= 0x100)) {
|
|
val += this[offset + --byteLength] * mul
|
|
}
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 1, this.length)
|
|
return this[offset]
|
|
}
|
|
|
|
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
return this[offset] | (this[offset + 1] << 8)
|
|
}
|
|
|
|
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
return (this[offset] << 8) | this[offset + 1]
|
|
}
|
|
|
|
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return ((this[offset]) |
|
|
(this[offset + 1] << 8) |
|
|
(this[offset + 2] << 16)) +
|
|
(this[offset + 3] * 0x1000000)
|
|
}
|
|
|
|
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return (this[offset] * 0x1000000) +
|
|
((this[offset + 1] << 16) |
|
|
(this[offset + 2] << 8) |
|
|
this[offset + 3])
|
|
}
|
|
|
|
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
|
|
|
var val = this[offset]
|
|
var mul = 1
|
|
var i = 0
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
val += this[offset + i] * mul
|
|
}
|
|
mul *= 0x80
|
|
|
|
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
|
|
|
var i = byteLength
|
|
var mul = 1
|
|
var val = this[offset + --i]
|
|
while (i > 0 && (mul *= 0x100)) {
|
|
val += this[offset + --i] * mul
|
|
}
|
|
mul *= 0x80
|
|
|
|
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
|
|
|
return val
|
|
}
|
|
|
|
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 1, this.length)
|
|
if (!(this[offset] & 0x80)) return (this[offset])
|
|
return ((0xff - this[offset] + 1) * -1)
|
|
}
|
|
|
|
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
var val = this[offset] | (this[offset + 1] << 8)
|
|
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
|
}
|
|
|
|
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 2, this.length)
|
|
var val = this[offset + 1] | (this[offset] << 8)
|
|
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
|
}
|
|
|
|
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return (this[offset]) |
|
|
(this[offset + 1] << 8) |
|
|
(this[offset + 2] << 16) |
|
|
(this[offset + 3] << 24)
|
|
}
|
|
|
|
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
|
|
return (this[offset] << 24) |
|
|
(this[offset + 1] << 16) |
|
|
(this[offset + 2] << 8) |
|
|
(this[offset + 3])
|
|
}
|
|
|
|
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
return ieee754.read(this, offset, true, 23, 4)
|
|
}
|
|
|
|
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 4, this.length)
|
|
return ieee754.read(this, offset, false, 23, 4)
|
|
}
|
|
|
|
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 8, this.length)
|
|
return ieee754.read(this, offset, true, 52, 8)
|
|
}
|
|
|
|
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkOffset(offset, 8, this.length)
|
|
return ieee754.read(this, offset, false, 52, 8)
|
|
}
|
|
|
|
function checkInt (buf, value, offset, ext, max, min) {
|
|
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
|
|
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
|
|
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
|
}
|
|
|
|
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) {
|
|
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
|
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
|
}
|
|
|
|
var mul = 1
|
|
var i = 0
|
|
this[offset] = value & 0xFF
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
this[offset + i] = (value / mul) & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
byteLength = byteLength >>> 0
|
|
if (!noAssert) {
|
|
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
|
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
|
}
|
|
|
|
var i = byteLength - 1
|
|
var mul = 1
|
|
this[offset + i] = value & 0xFF
|
|
while (--i >= 0 && (mul *= 0x100)) {
|
|
this[offset + i] = (value / mul) & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
|
|
this[offset] = (value & 0xff)
|
|
return offset + 1
|
|
}
|
|
|
|
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
|
this[offset] = (value >>> 8)
|
|
this[offset + 1] = (value & 0xff)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
|
this[offset + 3] = (value >>> 24)
|
|
this[offset + 2] = (value >>> 16)
|
|
this[offset + 1] = (value >>> 8)
|
|
this[offset] = (value & 0xff)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
|
this[offset] = (value >>> 24)
|
|
this[offset + 1] = (value >>> 16)
|
|
this[offset + 2] = (value >>> 8)
|
|
this[offset + 3] = (value & 0xff)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
var limit = Math.pow(2, (8 * byteLength) - 1)
|
|
|
|
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
|
}
|
|
|
|
var i = 0
|
|
var mul = 1
|
|
var sub = 0
|
|
this[offset] = value & 0xFF
|
|
while (++i < byteLength && (mul *= 0x100)) {
|
|
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
|
|
sub = 1
|
|
}
|
|
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
var limit = Math.pow(2, (8 * byteLength) - 1)
|
|
|
|
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
|
}
|
|
|
|
var i = byteLength - 1
|
|
var mul = 1
|
|
var sub = 0
|
|
this[offset + i] = value & 0xFF
|
|
while (--i >= 0 && (mul *= 0x100)) {
|
|
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
|
|
sub = 1
|
|
}
|
|
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
|
}
|
|
|
|
return offset + byteLength
|
|
}
|
|
|
|
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
|
|
if (value < 0) value = 0xff + value + 1
|
|
this[offset] = (value & 0xff)
|
|
return offset + 1
|
|
}
|
|
|
|
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
|
this[offset] = (value >>> 8)
|
|
this[offset + 1] = (value & 0xff)
|
|
return offset + 2
|
|
}
|
|
|
|
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
|
this[offset] = (value & 0xff)
|
|
this[offset + 1] = (value >>> 8)
|
|
this[offset + 2] = (value >>> 16)
|
|
this[offset + 3] = (value >>> 24)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
|
if (value < 0) value = 0xffffffff + value + 1
|
|
this[offset] = (value >>> 24)
|
|
this[offset + 1] = (value >>> 16)
|
|
this[offset + 2] = (value >>> 8)
|
|
this[offset + 3] = (value & 0xff)
|
|
return offset + 4
|
|
}
|
|
|
|
function checkIEEE754 (buf, value, offset, ext, max, min) {
|
|
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
|
if (offset < 0) throw new RangeError('Index out of range')
|
|
}
|
|
|
|
function writeFloat (buf, value, offset, littleEndian, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
|
|
}
|
|
ieee754.write(buf, value, offset, littleEndian, 23, 4)
|
|
return offset + 4
|
|
}
|
|
|
|
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
|
|
return writeFloat(this, value, offset, true, noAssert)
|
|
}
|
|
|
|
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
|
|
return writeFloat(this, value, offset, false, noAssert)
|
|
}
|
|
|
|
function writeDouble (buf, value, offset, littleEndian, noAssert) {
|
|
value = +value
|
|
offset = offset >>> 0
|
|
if (!noAssert) {
|
|
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
|
|
}
|
|
ieee754.write(buf, value, offset, littleEndian, 52, 8)
|
|
return offset + 8
|
|
}
|
|
|
|
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
|
|
return writeDouble(this, value, offset, true, noAssert)
|
|
}
|
|
|
|
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
|
|
return writeDouble(this, value, offset, false, noAssert)
|
|
}
|
|
|
|
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
|
|
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
|
|
if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
|
|
if (!start) start = 0
|
|
if (!end && end !== 0) end = this.length
|
|
if (targetStart >= target.length) targetStart = target.length
|
|
if (!targetStart) targetStart = 0
|
|
if (end > 0 && end < start) end = start
|
|
|
|
// Copy 0 bytes; we're done
|
|
if (end === start) return 0
|
|
if (target.length === 0 || this.length === 0) return 0
|
|
|
|
// Fatal error conditions
|
|
if (targetStart < 0) {
|
|
throw new RangeError('targetStart out of bounds')
|
|
}
|
|
if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
|
|
if (end < 0) throw new RangeError('sourceEnd out of bounds')
|
|
|
|
// Are we oob?
|
|
if (end > this.length) end = this.length
|
|
if (target.length - targetStart < end - start) {
|
|
end = target.length - targetStart + start
|
|
}
|
|
|
|
var len = end - start
|
|
|
|
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
|
|
// Use built-in when available, missing from IE11
|
|
this.copyWithin(targetStart, start, end)
|
|
} else if (this === target && start < targetStart && targetStart < end) {
|
|
// descending copy from end
|
|
for (var i = len - 1; i >= 0; --i) {
|
|
target[i + targetStart] = this[i + start]
|
|
}
|
|
} else {
|
|
Uint8Array.prototype.set.call(
|
|
target,
|
|
this.subarray(start, end),
|
|
targetStart
|
|
)
|
|
}
|
|
|
|
return len
|
|
}
|
|
|
|
// Usage:
|
|
// buffer.fill(number[, offset[, end]])
|
|
// buffer.fill(buffer[, offset[, end]])
|
|
// buffer.fill(string[, offset[, end]][, encoding])
|
|
Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
|
// Handle string cases:
|
|
if (typeof val === 'string') {
|
|
if (typeof start === 'string') {
|
|
encoding = start
|
|
start = 0
|
|
end = this.length
|
|
} else if (typeof end === 'string') {
|
|
encoding = end
|
|
end = this.length
|
|
}
|
|
if (encoding !== undefined && typeof encoding !== 'string') {
|
|
throw new TypeError('encoding must be a string')
|
|
}
|
|
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
|
|
throw new TypeError('Unknown encoding: ' + encoding)
|
|
}
|
|
if (val.length === 1) {
|
|
var code = val.charCodeAt(0)
|
|
if ((encoding === 'utf8' && code < 128) ||
|
|
encoding === 'latin1') {
|
|
// Fast path: If `val` fits into a single byte, use that numeric value.
|
|
val = code
|
|
}
|
|
}
|
|
} else if (typeof val === 'number') {
|
|
val = val & 255
|
|
} else if (typeof val === 'boolean') {
|
|
val = Number(val)
|
|
}
|
|
|
|
// Invalid ranges are not set to a default, so can range check early.
|
|
if (start < 0 || this.length < start || this.length < end) {
|
|
throw new RangeError('Out of range index')
|
|
}
|
|
|
|
if (end <= start) {
|
|
return this
|
|
}
|
|
|
|
start = start >>> 0
|
|
end = end === undefined ? this.length : end >>> 0
|
|
|
|
if (!val) val = 0
|
|
|
|
var i
|
|
if (typeof val === 'number') {
|
|
for (i = start; i < end; ++i) {
|
|
this[i] = val
|
|
}
|
|
} else {
|
|
var bytes = Buffer.isBuffer(val)
|
|
? val
|
|
: Buffer.from(val, encoding)
|
|
var len = bytes.length
|
|
if (len === 0) {
|
|
throw new TypeError('The value "' + val +
|
|
'" is invalid for argument "value"')
|
|
}
|
|
for (i = 0; i < end - start; ++i) {
|
|
this[i + start] = bytes[i % len]
|
|
}
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
// HELPER FUNCTIONS
|
|
// ================
|
|
|
|
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
|
|
|
|
function base64clean (str) {
|
|
// Node takes equal signs as end of the Base64 encoding
|
|
str = str.split('=')[0]
|
|
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
|
str = str.trim().replace(INVALID_BASE64_RE, '')
|
|
// Node converts strings with length < 2 to ''
|
|
if (str.length < 2) return ''
|
|
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
|
|
while (str.length % 4 !== 0) {
|
|
str = str + '='
|
|
}
|
|
return str
|
|
}
|
|
|
|
function utf8ToBytes (string, units) {
|
|
units = units || Infinity
|
|
var codePoint
|
|
var length = string.length
|
|
var leadSurrogate = null
|
|
var bytes = []
|
|
|
|
for (var i = 0; i < length; ++i) {
|
|
codePoint = string.charCodeAt(i)
|
|
|
|
// is surrogate component
|
|
if (codePoint > 0xD7FF && codePoint < 0xE000) {
|
|
// last char was a lead
|
|
if (!leadSurrogate) {
|
|
// no lead yet
|
|
if (codePoint > 0xDBFF) {
|
|
// unexpected trail
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
continue
|
|
} else if (i + 1 === length) {
|
|
// unpaired lead
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
continue
|
|
}
|
|
|
|
// valid lead
|
|
leadSurrogate = codePoint
|
|
|
|
continue
|
|
}
|
|
|
|
// 2 leads in a row
|
|
if (codePoint < 0xDC00) {
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
leadSurrogate = codePoint
|
|
continue
|
|
}
|
|
|
|
// valid surrogate pair
|
|
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
|
|
} else if (leadSurrogate) {
|
|
// valid bmp char, but last char was a lead
|
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
|
}
|
|
|
|
leadSurrogate = null
|
|
|
|
// encode utf8
|
|
if (codePoint < 0x80) {
|
|
if ((units -= 1) < 0) break
|
|
bytes.push(codePoint)
|
|
} else if (codePoint < 0x800) {
|
|
if ((units -= 2) < 0) break
|
|
bytes.push(
|
|
codePoint >> 0x6 | 0xC0,
|
|
codePoint & 0x3F | 0x80
|
|
)
|
|
} else if (codePoint < 0x10000) {
|
|
if ((units -= 3) < 0) break
|
|
bytes.push(
|
|
codePoint >> 0xC | 0xE0,
|
|
codePoint >> 0x6 & 0x3F | 0x80,
|
|
codePoint & 0x3F | 0x80
|
|
)
|
|
} else if (codePoint < 0x110000) {
|
|
if ((units -= 4) < 0) break
|
|
bytes.push(
|
|
codePoint >> 0x12 | 0xF0,
|
|
codePoint >> 0xC & 0x3F | 0x80,
|
|
codePoint >> 0x6 & 0x3F | 0x80,
|
|
codePoint & 0x3F | 0x80
|
|
)
|
|
} else {
|
|
throw new Error('Invalid code point')
|
|
}
|
|
}
|
|
|
|
return bytes
|
|
}
|
|
|
|
function asciiToBytes (str) {
|
|
var byteArray = []
|
|
for (var i = 0; i < str.length; ++i) {
|
|
// Node's code seems to be doing this and not & 0x7F..
|
|
byteArray.push(str.charCodeAt(i) & 0xFF)
|
|
}
|
|
return byteArray
|
|
}
|
|
|
|
function utf16leToBytes (str, units) {
|
|
var c, hi, lo
|
|
var byteArray = []
|
|
for (var i = 0; i < str.length; ++i) {
|
|
if ((units -= 2) < 0) break
|
|
|
|
c = str.charCodeAt(i)
|
|
hi = c >> 8
|
|
lo = c % 256
|
|
byteArray.push(lo)
|
|
byteArray.push(hi)
|
|
}
|
|
|
|
return byteArray
|
|
}
|
|
|
|
function base64ToBytes (str) {
|
|
return base64.toByteArray(base64clean(str))
|
|
}
|
|
|
|
function blitBuffer (src, dst, offset, length) {
|
|
for (var i = 0; i < length; ++i) {
|
|
if ((i + offset >= dst.length) || (i >= src.length)) break
|
|
dst[i + offset] = src[i]
|
|
}
|
|
return i
|
|
}
|
|
|
|
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
|
|
// the `instanceof` check but they should be treated as of that type.
|
|
// See: https://github.com/feross/buffer/issues/166
|
|
function isInstance (obj, type) {
|
|
return obj instanceof type ||
|
|
(obj != null && obj.constructor != null && obj.constructor.name != null &&
|
|
obj.constructor.name === type.name)
|
|
}
|
|
function numberIsNaN (obj) {
|
|
// For IE11 support
|
|
return obj !== obj // eslint-disable-line no-self-compare
|
|
}
|
|
|
|
// Create lookup table for `toString('hex')`
|
|
// See: https://github.com/feross/buffer/issues/219
|
|
var hexSliceLookupTable = (function () {
|
|
var alphabet = '0123456789abcdef'
|
|
var table = new Array(256)
|
|
for (var i = 0; i < 16; ++i) {
|
|
var i16 = i * 16
|
|
for (var j = 0; j < 16; ++j) {
|
|
table[i16 + j] = alphabet[i] + alphabet[j]
|
|
}
|
|
}
|
|
return table
|
|
})()
|
|
|
|
}).call(this,require("buffer").Buffer)
|
|
},{"base64-js":98,"buffer":100,"ieee754":103}],101:[function(require,module,exports){
|
|
(function (Buffer){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
// NOTE: These type checking functions intentionally don't use `instanceof`
|
|
// because it is fragile and can be easily faked with `Object.create()`.
|
|
|
|
function isArray(arg) {
|
|
if (Array.isArray) {
|
|
return Array.isArray(arg);
|
|
}
|
|
return objectToString(arg) === '[object Array]';
|
|
}
|
|
exports.isArray = isArray;
|
|
|
|
function isBoolean(arg) {
|
|
return typeof arg === 'boolean';
|
|
}
|
|
exports.isBoolean = isBoolean;
|
|
|
|
function isNull(arg) {
|
|
return arg === null;
|
|
}
|
|
exports.isNull = isNull;
|
|
|
|
function isNullOrUndefined(arg) {
|
|
return arg == null;
|
|
}
|
|
exports.isNullOrUndefined = isNullOrUndefined;
|
|
|
|
function isNumber(arg) {
|
|
return typeof arg === 'number';
|
|
}
|
|
exports.isNumber = isNumber;
|
|
|
|
function isString(arg) {
|
|
return typeof arg === 'string';
|
|
}
|
|
exports.isString = isString;
|
|
|
|
function isSymbol(arg) {
|
|
return typeof arg === 'symbol';
|
|
}
|
|
exports.isSymbol = isSymbol;
|
|
|
|
function isUndefined(arg) {
|
|
return arg === void 0;
|
|
}
|
|
exports.isUndefined = isUndefined;
|
|
|
|
function isRegExp(re) {
|
|
return objectToString(re) === '[object RegExp]';
|
|
}
|
|
exports.isRegExp = isRegExp;
|
|
|
|
function isObject(arg) {
|
|
return typeof arg === 'object' && arg !== null;
|
|
}
|
|
exports.isObject = isObject;
|
|
|
|
function isDate(d) {
|
|
return objectToString(d) === '[object Date]';
|
|
}
|
|
exports.isDate = isDate;
|
|
|
|
function isError(e) {
|
|
return (objectToString(e) === '[object Error]' || e instanceof Error);
|
|
}
|
|
exports.isError = isError;
|
|
|
|
function isFunction(arg) {
|
|
return typeof arg === 'function';
|
|
}
|
|
exports.isFunction = isFunction;
|
|
|
|
function isPrimitive(arg) {
|
|
return arg === null ||
|
|
typeof arg === 'boolean' ||
|
|
typeof arg === 'number' ||
|
|
typeof arg === 'string' ||
|
|
typeof arg === 'symbol' || // ES6 symbol
|
|
typeof arg === 'undefined';
|
|
}
|
|
exports.isPrimitive = isPrimitive;
|
|
|
|
exports.isBuffer = Buffer.isBuffer;
|
|
|
|
function objectToString(o) {
|
|
return Object.prototype.toString.call(o);
|
|
}
|
|
|
|
}).call(this,{"isBuffer":require("../../is-buffer/index.js")})
|
|
},{"../../is-buffer/index.js":105}],102:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
var objectCreate = Object.create || objectCreatePolyfill
|
|
var objectKeys = Object.keys || objectKeysPolyfill
|
|
var bind = Function.prototype.bind || functionBindPolyfill
|
|
|
|
function EventEmitter() {
|
|
if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
|
|
this._events = objectCreate(null);
|
|
this._eventsCount = 0;
|
|
}
|
|
|
|
this._maxListeners = this._maxListeners || undefined;
|
|
}
|
|
module.exports = EventEmitter;
|
|
|
|
// Backwards-compat with node 0.10.x
|
|
EventEmitter.EventEmitter = EventEmitter;
|
|
|
|
EventEmitter.prototype._events = undefined;
|
|
EventEmitter.prototype._maxListeners = undefined;
|
|
|
|
// By default EventEmitters will print a warning if more than 10 listeners are
|
|
// added to it. This is a useful default which helps finding memory leaks.
|
|
var defaultMaxListeners = 10;
|
|
|
|
var hasDefineProperty;
|
|
try {
|
|
var o = {};
|
|
if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
|
|
hasDefineProperty = o.x === 0;
|
|
} catch (err) { hasDefineProperty = false }
|
|
if (hasDefineProperty) {
|
|
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
|
enumerable: true,
|
|
get: function() {
|
|
return defaultMaxListeners;
|
|
},
|
|
set: function(arg) {
|
|
// check whether the input is a positive number (whose value is zero or
|
|
// greater and not a NaN).
|
|
if (typeof arg !== 'number' || arg < 0 || arg !== arg)
|
|
throw new TypeError('"defaultMaxListeners" must be a positive number');
|
|
defaultMaxListeners = arg;
|
|
}
|
|
});
|
|
} else {
|
|
EventEmitter.defaultMaxListeners = defaultMaxListeners;
|
|
}
|
|
|
|
// Obviously not all Emitters should be limited to 10. This function allows
|
|
// that to be increased. Set to zero for unlimited.
|
|
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
|
if (typeof n !== 'number' || n < 0 || isNaN(n))
|
|
throw new TypeError('"n" argument must be a positive number');
|
|
this._maxListeners = n;
|
|
return this;
|
|
};
|
|
|
|
function $getMaxListeners(that) {
|
|
if (that._maxListeners === undefined)
|
|
return EventEmitter.defaultMaxListeners;
|
|
return that._maxListeners;
|
|
}
|
|
|
|
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
|
return $getMaxListeners(this);
|
|
};
|
|
|
|
// These standalone emit* functions are used to optimize calling of event
|
|
// handlers for fast cases because emit() itself often has a variable number of
|
|
// arguments and can be deoptimized because of that. These functions always have
|
|
// the same number of arguments and thus do not get deoptimized, so the code
|
|
// inside them can execute faster.
|
|
function emitNone(handler, isFn, self) {
|
|
if (isFn)
|
|
handler.call(self);
|
|
else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
listeners[i].call(self);
|
|
}
|
|
}
|
|
function emitOne(handler, isFn, self, arg1) {
|
|
if (isFn)
|
|
handler.call(self, arg1);
|
|
else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
listeners[i].call(self, arg1);
|
|
}
|
|
}
|
|
function emitTwo(handler, isFn, self, arg1, arg2) {
|
|
if (isFn)
|
|
handler.call(self, arg1, arg2);
|
|
else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
listeners[i].call(self, arg1, arg2);
|
|
}
|
|
}
|
|
function emitThree(handler, isFn, self, arg1, arg2, arg3) {
|
|
if (isFn)
|
|
handler.call(self, arg1, arg2, arg3);
|
|
else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
listeners[i].call(self, arg1, arg2, arg3);
|
|
}
|
|
}
|
|
|
|
function emitMany(handler, isFn, self, args) {
|
|
if (isFn)
|
|
handler.apply(self, args);
|
|
else {
|
|
var len = handler.length;
|
|
var listeners = arrayClone(handler, len);
|
|
for (var i = 0; i < len; ++i)
|
|
listeners[i].apply(self, args);
|
|
}
|
|
}
|
|
|
|
EventEmitter.prototype.emit = function emit(type) {
|
|
var er, handler, len, args, i, events;
|
|
var doError = (type === 'error');
|
|
|
|
events = this._events;
|
|
if (events)
|
|
doError = (doError && events.error == null);
|
|
else if (!doError)
|
|
return false;
|
|
|
|
// If there is no 'error' event listener then throw.
|
|
if (doError) {
|
|
if (arguments.length > 1)
|
|
er = arguments[1];
|
|
if (er instanceof Error) {
|
|
throw er; // Unhandled 'error' event
|
|
} else {
|
|
// At least give some kind of context to the user
|
|
var err = new Error('Unhandled "error" event. (' + er + ')');
|
|
err.context = er;
|
|
throw err;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
handler = events[type];
|
|
|
|
if (!handler)
|
|
return false;
|
|
|
|
var isFn = typeof handler === 'function';
|
|
len = arguments.length;
|
|
switch (len) {
|
|
// fast cases
|
|
case 1:
|
|
emitNone(handler, isFn, this);
|
|
break;
|
|
case 2:
|
|
emitOne(handler, isFn, this, arguments[1]);
|
|
break;
|
|
case 3:
|
|
emitTwo(handler, isFn, this, arguments[1], arguments[2]);
|
|
break;
|
|
case 4:
|
|
emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
|
|
break;
|
|
// slower
|
|
default:
|
|
args = new Array(len - 1);
|
|
for (i = 1; i < len; i++)
|
|
args[i - 1] = arguments[i];
|
|
emitMany(handler, isFn, this, args);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
function _addListener(target, type, listener, prepend) {
|
|
var m;
|
|
var events;
|
|
var existing;
|
|
|
|
if (typeof listener !== 'function')
|
|
throw new TypeError('"listener" argument must be a function');
|
|
|
|
events = target._events;
|
|
if (!events) {
|
|
events = target._events = objectCreate(null);
|
|
target._eventsCount = 0;
|
|
} else {
|
|
// To avoid recursion in the case that type === "newListener"! Before
|
|
// adding it to the listeners, first emit "newListener".
|
|
if (events.newListener) {
|
|
target.emit('newListener', type,
|
|
listener.listener ? listener.listener : listener);
|
|
|
|
// Re-assign `events` because a newListener handler could have caused the
|
|
// this._events to be assigned to a new object
|
|
events = target._events;
|
|
}
|
|
existing = events[type];
|
|
}
|
|
|
|
if (!existing) {
|
|
// Optimize the case of one listener. Don't need the extra array object.
|
|
existing = events[type] = listener;
|
|
++target._eventsCount;
|
|
} else {
|
|
if (typeof existing === 'function') {
|
|
// Adding the second element, need to change to array.
|
|
existing = events[type] =
|
|
prepend ? [listener, existing] : [existing, listener];
|
|
} else {
|
|
// If we've already got an array, just append.
|
|
if (prepend) {
|
|
existing.unshift(listener);
|
|
} else {
|
|
existing.push(listener);
|
|
}
|
|
}
|
|
|
|
// Check for listener leak
|
|
if (!existing.warned) {
|
|
m = $getMaxListeners(target);
|
|
if (m && m > 0 && existing.length > m) {
|
|
existing.warned = true;
|
|
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
|
existing.length + ' "' + String(type) + '" listeners ' +
|
|
'added. Use emitter.setMaxListeners() to ' +
|
|
'increase limit.');
|
|
w.name = 'MaxListenersExceededWarning';
|
|
w.emitter = target;
|
|
w.type = type;
|
|
w.count = existing.length;
|
|
if (typeof console === 'object' && console.warn) {
|
|
console.warn('%s: %s', w.name, w.message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
|
return _addListener(this, type, listener, false);
|
|
};
|
|
|
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
|
|
EventEmitter.prototype.prependListener =
|
|
function prependListener(type, listener) {
|
|
return _addListener(this, type, listener, true);
|
|
};
|
|
|
|
function onceWrapper() {
|
|
if (!this.fired) {
|
|
this.target.removeListener(this.type, this.wrapFn);
|
|
this.fired = true;
|
|
switch (arguments.length) {
|
|
case 0:
|
|
return this.listener.call(this.target);
|
|
case 1:
|
|
return this.listener.call(this.target, arguments[0]);
|
|
case 2:
|
|
return this.listener.call(this.target, arguments[0], arguments[1]);
|
|
case 3:
|
|
return this.listener.call(this.target, arguments[0], arguments[1],
|
|
arguments[2]);
|
|
default:
|
|
var args = new Array(arguments.length);
|
|
for (var i = 0; i < args.length; ++i)
|
|
args[i] = arguments[i];
|
|
this.listener.apply(this.target, args);
|
|
}
|
|
}
|
|
}
|
|
|
|
function _onceWrap(target, type, listener) {
|
|
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
|
var wrapped = bind.call(onceWrapper, state);
|
|
wrapped.listener = listener;
|
|
state.wrapFn = wrapped;
|
|
return wrapped;
|
|
}
|
|
|
|
EventEmitter.prototype.once = function once(type, listener) {
|
|
if (typeof listener !== 'function')
|
|
throw new TypeError('"listener" argument must be a function');
|
|
this.on(type, _onceWrap(this, type, listener));
|
|
return this;
|
|
};
|
|
|
|
EventEmitter.prototype.prependOnceListener =
|
|
function prependOnceListener(type, listener) {
|
|
if (typeof listener !== 'function')
|
|
throw new TypeError('"listener" argument must be a function');
|
|
this.prependListener(type, _onceWrap(this, type, listener));
|
|
return this;
|
|
};
|
|
|
|
// Emits a 'removeListener' event if and only if the listener was removed.
|
|
EventEmitter.prototype.removeListener =
|
|
function removeListener(type, listener) {
|
|
var list, events, position, i, originalListener;
|
|
|
|
if (typeof listener !== 'function')
|
|
throw new TypeError('"listener" argument must be a function');
|
|
|
|
events = this._events;
|
|
if (!events)
|
|
return this;
|
|
|
|
list = events[type];
|
|
if (!list)
|
|
return this;
|
|
|
|
if (list === listener || list.listener === listener) {
|
|
if (--this._eventsCount === 0)
|
|
this._events = objectCreate(null);
|
|
else {
|
|
delete events[type];
|
|
if (events.removeListener)
|
|
this.emit('removeListener', type, list.listener || listener);
|
|
}
|
|
} else if (typeof list !== 'function') {
|
|
position = -1;
|
|
|
|
for (i = list.length - 1; i >= 0; i--) {
|
|
if (list[i] === listener || list[i].listener === listener) {
|
|
originalListener = list[i].listener;
|
|
position = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (position < 0)
|
|
return this;
|
|
|
|
if (position === 0)
|
|
list.shift();
|
|
else
|
|
spliceOne(list, position);
|
|
|
|
if (list.length === 1)
|
|
events[type] = list[0];
|
|
|
|
if (events.removeListener)
|
|
this.emit('removeListener', type, originalListener || listener);
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
EventEmitter.prototype.removeAllListeners =
|
|
function removeAllListeners(type) {
|
|
var listeners, events, i;
|
|
|
|
events = this._events;
|
|
if (!events)
|
|
return this;
|
|
|
|
// not listening for removeListener, no need to emit
|
|
if (!events.removeListener) {
|
|
if (arguments.length === 0) {
|
|
this._events = objectCreate(null);
|
|
this._eventsCount = 0;
|
|
} else if (events[type]) {
|
|
if (--this._eventsCount === 0)
|
|
this._events = objectCreate(null);
|
|
else
|
|
delete events[type];
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// emit removeListener for all listeners on all events
|
|
if (arguments.length === 0) {
|
|
var keys = objectKeys(events);
|
|
var key;
|
|
for (i = 0; i < keys.length; ++i) {
|
|
key = keys[i];
|
|
if (key === 'removeListener') continue;
|
|
this.removeAllListeners(key);
|
|
}
|
|
this.removeAllListeners('removeListener');
|
|
this._events = objectCreate(null);
|
|
this._eventsCount = 0;
|
|
return this;
|
|
}
|
|
|
|
listeners = events[type];
|
|
|
|
if (typeof listeners === 'function') {
|
|
this.removeListener(type, listeners);
|
|
} else if (listeners) {
|
|
// LIFO order
|
|
for (i = listeners.length - 1; i >= 0; i--) {
|
|
this.removeListener(type, listeners[i]);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
function _listeners(target, type, unwrap) {
|
|
var events = target._events;
|
|
|
|
if (!events)
|
|
return [];
|
|
|
|
var evlistener = events[type];
|
|
if (!evlistener)
|
|
return [];
|
|
|
|
if (typeof evlistener === 'function')
|
|
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
|
|
|
return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
|
}
|
|
|
|
EventEmitter.prototype.listeners = function listeners(type) {
|
|
return _listeners(this, type, true);
|
|
};
|
|
|
|
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
|
return _listeners(this, type, false);
|
|
};
|
|
|
|
EventEmitter.listenerCount = function(emitter, type) {
|
|
if (typeof emitter.listenerCount === 'function') {
|
|
return emitter.listenerCount(type);
|
|
} else {
|
|
return listenerCount.call(emitter, type);
|
|
}
|
|
};
|
|
|
|
EventEmitter.prototype.listenerCount = listenerCount;
|
|
function listenerCount(type) {
|
|
var events = this._events;
|
|
|
|
if (events) {
|
|
var evlistener = events[type];
|
|
|
|
if (typeof evlistener === 'function') {
|
|
return 1;
|
|
} else if (evlistener) {
|
|
return evlistener.length;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
EventEmitter.prototype.eventNames = function eventNames() {
|
|
return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
|
|
};
|
|
|
|
// About 1.5x faster than the two-arg version of Array#splice().
|
|
function spliceOne(list, index) {
|
|
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
|
|
list[i] = list[k];
|
|
list.pop();
|
|
}
|
|
|
|
function arrayClone(arr, n) {
|
|
var copy = new Array(n);
|
|
for (var i = 0; i < n; ++i)
|
|
copy[i] = arr[i];
|
|
return copy;
|
|
}
|
|
|
|
function unwrapListeners(arr) {
|
|
var ret = new Array(arr.length);
|
|
for (var i = 0; i < ret.length; ++i) {
|
|
ret[i] = arr[i].listener || arr[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function objectCreatePolyfill(proto) {
|
|
var F = function() {};
|
|
F.prototype = proto;
|
|
return new F;
|
|
}
|
|
function objectKeysPolyfill(obj) {
|
|
var keys = [];
|
|
for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
|
|
keys.push(k);
|
|
}
|
|
return k;
|
|
}
|
|
function functionBindPolyfill(context) {
|
|
var fn = this;
|
|
return function () {
|
|
return fn.apply(context, arguments);
|
|
};
|
|
}
|
|
|
|
},{}],103:[function(require,module,exports){
|
|
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
|
|
var e, m
|
|
var eLen = (nBytes * 8) - mLen - 1
|
|
var eMax = (1 << eLen) - 1
|
|
var eBias = eMax >> 1
|
|
var nBits = -7
|
|
var i = isLE ? (nBytes - 1) : 0
|
|
var d = isLE ? -1 : 1
|
|
var s = buffer[offset + i]
|
|
|
|
i += d
|
|
|
|
e = s & ((1 << (-nBits)) - 1)
|
|
s >>= (-nBits)
|
|
nBits += eLen
|
|
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
|
|
|
m = e & ((1 << (-nBits)) - 1)
|
|
e >>= (-nBits)
|
|
nBits += mLen
|
|
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
|
|
|
if (e === 0) {
|
|
e = 1 - eBias
|
|
} else if (e === eMax) {
|
|
return m ? NaN : ((s ? -1 : 1) * Infinity)
|
|
} else {
|
|
m = m + Math.pow(2, mLen)
|
|
e = e - eBias
|
|
}
|
|
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
|
|
}
|
|
|
|
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
|
var e, m, c
|
|
var eLen = (nBytes * 8) - mLen - 1
|
|
var eMax = (1 << eLen) - 1
|
|
var eBias = eMax >> 1
|
|
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
|
|
var i = isLE ? 0 : (nBytes - 1)
|
|
var d = isLE ? 1 : -1
|
|
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
|
|
|
|
value = Math.abs(value)
|
|
|
|
if (isNaN(value) || value === Infinity) {
|
|
m = isNaN(value) ? 1 : 0
|
|
e = eMax
|
|
} else {
|
|
e = Math.floor(Math.log(value) / Math.LN2)
|
|
if (value * (c = Math.pow(2, -e)) < 1) {
|
|
e--
|
|
c *= 2
|
|
}
|
|
if (e + eBias >= 1) {
|
|
value += rt / c
|
|
} else {
|
|
value += rt * Math.pow(2, 1 - eBias)
|
|
}
|
|
if (value * c >= 2) {
|
|
e++
|
|
c /= 2
|
|
}
|
|
|
|
if (e + eBias >= eMax) {
|
|
m = 0
|
|
e = eMax
|
|
} else if (e + eBias >= 1) {
|
|
m = ((value * c) - 1) * Math.pow(2, mLen)
|
|
e = e + eBias
|
|
} else {
|
|
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
|
|
e = 0
|
|
}
|
|
}
|
|
|
|
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
|
|
|
|
e = (e << mLen) | m
|
|
eLen += mLen
|
|
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
|
|
|
|
buffer[offset + i - d] |= s * 128
|
|
}
|
|
|
|
},{}],104:[function(require,module,exports){
|
|
arguments[4][38][0].apply(exports,arguments)
|
|
},{"dup":38}],105:[function(require,module,exports){
|
|
/*!
|
|
* Determine if an object is a Buffer
|
|
*
|
|
* @author Feross Aboukhadijeh <https://feross.org>
|
|
* @license MIT
|
|
*/
|
|
|
|
// The _isBuffer check is for Safari 5-7 support, because it's missing
|
|
// Object.prototype.constructor. Remove this eventually
|
|
module.exports = function (obj) {
|
|
return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
|
|
}
|
|
|
|
function isBuffer (obj) {
|
|
return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
|
|
}
|
|
|
|
// For Node v0.10 support. Remove this eventually.
|
|
function isSlowBuffer (obj) {
|
|
return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
|
|
}
|
|
|
|
},{}],106:[function(require,module,exports){
|
|
var toString = {}.toString;
|
|
|
|
module.exports = Array.isArray || function (arr) {
|
|
return toString.call(arr) == '[object Array]';
|
|
};
|
|
|
|
},{}],107:[function(require,module,exports){
|
|
/*
|
|
object-assign
|
|
(c) Sindre Sorhus
|
|
@license MIT
|
|
*/
|
|
|
|
'use strict';
|
|
/* eslint-disable no-unused-vars */
|
|
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
|
|
function toObject(val) {
|
|
if (val === null || val === undefined) {
|
|
throw new TypeError('Object.assign cannot be called with null or undefined');
|
|
}
|
|
|
|
return Object(val);
|
|
}
|
|
|
|
function shouldUseNative() {
|
|
try {
|
|
if (!Object.assign) {
|
|
return false;
|
|
}
|
|
|
|
// Detect buggy property enumeration order in older V8 versions.
|
|
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=4118
|
|
var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
|
|
test1[5] = 'de';
|
|
if (Object.getOwnPropertyNames(test1)[0] === '5') {
|
|
return false;
|
|
}
|
|
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
|
|
var test2 = {};
|
|
for (var i = 0; i < 10; i++) {
|
|
test2['_' + String.fromCharCode(i)] = i;
|
|
}
|
|
var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
|
|
return test2[n];
|
|
});
|
|
if (order2.join('') !== '0123456789') {
|
|
return false;
|
|
}
|
|
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
|
|
var test3 = {};
|
|
'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
|
|
test3[letter] = letter;
|
|
});
|
|
if (Object.keys(Object.assign({}, test3)).join('') !==
|
|
'abcdefghijklmnopqrst') {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
} catch (err) {
|
|
// We don't expect any of the above to throw, but better to be safe.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
module.exports = shouldUseNative() ? Object.assign : function (target, source) {
|
|
var from;
|
|
var to = toObject(target);
|
|
var symbols;
|
|
|
|
for (var s = 1; s < arguments.length; s++) {
|
|
from = Object(arguments[s]);
|
|
|
|
for (var key in from) {
|
|
if (hasOwnProperty.call(from, key)) {
|
|
to[key] = from[key];
|
|
}
|
|
}
|
|
|
|
if (getOwnPropertySymbols) {
|
|
symbols = getOwnPropertySymbols(from);
|
|
for (var i = 0; i < symbols.length; i++) {
|
|
if (propIsEnumerable.call(from, symbols[i])) {
|
|
to[symbols[i]] = from[symbols[i]];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return to;
|
|
};
|
|
|
|
},{}],108:[function(require,module,exports){
|
|
(function (process){
|
|
'use strict';
|
|
|
|
if (typeof process === 'undefined' ||
|
|
!process.version ||
|
|
process.version.indexOf('v0.') === 0 ||
|
|
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
|
|
module.exports = { nextTick: nextTick };
|
|
} else {
|
|
module.exports = process
|
|
}
|
|
|
|
function nextTick(fn, arg1, arg2, arg3) {
|
|
if (typeof fn !== 'function') {
|
|
throw new TypeError('"callback" argument must be a function');
|
|
}
|
|
var len = arguments.length;
|
|
var args, i;
|
|
switch (len) {
|
|
case 0:
|
|
case 1:
|
|
return process.nextTick(fn);
|
|
case 2:
|
|
return process.nextTick(function afterTickOne() {
|
|
fn.call(null, arg1);
|
|
});
|
|
case 3:
|
|
return process.nextTick(function afterTickTwo() {
|
|
fn.call(null, arg1, arg2);
|
|
});
|
|
case 4:
|
|
return process.nextTick(function afterTickThree() {
|
|
fn.call(null, arg1, arg2, arg3);
|
|
});
|
|
default:
|
|
args = new Array(len - 1);
|
|
i = 0;
|
|
while (i < args.length) {
|
|
args[i++] = arguments[i];
|
|
}
|
|
return process.nextTick(function afterTick() {
|
|
fn.apply(null, args);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
}).call(this,require('_process'))
|
|
},{"_process":109}],109:[function(require,module,exports){
|
|
// shim for using process in browser
|
|
var process = module.exports = {};
|
|
|
|
// cached from whatever global is present so that test runners that stub it
|
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
// function because try/catches deoptimize in certain engines.
|
|
|
|
var cachedSetTimeout;
|
|
var cachedClearTimeout;
|
|
|
|
function defaultSetTimout() {
|
|
throw new Error('setTimeout has not been defined');
|
|
}
|
|
function defaultClearTimeout () {
|
|
throw new Error('clearTimeout has not been defined');
|
|
}
|
|
(function () {
|
|
try {
|
|
if (typeof setTimeout === 'function') {
|
|
cachedSetTimeout = setTimeout;
|
|
} else {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
} catch (e) {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
try {
|
|
if (typeof clearTimeout === 'function') {
|
|
cachedClearTimeout = clearTimeout;
|
|
} else {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} catch (e) {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} ())
|
|
function runTimeout(fun) {
|
|
if (cachedSetTimeout === setTimeout) {
|
|
//normal enviroments in sane situations
|
|
return setTimeout(fun, 0);
|
|
}
|
|
// if setTimeout wasn't available but was latter defined
|
|
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
cachedSetTimeout = setTimeout;
|
|
return setTimeout(fun, 0);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedSetTimeout(fun, 0);
|
|
} catch(e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedSetTimeout.call(null, fun, 0);
|
|
} catch(e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|
return cachedSetTimeout.call(this, fun, 0);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
function runClearTimeout(marker) {
|
|
if (cachedClearTimeout === clearTimeout) {
|
|
//normal enviroments in sane situations
|
|
return clearTimeout(marker);
|
|
}
|
|
// if clearTimeout wasn't available but was latter defined
|
|
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
cachedClearTimeout = clearTimeout;
|
|
return clearTimeout(marker);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedClearTimeout(marker);
|
|
} catch (e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedClearTimeout.call(null, marker);
|
|
} catch (e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
return cachedClearTimeout.call(this, marker);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
var queue = [];
|
|
var draining = false;
|
|
var currentQueue;
|
|
var queueIndex = -1;
|
|
|
|
function cleanUpNextTick() {
|
|
if (!draining || !currentQueue) {
|
|
return;
|
|
}
|
|
draining = false;
|
|
if (currentQueue.length) {
|
|
queue = currentQueue.concat(queue);
|
|
} else {
|
|
queueIndex = -1;
|
|
}
|
|
if (queue.length) {
|
|
drainQueue();
|
|
}
|
|
}
|
|
|
|
function drainQueue() {
|
|
if (draining) {
|
|
return;
|
|
}
|
|
var timeout = runTimeout(cleanUpNextTick);
|
|
draining = true;
|
|
|
|
var len = queue.length;
|
|
while(len) {
|
|
currentQueue = queue;
|
|
queue = [];
|
|
while (++queueIndex < len) {
|
|
if (currentQueue) {
|
|
currentQueue[queueIndex].run();
|
|
}
|
|
}
|
|
queueIndex = -1;
|
|
len = queue.length;
|
|
}
|
|
currentQueue = null;
|
|
draining = false;
|
|
runClearTimeout(timeout);
|
|
}
|
|
|
|
process.nextTick = function (fun) {
|
|
var args = new Array(arguments.length - 1);
|
|
if (arguments.length > 1) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
}
|
|
queue.push(new Item(fun, args));
|
|
if (queue.length === 1 && !draining) {
|
|
runTimeout(drainQueue);
|
|
}
|
|
};
|
|
|
|
// v8 likes predictible objects
|
|
function Item(fun, array) {
|
|
this.fun = fun;
|
|
this.array = array;
|
|
}
|
|
Item.prototype.run = function () {
|
|
this.fun.apply(null, this.array);
|
|
};
|
|
process.title = 'browser';
|
|
process.browser = true;
|
|
process.env = {};
|
|
process.argv = [];
|
|
process.version = ''; // empty string to avoid regexp issues
|
|
process.versions = {};
|
|
|
|
function noop() {}
|
|
|
|
process.on = noop;
|
|
process.addListener = noop;
|
|
process.once = noop;
|
|
process.off = noop;
|
|
process.removeListener = noop;
|
|
process.removeAllListeners = noop;
|
|
process.emit = noop;
|
|
process.prependListener = noop;
|
|
process.prependOnceListener = noop;
|
|
|
|
process.listeners = function (name) { return [] }
|
|
|
|
process.binding = function (name) {
|
|
throw new Error('process.binding is not supported');
|
|
};
|
|
|
|
process.cwd = function () { return '/' };
|
|
process.chdir = function (dir) {
|
|
throw new Error('process.chdir is not supported');
|
|
};
|
|
process.umask = function() { return 0; };
|
|
|
|
},{}],110:[function(require,module,exports){
|
|
module.exports = require('./lib/_stream_duplex.js');
|
|
|
|
},{"./lib/_stream_duplex.js":111}],111:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
// a duplex stream is just a stream that is both readable and writable.
|
|
// Since JS doesn't have multiple prototypal inheritance, this class
|
|
// prototypally inherits from Readable, and then parasitically from
|
|
// Writable.
|
|
|
|
'use strict';
|
|
|
|
/*<replacement>*/
|
|
|
|
var pna = require('process-nextick-args');
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var objectKeys = Object.keys || function (obj) {
|
|
var keys = [];
|
|
for (var key in obj) {
|
|
keys.push(key);
|
|
}return keys;
|
|
};
|
|
/*</replacement>*/
|
|
|
|
module.exports = Duplex;
|
|
|
|
/*<replacement>*/
|
|
var util = Object.create(require('core-util-is'));
|
|
util.inherits = require('inherits');
|
|
/*</replacement>*/
|
|
|
|
var Readable = require('./_stream_readable');
|
|
var Writable = require('./_stream_writable');
|
|
|
|
util.inherits(Duplex, Readable);
|
|
|
|
{
|
|
// avoid scope creep, the keys array can then be collected
|
|
var keys = objectKeys(Writable.prototype);
|
|
for (var v = 0; v < keys.length; v++) {
|
|
var method = keys[v];
|
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
}
|
|
}
|
|
|
|
function Duplex(options) {
|
|
if (!(this instanceof Duplex)) return new Duplex(options);
|
|
|
|
Readable.call(this, options);
|
|
Writable.call(this, options);
|
|
|
|
if (options && options.readable === false) this.readable = false;
|
|
|
|
if (options && options.writable === false) this.writable = false;
|
|
|
|
this.allowHalfOpen = true;
|
|
if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
|
|
|
|
this.once('end', onend);
|
|
}
|
|
|
|
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function () {
|
|
return this._writableState.highWaterMark;
|
|
}
|
|
});
|
|
|
|
// the no-half-open enforcer
|
|
function onend() {
|
|
// if we allow half-open state, or if the writable side ended,
|
|
// then we're ok.
|
|
if (this.allowHalfOpen || this._writableState.ended) return;
|
|
|
|
// no more data can be written.
|
|
// But allow more writes to happen in this tick.
|
|
pna.nextTick(onEndNT, this);
|
|
}
|
|
|
|
function onEndNT(self) {
|
|
self.end();
|
|
}
|
|
|
|
Object.defineProperty(Duplex.prototype, 'destroyed', {
|
|
get: function () {
|
|
if (this._readableState === undefined || this._writableState === undefined) {
|
|
return false;
|
|
}
|
|
return this._readableState.destroyed && this._writableState.destroyed;
|
|
},
|
|
set: function (value) {
|
|
// we ignore the value if the stream
|
|
// has not been initialized yet
|
|
if (this._readableState === undefined || this._writableState === undefined) {
|
|
return;
|
|
}
|
|
|
|
// backward compatibility, the user is explicitly
|
|
// managing destroyed
|
|
this._readableState.destroyed = value;
|
|
this._writableState.destroyed = value;
|
|
}
|
|
});
|
|
|
|
Duplex.prototype._destroy = function (err, cb) {
|
|
this.push(null);
|
|
this.end();
|
|
|
|
pna.nextTick(cb, err);
|
|
};
|
|
},{"./_stream_readable":113,"./_stream_writable":115,"core-util-is":101,"inherits":104,"process-nextick-args":108}],112:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
// a passthrough stream.
|
|
// basically just the most minimal sort of Transform stream.
|
|
// Every written chunk gets output as-is.
|
|
|
|
'use strict';
|
|
|
|
module.exports = PassThrough;
|
|
|
|
var Transform = require('./_stream_transform');
|
|
|
|
/*<replacement>*/
|
|
var util = Object.create(require('core-util-is'));
|
|
util.inherits = require('inherits');
|
|
/*</replacement>*/
|
|
|
|
util.inherits(PassThrough, Transform);
|
|
|
|
function PassThrough(options) {
|
|
if (!(this instanceof PassThrough)) return new PassThrough(options);
|
|
|
|
Transform.call(this, options);
|
|
}
|
|
|
|
PassThrough.prototype._transform = function (chunk, encoding, cb) {
|
|
cb(null, chunk);
|
|
};
|
|
},{"./_stream_transform":114,"core-util-is":101,"inherits":104}],113:[function(require,module,exports){
|
|
(function (process,global){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
'use strict';
|
|
|
|
/*<replacement>*/
|
|
|
|
var pna = require('process-nextick-args');
|
|
/*</replacement>*/
|
|
|
|
module.exports = Readable;
|
|
|
|
/*<replacement>*/
|
|
var isArray = require('isarray');
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var Duplex;
|
|
/*</replacement>*/
|
|
|
|
Readable.ReadableState = ReadableState;
|
|
|
|
/*<replacement>*/
|
|
var EE = require('events').EventEmitter;
|
|
|
|
var EElistenerCount = function (emitter, type) {
|
|
return emitter.listeners(type).length;
|
|
};
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var Stream = require('./internal/streams/stream');
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
|
|
var Buffer = require('safe-buffer').Buffer;
|
|
var OurUint8Array = global.Uint8Array || function () {};
|
|
function _uint8ArrayToBuffer(chunk) {
|
|
return Buffer.from(chunk);
|
|
}
|
|
function _isUint8Array(obj) {
|
|
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
|
|
}
|
|
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var util = Object.create(require('core-util-is'));
|
|
util.inherits = require('inherits');
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var debugUtil = require('util');
|
|
var debug = void 0;
|
|
if (debugUtil && debugUtil.debuglog) {
|
|
debug = debugUtil.debuglog('stream');
|
|
} else {
|
|
debug = function () {};
|
|
}
|
|
/*</replacement>*/
|
|
|
|
var BufferList = require('./internal/streams/BufferList');
|
|
var destroyImpl = require('./internal/streams/destroy');
|
|
var StringDecoder;
|
|
|
|
util.inherits(Readable, Stream);
|
|
|
|
var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
|
|
|
|
function prependListener(emitter, event, fn) {
|
|
// Sadly this is not cacheable as some libraries bundle their own
|
|
// event emitter implementation with them.
|
|
if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
|
|
|
|
// This is a hack to make sure that our error handler is attached before any
|
|
// userland ones. NEVER DO THIS. This is here only because this code needs
|
|
// to continue to work with older versions of Node.js that do not include
|
|
// the prependListener() method. The goal is to eventually remove this hack.
|
|
if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
|
|
}
|
|
|
|
function ReadableState(options, stream) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
|
|
options = options || {};
|
|
|
|
// Duplex streams are both readable and writable, but share
|
|
// the same options object.
|
|
// However, some cases require setting options to different
|
|
// values for the readable and the writable sides of the duplex stream.
|
|
// These options can be provided separately as readableXXX and writableXXX.
|
|
var isDuplex = stream instanceof Duplex;
|
|
|
|
// object stream flag. Used to make read(n) ignore n and to
|
|
// make all the buffer merging and length checks go away
|
|
this.objectMode = !!options.objectMode;
|
|
|
|
if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
|
|
|
|
// the point at which it stops calling _read() to fill the buffer
|
|
// Note: 0 is a valid value, means "don't call _read preemptively ever"
|
|
var hwm = options.highWaterMark;
|
|
var readableHwm = options.readableHighWaterMark;
|
|
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
|
|
|
|
if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm;
|
|
|
|
// cast to ints.
|
|
this.highWaterMark = Math.floor(this.highWaterMark);
|
|
|
|
// A linked list is used to store data chunks instead of an array because the
|
|
// linked list can remove elements from the beginning faster than
|
|
// array.shift()
|
|
this.buffer = new BufferList();
|
|
this.length = 0;
|
|
this.pipes = null;
|
|
this.pipesCount = 0;
|
|
this.flowing = null;
|
|
this.ended = false;
|
|
this.endEmitted = false;
|
|
this.reading = false;
|
|
|
|
// a flag to be able to tell if the event 'readable'/'data' is emitted
|
|
// immediately, or on a later tick. We set this to true at first, because
|
|
// any actions that shouldn't happen until "later" should generally also
|
|
// not happen before the first read call.
|
|
this.sync = true;
|
|
|
|
// whenever we return null, then we set a flag to say
|
|
// that we're awaiting a 'readable' event emission.
|
|
this.needReadable = false;
|
|
this.emittedReadable = false;
|
|
this.readableListening = false;
|
|
this.resumeScheduled = false;
|
|
|
|
// has it been destroyed
|
|
this.destroyed = false;
|
|
|
|
// Crypto is kind of old and crusty. Historically, its default string
|
|
// encoding is 'binary' so we have to make this configurable.
|
|
// Everything else in the universe uses 'utf8', though.
|
|
this.defaultEncoding = options.defaultEncoding || 'utf8';
|
|
|
|
// the number of writers that are awaiting a drain event in .pipe()s
|
|
this.awaitDrain = 0;
|
|
|
|
// if true, a maybeReadMore has been scheduled
|
|
this.readingMore = false;
|
|
|
|
this.decoder = null;
|
|
this.encoding = null;
|
|
if (options.encoding) {
|
|
if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
|
|
this.decoder = new StringDecoder(options.encoding);
|
|
this.encoding = options.encoding;
|
|
}
|
|
}
|
|
|
|
function Readable(options) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
|
|
if (!(this instanceof Readable)) return new Readable(options);
|
|
|
|
this._readableState = new ReadableState(options, this);
|
|
|
|
// legacy
|
|
this.readable = true;
|
|
|
|
if (options) {
|
|
if (typeof options.read === 'function') this._read = options.read;
|
|
|
|
if (typeof options.destroy === 'function') this._destroy = options.destroy;
|
|
}
|
|
|
|
Stream.call(this);
|
|
}
|
|
|
|
Object.defineProperty(Readable.prototype, 'destroyed', {
|
|
get: function () {
|
|
if (this._readableState === undefined) {
|
|
return false;
|
|
}
|
|
return this._readableState.destroyed;
|
|
},
|
|
set: function (value) {
|
|
// we ignore the value if the stream
|
|
// has not been initialized yet
|
|
if (!this._readableState) {
|
|
return;
|
|
}
|
|
|
|
// backward compatibility, the user is explicitly
|
|
// managing destroyed
|
|
this._readableState.destroyed = value;
|
|
}
|
|
});
|
|
|
|
Readable.prototype.destroy = destroyImpl.destroy;
|
|
Readable.prototype._undestroy = destroyImpl.undestroy;
|
|
Readable.prototype._destroy = function (err, cb) {
|
|
this.push(null);
|
|
cb(err);
|
|
};
|
|
|
|
// Manually shove something into the read() buffer.
|
|
// This returns true if the highWaterMark has not been hit yet,
|
|
// similar to how Writable.write() returns true if you should
|
|
// write() some more.
|
|
Readable.prototype.push = function (chunk, encoding) {
|
|
var state = this._readableState;
|
|
var skipChunkCheck;
|
|
|
|
if (!state.objectMode) {
|
|
if (typeof chunk === 'string') {
|
|
encoding = encoding || state.defaultEncoding;
|
|
if (encoding !== state.encoding) {
|
|
chunk = Buffer.from(chunk, encoding);
|
|
encoding = '';
|
|
}
|
|
skipChunkCheck = true;
|
|
}
|
|
} else {
|
|
skipChunkCheck = true;
|
|
}
|
|
|
|
return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
|
|
};
|
|
|
|
// Unshift should *always* be something directly out of read()
|
|
Readable.prototype.unshift = function (chunk) {
|
|
return readableAddChunk(this, chunk, null, true, false);
|
|
};
|
|
|
|
function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
|
|
var state = stream._readableState;
|
|
if (chunk === null) {
|
|
state.reading = false;
|
|
onEofChunk(stream, state);
|
|
} else {
|
|
var er;
|
|
if (!skipChunkCheck) er = chunkInvalid(state, chunk);
|
|
if (er) {
|
|
stream.emit('error', er);
|
|
} else if (state.objectMode || chunk && chunk.length > 0) {
|
|
if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
|
|
chunk = _uint8ArrayToBuffer(chunk);
|
|
}
|
|
|
|
if (addToFront) {
|
|
if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
|
|
} else if (state.ended) {
|
|
stream.emit('error', new Error('stream.push() after EOF'));
|
|
} else {
|
|
state.reading = false;
|
|
if (state.decoder && !encoding) {
|
|
chunk = state.decoder.write(chunk);
|
|
if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
|
|
} else {
|
|
addChunk(stream, state, chunk, false);
|
|
}
|
|
}
|
|
} else if (!addToFront) {
|
|
state.reading = false;
|
|
}
|
|
}
|
|
|
|
return needMoreData(state);
|
|
}
|
|
|
|
function addChunk(stream, state, chunk, addToFront) {
|
|
if (state.flowing && state.length === 0 && !state.sync) {
|
|
stream.emit('data', chunk);
|
|
stream.read(0);
|
|
} else {
|
|
// update the buffer info.
|
|
state.length += state.objectMode ? 1 : chunk.length;
|
|
if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
|
|
|
|
if (state.needReadable) emitReadable(stream);
|
|
}
|
|
maybeReadMore(stream, state);
|
|
}
|
|
|
|
function chunkInvalid(state, chunk) {
|
|
var er;
|
|
if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
|
|
er = new TypeError('Invalid non-string/buffer chunk');
|
|
}
|
|
return er;
|
|
}
|
|
|
|
// if it's past the high water mark, we can push in some more.
|
|
// Also, if we have no data yet, we can stand some
|
|
// more bytes. This is to work around cases where hwm=0,
|
|
// such as the repl. Also, if the push() triggered a
|
|
// readable event, and the user called read(largeNumber) such that
|
|
// needReadable was set, then we ought to push more, so that another
|
|
// 'readable' event will be triggered.
|
|
function needMoreData(state) {
|
|
return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
|
|
}
|
|
|
|
Readable.prototype.isPaused = function () {
|
|
return this._readableState.flowing === false;
|
|
};
|
|
|
|
// backwards compatibility.
|
|
Readable.prototype.setEncoding = function (enc) {
|
|
if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
|
|
this._readableState.decoder = new StringDecoder(enc);
|
|
this._readableState.encoding = enc;
|
|
return this;
|
|
};
|
|
|
|
// Don't raise the hwm > 8MB
|
|
var MAX_HWM = 0x800000;
|
|
function computeNewHighWaterMark(n) {
|
|
if (n >= MAX_HWM) {
|
|
n = MAX_HWM;
|
|
} else {
|
|
// Get the next highest power of 2 to prevent increasing hwm excessively in
|
|
// tiny amounts
|
|
n--;
|
|
n |= n >>> 1;
|
|
n |= n >>> 2;
|
|
n |= n >>> 4;
|
|
n |= n >>> 8;
|
|
n |= n >>> 16;
|
|
n++;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
// This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
function howMuchToRead(n, state) {
|
|
if (n <= 0 || state.length === 0 && state.ended) return 0;
|
|
if (state.objectMode) return 1;
|
|
if (n !== n) {
|
|
// Only flow one buffer at a time
|
|
if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
|
|
}
|
|
// If we're asking for more than the current hwm, then raise the hwm.
|
|
if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
|
|
if (n <= state.length) return n;
|
|
// Don't have enough
|
|
if (!state.ended) {
|
|
state.needReadable = true;
|
|
return 0;
|
|
}
|
|
return state.length;
|
|
}
|
|
|
|
// you can override either this method, or the async _read(n) below.
|
|
Readable.prototype.read = function (n) {
|
|
debug('read', n);
|
|
n = parseInt(n, 10);
|
|
var state = this._readableState;
|
|
var nOrig = n;
|
|
|
|
if (n !== 0) state.emittedReadable = false;
|
|
|
|
// if we're doing read(0) to trigger a readable event, but we
|
|
// already have a bunch of data in the buffer, then just trigger
|
|
// the 'readable' event and move on.
|
|
if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
|
|
debug('read: emitReadable', state.length, state.ended);
|
|
if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
|
|
return null;
|
|
}
|
|
|
|
n = howMuchToRead(n, state);
|
|
|
|
// if we've ended, and we're now clear, then finish it up.
|
|
if (n === 0 && state.ended) {
|
|
if (state.length === 0) endReadable(this);
|
|
return null;
|
|
}
|
|
|
|
// All the actual chunk generation logic needs to be
|
|
// *below* the call to _read. The reason is that in certain
|
|
// synthetic stream cases, such as passthrough streams, _read
|
|
// may be a completely synchronous operation which may change
|
|
// the state of the read buffer, providing enough data when
|
|
// before there was *not* enough.
|
|
//
|
|
// So, the steps are:
|
|
// 1. Figure out what the state of things will be after we do
|
|
// a read from the buffer.
|
|
//
|
|
// 2. If that resulting state will trigger a _read, then call _read.
|
|
// Note that this may be asynchronous, or synchronous. Yes, it is
|
|
// deeply ugly to write APIs this way, but that still doesn't mean
|
|
// that the Readable class should behave improperly, as streams are
|
|
// designed to be sync/async agnostic.
|
|
// Take note if the _read call is sync or async (ie, if the read call
|
|
// has returned yet), so that we know whether or not it's safe to emit
|
|
// 'readable' etc.
|
|
//
|
|
// 3. Actually pull the requested chunks out of the buffer and return.
|
|
|
|
// if we need a readable event, then we need to do some reading.
|
|
var doRead = state.needReadable;
|
|
debug('need readable', doRead);
|
|
|
|
// if we currently have less than the highWaterMark, then also read some
|
|
if (state.length === 0 || state.length - n < state.highWaterMark) {
|
|
doRead = true;
|
|
debug('length less than watermark', doRead);
|
|
}
|
|
|
|
// however, if we've ended, then there's no point, and if we're already
|
|
// reading, then it's unnecessary.
|
|
if (state.ended || state.reading) {
|
|
doRead = false;
|
|
debug('reading or ended', doRead);
|
|
} else if (doRead) {
|
|
debug('do read');
|
|
state.reading = true;
|
|
state.sync = true;
|
|
// if the length is currently zero, then we *need* a readable event.
|
|
if (state.length === 0) state.needReadable = true;
|
|
// call internal read method
|
|
this._read(state.highWaterMark);
|
|
state.sync = false;
|
|
// If _read pushed data synchronously, then `reading` will be false,
|
|
// and we need to re-evaluate how much data we can return to the user.
|
|
if (!state.reading) n = howMuchToRead(nOrig, state);
|
|
}
|
|
|
|
var ret;
|
|
if (n > 0) ret = fromList(n, state);else ret = null;
|
|
|
|
if (ret === null) {
|
|
state.needReadable = true;
|
|
n = 0;
|
|
} else {
|
|
state.length -= n;
|
|
}
|
|
|
|
if (state.length === 0) {
|
|
// If we have nothing in the buffer, then we want to know
|
|
// as soon as we *do* get something into the buffer.
|
|
if (!state.ended) state.needReadable = true;
|
|
|
|
// If we tried to read() past the EOF, then emit end on the next tick.
|
|
if (nOrig !== n && state.ended) endReadable(this);
|
|
}
|
|
|
|
if (ret !== null) this.emit('data', ret);
|
|
|
|
return ret;
|
|
};
|
|
|
|
function onEofChunk(stream, state) {
|
|
if (state.ended) return;
|
|
if (state.decoder) {
|
|
var chunk = state.decoder.end();
|
|
if (chunk && chunk.length) {
|
|
state.buffer.push(chunk);
|
|
state.length += state.objectMode ? 1 : chunk.length;
|
|
}
|
|
}
|
|
state.ended = true;
|
|
|
|
// emit 'readable' now to make sure it gets picked up.
|
|
emitReadable(stream);
|
|
}
|
|
|
|
// Don't emit readable right away in sync mode, because this can trigger
|
|
// another read() call => stack overflow. This way, it might trigger
|
|
// a nextTick recursion warning, but that's not so bad.
|
|
function emitReadable(stream) {
|
|
var state = stream._readableState;
|
|
state.needReadable = false;
|
|
if (!state.emittedReadable) {
|
|
debug('emitReadable', state.flowing);
|
|
state.emittedReadable = true;
|
|
if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream);
|
|
}
|
|
}
|
|
|
|
function emitReadable_(stream) {
|
|
debug('emit readable');
|
|
stream.emit('readable');
|
|
flow(stream);
|
|
}
|
|
|
|
// at this point, the user has presumably seen the 'readable' event,
|
|
// and called read() to consume some data. that may have triggered
|
|
// in turn another _read(n) call, in which case reading = true if
|
|
// it's in progress.
|
|
// However, if we're not ended, or reading, and the length < hwm,
|
|
// then go ahead and try to read some more preemptively.
|
|
function maybeReadMore(stream, state) {
|
|
if (!state.readingMore) {
|
|
state.readingMore = true;
|
|
pna.nextTick(maybeReadMore_, stream, state);
|
|
}
|
|
}
|
|
|
|
function maybeReadMore_(stream, state) {
|
|
var len = state.length;
|
|
while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
|
|
debug('maybeReadMore read 0');
|
|
stream.read(0);
|
|
if (len === state.length)
|
|
// didn't get any data, stop spinning.
|
|
break;else len = state.length;
|
|
}
|
|
state.readingMore = false;
|
|
}
|
|
|
|
// abstract method. to be overridden in specific implementation classes.
|
|
// call cb(er, data) where data is <= n in length.
|
|
// for virtual (non-string, non-buffer) streams, "length" is somewhat
|
|
// arbitrary, and perhaps not very meaningful.
|
|
Readable.prototype._read = function (n) {
|
|
this.emit('error', new Error('_read() is not implemented'));
|
|
};
|
|
|
|
Readable.prototype.pipe = function (dest, pipeOpts) {
|
|
var src = this;
|
|
var state = this._readableState;
|
|
|
|
switch (state.pipesCount) {
|
|
case 0:
|
|
state.pipes = dest;
|
|
break;
|
|
case 1:
|
|
state.pipes = [state.pipes, dest];
|
|
break;
|
|
default:
|
|
state.pipes.push(dest);
|
|
break;
|
|
}
|
|
state.pipesCount += 1;
|
|
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
|
|
|
|
var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
|
|
|
|
var endFn = doEnd ? onend : unpipe;
|
|
if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn);
|
|
|
|
dest.on('unpipe', onunpipe);
|
|
function onunpipe(readable, unpipeInfo) {
|
|
debug('onunpipe');
|
|
if (readable === src) {
|
|
if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
|
|
unpipeInfo.hasUnpiped = true;
|
|
cleanup();
|
|
}
|
|
}
|
|
}
|
|
|
|
function onend() {
|
|
debug('onend');
|
|
dest.end();
|
|
}
|
|
|
|
// when the dest drains, it reduces the awaitDrain counter
|
|
// on the source. This would be more elegant with a .once()
|
|
// handler in flow(), but adding and removing repeatedly is
|
|
// too slow.
|
|
var ondrain = pipeOnDrain(src);
|
|
dest.on('drain', ondrain);
|
|
|
|
var cleanedUp = false;
|
|
function cleanup() {
|
|
debug('cleanup');
|
|
// cleanup event handlers once the pipe is broken
|
|
dest.removeListener('close', onclose);
|
|
dest.removeListener('finish', onfinish);
|
|
dest.removeListener('drain', ondrain);
|
|
dest.removeListener('error', onerror);
|
|
dest.removeListener('unpipe', onunpipe);
|
|
src.removeListener('end', onend);
|
|
src.removeListener('end', unpipe);
|
|
src.removeListener('data', ondata);
|
|
|
|
cleanedUp = true;
|
|
|
|
// if the reader is waiting for a drain event from this
|
|
// specific writer, then it would cause it to never start
|
|
// flowing again.
|
|
// So, if this is awaiting a drain, then we just call it now.
|
|
// If we don't know, then assume that we are waiting for one.
|
|
if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
|
|
}
|
|
|
|
// If the user pushes more data while we're writing to dest then we'll end up
|
|
// in ondata again. However, we only want to increase awaitDrain once because
|
|
// dest will only emit one 'drain' event for the multiple writes.
|
|
// => Introduce a guard on increasing awaitDrain.
|
|
var increasedAwaitDrain = false;
|
|
src.on('data', ondata);
|
|
function ondata(chunk) {
|
|
debug('ondata');
|
|
increasedAwaitDrain = false;
|
|
var ret = dest.write(chunk);
|
|
if (false === ret && !increasedAwaitDrain) {
|
|
// If the user unpiped during `dest.write()`, it is possible
|
|
// to get stuck in a permanently paused state if that write
|
|
// also returned false.
|
|
// => Check whether `dest` is still a piping destination.
|
|
if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
|
|
debug('false write response, pause', src._readableState.awaitDrain);
|
|
src._readableState.awaitDrain++;
|
|
increasedAwaitDrain = true;
|
|
}
|
|
src.pause();
|
|
}
|
|
}
|
|
|
|
// if the dest has an error, then stop piping into it.
|
|
// however, don't suppress the throwing behavior for this.
|
|
function onerror(er) {
|
|
debug('onerror', er);
|
|
unpipe();
|
|
dest.removeListener('error', onerror);
|
|
if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
|
|
}
|
|
|
|
// Make sure our error handler is attached before userland ones.
|
|
prependListener(dest, 'error', onerror);
|
|
|
|
// Both close and finish should trigger unpipe, but only once.
|
|
function onclose() {
|
|
dest.removeListener('finish', onfinish);
|
|
unpipe();
|
|
}
|
|
dest.once('close', onclose);
|
|
function onfinish() {
|
|
debug('onfinish');
|
|
dest.removeListener('close', onclose);
|
|
unpipe();
|
|
}
|
|
dest.once('finish', onfinish);
|
|
|
|
function unpipe() {
|
|
debug('unpipe');
|
|
src.unpipe(dest);
|
|
}
|
|
|
|
// tell the dest that it's being piped to
|
|
dest.emit('pipe', src);
|
|
|
|
// start the flow if it hasn't been started already.
|
|
if (!state.flowing) {
|
|
debug('pipe resume');
|
|
src.resume();
|
|
}
|
|
|
|
return dest;
|
|
};
|
|
|
|
function pipeOnDrain(src) {
|
|
return function () {
|
|
var state = src._readableState;
|
|
debug('pipeOnDrain', state.awaitDrain);
|
|
if (state.awaitDrain) state.awaitDrain--;
|
|
if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
|
|
state.flowing = true;
|
|
flow(src);
|
|
}
|
|
};
|
|
}
|
|
|
|
Readable.prototype.unpipe = function (dest) {
|
|
var state = this._readableState;
|
|
var unpipeInfo = { hasUnpiped: false };
|
|
|
|
// if we're not piping anywhere, then do nothing.
|
|
if (state.pipesCount === 0) return this;
|
|
|
|
// just one destination. most common case.
|
|
if (state.pipesCount === 1) {
|
|
// passed in one, but it's not the right one.
|
|
if (dest && dest !== state.pipes) return this;
|
|
|
|
if (!dest) dest = state.pipes;
|
|
|
|
// got a match.
|
|
state.pipes = null;
|
|
state.pipesCount = 0;
|
|
state.flowing = false;
|
|
if (dest) dest.emit('unpipe', this, unpipeInfo);
|
|
return this;
|
|
}
|
|
|
|
// slow case. multiple pipe destinations.
|
|
|
|
if (!dest) {
|
|
// remove all.
|
|
var dests = state.pipes;
|
|
var len = state.pipesCount;
|
|
state.pipes = null;
|
|
state.pipesCount = 0;
|
|
state.flowing = false;
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
dests[i].emit('unpipe', this, unpipeInfo);
|
|
}return this;
|
|
}
|
|
|
|
// try to find the right one.
|
|
var index = indexOf(state.pipes, dest);
|
|
if (index === -1) return this;
|
|
|
|
state.pipes.splice(index, 1);
|
|
state.pipesCount -= 1;
|
|
if (state.pipesCount === 1) state.pipes = state.pipes[0];
|
|
|
|
dest.emit('unpipe', this, unpipeInfo);
|
|
|
|
return this;
|
|
};
|
|
|
|
// set up data events if they are asked for
|
|
// Ensure readable listeners eventually get something
|
|
Readable.prototype.on = function (ev, fn) {
|
|
var res = Stream.prototype.on.call(this, ev, fn);
|
|
|
|
if (ev === 'data') {
|
|
// Start flowing on next tick if stream isn't explicitly paused
|
|
if (this._readableState.flowing !== false) this.resume();
|
|
} else if (ev === 'readable') {
|
|
var state = this._readableState;
|
|
if (!state.endEmitted && !state.readableListening) {
|
|
state.readableListening = state.needReadable = true;
|
|
state.emittedReadable = false;
|
|
if (!state.reading) {
|
|
pna.nextTick(nReadingNextTick, this);
|
|
} else if (state.length) {
|
|
emitReadable(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
Readable.prototype.addListener = Readable.prototype.on;
|
|
|
|
function nReadingNextTick(self) {
|
|
debug('readable nexttick read 0');
|
|
self.read(0);
|
|
}
|
|
|
|
// pause() and resume() are remnants of the legacy readable stream API
|
|
// If the user uses them, then switch into old mode.
|
|
Readable.prototype.resume = function () {
|
|
var state = this._readableState;
|
|
if (!state.flowing) {
|
|
debug('resume');
|
|
state.flowing = true;
|
|
resume(this, state);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
function resume(stream, state) {
|
|
if (!state.resumeScheduled) {
|
|
state.resumeScheduled = true;
|
|
pna.nextTick(resume_, stream, state);
|
|
}
|
|
}
|
|
|
|
function resume_(stream, state) {
|
|
if (!state.reading) {
|
|
debug('resume read 0');
|
|
stream.read(0);
|
|
}
|
|
|
|
state.resumeScheduled = false;
|
|
state.awaitDrain = 0;
|
|
stream.emit('resume');
|
|
flow(stream);
|
|
if (state.flowing && !state.reading) stream.read(0);
|
|
}
|
|
|
|
Readable.prototype.pause = function () {
|
|
debug('call pause flowing=%j', this._readableState.flowing);
|
|
if (false !== this._readableState.flowing) {
|
|
debug('pause');
|
|
this._readableState.flowing = false;
|
|
this.emit('pause');
|
|
}
|
|
return this;
|
|
};
|
|
|
|
function flow(stream) {
|
|
var state = stream._readableState;
|
|
debug('flow', state.flowing);
|
|
while (state.flowing && stream.read() !== null) {}
|
|
}
|
|
|
|
// wrap an old-style stream as the async data source.
|
|
// This is *not* part of the readable stream interface.
|
|
// It is an ugly unfortunate mess of history.
|
|
Readable.prototype.wrap = function (stream) {
|
|
var _this = this;
|
|
|
|
var state = this._readableState;
|
|
var paused = false;
|
|
|
|
stream.on('end', function () {
|
|
debug('wrapped end');
|
|
if (state.decoder && !state.ended) {
|
|
var chunk = state.decoder.end();
|
|
if (chunk && chunk.length) _this.push(chunk);
|
|
}
|
|
|
|
_this.push(null);
|
|
});
|
|
|
|
stream.on('data', function (chunk) {
|
|
debug('wrapped data');
|
|
if (state.decoder) chunk = state.decoder.write(chunk);
|
|
|
|
// don't skip over falsy values in objectMode
|
|
if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
|
|
|
|
var ret = _this.push(chunk);
|
|
if (!ret) {
|
|
paused = true;
|
|
stream.pause();
|
|
}
|
|
});
|
|
|
|
// proxy all the other methods.
|
|
// important when wrapping filters and duplexes.
|
|
for (var i in stream) {
|
|
if (this[i] === undefined && typeof stream[i] === 'function') {
|
|
this[i] = function (method) {
|
|
return function () {
|
|
return stream[method].apply(stream, arguments);
|
|
};
|
|
}(i);
|
|
}
|
|
}
|
|
|
|
// proxy certain important events.
|
|
for (var n = 0; n < kProxyEvents.length; n++) {
|
|
stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
|
|
}
|
|
|
|
// when we try to consume some more bytes, simply unpause the
|
|
// underlying stream.
|
|
this._read = function (n) {
|
|
debug('wrapped _read', n);
|
|
if (paused) {
|
|
paused = false;
|
|
stream.resume();
|
|
}
|
|
};
|
|
|
|
return this;
|
|
};
|
|
|
|
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function () {
|
|
return this._readableState.highWaterMark;
|
|
}
|
|
});
|
|
|
|
// exposed for testing purposes only.
|
|
Readable._fromList = fromList;
|
|
|
|
// Pluck off n bytes from an array of buffers.
|
|
// Length is the combined lengths of all the buffers in the list.
|
|
// This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
function fromList(n, state) {
|
|
// nothing buffered
|
|
if (state.length === 0) return null;
|
|
|
|
var ret;
|
|
if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
|
|
// read it all, truncate the list
|
|
if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
|
|
state.buffer.clear();
|
|
} else {
|
|
// read part of list
|
|
ret = fromListPartial(n, state.buffer, state.decoder);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Extracts only enough buffered data to satisfy the amount requested.
|
|
// This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
function fromListPartial(n, list, hasStrings) {
|
|
var ret;
|
|
if (n < list.head.data.length) {
|
|
// slice is the same for buffers and strings
|
|
ret = list.head.data.slice(0, n);
|
|
list.head.data = list.head.data.slice(n);
|
|
} else if (n === list.head.data.length) {
|
|
// first chunk is a perfect match
|
|
ret = list.shift();
|
|
} else {
|
|
// result spans more than one buffer
|
|
ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Copies a specified amount of characters from the list of buffered data
|
|
// chunks.
|
|
// This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
function copyFromBufferString(n, list) {
|
|
var p = list.head;
|
|
var c = 1;
|
|
var ret = p.data;
|
|
n -= ret.length;
|
|
while (p = p.next) {
|
|
var str = p.data;
|
|
var nb = n > str.length ? str.length : n;
|
|
if (nb === str.length) ret += str;else ret += str.slice(0, n);
|
|
n -= nb;
|
|
if (n === 0) {
|
|
if (nb === str.length) {
|
|
++c;
|
|
if (p.next) list.head = p.next;else list.head = list.tail = null;
|
|
} else {
|
|
list.head = p;
|
|
p.data = str.slice(nb);
|
|
}
|
|
break;
|
|
}
|
|
++c;
|
|
}
|
|
list.length -= c;
|
|
return ret;
|
|
}
|
|
|
|
// Copies a specified amount of bytes from the list of buffered data chunks.
|
|
// This function is designed to be inlinable, so please take care when making
|
|
// changes to the function body.
|
|
function copyFromBuffer(n, list) {
|
|
var ret = Buffer.allocUnsafe(n);
|
|
var p = list.head;
|
|
var c = 1;
|
|
p.data.copy(ret);
|
|
n -= p.data.length;
|
|
while (p = p.next) {
|
|
var buf = p.data;
|
|
var nb = n > buf.length ? buf.length : n;
|
|
buf.copy(ret, ret.length - n, 0, nb);
|
|
n -= nb;
|
|
if (n === 0) {
|
|
if (nb === buf.length) {
|
|
++c;
|
|
if (p.next) list.head = p.next;else list.head = list.tail = null;
|
|
} else {
|
|
list.head = p;
|
|
p.data = buf.slice(nb);
|
|
}
|
|
break;
|
|
}
|
|
++c;
|
|
}
|
|
list.length -= c;
|
|
return ret;
|
|
}
|
|
|
|
function endReadable(stream) {
|
|
var state = stream._readableState;
|
|
|
|
// If we get here before consuming all the bytes, then that is a
|
|
// bug in node. Should never happen.
|
|
if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
|
|
|
|
if (!state.endEmitted) {
|
|
state.ended = true;
|
|
pna.nextTick(endReadableNT, state, stream);
|
|
}
|
|
}
|
|
|
|
function endReadableNT(state, stream) {
|
|
// Check that we didn't get one last unshift.
|
|
if (!state.endEmitted && state.length === 0) {
|
|
state.endEmitted = true;
|
|
stream.readable = false;
|
|
stream.emit('end');
|
|
}
|
|
}
|
|
|
|
function indexOf(xs, x) {
|
|
for (var i = 0, l = xs.length; i < l; i++) {
|
|
if (xs[i] === x) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{"./_stream_duplex":111,"./internal/streams/BufferList":116,"./internal/streams/destroy":117,"./internal/streams/stream":118,"_process":109,"core-util-is":101,"events":102,"inherits":104,"isarray":106,"process-nextick-args":108,"safe-buffer":119,"string_decoder/":120,"util":99}],114:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
// a transform stream is a readable/writable stream where you do
|
|
// something with the data. Sometimes it's called a "filter",
|
|
// but that's not a great name for it, since that implies a thing where
|
|
// some bits pass through, and others are simply ignored. (That would
|
|
// be a valid example of a transform, of course.)
|
|
//
|
|
// While the output is causally related to the input, it's not a
|
|
// necessarily symmetric or synchronous transformation. For example,
|
|
// a zlib stream might take multiple plain-text writes(), and then
|
|
// emit a single compressed chunk some time in the future.
|
|
//
|
|
// Here's how this works:
|
|
//
|
|
// The Transform stream has all the aspects of the readable and writable
|
|
// stream classes. When you write(chunk), that calls _write(chunk,cb)
|
|
// internally, and returns false if there's a lot of pending writes
|
|
// buffered up. When you call read(), that calls _read(n) until
|
|
// there's enough pending readable data buffered up.
|
|
//
|
|
// In a transform stream, the written data is placed in a buffer. When
|
|
// _read(n) is called, it transforms the queued up data, calling the
|
|
// buffered _write cb's as it consumes chunks. If consuming a single
|
|
// written chunk would result in multiple output chunks, then the first
|
|
// outputted bit calls the readcb, and subsequent chunks just go into
|
|
// the read buffer, and will cause it to emit 'readable' if necessary.
|
|
//
|
|
// This way, back-pressure is actually determined by the reading side,
|
|
// since _read has to be called to start processing a new chunk. However,
|
|
// a pathological inflate type of transform can cause excessive buffering
|
|
// here. For example, imagine a stream where every byte of input is
|
|
// interpreted as an integer from 0-255, and then results in that many
|
|
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
|
|
// 1kb of data being output. In this case, you could write a very small
|
|
// amount of input, and end up with a very large amount of output. In
|
|
// such a pathological inflating mechanism, there'd be no way to tell
|
|
// the system to stop doing the transform. A single 4MB write could
|
|
// cause the system to run out of memory.
|
|
//
|
|
// However, even in such a pathological case, only a single written chunk
|
|
// would be consumed, and then the rest would wait (un-transformed) until
|
|
// the results of the previous transformed chunk were consumed.
|
|
|
|
'use strict';
|
|
|
|
module.exports = Transform;
|
|
|
|
var Duplex = require('./_stream_duplex');
|
|
|
|
/*<replacement>*/
|
|
var util = Object.create(require('core-util-is'));
|
|
util.inherits = require('inherits');
|
|
/*</replacement>*/
|
|
|
|
util.inherits(Transform, Duplex);
|
|
|
|
function afterTransform(er, data) {
|
|
var ts = this._transformState;
|
|
ts.transforming = false;
|
|
|
|
var cb = ts.writecb;
|
|
|
|
if (!cb) {
|
|
return this.emit('error', new Error('write callback called multiple times'));
|
|
}
|
|
|
|
ts.writechunk = null;
|
|
ts.writecb = null;
|
|
|
|
if (data != null) // single equals check for both `null` and `undefined`
|
|
this.push(data);
|
|
|
|
cb(er);
|
|
|
|
var rs = this._readableState;
|
|
rs.reading = false;
|
|
if (rs.needReadable || rs.length < rs.highWaterMark) {
|
|
this._read(rs.highWaterMark);
|
|
}
|
|
}
|
|
|
|
function Transform(options) {
|
|
if (!(this instanceof Transform)) return new Transform(options);
|
|
|
|
Duplex.call(this, options);
|
|
|
|
this._transformState = {
|
|
afterTransform: afterTransform.bind(this),
|
|
needTransform: false,
|
|
transforming: false,
|
|
writecb: null,
|
|
writechunk: null,
|
|
writeencoding: null
|
|
};
|
|
|
|
// start out asking for a readable event once data is transformed.
|
|
this._readableState.needReadable = true;
|
|
|
|
// we have implemented the _read method, and done the other things
|
|
// that Readable wants before the first _read call, so unset the
|
|
// sync guard flag.
|
|
this._readableState.sync = false;
|
|
|
|
if (options) {
|
|
if (typeof options.transform === 'function') this._transform = options.transform;
|
|
|
|
if (typeof options.flush === 'function') this._flush = options.flush;
|
|
}
|
|
|
|
// When the writable side finishes, then flush out anything remaining.
|
|
this.on('prefinish', prefinish);
|
|
}
|
|
|
|
function prefinish() {
|
|
var _this = this;
|
|
|
|
if (typeof this._flush === 'function') {
|
|
this._flush(function (er, data) {
|
|
done(_this, er, data);
|
|
});
|
|
} else {
|
|
done(this, null, null);
|
|
}
|
|
}
|
|
|
|
Transform.prototype.push = function (chunk, encoding) {
|
|
this._transformState.needTransform = false;
|
|
return Duplex.prototype.push.call(this, chunk, encoding);
|
|
};
|
|
|
|
// This is the part where you do stuff!
|
|
// override this function in implementation classes.
|
|
// 'chunk' is an input chunk.
|
|
//
|
|
// Call `push(newChunk)` to pass along transformed output
|
|
// to the readable side. You may call 'push' zero or more times.
|
|
//
|
|
// Call `cb(err)` when you are done with this chunk. If you pass
|
|
// an error, then that'll put the hurt on the whole operation. If you
|
|
// never call cb(), then you'll never get another chunk.
|
|
Transform.prototype._transform = function (chunk, encoding, cb) {
|
|
throw new Error('_transform() is not implemented');
|
|
};
|
|
|
|
Transform.prototype._write = function (chunk, encoding, cb) {
|
|
var ts = this._transformState;
|
|
ts.writecb = cb;
|
|
ts.writechunk = chunk;
|
|
ts.writeencoding = encoding;
|
|
if (!ts.transforming) {
|
|
var rs = this._readableState;
|
|
if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
|
|
}
|
|
};
|
|
|
|
// Doesn't matter what the args are here.
|
|
// _transform does all the work.
|
|
// That we got here means that the readable side wants more data.
|
|
Transform.prototype._read = function (n) {
|
|
var ts = this._transformState;
|
|
|
|
if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
|
|
ts.transforming = true;
|
|
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
|
|
} else {
|
|
// mark that we need a transform, so that any data that comes in
|
|
// will get processed, now that we've asked for it.
|
|
ts.needTransform = true;
|
|
}
|
|
};
|
|
|
|
Transform.prototype._destroy = function (err, cb) {
|
|
var _this2 = this;
|
|
|
|
Duplex.prototype._destroy.call(this, err, function (err2) {
|
|
cb(err2);
|
|
_this2.emit('close');
|
|
});
|
|
};
|
|
|
|
function done(stream, er, data) {
|
|
if (er) return stream.emit('error', er);
|
|
|
|
if (data != null) // single equals check for both `null` and `undefined`
|
|
stream.push(data);
|
|
|
|
// if there's nothing in the write buffer, then that means
|
|
// that nothing more will ever be provided
|
|
if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0');
|
|
|
|
if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming');
|
|
|
|
return stream.push(null);
|
|
}
|
|
},{"./_stream_duplex":111,"core-util-is":101,"inherits":104}],115:[function(require,module,exports){
|
|
(function (process,global,setImmediate){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
// A bit simpler than readable streams.
|
|
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
|
|
// the drain event emission and buffering.
|
|
|
|
'use strict';
|
|
|
|
/*<replacement>*/
|
|
|
|
var pna = require('process-nextick-args');
|
|
/*</replacement>*/
|
|
|
|
module.exports = Writable;
|
|
|
|
/* <replacement> */
|
|
function WriteReq(chunk, encoding, cb) {
|
|
this.chunk = chunk;
|
|
this.encoding = encoding;
|
|
this.callback = cb;
|
|
this.next = null;
|
|
}
|
|
|
|
// It seems a linked list but it is not
|
|
// there will be only 2 of these for each stream
|
|
function CorkedRequest(state) {
|
|
var _this = this;
|
|
|
|
this.next = null;
|
|
this.entry = null;
|
|
this.finish = function () {
|
|
onCorkedFinish(_this, state);
|
|
};
|
|
}
|
|
/* </replacement> */
|
|
|
|
/*<replacement>*/
|
|
var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var Duplex;
|
|
/*</replacement>*/
|
|
|
|
Writable.WritableState = WritableState;
|
|
|
|
/*<replacement>*/
|
|
var util = Object.create(require('core-util-is'));
|
|
util.inherits = require('inherits');
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var internalUtil = {
|
|
deprecate: require('util-deprecate')
|
|
};
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
var Stream = require('./internal/streams/stream');
|
|
/*</replacement>*/
|
|
|
|
/*<replacement>*/
|
|
|
|
var Buffer = require('safe-buffer').Buffer;
|
|
var OurUint8Array = global.Uint8Array || function () {};
|
|
function _uint8ArrayToBuffer(chunk) {
|
|
return Buffer.from(chunk);
|
|
}
|
|
function _isUint8Array(obj) {
|
|
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
|
|
}
|
|
|
|
/*</replacement>*/
|
|
|
|
var destroyImpl = require('./internal/streams/destroy');
|
|
|
|
util.inherits(Writable, Stream);
|
|
|
|
function nop() {}
|
|
|
|
function WritableState(options, stream) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
|
|
options = options || {};
|
|
|
|
// Duplex streams are both readable and writable, but share
|
|
// the same options object.
|
|
// However, some cases require setting options to different
|
|
// values for the readable and the writable sides of the duplex stream.
|
|
// These options can be provided separately as readableXXX and writableXXX.
|
|
var isDuplex = stream instanceof Duplex;
|
|
|
|
// object stream flag to indicate whether or not this stream
|
|
// contains buffers or objects.
|
|
this.objectMode = !!options.objectMode;
|
|
|
|
if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
|
|
|
|
// the point at which write() starts returning false
|
|
// Note: 0 is a valid value, means that we always return false if
|
|
// the entire buffer is not flushed immediately on write()
|
|
var hwm = options.highWaterMark;
|
|
var writableHwm = options.writableHighWaterMark;
|
|
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
|
|
|
|
if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm;
|
|
|
|
// cast to ints.
|
|
this.highWaterMark = Math.floor(this.highWaterMark);
|
|
|
|
// if _final has been called
|
|
this.finalCalled = false;
|
|
|
|
// drain event flag.
|
|
this.needDrain = false;
|
|
// at the start of calling end()
|
|
this.ending = false;
|
|
// when end() has been called, and returned
|
|
this.ended = false;
|
|
// when 'finish' is emitted
|
|
this.finished = false;
|
|
|
|
// has it been destroyed
|
|
this.destroyed = false;
|
|
|
|
// should we decode strings into buffers before passing to _write?
|
|
// this is here so that some node-core streams can optimize string
|
|
// handling at a lower level.
|
|
var noDecode = options.decodeStrings === false;
|
|
this.decodeStrings = !noDecode;
|
|
|
|
// Crypto is kind of old and crusty. Historically, its default string
|
|
// encoding is 'binary' so we have to make this configurable.
|
|
// Everything else in the universe uses 'utf8', though.
|
|
this.defaultEncoding = options.defaultEncoding || 'utf8';
|
|
|
|
// not an actual buffer we keep track of, but a measurement
|
|
// of how much we're waiting to get pushed to some underlying
|
|
// socket or file.
|
|
this.length = 0;
|
|
|
|
// a flag to see when we're in the middle of a write.
|
|
this.writing = false;
|
|
|
|
// when true all writes will be buffered until .uncork() call
|
|
this.corked = 0;
|
|
|
|
// a flag to be able to tell if the onwrite cb is called immediately,
|
|
// or on a later tick. We set this to true at first, because any
|
|
// actions that shouldn't happen until "later" should generally also
|
|
// not happen before the first write call.
|
|
this.sync = true;
|
|
|
|
// a flag to know if we're processing previously buffered items, which
|
|
// may call the _write() callback in the same tick, so that we don't
|
|
// end up in an overlapped onwrite situation.
|
|
this.bufferProcessing = false;
|
|
|
|
// the callback that's passed to _write(chunk,cb)
|
|
this.onwrite = function (er) {
|
|
onwrite(stream, er);
|
|
};
|
|
|
|
// the callback that the user supplies to write(chunk,encoding,cb)
|
|
this.writecb = null;
|
|
|
|
// the amount that is being written when _write is called.
|
|
this.writelen = 0;
|
|
|
|
this.bufferedRequest = null;
|
|
this.lastBufferedRequest = null;
|
|
|
|
// number of pending user-supplied write callbacks
|
|
// this must be 0 before 'finish' can be emitted
|
|
this.pendingcb = 0;
|
|
|
|
// emit prefinish if the only thing we're waiting for is _write cbs
|
|
// This is relevant for synchronous Transform streams
|
|
this.prefinished = false;
|
|
|
|
// True if the error was already emitted and should not be thrown again
|
|
this.errorEmitted = false;
|
|
|
|
// count buffered requests
|
|
this.bufferedRequestCount = 0;
|
|
|
|
// allocate the first CorkedRequest, there is always
|
|
// one allocated and free to use, and we maintain at most two
|
|
this.corkedRequestsFree = new CorkedRequest(this);
|
|
}
|
|
|
|
WritableState.prototype.getBuffer = function getBuffer() {
|
|
var current = this.bufferedRequest;
|
|
var out = [];
|
|
while (current) {
|
|
out.push(current);
|
|
current = current.next;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
(function () {
|
|
try {
|
|
Object.defineProperty(WritableState.prototype, 'buffer', {
|
|
get: internalUtil.deprecate(function () {
|
|
return this.getBuffer();
|
|
}, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
|
|
});
|
|
} catch (_) {}
|
|
})();
|
|
|
|
// Test _writableState for inheritance to account for Duplex streams,
|
|
// whose prototype chain only points to Readable.
|
|
var realHasInstance;
|
|
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
|
|
realHasInstance = Function.prototype[Symbol.hasInstance];
|
|
Object.defineProperty(Writable, Symbol.hasInstance, {
|
|
value: function (object) {
|
|
if (realHasInstance.call(this, object)) return true;
|
|
if (this !== Writable) return false;
|
|
|
|
return object && object._writableState instanceof WritableState;
|
|
}
|
|
});
|
|
} else {
|
|
realHasInstance = function (object) {
|
|
return object instanceof this;
|
|
};
|
|
}
|
|
|
|
function Writable(options) {
|
|
Duplex = Duplex || require('./_stream_duplex');
|
|
|
|
// Writable ctor is applied to Duplexes, too.
|
|
// `realHasInstance` is necessary because using plain `instanceof`
|
|
// would return false, as no `_writableState` property is attached.
|
|
|
|
// Trying to use the custom `instanceof` for Writable here will also break the
|
|
// Node.js LazyTransform implementation, which has a non-trivial getter for
|
|
// `_writableState` that would lead to infinite recursion.
|
|
if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
|
|
return new Writable(options);
|
|
}
|
|
|
|
this._writableState = new WritableState(options, this);
|
|
|
|
// legacy.
|
|
this.writable = true;
|
|
|
|
if (options) {
|
|
if (typeof options.write === 'function') this._write = options.write;
|
|
|
|
if (typeof options.writev === 'function') this._writev = options.writev;
|
|
|
|
if (typeof options.destroy === 'function') this._destroy = options.destroy;
|
|
|
|
if (typeof options.final === 'function') this._final = options.final;
|
|
}
|
|
|
|
Stream.call(this);
|
|
}
|
|
|
|
// Otherwise people can pipe Writable streams, which is just wrong.
|
|
Writable.prototype.pipe = function () {
|
|
this.emit('error', new Error('Cannot pipe, not readable'));
|
|
};
|
|
|
|
function writeAfterEnd(stream, cb) {
|
|
var er = new Error('write after end');
|
|
// TODO: defer error events consistently everywhere, not just the cb
|
|
stream.emit('error', er);
|
|
pna.nextTick(cb, er);
|
|
}
|
|
|
|
// Checks that a user-supplied chunk is valid, especially for the particular
|
|
// mode the stream is in. Currently this means that `null` is never accepted
|
|
// and undefined/non-string values are only allowed in object mode.
|
|
function validChunk(stream, state, chunk, cb) {
|
|
var valid = true;
|
|
var er = false;
|
|
|
|
if (chunk === null) {
|
|
er = new TypeError('May not write null values to stream');
|
|
} else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
|
|
er = new TypeError('Invalid non-string/buffer chunk');
|
|
}
|
|
if (er) {
|
|
stream.emit('error', er);
|
|
pna.nextTick(cb, er);
|
|
valid = false;
|
|
}
|
|
return valid;
|
|
}
|
|
|
|
Writable.prototype.write = function (chunk, encoding, cb) {
|
|
var state = this._writableState;
|
|
var ret = false;
|
|
var isBuf = !state.objectMode && _isUint8Array(chunk);
|
|
|
|
if (isBuf && !Buffer.isBuffer(chunk)) {
|
|
chunk = _uint8ArrayToBuffer(chunk);
|
|
}
|
|
|
|
if (typeof encoding === 'function') {
|
|
cb = encoding;
|
|
encoding = null;
|
|
}
|
|
|
|
if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
|
|
|
|
if (typeof cb !== 'function') cb = nop;
|
|
|
|
if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
|
|
state.pendingcb++;
|
|
ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
Writable.prototype.cork = function () {
|
|
var state = this._writableState;
|
|
|
|
state.corked++;
|
|
};
|
|
|
|
Writable.prototype.uncork = function () {
|
|
var state = this._writableState;
|
|
|
|
if (state.corked) {
|
|
state.corked--;
|
|
|
|
if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
|
|
}
|
|
};
|
|
|
|
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
|
|
// node::ParseEncoding() requires lower case.
|
|
if (typeof encoding === 'string') encoding = encoding.toLowerCase();
|
|
if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
|
|
this._writableState.defaultEncoding = encoding;
|
|
return this;
|
|
};
|
|
|
|
function decodeChunk(state, chunk, encoding) {
|
|
if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
|
|
chunk = Buffer.from(chunk, encoding);
|
|
}
|
|
return chunk;
|
|
}
|
|
|
|
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
|
|
// making it explicit this property is not enumerable
|
|
// because otherwise some prototype manipulation in
|
|
// userland will fail
|
|
enumerable: false,
|
|
get: function () {
|
|
return this._writableState.highWaterMark;
|
|
}
|
|
});
|
|
|
|
// if we're already writing something, then just put this
|
|
// in the queue, and wait our turn. Otherwise, call _write
|
|
// If we return false, then we need a drain event, so set that flag.
|
|
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
|
|
if (!isBuf) {
|
|
var newChunk = decodeChunk(state, chunk, encoding);
|
|
if (chunk !== newChunk) {
|
|
isBuf = true;
|
|
encoding = 'buffer';
|
|
chunk = newChunk;
|
|
}
|
|
}
|
|
var len = state.objectMode ? 1 : chunk.length;
|
|
|
|
state.length += len;
|
|
|
|
var ret = state.length < state.highWaterMark;
|
|
// we must ensure that previous needDrain will not be reset to false.
|
|
if (!ret) state.needDrain = true;
|
|
|
|
if (state.writing || state.corked) {
|
|
var last = state.lastBufferedRequest;
|
|
state.lastBufferedRequest = {
|
|
chunk: chunk,
|
|
encoding: encoding,
|
|
isBuf: isBuf,
|
|
callback: cb,
|
|
next: null
|
|
};
|
|
if (last) {
|
|
last.next = state.lastBufferedRequest;
|
|
} else {
|
|
state.bufferedRequest = state.lastBufferedRequest;
|
|
}
|
|
state.bufferedRequestCount += 1;
|
|
} else {
|
|
doWrite(stream, state, false, len, chunk, encoding, cb);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
|
|
state.writelen = len;
|
|
state.writecb = cb;
|
|
state.writing = true;
|
|
state.sync = true;
|
|
if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
|
|
state.sync = false;
|
|
}
|
|
|
|
function onwriteError(stream, state, sync, er, cb) {
|
|
--state.pendingcb;
|
|
|
|
if (sync) {
|
|
// defer the callback if we are being called synchronously
|
|
// to avoid piling up things on the stack
|
|
pna.nextTick(cb, er);
|
|
// this can emit finish, and it will always happen
|
|
// after error
|
|
pna.nextTick(finishMaybe, stream, state);
|
|
stream._writableState.errorEmitted = true;
|
|
stream.emit('error', er);
|
|
} else {
|
|
// the caller expect this to happen before if
|
|
// it is async
|
|
cb(er);
|
|
stream._writableState.errorEmitted = true;
|
|
stream.emit('error', er);
|
|
// this can emit finish, but finish must
|
|
// always follow error
|
|
finishMaybe(stream, state);
|
|
}
|
|
}
|
|
|
|
function onwriteStateUpdate(state) {
|
|
state.writing = false;
|
|
state.writecb = null;
|
|
state.length -= state.writelen;
|
|
state.writelen = 0;
|
|
}
|
|
|
|
function onwrite(stream, er) {
|
|
var state = stream._writableState;
|
|
var sync = state.sync;
|
|
var cb = state.writecb;
|
|
|
|
onwriteStateUpdate(state);
|
|
|
|
if (er) onwriteError(stream, state, sync, er, cb);else {
|
|
// Check if we're actually ready to finish, but don't emit yet
|
|
var finished = needFinish(state);
|
|
|
|
if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
|
|
clearBuffer(stream, state);
|
|
}
|
|
|
|
if (sync) {
|
|
/*<replacement>*/
|
|
asyncWrite(afterWrite, stream, state, finished, cb);
|
|
/*</replacement>*/
|
|
} else {
|
|
afterWrite(stream, state, finished, cb);
|
|
}
|
|
}
|
|
}
|
|
|
|
function afterWrite(stream, state, finished, cb) {
|
|
if (!finished) onwriteDrain(stream, state);
|
|
state.pendingcb--;
|
|
cb();
|
|
finishMaybe(stream, state);
|
|
}
|
|
|
|
// Must force callback to be called on nextTick, so that we don't
|
|
// emit 'drain' before the write() consumer gets the 'false' return
|
|
// value, and has a chance to attach a 'drain' listener.
|
|
function onwriteDrain(stream, state) {
|
|
if (state.length === 0 && state.needDrain) {
|
|
state.needDrain = false;
|
|
stream.emit('drain');
|
|
}
|
|
}
|
|
|
|
// if there's something in the buffer waiting, then process it
|
|
function clearBuffer(stream, state) {
|
|
state.bufferProcessing = true;
|
|
var entry = state.bufferedRequest;
|
|
|
|
if (stream._writev && entry && entry.next) {
|
|
// Fast case, write everything using _writev()
|
|
var l = state.bufferedRequestCount;
|
|
var buffer = new Array(l);
|
|
var holder = state.corkedRequestsFree;
|
|
holder.entry = entry;
|
|
|
|
var count = 0;
|
|
var allBuffers = true;
|
|
while (entry) {
|
|
buffer[count] = entry;
|
|
if (!entry.isBuf) allBuffers = false;
|
|
entry = entry.next;
|
|
count += 1;
|
|
}
|
|
buffer.allBuffers = allBuffers;
|
|
|
|
doWrite(stream, state, true, state.length, buffer, '', holder.finish);
|
|
|
|
// doWrite is almost always async, defer these to save a bit of time
|
|
// as the hot path ends with doWrite
|
|
state.pendingcb++;
|
|
state.lastBufferedRequest = null;
|
|
if (holder.next) {
|
|
state.corkedRequestsFree = holder.next;
|
|
holder.next = null;
|
|
} else {
|
|
state.corkedRequestsFree = new CorkedRequest(state);
|
|
}
|
|
state.bufferedRequestCount = 0;
|
|
} else {
|
|
// Slow case, write chunks one-by-one
|
|
while (entry) {
|
|
var chunk = entry.chunk;
|
|
var encoding = entry.encoding;
|
|
var cb = entry.callback;
|
|
var len = state.objectMode ? 1 : chunk.length;
|
|
|
|
doWrite(stream, state, false, len, chunk, encoding, cb);
|
|
entry = entry.next;
|
|
state.bufferedRequestCount--;
|
|
// if we didn't call the onwrite immediately, then
|
|
// it means that we need to wait until it does.
|
|
// also, that means that the chunk and cb are currently
|
|
// being processed, so move the buffer counter past them.
|
|
if (state.writing) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (entry === null) state.lastBufferedRequest = null;
|
|
}
|
|
|
|
state.bufferedRequest = entry;
|
|
state.bufferProcessing = false;
|
|
}
|
|
|
|
Writable.prototype._write = function (chunk, encoding, cb) {
|
|
cb(new Error('_write() is not implemented'));
|
|
};
|
|
|
|
Writable.prototype._writev = null;
|
|
|
|
Writable.prototype.end = function (chunk, encoding, cb) {
|
|
var state = this._writableState;
|
|
|
|
if (typeof chunk === 'function') {
|
|
cb = chunk;
|
|
chunk = null;
|
|
encoding = null;
|
|
} else if (typeof encoding === 'function') {
|
|
cb = encoding;
|
|
encoding = null;
|
|
}
|
|
|
|
if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
|
|
|
|
// .end() fully uncorks
|
|
if (state.corked) {
|
|
state.corked = 1;
|
|
this.uncork();
|
|
}
|
|
|
|
// ignore unnecessary end() calls.
|
|
if (!state.ending && !state.finished) endWritable(this, state, cb);
|
|
};
|
|
|
|
function needFinish(state) {
|
|
return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
|
|
}
|
|
function callFinal(stream, state) {
|
|
stream._final(function (err) {
|
|
state.pendingcb--;
|
|
if (err) {
|
|
stream.emit('error', err);
|
|
}
|
|
state.prefinished = true;
|
|
stream.emit('prefinish');
|
|
finishMaybe(stream, state);
|
|
});
|
|
}
|
|
function prefinish(stream, state) {
|
|
if (!state.prefinished && !state.finalCalled) {
|
|
if (typeof stream._final === 'function') {
|
|
state.pendingcb++;
|
|
state.finalCalled = true;
|
|
pna.nextTick(callFinal, stream, state);
|
|
} else {
|
|
state.prefinished = true;
|
|
stream.emit('prefinish');
|
|
}
|
|
}
|
|
}
|
|
|
|
function finishMaybe(stream, state) {
|
|
var need = needFinish(state);
|
|
if (need) {
|
|
prefinish(stream, state);
|
|
if (state.pendingcb === 0) {
|
|
state.finished = true;
|
|
stream.emit('finish');
|
|
}
|
|
}
|
|
return need;
|
|
}
|
|
|
|
function endWritable(stream, state, cb) {
|
|
state.ending = true;
|
|
finishMaybe(stream, state);
|
|
if (cb) {
|
|
if (state.finished) pna.nextTick(cb);else stream.once('finish', cb);
|
|
}
|
|
state.ended = true;
|
|
stream.writable = false;
|
|
}
|
|
|
|
function onCorkedFinish(corkReq, state, err) {
|
|
var entry = corkReq.entry;
|
|
corkReq.entry = null;
|
|
while (entry) {
|
|
var cb = entry.callback;
|
|
state.pendingcb--;
|
|
cb(err);
|
|
entry = entry.next;
|
|
}
|
|
if (state.corkedRequestsFree) {
|
|
state.corkedRequestsFree.next = corkReq;
|
|
} else {
|
|
state.corkedRequestsFree = corkReq;
|
|
}
|
|
}
|
|
|
|
Object.defineProperty(Writable.prototype, 'destroyed', {
|
|
get: function () {
|
|
if (this._writableState === undefined) {
|
|
return false;
|
|
}
|
|
return this._writableState.destroyed;
|
|
},
|
|
set: function (value) {
|
|
// we ignore the value if the stream
|
|
// has not been initialized yet
|
|
if (!this._writableState) {
|
|
return;
|
|
}
|
|
|
|
// backward compatibility, the user is explicitly
|
|
// managing destroyed
|
|
this._writableState.destroyed = value;
|
|
}
|
|
});
|
|
|
|
Writable.prototype.destroy = destroyImpl.destroy;
|
|
Writable.prototype._undestroy = destroyImpl.undestroy;
|
|
Writable.prototype._destroy = function (err, cb) {
|
|
this.end();
|
|
cb(err);
|
|
};
|
|
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate)
|
|
},{"./_stream_duplex":111,"./internal/streams/destroy":117,"./internal/streams/stream":118,"_process":109,"core-util-is":101,"inherits":104,"process-nextick-args":108,"safe-buffer":119,"timers":128,"util-deprecate":129}],116:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var Buffer = require('safe-buffer').Buffer;
|
|
var util = require('util');
|
|
|
|
function copyBuffer(src, target, offset) {
|
|
src.copy(target, offset);
|
|
}
|
|
|
|
module.exports = function () {
|
|
function BufferList() {
|
|
_classCallCheck(this, BufferList);
|
|
|
|
this.head = null;
|
|
this.tail = null;
|
|
this.length = 0;
|
|
}
|
|
|
|
BufferList.prototype.push = function push(v) {
|
|
var entry = { data: v, next: null };
|
|
if (this.length > 0) this.tail.next = entry;else this.head = entry;
|
|
this.tail = entry;
|
|
++this.length;
|
|
};
|
|
|
|
BufferList.prototype.unshift = function unshift(v) {
|
|
var entry = { data: v, next: this.head };
|
|
if (this.length === 0) this.tail = entry;
|
|
this.head = entry;
|
|
++this.length;
|
|
};
|
|
|
|
BufferList.prototype.shift = function shift() {
|
|
if (this.length === 0) return;
|
|
var ret = this.head.data;
|
|
if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
|
|
--this.length;
|
|
return ret;
|
|
};
|
|
|
|
BufferList.prototype.clear = function clear() {
|
|
this.head = this.tail = null;
|
|
this.length = 0;
|
|
};
|
|
|
|
BufferList.prototype.join = function join(s) {
|
|
if (this.length === 0) return '';
|
|
var p = this.head;
|
|
var ret = '' + p.data;
|
|
while (p = p.next) {
|
|
ret += s + p.data;
|
|
}return ret;
|
|
};
|
|
|
|
BufferList.prototype.concat = function concat(n) {
|
|
if (this.length === 0) return Buffer.alloc(0);
|
|
if (this.length === 1) return this.head.data;
|
|
var ret = Buffer.allocUnsafe(n >>> 0);
|
|
var p = this.head;
|
|
var i = 0;
|
|
while (p) {
|
|
copyBuffer(p.data, ret, i);
|
|
i += p.data.length;
|
|
p = p.next;
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
return BufferList;
|
|
}();
|
|
|
|
if (util && util.inspect && util.inspect.custom) {
|
|
module.exports.prototype[util.inspect.custom] = function () {
|
|
var obj = util.inspect({ length: this.length });
|
|
return this.constructor.name + ' ' + obj;
|
|
};
|
|
}
|
|
},{"safe-buffer":119,"util":99}],117:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
/*<replacement>*/
|
|
|
|
var pna = require('process-nextick-args');
|
|
/*</replacement>*/
|
|
|
|
// undocumented cb() API, needed for core, not for public API
|
|
function destroy(err, cb) {
|
|
var _this = this;
|
|
|
|
var readableDestroyed = this._readableState && this._readableState.destroyed;
|
|
var writableDestroyed = this._writableState && this._writableState.destroyed;
|
|
|
|
if (readableDestroyed || writableDestroyed) {
|
|
if (cb) {
|
|
cb(err);
|
|
} else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
|
|
pna.nextTick(emitErrorNT, this, err);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// we set destroyed to true before firing error callbacks in order
|
|
// to make it re-entrance safe in case destroy() is called within callbacks
|
|
|
|
if (this._readableState) {
|
|
this._readableState.destroyed = true;
|
|
}
|
|
|
|
// if this is a duplex stream mark the writable part as destroyed as well
|
|
if (this._writableState) {
|
|
this._writableState.destroyed = true;
|
|
}
|
|
|
|
this._destroy(err || null, function (err) {
|
|
if (!cb && err) {
|
|
pna.nextTick(emitErrorNT, _this, err);
|
|
if (_this._writableState) {
|
|
_this._writableState.errorEmitted = true;
|
|
}
|
|
} else if (cb) {
|
|
cb(err);
|
|
}
|
|
});
|
|
|
|
return this;
|
|
}
|
|
|
|
function undestroy() {
|
|
if (this._readableState) {
|
|
this._readableState.destroyed = false;
|
|
this._readableState.reading = false;
|
|
this._readableState.ended = false;
|
|
this._readableState.endEmitted = false;
|
|
}
|
|
|
|
if (this._writableState) {
|
|
this._writableState.destroyed = false;
|
|
this._writableState.ended = false;
|
|
this._writableState.ending = false;
|
|
this._writableState.finished = false;
|
|
this._writableState.errorEmitted = false;
|
|
}
|
|
}
|
|
|
|
function emitErrorNT(self, err) {
|
|
self.emit('error', err);
|
|
}
|
|
|
|
module.exports = {
|
|
destroy: destroy,
|
|
undestroy: undestroy
|
|
};
|
|
},{"process-nextick-args":108}],118:[function(require,module,exports){
|
|
module.exports = require('events').EventEmitter;
|
|
|
|
},{"events":102}],119:[function(require,module,exports){
|
|
/* eslint-disable node/no-deprecated-api */
|
|
var buffer = require('buffer')
|
|
var Buffer = buffer.Buffer
|
|
|
|
// alternative to using Object.keys for old browsers
|
|
function copyProps (src, dst) {
|
|
for (var key in src) {
|
|
dst[key] = src[key]
|
|
}
|
|
}
|
|
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
|
|
module.exports = buffer
|
|
} else {
|
|
// Copy properties from require('buffer')
|
|
copyProps(buffer, exports)
|
|
exports.Buffer = SafeBuffer
|
|
}
|
|
|
|
function SafeBuffer (arg, encodingOrOffset, length) {
|
|
return Buffer(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
// Copy static methods from Buffer
|
|
copyProps(Buffer, SafeBuffer)
|
|
|
|
SafeBuffer.from = function (arg, encodingOrOffset, length) {
|
|
if (typeof arg === 'number') {
|
|
throw new TypeError('Argument must not be a number')
|
|
}
|
|
return Buffer(arg, encodingOrOffset, length)
|
|
}
|
|
|
|
SafeBuffer.alloc = function (size, fill, encoding) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
var buf = Buffer(size)
|
|
if (fill !== undefined) {
|
|
if (typeof encoding === 'string') {
|
|
buf.fill(fill, encoding)
|
|
} else {
|
|
buf.fill(fill)
|
|
}
|
|
} else {
|
|
buf.fill(0)
|
|
}
|
|
return buf
|
|
}
|
|
|
|
SafeBuffer.allocUnsafe = function (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
return Buffer(size)
|
|
}
|
|
|
|
SafeBuffer.allocUnsafeSlow = function (size) {
|
|
if (typeof size !== 'number') {
|
|
throw new TypeError('Argument must be a number')
|
|
}
|
|
return buffer.SlowBuffer(size)
|
|
}
|
|
|
|
},{"buffer":100}],120:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
'use strict';
|
|
|
|
/*<replacement>*/
|
|
|
|
var Buffer = require('safe-buffer').Buffer;
|
|
/*</replacement>*/
|
|
|
|
var isEncoding = Buffer.isEncoding || function (encoding) {
|
|
encoding = '' + encoding;
|
|
switch (encoding && encoding.toLowerCase()) {
|
|
case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
};
|
|
|
|
function _normalizeEncoding(enc) {
|
|
if (!enc) return 'utf8';
|
|
var retried;
|
|
while (true) {
|
|
switch (enc) {
|
|
case 'utf8':
|
|
case 'utf-8':
|
|
return 'utf8';
|
|
case 'ucs2':
|
|
case 'ucs-2':
|
|
case 'utf16le':
|
|
case 'utf-16le':
|
|
return 'utf16le';
|
|
case 'latin1':
|
|
case 'binary':
|
|
return 'latin1';
|
|
case 'base64':
|
|
case 'ascii':
|
|
case 'hex':
|
|
return enc;
|
|
default:
|
|
if (retried) return; // undefined
|
|
enc = ('' + enc).toLowerCase();
|
|
retried = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Do not cache `Buffer.isEncoding` when checking encoding names as some
|
|
// modules monkey-patch it to support additional encodings
|
|
function normalizeEncoding(enc) {
|
|
var nenc = _normalizeEncoding(enc);
|
|
if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
|
|
return nenc || enc;
|
|
}
|
|
|
|
// StringDecoder provides an interface for efficiently splitting a series of
|
|
// buffers into a series of JS strings without breaking apart multi-byte
|
|
// characters.
|
|
exports.StringDecoder = StringDecoder;
|
|
function StringDecoder(encoding) {
|
|
this.encoding = normalizeEncoding(encoding);
|
|
var nb;
|
|
switch (this.encoding) {
|
|
case 'utf16le':
|
|
this.text = utf16Text;
|
|
this.end = utf16End;
|
|
nb = 4;
|
|
break;
|
|
case 'utf8':
|
|
this.fillLast = utf8FillLast;
|
|
nb = 4;
|
|
break;
|
|
case 'base64':
|
|
this.text = base64Text;
|
|
this.end = base64End;
|
|
nb = 3;
|
|
break;
|
|
default:
|
|
this.write = simpleWrite;
|
|
this.end = simpleEnd;
|
|
return;
|
|
}
|
|
this.lastNeed = 0;
|
|
this.lastTotal = 0;
|
|
this.lastChar = Buffer.allocUnsafe(nb);
|
|
}
|
|
|
|
StringDecoder.prototype.write = function (buf) {
|
|
if (buf.length === 0) return '';
|
|
var r;
|
|
var i;
|
|
if (this.lastNeed) {
|
|
r = this.fillLast(buf);
|
|
if (r === undefined) return '';
|
|
i = this.lastNeed;
|
|
this.lastNeed = 0;
|
|
} else {
|
|
i = 0;
|
|
}
|
|
if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
|
|
return r || '';
|
|
};
|
|
|
|
StringDecoder.prototype.end = utf8End;
|
|
|
|
// Returns only complete characters in a Buffer
|
|
StringDecoder.prototype.text = utf8Text;
|
|
|
|
// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
|
|
StringDecoder.prototype.fillLast = function (buf) {
|
|
if (this.lastNeed <= buf.length) {
|
|
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
|
|
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
|
|
}
|
|
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
|
|
this.lastNeed -= buf.length;
|
|
};
|
|
|
|
// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
|
|
// continuation byte. If an invalid byte is detected, -2 is returned.
|
|
function utf8CheckByte(byte) {
|
|
if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
|
|
return byte >> 6 === 0x02 ? -1 : -2;
|
|
}
|
|
|
|
// Checks at most 3 bytes at the end of a Buffer in order to detect an
|
|
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
|
|
// needed to complete the UTF-8 character (if applicable) are returned.
|
|
function utf8CheckIncomplete(self, buf, i) {
|
|
var j = buf.length - 1;
|
|
if (j < i) return 0;
|
|
var nb = utf8CheckByte(buf[j]);
|
|
if (nb >= 0) {
|
|
if (nb > 0) self.lastNeed = nb - 1;
|
|
return nb;
|
|
}
|
|
if (--j < i || nb === -2) return 0;
|
|
nb = utf8CheckByte(buf[j]);
|
|
if (nb >= 0) {
|
|
if (nb > 0) self.lastNeed = nb - 2;
|
|
return nb;
|
|
}
|
|
if (--j < i || nb === -2) return 0;
|
|
nb = utf8CheckByte(buf[j]);
|
|
if (nb >= 0) {
|
|
if (nb > 0) {
|
|
if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
|
|
}
|
|
return nb;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Validates as many continuation bytes for a multi-byte UTF-8 character as
|
|
// needed or are available. If we see a non-continuation byte where we expect
|
|
// one, we "replace" the validated continuation bytes we've seen so far with
|
|
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
|
|
// behavior. The continuation byte check is included three times in the case
|
|
// where all of the continuation bytes for a character exist in the same buffer.
|
|
// It is also done this way as a slight performance increase instead of using a
|
|
// loop.
|
|
function utf8CheckExtraBytes(self, buf, p) {
|
|
if ((buf[0] & 0xC0) !== 0x80) {
|
|
self.lastNeed = 0;
|
|
return '\ufffd';
|
|
}
|
|
if (self.lastNeed > 1 && buf.length > 1) {
|
|
if ((buf[1] & 0xC0) !== 0x80) {
|
|
self.lastNeed = 1;
|
|
return '\ufffd';
|
|
}
|
|
if (self.lastNeed > 2 && buf.length > 2) {
|
|
if ((buf[2] & 0xC0) !== 0x80) {
|
|
self.lastNeed = 2;
|
|
return '\ufffd';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
|
|
function utf8FillLast(buf) {
|
|
var p = this.lastTotal - this.lastNeed;
|
|
var r = utf8CheckExtraBytes(this, buf, p);
|
|
if (r !== undefined) return r;
|
|
if (this.lastNeed <= buf.length) {
|
|
buf.copy(this.lastChar, p, 0, this.lastNeed);
|
|
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
|
|
}
|
|
buf.copy(this.lastChar, p, 0, buf.length);
|
|
this.lastNeed -= buf.length;
|
|
}
|
|
|
|
// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
|
|
// partial character, the character's bytes are buffered until the required
|
|
// number of bytes are available.
|
|
function utf8Text(buf, i) {
|
|
var total = utf8CheckIncomplete(this, buf, i);
|
|
if (!this.lastNeed) return buf.toString('utf8', i);
|
|
this.lastTotal = total;
|
|
var end = buf.length - (total - this.lastNeed);
|
|
buf.copy(this.lastChar, 0, end);
|
|
return buf.toString('utf8', i, end);
|
|
}
|
|
|
|
// For UTF-8, a replacement character is added when ending on a partial
|
|
// character.
|
|
function utf8End(buf) {
|
|
var r = buf && buf.length ? this.write(buf) : '';
|
|
if (this.lastNeed) return r + '\ufffd';
|
|
return r;
|
|
}
|
|
|
|
// UTF-16LE typically needs two bytes per character, but even if we have an even
|
|
// number of bytes available, we need to check if we end on a leading/high
|
|
// surrogate. In that case, we need to wait for the next two bytes in order to
|
|
// decode the last character properly.
|
|
function utf16Text(buf, i) {
|
|
if ((buf.length - i) % 2 === 0) {
|
|
var r = buf.toString('utf16le', i);
|
|
if (r) {
|
|
var c = r.charCodeAt(r.length - 1);
|
|
if (c >= 0xD800 && c <= 0xDBFF) {
|
|
this.lastNeed = 2;
|
|
this.lastTotal = 4;
|
|
this.lastChar[0] = buf[buf.length - 2];
|
|
this.lastChar[1] = buf[buf.length - 1];
|
|
return r.slice(0, -1);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
this.lastNeed = 1;
|
|
this.lastTotal = 2;
|
|
this.lastChar[0] = buf[buf.length - 1];
|
|
return buf.toString('utf16le', i, buf.length - 1);
|
|
}
|
|
|
|
// For UTF-16LE we do not explicitly append special replacement characters if we
|
|
// end on a partial character, we simply let v8 handle that.
|
|
function utf16End(buf) {
|
|
var r = buf && buf.length ? this.write(buf) : '';
|
|
if (this.lastNeed) {
|
|
var end = this.lastTotal - this.lastNeed;
|
|
return r + this.lastChar.toString('utf16le', 0, end);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
function base64Text(buf, i) {
|
|
var n = (buf.length - i) % 3;
|
|
if (n === 0) return buf.toString('base64', i);
|
|
this.lastNeed = 3 - n;
|
|
this.lastTotal = 3;
|
|
if (n === 1) {
|
|
this.lastChar[0] = buf[buf.length - 1];
|
|
} else {
|
|
this.lastChar[0] = buf[buf.length - 2];
|
|
this.lastChar[1] = buf[buf.length - 1];
|
|
}
|
|
return buf.toString('base64', i, buf.length - n);
|
|
}
|
|
|
|
function base64End(buf) {
|
|
var r = buf && buf.length ? this.write(buf) : '';
|
|
if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
|
|
return r;
|
|
}
|
|
|
|
// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
|
|
function simpleWrite(buf) {
|
|
return buf.toString(this.encoding);
|
|
}
|
|
|
|
function simpleEnd(buf) {
|
|
return buf && buf.length ? this.write(buf) : '';
|
|
}
|
|
},{"safe-buffer":119}],121:[function(require,module,exports){
|
|
module.exports = require('./readable').PassThrough
|
|
|
|
},{"./readable":122}],122:[function(require,module,exports){
|
|
exports = module.exports = require('./lib/_stream_readable.js');
|
|
exports.Stream = exports;
|
|
exports.Readable = exports;
|
|
exports.Writable = require('./lib/_stream_writable.js');
|
|
exports.Duplex = require('./lib/_stream_duplex.js');
|
|
exports.Transform = require('./lib/_stream_transform.js');
|
|
exports.PassThrough = require('./lib/_stream_passthrough.js');
|
|
|
|
},{"./lib/_stream_duplex.js":111,"./lib/_stream_passthrough.js":112,"./lib/_stream_readable.js":113,"./lib/_stream_transform.js":114,"./lib/_stream_writable.js":115}],123:[function(require,module,exports){
|
|
module.exports = require('./readable').Transform
|
|
|
|
},{"./readable":122}],124:[function(require,module,exports){
|
|
module.exports = require('./lib/_stream_writable.js');
|
|
|
|
},{"./lib/_stream_writable.js":115}],125:[function(require,module,exports){
|
|
arguments[4][85][0].apply(exports,arguments)
|
|
},{"buffer":100,"dup":85}],126:[function(require,module,exports){
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
// persons to whom the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
module.exports = Stream;
|
|
|
|
var EE = require('events').EventEmitter;
|
|
var inherits = require('inherits');
|
|
|
|
inherits(Stream, EE);
|
|
Stream.Readable = require('readable-stream/readable.js');
|
|
Stream.Writable = require('readable-stream/writable.js');
|
|
Stream.Duplex = require('readable-stream/duplex.js');
|
|
Stream.Transform = require('readable-stream/transform.js');
|
|
Stream.PassThrough = require('readable-stream/passthrough.js');
|
|
|
|
// Backwards-compat with node 0.4.x
|
|
Stream.Stream = Stream;
|
|
|
|
|
|
|
|
// old-style streams. Note that the pipe method (the only relevant
|
|
// part of this class) is overridden in the Readable class.
|
|
|
|
function Stream() {
|
|
EE.call(this);
|
|
}
|
|
|
|
Stream.prototype.pipe = function(dest, options) {
|
|
var source = this;
|
|
|
|
function ondata(chunk) {
|
|
if (dest.writable) {
|
|
if (false === dest.write(chunk) && source.pause) {
|
|
source.pause();
|
|
}
|
|
}
|
|
}
|
|
|
|
source.on('data', ondata);
|
|
|
|
function ondrain() {
|
|
if (source.readable && source.resume) {
|
|
source.resume();
|
|
}
|
|
}
|
|
|
|
dest.on('drain', ondrain);
|
|
|
|
// If the 'end' option is not supplied, dest.end() will be called when
|
|
// source gets the 'end' or 'close' events. Only dest.end() once.
|
|
if (!dest._isStdio && (!options || options.end !== false)) {
|
|
source.on('end', onend);
|
|
source.on('close', onclose);
|
|
}
|
|
|
|
var didOnEnd = false;
|
|
function onend() {
|
|
if (didOnEnd) return;
|
|
didOnEnd = true;
|
|
|
|
dest.end();
|
|
}
|
|
|
|
|
|
function onclose() {
|
|
if (didOnEnd) return;
|
|
didOnEnd = true;
|
|
|
|
if (typeof dest.destroy === 'function') dest.destroy();
|
|
}
|
|
|
|
// don't leave dangling pipes when there are errors.
|
|
function onerror(er) {
|
|
cleanup();
|
|
if (EE.listenerCount(this, 'error') === 0) {
|
|
throw er; // Unhandled stream error in pipe.
|
|
}
|
|
}
|
|
|
|
source.on('error', onerror);
|
|
dest.on('error', onerror);
|
|
|
|
// remove all the event listeners that were added.
|
|
function cleanup() {
|
|
source.removeListener('data', ondata);
|
|
dest.removeListener('drain', ondrain);
|
|
|
|
source.removeListener('end', onend);
|
|
source.removeListener('close', onclose);
|
|
|
|
source.removeListener('error', onerror);
|
|
dest.removeListener('error', onerror);
|
|
|
|
source.removeListener('end', cleanup);
|
|
source.removeListener('close', cleanup);
|
|
|
|
dest.removeListener('close', cleanup);
|
|
}
|
|
|
|
source.on('end', cleanup);
|
|
source.on('close', cleanup);
|
|
|
|
dest.on('close', cleanup);
|
|
|
|
dest.emit('pipe', source);
|
|
|
|
// Allow for unix-like usage: A.pipe(B).pipe(C)
|
|
return dest;
|
|
};
|
|
|
|
},{"events":102,"inherits":104,"readable-stream/duplex.js":110,"readable-stream/passthrough.js":121,"readable-stream/readable.js":122,"readable-stream/transform.js":123,"readable-stream/writable.js":124}],127:[function(require,module,exports){
|
|
arguments[4][120][0].apply(exports,arguments)
|
|
},{"dup":120,"safe-buffer":125}],128:[function(require,module,exports){
|
|
(function (setImmediate,clearImmediate){
|
|
var nextTick = require('process/browser.js').nextTick;
|
|
var apply = Function.prototype.apply;
|
|
var slice = Array.prototype.slice;
|
|
var immediateIds = {};
|
|
var nextImmediateId = 0;
|
|
|
|
// DOM APIs, for completeness
|
|
|
|
exports.setTimeout = function() {
|
|
return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
|
|
};
|
|
exports.setInterval = function() {
|
|
return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
|
|
};
|
|
exports.clearTimeout =
|
|
exports.clearInterval = function(timeout) { timeout.close(); };
|
|
|
|
function Timeout(id, clearFn) {
|
|
this._id = id;
|
|
this._clearFn = clearFn;
|
|
}
|
|
Timeout.prototype.unref = Timeout.prototype.ref = function() {};
|
|
Timeout.prototype.close = function() {
|
|
this._clearFn.call(window, this._id);
|
|
};
|
|
|
|
// Does not start the time, just sets up the members needed.
|
|
exports.enroll = function(item, msecs) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
item._idleTimeout = msecs;
|
|
};
|
|
|
|
exports.unenroll = function(item) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
item._idleTimeout = -1;
|
|
};
|
|
|
|
exports._unrefActive = exports.active = function(item) {
|
|
clearTimeout(item._idleTimeoutId);
|
|
|
|
var msecs = item._idleTimeout;
|
|
if (msecs >= 0) {
|
|
item._idleTimeoutId = setTimeout(function onTimeout() {
|
|
if (item._onTimeout)
|
|
item._onTimeout();
|
|
}, msecs);
|
|
}
|
|
};
|
|
|
|
// That's not how node.js implements it but the exposed api is the same.
|
|
exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
|
|
var id = nextImmediateId++;
|
|
var args = arguments.length < 2 ? false : slice.call(arguments, 1);
|
|
|
|
immediateIds[id] = true;
|
|
|
|
nextTick(function onNextTick() {
|
|
if (immediateIds[id]) {
|
|
// fn.call() is faster so we optimize for the common use-case
|
|
// @see http://jsperf.com/call-apply-segu
|
|
if (args) {
|
|
fn.apply(null, args);
|
|
} else {
|
|
fn.call(null);
|
|
}
|
|
// Prevent ids from leaking
|
|
exports.clearImmediate(id);
|
|
}
|
|
});
|
|
|
|
return id;
|
|
};
|
|
|
|
exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
|
|
delete immediateIds[id];
|
|
};
|
|
}).call(this,require("timers").setImmediate,require("timers").clearImmediate)
|
|
},{"process/browser.js":109,"timers":128}],129:[function(require,module,exports){
|
|
(function (global){
|
|
|
|
/**
|
|
* Module exports.
|
|
*/
|
|
|
|
module.exports = deprecate;
|
|
|
|
/**
|
|
* Mark that a method should not be used.
|
|
* Returns a modified function which warns once by default.
|
|
*
|
|
* If `localStorage.noDeprecation = true` is set, then it is a no-op.
|
|
*
|
|
* If `localStorage.throwDeprecation = true` is set, then deprecated functions
|
|
* will throw an Error when invoked.
|
|
*
|
|
* If `localStorage.traceDeprecation = true` is set, then deprecated functions
|
|
* will invoke `console.trace()` instead of `console.error()`.
|
|
*
|
|
* @param {Function} fn - the function to deprecate
|
|
* @param {String} msg - the string to print to the console when `fn` is invoked
|
|
* @returns {Function} a new "deprecated" version of `fn`
|
|
* @api public
|
|
*/
|
|
|
|
function deprecate (fn, msg) {
|
|
if (config('noDeprecation')) {
|
|
return fn;
|
|
}
|
|
|
|
var warned = false;
|
|
function deprecated() {
|
|
if (!warned) {
|
|
if (config('throwDeprecation')) {
|
|
throw new Error(msg);
|
|
} else if (config('traceDeprecation')) {
|
|
console.trace(msg);
|
|
} else {
|
|
console.warn(msg);
|
|
}
|
|
warned = true;
|
|
}
|
|
return fn.apply(this, arguments);
|
|
}
|
|
|
|
return deprecated;
|
|
}
|
|
|
|
/**
|
|
* Checks `localStorage` for boolean values for the given `name`.
|
|
*
|
|
* @param {String} name
|
|
* @returns {Boolean}
|
|
* @api private
|
|
*/
|
|
|
|
function config (name) {
|
|
// accessing global.localStorage can trigger a DOMException in sandboxed iframes
|
|
try {
|
|
if (!global.localStorage) return false;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
var val = global.localStorage[name];
|
|
if (null == val) return false;
|
|
return String(val).toLowerCase() === 'true';
|
|
}
|
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
},{}]},{},[1]);
|