FRE-651: CEO coordination notes for founder bio/headshot assets
This commit is contained in:
283
node_modules/@stablelib/base64/base64.ts
generated
vendored
Normal file
283
node_modules/@stablelib/base64/base64.ts
generated
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
// Copyright (C) 2016 Dmitry Chestnykh
|
||||
// MIT License. See LICENSE file for details.
|
||||
|
||||
/**
|
||||
* Package base64 implements Base64 encoding and decoding.
|
||||
*/
|
||||
|
||||
// Invalid character used in decoding to indicate
|
||||
// that the character to decode is out of range of
|
||||
// alphabet and cannot be decoded.
|
||||
const INVALID_BYTE = 256;
|
||||
|
||||
/**
|
||||
* Implements standard Base64 encoding.
|
||||
*
|
||||
* Operates in constant time.
|
||||
*/
|
||||
export class Coder {
|
||||
// TODO(dchest): methods to encode chunk-by-chunk.
|
||||
|
||||
constructor(private _paddingCharacter = "=") { }
|
||||
|
||||
encodedLength(length: number): number {
|
||||
if (!this._paddingCharacter) {
|
||||
return (length * 8 + 5) / 6 | 0;
|
||||
}
|
||||
return (length + 2) / 3 * 4 | 0;
|
||||
}
|
||||
|
||||
encode(data: Uint8Array): string {
|
||||
let out = "";
|
||||
|
||||
let i = 0;
|
||||
for (; i < data.length - 2; i += 3) {
|
||||
let c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
|
||||
out += this._encodeByte((c >>> 3 * 6) & 63);
|
||||
out += this._encodeByte((c >>> 2 * 6) & 63);
|
||||
out += this._encodeByte((c >>> 1 * 6) & 63);
|
||||
out += this._encodeByte((c >>> 0 * 6) & 63);
|
||||
}
|
||||
|
||||
const left = data.length - i;
|
||||
if (left > 0) {
|
||||
let c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);
|
||||
out += this._encodeByte((c >>> 3 * 6) & 63);
|
||||
out += this._encodeByte((c >>> 2 * 6) & 63);
|
||||
if (left === 2) {
|
||||
out += this._encodeByte((c >>> 1 * 6) & 63);
|
||||
} else {
|
||||
out += this._paddingCharacter || "";
|
||||
}
|
||||
out += this._paddingCharacter || "";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
maxDecodedLength(length: number): number {
|
||||
if (!this._paddingCharacter) {
|
||||
return (length * 6 + 7) / 8 | 0;
|
||||
}
|
||||
return length / 4 * 3 | 0;
|
||||
}
|
||||
|
||||
decodedLength(s: string): number {
|
||||
return this.maxDecodedLength(s.length - this._getPaddingLength(s));
|
||||
}
|
||||
|
||||
decode(s: string): Uint8Array {
|
||||
if (s.length === 0) {
|
||||
return new Uint8Array(0);
|
||||
}
|
||||
const paddingLength = this._getPaddingLength(s);
|
||||
const length = s.length - paddingLength;
|
||||
const out = new Uint8Array(this.maxDecodedLength(length));
|
||||
let op = 0;
|
||||
let i = 0;
|
||||
let haveBad = 0;
|
||||
let v0 = 0, v1 = 0, v2 = 0, v3 = 0;
|
||||
for (; i < length - 4; i += 4) {
|
||||
v0 = this._decodeChar(s.charCodeAt(i + 0));
|
||||
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
||||
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
||||
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
||||
out[op++] = (v0 << 2) | (v1 >>> 4);
|
||||
out[op++] = (v1 << 4) | (v2 >>> 2);
|
||||
out[op++] = (v2 << 6) | v3;
|
||||
haveBad |= v0 & INVALID_BYTE;
|
||||
haveBad |= v1 & INVALID_BYTE;
|
||||
haveBad |= v2 & INVALID_BYTE;
|
||||
haveBad |= v3 & INVALID_BYTE;
|
||||
}
|
||||
if (i < length - 1) {
|
||||
v0 = this._decodeChar(s.charCodeAt(i));
|
||||
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
||||
out[op++] = (v0 << 2) | (v1 >>> 4);
|
||||
haveBad |= v0 & INVALID_BYTE;
|
||||
haveBad |= v1 & INVALID_BYTE;
|
||||
}
|
||||
if (i < length - 2) {
|
||||
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
||||
out[op++] = (v1 << 4) | (v2 >>> 2);
|
||||
haveBad |= v2 & INVALID_BYTE;
|
||||
}
|
||||
if (i < length - 3) {
|
||||
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
||||
out[op++] = (v2 << 6) | v3;
|
||||
haveBad |= v3 & INVALID_BYTE;
|
||||
}
|
||||
if (haveBad !== 0) {
|
||||
throw new Error("Base64Coder: incorrect characters for decoding");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Standard encoding have the following encoded/decoded ranges,
|
||||
// which we need to convert between.
|
||||
//
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /
|
||||
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
||||
// ASCII: 65 - 90 97 - 122 48 - 57 43 47
|
||||
//
|
||||
|
||||
// Encode 6 bits in b into a new character.
|
||||
protected _encodeByte(b: number): string {
|
||||
// Encoding uses constant time operations as follows:
|
||||
//
|
||||
// 1. Define comparison of A with B using (A - B) >>> 8:
|
||||
// if A > B, then result is positive integer
|
||||
// if A <= B, then result is 0
|
||||
//
|
||||
// 2. Define selection of C or 0 using bitwise AND: X & C:
|
||||
// if X == 0, then result is 0
|
||||
// if X != 0, then result is C
|
||||
//
|
||||
// 3. Start with the smallest comparison (b >= 0), which is always
|
||||
// true, so set the result to the starting ASCII value (65).
|
||||
//
|
||||
// 4. Continue comparing b to higher ASCII values, and selecting
|
||||
// zero if comparison isn't true, otherwise selecting a value
|
||||
// to add to result, which:
|
||||
//
|
||||
// a) undoes the previous addition
|
||||
// b) provides new value to add
|
||||
//
|
||||
let result = b;
|
||||
// b >= 0
|
||||
result += 65;
|
||||
// b > 25
|
||||
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
||||
// b > 51
|
||||
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
||||
// b > 61
|
||||
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);
|
||||
// b > 62
|
||||
result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);
|
||||
|
||||
return String.fromCharCode(result);
|
||||
}
|
||||
|
||||
// Decode a character code into a byte.
|
||||
// Must return 256 if character is out of alphabet range.
|
||||
protected _decodeChar(c: number): number {
|
||||
// Decoding works similar to encoding: using the same comparison
|
||||
// function, but now it works on ranges: result is always incremented
|
||||
// by value, but this value becomes zero if the range is not
|
||||
// satisfied.
|
||||
//
|
||||
// Decoding starts with invalid value, 256, which is then
|
||||
// subtracted when the range is satisfied. If none of the ranges
|
||||
// apply, the function returns 256, which is then checked by
|
||||
// the caller to throw error.
|
||||
let result = INVALID_BYTE; // start with invalid character
|
||||
|
||||
// c == 43 (c > 42 and c < 44)
|
||||
result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);
|
||||
// c == 47 (c > 46 and c < 48)
|
||||
result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);
|
||||
// c > 47 and c < 58
|
||||
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
||||
// c > 64 and c < 91
|
||||
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
||||
// c > 96 and c < 123
|
||||
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private _getPaddingLength(s: string): number {
|
||||
let paddingLength = 0;
|
||||
if (this._paddingCharacter) {
|
||||
for (let i = s.length - 1; i >= 0; i--) {
|
||||
if (s[i] !== this._paddingCharacter) {
|
||||
break;
|
||||
}
|
||||
paddingLength++;
|
||||
}
|
||||
if (s.length < 4 || paddingLength > 2) {
|
||||
throw new Error("Base64Coder: incorrect padding");
|
||||
}
|
||||
}
|
||||
return paddingLength;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const stdCoder = new Coder();
|
||||
|
||||
export function encode(data: Uint8Array): string {
|
||||
return stdCoder.encode(data);
|
||||
}
|
||||
|
||||
export function decode(s: string): Uint8Array {
|
||||
return stdCoder.decode(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements URL-safe Base64 encoding.
|
||||
* (Same as Base64, but '+' is replaced with '-', and '/' with '_').
|
||||
*
|
||||
* Operates in constant time.
|
||||
*/
|
||||
export class URLSafeCoder extends Coder {
|
||||
// URL-safe encoding have the following encoded/decoded ranges:
|
||||
//
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _
|
||||
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
||||
// ASCII: 65 - 90 97 - 122 48 - 57 45 95
|
||||
//
|
||||
|
||||
protected _encodeByte(b: number): string {
|
||||
let result = b;
|
||||
// b >= 0
|
||||
result += 65;
|
||||
// b > 25
|
||||
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
||||
// b > 51
|
||||
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
||||
// b > 61
|
||||
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);
|
||||
// b > 62
|
||||
result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);
|
||||
|
||||
return String.fromCharCode(result);
|
||||
}
|
||||
|
||||
protected _decodeChar(c: number): number {
|
||||
let result = INVALID_BYTE;
|
||||
|
||||
// c == 45 (c > 44 and c < 46)
|
||||
result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);
|
||||
// c == 95 (c > 94 and c < 96)
|
||||
result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);
|
||||
// c > 47 and c < 58
|
||||
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
||||
// c > 64 and c < 91
|
||||
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
||||
// c > 96 and c < 123
|
||||
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
const urlSafeCoder = new URLSafeCoder();
|
||||
|
||||
export function encodeURLSafe(data: Uint8Array): string {
|
||||
return urlSafeCoder.encode(data);
|
||||
}
|
||||
|
||||
export function decodeURLSafe(s: string): Uint8Array {
|
||||
return urlSafeCoder.decode(s);
|
||||
}
|
||||
|
||||
|
||||
export const encodedLength = (length: number) =>
|
||||
stdCoder.encodedLength(length);
|
||||
|
||||
export const maxDecodedLength = (length: number) =>
|
||||
stdCoder.maxDecodedLength(length);
|
||||
|
||||
export const decodedLength = (s: string) =>
|
||||
stdCoder.decodedLength(s);
|
||||
Reference in New Issue
Block a user