'use strict'; 
 | 
var globalThis = require('../internals/global-this'); 
 | 
var uncurryThis = require('../internals/function-uncurry-this'); 
 | 
var anObjectOrUndefined = require('../internals/an-object-or-undefined'); 
 | 
var aString = require('../internals/a-string'); 
 | 
var hasOwn = require('../internals/has-own-property'); 
 | 
var base64Map = require('../internals/base64-map'); 
 | 
var getAlphabetOption = require('../internals/get-alphabet-option'); 
 | 
var notDetached = require('../internals/array-buffer-not-detached'); 
 | 
  
 | 
var base64Alphabet = base64Map.c2i; 
 | 
var base64UrlAlphabet = base64Map.c2iUrl; 
 | 
  
 | 
var SyntaxError = globalThis.SyntaxError; 
 | 
var TypeError = globalThis.TypeError; 
 | 
var at = uncurryThis(''.charAt); 
 | 
  
 | 
var skipAsciiWhitespace = function (string, index) { 
 | 
  var length = string.length; 
 | 
  for (;index < length; index++) { 
 | 
    var chr = at(string, index); 
 | 
    if (chr !== ' ' && chr !== '\t' && chr !== '\n' && chr !== '\f' && chr !== '\r') break; 
 | 
  } return index; 
 | 
}; 
 | 
  
 | 
var decodeBase64Chunk = function (chunk, alphabet, throwOnExtraBits) { 
 | 
  var chunkLength = chunk.length; 
 | 
  
 | 
  if (chunkLength < 4) { 
 | 
    chunk += chunkLength === 2 ? 'AA' : 'A'; 
 | 
  } 
 | 
  
 | 
  var triplet = (alphabet[at(chunk, 0)] << 18) 
 | 
    + (alphabet[at(chunk, 1)] << 12) 
 | 
    + (alphabet[at(chunk, 2)] << 6) 
 | 
    + alphabet[at(chunk, 3)]; 
 | 
  
 | 
  var chunkBytes = [ 
 | 
    (triplet >> 16) & 255, 
 | 
    (triplet >> 8) & 255, 
 | 
    triplet & 255 
 | 
  ]; 
 | 
  
 | 
  if (chunkLength === 2) { 
 | 
    if (throwOnExtraBits && chunkBytes[1] !== 0) { 
 | 
      throw new SyntaxError('Extra bits'); 
 | 
    } 
 | 
    return [chunkBytes[0]]; 
 | 
  } 
 | 
  
 | 
  if (chunkLength === 3) { 
 | 
    if (throwOnExtraBits && chunkBytes[2] !== 0) { 
 | 
      throw new SyntaxError('Extra bits'); 
 | 
    } 
 | 
    return [chunkBytes[0], chunkBytes[1]]; 
 | 
  } 
 | 
  
 | 
  return chunkBytes; 
 | 
}; 
 | 
  
 | 
var writeBytes = function (bytes, elements, written) { 
 | 
  var elementsLength = elements.length; 
 | 
  for (var index = 0; index < elementsLength; index++) { 
 | 
    bytes[written + index] = elements[index]; 
 | 
  } 
 | 
  return written + elementsLength; 
 | 
}; 
 | 
  
 | 
/* eslint-disable max-statements, max-depth -- TODO */ 
 | 
module.exports = function (string, options, into, maxLength) { 
 | 
  aString(string); 
 | 
  anObjectOrUndefined(options); 
 | 
  var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; 
 | 
  var lastChunkHandling = options ? options.lastChunkHandling : undefined; 
 | 
  
 | 
  if (lastChunkHandling === undefined) lastChunkHandling = 'loose'; 
 | 
  
 | 
  if (lastChunkHandling !== 'loose' && lastChunkHandling !== 'strict' && lastChunkHandling !== 'stop-before-partial') { 
 | 
    throw new TypeError('Incorrect `lastChunkHandling` option'); 
 | 
  } 
 | 
  
 | 
  if (into) notDetached(into.buffer); 
 | 
  
 | 
  var bytes = into || []; 
 | 
  var written = 0; 
 | 
  var read = 0; 
 | 
  var chunk = ''; 
 | 
  var index = 0; 
 | 
  
 | 
  if (maxLength) while (true) { 
 | 
    index = skipAsciiWhitespace(string, index); 
 | 
    if (index === string.length) { 
 | 
      if (chunk.length > 0) { 
 | 
        if (lastChunkHandling === 'stop-before-partial') { 
 | 
          break; 
 | 
        } 
 | 
        if (lastChunkHandling === 'loose') { 
 | 
          if (chunk.length === 1) { 
 | 
            throw new SyntaxError('Malformed padding: exactly one additional character'); 
 | 
          } 
 | 
          written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); 
 | 
        } else { 
 | 
          throw new SyntaxError('Missing padding'); 
 | 
        } 
 | 
      } 
 | 
      read = string.length; 
 | 
      break; 
 | 
    } 
 | 
    var chr = at(string, index); 
 | 
    ++index; 
 | 
    if (chr === '=') { 
 | 
      if (chunk.length < 2) { 
 | 
        throw new SyntaxError('Padding is too early'); 
 | 
      } 
 | 
      index = skipAsciiWhitespace(string, index); 
 | 
      if (chunk.length === 2) { 
 | 
        if (index === string.length) { 
 | 
          if (lastChunkHandling === 'stop-before-partial') { 
 | 
            break; 
 | 
          } 
 | 
          throw new SyntaxError('Malformed padding: only one ='); 
 | 
        } 
 | 
        if (at(string, index) === '=') { 
 | 
          ++index; 
 | 
          index = skipAsciiWhitespace(string, index); 
 | 
        } 
 | 
      } 
 | 
      if (index < string.length) { 
 | 
        throw new SyntaxError('Unexpected character after padding'); 
 | 
      } 
 | 
      written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written); 
 | 
      read = string.length; 
 | 
      break; 
 | 
    } 
 | 
    if (!hasOwn(alphabet, chr)) { 
 | 
      throw new SyntaxError('Unexpected character'); 
 | 
    } 
 | 
    var remainingBytes = maxLength - written; 
 | 
    if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) { 
 | 
      // special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=` 
 | 
      break; 
 | 
    } 
 | 
  
 | 
    chunk += chr; 
 | 
    if (chunk.length === 4) { 
 | 
      written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); 
 | 
      chunk = ''; 
 | 
      read = index; 
 | 
      if (written === maxLength) { 
 | 
        break; 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
  
 | 
  return { bytes: bytes, read: read, written: written }; 
 | 
}; 
 |