@firebase/util 1.10.1 → 1.10.2

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.
Files changed (79) hide show
  1. package/dist/index.cjs.js +2086 -2086
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.d.ts +39 -39
  4. package/dist/index.esm2017.js +2086 -2086
  5. package/dist/index.esm2017.js.map +1 -1
  6. package/dist/index.node.cjs.js +2103 -2103
  7. package/dist/index.node.cjs.js.map +1 -1
  8. package/dist/index.node.d.ts +39 -39
  9. package/dist/node-esm/index.d.ts +39 -39
  10. package/dist/node-esm/index.node.d.ts +39 -39
  11. package/dist/node-esm/index.node.esm.js +2103 -2103
  12. package/dist/node-esm/index.node.esm.js.map +1 -1
  13. package/dist/node-esm/src/assert.d.ts +24 -24
  14. package/dist/node-esm/src/compat.d.ts +20 -20
  15. package/dist/node-esm/src/constants.d.ts +33 -33
  16. package/dist/node-esm/src/crypt.d.ts +66 -66
  17. package/dist/node-esm/src/deepCopy.d.ts +35 -35
  18. package/dist/node-esm/src/defaults.d.ts +79 -79
  19. package/dist/node-esm/src/deferred.d.ts +28 -28
  20. package/dist/node-esm/src/emulator.d.ts +47 -47
  21. package/dist/node-esm/src/environment.d.ts +90 -90
  22. package/dist/node-esm/src/errors.d.ts +87 -87
  23. package/dist/node-esm/src/exponential_backoff.d.ts +37 -37
  24. package/dist/node-esm/src/formatters.d.ts +20 -20
  25. package/dist/node-esm/src/global.d.ts +22 -22
  26. package/dist/node-esm/src/json.d.ts +29 -29
  27. package/dist/node-esm/src/jwt.d.ts +73 -73
  28. package/dist/node-esm/src/obj.d.ts +30 -30
  29. package/dist/node-esm/src/promise.d.ts +21 -21
  30. package/dist/node-esm/src/query.d.ts +33 -33
  31. package/dist/node-esm/src/sha1.d.ts +84 -84
  32. package/dist/node-esm/src/subscribe.d.ts +49 -49
  33. package/dist/node-esm/src/utf8.d.ts +27 -27
  34. package/dist/node-esm/src/uuid.d.ts +22 -22
  35. package/dist/node-esm/src/validation.d.ts +43 -43
  36. package/dist/node-esm/test/base64.test.d.ts +1 -1
  37. package/dist/node-esm/test/compat.test.d.ts +17 -17
  38. package/dist/node-esm/test/deepCopy.test.d.ts +1 -1
  39. package/dist/node-esm/test/defaults.test.d.ts +1 -1
  40. package/dist/node-esm/test/emulator.test.d.ts +1 -1
  41. package/dist/node-esm/test/environments.test.d.ts +17 -17
  42. package/dist/node-esm/test/errors.test.d.ts +1 -1
  43. package/dist/node-esm/test/exponential_backoff.test.d.ts +17 -17
  44. package/dist/node-esm/test/object.test.d.ts +17 -17
  45. package/dist/node-esm/test/subscribe.test.d.ts +17 -17
  46. package/dist/src/assert.d.ts +24 -24
  47. package/dist/src/compat.d.ts +20 -20
  48. package/dist/src/constants.d.ts +33 -33
  49. package/dist/src/crypt.d.ts +66 -66
  50. package/dist/src/deepCopy.d.ts +35 -35
  51. package/dist/src/defaults.d.ts +79 -79
  52. package/dist/src/deferred.d.ts +28 -28
  53. package/dist/src/emulator.d.ts +47 -47
  54. package/dist/src/environment.d.ts +90 -90
  55. package/dist/src/errors.d.ts +87 -87
  56. package/dist/src/exponential_backoff.d.ts +37 -37
  57. package/dist/src/formatters.d.ts +20 -20
  58. package/dist/src/global.d.ts +22 -22
  59. package/dist/src/json.d.ts +29 -29
  60. package/dist/src/jwt.d.ts +73 -73
  61. package/dist/src/obj.d.ts +30 -30
  62. package/dist/src/promise.d.ts +21 -21
  63. package/dist/src/query.d.ts +33 -33
  64. package/dist/src/sha1.d.ts +84 -84
  65. package/dist/src/subscribe.d.ts +49 -49
  66. package/dist/src/utf8.d.ts +27 -27
  67. package/dist/src/uuid.d.ts +22 -22
  68. package/dist/src/validation.d.ts +43 -43
  69. package/dist/test/base64.test.d.ts +1 -1
  70. package/dist/test/compat.test.d.ts +17 -17
  71. package/dist/test/deepCopy.test.d.ts +1 -1
  72. package/dist/test/defaults.test.d.ts +1 -1
  73. package/dist/test/emulator.test.d.ts +1 -1
  74. package/dist/test/environments.test.d.ts +17 -17
  75. package/dist/test/errors.test.d.ts +1 -1
  76. package/dist/test/exponential_backoff.test.d.ts +17 -17
  77. package/dist/test/object.test.d.ts +17 -17
  78. package/dist/test/subscribe.test.d.ts +17 -17
  79. package/package.json +2 -2
@@ -1,2152 +1,2152 @@
1
- /**
2
- * @license
3
- * Copyright 2017 Google LLC
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- /**
18
- * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.
19
- */
20
- const CONSTANTS = {
21
- /**
22
- * @define {boolean} Whether this is the client Node.js SDK.
23
- */
24
- NODE_CLIENT: false,
25
- /**
26
- * @define {boolean} Whether this is the Admin Node.js SDK.
27
- */
28
- NODE_ADMIN: false,
29
- /**
30
- * Firebase SDK Version
31
- */
32
- SDK_VERSION: '${JSCORE_VERSION}'
1
+ /**
2
+ * @license
3
+ * Copyright 2017 Google LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.
19
+ */
20
+ const CONSTANTS = {
21
+ /**
22
+ * @define {boolean} Whether this is the client Node.js SDK.
23
+ */
24
+ NODE_CLIENT: false,
25
+ /**
26
+ * @define {boolean} Whether this is the Admin Node.js SDK.
27
+ */
28
+ NODE_ADMIN: false,
29
+ /**
30
+ * Firebase SDK Version
31
+ */
32
+ SDK_VERSION: '${JSCORE_VERSION}'
33
33
  };
34
34
 
35
- /**
36
- * @license
37
- * Copyright 2017 Google LLC
38
- *
39
- * Licensed under the Apache License, Version 2.0 (the "License");
40
- * you may not use this file except in compliance with the License.
41
- * You may obtain a copy of the License at
42
- *
43
- * http://www.apache.org/licenses/LICENSE-2.0
44
- *
45
- * Unless required by applicable law or agreed to in writing, software
46
- * distributed under the License is distributed on an "AS IS" BASIS,
47
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48
- * See the License for the specific language governing permissions and
49
- * limitations under the License.
50
- */
51
- /**
52
- * Throws an error if the provided assertion is falsy
53
- */
54
- const assert = function (assertion, message) {
55
- if (!assertion) {
56
- throw assertionError(message);
57
- }
58
- };
59
- /**
60
- * Returns an Error object suitable for throwing.
61
- */
62
- const assertionError = function (message) {
63
- return new Error('Firebase Database (' +
64
- CONSTANTS.SDK_VERSION +
65
- ') INTERNAL ASSERT FAILED: ' +
66
- message);
35
+ /**
36
+ * @license
37
+ * Copyright 2017 Google LLC
38
+ *
39
+ * Licensed under the Apache License, Version 2.0 (the "License");
40
+ * you may not use this file except in compliance with the License.
41
+ * You may obtain a copy of the License at
42
+ *
43
+ * http://www.apache.org/licenses/LICENSE-2.0
44
+ *
45
+ * Unless required by applicable law or agreed to in writing, software
46
+ * distributed under the License is distributed on an "AS IS" BASIS,
47
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48
+ * See the License for the specific language governing permissions and
49
+ * limitations under the License.
50
+ */
51
+ /**
52
+ * Throws an error if the provided assertion is falsy
53
+ */
54
+ const assert = function (assertion, message) {
55
+ if (!assertion) {
56
+ throw assertionError(message);
57
+ }
58
+ };
59
+ /**
60
+ * Returns an Error object suitable for throwing.
61
+ */
62
+ const assertionError = function (message) {
63
+ return new Error('Firebase Database (' +
64
+ CONSTANTS.SDK_VERSION +
65
+ ') INTERNAL ASSERT FAILED: ' +
66
+ message);
67
67
  };
68
68
 
69
- /**
70
- * @license
71
- * Copyright 2017 Google LLC
72
- *
73
- * Licensed under the Apache License, Version 2.0 (the "License");
74
- * you may not use this file except in compliance with the License.
75
- * You may obtain a copy of the License at
76
- *
77
- * http://www.apache.org/licenses/LICENSE-2.0
78
- *
79
- * Unless required by applicable law or agreed to in writing, software
80
- * distributed under the License is distributed on an "AS IS" BASIS,
81
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82
- * See the License for the specific language governing permissions and
83
- * limitations under the License.
84
- */
85
- const stringToByteArray$1 = function (str) {
86
- // TODO(user): Use native implementations if/when available
87
- const out = [];
88
- let p = 0;
89
- for (let i = 0; i < str.length; i++) {
90
- let c = str.charCodeAt(i);
91
- if (c < 128) {
92
- out[p++] = c;
93
- }
94
- else if (c < 2048) {
95
- out[p++] = (c >> 6) | 192;
96
- out[p++] = (c & 63) | 128;
97
- }
98
- else if ((c & 0xfc00) === 0xd800 &&
99
- i + 1 < str.length &&
100
- (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00) {
101
- // Surrogate Pair
102
- c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
103
- out[p++] = (c >> 18) | 240;
104
- out[p++] = ((c >> 12) & 63) | 128;
105
- out[p++] = ((c >> 6) & 63) | 128;
106
- out[p++] = (c & 63) | 128;
107
- }
108
- else {
109
- out[p++] = (c >> 12) | 224;
110
- out[p++] = ((c >> 6) & 63) | 128;
111
- out[p++] = (c & 63) | 128;
112
- }
113
- }
114
- return out;
115
- };
116
- /**
117
- * Turns an array of numbers into the string given by the concatenation of the
118
- * characters to which the numbers correspond.
119
- * @param bytes Array of numbers representing characters.
120
- * @return Stringification of the array.
121
- */
122
- const byteArrayToString = function (bytes) {
123
- // TODO(user): Use native implementations if/when available
124
- const out = [];
125
- let pos = 0, c = 0;
126
- while (pos < bytes.length) {
127
- const c1 = bytes[pos++];
128
- if (c1 < 128) {
129
- out[c++] = String.fromCharCode(c1);
130
- }
131
- else if (c1 > 191 && c1 < 224) {
132
- const c2 = bytes[pos++];
133
- out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
134
- }
135
- else if (c1 > 239 && c1 < 365) {
136
- // Surrogate Pair
137
- const c2 = bytes[pos++];
138
- const c3 = bytes[pos++];
139
- const c4 = bytes[pos++];
140
- const u = (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
141
- 0x10000;
142
- out[c++] = String.fromCharCode(0xd800 + (u >> 10));
143
- out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
144
- }
145
- else {
146
- const c2 = bytes[pos++];
147
- const c3 = bytes[pos++];
148
- out[c++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
149
- }
150
- }
151
- return out.join('');
152
- };
153
- // We define it as an object literal instead of a class because a class compiled down to es5 can't
154
- // be treeshaked. https://github.com/rollup/rollup/issues/1691
155
- // Static lookup maps, lazily populated by init_()
156
- // TODO(dlarocque): Define this as a class, since we no longer target ES5.
157
- const base64 = {
158
- /**
159
- * Maps bytes to characters.
160
- */
161
- byteToCharMap_: null,
162
- /**
163
- * Maps characters to bytes.
164
- */
165
- charToByteMap_: null,
166
- /**
167
- * Maps bytes to websafe characters.
168
- * @private
169
- */
170
- byteToCharMapWebSafe_: null,
171
- /**
172
- * Maps websafe characters to bytes.
173
- * @private
174
- */
175
- charToByteMapWebSafe_: null,
176
- /**
177
- * Our default alphabet, shared between
178
- * ENCODED_VALS and ENCODED_VALS_WEBSAFE
179
- */
180
- ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',
181
- /**
182
- * Our default alphabet. Value 64 (=) is special; it means "nothing."
183
- */
184
- get ENCODED_VALS() {
185
- return this.ENCODED_VALS_BASE + '+/=';
186
- },
187
- /**
188
- * Our websafe alphabet.
189
- */
190
- get ENCODED_VALS_WEBSAFE() {
191
- return this.ENCODED_VALS_BASE + '-_.';
192
- },
193
- /**
194
- * Whether this browser supports the atob and btoa functions. This extension
195
- * started at Mozilla but is now implemented by many browsers. We use the
196
- * ASSUME_* variables to avoid pulling in the full useragent detection library
197
- * but still allowing the standard per-browser compilations.
198
- *
199
- */
200
- HAS_NATIVE_SUPPORT: typeof atob === 'function',
201
- /**
202
- * Base64-encode an array of bytes.
203
- *
204
- * @param input An array of bytes (numbers with
205
- * value in [0, 255]) to encode.
206
- * @param webSafe Boolean indicating we should use the
207
- * alternative alphabet.
208
- * @return The base64 encoded string.
209
- */
210
- encodeByteArray(input, webSafe) {
211
- if (!Array.isArray(input)) {
212
- throw Error('encodeByteArray takes an array as a parameter');
213
- }
214
- this.init_();
215
- const byteToCharMap = webSafe
216
- ? this.byteToCharMapWebSafe_
217
- : this.byteToCharMap_;
218
- const output = [];
219
- for (let i = 0; i < input.length; i += 3) {
220
- const byte1 = input[i];
221
- const haveByte2 = i + 1 < input.length;
222
- const byte2 = haveByte2 ? input[i + 1] : 0;
223
- const haveByte3 = i + 2 < input.length;
224
- const byte3 = haveByte3 ? input[i + 2] : 0;
225
- const outByte1 = byte1 >> 2;
226
- const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
227
- let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);
228
- let outByte4 = byte3 & 0x3f;
229
- if (!haveByte3) {
230
- outByte4 = 64;
231
- if (!haveByte2) {
232
- outByte3 = 64;
233
- }
234
- }
235
- output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);
236
- }
237
- return output.join('');
238
- },
239
- /**
240
- * Base64-encode a string.
241
- *
242
- * @param input A string to encode.
243
- * @param webSafe If true, we should use the
244
- * alternative alphabet.
245
- * @return The base64 encoded string.
246
- */
247
- encodeString(input, webSafe) {
248
- // Shortcut for Mozilla browsers that implement
249
- // a native base64 encoder in the form of "btoa/atob"
250
- if (this.HAS_NATIVE_SUPPORT && !webSafe) {
251
- return btoa(input);
252
- }
253
- return this.encodeByteArray(stringToByteArray$1(input), webSafe);
254
- },
255
- /**
256
- * Base64-decode a string.
257
- *
258
- * @param input to decode.
259
- * @param webSafe True if we should use the
260
- * alternative alphabet.
261
- * @return string representing the decoded value.
262
- */
263
- decodeString(input, webSafe) {
264
- // Shortcut for Mozilla browsers that implement
265
- // a native base64 encoder in the form of "btoa/atob"
266
- if (this.HAS_NATIVE_SUPPORT && !webSafe) {
267
- return atob(input);
268
- }
269
- return byteArrayToString(this.decodeStringToByteArray(input, webSafe));
270
- },
271
- /**
272
- * Base64-decode a string.
273
- *
274
- * In base-64 decoding, groups of four characters are converted into three
275
- * bytes. If the encoder did not apply padding, the input length may not
276
- * be a multiple of 4.
277
- *
278
- * In this case, the last group will have fewer than 4 characters, and
279
- * padding will be inferred. If the group has one or two characters, it decodes
280
- * to one byte. If the group has three characters, it decodes to two bytes.
281
- *
282
- * @param input Input to decode.
283
- * @param webSafe True if we should use the web-safe alphabet.
284
- * @return bytes representing the decoded value.
285
- */
286
- decodeStringToByteArray(input, webSafe) {
287
- this.init_();
288
- const charToByteMap = webSafe
289
- ? this.charToByteMapWebSafe_
290
- : this.charToByteMap_;
291
- const output = [];
292
- for (let i = 0; i < input.length;) {
293
- const byte1 = charToByteMap[input.charAt(i++)];
294
- const haveByte2 = i < input.length;
295
- const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;
296
- ++i;
297
- const haveByte3 = i < input.length;
298
- const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;
299
- ++i;
300
- const haveByte4 = i < input.length;
301
- const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;
302
- ++i;
303
- if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {
304
- throw new DecodeBase64StringError();
305
- }
306
- const outByte1 = (byte1 << 2) | (byte2 >> 4);
307
- output.push(outByte1);
308
- if (byte3 !== 64) {
309
- const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);
310
- output.push(outByte2);
311
- if (byte4 !== 64) {
312
- const outByte3 = ((byte3 << 6) & 0xc0) | byte4;
313
- output.push(outByte3);
314
- }
315
- }
316
- }
317
- return output;
318
- },
319
- /**
320
- * Lazy static initialization function. Called before
321
- * accessing any of the static map variables.
322
- * @private
323
- */
324
- init_() {
325
- if (!this.byteToCharMap_) {
326
- this.byteToCharMap_ = {};
327
- this.charToByteMap_ = {};
328
- this.byteToCharMapWebSafe_ = {};
329
- this.charToByteMapWebSafe_ = {};
330
- // We want quick mappings back and forth, so we precompute two maps.
331
- for (let i = 0; i < this.ENCODED_VALS.length; i++) {
332
- this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);
333
- this.charToByteMap_[this.byteToCharMap_[i]] = i;
334
- this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);
335
- this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;
336
- // Be forgiving when decoding and correctly decode both encodings.
337
- if (i >= this.ENCODED_VALS_BASE.length) {
338
- this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;
339
- this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;
340
- }
341
- }
342
- }
343
- }
344
- };
345
- /**
346
- * An error encountered while decoding base64 string.
347
- */
348
- class DecodeBase64StringError extends Error {
349
- constructor() {
350
- super(...arguments);
351
- this.name = 'DecodeBase64StringError';
352
- }
353
- }
354
- /**
355
- * URL-safe base64 encoding
356
- */
357
- const base64Encode = function (str) {
358
- const utf8Bytes = stringToByteArray$1(str);
359
- return base64.encodeByteArray(utf8Bytes, true);
360
- };
361
- /**
362
- * URL-safe base64 encoding (without "." padding in the end).
363
- * e.g. Used in JSON Web Token (JWT) parts.
364
- */
365
- const base64urlEncodeWithoutPadding = function (str) {
366
- // Use base64url encoding and remove padding in the end (dot characters).
367
- return base64Encode(str).replace(/\./g, '');
368
- };
369
- /**
370
- * URL-safe base64 decoding
371
- *
372
- * NOTE: DO NOT use the global atob() function - it does NOT support the
373
- * base64Url variant encoding.
374
- *
375
- * @param str To be decoded
376
- * @return Decoded result, if possible
377
- */
378
- const base64Decode = function (str) {
379
- try {
380
- return base64.decodeString(str, true);
381
- }
382
- catch (e) {
383
- console.error('base64Decode failed: ', e);
384
- }
385
- return null;
69
+ /**
70
+ * @license
71
+ * Copyright 2017 Google LLC
72
+ *
73
+ * Licensed under the Apache License, Version 2.0 (the "License");
74
+ * you may not use this file except in compliance with the License.
75
+ * You may obtain a copy of the License at
76
+ *
77
+ * http://www.apache.org/licenses/LICENSE-2.0
78
+ *
79
+ * Unless required by applicable law or agreed to in writing, software
80
+ * distributed under the License is distributed on an "AS IS" BASIS,
81
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82
+ * See the License for the specific language governing permissions and
83
+ * limitations under the License.
84
+ */
85
+ const stringToByteArray$1 = function (str) {
86
+ // TODO(user): Use native implementations if/when available
87
+ const out = [];
88
+ let p = 0;
89
+ for (let i = 0; i < str.length; i++) {
90
+ let c = str.charCodeAt(i);
91
+ if (c < 128) {
92
+ out[p++] = c;
93
+ }
94
+ else if (c < 2048) {
95
+ out[p++] = (c >> 6) | 192;
96
+ out[p++] = (c & 63) | 128;
97
+ }
98
+ else if ((c & 0xfc00) === 0xd800 &&
99
+ i + 1 < str.length &&
100
+ (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00) {
101
+ // Surrogate Pair
102
+ c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);
103
+ out[p++] = (c >> 18) | 240;
104
+ out[p++] = ((c >> 12) & 63) | 128;
105
+ out[p++] = ((c >> 6) & 63) | 128;
106
+ out[p++] = (c & 63) | 128;
107
+ }
108
+ else {
109
+ out[p++] = (c >> 12) | 224;
110
+ out[p++] = ((c >> 6) & 63) | 128;
111
+ out[p++] = (c & 63) | 128;
112
+ }
113
+ }
114
+ return out;
115
+ };
116
+ /**
117
+ * Turns an array of numbers into the string given by the concatenation of the
118
+ * characters to which the numbers correspond.
119
+ * @param bytes Array of numbers representing characters.
120
+ * @return Stringification of the array.
121
+ */
122
+ const byteArrayToString = function (bytes) {
123
+ // TODO(user): Use native implementations if/when available
124
+ const out = [];
125
+ let pos = 0, c = 0;
126
+ while (pos < bytes.length) {
127
+ const c1 = bytes[pos++];
128
+ if (c1 < 128) {
129
+ out[c++] = String.fromCharCode(c1);
130
+ }
131
+ else if (c1 > 191 && c1 < 224) {
132
+ const c2 = bytes[pos++];
133
+ out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
134
+ }
135
+ else if (c1 > 239 && c1 < 365) {
136
+ // Surrogate Pair
137
+ const c2 = bytes[pos++];
138
+ const c3 = bytes[pos++];
139
+ const c4 = bytes[pos++];
140
+ const u = (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -
141
+ 0x10000;
142
+ out[c++] = String.fromCharCode(0xd800 + (u >> 10));
143
+ out[c++] = String.fromCharCode(0xdc00 + (u & 1023));
144
+ }
145
+ else {
146
+ const c2 = bytes[pos++];
147
+ const c3 = bytes[pos++];
148
+ out[c++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
149
+ }
150
+ }
151
+ return out.join('');
152
+ };
153
+ // We define it as an object literal instead of a class because a class compiled down to es5 can't
154
+ // be treeshaked. https://github.com/rollup/rollup/issues/1691
155
+ // Static lookup maps, lazily populated by init_()
156
+ // TODO(dlarocque): Define this as a class, since we no longer target ES5.
157
+ const base64 = {
158
+ /**
159
+ * Maps bytes to characters.
160
+ */
161
+ byteToCharMap_: null,
162
+ /**
163
+ * Maps characters to bytes.
164
+ */
165
+ charToByteMap_: null,
166
+ /**
167
+ * Maps bytes to websafe characters.
168
+ * @private
169
+ */
170
+ byteToCharMapWebSafe_: null,
171
+ /**
172
+ * Maps websafe characters to bytes.
173
+ * @private
174
+ */
175
+ charToByteMapWebSafe_: null,
176
+ /**
177
+ * Our default alphabet, shared between
178
+ * ENCODED_VALS and ENCODED_VALS_WEBSAFE
179
+ */
180
+ ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',
181
+ /**
182
+ * Our default alphabet. Value 64 (=) is special; it means "nothing."
183
+ */
184
+ get ENCODED_VALS() {
185
+ return this.ENCODED_VALS_BASE + '+/=';
186
+ },
187
+ /**
188
+ * Our websafe alphabet.
189
+ */
190
+ get ENCODED_VALS_WEBSAFE() {
191
+ return this.ENCODED_VALS_BASE + '-_.';
192
+ },
193
+ /**
194
+ * Whether this browser supports the atob and btoa functions. This extension
195
+ * started at Mozilla but is now implemented by many browsers. We use the
196
+ * ASSUME_* variables to avoid pulling in the full useragent detection library
197
+ * but still allowing the standard per-browser compilations.
198
+ *
199
+ */
200
+ HAS_NATIVE_SUPPORT: typeof atob === 'function',
201
+ /**
202
+ * Base64-encode an array of bytes.
203
+ *
204
+ * @param input An array of bytes (numbers with
205
+ * value in [0, 255]) to encode.
206
+ * @param webSafe Boolean indicating we should use the
207
+ * alternative alphabet.
208
+ * @return The base64 encoded string.
209
+ */
210
+ encodeByteArray(input, webSafe) {
211
+ if (!Array.isArray(input)) {
212
+ throw Error('encodeByteArray takes an array as a parameter');
213
+ }
214
+ this.init_();
215
+ const byteToCharMap = webSafe
216
+ ? this.byteToCharMapWebSafe_
217
+ : this.byteToCharMap_;
218
+ const output = [];
219
+ for (let i = 0; i < input.length; i += 3) {
220
+ const byte1 = input[i];
221
+ const haveByte2 = i + 1 < input.length;
222
+ const byte2 = haveByte2 ? input[i + 1] : 0;
223
+ const haveByte3 = i + 2 < input.length;
224
+ const byte3 = haveByte3 ? input[i + 2] : 0;
225
+ const outByte1 = byte1 >> 2;
226
+ const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
227
+ let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);
228
+ let outByte4 = byte3 & 0x3f;
229
+ if (!haveByte3) {
230
+ outByte4 = 64;
231
+ if (!haveByte2) {
232
+ outByte3 = 64;
233
+ }
234
+ }
235
+ output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);
236
+ }
237
+ return output.join('');
238
+ },
239
+ /**
240
+ * Base64-encode a string.
241
+ *
242
+ * @param input A string to encode.
243
+ * @param webSafe If true, we should use the
244
+ * alternative alphabet.
245
+ * @return The base64 encoded string.
246
+ */
247
+ encodeString(input, webSafe) {
248
+ // Shortcut for Mozilla browsers that implement
249
+ // a native base64 encoder in the form of "btoa/atob"
250
+ if (this.HAS_NATIVE_SUPPORT && !webSafe) {
251
+ return btoa(input);
252
+ }
253
+ return this.encodeByteArray(stringToByteArray$1(input), webSafe);
254
+ },
255
+ /**
256
+ * Base64-decode a string.
257
+ *
258
+ * @param input to decode.
259
+ * @param webSafe True if we should use the
260
+ * alternative alphabet.
261
+ * @return string representing the decoded value.
262
+ */
263
+ decodeString(input, webSafe) {
264
+ // Shortcut for Mozilla browsers that implement
265
+ // a native base64 encoder in the form of "btoa/atob"
266
+ if (this.HAS_NATIVE_SUPPORT && !webSafe) {
267
+ return atob(input);
268
+ }
269
+ return byteArrayToString(this.decodeStringToByteArray(input, webSafe));
270
+ },
271
+ /**
272
+ * Base64-decode a string.
273
+ *
274
+ * In base-64 decoding, groups of four characters are converted into three
275
+ * bytes. If the encoder did not apply padding, the input length may not
276
+ * be a multiple of 4.
277
+ *
278
+ * In this case, the last group will have fewer than 4 characters, and
279
+ * padding will be inferred. If the group has one or two characters, it decodes
280
+ * to one byte. If the group has three characters, it decodes to two bytes.
281
+ *
282
+ * @param input Input to decode.
283
+ * @param webSafe True if we should use the web-safe alphabet.
284
+ * @return bytes representing the decoded value.
285
+ */
286
+ decodeStringToByteArray(input, webSafe) {
287
+ this.init_();
288
+ const charToByteMap = webSafe
289
+ ? this.charToByteMapWebSafe_
290
+ : this.charToByteMap_;
291
+ const output = [];
292
+ for (let i = 0; i < input.length;) {
293
+ const byte1 = charToByteMap[input.charAt(i++)];
294
+ const haveByte2 = i < input.length;
295
+ const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;
296
+ ++i;
297
+ const haveByte3 = i < input.length;
298
+ const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;
299
+ ++i;
300
+ const haveByte4 = i < input.length;
301
+ const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;
302
+ ++i;
303
+ if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {
304
+ throw new DecodeBase64StringError();
305
+ }
306
+ const outByte1 = (byte1 << 2) | (byte2 >> 4);
307
+ output.push(outByte1);
308
+ if (byte3 !== 64) {
309
+ const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);
310
+ output.push(outByte2);
311
+ if (byte4 !== 64) {
312
+ const outByte3 = ((byte3 << 6) & 0xc0) | byte4;
313
+ output.push(outByte3);
314
+ }
315
+ }
316
+ }
317
+ return output;
318
+ },
319
+ /**
320
+ * Lazy static initialization function. Called before
321
+ * accessing any of the static map variables.
322
+ * @private
323
+ */
324
+ init_() {
325
+ if (!this.byteToCharMap_) {
326
+ this.byteToCharMap_ = {};
327
+ this.charToByteMap_ = {};
328
+ this.byteToCharMapWebSafe_ = {};
329
+ this.charToByteMapWebSafe_ = {};
330
+ // We want quick mappings back and forth, so we precompute two maps.
331
+ for (let i = 0; i < this.ENCODED_VALS.length; i++) {
332
+ this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);
333
+ this.charToByteMap_[this.byteToCharMap_[i]] = i;
334
+ this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);
335
+ this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;
336
+ // Be forgiving when decoding and correctly decode both encodings.
337
+ if (i >= this.ENCODED_VALS_BASE.length) {
338
+ this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;
339
+ this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;
340
+ }
341
+ }
342
+ }
343
+ }
344
+ };
345
+ /**
346
+ * An error encountered while decoding base64 string.
347
+ */
348
+ class DecodeBase64StringError extends Error {
349
+ constructor() {
350
+ super(...arguments);
351
+ this.name = 'DecodeBase64StringError';
352
+ }
353
+ }
354
+ /**
355
+ * URL-safe base64 encoding
356
+ */
357
+ const base64Encode = function (str) {
358
+ const utf8Bytes = stringToByteArray$1(str);
359
+ return base64.encodeByteArray(utf8Bytes, true);
360
+ };
361
+ /**
362
+ * URL-safe base64 encoding (without "." padding in the end).
363
+ * e.g. Used in JSON Web Token (JWT) parts.
364
+ */
365
+ const base64urlEncodeWithoutPadding = function (str) {
366
+ // Use base64url encoding and remove padding in the end (dot characters).
367
+ return base64Encode(str).replace(/\./g, '');
368
+ };
369
+ /**
370
+ * URL-safe base64 decoding
371
+ *
372
+ * NOTE: DO NOT use the global atob() function - it does NOT support the
373
+ * base64Url variant encoding.
374
+ *
375
+ * @param str To be decoded
376
+ * @return Decoded result, if possible
377
+ */
378
+ const base64Decode = function (str) {
379
+ try {
380
+ return base64.decodeString(str, true);
381
+ }
382
+ catch (e) {
383
+ console.error('base64Decode failed: ', e);
384
+ }
385
+ return null;
386
386
  };
