@file-viewer/renderer-ofd 2.1.23 → 2.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,525 @@
1
+ import Int10 from './int10.js';
2
+ import oids from './oids.js';
3
+ var
4
+ ellipsis = "\u2026",
5
+ reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/,
6
+ reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
7
+
8
+ function stringCut(str, len) {
9
+ if (str.length > len)
10
+ str = str.substring(0, len) + ellipsis;
11
+ return str;
12
+ }
13
+
14
+ function Stream(enc, pos) {
15
+ if (enc instanceof Stream) {
16
+ this.enc = enc.enc;
17
+ this.pos = enc.pos;
18
+ } else {
19
+ // enc should be an array or a binary string
20
+ this.enc = enc;
21
+ this.pos = pos;
22
+ }
23
+ }
24
+ Stream.prototype.get = function (pos) {
25
+ if (pos === undefined)
26
+ pos = this.pos++;
27
+ if (pos >= this.enc.length)
28
+ throw 'Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length;
29
+ return (typeof this.enc == "string") ? this.enc.charCodeAt(pos) : this.enc[pos];
30
+ };
31
+ Stream.prototype.hexDigits = "0123456789ABCDEF";
32
+ Stream.prototype.hexByte = function (b) {
33
+ return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
34
+ };
35
+ Stream.prototype.hexDump = function (start, end, raw) {
36
+ var s = "";
37
+ for (var i = start; i < end; ++i) {
38
+ s += this.hexByte(this.get(i));
39
+ if (raw !== true)
40
+ switch (i & 0xF) {
41
+ case 0x7: s += " "; break;
42
+ case 0xF: s += "\n"; break;
43
+ default: s += " ";
44
+ }
45
+ }
46
+ return s;
47
+ };
48
+ var b64Safe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
49
+ Stream.prototype.b64Dump = function (start, end) {
50
+ var extra = (end - start) % 3,
51
+ s = '',
52
+ i, c;
53
+ for (i = start; i + 2 < end; i += 3) {
54
+ c = this.get(i) << 16 | this.get(i + 1) << 8 | this.get(i + 2);
55
+ s += b64Safe.charAt(c >> 18 & 0x3F);
56
+ s += b64Safe.charAt(c >> 12 & 0x3F);
57
+ s += b64Safe.charAt(c >> 6 & 0x3F);
58
+ s += b64Safe.charAt(c & 0x3F);
59
+ }
60
+ if (extra > 0) {
61
+ c = this.get(i) << 16;
62
+ if (extra > 1) c |= this.get(i + 1) << 8;
63
+ s += b64Safe.charAt(c >> 18 & 0x3F);
64
+ s += b64Safe.charAt(c >> 12 & 0x3F);
65
+ if (extra == 2) s += b64Safe.charAt(c >> 6 & 0x3F);
66
+ }
67
+ return s;
68
+ };
69
+ Stream.prototype.isASCII = function (start, end) {
70
+ for (var i = start; i < end; ++i) {
71
+ var c = this.get(i);
72
+ if (c < 32 || c > 176)
73
+ return false;
74
+ }
75
+ return true;
76
+ };
77
+ Stream.prototype.parseStringISO = function (start, end) {
78
+ var s = "";
79
+ for (var i = start; i < end; ++i)
80
+ s += String.fromCharCode(this.get(i));
81
+ return s;
82
+ };
83
+ Stream.prototype.parseStringUTF = function (start, end) {
84
+ function ex(c) { // must be 10xxxxxx
85
+ if ((c < 0x80) || (c >= 0xC0))
86
+ throw new Error('Invalid UTF-8 continuation byte: ' + c);
87
+ return (c & 0x3F);
88
+ }
89
+ function surrogate(cp) {
90
+ if (cp < 0x10000)
91
+ throw new Error('UTF-8 overlong encoding, codepoint encoded in 4 bytes: ' + cp);
92
+ // we could use String.fromCodePoint(cp) but let's be nice to older browsers and use surrogate pairs
93
+ cp -= 0x10000;
94
+ return String.fromCharCode((cp >> 10) + 0xD800, (cp & 0x3FF) + 0xDC00);
95
+ }
96
+ var s = "";
97
+ for (var i = start; i < end; ) {
98
+ var c = this.get(i++);
99
+ if (c < 0x80) // 0xxxxxxx (7 bit)
100
+ s += String.fromCharCode(c);
101
+ else if (c < 0xC0)
102
+ throw new Error('Invalid UTF-8 starting byte: ' + c);
103
+ else if (c < 0xE0) // 110xxxxx 10xxxxxx (11 bit)
104
+ s += String.fromCharCode(((c & 0x1F) << 6) | ex(this.get(i++)));
105
+ else if (c < 0xF0) // 1110xxxx 10xxxxxx 10xxxxxx (16 bit)
106
+ s += String.fromCharCode(((c & 0x0F) << 12) | (ex(this.get(i++)) << 6) | ex(this.get(i++)));
107
+ else if (c < 0xF8) // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (21 bit)
108
+ s += surrogate(((c & 0x07) << 18) | (ex(this.get(i++)) << 12) | (ex(this.get(i++)) << 6) | ex(this.get(i++)));
109
+ else
110
+ throw new Error('Invalid UTF-8 starting byte (since 2003 it is restricted to 4 bytes): ' + c);
111
+ }
112
+ return s;
113
+ };
114
+ Stream.prototype.parseStringBMP = function (start, end) {
115
+ var str = "", hi, lo;
116
+ for (var i = start; i < end; ) {
117
+ hi = this.get(i++);
118
+ lo = this.get(i++);
119
+ str += String.fromCharCode((hi << 8) | lo);
120
+ }
121
+ return str;
122
+ };
123
+ Stream.prototype.parseTime = function (start, end, shortYear) {
124
+ var s = this.parseStringISO(start, end),
125
+ m = (shortYear ? reTimeS : reTimeL).exec(s);
126
+ if (!m)
127
+ return "Unrecognized time: " + s;
128
+ if (shortYear) {
129
+ // to avoid querying the timer, use the fixed range [1970, 2069]
130
+ // it will conform with ITU X.400 [-10, +40] sliding window until 2030
131
+ m[1] = +m[1];
132
+ m[1] += (m[1] < 70) ? 2000 : 1900;
133
+ }
134
+ s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
135
+ if (m[5]) {
136
+ s += ":" + m[5];
137
+ if (m[6]) {
138
+ s += ":" + m[6];
139
+ if (m[7])
140
+ s += "." + m[7];
141
+ }
142
+ }
143
+ if (m[8]) {
144
+ s += " UTC";
145
+ if (m[8] != 'Z') {
146
+ s += m[8];
147
+ if (m[9])
148
+ s += ":" + m[9];
149
+ }
150
+ }
151
+ return s;
152
+ };
153
+ Stream.prototype.parseInteger = function (start, end) {
154
+ var v = this.get(start),
155
+ neg = (v > 127),
156
+ pad = neg ? 255 : 0,
157
+ len,
158
+ s = '';
159
+ // skip unuseful bits (not allowed in DER)
160
+ while (v == pad && ++start < end)
161
+ v = this.get(start);
162
+ len = end - start;
163
+ if (len === 0)
164
+ return neg ? '-1' : '0';
165
+ // show bit length of huge integers
166
+ if (len > 4) {
167
+ s = v;
168
+ len <<= 3;
169
+ while (((s ^ pad) & 0x80) == 0) {
170
+ s <<= 1;
171
+ --len;
172
+ }
173
+ s = "(" + len + " bit)\n";
174
+ }
175
+ // decode the integer
176
+ if (neg) v = v - 256;
177
+ var n = new Int10(v);
178
+ for (var i = start + 1; i < end; ++i)
179
+ n.mulAdd(256, this.get(i));
180
+ return s + n.toString();
181
+ };
182
+ Stream.prototype.parseBitString = function (start, end, maxLength) {
183
+ var unusedBits = this.get(start);
184
+ if (unusedBits > 7)
185
+ throw 'Invalid BitString with unusedBits=' + unusedBits;
186
+ var lenBit = ((end - start - 1) << 3) - unusedBits,
187
+ s = "";
188
+ for (var i = start + 1; i < end; ++i) {
189
+ var b = this.get(i),
190
+ skip = (i == end - 1) ? unusedBits : 0;
191
+ for (var j = 7; j >= skip; --j)
192
+ s += (b >> j) & 1 ? "1" : "0";
193
+ if (s.length > maxLength)
194
+ s = stringCut(s, maxLength);
195
+ }
196
+ return { size: lenBit, str: s };
197
+ };
198
+ Stream.prototype.parseOctetString = function (start, end, maxLength) {
199
+ var len = end - start,
200
+ s;
201
+ try {
202
+ s = this.parseStringUTF(start, end);
203
+ var v;
204
+ for (i = 0; i < s.length; ++i) {
205
+ v = s.charCodeAt(i);
206
+ if (v < 32 && v != 9 && v != 10 && v != 13) // [\t\r\n] are (kinda) printable
207
+ throw new Error('Unprintable character at index ' + i + ' (code ' + s.charCodeAt(i) + ")");
208
+ }
209
+ return { size: len, str: s };
210
+ } catch (e) {
211
+ // ignore
212
+ }
213
+ maxLength /= 2; // we work in bytes
214
+ if (len > maxLength)
215
+ end = start + maxLength;
216
+ s = '';
217
+ for (var i = start; i < end; ++i)
218
+ s += this.hexByte(this.get(i));
219
+ if (len > maxLength)
220
+ s += ellipsis;
221
+ return { size: len, str: s };
222
+ };
223
+ Stream.prototype.parseOID = function (start, end, maxLength) {
224
+ var s = '',
225
+ n = new Int10(),
226
+ bits = 0;
227
+ for (var i = start; i < end; ++i) {
228
+ var v = this.get(i);
229
+ n.mulAdd(128, v & 0x7F);
230
+ bits += 7;
231
+ if (!(v & 0x80)) { // finished
232
+ if (s === '') {
233
+ n = n.simplify();
234
+ if (n instanceof Int10) {
235
+ n.sub(80);
236
+ s = "2." + n.toString();
237
+ } else {
238
+ var m = n < 80 ? n < 40 ? 0 : 1 : 2;
239
+ s = m + "." + (n - m * 40);
240
+ }
241
+ } else
242
+ s += "." + n.toString();
243
+ if (s.length > maxLength)
244
+ return stringCut(s, maxLength);
245
+ n = new Int10();
246
+ bits = 0;
247
+ }
248
+ }
249
+ if (bits > 0)
250
+ s += ".incomplete";
251
+ if (typeof oids === 'object') {
252
+ var oid = oids[s];
253
+ if (oid) {
254
+ if (oid.d) s += "\n" + oid.d;
255
+ if (oid.c) s += "\n" + oid.c;
256
+ if (oid.w) s += "\n(warning!)";
257
+ }
258
+ }
259
+ return s;
260
+ };
261
+
262
+ function ASN1(stream, header, length, tag, tagLen, sub) {
263
+ if (!(tag instanceof ASN1Tag)) throw 'Invalid tag value.';
264
+ this.stream = stream;
265
+ this.header = header;
266
+ this.length = length;
267
+ this.tag = tag;
268
+ this.tagLen = tagLen;
269
+ this.sub = sub;
270
+ }
271
+ ASN1.prototype.typeName = function () {
272
+ switch (this.tag.tagClass) {
273
+ case 0: // universal
274
+ switch (this.tag.tagNumber) {
275
+ case 0x00: return "EOC";
276
+ case 0x01: return "BOOLEAN";
277
+ case 0x02: return "INTEGER";
278
+ case 0x03: return "BIT_STRING";
279
+ case 0x04: return "OCTET_STRING";
280
+ case 0x05: return "NULL";
281
+ case 0x06: return "OBJECT_IDENTIFIER";
282
+ case 0x07: return "ObjectDescriptor";
283
+ case 0x08: return "EXTERNAL";
284
+ case 0x09: return "REAL";
285
+ case 0x0A: return "ENUMERATED";
286
+ case 0x0B: return "EMBEDDED_PDV";
287
+ case 0x0C: return "UTF8String";
288
+ case 0x10: return "SEQUENCE";
289
+ case 0x11: return "SET";
290
+ case 0x12: return "NumericString";
291
+ case 0x13: return "PrintableString"; // ASCII subset
292
+ case 0x14: return "TeletexString"; // aka T61String
293
+ case 0x15: return "VideotexString";
294
+ case 0x16: return "IA5String"; // ASCII
295
+ case 0x17: return "UTCTime";
296
+ case 0x18: return "GeneralizedTime";
297
+ case 0x19: return "GraphicString";
298
+ case 0x1A: return "VisibleString"; // ASCII subset
299
+ case 0x1B: return "GeneralString";
300
+ case 0x1C: return "UniversalString";
301
+ case 0x1E: return "BMPString";
302
+ }
303
+ return "Universal_" + this.tag.tagNumber.toString();
304
+ case 1: return "Application_" + this.tag.tagNumber.toString();
305
+ case 2: return "[" + this.tag.tagNumber.toString() + "]"; // Context
306
+ case 3: return "Private_" + this.tag.tagNumber.toString();
307
+ }
308
+ };
309
+ function recurse(el, parser, maxLength) {
310
+ var differentTags = false;
311
+ if (el.sub) el.sub.forEach(function (e1) {
312
+ if (e1.tag.tagClass != el.tag.tagClass || e1.tag.tagNumber != el.tag.tagNumber)
313
+ differentTags = true;
314
+ });
315
+ if (!el.sub || differentTags)
316
+ return el.stream[parser](el.posContent(), el.posContent() + Math.abs(el.length), maxLength);
317
+ var d = { size: 0, str: '' };
318
+ el.sub.forEach(function (el) {
319
+ var d1 = recurse(el, parser, maxLength - d.str.length);
320
+ d.size += d1.size;
321
+ d.str += d1.str;
322
+ });
323
+ return d;
324
+ }
325
+ /** A string preview of the content (intended for humans). */
326
+ ASN1.prototype.content = function (maxLength) {
327
+ if (this.tag === undefined)
328
+ return null;
329
+ if (maxLength === undefined)
330
+ maxLength = Infinity;
331
+ var content = this.posContent(),
332
+ len = Math.abs(this.length);
333
+ if (!this.tag.isUniversal()) {
334
+ if (this.sub !== null)
335
+ return "(" + this.sub.length + " elem)";
336
+ var d1 = this.stream.parseOctetString(content, content + len, maxLength);
337
+ return "(" + d1.size + " byte)\n" + d1.str;
338
+ }
339
+ switch (this.tag.tagNumber) {
340
+ case 0x01: // BOOLEAN
341
+ return (this.stream.get(content) === 0) ? "false" : "true";
342
+ case 0x02: // INTEGER
343
+ return this.stream.parseInteger(content, content + len);
344
+ case 0x03: // BIT_STRING
345
+ var d = recurse(this, 'parseBitString', maxLength);
346
+ return "(" + d.size + " bit)\n" + d.str;
347
+ case 0x04: // OCTET_STRING
348
+ d = recurse(this, 'parseOctetString', maxLength);
349
+ return "(" + d.size + " byte)\n" + d.str;
350
+ //case 0x05: // NULL
351
+ case 0x06: // OBJECT_IDENTIFIER
352
+ return this.stream.parseOID(content, content + len, maxLength);
353
+ //case 0x07: // ObjectDescriptor
354
+ //case 0x08: // EXTERNAL
355
+ //case 0x09: // REAL
356
+ case 0x0A: // ENUMERATED
357
+ return this.stream.parseInteger(content, content + len);
358
+ //case 0x0B: // EMBEDDED_PDV
359
+ case 0x10: // SEQUENCE
360
+ case 0x11: // SET
361
+ if (this.sub !== null)
362
+ return "(" + this.sub.length + " elem)";
363
+ else
364
+ return "(no elem)";
365
+ case 0x0C: // UTF8String
366
+ return stringCut(this.stream.parseStringUTF(content, content + len), maxLength);
367
+ case 0x12: // NumericString
368
+ case 0x13: // PrintableString
369
+ case 0x14: // TeletexString
370
+ case 0x15: // VideotexString
371
+ case 0x16: // IA5String
372
+ case 0x1A: // VisibleString
373
+ case 0x1B: // GeneralString
374
+ //case 0x19: // GraphicString
375
+ //case 0x1C: // UniversalString
376
+ return stringCut(this.stream.parseStringISO(content, content + len), maxLength);
377
+ case 0x1E: // BMPString
378
+ return stringCut(this.stream.parseStringBMP(content, content + len), maxLength);
379
+ case 0x17: // UTCTime
380
+ case 0x18: // GeneralizedTime
381
+ return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
382
+ }
383
+ return null;
384
+ };
385
+ ASN1.prototype.toString = function () {
386
+ return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? 'null' : this.sub.length) + "]";
387
+ };
388
+ ASN1.prototype.toPrettyString = function (indent) {
389
+ if (indent === undefined) indent = '';
390
+ var s = indent + this.typeName() + " @" + this.stream.pos;
391
+ if (this.length >= 0)
392
+ s += "+";
393
+ s += this.length;
394
+ if (this.tag.tagConstructed)
395
+ s += " (constructed)";
396
+ else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null))
397
+ s += " (encapsulates)";
398
+ var content = this.content();
399
+ if (content)
400
+ s += ": " + content.replace(/\n/g, '|');
401
+ s += "\n";
402
+ if (this.sub !== null) {
403
+ indent += ' ';
404
+ for (var i = 0, max = this.sub.length; i < max; ++i)
405
+ s += this.sub[i].toPrettyString(indent);
406
+ }
407
+ return s;
408
+ };
409
+ ASN1.prototype.posStart = function () {
410
+ return this.stream.pos;
411
+ };
412
+ ASN1.prototype.posContent = function () {
413
+ return this.stream.pos + this.header;
414
+ };
415
+ ASN1.prototype.posEnd = function () {
416
+ return this.stream.pos + this.header + Math.abs(this.length);
417
+ };
418
+ /** Position of the length. */
419
+ ASN1.prototype.posLen = function() {
420
+ return this.stream.pos + this.tagLen;
421
+ };
422
+ ASN1.prototype.toHexString = function () {
423
+ return this.stream.hexDump(this.posStart(), this.posEnd(), true);
424
+ };
425
+ ASN1.prototype.toB64String = function () {
426
+ return this.stream.b64Dump(this.posStart(), this.posEnd());
427
+ };
428
+ ASN1.decodeLength = function (stream) {
429
+ var buf = stream.get(),
430
+ len = buf & 0x7F;
431
+ if (len == buf) // first bit was 0, short form
432
+ return len;
433
+ if (len === 0) // long form with length 0 is a special case
434
+ return null; // undefined length
435
+ if (len > 6) // no reason to use Int10, as it would be a huge buffer anyways
436
+ throw "Length over 48 bits not supported at position " + (stream.pos - 1);
437
+ buf = 0;
438
+ for (var i = 0; i < len; ++i)
439
+ buf = (buf * 256) + stream.get();
440
+ return buf;
441
+ };
442
+ function ASN1Tag(stream) {
443
+ var buf = stream.get();
444
+ this.tagClass = buf >> 6;
445
+ this.tagConstructed = ((buf & 0x20) !== 0);
446
+ this.tagNumber = buf & 0x1F;
447
+ if (this.tagNumber == 0x1F) { // long tag
448
+ var n = new Int10();
449
+ do {
450
+ buf = stream.get();
451
+ n.mulAdd(128, buf & 0x7F);
452
+ } while (buf & 0x80);
453
+ this.tagNumber = n.simplify();
454
+ }
455
+ }
456
+ ASN1Tag.prototype.isUniversal = function () {
457
+ return this.tagClass === 0x00;
458
+ };
459
+ ASN1Tag.prototype.isEOC = function () {
460
+ return this.tagClass === 0x00 && this.tagNumber === 0x00;
461
+ };
462
+ ASN1.decode = function (stream, offset) {
463
+ if (!(stream instanceof Stream))
464
+ stream = new Stream(stream, offset || 0);
465
+ var streamStart = new Stream(stream),
466
+ tag = new ASN1Tag(stream),
467
+ tagLen = stream.pos - streamStart.pos,
468
+ len = ASN1.decodeLength(stream),
469
+ start = stream.pos,
470
+ header = start - streamStart.pos,
471
+ sub = null,
472
+ getSub = function () {
473
+ sub = [];
474
+ if (len !== null) {
475
+ // definite length
476
+ var end = start + len;
477
+ if (end > stream.enc.length)
478
+ throw 'Container at offset ' + start + ' has a length of ' + len + ', which is past the end of the stream';
479
+ while (stream.pos < end)
480
+ sub[sub.length] = ASN1.decode(stream);
481
+ if (stream.pos != end)
482
+ throw 'Content size is not correct for container at offset ' + start;
483
+ } else {
484
+ // undefined length
485
+ try {
486
+ for (;;) {
487
+ var s = ASN1.decode(stream);
488
+ if (s.tag.isEOC())
489
+ break;
490
+ sub[sub.length] = s;
491
+ }
492
+ len = start - stream.pos; // undefined lengths are represented as negative values
493
+ } catch (e) {
494
+ throw 'Exception while decoding undefined length content at offset ' + start + ': ' + e;
495
+ }
496
+ }
497
+ };
498
+ if (tag.tagConstructed) {
499
+ // must have valid content
500
+ getSub();
501
+ } else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
502
+ // sometimes BitString and OctetString are used to encapsulate ASN.1
503
+ try {
504
+ if (tag.tagNumber == 0x03)
505
+ if (stream.get() != 0)
506
+ throw "BIT STRINGs with unused bits cannot encapsulate.";
507
+ getSub();
508
+ for (var i = 0; i < sub.length; ++i)
509
+ if (sub[i].tag.isEOC())
510
+ throw 'EOC is not supposed to be actual content.';
511
+ } catch (e) {
512
+ // but silently ignore when they don't
513
+ sub = null;
514
+ //DEBUG console.log('Could not decode structure at ' + start + ':', e);
515
+ }
516
+ }
517
+ if (sub === null) {
518
+ if (len === null)
519
+ throw "We can't skip over an invalid tag with undefined length at offset " + start;
520
+ stream.pos = start + Math.abs(len);
521
+ }
522
+ return new ASN1(streamStart, header, len, tag, tagLen, sub);
523
+ };
524
+
525
+ export default ASN1;
@@ -0,0 +1,82 @@
1
+ var Base64 = {},
2
+ decoder, // populated on first usage
3
+ haveU8 = (typeof Uint8Array == 'function');
4
+
5
+ Base64.decode = function (a) {
6
+ var isString = (typeof a == 'string');
7
+ var i;
8
+ if (decoder === undefined) {
9
+ var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
10
+ ignore = "= \f\n\r\t\u00A0\u2028\u2029";
11
+ decoder = [];
12
+ for (i = 0; i < 64; ++i)
13
+ decoder[b64.charCodeAt(i)] = i;
14
+ for (i = 0; i < ignore.length; ++i)
15
+ decoder[ignore.charCodeAt(i)] = -1;
16
+ // RFC 3548 URL & file safe encoding
17
+ decoder['-'.charCodeAt(0)] = decoder['+'.charCodeAt(0)];
18
+ decoder['_'.charCodeAt(0)] = decoder['/'.charCodeAt(0)];
19
+ }
20
+ var out = haveU8 ? new Uint8Array(a.length * 3 >> 2) : [];
21
+ var bits = 0, char_count = 0, len = 0;
22
+ for (i = 0; i < a.length; ++i) {
23
+ var c = isString ? a.charCodeAt(i) : a[i];
24
+ if (c == 61) // '='.charCodeAt(0)
25
+ break;
26
+ c = decoder[c];
27
+ if (c == -1)
28
+ continue;
29
+ if (c === undefined)
30
+ throw 'Illegal character at offset ' + i;
31
+ bits |= c;
32
+ if (++char_count >= 4) {
33
+ out[len++] = (bits >> 16);
34
+ out[len++] = (bits >> 8) & 0xFF;
35
+ out[len++] = bits & 0xFF;
36
+ bits = 0;
37
+ char_count = 0;
38
+ } else {
39
+ bits <<= 6;
40
+ }
41
+ }
42
+ switch (char_count) {
43
+ case 1:
44
+ throw "Base64 encoding incomplete: at least 2 bits missing";
45
+ case 2:
46
+ out[len++] = (bits >> 10);
47
+ break;
48
+ case 3:
49
+ out[len++] = (bits >> 16);
50
+ out[len++] = (bits >> 8) & 0xFF;
51
+ break;
52
+ }
53
+ if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters
54
+ out = out.subarray(0, len);
55
+ return out;
56
+ };
57
+
58
+ Base64.pretty = function (str) {
59
+ // fix padding
60
+ if (str.length % 4 > 0)
61
+ str = (str + '===').slice(0, str.length + str.length % 4);
62
+ // convert RFC 3548 to standard Base64
63
+ str = str.replace(/-/g, '+').replace(/_/g, '/');
64
+ // 80 column width
65
+ return str.replace(/(.{80})/g, '$1\n');
66
+ };
67
+
68
+ Base64.re = /-----BEGIN [^-]+-----([A-Za-z0-9+/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+/=\s]+)====/;
69
+ Base64.unarmor = function (a) {
70
+ var m = Base64.re.exec(a);
71
+ if (m) {
72
+ if (m[1])
73
+ a = m[1];
74
+ else if (m[2])
75
+ a = m[2];
76
+ else
77
+ throw "RegExp out of sync";
78
+ }
79
+ return Base64.decode(a);
80
+ };
81
+
82
+ export default Base64;
@@ -0,0 +1,51 @@
1
+ var Hex = {},
2
+ decoder, // populated on first usage
3
+ haveU8 = (typeof Uint8Array == 'function');
4
+
5
+ /**
6
+ * Decodes an hexadecimal value.
7
+ * @param {string|Array|Uint8Array} a - a string representing hexadecimal data, or an array representation of its charcodes
8
+ */
9
+ Hex.decode = function(a) {
10
+ var isString = (typeof a == 'string');
11
+ var i;
12
+ if (decoder === undefined) {
13
+ var hex = "0123456789ABCDEF",
14
+ ignore = " \f\n\r\t\u00A0\u2028\u2029";
15
+ decoder = [];
16
+ for (i = 0; i < 16; ++i)
17
+ decoder[hex.charCodeAt(i)] = i;
18
+ hex = hex.toLowerCase();
19
+ for (i = 10; i < 16; ++i)
20
+ decoder[hex.charCodeAt(i)] = i;
21
+ for (i = 0; i < ignore.length; ++i)
22
+ decoder[ignore.charCodeAt(i)] = -1;
23
+ }
24
+ var out = haveU8 ? new Uint8Array(a.length >> 1) : [],
25
+ bits = 0,
26
+ char_count = 0,
27
+ len = 0;
28
+ for (i = 0; i < a.length; ++i) {
29
+ var c = isString ? a.charCodeAt(i) : a[i];
30
+ c = decoder[c];
31
+ if (c == -1)
32
+ continue;
33
+ if (c === undefined)
34
+ throw 'Illegal character at offset ' + i;
35
+ bits |= c;
36
+ if (++char_count >= 2) {
37
+ out[len++] = bits;
38
+ bits = 0;
39
+ char_count = 0;
40
+ } else {
41
+ bits <<= 4;
42
+ }
43
+ }
44
+ if (char_count)
45
+ throw "Hex encoding incomplete: 4 bits missing";
46
+ if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters
47
+ out = out.subarray(0, len);
48
+ return out;
49
+ };
50
+
51
+ export default Hex;