;(function (exports) { 'use strict' var i var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' var lookup = [] for (i = 0; i < code.length; i++) { lookup[i] = code[i] } var revLookup = [] for (i = 0; i < code.length; ++i) { revLookup[code.charCodeAt(i)] = i } revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 var Arr = (typeof Uint8Array !== 'undefined') ? Uint8Array : Array function decode (elt) { var v = revLookup[elt.charCodeAt(0)] return v !== undefined ? v : -1 } function b64ToByteArray (b64) { var i, j, l, tmp, placeHolders, arr if (b64.length % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // the number of equal signs (place holders) // if there are two placeholders, than the two characters before it // represent one byte // if there is only one, then the three characters before it represent 2 bytes // this is just a cheap hack to not do indexOf twice var len = b64.length placeHolders = b64.charAt(len - 2) === '=' ? 2 : b64.charAt(len - 1) === '=' ? 1 : 0 // base64 is 4/3 + up to two characters of the original data arr = new Arr(b64.length * 3 / 4 - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? b64.length - 4 : b64.length var L = 0 function push (v) { arr[L++] = v } for (i = 0, j = 0; i < l; i += 4, j += 3) { tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) push((tmp & 0xFF0000) >> 16) push((tmp & 0xFF00) >> 8) push(tmp & 0xFF) } if (placeHolders === 2) { tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) push(tmp & 0xFF) } else if (placeHolders === 1) { tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) push((tmp >> 8) & 0xFF) push(tmp & 0xFF) } return arr } function encode (num) { return lookup[num] } function tripletToBase64 (num) { return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) } function encodeChunk (uint8, start, end) { var temp var output = [] for (var i = start; i < end; i += 3) { temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) output.push(tripletToBase64(temp)) } return output.join('') } function uint8ToBase64 (uint8) { var i var extraBytes = uint8.length % 3 // if we have 1 byte left, pad 2 bytes var output = '' var parts = [] var temp, length var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (i = 0, length = uint8.length - extraBytes; i < length; i += maxChunkLength) { parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > length ? length : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes switch (extraBytes) { case 1: temp = uint8[uint8.length - 1] output += encode(temp >> 2) output += encode((temp << 4) & 0x3F) output += '==' break case 2: temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) output += encode(temp >> 10) output += encode((temp >> 4) & 0x3F) output += encode((temp << 2) & 0x3F) output += '=' break default: break } parts.push(output) return parts.join('') } exports.toByteArray = b64ToByteArray exports.fromByteArray = uint8ToBase64 }(typeof exports === 'undefined' ? (this.base64js = {}) : exports))