387
387
 
388
- /**
389
- * @license
390
- * Copyright 2017 Google LLC
391
- *
392
- * Licensed under the Apache License, Version 2.0 (the "License");
393
- * you may not use this file except in compliance with the License.
394
- * You may obtain a copy of the License at
395
- *
396
- * http://www.apache.org/licenses/LICENSE-2.0
397
- *
398
- * Unless required by applicable law or agreed to in writing, software
399
- * distributed under the License is distributed on an "AS IS" BASIS,
400
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
401
- * See the License for the specific language governing permissions and
402
- * limitations under the License.
403
- */
404
- /**
405
- * Do a deep-copy of basic JavaScript Objects or Arrays.
406
- */
407
- function deepCopy(value) {
408
- return deepExtend(undefined, value);
409
- }
410
- /**
411
- * Copy properties from source to target (recursively allows extension
412
- * of Objects and Arrays). Scalar values in the target are over-written.
413
- * If target is undefined, an object of the appropriate type will be created
414
- * (and returned).
415
- *
416
- * We recursively copy all child properties of plain Objects in the source- so
417
- * that namespace- like dictionaries are merged.
418
- *
419
- * Note that the target can be a function, in which case the properties in
420
- * the source Object are copied onto it as static properties of the Function.
421
- *
422
- * Note: we don't merge __proto__ to prevent prototype pollution
423
- */
424
- function deepExtend(target, source) {
425
- if (!(source instanceof Object)) {
426
- return source;
427
- }
428
- switch (source.constructor) {
429
- case Date:
430
- // Treat Dates like scalars; if the target date object had any child
431
- // properties - they will be lost!
432
- const dateValue = source;
433
- return new Date(dateValue.getTime());
434
- case Object:
435
- if (target === undefined) {
436
- target = {};
437
- }
438
- break;
439
- case Array:
440
- // Always copy the array source and overwrite the target.
441
- target = [];
442
- break;
443
- default:
444
- // Not a plain Object - treat it as a scalar.
445
- return source;
446
- }
447
- for (const prop in source) {
448
- // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202
449
- if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {
450
- continue;
451
- }
452
- target[prop] = deepExtend(target[prop], source[prop]);
453
- }
454
- return target;
455
- }
456
- function isValidKey(key) {
457
- return key !== '__proto__';
388
+ /**
389
+ * @license
390
+ * Copyright 2017 Google LLC
391
+ *
392
+ * Licensed under the Apache License, Version 2.0 (the "License");
393
+ * you may not use this file except in compliance with the License.
394
+ * You may obtain a copy of the License at
395
+ *
396
+ * http://www.apache.org/licenses/LICENSE-2.0
397
+ *
398
+ * Unless required by applicable law or agreed to in writing, software
399
+ * distributed under the License is distributed on an "AS IS" BASIS,
400
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
401
+ * See the License for the specific language governing permissions and
402
+ * limitations under the License.
403
+ */
404
+ /**
405
+ * Do a deep-copy of basic JavaScript Objects or Arrays.
406
+ */
407
+ function deepCopy(value) {
408
+ return deepExtend(undefined, value);
409
+ }
410
+ /**
411
+ * Copy properties from source to target (recursively allows extension
412
+ * of Objects and Arrays). Scalar values in the target are over-written.
413
+ * If target is undefined, an object of the appropriate type will be created
414
+ * (and returned).
415
+ *
416
+ * We recursively copy all child properties of plain Objects in the source- so
417
+ * that namespace- like dictionaries are merged.
418
+ *
419
+ * Note that the target can be a function, in which case the properties in
420
+ * the source Object are copied onto it as static properties of the Function.
421
+ *
422
+ * Note: we don't merge __proto__ to prevent prototype pollution
423
+ */
424
+ function deepExtend(target, source) {
425
+ if (!(source instanceof Object)) {
426
+ return source;
427
+ }
428
+ switch (source.constructor) {
429
+ case Date:
430
+ // Treat Dates like scalars; if the target date object had any child
431
+ // properties - they will be lost!
432
+ const dateValue = source;
433
+ return new Date(dateValue.getTime());
434
+ case Object:
435
+ if (target === undefined) {
436
+ target = {};
437
+ }
438
+ break;
439
+ case Array:
440
+ // Always copy the array source and overwrite the target.
441
+ target = [];
442
+ break;
443
+ default:
444
+ // Not a plain Object - treat it as a scalar.
445
+ return source;
446
+ }
447
+ for (const prop in source) {
448
+ // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202
449
+ if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {
450
+ continue;
451
+ }
452
+ target[prop] = deepExtend(target[prop], source[prop]);
453
+ }
454
+ return target;
455
+ }
456
+ function isValidKey(key) {
457
+ return key !== '__proto__';
458
458
  }
459
459
 
460
- /**
461
- * @license
462
- * Copyright 2022 Google LLC
463
- *
464
- * Licensed under the Apache License, Version 2.0 (the "License");
465
- * you may not use this file except in compliance with the License.
466
- * You may obtain a copy of the License at
467
- *
468
- * http://www.apache.org/licenses/LICENSE-2.0
469
- *
470
- * Unless required by applicable law or agreed to in writing, software
471
- * distributed under the License is distributed on an "AS IS" BASIS,
472
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
473
- * See the License for the specific language governing permissions and
474
- * limitations under the License.
475
- */
476
- /**
477
- * Polyfill for `globalThis` object.
478
- * @returns the `globalThis` object for the given environment.
479
- * @public
480
- */
481
- function getGlobal() {
482
- if (typeof self !== 'undefined') {
483
- return self;
484
- }
485
- if (typeof window !== 'undefined') {
486
- return window;
487
- }
488
- if (typeof global !== 'undefined') {
489
- return global;
490
- }
491
- throw new Error('Unable to locate global object.');
460
+ /**
461
+ * @license
462
+ * Copyright 2022 Google LLC
463
+ *
464
+ * Licensed under the Apache License, Version 2.0 (the "License");
465
+ * you may not use this file except in compliance with the License.
466
+ * You may obtain a copy of the License at
467
+ *
468
+ * http://www.apache.org/licenses/LICENSE-2.0
469
+ *
470
+ * Unless required by applicable law or agreed to in writing, software
471
+ * distributed under the License is distributed on an "AS IS" BASIS,
472
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
473
+ * See the License for the specific language governing permissions and
474
+ * limitations under the License.
475
+ */
476
+ /**
477
+ * Polyfill for `globalThis` object.
478
+ * @returns the `globalThis` object for the given environment.
479
+ * @public
480
+ */
481
+ function getGlobal() {
482
+ if (typeof self !== 'undefined') {
483
+ return self;
484
+ }
485
+ if (typeof window !== 'undefined') {
486
+ return window;
487
+ }
488
+ if (typeof global !== 'undefined') {
489
+ return global;
490
+ }
491
+ throw new Error('Unable to locate global object.');
492
492
  }
493
493
 
494
- /**
495
- * @license
496
- * Copyright 2022 Google LLC
497
- *
498
- * Licensed under the Apache License, Version 2.0 (the "License");
499
- * you may not use this file except in compliance with the License.
500
- * You may obtain a copy of the License at
501
- *
502
- * http://www.apache.org/licenses/LICENSE-2.0
503
- *
504
- * Unless required by applicable law or agreed to in writing, software
505
- * distributed under the License is distributed on an "AS IS" BASIS,
506
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
507
- * See the License for the specific language governing permissions and
508
- * limitations under the License.
509
- */
510
- const getDefaultsFromGlobal = () => getGlobal().__FIREBASE_DEFAULTS__;
511
- /**
512
- * Attempt to read defaults from a JSON string provided to
513
- * process(.)env(.)__FIREBASE_DEFAULTS__ or a JSON file whose path is in
514
- * process(.)env(.)__FIREBASE_DEFAULTS_PATH__
515
- * The dots are in parens because certain compilers (Vite?) cannot
516
- * handle seeing that variable in comments.
517
- * See https://github.com/firebase/firebase-js-sdk/issues/6838
518
- */
519
- const getDefaultsFromEnvVariable = () => {
520
- if (typeof process === 'undefined' || typeof process.env === 'undefined') {
521
- return;
522
- }
523
- const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__;
524
- if (defaultsJsonString) {
525
- return JSON.parse(defaultsJsonString);
526
- }
527
- };
528
- const getDefaultsFromCookie = () => {
529
- if (typeof document === 'undefined') {
530
- return;
531
- }
532
- let match;
533
- try {
534
- match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/);
535
- }
536
- catch (e) {
537
- // Some environments such as Angular Universal SSR have a
538
- // `document` object but error on accessing `document.cookie`.
539
- return;
540
- }
541
- const decoded = match && base64Decode(match[1]);
542
- return decoded && JSON.parse(decoded);
543
- };
544
- /**
545
- * Get the __FIREBASE_DEFAULTS__ object. It checks in order:
546
- * (1) if such an object exists as a property of `globalThis`
547
- * (2) if such an object was provided on a shell environment variable
548
- * (3) if such an object exists in a cookie
549
- * @public
550
- */
551
- const getDefaults = () => {
552
- try {
553
- return (getDefaultsFromGlobal() ||
554
- getDefaultsFromEnvVariable() ||
555
- getDefaultsFromCookie());
556
- }
557
- catch (e) {
558
- /**
559
- * Catch-all for being unable to get __FIREBASE_DEFAULTS__ due
560
- * to any environment case we have not accounted for. Log to
561
- * info instead of swallowing so we can find these unknown cases
562
- * and add paths for them if needed.
563
- */
564
- console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`);
565
- return;
566
- }
567
- };
568
- /**
569
- * Returns emulator host stored in the __FIREBASE_DEFAULTS__ object
570
- * for the given product.
571
- * @returns a URL host formatted like `127.0.0.1:9999` or `[::1]:4000` if available
572
- * @public
573
- */
574
- const getDefaultEmulatorHost = (productName) => { var _a, _b; return (_b = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.emulatorHosts) === null || _b === void 0 ? void 0 : _b[productName]; };
575
- /**
576
- * Returns emulator hostname and port stored in the __FIREBASE_DEFAULTS__ object
577
- * for the given product.
578
- * @returns a pair of hostname and port like `["::1", 4000]` if available
579
- * @public
580
- */
581
- const getDefaultEmulatorHostnameAndPort = (productName) => {
582
- const host = getDefaultEmulatorHost(productName);
583
- if (!host) {
584
- return undefined;
585
- }
586
- const separatorIndex = host.lastIndexOf(':'); // Finding the last since IPv6 addr also has colons.
587
- if (separatorIndex <= 0 || separatorIndex + 1 === host.length) {
588
- throw new Error(`Invalid host ${host} with no separate hostname and port!`);
589
- }
590
- // eslint-disable-next-line no-restricted-globals
591
- const port = parseInt(host.substring(separatorIndex + 1), 10);
592
- if (host[0] === '[') {
593
- // Bracket-quoted `[ipv6addr]:port` => return "ipv6addr" (without brackets).
594
- return [host.substring(1, separatorIndex - 1), port];
595
- }
596
- else {
597
- return [host.substring(0, separatorIndex), port];
598
- }
599
- };
600
- /**
601
- * Returns Firebase app config stored in the __FIREBASE_DEFAULTS__ object.
602
- * @public
603
- */
604
- const getDefaultAppConfig = () => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.config; };
605
- /**
606
- * Returns an experimental setting on the __FIREBASE_DEFAULTS__ object (properties
607
- * prefixed by "_")
608
- * @public
609
- */
494
+ /**
495
+ * @license
496
+ * Copyright 2022 Google LLC
497
+ *
498
+ * Licensed under the Apache License, Version 2.0 (the "License");
499
+ * you may not use this file except in compliance with the License.
500
+ * You may obtain a copy of the License at
501
+ *
502
+ * http://www.apache.org/licenses/LICENSE-2.0
503
+ *
504
+ * Unless required by applicable law or agreed to in writing, software
505
+ * distributed under the License is distributed on an "AS IS" BASIS,
506
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
507
+ * See the License for the specific language governing permissions and
508
+ * limitations under the License.
509
+ */
510
+ const getDefaultsFromGlobal = () => getGlobal().__FIREBASE_DEFAULTS__;
511
+ /**
512
+ * Attempt to read defaults from a JSON string provided to
513
+ * process(.)env(.)__FIREBASE_DEFAULTS__ or a JSON file whose path is in
514
+ * process(.)env(.)__FIREBASE_DEFAULTS_PATH__
515
+ * The dots are in parens because certain compilers (Vite?) cannot
516
+ * handle seeing that variable in comments.
517
+ * See https://github.com/firebase/firebase-js-sdk/issues/6838
518
+ */
519
+ const getDefaultsFromEnvVariable = () => {
520
+ if (typeof process === 'undefined' || typeof process.env === 'undefined') {
521
+ return;
522
+ }
523
+ const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__;
524
+ if (defaultsJsonString) {
525
+ return JSON.parse(defaultsJsonString);
526
+ }
527
+ };
528
+ const getDefaultsFromCookie = () => {
529
+ if (typeof document === 'undefined') {
530
+ return;
531
+ }
532
+ let match;
533
+ try {
534
+ match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/);
535
+ }
536
+ catch (e) {
537
+ // Some environments such as Angular Universal SSR have a
538
+ // `document` object but error on accessing `document.cookie`.
539
+ return;
540
+ }
541
+ const decoded = match && base64Decode(match[1]);
542
+ return decoded && JSON.parse(decoded);
543
+ };
544
+ /**
545
+ * Get the __FIREBASE_DEFAULTS__ object. It checks in order:
546
+ * (1) if such an object exists as a property of `globalThis`
547
+ * (2) if such an object was provided on a shell environment variable
548
+ * (3) if such an object exists in a cookie
549
+ * @public
550
+ */
551
+ const getDefaults = () => {
552
+ try {
553
+ return (getDefaultsFromGlobal() ||
554
+ getDefaultsFromEnvVariable() ||
555
+ getDefaultsFromCookie());
556
+ }
557
+ catch (e) {
558
+ /**
559
+ * Catch-all for being unable to get __FIREBASE_DEFAULTS__ due
560
+ * to any environment case we have not accounted for. Log to
561
+ * info instead of swallowing so we can find these unknown cases
562
+ * and add paths for them if needed.
563
+ */
564
+ console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`);
565
+ return;
566
+ }
567
+ };
568
+ /**
569
+ * Returns emulator host stored in the __FIREBASE_DEFAULTS__ object
570
+ * for the given product.
571
+ * @returns a URL host formatted like `127.0.0.1:9999` or `[::1]:4000` if available
572
+ * @public
573
+ */
574
+ const getDefaultEmulatorHost = (productName) => { var _a, _b; return (_b = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.emulatorHosts) === null || _b === void 0 ? void 0 : _b[productName]; };
575
+ /**
576
+ * Returns emulator hostname and port stored in the __FIREBASE_DEFAULTS__ object
577
+ * for the given product.
578
+ * @returns a pair of hostname and port like `["::1", 4000]` if available
579
+ * @public
580
+ */
581
+ const getDefaultEmulatorHostnameAndPort = (productName) => {
582
+ const host = getDefaultEmulatorHost(productName);
583
+ if (!host) {
584
+ return undefined;
585
+ }
586
+ const separatorIndex = host.lastIndexOf(':'); // Finding the last since IPv6 addr also has colons.
587
+ if (separatorIndex <= 0 || separatorIndex + 1 === host.length) {
588
+ throw new Error(`Invalid host ${host} with no separate hostname and port!`);
589
+ }
590
+ // eslint-disable-next-line no-restricted-globals
591
+ const port = parseInt(host.substring(separatorIndex + 1), 10);
592
+ if (host[0] === '[') {
593
+ // Bracket-quoted `[ipv6addr]:port` => return "ipv6addr" (without brackets).
594
+ return [host.substring(1, separatorIndex - 1), port];
595
+ }
596
+ else {
597
+ return [host.substring(0, separatorIndex), port];
598
+ }
599
+ };
600
+ /**
601
+ * Returns Firebase app config stored in the __FIREBASE_DEFAULTS__ object.
602
+ * @public
603
+ */
604
+ const getDefaultAppConfig = () => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.config; };
605
+ /**
606
+ * Returns an experimental setting on the __FIREBASE_DEFAULTS__ object (properties
607
+ * prefixed by "_")
608
+ * @public
609
+ */
610
610
  const getExperimentalSetting = (name) => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a[`_${name}`]; };
