| // General purpose utility functions go in this file. | |
| function allAreFinite(args) { | |
| for (var i = 0; i < args.length; i++) { | |
| if (args[i] !== undefined && !Number.isFinite(args[i])) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| function toBase64String(bytes) { | |
| if (typeof Buffer !== 'undefined') { // Are we on node? | |
| return Buffer.from(bytes).toString('base64'); | |
| } else { | |
| // From https://stackoverflow.com/a/25644409 | |
| // because the naive solution of | |
| // btoa(String.fromCharCode.apply(null, bytes)); | |
| // would occasionally throw "Maximum call stack size exceeded" | |
| var CHUNK_SIZE = 0x8000; //arbitrary number | |
| var index = 0; | |
| var length = bytes.length; | |
| var result = ''; | |
| var slice; | |
| while (index < length) { | |
| slice = bytes.slice(index, Math.min(index + CHUNK_SIZE, length)); | |
| result += String.fromCharCode.apply(null, slice); | |
| index += CHUNK_SIZE; | |
| } | |
| return btoa(result); | |
| } | |
| } | |