base64.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. if (Uint8Array) {
  2. const _slice = Uint8Array.prototype.slice;
  3. try {
  4. // Can't be used with DOM elements in IE < 9
  5. _slice.call(document.documentElement);
  6. } catch (e) { // Fails in IE < 9
  7. // This will work for genuine arrays, array-like objects,
  8. // NamedNodeMap (attributes, entities, notations),
  9. // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
  10. // and will not fail on other DOM objects (as do DOM elements in IE < 9)
  11. Uint8Array.prototype.slice = function(begin, end) {
  12. // IE < 9 gets unhappy with an undefined end argument
  13. end = (typeof end !== 'undefined') ? end : this.length;
  14. // For native Array objects, we use the native slice function
  15. if (Object.prototype.toString.call(this) === '[object Array]') {
  16. return _slice.call(this, begin, end);
  17. }
  18. // For array like object we handle it ourselves.
  19. let i,
  20. cloned = [],
  21. size,
  22. len = this.length;
  23. // Handle negative value for "begin"
  24. let start = begin || 0;
  25. start = (start >= 0) ? start : Math.max(0, len + start);
  26. // Handle negative value for "end"
  27. let upTo = (typeof end === 'number') ? Math.min(end, len) : len;
  28. if (end < 0) {
  29. upTo = len + end;
  30. }
  31. // Actual expected size of the slice
  32. size = upTo - start;
  33. if (size > 0) {
  34. cloned = new Array(size);
  35. if (this.charAt) {
  36. for (i = 0; i < size; i++) {
  37. cloned[i] = this.charAt(start + i);
  38. }
  39. } else {
  40. for (i = 0; i < size; i++) {
  41. cloned[i] = this[start + i];
  42. }
  43. }
  44. }
  45. return cloned;
  46. };
  47. }
  48. if (!Uint8Array.from) {
  49. Uint8Array.from = (function() {
  50. const toStr = Object.prototype.toString;
  51. const isCallable = function(fn) {
  52. return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
  53. };
  54. const toInteger = function(value) {
  55. const number = Number(value);
  56. if (isNaN(number)) { return 0; }
  57. if (number === 0 || !isFinite(number)) { return number; }
  58. return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
  59. };
  60. const maxSafeInteger = Math.pow(2, 53) - 1;
  61. const toLength = function(value) {
  62. const len = toInteger(value);
  63. return Math.min(Math.max(len, 0), maxSafeInteger);
  64. };
  65. const toItems = function(value) {
  66. // support set
  67. if (value.size > 0 && value.values) {
  68. const values = value.values();
  69. let it = values.next();
  70. const o = [];
  71. while (!it.done) {
  72. o.push(it.value);
  73. it = values.next();
  74. }
  75. return o;
  76. }
  77. return Object(value);
  78. };
  79. // The length property of the from method is 1.
  80. return function from(arrayLike/* , mapFn, thisArg */) {
  81. // 1. Let C be the this value.
  82. const C = this;
  83. // 2. Let items be ToObject(arrayLike).
  84. const items = toItems(arrayLike);
  85. // 3. ReturnIfAbrupt(items).
  86. if (arrayLike == null) {
  87. throw new TypeError('Array.from requires an array-like object - not null or undefined');
  88. }
  89. // 4. If mapfn is undefined, then let mapping be false.
  90. const mapFn = arguments.length > 1 ? arguments[1] : void undefined;
  91. let T;
  92. if (typeof mapFn !== 'undefined') {
  93. // 5. else
  94. // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
  95. if (!isCallable(mapFn)) {
  96. throw new TypeError('Array.from: when provided, the second argument must be a function');
  97. }
  98. // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
  99. if (arguments.length > 2) {
  100. T = arguments[2];
  101. }
  102. }
  103. // 10. Let lenValue be Get(items, "length").
  104. // 11. Let len be ToLength(lenValue).
  105. const len = toLength(items.length);
  106. // 13. If IsConstructor(C) is true, then
  107. // 13. a. Let A be the result of calling the [[Construct]] internal method
  108. // of C with an argument list containing the single item len.
  109. // 14. a. Else, Let A be ArrayCreate(len).
  110. const A = isCallable(C) ? Object(new C(len)) : new Array(len);
  111. // 16. Let k be 0.
  112. let k = 0;
  113. // 17. Repeat, while k < len�� (also steps a - h)
  114. let kValue;
  115. while (k < len) {
  116. kValue = items[k];
  117. if (mapFn) {
  118. A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
  119. } else {
  120. A[k] = kValue;
  121. }
  122. k += 1;
  123. }
  124. // 18. Let putStatus be Put(A, "length", len, true).
  125. A.length = len;
  126. // 20. Return A.
  127. return A;
  128. };
  129. }());
  130. }
  131. }
  132. (function(global, factory) {
  133. typeof exports === 'object' && typeof module !== 'undefined'
  134. ? module.exports = factory(global)
  135. : typeof define === 'function' && define.amd
  136. ? define(factory) : factory(global);
  137. }((
  138. typeof self !== 'undefined' ? self
  139. : typeof window !== 'undefined' ? window
  140. : typeof global !== 'undefined' ? global
  141. : this
  142. ), function(global) {
  143. 'use strict';
  144. // existing version for noConflict()
  145. global = global || {};
  146. const _Base64 = global.Base64;
  147. const version = '2.6.2';
  148. // constants
  149. const b64chars
  150. = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  151. const b64tab = function(bin) {
  152. const t = {};
  153. for (let i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
  154. return t;
  155. }(b64chars);
  156. const fromCharCode = String.fromCharCode;
  157. // encoder stuff
  158. const cb_utob = function(c) {
  159. if (c.length < 2) {
  160. var cc = c.charCodeAt(0);
  161. return cc < 0x80 ? c
  162. : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
  163. + fromCharCode(0x80 | (cc & 0x3f)))
  164. : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
  165. + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
  166. + fromCharCode(0x80 | (cc & 0x3f)));
  167. }
  168. var cc = 0x10000
  169. + (c.charCodeAt(0) - 0xD800) * 0x400
  170. + (c.charCodeAt(1) - 0xDC00);
  171. return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
  172. + fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
  173. + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
  174. + fromCharCode(0x80 | (cc & 0x3f)));
  175. };
  176. const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
  177. const utob = function(u) {
  178. return u.replace(re_utob, cb_utob);
  179. };
  180. const cb_encode = function(ccc) {
  181. const padlen = [ 0, 2, 1 ][ccc.length % 3],
  182. ord = ccc.charCodeAt(0) << 16
  183. | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
  184. | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
  185. chars = [
  186. b64chars.charAt(ord >>> 18),
  187. b64chars.charAt((ord >>> 12) & 63),
  188. padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
  189. padlen >= 1 ? '=' : b64chars.charAt(ord & 63),
  190. ];
  191. return chars.join('');
  192. };
  193. const btoa = global.btoa && typeof global.btoa === 'function'
  194. ? function(b) { return global.btoa(b); } : function(b) {
  195. if (b.match(/[^\x00-\xFF]/)) {
  196. throw new RangeError(
  197. 'The string contains invalid characters.'
  198. );
  199. }
  200. return b.replace(/[\s\S]{1,3}/g, cb_encode);
  201. };
  202. const _encode = function(u) {
  203. return btoa(utob(String(u)));
  204. };
  205. const mkUriSafe = function(b64) {
  206. return b64.replace(/[+\/]/g, function(m0) {
  207. return m0 == '+' ? '-' : '_';
  208. }).replace(/=/g, '');
  209. };
  210. const encode = function(u, urisafe) {
  211. return urisafe ? mkUriSafe(_encode(u)) : _encode(u);
  212. };
  213. const encodeURI = function(u) { return encode(u, true); };
  214. let fromUint8Array;
  215. if (global.Uint8Array) {
  216. fromUint8Array = function(a, urisafe) {
  217. // return btoa(fromCharCode.apply(null, a));
  218. let b64 = '';
  219. for (let i = 0, l = a.length; i < l; i += 3) {
  220. const a0 = a[i],
  221. a1 = a[i + 1],
  222. a2 = a[i + 2];
  223. const ord = a0 << 16 | a1 << 8 | a2;
  224. b64 += b64chars.charAt(ord >>> 18)
  225. + b64chars.charAt((ord >>> 12) & 63)
  226. + (typeof a1 !== 'undefined'
  227. ? b64chars.charAt((ord >>> 6) & 63) : '=')
  228. + (typeof a2 !== 'undefined'
  229. ? b64chars.charAt(ord & 63) : '=');
  230. }
  231. return urisafe ? mkUriSafe(b64) : b64;
  232. };
  233. }
  234. // decoder stuff
  235. const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
  236. const cb_btou = function(cccc) {
  237. switch (cccc.length) {
  238. case 4:
  239. var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
  240. | ((0x3f & cccc.charCodeAt(1)) << 12)
  241. | ((0x3f & cccc.charCodeAt(2)) << 6)
  242. | (0x3f & cccc.charCodeAt(3)),
  243. offset = cp - 0x10000;
  244. return (fromCharCode((offset >>> 10) + 0xD800)
  245. + fromCharCode((offset & 0x3FF) + 0xDC00));
  246. case 3:
  247. return fromCharCode(
  248. ((0x0f & cccc.charCodeAt(0)) << 12)
  249. | ((0x3f & cccc.charCodeAt(1)) << 6)
  250. | (0x3f & cccc.charCodeAt(2))
  251. );
  252. default:
  253. return fromCharCode(
  254. ((0x1f & cccc.charCodeAt(0)) << 6)
  255. | (0x3f & cccc.charCodeAt(1))
  256. );
  257. }
  258. };
  259. const btou = function(b) {
  260. return b.replace(re_btou, cb_btou);
  261. };
  262. const cb_decode = function(cccc) {
  263. const len = cccc.length,
  264. padlen = len % 4,
  265. n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
  266. | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
  267. | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
  268. | (len > 3 ? b64tab[cccc.charAt(3)] : 0),
  269. chars = [
  270. fromCharCode(n >>> 16),
  271. fromCharCode((n >>> 8) & 0xff),
  272. fromCharCode(n & 0xff),
  273. ];
  274. chars.length -= [ 0, 0, 2, 1 ][padlen];
  275. return chars.join('');
  276. };
  277. const _atob = global.atob && typeof global.atob === 'function'
  278. ? function(a) { return global.atob(a); } : function(a) {
  279. return a.replace(/\S{1,4}/g, cb_decode);
  280. };
  281. const atob = function(a) {
  282. return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g, ''));
  283. };
  284. const _decode = function(a) { return btou(_atob(a)); };
  285. const decode = function(a) {
  286. return _decode(
  287. String(a).replace(/[-_]/g, function(m0) {
  288. return m0 == '-' ? '+' : '/';
  289. }).replace(/[^A-Za-z0-9\+\/]/g, '')
  290. );
  291. };
  292. let toUint8Array;
  293. if (global.Uint8Array) {
  294. toUint8Array = function(a) {
  295. return Uint8Array.from(atob(a), function(c) {
  296. return c.charCodeAt(0);
  297. });
  298. };
  299. }
  300. const noConflict = function() {
  301. const Base64 = global.Base64;
  302. global.Base64 = _Base64;
  303. return Base64;
  304. };
  305. // export Base64
  306. global.Base64 = {
  307. VERSION: version,
  308. atob,
  309. btoa,
  310. fromBase64: decode,
  311. toBase64: encode,
  312. utob,
  313. encode,
  314. encodeURI,
  315. btou,
  316. decode,
  317. noConflict,
  318. fromUint8Array,
  319. toUint8Array,
  320. };
  321. // if ES5 is available, make Base64.extendString() available
  322. if (typeof Object.defineProperty === 'function') {
  323. const noEnum = function(v) {
  324. return { value: v, enumerable: false, writable: true, configurable: true };
  325. };
  326. global.Base64.extendString = function() {
  327. Object.defineProperty(
  328. String.prototype, 'fromBase64', noEnum(function() {
  329. return decode(this);
  330. }));
  331. Object.defineProperty(
  332. String.prototype, 'toBase64', noEnum(function(urisafe) {
  333. return encode(this, urisafe);
  334. }));
  335. Object.defineProperty(
  336. String.prototype, 'toBase64URI', noEnum(function() {
  337. return encode(this, true);
  338. }));
  339. };
  340. }
  341. //
  342. // export Base64 to the namespace
  343. //
  344. if (global.Meteor) { // Meteor.js
  345. Base64 = global.Base64;
  346. }
  347. // module.exports and AMD are mutually exclusive.
  348. // module.exports has precedence.
  349. if (typeof module !== 'undefined' && module.exports) {
  350. module.exports.Base64 = global.Base64;
  351. } else if (typeof define === 'function' && define.amd) {
  352. // AMD. Register as an anonymous module.
  353. define([], function() { return global.Base64; });
  354. }
  355. // that's it!
  356. return { Base64: global.Base64 };
  357. }));