611
611
 
612
- /**
613
- * @license
614
- * Copyright 2017 Google LLC
615
- *
616
- * Licensed under the Apache License, Version 2.0 (the "License");
617
- * you may not use this file except in compliance with the License.
618
- * You may obtain a copy of the License at
619
- *
620
- * http://www.apache.org/licenses/LICENSE-2.0
621
- *
622
- * Unless required by applicable law or agreed to in writing, software
623
- * distributed under the License is distributed on an "AS IS" BASIS,
624
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
625
- * See the License for the specific language governing permissions and
626
- * limitations under the License.
627
- */
628
- class Deferred {
629
- constructor() {
630
- this.reject = () => { };
631
- this.resolve = () => { };
632
- this.promise = new Promise((resolve, reject) => {
633
- this.resolve = resolve;
634
- this.reject = reject;
635
- });
636
- }
637
- /**
638
- * Our API internals are not promisified and cannot because our callback APIs have subtle expectations around
639
- * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback
640
- * and returns a node-style callback which will resolve or reject the Deferred's promise.
641
- */
642
- wrapCallback(callback) {
643
- return (error, value) => {
644
- if (error) {
645
- this.reject(error);
646
- }
647
- else {
648
- this.resolve(value);
649
- }
650
- if (typeof callback === 'function') {
651
- // Attaching noop handler just in case developer wasn't expecting
652
- // promises
653
- this.promise.catch(() => { });
654
- // Some of our callbacks don't expect a value and our own tests
655
- // assert that the parameter length is 1
656
- if (callback.length === 1) {
657
- callback(error);
658
- }
659
- else {
660
- callback(error, value);
661
- }
662
- }
663
- };
664
- }
612
+ /**
613
+ * @license
614
+ * Copyright 2017 Google LLC
615
+ *
616
+ * Licensed under the Apache License, Version 2.0 (the "License");
617
+ * you may not use this file except in compliance with the License.
618
+ * You may obtain a copy of the License at
619
+ *
620
+ * http://www.apache.org/licenses/LICENSE-2.0
621
+ *
622
+ * Unless required by applicable law or agreed to in writing, software
623
+ * distributed under the License is distributed on an "AS IS" BASIS,
624
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
625
+ * See the License for the specific language governing permissions and
626
+ * limitations under the License.
627
+ */
628
+ class Deferred {
629
+ constructor() {
630
+ this.reject = () => { };
631
+ this.resolve = () => { };
632
+ this.promise = new Promise((resolve, reject) => {
633
+ this.resolve = resolve;
634
+ this.reject = reject;
635
+ });
636
+ }
637
+ /**
638
+ * Our API internals are not promisified and cannot because our callback APIs have subtle expectations around
639
+ * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback
640
+ * and returns a node-style callback which will resolve or reject the Deferred's promise.
641
+ */
642
+ wrapCallback(callback) {
643
+ return (error, value) => {
644
+ if (error) {
645
+ this.reject(error);
646
+ }
647
+ else {
648
+ this.resolve(value);
649
+ }
650
+ if (typeof callback === 'function') {
651
+ // Attaching noop handler just in case developer wasn't expecting
652
+ // promises
653
+ this.promise.catch(() => { });
654
+ // Some of our callbacks don't expect a value and our own tests
655
+ // assert that the parameter length is 1
656
+ if (callback.length === 1) {
657
+ callback(error);
658
+ }
659
+ else {
660
+ callback(error, value);
661
+ }
662
+ }
663
+ };
664
+ }
665
665
  }
666
666
 
667
- /**
668
- * @license
669
- * Copyright 2021 Google LLC
670
- *
671
- * Licensed under the Apache License, Version 2.0 (the "License");
672
- * you may not use this file except in compliance with the License.
673
- * You may obtain a copy of the License at
674
- *
675
- * http://www.apache.org/licenses/LICENSE-2.0
676
- *
677
- * Unless required by applicable law or agreed to in writing, software
678
- * distributed under the License is distributed on an "AS IS" BASIS,
679
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
680
- * See the License for the specific language governing permissions and
681
- * limitations under the License.
682
- */
683
- function createMockUserToken(token, projectId) {
684
- if (token.uid) {
685
- throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.');
686
- }
687
- // Unsecured JWTs use "none" as the algorithm.
688
- const header = {
689
- alg: 'none',
690
- type: 'JWT'
691
- };
692
- const project = projectId || 'demo-project';
693
- const iat = token.iat || 0;
694
- const sub = token.sub || token.user_id;
695
- if (!sub) {
696
- throw new Error("mockUserToken must contain 'sub' or 'user_id' field!");
697
- }
698
- const payload = Object.assign({
699
- // Set all required fields to decent defaults
700
- iss: `https://securetoken.google.com/${project}`, aud: project, iat, exp: iat + 3600, auth_time: iat, sub, user_id: sub, firebase: {
701
- sign_in_provider: 'custom',
702
- identities: {}
703
- } }, token);
704
- // Unsecured JWTs use the empty string as a signature.
705
- const signature = '';
706
- return [
707
- base64urlEncodeWithoutPadding(JSON.stringify(header)),
708
- base64urlEncodeWithoutPadding(JSON.stringify(payload)),
709
- signature
710
- ].join('.');
667
+ /**
668
+ * @license
669
+ * Copyright 2021 Google LLC
670
+ *
671
+ * Licensed under the Apache License, Version 2.0 (the "License");
672
+ * you may not use this file except in compliance with the License.
673
+ * You may obtain a copy of the License at
674
+ *
675
+ * http://www.apache.org/licenses/LICENSE-2.0
676
+ *
677
+ * Unless required by applicable law or agreed to in writing, software
678
+ * distributed under the License is distributed on an "AS IS" BASIS,
679
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
680
+ * See the License for the specific language governing permissions and
681
+ * limitations under the License.
682
+ */
683
+ function createMockUserToken(token, projectId) {
684
+ if (token.uid) {
685
+ throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.');
686
+ }
687
+ // Unsecured JWTs use "none" as the algorithm.
688
+ const header = {
689
+ alg: 'none',
690
+ type: 'JWT'
691
+ };
692
+ const project = projectId || 'demo-project';
693
+ const iat = token.iat || 0;
694
+ const sub = token.sub || token.user_id;
695
+ if (!sub) {
696
+ throw new Error("mockUserToken must contain 'sub' or 'user_id' field!");
697
+ }
698
+ const payload = Object.assign({
699
+ // Set all required fields to decent defaults
700
+ iss: `https://securetoken.google.com/${project}`, aud: project, iat, exp: iat + 3600, auth_time: iat, sub, user_id: sub, firebase: {
701
+ sign_in_provider: 'custom',
702
+ identities: {}
703
+ } }, token);
704
+ // Unsecured JWTs use the empty string as a signature.
705
+ const signature = '';
706
+ return [
707
+ base64urlEncodeWithoutPadding(JSON.stringify(header)),
708
+ base64urlEncodeWithoutPadding(JSON.stringify(payload)),
709
+ signature
710
+ ].join('.');
711
711
  }
712
712
 
713
- /**
714
- * @license
715
- * Copyright 2017 Google LLC
716
- *
717
- * Licensed under the Apache License, Version 2.0 (the "License");
718
- * you may not use this file except in compliance with the License.
719
- * You may obtain a copy of the License at
720
- *
721
- * http://www.apache.org/licenses/LICENSE-2.0
722
- *
723
- * Unless required by applicable law or agreed to in writing, software
724
- * distributed under the License is distributed on an "AS IS" BASIS,
725
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
726
- * See the License for the specific language governing permissions and
727
- * limitations under the License.
728
- */
729
- /**
730
- * Returns navigator.userAgent string or '' if it's not defined.
731
- * @return user agent string
732
- */
733
- function getUA() {
734
- if (typeof navigator !== 'undefined' &&
735
- typeof navigator['userAgent'] === 'string') {
736
- return navigator['userAgent'];
737
- }
738
- else {
739
- return '';
740
- }
741
- }
742
- /**
743
- * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.
744
- *
745
- * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap
746
- * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally
747
- * wait for a callback.
748
- */
749
- function isMobileCordova() {
750
- return (typeof window !== 'undefined' &&
751
- // @ts-ignore Setting up an broadly applicable index signature for Window
752
- // just to deal with this case would probably be a bad idea.
753
- !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&
754
- /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()));
755
- }
756
- /**
757
- * Detect Node.js.
758
- *
759
- * @return true if Node.js environment is detected or specified.
760
- */
761
- // Node detection logic from: https://github.com/iliakan/detect-node/
762
- function isNode() {
763
- var _a;
764
- const forceEnvironment = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.forceEnvironment;
765
- if (forceEnvironment === 'node') {
766
- return true;
767
- }
768
- else if (forceEnvironment === 'browser') {
769
- return false;
770
- }
771
- try {
772
- return (Object.prototype.toString.call(global.process) === '[object process]');
773
- }
774
- catch (e) {
775
- return false;
776
- }
777
- }
778
- /**
779
- * Detect Browser Environment.
780
- * Note: This will return true for certain test frameworks that are incompletely
781
- * mimicking a browser, and should not lead to assuming all browser APIs are
782
- * available.
783
- */
784
- function isBrowser() {
785
- return typeof window !== 'undefined' || isWebWorker();
786
- }
787
- /**
788
- * Detect Web Worker context.
789
- */
790
- function isWebWorker() {
791
- return (typeof WorkerGlobalScope !== 'undefined' &&
792
- typeof self !== 'undefined' &&
793
- self instanceof WorkerGlobalScope);
794
- }
795
- /**
796
- * Detect Cloudflare Worker context.
797
- */
798
- function isCloudflareWorker() {
799
- return (typeof navigator !== 'undefined' &&
800
- navigator.userAgent === 'Cloudflare-Workers');
801
- }
802
- function isBrowserExtension() {
803
- const runtime = typeof chrome === 'object'
804
- ? chrome.runtime
805
- : typeof browser === 'object'
806
- ? browser.runtime
807
- : undefined;
808
- return typeof runtime === 'object' && runtime.id !== undefined;
809
- }
810
- /**
811
- * Detect React Native.
812
- *
813
- * @return true if ReactNative environment is detected.
814
- */
815
- function isReactNative() {
816
- return (typeof navigator === 'object' && navigator['product'] === 'ReactNative');
817
- }
818
- /** Detects Electron apps. */
819
- function isElectron() {
820
- return getUA().indexOf('Electron/') >= 0;
821
- }
822
- /** Detects Internet Explorer. */
823
- function isIE() {
824
- const ua = getUA();
825
- return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
826
- }
827
- /** Detects Universal Windows Platform apps. */
828
- function isUWP() {
829
- return getUA().indexOf('MSAppHost/') >= 0;
830
- }
831
- /**
832
- * Detect whether the current SDK build is the Node version.
833
- *
834
- * @return true if it's the Node SDK build.
835
- */
836
- function isNodeSdk() {
837
- return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;
838
- }
839
- /** Returns true if we are running in Safari. */
840
- function isSafari() {
841
- return (!isNode() &&
842
- !!navigator.userAgent &&
843
- navigator.userAgent.includes('Safari') &&
844
- !navigator.userAgent.includes('Chrome'));
845
- }
846
- /**
847
- * This method checks if indexedDB is supported by current browser/service worker context
848
- * @return true if indexedDB is supported by current browser/service worker context
849
- */
850
- function isIndexedDBAvailable() {
851
- try {
852
- return typeof indexedDB === 'object';
853
- }
854
- catch (e) {
855
- return false;
856
- }
857
- }
858
- /**
859
- * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject
860
- * if errors occur during the database open operation.
861
- *
862
- * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox
863
- * private browsing)
864
- */
865
- function validateIndexedDBOpenable() {
866
- return new Promise((resolve, reject) => {
867
- try {
868
- let preExist = true;
869
- const DB_CHECK_NAME = 'validate-browser-context-for-indexeddb-analytics-module';
870
- const request = self.indexedDB.open(DB_CHECK_NAME);
871
- request.onsuccess = () => {
872
- request.result.close();
873
- // delete database only when it doesn't pre-exist
874
- if (!preExist) {
875
- self.indexedDB.deleteDatabase(DB_CHECK_NAME);
876
- }
877
- resolve(true);
878
- };
879
- request.onupgradeneeded = () => {
880
- preExist = false;
881
- };
882
- request.onerror = () => {
883
- var _a;
884
- reject(((_a = request.error) === null || _a === void 0 ? void 0 : _a.message) || '');
885
- };
886
- }
887
- catch (error) {
888
- reject(error);
889
- }
890
- });
891
- }
892
- /**
893
- *
894
- * This method checks whether cookie is enabled within current browser
895
- * @return true if cookie is enabled within current browser
896
- */
897
- function areCookiesEnabled() {
898
- if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {
899
- return false;
900
- }
901
- return true;
713
+ /**
714
+ * @license
715
+ * Copyright 2017 Google LLC
716
+ *
717
+ * Licensed under the Apache License, Version 2.0 (the "License");
718
+ * you may not use this file except in compliance with the License.
719
+ * You may obtain a copy of the License at
720
+ *
721
+ * http://www.apache.org/licenses/LICENSE-2.0
722
+ *
723
+ * Unless required by applicable law or agreed to in writing, software
724
+ * distributed under the License is distributed on an "AS IS" BASIS,
725
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
726
+ * See the License for the specific language governing permissions and
727
+ * limitations under the License.
728
+ */
729
+ /**
730
+ * Returns navigator.userAgent string or '' if it's not defined.
731
+ * @return user agent string
732
+ */
733
+ function getUA() {
734
+ if (typeof navigator !== 'undefined' &&
735
+ typeof navigator['userAgent'] === 'string') {
736
+ return navigator['userAgent'];
737
+ }
738
+ else {
739
+ return '';
740
+ }
741
+ }
742
+ /**
743
+ * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.
744
+ *
745
+ * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap
746
+ * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally
747
+ * wait for a callback.
748
+ */
749
+ function isMobileCordova() {
750
+ return (typeof window !== 'undefined' &&
751
+ // @ts-ignore Setting up an broadly applicable index signature for Window
752
+ // just to deal with this case would probably be a bad idea.
753
+ !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&
754
+ /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()));
755
+ }
756
+ /**
757
+ * Detect Node.js.
758
+ *
759
+ * @return true if Node.js environment is detected or specified.
760
+ */
761
+ // Node detection logic from: https://github.com/iliakan/detect-node/
762
+ function isNode() {
763
+ var _a;
764
+ const forceEnvironment = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.forceEnvironment;
765
+ if (forceEnvironment === 'node') {
766
+ return true;
767
+ }
768
+ else if (forceEnvironment === 'browser') {
769
+ return false;
770
+ }
771
+ try {
772
+ return (Object.prototype.toString.call(global.process) === '[object process]');
773
+ }
774
+ catch (e) {
775
+ return false;
776
+ }
777
+ }
778
+ /**
779
+ * Detect Browser Environment.
780
+ * Note: This will return true for certain test frameworks that are incompletely
781
+ * mimicking a browser, and should not lead to assuming all browser APIs are
782
+ * available.
783
+ */
784
+ function isBrowser() {
785
+ return typeof window !== 'undefined' || isWebWorker();
786
+ }
787
+ /**
788
+ * Detect Web Worker context.
789
+ */
790
+ function isWebWorker() {
791
+ return (typeof WorkerGlobalScope !== 'undefined' &&
792
+ typeof self !== 'undefined' &&
793
+ self instanceof WorkerGlobalScope);
794
+ }
795
+ /**
796
+ * Detect Cloudflare Worker context.
797
+ */
798
+ function isCloudflareWorker() {
799
+ return (typeof navigator !== 'undefined' &&
800
+ navigator.userAgent === 'Cloudflare-Workers');
801
+ }
802
+ function isBrowserExtension() {
803
+ const runtime = typeof chrome === 'object'
804
+ ? chrome.runtime
805
+ : typeof browser === 'object'
806
+ ? browser.runtime
807
+ : undefined;
808
+ return typeof runtime === 'object' && runtime.id !== undefined;
809
+ }
810
+ /**
811
+ * Detect React Native.
812
+ *
813
+ * @return true if ReactNative environment is detected.
814
+ */
815
+ function isReactNative() {
816
+ return (typeof navigator === 'object' && navigator['product'] === 'ReactNative');
817
+ }
818
+ /** Detects Electron apps. */
819
+ function isElectron() {
820
+ return getUA().indexOf('Electron/') >= 0;
821
+ }
822
+ /** Detects Internet Explorer. */
823
+ function isIE() {
824
+ const ua = getUA();
825
+ return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
826
+ }
827
+ /** Detects Universal Windows Platform apps. */
828
+ function isUWP() {
829
+ return getUA().indexOf('MSAppHost/') >= 0;
830
+ }
831
+ /**
832
+ * Detect whether the current SDK build is the Node version.
833
+ *
834
+ * @return true if it's the Node SDK build.
835
+ */
836
+ function isNodeSdk() {
837
+ return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;
838
+ }
839
+ /** Returns true if we are running in Safari. */
840
+ function isSafari() {
841
+ return (!isNode() &&
842
+ !!navigator.userAgent &&
843
+ navigator.userAgent.includes('Safari') &&
844
+ !navigator.userAgent.includes('Chrome'));
845
+ }
846
+ /**
847
+ * This method checks if indexedDB is supported by current browser/service worker context
848
+ * @return true if indexedDB is supported by current browser/service worker context
849
+ */
850
+ function isIndexedDBAvailable() {
851
+ try {
852
+ return typeof indexedDB === 'object';
853
+ }
854
+ catch (e) {
855
+ return false;
856
+ }
857
+ }
858
+ /**
859
+ * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject
860
+ * if errors occur during the database open operation.
861
+ *
862
+ * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox
863
+ * private browsing)
864
+ */
865
+ function validateIndexedDBOpenable() {
866
+ return new Promise((resolve, reject) => {
867
+ try {
868
+ let preExist = true;
869
+ const DB_CHECK_NAME = 'validate-browser-context-for-indexeddb-analytics-module';
870
+ const request = self.indexedDB.open(DB_CHECK_NAME);
871
+ request.onsuccess = () => {
872
+ request.result.close();
873
+ // delete database only when it doesn't pre-exist
874
+ if (!preExist) {
875
+ self.indexedDB.deleteDatabase(DB_CHECK_NAME);
876
+ }
877
+ resolve(true);
878
+ };
879
+ request.onupgradeneeded = () => {
880
+ preExist = false;
881
+ };
882
+ request.onerror = () => {
883
+ var _a;
884
+ reject(((_a = request.error) === null || _a === void 0 ? void 0 : _a.message) || '');
885
+ };
886
+ }
887
+ catch (error) {
888
+ reject(error);
889
+ }
890
+ });
891
+ }
892
+ /**
893
+ *
894
+ * This method checks whether cookie is enabled within current browser
895
+ * @return true if cookie is enabled within current browser
896
+ */
897
+ function areCookiesEnabled() {
898
+ if (typeof navigator === 'undefined' || !navigator.cookieEnabled) {
899
+ return false;
900
+ }
901
+ return true;
902
902
  }
903
903
 
904
- /**
905
- * @license
906
- * Copyright 2017 Google LLC
907
- *
908
- * Licensed under the Apache License, Version 2.0 (the "License");
909
- * you may not use this file except in compliance with the License.
910
- * You may obtain a copy of the License at
911
- *
912
- * http://www.apache.org/licenses/LICENSE-2.0
913
- *
914
- * Unless required by applicable law or agreed to in writing, software
915
- * distributed under the License is distributed on an "AS IS" BASIS,
916
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
917
- * See the License for the specific language governing permissions and
918
- * limitations under the License.
919
- */
920
- /**
921
- * @fileoverview Standardized Firebase Error.
922
- *
923
- * Usage:
924
- *
925
- * // TypeScript string literals for type-safe codes
926
- * type Err =
927
- * 'unknown' |
928
- * 'object-not-found'
929
- * ;
930
- *
931
- * // Closure enum for type-safe error codes
932
- * // at-enum {string}
933
- * var Err = {
934
- * UNKNOWN: 'unknown',
935
- * OBJECT_NOT_FOUND: 'object-not-found',
936
- * }
937
- *
938
- * let errors: Map<Err, string> = {
939
- * 'generic-error': "Unknown error",
940
- * 'file-not-found': "Could not find file: {$file}",
941
- * };
942
- *
943
- * // Type-safe function - must pass a valid error code as param.
944
- * let error = new ErrorFactory<Err>('service', 'Service', errors);
945
- *
946
- * ...
947
- * throw error.create(Err.GENERIC);
948
- * ...
949
- * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});
950
- * ...
951
- * // Service: Could not file file: foo.txt (service/file-not-found).
952
- *
953
- * catch (e) {
954
- * assert(e.message === "Could not find file: foo.txt.");
955
- * if ((e as FirebaseError)?.code === 'service/file-not-found') {
956
- * console.log("Could not read file: " + e['file']);
957
- * }
958
- * }
959
- */
960
- const ERROR_NAME = 'FirebaseError';
961
- // Based on code from:
962
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types
963
- class FirebaseError extends Error {
964
- constructor(
965
- /** The error code for this error. */
966
- code, message,
967
- /** Custom data for this error. */
968
- customData) {
969
- super(message);
970
- this.code = code;
971
- this.customData = customData;
972
- /** The custom name for all FirebaseErrors. */
973
- this.name = ERROR_NAME;
974
- // Fix For ES5
975
- // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
976
- // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget
977
- // which we can now use since we no longer target ES5.
978
- Object.setPrototypeOf(this, FirebaseError.prototype);
979
- // Maintains proper stack trace for where our error was thrown.
980
- // Only available on V8.
981
- if (Error.captureStackTrace) {
982
- Error.captureStackTrace(this, ErrorFactory.prototype.create);
983
- }
984
- }
985
- }
986
- class ErrorFactory {
987
- constructor(service, serviceName, errors) {
988
- this.service = service;
989
- this.serviceName = serviceName;
990
- this.errors = errors;
991
- }
992
- create(code, ...data) {
993
- const customData = data[0] || {};
994
- const fullCode = `${this.service}/${code}`;
995
- const template = this.errors[code];
996
- const message = template ? replaceTemplate(template, customData) : 'Error';
997
- // Service Name: Error message (service/code).
998
- const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;
999
- const error = new FirebaseError(fullCode, fullMessage, customData);
1000
- return error;
1001
- }
1002
- }
1003
- function replaceTemplate(template, data) {
1004
- return template.replace(PATTERN, (_, key) => {
1005
- const value = data[key];
1006
- return value != null ? String(value) : `<${key}?>`;
1007
- });
1008
- }
904
+ /**
905
+ * @license
906
+ * Copyright 2017 Google LLC
907
+ *
908
+ * Licensed under the Apache License, Version 2.0 (the "License");
909
+ * you may not use this file except in compliance with the License.
910
+ * You may obtain a copy of the License at
911
+ *
912
+ * http://www.apache.org/licenses/LICENSE-2.0
913
+ *
914
+ * Unless required by applicable law or agreed to in writing, software
915
+ * distributed under the License is distributed on an "AS IS" BASIS,
916
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
917
+ * See the License for the specific language governing permissions and
918
+ * limitations under the License.
919
+ */
920
+ /**
921
+ * @fileoverview Standardized Firebase Error.
922
+ *
923
+ * Usage:
924
+ *
925
+ * // TypeScript string literals for type-safe codes
926
+ * type Err =
927
+ * 'unknown' |
928
+ * 'object-not-found'
929
+ * ;
930
+ *
931
+ * // Closure enum for type-safe error codes
932
+ * // at-enum {string}
933
+ * var Err = {
934
+ * UNKNOWN: 'unknown',
935
+ * OBJECT_NOT_FOUND: 'object-not-found',
936
+ * }
937
+ *
938
+ * let errors: Map<Err, string> = {
939
+ * 'generic-error': "Unknown error",
940
+ * 'file-not-found': "Could not find file: {$file}",
941
+ * };
942
+ *
943
+ * // Type-safe function - must pass a valid error code as param.
944
+ * let error = new ErrorFactory<Err>('service', 'Service', errors);
945
+ *
946
+ * ...
947
+ * throw error.create(Err.GENERIC);
948
+ * ...
949
+ * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});
950
+ * ...
951
+ * // Service: Could not file file: foo.txt (service/file-not-found).
952
+ *
953
+ * catch (e) {
954
+ * assert(e.message === "Could not find file: foo.txt.");
955
+ * if ((e as FirebaseError)?.code === 'service/file-not-found') {
956
+ * console.log("Could not read file: " + e['file']);
957
+ * }
958
+ * }
959
+ */
960
+ const ERROR_NAME = 'FirebaseError';
961
+ // Based on code from:
962
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types
963
+ class FirebaseError extends Error {
964
+ constructor(
965
+ /** The error code for this error. */
966
+ code, message,
967
+ /** Custom data for this error. */
968
+ customData) {
969
+ super(message);
970
+ this.code = code;
971
+ this.customData = customData;
972
+ /** The custom name for all FirebaseErrors. */
973
+ this.name = ERROR_NAME;
974
+ // Fix For ES5
975
+ // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
976
+ // TODO(dlarocque): Replace this with `new.target`: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget
977
+ // which we can now use since we no longer target ES5.
978
+ Object.setPrototypeOf(this, FirebaseError.prototype);
979
+ // Maintains proper stack trace for where our error was thrown.
980
+ // Only available on V8.
981
+ if (Error.captureStackTrace) {
982
+ Error.captureStackTrace(this, ErrorFactory.prototype.create);
983
+ }
984
+ }
985
+ }
986
+ class ErrorFactory {
987
+ constructor(service, serviceName, errors) {
988
+ this.service = service;
989
+ this.serviceName = serviceName;
990
+ this.errors = errors;
991
+ }
992
+ create(code, ...data) {
993
+ const customData = data[0] || {};
994
+ const fullCode = `${this.service}/${code}`;
995
+ const template = this.errors[code];
996
+ const message = template ? replaceTemplate(template, customData) : 'Error';
997
+ // Service Name: Error message (service/code).
998
+ const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;
999
+ const error = new FirebaseError(fullCode, fullMessage, customData);
1000
+ return error;
1001
+ }
1002
+ }
1003
+ function replaceTemplate(template, data) {
1004
+ return template.replace(PATTERN, (_, key) => {
1005
+ const value = data[key];
1006
+ return value != null ? String(value) : `<${key}?>`;
1007
+ });
1008
+ }
1009
1009
  const PATTERN = /\{\$([^}]+)}/g;
