bare-buffer 3.2.0 → 3.3.1
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.
- package/CMakeLists.txt +1 -1
- package/binding.c +124 -35
- package/global.d.ts +3 -0
- package/global.js +6 -1
- package/index.d.ts +3 -0
- package/index.js +13 -1
- package/lib/base64url.js +27 -0
- package/package.json +1 -1
- package/prebuilds/android-arm/bare-buffer.bare +0 -0
- package/prebuilds/android-arm64/bare-buffer.bare +0 -0
- package/prebuilds/android-ia32/bare-buffer.bare +0 -0
- package/prebuilds/android-x64/bare-buffer.bare +0 -0
- package/prebuilds/darwin-arm64/bare-buffer.bare +0 -0
- package/prebuilds/darwin-x64/bare-buffer.bare +0 -0
- package/prebuilds/ios-arm64/bare-buffer.bare +0 -0
- package/prebuilds/ios-arm64-simulator/bare-buffer.bare +0 -0
- package/prebuilds/ios-x64-simulator/bare-buffer.bare +0 -0
- package/prebuilds/linux-arm64/bare-buffer.bare +0 -0
- package/prebuilds/linux-x64/bare-buffer.bare +0 -0
- package/prebuilds/win32-arm64/bare-buffer.bare +0 -0
- package/prebuilds/win32-x64/bare-buffer.bare +0 -0
package/CMakeLists.txt
CHANGED
|
@@ -6,7 +6,7 @@ find_package(cmake-fetch REQUIRED PATHS node_modules/cmake-fetch)
|
|
|
6
6
|
project(bare_buffer C)
|
|
7
7
|
|
|
8
8
|
fetch_package("github:holepunchto/libutf#9509b28")
|
|
9
|
-
fetch_package("github:holepunchto/libbase64#
|
|
9
|
+
fetch_package("github:holepunchto/libbase64#86afd29")
|
|
10
10
|
fetch_package("github:holepunchto/libhex#1dfad95")
|
|
11
11
|
|
|
12
12
|
add_bare_module(bare_buffer)
|
package/binding.c
CHANGED
|
@@ -7,22 +7,26 @@
|
|
|
7
7
|
#include <string.h>
|
|
8
8
|
#include <utf.h>
|
|
9
9
|
|
|
10
|
+
static void
|
|
11
|
+
bare_buffer__on_finalize_string(js_env_t *env, void *data, void *finalize_hint) {
|
|
12
|
+
free(data);
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
static inline int
|
|
11
|
-
|
|
12
|
-
int
|
|
16
|
+
bare_buffer__get_info(js_env_t *env, js_value_t *buffer, void **data, size_t *len) {
|
|
17
|
+
int err;
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return 0;
|
|
18
|
-
}
|
|
19
|
+
bool is_shared;
|
|
20
|
+
err = js_is_sharedarraybuffer(env, buffer, &is_shared);
|
|
21
|
+
if (err < 0) return err;
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
if (is_shared) {
|
|
24
|
+
err = js_get_sharedarraybuffer_info(env, buffer, data, len);
|
|
25
|
+
} else {
|
|
26
|
+
err = js_get_arraybuffer_info(env, buffer, data, len);
|
|
27
|
+
}
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
bare_buffer__on_finalize_string(js_env_t *env, void *data, void *finalize_hint) {
|
|
25
|
-
free(data);
|
|
29
|
+
return err;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
static js_value_t *
|
|
@@ -122,7 +126,7 @@ bare_buffer_to_string_utf8(js_env_t *env, js_callback_info_t *info) {
|
|
|
122
126
|
assert(argc == 3);
|
|
123
127
|
|
|
124
128
|
utf8_t *buf;
|
|
125
|
-
err =
|
|
129
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
126
130
|
assert(err == 0);
|
|
127
131
|
|
|
128
132
|
int64_t offset;
|
|
@@ -156,7 +160,7 @@ bare_buffer_typed_write_utf8(
|
|
|
156
160
|
assert(err == 0);
|
|
157
161
|
|
|
158
162
|
utf8_t *buf;
|
|
159
|
-
err =
|
|
163
|
+
err = bare_buffer__get_info(env, handle, (void **) &buf, NULL);
|
|
160
164
|
assert(err == 0);
|
|
161
165
|
|
|
162
166
|
size_t str_len;
|
|
@@ -179,7 +183,7 @@ bare_buffer_write_utf8(js_env_t *env, js_callback_info_t *info) {
|
|
|
179
183
|
assert(argc == 4);
|
|
180
184
|
|
|
181
185
|
utf8_t *buf;
|
|
182
|
-
err =
|
|
186
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
183
187
|
assert(err == 0);
|
|
184
188
|
|
|
185
189
|
int64_t offset;
|
|
@@ -214,7 +218,7 @@ bare_buffer_to_string_utf16le(js_env_t *env, js_callback_info_t *info) {
|
|
|
214
218
|
assert(argc == 3);
|
|
215
219
|
|
|
216
220
|
utf16_t *buf;
|
|
217
|
-
err =
|
|
221
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
218
222
|
assert(err == 0);
|
|
219
223
|
|
|
220
224
|
int64_t offset;
|
|
@@ -251,7 +255,7 @@ bare_buffer_typed_write_utf16le(
|
|
|
251
255
|
assert(err == 0);
|
|
252
256
|
|
|
253
257
|
utf16_t *buf;
|
|
254
|
-
err =
|
|
258
|
+
err = bare_buffer__get_info(env, handle, (void **) &buf, NULL);
|
|
255
259
|
assert(err == 0);
|
|
256
260
|
|
|
257
261
|
offset /= sizeof(utf16_t);
|
|
@@ -279,7 +283,7 @@ bare_buffer_write_utf16le(js_env_t *env, js_callback_info_t *info) {
|
|
|
279
283
|
assert(argc == 4);
|
|
280
284
|
|
|
281
285
|
utf16_t *buf;
|
|
282
|
-
err =
|
|
286
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
283
287
|
assert(err == 0);
|
|
284
288
|
|
|
285
289
|
int64_t offset;
|
|
@@ -319,7 +323,7 @@ bare_buffer_to_string_latin1(js_env_t *env, js_callback_info_t *info) {
|
|
|
319
323
|
assert(argc == 3);
|
|
320
324
|
|
|
321
325
|
latin1_t *buf;
|
|
322
|
-
err =
|
|
326
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
323
327
|
assert(err == 0);
|
|
324
328
|
|
|
325
329
|
int64_t offset;
|
|
@@ -353,7 +357,7 @@ bare_buffer_typed_write_latin1(
|
|
|
353
357
|
assert(err == 0);
|
|
354
358
|
|
|
355
359
|
latin1_t *buf;
|
|
356
|
-
err =
|
|
360
|
+
err = bare_buffer__get_info(env, handle, (void **) &buf, NULL);
|
|
357
361
|
assert(err == 0);
|
|
358
362
|
|
|
359
363
|
size_t str_len;
|
|
@@ -376,7 +380,7 @@ bare_buffer_write_latin1(js_env_t *env, js_callback_info_t *info) {
|
|
|
376
380
|
assert(argc == 4);
|
|
377
381
|
|
|
378
382
|
latin1_t *buf;
|
|
379
|
-
err =
|
|
383
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
380
384
|
assert(err == 0);
|
|
381
385
|
|
|
382
386
|
int64_t offset;
|
|
@@ -411,7 +415,7 @@ bare_buffer_to_string_base64(js_env_t *env, js_callback_info_t *info) {
|
|
|
411
415
|
assert(argc == 3);
|
|
412
416
|
|
|
413
417
|
utf8_t *buf;
|
|
414
|
-
err =
|
|
418
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
415
419
|
assert(err == 0);
|
|
416
420
|
|
|
417
421
|
int64_t offset;
|
|
@@ -437,6 +441,45 @@ bare_buffer_to_string_base64(js_env_t *env, js_callback_info_t *info) {
|
|
|
437
441
|
return result;
|
|
438
442
|
}
|
|
439
443
|
|
|
444
|
+
static js_value_t *
|
|
445
|
+
bare_buffer_to_string_base64url(js_env_t *env, js_callback_info_t *info) {
|
|
446
|
+
int err;
|
|
447
|
+
|
|
448
|
+
size_t argc = 3;
|
|
449
|
+
js_value_t *argv[3];
|
|
450
|
+
|
|
451
|
+
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
452
|
+
assert(err == 0);
|
|
453
|
+
|
|
454
|
+
assert(argc == 3);
|
|
455
|
+
|
|
456
|
+
utf8_t *buf;
|
|
457
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
458
|
+
assert(err == 0);
|
|
459
|
+
|
|
460
|
+
int64_t offset;
|
|
461
|
+
err = js_get_value_int64(env, argv[1], &offset);
|
|
462
|
+
assert(err == 0);
|
|
463
|
+
|
|
464
|
+
int64_t len;
|
|
465
|
+
err = js_get_value_int64(env, argv[2], &len);
|
|
466
|
+
assert(err == 0);
|
|
467
|
+
|
|
468
|
+
size_t str_len;
|
|
469
|
+
err = base64url_encode_utf8(&buf[offset], len, NULL, &str_len);
|
|
470
|
+
assert(err == 0);
|
|
471
|
+
|
|
472
|
+
utf8_t *str = malloc(str_len);
|
|
473
|
+
err = base64url_encode_utf8(&buf[offset], len, str, &str_len);
|
|
474
|
+
assert(err == 0);
|
|
475
|
+
|
|
476
|
+
js_value_t *result;
|
|
477
|
+
err = js_create_external_string_latin1(env, str, str_len, bare_buffer__on_finalize_string, NULL, &result, NULL);
|
|
478
|
+
assert(err == 0);
|
|
479
|
+
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
|
|
440
483
|
static int64_t
|
|
441
484
|
bare_buffer_typed_write_base64(
|
|
442
485
|
js_value_t *receiver,
|
|
@@ -453,7 +496,7 @@ bare_buffer_typed_write_base64(
|
|
|
453
496
|
assert(err == 0);
|
|
454
497
|
|
|
455
498
|
utf8_t *buf;
|
|
456
|
-
err =
|
|
499
|
+
err = bare_buffer__get_info(env, handle, (void **) &buf, NULL);
|
|
457
500
|
assert(err == 0);
|
|
458
501
|
|
|
459
502
|
js_string_encoding_t encoding;
|
|
@@ -468,10 +511,18 @@ bare_buffer_typed_write_base64(
|
|
|
468
511
|
|
|
469
512
|
if (encoding == js_utf16le) {
|
|
470
513
|
err = base64_decode_utf16le(str, str_len, &buf[offset], &written);
|
|
471
|
-
assert(err == 0);
|
|
472
514
|
} else {
|
|
473
515
|
err = base64_decode_utf8(str, str_len, &buf[offset], &written);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (err != 0) {
|
|
519
|
+
err = js_throw_error(env, NULL, "Invalid input");
|
|
520
|
+
assert(err == 0);
|
|
521
|
+
|
|
522
|
+
err = js_release_string_view(env, str_view);
|
|
474
523
|
assert(err == 0);
|
|
524
|
+
|
|
525
|
+
return 0;
|
|
475
526
|
}
|
|
476
527
|
|
|
477
528
|
err = js_release_string_view(env, str_view);
|
|
@@ -493,7 +544,7 @@ bare_buffer_write_base64(js_env_t *env, js_callback_info_t *info) {
|
|
|
493
544
|
assert(argc == 4);
|
|
494
545
|
|
|
495
546
|
utf8_t *buf;
|
|
496
|
-
err =
|
|
547
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
497
548
|
assert(err == 0);
|
|
498
549
|
|
|
499
550
|
int64_t offset;
|
|
@@ -516,10 +567,18 @@ bare_buffer_write_base64(js_env_t *env, js_callback_info_t *info) {
|
|
|
516
567
|
|
|
517
568
|
if (encoding == js_utf16le) {
|
|
518
569
|
err = base64_decode_utf16le(str, str_len, &buf[offset], &written);
|
|
519
|
-
assert(err == 0);
|
|
520
570
|
} else {
|
|
521
571
|
err = base64_decode_utf8(str, str_len, &buf[offset], &written);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (err != 0) {
|
|
575
|
+
err = js_throw_error(env, NULL, "Invalid input");
|
|
522
576
|
assert(err == 0);
|
|
577
|
+
|
|
578
|
+
err = js_release_string_view(env, str_view);
|
|
579
|
+
assert(err == 0);
|
|
580
|
+
|
|
581
|
+
return NULL;
|
|
523
582
|
}
|
|
524
583
|
|
|
525
584
|
err = js_release_string_view(env, str_view);
|
|
@@ -545,7 +604,7 @@ bare_buffer_to_string_hex(js_env_t *env, js_callback_info_t *info) {
|
|
|
545
604
|
assert(argc == 3);
|
|
546
605
|
|
|
547
606
|
utf8_t *buf;
|
|
548
|
-
err =
|
|
607
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
549
608
|
assert(err == 0);
|
|
550
609
|
|
|
551
610
|
int64_t offset;
|
|
@@ -587,7 +646,7 @@ bare_buffer_typed_write_hex(
|
|
|
587
646
|
assert(err == 0);
|
|
588
647
|
|
|
589
648
|
utf8_t *buf;
|
|
590
|
-
err =
|
|
649
|
+
err = bare_buffer__get_info(env, handle, (void **) &buf, NULL);
|
|
591
650
|
assert(err == 0);
|
|
592
651
|
|
|
593
652
|
js_string_encoding_t encoding;
|
|
@@ -602,10 +661,18 @@ bare_buffer_typed_write_hex(
|
|
|
602
661
|
|
|
603
662
|
if (encoding == js_utf16le) {
|
|
604
663
|
err = hex_decode_utf16le(str, str_len, &buf[offset], &written);
|
|
605
|
-
assert(err == 0);
|
|
606
664
|
} else {
|
|
607
665
|
err = hex_decode_utf8(str, str_len, &buf[offset], &written);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if (err != 0) {
|
|
669
|
+
err = js_throw_error(env, NULL, "Invalid input");
|
|
608
670
|
assert(err == 0);
|
|
671
|
+
|
|
672
|
+
err = js_release_string_view(env, str_view);
|
|
673
|
+
assert(err == 0);
|
|
674
|
+
|
|
675
|
+
return 0;
|
|
609
676
|
}
|
|
610
677
|
|
|
611
678
|
err = js_release_string_view(env, str_view);
|
|
@@ -627,7 +694,7 @@ bare_buffer_write_hex(js_env_t *env, js_callback_info_t *info) {
|
|
|
627
694
|
assert(argc == 4);
|
|
628
695
|
|
|
629
696
|
utf8_t *buf;
|
|
630
|
-
err =
|
|
697
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &buf, NULL);
|
|
631
698
|
assert(err == 0);
|
|
632
699
|
|
|
633
700
|
int64_t offset;
|
|
@@ -650,10 +717,18 @@ bare_buffer_write_hex(js_env_t *env, js_callback_info_t *info) {
|
|
|
650
717
|
|
|
651
718
|
if (encoding == js_utf16le) {
|
|
652
719
|
err = hex_decode_utf16le(str, str_len, &buf[offset], &written);
|
|
653
|
-
assert(err == 0);
|
|
654
720
|
} else {
|
|
655
721
|
err = hex_decode_utf8(str, str_len, &buf[offset], &written);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
if (err != 0) {
|
|
725
|
+
err = js_throw_error(env, NULL, "Invalid input");
|
|
726
|
+
assert(err == 0);
|
|
727
|
+
|
|
728
|
+
err = js_release_string_view(env, str_view);
|
|
656
729
|
assert(err == 0);
|
|
730
|
+
|
|
731
|
+
return NULL;
|
|
657
732
|
}
|
|
658
733
|
|
|
659
734
|
err = js_release_string_view(env, str_view);
|
|
@@ -666,6 +741,19 @@ bare_buffer_write_hex(js_env_t *env, js_callback_info_t *info) {
|
|
|
666
741
|
return result;
|
|
667
742
|
}
|
|
668
743
|
|
|
744
|
+
static inline int
|
|
745
|
+
bare_buffer__memcmp(void *a, size_t a_len, void *b, size_t b_len) {
|
|
746
|
+
int r = memcmp(a, b, a_len < b_len ? a_len : b_len);
|
|
747
|
+
|
|
748
|
+
if (r == 0) {
|
|
749
|
+
if (a_len < b_len) return -1;
|
|
750
|
+
if (a_len > b_len) return 1;
|
|
751
|
+
return 0;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
return r < 0 ? -1 : 1;
|
|
755
|
+
}
|
|
756
|
+
|
|
669
757
|
static int32_t
|
|
670
758
|
bare_buffer_typed_compare(
|
|
671
759
|
js_value_t *receiver,
|
|
@@ -684,11 +772,11 @@ bare_buffer_typed_compare(
|
|
|
684
772
|
assert(err == 0);
|
|
685
773
|
|
|
686
774
|
uint8_t *a;
|
|
687
|
-
err =
|
|
775
|
+
err = bare_buffer__get_info(env, a_handle, (void **) &a, NULL);
|
|
688
776
|
assert(err == 0);
|
|
689
777
|
|
|
690
778
|
uint8_t *b;
|
|
691
|
-
err =
|
|
779
|
+
err = bare_buffer__get_info(env, b_handle, (void **) &b, NULL);
|
|
692
780
|
assert(err == 0);
|
|
693
781
|
|
|
694
782
|
return bare_buffer__memcmp(&a[a_offset], a_len, &b[b_offset], b_len);
|
|
@@ -707,7 +795,7 @@ bare_buffer_compare(js_env_t *env, js_callback_info_t *info) {
|
|
|
707
795
|
assert(argc == 6);
|
|
708
796
|
|
|
709
797
|
uint8_t *a;
|
|
710
|
-
err =
|
|
798
|
+
err = bare_buffer__get_info(env, argv[0], (void **) &a, NULL);
|
|
711
799
|
assert(err == 0);
|
|
712
800
|
|
|
713
801
|
int64_t a_offset;
|
|
@@ -719,7 +807,7 @@ bare_buffer_compare(js_env_t *env, js_callback_info_t *info) {
|
|
|
719
807
|
assert(err == 0);
|
|
720
808
|
|
|
721
809
|
uint8_t *b;
|
|
722
|
-
err =
|
|
810
|
+
err = bare_buffer__get_info(env, argv[3], (void **) &b, NULL);
|
|
723
811
|
assert(err == 0);
|
|
724
812
|
|
|
725
813
|
int64_t b_offset;
|
|
@@ -864,6 +952,7 @@ bare_buffer_exports(js_env_t *env, js_value_t *exports) {
|
|
|
864
952
|
);
|
|
865
953
|
|
|
866
954
|
V("toStringBase64", bare_buffer_to_string_base64, NULL, NULL);
|
|
955
|
+
V("toStringBase64URL", bare_buffer_to_string_base64url, NULL, NULL);
|
|
867
956
|
|
|
868
957
|
V(
|
|
869
958
|
"writeBase64",
|
package/global.d.ts
CHANGED
package/global.js
CHANGED
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const constants = require('./lib/constants')
|
|
2
2
|
const ascii = require('./lib/ascii')
|
|
3
3
|
const base64 = require('./lib/base64')
|
|
4
|
+
const base64url = require('./lib/base64url')
|
|
4
5
|
const hex = require('./lib/hex')
|
|
5
6
|
const utf8 = require('./lib/utf8')
|
|
6
7
|
const utf16le = require('./lib/utf16le')
|
|
@@ -536,6 +537,7 @@ const codecs = Object.create(null)
|
|
|
536
537
|
|
|
537
538
|
codecs.ascii = ascii
|
|
538
539
|
codecs.base64 = base64
|
|
540
|
+
codecs.base64url = base64url
|
|
539
541
|
codecs.hex = hex
|
|
540
542
|
codecs.utf8 = codecs['utf-8'] = utf8
|
|
541
543
|
codecs.utf16le = codecs.ucs2 = codecs['utf-16le'] = codecs['ucs-2'] = utf16le
|
|
@@ -548,7 +550,7 @@ function codecFor(encoding = 'utf8') {
|
|
|
548
550
|
|
|
549
551
|
if (encoding in codecs) return codecs[encoding]
|
|
550
552
|
|
|
551
|
-
throw new Error(`Unknown encoding
|
|
553
|
+
throw new Error(`Unknown encoding '${encoding}'`)
|
|
552
554
|
}
|
|
553
555
|
|
|
554
556
|
const views = new WeakMap()
|
|
@@ -740,3 +742,13 @@ function swap(buffer, n, m) {
|
|
|
740
742
|
buffer[n] = buffer[m]
|
|
741
743
|
buffer[m] = i
|
|
742
744
|
}
|
|
745
|
+
|
|
746
|
+
exports.atob = function atob(data) {
|
|
747
|
+
return Buffer.from(data, 'base64').toString('latin1')
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
exports.btoa = function btoa(data) {
|
|
751
|
+
if (typeof data !== 'string') data = String(data)
|
|
752
|
+
|
|
753
|
+
return Buffer.from(data, 'latin1').toString('base64')
|
|
754
|
+
}
|
package/lib/base64url.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const binding = require('../binding')
|
|
2
|
+
|
|
3
|
+
exports.byteLength = function byteLength(string) {
|
|
4
|
+
let len = string.length
|
|
5
|
+
|
|
6
|
+
if (string.charCodeAt(len - 1) === 0x3d) len--
|
|
7
|
+
if (len > 1 && string.charCodeAt(len - 1) === 0x3d) len--
|
|
8
|
+
|
|
9
|
+
return (len * 3) >>> 2
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
exports.toString = function toString(buffer) {
|
|
13
|
+
return binding.toStringBase64URL(
|
|
14
|
+
buffer.buffer,
|
|
15
|
+
buffer.byteOffset,
|
|
16
|
+
buffer.byteLength
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.write = function write(buffer, string) {
|
|
21
|
+
return binding.writeBase64(
|
|
22
|
+
buffer.buffer,
|
|
23
|
+
buffer.byteOffset,
|
|
24
|
+
buffer.byteLength,
|
|
25
|
+
string
|
|
26
|
+
)
|
|
27
|
+
}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|