From f0fca6fc1c91b0c4158e7b92bdd2582341575c8e Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Tue, 20 Oct 2026 15:42:38 +0200 Subject: [PATCH] update dependencies and rebuild --- dist/{cache-C3QW-iHv.js => cache-BzPKClMA.js} | 80758 ++++++++-------- dist/{cache-DrBcWZx-.js => cache-Dl81DHPs.js} | 2131 +- ...leanup-CXZWJx5g.js => cleanup-e3M0pm4f.js} | 2302 +- dist/restore.js | 2 +- dist/save.js | 2 +- package-lock.json | 455 +- package.json | 6 +- 7 files changed, 43318 insertions(+), 42338 deletions(-) rename dist/{cache-C3QW-iHv.js => cache-BzPKClMA.js} (84%) rename dist/{cache-DrBcWZx-.js => cache-Dl81DHPs.js} (96%) rename dist/{cleanup-CXZWJx5g.js => cleanup-e3M0pm4f.js} (96%) diff --git a/dist/cache-C3QW-iHv.js b/dist/cache-BzPKClMA.js similarity index 84% rename from dist/cache-C3QW-iHv.js rename to dist/cache-BzPKClMA.js index a93b0c9..9c7a3dc 100644 --- a/dist/cache-C3QW-iHv.js +++ b/dist/cache-BzPKClMA.js @@ -1,4 +1,4 @@ -import { v as commonjsGlobal, x as requireTunnel, y as getDefaultExportFromCjs, z as getAugmentedNamespace } from './cleanup-CXZWJx5g.js'; +import { x as commonjsGlobal, y as requireTunnel, z as getDefaultExportFromCjs, A as getAugmentedNamespace } from './cleanup-e3M0pm4f.js'; import os__default from 'os'; import crypto__default from 'crypto'; import fs__default from 'fs'; @@ -704,12 +704,12 @@ function requireErrors$2 () { return errors$2; } -var constants$f; -var hasRequiredConstants$f; +var constants$g; +var hasRequiredConstants$g; -function requireConstants$f () { - if (hasRequiredConstants$f) return constants$f; - hasRequiredConstants$f = 1; +function requireConstants$g () { + if (hasRequiredConstants$g) return constants$g; + hasRequiredConstants$g = 1; /** @type {Record} */ const headerNameLowerCasedRecord = {}; @@ -823,11 +823,11 @@ function requireConstants$f () { // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. Object.setPrototypeOf(headerNameLowerCasedRecord, null); - constants$f = { + constants$g = { wellknownHeaderNames, headerNameLowerCasedRecord }; - return constants$f; + return constants$g; } var util$i; @@ -846,7 +846,7 @@ function requireUtil$i () { const { Blob } = require$$0__default; const nodeUtil = require$$0__default$1; const { stringify } = require$$1$1; - const { headerNameLowerCasedRecord } = requireConstants$f(); + const { headerNameLowerCasedRecord } = requireConstants$g(); const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)); @@ -3092,12 +3092,12 @@ function requireMain () { return main$2.exports; } -var constants$e; -var hasRequiredConstants$e; +var constants$f; +var hasRequiredConstants$f; -function requireConstants$e () { - if (hasRequiredConstants$e) return constants$e; - hasRequiredConstants$e = 1; +function requireConstants$f () { + if (hasRequiredConstants$f) return constants$f; + hasRequiredConstants$f = 1; const { MessageChannel, receiveMessageOnPort } = require$$0$9; @@ -3223,7 +3223,7 @@ function requireConstants$e () { return receiveMessageOnPort(channel.port2).message }; - constants$e = { + constants$f = { DOMException, structuredClone, subresource, @@ -3248,7 +3248,7 @@ function requireConstants$e () { forbiddenMethodsSet, referrerPolicySet }; - return constants$e; + return constants$f; } var global$4; @@ -3306,7 +3306,7 @@ function requireUtil$h () { if (hasRequiredUtil$h) return util$h; hasRequiredUtil$h = 1; - const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = requireConstants$e(); + const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = requireConstants$f(); const { getGlobalOrigin } = requireGlobal$3(); const { performance } = require$$2$2; const { isBlobLike, toUSVString, ReadableStreamFrom } = requireUtil$i(); @@ -5758,12 +5758,12 @@ function requireDataURL$1 () { return dataURL$1; } -var file$3; -var hasRequiredFile$3; +var file$4; +var hasRequiredFile$4; -function requireFile$3 () { - if (hasRequiredFile$3) return file$3; - hasRequiredFile$3 = 1; +function requireFile$4 () { + if (hasRequiredFile$4) return file$4; + hasRequiredFile$4 = 1; const { Blob, File: NativeFile } = require$$0__default; const { types } = require$$0__default$1; @@ -6106,8 +6106,8 @@ function requireFile$3 () { ) } - file$3 = { File, FileLike, isFileLike }; - return file$3; + file$4 = { File, FileLike, isFileLike }; + return file$4; } var formdata$1; @@ -6119,7 +6119,7 @@ function requireFormdata$1 () { const { isBlobLike, toUSVString, makeIterator } = requireUtil$h(); const { kState } = requireSymbols$8(); - const { File: UndiciFile, FileLike, isFileLike } = requireFile$3(); + const { File: UndiciFile, FileLike, isFileLike } = requireFile$4(); const { webidl } = requireWebidl$1(); const { Blob, File: NativeFile } = require$$0__default; @@ -6403,13 +6403,13 @@ function requireBody$1 () { const { FormData } = requireFormdata$1(); const { kState } = requireSymbols$8(); const { webidl } = requireWebidl$1(); - const { DOMException, structuredClone } = requireConstants$e(); + const { DOMException, structuredClone } = requireConstants$f(); const { Blob, File: NativeFile } = require$$0__default; const { kBodyUsed } = requireSymbols$9(); const assert$1 = assert; const { isErrored } = requireUtil$i(); const { isUint8Array, isArrayBuffer } = require$$5; - const { File: UndiciFile } = requireFile$3(); + const { File: UndiciFile } = requireFile$4(); const { parseMIMEType, serializeAMimeType } = requireDataURL$1(); let random; @@ -7935,7 +7935,7 @@ function requireConnect$1 () { return connect$1; } -var constants$d = {}; +var constants$e = {}; var utils$6 = {}; @@ -7961,11 +7961,11 @@ function requireUtils$6 () { return utils$6; } -var hasRequiredConstants$d; +var hasRequiredConstants$e; -function requireConstants$d () { - if (hasRequiredConstants$d) return constants$d; - hasRequiredConstants$d = 1; +function requireConstants$e () { + if (hasRequiredConstants$e) return constants$e; + hasRequiredConstants$e = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; @@ -8238,8 +8238,8 @@ function requireConstants$d () { 'upgrade': HEADER_STATE.UPGRADE, }; - } (constants$d)); - return constants$d; + } (constants$e)); + return constants$e; } var RedirectHandler_1$1; @@ -8989,7 +8989,7 @@ function requireClient$1 () { resume(client); } - const constants = requireConstants$d(); + const constants = requireConstants$e(); const createRedirectInterceptor = requireRedirectInterceptor$1(); const EMPTY_BUF = Buffer.alloc(0); @@ -15315,7 +15315,7 @@ function requireResponse$2 () { redirectStatusSet, nullBodyStatus, DOMException - } = requireConstants$e(); + } = requireConstants$f(); const { kState, kHeaders, kGuard, kRealm } = requireSymbols$8(); const { webidl } = requireWebidl$1(); const { FormData } = requireFormdata$1(); @@ -15899,7 +15899,7 @@ function requireRequest$2 () { requestCredentials, requestCache, requestDuplex - } = requireConstants$e(); + } = requireConstants$f(); const { kEnumerableProperty } = util; const { kHeaders, kSignal, kState, kGuard, kRealm } = requireSymbols$8(); const { webidl } = requireWebidl$1(); @@ -16881,7 +16881,7 @@ function requireFetch$1 () { requestBodyHeader, subresourceSet, DOMException - } = requireConstants$e(); + } = requireConstants$f(); const { kHeadersList } = requireSymbols$9(); const EE = require$$0__default$3; const { Readable, pipeline } = require$$0__default$2; @@ -19322,7 +19322,7 @@ function requireUtil$f () { } = requireSymbols$7(); const { ProgressEvent } = requireProgressevent$1(); const { getEncoding } = requireEncoding$1(); - const { DOMException } = requireConstants$e(); + const { DOMException } = requireConstants$f(); const { serializeAMimeType, parseMIMEType } = requireDataURL$1(); const { types } = require$$0__default$1; const { StringDecoder } = require$$6; @@ -21126,12 +21126,12 @@ function requireCachestorage$1 () { return cachestorage$1; } -var constants$c; -var hasRequiredConstants$c; +var constants$d; +var hasRequiredConstants$d; -function requireConstants$c () { - if (hasRequiredConstants$c) return constants$c; - hasRequiredConstants$c = 1; +function requireConstants$d () { + if (hasRequiredConstants$d) return constants$d; + hasRequiredConstants$d = 1; // https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size const maxAttributeValueSize = 1024; @@ -21139,11 +21139,11 @@ function requireConstants$c () { // https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size const maxNameValuePairSize = 4096; - constants$c = { + constants$d = { maxAttributeValueSize, maxNameValuePairSize }; - return constants$c; + return constants$d; } var util$d; @@ -21435,7 +21435,7 @@ function requireParse$2 () { if (hasRequiredParse$2) return parse$5; hasRequiredParse$2 = 1; - const { maxNameValuePairSize, maxAttributeValueSize } = requireConstants$c(); + const { maxNameValuePairSize, maxAttributeValueSize } = requireConstants$d(); const { isCTLExcludingHtab } = requireUtil$d(); const { collectASequenceOfCodePointsFast } = requireDataURL$1(); const assert$1 = assert; @@ -21944,12 +21944,12 @@ function requireCookies$1 () { return cookies$1; } -var constants$b; -var hasRequiredConstants$b; +var constants$c; +var hasRequiredConstants$c; -function requireConstants$b () { - if (hasRequiredConstants$b) return constants$b; - hasRequiredConstants$b = 1; +function requireConstants$c () { + if (hasRequiredConstants$c) return constants$c; + hasRequiredConstants$c = 1; // This is a Globally Unique Identifier unique used // to validate that the endpoint accepts websocket @@ -21991,7 +21991,7 @@ function requireConstants$b () { const emptyBuffer = Buffer.allocUnsafe(0); - constants$b = { + constants$c = { uid, staticPropertyDescriptors, states, @@ -22000,7 +22000,7 @@ function requireConstants$b () { parserStates, emptyBuffer }; - return constants$b; + return constants$c; } var symbols$5; @@ -22342,7 +22342,7 @@ function requireUtil$c () { hasRequiredUtil$c = 1; const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = requireSymbols$5(); - const { states, opcodes } = requireConstants$b(); + const { states, opcodes } = requireConstants$c(); const { MessageEvent, ErrorEvent } = requireEvents$1(); /* globals Blob */ @@ -22550,7 +22550,7 @@ function requireConnection$1 () { hasRequiredConnection$1 = 1; const diagnosticsChannel = require$$0$a; - const { uid, states } = requireConstants$b(); + const { uid, states } = requireConstants$c(); const { kReadyState, kSentClose, @@ -22848,7 +22848,7 @@ function requireFrame$1 () { if (hasRequiredFrame$1) return frame$1; hasRequiredFrame$1 = 1; - const { maxUnsigned16Bit } = requireConstants$b(); + const { maxUnsigned16Bit } = requireConstants$c(); /** @type {import('crypto')} */ let crypto; @@ -22931,7 +22931,7 @@ function requireReceiver$1 () { const { Writable } = require$$0__default$2; const diagnosticsChannel = require$$0$a; - const { parserStates, opcodes, states, emptyBuffer } = requireConstants$b(); + const { parserStates, opcodes, states, emptyBuffer } = requireConstants$c(); const { kReadyState, kSentClose, kResponse, kReceivedClose } = requireSymbols$5(); const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = requireUtil$c(); const { WebsocketFrameSend } = requireFrame$1(); @@ -23282,10 +23282,10 @@ function requireWebsocket$1 () { hasRequiredWebsocket$1 = 1; const { webidl } = requireWebidl$1(); - const { DOMException } = requireConstants$e(); + const { DOMException } = requireConstants$f(); const { URLSerializer } = requireDataURL$1(); const { getGlobalOrigin } = requireGlobal$3(); - const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = requireConstants$b(); + const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = requireConstants$c(); const { kWebSocketURL, kReadyState, @@ -24045,7 +24045,7 @@ function requireUndici$1 () { undici$1.Response = requireResponse$2().Response; undici$1.Request = requireRequest$2().Request; undici$1.FormData = requireFormdata$1().FormData; - undici$1.File = requireFile$3().File; + undici$1.File = requireFile$4().File; undici$1.FileReader = requireFilereader$1().FileReader; const { setGlobalOrigin, getGlobalOrigin } = requireGlobal$3(); @@ -27391,28 +27391,6 @@ function requireInternalPatternHelper () { var internalPattern = {}; -var concatMap; -var hasRequiredConcatMap; - -function requireConcatMap () { - if (hasRequiredConcatMap) return concatMap; - hasRequiredConcatMap = 1; - concatMap = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; - }; - - var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; - }; - return concatMap; -} - var balancedMatch; var hasRequiredBalancedMatch; @@ -27489,7 +27467,6 @@ var hasRequiredBraceExpansion; function requireBraceExpansion () { if (hasRequiredBraceExpansion) return braceExpansion; hasRequiredBraceExpansion = 1; - var concatMap = requireConcatMap(); var balanced = requireBalancedMatch(); braceExpansion = expandTop; @@ -27500,6 +27477,40 @@ function requireBraceExpansion () { var escComma = '\0COMMA'+Math.random()+'\0'; var escPeriod = '\0PERIOD'+Math.random()+'\0'; + var EXPANSION_MAX = 100000; + + // `EXPANSION_MAX` caps the *number* of expansions, but not their length. An + // input like `'{a,b}'.repeat(1500)` stays under that count - its output is + // truncated to 100k results - while making every result ~1500 characters + // long. The result set, and the intermediate arrays built while combining + // brace sets, then grow large enough to exhaust memory and crash the process + // (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of + // characters the accumulator may hold at any point, so memory stays flat no + // matter how many brace groups are chained. The limit sits well above any + // realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M + // characters) so legitimate input is unaffected. + var EXPANSION_MAX_LENGTH = 4000000; + + // `expand` recurses once per level of brace *nesting* - both when expanding a + // set's comma members and when re-wrapping a set whose body is a single part. + // The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one + // level per chained group), which left nesting depth unbounded: about 3,100 + // levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack + // and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser + // will follow nesting. It sits far above any realistic pattern and well below + // the depth at which the stack runs out. + var EXPANSION_MAX_DEPTH = 1000; + + // Bash keeps a quirk where a brace group followed by a comma set still expands + // (`{a},b}`). The parser implements it by rewriting the string and restarting + // the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n` + // full passes over a string that itself grows by one `escClose` sentinel each + // time - quadratic in `n`, with a ~26x constant from the sentinel's length. + // 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27 + // seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many + // times the scan may restart. Real `{a},b}` input needs a handful. + var EXPANSION_MAX_REWRITES = 1000; + function numeric(str) { return parseInt(str, 10) == str ? parseInt(str, 10) @@ -27523,34 +27534,54 @@ function requireBraceExpansion () { } + // Like `target.push(...items)` but doesn't overflow the stack + function pushAll(target, items) { + for (var i = 0; i < items.length; i++) { + target.push(items[i]); + } + } + // Basically just str.split(","), but handling cases // where we have nested braced sections, which should be // treated as individual members, like {a,{b,c},d} function parseCommaParts(str) { - if (!str) - return ['']; - var parts = []; - var m = balanced('{', '}', str); - if (!m) - return str.split(','); + // Walk the brace groups iteratively. Recursing on `post` once per group let a + // chain of them exhaust the stack - the parsing-side counterpart to + // the `expand` overflow fixed for CVE-2026-14257, and not something `max` or + // `maxLength` can bound, since it happens before expansion. + // + // The part the next chunk continues + var carry = ''; - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); + for (;;) { + var m = balanced('{', '}', str); - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); + if (!m) { + var tail = str.split(','); + tail[0] = carry + tail[0]; + pushAll(parts, tail); + return parts; + } + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[0] = carry + p[0]; + p[p.length-1] += '{' + body + '}'; + + if (!post.length) { + pushAll(parts, p); + return parts; + } + + carry = p.pop(); + pushAll(parts, p); + str = post; } - - parts.push.apply(parts, p); - - return parts; } function expandTop(str, options) { @@ -27558,7 +27589,10 @@ function requireBraceExpansion () { return []; options = options || {}; - var max = options.max == null ? Infinity : options.max; + var max = options.max == null ? EXPANSION_MAX : options.max; + var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength; + var maxDepth = options.maxDepth == null ? EXPANSION_MAX_DEPTH : options.maxDepth; + var maxRewrites = options.maxRewrites == null ? EXPANSION_MAX_REWRITES : options.maxRewrites; // I don't know why Bash 4.3 does this, but it does. // Anything starting with {} will have the first two bytes preserved @@ -27570,7 +27604,7 @@ function requireBraceExpansion () { str = '\\{\\}' + str.substr(2); } - return expand(escapeBraces(str), max, true).map(unescapeBraces); + return expand(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces); } function embrace(str) { @@ -27587,15 +27621,168 @@ function requireBraceExpansion () { return i >= y; } - function expand(str, max, isTop) { - var expansions = []; + // Build `{ acc[a] + pre + values[v] }` for every combination, capping the + // number of results at `max` and the total number of characters at `maxLength`. + // This is the one place output grows, so bounding it here keeps the single + // accumulator - and therefore memory - flat regardless of how many brace groups + // are combined (CVE-2026-14257). + // + // `base[a]` is the length of the part of `acc[a]` that predates the current + // empty-drop baseline (see `expand`). The matching baselines for the results + // are appended to `outBase`, which the caller carries forward alongside them. + function combine( + acc, + base, + pre, + values, + max, + maxLength, + dropEmpties, + outBase + ) { + var out = []; + var length = 0; + for (var a = 0; a < acc.length; a++) { + for (var v = 0; v < values.length; v++) { + if (out.length >= max) return out + var expansion = acc[a] + pre + values[v]; + // Bash drops empty results at the top level. Skip them before they count + // against `max`, so `max` bounds the number of *kept* results. "Empty" + // means "adds nothing past the baseline", not "empty overall". + if (dropEmpties && expansion.length === base[a]) continue + if (length + expansion.length > maxLength) return out + out.push(expansion); + outBase.push(base[a]); + length += expansion.length; + } + } + return out + } + + // The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`) + // sequence body. + function expandSequence( + body, + isAlphaSequence, + max, + maxLength + ) { + var n = body.split(/\.\./); + var N = []; + // A sequence body always splits into two or three parts, but the compiler + // can't know that. + /* c8 ignore start */ + if (n[0] === undefined || n[1] === undefined) { + return N + } + /* c8 ignore stop */ + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length); + var incr = + n.length === 3 && n[2] !== undefined ? + Math.max(Math.abs(numeric(n[2])), 1) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + var length = 0; + for (var i = x; test(i, y) && N.length < max; i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') { + c = ''; + } + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) { + c = '-' + z + c.slice(1); + } else { + c = z + c; + } + } + } + } + if (length + c.length > maxLength) break + N.push(c); + length += c.length; + } + return N + } + + function expand( + str, + max, + maxLength, + maxDepth, + depth, + maxRewrites, + isTop + ) { + // Too deeply nested to keep following: treat the rest as literal, the same + // way a group that cannot expand is already handled. Truncating rather than + // throwing keeps expansion total, matching `max` and `maxLength`. + if (depth > maxDepth) { + return [str]; + } + + // Consume the string's top-level brace groups left to right, threading a + // running set of combined prefixes (`acc`). Expanding the tail iteratively - + // rather than recursing on `m.post` once per group - keeps the native stack + // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no + // longer overflow the stack, and leaves a single accumulator whose size + // `maxLength` bounds directly (CVE-2026-14257). + var acc = ['']; + + // Bash drops empty results, but only when the *first* group of the run is a + // comma set - a sequence like `{a..\}` may legitimately yield ''. The drop + // is on the final strings, so it is applied to whichever `combine` produces + // them (the one with no brace set left in the tail). + // + // The old implementation recursed on `m.post`, so the drop tested only the + // expansion of the current call's substring. The `{a},b}` rewrite below turns + // `isTop` back on part-way through a string, starting a fresh such run, so + // the drop must ignore whatever `acc` already holds from earlier groups. + // `accBase[a]` records how much of `acc[a]` predates the current run; + // `combine` treats an expansion as empty when it adds nothing past that. + var accBase = [0]; + // How many times the `{a},b}` rewrite below has restarted the scan. Each pass + // re-reads the whole string, so leaving this unbounded is quadratic. + var rewrites = 0; + var dropEmpties = false; + var firstGroup = true; + var nextBase; - // The `{a},b}` rewrite below restarts expansion on a rewritten string with - // the same `max` and `isTop = true`. Loop instead of recursing so a long run - // of non-expanding `{}` groups can't exhaust the call stack. for (;;) { var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; + + // No brace set left: the rest of the string is literal. + if (!m) { + return combine(acc, accBase, str, [''], max, maxLength, dropEmpties, []) + } + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + + // For compatibility reasons, `${` is not eligible for brace expansion, and + // on the 1.x line it suppresses expansion of the rest of the string too: + // the whole remainder is literal. The 2.x and 5.x lines instead keep + // expanding the tail, which is what bash does, but changing that here would + // be a breaking change for 1.x consumers. Routed through `combine` so the + // result is still bounded by `max` and `maxLength`. + if (/\$$/.test(pre)) { + return combine(acc, accBase, str, [''], max, maxLength, dropEmpties, []) + } var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); @@ -27603,96 +27790,115 @@ function requireBraceExpansion () { var isOptions = m.body.indexOf(',') >= 0; if (!isSequence && !isOptions) { // {a},b} - if (m.post.match(/,(?!,).*\}/)) { + if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) { + rewrites++; str = m.pre + '{' + m.body + escClose + m.post; + // The rewritten string is expanded as if it were a fresh top-level one, + // so start a new empty-drop run: anchor the baseline at what `acc` + // holds now, and let the next expanding group decide whether to drop. isTop = true; + firstGroup = true; + dropEmpties = false; + accBase = []; + for (var b = 0; b < acc.length; b++) { + accBase.push(acc[b].length); + } continue } - return [str]; + // Nothing here expands, so the whole remaining string is literal. + return combine( + acc, + accBase, + pre + '{' + m.body + '}' + m.post, + [''], + max, + maxLength, + dropEmpties, + [] + ) } - var n; + if (firstGroup) { + dropEmpties = isTop && !isSequence; + firstGroup = false; + } + + var values; if (isSequence) { - n = m.body.split(/\.\./); + values = expandSequence(m.body, isAlphaSequence, max, maxLength); } else { - n = parseCommaParts(m.body); - if (n.length === 1) { + var n = parseCommaParts(m.body); + if (n.length === 1 && n[0] !== undefined) { // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], max, false).map(embrace); + n = expand(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace); + //XXX is this necessary? Can't seem to hit it in tests. + /* c8 ignore start */ if (n.length === 1) { - var post = m.post.length - ? expand(m.post, max, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); + nextBase = []; + acc = combine( + acc, + accBase, + pre + n[0], + [''], + max, + maxLength, + dropEmpties && !m.post.length, + nextBase + ); + accBase = nextBase; + if (!m.post.length) break + str = m.post; + continue + } + /* c8 ignore stop */ + } + + // Values that `combine` is going to drop as empty produce no result, so + // they must not count against `max` - otherwise `{a,,b}` with `max: 2` + // would stop at `['a', '']` and yield one result instead of two. Skipping + // them outright keeps `values` bounded while leaving `max` a bound on + // *kept* results. A value is dropped when it adds nothing past the + // baseline, which is what `combine` tests. + var dropsEmpties = dropEmpties && !m.post.length && !pre; + for (var d = 0; dropsEmpties && d < acc.length; d++) { + if (acc[d].length !== accBase[d]) { + dropsEmpties = false; } } - } - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, max, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length); - var incr = n.length == 3 - ? Math.max(Math.abs(numeric(n[2])), 1) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y) && N.length < max; i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } + values = []; + var valuesLength = 0; + outer: for (var j = 0; j < n.length; j++) { + var expanded = expand(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, false); + for (var k = 0; k < expanded.length; k++) { + var v = expanded[k]; + if (dropsEmpties && !v) continue + if (values.length >= max || valuesLength + v.length > maxLength) { + break outer } + values.push(v); + valuesLength += v.length; } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, max, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length && expansions.length < max; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); } } - return expansions; + nextBase = []; + acc = combine( + acc, + accBase, + pre, + values, + max, + maxLength, + dropEmpties && !m.post.length, + nextBase + ); + accBase = nextBase; + if (!m.post.length) break + str = m.post; } + + return acc } return braceExpansion; } @@ -31271,20 +31477,20 @@ function requireUuid () { return uuid_1; } -var constants$a = {}; +var constants$b = {}; -var hasRequiredConstants$a; +var hasRequiredConstants$b; -function requireConstants$a () { - if (hasRequiredConstants$a) return constants$a; - hasRequiredConstants$a = 1; - Object.defineProperty(constants$a, "__esModule", { value: true }); - constants$a.ManifestFilename = constants$a.TarFilename = constants$a.SystemTarPathOnWindows = constants$a.GnuTarPathOnWindows = constants$a.SocketTimeout = constants$a.DefaultRetryDelay = constants$a.DefaultRetryAttempts = constants$a.ArchiveToolType = constants$a.CompressionMethod = constants$a.CacheFilename = void 0; +function requireConstants$b () { + if (hasRequiredConstants$b) return constants$b; + hasRequiredConstants$b = 1; + Object.defineProperty(constants$b, "__esModule", { value: true }); + constants$b.ManifestFilename = constants$b.TarFilename = constants$b.SystemTarPathOnWindows = constants$b.GnuTarPathOnWindows = constants$b.SocketTimeout = constants$b.DefaultRetryDelay = constants$b.DefaultRetryAttempts = constants$b.ArchiveToolType = constants$b.CompressionMethod = constants$b.CacheFilename = void 0; var CacheFilename; (function (CacheFilename) { CacheFilename["Gzip"] = "cache.tgz"; CacheFilename["Zstd"] = "cache.tzst"; - })(CacheFilename || (constants$a.CacheFilename = CacheFilename = {})); + })(CacheFilename || (constants$b.CacheFilename = CacheFilename = {})); var CompressionMethod; (function (CompressionMethod) { CompressionMethod["Gzip"] = "gzip"; @@ -31292,28 +31498,28 @@ function requireConstants$a () { // This enum is for earlier version of zstd that does not have --long support CompressionMethod["ZstdWithoutLong"] = "zstd-without-long"; CompressionMethod["Zstd"] = "zstd"; - })(CompressionMethod || (constants$a.CompressionMethod = CompressionMethod = {})); + })(CompressionMethod || (constants$b.CompressionMethod = CompressionMethod = {})); var ArchiveToolType; (function (ArchiveToolType) { ArchiveToolType["GNU"] = "gnu"; ArchiveToolType["BSD"] = "bsd"; - })(ArchiveToolType || (constants$a.ArchiveToolType = ArchiveToolType = {})); + })(ArchiveToolType || (constants$b.ArchiveToolType = ArchiveToolType = {})); // The default number of retry attempts. - constants$a.DefaultRetryAttempts = 2; + constants$b.DefaultRetryAttempts = 2; // The default delay in milliseconds between retry attempts. - constants$a.DefaultRetryDelay = 5000; + constants$b.DefaultRetryDelay = 5000; // Socket timeout in milliseconds during download. If no traffic is received // over the socket during this period, the socket is destroyed and the download // is aborted. - constants$a.SocketTimeout = 5000; + constants$b.SocketTimeout = 5000; // The default path of GNUtar on hosted Windows runners - constants$a.GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`; + constants$b.GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`; // The default path of BSDtar on hosted Windows runners - constants$a.SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`; - constants$a.TarFilename = 'cache.tar'; - constants$a.ManifestFilename = 'manifest.txt'; + constants$b.SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`; + constants$b.TarFilename = 'cache.tar'; + constants$b.ManifestFilename = 'manifest.txt'; - return constants$a; + return constants$b; } var hasRequiredCacheUtils; @@ -31371,7 +31577,7 @@ function requireCacheUtils () { const semver = __importStar(requireSemver()); const util = __importStar(require$$0__default$1); const uuid_1 = requireUuid(); - const constants_1 = requireConstants$a(); + const constants_1 = requireConstants$b(); // From https://github.com/actions/toolkit/blob/main/packages/tool-cache/src/tool-cache.ts#L23 function createTempDirectory() { return __awaiter(this, void 0, void 0, function* () { @@ -32034,12 +32240,12 @@ function requireErrors$1 () { return errors$1; } -var constants$9; -var hasRequiredConstants$9; +var constants$a; +var hasRequiredConstants$a; -function requireConstants$9 () { - if (hasRequiredConstants$9) return constants$9; - hasRequiredConstants$9 = 1; +function requireConstants$a () { + if (hasRequiredConstants$a) return constants$a; + hasRequiredConstants$a = 1; /** @type {Record} */ const headerNameLowerCasedRecord = {}; @@ -32153,11 +32359,11 @@ function requireConstants$9 () { // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. Object.setPrototypeOf(headerNameLowerCasedRecord, null); - constants$9 = { + constants$a = { wellknownHeaderNames, headerNameLowerCasedRecord }; - return constants$9; + return constants$a; } var util$b; @@ -32176,7 +32382,7 @@ function requireUtil$b () { const { Blob } = require$$0__default; const nodeUtil = require$$0__default$1; const { stringify } = require$$1$1; - const { headerNameLowerCasedRecord } = requireConstants$9(); + const { headerNameLowerCasedRecord } = requireConstants$a(); const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)); @@ -32795,12 +33001,12 @@ function requireTimers () { return timers; } -var constants$8; -var hasRequiredConstants$8; +var constants$9; +var hasRequiredConstants$9; -function requireConstants$8 () { - if (hasRequiredConstants$8) return constants$8; - hasRequiredConstants$8 = 1; +function requireConstants$9 () { + if (hasRequiredConstants$9) return constants$9; + hasRequiredConstants$9 = 1; const { MessageChannel, receiveMessageOnPort } = require$$0$9; @@ -32926,7 +33132,7 @@ function requireConstants$8 () { return receiveMessageOnPort(channel.port2).message }; - constants$8 = { + constants$9 = { DOMException, structuredClone, subresource, @@ -32951,7 +33157,7 @@ function requireConstants$8 () { forbiddenMethodsSet, referrerPolicySet }; - return constants$8; + return constants$9; } var global$2; @@ -33009,7 +33215,7 @@ function requireUtil$a () { if (hasRequiredUtil$a) return util$a; hasRequiredUtil$a = 1; - const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = requireConstants$8(); + const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = requireConstants$9(); const { getGlobalOrigin } = requireGlobal$1(); const { performance } = require$$2$2; const { isBlobLike, toUSVString, ReadableStreamFrom } = requireUtil$b(); @@ -35461,12 +35667,12 @@ function requireDataURL () { return dataURL; } -var file$2; -var hasRequiredFile$2; +var file$3; +var hasRequiredFile$3; -function requireFile$2 () { - if (hasRequiredFile$2) return file$2; - hasRequiredFile$2 = 1; +function requireFile$3 () { + if (hasRequiredFile$3) return file$3; + hasRequiredFile$3 = 1; const { Blob, File: NativeFile } = require$$0__default; const { types } = require$$0__default$1; @@ -35809,8 +36015,8 @@ function requireFile$2 () { ) } - file$2 = { File, FileLike, isFileLike }; - return file$2; + file$3 = { File, FileLike, isFileLike }; + return file$3; } var formdata; @@ -35822,7 +36028,7 @@ function requireFormdata () { const { isBlobLike, toUSVString, makeIterator } = requireUtil$a(); const { kState } = requireSymbols$3(); - const { File: UndiciFile, FileLike, isFileLike } = requireFile$2(); + const { File: UndiciFile, FileLike, isFileLike } = requireFile$3(); const { webidl } = requireWebidl(); const { Blob, File: NativeFile } = require$$0__default; @@ -36106,13 +36312,13 @@ function requireBody () { const { FormData } = requireFormdata(); const { kState } = requireSymbols$3(); const { webidl } = requireWebidl(); - const { DOMException, structuredClone } = requireConstants$8(); + const { DOMException, structuredClone } = requireConstants$9(); const { Blob, File: NativeFile } = require$$0__default; const { kBodyUsed } = requireSymbols$4(); const assert$1 = assert; const { isErrored } = requireUtil$b(); const { isUint8Array, isArrayBuffer } = require$$5; - const { File: UndiciFile } = requireFile$2(); + const { File: UndiciFile } = requireFile$3(); const { parseMIMEType, serializeAMimeType } = requireDataURL(); let random; @@ -37638,7 +37844,7 @@ function requireConnect () { return connect; } -var constants$7 = {}; +var constants$8 = {}; var utils$3 = {}; @@ -37664,11 +37870,11 @@ function requireUtils$5 () { return utils$3; } -var hasRequiredConstants$7; +var hasRequiredConstants$8; -function requireConstants$7 () { - if (hasRequiredConstants$7) return constants$7; - hasRequiredConstants$7 = 1; +function requireConstants$8 () { + if (hasRequiredConstants$8) return constants$8; + hasRequiredConstants$8 = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; @@ -37941,8 +38147,8 @@ function requireConstants$7 () { 'upgrade': HEADER_STATE.UPGRADE, }; - } (constants$7)); - return constants$7; + } (constants$8)); + return constants$8; } var RedirectHandler_1; @@ -38692,7 +38898,7 @@ function requireClient () { resume(client); } - const constants = requireConstants$7(); + const constants = requireConstants$8(); const createRedirectInterceptor = requireRedirectInterceptor(); const EMPTY_BUF = Buffer.alloc(0); @@ -45018,7 +45224,7 @@ function requireResponse$1 () { redirectStatusSet, nullBodyStatus, DOMException - } = requireConstants$8(); + } = requireConstants$9(); const { kState, kHeaders, kGuard, kRealm } = requireSymbols$3(); const { webidl } = requireWebidl(); const { FormData } = requireFormdata(); @@ -45602,7 +45808,7 @@ function requireRequest () { requestCredentials, requestCache, requestDuplex - } = requireConstants$8(); + } = requireConstants$9(); const { kEnumerableProperty } = util; const { kHeaders, kSignal, kState, kGuard, kRealm } = requireSymbols$3(); const { webidl } = requireWebidl(); @@ -46584,7 +46790,7 @@ function requireFetch () { requestBodyHeader, subresourceSet, DOMException - } = requireConstants$8(); + } = requireConstants$9(); const { kHeadersList } = requireSymbols$4(); const EE = require$$0__default$3; const { Readable, pipeline } = require$$0__default$2; @@ -49025,7 +49231,7 @@ function requireUtil$8 () { } = requireSymbols$2(); const { ProgressEvent } = requireProgressevent(); const { getEncoding } = requireEncoding(); - const { DOMException } = requireConstants$8(); + const { DOMException } = requireConstants$9(); const { serializeAMimeType, parseMIMEType } = requireDataURL(); const { types } = require$$0__default$1; const { StringDecoder } = require$$6; @@ -50829,12 +51035,12 @@ function requireCachestorage () { return cachestorage; } -var constants$6; -var hasRequiredConstants$6; +var constants$7; +var hasRequiredConstants$7; -function requireConstants$6 () { - if (hasRequiredConstants$6) return constants$6; - hasRequiredConstants$6 = 1; +function requireConstants$7 () { + if (hasRequiredConstants$7) return constants$7; + hasRequiredConstants$7 = 1; // https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size const maxAttributeValueSize = 1024; @@ -50842,11 +51048,11 @@ function requireConstants$6 () { // https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size const maxNameValuePairSize = 4096; - constants$6 = { + constants$7 = { maxAttributeValueSize, maxNameValuePairSize }; - return constants$6; + return constants$7; } var util$6; @@ -51138,7 +51344,7 @@ function requireParse$1 () { if (hasRequiredParse$1) return parse$4; hasRequiredParse$1 = 1; - const { maxNameValuePairSize, maxAttributeValueSize } = requireConstants$6(); + const { maxNameValuePairSize, maxAttributeValueSize } = requireConstants$7(); const { isCTLExcludingHtab } = requireUtil$6(); const { collectASequenceOfCodePointsFast } = requireDataURL(); const assert$1 = assert; @@ -51647,12 +51853,12 @@ function requireCookies () { return cookies; } -var constants$5; -var hasRequiredConstants$5; +var constants$6; +var hasRequiredConstants$6; -function requireConstants$5 () { - if (hasRequiredConstants$5) return constants$5; - hasRequiredConstants$5 = 1; +function requireConstants$6 () { + if (hasRequiredConstants$6) return constants$6; + hasRequiredConstants$6 = 1; // This is a Globally Unique Identifier unique used // to validate that the endpoint accepts websocket @@ -51694,7 +51900,7 @@ function requireConstants$5 () { const emptyBuffer = Buffer.allocUnsafe(0); - constants$5 = { + constants$6 = { uid, staticPropertyDescriptors, states, @@ -51703,7 +51909,7 @@ function requireConstants$5 () { parserStates, emptyBuffer }; - return constants$5; + return constants$6; } var symbols; @@ -52045,7 +52251,7 @@ function requireUtil$5 () { hasRequiredUtil$5 = 1; const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = requireSymbols(); - const { states, opcodes } = requireConstants$5(); + const { states, opcodes } = requireConstants$6(); const { MessageEvent, ErrorEvent } = requireEvents(); /* globals Blob */ @@ -52253,7 +52459,7 @@ function requireConnection () { hasRequiredConnection = 1; const diagnosticsChannel = require$$0$a; - const { uid, states } = requireConstants$5(); + const { uid, states } = requireConstants$6(); const { kReadyState, kSentClose, @@ -52551,7 +52757,7 @@ function requireFrame () { if (hasRequiredFrame) return frame; hasRequiredFrame = 1; - const { maxUnsigned16Bit } = requireConstants$5(); + const { maxUnsigned16Bit } = requireConstants$6(); /** @type {import('crypto')} */ let crypto; @@ -52634,7 +52840,7 @@ function requireReceiver () { const { Writable } = require$$0__default$2; const diagnosticsChannel = require$$0$a; - const { parserStates, opcodes, states, emptyBuffer } = requireConstants$5(); + const { parserStates, opcodes, states, emptyBuffer } = requireConstants$6(); const { kReadyState, kSentClose, kResponse, kReceivedClose } = requireSymbols(); const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = requireUtil$5(); const { WebsocketFrameSend } = requireFrame(); @@ -52985,10 +53191,10 @@ function requireWebsocket () { hasRequiredWebsocket = 1; const { webidl } = requireWebidl(); - const { DOMException } = requireConstants$8(); + const { DOMException } = requireConstants$9(); const { URLSerializer } = requireDataURL(); const { getGlobalOrigin } = requireGlobal$1(); - const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = requireConstants$5(); + const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = requireConstants$6(); const { kWebSocketURL, kReadyState, @@ -53748,7 +53954,7 @@ function requireUndici () { undici.Response = requireResponse$1().Response; undici.Request = requireRequest().Request; undici.FormData = requireFormdata().FormData; - undici.File = requireFile$2().File; + undici.File = requireFile$3().File; undici.FileReader = requireFilereader().FileReader; const { setGlobalOrigin, getGlobalOrigin } = requireGlobal$1(); @@ -54737,13 +54943,13 @@ var beforeAfterHookExports = requireBeforeAfterHook(); const VERSION$5 = "9.0.6"; -const userAgent$2 = `octokit-endpoint.js/${VERSION$5} ${getUserAgent()}`; +const userAgent$3 = `octokit-endpoint.js/${VERSION$5} ${getUserAgent()}`; const DEFAULTS = { method: "GET", baseUrl: "https://api.github.com", headers: { accept: "application/vnd.github.v3+json", - "user-agent": userAgent$2 + "user-agent": userAgent$3 }, mediaType: { format: "" @@ -58390,7 +58596,7 @@ function requireRequestUtils () { requestUtils.retryHttpClientResponse = requestUtils.retryTypedResponse = requestUtils.retry = requestUtils.isRetryableStatusCode = requestUtils.isServerErrorStatusCode = requestUtils.isSuccessStatusCode = void 0; const core = __importStar(requireCore()); const http_client_1 = requireLib$3(); - const constants_1 = requireConstants$a(); + const constants_1 = requireConstants$b(); function isSuccessStatusCode(statusCode) { if (!statusCode) { return false; @@ -136729,1300 +136935,1300 @@ function requireUrlStateMachine () { if (hasRequiredUrlStateMachine) return urlStateMachine.exports; hasRequiredUrlStateMachine = 1; (function (module) { - const punycode = require$$0$b; - const tr46 = requireTr46(); - - const specialSchemes = { - ftp: 21, - file: null, - gopher: 70, - http: 80, - https: 443, - ws: 80, - wss: 443 - }; - - const failure = Symbol("failure"); - - function countSymbols(str) { - return punycode.ucs2.decode(str).length; - } - - function at(input, idx) { - const c = input[idx]; - return isNaN(c) ? undefined : String.fromCodePoint(c); - } - - function isASCIIDigit(c) { - return c >= 0x30 && c <= 0x39; - } - - function isASCIIAlpha(c) { - return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); - } - - function isASCIIAlphanumeric(c) { - return isASCIIAlpha(c) || isASCIIDigit(c); - } - - function isASCIIHex(c) { - return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); - } - - function isSingleDot(buffer) { - return buffer === "." || buffer.toLowerCase() === "%2e"; - } - - function isDoubleDot(buffer) { - buffer = buffer.toLowerCase(); - return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; - } - - function isWindowsDriveLetterCodePoints(cp1, cp2) { - return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); - } - - function isWindowsDriveLetterString(string) { - return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); - } - - function isNormalizedWindowsDriveLetterString(string) { - return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; - } - - function containsForbiddenHostCodePoint(string) { - return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; - } - - function containsForbiddenHostCodePointExcludingPercent(string) { - return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; - } - - function isSpecialScheme(scheme) { - return specialSchemes[scheme] !== undefined; - } - - function isSpecial(url) { - return isSpecialScheme(url.scheme); - } - - function defaultPort(scheme) { - return specialSchemes[scheme]; - } - - function percentEncode(c) { - let hex = c.toString(16).toUpperCase(); - if (hex.length === 1) { - hex = "0" + hex; - } - - return "%" + hex; - } - - function utf8PercentEncode(c) { - const buf = new Buffer(c); - - let str = ""; - - for (let i = 0; i < buf.length; ++i) { - str += percentEncode(buf[i]); - } - - return str; - } - - function utf8PercentDecode(str) { - const input = new Buffer(str); - const output = []; - for (let i = 0; i < input.length; ++i) { - if (input[i] !== 37) { - output.push(input[i]); - } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { - output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); - i += 2; - } else { - output.push(input[i]); - } - } - return new Buffer(output).toString(); - } - - function isC0ControlPercentEncode(c) { - return c <= 0x1F || c > 0x7E; - } - - const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); - function isPathPercentEncode(c) { - return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); - } - - const extraUserinfoPercentEncodeSet = - new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); - function isUserinfoPercentEncode(c) { - return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); - } - - function percentEncodeChar(c, encodeSetPredicate) { - const cStr = String.fromCodePoint(c); - - if (encodeSetPredicate(c)) { - return utf8PercentEncode(cStr); - } - - return cStr; - } - - function parseIPv4Number(input) { - let R = 10; - - if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { - input = input.substring(2); - R = 16; - } else if (input.length >= 2 && input.charAt(0) === "0") { - input = input.substring(1); - R = 8; - } - - if (input === "") { - return 0; - } - - const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); - if (regex.test(input)) { - return failure; - } - - return parseInt(input, R); - } - - function parseIPv4(input) { - const parts = input.split("."); - if (parts[parts.length - 1] === "") { - if (parts.length > 1) { - parts.pop(); - } - } - - if (parts.length > 4) { - return input; - } - - const numbers = []; - for (const part of parts) { - if (part === "") { - return input; - } - const n = parseIPv4Number(part); - if (n === failure) { - return input; - } - - numbers.push(n); - } - - for (let i = 0; i < numbers.length - 1; ++i) { - if (numbers[i] > 255) { - return failure; - } - } - if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { - return failure; - } - - let ipv4 = numbers.pop(); - let counter = 0; - - for (const n of numbers) { - ipv4 += n * Math.pow(256, 3 - counter); - ++counter; - } - - return ipv4; - } - - function serializeIPv4(address) { - let output = ""; - let n = address; - - for (let i = 1; i <= 4; ++i) { - output = String(n % 256) + output; - if (i !== 4) { - output = "." + output; - } - n = Math.floor(n / 256); - } - - return output; - } - - function parseIPv6(input) { - const address = [0, 0, 0, 0, 0, 0, 0, 0]; - let pieceIndex = 0; - let compress = null; - let pointer = 0; - - input = punycode.ucs2.decode(input); - - if (input[pointer] === 58) { - if (input[pointer + 1] !== 58) { - return failure; - } - - pointer += 2; - ++pieceIndex; - compress = pieceIndex; - } - - while (pointer < input.length) { - if (pieceIndex === 8) { - return failure; - } - - if (input[pointer] === 58) { - if (compress !== null) { - return failure; - } - ++pointer; - ++pieceIndex; - compress = pieceIndex; - continue; - } - - let value = 0; - let length = 0; - - while (length < 4 && isASCIIHex(input[pointer])) { - value = value * 0x10 + parseInt(at(input, pointer), 16); - ++pointer; - ++length; - } - - if (input[pointer] === 46) { - if (length === 0) { - return failure; - } - - pointer -= length; - - if (pieceIndex > 6) { - return failure; - } - - let numbersSeen = 0; - - while (input[pointer] !== undefined) { - let ipv4Piece = null; - - if (numbersSeen > 0) { - if (input[pointer] === 46 && numbersSeen < 4) { - ++pointer; - } else { - return failure; - } - } - - if (!isASCIIDigit(input[pointer])) { - return failure; - } - - while (isASCIIDigit(input[pointer])) { - const number = parseInt(at(input, pointer)); - if (ipv4Piece === null) { - ipv4Piece = number; - } else if (ipv4Piece === 0) { - return failure; - } else { - ipv4Piece = ipv4Piece * 10 + number; - } - if (ipv4Piece > 255) { - return failure; - } - ++pointer; - } - - address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; - - ++numbersSeen; - - if (numbersSeen === 2 || numbersSeen === 4) { - ++pieceIndex; - } - } - - if (numbersSeen !== 4) { - return failure; - } - - break; - } else if (input[pointer] === 58) { - ++pointer; - if (input[pointer] === undefined) { - return failure; - } - } else if (input[pointer] !== undefined) { - return failure; - } - - address[pieceIndex] = value; - ++pieceIndex; - } - - if (compress !== null) { - let swaps = pieceIndex - compress; - pieceIndex = 7; - while (pieceIndex !== 0 && swaps > 0) { - const temp = address[compress + swaps - 1]; - address[compress + swaps - 1] = address[pieceIndex]; - address[pieceIndex] = temp; - --pieceIndex; - --swaps; - } - } else if (compress === null && pieceIndex !== 8) { - return failure; - } - - return address; - } - - function serializeIPv6(address) { - let output = ""; - const seqResult = findLongestZeroSequence(address); - const compress = seqResult.idx; - let ignore0 = false; - - for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { - if (ignore0 && address[pieceIndex] === 0) { - continue; - } else if (ignore0) { - ignore0 = false; - } - - if (compress === pieceIndex) { - const separator = pieceIndex === 0 ? "::" : ":"; - output += separator; - ignore0 = true; - continue; - } - - output += address[pieceIndex].toString(16); - - if (pieceIndex !== 7) { - output += ":"; - } - } - - return output; - } - - function parseHost(input, isSpecialArg) { - if (input[0] === "[") { - if (input[input.length - 1] !== "]") { - return failure; - } - - return parseIPv6(input.substring(1, input.length - 1)); - } - - if (!isSpecialArg) { - return parseOpaqueHost(input); - } - - const domain = utf8PercentDecode(input); - const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); - if (asciiDomain === null) { - return failure; - } - - if (containsForbiddenHostCodePoint(asciiDomain)) { - return failure; - } - - const ipv4Host = parseIPv4(asciiDomain); - if (typeof ipv4Host === "number" || ipv4Host === failure) { - return ipv4Host; - } - - return asciiDomain; - } - - function parseOpaqueHost(input) { - if (containsForbiddenHostCodePointExcludingPercent(input)) { - return failure; - } - - let output = ""; - const decoded = punycode.ucs2.decode(input); - for (let i = 0; i < decoded.length; ++i) { - output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); - } - return output; - } - - function findLongestZeroSequence(arr) { - let maxIdx = null; - let maxLen = 1; // only find elements > 1 - let currStart = null; - let currLen = 0; - - for (let i = 0; i < arr.length; ++i) { - if (arr[i] !== 0) { - if (currLen > maxLen) { - maxIdx = currStart; - maxLen = currLen; - } - - currStart = null; - currLen = 0; - } else { - if (currStart === null) { - currStart = i; - } - ++currLen; - } - } - - // if trailing zeros - if (currLen > maxLen) { - maxIdx = currStart; - maxLen = currLen; - } - - return { - idx: maxIdx, - len: maxLen - }; - } - - function serializeHost(host) { - if (typeof host === "number") { - return serializeIPv4(host); - } - - // IPv6 serializer - if (host instanceof Array) { - return "[" + serializeIPv6(host) + "]"; - } - - return host; - } - - function trimControlChars(url) { - return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); - } - - function trimTabAndNewline(url) { - return url.replace(/\u0009|\u000A|\u000D/g, ""); - } - - function shortenPath(url) { - const path = url.path; - if (path.length === 0) { - return; - } - if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { - return; - } - - path.pop(); - } - - function includesCredentials(url) { - return url.username !== "" || url.password !== ""; - } - - function cannotHaveAUsernamePasswordPort(url) { - return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; - } - - function isNormalizedWindowsDriveLetter(string) { - return /^[A-Za-z]:$/.test(string); - } - - function URLStateMachine(input, base, encodingOverride, url, stateOverride) { - this.pointer = 0; - this.input = input; - this.base = base || null; - this.encodingOverride = encodingOverride || "utf-8"; - this.stateOverride = stateOverride; - this.url = url; - this.failure = false; - this.parseError = false; - - if (!this.url) { - this.url = { - scheme: "", - username: "", - password: "", - host: null, - port: null, - path: [], - query: null, - fragment: null, - - cannotBeABaseURL: false - }; - - const res = trimControlChars(this.input); - if (res !== this.input) { - this.parseError = true; - } - this.input = res; - } - - const res = trimTabAndNewline(this.input); - if (res !== this.input) { - this.parseError = true; - } - this.input = res; - - this.state = stateOverride || "scheme start"; - - this.buffer = ""; - this.atFlag = false; - this.arrFlag = false; - this.passwordTokenSeenFlag = false; - - this.input = punycode.ucs2.decode(this.input); - - for (; this.pointer <= this.input.length; ++this.pointer) { - const c = this.input[this.pointer]; - const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); - - // exec state machine - const ret = this["parse " + this.state](c, cStr); - if (!ret) { - break; // terminate algorithm - } else if (ret === failure) { - this.failure = true; - break; - } - } - } - - URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { - if (isASCIIAlpha(c)) { - this.buffer += cStr.toLowerCase(); - this.state = "scheme"; - } else if (!this.stateOverride) { - this.state = "no scheme"; - --this.pointer; - } else { - this.parseError = true; - return failure; - } - - return true; - }; - - URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { - if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { - this.buffer += cStr.toLowerCase(); - } else if (c === 58) { - if (this.stateOverride) { - if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { - return false; - } - - if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { - return false; - } - - if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { - return false; - } - - if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { - return false; - } - } - this.url.scheme = this.buffer; - this.buffer = ""; - if (this.stateOverride) { - return false; - } - if (this.url.scheme === "file") { - if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { - this.parseError = true; - } - this.state = "file"; - } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { - this.state = "special relative or authority"; - } else if (isSpecial(this.url)) { - this.state = "special authority slashes"; - } else if (this.input[this.pointer + 1] === 47) { - this.state = "path or authority"; - ++this.pointer; - } else { - this.url.cannotBeABaseURL = true; - this.url.path.push(""); - this.state = "cannot-be-a-base-URL path"; - } - } else if (!this.stateOverride) { - this.buffer = ""; - this.state = "no scheme"; - this.pointer = -1; - } else { - this.parseError = true; - return failure; - } - - return true; - }; - - URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { - if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { - return failure; - } else if (this.base.cannotBeABaseURL && c === 35) { - this.url.scheme = this.base.scheme; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.url.cannotBeABaseURL = true; - this.state = "fragment"; - } else if (this.base.scheme === "file") { - this.state = "file"; - --this.pointer; - } else { - this.state = "relative"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = "special authority ignore slashes"; - ++this.pointer; - } else { - this.parseError = true; - this.state = "relative"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { - if (c === 47) { - this.state = "authority"; - } else { - this.state = "path"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse relative"] = function parseRelative(c) { - this.url.scheme = this.base.scheme; - if (isNaN(c)) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - } else if (c === 47) { - this.state = "relative slash"; - } else if (c === 63) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.state = "fragment"; - } else if (isSpecial(this.url) && c === 92) { - this.parseError = true; - this.state = "relative slash"; - } else { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(0, this.base.path.length - 1); - - this.state = "path"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { - if (isSpecial(this.url) && (c === 47 || c === 92)) { - if (c === 92) { - this.parseError = true; - } - this.state = "special authority ignore slashes"; - } else if (c === 47) { - this.state = "authority"; - } else { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.state = "path"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = "special authority ignore slashes"; - ++this.pointer; - } else { - this.parseError = true; - this.state = "special authority ignore slashes"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { - if (c !== 47 && c !== 92) { - this.state = "authority"; - --this.pointer; - } else { - this.parseError = true; - } - - return true; - }; - - URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { - if (c === 64) { - this.parseError = true; - if (this.atFlag) { - this.buffer = "%40" + this.buffer; - } - this.atFlag = true; - - // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars - const len = countSymbols(this.buffer); - for (let pointer = 0; pointer < len; ++pointer) { - const codePoint = this.buffer.codePointAt(pointer); - - if (codePoint === 58 && !this.passwordTokenSeenFlag) { - this.passwordTokenSeenFlag = true; - continue; - } - const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); - if (this.passwordTokenSeenFlag) { - this.url.password += encodedCodePoints; - } else { - this.url.username += encodedCodePoints; - } - } - this.buffer = ""; - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92)) { - if (this.atFlag && this.buffer === "") { - this.parseError = true; - return failure; - } - this.pointer -= countSymbols(this.buffer) + 1; - this.buffer = ""; - this.state = "host"; - } else { - this.buffer += cStr; - } - - return true; - }; - - URLStateMachine.prototype["parse hostname"] = - URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { - if (this.stateOverride && this.url.scheme === "file") { - --this.pointer; - this.state = "file host"; - } else if (c === 58 && !this.arrFlag) { - if (this.buffer === "") { - this.parseError = true; - return failure; - } - - const host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - - this.url.host = host; - this.buffer = ""; - this.state = "port"; - if (this.stateOverride === "hostname") { - return false; - } - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92)) { - --this.pointer; - if (isSpecial(this.url) && this.buffer === "") { - this.parseError = true; - return failure; - } else if (this.stateOverride && this.buffer === "" && - (includesCredentials(this.url) || this.url.port !== null)) { - this.parseError = true; - return false; - } - - const host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - - this.url.host = host; - this.buffer = ""; - this.state = "path start"; - if (this.stateOverride) { - return false; - } - } else { - if (c === 91) { - this.arrFlag = true; - } else if (c === 93) { - this.arrFlag = false; - } - this.buffer += cStr; - } - - return true; - }; - - URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { - if (isASCIIDigit(c)) { - this.buffer += cStr; - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92) || - this.stateOverride) { - if (this.buffer !== "") { - const port = parseInt(this.buffer); - if (port > Math.pow(2, 16) - 1) { - this.parseError = true; - return failure; - } - this.url.port = port === defaultPort(this.url.scheme) ? null : port; - this.buffer = ""; - } - if (this.stateOverride) { - return false; - } - this.state = "path start"; - --this.pointer; - } else { - this.parseError = true; - return failure; - } - - return true; - }; - - const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); - - URLStateMachine.prototype["parse file"] = function parseFile(c) { - this.url.scheme = "file"; - - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true; - } - this.state = "file slash"; - } else if (this.base !== null && this.base.scheme === "file") { - if (isNaN(c)) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - } else if (c === 63) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.state = "fragment"; - } else { - if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points - !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || - (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points - !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - shortenPath(this.url); - } else { - this.parseError = true; - } - - this.state = "path"; - --this.pointer; - } - } else { - this.state = "path"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true; - } - this.state = "file host"; - } else { - if (this.base !== null && this.base.scheme === "file") { - if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { - this.url.path.push(this.base.path[0]); - } else { - this.url.host = this.base.host; - } - } - this.state = "path"; - --this.pointer; - } - - return true; - }; - - URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { - if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { - --this.pointer; - if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { - this.parseError = true; - this.state = "path"; - } else if (this.buffer === "") { - this.url.host = ""; - if (this.stateOverride) { - return false; - } - this.state = "path start"; - } else { - let host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - if (host === "localhost") { - host = ""; - } - this.url.host = host; - - if (this.stateOverride) { - return false; - } - - this.buffer = ""; - this.state = "path start"; - } - } else { - this.buffer += cStr; - } - - return true; - }; - - URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { - if (isSpecial(this.url)) { - if (c === 92) { - this.parseError = true; - } - this.state = "path"; - - if (c !== 47 && c !== 92) { - --this.pointer; - } - } else if (!this.stateOverride && c === 63) { - this.url.query = ""; - this.state = "query"; - } else if (!this.stateOverride && c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } else if (c !== undefined) { - this.state = "path"; - if (c !== 47) { - --this.pointer; - } - } - - return true; - }; - - URLStateMachine.prototype["parse path"] = function parsePath(c) { - if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || - (!this.stateOverride && (c === 63 || c === 35))) { - if (isSpecial(this.url) && c === 92) { - this.parseError = true; - } - - if (isDoubleDot(this.buffer)) { - shortenPath(this.url); - if (c !== 47 && !(isSpecial(this.url) && c === 92)) { - this.url.path.push(""); - } - } else if (isSingleDot(this.buffer) && c !== 47 && - !(isSpecial(this.url) && c === 92)) { - this.url.path.push(""); - } else if (!isSingleDot(this.buffer)) { - if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { - if (this.url.host !== "" && this.url.host !== null) { - this.parseError = true; - this.url.host = ""; - } - this.buffer = this.buffer[0] + ":"; - } - this.url.path.push(this.buffer); - } - this.buffer = ""; - if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { - while (this.url.path.length > 1 && this.url.path[0] === "") { - this.parseError = true; - this.url.path.shift(); - } - } - if (c === 63) { - this.url.query = ""; - this.state = "query"; - } - if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.buffer += percentEncodeChar(c, isPathPercentEncode); - } - - return true; - }; - - URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { - if (c === 63) { - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } else { - // TODO: Add: not a URL code point - if (!isNaN(c) && c !== 37) { - this.parseError = true; - } - - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - if (!isNaN(c)) { - this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); - } - } - - return true; - }; - - URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { - if (isNaN(c) || (!this.stateOverride && c === 35)) { - if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { - this.encodingOverride = "utf-8"; - } - - const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead - for (let i = 0; i < buffer.length; ++i) { - if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || - buffer[i] === 0x3C || buffer[i] === 0x3E) { - this.url.query += percentEncode(buffer[i]); - } else { - this.url.query += String.fromCodePoint(buffer[i]); - } - } - - this.buffer = ""; - if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.buffer += cStr; - } - - return true; - }; - - URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { - if (isNaN(c)) ; else if (c === 0x0) { - this.parseError = true; - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); - } - - return true; - }; - - function serializeURL(url, excludeFragment) { - let output = url.scheme + ":"; - if (url.host !== null) { - output += "//"; - - if (url.username !== "" || url.password !== "") { - output += url.username; - if (url.password !== "") { - output += ":" + url.password; - } - output += "@"; - } - - output += serializeHost(url.host); - - if (url.port !== null) { - output += ":" + url.port; - } - } else if (url.host === null && url.scheme === "file") { - output += "//"; - } - - if (url.cannotBeABaseURL) { - output += url.path[0]; - } else { - for (const string of url.path) { - output += "/" + string; - } - } - - if (url.query !== null) { - output += "?" + url.query; - } - - if (!excludeFragment && url.fragment !== null) { - output += "#" + url.fragment; - } - - return output; - } - - function serializeOrigin(tuple) { - let result = tuple.scheme + "://"; - result += serializeHost(tuple.host); - - if (tuple.port !== null) { - result += ":" + tuple.port; - } - - return result; - } - - module.exports.serializeURL = serializeURL; - - module.exports.serializeURLOrigin = function (url) { - // https://url.spec.whatwg.org/#concept-url-origin - switch (url.scheme) { - case "blob": - try { - return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); - } catch (e) { - // serializing an opaque origin returns "null" - return "null"; - } - case "ftp": - case "gopher": - case "http": - case "https": - case "ws": - case "wss": - return serializeOrigin({ - scheme: url.scheme, - host: url.host, - port: url.port - }); - case "file": - // spec says "exercise to the reader", chrome says "file://" - return "file://"; - default: - // serializing an opaque origin returns "null" - return "null"; - } - }; - - module.exports.basicURLParse = function (input, options) { - if (options === undefined) { - options = {}; - } - - const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); - if (usm.failure) { - return "failure"; - } - - return usm.url; - }; - - module.exports.setTheUsername = function (url, username) { - url.username = ""; - const decoded = punycode.ucs2.decode(username); - for (let i = 0; i < decoded.length; ++i) { - url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); - } - }; - - module.exports.setThePassword = function (url, password) { - url.password = ""; - const decoded = punycode.ucs2.decode(password); - for (let i = 0; i < decoded.length; ++i) { - url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); - } - }; - - module.exports.serializeHost = serializeHost; - - module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; - - module.exports.serializeInteger = function (integer) { - return String(integer); - }; - - module.exports.parseURL = function (input, options) { - if (options === undefined) { - options = {}; - } - - // We don't handle blobs, so this just delegates: - return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); + const punycode = require$$0$b; + const tr46 = requireTr46(); + + const specialSchemes = { + ftp: 21, + file: null, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443 + }; + + const failure = Symbol("failure"); + + function countSymbols(str) { + return punycode.ucs2.decode(str).length; + } + + function at(input, idx) { + const c = input[idx]; + return isNaN(c) ? undefined : String.fromCodePoint(c); + } + + function isASCIIDigit(c) { + return c >= 0x30 && c <= 0x39; + } + + function isASCIIAlpha(c) { + return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); + } + + function isASCIIAlphanumeric(c) { + return isASCIIAlpha(c) || isASCIIDigit(c); + } + + function isASCIIHex(c) { + return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); + } + + function isSingleDot(buffer) { + return buffer === "." || buffer.toLowerCase() === "%2e"; + } + + function isDoubleDot(buffer) { + buffer = buffer.toLowerCase(); + return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; + } + + function isWindowsDriveLetterCodePoints(cp1, cp2) { + return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); + } + + function isWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); + } + + function isNormalizedWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; + } + + function containsForbiddenHostCodePoint(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; + } + + function containsForbiddenHostCodePointExcludingPercent(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; + } + + function isSpecialScheme(scheme) { + return specialSchemes[scheme] !== undefined; + } + + function isSpecial(url) { + return isSpecialScheme(url.scheme); + } + + function defaultPort(scheme) { + return specialSchemes[scheme]; + } + + function percentEncode(c) { + let hex = c.toString(16).toUpperCase(); + if (hex.length === 1) { + hex = "0" + hex; + } + + return "%" + hex; + } + + function utf8PercentEncode(c) { + const buf = new Buffer(c); + + let str = ""; + + for (let i = 0; i < buf.length; ++i) { + str += percentEncode(buf[i]); + } + + return str; + } + + function utf8PercentDecode(str) { + const input = new Buffer(str); + const output = []; + for (let i = 0; i < input.length; ++i) { + if (input[i] !== 37) { + output.push(input[i]); + } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { + output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); + i += 2; + } else { + output.push(input[i]); + } + } + return new Buffer(output).toString(); + } + + function isC0ControlPercentEncode(c) { + return c <= 0x1F || c > 0x7E; + } + + const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); + function isPathPercentEncode(c) { + return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); + } + + const extraUserinfoPercentEncodeSet = + new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); + function isUserinfoPercentEncode(c) { + return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); + } + + function percentEncodeChar(c, encodeSetPredicate) { + const cStr = String.fromCodePoint(c); + + if (encodeSetPredicate(c)) { + return utf8PercentEncode(cStr); + } + + return cStr; + } + + function parseIPv4Number(input) { + let R = 10; + + if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { + input = input.substring(2); + R = 16; + } else if (input.length >= 2 && input.charAt(0) === "0") { + input = input.substring(1); + R = 8; + } + + if (input === "") { + return 0; + } + + const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); + if (regex.test(input)) { + return failure; + } + + return parseInt(input, R); + } + + function parseIPv4(input) { + const parts = input.split("."); + if (parts[parts.length - 1] === "") { + if (parts.length > 1) { + parts.pop(); + } + } + + if (parts.length > 4) { + return input; + } + + const numbers = []; + for (const part of parts) { + if (part === "") { + return input; + } + const n = parseIPv4Number(part); + if (n === failure) { + return input; + } + + numbers.push(n); + } + + for (let i = 0; i < numbers.length - 1; ++i) { + if (numbers[i] > 255) { + return failure; + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + return failure; + } + + let ipv4 = numbers.pop(); + let counter = 0; + + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter); + ++counter; + } + + return ipv4; + } + + function serializeIPv4(address) { + let output = ""; + let n = address; + + for (let i = 1; i <= 4; ++i) { + output = String(n % 256) + output; + if (i !== 4) { + output = "." + output; + } + n = Math.floor(n / 256); + } + + return output; + } + + function parseIPv6(input) { + const address = [0, 0, 0, 0, 0, 0, 0, 0]; + let pieceIndex = 0; + let compress = null; + let pointer = 0; + + input = punycode.ucs2.decode(input); + + if (input[pointer] === 58) { + if (input[pointer + 1] !== 58) { + return failure; + } + + pointer += 2; + ++pieceIndex; + compress = pieceIndex; + } + + while (pointer < input.length) { + if (pieceIndex === 8) { + return failure; + } + + if (input[pointer] === 58) { + if (compress !== null) { + return failure; + } + ++pointer; + ++pieceIndex; + compress = pieceIndex; + continue; + } + + let value = 0; + let length = 0; + + while (length < 4 && isASCIIHex(input[pointer])) { + value = value * 0x10 + parseInt(at(input, pointer), 16); + ++pointer; + ++length; + } + + if (input[pointer] === 46) { + if (length === 0) { + return failure; + } + + pointer -= length; + + if (pieceIndex > 6) { + return failure; + } + + let numbersSeen = 0; + + while (input[pointer] !== undefined) { + let ipv4Piece = null; + + if (numbersSeen > 0) { + if (input[pointer] === 46 && numbersSeen < 4) { + ++pointer; + } else { + return failure; + } + } + + if (!isASCIIDigit(input[pointer])) { + return failure; + } + + while (isASCIIDigit(input[pointer])) { + const number = parseInt(at(input, pointer)); + if (ipv4Piece === null) { + ipv4Piece = number; + } else if (ipv4Piece === 0) { + return failure; + } else { + ipv4Piece = ipv4Piece * 10 + number; + } + if (ipv4Piece > 255) { + return failure; + } + ++pointer; + } + + address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; + + ++numbersSeen; + + if (numbersSeen === 2 || numbersSeen === 4) { + ++pieceIndex; + } + } + + if (numbersSeen !== 4) { + return failure; + } + + break; + } else if (input[pointer] === 58) { + ++pointer; + if (input[pointer] === undefined) { + return failure; + } + } else if (input[pointer] !== undefined) { + return failure; + } + + address[pieceIndex] = value; + ++pieceIndex; + } + + if (compress !== null) { + let swaps = pieceIndex - compress; + pieceIndex = 7; + while (pieceIndex !== 0 && swaps > 0) { + const temp = address[compress + swaps - 1]; + address[compress + swaps - 1] = address[pieceIndex]; + address[pieceIndex] = temp; + --pieceIndex; + --swaps; + } + } else if (compress === null && pieceIndex !== 8) { + return failure; + } + + return address; + } + + function serializeIPv6(address) { + let output = ""; + const seqResult = findLongestZeroSequence(address); + const compress = seqResult.idx; + let ignore0 = false; + + for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { + if (ignore0 && address[pieceIndex] === 0) { + continue; + } else if (ignore0) { + ignore0 = false; + } + + if (compress === pieceIndex) { + const separator = pieceIndex === 0 ? "::" : ":"; + output += separator; + ignore0 = true; + continue; + } + + output += address[pieceIndex].toString(16); + + if (pieceIndex !== 7) { + output += ":"; + } + } + + return output; + } + + function parseHost(input, isSpecialArg) { + if (input[0] === "[") { + if (input[input.length - 1] !== "]") { + return failure; + } + + return parseIPv6(input.substring(1, input.length - 1)); + } + + if (!isSpecialArg) { + return parseOpaqueHost(input); + } + + const domain = utf8PercentDecode(input); + const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); + if (asciiDomain === null) { + return failure; + } + + if (containsForbiddenHostCodePoint(asciiDomain)) { + return failure; + } + + const ipv4Host = parseIPv4(asciiDomain); + if (typeof ipv4Host === "number" || ipv4Host === failure) { + return ipv4Host; + } + + return asciiDomain; + } + + function parseOpaqueHost(input) { + if (containsForbiddenHostCodePointExcludingPercent(input)) { + return failure; + } + + let output = ""; + const decoded = punycode.ucs2.decode(input); + for (let i = 0; i < decoded.length; ++i) { + output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); + } + return output; + } + + function findLongestZeroSequence(arr) { + let maxIdx = null; + let maxLen = 1; // only find elements > 1 + let currStart = null; + let currLen = 0; + + for (let i = 0; i < arr.length; ++i) { + if (arr[i] !== 0) { + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + currStart = null; + currLen = 0; + } else { + if (currStart === null) { + currStart = i; + } + ++currLen; + } + } + + // if trailing zeros + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + return { + idx: maxIdx, + len: maxLen + }; + } + + function serializeHost(host) { + if (typeof host === "number") { + return serializeIPv4(host); + } + + // IPv6 serializer + if (host instanceof Array) { + return "[" + serializeIPv6(host) + "]"; + } + + return host; + } + + function trimControlChars(url) { + return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); + } + + function trimTabAndNewline(url) { + return url.replace(/\u0009|\u000A|\u000D/g, ""); + } + + function shortenPath(url) { + const path = url.path; + if (path.length === 0) { + return; + } + if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { + return; + } + + path.pop(); + } + + function includesCredentials(url) { + return url.username !== "" || url.password !== ""; + } + + function cannotHaveAUsernamePasswordPort(url) { + return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; + } + + function isNormalizedWindowsDriveLetter(string) { + return /^[A-Za-z]:$/.test(string); + } + + function URLStateMachine(input, base, encodingOverride, url, stateOverride) { + this.pointer = 0; + this.input = input; + this.base = base || null; + this.encodingOverride = encodingOverride || "utf-8"; + this.stateOverride = stateOverride; + this.url = url; + this.failure = false; + this.parseError = false; + + if (!this.url) { + this.url = { + scheme: "", + username: "", + password: "", + host: null, + port: null, + path: [], + query: null, + fragment: null, + + cannotBeABaseURL: false + }; + + const res = trimControlChars(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + } + + const res = trimTabAndNewline(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + + this.state = stateOverride || "scheme start"; + + this.buffer = ""; + this.atFlag = false; + this.arrFlag = false; + this.passwordTokenSeenFlag = false; + + this.input = punycode.ucs2.decode(this.input); + + for (; this.pointer <= this.input.length; ++this.pointer) { + const c = this.input[this.pointer]; + const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); + + // exec state machine + const ret = this["parse " + this.state](c, cStr); + if (!ret) { + break; // terminate algorithm + } else if (ret === failure) { + this.failure = true; + break; + } + } + } + + URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { + if (isASCIIAlpha(c)) { + this.buffer += cStr.toLowerCase(); + this.state = "scheme"; + } else if (!this.stateOverride) { + this.state = "no scheme"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; + }; + + URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { + if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { + this.buffer += cStr.toLowerCase(); + } else if (c === 58) { + if (this.stateOverride) { + if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { + return false; + } + + if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { + return false; + } + + if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { + return false; + } + + if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { + return false; + } + } + this.url.scheme = this.buffer; + this.buffer = ""; + if (this.stateOverride) { + return false; + } + if (this.url.scheme === "file") { + if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { + this.parseError = true; + } + this.state = "file"; + } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { + this.state = "special relative or authority"; + } else if (isSpecial(this.url)) { + this.state = "special authority slashes"; + } else if (this.input[this.pointer + 1] === 47) { + this.state = "path or authority"; + ++this.pointer; + } else { + this.url.cannotBeABaseURL = true; + this.url.path.push(""); + this.state = "cannot-be-a-base-URL path"; + } + } else if (!this.stateOverride) { + this.buffer = ""; + this.state = "no scheme"; + this.pointer = -1; + } else { + this.parseError = true; + return failure; + } + + return true; + }; + + URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { + if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { + return failure; + } else if (this.base.cannotBeABaseURL && c === 35) { + this.url.scheme = this.base.scheme; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.url.cannotBeABaseURL = true; + this.state = "fragment"; + } else if (this.base.scheme === "file") { + this.state = "file"; + --this.pointer; + } else { + this.state = "relative"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "relative"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { + if (c === 47) { + this.state = "authority"; + } else { + this.state = "path"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse relative"] = function parseRelative(c) { + this.url.scheme = this.base.scheme; + if (isNaN(c)) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 47) { + this.state = "relative slash"; + } else if (c === 63) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else if (isSpecial(this.url) && c === 92) { + this.parseError = true; + this.state = "relative slash"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(0, this.base.path.length - 1); + + this.state = "path"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { + if (isSpecial(this.url) && (c === 47 || c === 92)) { + if (c === 92) { + this.parseError = true; + } + this.state = "special authority ignore slashes"; + } else if (c === 47) { + this.state = "authority"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.state = "path"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "special authority ignore slashes"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { + if (c !== 47 && c !== 92) { + this.state = "authority"; + --this.pointer; + } else { + this.parseError = true; + } + + return true; + }; + + URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { + if (c === 64) { + this.parseError = true; + if (this.atFlag) { + this.buffer = "%40" + this.buffer; + } + this.atFlag = true; + + // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars + const len = countSymbols(this.buffer); + for (let pointer = 0; pointer < len; ++pointer) { + const codePoint = this.buffer.codePointAt(pointer); + + if (codePoint === 58 && !this.passwordTokenSeenFlag) { + this.passwordTokenSeenFlag = true; + continue; + } + const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); + if (this.passwordTokenSeenFlag) { + this.url.password += encodedCodePoints; + } else { + this.url.username += encodedCodePoints; + } + } + this.buffer = ""; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + if (this.atFlag && this.buffer === "") { + this.parseError = true; + return failure; + } + this.pointer -= countSymbols(this.buffer) + 1; + this.buffer = ""; + this.state = "host"; + } else { + this.buffer += cStr; + } + + return true; + }; + + URLStateMachine.prototype["parse hostname"] = + URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { + if (this.stateOverride && this.url.scheme === "file") { + --this.pointer; + this.state = "file host"; + } else if (c === 58 && !this.arrFlag) { + if (this.buffer === "") { + this.parseError = true; + return failure; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "port"; + if (this.stateOverride === "hostname") { + return false; + } + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + --this.pointer; + if (isSpecial(this.url) && this.buffer === "") { + this.parseError = true; + return failure; + } else if (this.stateOverride && this.buffer === "" && + (includesCredentials(this.url) || this.url.port !== null)) { + this.parseError = true; + return false; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "path start"; + if (this.stateOverride) { + return false; + } + } else { + if (c === 91) { + this.arrFlag = true; + } else if (c === 93) { + this.arrFlag = false; + } + this.buffer += cStr; + } + + return true; + }; + + URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { + if (isASCIIDigit(c)) { + this.buffer += cStr; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92) || + this.stateOverride) { + if (this.buffer !== "") { + const port = parseInt(this.buffer); + if (port > Math.pow(2, 16) - 1) { + this.parseError = true; + return failure; + } + this.url.port = port === defaultPort(this.url.scheme) ? null : port; + this.buffer = ""; + } + if (this.stateOverride) { + return false; + } + this.state = "path start"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; + }; + + const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); + + URLStateMachine.prototype["parse file"] = function parseFile(c) { + this.url.scheme = "file"; + + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file slash"; + } else if (this.base !== null && this.base.scheme === "file") { + if (isNaN(c)) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 63) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else { + if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points + !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || + (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points + !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + shortenPath(this.url); + } else { + this.parseError = true; + } + + this.state = "path"; + --this.pointer; + } + } else { + this.state = "path"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file host"; + } else { + if (this.base !== null && this.base.scheme === "file") { + if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { + this.url.path.push(this.base.path[0]); + } else { + this.url.host = this.base.host; + } + } + this.state = "path"; + --this.pointer; + } + + return true; + }; + + URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { + if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { + --this.pointer; + if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { + this.parseError = true; + this.state = "path"; + } else if (this.buffer === "") { + this.url.host = ""; + if (this.stateOverride) { + return false; + } + this.state = "path start"; + } else { + let host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + if (host === "localhost") { + host = ""; + } + this.url.host = host; + + if (this.stateOverride) { + return false; + } + + this.buffer = ""; + this.state = "path start"; + } + } else { + this.buffer += cStr; + } + + return true; + }; + + URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { + if (isSpecial(this.url)) { + if (c === 92) { + this.parseError = true; + } + this.state = "path"; + + if (c !== 47 && c !== 92) { + --this.pointer; + } + } else if (!this.stateOverride && c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (!this.stateOverride && c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else if (c !== undefined) { + this.state = "path"; + if (c !== 47) { + --this.pointer; + } + } + + return true; + }; + + URLStateMachine.prototype["parse path"] = function parsePath(c) { + if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || + (!this.stateOverride && (c === 63 || c === 35))) { + if (isSpecial(this.url) && c === 92) { + this.parseError = true; + } + + if (isDoubleDot(this.buffer)) { + shortenPath(this.url); + if (c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } + } else if (isSingleDot(this.buffer) && c !== 47 && + !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } else if (!isSingleDot(this.buffer)) { + if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { + if (this.url.host !== "" && this.url.host !== null) { + this.parseError = true; + this.url.host = ""; + } + this.buffer = this.buffer[0] + ":"; + } + this.url.path.push(this.buffer); + } + this.buffer = ""; + if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { + while (this.url.path.length > 1 && this.url.path[0] === "") { + this.parseError = true; + this.url.path.shift(); + } + } + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += percentEncodeChar(c, isPathPercentEncode); + } + + return true; + }; + + URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else { + // TODO: Add: not a URL code point + if (!isNaN(c) && c !== 37) { + this.parseError = true; + } + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + if (!isNaN(c)) { + this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); + } + } + + return true; + }; + + URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { + if (isNaN(c) || (!this.stateOverride && c === 35)) { + if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { + this.encodingOverride = "utf-8"; + } + + const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || + buffer[i] === 0x3C || buffer[i] === 0x3E) { + this.url.query += percentEncode(buffer[i]); + } else { + this.url.query += String.fromCodePoint(buffer[i]); + } + } + + this.buffer = ""; + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += cStr; + } + + return true; + }; + + URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { + if (isNaN(c)) ; else if (c === 0x0) { + this.parseError = true; + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); + } + + return true; + }; + + function serializeURL(url, excludeFragment) { + let output = url.scheme + ":"; + if (url.host !== null) { + output += "//"; + + if (url.username !== "" || url.password !== "") { + output += url.username; + if (url.password !== "") { + output += ":" + url.password; + } + output += "@"; + } + + output += serializeHost(url.host); + + if (url.port !== null) { + output += ":" + url.port; + } + } else if (url.host === null && url.scheme === "file") { + output += "//"; + } + + if (url.cannotBeABaseURL) { + output += url.path[0]; + } else { + for (const string of url.path) { + output += "/" + string; + } + } + + if (url.query !== null) { + output += "?" + url.query; + } + + if (!excludeFragment && url.fragment !== null) { + output += "#" + url.fragment; + } + + return output; + } + + function serializeOrigin(tuple) { + let result = tuple.scheme + "://"; + result += serializeHost(tuple.host); + + if (tuple.port !== null) { + result += ":" + tuple.port; + } + + return result; + } + + module.exports.serializeURL = serializeURL; + + module.exports.serializeURLOrigin = function (url) { + // https://url.spec.whatwg.org/#concept-url-origin + switch (url.scheme) { + case "blob": + try { + return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); + } catch (e) { + // serializing an opaque origin returns "null" + return "null"; + } + case "ftp": + case "gopher": + case "http": + case "https": + case "ws": + case "wss": + return serializeOrigin({ + scheme: url.scheme, + host: url.host, + port: url.port + }); + case "file": + // spec says "exercise to the reader", chrome says "file://" + return "file://"; + default: + // serializing an opaque origin returns "null" + return "null"; + } + }; + + module.exports.basicURLParse = function (input, options) { + if (options === undefined) { + options = {}; + } + + const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); + if (usm.failure) { + return "failure"; + } + + return usm.url; + }; + + module.exports.setTheUsername = function (url, username) { + url.username = ""; + const decoded = punycode.ucs2.decode(username); + for (let i = 0; i < decoded.length; ++i) { + url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } + }; + + module.exports.setThePassword = function (url, password) { + url.password = ""; + const decoded = punycode.ucs2.decode(password); + for (let i = 0; i < decoded.length; ++i) { + url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } + }; + + module.exports.serializeHost = serializeHost; + + module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; + + module.exports.serializeInteger = function (integer) { + return String(integer); + }; + + module.exports.parseURL = function (input, options) { + if (options === undefined) { + options = {}; + } + + // We don't handle blobs, so this just delegates: + return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); }; } (urlStateMachine)); return urlStateMachine.exports; @@ -141983,2922 +142189,2922 @@ function requireBignumber () { if (hasRequiredBignumber) return bignumber$1.exports; hasRequiredBignumber = 1; (function (module) { -(function (globalObject) { - - /* - * bignumber.js v9.3.1 - * A JavaScript library for arbitrary-precision arithmetic. - * https://github.com/MikeMcl/bignumber.js - * Copyright (c) 2025 Michael Mclaughlin - * MIT Licensed. - * - * BigNumber.prototype methods | BigNumber methods - * | - * absoluteValue abs | clone - * comparedTo | config set - * decimalPlaces dp | DECIMAL_PLACES - * dividedBy div | ROUNDING_MODE - * dividedToIntegerBy idiv | EXPONENTIAL_AT - * exponentiatedBy pow | RANGE - * integerValue | CRYPTO - * isEqualTo eq | MODULO_MODE - * isFinite | POW_PRECISION - * isGreaterThan gt | FORMAT - * isGreaterThanOrEqualTo gte | ALPHABET - * isInteger | isBigNumber - * isLessThan lt | maximum max - * isLessThanOrEqualTo lte | minimum min - * isNaN | random - * isNegative | sum - * isPositive | - * isZero | - * minus | - * modulo mod | - * multipliedBy times | - * negated | - * plus | - * precision sd | - * shiftedBy | - * squareRoot sqrt | - * toExponential | - * toFixed | - * toFormat | - * toFraction | - * toJSON | - * toNumber | - * toPrecision | - * toString | - * valueOf | - * - */ - - - var BigNumber, - isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, - mathceil = Math.ceil, - mathfloor = Math.floor, - - bignumberError = '[BigNumber Error] ', - tooManyDigits = bignumberError + 'Number primitive has more than 15 significant digits: ', - - BASE = 1e14, - LOG_BASE = 14, - MAX_SAFE_INTEGER = 0x1fffffffffffff, // 2^53 - 1 - // MAX_INT32 = 0x7fffffff, // 2^31 - 1 - POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], - SQRT_BASE = 1e7, - - // EDITABLE - // The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and - // the arguments to toExponential, toFixed, toFormat, and toPrecision. - MAX = 1E9; // 0 to MAX_INT32 - - - /* - * Create and return a BigNumber constructor. - */ - function clone(configObject) { - var div, convertBase, parseNumeric, - P = BigNumber.prototype = { constructor: BigNumber, toString: null, valueOf: null }, - ONE = new BigNumber(1), - - - //----------------------------- EDITABLE CONFIG DEFAULTS ------------------------------- - - - // The default values below must be integers within the inclusive ranges stated. - // The values can also be changed at run-time using BigNumber.set. - - // The maximum number of decimal places for operations involving division. - DECIMAL_PLACES = 20, // 0 to MAX - - // The rounding mode used when rounding to the above decimal places, and when using - // toExponential, toFixed, toFormat and toPrecision, and round (default value). - // UP 0 Away from zero. - // DOWN 1 Towards zero. - // CEIL 2 Towards +Infinity. - // FLOOR 3 Towards -Infinity. - // HALF_UP 4 Towards nearest neighbour. If equidistant, up. - // HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. - // HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. - // HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. - // HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. - ROUNDING_MODE = 4, // 0 to 8 - - // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS] - - // The exponent value at and beneath which toString returns exponential notation. - // Number type: -7 - TO_EXP_NEG = -7, // 0 to -MAX - - // The exponent value at and above which toString returns exponential notation. - // Number type: 21 - TO_EXP_POS = 21, // 0 to MAX - - // RANGE : [MIN_EXP, MAX_EXP] - - // The minimum exponent value, beneath which underflow to zero occurs. - // Number type: -324 (5e-324) - MIN_EXP = -1e7, // -1 to -MAX - - // The maximum exponent value, above which overflow to Infinity occurs. - // Number type: 308 (1.7976931348623157e+308) - // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow. - MAX_EXP = 1e7, // 1 to MAX - - // Whether to use cryptographically-secure random number generation, if available. - CRYPTO = false, // true or false - - // 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. - // This modulo mode is commonly known as 'truncated division' and is - // equivalent to (a % n) in JavaScript. - // FLOOR 3 The remainder has the same sign as the divisor (Python %). - // HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function. - // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). - // The remainder is always positive. - // - // The truncated division, floored division, Euclidian division and IEEE 754 remainder - // modes are commonly used for the modulus operation. - // Although the other rounding modes can also be used, they may not give useful results. - MODULO_MODE = 1, // 0 to 9 - - // The maximum number of significant digits of the result of the exponentiatedBy operation. - // If POW_PRECISION is 0, there will be unlimited significant digits. - POW_PRECISION = 0, // 0 to MAX - - // The format specification used by the BigNumber.prototype.toFormat method. - FORMAT = { - prefix: '', - groupSize: 3, - secondaryGroupSize: 0, - groupSeparator: ',', - decimalSeparator: '.', - fractionGroupSize: 0, - fractionGroupSeparator: '\xA0', // non-breaking space - suffix: '' - }, - - // The alphabet used for base conversion. It must be at least 2 characters long, with no '+', - // '-', '.', whitespace, or repeated character. - // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_' - ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz', - alphabetHasNormalDecimalDigits = true; - - - //------------------------------------------------------------------------------------------ - - - // CONSTRUCTOR - - - /* - * The BigNumber constructor and exported function. - * Create and return a new instance of a BigNumber object. - * - * v {number|string|BigNumber} A numeric value. - * [b] {number} The base of v. Integer, 2 to ALPHABET.length inclusive. - */ - function BigNumber(v, b) { - var alphabet, c, caseChanged, e, i, isNum, len, str, - x = this; - - // Enable constructor call without `new`. - if (!(x instanceof BigNumber)) return new BigNumber(v, b); - - if (b == null) { - - if (v && v._isBigNumber === true) { - x.s = v.s; - - if (!v.c || v.e > MAX_EXP) { - x.c = x.e = null; - } else if (v.e < MIN_EXP) { - x.c = [x.e = 0]; - } else { - x.e = v.e; - x.c = v.c.slice(); - } - - return; - } - - if ((isNum = typeof v == 'number') && v * 0 == 0) { - - // Use `1 / n` to handle minus zero also. - x.s = 1 / v < 0 ? (v = -v, -1) : 1; - - // Fast path for integers, where n < 2147483648 (2**31). - if (v === ~~v) { - for (e = 0, i = v; i >= 10; i /= 10, e++); - - if (e > MAX_EXP) { - x.c = x.e = null; - } else { - x.e = e; - x.c = [v]; - } - - return; - } - - str = String(v); - } else { - - if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum); - - x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1; - } - - // 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; - } - - } else { - - // '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}' - intCheck(b, 2, ALPHABET.length, 'Base'); - - // Allow exponential notation to be used with base 10 argument, while - // also rounding to DECIMAL_PLACES as with other bases. - if (b == 10 && alphabetHasNormalDecimalDigits) { - x = new BigNumber(v); - return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE); - } - - str = String(v); - - if (isNum = typeof v == 'number') { - - // Avoid potential interpretation of Infinity and NaN as base 44+ values. - if (v * 0 != 0) return parseNumeric(x, str, isNum, b); - - x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1; - - // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}' - if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, '').length > 15) { - throw Error - (tooManyDigits + v); - } - } else { - x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1; - } - - alphabet = ALPHABET.slice(0, b); - e = i = 0; - - // Check that str is a valid base b number. - // Don't use RegExp, so alphabet can contain special characters. - for (len = str.length; i < len; i++) { - if (alphabet.indexOf(c = str.charAt(i)) < 0) { - if (c == '.') { - - // If '.' is not the first character and it has not be found before. - if (i > e) { - e = len; - continue; - } - } else if (!caseChanged) { - - // Allow e.g. hexadecimal 'FF' as well as 'ff'. - if (str == str.toUpperCase() && (str = str.toLowerCase()) || - str == str.toLowerCase() && (str = str.toUpperCase())) { - caseChanged = true; - i = -1; - e = 0; - continue; - } - } - - return parseNumeric(x, String(v), isNum, b); - } - } - - // Prevent later check for length on converted number. - isNum = false; - str = convertBase(str, b, 10, x.s); - - // Decimal point? - if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); - else e = str.length; - } - - // Determine leading zeros. - for (i = 0; str.charCodeAt(i) === 48; i++); - - // Determine trailing zeros. - for (len = str.length; str.charCodeAt(--len) === 48;); - - if (str = str.slice(i, ++len)) { - len -= i; - - // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}' - if (isNum && BigNumber.DEBUG && - len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) { - throw Error - (tooManyDigits + (x.s * v)); - } - - // Overflow? - if ((e = e - i - 1) > MAX_EXP) { - - // Infinity. - x.c = x.e = null; - - // Underflow? - } else if (e < MIN_EXP) { - - // Zero. - x.c = [x.e = 0]; - } else { - x.e = e; - x.c = []; - - // Transform base - - // e is the base 10 exponent. - // i is where to slice str to get the first element of the coefficient array. - i = (e + 1) % LOG_BASE; - if (e < 0) i += LOG_BASE; // i < 1 - - if (i < len) { - if (i) x.c.push(+str.slice(0, i)); - - for (len -= LOG_BASE; i < len;) { - x.c.push(+str.slice(i, i += LOG_BASE)); - } - - i = LOG_BASE - (str = str.slice(i)).length; - } else { - i -= len; - } - - for (; i--; str += '0'); - x.c.push(+str); - } - } else { - - // Zero. - x.c = [x.e = 0]; - } - } - - - // CONSTRUCTOR PROPERTIES - - - BigNumber.clone = clone; - - BigNumber.ROUND_UP = 0; - BigNumber.ROUND_DOWN = 1; - BigNumber.ROUND_CEIL = 2; - BigNumber.ROUND_FLOOR = 3; - BigNumber.ROUND_HALF_UP = 4; - BigNumber.ROUND_HALF_DOWN = 5; - BigNumber.ROUND_HALF_EVEN = 6; - BigNumber.ROUND_HALF_CEIL = 7; - BigNumber.ROUND_HALF_FLOOR = 8; - BigNumber.EUCLID = 9; - - - /* - * Configure infrequently-changing library-wide settings. - * - * Accept an object with the following optional properties (if the value of a property is - * a number, it must be an integer within the inclusive range stated): - * - * DECIMAL_PLACES {number} 0 to MAX - * ROUNDING_MODE {number} 0 to 8 - * EXPONENTIAL_AT {number|number[]} -MAX to MAX or [-MAX to 0, 0 to MAX] - * RANGE {number|number[]} -MAX to MAX (not zero) or [-MAX to -1, 1 to MAX] - * CRYPTO {boolean} true or false - * MODULO_MODE {number} 0 to 9 - * POW_PRECISION {number} 0 to MAX - * ALPHABET {string} A string of two or more unique characters which does - * not contain '.'. - * FORMAT {object} An object with some of the following properties: - * prefix {string} - * groupSize {number} - * secondaryGroupSize {number} - * groupSeparator {string} - * decimalSeparator {string} - * fractionGroupSize {number} - * fractionGroupSeparator {string} - * suffix {string} - * - * (The values assigned to the above FORMAT object properties are not checked for validity.) - * - * E.g. - * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 }) - * - * Ignore properties/parameters set to null or undefined, except for ALPHABET. - * - * Return an object with the properties current values. - */ - BigNumber.config = BigNumber.set = function (obj) { - var p, v; - - if (obj != null) { - - if (typeof obj == 'object') { - - // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive. - // '[BigNumber Error] DECIMAL_PLACES {not a primitive number|not an integer|out of range}: {v}' - if (obj.hasOwnProperty(p = 'DECIMAL_PLACES')) { - v = obj[p]; - intCheck(v, 0, MAX, p); - DECIMAL_PLACES = v; - } - - // ROUNDING_MODE {number} Integer, 0 to 8 inclusive. - // '[BigNumber Error] ROUNDING_MODE {not a primitive number|not an integer|out of range}: {v}' - if (obj.hasOwnProperty(p = 'ROUNDING_MODE')) { - v = obj[p]; - intCheck(v, 0, 8, p); - ROUNDING_MODE = v; - } - - // EXPONENTIAL_AT {number|number[]} - // Integer, -MAX to MAX inclusive or - // [integer -MAX to 0 inclusive, 0 to MAX inclusive]. - // '[BigNumber Error] EXPONENTIAL_AT {not a primitive number|not an integer|out of range}: {v}' - if (obj.hasOwnProperty(p = 'EXPONENTIAL_AT')) { - v = obj[p]; - if (v && v.pop) { - intCheck(v[0], -MAX, 0, p); - intCheck(v[1], 0, MAX, p); - TO_EXP_NEG = v[0]; - TO_EXP_POS = v[1]; - } else { - intCheck(v, -MAX, MAX, p); - TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v); - } - } - - // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or - // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive]. - // '[BigNumber Error] RANGE {not a primitive number|not an integer|out of range|cannot be zero}: {v}' - if (obj.hasOwnProperty(p = 'RANGE')) { - v = obj[p]; - if (v && v.pop) { - intCheck(v[0], -MAX, -1, p); - intCheck(v[1], 1, MAX, p); - MIN_EXP = v[0]; - MAX_EXP = v[1]; - } else { - intCheck(v, -MAX, MAX, p); - if (v) { - MIN_EXP = -(MAX_EXP = v < 0 ? -v : v); - } else { - throw Error - (bignumberError + p + ' cannot be zero: ' + v); - } - } - } - - // CRYPTO {boolean} true or false. - // '[BigNumber Error] CRYPTO not true or false: {v}' - // '[BigNumber Error] crypto unavailable' - if (obj.hasOwnProperty(p = 'CRYPTO')) { - v = obj[p]; - if (v === !!v) { - if (v) { - if (typeof crypto != 'undefined' && crypto && - (crypto.getRandomValues || crypto.randomBytes)) { - CRYPTO = v; - } else { - CRYPTO = !v; - throw Error - (bignumberError + 'crypto unavailable'); - } - } else { - CRYPTO = v; - } - } else { - throw Error - (bignumberError + p + ' not true or false: ' + v); - } - } - - // MODULO_MODE {number} Integer, 0 to 9 inclusive. - // '[BigNumber Error] MODULO_MODE {not a primitive number|not an integer|out of range}: {v}' - if (obj.hasOwnProperty(p = 'MODULO_MODE')) { - v = obj[p]; - intCheck(v, 0, 9, p); - MODULO_MODE = v; - } - - // POW_PRECISION {number} Integer, 0 to MAX inclusive. - // '[BigNumber Error] POW_PRECISION {not a primitive number|not an integer|out of range}: {v}' - if (obj.hasOwnProperty(p = 'POW_PRECISION')) { - v = obj[p]; - intCheck(v, 0, MAX, p); - POW_PRECISION = v; - } - - // FORMAT {object} - // '[BigNumber Error] FORMAT not an object: {v}' - if (obj.hasOwnProperty(p = 'FORMAT')) { - v = obj[p]; - if (typeof v == 'object') FORMAT = v; - else throw Error - (bignumberError + p + ' not an object: ' + v); - } - - // ALPHABET {string} - // '[BigNumber Error] ALPHABET invalid: {v}' - if (obj.hasOwnProperty(p = 'ALPHABET')) { - v = obj[p]; - - // Disallow if less than two characters, - // or if it contains '+', '-', '.', whitespace, or a repeated character. - if (typeof v == 'string' && !/^.?$|[+\-.\s]|(.).*\1/.test(v)) { - alphabetHasNormalDecimalDigits = v.slice(0, 10) == '0123456789'; - ALPHABET = v; - } else { - throw Error - (bignumberError + p + ' invalid: ' + v); - } - } - - } else { - - // '[BigNumber Error] Object expected: {v}' - throw Error - (bignumberError + 'Object expected: ' + obj); - } - } - - return { - DECIMAL_PLACES: DECIMAL_PLACES, - ROUNDING_MODE: ROUNDING_MODE, - EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS], - RANGE: [MIN_EXP, MAX_EXP], - CRYPTO: CRYPTO, - MODULO_MODE: MODULO_MODE, - POW_PRECISION: POW_PRECISION, - FORMAT: FORMAT, - ALPHABET: ALPHABET - }; - }; - - - /* - * Return true if v is a BigNumber instance, otherwise return false. - * - * If BigNumber.DEBUG is true, throw if a BigNumber instance is not well-formed. - * - * v {any} - * - * '[BigNumber Error] Invalid BigNumber: {v}' - */ - BigNumber.isBigNumber = function (v) { - if (!v || v._isBigNumber !== true) return false; - if (!BigNumber.DEBUG) return true; - - var i, n, - c = v.c, - e = v.e, - s = v.s; - - out: if ({}.toString.call(c) == '[object Array]') { - - if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) { - - // If the first element is zero, the BigNumber value must be zero. - if (c[0] === 0) { - if (e === 0 && c.length === 1) return true; - break out; - } - - // Calculate number of digits that c[0] should have, based on the exponent. - i = (e + 1) % LOG_BASE; - if (i < 1) i += LOG_BASE; - - // Calculate number of digits of c[0]. - //if (Math.ceil(Math.log(c[0] + 1) / Math.LN10) == i) { - if (String(c[0]).length == i) { - - for (i = 0; i < c.length; i++) { - n = c[i]; - if (n < 0 || n >= BASE || n !== mathfloor(n)) break out; - } - - // Last element cannot be zero, unless it is the only element. - if (n !== 0) return true; - } - } - - // Infinity/NaN - } else if (c === null && e === null && (s === null || s === 1 || s === -1)) { - return true; - } - - throw Error - (bignumberError + 'Invalid BigNumber: ' + v); - }; - - - /* - * Return a new BigNumber whose value is the maximum of the arguments. - * - * arguments {number|string|BigNumber} - */ - BigNumber.maximum = BigNumber.max = function () { - return maxOrMin(arguments, -1); - }; - - - /* - * Return a new BigNumber whose value is the minimum of the arguments. - * - * arguments {number|string|BigNumber} - */ - BigNumber.minimum = BigNumber.min = function () { - return maxOrMin(arguments, 1); - }; - - - /* - * Return a new BigNumber with a random value equal to or greater than 0 and less than 1, - * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing - * zeros are produced). - * - * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp}' - * '[BigNumber Error] crypto unavailable' - */ - BigNumber.random = (function () { - var pow2_53 = 0x20000000000000; - - // Return a 53 bit integer n, where 0 <= n < 9007199254740992. - // Check if Math.random() produces more than 32 bits of randomness. - // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits. - // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1. - var random53bitInt = (Math.random() * pow2_53) & 0x1fffff - ? function () { return mathfloor(Math.random() * pow2_53); } - : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) + - (Math.random() * 0x800000 | 0); }; - - return function (dp) { - var a, b, e, k, v, - i = 0, - c = [], - rand = new BigNumber(ONE); - - if (dp == null) dp = DECIMAL_PLACES; - else intCheck(dp, 0, MAX); - - k = mathceil(dp / LOG_BASE); - - if (CRYPTO) { - - // Browsers supporting crypto.getRandomValues. - if (crypto.getRandomValues) { - - a = crypto.getRandomValues(new Uint32Array(k *= 2)); - - for (; i < k;) { - - // 53 bits: - // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2) - // 11111 11111111 11111111 11111111 11100000 00000000 00000000 - // ((Math.pow(2, 32) - 1) >>> 11).toString(2) - // 11111 11111111 11111111 - // 0x20000 is 2^21. - v = a[i] * 0x20000 + (a[i + 1] >>> 11); - - // Rejection sampling: - // 0 <= v < 9007199254740992 - // Probability that v >= 9e15, is - // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251 - if (v >= 9e15) { - b = crypto.getRandomValues(new Uint32Array(2)); - a[i] = b[0]; - a[i + 1] = b[1]; - } else { - - // 0 <= v <= 8999999999999999 - // 0 <= (v % 1e14) <= 99999999999999 - c.push(v % 1e14); - i += 2; - } - } - i = k / 2; - - // Node.js supporting crypto.randomBytes. - } else if (crypto.randomBytes) { - - // buffer - a = crypto.randomBytes(k *= 7); - - for (; i < k;) { - - // 0x1000000000000 is 2^48, 0x10000000000 is 2^40 - // 0x100000000 is 2^32, 0x1000000 is 2^24 - // 11111 11111111 11111111 11111111 11111111 11111111 11111111 - // 0 <= v < 9007199254740992 - v = ((a[i] & 31) * 0x1000000000000) + (a[i + 1] * 0x10000000000) + - (a[i + 2] * 0x100000000) + (a[i + 3] * 0x1000000) + - (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6]; - - if (v >= 9e15) { - crypto.randomBytes(7).copy(a, i); - } else { - - // 0 <= (v % 1e14) <= 99999999999999 - c.push(v % 1e14); - i += 7; - } - } - i = k / 7; - } else { - CRYPTO = false; - throw Error - (bignumberError + 'crypto unavailable'); - } - } - - // Use Math.random. - if (!CRYPTO) { - - for (; i < k;) { - v = random53bitInt(); - if (v < 9e15) c[i++] = v % 1e14; - } - } - - k = c[--i]; - dp %= LOG_BASE; - - // Convert trailing digits to zeros according to dp. - if (k && dp) { - v = POWS_TEN[LOG_BASE - dp]; - c[i] = mathfloor(k / v) * v; - } - - // Remove trailing elements which are zero. - for (; c[i] === 0; c.pop(), i--); - - // Zero? - if (i < 0) { - c = [e = 0]; - } else { - - // Remove leading elements which are zero and adjust exponent accordingly. - for (e = -1 ; c[0] === 0; c.splice(0, 1), e -= LOG_BASE); - - // Count the digits of the first element of c to determine leading zeros, and... - for (i = 1, v = c[0]; v >= 10; v /= 10, i++); - - // adjust the exponent accordingly. - if (i < LOG_BASE) e -= LOG_BASE - i; - } - - rand.e = e; - rand.c = c; - return rand; - }; - })(); - - - /* - * Return a BigNumber whose value is the sum of the arguments. - * - * arguments {number|string|BigNumber} - */ - BigNumber.sum = function () { - var i = 1, - args = arguments, - sum = new BigNumber(args[0]); - for (; i < args.length;) sum = sum.plus(args[i++]); - return sum; - }; - - - // PRIVATE FUNCTIONS - - - // Called by BigNumber and BigNumber.prototype.toString. - convertBase = (function () { - var decimal = '0123456789'; - - /* - * Convert string of baseIn to an array of numbers of baseOut. - * Eg. toBaseOut('255', 10, 16) returns [15, 15]. - * Eg. toBaseOut('ff', 16, 10) returns [2, 5, 5]. - */ - function toBaseOut(str, baseIn, baseOut, alphabet) { - var j, - arr = [0], - arrL, - i = 0, - len = str.length; - - for (; i < len;) { - for (arrL = arr.length; arrL--; arr[arrL] *= baseIn); - - arr[0] += alphabet.indexOf(str.charAt(i++)); - - for (j = 0; j < arr.length; j++) { - - if (arr[j] > baseOut - 1) { - if (arr[j + 1] == null) arr[j + 1] = 0; - arr[j + 1] += arr[j] / baseOut | 0; - arr[j] %= baseOut; - } - } - } - - return arr.reverse(); - } - - // Convert a numeric string of baseIn to a numeric string of baseOut. - // If the caller is toString, we are converting from base 10 to baseOut. - // If the caller is BigNumber, we are converting from baseIn to base 10. - return function (str, baseIn, baseOut, sign, callerIsToString) { - var alphabet, d, e, k, r, x, xc, y, - i = str.indexOf('.'), - dp = DECIMAL_PLACES, - rm = ROUNDING_MODE; - - // Non-integer. - if (i >= 0) { - k = POW_PRECISION; - - // Unlimited precision. - POW_PRECISION = 0; - str = str.replace('.', ''); - y = new BigNumber(baseIn); - x = y.pow(str.length - i); - POW_PRECISION = k; - - // Convert str as if an integer, then restore the fraction part by dividing the - // result by its base raised to a power. - - y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, '0'), - 10, baseOut, decimal); - y.e = y.c.length; - } - - // Convert the number as integer. - - xc = toBaseOut(str, baseIn, baseOut, callerIsToString - ? (alphabet = ALPHABET, decimal) - : (alphabet = decimal, ALPHABET)); - - // xc now represents str as an integer and converted to baseOut. e is the exponent. - e = k = xc.length; - - // Remove trailing zeros. - for (; xc[--k] == 0; xc.pop()); - - // Zero? - if (!xc[0]) return alphabet.charAt(0); - - // Does str represent an integer? If so, no need for the division. - if (i < 0) { - --e; - } else { - x.c = xc; - x.e = e; - - // The sign is needed for correct rounding. - x.s = sign; - x = div(x, y, dp, rm, baseOut); - xc = x.c; - r = x.r; - e = x.e; - } - - // xc now represents str converted to baseOut. - - // The index of the rounding digit. - d = e + dp + 1; - - // The rounding digit: the digit to the right of the digit that may be rounded up. - i = xc[d]; - - // Look at the rounding digits and mode to determine whether to round up. - - k = baseOut / 2; - r = r || d < 0 || xc[d + 1] != null; - - r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : i > k || i == k &&(rm == 4 || r || rm == 6 && xc[d - 1] & 1 || - rm == (x.s < 0 ? 8 : 7)); - - // If the index of the rounding digit is not greater than zero, or xc represents - // zero, then the result of the base conversion is zero or, if rounding up, a value - // such as 0.00001. - if (d < 1 || !xc[0]) { - - // 1^-dp or 0 - str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0); - } else { - - // Truncate xc to the required number of decimal places. - xc.length = d; - - // Round up? - if (r) { - - // Rounding up may mean the previous digit has to be rounded up and so on. - for (--baseOut; ++xc[--d] > baseOut;) { - xc[d] = 0; - - if (!d) { - ++e; - xc = [1].concat(xc); - } - } - } - - // Determine trailing zeros. - for (k = xc.length; !xc[--k];); - - // E.g. [4, 11, 15] becomes 4bf. - for (i = 0, str = ''; i <= k; str += alphabet.charAt(xc[i++])); - - // Add leading zeros, decimal point and trailing zeros as required. - str = toFixedPoint(str, e, alphabet.charAt(0)); - } - - // The caller will add the sign. - return str; - }; - })(); - - - // Perform division in the specified base. Called by div and convertBase. - div = (function () { - - // Assume non-zero x and k. - function multiply(x, k, base) { - var m, temp, xlo, xhi, - carry = 0, - i = x.length, - klo = k % SQRT_BASE, - khi = k / SQRT_BASE | 0; - - for (x = x.slice(); i--;) { - xlo = x[i] % SQRT_BASE; - xhi = x[i] / SQRT_BASE | 0; - m = khi * xlo + xhi * klo; - temp = klo * xlo + ((m % SQRT_BASE) * SQRT_BASE) + carry; - carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi; - x[i] = temp % base; - } - - if (carry) x = [carry].concat(x); - - return x; - } - - function compare(a, b, aL, bL) { - var i, cmp; - - if (aL != bL) { - cmp = aL > bL ? 1 : -1; - } else { - - for (i = cmp = 0; i < aL; i++) { - - if (a[i] != b[i]) { - cmp = a[i] > b[i] ? 1 : -1; - break; - } - } - } - - return cmp; - } - - 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.splice(0, 1)); - } - - // x: dividend, y: divisor. - return function (x, y, dp, rm, base) { - var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0, - yL, yz, - s = x.s == y.s ? 1 : -1, - xc = x.c, - yc = y.c; - - // Either NaN, Infinity or 0? - if (!xc || !xc[0] || !yc || !yc[0]) { - - return new BigNumber( - - // Return NaN if either NaN, or both Infinity or 0. - !x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN : - - // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0. - xc && xc[0] == 0 || !yc ? s * 0 : s / 0 - ); - } - - q = new BigNumber(s); - qc = q.c = []; - e = x.e - y.e; - s = dp + e + 1; - - if (!base) { - base = BASE; - e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE); - s = s / LOG_BASE | 0; - } - - // Result exponent may be one less then the current value of e. - // The coefficients of the BigNumbers from convertBase may have trailing zeros. - for (i = 0; yc[i] == (xc[i] || 0); i++); - - if (yc[i] > (xc[i] || 0)) e--; - - if (s < 0) { - qc.push(1); - more = true; - } else { - xL = xc.length; - yL = yc.length; - i = 0; - s += 2; - - // Normalise xc and yc so highest order digit of yc is >= base / 2. - - n = mathfloor(base / (yc[0] + 1)); - - // Not necessary, but to handle odd bases where yc[0] == (base / 2) - 1. - // if (n > 1 || n++ == 1 && yc[0] < base / 2) { - if (n > 1) { - yc = multiply(yc, n, base); - xc = multiply(xc, n, base); - yL = yc.length; - xL = xc.length; - } - - xi = yL; - rem = xc.slice(0, yL); - remL = rem.length; - - // Add zeros to make remainder as long as divisor. - for (; remL < yL; rem[remL++] = 0); - yz = yc.slice(); - yz = [0].concat(yz); - yc0 = yc[0]; - if (yc[1] >= base / 2) yc0++; - // Not necessary, but to prevent trial digit n > base, when using base 3. - // else if (base == 3 && yc0 == 1) yc0 = 1 + 1e-15; - - do { - n = 0; - - // Compare divisor and remainder. - cmp = compare(yc, rem, yL, remL); - - // If divisor < remainder. - if (cmp < 0) { - - // Calculate trial digit, n. - - rem0 = rem[0]; - if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); - - // n is how many times the divisor goes into the current remainder. - n = mathfloor(rem0 / yc0); - - // Algorithm: - // product = divisor multiplied by trial digit (n). - // Compare product and remainder. - // If product is greater than remainder: - // Subtract divisor from product, decrement trial digit. - // Subtract product from remainder. - // If product was less than remainder at the last compare: - // Compare new remainder and divisor. - // If remainder is greater than divisor: - // Subtract divisor from remainder, increment trial digit. - - if (n > 1) { - - // n may be > base only when base is 3. - if (n >= base) n = base - 1; - - // product = divisor * trial digit. - prod = multiply(yc, n, base); - prodL = prod.length; - remL = rem.length; - - // Compare product and remainder. - // If product > remainder then trial digit n too high. - // n is 1 too high about 5% of the time, and is not known to have - // ever been more than 1 too high. - while (compare(prod, rem, prodL, remL) == 1) { - n--; - - // Subtract divisor from product. - subtract(prod, yL < prodL ? yz : yc, prodL, base); - prodL = prod.length; - cmp = 1; - } - } else { - - // n is 0 or 1, cmp is -1. - // If n is 0, there is no need to compare yc and rem again below, - // so change cmp to 1 to avoid it. - // If n is 1, leave cmp as -1, so yc and rem are compared again. - if (n == 0) { - - // divisor < remainder, so n must be at least 1. - cmp = n = 1; - } - - // product = divisor - prod = yc.slice(); - prodL = prod.length; - } - - if (prodL < remL) prod = [0].concat(prod); - - // Subtract product from remainder. - subtract(rem, prod, remL, base); - remL = rem.length; - - // If product was < remainder. - if (cmp == -1) { - - // Compare divisor and new remainder. - // If divisor < new remainder, subtract divisor from remainder. - // Trial digit n too low. - // n is 1 too low about 5% of the time, and very rarely 2 too low. - while (compare(yc, rem, yL, remL) < 1) { - n++; - - // Subtract divisor from remainder. - subtract(rem, yL < remL ? yz : yc, remL, base); - remL = rem.length; - } - } - } else if (cmp === 0) { - n++; - rem = [0]; - } // else cmp === 1 and n will be 0 - - // Add the next digit, n, to the result array. - qc[i++] = n; - - // Update the remainder. - if (rem[0]) { - rem[remL++] = xc[xi] || 0; - } else { - rem = [xc[xi]]; - remL = 1; - } - } while ((xi++ < xL || rem[0] != null) && s--); - - more = rem[0] != null; - - // Leading zero? - if (!qc[0]) qc.splice(0, 1); - } - - if (base == BASE) { - - // To calculate q.e, first get the number of digits of qc[0]. - for (i = 1, s = qc[0]; s >= 10; s /= 10, i++); - - round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more); - - // Caller is convertBase. - } else { - q.e = e; - q.r = +more; - } - - return q; - }; - })(); - - - /* - * Return a string representing the value of BigNumber n in fixed-point or exponential - * notation rounded to the specified decimal places or significant digits. - * - * n: a BigNumber. - * i: the index of the last digit required (i.e. the digit that may be rounded up). - * rm: the rounding mode. - * id: 1 (toExponential) or 2 (toPrecision). - */ - function format(n, i, rm, id) { - var c0, e, ne, len, str; - - if (rm == null) rm = ROUNDING_MODE; - else intCheck(rm, 0, 8); - - if (!n.c) return n.toString(); - - c0 = n.c[0]; - ne = n.e; - - if (i == null) { - str = coeffToString(n.c); - str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS) - ? toExponential(str, ne) - : toFixedPoint(str, ne, '0'); - } else { - n = round(new BigNumber(n), i, rm); - - // n.e may have changed if the value was rounded up. - e = n.e; - - str = coeffToString(n.c); - len = str.length; - - // toPrecision returns exponential notation if the number of significant digits - // specified is less than the number of digits necessary to represent the integer - // part of the value in fixed-point notation. - - // Exponential notation. - if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) { - - // Append zeros? - for (; len < i; str += '0', len++); - str = toExponential(str, e); - - // Fixed-point notation. - } else { - i -= ne + (id === 2 && e > ne); - str = toFixedPoint(str, e, '0'); - - // Append zeros? - if (e + 1 > len) { - if (--i > 0) for (str += '.'; i--; str += '0'); - } else { - i += e - len; - if (i > 0) { - if (e + 1 == len) str += '.'; - for (; i--; str += '0'); - } - } - } - } - - return n.s < 0 && c0 ? '-' + str : str; - } - - - // Handle BigNumber.max and BigNumber.min. - // If any number is NaN, return NaN. - function maxOrMin(args, n) { - var k, y, - i = 1, - x = new BigNumber(args[0]); - - for (; i < args.length; i++) { - y = new BigNumber(args[i]); - if (!y.s || (k = compare(x, y)) === n || k === 0 && x.s === n) { - x = y; - } - } - - return x; - } - - - /* - * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP. - * Called by minus, plus and times. - */ - function normalise(n, c, e) { - var i = 1, - j = c.length; - - // Remove trailing zeros. - for (; !c[--j]; c.pop()); - - // Calculate the base 10 exponent. First get the number of digits of c[0]. - for (j = c[0]; j >= 10; j /= 10, i++); - - // Overflow? - if ((e = i + e * LOG_BASE - 1) > MAX_EXP) { - - // Infinity. - n.c = n.e = null; - - // Underflow? - } else if (e < MIN_EXP) { - - // Zero. - n.c = [n.e = 0]; - } else { - n.e = e; - n.c = c; - } - - return n; - } - - - // Handle values that fail the validity test in BigNumber. - parseNumeric = (function () { - var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, - dotAfter = /^([^.]+)\.$/, - dotBefore = /^\.([^.]+)$/, - isInfinityOrNaN = /^-?(Infinity|NaN)$/, - whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g; - - return function (x, str, isNum, b) { - var base, - s = isNum ? str : str.replace(whitespaceOrPlus, ''); - - // No exception on ±Infinity or NaN. - if (isInfinityOrNaN.test(s)) { - x.s = isNaN(s) ? null : s < 0 ? -1 : 1; - } else { - if (!isNum) { - - // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i - s = s.replace(basePrefix, function (m, p1, p2) { - base = (p2 = p2.toLowerCase()) == 'x' ? 16 : p2 == 'b' ? 2 : 8; - return !b || b == base ? p1 : m; - }); - - if (b) { - base = b; - - // E.g. '1.' to '1', '.1' to '0.1' - s = s.replace(dotAfter, '$1').replace(dotBefore, '0.$1'); - } - - if (str != s) return new BigNumber(s, base); - } - - // '[BigNumber Error] Not a number: {n}' - // '[BigNumber Error] Not a base {b} number: {n}' - if (BigNumber.DEBUG) { - throw Error - (bignumberError + 'Not a' + (b ? ' base ' + b : '') + ' number: ' + str); - } - - // NaN - x.s = null; - } - - x.c = x.e = null; - } - })(); - - - /* - * Round x to sd significant digits using rounding mode rm. Check for over/under-flow. - * If r is truthy, it is known that there are more digits after the rounding digit. - */ - function round(x, sd, rm, r) { - var d, i, j, k, n, ni, rd, - xc = x.c, - pows10 = POWS_TEN; - - // if x is not Infinity or NaN... - if (xc) { - - // rd is the rounding digit, i.e. the digit after the digit that may be rounded up. - // n is a base 1e14 number, the value of the element of array x.c containing rd. - // ni is the index of n within x.c. - // d is the number of digits of n. - // i is the index of rd within n including leading zeros. - // j is the actual index of rd within n (if < 0, rd is a leading zero). - out: { - - // Get the number of digits of the first element of xc. - for (d = 1, k = xc[0]; k >= 10; k /= 10, d++); - i = sd - d; - - // If the rounding digit is in the first element of xc... - if (i < 0) { - i += LOG_BASE; - j = sd; - n = xc[ni = 0]; - - // Get the rounding digit at index j of n. - rd = mathfloor(n / pows10[d - j - 1] % 10); - } else { - ni = mathceil((i + 1) / LOG_BASE); - - if (ni >= xc.length) { - - if (r) { - - // Needed by sqrt. - for (; xc.length <= ni; xc.push(0)); - n = rd = 0; - d = 1; - i %= LOG_BASE; - j = i - LOG_BASE + 1; - } else { - break out; - } - } else { - n = k = xc[ni]; - - // Get the number of digits of n. - for (d = 1; k >= 10; k /= 10, d++); - - // Get the index of rd within n. - i %= LOG_BASE; - - // Get the index of rd within n, adjusted for leading zeros. - // The number of leading zeros of n is given by LOG_BASE - d. - j = i - LOG_BASE + d; - - // Get the rounding digit at index j of n. - rd = j < 0 ? 0 : mathfloor(n / pows10[d - j - 1] % 10); - } - } - - r = r || sd < 0 || - - // Are there any non-zero digits after the rounding digit? - // The expression n % pows10[d - j - 1] returns all digits of n to the right - // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714. - xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]); - - r = rm < 4 - ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 && - - // Check whether the digit to the left of the rounding digit is odd. - ((i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10) & 1 || - rm == (x.s < 0 ? 8 : 7)); - - if (sd < 1 || !xc[0]) { - xc.length = 0; - - if (r) { - - // Convert sd to decimal places. - sd -= x.e + 1; - - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE]; - x.e = -sd || 0; - } else { - - // Zero. - xc[0] = x.e = 0; - } - - return x; - } - - // Remove excess digits. - if (i == 0) { - xc.length = ni; - k = 1; - ni--; - } else { - xc.length = ni + 1; - k = pows10[LOG_BASE - i]; - - // E.g. 56700 becomes 56000 if 7 is the rounding digit. - // j > 0 means i > number of leading zeros of n. - xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0; - } - - // Round up? - if (r) { - - for (; ;) { - - // If the digit to be rounded up is in the first element of xc... - if (ni == 0) { - - // i will be the length of xc[0] before k is added. - for (i = 1, j = xc[0]; j >= 10; j /= 10, i++); - j = xc[0] += k; - for (k = 1; j >= 10; j /= 10, k++); - - // if i != k the length has increased. - if (i != k) { - x.e++; - if (xc[0] == BASE) xc[0] = 1; - } - - break; - } else { - xc[ni] += k; - if (xc[ni] != BASE) break; - xc[ni--] = 0; - k = 1; - } - } - } - - // Remove trailing zeros. - for (i = xc.length; xc[--i] === 0; xc.pop()); - } - - // Overflow? Infinity. - if (x.e > MAX_EXP) { - x.c = x.e = null; - - // Underflow? Zero. - } else if (x.e < MIN_EXP) { - x.c = [x.e = 0]; - } - } - - return x; - } - - - function valueOf(n) { - var str, - e = n.e; - - if (e === null) return n.toString(); - - str = coeffToString(n.c); - - str = e <= TO_EXP_NEG || e >= TO_EXP_POS - ? toExponential(str, e) - : toFixedPoint(str, e, '0'); - - return n.s < 0 ? '-' + str : str; - } - - - // PROTOTYPE/INSTANCE METHODS - - - /* - * Return a new BigNumber whose value is the absolute value of this BigNumber. - */ - P.absoluteValue = P.abs = function () { - var x = new BigNumber(this); - if (x.s < 0) x.s = 1; - return x; - }; - - - /* - * Return - * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b), - * -1 if the value of this BigNumber is less than the value of BigNumber(y, b), - * 0 if they have the same value, - * or null if the value of either is NaN. - */ - P.comparedTo = function (y, b) { - return compare(this, new BigNumber(y, b)); - }; - - - /* - * If dp is undefined or null or true or false, return the number of decimal places of the - * value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN. - * - * Otherwise, if dp is a number, return a new BigNumber whose value is the value of this - * BigNumber rounded to a maximum of dp decimal places using rounding mode rm, or - * ROUNDING_MODE if rm is omitted. - * - * [dp] {number} Decimal places: integer, 0 to MAX inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' - */ - P.decimalPlaces = P.dp = function (dp, rm) { - var c, n, v, - x = this; - - if (dp != null) { - intCheck(dp, 0, MAX); - if (rm == null) rm = ROUNDING_MODE; - else intCheck(rm, 0, 8); - - return round(new BigNumber(x), dp + x.e + 1, rm); - } - - if (!(c = x.c)) return null; - n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE; - - // Subtract the number of trailing zeros of the last number. - if (v = c[v]) for (; v % 10 == 0; v /= 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 BigNumber whose value is the value of this BigNumber divided by the value of - * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE. - */ - P.dividedBy = P.div = function (y, b) { - return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE); - }; - - - /* - * Return a new BigNumber whose value is the integer part of dividing the value of this - * BigNumber by the value of BigNumber(y, b). - */ - P.dividedToIntegerBy = P.idiv = function (y, b) { - return div(this, new BigNumber(y, b), 0, 1); - }; - - - /* - * Return a BigNumber whose value is the value of this BigNumber exponentiated by n. - * - * If m is present, return the result modulo m. - * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE. - * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using ROUNDING_MODE. - * - * The modular power operation works efficiently when x, n, and m are integers, otherwise it - * is equivalent to calculating x.exponentiatedBy(n).modulo(m) with a POW_PRECISION of 0. - * - * n {number|string|BigNumber} The exponent. An integer. - * [m] {number|string|BigNumber} The modulus. - * - * '[BigNumber Error] Exponent not an integer: {n}' - */ - P.exponentiatedBy = P.pow = function (n, m) { - var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y, - x = this; - - n = new BigNumber(n); - - // Allow NaN and ±Infinity, but not other non-integers. - if (n.c && !n.isInteger()) { - throw Error - (bignumberError + 'Exponent not an integer: ' + valueOf(n)); - } - - if (m != null) m = new BigNumber(m); - - // Exponent of MAX_SAFE_INTEGER is 15. - nIsBig = n.e > 14; - - // If x is NaN, ±Infinity, ±0 or ±1, or n is ±Infinity, NaN or ±0. - if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) { - - // The sign of the result of pow when x is negative depends on the evenness of n. - // If +n overflows to ±Infinity, the evenness of n would be not be known. - y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? n.s * (2 - isOdd(n)) : +valueOf(n))); - return m ? y.mod(m) : y; - } - - nIsNeg = n.s < 0; - - if (m) { - - // x % m returns NaN if abs(m) is zero, or m is NaN. - if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN); - - isModExp = !nIsNeg && x.isInteger() && m.isInteger(); - - if (isModExp) x = x.mod(m); - - // Overflow to ±Infinity: >=2**1e10 or >=1.0000024**1e15. - // Underflow to ±0: <=0.79**1e10 or <=0.9999975**1e15. - } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0 - // [1, 240000000] - ? x.c[0] > 1 || nIsBig && x.c[1] >= 24e7 - // [80000000000000] [99999750000000] - : x.c[0] < 8e13 || nIsBig && x.c[0] <= 9999975e7))) { - - // If x is negative and n is odd, k = -0, else k = 0. - k = x.s < 0 && isOdd(n) ? -0 : 0; - - // If x >= 1, k = ±Infinity. - if (x.e > -1) k = 1 / k; - - // If n is negative return ±0, else return ±Infinity. - return new BigNumber(nIsNeg ? 1 / k : k); - - } else if (POW_PRECISION) { - - // Truncating each coefficient array to a length of k after each multiplication - // equates to truncating significant digits to POW_PRECISION + [28, 41], - // i.e. there will be a minimum of 28 guard digits retained. - k = mathceil(POW_PRECISION / LOG_BASE + 2); - } - - if (nIsBig) { - half = new BigNumber(0.5); - if (nIsNeg) n.s = 1; - nIsOdd = isOdd(n); - } else { - i = Math.abs(+valueOf(n)); - nIsOdd = i % 2; - } - - y = new BigNumber(ONE); - - // Performs 54 loop iterations for n of 9007199254740991. - for (; ;) { - - if (nIsOdd) { - y = y.times(x); - if (!y.c) break; - - if (k) { - if (y.c.length > k) y.c.length = k; - } else if (isModExp) { - y = y.mod(m); //y = y.minus(div(y, m, 0, MODULO_MODE).times(m)); - } - } - - if (i) { - i = mathfloor(i / 2); - if (i === 0) break; - nIsOdd = i % 2; - } else { - n = n.times(half); - round(n, n.e + 1, 1); - - if (n.e > 14) { - nIsOdd = isOdd(n); - } else { - i = +valueOf(n); - if (i === 0) break; - nIsOdd = i % 2; - } - } - - x = x.times(x); - - if (k) { - if (x.c && x.c.length > k) x.c.length = k; - } else if (isModExp) { - x = x.mod(m); //x = x.minus(div(x, m, 0, MODULO_MODE).times(m)); - } - } - - if (isModExp) return y; - if (nIsNeg) y = ONE.div(y); - - return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y; - }; - - - /* - * Return a new BigNumber whose value is the value of this BigNumber rounded to an integer - * using rounding mode rm, or ROUNDING_MODE if rm is omitted. - * - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {rm}' - */ - P.integerValue = function (rm) { - var n = new BigNumber(this); - if (rm == null) rm = ROUNDING_MODE; - else intCheck(rm, 0, 8); - return round(n, n.e + 1, rm); - }; - - - /* - * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b), - * otherwise return false. - */ - P.isEqualTo = P.eq = function (y, b) { - return compare(this, new BigNumber(y, b)) === 0; - }; - - - /* - * Return true if the value of this BigNumber is a finite number, otherwise return false. - */ - P.isFinite = function () { - return !!this.c; - }; - - - /* - * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b), - * otherwise return false. - */ - P.isGreaterThan = P.gt = function (y, b) { - return compare(this, new BigNumber(y, b)) > 0; - }; - - - /* - * Return true if the value of this BigNumber is greater than or equal to the value of - * BigNumber(y, b), otherwise return false. - */ - P.isGreaterThanOrEqualTo = P.gte = function (y, b) { - return (b = compare(this, new BigNumber(y, b))) === 1 || b === 0; - - }; - - - /* - * Return true if the value of this BigNumber is an integer, otherwise return false. - */ - P.isInteger = function () { - return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2; - }; - - - /* - * Return true if the value of this BigNumber is less than the value of BigNumber(y, b), - * otherwise return false. - */ - P.isLessThan = P.lt = function (y, b) { - return compare(this, new BigNumber(y, b)) < 0; - }; - - - /* - * Return true if the value of this BigNumber is less than or equal to the value of - * BigNumber(y, b), otherwise return false. - */ - P.isLessThanOrEqualTo = P.lte = function (y, b) { - return (b = compare(this, new BigNumber(y, b))) === -1 || b === 0; - }; - - - /* - * Return true if the value of this BigNumber is NaN, otherwise return false. - */ - P.isNaN = function () { - return !this.s; - }; - - - /* - * Return true if the value of this BigNumber is negative, otherwise return false. - */ - P.isNegative = function () { - return this.s < 0; - }; - - - /* - * Return true if the value of this BigNumber is positive, otherwise return false. - */ - P.isPositive = function () { - return this.s > 0; - }; - - - /* - * Return true if the value of this BigNumber is 0 or -0, otherwise return false. - */ - P.isZero = function () { - return !!this.c && this.c[0] == 0; - }; - - - /* - * n - 0 = n - * n - N = N - * n - I = -I - * 0 - n = -n - * 0 - 0 = 0 - * 0 - N = N - * 0 - I = -I - * N - n = N - * N - 0 = N - * N - N = N - * N - I = N - * I - n = I - * I - 0 = I - * I - N = N - * I - I = N - * - * Return a new BigNumber whose value is the value of this BigNumber minus the value of - * BigNumber(y, b). - */ - P.minus = function (y, b) { - var i, j, t, xLTy, - x = this, - a = x.s; - - y = new BigNumber(y, b); - b = y.s; - - // Either NaN? - if (!a || !b) return new BigNumber(NaN); - - // Signs differ? - if (a != b) { - y.s = -b; - return x.plus(y); - } - - var xe = x.e / LOG_BASE, - ye = y.e / LOG_BASE, - xc = x.c, - yc = y.c; - - if (!xe || !ye) { - - // Either Infinity? - if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN); - - // Either zero? - if (!xc[0] || !yc[0]) { - - // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. - return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x : - - // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity - ROUNDING_MODE == 3 ? -0 : 0); - } - } - - xe = bitFloor(xe); - ye = bitFloor(ye); - xc = xc.slice(); - - // Determine which is the bigger number. - if (a = xe - ye) { - - if (xLTy = a < 0) { - a = -a; - t = xc; - } else { - ye = xe; - t = yc; - } - - t.reverse(); - - // Prepend zeros to equalise exponents. - for (b = a; b--; t.push(0)); - t.reverse(); - } else { - - // Exponents equal. Check digit by digit. - j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b; - - for (a = b = 0; b < j; b++) { - - if (xc[b] != yc[b]) { - xLTy = xc[b] < yc[b]; - break; - } - } - } - - // x < y? Point xc to the array of the bigger number. - if (xLTy) { - t = xc; - xc = yc; - yc = t; - y.s = -y.s; - } - - b = (j = yc.length) - (i = xc.length); - - // Append zeros to xc if shorter. - // No need to add zeros to yc if shorter as subtract only needs to start at yc.length. - if (b > 0) for (; b--; xc[i++] = 0); - b = BASE - 1; - - // Subtract yc from xc. - for (; j > a;) { - - if (xc[--j] < yc[j]) { - for (i = j; i && !xc[--i]; xc[i] = b); - --xc[i]; - xc[j] += BASE; - } - - xc[j] -= yc[j]; - } - - // Remove leading zeros and adjust exponent accordingly. - for (; xc[0] == 0; xc.splice(0, 1), --ye); - - // Zero? - if (!xc[0]) { - - // Following IEEE 754 (2008) 6.3, - // n - n = +0 but n - n = -0 when rounding towards -Infinity. - y.s = ROUNDING_MODE == 3 ? -1 : 1; - y.c = [y.e = 0]; - return y; - } - - // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity - // for finite x and y. - return normalise(y, xc, ye); - }; - - - /* - * 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 BigNumber whose value is the value of this BigNumber modulo the value of - * BigNumber(y, b). The result depends on the value of MODULO_MODE. - */ - P.modulo = P.mod = function (y, b) { - var q, s, - x = this; - - y = new BigNumber(y, b); - - // Return NaN if x is Infinity or NaN, or y is NaN or zero. - if (!x.c || !y.s || y.c && !y.c[0]) { - return new BigNumber(NaN); - - // Return x if y is Infinity or x is zero. - } else if (!y.c || x.c && !x.c[0]) { - return new BigNumber(x); - } - - if (MODULO_MODE == 9) { - - // Euclidian division: q = sign(y) * floor(x / abs(y)) - // r = x - qy where 0 <= r < abs(y) - s = y.s; - y.s = 1; - q = div(x, y, 0, 3); - y.s = s; - q.s *= s; - } else { - q = div(x, y, 0, MODULO_MODE); - } - - y = x.minus(q.times(y)); - - // To match JavaScript %, ensure sign of zero is sign of dividend. - if (!y.c[0] && MODULO_MODE == 1) y.s = x.s; - - return y; - }; - - - /* - * n * 0 = 0 - * n * N = N - * n * I = I - * 0 * n = 0 - * 0 * 0 = 0 - * 0 * N = N - * 0 * I = N - * N * n = N - * N * 0 = N - * N * N = N - * N * I = N - * I * n = I - * I * 0 = N - * I * N = N - * I * I = I - * - * Return a new BigNumber whose value is the value of this BigNumber multiplied by the value - * of BigNumber(y, b). - */ - P.multipliedBy = P.times = function (y, b) { - var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc, - base, sqrtBase, - x = this, - xc = x.c, - yc = (y = new BigNumber(y, b)).c; - - // Either NaN, ±Infinity or ±0? - if (!xc || !yc || !xc[0] || !yc[0]) { - - // Return NaN if either is NaN, or one is 0 and the other is Infinity. - if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) { - y.c = y.e = y.s = null; - } else { - y.s *= x.s; - - // Return ±Infinity if either is ±Infinity. - if (!xc || !yc) { - y.c = y.e = null; - - // Return ±0 if either is ±0. - } else { - y.c = [0]; - y.e = 0; - } - } - - return y; - } - - e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE); - y.s *= x.s; - xcL = xc.length; - ycL = yc.length; - - // Ensure xc points to longer array and xcL to its length. - if (xcL < ycL) { - zc = xc; - xc = yc; - yc = zc; - i = xcL; - xcL = ycL; - ycL = i; - } - - // Initialise the result array with zeros. - for (i = xcL + ycL, zc = []; i--; zc.push(0)); - - base = BASE; - sqrtBase = SQRT_BASE; - - for (i = ycL; --i >= 0;) { - c = 0; - ylo = yc[i] % sqrtBase; - yhi = yc[i] / sqrtBase | 0; - - for (k = xcL, j = i + k; j > i;) { - xlo = xc[--k] % sqrtBase; - xhi = xc[k] / sqrtBase | 0; - m = yhi * xlo + xhi * ylo; - xlo = ylo * xlo + ((m % sqrtBase) * sqrtBase) + zc[j] + c; - c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi; - zc[j--] = xlo % base; - } - - zc[j] = c; - } - - if (c) { - ++e; - } else { - zc.splice(0, 1); - } - - return normalise(y, zc, e); - }; - - - /* - * Return a new BigNumber whose value is the value of this BigNumber negated, - * i.e. multiplied by -1. - */ - P.negated = function () { - var x = new BigNumber(this); - x.s = -x.s || null; - return x; - }; - - - /* - * n + 0 = n - * n + N = N - * n + I = I - * 0 + n = n - * 0 + 0 = 0 - * 0 + N = N - * 0 + I = I - * N + n = N - * N + 0 = N - * N + N = N - * N + I = N - * I + n = I - * I + 0 = I - * I + N = N - * I + I = I - * - * Return a new BigNumber whose value is the value of this BigNumber plus the value of - * BigNumber(y, b). - */ - P.plus = function (y, b) { - var t, - x = this, - a = x.s; - - y = new BigNumber(y, b); - b = y.s; - - // Either NaN? - if (!a || !b) return new BigNumber(NaN); - - // Signs differ? - if (a != b) { - y.s = -b; - return x.minus(y); - } - - var xe = x.e / LOG_BASE, - ye = y.e / LOG_BASE, - xc = x.c, - yc = y.c; - - if (!xe || !ye) { - - // Return ±Infinity if either ±Infinity. - if (!xc || !yc) return new BigNumber(a / 0); - - // Either zero? - // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. - if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0); - } - - xe = bitFloor(xe); - ye = bitFloor(ye); - xc = xc.slice(); - - // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts. - if (a = xe - ye) { - if (a > 0) { - ye = xe; - t = yc; - } else { - a = -a; - t = xc; - } - - t.reverse(); - for (; a--; t.push(0)); - t.reverse(); - } - - a = xc.length; - b = yc.length; - - // Point xc to the longer array, and b to the shorter length. - if (a - b < 0) { - t = yc; - yc = xc; - xc = t; - b = a; - } - - // Only start adding at yc.length - 1 as the further digits of xc can be ignored. - for (a = 0; b;) { - a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0; - xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE; - } - - if (a) { - xc = [a].concat(xc); - ++ye; - } - - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - // ye = MAX_EXP + 1 possible - return normalise(y, xc, ye); - }; - - - /* - * If sd is undefined or null or true or false, return the number of significant digits of - * the value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN. - * If sd is true include integer-part trailing zeros in the count. - * - * Otherwise, if sd is a number, return a new BigNumber whose value is the value of this - * BigNumber rounded to a maximum of sd significant digits using rounding mode rm, or - * ROUNDING_MODE if rm is omitted. - * - * sd {number|boolean} number: significant digits: integer, 1 to MAX inclusive. - * boolean: whether to count integer-part trailing zeros: true or false. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}' - */ - P.precision = P.sd = function (sd, rm) { - var c, n, v, - x = this; - - if (sd != null && sd !== !!sd) { - intCheck(sd, 1, MAX); - if (rm == null) rm = ROUNDING_MODE; - else intCheck(rm, 0, 8); - - return round(new BigNumber(x), sd, rm); - } - - if (!(c = x.c)) return null; - v = c.length - 1; - n = v * LOG_BASE + 1; - - if (v = c[v]) { - - // Subtract the number of trailing zeros of the last element. - for (; v % 10 == 0; v /= 10, n--); - - // Add the number of digits of the first element. - for (v = c[0]; v >= 10; v /= 10, n++); - } - - if (sd && x.e + 1 > n) n = x.e + 1; - - return n; - }; - - - /* - * Return a new BigNumber whose value is the value of this BigNumber shifted by k places - * (powers of 10). Shift to the right if n > 0, and to the left if n < 0. - * - * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {k}' - */ - P.shiftedBy = function (k) { - intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); - return this.times('1e' + k); - }; - - - /* - * sqrt(-n) = N - * sqrt(N) = N - * sqrt(-I) = N - * sqrt(I) = I - * sqrt(0) = 0 - * sqrt(-0) = -0 - * - * Return a new BigNumber whose value is the square root of the value of this BigNumber, - * rounded according to DECIMAL_PLACES and ROUNDING_MODE. - */ - P.squareRoot = P.sqrt = function () { - var m, n, r, rep, t, - x = this, - c = x.c, - s = x.s, - e = x.e, - dp = DECIMAL_PLACES + 4, - half = new BigNumber('0.5'); - - // Negative/NaN/Infinity/zero? - if (s !== 1 || !c || !c[0]) { - return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0); - } - - // Initial estimate. - s = Math.sqrt(+valueOf(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 = coeffToString(c); - if ((n.length + e) % 2 == 0) n += '0'; - s = Math.sqrt(+n); - e = bitFloor((e + 1) / 2) - (e < 0 || e % 2); - - if (s == 1 / 0) { - n = '5e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } - - r = new BigNumber(n); - } else { - r = new BigNumber(s + ''); - } - - // Check for zero. - // r could be zero if MIN_EXP is changed after the this value was created. - // This would cause a division by zero (x/t) and hence Infinity below, which would cause - // coeffToString to throw. - if (r.c[0]) { - e = r.e; - s = e + dp; - if (s < 3) s = 0; - - // Newton-Raphson iteration. - for (; ;) { - t = r; - r = half.times(t.plus(div(x, t, dp, 1))); - - if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) { - - // The exponent of r may here be one less than the final result exponent, - // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits - // are indexed correctly. - if (r.e < e) --s; - n = n.slice(s - 3, s + 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) { - round(t, t.e + DECIMAL_PLACES + 2, 0); - - if (t.times(t).eq(x)) { - r = t; - break; - } - } - - dp += 4; - s += 4; - rep = 1; - } else { - - // If rounding digits are null, 0{0,4} or 50{0,3}, check for 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. - round(r, r.e + DECIMAL_PLACES + 2, 1); - m = !r.times(r).eq(x); - } - - break; - } - } - } - } - - return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m); - }; - - - /* - * Return a string representing the value of this BigNumber in exponential notation and - * rounded using ROUNDING_MODE to dp fixed decimal places. - * - * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' - */ - P.toExponential = function (dp, rm) { - if (dp != null) { - intCheck(dp, 0, MAX); - dp++; - } - return format(this, dp, rm, 1); - }; - - - /* - * Return a string representing the value of this BigNumber in fixed-point notation rounding - * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted. - * - * Note: as with JavaScript's number type, (-0).toFixed(0) is '0', - * but e.g. (-0.00001).toFixed(0) is '-0'. - * - * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' - */ - P.toFixed = function (dp, rm) { - if (dp != null) { - intCheck(dp, 0, MAX); - dp = dp + this.e + 1; - } - return format(this, dp, rm); - }; - - - /* - * Return a string representing the value of this BigNumber in fixed-point notation rounded - * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties - * of the format or FORMAT object (see BigNumber.set). - * - * The formatting object may contain some or all of the properties shown below. - * - * FORMAT = { - * prefix: '', - * groupSize: 3, - * secondaryGroupSize: 0, - * groupSeparator: ',', - * decimalSeparator: '.', - * fractionGroupSize: 0, - * fractionGroupSeparator: '\xA0', // non-breaking space - * suffix: '' - * }; - * - * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * [format] {object} Formatting options. See FORMAT pbject above. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' - * '[BigNumber Error] Argument not an object: {format}' - */ - P.toFormat = function (dp, rm, format) { - var str, - x = this; - - if (format == null) { - if (dp != null && rm && typeof rm == 'object') { - format = rm; - rm = null; - } else if (dp && typeof dp == 'object') { - format = dp; - dp = rm = null; - } else { - format = FORMAT; - } - } else if (typeof format != 'object') { - throw Error - (bignumberError + 'Argument not an object: ' + format); - } - - str = x.toFixed(dp, rm); - - if (x.c) { - var i, - arr = str.split('.'), - g1 = +format.groupSize, - g2 = +format.secondaryGroupSize, - groupSeparator = format.groupSeparator || '', - intPart = arr[0], - fractionPart = arr[1], - isNeg = x.s < 0, - intDigits = isNeg ? intPart.slice(1) : intPart, - len = intDigits.length; - - if (g2) { - i = g1; - g1 = g2; - g2 = i; - len -= i; - } - - if (g1 > 0 && len > 0) { - i = len % g1 || g1; - intPart = intDigits.substr(0, i); - for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1); - if (g2 > 0) intPart += groupSeparator + intDigits.slice(i); - if (isNeg) intPart = '-' + intPart; - } - - str = fractionPart - ? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize) - ? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'), - '$&' + (format.fractionGroupSeparator || '')) - : fractionPart) - : intPart; - } - - return (format.prefix || '') + str + (format.suffix || ''); - }; - - - /* - * Return an array of two BigNumbers representing the value of this BigNumber as a simple - * fraction with an integer numerator and an integer denominator. - * The denominator will be a positive non-zero value less than or equal to the specified - * maximum denominator. If a maximum denominator is not specified, the denominator will be - * the lowest value necessary to represent the number exactly. - * - * [md] {number|string|BigNumber} Integer >= 1, or Infinity. The maximum denominator. - * - * '[BigNumber Error] Argument {not an integer|out of range} : {md}' - */ - P.toFraction = function (md) { - var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s, - x = this, - xc = x.c; - - if (md != null) { - n = new BigNumber(md); - - // Throw if md is less than one or is not an integer, unless it is Infinity. - if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) { - throw Error - (bignumberError + 'Argument ' + - (n.isInteger() ? 'out of range: ' : 'not an integer: ') + valueOf(n)); - } - } - - if (!xc) return new BigNumber(x); - - d = new BigNumber(ONE); - n1 = d0 = new BigNumber(ONE); - d1 = n0 = new BigNumber(ONE); - s = coeffToString(xc); - - // Determine initial denominator. - // d is a power of 10 and the minimum max denominator that specifies the value exactly. - e = d.e = s.length - x.e - 1; - d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp]; - md = !md || n.comparedTo(d) > 0 ? (e > 0 ? d : n1) : n; - - exp = MAX_EXP; - MAX_EXP = 1 / 0; - n = new BigNumber(s); - - // n0 = d1 = 0 - n0.c[0] = 0; - - for (; ;) { - q = div(n, d, 0, 1); - d2 = d0.plus(q.times(d1)); - if (d2.comparedTo(md) == 1) break; - d0 = d1; - d1 = d2; - n1 = n0.plus(q.times(d2 = n1)); - n0 = d2; - d = n.minus(q.times(d2 = d)); - n = d2; - } - - d2 = div(md.minus(d0), d1, 0, 1); - n0 = n0.plus(d2.times(n1)); - d0 = d0.plus(d2.times(d1)); - n0.s = n1.s = x.s; - e = e * 2; - - // Determine which fraction is closer to x, n0/d0 or n1/d1 - r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo( - div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [n1, d1] : [n0, d0]; - - MAX_EXP = exp; - - return r; - }; - - - /* - * Return the value of this BigNumber converted to a number primitive. - */ - P.toNumber = function () { - return +valueOf(this); - }; - - - /* - * Return a string representing the value of this BigNumber rounded to sd significant digits - * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits - * necessary to represent the integer part of the value in fixed-point notation, then use - * exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}' - */ - P.toPrecision = function (sd, rm) { - if (sd != null) intCheck(sd, 1, MAX); - return format(this, sd, rm, 2); - }; - - - /* - * Return a string representing the value of this BigNumber in base b, or base 10 if b is - * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and - * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent - * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than - * TO_EXP_NEG, return exponential notation. - * - * [b] {number} Integer, 2 to ALPHABET.length inclusive. - * - * '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}' - */ - P.toString = function (b) { - var str, - n = this, - s = n.s, - e = n.e; - - // Infinity or NaN? - if (e === null) { - if (s) { - str = 'Infinity'; - if (s < 0) str = '-' + str; - } else { - str = 'NaN'; - } - } else { - if (b == null) { - str = e <= TO_EXP_NEG || e >= TO_EXP_POS - ? toExponential(coeffToString(n.c), e) - : toFixedPoint(coeffToString(n.c), e, '0'); - } else if (b === 10 && alphabetHasNormalDecimalDigits) { - n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE); - str = toFixedPoint(coeffToString(n.c), n.e, '0'); - } else { - intCheck(b, 2, ALPHABET.length, 'Base'); - str = convertBase(toFixedPoint(coeffToString(n.c), e, '0'), 10, b, s, true); - } - - if (s < 0 && n.c[0]) str = '-' + str; - } - - return str; - }; - - - /* - * Return as toString, but do not accept a base argument, and include the minus sign for - * negative zero. - */ - P.valueOf = P.toJSON = function () { - return valueOf(this); - }; - - - P._isBigNumber = true; - - if (configObject != null) BigNumber.set(configObject); - - return BigNumber; - } - - - // PRIVATE HELPER FUNCTIONS - - // These functions don't need access to variables, - // e.g. DECIMAL_PLACES, in the scope of the `clone` function above. - - - function bitFloor(n) { - var i = n | 0; - return n > 0 || n === i ? i : i - 1; - } - - - // Return a coefficient array as a string of base 10 digits. - function coeffToString(a) { - var s, z, - i = 1, - j = a.length, - r = a[0] + ''; - - for (; i < j;) { - s = a[i++] + ''; - z = LOG_BASE - s.length; - for (; z--; s = '0' + s); - r += s; - } - - // Determine trailing zeros. - for (j = r.length; r.charCodeAt(--j) === 48;); - - return r.slice(0, j + 1 || 1); - } - - - // Compare the value of BigNumbers x and y. - function compare(x, y) { - var a, b, - xc = x.c, - yc = y.c, - i = x.s, - j = y.s, - k = x.e, - l = y.e; - - // Either NaN? - if (!i || !j) return null; - - a = xc && !xc[0]; - b = yc && !yc[0]; - - // Either zero? - if (a || b) return a ? b ? 0 : -j : i; - - // Signs differ? - if (i != j) return i; - - a = i < 0; - b = k == l; - - // Either Infinity? - if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1; - - // Compare exponents. - if (!b) return k > l ^ a ? 1 : -1; - - j = (k = xc.length) < (l = yc.length) ? k : l; - - // Compare digit by digit. - for (i = 0; i < j; i++) if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1; - - // Compare lengths. - return k == l ? 0 : k > l ^ a ? 1 : -1; - } - - - /* - * Check that n is a primitive number, an integer, and in range, otherwise throw. - */ - function intCheck(n, min, max, name) { - if (n < min || n > max || n !== mathfloor(n)) { - throw Error - (bignumberError + (name || 'Argument') + (typeof n == 'number' - ? n < min || n > max ? ' out of range: ' : ' not an integer: ' - : ' not a primitive number: ') + String(n)); - } - } - - - // Assumes finite n. - function isOdd(n) { - var k = n.c.length - 1; - return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0; - } - - - function toExponential(str, e) { - return (str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str) + - (e < 0 ? 'e' : 'e+') + e; - } - - - function toFixedPoint(str, e, z) { - var len, zs; - - // Negative exponent? - if (e < 0) { - - // Prepend zeros. - for (zs = z + '.'; ++e; zs += z); - str = zs + str; - - // Positive exponent - } else { - len = str.length; - - // Append zeros. - if (++e > len) { - for (zs = z, e -= len; --e; zs += z); - str += zs; - } else if (e < len) { - str = str.slice(0, e) + '.' + str.slice(e); - } - } - - return str; - } - - - // EXPORT - - - BigNumber = clone(); - BigNumber['default'] = BigNumber.BigNumber = BigNumber; - - // AMD. - if (module.exports) { - module.exports = BigNumber; - - // Browser. - } else { - if (!globalObject) { - globalObject = typeof self != 'undefined' && self ? self : window; - } - - globalObject.BigNumber = BigNumber; - } +(function (globalObject) { + + /* + * bignumber.js v9.3.1 + * A JavaScript library for arbitrary-precision arithmetic. + * https://github.com/MikeMcl/bignumber.js + * Copyright (c) 2025 Michael Mclaughlin + * MIT Licensed. + * + * BigNumber.prototype methods | BigNumber methods + * | + * absoluteValue abs | clone + * comparedTo | config set + * decimalPlaces dp | DECIMAL_PLACES + * dividedBy div | ROUNDING_MODE + * dividedToIntegerBy idiv | EXPONENTIAL_AT + * exponentiatedBy pow | RANGE + * integerValue | CRYPTO + * isEqualTo eq | MODULO_MODE + * isFinite | POW_PRECISION + * isGreaterThan gt | FORMAT + * isGreaterThanOrEqualTo gte | ALPHABET + * isInteger | isBigNumber + * isLessThan lt | maximum max + * isLessThanOrEqualTo lte | minimum min + * isNaN | random + * isNegative | sum + * isPositive | + * isZero | + * minus | + * modulo mod | + * multipliedBy times | + * negated | + * plus | + * precision sd | + * shiftedBy | + * squareRoot sqrt | + * toExponential | + * toFixed | + * toFormat | + * toFraction | + * toJSON | + * toNumber | + * toPrecision | + * toString | + * valueOf | + * + */ + + + var BigNumber, + isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, + mathceil = Math.ceil, + mathfloor = Math.floor, + + bignumberError = '[BigNumber Error] ', + tooManyDigits = bignumberError + 'Number primitive has more than 15 significant digits: ', + + BASE = 1e14, + LOG_BASE = 14, + MAX_SAFE_INTEGER = 0x1fffffffffffff, // 2^53 - 1 + // MAX_INT32 = 0x7fffffff, // 2^31 - 1 + POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], + SQRT_BASE = 1e7, + + // EDITABLE + // The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and + // the arguments to toExponential, toFixed, toFormat, and toPrecision. + MAX = 1E9; // 0 to MAX_INT32 + + + /* + * Create and return a BigNumber constructor. + */ + function clone(configObject) { + var div, convertBase, parseNumeric, + P = BigNumber.prototype = { constructor: BigNumber, toString: null, valueOf: null }, + ONE = new BigNumber(1), + + + //----------------------------- EDITABLE CONFIG DEFAULTS ------------------------------- + + + // The default values below must be integers within the inclusive ranges stated. + // The values can also be changed at run-time using BigNumber.set. + + // The maximum number of decimal places for operations involving division. + DECIMAL_PLACES = 20, // 0 to MAX + + // The rounding mode used when rounding to the above decimal places, and when using + // toExponential, toFixed, toFormat and toPrecision, and round (default value). + // UP 0 Away from zero. + // DOWN 1 Towards zero. + // CEIL 2 Towards +Infinity. + // FLOOR 3 Towards -Infinity. + // HALF_UP 4 Towards nearest neighbour. If equidistant, up. + // HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + // HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + // HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + // HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + ROUNDING_MODE = 4, // 0 to 8 + + // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS] + + // The exponent value at and beneath which toString returns exponential notation. + // Number type: -7 + TO_EXP_NEG = -7, // 0 to -MAX + + // The exponent value at and above which toString returns exponential notation. + // Number type: 21 + TO_EXP_POS = 21, // 0 to MAX + + // RANGE : [MIN_EXP, MAX_EXP] + + // The minimum exponent value, beneath which underflow to zero occurs. + // Number type: -324 (5e-324) + MIN_EXP = -1e7, // -1 to -MAX + + // The maximum exponent value, above which overflow to Infinity occurs. + // Number type: 308 (1.7976931348623157e+308) + // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow. + MAX_EXP = 1e7, // 1 to MAX + + // Whether to use cryptographically-secure random number generation, if available. + CRYPTO = false, // true or false + + // 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. + // This modulo mode is commonly known as 'truncated division' and is + // equivalent to (a % n) in JavaScript. + // FLOOR 3 The remainder has the same sign as the divisor (Python %). + // HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function. + // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). + // The remainder is always positive. + // + // The truncated division, floored division, Euclidian division and IEEE 754 remainder + // modes are commonly used for the modulus operation. + // Although the other rounding modes can also be used, they may not give useful results. + MODULO_MODE = 1, // 0 to 9 + + // The maximum number of significant digits of the result of the exponentiatedBy operation. + // If POW_PRECISION is 0, there will be unlimited significant digits. + POW_PRECISION = 0, // 0 to MAX + + // The format specification used by the BigNumber.prototype.toFormat method. + FORMAT = { + prefix: '', + groupSize: 3, + secondaryGroupSize: 0, + groupSeparator: ',', + decimalSeparator: '.', + fractionGroupSize: 0, + fractionGroupSeparator: '\xA0', // non-breaking space + suffix: '' + }, + + // The alphabet used for base conversion. It must be at least 2 characters long, with no '+', + // '-', '.', whitespace, or repeated character. + // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_' + ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz', + alphabetHasNormalDecimalDigits = true; + + + //------------------------------------------------------------------------------------------ + + + // CONSTRUCTOR + + + /* + * The BigNumber constructor and exported function. + * Create and return a new instance of a BigNumber object. + * + * v {number|string|BigNumber} A numeric value. + * [b] {number} The base of v. Integer, 2 to ALPHABET.length inclusive. + */ + function BigNumber(v, b) { + var alphabet, c, caseChanged, e, i, isNum, len, str, + x = this; + + // Enable constructor call without `new`. + if (!(x instanceof BigNumber)) return new BigNumber(v, b); + + if (b == null) { + + if (v && v._isBigNumber === true) { + x.s = v.s; + + if (!v.c || v.e > MAX_EXP) { + x.c = x.e = null; + } else if (v.e < MIN_EXP) { + x.c = [x.e = 0]; + } else { + x.e = v.e; + x.c = v.c.slice(); + } + + return; + } + + if ((isNum = typeof v == 'number') && v * 0 == 0) { + + // Use `1 / n` to handle minus zero also. + x.s = 1 / v < 0 ? (v = -v, -1) : 1; + + // Fast path for integers, where n < 2147483648 (2**31). + if (v === ~~v) { + for (e = 0, i = v; i >= 10; i /= 10, e++); + + if (e > MAX_EXP) { + x.c = x.e = null; + } else { + x.e = e; + x.c = [v]; + } + + return; + } + + str = String(v); + } else { + + if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum); + + x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1; + } + + // 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; + } + + } else { + + // '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}' + intCheck(b, 2, ALPHABET.length, 'Base'); + + // Allow exponential notation to be used with base 10 argument, while + // also rounding to DECIMAL_PLACES as with other bases. + if (b == 10 && alphabetHasNormalDecimalDigits) { + x = new BigNumber(v); + return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE); + } + + str = String(v); + + if (isNum = typeof v == 'number') { + + // Avoid potential interpretation of Infinity and NaN as base 44+ values. + if (v * 0 != 0) return parseNumeric(x, str, isNum, b); + + x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1; + + // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}' + if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, '').length > 15) { + throw Error + (tooManyDigits + v); + } + } else { + x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1; + } + + alphabet = ALPHABET.slice(0, b); + e = i = 0; + + // Check that str is a valid base b number. + // Don't use RegExp, so alphabet can contain special characters. + for (len = str.length; i < len; i++) { + if (alphabet.indexOf(c = str.charAt(i)) < 0) { + if (c == '.') { + + // If '.' is not the first character and it has not be found before. + if (i > e) { + e = len; + continue; + } + } else if (!caseChanged) { + + // Allow e.g. hexadecimal 'FF' as well as 'ff'. + if (str == str.toUpperCase() && (str = str.toLowerCase()) || + str == str.toLowerCase() && (str = str.toUpperCase())) { + caseChanged = true; + i = -1; + e = 0; + continue; + } + } + + return parseNumeric(x, String(v), isNum, b); + } + } + + // Prevent later check for length on converted number. + isNum = false; + str = convertBase(str, b, 10, x.s); + + // Decimal point? + if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + else e = str.length; + } + + // Determine leading zeros. + for (i = 0; str.charCodeAt(i) === 48; i++); + + // Determine trailing zeros. + for (len = str.length; str.charCodeAt(--len) === 48;); + + if (str = str.slice(i, ++len)) { + len -= i; + + // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}' + if (isNum && BigNumber.DEBUG && + len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) { + throw Error + (tooManyDigits + (x.s * v)); + } + + // Overflow? + if ((e = e - i - 1) > MAX_EXP) { + + // Infinity. + x.c = x.e = null; + + // Underflow? + } else if (e < MIN_EXP) { + + // Zero. + x.c = [x.e = 0]; + } else { + x.e = e; + x.c = []; + + // Transform base + + // e is the base 10 exponent. + // i is where to slice str to get the first element of the coefficient array. + i = (e + 1) % LOG_BASE; + if (e < 0) i += LOG_BASE; // i < 1 + + if (i < len) { + if (i) x.c.push(+str.slice(0, i)); + + for (len -= LOG_BASE; i < len;) { + x.c.push(+str.slice(i, i += LOG_BASE)); + } + + i = LOG_BASE - (str = str.slice(i)).length; + } else { + i -= len; + } + + for (; i--; str += '0'); + x.c.push(+str); + } + } else { + + // Zero. + x.c = [x.e = 0]; + } + } + + + // CONSTRUCTOR PROPERTIES + + + BigNumber.clone = clone; + + BigNumber.ROUND_UP = 0; + BigNumber.ROUND_DOWN = 1; + BigNumber.ROUND_CEIL = 2; + BigNumber.ROUND_FLOOR = 3; + BigNumber.ROUND_HALF_UP = 4; + BigNumber.ROUND_HALF_DOWN = 5; + BigNumber.ROUND_HALF_EVEN = 6; + BigNumber.ROUND_HALF_CEIL = 7; + BigNumber.ROUND_HALF_FLOOR = 8; + BigNumber.EUCLID = 9; + + + /* + * Configure infrequently-changing library-wide settings. + * + * Accept an object with the following optional properties (if the value of a property is + * a number, it must be an integer within the inclusive range stated): + * + * DECIMAL_PLACES {number} 0 to MAX + * ROUNDING_MODE {number} 0 to 8 + * EXPONENTIAL_AT {number|number[]} -MAX to MAX or [-MAX to 0, 0 to MAX] + * RANGE {number|number[]} -MAX to MAX (not zero) or [-MAX to -1, 1 to MAX] + * CRYPTO {boolean} true or false + * MODULO_MODE {number} 0 to 9 + * POW_PRECISION {number} 0 to MAX + * ALPHABET {string} A string of two or more unique characters which does + * not contain '.'. + * FORMAT {object} An object with some of the following properties: + * prefix {string} + * groupSize {number} + * secondaryGroupSize {number} + * groupSeparator {string} + * decimalSeparator {string} + * fractionGroupSize {number} + * fractionGroupSeparator {string} + * suffix {string} + * + * (The values assigned to the above FORMAT object properties are not checked for validity.) + * + * E.g. + * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 }) + * + * Ignore properties/parameters set to null or undefined, except for ALPHABET. + * + * Return an object with the properties current values. + */ + BigNumber.config = BigNumber.set = function (obj) { + var p, v; + + if (obj != null) { + + if (typeof obj == 'object') { + + // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive. + // '[BigNumber Error] DECIMAL_PLACES {not a primitive number|not an integer|out of range}: {v}' + if (obj.hasOwnProperty(p = 'DECIMAL_PLACES')) { + v = obj[p]; + intCheck(v, 0, MAX, p); + DECIMAL_PLACES = v; + } + + // ROUNDING_MODE {number} Integer, 0 to 8 inclusive. + // '[BigNumber Error] ROUNDING_MODE {not a primitive number|not an integer|out of range}: {v}' + if (obj.hasOwnProperty(p = 'ROUNDING_MODE')) { + v = obj[p]; + intCheck(v, 0, 8, p); + ROUNDING_MODE = v; + } + + // EXPONENTIAL_AT {number|number[]} + // Integer, -MAX to MAX inclusive or + // [integer -MAX to 0 inclusive, 0 to MAX inclusive]. + // '[BigNumber Error] EXPONENTIAL_AT {not a primitive number|not an integer|out of range}: {v}' + if (obj.hasOwnProperty(p = 'EXPONENTIAL_AT')) { + v = obj[p]; + if (v && v.pop) { + intCheck(v[0], -MAX, 0, p); + intCheck(v[1], 0, MAX, p); + TO_EXP_NEG = v[0]; + TO_EXP_POS = v[1]; + } else { + intCheck(v, -MAX, MAX, p); + TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v); + } + } + + // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or + // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive]. + // '[BigNumber Error] RANGE {not a primitive number|not an integer|out of range|cannot be zero}: {v}' + if (obj.hasOwnProperty(p = 'RANGE')) { + v = obj[p]; + if (v && v.pop) { + intCheck(v[0], -MAX, -1, p); + intCheck(v[1], 1, MAX, p); + MIN_EXP = v[0]; + MAX_EXP = v[1]; + } else { + intCheck(v, -MAX, MAX, p); + if (v) { + MIN_EXP = -(MAX_EXP = v < 0 ? -v : v); + } else { + throw Error + (bignumberError + p + ' cannot be zero: ' + v); + } + } + } + + // CRYPTO {boolean} true or false. + // '[BigNumber Error] CRYPTO not true or false: {v}' + // '[BigNumber Error] crypto unavailable' + if (obj.hasOwnProperty(p = 'CRYPTO')) { + v = obj[p]; + if (v === !!v) { + if (v) { + if (typeof crypto != 'undefined' && crypto && + (crypto.getRandomValues || crypto.randomBytes)) { + CRYPTO = v; + } else { + CRYPTO = !v; + throw Error + (bignumberError + 'crypto unavailable'); + } + } else { + CRYPTO = v; + } + } else { + throw Error + (bignumberError + p + ' not true or false: ' + v); + } + } + + // MODULO_MODE {number} Integer, 0 to 9 inclusive. + // '[BigNumber Error] MODULO_MODE {not a primitive number|not an integer|out of range}: {v}' + if (obj.hasOwnProperty(p = 'MODULO_MODE')) { + v = obj[p]; + intCheck(v, 0, 9, p); + MODULO_MODE = v; + } + + // POW_PRECISION {number} Integer, 0 to MAX inclusive. + // '[BigNumber Error] POW_PRECISION {not a primitive number|not an integer|out of range}: {v}' + if (obj.hasOwnProperty(p = 'POW_PRECISION')) { + v = obj[p]; + intCheck(v, 0, MAX, p); + POW_PRECISION = v; + } + + // FORMAT {object} + // '[BigNumber Error] FORMAT not an object: {v}' + if (obj.hasOwnProperty(p = 'FORMAT')) { + v = obj[p]; + if (typeof v == 'object') FORMAT = v; + else throw Error + (bignumberError + p + ' not an object: ' + v); + } + + // ALPHABET {string} + // '[BigNumber Error] ALPHABET invalid: {v}' + if (obj.hasOwnProperty(p = 'ALPHABET')) { + v = obj[p]; + + // Disallow if less than two characters, + // or if it contains '+', '-', '.', whitespace, or a repeated character. + if (typeof v == 'string' && !/^.?$|[+\-.\s]|(.).*\1/.test(v)) { + alphabetHasNormalDecimalDigits = v.slice(0, 10) == '0123456789'; + ALPHABET = v; + } else { + throw Error + (bignumberError + p + ' invalid: ' + v); + } + } + + } else { + + // '[BigNumber Error] Object expected: {v}' + throw Error + (bignumberError + 'Object expected: ' + obj); + } + } + + return { + DECIMAL_PLACES: DECIMAL_PLACES, + ROUNDING_MODE: ROUNDING_MODE, + EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS], + RANGE: [MIN_EXP, MAX_EXP], + CRYPTO: CRYPTO, + MODULO_MODE: MODULO_MODE, + POW_PRECISION: POW_PRECISION, + FORMAT: FORMAT, + ALPHABET: ALPHABET + }; + }; + + + /* + * Return true if v is a BigNumber instance, otherwise return false. + * + * If BigNumber.DEBUG is true, throw if a BigNumber instance is not well-formed. + * + * v {any} + * + * '[BigNumber Error] Invalid BigNumber: {v}' + */ + BigNumber.isBigNumber = function (v) { + if (!v || v._isBigNumber !== true) return false; + if (!BigNumber.DEBUG) return true; + + var i, n, + c = v.c, + e = v.e, + s = v.s; + + out: if ({}.toString.call(c) == '[object Array]') { + + if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) { + + // If the first element is zero, the BigNumber value must be zero. + if (c[0] === 0) { + if (e === 0 && c.length === 1) return true; + break out; + } + + // Calculate number of digits that c[0] should have, based on the exponent. + i = (e + 1) % LOG_BASE; + if (i < 1) i += LOG_BASE; + + // Calculate number of digits of c[0]. + //if (Math.ceil(Math.log(c[0] + 1) / Math.LN10) == i) { + if (String(c[0]).length == i) { + + for (i = 0; i < c.length; i++) { + n = c[i]; + if (n < 0 || n >= BASE || n !== mathfloor(n)) break out; + } + + // Last element cannot be zero, unless it is the only element. + if (n !== 0) return true; + } + } + + // Infinity/NaN + } else if (c === null && e === null && (s === null || s === 1 || s === -1)) { + return true; + } + + throw Error + (bignumberError + 'Invalid BigNumber: ' + v); + }; + + + /* + * Return a new BigNumber whose value is the maximum of the arguments. + * + * arguments {number|string|BigNumber} + */ + BigNumber.maximum = BigNumber.max = function () { + return maxOrMin(arguments, -1); + }; + + + /* + * Return a new BigNumber whose value is the minimum of the arguments. + * + * arguments {number|string|BigNumber} + */ + BigNumber.minimum = BigNumber.min = function () { + return maxOrMin(arguments, 1); + }; + + + /* + * Return a new BigNumber with a random value equal to or greater than 0 and less than 1, + * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing + * zeros are produced). + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp}' + * '[BigNumber Error] crypto unavailable' + */ + BigNumber.random = (function () { + var pow2_53 = 0x20000000000000; + + // Return a 53 bit integer n, where 0 <= n < 9007199254740992. + // Check if Math.random() produces more than 32 bits of randomness. + // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits. + // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1. + var random53bitInt = (Math.random() * pow2_53) & 0x1fffff + ? function () { return mathfloor(Math.random() * pow2_53); } + : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) + + (Math.random() * 0x800000 | 0); }; + + return function (dp) { + var a, b, e, k, v, + i = 0, + c = [], + rand = new BigNumber(ONE); + + if (dp == null) dp = DECIMAL_PLACES; + else intCheck(dp, 0, MAX); + + k = mathceil(dp / LOG_BASE); + + if (CRYPTO) { + + // Browsers supporting crypto.getRandomValues. + if (crypto.getRandomValues) { + + a = crypto.getRandomValues(new Uint32Array(k *= 2)); + + for (; i < k;) { + + // 53 bits: + // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2) + // 11111 11111111 11111111 11111111 11100000 00000000 00000000 + // ((Math.pow(2, 32) - 1) >>> 11).toString(2) + // 11111 11111111 11111111 + // 0x20000 is 2^21. + v = a[i] * 0x20000 + (a[i + 1] >>> 11); + + // Rejection sampling: + // 0 <= v < 9007199254740992 + // Probability that v >= 9e15, is + // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251 + if (v >= 9e15) { + b = crypto.getRandomValues(new Uint32Array(2)); + a[i] = b[0]; + a[i + 1] = b[1]; + } else { + + // 0 <= v <= 8999999999999999 + // 0 <= (v % 1e14) <= 99999999999999 + c.push(v % 1e14); + i += 2; + } + } + i = k / 2; + + // Node.js supporting crypto.randomBytes. + } else if (crypto.randomBytes) { + + // buffer + a = crypto.randomBytes(k *= 7); + + for (; i < k;) { + + // 0x1000000000000 is 2^48, 0x10000000000 is 2^40 + // 0x100000000 is 2^32, 0x1000000 is 2^24 + // 11111 11111111 11111111 11111111 11111111 11111111 11111111 + // 0 <= v < 9007199254740992 + v = ((a[i] & 31) * 0x1000000000000) + (a[i + 1] * 0x10000000000) + + (a[i + 2] * 0x100000000) + (a[i + 3] * 0x1000000) + + (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6]; + + if (v >= 9e15) { + crypto.randomBytes(7).copy(a, i); + } else { + + // 0 <= (v % 1e14) <= 99999999999999 + c.push(v % 1e14); + i += 7; + } + } + i = k / 7; + } else { + CRYPTO = false; + throw Error + (bignumberError + 'crypto unavailable'); + } + } + + // Use Math.random. + if (!CRYPTO) { + + for (; i < k;) { + v = random53bitInt(); + if (v < 9e15) c[i++] = v % 1e14; + } + } + + k = c[--i]; + dp %= LOG_BASE; + + // Convert trailing digits to zeros according to dp. + if (k && dp) { + v = POWS_TEN[LOG_BASE - dp]; + c[i] = mathfloor(k / v) * v; + } + + // Remove trailing elements which are zero. + for (; c[i] === 0; c.pop(), i--); + + // Zero? + if (i < 0) { + c = [e = 0]; + } else { + + // Remove leading elements which are zero and adjust exponent accordingly. + for (e = -1 ; c[0] === 0; c.splice(0, 1), e -= LOG_BASE); + + // Count the digits of the first element of c to determine leading zeros, and... + for (i = 1, v = c[0]; v >= 10; v /= 10, i++); + + // adjust the exponent accordingly. + if (i < LOG_BASE) e -= LOG_BASE - i; + } + + rand.e = e; + rand.c = c; + return rand; + }; + })(); + + + /* + * Return a BigNumber whose value is the sum of the arguments. + * + * arguments {number|string|BigNumber} + */ + BigNumber.sum = function () { + var i = 1, + args = arguments, + sum = new BigNumber(args[0]); + for (; i < args.length;) sum = sum.plus(args[i++]); + return sum; + }; + + + // PRIVATE FUNCTIONS + + + // Called by BigNumber and BigNumber.prototype.toString. + convertBase = (function () { + var decimal = '0123456789'; + + /* + * Convert string of baseIn to an array of numbers of baseOut. + * Eg. toBaseOut('255', 10, 16) returns [15, 15]. + * Eg. toBaseOut('ff', 16, 10) returns [2, 5, 5]. + */ + function toBaseOut(str, baseIn, baseOut, alphabet) { + var j, + arr = [0], + arrL, + i = 0, + len = str.length; + + for (; i < len;) { + for (arrL = arr.length; arrL--; arr[arrL] *= baseIn); + + arr[0] += alphabet.indexOf(str.charAt(i++)); + + for (j = 0; j < arr.length; j++) { + + if (arr[j] > baseOut - 1) { + if (arr[j + 1] == null) arr[j + 1] = 0; + arr[j + 1] += arr[j] / baseOut | 0; + arr[j] %= baseOut; + } + } + } + + return arr.reverse(); + } + + // Convert a numeric string of baseIn to a numeric string of baseOut. + // If the caller is toString, we are converting from base 10 to baseOut. + // If the caller is BigNumber, we are converting from baseIn to base 10. + return function (str, baseIn, baseOut, sign, callerIsToString) { + var alphabet, d, e, k, r, x, xc, y, + i = str.indexOf('.'), + dp = DECIMAL_PLACES, + rm = ROUNDING_MODE; + + // Non-integer. + if (i >= 0) { + k = POW_PRECISION; + + // Unlimited precision. + POW_PRECISION = 0; + str = str.replace('.', ''); + y = new BigNumber(baseIn); + x = y.pow(str.length - i); + POW_PRECISION = k; + + // Convert str as if an integer, then restore the fraction part by dividing the + // result by its base raised to a power. + + y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, '0'), + 10, baseOut, decimal); + y.e = y.c.length; + } + + // Convert the number as integer. + + xc = toBaseOut(str, baseIn, baseOut, callerIsToString + ? (alphabet = ALPHABET, decimal) + : (alphabet = decimal, ALPHABET)); + + // xc now represents str as an integer and converted to baseOut. e is the exponent. + e = k = xc.length; + + // Remove trailing zeros. + for (; xc[--k] == 0; xc.pop()); + + // Zero? + if (!xc[0]) return alphabet.charAt(0); + + // Does str represent an integer? If so, no need for the division. + if (i < 0) { + --e; + } else { + x.c = xc; + x.e = e; + + // The sign is needed for correct rounding. + x.s = sign; + x = div(x, y, dp, rm, baseOut); + xc = x.c; + r = x.r; + e = x.e; + } + + // xc now represents str converted to baseOut. + + // The index of the rounding digit. + d = e + dp + 1; + + // The rounding digit: the digit to the right of the digit that may be rounded up. + i = xc[d]; + + // Look at the rounding digits and mode to determine whether to round up. + + k = baseOut / 2; + r = r || d < 0 || xc[d + 1] != null; + + r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) + : i > k || i == k &&(rm == 4 || r || rm == 6 && xc[d - 1] & 1 || + rm == (x.s < 0 ? 8 : 7)); + + // If the index of the rounding digit is not greater than zero, or xc represents + // zero, then the result of the base conversion is zero or, if rounding up, a value + // such as 0.00001. + if (d < 1 || !xc[0]) { + + // 1^-dp or 0 + str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0); + } else { + + // Truncate xc to the required number of decimal places. + xc.length = d; + + // Round up? + if (r) { + + // Rounding up may mean the previous digit has to be rounded up and so on. + for (--baseOut; ++xc[--d] > baseOut;) { + xc[d] = 0; + + if (!d) { + ++e; + xc = [1].concat(xc); + } + } + } + + // Determine trailing zeros. + for (k = xc.length; !xc[--k];); + + // E.g. [4, 11, 15] becomes 4bf. + for (i = 0, str = ''; i <= k; str += alphabet.charAt(xc[i++])); + + // Add leading zeros, decimal point and trailing zeros as required. + str = toFixedPoint(str, e, alphabet.charAt(0)); + } + + // The caller will add the sign. + return str; + }; + })(); + + + // Perform division in the specified base. Called by div and convertBase. + div = (function () { + + // Assume non-zero x and k. + function multiply(x, k, base) { + var m, temp, xlo, xhi, + carry = 0, + i = x.length, + klo = k % SQRT_BASE, + khi = k / SQRT_BASE | 0; + + for (x = x.slice(); i--;) { + xlo = x[i] % SQRT_BASE; + xhi = x[i] / SQRT_BASE | 0; + m = khi * xlo + xhi * klo; + temp = klo * xlo + ((m % SQRT_BASE) * SQRT_BASE) + carry; + carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi; + x[i] = temp % base; + } + + if (carry) x = [carry].concat(x); + + return x; + } + + function compare(a, b, aL, bL) { + var i, cmp; + + if (aL != bL) { + cmp = aL > bL ? 1 : -1; + } else { + + for (i = cmp = 0; i < aL; i++) { + + if (a[i] != b[i]) { + cmp = a[i] > b[i] ? 1 : -1; + break; + } + } + } + + return cmp; + } + + 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.splice(0, 1)); + } + + // x: dividend, y: divisor. + return function (x, y, dp, rm, base) { + var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0, + yL, yz, + s = x.s == y.s ? 1 : -1, + xc = x.c, + yc = y.c; + + // Either NaN, Infinity or 0? + if (!xc || !xc[0] || !yc || !yc[0]) { + + return new BigNumber( + + // Return NaN if either NaN, or both Infinity or 0. + !x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN : + + // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0. + xc && xc[0] == 0 || !yc ? s * 0 : s / 0 + ); + } + + q = new BigNumber(s); + qc = q.c = []; + e = x.e - y.e; + s = dp + e + 1; + + if (!base) { + base = BASE; + e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE); + s = s / LOG_BASE | 0; + } + + // Result exponent may be one less then the current value of e. + // The coefficients of the BigNumbers from convertBase may have trailing zeros. + for (i = 0; yc[i] == (xc[i] || 0); i++); + + if (yc[i] > (xc[i] || 0)) e--; + + if (s < 0) { + qc.push(1); + more = true; + } else { + xL = xc.length; + yL = yc.length; + i = 0; + s += 2; + + // Normalise xc and yc so highest order digit of yc is >= base / 2. + + n = mathfloor(base / (yc[0] + 1)); + + // Not necessary, but to handle odd bases where yc[0] == (base / 2) - 1. + // if (n > 1 || n++ == 1 && yc[0] < base / 2) { + if (n > 1) { + yc = multiply(yc, n, base); + xc = multiply(xc, n, base); + yL = yc.length; + xL = xc.length; + } + + xi = yL; + rem = xc.slice(0, yL); + remL = rem.length; + + // Add zeros to make remainder as long as divisor. + for (; remL < yL; rem[remL++] = 0); + yz = yc.slice(); + yz = [0].concat(yz); + yc0 = yc[0]; + if (yc[1] >= base / 2) yc0++; + // Not necessary, but to prevent trial digit n > base, when using base 3. + // else if (base == 3 && yc0 == 1) yc0 = 1 + 1e-15; + + do { + n = 0; + + // Compare divisor and remainder. + cmp = compare(yc, rem, yL, remL); + + // If divisor < remainder. + if (cmp < 0) { + + // Calculate trial digit, n. + + rem0 = rem[0]; + if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); + + // n is how many times the divisor goes into the current remainder. + n = mathfloor(rem0 / yc0); + + // Algorithm: + // product = divisor multiplied by trial digit (n). + // Compare product and remainder. + // If product is greater than remainder: + // Subtract divisor from product, decrement trial digit. + // Subtract product from remainder. + // If product was less than remainder at the last compare: + // Compare new remainder and divisor. + // If remainder is greater than divisor: + // Subtract divisor from remainder, increment trial digit. + + if (n > 1) { + + // n may be > base only when base is 3. + if (n >= base) n = base - 1; + + // product = divisor * trial digit. + prod = multiply(yc, n, base); + prodL = prod.length; + remL = rem.length; + + // Compare product and remainder. + // If product > remainder then trial digit n too high. + // n is 1 too high about 5% of the time, and is not known to have + // ever been more than 1 too high. + while (compare(prod, rem, prodL, remL) == 1) { + n--; + + // Subtract divisor from product. + subtract(prod, yL < prodL ? yz : yc, prodL, base); + prodL = prod.length; + cmp = 1; + } + } else { + + // n is 0 or 1, cmp is -1. + // If n is 0, there is no need to compare yc and rem again below, + // so change cmp to 1 to avoid it. + // If n is 1, leave cmp as -1, so yc and rem are compared again. + if (n == 0) { + + // divisor < remainder, so n must be at least 1. + cmp = n = 1; + } + + // product = divisor + prod = yc.slice(); + prodL = prod.length; + } + + if (prodL < remL) prod = [0].concat(prod); + + // Subtract product from remainder. + subtract(rem, prod, remL, base); + remL = rem.length; + + // If product was < remainder. + if (cmp == -1) { + + // Compare divisor and new remainder. + // If divisor < new remainder, subtract divisor from remainder. + // Trial digit n too low. + // n is 1 too low about 5% of the time, and very rarely 2 too low. + while (compare(yc, rem, yL, remL) < 1) { + n++; + + // Subtract divisor from remainder. + subtract(rem, yL < remL ? yz : yc, remL, base); + remL = rem.length; + } + } + } else if (cmp === 0) { + n++; + rem = [0]; + } // else cmp === 1 and n will be 0 + + // Add the next digit, n, to the result array. + qc[i++] = n; + + // Update the remainder. + if (rem[0]) { + rem[remL++] = xc[xi] || 0; + } else { + rem = [xc[xi]]; + remL = 1; + } + } while ((xi++ < xL || rem[0] != null) && s--); + + more = rem[0] != null; + + // Leading zero? + if (!qc[0]) qc.splice(0, 1); + } + + if (base == BASE) { + + // To calculate q.e, first get the number of digits of qc[0]. + for (i = 1, s = qc[0]; s >= 10; s /= 10, i++); + + round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more); + + // Caller is convertBase. + } else { + q.e = e; + q.r = +more; + } + + return q; + }; + })(); + + + /* + * Return a string representing the value of BigNumber n in fixed-point or exponential + * notation rounded to the specified decimal places or significant digits. + * + * n: a BigNumber. + * i: the index of the last digit required (i.e. the digit that may be rounded up). + * rm: the rounding mode. + * id: 1 (toExponential) or 2 (toPrecision). + */ + function format(n, i, rm, id) { + var c0, e, ne, len, str; + + if (rm == null) rm = ROUNDING_MODE; + else intCheck(rm, 0, 8); + + if (!n.c) return n.toString(); + + c0 = n.c[0]; + ne = n.e; + + if (i == null) { + str = coeffToString(n.c); + str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS) + ? toExponential(str, ne) + : toFixedPoint(str, ne, '0'); + } else { + n = round(new BigNumber(n), i, rm); + + // n.e may have changed if the value was rounded up. + e = n.e; + + str = coeffToString(n.c); + len = str.length; + + // toPrecision returns exponential notation if the number of significant digits + // specified is less than the number of digits necessary to represent the integer + // part of the value in fixed-point notation. + + // Exponential notation. + if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) { + + // Append zeros? + for (; len < i; str += '0', len++); + str = toExponential(str, e); + + // Fixed-point notation. + } else { + i -= ne + (id === 2 && e > ne); + str = toFixedPoint(str, e, '0'); + + // Append zeros? + if (e + 1 > len) { + if (--i > 0) for (str += '.'; i--; str += '0'); + } else { + i += e - len; + if (i > 0) { + if (e + 1 == len) str += '.'; + for (; i--; str += '0'); + } + } + } + } + + return n.s < 0 && c0 ? '-' + str : str; + } + + + // Handle BigNumber.max and BigNumber.min. + // If any number is NaN, return NaN. + function maxOrMin(args, n) { + var k, y, + i = 1, + x = new BigNumber(args[0]); + + for (; i < args.length; i++) { + y = new BigNumber(args[i]); + if (!y.s || (k = compare(x, y)) === n || k === 0 && x.s === n) { + x = y; + } + } + + return x; + } + + + /* + * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP. + * Called by minus, plus and times. + */ + function normalise(n, c, e) { + var i = 1, + j = c.length; + + // Remove trailing zeros. + for (; !c[--j]; c.pop()); + + // Calculate the base 10 exponent. First get the number of digits of c[0]. + for (j = c[0]; j >= 10; j /= 10, i++); + + // Overflow? + if ((e = i + e * LOG_BASE - 1) > MAX_EXP) { + + // Infinity. + n.c = n.e = null; + + // Underflow? + } else if (e < MIN_EXP) { + + // Zero. + n.c = [n.e = 0]; + } else { + n.e = e; + n.c = c; + } + + return n; + } + + + // Handle values that fail the validity test in BigNumber. + parseNumeric = (function () { + var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, + dotAfter = /^([^.]+)\.$/, + dotBefore = /^\.([^.]+)$/, + isInfinityOrNaN = /^-?(Infinity|NaN)$/, + whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g; + + return function (x, str, isNum, b) { + var base, + s = isNum ? str : str.replace(whitespaceOrPlus, ''); + + // No exception on ±Infinity or NaN. + if (isInfinityOrNaN.test(s)) { + x.s = isNaN(s) ? null : s < 0 ? -1 : 1; + } else { + if (!isNum) { + + // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i + s = s.replace(basePrefix, function (m, p1, p2) { + base = (p2 = p2.toLowerCase()) == 'x' ? 16 : p2 == 'b' ? 2 : 8; + return !b || b == base ? p1 : m; + }); + + if (b) { + base = b; + + // E.g. '1.' to '1', '.1' to '0.1' + s = s.replace(dotAfter, '$1').replace(dotBefore, '0.$1'); + } + + if (str != s) return new BigNumber(s, base); + } + + // '[BigNumber Error] Not a number: {n}' + // '[BigNumber Error] Not a base {b} number: {n}' + if (BigNumber.DEBUG) { + throw Error + (bignumberError + 'Not a' + (b ? ' base ' + b : '') + ' number: ' + str); + } + + // NaN + x.s = null; + } + + x.c = x.e = null; + } + })(); + + + /* + * Round x to sd significant digits using rounding mode rm. Check for over/under-flow. + * If r is truthy, it is known that there are more digits after the rounding digit. + */ + function round(x, sd, rm, r) { + var d, i, j, k, n, ni, rd, + xc = x.c, + pows10 = POWS_TEN; + + // if x is not Infinity or NaN... + if (xc) { + + // rd is the rounding digit, i.e. the digit after the digit that may be rounded up. + // n is a base 1e14 number, the value of the element of array x.c containing rd. + // ni is the index of n within x.c. + // d is the number of digits of n. + // i is the index of rd within n including leading zeros. + // j is the actual index of rd within n (if < 0, rd is a leading zero). + out: { + + // Get the number of digits of the first element of xc. + for (d = 1, k = xc[0]; k >= 10; k /= 10, d++); + i = sd - d; + + // If the rounding digit is in the first element of xc... + if (i < 0) { + i += LOG_BASE; + j = sd; + n = xc[ni = 0]; + + // Get the rounding digit at index j of n. + rd = mathfloor(n / pows10[d - j - 1] % 10); + } else { + ni = mathceil((i + 1) / LOG_BASE); + + if (ni >= xc.length) { + + if (r) { + + // Needed by sqrt. + for (; xc.length <= ni; xc.push(0)); + n = rd = 0; + d = 1; + i %= LOG_BASE; + j = i - LOG_BASE + 1; + } else { + break out; + } + } else { + n = k = xc[ni]; + + // Get the number of digits of n. + for (d = 1; k >= 10; k /= 10, d++); + + // Get the index of rd within n. + i %= LOG_BASE; + + // Get the index of rd within n, adjusted for leading zeros. + // The number of leading zeros of n is given by LOG_BASE - d. + j = i - LOG_BASE + d; + + // Get the rounding digit at index j of n. + rd = j < 0 ? 0 : mathfloor(n / pows10[d - j - 1] % 10); + } + } + + r = r || sd < 0 || + + // Are there any non-zero digits after the rounding digit? + // The expression n % pows10[d - j - 1] returns all digits of n to the right + // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714. + xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]); + + r = rm < 4 + ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) + : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 && + + // Check whether the digit to the left of the rounding digit is odd. + ((i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10) & 1 || + rm == (x.s < 0 ? 8 : 7)); + + if (sd < 1 || !xc[0]) { + xc.length = 0; + + if (r) { + + // Convert sd to decimal places. + sd -= x.e + 1; + + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE]; + x.e = -sd || 0; + } else { + + // Zero. + xc[0] = x.e = 0; + } + + return x; + } + + // Remove excess digits. + if (i == 0) { + xc.length = ni; + k = 1; + ni--; + } else { + xc.length = ni + 1; + k = pows10[LOG_BASE - i]; + + // E.g. 56700 becomes 56000 if 7 is the rounding digit. + // j > 0 means i > number of leading zeros of n. + xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0; + } + + // Round up? + if (r) { + + for (; ;) { + + // If the digit to be rounded up is in the first element of xc... + if (ni == 0) { + + // i will be the length of xc[0] before k is added. + for (i = 1, j = xc[0]; j >= 10; j /= 10, i++); + j = xc[0] += k; + for (k = 1; j >= 10; j /= 10, k++); + + // if i != k the length has increased. + if (i != k) { + x.e++; + if (xc[0] == BASE) xc[0] = 1; + } + + break; + } else { + xc[ni] += k; + if (xc[ni] != BASE) break; + xc[ni--] = 0; + k = 1; + } + } + } + + // Remove trailing zeros. + for (i = xc.length; xc[--i] === 0; xc.pop()); + } + + // Overflow? Infinity. + if (x.e > MAX_EXP) { + x.c = x.e = null; + + // Underflow? Zero. + } else if (x.e < MIN_EXP) { + x.c = [x.e = 0]; + } + } + + return x; + } + + + function valueOf(n) { + var str, + e = n.e; + + if (e === null) return n.toString(); + + str = coeffToString(n.c); + + str = e <= TO_EXP_NEG || e >= TO_EXP_POS + ? toExponential(str, e) + : toFixedPoint(str, e, '0'); + + return n.s < 0 ? '-' + str : str; + } + + + // PROTOTYPE/INSTANCE METHODS + + + /* + * Return a new BigNumber whose value is the absolute value of this BigNumber. + */ + P.absoluteValue = P.abs = function () { + var x = new BigNumber(this); + if (x.s < 0) x.s = 1; + return x; + }; + + + /* + * Return + * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b), + * -1 if the value of this BigNumber is less than the value of BigNumber(y, b), + * 0 if they have the same value, + * or null if the value of either is NaN. + */ + P.comparedTo = function (y, b) { + return compare(this, new BigNumber(y, b)); + }; + + + /* + * If dp is undefined or null or true or false, return the number of decimal places of the + * value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN. + * + * Otherwise, if dp is a number, return a new BigNumber whose value is the value of this + * BigNumber rounded to a maximum of dp decimal places using rounding mode rm, or + * ROUNDING_MODE if rm is omitted. + * + * [dp] {number} Decimal places: integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' + */ + P.decimalPlaces = P.dp = function (dp, rm) { + var c, n, v, + x = this; + + if (dp != null) { + intCheck(dp, 0, MAX); + if (rm == null) rm = ROUNDING_MODE; + else intCheck(rm, 0, 8); + + return round(new BigNumber(x), dp + x.e + 1, rm); + } + + if (!(c = x.c)) return null; + n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE; + + // Subtract the number of trailing zeros of the last number. + if (v = c[v]) for (; v % 10 == 0; v /= 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 BigNumber whose value is the value of this BigNumber divided by the value of + * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE. + */ + P.dividedBy = P.div = function (y, b) { + return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE); + }; + + + /* + * Return a new BigNumber whose value is the integer part of dividing the value of this + * BigNumber by the value of BigNumber(y, b). + */ + P.dividedToIntegerBy = P.idiv = function (y, b) { + return div(this, new BigNumber(y, b), 0, 1); + }; + + + /* + * Return a BigNumber whose value is the value of this BigNumber exponentiated by n. + * + * If m is present, return the result modulo m. + * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE. + * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using ROUNDING_MODE. + * + * The modular power operation works efficiently when x, n, and m are integers, otherwise it + * is equivalent to calculating x.exponentiatedBy(n).modulo(m) with a POW_PRECISION of 0. + * + * n {number|string|BigNumber} The exponent. An integer. + * [m] {number|string|BigNumber} The modulus. + * + * '[BigNumber Error] Exponent not an integer: {n}' + */ + P.exponentiatedBy = P.pow = function (n, m) { + var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y, + x = this; + + n = new BigNumber(n); + + // Allow NaN and ±Infinity, but not other non-integers. + if (n.c && !n.isInteger()) { + throw Error + (bignumberError + 'Exponent not an integer: ' + valueOf(n)); + } + + if (m != null) m = new BigNumber(m); + + // Exponent of MAX_SAFE_INTEGER is 15. + nIsBig = n.e > 14; + + // If x is NaN, ±Infinity, ±0 or ±1, or n is ±Infinity, NaN or ±0. + if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) { + + // The sign of the result of pow when x is negative depends on the evenness of n. + // If +n overflows to ±Infinity, the evenness of n would be not be known. + y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? n.s * (2 - isOdd(n)) : +valueOf(n))); + return m ? y.mod(m) : y; + } + + nIsNeg = n.s < 0; + + if (m) { + + // x % m returns NaN if abs(m) is zero, or m is NaN. + if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN); + + isModExp = !nIsNeg && x.isInteger() && m.isInteger(); + + if (isModExp) x = x.mod(m); + + // Overflow to ±Infinity: >=2**1e10 or >=1.0000024**1e15. + // Underflow to ±0: <=0.79**1e10 or <=0.9999975**1e15. + } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0 + // [1, 240000000] + ? x.c[0] > 1 || nIsBig && x.c[1] >= 24e7 + // [80000000000000] [99999750000000] + : x.c[0] < 8e13 || nIsBig && x.c[0] <= 9999975e7))) { + + // If x is negative and n is odd, k = -0, else k = 0. + k = x.s < 0 && isOdd(n) ? -0 : 0; + + // If x >= 1, k = ±Infinity. + if (x.e > -1) k = 1 / k; + + // If n is negative return ±0, else return ±Infinity. + return new BigNumber(nIsNeg ? 1 / k : k); + + } else if (POW_PRECISION) { + + // Truncating each coefficient array to a length of k after each multiplication + // equates to truncating significant digits to POW_PRECISION + [28, 41], + // i.e. there will be a minimum of 28 guard digits retained. + k = mathceil(POW_PRECISION / LOG_BASE + 2); + } + + if (nIsBig) { + half = new BigNumber(0.5); + if (nIsNeg) n.s = 1; + nIsOdd = isOdd(n); + } else { + i = Math.abs(+valueOf(n)); + nIsOdd = i % 2; + } + + y = new BigNumber(ONE); + + // Performs 54 loop iterations for n of 9007199254740991. + for (; ;) { + + if (nIsOdd) { + y = y.times(x); + if (!y.c) break; + + if (k) { + if (y.c.length > k) y.c.length = k; + } else if (isModExp) { + y = y.mod(m); //y = y.minus(div(y, m, 0, MODULO_MODE).times(m)); + } + } + + if (i) { + i = mathfloor(i / 2); + if (i === 0) break; + nIsOdd = i % 2; + } else { + n = n.times(half); + round(n, n.e + 1, 1); + + if (n.e > 14) { + nIsOdd = isOdd(n); + } else { + i = +valueOf(n); + if (i === 0) break; + nIsOdd = i % 2; + } + } + + x = x.times(x); + + if (k) { + if (x.c && x.c.length > k) x.c.length = k; + } else if (isModExp) { + x = x.mod(m); //x = x.minus(div(x, m, 0, MODULO_MODE).times(m)); + } + } + + if (isModExp) return y; + if (nIsNeg) y = ONE.div(y); + + return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber rounded to an integer + * using rounding mode rm, or ROUNDING_MODE if rm is omitted. + * + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {rm}' + */ + P.integerValue = function (rm) { + var n = new BigNumber(this); + if (rm == null) rm = ROUNDING_MODE; + else intCheck(rm, 0, 8); + return round(n, n.e + 1, rm); + }; + + + /* + * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b), + * otherwise return false. + */ + P.isEqualTo = P.eq = function (y, b) { + return compare(this, new BigNumber(y, b)) === 0; + }; + + + /* + * Return true if the value of this BigNumber is a finite number, otherwise return false. + */ + P.isFinite = function () { + return !!this.c; + }; + + + /* + * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b), + * otherwise return false. + */ + P.isGreaterThan = P.gt = function (y, b) { + return compare(this, new BigNumber(y, b)) > 0; + }; + + + /* + * Return true if the value of this BigNumber is greater than or equal to the value of + * BigNumber(y, b), otherwise return false. + */ + P.isGreaterThanOrEqualTo = P.gte = function (y, b) { + return (b = compare(this, new BigNumber(y, b))) === 1 || b === 0; + + }; + + + /* + * Return true if the value of this BigNumber is an integer, otherwise return false. + */ + P.isInteger = function () { + return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2; + }; + + + /* + * Return true if the value of this BigNumber is less than the value of BigNumber(y, b), + * otherwise return false. + */ + P.isLessThan = P.lt = function (y, b) { + return compare(this, new BigNumber(y, b)) < 0; + }; + + + /* + * Return true if the value of this BigNumber is less than or equal to the value of + * BigNumber(y, b), otherwise return false. + */ + P.isLessThanOrEqualTo = P.lte = function (y, b) { + return (b = compare(this, new BigNumber(y, b))) === -1 || b === 0; + }; + + + /* + * Return true if the value of this BigNumber is NaN, otherwise return false. + */ + P.isNaN = function () { + return !this.s; + }; + + + /* + * Return true if the value of this BigNumber is negative, otherwise return false. + */ + P.isNegative = function () { + return this.s < 0; + }; + + + /* + * Return true if the value of this BigNumber is positive, otherwise return false. + */ + P.isPositive = function () { + return this.s > 0; + }; + + + /* + * Return true if the value of this BigNumber is 0 or -0, otherwise return false. + */ + P.isZero = function () { + return !!this.c && this.c[0] == 0; + }; + + + /* + * n - 0 = n + * n - N = N + * n - I = -I + * 0 - n = -n + * 0 - 0 = 0 + * 0 - N = N + * 0 - I = -I + * N - n = N + * N - 0 = N + * N - N = N + * N - I = N + * I - n = I + * I - 0 = I + * I - N = N + * I - I = N + * + * Return a new BigNumber whose value is the value of this BigNumber minus the value of + * BigNumber(y, b). + */ + P.minus = function (y, b) { + var i, j, t, xLTy, + x = this, + a = x.s; + + y = new BigNumber(y, b); + b = y.s; + + // Either NaN? + if (!a || !b) return new BigNumber(NaN); + + // Signs differ? + if (a != b) { + y.s = -b; + return x.plus(y); + } + + var xe = x.e / LOG_BASE, + ye = y.e / LOG_BASE, + xc = x.c, + yc = y.c; + + if (!xe || !ye) { + + // Either Infinity? + if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN); + + // Either zero? + if (!xc[0] || !yc[0]) { + + // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. + return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x : + + // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity + ROUNDING_MODE == 3 ? -0 : 0); + } + } + + xe = bitFloor(xe); + ye = bitFloor(ye); + xc = xc.slice(); + + // Determine which is the bigger number. + if (a = xe - ye) { + + if (xLTy = a < 0) { + a = -a; + t = xc; + } else { + ye = xe; + t = yc; + } + + t.reverse(); + + // Prepend zeros to equalise exponents. + for (b = a; b--; t.push(0)); + t.reverse(); + } else { + + // Exponents equal. Check digit by digit. + j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b; + + for (a = b = 0; b < j; b++) { + + if (xc[b] != yc[b]) { + xLTy = xc[b] < yc[b]; + break; + } + } + } + + // x < y? Point xc to the array of the bigger number. + if (xLTy) { + t = xc; + xc = yc; + yc = t; + y.s = -y.s; + } + + b = (j = yc.length) - (i = xc.length); + + // Append zeros to xc if shorter. + // No need to add zeros to yc if shorter as subtract only needs to start at yc.length. + if (b > 0) for (; b--; xc[i++] = 0); + b = BASE - 1; + + // Subtract yc from xc. + for (; j > a;) { + + if (xc[--j] < yc[j]) { + for (i = j; i && !xc[--i]; xc[i] = b); + --xc[i]; + xc[j] += BASE; + } + + xc[j] -= yc[j]; + } + + // Remove leading zeros and adjust exponent accordingly. + for (; xc[0] == 0; xc.splice(0, 1), --ye); + + // Zero? + if (!xc[0]) { + + // Following IEEE 754 (2008) 6.3, + // n - n = +0 but n - n = -0 when rounding towards -Infinity. + y.s = ROUNDING_MODE == 3 ? -1 : 1; + y.c = [y.e = 0]; + return y; + } + + // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity + // for finite x and y. + return normalise(y, xc, ye); + }; + + + /* + * 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 BigNumber whose value is the value of this BigNumber modulo the value of + * BigNumber(y, b). The result depends on the value of MODULO_MODE. + */ + P.modulo = P.mod = function (y, b) { + var q, s, + x = this; + + y = new BigNumber(y, b); + + // Return NaN if x is Infinity or NaN, or y is NaN or zero. + if (!x.c || !y.s || y.c && !y.c[0]) { + return new BigNumber(NaN); + + // Return x if y is Infinity or x is zero. + } else if (!y.c || x.c && !x.c[0]) { + return new BigNumber(x); + } + + if (MODULO_MODE == 9) { + + // Euclidian division: q = sign(y) * floor(x / abs(y)) + // r = x - qy where 0 <= r < abs(y) + s = y.s; + y.s = 1; + q = div(x, y, 0, 3); + y.s = s; + q.s *= s; + } else { + q = div(x, y, 0, MODULO_MODE); + } + + y = x.minus(q.times(y)); + + // To match JavaScript %, ensure sign of zero is sign of dividend. + if (!y.c[0] && MODULO_MODE == 1) y.s = x.s; + + return y; + }; + + + /* + * n * 0 = 0 + * n * N = N + * n * I = I + * 0 * n = 0 + * 0 * 0 = 0 + * 0 * N = N + * 0 * I = N + * N * n = N + * N * 0 = N + * N * N = N + * N * I = N + * I * n = I + * I * 0 = N + * I * N = N + * I * I = I + * + * Return a new BigNumber whose value is the value of this BigNumber multiplied by the value + * of BigNumber(y, b). + */ + P.multipliedBy = P.times = function (y, b) { + var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc, + base, sqrtBase, + x = this, + xc = x.c, + yc = (y = new BigNumber(y, b)).c; + + // Either NaN, ±Infinity or ±0? + if (!xc || !yc || !xc[0] || !yc[0]) { + + // Return NaN if either is NaN, or one is 0 and the other is Infinity. + if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) { + y.c = y.e = y.s = null; + } else { + y.s *= x.s; + + // Return ±Infinity if either is ±Infinity. + if (!xc || !yc) { + y.c = y.e = null; + + // Return ±0 if either is ±0. + } else { + y.c = [0]; + y.e = 0; + } + } + + return y; + } + + e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE); + y.s *= x.s; + xcL = xc.length; + ycL = yc.length; + + // Ensure xc points to longer array and xcL to its length. + if (xcL < ycL) { + zc = xc; + xc = yc; + yc = zc; + i = xcL; + xcL = ycL; + ycL = i; + } + + // Initialise the result array with zeros. + for (i = xcL + ycL, zc = []; i--; zc.push(0)); + + base = BASE; + sqrtBase = SQRT_BASE; + + for (i = ycL; --i >= 0;) { + c = 0; + ylo = yc[i] % sqrtBase; + yhi = yc[i] / sqrtBase | 0; + + for (k = xcL, j = i + k; j > i;) { + xlo = xc[--k] % sqrtBase; + xhi = xc[k] / sqrtBase | 0; + m = yhi * xlo + xhi * ylo; + xlo = ylo * xlo + ((m % sqrtBase) * sqrtBase) + zc[j] + c; + c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi; + zc[j--] = xlo % base; + } + + zc[j] = c; + } + + if (c) { + ++e; + } else { + zc.splice(0, 1); + } + + return normalise(y, zc, e); + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber negated, + * i.e. multiplied by -1. + */ + P.negated = function () { + var x = new BigNumber(this); + x.s = -x.s || null; + return x; + }; + + + /* + * n + 0 = n + * n + N = N + * n + I = I + * 0 + n = n + * 0 + 0 = 0 + * 0 + N = N + * 0 + I = I + * N + n = N + * N + 0 = N + * N + N = N + * N + I = N + * I + n = I + * I + 0 = I + * I + N = N + * I + I = I + * + * Return a new BigNumber whose value is the value of this BigNumber plus the value of + * BigNumber(y, b). + */ + P.plus = function (y, b) { + var t, + x = this, + a = x.s; + + y = new BigNumber(y, b); + b = y.s; + + // Either NaN? + if (!a || !b) return new BigNumber(NaN); + + // Signs differ? + if (a != b) { + y.s = -b; + return x.minus(y); + } + + var xe = x.e / LOG_BASE, + ye = y.e / LOG_BASE, + xc = x.c, + yc = y.c; + + if (!xe || !ye) { + + // Return ±Infinity if either ±Infinity. + if (!xc || !yc) return new BigNumber(a / 0); + + // Either zero? + // Return y if y is non-zero, x if x is non-zero, or zero if both are zero. + if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0); + } + + xe = bitFloor(xe); + ye = bitFloor(ye); + xc = xc.slice(); + + // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts. + if (a = xe - ye) { + if (a > 0) { + ye = xe; + t = yc; + } else { + a = -a; + t = xc; + } + + t.reverse(); + for (; a--; t.push(0)); + t.reverse(); + } + + a = xc.length; + b = yc.length; + + // Point xc to the longer array, and b to the shorter length. + if (a - b < 0) { + t = yc; + yc = xc; + xc = t; + b = a; + } + + // Only start adding at yc.length - 1 as the further digits of xc can be ignored. + for (a = 0; b;) { + a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0; + xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE; + } + + if (a) { + xc = [a].concat(xc); + ++ye; + } + + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + // ye = MAX_EXP + 1 possible + return normalise(y, xc, ye); + }; + + + /* + * If sd is undefined or null or true or false, return the number of significant digits of + * the value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN. + * If sd is true include integer-part trailing zeros in the count. + * + * Otherwise, if sd is a number, return a new BigNumber whose value is the value of this + * BigNumber rounded to a maximum of sd significant digits using rounding mode rm, or + * ROUNDING_MODE if rm is omitted. + * + * sd {number|boolean} number: significant digits: integer, 1 to MAX inclusive. + * boolean: whether to count integer-part trailing zeros: true or false. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}' + */ + P.precision = P.sd = function (sd, rm) { + var c, n, v, + x = this; + + if (sd != null && sd !== !!sd) { + intCheck(sd, 1, MAX); + if (rm == null) rm = ROUNDING_MODE; + else intCheck(rm, 0, 8); + + return round(new BigNumber(x), sd, rm); + } + + if (!(c = x.c)) return null; + v = c.length - 1; + n = v * LOG_BASE + 1; + + if (v = c[v]) { + + // Subtract the number of trailing zeros of the last element. + for (; v % 10 == 0; v /= 10, n--); + + // Add the number of digits of the first element. + for (v = c[0]; v >= 10; v /= 10, n++); + } + + if (sd && x.e + 1 > n) n = x.e + 1; + + return n; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber shifted by k places + * (powers of 10). Shift to the right if n > 0, and to the left if n < 0. + * + * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {k}' + */ + P.shiftedBy = function (k) { + intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); + return this.times('1e' + k); + }; + + + /* + * sqrt(-n) = N + * sqrt(N) = N + * sqrt(-I) = N + * sqrt(I) = I + * sqrt(0) = 0 + * sqrt(-0) = -0 + * + * Return a new BigNumber whose value is the square root of the value of this BigNumber, + * rounded according to DECIMAL_PLACES and ROUNDING_MODE. + */ + P.squareRoot = P.sqrt = function () { + var m, n, r, rep, t, + x = this, + c = x.c, + s = x.s, + e = x.e, + dp = DECIMAL_PLACES + 4, + half = new BigNumber('0.5'); + + // Negative/NaN/Infinity/zero? + if (s !== 1 || !c || !c[0]) { + return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0); + } + + // Initial estimate. + s = Math.sqrt(+valueOf(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 = coeffToString(c); + if ((n.length + e) % 2 == 0) n += '0'; + s = Math.sqrt(+n); + e = bitFloor((e + 1) / 2) - (e < 0 || e % 2); + + if (s == 1 / 0) { + n = '5e' + e; + } else { + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; + } + + r = new BigNumber(n); + } else { + r = new BigNumber(s + ''); + } + + // Check for zero. + // r could be zero if MIN_EXP is changed after the this value was created. + // This would cause a division by zero (x/t) and hence Infinity below, which would cause + // coeffToString to throw. + if (r.c[0]) { + e = r.e; + s = e + dp; + if (s < 3) s = 0; + + // Newton-Raphson iteration. + for (; ;) { + t = r; + r = half.times(t.plus(div(x, t, dp, 1))); + + if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) { + + // The exponent of r may here be one less than the final result exponent, + // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits + // are indexed correctly. + if (r.e < e) --s; + n = n.slice(s - 3, s + 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) { + round(t, t.e + DECIMAL_PLACES + 2, 0); + + if (t.times(t).eq(x)) { + r = t; + break; + } + } + + dp += 4; + s += 4; + rep = 1; + } else { + + // If rounding digits are null, 0{0,4} or 50{0,3}, check for 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. + round(r, r.e + DECIMAL_PLACES + 2, 1); + m = !r.times(r).eq(x); + } + + break; + } + } + } + } + + return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m); + }; + + + /* + * Return a string representing the value of this BigNumber in exponential notation and + * rounded using ROUNDING_MODE to dp fixed decimal places. + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' + */ + P.toExponential = function (dp, rm) { + if (dp != null) { + intCheck(dp, 0, MAX); + dp++; + } + return format(this, dp, rm, 1); + }; + + + /* + * Return a string representing the value of this BigNumber in fixed-point notation rounding + * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted. + * + * Note: as with JavaScript's number type, (-0).toFixed(0) is '0', + * but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' + */ + P.toFixed = function (dp, rm) { + if (dp != null) { + intCheck(dp, 0, MAX); + dp = dp + this.e + 1; + } + return format(this, dp, rm); + }; + + + /* + * Return a string representing the value of this BigNumber in fixed-point notation rounded + * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties + * of the format or FORMAT object (see BigNumber.set). + * + * The formatting object may contain some or all of the properties shown below. + * + * FORMAT = { + * prefix: '', + * groupSize: 3, + * secondaryGroupSize: 0, + * groupSeparator: ',', + * decimalSeparator: '.', + * fractionGroupSize: 0, + * fractionGroupSeparator: '\xA0', // non-breaking space + * suffix: '' + * }; + * + * [dp] {number} Decimal places. Integer, 0 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * [format] {object} Formatting options. See FORMAT pbject above. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}' + * '[BigNumber Error] Argument not an object: {format}' + */ + P.toFormat = function (dp, rm, format) { + var str, + x = this; + + if (format == null) { + if (dp != null && rm && typeof rm == 'object') { + format = rm; + rm = null; + } else if (dp && typeof dp == 'object') { + format = dp; + dp = rm = null; + } else { + format = FORMAT; + } + } else if (typeof format != 'object') { + throw Error + (bignumberError + 'Argument not an object: ' + format); + } + + str = x.toFixed(dp, rm); + + if (x.c) { + var i, + arr = str.split('.'), + g1 = +format.groupSize, + g2 = +format.secondaryGroupSize, + groupSeparator = format.groupSeparator || '', + intPart = arr[0], + fractionPart = arr[1], + isNeg = x.s < 0, + intDigits = isNeg ? intPart.slice(1) : intPart, + len = intDigits.length; + + if (g2) { + i = g1; + g1 = g2; + g2 = i; + len -= i; + } + + if (g1 > 0 && len > 0) { + i = len % g1 || g1; + intPart = intDigits.substr(0, i); + for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1); + if (g2 > 0) intPart += groupSeparator + intDigits.slice(i); + if (isNeg) intPart = '-' + intPart; + } + + str = fractionPart + ? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize) + ? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'), + '$&' + (format.fractionGroupSeparator || '')) + : fractionPart) + : intPart; + } + + return (format.prefix || '') + str + (format.suffix || ''); + }; + + + /* + * Return an array of two BigNumbers representing the value of this BigNumber as a simple + * fraction with an integer numerator and an integer denominator. + * The denominator will be a positive non-zero value less than or equal to the specified + * maximum denominator. If a maximum denominator is not specified, the denominator will be + * the lowest value necessary to represent the number exactly. + * + * [md] {number|string|BigNumber} Integer >= 1, or Infinity. The maximum denominator. + * + * '[BigNumber Error] Argument {not an integer|out of range} : {md}' + */ + P.toFraction = function (md) { + var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s, + x = this, + xc = x.c; + + if (md != null) { + n = new BigNumber(md); + + // Throw if md is less than one or is not an integer, unless it is Infinity. + if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) { + throw Error + (bignumberError + 'Argument ' + + (n.isInteger() ? 'out of range: ' : 'not an integer: ') + valueOf(n)); + } + } + + if (!xc) return new BigNumber(x); + + d = new BigNumber(ONE); + n1 = d0 = new BigNumber(ONE); + d1 = n0 = new BigNumber(ONE); + s = coeffToString(xc); + + // Determine initial denominator. + // d is a power of 10 and the minimum max denominator that specifies the value exactly. + e = d.e = s.length - x.e - 1; + d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp]; + md = !md || n.comparedTo(d) > 0 ? (e > 0 ? d : n1) : n; + + exp = MAX_EXP; + MAX_EXP = 1 / 0; + n = new BigNumber(s); + + // n0 = d1 = 0 + n0.c[0] = 0; + + for (; ;) { + q = div(n, d, 0, 1); + d2 = d0.plus(q.times(d1)); + if (d2.comparedTo(md) == 1) break; + d0 = d1; + d1 = d2; + n1 = n0.plus(q.times(d2 = n1)); + n0 = d2; + d = n.minus(q.times(d2 = d)); + n = d2; + } + + d2 = div(md.minus(d0), d1, 0, 1); + n0 = n0.plus(d2.times(n1)); + d0 = d0.plus(d2.times(d1)); + n0.s = n1.s = x.s; + e = e * 2; + + // Determine which fraction is closer to x, n0/d0 or n1/d1 + r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo( + div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [n1, d1] : [n0, d0]; + + MAX_EXP = exp; + + return r; + }; + + + /* + * Return the value of this BigNumber converted to a number primitive. + */ + P.toNumber = function () { + return +valueOf(this); + }; + + + /* + * Return a string representing the value of this BigNumber rounded to sd significant digits + * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits + * necessary to represent the integer part of the value in fixed-point notation, then use + * exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}' + */ + P.toPrecision = function (sd, rm) { + if (sd != null) intCheck(sd, 1, MAX); + return format(this, sd, rm, 2); + }; + + + /* + * Return a string representing the value of this BigNumber in base b, or base 10 if b is + * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and + * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent + * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than + * TO_EXP_NEG, return exponential notation. + * + * [b] {number} Integer, 2 to ALPHABET.length inclusive. + * + * '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}' + */ + P.toString = function (b) { + var str, + n = this, + s = n.s, + e = n.e; + + // Infinity or NaN? + if (e === null) { + if (s) { + str = 'Infinity'; + if (s < 0) str = '-' + str; + } else { + str = 'NaN'; + } + } else { + if (b == null) { + str = e <= TO_EXP_NEG || e >= TO_EXP_POS + ? toExponential(coeffToString(n.c), e) + : toFixedPoint(coeffToString(n.c), e, '0'); + } else if (b === 10 && alphabetHasNormalDecimalDigits) { + n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE); + str = toFixedPoint(coeffToString(n.c), n.e, '0'); + } else { + intCheck(b, 2, ALPHABET.length, 'Base'); + str = convertBase(toFixedPoint(coeffToString(n.c), e, '0'), 10, b, s, true); + } + + if (s < 0 && n.c[0]) str = '-' + str; + } + + return str; + }; + + + /* + * Return as toString, but do not accept a base argument, and include the minus sign for + * negative zero. + */ + P.valueOf = P.toJSON = function () { + return valueOf(this); + }; + + + P._isBigNumber = true; + + if (configObject != null) BigNumber.set(configObject); + + return BigNumber; + } + + + // PRIVATE HELPER FUNCTIONS + + // These functions don't need access to variables, + // e.g. DECIMAL_PLACES, in the scope of the `clone` function above. + + + function bitFloor(n) { + var i = n | 0; + return n > 0 || n === i ? i : i - 1; + } + + + // Return a coefficient array as a string of base 10 digits. + function coeffToString(a) { + var s, z, + i = 1, + j = a.length, + r = a[0] + ''; + + for (; i < j;) { + s = a[i++] + ''; + z = LOG_BASE - s.length; + for (; z--; s = '0' + s); + r += s; + } + + // Determine trailing zeros. + for (j = r.length; r.charCodeAt(--j) === 48;); + + return r.slice(0, j + 1 || 1); + } + + + // Compare the value of BigNumbers x and y. + function compare(x, y) { + var a, b, + xc = x.c, + yc = y.c, + i = x.s, + j = y.s, + k = x.e, + l = y.e; + + // Either NaN? + if (!i || !j) return null; + + a = xc && !xc[0]; + b = yc && !yc[0]; + + // Either zero? + if (a || b) return a ? b ? 0 : -j : i; + + // Signs differ? + if (i != j) return i; + + a = i < 0; + b = k == l; + + // Either Infinity? + if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1; + + // Compare exponents. + if (!b) return k > l ^ a ? 1 : -1; + + j = (k = xc.length) < (l = yc.length) ? k : l; + + // Compare digit by digit. + for (i = 0; i < j; i++) if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1; + + // Compare lengths. + return k == l ? 0 : k > l ^ a ? 1 : -1; + } + + + /* + * Check that n is a primitive number, an integer, and in range, otherwise throw. + */ + function intCheck(n, min, max, name) { + if (n < min || n > max || n !== mathfloor(n)) { + throw Error + (bignumberError + (name || 'Argument') + (typeof n == 'number' + ? n < min || n > max ? ' out of range: ' : ' not an integer: ' + : ' not a primitive number: ') + String(n)); + } + } + + + // Assumes finite n. + function isOdd(n) { + var k = n.c.length - 1; + return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0; + } + + + function toExponential(str, e) { + return (str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str) + + (e < 0 ? 'e' : 'e+') + e; + } + + + function toFixedPoint(str, e, z) { + var len, zs; + + // Negative exponent? + if (e < 0) { + + // Prepend zeros. + for (zs = z + '.'; ++e; zs += z); + str = zs + str; + + // Positive exponent + } else { + len = str.length; + + // Append zeros. + if (++e > len) { + for (zs = z, e -= len; --e; zs += z); + str += zs; + } else if (e < len) { + str = str.slice(0, e) + '.' + str.slice(e); + } + } + + return str; + } + + + // EXPORT + + + BigNumber = clone(); + BigNumber['default'] = BigNumber.BigNumber = BigNumber; + + // AMD. + if (module.exports) { + module.exports = BigNumber; + + // Browser. + } else { + if (!globalObject) { + globalObject = typeof self != 'undefined' && self ? self : window; + } + + globalObject.BigNumber = BigNumber; + } })(bignumber); } (bignumber$1)); return bignumber$1.exports; @@ -154897,7 +155103,7 @@ function requireSrc$7 () { return src$6; } -var commonjs$f = {}; +var commonjs$g = {}; var namedReferences = {}; @@ -155030,12 +155236,12 @@ function requireSurrogatePairs () { return surrogatePairs; } -var hasRequiredCommonjs$f; +var hasRequiredCommonjs$g; -function requireCommonjs$f () { - if (hasRequiredCommonjs$f) return commonjs$f; - hasRequiredCommonjs$f = 1; - var __assign = (commonjs$f && commonjs$f.__assign) || function () { +function requireCommonjs$g () { + if (hasRequiredCommonjs$g) return commonjs$g; + hasRequiredCommonjs$g = 1; + var __assign = (commonjs$g && commonjs$g.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; @@ -155046,10 +155252,10 @@ function requireCommonjs$f () { }; return __assign.apply(this, arguments); }; - Object.defineProperty(commonjs$f, "__esModule", { value: true }); - commonjs$f.encode = encode; - commonjs$f.decodeEntity = decodeEntity; - commonjs$f.decode = decode; + Object.defineProperty(commonjs$g, "__esModule", { value: true }); + commonjs$g.encode = encode; + commonjs$g.decodeEntity = decodeEntity; + commonjs$g.decode = decode; var named_references_js_1 = requireNamedReferences(); var numeric_unicode_map_js_1 = requireNumericUnicodeMap(); var surrogate_pairs_js_1 = requireSurrogatePairs(); @@ -155163,7 +155369,7 @@ function requireCommonjs$f () { return text.replace(decodeRegExp, function (entity) { return getDecodedEntity(entity, references, isAttribute, isStrict); }); } - return commonjs$f; + return commonjs$g; } var retryRequest = {exports: {}}; @@ -157433,11 +157639,11 @@ var packageJsonHelper = {}; var name = "@google-cloud/storage"; var description = "Cloud Storage Client Library for Node.js"; -var version = "7.21.0"; +var version = "7.22.0"; var license = "Apache-2.0"; var author = "Google Inc."; var engines = { - node: ">=14" + node: ">=18" }; var repository = { type: "git", @@ -157501,9 +157707,9 @@ var scripts = { "presystem-test": "npm run compile -- --sourceMap", pretest: "npm run compile -- --sourceMap", "samples-test": "npm link && cd samples/ && npm link ../ && npm test && cd ../", - "system-test:esm": "mocha build/esm/system-test --timeout 600000 --exit", - "system-test": "mocha build/cjs/system-test --timeout 600000 --exit", - test: "cross-env NODE_OPTIONS='--no-deprecation' c8 mocha build/cjs/test" + "system-test:esm": "mkdir -p $HOME/.config && mocha build/esm/system-test --timeout 600000 --exit", + "system-test": "mkdir -p $HOME/.config && mocha build/cjs/system-test --timeout 600000 --exit", + test: "cross-env NODE_OPTIONS=\"--require ./scripts/preload-yargs.cjs --no-deprecation\" c8 mocha build/cjs/test" }; var dependencies = { "@google-cloud/paginator": "^5.0.0", @@ -157538,7 +157744,7 @@ var devDependencies = { "@types/request": "^2.48.4", "@types/sinon": "^17.0.0", "@types/tmp": "0.2.6", - "@types/yargs": "^17.0.10", + "@types/yargs": "^17.0.35", c8: "^9.0.0", "form-data": "^4.0.4", "gapic-tools": "^0.4.0", @@ -157557,7 +157763,7 @@ var devDependencies = { "path-to-regexp": "6.3.0", tmp: "^0.2.0", typescript: "^5.1.6", - yargs: "^17.3.1", + yargs: "^17.7.2", "cross-env": "^7.0.3" }; var homepage = "https://github.com/googleapis/google-cloud-node/tree/main/handwritten/storage"; @@ -160981,11 +161187,11 @@ function require_stream_passthrough () { } var pipeline_1; -var hasRequiredPipeline$4; +var hasRequiredPipeline$5; -function requirePipeline$4 () { - if (hasRequiredPipeline$4) return pipeline_1; - hasRequiredPipeline$4 = 1; +function requirePipeline$5 () { + if (hasRequiredPipeline$5) return pipeline_1; + hasRequiredPipeline$5 = 1; var eos; function once(callback) { @@ -161091,7 +161297,7 @@ function requireReadable () { exports.Transform = require_stream_transform(); exports.PassThrough = require_stream_passthrough(); exports.finished = requireEndOfStream$1(); - exports.pipeline = requirePipeline$4(); + exports.pipeline = requirePipeline$5(); } } (readable, readable.exports)); return readable.exports; @@ -161542,7 +161748,7 @@ function requireUtil$1 () { * @module common/util */ const projectify_1 = requireSrc$7(); - const htmlEntities = __importStar(/*@__PURE__*/ requireCommonjs$f()); + const htmlEntities = __importStar(/*@__PURE__*/ requireCommonjs$g()); const google_auth_library_1 = requireSrc$8(); const retry_request_1 = __importDefault(requireRetryRequest()); const stream_1 = require$$0__default$2; @@ -162125,6 +162331,20 @@ function requireUtil$1 () { delete reqOpts.json.autoPaginate; delete reqOpts.json.autoPaginateVal; reqOpts.json = (0, projectify_1.replaceProjectIdToken)(reqOpts.json, projectId); + const headers = reqOpts.headers || {}; + if (typeof headers.set === 'function' && + typeof headers.has === 'function') { + if (!headers.has('content-type')) { + headers.set('Content-Type', 'application/json'); + } + reqOpts.headers = headers; + } + else { + const hasContentType = Object.keys(headers).some(key => key.toLowerCase() === 'content-type'); + reqOpts.headers = hasContentType + ? headers + : { ...headers, 'Content-Type': 'application/json' }; + } } reqOpts.uri = (0, projectify_1.replaceProjectIdToken)(reqOpts.uri, projectId); return reqOpts; @@ -164636,7 +164856,7 @@ function requireAcl () { return acl; } -var file$1 = {}; +var file$2 = {}; var resumableUpload = {}; @@ -165929,7 +166149,7 @@ function requireHashStreamValidator () { const crypto_1 = crypto__default; const stream_1 = require$$0__default$2; const crc32c_js_1 = requireCrc32c(); - const file_js_1 = requireFile$1(); + const file_js_1 = requireFile$2(); class HashStreamValidator extends stream_1.Transform { constructor(options = {}) { super(); @@ -166109,7 +166329,7 @@ function requireResumableUpload () { const crypto = __importStar(crypto__default); const util_js_1 = requireUtil$2(); const util_js_2 = requireUtil$1(); - const file_js_1 = requireFile$1(); + const file_js_1 = requireFile$2(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const package_json_helper_cjs_1 = requirePackageJsonHelper(); @@ -166912,7 +167132,7 @@ function requireResumableUpload () { else { const retryDelay = this.getRetryDelay(); if (retryDelay <= 0) { - this.destroy(new Error(`Retry total time limit exceeded - ${JSON.stringify(resp.data)}`)); + this.destroy(buildRetryError('Retry total time limit exceeded', resp)); return; } // Unshift the local cache back in case it's needed for the next request. @@ -166930,7 +167150,7 @@ function requireResumableUpload () { this.numRetries++; } else { - this.destroy(new Error(`Retry limit exceeded - ${JSON.stringify(resp.data)}`)); + this.destroy(buildRetryError('Retry limit exceeded', resp)); } } /** @@ -167008,6 +167228,62 @@ function requireResumableUpload () { headers['X-Goog-Hash'] = checksums.join(','); } }; + function buildRetryError(prefix, resp) { + var _a, _b, _c, _d; + const parts = []; + if (typeof resp.status === 'number' && !isNaN(resp.status)) { + parts.push(`status: ${resp.status}`); + } + const err = resp.data; + if (err !== undefined && err !== null) { + if (typeof err === 'object') { + const gaxiosErrLike = err; + const errParts = []; + if (gaxiosErrLike.message) { + errParts.push(String(gaxiosErrLike.message)); + } + const status = (_a = gaxiosErrLike.status) !== null && _a !== void 0 ? _a : (_b = gaxiosErrLike.response) === null || _b === void 0 ? void 0 : _b.status; + if (typeof status === 'number' && !isNaN(status) && status !== resp.status) { + errParts.push(`status: ${status}`); + } + const statusText = (_c = gaxiosErrLike.response) === null || _c === void 0 ? void 0 : _c.statusText; + if (statusText) { + errParts.push(`statusText: ${statusText}`); + } + const responseData = (_d = gaxiosErrLike.response) === null || _d === void 0 ? void 0 : _d.data; + if (responseData !== undefined && responseData !== null && responseData !== '') { + errParts.push(`response: ${typeof responseData === 'object' + ? JSON.stringify(responseData) + : responseData}`); + } + if (gaxiosErrLike.code) { + errParts.push(`code: ${String(gaxiosErrLike.code)}`); + } + if (errParts.length > 0) { + parts.push(...errParts); + } + else if (err instanceof Error) { + parts.push(err.toString() || err.name || 'Unknown Error'); + } + else { + const stringified = JSON.stringify(err); + if (stringified && stringified !== '{}') { + parts.push(stringified); + } + } + } + else if (typeof err === 'string') { + if (err !== '') { + parts.push(err); + } + } + else { + parts.push(String(err)); + } + } + const suffix = parts.join(' - '); + return new Error(`${prefix} - ${suffix || 'Unknown Error'}`); + } function upload(cfg) { return new Upload(cfg); } @@ -167378,11 +167654,11 @@ function requireSigner () { return signer; } -var hasRequiredFile$1; +var hasRequiredFile$2; -function requireFile$1 () { - if (hasRequiredFile$1) return file$1; - hasRequiredFile$1 = 1; +function requireFile$2 () { + if (hasRequiredFile$2) return file$2; + hasRequiredFile$2 = 1; // Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -167396,7 +167672,7 @@ function requireFile$1 () { // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - var __createBinding = (file$1 && file$1.__createBinding) || (Object.create ? (function(o, m, k, k2) { + var __createBinding = (file$2 && file$2.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { @@ -167407,12 +167683,12 @@ function requireFile$1 () { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); - var __setModuleDefault = (file$1 && file$1.__setModuleDefault) || (Object.create ? (function(o, v) { + var __setModuleDefault = (file$2 && file$2.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); - var __importStar = (file$1 && file$1.__importStar) || (function () { + var __importStar = (file$2 && file$2.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; @@ -167429,17 +167705,17 @@ function requireFile$1 () { return result; }; })(); - var __classPrivateFieldGet = (file$1 && file$1.__classPrivateFieldGet) || function (receiver, state, kind, f) { + var __classPrivateFieldGet = (file$2 && file$2.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; - var __importDefault = (file$1 && file$1.__importDefault) || function (mod) { + var __importDefault = (file$2 && file$2.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _File_instances, _File_validateIntegrity; - Object.defineProperty(file$1, "__esModule", { value: true }); - file$1.File = file$1.FileExceptionMessages = file$1.RequestError = file$1.SkipReason = file$1.STORAGE_POST_POLICY_BASE_URL = file$1.ActionToHTTPMethod = void 0; + Object.defineProperty(file$2, "__esModule", { value: true }); + file$2.File = file$2.FileExceptionMessages = file$2.RequestError = file$2.SkipReason = file$2.STORAGE_POST_POLICY_BASE_URL = file$2.ActionToHTTPMethod = void 0; const index_js_1 = requireNodejsCommon(); const promisify_1 = requireSrc$4(); const crypto = __importStar(crypto__default); @@ -167464,11 +167740,11 @@ function requireFile$1 () { ActionToHTTPMethod["write"] = "PUT"; ActionToHTTPMethod["delete"] = "DELETE"; ActionToHTTPMethod["resumable"] = "POST"; - })(ActionToHTTPMethod || (file$1.ActionToHTTPMethod = ActionToHTTPMethod = {})); + })(ActionToHTTPMethod || (file$2.ActionToHTTPMethod = ActionToHTTPMethod = {})); /** * @deprecated - no longer used */ - file$1.STORAGE_POST_POLICY_BASE_URL = 'https://storage.googleapis.com'; + file$2.STORAGE_POST_POLICY_BASE_URL = 'https://storage.googleapis.com'; /** * @private */ @@ -167496,10 +167772,10 @@ function requireFile$1 () { SkipReason["ILLEGAL_CHARACTER"] = "ILLEGAL_CHARACTER"; SkipReason["ALREADY_EXISTS"] = "ALREADY_EXISTS"; SkipReason["DOWNLOAD_ERROR"] = "DOWNLOAD_ERROR"; - })(SkipReason || (file$1.SkipReason = SkipReason = {})); + })(SkipReason || (file$2.SkipReason = SkipReason = {})); class RequestError extends Error { } - file$1.RequestError = RequestError; + file$2.RequestError = RequestError; const SEVEN_DAYS = 7 * 24 * 60 * 60; const GS_UTIL_URL_REGEX = /(gs):\/\/([a-z0-9_.-]+)\/(.+)/g; const HTTPS_PUBLIC_URL_REGEX = /(https):\/\/(storage\.googleapis\.com)\/([a-z0-9_.-]+)\/(.+)/g; @@ -167517,7 +167793,7 @@ function requireFile$1 () { FileExceptionMessages["UPLOAD_MISMATCH"] = "The uploaded data did not match the data from the server.\n As a precaution, the file has been deleted.\n To be sure the content is the same, you should try uploading the file again."; FileExceptionMessages["MD5_RESUMED_UPLOAD"] = "MD5 cannot be used with a continued resumable upload as MD5 cannot be extended from an existing value"; FileExceptionMessages["MISSING_RESUME_CRC32C_FINAL_UPLOAD"] = "The CRC32C is missing for the final portion of a resumed upload, which is required for validation. Please provide `resumeCRC32C` if validation is required, or disable `validation`."; - })(FileExceptionMessages || (file$1.FileExceptionMessages = FileExceptionMessages = {})); + })(FileExceptionMessages || (file$2.FileExceptionMessages = FileExceptionMessages = {})); /** * A File object is created from your {@link Bucket} object using * {@link Bucket#file}. @@ -168941,6 +169217,27 @@ function requireFile$1 () { } // remove temporary noop listener as we now create a pipeline that handles the errors emitStream.removeListener('error', noop); + if (fileWriteStream.destroyed) { + let callbackCalled = false; + const onError = (err) => { + if (!callbackCalled) { + callbackCalled = true; + pipelineCallback(err); + } + }; + fileWriteStream.once('error', onError); + emitStream.destroy(); + process.nextTick(() => { + fileWriteStream.removeListener('error', onError); + if (!callbackCalled) { + callbackCalled = true; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const err = fileWriteStream.errored || new Error('Write stream destroyed'); + pipelineCallback(err); + } + }); + return; + } (0, stream_1.pipeline)(emitStream, ...transformStreams, fileWriteStream, async (e) => { if (e) { return pipelineCallback(e); @@ -169808,6 +170105,7 @@ function requireFile$1 () { contentMd5: cfg.contentMd5, contentType: cfg.contentType, host: cfg.host, + signingEndpoint: cfg.signingEndpoint, }; if (cfg.cname) { signConfig.cname = cfg.cname; @@ -170942,7 +171240,7 @@ function requireFile$1 () { return Buffer.concat(buf); } } - file$1.File = File; + file$2.File = File; _File_instances = new WeakSet(), _File_validateIntegrity = /** * @@ -171005,7 +171303,7 @@ function requireFile$1 () { 'restore', ], }); - return file$1; + return file$2; } var iam = {}; @@ -171652,7 +171950,7 @@ function requireBucket () { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(bucket, "__esModule", { value: true }); - bucket.Bucket = bucket.BucketExceptionMessages = bucket.AvailableServiceObjectMethods = bucket.BucketActionToHTTPMethod = void 0; + bucket.Bucket = bucket.BucketExceptionMessages = bucket.AvailableServiceObjectMethods = bucket.BucketActionToHTTPMethod = bucket.ComposeCleanupError = void 0; const index_js_1 = requireNodejsCommon(); const paginator_1 = requireSrc$3(); const promisify_1 = requireSrc$4(); @@ -171664,13 +171962,23 @@ function requireBucket () { const async_retry_1 = __importDefault(requireLib()); const util_js_1 = requireUtil$2(); const acl_js_1 = requireAcl(); - const file_js_1 = requireFile$1(); + const file_js_1 = requireFile$2(); const iam_js_1 = requireIam(); const notification_js_1 = requireNotification(); const storage_js_1 = requireStorage(); const signer_js_1 = requireSigner(); const stream_1 = require$$0__default$2; const url_1 = require$$2$3; + class ComposeCleanupError extends Error { + constructor(message, errors, newFile, apiResponse) { + super(message); + this.name = 'ComposeCleanupError'; + this.errors = errors; + this.newFile = newFile; + this.apiResponse = apiResponse; + } + } + bucket.ComposeCleanupError = ComposeCleanupError; var BucketActionToHTTPMethod; (function (BucketActionToHTTPMethod) { BucketActionToHTTPMethod["list"] = "GET"; @@ -172633,7 +172941,9 @@ function requireBucket () { * metadata's `kms_key_name` value, if any. * @property {string} [userProject] The ID of the project which will be * billed for the request. - */ + * @property {boolean} [deleteSourceObjects] If true, the source objects + * will be permanently deleted after a successful compose operation. + */ /** * @callback CombineCallback * @param {?Error} err Request error, if any. @@ -172666,7 +172976,8 @@ function requireBucket () { * metadata's `kms_key_name` value, if any. * @param {string} [options.userProject] The ID of the project which will be * billed for the request. - + * @param {boolean} [options.deleteSourceObjects] If true, the source objects + * will be permanently deleted after a successful compose operation. * @param {CombineCallback} [callback] Callback function. * @returns {Promise} * @@ -172743,8 +173054,11 @@ function requireBucket () { storage_js_1.IdempotencyStrategy.RetryNever) { maxRetries = 0; } - if (options.ifGenerationMatch === undefined) { - Object.assign(options, destinationFile.instancePreconditionOpts, options); + const deleteSourceObjects = options.deleteSourceObjects; + const requestQueryObject = Object.assign({}, options); + delete requestQueryObject.deleteSourceObjects; + if (requestQueryObject.ifGenerationMatch === undefined) { + Object.assign(requestQueryObject, destinationFile.instancePreconditionOpts, requestQueryObject); } // Make the request from the destination File object. destinationFile.request({ @@ -172755,26 +173069,55 @@ function requireBucket () { destination: { contentType: destinationFile.metadata.contentType, contentEncoding: destinationFile.metadata.contentEncoding, - contexts: options.contexts || destinationFile.metadata.contexts, + contexts: requestQueryObject.contexts || destinationFile.metadata.contexts, }, sourceObjects: sources.map(source => { + var _a, _b; const sourceObject = { name: source.name, }; - if (source.metadata && source.metadata.generation) { - sourceObject.generation = parseInt(source.metadata.generation.toString()); + const generation = (_a = source.generation) !== null && _a !== void 0 ? _a : (_b = source.metadata) === null || _b === void 0 ? void 0 : _b.generation; + if (generation !== undefined) { + sourceObject.generation = parseInt(generation.toString()); } return sourceObject; }), }, - qs: options, + qs: requestQueryObject, }, (err, resp) => { this.storage.retryOptions.autoRetry = this.instanceRetryValue; if (err) { callback(err, null, resp); return; } - callback(null, destinationFile, resp); + if (deleteSourceObjects) { + const deletePromises = sources.map(source => { + var _a, _b; + const deleteOptions = { + ignoreNotFound: true, + userProject: options.userProject, + }; + const generation = (_a = source.generation) !== null && _a !== void 0 ? _a : (_b = source.metadata) === null || _b === void 0 ? void 0 : _b.generation; + if (generation !== undefined) { + deleteOptions.ifGenerationMatch = generation; + } + return source + .delete(deleteOptions) + .catch(deleteErr => deleteErr); + }); + Promise.all(deletePromises).then(results => { + const errors = results.filter((res) => res instanceof Error); + if (errors.length > 0) { + const cleanupErr = new ComposeCleanupError(`Compose operation succeeded, but cleaning up source objects failed. Failed to delete ${errors.length} source object(s).`, errors, destinationFile, resp); + callback(cleanupErr, destinationFile, resp); + return; + } + callback(null, destinationFile, resp); + }); + } + else { + callback(null, destinationFile, resp); + } }); } /** @@ -175036,10 +175379,16 @@ function requireBucket () { if (options.onUploadProgress) { writable.on('progress', options.onUploadProgress); } - fs.createReadStream(pathString) - .on('error', bail) + const readStream = fs.createReadStream(pathString); + readStream + .on('error', err => { + readStream.destroy(); + writable.destroy(); + bail(err); + }) .pipe(writable) .on('error', err => { + readStream.destroy(); if (this.storage.retryOptions.autoRetry && this.storage.retryOptions.retryableErrorFn(err)) { return reject(err); @@ -175715,7 +176064,7 @@ function requireStorage () { const stream_1 = require$$0__default$2; const bucket_js_1 = requireBucket(); const channel_js_1 = requireChannel(); - const file_js_1 = requireFile$1(); + const file_js_1 = requireFile$2(); const util_js_1 = requireUtil$2(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -176881,7 +177230,7 @@ var hasRequiredFxp; function requireFxp () { if (hasRequiredFxp) return fxp.exports; hasRequiredFxp = 1; - (()=>{var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:true,get:i[n]});},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:true});}},e={};t.r(e),t.d(e,{XMLBuilder:()=>Oe,XMLParser:()=>re,XMLValidator:()=>je});const i=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",n=new RegExp("^["+i+"]["+i+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function r(t,e){const i=[];let n=e.exec(t);for(;n;){const r=[];r.startIndex=e.lastIndex-n[0].length;const s=n.length;for(let t=0;t"!==t[s]&&" "!==t[s]&&"\t"!==t[s]&&"\n"!==t[s]&&"\r"!==t[s];s++)l+=t[s];if(l=l.trim(),"/"===l[l.length-1]&&(l=l.substring(0,l.length-1),s--),!E(l)){let e;return e=0===l.trim().length?"Invalid space after '<'.":"Tag '"+l+"' is an invalid name.",y("InvalidTag",e,w(t,s))}const p=g(t,s);if(false===p)return y("InvalidAttr","Attributes for '"+l+"' have open quote.",w(t,s));let u=p.value;if(s=p.index,"/"===u[u.length-1]){const i=s-u.length;u=u.substring(0,u.length-1);const r=x(u,e);if(true!==r)return y(r.err.code,r.err.msg,w(t,i+r.err.line));n=true;}else if(a){if(!p.tagClosed)return y("InvalidTag","Closing tag '"+l+"' doesn't have proper closing.",w(t,s));if(u.trim().length>0)return y("InvalidTag","Closing tag '"+l+"' can't have attributes or invalid starting.",w(t,o));if(0===i.length)return y("InvalidTag","Closing tag '"+l+"' has not been opened.",w(t,o));{const e=i.pop();if(l!==e.tagName){let i=w(t,e.tagStartPos);return y("InvalidTag","Expected closing tag '"+e.tagName+"' (opened in line "+i.line+", col "+i.col+") instead of closing tag '"+l+"'.",w(t,o))}0==i.length&&(r=true);}}else {const a=x(u,e);if(true!==a)return y(a.err.code,a.err.msg,w(t,s-u.length+a.err.line));if(true===r)return y("InvalidXml","Multiple possible root nodes found.",w(t,s));-1!==e.unpairedTags.indexOf(l)||i.push({tagName:l,tagStartPos:o}),n=true;}for(s++;s0)||y("InvalidXml","Invalid '"+JSON.stringify(i.map(t=>t.tagName),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):y("InvalidXml","Start tag expected.",1)}function c(t){return " "===t||"\t"===t||"\n"===t||"\r"===t}function h(t,e){const i=e;for(;e5&&"xml"===n)return y("InvalidXml","XML declaration allowed only at the start of the document.",w(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}continue}return e}function d(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){let i=1;for(e+=8;e"===t[e]&&(i--,0===i))break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}const u='"',f="'";function g(t,e){let i="",n="",r=false;for(;e"===t[e]&&""===n){r=true;break}i+=t[e];}return ""===n&&{value:i,index:e,tagClosed:r}}const m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function x(t,e){const i=r(t,m),n={};for(let t=0;to.includes(t)?"__"+t:t,A={preserveOrder:false,attributeNamePrefix:"@_",attributesGroupName:false,textNodeName:"#text",ignoreAttributes:true,removeNSPrefix:false,allowBooleanAttributes:false,parseTagValue:true,parseAttributeValue:false,trimValues:true,cdataPropName:false,numberParseOptions:{hex:true,leadingZeros:true,eNotation:true,unicode:false},tagValueProcessor:function(t,e){return e},attributeValueProcessor:function(t,e){return e},stopNodes:[],alwaysCreateTextNode:false,isArray:()=>false,commentPropName:false,unpairedTags:[],processEntities:true,htmlEntities:false,entityDecoder:null,ignoreDeclaration:false,ignorePiTags:false,transformTagName:false,transformAttributeName:false,updateTag:function(t,e,i){return t},captureMetaData:false,maxNestedTags:100,strictReservedNames:true,jPath:true,onDangerousProperty:S};function T(t,e){if("string"!=typeof t)return;const i=t.toLowerCase();if(o.some(t=>i===t.toLowerCase()))throw new Error(`[SECURITY] Invalid ${e}: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`);if(a.some(t=>i===t.toLowerCase()))throw new Error(`[SECURITY] Invalid ${e}: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`)}function _(t,e){return "boolean"==typeof t?{enabled:t,maxEntitySize:1e4,maxExpansionDepth:1e4,maxTotalExpansions:1/0,maxExpandedLength:1e5,maxEntityCount:1e3,allowedTags:null,tagFilter:null,appliesTo:"all"}:"object"==typeof t&&null!==t?{enabled:false!==t.enabled,maxEntitySize:Math.max(1,t.maxEntitySize??1e4),maxExpansionDepth:Math.max(1,t.maxExpansionDepth??1e4),maxTotalExpansions:Math.max(1,t.maxTotalExpansions??1/0),maxExpandedLength:Math.max(1,t.maxExpandedLength??1e5),maxEntityCount:Math.max(1,t.maxEntityCount??1e3),allowedTags:t.allowedTags??null,tagFilter:t.tagFilter??null,appliesTo:t.appliesTo??"all"}:_(true)}const C=function(t){const e=Object.assign({},A,t),i=[{value:e.attributeNamePrefix,name:"attributeNamePrefix"},{value:e.attributesGroupName,name:"attributesGroupName"},{value:e.textNodeName,name:"textNodeName"},{value:e.cdataPropName,name:"cdataPropName"},{value:e.commentPropName,name:"commentPropName"}];for(const{value:t,name:e}of i)t&&T(t,e);return null===e.onDangerousProperty&&(e.onDangerousProperty=S),e.processEntities=_(e.processEntities,e.htmlEntities),e.unpairedTagsSet=new Set(e.unpairedTags),e.stopNodes&&Array.isArray(e.stopNodes)&&(e.stopNodes=e.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),e};let $;$="function"!=typeof Symbol?"@@xmlMetadata":Symbol("XML Node Metadata");class P{constructor(t){this.tagname=t,this.child=[],this[":@"]=Object.create(null);}add(t,e){"__proto__"===t&&(t="#__proto__"),this.child.push({[t]:e});}addChild(t,e){"__proto__"===t.tagname&&(t.tagname="#__proto__"),t[":@"]&&Object.keys(t[":@"]).length>0?this.child.push({[t.tagname]:t.child,":@":t[":@"]}):this.child.push({[t.tagname]:t.child}),void 0!==e&&(this.child[this.child.length-1][$]={startIndex:e});}static getMetaDataSymbol(){return $}}const O=":A-Za-z_À-ÖØ-öø-˿Ͱ-ͽͿ-҆҈-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�",j=":A-Za-z_À-˿Ͱ-ͽͿ-҆҈-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿",I=j+"\\-\\.\\d·̀-ͯ҇‿-⁀",k=(t,e,i="")=>{const n=`[${t.replace(":","")}][${e.replace(":","")}]*`;return {name:new RegExp(`^[${t}][${e}]*$`,i),ncName:new RegExp(`^${n}$`,i),qName:new RegExp(`^${n}(?::${n})?$`,i),nmToken:new RegExp(`^[${e}]+$`,i),nmTokens:new RegExp(`^[${e}]+(?:\\s+[${e}]+)*$`,i)}},L=k(O,O+"\\-\\.\\d·̀-ͯ‿-⁀"),D=k(j,I,"u"),R=":A-Za-z_",M=k(R,R+"\\-\\.\\d"),V=(t,{xmlVersion:e="1.0",asciiOnly:i=false}={})=>((t="1.0",e=false)=>e?M:"1.1"===t?D:L)(e,i).qName.test(t);class q{constructor(t,e){this.suppressValidationErr=!t,this.options=t,this.xmlVersion=e||1;}setXmlVersion(t=1){this.xmlVersion=t;}readDocType(t,e){const i=Object.create(null);let n=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");{e+=9;let r=1,s=false,o=false,a="";for(;e"===t[e]){if(o?"-"===t[e-1]&&"-"===t[e-2]&&(o=false,r--):r--,0===r)break}else "["===t[e]?s=true:a+=t[e];else {if(s&&U(t,"!ENTITY",e)){let r,s;if(e+=7,[r,s,e]=this.readEntityExp(t,e+1,this.suppressValidationErr),-1===s.indexOf("&")){if(false!==this.options.enabled&&null!=this.options.maxEntityCount&&n>=this.options.maxEntityCount)throw new Error(`Entity count (${n+1}) exceeds maximum allowed (${this.options.maxEntityCount})`);i[r]=s,n++;}}else if(s&&U(t,"!ELEMENT",e)){e+=8;const{index:i}=this.readElementExp(t,e+1);e=i;}else if(s&&U(t,"!ATTLIST",e))e+=8;else if(s&&U(t,"!NOTATION",e)){e+=9;const{index:i}=this.readNotationExp(t,e+1,this.suppressValidationErr);e=i;}else {if(!U(t,"!--",e))throw new Error("Invalid DOCTYPE");o=true;}r++,a="";}if(0!==r)throw new Error("Unclosed DOCTYPE")}return {entities:i,i:e}}readEntityExp(t,e){const i=e=F(t,e);for(;ethis.options.maxEntitySize)throw new Error(`Entity "${n}" size (${r.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);return [n,r,--e]}readNotationExp(t,e){const i=e=F(t,e);for(;e{for(;e=48&&r<=57||45===r))if(r=55296&&r<=56319){if(n+1=56320&&e<=57343){const t=65536+(r-55296<<10)+(e-56320);if(X.has(t)){i=n;break}}}}else if(255!==z[r-W]||Y.has(r)){i=n;break}}if(-1===i)return t;const n=[];i>0&&n.push(t.slice(0,i));for(let r=i;r=48&&i<=57||45===i){n.push(t[r]);continue}if(i=55296&&i<=56319){if(r+1=56320&&e<=57343){const t=65536+(i-55296<<10)+(e-56320),s=X.get(t);if(void 0!==s){n.push(String.fromCharCode(s+48)),r++;continue}}}n.push(t[r]);continue}if(Y.has(i)){n.push("-");continue}const s=z[i-W];n.push(255!==s?String.fromCharCode(s+48):t[r]);}return n.join("")}(i),"0"===i))return 0;if(e.hex&&H.test(i))return it(i,16);if(e.binary&&Q.test(i))return it(i,2);if(e.octal&&J.test(i))return it(i,8);if(isFinite(i)){if(i.includes("e")||i.includes("E"))return function(t,e,i){if(!i.eNotation)return t;const n=e.match(et);if(n){let r=n[1]||"";const s=-1===n[3].indexOf("e")?"E":"e",o=n[2],a=r?t[o.length+1]===s:t[o.length]===s;return o.length>1&&a?t:(1!==o.length||!n[3].startsWith(`.${s}`)&&n[3][0]!==s)&&o.length>0?i.leadingZeros&&!a?(e=(n[1]||"")+n[3],Number(e)):t:Number(e)}return t}(t,i,e);{const r=Z.exec(i);if(r){const s=r[1]||"",o=r[2];let a=(n=r[3])&&-1!==n.indexOf(".")?("."===(n=n.replace(/0+$/,""))?n="0":"."===n[0]?n="0"+n:"."===n[n.length-1]&&(n=n.substring(0,n.length-1)),n):n;const l=s?"."===t[o.length+1]:"."===t[o.length];if(!e.leadingZeros&&(o.length>1||1===o.length&&!l))return t;{const n=Number(i),r=String(n);if(0===n)return n;if(-1!==r.search(/[eE]/))return e.eNotation?n:t;if(-1!==i.indexOf("."))return "0"===r||r===a||r===`${s}${a}`?n:t;let l=o?a:i;return o?l===r||s+l===r?n:t:l===r||l===s+r?n:t}}return t}}var n;return function(t,e,i){const n=e===1/0;switch(i.infinity.toLowerCase()){case "null":return null;case "infinity":return e;case "string":return n?"Infinity":"-Infinity";default:return t}}(t,Number(i),e)}const et=/^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;function it(t,e){const i=t.trim();if(2!==e&&8!==e||(t=i.substring(2)),parseInt)return parseInt(t,e);if(Number.parseInt)return Number.parseInt(t,e);if(window&&window.parseInt)return window.parseInt(t,e);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}class nt{constructor(t){this._matcher=t;}get separator(){return this._matcher.separator}getCurrentTag(){const t=this._matcher.path;return t.length>0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return false;const i=e[e.length-1];return void 0!==i.values&&t in i.values}getAnyParentAttr(t){return this._matcher.getAnyParentAttr(t)}hasAnyParentAttr(t){return this._matcher.hasAnyParentAttr(t)}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=true){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class rt{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new nt(this),this._keptAttrs=[];}push(t,e=null,i=null,n=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const r=this.path.length;let s=this.siblingStacks[r];s||(s={counts:new Map,total:0},this.siblingStacks[r]=s);const o=i?`${i}:${t}`:t,a=s.counts.get(o)||0,l=s.total;s.counts.set(o,a+1),s.total++;const p={tag:t,position:l,counter:a};null!=i&&(p.namespace=i),null!=e&&(p.values=e),this.path.push(p);const c=this.path.length,h=null!==n?n.keep:null;if(null!=h&&h.length>0&&e)for(let t=0;tthis.path.length+1&&(this.siblingStacks.length=this.path.length+1);const e=this.path.length+1;for(;this._keptAttrs.length>0&&this._keptAttrs[this._keptAttrs.length-1].depth>=e;)this._keptAttrs.pop();return t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t);}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return false;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getAnyParentAttr(t){const e=this._keptAttrs;for(let i=e.length-1;i>=0;i--)if(e[i].name===t)return e[i].value}hasAnyParentAttr(t){const e=this._keptAttrs;for(let i=e.length-1;i>=0;i--)if(e[i].name===t)return true;return false}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=true){const i=t||this.separator;if(i===this.separator&&true===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[],this._keptAttrs=[];}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return false;for(let e=0;e=0&&e>=0;){const n=t[i];if("deep-wildcard"===n.type){if(i--,i<0)return true;const n=t[i];let r=false;for(let t=e;t>=0;t--)if(this._matchSegment(n,this.path[t],t===this.path.length-1)){e=t-1,i--,r=true;break}if(!r)return false}else {if(!this._matchSegment(n,this.path[e],e===this.path.length-1))return false;e--,i--;}}return i<0}_matchSegment(t,e,i){if("*"!==t.tag&&t.tag!==e.tag)return false;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return false;if(void 0!==t.attrName){if(!i)return false;if(!e.values||!(t.attrName in e.values))return false;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return false}if(void 0!==t.position){if(!i)return false;const n=e.counter??0;if("first"===t.position&&0!==n)return false;if("odd"===t.position&&n%2!=1)return false;if("even"===t.position&&n%2!=0)return false;if("nth"===t.position&&n!==t.positionValue)return false}return true}matchesAny(t){return t.matchesAny(this)}snapshot(){return {path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>t?{counts:new Map(t.counts),total:t.total}:t),keptAttrs:this._keptAttrs.map(t=>({...t}))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>t?{counts:new Map(t.counts),total:t.total}:t),this._keptAttrs=(t.keptAttrs||[]).map(t=>({...t}));}readOnly(){return this._view}}class st{constructor(t,e={},i){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=i,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position);}_parse(t){const e=[];let i=0,n="";for(;i",lt:"<",quot:'"'},pt={nbsp:" ",copy:"©",reg:"®",trade:"™",mdash:"—",ndash:"–",hellip:"…",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",bull:"•",para:"¶",sect:"§",deg:"°",frac12:"½",frac14:"¼",frac34:"¾"},ct=Object.freeze({ALLOW:"allow",BLOCK:"block",THROW:"throw"}),ht=new Set("!?\\\\/[]$%{}^&*()<>|+");function dt(t){if("#"===t[0])throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${t}"`);for(const e of t)if(ht.has(e))throw new Error(`[EntityReplacer] Invalid character '${e}' in entity name: "${t}"`);return t}function ut(...t){const e=Object.create(null);for(const i of t)if(i)for(const t of Object.keys(i)){const n=i[t];if("string"==typeof n)e[t]=n;else if(n&&"object"==typeof n&&void 0!==n.val){const i=n.val;"string"==typeof i&&(e[t]=i);}}return e}const ft="external",gt="base",mt="all",xt=Object.freeze({allow:0,leave:1,remove:2,throw:3}),bt=new Set([9,10,13]);class yt{constructor(t={}){var e;this._limit=t.limit||{},this._maxTotalExpansions=this._limit.maxTotalExpansions||0,this._maxExpandedLength=this._limit.maxExpandedLength||0,this._postCheck="function"==typeof t.postCheck?t.postCheck:t=>t,this._limitTiers=(e=this._limit.applyLimitsTo??ft)&&e!==ft?e===mt?new Set([mt]):e===gt?new Set([gt]):Array.isArray(e)?new Set(e):new Set([ft]):new Set([ft]),this._numericAllowed=t.numericAllowed??true,this._baseMap=ut(lt,t.namedEntities||null),this._externalMap=Object.create(null),this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this._removeSet=new Set(t.remove&&Array.isArray(t.remove)?t.remove:[]),this._leaveSet=new Set(t.leave&&Array.isArray(t.leave)?t.leave:[]);const i=function(t){if(!t)return {xmlVersion:1,onLevel:xt.allow,nullLevel:xt.remove};const e=1.1===t.xmlVersion?1.1:1,i=xt[t.onNCR]??xt.allow,n=xt[t.nullNCR]??xt.remove;return {xmlVersion:e,onLevel:i,nullLevel:Math.max(n,xt.remove)}}(t.ncr);this._ncrXmlVersion=i.xmlVersion,this._ncrOnLevel=i.onLevel,this._ncrNullLevel=i.nullLevel,this._onExternalEntity="function"==typeof t.onExternalEntity?t.onExternalEntity:null,this._onInputEntity="function"==typeof t.onInputEntity?t.onInputEntity:null;}_applyRegistrationHook(t,e,i,n){if(!t)return true;const r=t(e,i);if(r===ct.BLOCK)return false;if(r===ct.THROW)throw new Error(`[EntityDecoder] Registration of ${n} entity "&${e};" was rejected by hook`);return true}setExternalEntities(t){if(t)for(const e of Object.keys(t))dt(e);if(!this._onExternalEntity)return void(this._externalMap=ut(t));const e=ut(t),i=Object.create(null);for(const[t,n]of Object.entries(e))this._applyRegistrationHook(this._onExternalEntity,t,n,"external")&&(i[t]=n);this._externalMap=i;}addExternalEntity(t,e){dt(t),"string"==typeof e&&-1===e.indexOf("&")&&this._applyRegistrationHook(this._onExternalEntity,t,e,"external")&&(this._externalMap[t]=e);}addInputEntities(t){if(this._totalExpansions=0,this._expandedLength=0,!this._onInputEntity)return void(this._inputMap=ut(t));const e=ut(t),i=Object.create(null);for(const[t,n]of Object.entries(e))this._applyRegistrationHook(this._onInputEntity,t,n,"input")&&(i[t]=n);this._inputMap=i;}reset(){return this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this}setXmlVersion(t){this._ncrXmlVersion=1.1===t?1.1:1;}decode(t){if("string"!=typeof t||0===t.length)return t;if(-1===t.indexOf("&"))return t;const e=t,i=[],n=t.length;let r=0,s=0;const o=this._maxTotalExpansions>0,a=this._maxExpandedLength>0,l=o||a;for(;s=n||59!==t.charCodeAt(e)){s++;continue}const p=t.slice(s+1,e);if(0===p.length){s++;continue}let c,h;if(this._removeSet.has(p))c="",void 0===h&&(h=ft);else {if(this._leaveSet.has(p)){s++;continue}if(35===p.charCodeAt(0)){const t=this._resolveNCR(p);if(void 0===t){s++;continue}c=t,h=gt;}else {const t=this._resolveName(p);c=t?.value,h=t?.tier;}}if(void 0!==c){if(s>r&&i.push(t.slice(r,s)),i.push(c),r=e+1,s=r,l&&this._tierCounts(h)){if(o&&(this._totalExpansions++,this._totalExpansions>this._maxTotalExpansions))throw new Error(`[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}`);if(a){const t=c.length-(p.length+2);if(t>0&&(this._expandedLength+=t,this._expandedLength>this._maxExpandedLength))throw new Error(`[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}`)}}}else s++;}r=55296&&t<=57343||1===this._ncrXmlVersion&&t>=1&&t<=31&&!bt.has(t)?xt.remove:-1}_applyNCRAction(t,e,i){switch(t){case xt.allow:return String.fromCodePoint(i);case xt.remove:return "";case xt.leave:return;case xt.throw:throw new Error(`[EntityDecoder] Prohibited numeric character reference &${e}; (U+${i.toString(16).toUpperCase().padStart(4,"0")})`);default:return String.fromCodePoint(i)}}_resolveNCR(t){const e=t.charCodeAt(1);let i;if(i=120===e||88===e?parseInt(t.slice(2),16):parseInt(t.slice(1),10),Number.isNaN(i)||i<0||i>1114111)return;const n=this._classifyNCR(i);if(!this._numericAllowed&&n/]/i},{id:"html-script-close",description:"<\/script closing tag",pattern:/<\/script[\s>]/i},{id:"html-javascript-protocol",description:"javascript: URI scheme (with optional whitespace/encoding)",pattern:/j[\t\n\r ]*a[\t\n\r ]*v[\t\n\r ]*a[\t\n\r ]*s[\t\n\r ]*c[\t\n\r ]*r[\t\n\r ]*i[\t\n\r ]*p[\t\n\r ]*t[\t\n\r ]*:/i},{id:"html-vbscript-protocol",description:"vbscript: URI scheme",pattern:/vbscript[\t\n\r ]*:/i},{id:"html-data-html",description:"data:text/html URI — can execute scripts in browsers",pattern:/data[\t\n\r ]*:[\t\n\r ]*text\/html/i},{id:"html-data-xhtml",description:"data:application/xhtml+xml URI",pattern:/data[\t\n\r ]*:[\t\n\r ]*application\/xhtml/i},{id:"html-data-svg",description:"data:image/svg+xml URI — can execute scripts",pattern:/data[\t\n\r ]*:[\t\n\r ]*image\/svg\+xml/i},{id:"html-inline-event-handler",description:"Inline event handler attributes: onclick=, onerror=, onload=, etc.",pattern:/\bon\w{1,30}\s*=/i},{id:"html-entity-obfuscated-script",description:"HTML-entity-encoded