1010
1010
 
1011
- /**
1012
- * @license
1013
- * Copyright 2017 Google LLC
1014
- *
1015
- * Licensed under the Apache License, Version 2.0 (the "License");
1016
- * you may not use this file except in compliance with the License.
1017
- * You may obtain a copy of the License at
1018
- *
1019
- * http://www.apache.org/licenses/LICENSE-2.0
1020
- *
1021
- * Unless required by applicable law or agreed to in writing, software
1022
- * distributed under the License is distributed on an "AS IS" BASIS,
1023
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1024
- * See the License for the specific language governing permissions and
1025
- * limitations under the License.
1026
- */
1027
- /**
1028
- * Evaluates a JSON string into a javascript object.
1029
- *
1030
- * @param {string} str A string containing JSON.
1031
- * @return {*} The javascript object representing the specified JSON.
1032
- */
1033
- function jsonEval(str) {
1034
- return JSON.parse(str);
1035
- }
1036
- /**
1037
- * Returns JSON representing a javascript object.
1038
- * @param {*} data JavaScript object to be stringified.
1039
- * @return {string} The JSON contents of the object.
1040
- */
1041
- function stringify(data) {
1042
- return JSON.stringify(data);
1011
+ /**
1012
+ * @license
1013
+ * Copyright 2017 Google LLC
1014
+ *
1015
+ * Licensed under the Apache License, Version 2.0 (the "License");
1016
+ * you may not use this file except in compliance with the License.
1017
+ * You may obtain a copy of the License at
1018
+ *
1019
+ * http://www.apache.org/licenses/LICENSE-2.0
1020
+ *
1021
+ * Unless required by applicable law or agreed to in writing, software
1022
+ * distributed under the License is distributed on an "AS IS" BASIS,
1023
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1024
+ * See the License for the specific language governing permissions and
1025
+ * limitations under the License.
1026
+ */
1027
+ /**
1028
+ * Evaluates a JSON string into a javascript object.
1029
+ *
1030
+ * @param {string} str A string containing JSON.
1031
+ * @return {*} The javascript object representing the specified JSON.
1032
+ */
1033
+ function jsonEval(str) {
1034
+ return JSON.parse(str);
1035
+ }
1036
+ /**
1037
+ * Returns JSON representing a javascript object.
1038
+ * @param {*} data JavaScript object to be stringified.
1039
+ * @return {string} The JSON contents of the object.
1040
+ */
1041
+ function stringify(data) {
1042
+ return JSON.stringify(data);
1043
1043
  }
1044
1044
 
1045
- /**
1046
- * @license
1047
- * Copyright 2017 Google LLC
1048
- *
1049
- * Licensed under the Apache License, Version 2.0 (the "License");
1050
- * you may not use this file except in compliance with the License.
1051
- * You may obtain a copy of the License at
1052
- *
1053
- * http://www.apache.org/licenses/LICENSE-2.0
1054
- *
1055
- * Unless required by applicable law or agreed to in writing, software
1056
- * distributed under the License is distributed on an "AS IS" BASIS,
1057
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1058
- * See the License for the specific language governing permissions and
1059
- * limitations under the License.
1060
- */
1061
- /**
1062
- * Decodes a Firebase auth. token into constituent parts.
1063
- *
1064
- * Notes:
1065
- * - May return with invalid / incomplete claims if there's no native base64 decoding support.
1066
- * - Doesn't check if the token is actually valid.
1067
- */
1068
- const decode = function (token) {
1069
- let header = {}, claims = {}, data = {}, signature = '';
1070
- try {
1071
- const parts = token.split('.');
1072
- header = jsonEval(base64Decode(parts[0]) || '');
1073
- claims = jsonEval(base64Decode(parts[1]) || '');
1074
- signature = parts[2];
1075
- data = claims['d'] || {};
1076
- delete claims['d'];
1077
- }
1078
- catch (e) { }
1079
- return {
1080
- header,
1081
- claims,
1082
- data,
1083
- signature
1084
- };
1085
- };
1086
- /**
1087
- * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the
1088
- * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.
1089
- *
1090
- * Notes:
1091
- * - May return a false negative if there's no native base64 decoding support.
1092
- * - Doesn't check if the token is actually valid.
1093
- */
1094
- const isValidTimestamp = function (token) {
1095
- const claims = decode(token).claims;
1096
- const now = Math.floor(new Date().getTime() / 1000);
1097
- let validSince = 0, validUntil = 0;
1098
- if (typeof claims === 'object') {
1099
- if (claims.hasOwnProperty('nbf')) {
1100
- validSince = claims['nbf'];
1101
- }
1102
- else if (claims.hasOwnProperty('iat')) {
1103
- validSince = claims['iat'];
1104
- }
1105
- if (claims.hasOwnProperty('exp')) {
1106
- validUntil = claims['exp'];
1107
- }
1108
- else {
1109
- // token will expire after 24h by default
1110
- validUntil = validSince + 86400;
1111
- }
1112
- }
1113
- return (!!now &&
1114
- !!validSince &&
1115
- !!validUntil &&
1116
- now >= validSince &&
1117
- now <= validUntil);
1118
- };
1119
- /**
1120
- * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.
1121
- *
1122
- * Notes:
1123
- * - May return null if there's no native base64 decoding support.
1124
- * - Doesn't check if the token is actually valid.
1125
- */
1126
- const issuedAtTime = function (token) {
1127
- const claims = decode(token).claims;
1128
- if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {
1129
- return claims['iat'];
1130
- }
1131
- return null;
1132
- };
1133
- /**
1134
- * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.
1135
- *
1136
- * Notes:
1137
- * - May return a false negative if there's no native base64 decoding support.
1138
- * - Doesn't check if the token is actually valid.
1139
- */
1140
- const isValidFormat = function (token) {
1141
- const decoded = decode(token), claims = decoded.claims;
1142
- return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');
1143
- };
1144
- /**
1145
- * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.
1146
- *
1147
- * Notes:
1148
- * - May return a false negative if there's no native base64 decoding support.
1149
- * - Doesn't check if the token is actually valid.
1150
- */
1151
- const isAdmin = function (token) {
1152
- const claims = decode(token).claims;
1153
- return typeof claims === 'object' && claims['admin'] === true;
1045
+ /**
1046
+ * @license
1047
+ * Copyright 2017 Google LLC
1048
+ *
1049
+ * Licensed under the Apache License, Version 2.0 (the "License");
1050
+ * you may not use this file except in compliance with the License.
1051
+ * You may obtain a copy of the License at
1052
+ *
1053
+ * http://www.apache.org/licenses/LICENSE-2.0
1054
+ *
1055
+ * Unless required by applicable law or agreed to in writing, software
1056
+ * distributed under the License is distributed on an "AS IS" BASIS,
1057
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1058
+ * See the License for the specific language governing permissions and
1059
+ * limitations under the License.
1060
+ */
1061
+ /**
1062
+ * Decodes a Firebase auth. token into constituent parts.
1063
+ *
1064
+ * Notes:
1065
+ * - May return with invalid / incomplete claims if there's no native base64 decoding support.
1066
+ * - Doesn't check if the token is actually valid.
1067
+ */
1068
+ const decode = function (token) {
1069
+ let header = {}, claims = {}, data = {}, signature = '';
1070
+ try {
1071
+ const parts = token.split('.');
1072
+ header = jsonEval(base64Decode(parts[0]) || '');
1073
+ claims = jsonEval(base64Decode(parts[1]) || '');
1074
+ signature = parts[2];
1075
+ data = claims['d'] || {};
1076
+ delete claims['d'];
1077
+ }
1078
+ catch (e) { }
1079
+ return {
1080
+ header,
1081
+ claims,
1082
+ data,
1083
+ signature
1084
+ };
1085
+ };
1086
+ /**
1087
+ * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the
1088
+ * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.
1089
+ *
1090
+ * Notes:
1091
+ * - May return a false negative if there's no native base64 decoding support.
1092
+ * - Doesn't check if the token is actually valid.
1093
+ */
1094
+ const isValidTimestamp = function (token) {
1095
+ const claims = decode(token).claims;
1096
+ const now = Math.floor(new Date().getTime() / 1000);
1097
+ let validSince = 0, validUntil = 0;
1098
+ if (typeof claims === 'object') {
1099
+ if (claims.hasOwnProperty('nbf')) {
1100
+ validSince = claims['nbf'];
1101
+ }
1102
+ else if (claims.hasOwnProperty('iat')) {
1103
+ validSince = claims['iat'];
1104
+ }
1105
+ if (claims.hasOwnProperty('exp')) {
1106
+ validUntil = claims['exp'];
1107
+ }
1108
+ else {
1109
+ // token will expire after 24h by default
1110
+ validUntil = validSince + 86400;
1111
+ }
1112
+ }
1113
+ return (!!now &&
1114
+ !!validSince &&
1115
+ !!validUntil &&
1116
+ now >= validSince &&
1117
+ now <= validUntil);
1118
+ };
1119
+ /**
1120
+ * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.
1121
+ *
1122
+ * Notes:
1123
+ * - May return null if there's no native base64 decoding support.
1124
+ * - Doesn't check if the token is actually valid.
1125
+ */
1126
+ const issuedAtTime = function (token) {
1127
+ const claims = decode(token).claims;
1128
+ if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {
1129
+ return claims['iat'];
1130
+ }
1131
+ return null;
1132
+ };
1133
+ /**
1134
+ * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.
1135
+ *
1136
+ * Notes:
1137
+ * - May return a false negative if there's no native base64 decoding support.
1138
+ * - Doesn't check if the token is actually valid.
1139
+ */
1140
+ const isValidFormat = function (token) {
1141
+ const decoded = decode(token), claims = decoded.claims;
1142
+ return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');
1143
+ };
1144
+ /**
1145
+ * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.
1146
+ *
1147
+ * Notes:
1148
+ * - May return a false negative if there's no native base64 decoding support.
1149
+ * - Doesn't check if the token is actually valid.
1150
+ */
1151
+ const isAdmin = function (token) {
1152
+ const claims = decode(token).claims;
1153
+ return typeof claims === 'object' && claims['admin'] === true;
1154
1154
  };
1155
1155
 
1156
- /**
1157
- * @license
1158
- * Copyright 2017 Google LLC
1159
- *
1160
- * Licensed under the Apache License, Version 2.0 (the "License");
1161
- * you may not use this file except in compliance with the License.
1162
- * You may obtain a copy of the License at
1163
- *
1164
- * http://www.apache.org/licenses/LICENSE-2.0
1165
- *
1166
- * Unless required by applicable law or agreed to in writing, software
1167
- * distributed under the License is distributed on an "AS IS" BASIS,
1168
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1169
- * See the License for the specific language governing permissions and
1170
- * limitations under the License.
1171
- */
1172
- function contains(obj, key) {
1173
- return Object.prototype.hasOwnProperty.call(obj, key);
1174
- }
1175
- function safeGet(obj, key) {
1176
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
1177
- return obj[key];
1178
- }
1179
- else {
1180
- return undefined;
1181
- }
1182
- }
1183
- function isEmpty(obj) {
1184
- for (const key in obj) {
1185
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
1186
- return false;
1187
- }
1188
- }
1189
- return true;
1190
- }
1191
- function map(obj, fn, contextObj) {
1192
- const res = {};
1193
- for (const key in obj) {
1194
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
1195
- res[key] = fn.call(contextObj, obj[key], key, obj);
1196
- }
1197
- }
1198
- return res;
1199
- }
1200
- /**
1201
- * Deep equal two objects. Support Arrays and Objects.
1202
- */
1203
- function deepEqual(a, b) {
1204
- if (a === b) {
1205
- return true;
1206
- }
1207
- const aKeys = Object.keys(a);
1208
- const bKeys = Object.keys(b);
1209
- for (const k of aKeys) {
1210
- if (!bKeys.includes(k)) {
1211
- return false;
1212
- }
1213
- const aProp = a[k];
1214
- const bProp = b[k];
1215
- if (isObject(aProp) && isObject(bProp)) {
1216
- if (!deepEqual(aProp, bProp)) {
1217
- return false;
1218
- }
1219
- }
1220
- else if (aProp !== bProp) {
1221
- return false;
1222
- }
1223
- }
1224
- for (const k of bKeys) {
1225
- if (!aKeys.includes(k)) {
1226
- return false;
1227
- }
1228
- }
1229
- return true;
1230
- }
1231
- function isObject(thing) {
1232
- return thing !== null && typeof thing === 'object';
1156
+ /**
1157
+ * @license
1158
+ * Copyright 2017 Google LLC
1159
+ *
1160
+ * Licensed under the Apache License, Version 2.0 (the "License");
1161
+ * you may not use this file except in compliance with the License.
1162
+ * You may obtain a copy of the License at
1163
+ *
1164
+ * http://www.apache.org/licenses/LICENSE-2.0
1165
+ *
1166
+ * Unless required by applicable law or agreed to in writing, software
1167
+ * distributed under the License is distributed on an "AS IS" BASIS,
1168
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1169
+ * See the License for the specific language governing permissions and
1170
+ * limitations under the License.
1171
+ */
1172
+ function contains(obj, key) {
1173
+ return Object.prototype.hasOwnProperty.call(obj, key);
1174
+ }
1175
+ function safeGet(obj, key) {
1176
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
1177
+ return obj[key];
1178
+ }
1179
+ else {
1180
+ return undefined;
1181
+ }
1182
+ }
1183
+ function isEmpty(obj) {
1184
+ for (const key in obj) {
1185
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
1186
+ return false;
1187
+ }
1188
+ }
1189
+ return true;
1190
+ }
1191
+ function map(obj, fn, contextObj) {
1192
+ const res = {};
1193
+ for (const key in obj) {
1194
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
1195
+ res[key] = fn.call(contextObj, obj[key], key, obj);
1196
+ }
1197
+ }
1198
+ return res;
1199
+ }
1200
+ /**
1201
+ * Deep equal two objects. Support Arrays and Objects.
1202
+ */
1203
+ function deepEqual(a, b) {
1204
+ if (a === b) {
1205
+ return true;
1206
+ }
1207
+ const aKeys = Object.keys(a);
1208
+ const bKeys = Object.keys(b);
1209
+ for (const k of aKeys) {
1210
+ if (!bKeys.includes(k)) {
1211
+ return false;
1212
+ }
1213
+ const aProp = a[k];
1214
+ const bProp = b[k];
1215
+ if (isObject(aProp) && isObject(bProp)) {
1216
+ if (!deepEqual(aProp, bProp)) {
1217
+ return false;
1218
+ }
1219
+ }
1220
+ else if (aProp !== bProp) {
1221
+ return false;
1222
+ }
1223
+ }
1224
+ for (const k of bKeys) {
1225
+ if (!aKeys.includes(k)) {
1226
+ return false;
1227
+ }
1228
+ }
1229
+ return true;
1230
+ }
1231
+ function isObject(thing) {
1232
+ return thing !== null && typeof thing === 'object';
1233
1233
  }
1234
1234
 
1235
- /**
1236
- * @license
1237
- * Copyright 2022 Google LLC
1238
- *
1239
- * Licensed under the Apache License, Version 2.0 (the "License");
1240
- * you may not use this file except in compliance with the License.
1241
- * You may obtain a copy of the License at
1242
- *
1243
- * http://www.apache.org/licenses/LICENSE-2.0
1244
- *
1245
- * Unless required by applicable law or agreed to in writing, software
1246
- * distributed under the License is distributed on an "AS IS" BASIS,
1247
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248
- * See the License for the specific language governing permissions and
1249
- * limitations under the License.
1250
- */
1251
- /**
1252
- * Rejects if the given promise doesn't resolve in timeInMS milliseconds.
1253
- * @internal
1254
- */
1255
- function promiseWithTimeout(promise, timeInMS = 2000) {
1256
- const deferredPromise = new Deferred();
1257
- setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);
1258
- promise.then(deferredPromise.resolve, deferredPromise.reject);
1259
- return deferredPromise.promise;
1235
+ /**
1236
+ * @license
1237
+ * Copyright 2022 Google LLC
1238
+ *
1239
+ * Licensed under the Apache License, Version 2.0 (the "License");
1240
+ * you may not use this file except in compliance with the License.
1241
+ * You may obtain a copy of the License at
1242
+ *
1243
+ * http://www.apache.org/licenses/LICENSE-2.0
1244
+ *
1245
+ * Unless required by applicable law or agreed to in writing, software
1246
+ * distributed under the License is distributed on an "AS IS" BASIS,
1247
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248
+ * See the License for the specific language governing permissions and
1249
+ * limitations under the License.
1250
+ */
1251
+ /**
1252
+ * Rejects if the given promise doesn't resolve in timeInMS milliseconds.
1253
+ * @internal
1254
+ */
1255
+ function promiseWithTimeout(promise, timeInMS = 2000) {
1256
+ const deferredPromise = new Deferred();
1257
+ setTimeout(() => deferredPromise.reject('timeout!'), timeInMS);
1258
+ promise.then(deferredPromise.resolve, deferredPromise.reject);
1259
+ return deferredPromise.promise;
1260
1260
  }
1261
1261
 
1262
- /**
1263
- * @license
1264
- * Copyright 2017 Google LLC
1265
- *
1266
- * Licensed under the Apache License, Version 2.0 (the "License");
1267
- * you may not use this file except in compliance with the License.
1268
- * You may obtain a copy of the License at
1269
- *
1270
- * http://www.apache.org/licenses/LICENSE-2.0
1271
- *
1272
- * Unless required by applicable law or agreed to in writing, software
1273
- * distributed under the License is distributed on an "AS IS" BASIS,
1274
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1275
- * See the License for the specific language governing permissions and
1276
- * limitations under the License.
1277
- */
1278
- /**
1279
- * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a
1280
- * params object (e.g. {arg: 'val', arg2: 'val2'})
1281
- * Note: You must prepend it with ? when adding it to a URL.
1282
- */
1283
- function querystring(querystringParams) {
1284
- const params = [];
1285
- for (const [key, value] of Object.entries(querystringParams)) {
1286
- if (Array.isArray(value)) {
1287
- value.forEach(arrayVal => {
1288
- params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal));
1289
- });
1290
- }
1291
- else {
1292
- params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
1293
- }
1294
- }
1295
- return params.length ? '&' + params.join('&') : '';
1296
- }
1297
- /**
1298
- * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object
1299
- * (e.g. {arg: 'val', arg2: 'val2'})
1300
- */
1301
- function querystringDecode(querystring) {
1302
- const obj = {};
1303
- const tokens = querystring.replace(/^\?/, '').split('&');
1304
- tokens.forEach(token => {
1305
- if (token) {
1306
- const [key, value] = token.split('=');
1307
- obj[decodeURIComponent(key)] = decodeURIComponent(value);
1308
- }
1309
- });
1310
- return obj;
1311
- }
1312
- /**
1313
- * Extract the query string part of a URL, including the leading question mark (if present).
1314
- */
1315
- function extractQuerystring(url) {
1316
- const queryStart = url.indexOf('?');
1317
- if (!queryStart) {
1318
- return '';
1319
- }
1320
- const fragmentStart = url.indexOf('#', queryStart);
1321
- return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : undefined);
1262
+ /**
1263
+ * @license
1264
+ * Copyright 2017 Google LLC
1265
+ *
1266
+ * Licensed under the Apache License, Version 2.0 (the "License");
1267
+ * you may not use this file except in compliance with the License.
1268
+ * You may obtain a copy of the License at
1269
+ *
1270
+ * http://www.apache.org/licenses/LICENSE-2.0
1271
+ *
1272
+ * Unless required by applicable law or agreed to in writing, software
1273
+ * distributed under the License is distributed on an "AS IS" BASIS,
1274
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1275
+ * See the License for the specific language governing permissions and
1276
+ * limitations under the License.
1277
+ */
1278
+ /**
1279
+ * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a
1280
+ * params object (e.g. {arg: 'val', arg2: 'val2'})
1281
+ * Note: You must prepend it with ? when adding it to a URL.
1282
+ */
1283
+ function querystring(querystringParams) {
1284
+ const params = [];
1285
+ for (const [key, value] of Object.entries(querystringParams)) {
1286
+ if (Array.isArray(value)) {
1287
+ value.forEach(arrayVal => {
1288
+ params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal));
1289
+ });
1290
+ }
1291
+ else {
1292
+ params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
1293
+ }
1294
+ }
1295
+ return params.length ? '&' + params.join('&') : '';
1296
+ }
1297
+ /**
1298
+ * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object
1299
+ * (e.g. {arg: 'val', arg2: 'val2'})
1300
+ */
1301
+ function querystringDecode(querystring) {
1302
+ const obj = {};
1303
+ const tokens = querystring.replace(/^\?/, '').split('&');
1304
+ tokens.forEach(token => {
1305
+ if (token) {
1306
+ const [key, value] = token.split('=');
1307
+ obj[decodeURIComponent(key)] = decodeURIComponent(value);
1308
+ }
1309
+ });
1310
+ return obj;
1311
+ }
1312
+ /**
1313
+ * Extract the query string part of a URL, including the leading question mark (if present).
1314
+ */
1315
+ function extractQuerystring(url) {
1316
+ const queryStart = url.indexOf('?');
1317
+ if (!queryStart) {
1318
+ return '';
1319
+ }
1320
+ const fragmentStart = url.indexOf('#', queryStart);
1321
+ return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : undefined);
1322
1322
  }
1323
1323
 
1324
- /**
1325
- * @license
1326
- * Copyright 2017 Google LLC
1327
- *
1328
- * Licensed under the Apache License, Version 2.0 (the "License");
1329
- * you may not use this file except in compliance with the License.
1330
- * You may obtain a copy of the License at
1331
- *
1332
- * http://www.apache.org/licenses/LICENSE-2.0
1333
- *
1334
- * Unless required by applicable law or agreed to in writing, software
1335
- * distributed under the License is distributed on an "AS IS" BASIS,
1336
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1337
- * See the License for the specific language governing permissions and
1338
- * limitations under the License.
1339
- */
1340
- /**
1341
- * @fileoverview SHA-1 cryptographic hash.
1342
- * Variable names follow the notation in FIPS PUB 180-3:
1343
- * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.
1344
- *
1345
- * Usage:
1346
- * var sha1 = new sha1();
1347
- * sha1.update(bytes);
1348
- * var hash = sha1.digest();
1349
- *
1350
- * Performance:
1351
- * Chrome 23: ~400 Mbit/s
1352
- * Firefox 16: ~250 Mbit/s
1353
- *
1354
- */
1355
- /**
1356
- * SHA-1 cryptographic hash constructor.
1357
- *
1358
- * The properties declared here are discussed in the above algorithm document.
1359
- * @constructor
1360
- * @final
1361
- * @struct
1362
- */
1363
- class Sha1 {
1364
- constructor() {
1365
- /**
1366
- * Holds the previous values of accumulated variables a-e in the compress_
1367
- * function.
1368
- * @private
1369
- */
1370
- this.chain_ = [];
1371
- /**
1372
- * A buffer holding the partially computed hash result.
1373
- * @private
1374
- */
1375
- this.buf_ = [];
1376
- /**
1377
- * An array of 80 bytes, each a part of the message to be hashed. Referred to
1378
- * as the message schedule in the docs.
1379
- * @private
1380
- */
1381
- this.W_ = [];
1382
- /**
1383
- * Contains data needed to pad messages less than 64 bytes.
1384
- * @private
1385
- */
1386
- this.pad_ = [];
1387
- /**
1388
- * @private {number}
1389
- */
1390
- this.inbuf_ = 0;
1391
- /**
1392
- * @private {number}
1393
- */
1394
- this.total_ = 0;
1395
- this.blockSize = 512 / 8;
1396
- this.pad_[0] = 128;
1397
- for (let i = 1; i < this.blockSize; ++i) {
1398
- this.pad_[i] = 0;
1399
- }
1400
- this.reset();
1401
- }
1402
- reset() {
1403
- this.chain_[0] = 0x67452301;
1404
- this.chain_[1] = 0xefcdab89;
1405
- this.chain_[2] = 0x98badcfe;
1406
- this.chain_[3] = 0x10325476;
1407
- this.chain_[4] = 0xc3d2e1f0;
1408
- this.inbuf_ = 0;
1409
- this.total_ = 0;
1410
- }
1411
- /**
1412
- * Internal compress helper function.
1413
- * @param buf Block to compress.
1414
- * @param offset Offset of the block in the buffer.
1415
- * @private
1416
- */
1417
- compress_(buf, offset) {
1418
- if (!offset) {
1419
- offset = 0;
1420
- }
1421
- const W = this.W_;
1422
- // get 16 big endian words
1423
- if (typeof buf === 'string') {
1424
- for (let i = 0; i < 16; i++) {
1425
- // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS
1426
- // have a bug that turns the post-increment ++ operator into pre-increment
1427
- // during JIT compilation. We have code that depends heavily on SHA-1 for
1428
- // correctness and which is affected by this bug, so I've removed all uses
1429
- // of post-increment ++ in which the result value is used. We can revert
1430
- // this change once the Safari bug
1431
- // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and
1432
- // most clients have been updated.
1433
- W[i] =
1434
- (buf.charCodeAt(offset) << 24) |
1435
- (buf.charCodeAt(offset + 1) << 16) |
1436
- (buf.charCodeAt(offset + 2) << 8) |
1437
- buf.charCodeAt(offset + 3);
1438
- offset += 4;
1439
- }
1440
- }
1441
- else {
1442
- for (let i = 0; i < 16; i++) {
1443
- W[i] =
1444
- (buf[offset] << 24) |
1445
- (buf[offset + 1] << 16) |
1446
- (buf[offset + 2] << 8) |
1447
- buf[offset + 3];
1448
- offset += 4;
1449
- }
1450
- }
1451
- // expand to 80 words
1452
- for (let i = 16; i < 80; i++) {
1453
- const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
1454
- W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;
1455
- }
1456
- let a = this.chain_[0];
1457
- let b = this.chain_[1];
1458
- let c = this.chain_[2];
1459
- let d = this.chain_[3];
1460
- let e = this.chain_[4];
1461
- let f, k;
1462
- // TODO(user): Try to unroll this loop to speed up the computation.
1463
- for (let i = 0; i < 80; i++) {
1464
- if (i < 40) {
1465
- if (i < 20) {
1466
- f = d ^ (b & (c ^ d));
1467
- k = 0x5a827999;
1468
- }
1469
- else {
1470
- f = b ^ c ^ d;
1471
- k = 0x6ed9eba1;
1472
- }
1473
- }
1474
- else {
1475
- if (i < 60) {
1476
- f = (b & c) | (d & (b | c));
1477
- k = 0x8f1bbcdc;
1478
- }
1479
- else {
1480
- f = b ^ c ^ d;
1481
- k = 0xca62c1d6;
1482
- }
1483
- }
1484
- const t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;
1485
- e = d;
1486
- d = c;
1487
- c = ((b << 30) | (b >>> 2)) & 0xffffffff;
1488
- b = a;
1489
- a = t;
1490
- }
1491
- this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;
1492
- this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;
1493
- this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;
1494
- this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;
1495
- this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;
1496
- }
1497
- update(bytes, length) {
1498
- // TODO(johnlenz): tighten the function signature and remove this check
1499
- if (bytes == null) {
1500
- return;
1501
- }
1502
- if (length === undefined) {
1503
- length = bytes.length;
1504
- }
1505
- const lengthMinusBlock = length - this.blockSize;
1506
- let n = 0;
1507
- // Using local instead of member variables gives ~5% speedup on Firefox 16.
1508
- const buf = this.buf_;
1509
- let inbuf = this.inbuf_;
1510
- // The outer while loop should execute at most twice.
1511
- while (n < length) {
1512
- // When we have no data in the block to top up, we can directly process the
1513
- // input buffer (assuming it contains sufficient data). This gives ~25%
1514
- // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that
1515
- // the data is provided in large chunks (or in multiples of 64 bytes).
1516
- if (inbuf === 0) {
1517
- while (n <= lengthMinusBlock) {
1518
- this.compress_(bytes, n);
1519
- n += this.blockSize;
1520
- }
1521
- }
1522
- if (typeof bytes === 'string') {
1523
- while (n < length) {
1524
- buf[inbuf] = bytes.charCodeAt(n);
1525
- ++inbuf;
1526
- ++n;
1527
- if (inbuf === this.blockSize) {
1528
- this.compress_(buf);
1529
- inbuf = 0;
1530
- // Jump to the outer loop so we use the full-block optimization.
1531
- break;
1532
- }
1533
- }
1534
- }
1535
- else {
1536
- while (n < length) {
1537
- buf[inbuf] = bytes[n];
1538
- ++inbuf;
1539
- ++n;
1540
- if (inbuf === this.blockSize) {
1541
- this.compress_(buf);
1542
- inbuf = 0;
1543
- // Jump to the outer loop so we use the full-block optimization.
1544
- break;
1545
- }
1546
- }
1547
- }
1548
- }
1549
- this.inbuf_ = inbuf;
1550
- this.total_ += length;
1551
- }
1552
- /** @override */
1553
- digest() {
1554
- const digest = [];
1555
- let totalBits = this.total_ * 8;
1556
- // Add pad 0x80 0x00*.
1557
- if (this.inbuf_ < 56) {
1558
- this.update(this.pad_, 56 - this.inbuf_);
1559
- }
1560
- else {
1561
- this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));
1562
- }
1563
- // Add # bits.
1564
- for (let i = this.blockSize - 1; i >= 56; i--) {
1565
- this.buf_[i] = totalBits & 255;
1566
- totalBits /= 256; // Don't use bit-shifting here!
1567
- }
1568
- this.compress_(this.buf_);
1569
- let n = 0;
1570
- for (let i = 0; i < 5; i++) {
1571
- for (let j = 24; j >= 0; j -= 8) {
1572
- digest[n] = (this.chain_[i] >> j) & 255;
1573
- ++n;
1574
- }
1575
- }
1576
- return digest;
1577
- }
1324
+ /**
1325
+ * @license
1326
+ * Copyright 2017 Google LLC
1327
+ *
1328
+ * Licensed under the Apache License, Version 2.0 (the "License");
1329
+ * you may not use this file except in compliance with the License.
1330
+ * You may obtain a copy of the License at
1331
+ *
1332
+ * http://www.apache.org/licenses/LICENSE-2.0
1333
+ *
1334
+ * Unless required by applicable law or agreed to in writing, software
1335
+ * distributed under the License is distributed on an "AS IS" BASIS,
1336
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1337
+ * See the License for the specific language governing permissions and
1338
+ * limitations under the License.
1339
+ */
1340
+ /**
1341
+ * @fileoverview SHA-1 cryptographic hash.
1342
+ * Variable names follow the notation in FIPS PUB 180-3:
1343
+ * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.
1344
+ *
1345
+ * Usage:
1346
+ * var sha1 = new sha1();
1347
+ * sha1.update(bytes);
1348
+ * var hash = sha1.digest();
1349
+ *
1350
+ * Performance:
1351
+ * Chrome 23: ~400 Mbit/s
1352
+ * Firefox 16: ~250 Mbit/s
1353
+ *
1354
+ */
1355
+ /**
1356
+ * SHA-1 cryptographic hash constructor.
1357
+ *
1358
+ * The properties declared here are discussed in the above algorithm document.
1359
+ * @constructor
1360
+ * @final
1361
+ * @struct
1362
+ */
1363
+ class Sha1 {
1364
+ constructor() {
1365
+ /**
1366
+ * Holds the previous values of accumulated variables a-e in the compress_
1367
+ * function.
1368
+ * @private
1369
+ */
1370
+ this.chain_ = [];
1371
+ /**
1372
+ * A buffer holding the partially computed hash result.
1373
+ * @private
1374
+ */
1375
+ this.buf_ = [];
1376
+ /**
1377
+ * An array of 80 bytes, each a part of the message to be hashed. Referred to
1378
+ * as the message schedule in the docs.
1379
+ * @private
1380
+ */
1381
+ this.W_ = [];
1382
+ /**
1383
+ * Contains data needed to pad messages less than 64 bytes.
1384
+ * @private
1385
+ */
1386
+ this.pad_ = [];
1387
+ /**
1388
+ * @private {number}
1389
+ */
1390
+ this.inbuf_ = 0;
1391
+ /**
1392
+ * @private {number}
1393
+ */
1394
+ this.total_ = 0;
1395
+ this.blockSize = 512 / 8;
1396
+ this.pad_[0] = 128;
1397
+ for (let i = 1; i < this.blockSize; ++i) {
1398
+ this.pad_[i] = 0;
1399
+ }
1400
+ this.reset();
1401
+ }
1402
+ reset() {
1403
+ this.chain_[0] = 0x67452301;
1404
+ this.chain_[1] = 0xefcdab89;
1405
+ this.chain_[2] = 0x98badcfe;
1406
+ this.chain_[3] = 0x10325476;
1407
+ this.chain_[4] = 0xc3d2e1f0;
1408
+ this.inbuf_ = 0;
1409
+ this.total_ = 0;
1410
+ }
1411
+ /**
1412
+ * Internal compress helper function.
1413
+ * @param buf Block to compress.
1414
+ * @param offset Offset of the block in the buffer.
1415
+ * @private
1416
+ */
1417
+ compress_(buf, offset) {
1418
+ if (!offset) {
1419
+ offset = 0;
1420
+ }
1421
+ const W = this.W_;
1422
+ // get 16 big endian words
1423
+ if (typeof buf === 'string') {
1424
+ for (let i = 0; i < 16; i++) {
1425
+ // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS
1426
+ // have a bug that turns the post-increment ++ operator into pre-increment
1427
+ // during JIT compilation. We have code that depends heavily on SHA-1 for
1428
+ // correctness and which is affected by this bug, so I've removed all uses
1429
+ // of post-increment ++ in which the result value is used. We can revert
1430
+ // this change once the Safari bug
1431
+ // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and
1432
+ // most clients have been updated.
1433
+ W[i] =
1434
+ (buf.charCodeAt(offset) << 24) |
1435
+ (buf.charCodeAt(offset + 1) << 16) |
1436
+ (buf.charCodeAt(offset + 2) << 8) |
1437
+ buf.charCodeAt(offset + 3);
1438
+ offset += 4;
1439
+ }
1440
+ }
1441
+ else {
1442
+ for (let i = 0; i < 16; i++) {
1443
+ W[i] =
1444
+ (buf[offset] << 24) |
1445
+ (buf[offset + 1] << 16) |
1446
+ (buf[offset + 2] << 8) |
1447
+ buf[offset + 3];
1448
+ offset += 4;
1449
+ }
1450
+ }
1451
+ // expand to 80 words
1452
+ for (let i = 16; i < 80; i++) {
1453
+ const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
1454
+ W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;
1455
+ }
1456
+ let a = this.chain_[0];
1457
+ let b = this.chain_[1];
1458
+ let c = this.chain_[2];
1459
+ let d = this.chain_[3];
1460
+ let e = this.chain_[4];
1461
+ let f, k;
1462
+ // TODO(user): Try to unroll this loop to speed up the computation.
1463
+ for (let i = 0; i < 80; i++) {
1464
+ if (i < 40) {
1465
+ if (i < 20) {
1466
+ f = d ^ (b & (c ^ d));
1467
+ k = 0x5a827999;
1468
+ }
1469
+ else {
1470
+ f = b ^ c ^ d;
1471
+ k = 0x6ed9eba1;
1472
+ }
1473
+ }
1474
+ else {
1475
+ if (i < 60) {
1476
+ f = (b & c) | (d & (b | c));
1477
+ k = 0x8f1bbcdc;
1478
+ }
1479
+ else {
1480
+ f = b ^ c ^ d;
1481
+ k = 0xca62c1d6;
1482
+ }
1483
+ }
1484
+ const t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;
1485
+ e = d;
1486
+ d = c;
1487
+ c = ((b << 30) | (b >>> 2)) & 0xffffffff;
1488
+ b = a;
1489
+ a = t;
1490
+ }
1491
+ this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;
1492
+ this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;
1493
+ this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;
1494
+ this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;
1495
+ this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;
1496
+ }
1497
+ update(bytes, length) {
1498
+ // TODO(johnlenz): tighten the function signature and remove this check
1499
+ if (bytes == null) {
1500
+ return;
1501
+ }
1502
+ if (length === undefined) {
1503
+ length = bytes.length;
1504
+ }
1505
+ const lengthMinusBlock = length - this.blockSize;
1506
+ let n = 0;
1507
+ // Using local instead of member variables gives ~5% speedup on Firefox 16.
1508
+ const buf = this.buf_;
1509
+ let inbuf = this.inbuf_;
1510
+ // The outer while loop should execute at most twice.
1511
+ while (n < length) {
1512
+ // When we have no data in the block to top up, we can directly process the
1513
+ // input buffer (assuming it contains sufficient data). This gives ~25%
1514
+ // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that
1515
+ // the data is provided in large chunks (or in multiples of 64 bytes).
1516
+ if (inbuf === 0) {
1517
+ while (n <= lengthMinusBlock) {
1518
+ this.compress_(bytes, n);
1519
+ n += this.blockSize;
1520
+ }
1521
+ }
1522
+ if (typeof bytes === 'string') {
1523
+ while (n < length) {
1524
+ buf[inbuf] = bytes.charCodeAt(n);
1525
+ ++inbuf;
1526
+ ++n;
1527
+ if (inbuf === this.blockSize) {
1528
+ this.compress_(buf);
1529
+ inbuf = 0;
1530
+ // Jump to the outer loop so we use the full-block optimization.
1531
+ break;
1532
+ }
1533
+ }
1534
+ }
1535
+ else {
1536
+ while (n < length) {
1537
+ buf[inbuf] = bytes[n];
1538
+ ++inbuf;
1539
+ ++n;
1540
+ if (inbuf === this.blockSize) {
1541
+ this.compress_(buf);
1542
+ inbuf = 0;
1543
+ // Jump to the outer loop so we use the full-block optimization.
1544
+ break;
1545
+ }
1546
+ }
1547
+ }
1548
+ }
1549
+ this.inbuf_ = inbuf;
1550
+ this.total_ += length;
1551
+ }
1552
+ /** @override */
1553
+ digest() {
1554
+ const digest = [];
1555
+ let totalBits = this.total_ * 8;
1556
+ // Add pad 0x80 0x00*.
1557
+ if (this.inbuf_ < 56) {
1558
+ this.update(this.pad_, 56 - this.inbuf_);
1559
+ }
1560
+ else {
1561
+ this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));
1562
+ }
1563
+ // Add # bits.
1564
+ for (let i = this.blockSize - 1; i >= 56; i--) {
1565
+ this.buf_[i] = totalBits & 255;
1566
+ totalBits /= 256; // Don't use bit-shifting here!
1567
+ }
1568
+ this.compress_(this.buf_);
1569
+ let n = 0;
1570
+ for (let i = 0; i < 5; i++) {
1571
+ for (let j = 24; j >= 0; j -= 8) {
1572
+ digest[n] = (this.chain_[i] >> j) & 255;
1573
+ ++n;
1574
+ }
1575
+ }
1576
+ return digest;
1577
+ }
1578
1578
  }
1579
1579
 
1580
- /**
1581
- * Helper to make a Subscribe function (just like Promise helps make a
1582
- * Thenable).
1583
- *
1584
- * @param executor Function which can make calls to a single Observer
1585
- * as a proxy.
1586
- * @param onNoObservers Callback when count of Observers goes to zero.
1587
- */
1588
- function createSubscribe(executor, onNoObservers) {
1589
- const proxy = new ObserverProxy(executor, onNoObservers);
1590
- return proxy.subscribe.bind(proxy);
1591
- }
1592
- /**
1593
- * Implement fan-out for any number of Observers attached via a subscribe
1594
- * function.
1595
- */
1596
- class ObserverProxy {
1597
- /**
1598
- * @param executor Function which can make calls to a single Observer
1599
- * as a proxy.
1600
- * @param onNoObservers Callback when count of Observers goes to zero.
1601
- */
1602
- constructor(executor, onNoObservers) {
1603
- this.observers = [];
1604
- this.unsubscribes = [];
1605
- this.observerCount = 0;
1606
- // Micro-task scheduling by calling task.then().
1607
- this.task = Promise.resolve();
1608
- this.finalized = false;
1609
- this.onNoObservers = onNoObservers;
1610
- // Call the executor asynchronously so subscribers that are called
1611
- // synchronously after the creation of the subscribe function
1612
- // can still receive the very first value generated in the executor.
1613
- this.task
1614
- .then(() => {
1615
- executor(this);
1616
- })
1617
- .catch(e => {
1618
- this.error(e);
1619
- });
1620
- }
1621
- next(value) {
1622
- this.forEachObserver((observer) => {
1623
- observer.next(value);
1624
- });
1625
- }
1626
- error(error) {
1627
- this.forEachObserver((observer) => {
1628
- observer.error(error);
1629
- });
1630
- this.close(error);
1631
- }
1632
- complete() {
1633
- this.forEachObserver((observer) => {
1634
- observer.complete();
1635
- });
1636
- this.close();
1637
- }
1638
- /**
1639
- * Subscribe function that can be used to add an Observer to the fan-out list.
1640
- *
1641
- * - We require that no event is sent to a subscriber synchronously to their
1642
- * call to subscribe().
1643
- */
1644
- subscribe(nextOrObserver, error, complete) {
1645
- let observer;
1646
- if (nextOrObserver === undefined &&
1647
- error === undefined &&
1648
- complete === undefined) {
1649
- throw new Error('Missing Observer.');
1650
- }
1651
- // Assemble an Observer object when passed as callback functions.
1652
- if (implementsAnyMethods(nextOrObserver, [
1653
- 'next',
1654
- 'error',
1655
- 'complete'
1656
- ])) {
1657
- observer = nextOrObserver;
1658
- }
1659
- else {
1660
- observer = {
1661
- next: nextOrObserver,
1662
- error,
1663
- complete
1664
- };
1665
- }
1666
- if (observer.next === undefined) {
1667
- observer.next = noop;
1668
- }
1669
- if (observer.error === undefined) {
1670
- observer.error = noop;
1671
- }
1672
- if (observer.complete === undefined) {
1673
- observer.complete = noop;
1674
- }
1675
- const unsub = this.unsubscribeOne.bind(this, this.observers.length);
1676
- // Attempt to subscribe to a terminated Observable - we
1677
- // just respond to the Observer with the final error or complete
1678
- // event.
1679
- if (this.finalized) {
1680
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1681
- this.task.then(() => {
1682
- try {
1683
- if (this.finalError) {
1684
- observer.error(this.finalError);
1685
- }
1686
- else {
1687
- observer.complete();
1688
- }
1689
- }
1690
- catch (e) {
1691
- // nothing
1692
- }
1693
- return;
1694
- });
1695
- }
1696
- this.observers.push(observer);
1697
- return unsub;
1698
- }
1699
- // Unsubscribe is synchronous - we guarantee that no events are sent to
1700
- // any unsubscribed Observer.
1701
- unsubscribeOne(i) {
1702
- if (this.observers === undefined || this.observers[i] === undefined) {
1703
- return;
1704
- }
1705
- delete this.observers[i];
1706
- this.observerCount -= 1;
1707
- if (this.observerCount === 0 && this.onNoObservers !== undefined) {
1708
- this.onNoObservers(this);
1709
- }
1710
- }
1711
- forEachObserver(fn) {
1712
- if (this.finalized) {
1713
- // Already closed by previous event....just eat the additional values.
1714
- return;
1715
- }
1716
- // Since sendOne calls asynchronously - there is no chance that
1717
- // this.observers will become undefined.
1718
- for (let i = 0; i < this.observers.length; i++) {
1719
- this.sendOne(i, fn);
1720
- }
1721
- }
1722
- // Call the Observer via one of it's callback function. We are careful to
1723
- // confirm that the observe has not been unsubscribed since this asynchronous
1724
- // function had been queued.
1725
- sendOne(i, fn) {
1726
- // Execute the callback asynchronously
1727
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1728
- this.task.then(() => {
1729
- if (this.observers !== undefined && this.observers[i] !== undefined) {
1730
- try {
1731
- fn(this.observers[i]);
1732
- }
1733
- catch (e) {
1734
- // Ignore exceptions raised in Observers or missing methods of an
1735
- // Observer.
1736
- // Log error to console. b/31404806
1737
- if (typeof console !== 'undefined' && console.error) {
1738
- console.error(e);
1739
- }
1740
- }
1741
- }
1742
- });
1743
- }
1744
- close(err) {
1745
- if (this.finalized) {
1746
- return;
1747
- }
1748
- this.finalized = true;
1749
- if (err !== undefined) {
1750
- this.finalError = err;
1751
- }
1752
- // Proxy is no longer needed - garbage collect references
1753
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1754
- this.task.then(() => {
1755
- this.observers = undefined;
1756
- this.onNoObservers = undefined;
1757
- });
1758
- }
1759
- }
1760
- /** Turn synchronous function into one called asynchronously. */
1761
- // eslint-disable-next-line @typescript-eslint/ban-types
1762
- function async(fn, onError) {
1763
- return (...args) => {
1764
- Promise.resolve(true)
1765
- .then(() => {
1766
- fn(...args);
1767
- })
1768
- .catch((error) => {
1769
- if (onError) {
1770
- onError(error);
1771
- }
1772
- });
1773
- };
1774
- }
1775
- /**
1776
- * Return true if the object passed in implements any of the named methods.
1777
- */
1778
- function implementsAnyMethods(obj, methods) {
1779
- if (typeof obj !== 'object' || obj === null) {
1780
- return false;
1781
- }
1782
- for (const method of methods) {
1783
- if (method in obj && typeof obj[method] === 'function') {
1784
- return true;
1785
- }
1786
- }
1787
- return false;
1788
- }
1789
- function noop() {
1790
- // do nothing
1580
+ /**
1581
+ * Helper to make a Subscribe function (just like Promise helps make a
1582
+ * Thenable).
1583
+ *
1584
+ * @param executor Function which can make calls to a single Observer
1585
+ * as a proxy.
1586
+ * @param onNoObservers Callback when count of Observers goes to zero.
1587
+ */
1588
+ function createSubscribe(executor, onNoObservers) {
1589
+ const proxy = new ObserverProxy(executor, onNoObservers);
1590
+ return proxy.subscribe.bind(proxy);
1591
+ }
1592
+ /**
1593
+ * Implement fan-out for any number of Observers attached via a subscribe
1594
+ * function.
1595
+ */
1596
+ class ObserverProxy {
1597
+ /**
1598
+ * @param executor Function which can make calls to a single Observer
1599
+ * as a proxy.
1600
+ * @param onNoObservers Callback when count of Observers goes to zero.
1601
+ */
1602
+ constructor(executor, onNoObservers) {
1603
+ this.observers = [];
1604
+ this.unsubscribes = [];
1605
+ this.observerCount = 0;
1606
+ // Micro-task scheduling by calling task.then().
1607
+ this.task = Promise.resolve();
1608
+ this.finalized = false;
1609
+ this.onNoObservers = onNoObservers;
1610
+ // Call the executor asynchronously so subscribers that are called
1611
+ // synchronously after the creation of the subscribe function
1612
+ // can still receive the very first value generated in the executor.
1613
+ this.task
1614
+ .then(() => {
1615
+ executor(this);
1616
+ })
1617
+ .catch(e => {
1618
+ this.error(e);
1619
+ });
1620
+ }
1621
+ next(value) {
1622
+ this.forEachObserver((observer) => {
1623
+ observer.next(value);
1624
+ });
1625
+ }
1626
+ error(error) {
1627
+ this.forEachObserver((observer) => {
1628
+ observer.error(error);
1629
+ });
1630
+ this.close(error);
1631
+ }
1632
+ complete() {
1633
+ this.forEachObserver((observer) => {
1634
+ observer.complete();
1635
+ });
1636
+ this.close();
1637
+ }
1638
+ /**
1639
+ * Subscribe function that can be used to add an Observer to the fan-out list.
1640
+ *
1641
+ * - We require that no event is sent to a subscriber synchronously to their
1642
+ * call to subscribe().
1643
+ */
1644
+ subscribe(nextOrObserver, error, complete) {
1645
+ let observer;
1646
+ if (nextOrObserver === undefined &&
1647
+ error === undefined &&
1648
+ complete === undefined) {
1649
+ throw new Error('Missing Observer.');
1650
+ }
1651
+ // Assemble an Observer object when passed as callback functions.
1652
+ if (implementsAnyMethods(nextOrObserver, [
1653
+ 'next',
1654
+ 'error',
1655
+ 'complete'
1656
+ ])) {
1657
+ observer = nextOrObserver;
1658
+ }
1659
+ else {
1660
+ observer = {
1661
+ next: nextOrObserver,
1662
+ error,
1663
+ complete
1664
+ };
1665
+ }
1666
+ if (observer.next === undefined) {
1667
+ observer.next = noop;
1668
+ }
1669
+ if (observer.error === undefined) {
1670
+ observer.error = noop;
1671
+ }
1672
+ if (observer.complete === undefined) {
1673
+ observer.complete = noop;
1674
+ }
1675
+ const unsub = this.unsubscribeOne.bind(this, this.observers.length);
1676
+ // Attempt to subscribe to a terminated Observable - we
1677
+ // just respond to the Observer with the final error or complete
1678
+ // event.
1679
+ if (this.finalized) {
1680
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1681
+ this.task.then(() => {
1682
+ try {
1683
+ if (this.finalError) {
1684
+ observer.error(this.finalError);
1685
+ }
1686
+ else {
1687
+ observer.complete();
1688
+ }
1689
+ }
1690
+ catch (e) {
1691
+ // nothing
1692
+ }
1693
+ return;
1694
+ });
1695
+ }
1696
+ this.observers.push(observer);
1697
+ return unsub;
1698
+ }
1699
+ // Unsubscribe is synchronous - we guarantee that no events are sent to
1700
+ // any unsubscribed Observer.
1701
+ unsubscribeOne(i) {
1702
+ if (this.observers === undefined || this.observers[i] === undefined) {
1703
+ return;
1704
+ }
1705
+ delete this.observers[i];
1706
+ this.observerCount -= 1;
1707
+ if (this.observerCount === 0 && this.onNoObservers !== undefined) {
1708
+ this.onNoObservers(this);
1709
+ }
1710
+ }
1711
+ forEachObserver(fn) {
1712
+ if (this.finalized) {
1713
+ // Already closed by previous event....just eat the additional values.
1714
+ return;
1715
+ }
1716
+ // Since sendOne calls asynchronously - there is no chance that
1717
+ // this.observers will become undefined.
1718
+ for (let i = 0; i < this.observers.length; i++) {
1719
+ this.sendOne(i, fn);
1720
+ }
1721
+ }
1722
+ // Call the Observer via one of it's callback function. We are careful to
1723
+ // confirm that the observe has not been unsubscribed since this asynchronous
1724
+ // function had been queued.
1725
+ sendOne(i, fn) {
1726
+ // Execute the callback asynchronously
1727
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1728
+ this.task.then(() => {
1729
+ if (this.observers !== undefined && this.observers[i] !== undefined) {
1730
+ try {
1731
+ fn(this.observers[i]);
1732
+ }
1733
+ catch (e) {
1734
+ // Ignore exceptions raised in Observers or missing methods of an
1735
+ // Observer.
1736
+ // Log error to console. b/31404806
1737
+ if (typeof console !== 'undefined' && console.error) {
1738
+ console.error(e);
1739
+ }
1740
+ }
1741
+ }
1742
+ });
1743
+ }
1744
+ close(err) {
1745
+ if (this.finalized) {
1746
+ return;
1747
+ }
1748
+ this.finalized = true;
1749
+ if (err !== undefined) {
1750
+ this.finalError = err;
1751
+ }
1752
+ // Proxy is no longer needed - garbage collect references
1753
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1754
+ this.task.then(() => {
1755
+ this.observers = undefined;
1756
+ this.onNoObservers = undefined;
1757
+ });
1758
+ }
1759
+ }
1760
+ /** Turn synchronous function into one called asynchronously. */
1761
+ // eslint-disable-next-line @typescript-eslint/ban-types
1762
+ function async(fn, onError) {
1763
+ return (...args) => {
1764
+ Promise.resolve(true)
1765
+ .then(() => {
1766
+ fn(...args);
1767
+ })
1768
+ .catch((error) => {
1769
+ if (onError) {
1770
+ onError(error);
1771
+ }
1772
+ });
1773
+ };
1774
+ }
1775
+ /**
1776
+ * Return true if the object passed in implements any of the named methods.
1777
+ */
1778
+ function implementsAnyMethods(obj, methods) {
1779
+ if (typeof obj !== 'object' || obj === null) {
1780
+ return false;
1781
+ }
1782
+ for (const method of methods) {
1783
+ if (method in obj && typeof obj[method] === 'function') {
1784
+ return true;
1785
+ }
1786
+ }
1787
+ return false;
1788
+ }
1789
+ function noop() {
1790
+ // do nothing
1791
1791
  }
1792
1792
 
1793
- /**
1794
- * @license
1795
- * Copyright 2017 Google LLC
1796
- *
1797
- * Licensed under the Apache License, Version 2.0 (the "License");
1798
- * you may not use this file except in compliance with the License.
1799
- * You may obtain a copy of the License at
1800
- *
1801
- * http://www.apache.org/licenses/LICENSE-2.0
1802
- *
1803
- * Unless required by applicable law or agreed to in writing, software
1804
- * distributed under the License is distributed on an "AS IS" BASIS,
1805
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1806
- * See the License for the specific language governing permissions and
1807
- * limitations under the License.
1808
- */
1809
- /**
1810
- * Check to make sure the appropriate number of arguments are provided for a public function.
1811
- * Throws an error if it fails.
1812
- *
1813
- * @param fnName The function name
1814
- * @param minCount The minimum number of arguments to allow for the function call
1815
- * @param maxCount The maximum number of argument to allow for the function call
1816
- * @param argCount The actual number of arguments provided.
1817
- */
1818
- const validateArgCount = function (fnName, minCount, maxCount, argCount) {
1819
- let argError;
1820
- if (argCount < minCount) {
1821
- argError = 'at least ' + minCount;
1822
- }
1823
- else if (argCount > maxCount) {
1824
- argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;
1825
- }
1826
- if (argError) {
1827
- const error = fnName +
1828
- ' failed: Was called with ' +
1829
- argCount +
1830
- (argCount === 1 ? ' argument.' : ' arguments.') +
1831
- ' Expects ' +
1832
- argError +
1833
- '.';
1834
- throw new Error(error);
1835
- }
1836
- };
1837
- /**
1838
- * Generates a string to prefix an error message about failed argument validation
1839
- *
1840
- * @param fnName The function name
1841
- * @param argName The name of the argument
1842
- * @return The prefix to add to the error thrown for validation.
1843
- */
1844
- function errorPrefix(fnName, argName) {
1845
- return `${fnName} failed: ${argName} argument `;
1846
- }
1847
- /**
1848
- * @param fnName
1849
- * @param argumentNumber
1850
- * @param namespace
1851
- * @param optional
1852
- */
1853
- function validateNamespace(fnName, namespace, optional) {
1854
- if (optional && !namespace) {
1855
- return;
1856
- }
1857
- if (typeof namespace !== 'string') {
1858
- //TODO: I should do more validation here. We only allow certain chars in namespaces.
1859
- throw new Error(errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.');
1860
- }
1861
- }
1862
- function validateCallback(fnName, argumentName,
1863
- // eslint-disable-next-line @typescript-eslint/ban-types
1864
- callback, optional) {
1865
- if (optional && !callback) {
1866
- return;
1867
- }
1868
- if (typeof callback !== 'function') {
1869
- throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid function.');
1870
- }
1871
- }
1872
- function validateContextObject(fnName, argumentName, context, optional) {
1873
- if (optional && !context) {
1874
- return;
1875
- }
1876
- if (typeof context !== 'object' || context === null) {
1877
- throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid context object.');
1878
- }
1793
+ /**
1794
+ * @license
1795
+ * Copyright 2017 Google LLC
1796
+ *
1797
+ * Licensed under the Apache License, Version 2.0 (the "License");
1798
+ * you may not use this file except in compliance with the License.
1799
+ * You may obtain a copy of the License at
1800
+ *
1801
+ * http://www.apache.org/licenses/LICENSE-2.0
1802
+ *
1803
+ * Unless required by applicable law or agreed to in writing, software
1804
+ * distributed under the License is distributed on an "AS IS" BASIS,
1805
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1806
+ * See the License for the specific language governing permissions and
1807
+ * limitations under the License.
1808
+ */
1809
+ /**
1810
+ * Check to make sure the appropriate number of arguments are provided for a public function.
1811
+ * Throws an error if it fails.
1812
+ *
1813
+ * @param fnName The function name
1814
+ * @param minCount The minimum number of arguments to allow for the function call
1815
+ * @param maxCount The maximum number of argument to allow for the function call
1816
+ * @param argCount The actual number of arguments provided.
1817
+ */
1818
+ const validateArgCount = function (fnName, minCount, maxCount, argCount) {
1819
+ let argError;
1820
+ if (argCount < minCount) {
1821
+ argError = 'at least ' + minCount;
1822
+ }
1823
+ else if (argCount > maxCount) {
1824
+ argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;
1825
+ }
1826
+ if (argError) {
1827
+ const error = fnName +
1828
+ ' failed: Was called with ' +
1829
+ argCount +
1830
+ (argCount === 1 ? ' argument.' : ' arguments.') +
1831
+ ' Expects ' +
1832
+ argError +
1833
+ '.';
1834
+ throw new Error(error);
1835
+ }
1836
+ };
1837
+ /**
1838
+ * Generates a string to prefix an error message about failed argument validation
1839
+ *
1840
+ * @param fnName The function name
1841
+ * @param argName The name of the argument
1842
+ * @return The prefix to add to the error thrown for validation.
1843
+ */
1844
+ function errorPrefix(fnName, argName) {
1845
+ return `${fnName} failed: ${argName} argument `;
1846
+ }
1847
+ /**
1848
+ * @param fnName
1849
+ * @param argumentNumber
1850
+ * @param namespace
1851
+ * @param optional
1852
+ */
1853
+ function validateNamespace(fnName, namespace, optional) {
1854
+ if (optional && !namespace) {
1855
+ return;
1856
+ }
1857
+ if (typeof namespace !== 'string') {
1858
+ //TODO: I should do more validation here. We only allow certain chars in namespaces.
1859
+ throw new Error(errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.');
1860
+ }
1861
+ }
1862
+ function validateCallback(fnName, argumentName,
1863
+ // eslint-disable-next-line @typescript-eslint/ban-types
1864
+ callback, optional) {
1865
+ if (optional && !callback) {
1866
+ return;
1867
+ }
1868
+ if (typeof callback !== 'function') {
1869
+ throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid function.');
1870
+ }
1871
+ }
1872
+ function validateContextObject(fnName, argumentName, context, optional) {
1873
+ if (optional && !context) {
1874
+ return;
1875
+ }
1876
+ if (typeof context !== 'object' || context === null) {
1877
+ throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid context object.');
1878
+ }
1879
1879
  }
1880
1880
 
1881
- /**
1882
- * @license
1883
- * Copyright 2017 Google LLC
1884
- *
1885
- * Licensed under the Apache License, Version 2.0 (the "License");
1886
- * you may not use this file except in compliance with the License.
1887
- * You may obtain a copy of the License at
1888
- *
1889
- * http://www.apache.org/licenses/LICENSE-2.0
1890
- *
1891
- * Unless required by applicable law or agreed to in writing, software
1892
- * distributed under the License is distributed on an "AS IS" BASIS,
1893
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1894
- * See the License for the specific language governing permissions and
1895
- * limitations under the License.
1896
- */
1897
- // Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they
1898
- // automatically replaced '\r\n' with '\n', and they didn't handle surrogate pairs,
1899
- // so it's been modified.
1900
- // Note that not all Unicode characters appear as single characters in JavaScript strings.
1901
- // fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters
1902
- // use 2 characters in JavaScript. All 4-byte UTF-8 characters begin with a first
1903
- // character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate
1904
- // pair).
1905
- // See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3
1906
- /**
1907
- * @param {string} str
1908
- * @return {Array}
1909
- */
1910
- const stringToByteArray = function (str) {
1911
- const out = [];
1912
- let p = 0;
1913
- for (let i = 0; i < str.length; i++) {
1914
- let c = str.charCodeAt(i);
1915
- // Is this the lead surrogate in a surrogate pair?
1916
- if (c >= 0xd800 && c <= 0xdbff) {
1917
- const high = c - 0xd800; // the high 10 bits.
1918
- i++;
1919
- assert(i < str.length, 'Surrogate pair missing trail surrogate.');
1920
- const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.
1921
- c = 0x10000 + (high << 10) + low;
1922
- }
1923
- if (c < 128) {
1924
- out[p++] = c;
1925
- }
1926
- else if (c < 2048) {
1927
- out[p++] = (c >> 6) | 192;
1928
- out[p++] = (c & 63) | 128;
1929
- }
1930
- else if (c < 65536) {
1931
- out[p++] = (c >> 12) | 224;
1932
- out[p++] = ((c >> 6) & 63) | 128;
1933
- out[p++] = (c & 63) | 128;
1934
- }
1935
- else {
1936
- out[p++] = (c >> 18) | 240;
1937
- out[p++] = ((c >> 12) & 63) | 128;
1938
- out[p++] = ((c >> 6) & 63) | 128;
1939
- out[p++] = (c & 63) | 128;
1940
- }
1941
- }
1942
- return out;
1943
- };
1944
- /**
1945
- * Calculate length without actually converting; useful for doing cheaper validation.
1946
- * @param {string} str
1947
- * @return {number}
1948
- */
1949
- const stringLength = function (str) {
1950
- let p = 0;
1951
- for (let i = 0; i < str.length; i++) {
1952
- const c = str.charCodeAt(i);
1953
- if (c < 128) {
1954
- p++;
1955
- }
1956
- else if (c < 2048) {
1957
- p += 2;
1958
- }
1959
- else if (c >= 0xd800 && c <= 0xdbff) {
1960
- // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.
1961
- p += 4;
1962
- i++; // skip trail surrogate.
1963
- }
1964
- else {
1965
- p += 3;
1966
- }
1967
- }
1968
- return p;
1881
+ /**
1882
+ * @license
1883
+ * Copyright 2017 Google LLC
1884
+ *
1885
+ * Licensed under the Apache License, Version 2.0 (the "License");
1886
+ * you may not use this file except in compliance with the License.
1887
+ * You may obtain a copy of the License at
1888
+ *
1889
+ * http://www.apache.org/licenses/LICENSE-2.0
1890
+ *
1891
+ * Unless required by applicable law or agreed to in writing, software
1892
+ * distributed under the License is distributed on an "AS IS" BASIS,
1893
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1894
+ * See the License for the specific language governing permissions and
1895
+ * limitations under the License.
1896
+ */
1897
+ // Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they
1898
+ // automatically replaced '\r\n' with '\n', and they didn't handle surrogate pairs,
1899
+ // so it's been modified.
1900
+ // Note that not all Unicode characters appear as single characters in JavaScript strings.
1901
+ // fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters
1902
+ // use 2 characters in JavaScript. All 4-byte UTF-8 characters begin with a first
1903
+ // character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate
1904
+ // pair).
1905
+ // See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3
1906
+ /**
1907
+ * @param {string} str
1908
+ * @return {Array}
1909
+ */
1910
+ const stringToByteArray = function (str) {
1911
+ const out = [];
1912
+ let p = 0;
1913
+ for (let i = 0; i < str.length; i++) {
1914
+ let c = str.charCodeAt(i);
1915
+ // Is this the lead surrogate in a surrogate pair?
1916
+ if (c >= 0xd800 && c <= 0xdbff) {
1917
+ const high = c - 0xd800; // the high 10 bits.
1918
+ i++;
1919
+ assert(i < str.length, 'Surrogate pair missing trail surrogate.');
1920
+ const low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.
1921
+ c = 0x10000 + (high << 10) + low;
1922
+ }
1923
+ if (c < 128) {
1924
+ out[p++] = c;
1925
+ }
1926
+ else if (c < 2048) {
1927
+ out[p++] = (c >> 6) | 192;
1928
+ out[p++] = (c & 63) | 128;
1929
+ }
1930
+ else if (c < 65536) {
1931
+ out[p++] = (c >> 12) | 224;
1932
+ out[p++] = ((c >> 6) & 63) | 128;
1933
+ out[p++] = (c & 63) | 128;
1934
+ }
1935
+ else {
1936
+ out[p++] = (c >> 18) | 240;
1937
+ out[p++] = ((c >> 12) & 63) | 128;
1938
+ out[p++] = ((c >> 6) & 63) | 128;
1939
+ out[p++] = (c & 63) | 128;
1940
+ }
1941
+ }
1942
+ return out;
1943
+ };
1944
+ /**
1945
+ * Calculate length without actually converting; useful for doing cheaper validation.
1946
+ * @param {string} str
1947
+ * @return {number}
1948
+ */
1949
+ const stringLength = function (str) {
1950
+ let p = 0;
1951
+ for (let i = 0; i < str.length; i++) {
1952
+ const c = str.charCodeAt(i);
1953
+ if (c < 128) {
1954
+ p++;
1955
+ }
1956
+ else if (c < 2048) {
1957
+ p += 2;
1958
+ }
1959
+ else if (c >= 0xd800 && c <= 0xdbff) {
1960
+ // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.
1961
+ p += 4;
1962
+ i++; // skip trail surrogate.
1963
+ }
1964
+ else {
1965
+ p += 3;
1966
+ }
1967
+ }
1968
+ return p;
1969
1969
  };
1970
1970
 
1971
- /**
1972
- * @license
1973
- * Copyright 2022 Google LLC
1974
- *
1975
- * Licensed under the Apache License, Version 2.0 (the "License");
1976
- * you may not use this file except in compliance with the License.
1977
- * You may obtain a copy of the License at
1978
- *
1979
- * http://www.apache.org/licenses/LICENSE-2.0
1980
- *
1981
- * Unless required by applicable law or agreed to in writing, software
1982
- * distributed under the License is distributed on an "AS IS" BASIS,
1983
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1984
- * See the License for the specific language governing permissions and
1985
- * limitations under the License.
1986
- */
1987
- /**
1988
- * Copied from https://stackoverflow.com/a/2117523
1989
- * Generates a new uuid.
1990
- * @public
1991
- */
1992
- const uuidv4 = function () {
1993
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
1994
- const r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8;
1995
- return v.toString(16);
1996
- });
1971
+ /**
1972
+ * @license
1973
+ * Copyright 2022 Google LLC
1974
+ *
1975
+ * Licensed under the Apache License, Version 2.0 (the "License");
1976
+ * you may not use this file except in compliance with the License.
1977
+ * You may obtain a copy of the License at
1978
+ *
1979
+ * http://www.apache.org/licenses/LICENSE-2.0
1980
+ *
1981
+ * Unless required by applicable law or agreed to in writing, software
1982
+ * distributed under the License is distributed on an "AS IS" BASIS,
1983
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1984
+ * See the License for the specific language governing permissions and
1985
+ * limitations under the License.
1986
+ */
1987
+ /**
1988
+ * Copied from https://stackoverflow.com/a/2117523
1989
+ * Generates a new uuid.
1990
+ * @public
1991
+ */
1992
+ const uuidv4 = function () {
1993
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
1994
+ const r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8;
1995
+ return v.toString(16);
1996
+ });
1997
1997
  };
1998
1998
 
1999
- /**
2000
- * @license
2001
- * Copyright 2019 Google LLC
2002
- *
2003
- * Licensed under the Apache License, Version 2.0 (the "License");
2004
- * you may not use this file except in compliance with the License.
2005
- * You may obtain a copy of the License at
2006
- *
2007
- * http://www.apache.org/licenses/LICENSE-2.0
2008
- *
2009
- * Unless required by applicable law or agreed to in writing, software
2010
- * distributed under the License is distributed on an "AS IS" BASIS,
2011
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2012
- * See the License for the specific language governing permissions and
2013
- * limitations under the License.
2014
- */
2015
- /**
2016
- * The amount of milliseconds to exponentially increase.
2017
- */
2018
- const DEFAULT_INTERVAL_MILLIS = 1000;
2019
- /**
2020
- * The factor to backoff by.
2021
- * Should be a number greater than 1.
2022
- */
2023
- const DEFAULT_BACKOFF_FACTOR = 2;
2024
- /**
2025
- * The maximum milliseconds to increase to.
2026
- *
2027
- * <p>Visible for testing
2028
- */
2029
- const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.
2030
- /**
2031
- * The percentage of backoff time to randomize by.
2032
- * See
2033
- * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic
2034
- * for context.
2035
- *
2036
- * <p>Visible for testing
2037
- */
2038
- const RANDOM_FACTOR = 0.5;
2039
- /**
2040
- * Based on the backoff method from
2041
- * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.
2042
- * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.
2043
- */
2044
- function calculateBackoffMillis(backoffCount, intervalMillis = DEFAULT_INTERVAL_MILLIS, backoffFactor = DEFAULT_BACKOFF_FACTOR) {
2045
- // Calculates an exponentially increasing value.
2046
- // Deviation: calculates value from count and a constant interval, so we only need to save value
2047
- // and count to restore state.
2048
- const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);
2049
- // A random "fuzz" to avoid waves of retries.
2050
- // Deviation: randomFactor is required.
2051
- const randomWait = Math.round(
2052
- // A fraction of the backoff value to add/subtract.
2053
- // Deviation: changes multiplication order to improve readability.
2054
- RANDOM_FACTOR *
2055
- currBaseValue *
2056
- // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines
2057
- // if we add or subtract.
2058
- (Math.random() - 0.5) *
2059
- 2);
2060
- // Limits backoff to max to avoid effectively permanent backoff.
2061
- return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);
1999
+ /**
2000
+ * @license
2001
+ * Copyright 2019 Google LLC
2002
+ *
2003
+ * Licensed under the Apache License, Version 2.0 (the "License");
2004
+ * you may not use this file except in compliance with the License.
2005
+ * You may obtain a copy of the License at
2006
+ *
2007
+ * http://www.apache.org/licenses/LICENSE-2.0
2008
+ *
2009
+ * Unless required by applicable law or agreed to in writing, software
2010
+ * distributed under the License is distributed on an "AS IS" BASIS,
2011
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2012
+ * See the License for the specific language governing permissions and
2013
+ * limitations under the License.
2014
+ */
2015
+ /**
2016
+ * The amount of milliseconds to exponentially increase.
2017
+ */
2018
+ const DEFAULT_INTERVAL_MILLIS = 1000;
2019
+ /**
2020
+ * The factor to backoff by.
2021
+ * Should be a number greater than 1.
2022
+ */
2023
+ const DEFAULT_BACKOFF_FACTOR = 2;
2024
+ /**
2025
+ * The maximum milliseconds to increase to.
2026
+ *
2027
+ * <p>Visible for testing
2028
+ */
2029
+ const MAX_VALUE_MILLIS = 4 * 60 * 60 * 1000; // Four hours, like iOS and Android.
2030
+ /**
2031
+ * The percentage of backoff time to randomize by.
2032
+ * See
2033
+ * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic
2034
+ * for context.
2035
+ *
2036
+ * <p>Visible for testing
2037
+ */
2038
+ const RANDOM_FACTOR = 0.5;
2039
+ /**
2040
+ * Based on the backoff method from
2041
+ * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.
2042
+ * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.
2043
+ */
2044
+ function calculateBackoffMillis(backoffCount, intervalMillis = DEFAULT_INTERVAL_MILLIS, backoffFactor = DEFAULT_BACKOFF_FACTOR) {
2045
+ // Calculates an exponentially increasing value.
2046
+ // Deviation: calculates value from count and a constant interval, so we only need to save value
2047
+ // and count to restore state.
2048
+ const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);
2049
+ // A random "fuzz" to avoid waves of retries.
2050
+ // Deviation: randomFactor is required.
2051
+ const randomWait = Math.round(
2052
+ // A fraction of the backoff value to add/subtract.
2053
+ // Deviation: changes multiplication order to improve readability.
2054
+ RANDOM_FACTOR *
2055
+ currBaseValue *
2056
+ // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines
2057
+ // if we add or subtract.
2058
+ (Math.random() - 0.5) *
2059
+ 2);
2060
+ // Limits backoff to max to avoid effectively permanent backoff.
2061
+ return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);
2062
2062
  }
2063
2063
 
2064
- /**
2065
- * @license
2066
- * Copyright 2020 Google LLC
2067
- *
2068
- * Licensed under the Apache License, Version 2.0 (the "License");
2069
- * you may not use this file except in compliance with the License.
2070
- * You may obtain a copy of the License at
2071
- *
2072
- * http://www.apache.org/licenses/LICENSE-2.0
2073
- *
2074
- * Unless required by applicable law or agreed to in writing, software
2075
- * distributed under the License is distributed on an "AS IS" BASIS,
2076
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2077
- * See the License for the specific language governing permissions and
2078
- * limitations under the License.
2079
- */
2080
- /**
2081
- * Provide English ordinal letters after a number
2082
- */
2083
- function ordinal(i) {
2084
- if (!Number.isFinite(i)) {
2085
- return `${i}`;
2086
- }
2087
- return i + indicator(i);
2088
- }
2089
- function indicator(i) {
2090
- i = Math.abs(i);
2091
- const cent = i % 100;
2092
- if (cent >= 10 && cent <= 20) {
2093
- return 'th';
2094
- }
2095
- const dec = i % 10;
2096
- if (dec === 1) {
2097
- return 'st';
2098
- }
2099
- if (dec === 2) {
2100
- return 'nd';
2101
- }
2102
- if (dec === 3) {
2103
- return 'rd';
2104
- }
2105
- return 'th';
2064
+ /**
2065
+ * @license
2066
+ * Copyright 2020 Google LLC
2067
+ *
2068
+ * Licensed under the Apache License, Version 2.0 (the "License");
2069
+ * you may not use this file except in compliance with the License.
2070
+ * You may obtain a copy of the License at
2071
+ *
2072
+ * http://www.apache.org/licenses/LICENSE-2.0
2073
+ *
2074
+ * Unless required by applicable law or agreed to in writing, software
2075
+ * distributed under the License is distributed on an "AS IS" BASIS,
2076
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2077
+ * See the License for the specific language governing permissions and
2078
+ * limitations under the License.
2079
+ */
2080
+ /**
2081
+ * Provide English ordinal letters after a number
2082
+ */
2083
+ function ordinal(i) {
2084
+ if (!Number.isFinite(i)) {
2085
+ return `${i}`;
2086
+ }
2087
+ return i + indicator(i);
2088
+ }
2089
+ function indicator(i) {
2090
+ i = Math.abs(i);
2091
+ const cent = i % 100;
2092
+ if (cent >= 10 && cent <= 20) {
2093
+ return 'th';
2094
+ }
2095
+ const dec = i % 10;
2096
+ if (dec === 1) {
2097
+ return 'st';
2098
+ }
2099
+ if (dec === 2) {
2100
+ return 'nd';
2101
+ }
2102
+ if (dec === 3) {
2103
+ return 'rd';
2104
+ }
2105
+ return 'th';
2106
2106
  }
2107
2107
 
2108
- /**
2109
- * @license
2110
- * Copyright 2021 Google LLC
2111
- *
2112
- * Licensed under the Apache License, Version 2.0 (the "License");
2113
- * you may not use this file except in compliance with the License.
2114
- * You may obtain a copy of the License at
2115
- *
2116
- * http://www.apache.org/licenses/LICENSE-2.0
2117
- *
2118
- * Unless required by applicable law or agreed to in writing, software
2119
- * distributed under the License is distributed on an "AS IS" BASIS,
2120
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2121
- * See the License for the specific language governing permissions and
2122
- * limitations under the License.
2123
- */
2124
- function getModularInstance(service) {
2125
- if (service && service._delegate) {
2126
- return service._delegate;
2127
- }
2128
- else {
2129
- return service;
2130
- }
2108
+ /**
2109
+ * @license
2110
+ * Copyright 2021 Google LLC
2111
+ *
2112
+ * Licensed under the Apache License, Version 2.0 (the "License");
2113
+ * you may not use this file except in compliance with the License.
2114
+ * You may obtain a copy of the License at
2115
+ *
2116
+ * http://www.apache.org/licenses/LICENSE-2.0
2117
+ *
2118
+ * Unless required by applicable law or agreed to in writing, software
2119
+ * distributed under the License is distributed on an "AS IS" BASIS,
2120
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2121
+ * See the License for the specific language governing permissions and
2122
+ * limitations under the License.
2123
+ */
2124
+ function getModularInstance(service) {
2125
+ if (service && service._delegate) {
2126
+ return service._delegate;
2127
+ }
2128
+ else {
2129
+ return service;
2130
+ }
2131
2131
  }
2132
2132
 
2133
- /**
2134
- * @license
2135
- * Copyright 2017 Google LLC
2136
- *
2137
- * Licensed under the Apache License, Version 2.0 (the "License");
2138
- * you may not use this file except in compliance with the License.
2139
- * You may obtain a copy of the License at
2140
- *
2141
- * http://www.apache.org/licenses/LICENSE-2.0
2142
- *
2143
- * Unless required by applicable law or agreed to in writing, software
2144
- * distributed under the License is distributed on an "AS IS" BASIS,
2145
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2146
- * See the License for the specific language governing permissions and
2147
- * limitations under the License.
2148
- */
2149
- // Overriding the constant (we should be the only ones doing this)
2133
+ /**
2134
+ * @license
2135
+ * Copyright 2017 Google LLC
2136
+ *
2137
+ * Licensed under the Apache License, Version 2.0 (the "License");
2138
+ * you may not use this file except in compliance with the License.
2139
+ * You may obtain a copy of the License at
2140
+ *
2141
+ * http://www.apache.org/licenses/LICENSE-2.0
2142
+ *
2143
+ * Unless required by applicable law or agreed to in writing, software
2144
+ * distributed under the License is distributed on an "AS IS" BASIS,
2145
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2146
+ * See the License for the specific language governing permissions and
2147
+ * limitations under the License.
2148
+ */
2149
+ // Overriding the constant (we should be the only ones doing this)
2150
2150
  CONSTANTS.NODE_CLIENT = true;
2151
2151
 
2152
2152
  export { CONSTANTS, DecodeBase64StringError, Deferred, ErrorFactory, FirebaseError, MAX_VALUE_MILLIS, RANDOM_FACTOR, Sha1, areCookiesEnabled, assert, assertionError, async, base64, base64Decode, base64Encode, base64urlEncodeWithoutPadding, calculateBackoffMillis, contains, createMockUserToken, createSubscribe, decode, deepCopy, deepEqual, deepExtend, errorPrefix, extractQuerystring, getDefaultAppConfig, getDefaultEmulatorHost, getDefaultEmulatorHostnameAndPort, getDefaults, getExperimentalSetting, getGlobal, getModularInstance, getUA, isAdmin, isBrowser, isBrowserExtension, isCloudflareWorker, isElectron, isEmpty, isIE, isIndexedDBAvailable, isMobileCordova, isNode, isNodeSdk, isReactNative, isSafari, isUWP, isValidFormat, isValidTimestamp, isWebWorker, issuedAtTime, jsonEval, map, ordinal, promiseWithTimeout, querystring, querystringDecode, safeGet, stringLength, stringToByteArray, stringify, uuidv4, validateArgCount, validateCallback, validateContextObject, validateIndexedDBOpenable, validateNamespace };