@gisatcz/deckgl-geolib 2.4.0-dev.5 → 2.4.0
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/dist/cjs/index.js +463 -1027
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +2 -2
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/esm/index.js +463 -1027
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +2 -2
- package/dist/esm/index.min.js.map +1 -1
- package/package.json +2 -2
package/dist/esm/index.js
CHANGED
|
@@ -445,31 +445,30 @@ function findTagsByName(xml, tagName, options) {
|
|
|
445
445
|
return tags;
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
DOUBLE: /** @type {12} */ (0x000c),
|
|
448
|
+
const fieldTypes = Object.freeze({
|
|
449
|
+
BYTE: 0x0001,
|
|
450
|
+
ASCII: 0x0002,
|
|
451
|
+
SHORT: 0x0003,
|
|
452
|
+
LONG: 0x0004,
|
|
453
|
+
RATIONAL: 0x0005,
|
|
454
|
+
SBYTE: 0x0006,
|
|
455
|
+
UNDEFINED: 0x0007,
|
|
456
|
+
SSHORT: 0x0008,
|
|
457
|
+
SLONG: 0x0009,
|
|
458
|
+
SRATIONAL: 0x000a,
|
|
459
|
+
FLOAT: 0x000b,
|
|
460
|
+
DOUBLE: 0x000c,
|
|
462
461
|
// IFD offset, suggested by https://owl.phy.queensu.ca/~phil/exiftool/standards.html
|
|
463
|
-
IFD:
|
|
462
|
+
IFD: 0x000d,
|
|
464
463
|
// introduced by BigTIFF
|
|
465
|
-
LONG8:
|
|
466
|
-
SLONG8:
|
|
467
|
-
IFD8:
|
|
468
|
-
};
|
|
464
|
+
LONG8: 0x0010,
|
|
465
|
+
SLONG8: 0x0011,
|
|
466
|
+
IFD8: 0x0012,
|
|
467
|
+
});
|
|
469
468
|
/** @typedef {keyof fieldTypes} FieldTypeName */
|
|
470
469
|
/** @typedef {fieldTypes[keyof typeof fieldTypes]} FieldType */
|
|
471
470
|
/** @typedef {Record<FieldTypeName, number>} FieldTypeSizes */
|
|
472
|
-
const fieldTypeSizes =
|
|
471
|
+
const fieldTypeSizes = Object.freeze({
|
|
473
472
|
[fieldTypes.BYTE]: 1,
|
|
474
473
|
[fieldTypes.ASCII]: 1,
|
|
475
474
|
[fieldTypes.SBYTE]: 1,
|
|
@@ -501,196 +500,219 @@ function getFieldTypeSize(fieldType) {
|
|
|
501
500
|
}
|
|
502
501
|
return size;
|
|
503
502
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
503
|
+
const tagSource = [
|
|
504
|
+
{ tag: 254, name: 'NewSubfileType', fieldTypes: fieldTypes.LONG },
|
|
505
|
+
{ tag: 255, name: 'SubfileType', type: fieldTypes.SHORT },
|
|
506
|
+
{ tag: 256, name: 'ImageWidth', type: fieldTypes.SHORT },
|
|
507
|
+
{ tag: 257, name: 'ImageLength', type: fieldTypes.SHORT },
|
|
508
|
+
{
|
|
509
|
+
tag: 258,
|
|
510
|
+
name: 'BitsPerSample',
|
|
511
|
+
type: fieldTypes.SHORT,
|
|
512
|
+
isArray: true,
|
|
513
|
+
eager: true,
|
|
514
|
+
},
|
|
515
|
+
{ tag: 259, name: 'Compression', type: fieldTypes.SHORT },
|
|
516
|
+
{ tag: 262, name: 'PhotometricInterpretation', type: fieldTypes.SHORT },
|
|
517
|
+
{ tag: 263, name: 'Threshholding', type: fieldTypes.SHORT },
|
|
518
|
+
{ tag: 264, name: 'CellWidth', type: fieldTypes.SHORT },
|
|
519
|
+
{ tag: 265, name: 'CellLength', type: fieldTypes.SHORT },
|
|
520
|
+
{ tag: 266, name: 'FillOrder', type: fieldTypes.SHORT },
|
|
521
|
+
{ tag: 269, name: 'DocumentName', type: fieldTypes.ASCII },
|
|
522
|
+
{ tag: 270, name: 'ImageDescription', type: fieldTypes.ASCII },
|
|
523
|
+
{ tag: 271, name: 'Make', type: fieldTypes.ASCII },
|
|
524
|
+
{ tag: 272, name: 'Model', type: fieldTypes.ASCII },
|
|
525
|
+
{ tag: 273, name: 'StripOffsets', type: fieldTypes.SHORT, isArray: true },
|
|
526
|
+
{ tag: 274, name: 'Orientation', type: fieldTypes.SHORT },
|
|
527
|
+
{ tag: 277, name: 'SamplesPerPixel', type: fieldTypes.SHORT },
|
|
528
|
+
{ tag: 278, name: 'RowsPerStrip', type: fieldTypes.SHORT },
|
|
529
|
+
{ tag: 279, name: 'StripByteCounts', type: fieldTypes.LONG, isArray: true },
|
|
530
|
+
{ tag: 280, name: 'MinSampleValue', type: fieldTypes.SHORT, isArray: true },
|
|
531
|
+
{ tag: 281, name: 'MaxSampleValue', type: fieldTypes.SHORT, isArray: true },
|
|
532
|
+
{ tag: 282, name: 'XResolution', type: fieldTypes.RATIONAL },
|
|
533
|
+
{ tag: 283, name: 'YResolution', type: fieldTypes.RATIONAL },
|
|
534
|
+
{ tag: 284, name: 'PlanarConfiguration', fieldTypes: fieldTypes.SHORT },
|
|
535
|
+
{ tag: 285, name: 'PageName', type: fieldTypes.ASCII },
|
|
536
|
+
{ tag: 286, name: 'XPosition', type: fieldTypes.RATIONAL },
|
|
537
|
+
{ tag: 287, name: 'YPosition', type: fieldTypes.RATIONAL },
|
|
538
|
+
{ tag: 288, name: 'FreeOffsets', type: fieldTypes.LONG },
|
|
539
|
+
{ tag: 289, name: 'FreeByteCounts', type: fieldTypes.LONG },
|
|
540
|
+
{ tag: 290, name: 'GrayResponseUnit', type: fieldTypes.SHORT },
|
|
541
|
+
{
|
|
542
|
+
tag: 291,
|
|
543
|
+
name: 'GrayResponseCurve',
|
|
544
|
+
type: fieldTypes.SHORT,
|
|
545
|
+
isArray: true,
|
|
546
|
+
},
|
|
547
|
+
{ tag: 292, name: 'T4Options', type: fieldTypes.LONG },
|
|
548
|
+
{ tag: 293, name: 'T6Options', type: fieldTypes.LONG },
|
|
549
|
+
{ tag: 296, name: 'ResolutionUnit', type: fieldTypes.SHORT },
|
|
550
|
+
{ tag: 297, name: 'PageNumber', type: fieldTypes.SHORT, isArray: true },
|
|
551
|
+
{ tag: 301, name: 'TransferFunction', type: fieldTypes.SHORT, isArray: true },
|
|
552
|
+
{ tag: 305, name: 'Software', type: fieldTypes.ASCII },
|
|
553
|
+
{ tag: 306, name: 'DateTime', type: fieldTypes.ASCII },
|
|
554
|
+
{ tag: 315, name: 'Artist', type: fieldTypes.ASCII },
|
|
555
|
+
{ tag: 316, name: 'HostComputer', type: fieldTypes.ASCII },
|
|
556
|
+
{ tag: 317, name: 'Predictor', type: fieldTypes.SHORT },
|
|
557
|
+
{ tag: 318, name: 'WhitePoint', type: fieldTypes.RATIONAL, isArray: true },
|
|
558
|
+
{
|
|
559
|
+
tag: 319,
|
|
560
|
+
name: 'PrimaryChromaticities',
|
|
561
|
+
type: fieldTypes.RATIONAL,
|
|
562
|
+
isArray: true,
|
|
563
|
+
},
|
|
564
|
+
{ tag: 320, name: 'ColorMap', type: fieldTypes.SHORT, isArray: true },
|
|
565
|
+
{ tag: 321, name: 'HalftoneHints', type: fieldTypes.SHORT, isArray: true },
|
|
566
|
+
{ tag: 322, name: 'TileWidth', type: fieldTypes.SHORT },
|
|
567
|
+
{ tag: 323, name: 'TileLength', type: fieldTypes.SHORT },
|
|
568
|
+
{ tag: 324, name: 'TileOffsets', type: fieldTypes.LONG, isArray: true },
|
|
569
|
+
{ tag: 325, name: 'TileByteCounts', type: fieldTypes.SHORT, isArray: true },
|
|
570
|
+
{ tag: 332, name: 'InkSet', type: fieldTypes.SHORT },
|
|
571
|
+
{ tag: 333, name: 'InkNames', type: fieldTypes.ASCII },
|
|
572
|
+
{ tag: 334, name: 'NumberOfInks', type: fieldTypes.SHORT },
|
|
573
|
+
{ tag: 336, name: 'DotRange', type: fieldTypes.BYTE, isArray: true },
|
|
574
|
+
{ tag: 337, name: 'TargetPrinter', type: fieldTypes.ASCII },
|
|
575
|
+
{ tag: 338, name: 'ExtraSamples', type: fieldTypes.BYTE, isArray: true },
|
|
576
|
+
{
|
|
577
|
+
tag: 339,
|
|
578
|
+
name: 'SampleFormat',
|
|
579
|
+
type: fieldTypes.SHORT,
|
|
580
|
+
isArray: true,
|
|
581
|
+
eager: true,
|
|
582
|
+
},
|
|
583
|
+
{ tag: 340, name: 'SMinSampleValue', isArray: true },
|
|
584
|
+
{ tag: 341, name: 'SMaxSampleValue', isArray: true },
|
|
585
|
+
{ tag: 342, name: 'TransferRange', type: fieldTypes.SHORT, isArray: true },
|
|
586
|
+
{ tag: 512, name: 'JPEGProc', type: fieldTypes.SHORT },
|
|
587
|
+
{ tag: 513, name: 'JPEGInterchangeFormat', type: fieldTypes.LONG },
|
|
588
|
+
{ tag: 514, name: 'JPEGInterchangeFormatLngth', type: fieldTypes.LONG },
|
|
589
|
+
{ tag: 515, name: 'JPEGRestartInterval', type: fieldTypes.SHORT },
|
|
590
|
+
{
|
|
591
|
+
tag: 517,
|
|
592
|
+
name: 'JPEGLosslessPredictors',
|
|
593
|
+
type: fieldTypes.SHORT,
|
|
594
|
+
isArray: true,
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
tag: 518,
|
|
598
|
+
name: 'JPEGPointTransforms',
|
|
599
|
+
type: fieldTypes.SHORT,
|
|
600
|
+
isArray: true,
|
|
601
|
+
},
|
|
602
|
+
{ tag: 519, name: 'JPEGQTables', type: fieldTypes.LONG, isArray: true },
|
|
603
|
+
{ tag: 520, name: 'JPEGDCTables', type: fieldTypes.LONG, isArray: true },
|
|
604
|
+
{ tag: 521, name: 'JPEGACTables', type: fieldTypes.LONG, isArray: true },
|
|
605
|
+
{
|
|
606
|
+
tag: 529,
|
|
607
|
+
name: 'YCbCrCoefficients',
|
|
608
|
+
type: fieldTypes.RATIONAL,
|
|
609
|
+
isArray: true,
|
|
610
|
+
},
|
|
611
|
+
{ tag: 530, name: 'YCbCrSubSampling', type: fieldTypes.SHORT, isArray: true },
|
|
612
|
+
{ tag: 531, name: 'YCbCrPositioning', type: fieldTypes.SHORT },
|
|
613
|
+
{
|
|
614
|
+
tag: 532,
|
|
615
|
+
name: 'ReferenceBlackWhite',
|
|
616
|
+
type: fieldTypes.LONG,
|
|
617
|
+
isArray: true,
|
|
618
|
+
},
|
|
619
|
+
{ tag: 33432, name: 'Copyright', type: fieldTypes.ASCII },
|
|
620
|
+
// TIFF Extended
|
|
621
|
+
{ tag: 326, name: 'BadFaxLines' },
|
|
622
|
+
{ tag: 327, name: 'CleanFaxData' },
|
|
623
|
+
{ tag: 343, name: 'ClipPath' },
|
|
624
|
+
{ tag: 328, name: 'ConsecutiveBadFaxLines' },
|
|
625
|
+
{ tag: 433, name: 'Decode' },
|
|
626
|
+
{ tag: 434, name: 'DefaultImageColor' },
|
|
627
|
+
{ tag: 346, name: 'Indexed' },
|
|
628
|
+
{ tag: 347, name: 'JPEGTables', isArray: true, eager: true },
|
|
629
|
+
{ tag: 559, name: 'StripRowCounts', isArray: true },
|
|
630
|
+
{ tag: 330, name: 'SubIFDs', isArray: true },
|
|
631
|
+
{ tag: 344, name: 'XClipPathUnits' },
|
|
632
|
+
{ tag: 345, name: 'YClipPathUnits' },
|
|
633
|
+
// EXIF
|
|
634
|
+
{ tag: 37378, name: 'ApertureValue' },
|
|
635
|
+
{ tag: 40961, name: 'ColorSpace' },
|
|
636
|
+
{ tag: 36868, name: 'DateTimeDigitized' },
|
|
637
|
+
{ tag: 36867, name: 'DateTimeOriginal' },
|
|
638
|
+
{ tag: 34665, name: 'Exif IFD', type: fieldTypes.LONG },
|
|
639
|
+
{ tag: 36864, name: 'ExifVersion' },
|
|
640
|
+
{ tag: 33434, name: 'ExposureTime' },
|
|
641
|
+
{ tag: 41728, name: 'FileSource' },
|
|
642
|
+
{ tag: 37385, name: 'Flash' },
|
|
643
|
+
{ tag: 40960, name: 'FlashpixVersion' },
|
|
644
|
+
{ tag: 33437, name: 'FNumber' },
|
|
645
|
+
{ tag: 42016, name: 'ImageUniqueID' },
|
|
646
|
+
{ tag: 37384, name: 'LightSource' },
|
|
647
|
+
{ tag: 37500, name: 'MakerNote' },
|
|
648
|
+
{ tag: 37377, name: 'ShutterSpeedValue' },
|
|
649
|
+
{ tag: 37510, name: 'UserComment' },
|
|
650
|
+
// IPTC
|
|
651
|
+
{ tag: 33723, name: 'IPTC' },
|
|
652
|
+
// Laser Scanning Microscopy
|
|
653
|
+
{ tag: 34412, name: 'CZ_LSMINFO' },
|
|
654
|
+
// ICC
|
|
655
|
+
{ tag: 34675, name: 'ICC Profile' },
|
|
656
|
+
// XMP
|
|
657
|
+
{ tag: 700, name: 'XMP' },
|
|
658
|
+
// GDAL
|
|
659
|
+
{ tag: 42112, name: 'GDAL_METADATA' },
|
|
660
|
+
{ tag: 42113, name: 'GDAL_NODATA', type: fieldTypes.ASCII },
|
|
661
|
+
// Photoshop
|
|
662
|
+
{ tag: 34377, name: 'Photoshop' },
|
|
663
|
+
// GeoTiff
|
|
664
|
+
{
|
|
665
|
+
tag: 33550,
|
|
666
|
+
name: 'ModelPixelScale',
|
|
667
|
+
type: fieldTypes.DOUBLE,
|
|
668
|
+
isArray: true,
|
|
669
|
+
eager: true,
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
tag: 33922,
|
|
673
|
+
name: 'ModelTiepoint',
|
|
674
|
+
type: fieldTypes.DOUBLE,
|
|
675
|
+
isArray: true,
|
|
676
|
+
eager: true,
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
tag: 34264,
|
|
680
|
+
name: 'ModelTransformation',
|
|
681
|
+
type: fieldTypes.DOUBLE,
|
|
682
|
+
isArray: true,
|
|
683
|
+
eager: true,
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
tag: 34735,
|
|
687
|
+
name: 'GeoKeyDirectory',
|
|
688
|
+
type: fieldTypes.SHORT,
|
|
689
|
+
isArray: true,
|
|
690
|
+
eager: true,
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
tag: 34736,
|
|
694
|
+
name: 'GeoDoubleParams',
|
|
695
|
+
type: fieldTypes.DOUBLE,
|
|
696
|
+
isArray: true,
|
|
697
|
+
eager: true,
|
|
698
|
+
},
|
|
699
|
+
{ tag: 34737, name: 'GeoAsciiParams', type: fieldTypes.ASCII, eager: true },
|
|
700
|
+
// LERC
|
|
701
|
+
{ tag: 50674, name: 'LercParameters', eager: true },
|
|
702
|
+
];
|
|
679
703
|
/**
|
|
680
704
|
* Maps tag names to their numeric values
|
|
681
|
-
* @type {Record<string, number>}
|
|
682
705
|
*/
|
|
683
706
|
const tags = {};
|
|
684
707
|
/**
|
|
685
708
|
* Maps tag numbers to their definitions
|
|
686
|
-
* @type {Record<number, { tag: number, name: string, type: string|number|undefined, isArray: boolean, eager: boolean }>}
|
|
687
709
|
*/
|
|
688
710
|
const tagDefinitions = {};
|
|
689
711
|
/**
|
|
690
712
|
* Registers a new field tag
|
|
691
713
|
* @param {number} tag the numeric tiff tag
|
|
692
714
|
* @param {string} name the name of the tag that will be reported in the IFD
|
|
693
|
-
* @param {
|
|
715
|
+
* @param {string|number|undefined} type the tags data type
|
|
694
716
|
* @param {Boolean} isArray whether the tag is an array
|
|
695
717
|
* @param {boolean} [eager=false] whether to eagerly fetch deferred fields.
|
|
696
718
|
* When false (default), tags are loaded lazily on-demand.
|
|
@@ -700,9 +722,8 @@ function registerTag(tag, name, type, isArray = false, eager = false) {
|
|
|
700
722
|
tags[name] = tag;
|
|
701
723
|
tagDefinitions[tag] = { tag, name, type: typeof type === 'string' ? fieldTypes[type] : type, isArray, eager };
|
|
702
724
|
}
|
|
703
|
-
for (const
|
|
704
|
-
|
|
705
|
-
registerTag(entry.tag, entry.name || key, entry.type, entry.isArray, entry.eager);
|
|
725
|
+
for (const entry of tagSource) {
|
|
726
|
+
registerTag(entry.tag, entry.name, entry.type, entry.isArray, entry.eager);
|
|
706
727
|
}
|
|
707
728
|
/**
|
|
708
729
|
* @param {number|string} tagIdentifier The field tag ID or name
|
|
@@ -732,7 +753,7 @@ const LercAddCompression = {
|
|
|
732
753
|
Deflate: 1,
|
|
733
754
|
Zstandard: 2,
|
|
734
755
|
};
|
|
735
|
-
const geoKeyNames =
|
|
756
|
+
const geoKeyNames = Object.freeze({
|
|
736
757
|
1024: 'GTModelTypeGeoKey',
|
|
737
758
|
1025: 'GTRasterTypeGeoKey',
|
|
738
759
|
1026: 'GTCitationGeoKey',
|
|
@@ -781,7 +802,15 @@ const geoKeyNames = /** @type {const} */ ({
|
|
|
781
802
|
4098: 'VerticalDatumGeoKey',
|
|
782
803
|
4099: 'VerticalUnitsGeoKey',
|
|
783
804
|
});
|
|
784
|
-
|
|
805
|
+
/** @typedef {geoKeyNames[keyof typeof geoKeyNames]} GeoKeyName */
|
|
806
|
+
/**
|
|
807
|
+
* @type {Record<GeoKeyName, number>}
|
|
808
|
+
*/
|
|
809
|
+
const geoKeys = /** @type {Record<GeoKeyName, number>} */ ({});
|
|
810
|
+
for (const key in geoKeyNames) {
|
|
811
|
+
if (geoKeyNames.hasOwnProperty(key)) {
|
|
812
|
+
geoKeys[geoKeyNames[key]] = parseInt(key, 10);
|
|
813
|
+
}
|
|
785
814
|
}
|
|
786
815
|
|
|
787
816
|
function fromWhiteIsZero(raster, max) {
|
|
@@ -881,40 +910,39 @@ function fromCIELab(cieLabRaster) {
|
|
|
881
910
|
return rgbRaster;
|
|
882
911
|
}
|
|
883
912
|
|
|
884
|
-
|
|
913
|
+
const registry = new Map();
|
|
885
914
|
/**
|
|
886
|
-
* @typedef {Object}
|
|
887
|
-
* @property {
|
|
888
|
-
* @property {
|
|
889
|
-
* @property {
|
|
915
|
+
* @typedef {Object} DecoderParameters
|
|
916
|
+
* @property {number} tileWidth
|
|
917
|
+
* @property {number} tileHeight
|
|
918
|
+
* @property {number} planarConfiguration
|
|
919
|
+
* @property {number} bitsPerSample
|
|
920
|
+
* @property {number} predictor
|
|
890
921
|
*/
|
|
891
|
-
/** @type {Map<number | undefined, RegistryEntry>} */
|
|
892
|
-
const registry = new Map();
|
|
893
922
|
/**
|
|
894
923
|
* Default decoder parameter retrieval function
|
|
895
|
-
* @param {import("../imagefiledirectory
|
|
896
|
-
* @returns {Promise<
|
|
924
|
+
* @param {import("../imagefiledirectory").ImageFileDirectory} fileDirectory
|
|
925
|
+
* @returns {Promise<DecoderParameters>}
|
|
897
926
|
*/
|
|
898
927
|
async function defaultDecoderParameterFn(fileDirectory) {
|
|
899
928
|
const isTiled = !fileDirectory.hasTag('StripOffsets');
|
|
900
|
-
return
|
|
901
|
-
tileWidth: isTiled
|
|
902
|
-
|
|
903
|
-
: await fileDirectory.loadValue('ImageWidth'),
|
|
904
|
-
tileHeight: isTiled
|
|
905
|
-
? await fileDirectory.loadValue('TileLength')
|
|
906
|
-
: (await fileDirectory.loadValue('RowsPerStrip')
|
|
907
|
-
|| await fileDirectory.loadValue('ImageLength')),
|
|
929
|
+
return {
|
|
930
|
+
tileWidth: isTiled ? await fileDirectory.loadValue('TileWidth') : await fileDirectory.loadValue('ImageWidth'),
|
|
931
|
+
tileHeight: isTiled ? await fileDirectory.loadValue('TileLength') : (await fileDirectory.loadValue('RowsPerStrip') || await fileDirectory.loadValue('ImageLength')),
|
|
908
932
|
planarConfiguration: await fileDirectory.loadValue('PlanarConfiguration'),
|
|
909
933
|
bitsPerSample: await fileDirectory.loadValue('BitsPerSample'),
|
|
910
934
|
predictor: await fileDirectory.loadValue('Predictor') || 1,
|
|
911
|
-
}
|
|
935
|
+
};
|
|
912
936
|
}
|
|
937
|
+
/**
|
|
938
|
+
* Either a number or undefined.
|
|
939
|
+
* @typedef {(number|undefined)} NumberOrUndefined
|
|
940
|
+
*/
|
|
913
941
|
/**
|
|
914
942
|
* Register a decoder for a specific compression method or a range of compressions
|
|
915
|
-
* @param {(
|
|
916
|
-
* @param {function():Promise
|
|
917
|
-
* @param {function(import("../imagefiledirectory
|
|
943
|
+
* @param {(NumberOrUndefined|(NumberOrUndefined[]))} cases ids of the compression methods to register for
|
|
944
|
+
* @param {function():Promise} importFn the function to import the decoder
|
|
945
|
+
* @param {function(import("../imagefiledirectory").ImageFileDirectory):Promise} decoderParameterFn
|
|
918
946
|
* @param {boolean} preferWorker_ Whether to prefer running the decoder in a worker
|
|
919
947
|
*/
|
|
920
948
|
function addDecoder(cases, importFn, decoderParameterFn = defaultDecoderParameterFn, preferWorker_ = true) {
|
|
@@ -927,27 +955,27 @@ function addDecoder(cases, importFn, decoderParameterFn = defaultDecoderParamete
|
|
|
927
955
|
}
|
|
928
956
|
/**
|
|
929
957
|
* Get the required decoder parameters for a specific compression method
|
|
930
|
-
* @param {
|
|
958
|
+
* @param {NumberOrUndefined} compression
|
|
931
959
|
* @param {import('../imagefiledirectory.js').ImageFileDirectory} fileDirectory
|
|
932
960
|
*/
|
|
933
961
|
async function getDecoderParameters(compression, fileDirectory) {
|
|
934
962
|
if (!registry.has(compression)) {
|
|
935
963
|
throw new Error(`Unknown compression method identifier: ${compression}`);
|
|
936
964
|
}
|
|
937
|
-
const { decoderParameterFn } =
|
|
965
|
+
const { decoderParameterFn } = registry.get(compression);
|
|
938
966
|
return decoderParameterFn(fileDirectory);
|
|
939
967
|
}
|
|
940
968
|
/**
|
|
941
969
|
* Get a decoder for a specific compression and parameters
|
|
942
970
|
* @param {number} compression the compression method identifier
|
|
943
|
-
* @param {
|
|
971
|
+
* @param {DecoderParameters} decoderParameters the parameters for the decoder
|
|
944
972
|
* @returns {Promise<import('./basedecoder.js').default>}
|
|
945
973
|
*/
|
|
946
974
|
async function getDecoder(compression, decoderParameters) {
|
|
947
975
|
if (!registry.has(compression)) {
|
|
948
976
|
throw new Error(`Unknown compression method identifier: ${compression}`);
|
|
949
977
|
}
|
|
950
|
-
const { importFn } =
|
|
978
|
+
const { importFn } = registry.get(compression);
|
|
951
979
|
const Decoder = await importFn();
|
|
952
980
|
return new Decoder(decoderParameters);
|
|
953
981
|
}
|
|
@@ -974,9 +1002,6 @@ const defaultDecoderDefinitions = [
|
|
|
974
1002
|
{
|
|
975
1003
|
cases: 7,
|
|
976
1004
|
importFn: () => Promise.resolve().then(function () { return jpeg; }).then((m) => m.default),
|
|
977
|
-
/**
|
|
978
|
-
* @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
|
|
979
|
-
*/
|
|
980
1005
|
decoderParameterFn: async (fileDirectory) => {
|
|
981
1006
|
return {
|
|
982
1007
|
...await defaultDecoderParameterFn(fileDirectory),
|
|
@@ -1003,9 +1028,6 @@ const defaultDecoderDefinitions = [
|
|
|
1003
1028
|
return m;
|
|
1004
1029
|
})
|
|
1005
1030
|
.then((m) => m.default),
|
|
1006
|
-
/**
|
|
1007
|
-
* @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
|
|
1008
|
-
*/
|
|
1009
1031
|
decoderParameterFn: async (fileDirectory) => {
|
|
1010
1032
|
return {
|
|
1011
1033
|
...await defaultDecoderParameterFn(fileDirectory),
|
|
@@ -1027,13 +1049,10 @@ const defaultDecoderDefinitions = [
|
|
|
1027
1049
|
{
|
|
1028
1050
|
cases: 50001,
|
|
1029
1051
|
importFn: () => Promise.resolve().then(function () { return webimage; }).then((m) => m.default),
|
|
1030
|
-
/**
|
|
1031
|
-
* @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
|
|
1032
|
-
*/
|
|
1033
1052
|
decoderParameterFn: async (fileDirectory) => {
|
|
1034
1053
|
return {
|
|
1035
1054
|
...await defaultDecoderParameterFn(fileDirectory),
|
|
1036
|
-
samplesPerPixel:
|
|
1055
|
+
samplesPerPixel: await fileDirectory.loadValue('SamplesPerPixel') || 4,
|
|
1037
1056
|
};
|
|
1038
1057
|
},
|
|
1039
1058
|
preferWorker: false,
|
|
@@ -1048,23 +1067,17 @@ for (const decoderDefinition of defaultDecoderDefinitions) {
|
|
|
1048
1067
|
/**
|
|
1049
1068
|
* @module resample
|
|
1050
1069
|
*/
|
|
1051
|
-
/**
|
|
1052
|
-
* @param {import("./geotiff.js").TypedArray} array
|
|
1053
|
-
* @param {number} width
|
|
1054
|
-
* @param {number} height
|
|
1055
|
-
* @param {number} [samplesPerPixel=1]
|
|
1056
|
-
*/
|
|
1057
1070
|
function copyNewSize(array, width, height, samplesPerPixel = 1) {
|
|
1058
1071
|
return new (Object.getPrototypeOf(array).constructor)(width * height * samplesPerPixel);
|
|
1059
1072
|
}
|
|
1060
1073
|
/**
|
|
1061
1074
|
* Resample the input arrays using nearest neighbor value selection.
|
|
1062
|
-
* @param {import("./geotiff
|
|
1075
|
+
* @param {import("./geotiff").TypedArray[]} valueArrays The input arrays to resample
|
|
1063
1076
|
* @param {number} inWidth The width of the input rasters
|
|
1064
1077
|
* @param {number} inHeight The height of the input rasters
|
|
1065
1078
|
* @param {number} outWidth The desired width of the output rasters
|
|
1066
1079
|
* @param {number} outHeight The desired height of the output rasters
|
|
1067
|
-
* @returns {import("./geotiff
|
|
1080
|
+
* @returns {import("./geotiff").TypedArray[]} The resampled rasters
|
|
1068
1081
|
*/
|
|
1069
1082
|
function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {
|
|
1070
1083
|
const relX = inWidth / outWidth;
|
|
@@ -1084,22 +1097,17 @@ function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {
|
|
|
1084
1097
|
}
|
|
1085
1098
|
// simple linear interpolation, code from:
|
|
1086
1099
|
// https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support
|
|
1087
|
-
/**
|
|
1088
|
-
* @param {number} v0
|
|
1089
|
-
* @param {number} v1
|
|
1090
|
-
* @param {number} t
|
|
1091
|
-
*/
|
|
1092
1100
|
function lerp(v0, v1, t) {
|
|
1093
1101
|
return ((1 - t) * v0) + (t * v1);
|
|
1094
1102
|
}
|
|
1095
1103
|
/**
|
|
1096
1104
|
* Resample the input arrays using bilinear interpolation.
|
|
1097
|
-
* @param {import("./geotiff
|
|
1105
|
+
* @param {import("./geotiff").TypedArray[]} valueArrays The input arrays to resample
|
|
1098
1106
|
* @param {number} inWidth The width of the input rasters
|
|
1099
1107
|
* @param {number} inHeight The height of the input rasters
|
|
1100
1108
|
* @param {number} outWidth The desired width of the output rasters
|
|
1101
1109
|
* @param {number} outHeight The desired height of the output rasters
|
|
1102
|
-
* @returns {import("./geotiff
|
|
1110
|
+
* @returns {import("./geotiff").TypedArray[]} The resampled rasters
|
|
1103
1111
|
*/
|
|
1104
1112
|
function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {
|
|
1105
1113
|
const relX = inWidth / outWidth;
|
|
@@ -1128,13 +1136,13 @@ function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {
|
|
|
1128
1136
|
}
|
|
1129
1137
|
/**
|
|
1130
1138
|
* Resample the input arrays using the selected resampling method.
|
|
1131
|
-
* @param {import("./geotiff
|
|
1139
|
+
* @param {import("./geotiff").TypedArray[]} valueArrays The input arrays to resample
|
|
1132
1140
|
* @param {number} inWidth The width of the input rasters
|
|
1133
1141
|
* @param {number} inHeight The height of the input rasters
|
|
1134
1142
|
* @param {number} outWidth The desired width of the output rasters
|
|
1135
1143
|
* @param {number} outHeight The desired height of the output rasters
|
|
1136
1144
|
* @param {string} [method = 'nearest'] The desired resampling method
|
|
1137
|
-
* @returns {import("./geotiff
|
|
1145
|
+
* @returns {import("./geotiff").TypedArray[]} The resampled rasters
|
|
1138
1146
|
*/
|
|
1139
1147
|
function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method = 'nearest') {
|
|
1140
1148
|
switch (method.toLowerCase()) {
|
|
@@ -1149,14 +1157,14 @@ function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method =
|
|
|
1149
1157
|
}
|
|
1150
1158
|
/**
|
|
1151
1159
|
* Resample the pixel interleaved input array using nearest neighbor value selection.
|
|
1152
|
-
* @param {import("./geotiff
|
|
1160
|
+
* @param {import("./geotiff").TypedArray} valueArray The input array to resample
|
|
1153
1161
|
* @param {number} inWidth The width of the input rasters
|
|
1154
1162
|
* @param {number} inHeight The height of the input rasters
|
|
1155
1163
|
* @param {number} outWidth The desired width of the output rasters
|
|
1156
1164
|
* @param {number} outHeight The desired height of the output rasters
|
|
1157
1165
|
* @param {number} samples The number of samples per pixel for pixel
|
|
1158
1166
|
* interleaved data
|
|
1159
|
-
* @returns {import("./geotiff
|
|
1167
|
+
* @returns {import("./geotiff").TypedArray} The resampled raster
|
|
1160
1168
|
*/
|
|
1161
1169
|
function resampleNearestInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
|
|
1162
1170
|
const relX = inWidth / outWidth;
|
|
@@ -1176,14 +1184,14 @@ function resampleNearestInterleaved(valueArray, inWidth, inHeight, outWidth, out
|
|
|
1176
1184
|
}
|
|
1177
1185
|
/**
|
|
1178
1186
|
* Resample the pixel interleaved input array using bilinear interpolation.
|
|
1179
|
-
* @param {import("./geotiff
|
|
1187
|
+
* @param {import("./geotiff").TypedArray} valueArray The input array to resample
|
|
1180
1188
|
* @param {number} inWidth The width of the input rasters
|
|
1181
1189
|
* @param {number} inHeight The height of the input rasters
|
|
1182
1190
|
* @param {number} outWidth The desired width of the output rasters
|
|
1183
1191
|
* @param {number} outHeight The desired height of the output rasters
|
|
1184
1192
|
* @param {number} samples The number of samples per pixel for pixel
|
|
1185
1193
|
* interleaved data
|
|
1186
|
-
* @returns {import("./geotiff
|
|
1194
|
+
* @returns {import("./geotiff").TypedArray} The resampled raster
|
|
1187
1195
|
*/
|
|
1188
1196
|
function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
|
|
1189
1197
|
const relX = inWidth / outWidth;
|
|
@@ -1212,7 +1220,7 @@ function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, ou
|
|
|
1212
1220
|
}
|
|
1213
1221
|
/**
|
|
1214
1222
|
* Resample the pixel interleaved input array using the selected resampling method.
|
|
1215
|
-
* @param {import("./geotiff
|
|
1223
|
+
* @param {import("./geotiff").TypedArray} valueArray The input array to resample
|
|
1216
1224
|
* @param {number} inWidth The width of the input rasters
|
|
1217
1225
|
* @param {number} inHeight The height of the input rasters
|
|
1218
1226
|
* @param {number} outWidth The desired width of the output rasters
|
|
@@ -1220,7 +1228,7 @@ function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, ou
|
|
|
1220
1228
|
* @param {number} samples The number of samples per pixel for pixel
|
|
1221
1229
|
* interleaved data
|
|
1222
1230
|
* @param {string} [method = 'nearest'] The desired resampling method
|
|
1223
|
-
* @returns {import("./geotiff
|
|
1231
|
+
* @returns {import("./geotiff").TypedArray} The resampled rasters
|
|
1224
1232
|
*/
|
|
1225
1233
|
function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples, method = 'nearest') {
|
|
1226
1234
|
switch (method.toLowerCase()) {
|
|
@@ -1235,16 +1243,10 @@ function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight,
|
|
|
1235
1243
|
}
|
|
1236
1244
|
|
|
1237
1245
|
/** @module geotiffimage */
|
|
1238
|
-
/** @import {DecoderWorker, TypedArray} from "./geotiff
|
|
1239
|
-
/** @import {ReadRasterResult} from "./geotiff
|
|
1240
|
-
/** @import {ReadRastersOptions} from "./geotiff
|
|
1241
|
-
/** @import {ReadRGBOptions} from "./geotiff
|
|
1242
|
-
/**
|
|
1243
|
-
* @param {Array<number>|TypedArray} array
|
|
1244
|
-
* @param {number} start
|
|
1245
|
-
* @param {number} end
|
|
1246
|
-
* @returns {number}
|
|
1247
|
-
*/
|
|
1246
|
+
/** @import {DecoderWorker, TypedArray} from "./geotiff" */
|
|
1247
|
+
/** @import {ReadRasterResult} from "./geotiff" */
|
|
1248
|
+
/** @import {ReadRastersOptions} from "./geotiff" */
|
|
1249
|
+
/** @import {ReadRGBOptions} from "./geotiff" */
|
|
1248
1250
|
function sum(array, start, end) {
|
|
1249
1251
|
let s = 0;
|
|
1250
1252
|
for (let i = start; i < end; ++i) {
|
|
@@ -1252,64 +1254,42 @@ function sum(array, start, end) {
|
|
|
1252
1254
|
}
|
|
1253
1255
|
return s;
|
|
1254
1256
|
}
|
|
1255
|
-
|
|
1256
|
-
* @param {1|2|3} format
|
|
1257
|
-
* @param {number} bitsPerSample
|
|
1258
|
-
* @param {number|ArrayBufferLike} sizeOrData
|
|
1259
|
-
* @returns {TypedArray}
|
|
1260
|
-
*/
|
|
1261
|
-
function arrayForType(format, bitsPerSample, sizeOrData) {
|
|
1262
|
-
let TypedArrayConstructor;
|
|
1257
|
+
function arrayForType(format, bitsPerSample, size) {
|
|
1263
1258
|
switch (format) {
|
|
1264
1259
|
case 1: // unsigned integer data
|
|
1265
1260
|
if (bitsPerSample <= 8) {
|
|
1266
|
-
|
|
1261
|
+
return new Uint8Array(size);
|
|
1267
1262
|
}
|
|
1268
1263
|
else if (bitsPerSample <= 16) {
|
|
1269
|
-
|
|
1264
|
+
return new Uint16Array(size);
|
|
1270
1265
|
}
|
|
1271
1266
|
else if (bitsPerSample <= 32) {
|
|
1272
|
-
|
|
1267
|
+
return new Uint32Array(size);
|
|
1273
1268
|
}
|
|
1274
1269
|
break;
|
|
1275
1270
|
case 2: // twos complement signed integer data
|
|
1276
1271
|
if (bitsPerSample === 8) {
|
|
1277
|
-
|
|
1272
|
+
return new Int8Array(size);
|
|
1278
1273
|
}
|
|
1279
1274
|
else if (bitsPerSample === 16) {
|
|
1280
|
-
|
|
1275
|
+
return new Int16Array(size);
|
|
1281
1276
|
}
|
|
1282
1277
|
else if (bitsPerSample === 32) {
|
|
1283
|
-
|
|
1278
|
+
return new Int32Array(size);
|
|
1284
1279
|
}
|
|
1285
1280
|
break;
|
|
1286
1281
|
case 3: // floating point data
|
|
1287
1282
|
switch (bitsPerSample) {
|
|
1288
1283
|
case 16:
|
|
1289
1284
|
case 32:
|
|
1290
|
-
|
|
1291
|
-
break;
|
|
1285
|
+
return new Float32Array(size);
|
|
1292
1286
|
case 64:
|
|
1293
|
-
|
|
1294
|
-
break;
|
|
1287
|
+
return new Float64Array(size);
|
|
1295
1288
|
}
|
|
1296
1289
|
break;
|
|
1297
1290
|
}
|
|
1298
|
-
if (TypedArrayConstructor) {
|
|
1299
|
-
if (typeof sizeOrData === 'number') {
|
|
1300
|
-
return new TypedArrayConstructor(sizeOrData);
|
|
1301
|
-
}
|
|
1302
|
-
else if (sizeOrData instanceof ArrayBuffer) {
|
|
1303
|
-
return new TypedArrayConstructor(sizeOrData);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
1291
|
throw Error('Unsupported data format/bitsPerSample');
|
|
1307
1292
|
}
|
|
1308
|
-
/**
|
|
1309
|
-
* @param {1|2|3} format
|
|
1310
|
-
* @param {number} bitsPerSample
|
|
1311
|
-
* @returns {boolean}
|
|
1312
|
-
*/
|
|
1313
1293
|
function needsNormalization(format, bitsPerSample) {
|
|
1314
1294
|
if ((format === 1 || format === 2) && bitsPerSample <= 32 && bitsPerSample % 8 === 0) {
|
|
1315
1295
|
return false;
|
|
@@ -1319,16 +1299,6 @@ function needsNormalization(format, bitsPerSample) {
|
|
|
1319
1299
|
}
|
|
1320
1300
|
return true;
|
|
1321
1301
|
}
|
|
1322
|
-
/**
|
|
1323
|
-
* @param {ArrayBufferLike} inBuffer
|
|
1324
|
-
* @param {1|2|3} format
|
|
1325
|
-
* @param {1|2} planarConfiguration
|
|
1326
|
-
* @param {number} samplesPerPixel
|
|
1327
|
-
* @param {number} bitsPerSample
|
|
1328
|
-
* @param {number} tileWidth
|
|
1329
|
-
* @param {number} tileHeight
|
|
1330
|
-
* @returns {ArrayBufferLike}
|
|
1331
|
-
*/
|
|
1332
1302
|
function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel, bitsPerSample, tileWidth, tileHeight) {
|
|
1333
1303
|
// const inByteArray = new Uint8Array(inBuffer);
|
|
1334
1304
|
const view = new DataView(inBuffer);
|
|
@@ -1402,7 +1372,7 @@ function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel,
|
|
|
1402
1372
|
class GeoTIFFImage {
|
|
1403
1373
|
/**
|
|
1404
1374
|
* @constructor
|
|
1405
|
-
* @param {import("./imagefiledirectory
|
|
1375
|
+
* @param {import("./imagefiledirectory").ImageFileDirectory} fileDirectory The parsed file directory
|
|
1406
1376
|
* @param {Boolean} littleEndian Whether the file is encoded in little or big endian
|
|
1407
1377
|
* @param {Boolean} cache Whether or not decoded tiles shall be cached
|
|
1408
1378
|
* @param {import('./source/basesource.js').BaseSource} source The datasource to read from
|
|
@@ -1410,8 +1380,7 @@ class GeoTIFFImage {
|
|
|
1410
1380
|
constructor(fileDirectory, littleEndian, cache, source) {
|
|
1411
1381
|
this.fileDirectory = fileDirectory;
|
|
1412
1382
|
this.littleEndian = littleEndian;
|
|
1413
|
-
|
|
1414
|
-
this.tiles = cache ? [] : null;
|
|
1383
|
+
this.tiles = cache ? {} : null;
|
|
1415
1384
|
this.isTiled = !fileDirectory.hasTag('StripOffsets');
|
|
1416
1385
|
const planarConfiguration = fileDirectory.getValue('PlanarConfiguration') ?? 1;
|
|
1417
1386
|
if (planarConfiguration !== 1 && planarConfiguration !== 2) {
|
|
@@ -1423,7 +1392,7 @@ class GeoTIFFImage {
|
|
|
1423
1392
|
}
|
|
1424
1393
|
/**
|
|
1425
1394
|
* Returns the associated parsed file directory.
|
|
1426
|
-
* @returns {import("./imagefiledirectory
|
|
1395
|
+
* @returns {import("./imagefiledirectory").ImageFileDirectory} the parsed file directory
|
|
1427
1396
|
*/
|
|
1428
1397
|
getFileDirectory() {
|
|
1429
1398
|
return this.fileDirectory;
|
|
@@ -1440,50 +1409,46 @@ class GeoTIFFImage {
|
|
|
1440
1409
|
* @returns {Number} the width of the image
|
|
1441
1410
|
*/
|
|
1442
1411
|
getWidth() {
|
|
1443
|
-
return this.fileDirectory.getValue('ImageWidth')
|
|
1412
|
+
return this.fileDirectory.getValue('ImageWidth');
|
|
1444
1413
|
}
|
|
1445
1414
|
/**
|
|
1446
1415
|
* Returns the height of the image.
|
|
1447
1416
|
* @returns {Number} the height of the image
|
|
1448
1417
|
*/
|
|
1449
1418
|
getHeight() {
|
|
1450
|
-
return this.fileDirectory.getValue('ImageLength')
|
|
1419
|
+
return this.fileDirectory.getValue('ImageLength');
|
|
1451
1420
|
}
|
|
1452
1421
|
/**
|
|
1453
1422
|
* Returns the number of samples per pixel.
|
|
1454
|
-
* @returns {
|
|
1423
|
+
* @returns {Number} the number of samples per pixel
|
|
1455
1424
|
*/
|
|
1456
1425
|
getSamplesPerPixel() {
|
|
1457
|
-
return this.fileDirectory.
|
|
1426
|
+
return this.fileDirectory.hasTag('SamplesPerPixel')
|
|
1427
|
+
? this.fileDirectory.getValue('SamplesPerPixel') : 1;
|
|
1458
1428
|
}
|
|
1459
1429
|
/**
|
|
1460
1430
|
* Returns the width of each tile.
|
|
1461
|
-
* @returns {
|
|
1431
|
+
* @returns {Number} the width of each tile
|
|
1462
1432
|
*/
|
|
1463
1433
|
getTileWidth() {
|
|
1464
|
-
return this.isTiled ?
|
|
1434
|
+
return this.isTiled ? this.fileDirectory.getValue('TileWidth') : this.getWidth();
|
|
1465
1435
|
}
|
|
1466
1436
|
/**
|
|
1467
1437
|
* Returns the height of each tile.
|
|
1468
|
-
* @returns {
|
|
1438
|
+
* @returns {Number} the height of each tile
|
|
1469
1439
|
*/
|
|
1470
1440
|
getTileHeight() {
|
|
1471
1441
|
if (this.isTiled) {
|
|
1472
|
-
return this.fileDirectory.getValue('TileLength')
|
|
1442
|
+
return this.fileDirectory.getValue('TileLength');
|
|
1473
1443
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
return Math.min(rowsPerStrip, this.getHeight());
|
|
1444
|
+
if (this.fileDirectory.hasTag('RowsPerStrip')) {
|
|
1445
|
+
return Math.min(this.fileDirectory.getValue('RowsPerStrip'), this.getHeight());
|
|
1477
1446
|
}
|
|
1478
1447
|
return this.getHeight();
|
|
1479
1448
|
}
|
|
1480
1449
|
getBlockWidth() {
|
|
1481
1450
|
return this.getTileWidth();
|
|
1482
1451
|
}
|
|
1483
|
-
/**
|
|
1484
|
-
* @param {number} y
|
|
1485
|
-
* @returns {number}
|
|
1486
|
-
*/
|
|
1487
1452
|
getBlockHeight(y) {
|
|
1488
1453
|
if (this.isTiled || (y + 1) * this.getTileHeight() <= this.getHeight()) {
|
|
1489
1454
|
return this.getTileHeight();
|
|
@@ -1500,32 +1465,22 @@ class GeoTIFFImage {
|
|
|
1500
1465
|
getBytesPerPixel() {
|
|
1501
1466
|
let bytes = 0;
|
|
1502
1467
|
// this is a short list, so we assume this is already loaded
|
|
1503
|
-
|
|
1504
|
-
for (let i = 0; i < bitsPerSample.length; ++i) {
|
|
1468
|
+
for (let i = 0; i < this.fileDirectory.getValue('BitsPerSample').length; ++i) {
|
|
1505
1469
|
bytes += this.getSampleByteSize(i);
|
|
1506
1470
|
}
|
|
1507
1471
|
return bytes;
|
|
1508
1472
|
}
|
|
1509
|
-
/**
|
|
1510
|
-
* @param {number} i
|
|
1511
|
-
* @returns {number}
|
|
1512
|
-
*/
|
|
1513
1473
|
getSampleByteSize(i) {
|
|
1514
|
-
const bitsPerSample = this.fileDirectory.getValue('BitsPerSample')
|
|
1474
|
+
const bitsPerSample = this.fileDirectory.getValue('BitsPerSample');
|
|
1515
1475
|
if (i >= bitsPerSample.length) {
|
|
1516
1476
|
throw new RangeError(`Sample index ${i} is out of range.`);
|
|
1517
1477
|
}
|
|
1518
1478
|
return Math.ceil(bitsPerSample[i] / 8);
|
|
1519
1479
|
}
|
|
1520
|
-
/**
|
|
1521
|
-
* @param {number} sampleIndex
|
|
1522
|
-
* @returns {(this: DataView, byteOffset: number, littleEndian: boolean) => number}
|
|
1523
|
-
*/
|
|
1524
1480
|
getReaderForSample(sampleIndex) {
|
|
1525
|
-
const
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
const bitsPerSample = (this.fileDirectory.getValue('BitsPerSample') || [])[sampleIndex];
|
|
1481
|
+
const format = this.fileDirectory.hasTag('SampleFormat')
|
|
1482
|
+
? this.fileDirectory.getValue('SampleFormat')[sampleIndex] : 1;
|
|
1483
|
+
const bitsPerSample = this.fileDirectory.getValue('BitsPerSample')[sampleIndex];
|
|
1529
1484
|
switch (format) {
|
|
1530
1485
|
case 1: // unsigned integer data
|
|
1531
1486
|
if (bitsPerSample <= 8) {
|
|
@@ -1565,32 +1520,26 @@ class GeoTIFFImage {
|
|
|
1565
1520
|
throw Error('Unsupported data format/bitsPerSample');
|
|
1566
1521
|
}
|
|
1567
1522
|
getSampleFormat(sampleIndex = 0) {
|
|
1568
|
-
|
|
1569
|
-
|
|
1523
|
+
return this.fileDirectory.hasTag('SampleFormat')
|
|
1524
|
+
? this.fileDirectory.getValue('SampleFormat')[sampleIndex] : 1;
|
|
1570
1525
|
}
|
|
1571
1526
|
getBitsPerSample(sampleIndex = 0) {
|
|
1572
|
-
|
|
1573
|
-
return bitsPerSample ? bitsPerSample[sampleIndex] : 0;
|
|
1527
|
+
return this.fileDirectory.getValue('BitsPerSample')[sampleIndex];
|
|
1574
1528
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
* @param {number|ArrayBufferLike} sizeOrData
|
|
1578
|
-
* @returns {TypedArray}
|
|
1579
|
-
*/
|
|
1580
|
-
getArrayForSample(sampleIndex, sizeOrData) {
|
|
1581
|
-
const format = /** @type {1|2|3} */ (this.getSampleFormat(sampleIndex));
|
|
1529
|
+
getArrayForSample(sampleIndex, size) {
|
|
1530
|
+
const format = this.getSampleFormat(sampleIndex);
|
|
1582
1531
|
const bitsPerSample = this.getBitsPerSample(sampleIndex);
|
|
1583
|
-
return arrayForType(format, bitsPerSample,
|
|
1532
|
+
return arrayForType(format, bitsPerSample, size);
|
|
1584
1533
|
}
|
|
1585
1534
|
/**
|
|
1586
1535
|
* Returns the decoded strip or tile.
|
|
1587
1536
|
* @param {Number} x the strip or tile x-offset
|
|
1588
1537
|
* @param {Number} y the tile y-offset (0 for stripped images)
|
|
1589
1538
|
* @param {Number} sample the sample to get for separated samples
|
|
1590
|
-
* @param {DecoderWorker|import("./geotiff
|
|
1539
|
+
* @param {DecoderWorker|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
|
|
1591
1540
|
* @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
|
|
1592
1541
|
* to be aborted
|
|
1593
|
-
* @returns {Promise.<{x: number, y: number, sample: number, data:
|
|
1542
|
+
* @returns {Promise.<{x: number, y: number, sample: number, data: ArrayBuffer}>} the decoded strip or tile
|
|
1594
1543
|
*/
|
|
1595
1544
|
async getTileOrStrip(x, y, sample, poolOrDecoder, signal) {
|
|
1596
1545
|
const numTilesPerRow = Math.ceil(this.getWidth() / this.getTileWidth());
|
|
@@ -1609,12 +1558,12 @@ class GeoTIFFImage {
|
|
|
1609
1558
|
let offset;
|
|
1610
1559
|
let byteCount;
|
|
1611
1560
|
if (this.isTiled) {
|
|
1612
|
-
offset =
|
|
1613
|
-
byteCount =
|
|
1561
|
+
offset = await this.fileDirectory.loadValueIndexed('TileOffsets', index);
|
|
1562
|
+
byteCount = await this.fileDirectory.loadValueIndexed('TileByteCounts', index);
|
|
1614
1563
|
}
|
|
1615
1564
|
else {
|
|
1616
|
-
offset =
|
|
1617
|
-
byteCount =
|
|
1565
|
+
offset = await this.fileDirectory.loadValueIndexed('StripOffsets', index);
|
|
1566
|
+
byteCount = await this.fileDirectory.loadValueIndexed('StripByteCounts', index);
|
|
1618
1567
|
}
|
|
1619
1568
|
if (byteCount === 0) {
|
|
1620
1569
|
const nPixels = this.getBlockHeight(y) * this.getTileWidth();
|
|
@@ -1630,7 +1579,7 @@ class GeoTIFFImage {
|
|
|
1630
1579
|
// resolve each request by potentially applying array normalization
|
|
1631
1580
|
request = (async () => {
|
|
1632
1581
|
let data = await poolOrDecoder.decode(slice);
|
|
1633
|
-
const sampleFormat =
|
|
1582
|
+
const sampleFormat = this.getSampleFormat();
|
|
1634
1583
|
const bitsPerSample = this.getBitsPerSample();
|
|
1635
1584
|
if (needsNormalization(sampleFormat, bitsPerSample)) {
|
|
1636
1585
|
data = normalizeArray(data, sampleFormat, this.planarConfiguration, this.getSamplesPerPixel(), bitsPerSample, this.getTileWidth(), this.getBlockHeight(y));
|
|
@@ -1652,11 +1601,11 @@ class GeoTIFFImage {
|
|
|
1652
1601
|
/**
|
|
1653
1602
|
* Internal read function.
|
|
1654
1603
|
* @private
|
|
1655
|
-
* @param {Array
|
|
1656
|
-
* @param {Array
|
|
1604
|
+
* @param {Array} imageWindow The image window in pixel coordinates
|
|
1605
|
+
* @param {Array} samples The selected samples (0-based indices)
|
|
1657
1606
|
* @param {TypedArray|TypedArray[]} valueArrays The array(s) to write into
|
|
1658
1607
|
* @param {boolean|undefined} interleave Whether or not to write in an interleaved manner
|
|
1659
|
-
* @param {DecoderWorker|import("./geotiff
|
|
1608
|
+
* @param {DecoderWorker|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
|
|
1660
1609
|
* @param {number} [width] the width of window to be read into
|
|
1661
1610
|
* @param {number} [height] the height of window to be read into
|
|
1662
1611
|
* @param {string} [resampleMethod] the resampling method to be used when interpolating
|
|
@@ -1675,17 +1624,11 @@ class GeoTIFFImage {
|
|
|
1675
1624
|
const maxYTile = Math.min(Math.ceil(imageWindow[3] / tileHeight), Math.ceil(imageHeight / tileHeight));
|
|
1676
1625
|
const windowWidth = imageWindow[2] - imageWindow[0];
|
|
1677
1626
|
let bytesPerPixel = this.getBytesPerPixel();
|
|
1678
|
-
/** @type {Array<number>} */
|
|
1679
1627
|
const srcSampleOffsets = [];
|
|
1680
|
-
/** @type {Array<(this: DataView, byteOffset: number, littleEndian: boolean) => number>} */
|
|
1681
1628
|
const sampleReaders = [];
|
|
1682
1629
|
for (let i = 0; i < samples.length; ++i) {
|
|
1683
1630
|
if (this.planarConfiguration === 1) {
|
|
1684
|
-
|
|
1685
|
-
if (typeof bitsPerSample !== 'object') {
|
|
1686
|
-
throw new Error('Expected BitsPerSample to be an array or typed array.');
|
|
1687
|
-
}
|
|
1688
|
-
srcSampleOffsets.push(sum(bitsPerSample, 0, samples[i]) / 8);
|
|
1631
|
+
srcSampleOffsets.push(sum(await this.fileDirectory.loadValue('BitsPerSample'), 0, samples[i]) / 8);
|
|
1689
1632
|
}
|
|
1690
1633
|
else {
|
|
1691
1634
|
srcSampleOffsets.push(0);
|
|
@@ -1734,7 +1677,7 @@ class GeoTIFFImage {
|
|
|
1734
1677
|
}
|
|
1735
1678
|
else {
|
|
1736
1679
|
windowCoordinate = ((y + firstLine - imageWindow[1]) * windowWidth) + x + firstCol - imageWindow[0];
|
|
1737
|
-
|
|
1680
|
+
valueArrays[si][windowCoordinate] = value;
|
|
1738
1681
|
}
|
|
1739
1682
|
}
|
|
1740
1683
|
}
|
|
@@ -1770,12 +1713,12 @@ class GeoTIFFImage {
|
|
|
1770
1713
|
/**
|
|
1771
1714
|
* @overload
|
|
1772
1715
|
* @param {ReadRastersOptions & {interleave: true}} options optional parameters
|
|
1773
|
-
* @returns {Promise<import("./geotiff
|
|
1716
|
+
* @returns {Promise<import("./geotiff").TypedArrayWithDimensions>} the decoded arrays as a promise
|
|
1774
1717
|
*/
|
|
1775
1718
|
/**
|
|
1776
1719
|
* @overload
|
|
1777
1720
|
* @param {ReadRastersOptions & {interleave: false}} options optional parameters
|
|
1778
|
-
* @returns {Promise<import("./geotiff
|
|
1721
|
+
* @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
|
|
1779
1722
|
*/
|
|
1780
1723
|
/**
|
|
1781
1724
|
* @overload
|
|
@@ -1785,7 +1728,7 @@ class GeoTIFFImage {
|
|
|
1785
1728
|
/**
|
|
1786
1729
|
* @overload
|
|
1787
1730
|
* @param {ReadRastersOptions} [options={}] optional parameters
|
|
1788
|
-
* @returns {Promise<import("./geotiff
|
|
1731
|
+
* @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
|
|
1789
1732
|
*/
|
|
1790
1733
|
/**
|
|
1791
1734
|
* Reads raster data from the image. This function reads all selected samples
|
|
@@ -1823,16 +1766,9 @@ class GeoTIFFImage {
|
|
|
1823
1766
|
/** @type {TypedArray|TypedArray[]} */
|
|
1824
1767
|
let valueArrays;
|
|
1825
1768
|
if (interleave) {
|
|
1826
|
-
const
|
|
1827
|
-
|
|
1828
|
-
const
|
|
1829
|
-
? Math.max.apply(null, Array.from(sampleFormat)) : 1;
|
|
1830
|
-
if (format !== 1 && format !== 2 && format !== 3) {
|
|
1831
|
-
throw new Error('Unsupported sample format for interleaved data. Must be 1, 2, or 3.');
|
|
1832
|
-
}
|
|
1833
|
-
const bitsPerSample_ = fileDirectory.getValue('BitsPerSample');
|
|
1834
|
-
const bitsPerSample = bitsPerSample_
|
|
1835
|
-
? Math.max.apply(null, Array.from(bitsPerSample_)) : 8;
|
|
1769
|
+
const format = this.fileDirectory.hasTag('SampleFormat')
|
|
1770
|
+
? Math.max.apply(null, this.fileDirectory.getValue('SampleFormat')) : 1;
|
|
1771
|
+
const bitsPerSample = Math.max.apply(null, this.fileDirectory.getValue('BitsPerSample'));
|
|
1836
1772
|
valueArrays = arrayForType(format, bitsPerSample, numPixels * samples.length);
|
|
1837
1773
|
if (fillValue) {
|
|
1838
1774
|
if (Array.isArray(fillValue)) {
|
|
@@ -1865,12 +1801,12 @@ class GeoTIFFImage {
|
|
|
1865
1801
|
/**
|
|
1866
1802
|
* @overload
|
|
1867
1803
|
* @param {ReadRGBOptions & {interleave: true}} options optional parameters
|
|
1868
|
-
* @returns {Promise<import("./geotiff
|
|
1804
|
+
* @returns {Promise<import("./geotiff").TypedArrayWithDimensions>} the RGB array as a Promise
|
|
1869
1805
|
*/
|
|
1870
1806
|
/**
|
|
1871
1807
|
* @overload
|
|
1872
1808
|
* @param {ReadRGBOptions & {interleave: false}} options optional parameters
|
|
1873
|
-
* @returns {Promise<import("./geotiff
|
|
1809
|
+
* @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the RGB array as a Promise
|
|
1874
1810
|
*/
|
|
1875
1811
|
/**
|
|
1876
1812
|
* @overload
|
|
@@ -1880,7 +1816,7 @@ class GeoTIFFImage {
|
|
|
1880
1816
|
/**
|
|
1881
1817
|
* @overload
|
|
1882
1818
|
* @param {ReadRGBOptions} [options={}] optional parameters
|
|
1883
|
-
* @returns {Promise<import("./geotiff
|
|
1819
|
+
* @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the RGB array as a Promise
|
|
1884
1820
|
*/
|
|
1885
1821
|
/**
|
|
1886
1822
|
* Reads raster data from the image as RGB.
|
|
@@ -1903,11 +1839,9 @@ class GeoTIFFImage {
|
|
|
1903
1839
|
const pi = this.fileDirectory.getValue('PhotometricInterpretation');
|
|
1904
1840
|
if (pi === photometricInterpretations.RGB) {
|
|
1905
1841
|
let s = [0, 1, 2];
|
|
1906
|
-
|
|
1907
|
-
if (extraSamples && extraSamples[0] !== ExtraSamplesValues.Unspecified && enableAlpha) {
|
|
1842
|
+
if ((!(this.fileDirectory.getValue('ExtraSamples') === ExtraSamplesValues.Unspecified)) && enableAlpha) {
|
|
1908
1843
|
s = [];
|
|
1909
|
-
|
|
1910
|
-
for (let i = 0; i < bitsPerSample.length; i += 1) {
|
|
1844
|
+
for (let i = 0; i < this.fileDirectory.getValue('BitsPerSample').length; i += 1) {
|
|
1911
1845
|
s.push(i);
|
|
1912
1846
|
}
|
|
1913
1847
|
}
|
|
@@ -1962,7 +1896,7 @@ class GeoTIFFImage {
|
|
|
1962
1896
|
data = fromBlackIsZero(raster, max);
|
|
1963
1897
|
break;
|
|
1964
1898
|
case photometricInterpretations.Palette:
|
|
1965
|
-
data = fromPalette(raster,
|
|
1899
|
+
data = fromPalette(raster, await fileDirectory.loadValue('ColorMap'));
|
|
1966
1900
|
break;
|
|
1967
1901
|
case photometricInterpretations.CMYK:
|
|
1968
1902
|
data = fromCMYK(raster);
|
|
@@ -1989,23 +1923,20 @@ class GeoTIFFImage {
|
|
|
1989
1923
|
}
|
|
1990
1924
|
data = [red, green, blue];
|
|
1991
1925
|
}
|
|
1992
|
-
const dataWithDimensions = /** @type {import("./geotiff
|
|
1926
|
+
const dataWithDimensions = /** @type {import("./geotiff").ReadRasterResult} */ (data);
|
|
1993
1927
|
dataWithDimensions.width = raster.width;
|
|
1994
1928
|
dataWithDimensions.height = raster.height;
|
|
1995
1929
|
return dataWithDimensions;
|
|
1996
1930
|
}
|
|
1997
1931
|
/**
|
|
1998
1932
|
* Returns an array of tiepoints.
|
|
1999
|
-
* @returns {Promise<
|
|
1933
|
+
* @returns {Promise<Object[]>}
|
|
2000
1934
|
*/
|
|
2001
1935
|
async getTiePoints() {
|
|
2002
1936
|
if (!this.fileDirectory.hasTag('ModelTiepoint')) {
|
|
2003
1937
|
return [];
|
|
2004
1938
|
}
|
|
2005
1939
|
const modelTiePoint = await this.fileDirectory.loadValue('ModelTiepoint');
|
|
2006
|
-
if (typeof modelTiePoint !== 'object') {
|
|
2007
|
-
throw new Error('Expected ModelTiepoint to be an array or typed array.');
|
|
2008
|
-
}
|
|
2009
1940
|
const tiePoints = [];
|
|
2010
1941
|
for (let i = 0; i < modelTiePoint.length; i += 6) {
|
|
2011
1942
|
tiePoints.push({
|
|
@@ -2026,16 +1957,14 @@ class GeoTIFFImage {
|
|
|
2026
1957
|
* Otherwise only metadata specific to the provided sample will be returned.
|
|
2027
1958
|
*
|
|
2028
1959
|
* @param {number|null} [sample=null] The sample index.
|
|
2029
|
-
* @returns {Promise<
|
|
1960
|
+
* @returns {Promise<Object>}
|
|
2030
1961
|
*/
|
|
2031
1962
|
async getGDALMetadata(sample = null) {
|
|
2032
|
-
/** @type {Record<string, unknown>} */
|
|
2033
1963
|
const metadata = {};
|
|
2034
1964
|
if (!this.fileDirectory.hasTag('GDAL_METADATA')) {
|
|
2035
1965
|
return null;
|
|
2036
1966
|
}
|
|
2037
1967
|
const string = await this.fileDirectory.loadValue('GDAL_METADATA');
|
|
2038
|
-
/** @type {Array<{inner: unknown}>} */
|
|
2039
1968
|
let items = findTagsByName(string, 'Item');
|
|
2040
1969
|
if (sample === null) {
|
|
2041
1970
|
items = items.filter((item) => getAttribute(item, 'sample') === undefined);
|
|
@@ -2054,10 +1983,10 @@ class GeoTIFFImage {
|
|
|
2054
1983
|
* @returns {number|null}
|
|
2055
1984
|
*/
|
|
2056
1985
|
getGDALNoData() {
|
|
2057
|
-
|
|
2058
|
-
if (!string) {
|
|
1986
|
+
if (!this.fileDirectory.hasTag('GDAL_NODATA')) {
|
|
2059
1987
|
return null;
|
|
2060
1988
|
}
|
|
1989
|
+
const string = this.fileDirectory.getValue('GDAL_NODATA');
|
|
2061
1990
|
return Number(string.substring(0, string.length - 1));
|
|
2062
1991
|
}
|
|
2063
1992
|
/**
|
|
@@ -2146,9 +2075,9 @@ class GeoTIFFImage {
|
|
|
2146
2075
|
getBoundingBox(tilegrid = false) {
|
|
2147
2076
|
const height = this.getHeight();
|
|
2148
2077
|
const width = this.getWidth();
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
const [a, b, , d, e, f, , h] =
|
|
2078
|
+
if (this.fileDirectory.hasTag('ModelTransformation') && !tilegrid) {
|
|
2079
|
+
// eslint-disable-next-line no-unused-vars
|
|
2080
|
+
const [a, b, c, d, e, f, g, h] = this.fileDirectory.getValue('ModelTransformation');
|
|
2152
2081
|
const corners = [
|
|
2153
2082
|
[0, 0],
|
|
2154
2083
|
[0, height],
|
|
@@ -2186,20 +2115,12 @@ class GeoTIFFImage {
|
|
|
2186
2115
|
}
|
|
2187
2116
|
|
|
2188
2117
|
class DataView64 {
|
|
2189
|
-
/**
|
|
2190
|
-
* @param {ArrayBufferLike} arrayBuffer
|
|
2191
|
-
*/
|
|
2192
2118
|
constructor(arrayBuffer) {
|
|
2193
2119
|
this._dataView = new DataView(arrayBuffer);
|
|
2194
2120
|
}
|
|
2195
2121
|
get buffer() {
|
|
2196
2122
|
return this._dataView.buffer;
|
|
2197
2123
|
}
|
|
2198
|
-
/**
|
|
2199
|
-
* @param {number} offset
|
|
2200
|
-
* @param {boolean} littleEndian
|
|
2201
|
-
* @returns {number}
|
|
2202
|
-
*/
|
|
2203
2124
|
getUint64(offset, littleEndian) {
|
|
2204
2125
|
const left = this.getUint32(offset, littleEndian);
|
|
2205
2126
|
const right = this.getUint32(offset + 4, littleEndian);
|
|
@@ -2219,12 +2140,7 @@ class DataView64 {
|
|
|
2219
2140
|
}
|
|
2220
2141
|
return combined;
|
|
2221
2142
|
}
|
|
2222
|
-
|
|
2223
|
-
* Adapted from https://stackoverflow.com/a/55338384/8060591
|
|
2224
|
-
* @param {number} offset
|
|
2225
|
-
* @param {boolean} littleEndian
|
|
2226
|
-
* @returns {number}
|
|
2227
|
-
*/
|
|
2143
|
+
// adapted from https://stackoverflow.com/a/55338384/8060591
|
|
2228
2144
|
getInt64(offset, littleEndian) {
|
|
2229
2145
|
let value = 0;
|
|
2230
2146
|
const isNegative = (this._dataView.getUint8(offset + (littleEndian ? 7 : 0)) & 0x80) > 0;
|
|
@@ -2249,85 +2165,36 @@ class DataView64 {
|
|
|
2249
2165
|
}
|
|
2250
2166
|
return value;
|
|
2251
2167
|
}
|
|
2252
|
-
/**
|
|
2253
|
-
* @param {number} offset
|
|
2254
|
-
* @returns {number}
|
|
2255
|
-
*/
|
|
2256
2168
|
getUint8(offset) {
|
|
2257
2169
|
return this._dataView.getUint8(offset);
|
|
2258
2170
|
}
|
|
2259
|
-
/**
|
|
2260
|
-
* @param {number} offset
|
|
2261
|
-
* @returns {number}
|
|
2262
|
-
*/
|
|
2263
2171
|
getInt8(offset) {
|
|
2264
2172
|
return this._dataView.getInt8(offset);
|
|
2265
2173
|
}
|
|
2266
|
-
/**
|
|
2267
|
-
* @param {number} offset
|
|
2268
|
-
* @param {boolean} littleEndian
|
|
2269
|
-
* @returns {number}
|
|
2270
|
-
*/
|
|
2271
2174
|
getUint16(offset, littleEndian) {
|
|
2272
2175
|
return this._dataView.getUint16(offset, littleEndian);
|
|
2273
2176
|
}
|
|
2274
|
-
/**
|
|
2275
|
-
* @param {number} offset
|
|
2276
|
-
* @param {boolean} littleEndian
|
|
2277
|
-
* @returns {number}
|
|
2278
|
-
*/
|
|
2279
2177
|
getInt16(offset, littleEndian) {
|
|
2280
2178
|
return this._dataView.getInt16(offset, littleEndian);
|
|
2281
2179
|
}
|
|
2282
|
-
/**
|
|
2283
|
-
* @param {number} offset
|
|
2284
|
-
* @param {boolean} littleEndian
|
|
2285
|
-
* @returns {number}
|
|
2286
|
-
*/
|
|
2287
2180
|
getUint32(offset, littleEndian) {
|
|
2288
2181
|
return this._dataView.getUint32(offset, littleEndian);
|
|
2289
2182
|
}
|
|
2290
|
-
/**
|
|
2291
|
-
* @param {number} offset
|
|
2292
|
-
* @param {boolean} littleEndian
|
|
2293
|
-
* @returns {number}
|
|
2294
|
-
*/
|
|
2295
2183
|
getInt32(offset, littleEndian) {
|
|
2296
2184
|
return this._dataView.getInt32(offset, littleEndian);
|
|
2297
2185
|
}
|
|
2298
|
-
/**
|
|
2299
|
-
* @param {number} offset
|
|
2300
|
-
* @param {boolean} littleEndian
|
|
2301
|
-
* @returns {number}
|
|
2302
|
-
*/
|
|
2303
2186
|
getFloat16(offset, littleEndian) {
|
|
2304
2187
|
return getFloat16(this._dataView, offset, littleEndian);
|
|
2305
2188
|
}
|
|
2306
|
-
/**
|
|
2307
|
-
* @param {number} offset
|
|
2308
|
-
* @param {boolean} littleEndian
|
|
2309
|
-
* @returns {number}
|
|
2310
|
-
*/
|
|
2311
2189
|
getFloat32(offset, littleEndian) {
|
|
2312
2190
|
return this._dataView.getFloat32(offset, littleEndian);
|
|
2313
2191
|
}
|
|
2314
|
-
/**
|
|
2315
|
-
* @param {number} offset
|
|
2316
|
-
* @param {boolean} littleEndian
|
|
2317
|
-
* @returns {number}
|
|
2318
|
-
*/
|
|
2319
2192
|
getFloat64(offset, littleEndian) {
|
|
2320
2193
|
return this._dataView.getFloat64(offset, littleEndian);
|
|
2321
2194
|
}
|
|
2322
2195
|
}
|
|
2323
2196
|
|
|
2324
2197
|
class DataSlice {
|
|
2325
|
-
/**
|
|
2326
|
-
* @param {ArrayBufferLike} arrayBuffer
|
|
2327
|
-
* @param {number} sliceOffset
|
|
2328
|
-
* @param {boolean} littleEndian
|
|
2329
|
-
* @param {boolean} bigTiff
|
|
2330
|
-
*/
|
|
2331
2198
|
constructor(arrayBuffer, sliceOffset, littleEndian, bigTiff) {
|
|
2332
2199
|
this._dataView = new DataView(arrayBuffer);
|
|
2333
2200
|
this._sliceOffset = sliceOffset;
|
|
@@ -2349,74 +2216,33 @@ class DataSlice {
|
|
|
2349
2216
|
get buffer() {
|
|
2350
2217
|
return this._dataView.buffer;
|
|
2351
2218
|
}
|
|
2352
|
-
/**
|
|
2353
|
-
* @param {number} offset
|
|
2354
|
-
* @param {number} length
|
|
2355
|
-
* @returns {boolean}
|
|
2356
|
-
*/
|
|
2357
2219
|
covers(offset, length) {
|
|
2358
2220
|
return this.sliceOffset <= offset && this.sliceTop >= offset + length;
|
|
2359
2221
|
}
|
|
2360
|
-
/**
|
|
2361
|
-
* @param {number} offset
|
|
2362
|
-
* @returns {number}
|
|
2363
|
-
*/
|
|
2364
2222
|
readUint8(offset) {
|
|
2365
2223
|
return this._dataView.getUint8(offset - this._sliceOffset);
|
|
2366
2224
|
}
|
|
2367
|
-
/**
|
|
2368
|
-
* @param {number} offset
|
|
2369
|
-
* @returns {number}
|
|
2370
|
-
*/
|
|
2371
2225
|
readInt8(offset) {
|
|
2372
2226
|
return this._dataView.getInt8(offset - this._sliceOffset);
|
|
2373
2227
|
}
|
|
2374
|
-
/**
|
|
2375
|
-
* @param {number} offset
|
|
2376
|
-
* @returns {number}
|
|
2377
|
-
*/
|
|
2378
2228
|
readUint16(offset) {
|
|
2379
2229
|
return this._dataView.getUint16(offset - this._sliceOffset, this._littleEndian);
|
|
2380
2230
|
}
|
|
2381
|
-
/**
|
|
2382
|
-
* @param {number} offset
|
|
2383
|
-
* @returns {number}
|
|
2384
|
-
*/
|
|
2385
2231
|
readInt16(offset) {
|
|
2386
2232
|
return this._dataView.getInt16(offset - this._sliceOffset, this._littleEndian);
|
|
2387
2233
|
}
|
|
2388
|
-
/**
|
|
2389
|
-
* @param {number} offset
|
|
2390
|
-
* @returns {number}
|
|
2391
|
-
*/
|
|
2392
2234
|
readUint32(offset) {
|
|
2393
2235
|
return this._dataView.getUint32(offset - this._sliceOffset, this._littleEndian);
|
|
2394
2236
|
}
|
|
2395
|
-
/**
|
|
2396
|
-
* @param {number} offset
|
|
2397
|
-
* @returns {number}
|
|
2398
|
-
*/
|
|
2399
2237
|
readInt32(offset) {
|
|
2400
2238
|
return this._dataView.getInt32(offset - this._sliceOffset, this._littleEndian);
|
|
2401
2239
|
}
|
|
2402
|
-
/**
|
|
2403
|
-
* @param {number} offset
|
|
2404
|
-
* @returns {number}
|
|
2405
|
-
*/
|
|
2406
2240
|
readFloat32(offset) {
|
|
2407
2241
|
return this._dataView.getFloat32(offset - this._sliceOffset, this._littleEndian);
|
|
2408
2242
|
}
|
|
2409
|
-
/**
|
|
2410
|
-
* @param {number} offset
|
|
2411
|
-
* @returns {number}
|
|
2412
|
-
*/
|
|
2413
2243
|
readFloat64(offset) {
|
|
2414
2244
|
return this._dataView.getFloat64(offset - this._sliceOffset, this._littleEndian);
|
|
2415
2245
|
}
|
|
2416
|
-
/**
|
|
2417
|
-
* @param {number} offset
|
|
2418
|
-
* @returns {number}
|
|
2419
|
-
*/
|
|
2420
2246
|
readUint64(offset) {
|
|
2421
2247
|
const left = this.readUint32(offset);
|
|
2422
2248
|
const right = this.readUint32(offset + 4);
|
|
@@ -2436,11 +2262,7 @@ class DataSlice {
|
|
|
2436
2262
|
}
|
|
2437
2263
|
return combined;
|
|
2438
2264
|
}
|
|
2439
|
-
|
|
2440
|
-
* Adapted from https://stackoverflow.com/a/55338384/8060591
|
|
2441
|
-
* @param {number} offset
|
|
2442
|
-
* @returns {number}
|
|
2443
|
-
*/
|
|
2265
|
+
// adapted from https://stackoverflow.com/a/55338384/8060591
|
|
2444
2266
|
readInt64(offset) {
|
|
2445
2267
|
let value = 0;
|
|
2446
2268
|
const isNegative = (this._dataView.getUint8(offset + (this._littleEndian ? 7 : 0)) & 0x80)
|
|
@@ -2466,10 +2288,6 @@ class DataSlice {
|
|
|
2466
2288
|
}
|
|
2467
2289
|
return value;
|
|
2468
2290
|
}
|
|
2469
|
-
/**
|
|
2470
|
-
* @param {number} offset
|
|
2471
|
-
* @returns {number}
|
|
2472
|
-
*/
|
|
2473
2291
|
readOffset(offset) {
|
|
2474
2292
|
if (this._bigTiff) {
|
|
2475
2293
|
return this.readUint64(offset);
|
|
@@ -2479,17 +2297,13 @@ class DataSlice {
|
|
|
2479
2297
|
}
|
|
2480
2298
|
|
|
2481
2299
|
const CRLFCRLF = '\r\n\r\n';
|
|
2482
|
-
|
|
2300
|
+
/*
|
|
2483
2301
|
* Shim for 'Object.fromEntries'
|
|
2484
|
-
* @template T
|
|
2485
|
-
* @param {Array<[string, T]>} items
|
|
2486
|
-
* @return {Record<string, T>}
|
|
2487
2302
|
*/
|
|
2488
2303
|
function itemsToObject(items) {
|
|
2489
2304
|
if (typeof Object.fromEntries !== 'undefined') {
|
|
2490
2305
|
return Object.fromEntries(items);
|
|
2491
2306
|
}
|
|
2492
|
-
/** @type {Record<string, T>} */
|
|
2493
2307
|
const obj = {};
|
|
2494
2308
|
for (const [key, value] of items) {
|
|
2495
2309
|
obj[key.toLowerCase()] = value;
|
|
@@ -2498,15 +2312,14 @@ function itemsToObject(items) {
|
|
|
2498
2312
|
}
|
|
2499
2313
|
/**
|
|
2500
2314
|
* Parse HTTP headers from a given string.
|
|
2501
|
-
* @param {
|
|
2502
|
-
* @returns {
|
|
2315
|
+
* @param {String} text the text to parse the headers from
|
|
2316
|
+
* @returns {Object} the parsed headers with lowercase keys
|
|
2503
2317
|
*/
|
|
2504
2318
|
function parseHeaders(text) {
|
|
2505
|
-
/** @type {Array<[string, string]>} */
|
|
2506
2319
|
const items = text
|
|
2507
2320
|
.split('\r\n')
|
|
2508
2321
|
.map((line) => {
|
|
2509
|
-
const kv =
|
|
2322
|
+
const kv = line.split(':').map((str) => str.trim());
|
|
2510
2323
|
kv[0] = kv[0].toLowerCase();
|
|
2511
2324
|
return kv;
|
|
2512
2325
|
});
|
|
@@ -2514,8 +2327,8 @@ function parseHeaders(text) {
|
|
|
2514
2327
|
}
|
|
2515
2328
|
/**
|
|
2516
2329
|
* Parse a 'Content-Type' header value to the content-type and parameters
|
|
2517
|
-
* @param {string|
|
|
2518
|
-
* @returns {{type: string|null, params:
|
|
2330
|
+
* @param {string|null} rawContentType the raw string to parse from
|
|
2331
|
+
* @returns {{type: string|null, params: Object}}}
|
|
2519
2332
|
* the parsed content type with the fields: type and params
|
|
2520
2333
|
*/
|
|
2521
2334
|
function parseContentType(rawContentType) {
|
|
@@ -2523,12 +2336,12 @@ function parseContentType(rawContentType) {
|
|
|
2523
2336
|
return { type: null, params: {} };
|
|
2524
2337
|
}
|
|
2525
2338
|
const [type, ...rawParams] = rawContentType.split(';').map((s) => s.trim());
|
|
2526
|
-
const paramsItems =
|
|
2339
|
+
const paramsItems = rawParams.map((param) => param.split('='));
|
|
2527
2340
|
return { type, params: itemsToObject(paramsItems) };
|
|
2528
2341
|
}
|
|
2529
2342
|
/**
|
|
2530
2343
|
* Parse a 'Content-Range' header value to its start, end, and total parts
|
|
2531
|
-
* @param {string|
|
|
2344
|
+
* @param {string|null} rawContentRange the raw string to parse from
|
|
2532
2345
|
* @returns {{start: number, end: number, total: number}} the parsed parts
|
|
2533
2346
|
*/
|
|
2534
2347
|
function parseContentRange(rawContentRange) {
|
|
@@ -2548,12 +2361,11 @@ function parseContentRange(rawContentRange) {
|
|
|
2548
2361
|
* - offset: the offset of the byterange within its originating file
|
|
2549
2362
|
* - length: the length of the byterange
|
|
2550
2363
|
* @param {ArrayBuffer} responseArrayBuffer the response to be parsed and split
|
|
2551
|
-
* @param {
|
|
2552
|
-
* @returns {
|
|
2553
|
-
* the parsed byteranges
|
|
2364
|
+
* @param {String} boundary the boundary string used to split the sections
|
|
2365
|
+
* @returns {Object[]} the parsed byteranges
|
|
2554
2366
|
*/
|
|
2555
2367
|
function parseByteRanges(responseArrayBuffer, boundary) {
|
|
2556
|
-
let offset =
|
|
2368
|
+
let offset = null;
|
|
2557
2369
|
const decoder = new TextDecoder('ascii');
|
|
2558
2370
|
const out = [];
|
|
2559
2371
|
const startBoundary = `--${boundary}`;
|
|
@@ -2566,7 +2378,7 @@ function parseByteRanges(responseArrayBuffer, boundary) {
|
|
|
2566
2378
|
offset = i;
|
|
2567
2379
|
}
|
|
2568
2380
|
}
|
|
2569
|
-
if (offset ===
|
|
2381
|
+
if (offset === null) {
|
|
2570
2382
|
throw new Error('Could not find initial boundary');
|
|
2571
2383
|
}
|
|
2572
2384
|
while (offset < responseArrayBuffer.byteLength) {
|
|
@@ -2605,31 +2417,29 @@ function parseByteRanges(responseArrayBuffer, boundary) {
|
|
|
2605
2417
|
}
|
|
2606
2418
|
|
|
2607
2419
|
/**
|
|
2608
|
-
* @typedef
|
|
2420
|
+
* @typedef Slice
|
|
2609
2421
|
* @property {number} offset
|
|
2610
2422
|
* @property {number} length
|
|
2611
2423
|
*/
|
|
2612
|
-
/** @typedef {Slice & {data: ArrayBufferLike}} SliceWithData */
|
|
2613
2424
|
class BaseSource {
|
|
2614
2425
|
/**
|
|
2615
2426
|
* @param {Array<Slice>} slices
|
|
2616
2427
|
* @param {AbortSignal} [signal]
|
|
2617
|
-
* @returns {Promise
|
|
2428
|
+
* @returns {Promise<*[]>}
|
|
2618
2429
|
*/
|
|
2619
2430
|
async fetch(slices, signal) {
|
|
2620
|
-
return Promise.all(slices.map(
|
|
2431
|
+
return Promise.all(slices.map((slice) => this.fetchSlice(slice, signal)));
|
|
2621
2432
|
}
|
|
2622
2433
|
/**
|
|
2623
2434
|
* @param {Slice} slice
|
|
2624
2435
|
* @param {AbortSignal} [_signal]
|
|
2625
|
-
* @returns {Promise
|
|
2436
|
+
* @returns {Promise<*>}
|
|
2626
2437
|
*/
|
|
2627
2438
|
async fetchSlice(slice, _signal) {
|
|
2628
2439
|
throw new Error(`fetching of slice ${slice} not possible, not implemented`);
|
|
2629
2440
|
}
|
|
2630
2441
|
/**
|
|
2631
2442
|
* Returns the filesize if already determined and null otherwise
|
|
2632
|
-
* @returns {number|null}
|
|
2633
2443
|
*/
|
|
2634
2444
|
get fileSize() {
|
|
2635
2445
|
return null;
|
|
@@ -2923,14 +2733,18 @@ class QuickLRU extends Map {
|
|
|
2923
2733
|
}
|
|
2924
2734
|
}
|
|
2925
2735
|
|
|
2926
|
-
|
|
2736
|
+
/*
|
|
2927
2737
|
* Promisified wrapper around 'setTimeout' to allow 'await'
|
|
2928
|
-
* @param {number} [milliseconds]
|
|
2929
|
-
* @returns {Promise<void>}
|
|
2930
2738
|
*/
|
|
2931
2739
|
async function wait(milliseconds) {
|
|
2932
2740
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
2933
2741
|
}
|
|
2742
|
+
/**
|
|
2743
|
+
* @template T,U
|
|
2744
|
+
* @param {Iterable<T>} a
|
|
2745
|
+
* @param {Iterable<U>} b
|
|
2746
|
+
* @returns {Array<[T, U]>}
|
|
2747
|
+
*/
|
|
2934
2748
|
function zip(a, b) {
|
|
2935
2749
|
const A = Array.isArray(a) ? a : Array.from(a);
|
|
2936
2750
|
const B = Array.isArray(b) ? b : Array.from(b);
|
|
@@ -2938,15 +2752,14 @@ function zip(a, b) {
|
|
|
2938
2752
|
}
|
|
2939
2753
|
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
|
|
2940
2754
|
class AbortError extends Error {
|
|
2941
|
-
constructor(
|
|
2755
|
+
constructor(params) {
|
|
2942
2756
|
// Pass remaining arguments (including vendor specific ones) to parent constructor
|
|
2943
|
-
super(
|
|
2757
|
+
super(params);
|
|
2944
2758
|
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
2945
2759
|
if (Error.captureStackTrace) {
|
|
2946
2760
|
Error.captureStackTrace(this, AbortError);
|
|
2947
2761
|
}
|
|
2948
2762
|
this.name = 'AbortError';
|
|
2949
|
-
this.signal = undefined;
|
|
2950
2763
|
}
|
|
2951
2764
|
}
|
|
2952
2765
|
class CustomAggregateError extends Error {
|
|
@@ -3021,7 +2834,7 @@ class BlockedSource extends BaseSource {
|
|
|
3021
2834
|
return this.source.fileSize;
|
|
3022
2835
|
}
|
|
3023
2836
|
/**
|
|
3024
|
-
* @param {import("./basesource
|
|
2837
|
+
* @param {import("./basesource").Slice[]} slices
|
|
3025
2838
|
* @param {AbortSignal} [signal]
|
|
3026
2839
|
* @return {Promise<ArrayBuffer[]>}
|
|
3027
2840
|
*/
|
|
@@ -3103,25 +2916,24 @@ class BlockedSource extends BaseSource {
|
|
|
3103
2916
|
if (this.blockIdsToFetch.size > 0) {
|
|
3104
2917
|
const groups = this.groupBlocks(this.blockIdsToFetch);
|
|
3105
2918
|
// start requesting slices of data
|
|
3106
|
-
const groupRequests =
|
|
2919
|
+
const groupRequests = this.source.fetch(groups, signal);
|
|
3107
2920
|
for (let groupIndex = 0; groupIndex < groups.length; ++groupIndex) {
|
|
3108
2921
|
const group = groups[groupIndex];
|
|
3109
2922
|
for (const blockId of group.blockIds) {
|
|
3110
2923
|
// make an async IIFE for each block
|
|
3111
2924
|
this.blockRequests.set(blockId, (async () => {
|
|
3112
2925
|
try {
|
|
3113
|
-
const response = (await
|
|
2926
|
+
const response = (await groupRequests)[groupIndex];
|
|
3114
2927
|
const blockOffset = blockId * this.blockSize;
|
|
3115
2928
|
const o = blockOffset - response.offset;
|
|
3116
2929
|
const t = Math.min(o + this.blockSize, response.data.byteLength);
|
|
3117
2930
|
const data = response.data.slice(o, t);
|
|
3118
|
-
const block = new Block(blockOffset, data.byteLength,
|
|
3119
|
-
/** @type {ArrayBuffer} */ (data));
|
|
2931
|
+
const block = new Block(blockOffset, data.byteLength, data);
|
|
3120
2932
|
this.blockCache.set(blockId, block);
|
|
3121
2933
|
this.abortedBlockIds.delete(blockId);
|
|
3122
2934
|
}
|
|
3123
2935
|
catch (err) {
|
|
3124
|
-
if (err
|
|
2936
|
+
if (err.name === 'AbortError') {
|
|
3125
2937
|
// store the signal here, we need it to determine later if an
|
|
3126
2938
|
// error was caused by this signal
|
|
3127
2939
|
err.signal = signal;
|
|
@@ -3143,7 +2955,7 @@ class BlockedSource extends BaseSource {
|
|
|
3143
2955
|
}
|
|
3144
2956
|
/**
|
|
3145
2957
|
*
|
|
3146
|
-
* @param {Set
|
|
2958
|
+
* @param {Set} blockIds
|
|
3147
2959
|
* @returns {BlockGroup[]}
|
|
3148
2960
|
*/
|
|
3149
2961
|
groupBlocks(blockIds) {
|
|
@@ -3151,7 +2963,6 @@ class BlockedSource extends BaseSource {
|
|
|
3151
2963
|
if (sortedBlockIds.length === 0) {
|
|
3152
2964
|
return [];
|
|
3153
2965
|
}
|
|
3154
|
-
/** @type {number[]} */
|
|
3155
2966
|
let current = [];
|
|
3156
2967
|
let lastBlockId = null;
|
|
3157
2968
|
const groups = [];
|
|
@@ -3170,7 +2981,7 @@ class BlockedSource extends BaseSource {
|
|
|
3170
2981
|
return groups;
|
|
3171
2982
|
}
|
|
3172
2983
|
/**
|
|
3173
|
-
* @param {import("./basesource
|
|
2984
|
+
* @param {import("./basesource").Slice[]} slices
|
|
3174
2985
|
* @param {Map<number, Block>} blocks
|
|
3175
2986
|
* @returns {ArrayBuffer[]}
|
|
3176
2987
|
*/
|
|
@@ -3230,10 +3041,10 @@ class BaseResponse {
|
|
|
3230
3041
|
}
|
|
3231
3042
|
/**
|
|
3232
3043
|
* Returns the value of the specified header
|
|
3233
|
-
* @param {string}
|
|
3234
|
-
* @returns {string|
|
|
3044
|
+
* @param {string} headerName the header name
|
|
3045
|
+
* @returns {string|null} the header value
|
|
3235
3046
|
*/
|
|
3236
|
-
getHeader(
|
|
3047
|
+
getHeader(headerName) {
|
|
3237
3048
|
throw new Error('not implemented');
|
|
3238
3049
|
}
|
|
3239
3050
|
/**
|
|
@@ -3244,16 +3055,15 @@ class BaseResponse {
|
|
|
3244
3055
|
}
|
|
3245
3056
|
}
|
|
3246
3057
|
class BaseClient {
|
|
3247
|
-
/** @param {string} url */
|
|
3248
3058
|
constructor(url) {
|
|
3249
3059
|
this.url = url;
|
|
3250
3060
|
}
|
|
3251
3061
|
/**
|
|
3252
3062
|
* Send a request with the options
|
|
3253
|
-
* @param {RequestInit} [
|
|
3063
|
+
* @param {RequestInit} [options={}]
|
|
3254
3064
|
* @returns {Promise<BaseResponse>}
|
|
3255
3065
|
*/
|
|
3256
|
-
async request(
|
|
3066
|
+
async request({ headers, signal } = {}) {
|
|
3257
3067
|
throw new Error('request is not implemented');
|
|
3258
3068
|
}
|
|
3259
3069
|
}
|
|
@@ -3272,10 +3082,10 @@ class FetchResponse extends BaseResponse {
|
|
|
3272
3082
|
}
|
|
3273
3083
|
/**
|
|
3274
3084
|
* @param {string} name
|
|
3275
|
-
* @returns {string|
|
|
3085
|
+
* @returns {string|null}
|
|
3276
3086
|
*/
|
|
3277
3087
|
getHeader(name) {
|
|
3278
|
-
return this.response.headers.get(name)
|
|
3088
|
+
return this.response.headers.get(name);
|
|
3279
3089
|
}
|
|
3280
3090
|
async getData() {
|
|
3281
3091
|
const data = this.response.arrayBuffer
|
|
@@ -3286,10 +3096,6 @@ class FetchResponse extends BaseResponse {
|
|
|
3286
3096
|
}
|
|
3287
3097
|
}
|
|
3288
3098
|
class FetchClient extends BaseClient {
|
|
3289
|
-
/**
|
|
3290
|
-
* @param {string} url
|
|
3291
|
-
* @param {RequestCredentials} [credentials]
|
|
3292
|
-
*/
|
|
3293
3099
|
constructor(url, credentials) {
|
|
3294
3100
|
super(url);
|
|
3295
3101
|
this.credentials = credentials;
|
|
@@ -3320,23 +3126,14 @@ class XHRResponse extends BaseResponse {
|
|
|
3320
3126
|
get status() {
|
|
3321
3127
|
return this.xhr.status;
|
|
3322
3128
|
}
|
|
3323
|
-
/**
|
|
3324
|
-
* @param {string} name
|
|
3325
|
-
* @returns {string|undefined}
|
|
3326
|
-
*/
|
|
3327
3129
|
getHeader(name) {
|
|
3328
|
-
return this.xhr.getResponseHeader(name)
|
|
3130
|
+
return this.xhr.getResponseHeader(name);
|
|
3329
3131
|
}
|
|
3330
3132
|
async getData() {
|
|
3331
3133
|
return this.data;
|
|
3332
3134
|
}
|
|
3333
3135
|
}
|
|
3334
3136
|
class XHRClient extends BaseClient {
|
|
3335
|
-
/**
|
|
3336
|
-
* @param {Object<string, string>} headers
|
|
3337
|
-
* @param {AbortSignal} [signal]
|
|
3338
|
-
* @returns {Promise<XHRResponse>}
|
|
3339
|
-
*/
|
|
3340
3137
|
constructRequest(headers, signal) {
|
|
3341
3138
|
return new Promise((resolve, reject) => {
|
|
3342
3139
|
const xhr = new XMLHttpRequest();
|
|
@@ -3361,7 +3158,7 @@ class XHRClient extends BaseClient {
|
|
|
3361
3158
|
}
|
|
3362
3159
|
});
|
|
3363
3160
|
}
|
|
3364
|
-
async request({ headers =
|
|
3161
|
+
async request({ headers = undefined, signal = undefined } = {}) {
|
|
3365
3162
|
const response = await this.constructRequest(headers, signal);
|
|
3366
3163
|
return response;
|
|
3367
3164
|
}
|
|
@@ -3373,7 +3170,6 @@ class HttpResponse extends BaseResponse {
|
|
|
3373
3170
|
/**
|
|
3374
3171
|
* BaseResponse facade for node HTTP/HTTPS API Response
|
|
3375
3172
|
* @param {import('http').IncomingMessage} response
|
|
3376
|
-
* @param {Promise<ArrayBuffer>} dataPromise
|
|
3377
3173
|
*/
|
|
3378
3174
|
constructor(response, dataPromise) {
|
|
3379
3175
|
super();
|
|
@@ -3383,13 +3179,8 @@ class HttpResponse extends BaseResponse {
|
|
|
3383
3179
|
get status() {
|
|
3384
3180
|
return /** @type {number} */ (this.response.statusCode);
|
|
3385
3181
|
}
|
|
3386
|
-
/**
|
|
3387
|
-
* @param {string} name
|
|
3388
|
-
* @returns {string|undefined}
|
|
3389
|
-
*/
|
|
3390
3182
|
getHeader(name) {
|
|
3391
|
-
|
|
3392
|
-
return Array.isArray(value) ? value.join(', ') : value;
|
|
3183
|
+
return /** @type {string|null} */ (this.response.headers[name]);
|
|
3393
3184
|
}
|
|
3394
3185
|
async getData() {
|
|
3395
3186
|
const data = await this.dataPromise;
|
|
@@ -3397,17 +3188,11 @@ class HttpResponse extends BaseResponse {
|
|
|
3397
3188
|
}
|
|
3398
3189
|
}
|
|
3399
3190
|
class HttpClient extends BaseClient {
|
|
3400
|
-
/** @param {string} url */
|
|
3401
3191
|
constructor(url) {
|
|
3402
3192
|
super(url);
|
|
3403
3193
|
this.parsedUrl = fs.parse(this.url);
|
|
3404
3194
|
this.httpApi = (this.parsedUrl.protocol === 'http:' ? fs : fs);
|
|
3405
3195
|
}
|
|
3406
|
-
/**
|
|
3407
|
-
* @param {Object<string, string>} headers
|
|
3408
|
-
* @param {AbortSignal} [signal]
|
|
3409
|
-
* @returns {Promise<HttpResponse>}
|
|
3410
|
-
*/
|
|
3411
3196
|
constructRequest(headers, signal) {
|
|
3412
3197
|
return new Promise((resolve, reject) => {
|
|
3413
3198
|
const request = this.httpApi.get({
|
|
@@ -3415,7 +3200,6 @@ class HttpClient extends BaseClient {
|
|
|
3415
3200
|
headers,
|
|
3416
3201
|
}, (response) => {
|
|
3417
3202
|
const dataPromise = new Promise((resolveData) => {
|
|
3418
|
-
/** @type {Uint8Array[]} */
|
|
3419
3203
|
const chunks = [];
|
|
3420
3204
|
// collect chunks
|
|
3421
3205
|
response.on('data', (chunk) => {
|
|
@@ -3439,7 +3223,7 @@ class HttpClient extends BaseClient {
|
|
|
3439
3223
|
}
|
|
3440
3224
|
});
|
|
3441
3225
|
}
|
|
3442
|
-
async request({ headers =
|
|
3226
|
+
async request({ headers = undefined, signal = undefined } = {}) {
|
|
3443
3227
|
const response = await this.constructRequest(headers, signal);
|
|
3444
3228
|
return response;
|
|
3445
3229
|
}
|
|
@@ -3448,7 +3232,7 @@ class HttpClient extends BaseClient {
|
|
|
3448
3232
|
/** @import { RemoteSourceOptions, BlockedSourceOptions } from '../geotiff.js' */
|
|
3449
3233
|
class RemoteSource extends BaseSource {
|
|
3450
3234
|
/**
|
|
3451
|
-
* @param {import("../geotiff
|
|
3235
|
+
* @param {import("../geotiff").BaseClient} client
|
|
3452
3236
|
* @param {RemoteSourceOptions} options
|
|
3453
3237
|
*/
|
|
3454
3238
|
constructor(client, { headers, maxRanges = 0, allowFullFile } = {}) {
|
|
@@ -3462,29 +3246,24 @@ class RemoteSource extends BaseSource {
|
|
|
3462
3246
|
/**
|
|
3463
3247
|
* @param {import('./basesource.js').Slice[]} slices
|
|
3464
3248
|
* @param {AbortSignal} [signal]
|
|
3465
|
-
* @returns {Promise
|
|
3249
|
+
* @returns {Promise<*[]>}
|
|
3466
3250
|
*/
|
|
3467
3251
|
async fetch(slices, signal) {
|
|
3468
3252
|
// if we allow multi-ranges, split the incoming request into that many sub-requests
|
|
3469
3253
|
// and join them afterwards
|
|
3470
3254
|
if (this.maxRanges >= slices.length) {
|
|
3471
|
-
return this.fetchSlices(slices, signal)
|
|
3255
|
+
return this.fetchSlices(slices, signal);
|
|
3472
3256
|
}
|
|
3473
3257
|
else if (this.maxRanges > 0 && slices.length > 1) ;
|
|
3474
3258
|
// otherwise make a single request for each slice
|
|
3475
|
-
return Promise.all(slices.map(
|
|
3259
|
+
return Promise.all(slices.map((slice) => this.fetchSlice(slice, signal)));
|
|
3476
3260
|
}
|
|
3477
|
-
/**
|
|
3478
|
-
* @param {Array<import('./basesource.js').Slice>} slices
|
|
3479
|
-
* @param {AbortSignal} [signal]
|
|
3480
|
-
* @returns {Promise<Array<import('./basesource.js').SliceWithData>>}
|
|
3481
|
-
*/
|
|
3482
3261
|
async fetchSlices(slices, signal) {
|
|
3483
3262
|
const response = await this.client.request({
|
|
3484
3263
|
headers: {
|
|
3485
3264
|
...this.headers,
|
|
3486
3265
|
Range: `bytes=${slices
|
|
3487
|
-
.map(({ offset, length }) => `${offset}-${offset + length
|
|
3266
|
+
.map(({ offset, length }) => `${offset}-${offset + length}`)
|
|
3488
3267
|
.join(',')}`,
|
|
3489
3268
|
},
|
|
3490
3269
|
signal,
|
|
@@ -3502,11 +3281,10 @@ class RemoteSource extends BaseSource {
|
|
|
3502
3281
|
const data = await response.getData();
|
|
3503
3282
|
const { start, end, total } = parseContentRange(response.getHeader('content-range'));
|
|
3504
3283
|
this._fileSize = total || null;
|
|
3505
|
-
/** @type {import('./basesource.js').SliceWithData[]} */
|
|
3506
3284
|
const first = [{
|
|
3507
3285
|
data,
|
|
3508
3286
|
offset: start,
|
|
3509
|
-
length: end
|
|
3287
|
+
length: end - start,
|
|
3510
3288
|
}];
|
|
3511
3289
|
if (slices.length > 1) {
|
|
3512
3290
|
// we requested more than one slice, but got only the first
|
|
@@ -3531,17 +3309,12 @@ class RemoteSource extends BaseSource {
|
|
|
3531
3309
|
}];
|
|
3532
3310
|
}
|
|
3533
3311
|
}
|
|
3534
|
-
/**
|
|
3535
|
-
* @param {import('./basesource.js').Slice} slice
|
|
3536
|
-
* @param {AbortSignal} [signal]
|
|
3537
|
-
* @returns {Promise<import('./basesource.js').SliceWithData>}
|
|
3538
|
-
*/
|
|
3539
3312
|
async fetchSlice(slice, signal) {
|
|
3540
3313
|
const { offset, length } = slice;
|
|
3541
3314
|
const response = await this.client.request({
|
|
3542
3315
|
headers: {
|
|
3543
3316
|
...this.headers,
|
|
3544
|
-
Range: `bytes=${offset}-${offset + length
|
|
3317
|
+
Range: `bytes=${offset}-${offset + length}`,
|
|
3545
3318
|
},
|
|
3546
3319
|
signal,
|
|
3547
3320
|
});
|
|
@@ -3582,7 +3355,7 @@ class RemoteSource extends BaseSource {
|
|
|
3582
3355
|
* @returns {BaseSource}
|
|
3583
3356
|
*/
|
|
3584
3357
|
function maybeWrapInBlockedSource(source, { blockSize, cacheSize }) {
|
|
3585
|
-
if (blockSize ===
|
|
3358
|
+
if (blockSize === null) {
|
|
3586
3359
|
return source;
|
|
3587
3360
|
}
|
|
3588
3361
|
return new BlockedSource(source, { blockSize, cacheSize });
|
|
@@ -3633,30 +3406,17 @@ function makeRemoteSource(url, { forceXHR = false, ...clientOptions } = {}) {
|
|
|
3633
3406
|
}
|
|
3634
3407
|
|
|
3635
3408
|
class ArrayBufferSource extends BaseSource {
|
|
3636
|
-
/**
|
|
3637
|
-
* @param {ArrayBuffer} arrayBuffer
|
|
3638
|
-
*/
|
|
3639
3409
|
constructor(arrayBuffer) {
|
|
3640
3410
|
super();
|
|
3641
3411
|
this.arrayBuffer = arrayBuffer;
|
|
3642
3412
|
}
|
|
3643
|
-
/**
|
|
3644
|
-
* @param {import('./basesource.js').Slice} slice
|
|
3645
|
-
* @param {AbortSignal} [signal]
|
|
3646
|
-
* @returns {Promise<import('./basesource.js').SliceWithData>}
|
|
3647
|
-
*/
|
|
3648
3413
|
fetchSlice(slice, signal) {
|
|
3649
3414
|
if (signal && signal.aborted) {
|
|
3650
3415
|
throw new AbortError('Request aborted');
|
|
3651
3416
|
}
|
|
3652
|
-
return
|
|
3653
|
-
data: this.arrayBuffer.slice(slice.offset, slice.offset + slice.length),
|
|
3654
|
-
offset: slice.offset,
|
|
3655
|
-
length: slice.length,
|
|
3656
|
-
});
|
|
3417
|
+
return this.arrayBuffer.slice(slice.offset, slice.offset + slice.length);
|
|
3657
3418
|
}
|
|
3658
3419
|
}
|
|
3659
|
-
/** @param {ArrayBuffer} arrayBuffer */
|
|
3660
3420
|
function makeBufferSource(arrayBuffer) {
|
|
3661
3421
|
return new ArrayBufferSource(arrayBuffer);
|
|
3662
3422
|
}
|
|
@@ -3754,17 +3514,6 @@ function getDataSliceReader(dataSlice, fieldType) {
|
|
|
3754
3514
|
* @param {true} isArray - Whether to always return an array (vs single value)
|
|
3755
3515
|
* @returns {import('./geotiff.js').TypedArray|Array<number>} The decoded value(s)
|
|
3756
3516
|
*/
|
|
3757
|
-
/**
|
|
3758
|
-
* @overload
|
|
3759
|
-
* @param {import('./geotiff.js').TypedArray|Array<number>|null} outValues - Optional pre-allocated output array
|
|
3760
|
-
* @param {Function} readMethod - DataView read method (e.g., getUint16)
|
|
3761
|
-
* @param {DataSlice} dataSlice - Source data slice
|
|
3762
|
-
* @param {number} fieldType - TIFF field type constant
|
|
3763
|
-
* @param {number} count - Number of values to read
|
|
3764
|
-
* @param {number} offset - Byte offset to start reading
|
|
3765
|
-
* @param {boolean} [isArray] - Whether to always return an array (vs single value)
|
|
3766
|
-
* @returns {import('./geotiff.js').TypedArray|Array<number>|string|number} The decoded value(s)
|
|
3767
|
-
*/
|
|
3768
3517
|
/**
|
|
3769
3518
|
* Reads field values from a DataSlice.
|
|
3770
3519
|
* @param {import('./geotiff.js').TypedArray|Array<number>|null} outValues - Optional pre-allocated output array
|
|
@@ -3889,11 +3638,9 @@ class DeferredArray {
|
|
|
3889
3638
|
class ImageFileDirectory {
|
|
3890
3639
|
/**
|
|
3891
3640
|
* Create an ImageFileDirectory.
|
|
3892
|
-
* @param {Map
|
|
3893
|
-
* mapping tag names to
|
|
3894
|
-
* @param {Map
|
|
3895
|
-
* @param {Map<string|number, DeferredArray>} deferredArrays the deferred arrays, mapping tag names to
|
|
3896
|
-
* DeferredArray objects
|
|
3641
|
+
* @param {Map} actualizedFields the file directory, mapping tag names to values
|
|
3642
|
+
* @param {Map} deferredFields the deferred fields, mapping tag names to async functions
|
|
3643
|
+
* @param {Map} deferredArrays the deferred arrays, mapping tag names to DeferredArray objects
|
|
3897
3644
|
* @param {number} nextIFDByteOffset the byte offset to the next IFD
|
|
3898
3645
|
*/
|
|
3899
3646
|
constructor(actualizedFields, deferredFields, deferredArrays, nextIFDByteOffset) {
|
|
@@ -3904,7 +3651,7 @@ class ImageFileDirectory {
|
|
|
3904
3651
|
this.nextIFDByteOffset = nextIFDByteOffset;
|
|
3905
3652
|
}
|
|
3906
3653
|
/**
|
|
3907
|
-
* @param {
|
|
3654
|
+
* @param {number|string} tagIdentifier The field tag ID or name
|
|
3908
3655
|
* @returns {boolean} whether the field exists (actualized or deferred)
|
|
3909
3656
|
*/
|
|
3910
3657
|
hasTag(tagIdentifier) {
|
|
@@ -3913,11 +3660,8 @@ class ImageFileDirectory {
|
|
|
3913
3660
|
}
|
|
3914
3661
|
/**
|
|
3915
3662
|
* Synchronously retrieves the value for a given tag. If it is deferred, an error is thrown.
|
|
3916
|
-
* @
|
|
3917
|
-
* @
|
|
3918
|
-
* @returns {T extends import('./globals.js').TagName ? (import('./globals.js').TagValue<T> | undefined) : any}
|
|
3919
|
-
* the field value,
|
|
3920
|
-
* or undefined if it does not exist
|
|
3663
|
+
* @param {number|string} tagIdentifier The field tag ID or name
|
|
3664
|
+
* @returns the field value, or undefined if it does not exist
|
|
3921
3665
|
* @throws {Error} If the tag is deferred and requires asynchronous loading
|
|
3922
3666
|
*/
|
|
3923
3667
|
getValue(tagIdentifier) {
|
|
@@ -3928,27 +3672,25 @@ class ImageFileDirectory {
|
|
|
3928
3672
|
throw new Error(`Field '${tagName}' (${tag}) is deferred. Use loadValue() to load it asynchronously.`);
|
|
3929
3673
|
}
|
|
3930
3674
|
if (!this.actualizedFields.has(tag)) {
|
|
3931
|
-
return
|
|
3675
|
+
return undefined;
|
|
3932
3676
|
}
|
|
3933
|
-
return
|
|
3677
|
+
return this.actualizedFields.get(tag);
|
|
3934
3678
|
}
|
|
3935
3679
|
/**
|
|
3936
3680
|
* Retrieves the value for a given tag. If it is deferred, it will be loaded first.
|
|
3937
|
-
* @
|
|
3938
|
-
* @
|
|
3939
|
-
* @returns {Promise<T extends import('./globals.js').TagName ? (import('./globals.js').TagValue<T> | undefined) : any>}
|
|
3940
|
-
* the field value, or undefined if it does not exist
|
|
3681
|
+
* @param {number|string} tagIdentifier The field tag ID or name
|
|
3682
|
+
* @returns the field value, or undefined if it does not exist
|
|
3941
3683
|
*/
|
|
3942
3684
|
async loadValue(tagIdentifier) {
|
|
3943
3685
|
const tag = resolveTag(tagIdentifier);
|
|
3944
3686
|
if (this.actualizedFields.has(tag)) {
|
|
3945
|
-
return
|
|
3687
|
+
return this.actualizedFields.get(tag);
|
|
3946
3688
|
}
|
|
3947
3689
|
if (this.deferredFieldsBeingResolved.has(tag)) {
|
|
3948
|
-
return
|
|
3690
|
+
return this.deferredFieldsBeingResolved.get(tag);
|
|
3949
3691
|
}
|
|
3950
|
-
|
|
3951
|
-
|
|
3692
|
+
if (this.deferredFields.has(tag)) {
|
|
3693
|
+
const loaderFn = this.deferredFields.get(tag);
|
|
3952
3694
|
this.deferredFields.delete(tag);
|
|
3953
3695
|
// Set promise BEFORE starting async work to prevent race conditions
|
|
3954
3696
|
const valuePromise = (async () => {
|
|
@@ -3962,35 +3704,32 @@ class ImageFileDirectory {
|
|
|
3962
3704
|
}
|
|
3963
3705
|
})();
|
|
3964
3706
|
this.deferredFieldsBeingResolved.set(tag, valuePromise);
|
|
3965
|
-
return
|
|
3707
|
+
return valuePromise;
|
|
3966
3708
|
}
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
return
|
|
3709
|
+
if (this.deferredArrays.has(tag)) {
|
|
3710
|
+
const deferredArray = this.deferredArrays.get(tag);
|
|
3711
|
+
return deferredArray.loadAll();
|
|
3970
3712
|
}
|
|
3971
|
-
return
|
|
3713
|
+
return undefined;
|
|
3972
3714
|
}
|
|
3973
3715
|
/**
|
|
3974
3716
|
* Retrieves the value at a given index for a tag that is an array. If it is deferred, it will be loaded first.
|
|
3975
3717
|
* @param {number|string} tagIdentifier The field tag ID or name
|
|
3976
3718
|
* @param {number} index The index within the array
|
|
3977
|
-
* @returns
|
|
3719
|
+
* @returns the field value at the given index, or undefined if it does not exist
|
|
3978
3720
|
*/
|
|
3979
3721
|
async loadValueIndexed(tagIdentifier, index) {
|
|
3980
3722
|
const tag = resolveTag(tagIdentifier);
|
|
3981
3723
|
if (this.actualizedFields.has(tag)) {
|
|
3982
3724
|
const value = this.actualizedFields.get(tag);
|
|
3983
|
-
return
|
|
3725
|
+
return value[index];
|
|
3984
3726
|
}
|
|
3985
3727
|
else if (this.deferredArrays.has(tag)) {
|
|
3986
|
-
const deferredArray =
|
|
3728
|
+
const deferredArray = this.deferredArrays.get(tag);
|
|
3987
3729
|
return deferredArray.get(index);
|
|
3988
3730
|
}
|
|
3989
3731
|
else if (this.hasTag(tag)) {
|
|
3990
|
-
|
|
3991
|
-
if (value && typeof value !== 'number') {
|
|
3992
|
-
return value[index];
|
|
3993
|
-
}
|
|
3732
|
+
return (await this.loadValue(tag))[index];
|
|
3994
3733
|
}
|
|
3995
3734
|
return undefined;
|
|
3996
3735
|
}
|
|
@@ -4010,8 +3749,8 @@ class ImageFileDirectory {
|
|
|
4010
3749
|
/** @type {Partial<Record<import('./globals.js').GeoKeyName, *>>} */
|
|
4011
3750
|
const geoKeyDirectory = {};
|
|
4012
3751
|
for (let i = 4; i <= rawGeoKeyDirectory[3] * 4; i += 4) {
|
|
4013
|
-
const key =
|
|
4014
|
-
const location =
|
|
3752
|
+
const key = geoKeyNames[rawGeoKeyDirectory[i]];
|
|
3753
|
+
const location = rawGeoKeyDirectory[i + 1] || null;
|
|
4015
3754
|
const count = rawGeoKeyDirectory[i + 2];
|
|
4016
3755
|
const offset = rawGeoKeyDirectory[i + 3];
|
|
4017
3756
|
let value = null;
|
|
@@ -4038,10 +3777,9 @@ class ImageFileDirectory {
|
|
|
4038
3777
|
return geoKeyDirectory;
|
|
4039
3778
|
}
|
|
4040
3779
|
toObject() {
|
|
4041
|
-
/** @type {Record<string, unknown>} */
|
|
4042
3780
|
const obj = {};
|
|
4043
3781
|
for (const [tag, value] of this.actualizedFields.entries()) {
|
|
4044
|
-
const tagDefinition =
|
|
3782
|
+
const tagDefinition = tagDefinitions[tag];
|
|
4045
3783
|
const tagName = tagDefinition ? tagDefinition.name : `Tag${tag}`;
|
|
4046
3784
|
obj[tagName] = value;
|
|
4047
3785
|
}
|
|
@@ -4165,10 +3903,6 @@ class ImageFileDirectoryParser {
|
|
|
4165
3903
|
}
|
|
4166
3904
|
}
|
|
4167
3905
|
|
|
4168
|
-
/**
|
|
4169
|
-
* @param {Uint8Array|Uint16Array|Uint32Array} row
|
|
4170
|
-
* @param {number} stride
|
|
4171
|
-
*/
|
|
4172
3906
|
function decodeRowAcc(row, stride) {
|
|
4173
3907
|
let length = row.length - stride;
|
|
4174
3908
|
let offset = 0;
|
|
@@ -4180,11 +3914,6 @@ function decodeRowAcc(row, stride) {
|
|
|
4180
3914
|
length -= stride;
|
|
4181
3915
|
} while (length > 0);
|
|
4182
3916
|
}
|
|
4183
|
-
/**
|
|
4184
|
-
* @param {Uint8Array} row
|
|
4185
|
-
* @param {number} stride
|
|
4186
|
-
* @param {number} bytesPerSample
|
|
4187
|
-
*/
|
|
4188
3917
|
function decodeRowFloatingPoint(row, stride, bytesPerSample) {
|
|
4189
3918
|
let index = 0;
|
|
4190
3919
|
let count = row.length;
|
|
@@ -4203,15 +3932,6 @@ function decodeRowFloatingPoint(row, stride, bytesPerSample) {
|
|
|
4203
3932
|
}
|
|
4204
3933
|
}
|
|
4205
3934
|
}
|
|
4206
|
-
/**
|
|
4207
|
-
* @param {ArrayBufferLike} block
|
|
4208
|
-
* @param {number} predictor
|
|
4209
|
-
* @param {number} width
|
|
4210
|
-
* @param {number} height
|
|
4211
|
-
* @param {number[]} bitsPerSample
|
|
4212
|
-
* @param {number} planarConfiguration
|
|
4213
|
-
* @returns
|
|
4214
|
-
*/
|
|
4215
3935
|
function applyPredictor(block, predictor, width, height, bitsPerSample, planarConfiguration) {
|
|
4216
3936
|
if (!predictor || predictor === 1) {
|
|
4217
3937
|
return block;
|
|
@@ -4256,41 +3976,21 @@ function applyPredictor(block, predictor, width, height, bitsPerSample, planarCo
|
|
|
4256
3976
|
return block;
|
|
4257
3977
|
}
|
|
4258
3978
|
|
|
4259
|
-
/**
|
|
4260
|
-
* @typedef {Object} BaseDecoderParameters
|
|
4261
|
-
* @property {number} tileWidth
|
|
4262
|
-
* @property {number} tileHeight
|
|
4263
|
-
* @property {number} predictor
|
|
4264
|
-
* @property {number|number[]|import('../geotiff.js').TypedArray} bitsPerSample
|
|
4265
|
-
* @property {number} planarConfiguration
|
|
4266
|
-
* @property {number} [samplesPerPixel]
|
|
4267
|
-
*/
|
|
4268
3979
|
class BaseDecoder {
|
|
4269
|
-
/**
|
|
4270
|
-
* @param {BaseDecoderParameters} parameters
|
|
4271
|
-
*/
|
|
4272
3980
|
constructor(parameters) {
|
|
4273
3981
|
this.parameters = parameters;
|
|
4274
3982
|
}
|
|
4275
3983
|
/**
|
|
4276
3984
|
* @abstract
|
|
4277
|
-
* @param {ArrayBufferLike} _buffer
|
|
4278
|
-
* @returns {Promise<ArrayBufferLike>|ArrayBufferLike}
|
|
4279
3985
|
*/
|
|
4280
3986
|
decodeBlock(_buffer) {
|
|
4281
3987
|
throw new Error('decodeBlock not implemented');
|
|
4282
3988
|
}
|
|
4283
|
-
/**
|
|
4284
|
-
* @param {ArrayBufferLike} buffer
|
|
4285
|
-
* @returns {Promise<ArrayBufferLike>}
|
|
4286
|
-
*/
|
|
4287
3989
|
async decode(buffer) {
|
|
4288
3990
|
const decoded = await this.decodeBlock(buffer);
|
|
4289
3991
|
const { tileWidth, tileHeight, predictor, bitsPerSample, planarConfiguration, } = this.parameters;
|
|
4290
3992
|
if (predictor !== 1) {
|
|
4291
|
-
|
|
4292
|
-
const adaptedBitsPerSample = isBitsPerSampleArray ? Array.from(bitsPerSample) : [bitsPerSample];
|
|
4293
|
-
return applyPredictor(decoded, predictor, tileWidth, tileHeight, adaptedBitsPerSample, planarConfiguration);
|
|
3993
|
+
return applyPredictor(decoded, predictor, tileWidth, tileHeight, bitsPerSample, planarConfiguration);
|
|
4294
3994
|
}
|
|
4295
3995
|
return decoded;
|
|
4296
3996
|
}
|
|
@@ -4316,43 +4016,6 @@ class BaseDecoder {
|
|
|
4316
4016
|
* `TypedArray[] & { height: number; width: number}`
|
|
4317
4017
|
* @typedef {TypedArray[] & Dimensions} TypedArrayArrayWithDimensions
|
|
4318
4018
|
*/
|
|
4319
|
-
/**
|
|
4320
|
-
* @typedef {Object} GeotiffWriterMetadata
|
|
4321
|
-
* @property {number | number[]} [ImageWidth]
|
|
4322
|
-
* @property {number | number[]} [ImageLength]
|
|
4323
|
-
* @property {number} [width]
|
|
4324
|
-
* @property {number} [height]
|
|
4325
|
-
* @property {number | number[]} [BitsPerSample]
|
|
4326
|
-
* @property {number | number[]} [Compression]
|
|
4327
|
-
* @property {number | number[]} [PlanarConfiguration]
|
|
4328
|
-
* @property {number | number[]} [ExtraSamples]
|
|
4329
|
-
* @property {number | number[]} [PhotometricInterpretation]
|
|
4330
|
-
* @property {number | number[]} [SamplesPerPixel]
|
|
4331
|
-
* @property {number | number[]} [StripByteCounts]
|
|
4332
|
-
* @property {number[]} [ModelPixelScale]
|
|
4333
|
-
* @property {number[]} [ModelTransformation]
|
|
4334
|
-
* @property {number[]} [ModelTiepoint]
|
|
4335
|
-
* @property {number[]} [GeoKeyDirectory]
|
|
4336
|
-
* @property {string} [GeoAsciiParams]
|
|
4337
|
-
* @property {number[]} [GeoDoubleParams]
|
|
4338
|
-
* @property {number | number[]} [Orientation]
|
|
4339
|
-
* @property {number | number[]} [ResolutionUnit]
|
|
4340
|
-
* @property {number | number[]} [XPosition]
|
|
4341
|
-
* @property {number | number[]} [YPosition]
|
|
4342
|
-
* @property {number | number[]} [RowsPerStrip]
|
|
4343
|
-
* @property {number[]} [SampleFormat]
|
|
4344
|
-
* @property {number | number[]} [TileWidth]
|
|
4345
|
-
* @property {number | number[]} [TileLength]
|
|
4346
|
-
* @property {number[]} [TileOffsets]
|
|
4347
|
-
* @property {number[]} [TileByteCounts]
|
|
4348
|
-
* @property {string} [GDAL_NODATA]
|
|
4349
|
-
* @property {number | number[]} [GeographicTypeGeoKey]
|
|
4350
|
-
* @property {number | number[]} [ProjectedCSTypeGeoKey]
|
|
4351
|
-
* @property {string} [GeogCitationGeoKey]
|
|
4352
|
-
* @property {string} [GTCitationGeoKey]
|
|
4353
|
-
* @property {number | number[]} [GTModelTypeGeoKey]
|
|
4354
|
-
* @property {number | number[]} [GTRasterTypeGeoKey]
|
|
4355
|
-
*/
|
|
4356
4019
|
/**
|
|
4357
4020
|
* The autogenerated docs are a little confusing here. The effective type is:
|
|
4358
4021
|
*
|
|
@@ -4364,7 +4027,7 @@ class BaseDecoder {
|
|
|
4364
4027
|
* Use the {@link Pool.bindParameters} method to get a decoder worker for
|
|
4365
4028
|
* a specific compression and its parameters.
|
|
4366
4029
|
*
|
|
4367
|
-
* @property {(buffer:
|
|
4030
|
+
* @property {(buffer: ArrayBuffer) => Promise<ArrayBuffer>} decode
|
|
4368
4031
|
* A function that takes a compressed buffer and returns a promise resolving to the decoded buffer.
|
|
4369
4032
|
*/
|
|
4370
4033
|
/**
|
|
@@ -4403,12 +4066,12 @@ class BaseDecoder {
|
|
|
4403
4066
|
*/
|
|
4404
4067
|
/**
|
|
4405
4068
|
* @typedef {Object} BlockedSourceOptions
|
|
4406
|
-
* @property {number} [blockSize] Block size for a BlockedSource.
|
|
4069
|
+
* @property {number|null} [blockSize=null] Block size for a BlockedSource.
|
|
4407
4070
|
* @property {number} [cacheSize=100] The number of blocks to cache.
|
|
4408
4071
|
*/
|
|
4409
4072
|
/**
|
|
4410
4073
|
* @typedef {Object} RemoteSourceOptions
|
|
4411
|
-
* @property {
|
|
4074
|
+
* @property {Object} [headers={}] Additional headers to add to each request
|
|
4412
4075
|
* @property {number} [maxRanges=0] Maximum number of ranges to request in a single HTTP request. 0 means no multi-range requests.
|
|
4413
4076
|
* @property {boolean} [allowFullFile=false] Whether to allow full file responses when requesting ranges
|
|
4414
4077
|
* @property {boolean} [forceXHR=false] When the Fetch API would be used, force using XMLHttpRequest instead.
|
|
@@ -4429,7 +4092,7 @@ class BaseDecoder {
|
|
|
4429
4092
|
* @returns {TypedArray|Array<number>|string}
|
|
4430
4093
|
*/
|
|
4431
4094
|
function getValues(dataSlice, fieldType, count, offset) {
|
|
4432
|
-
/** @type {TypedArray|Array
|
|
4095
|
+
/** @type {TypedArray|Array|null} */
|
|
4433
4096
|
let values = null;
|
|
4434
4097
|
let readMethod = null;
|
|
4435
4098
|
const fieldTypeLength = getFieldTypeSize(fieldType);
|
|
@@ -4492,23 +4155,27 @@ function getValues(dataSlice, fieldType, count, offset) {
|
|
|
4492
4155
|
throw new RangeError(`Invalid field type: ${fieldType}`);
|
|
4493
4156
|
}
|
|
4494
4157
|
// normal fields
|
|
4495
|
-
{
|
|
4158
|
+
if (!(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
|
|
4496
4159
|
for (let i = 0; i < count; ++i) {
|
|
4497
4160
|
values[i] = readMethod.call(dataSlice, offset + (i * fieldTypeLength));
|
|
4498
4161
|
}
|
|
4499
4162
|
}
|
|
4500
|
-
{
|
|
4163
|
+
else { // RATIONAL or SRATIONAL
|
|
4164
|
+
for (let i = 0; i < count; i += 2) {
|
|
4165
|
+
values[i] = readMethod.call(dataSlice, offset + (i * fieldTypeLength));
|
|
4166
|
+
values[i + 1] = readMethod.call(dataSlice, offset + ((i * fieldTypeLength) + 4));
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
if (fieldType === fieldTypes.ASCII) {
|
|
4501
4170
|
return new TextDecoder('utf-8').decode(/** @type {Uint8Array} */ (values));
|
|
4502
4171
|
}
|
|
4172
|
+
return values;
|
|
4503
4173
|
}
|
|
4504
4174
|
/**
|
|
4505
4175
|
* Error class for cases when an IFD index was requested, that does not exist
|
|
4506
4176
|
* in the file.
|
|
4507
4177
|
*/
|
|
4508
4178
|
class GeoTIFFImageIndexError extends Error {
|
|
4509
|
-
/**
|
|
4510
|
-
* @param {number} index
|
|
4511
|
-
*/
|
|
4512
4179
|
constructor(index) {
|
|
4513
4180
|
super(`No image at index ${index}`);
|
|
4514
4181
|
this.index = index;
|
|
@@ -4593,7 +4260,7 @@ class GeoTIFFBase {
|
|
|
4593
4260
|
const image = await this.getImage(i);
|
|
4594
4261
|
const subfileType = image.fileDirectory.getValue('SubfileType');
|
|
4595
4262
|
const newSubfileType = image.fileDirectory.getValue('NewSubfileType');
|
|
4596
|
-
if (i === 0 || subfileType === 2 ||
|
|
4263
|
+
if (i === 0 || subfileType === 2 || newSubfileType & 1) {
|
|
4597
4264
|
allImages.push(image);
|
|
4598
4265
|
}
|
|
4599
4266
|
}
|
|
@@ -4653,16 +4320,9 @@ class GeoTIFF extends GeoTIFFBase {
|
|
|
4653
4320
|
this.bigTiff = bigTiff;
|
|
4654
4321
|
this.firstIFDOffset = firstIFDOffset;
|
|
4655
4322
|
this.cache = options.cache || false;
|
|
4656
|
-
/** @type {Array<Promise<import('./imagefiledirectory.js').ImageFileDirectory> | undefined>} */
|
|
4657
4323
|
this.ifdRequests = [];
|
|
4658
|
-
/** @type {Record<string, unknown>|null} */
|
|
4659
4324
|
this.ghostValues = null;
|
|
4660
4325
|
}
|
|
4661
|
-
/**
|
|
4662
|
-
* @param {number} offset
|
|
4663
|
-
* @param {number} [size]
|
|
4664
|
-
* @returns {Promise<DataSlice>}
|
|
4665
|
-
*/
|
|
4666
4326
|
async getSlice(offset, size) {
|
|
4667
4327
|
const fallbackSize = this.bigTiff ? 4048 : 1024;
|
|
4668
4328
|
return new DataSlice((await this.source.fetch([{
|
|
@@ -4670,10 +4330,6 @@ class GeoTIFF extends GeoTIFFBase {
|
|
|
4670
4330
|
length: typeof size !== 'undefined' ? size : fallbackSize,
|
|
4671
4331
|
}]))[0], offset, this.littleEndian, this.bigTiff);
|
|
4672
4332
|
}
|
|
4673
|
-
/**
|
|
4674
|
-
* @param {number} index
|
|
4675
|
-
* @return {Promise<import('./imagefiledirectory.js').ImageFileDirectory>}
|
|
4676
|
-
*/
|
|
4677
4333
|
async requestIFD(index) {
|
|
4678
4334
|
// see if we already have that IFD index requested.
|
|
4679
4335
|
if (this.ifdRequests[index]) {
|
|
@@ -4704,11 +4360,7 @@ class GeoTIFF extends GeoTIFFBase {
|
|
|
4704
4360
|
// if the previous IFD was loaded, we can finally fetch the one we are interested in.
|
|
4705
4361
|
// we need to wrap this in an IIFE, otherwise this.ifdRequests[index] would be delayed
|
|
4706
4362
|
this.ifdRequests[index] = (async () => {
|
|
4707
|
-
const
|
|
4708
|
-
if (!previousPromise) {
|
|
4709
|
-
throw new Error('Previous IFD request missing');
|
|
4710
|
-
}
|
|
4711
|
-
const previousIfd = await previousPromise;
|
|
4363
|
+
const previousIfd = await this.ifdRequests[index - 1];
|
|
4712
4364
|
if (previousIfd.nextIFDByteOffset === 0) {
|
|
4713
4365
|
throw new GeoTIFFImageIndexError(index);
|
|
4714
4366
|
}
|
|
@@ -4753,11 +4405,11 @@ class GeoTIFF extends GeoTIFFBase {
|
|
|
4753
4405
|
/**
|
|
4754
4406
|
* Get the values of the COG ghost area as a parsed map.
|
|
4755
4407
|
* See https://gdal.org/drivers/raster/cog.html#header-ghost-area for reference
|
|
4756
|
-
* @returns {Promise<
|
|
4408
|
+
* @returns {Promise<Object>} the parsed ghost area or null, if no such area was found
|
|
4757
4409
|
*/
|
|
4758
4410
|
async getGhostValues() {
|
|
4759
4411
|
const offset = this.bigTiff ? 16 : 8;
|
|
4760
|
-
if (this.ghostValues
|
|
4412
|
+
if (this.ghostValues) {
|
|
4761
4413
|
return this.ghostValues;
|
|
4762
4414
|
}
|
|
4763
4415
|
const detectionString = 'GDAL_STRUCTURAL_METADATA_SIZE=';
|
|
@@ -4771,16 +4423,15 @@ class GeoTIFF extends GeoTIFFBase {
|
|
|
4771
4423
|
slice = await this.getSlice(offset, metadataSize);
|
|
4772
4424
|
}
|
|
4773
4425
|
const fullString = getValues(slice, fieldTypes.ASCII, metadataSize, offset);
|
|
4774
|
-
/** @type {
|
|
4775
|
-
|
|
4426
|
+
/** @type {Object} */
|
|
4427
|
+
this.ghostValues = {};
|
|
4776
4428
|
fullString
|
|
4777
4429
|
.split('\n')
|
|
4778
4430
|
.filter((line) => line.length > 0)
|
|
4779
4431
|
.map((line) => line.split('='))
|
|
4780
4432
|
.forEach(([key, value]) => {
|
|
4781
|
-
ghostValues[key] = value;
|
|
4433
|
+
this.ghostValues[key] = value;
|
|
4782
4434
|
});
|
|
4783
|
-
this.ghostValues = ghostValues;
|
|
4784
4435
|
}
|
|
4785
4436
|
return this.ghostValues;
|
|
4786
4437
|
}
|
|
@@ -4795,7 +4446,7 @@ class GeoTIFF extends GeoTIFFBase {
|
|
|
4795
4446
|
static async fromSource(source, options, signal) {
|
|
4796
4447
|
const headerData = (await source.fetch([{ offset: 0, length: 1024 }], signal))[0];
|
|
4797
4448
|
const dataView = new DataView64(headerData);
|
|
4798
|
-
const BOM = dataView.getUint16(0,
|
|
4449
|
+
const BOM = dataView.getUint16(0, 0);
|
|
4799
4450
|
let littleEndian;
|
|
4800
4451
|
if (BOM === 0x4949) {
|
|
4801
4452
|
littleEndian = true;
|
|
@@ -7063,7 +6714,6 @@ class CogTerrainLayer extends CompositeLayer {
|
|
|
7063
6714
|
}
|
|
7064
6715
|
|
|
7065
6716
|
class RawDecoder extends BaseDecoder {
|
|
7066
|
-
/** @param {ArrayBuffer} buffer */
|
|
7067
6717
|
decodeBlock(buffer) {
|
|
7068
6718
|
return buffer;
|
|
7069
6719
|
}
|
|
@@ -7078,12 +6728,6 @@ const MIN_BITS = 9;
|
|
|
7078
6728
|
const CLEAR_CODE = 256; // clear code
|
|
7079
6729
|
const EOI_CODE = 257; // end of information
|
|
7080
6730
|
const MAX_BYTELENGTH = 12;
|
|
7081
|
-
/**
|
|
7082
|
-
* @param {Uint8Array} array
|
|
7083
|
-
* @param {number} position
|
|
7084
|
-
* @param {number} length
|
|
7085
|
-
* @returns {number}
|
|
7086
|
-
*/
|
|
7087
6731
|
function getByte(array, position, length) {
|
|
7088
6732
|
const d = position % 8;
|
|
7089
6733
|
const a = Math.floor(position / 8);
|
|
@@ -7111,21 +6755,12 @@ function getByte(array, position, length) {
|
|
|
7111
6755
|
}
|
|
7112
6756
|
return chunks;
|
|
7113
6757
|
}
|
|
7114
|
-
/**
|
|
7115
|
-
* @template T
|
|
7116
|
-
* @param {Array<T>} dest
|
|
7117
|
-
* @param {Array<T>} source
|
|
7118
|
-
* @returns {Array<T>}
|
|
7119
|
-
*/
|
|
7120
6758
|
function appendReversed(dest, source) {
|
|
7121
6759
|
for (let i = source.length - 1; i >= 0; i--) {
|
|
7122
6760
|
dest.push(source[i]);
|
|
7123
6761
|
}
|
|
7124
6762
|
return dest;
|
|
7125
6763
|
}
|
|
7126
|
-
/**
|
|
7127
|
-
* @param {ArrayBuffer} input
|
|
7128
|
-
*/
|
|
7129
6764
|
function decompress(input) {
|
|
7130
6765
|
const dictionaryIndex = new Uint16Array(4093);
|
|
7131
6766
|
const dictionaryChar = new Uint8Array(4093);
|
|
@@ -7140,23 +6775,17 @@ function decompress(input) {
|
|
|
7140
6775
|
dictionaryLength = 258;
|
|
7141
6776
|
byteLength = MIN_BITS;
|
|
7142
6777
|
}
|
|
7143
|
-
/** @param {Uint8Array} array */
|
|
7144
6778
|
function getNext(array) {
|
|
7145
6779
|
const byte = getByte(array, position, byteLength);
|
|
7146
6780
|
position += byteLength;
|
|
7147
6781
|
return byte;
|
|
7148
6782
|
}
|
|
7149
|
-
/**
|
|
7150
|
-
* @param {number} i
|
|
7151
|
-
* @param {number} c
|
|
7152
|
-
*/
|
|
7153
6783
|
function addToDictionary(i, c) {
|
|
7154
6784
|
dictionaryChar[dictionaryLength] = c;
|
|
7155
6785
|
dictionaryIndex[dictionaryLength] = i;
|
|
7156
6786
|
dictionaryLength++;
|
|
7157
6787
|
return dictionaryLength - 1;
|
|
7158
6788
|
}
|
|
7159
|
-
/** @param {number} n */
|
|
7160
6789
|
function getDictionaryReversed(n) {
|
|
7161
6790
|
const rev = [];
|
|
7162
6791
|
for (let i = n; i !== 4096; i = dictionaryIndex[i]) {
|
|
@@ -7191,15 +6820,10 @@ function decompress(input) {
|
|
|
7191
6820
|
else if (code < dictionaryLength) {
|
|
7192
6821
|
const val = getDictionaryReversed(code);
|
|
7193
6822
|
appendReversed(result, val);
|
|
7194
|
-
|
|
7195
|
-
addToDictionary(oldCode, val[val.length - 1]);
|
|
7196
|
-
}
|
|
6823
|
+
addToDictionary(oldCode, val[val.length - 1]);
|
|
7197
6824
|
oldCode = code;
|
|
7198
6825
|
}
|
|
7199
6826
|
else {
|
|
7200
|
-
if (oldCode === undefined) {
|
|
7201
|
-
throw new Error(`Invalid LZW code: ${code} with no previous code`);
|
|
7202
|
-
}
|
|
7203
6827
|
const oldVal = getDictionaryReversed(oldCode);
|
|
7204
6828
|
if (!oldVal) {
|
|
7205
6829
|
throw new Error(`Bogus entry. Not in dictionary, ${oldCode} / ${dictionaryLength}, position: ${position}`);
|
|
@@ -7222,7 +6846,6 @@ function decompress(input) {
|
|
|
7222
6846
|
return new Uint8Array(result);
|
|
7223
6847
|
}
|
|
7224
6848
|
class LZWDecoder extends BaseDecoder {
|
|
7225
|
-
/** @param {ArrayBuffer} buffer */
|
|
7226
6849
|
decodeBlock(buffer) {
|
|
7227
6850
|
return decompress(buffer).buffer;
|
|
7228
6851
|
}
|
|
@@ -7281,33 +6904,6 @@ const dctSqrt2 = 5793; // sqrt(2)
|
|
|
7281
6904
|
const dctSqrt1d2 = 2896; // sqrt(2) / 2
|
|
7282
6905
|
/** @typedef {(number|HuffmanNode)[]} HuffmanNode */
|
|
7283
6906
|
/** @typedef {{children: HuffmanNode, index: number}} Code */
|
|
7284
|
-
/**
|
|
7285
|
-
* @typedef {Object} JpegComponent
|
|
7286
|
-
* @property {number} h
|
|
7287
|
-
* @property {number} v
|
|
7288
|
-
* @property {number} [quantizationIdx]
|
|
7289
|
-
* @property {Int32Array} [quantizationTable]
|
|
7290
|
-
* @property {number} blocksPerLine
|
|
7291
|
-
* @property {number} blocksPerColumn
|
|
7292
|
-
* @property {Int32Array[][]} blocks
|
|
7293
|
-
* @property {HuffmanNode} [huffmanTableDC]
|
|
7294
|
-
* @property {HuffmanNode} [huffmanTableAC]
|
|
7295
|
-
* @property {number} [pred]
|
|
7296
|
-
*/
|
|
7297
|
-
/**
|
|
7298
|
-
* @typedef {Object} JpegFrame
|
|
7299
|
-
* @property {boolean} extended
|
|
7300
|
-
* @property {boolean} progressive
|
|
7301
|
-
* @property {number} precision
|
|
7302
|
-
* @property {number} scanLines
|
|
7303
|
-
* @property {number} samplesPerLine
|
|
7304
|
-
* @property {Object.<string, JpegComponent>} components
|
|
7305
|
-
* @property {number[]} componentsOrder
|
|
7306
|
-
* @property {number} maxH
|
|
7307
|
-
* @property {number} maxV
|
|
7308
|
-
* @property {number} mcusPerLine
|
|
7309
|
-
* @property {number} mcusPerColumn
|
|
7310
|
-
*/
|
|
7311
6907
|
/**
|
|
7312
6908
|
* @param {Uint8Array<ArrayBuffer>} codeLengths
|
|
7313
6909
|
* @param {Uint8Array<ArrayBuffer>} values
|
|
@@ -7357,25 +6953,8 @@ function buildHuffmanTable(codeLengths, values) {
|
|
|
7357
6953
|
}
|
|
7358
6954
|
return code[0].children;
|
|
7359
6955
|
}
|
|
7360
|
-
/**
|
|
7361
|
-
* @param {Uint8Array} data
|
|
7362
|
-
* @param {number} initialOffset
|
|
7363
|
-
* @param {JpegFrame} frame
|
|
7364
|
-
* @param {JpegComponent[]} components
|
|
7365
|
-
* @param {number} resetInterval
|
|
7366
|
-
* @param {number} spectralStart
|
|
7367
|
-
* @param {number} spectralEnd
|
|
7368
|
-
* @param {number} successivePrev
|
|
7369
|
-
* @param {number} successive
|
|
7370
|
-
*/
|
|
7371
6956
|
function decodeScan(data, initialOffset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
|
|
7372
6957
|
const { mcusPerLine, progressive } = frame;
|
|
7373
|
-
if (components.length > 1 && (mcusPerLine === undefined || frame.mcusPerColumn === undefined)) {
|
|
7374
|
-
throw new Error('Missing MCU dimensions');
|
|
7375
|
-
}
|
|
7376
|
-
if (components.length === 1 && (components[0].blocksPerLine === undefined || components[0].blocksPerColumn === undefined)) {
|
|
7377
|
-
throw new Error('Missing block dimensions');
|
|
7378
|
-
}
|
|
7379
6958
|
const startOffset = initialOffset;
|
|
7380
6959
|
let offset = initialOffset;
|
|
7381
6960
|
let bitsData = 0;
|
|
@@ -7396,26 +6975,20 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7396
6975
|
bitsCount = 7;
|
|
7397
6976
|
return bitsData >>> 7;
|
|
7398
6977
|
}
|
|
7399
|
-
/** @param {HuffmanNode|undefined} tree */
|
|
7400
6978
|
function decodeHuffman(tree) {
|
|
7401
|
-
if (!tree) {
|
|
7402
|
-
throw new Error('Huffman table not found');
|
|
7403
|
-
}
|
|
7404
6979
|
let node = tree;
|
|
7405
6980
|
let bit;
|
|
7406
6981
|
while ((bit = readBit()) !== null) { // eslint-disable-line no-cond-assign
|
|
7407
|
-
|
|
7408
|
-
if (typeof
|
|
7409
|
-
return
|
|
6982
|
+
node = node[bit];
|
|
6983
|
+
if (typeof node === 'number') {
|
|
6984
|
+
return node;
|
|
7410
6985
|
}
|
|
7411
|
-
if (typeof
|
|
6986
|
+
if (typeof node !== 'object') {
|
|
7412
6987
|
throw new Error('invalid huffman sequence');
|
|
7413
6988
|
}
|
|
7414
|
-
node = next;
|
|
7415
6989
|
}
|
|
7416
6990
|
return null;
|
|
7417
6991
|
}
|
|
7418
|
-
/** @param {number} initialLength */
|
|
7419
6992
|
function receive(initialLength) {
|
|
7420
6993
|
let length = initialLength;
|
|
7421
6994
|
let n = 0;
|
|
@@ -7429,7 +7002,6 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7429
7002
|
}
|
|
7430
7003
|
return n;
|
|
7431
7004
|
}
|
|
7432
|
-
/** @param {number} length */
|
|
7433
7005
|
function receiveAndExtend(length) {
|
|
7434
7006
|
const n = receive(length);
|
|
7435
7007
|
if (n === undefined) {
|
|
@@ -7440,22 +7012,9 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7440
7012
|
}
|
|
7441
7013
|
return n + (-1 << length) + 1;
|
|
7442
7014
|
}
|
|
7443
|
-
/**
|
|
7444
|
-
* @param {JpegComponent} component
|
|
7445
|
-
* @param {Int32Array} zz
|
|
7446
|
-
*/
|
|
7447
7015
|
function decodeBaseline(component, zz) {
|
|
7448
7016
|
const t = decodeHuffman(component.huffmanTableDC);
|
|
7449
|
-
if (t === null) {
|
|
7450
|
-
throw new Error('Huffman error');
|
|
7451
|
-
}
|
|
7452
7017
|
const diff = t === 0 ? 0 : receiveAndExtend(t);
|
|
7453
|
-
if (diff === undefined) {
|
|
7454
|
-
throw new Error('Unexpected end of stream');
|
|
7455
|
-
}
|
|
7456
|
-
if (component.pred === undefined) {
|
|
7457
|
-
component.pred = 0;
|
|
7458
|
-
}
|
|
7459
7018
|
component.pred += diff;
|
|
7460
7019
|
zz[0] = component.pred;
|
|
7461
7020
|
let k = 1;
|
|
@@ -7475,51 +7034,25 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7475
7034
|
else {
|
|
7476
7035
|
k += r;
|
|
7477
7036
|
const z = dctZigZag[k];
|
|
7478
|
-
|
|
7479
|
-
if (val === undefined) {
|
|
7480
|
-
throw new Error('Unexpected end of stream');
|
|
7481
|
-
}
|
|
7482
|
-
zz[z] = val;
|
|
7037
|
+
zz[z] = receiveAndExtend(s);
|
|
7483
7038
|
k++;
|
|
7484
7039
|
}
|
|
7485
7040
|
}
|
|
7486
7041
|
}
|
|
7487
|
-
/**
|
|
7488
|
-
* @param {JpegComponent} component
|
|
7489
|
-
* @param {Int32Array} zz
|
|
7490
|
-
*/
|
|
7491
7042
|
function decodeDCFirst(component, zz) {
|
|
7492
7043
|
const t = decodeHuffman(component.huffmanTableDC);
|
|
7493
|
-
if (t === null) {
|
|
7494
|
-
throw new Error('Huffman error');
|
|
7495
|
-
}
|
|
7496
7044
|
const value = receiveAndExtend(t);
|
|
7497
7045
|
if (value === undefined) {
|
|
7498
7046
|
throw new Error('Unexpected end of data in DC coefficient decoding');
|
|
7499
7047
|
}
|
|
7500
7048
|
const diff = t === 0 ? 0 : (value << successive);
|
|
7501
|
-
if (component.pred === undefined) {
|
|
7502
|
-
component.pred = 0;
|
|
7503
|
-
}
|
|
7504
7049
|
component.pred += diff;
|
|
7505
7050
|
zz[0] = component.pred;
|
|
7506
7051
|
}
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
* @param {Int32Array} zz
|
|
7510
|
-
*/
|
|
7511
|
-
function decodeDCSuccessive(_, zz) {
|
|
7512
|
-
const bit = readBit();
|
|
7513
|
-
if (bit === null) {
|
|
7514
|
-
throw new Error('Unexpected end of data in DC coefficient decoding');
|
|
7515
|
-
}
|
|
7516
|
-
zz[0] |= bit << successive;
|
|
7052
|
+
function decodeDCSuccessive(component, zz) {
|
|
7053
|
+
zz[0] |= readBit() << successive;
|
|
7517
7054
|
}
|
|
7518
7055
|
let eobrun = 0;
|
|
7519
|
-
/**
|
|
7520
|
-
* @param {JpegComponent} component
|
|
7521
|
-
* @param {Int32Array} zz
|
|
7522
|
-
*/
|
|
7523
7056
|
function decodeACFirst(component, zz) {
|
|
7524
7057
|
if (eobrun > 0) {
|
|
7525
7058
|
eobrun--;
|
|
@@ -7558,12 +7091,7 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7558
7091
|
}
|
|
7559
7092
|
}
|
|
7560
7093
|
let successiveACState = 0;
|
|
7561
|
-
/** @type {number} */
|
|
7562
7094
|
let successiveACNextValue;
|
|
7563
|
-
/**
|
|
7564
|
-
* @param {JpegComponent} component
|
|
7565
|
-
* @param {Int32Array} zz
|
|
7566
|
-
*/
|
|
7567
7095
|
function decodeACSuccessive(component, zz) {
|
|
7568
7096
|
let k = spectralStart;
|
|
7569
7097
|
const e = spectralEnd;
|
|
@@ -7597,11 +7125,7 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7597
7125
|
if (s !== 1) {
|
|
7598
7126
|
throw new Error('invalid ACn encoding');
|
|
7599
7127
|
}
|
|
7600
|
-
|
|
7601
|
-
if (nextVal === undefined) {
|
|
7602
|
-
throw new Error('Unexpected end of data in AC coefficient decoding');
|
|
7603
|
-
}
|
|
7604
|
-
successiveACNextValue = nextVal;
|
|
7128
|
+
successiveACNextValue = receiveAndExtend(s);
|
|
7605
7129
|
successiveACState = r ? 2 : 3;
|
|
7606
7130
|
}
|
|
7607
7131
|
continue; // eslint-disable-line no-continue
|
|
@@ -7609,11 +7133,7 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7609
7133
|
case 1: // skipping r zero items
|
|
7610
7134
|
case 2:
|
|
7611
7135
|
if (zz[z]) {
|
|
7612
|
-
|
|
7613
|
-
if (bit === null) {
|
|
7614
|
-
throw new Error('Unexpected end of data in AC coefficient decoding');
|
|
7615
|
-
}
|
|
7616
|
-
zz[z] += (bit << successive) * direction;
|
|
7136
|
+
zz[z] += (readBit() << successive) * direction;
|
|
7617
7137
|
}
|
|
7618
7138
|
else {
|
|
7619
7139
|
r--;
|
|
@@ -7624,11 +7144,7 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7624
7144
|
break;
|
|
7625
7145
|
case 3: // set value for a zero item
|
|
7626
7146
|
if (zz[z]) {
|
|
7627
|
-
|
|
7628
|
-
if (bit === null) {
|
|
7629
|
-
throw new Error('Unexpected end of data in AC coefficient decoding');
|
|
7630
|
-
}
|
|
7631
|
-
zz[z] += (bit << successive) * direction;
|
|
7147
|
+
zz[z] += (readBit() << successive) * direction;
|
|
7632
7148
|
}
|
|
7633
7149
|
else {
|
|
7634
7150
|
zz[z] = successiveACNextValue << successive;
|
|
@@ -7637,11 +7153,7 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7637
7153
|
break;
|
|
7638
7154
|
case 4: // eob
|
|
7639
7155
|
if (zz[z]) {
|
|
7640
|
-
|
|
7641
|
-
if (bit === null) {
|
|
7642
|
-
throw new Error('Unexpected end of data in AC coefficient decoding');
|
|
7643
|
-
}
|
|
7644
|
-
zz[z] += (bit << successive) * direction;
|
|
7156
|
+
zz[z] += (readBit() << successive) * direction;
|
|
7645
7157
|
}
|
|
7646
7158
|
break;
|
|
7647
7159
|
}
|
|
@@ -7654,34 +7166,16 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7654
7166
|
}
|
|
7655
7167
|
}
|
|
7656
7168
|
}
|
|
7657
|
-
/**
|
|
7658
|
-
* @param {JpegComponent} component
|
|
7659
|
-
* @param {function} decodeFunction
|
|
7660
|
-
* @param {number} mcu
|
|
7661
|
-
* @param {number} row
|
|
7662
|
-
* @param {number} col
|
|
7663
|
-
*/
|
|
7664
7169
|
function decodeMcu(component, decodeFunction, mcu, row, col) {
|
|
7665
7170
|
const mcuRow = (mcu / mcusPerLine) | 0;
|
|
7666
7171
|
const mcuCol = mcu % mcusPerLine;
|
|
7667
7172
|
const blockRow = (mcuRow * component.v) + row;
|
|
7668
7173
|
const blockCol = (mcuCol * component.h) + col;
|
|
7669
|
-
if (!component.blocks) {
|
|
7670
|
-
throw new Error('Missing blocks');
|
|
7671
|
-
}
|
|
7672
7174
|
decodeFunction(component, component.blocks[blockRow][blockCol]);
|
|
7673
7175
|
}
|
|
7674
|
-
/**
|
|
7675
|
-
* @param {JpegComponent} component
|
|
7676
|
-
* @param {function} decodeFunction
|
|
7677
|
-
* @param {number} mcu
|
|
7678
|
-
*/
|
|
7679
7176
|
function decodeBlock(component, decodeFunction, mcu) {
|
|
7680
7177
|
const blockRow = (mcu / component.blocksPerLine) | 0;
|
|
7681
7178
|
const blockCol = mcu % component.blocksPerLine;
|
|
7682
|
-
if (!component.blocks) {
|
|
7683
|
-
throw new Error('Missing blocks');
|
|
7684
|
-
}
|
|
7685
7179
|
decodeFunction(component, component.blocks[blockRow][blockCol]);
|
|
7686
7180
|
}
|
|
7687
7181
|
const componentsLength = components.length;
|
|
@@ -7758,15 +7252,9 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
|
|
|
7758
7252
|
}
|
|
7759
7253
|
return offset - startOffset;
|
|
7760
7254
|
}
|
|
7761
|
-
|
|
7762
|
-
* @param {JpegComponent} component
|
|
7763
|
-
*/
|
|
7764
|
-
function buildComponentData(component) {
|
|
7255
|
+
function buildComponentData(frame, component) {
|
|
7765
7256
|
const lines = [];
|
|
7766
7257
|
const { blocksPerLine, blocksPerColumn } = component;
|
|
7767
|
-
if (!blocksPerLine || !blocksPerColumn || !component.blocks) {
|
|
7768
|
-
throw new Error('Missing component data');
|
|
7769
|
-
}
|
|
7770
7258
|
const samplesPerLine = blocksPerLine << 3;
|
|
7771
7259
|
const R = new Int32Array(64);
|
|
7772
7260
|
const r = new Uint8Array(64);
|
|
@@ -7775,16 +7263,8 @@ function buildComponentData(component) {
|
|
|
7775
7263
|
// "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
|
|
7776
7264
|
// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
|
|
7777
7265
|
// 988-991.
|
|
7778
|
-
/**
|
|
7779
|
-
* @param {Int32Array} zz
|
|
7780
|
-
* @param {Uint8Array} dataOut
|
|
7781
|
-
* @param {Int32Array} dataIn
|
|
7782
|
-
*/
|
|
7783
7266
|
function quantizeAndInverse(zz, dataOut, dataIn) {
|
|
7784
7267
|
const qt = component.quantizationTable;
|
|
7785
|
-
if (!qt) {
|
|
7786
|
-
throw new Error('No quantization table found');
|
|
7787
|
-
}
|
|
7788
7268
|
let v0;
|
|
7789
7269
|
let v1;
|
|
7790
7270
|
let v2;
|
|
@@ -7963,21 +7443,14 @@ class JpegStreamReader {
|
|
|
7963
7443
|
constructor() {
|
|
7964
7444
|
this.jfif = null;
|
|
7965
7445
|
this.adobe = null;
|
|
7966
|
-
/** @type {number} */
|
|
7967
|
-
this.resetInterval = 0;
|
|
7968
|
-
/** @type {Int32Array[]} */
|
|
7969
7446
|
this.quantizationTables = [];
|
|
7970
|
-
/** @type {HuffmanNode[]} */
|
|
7971
7447
|
this.huffmanTablesAC = [];
|
|
7972
|
-
/** @type {HuffmanNode[]} */
|
|
7973
7448
|
this.huffmanTablesDC = [];
|
|
7974
|
-
/** @type {JpegFrame[]} */
|
|
7975
7449
|
this.frames = [];
|
|
7976
7450
|
}
|
|
7977
7451
|
resetFrames() {
|
|
7978
7452
|
this.frames = [];
|
|
7979
7453
|
}
|
|
7980
|
-
/** @param {Uint8Array} data */
|
|
7981
7454
|
parse(data) {
|
|
7982
7455
|
let offset = 0;
|
|
7983
7456
|
// const { length } = data;
|
|
@@ -7992,7 +7465,6 @@ class JpegStreamReader {
|
|
|
7992
7465
|
offset += array.length;
|
|
7993
7466
|
return array;
|
|
7994
7467
|
}
|
|
7995
|
-
/** @param {JpegFrame} frame */
|
|
7996
7468
|
function prepareComponents(frame) {
|
|
7997
7469
|
let maxH = 0;
|
|
7998
7470
|
let maxV = 0;
|
|
@@ -8119,21 +7591,15 @@ class JpegStreamReader {
|
|
|
8119
7591
|
case 0xFFC1: // SOF1 (Start of Frame, Extended DCT)
|
|
8120
7592
|
case 0xFFC2: { // SOF2 (Start of Frame, Progressive DCT)
|
|
8121
7593
|
readUint16(); // skip data length
|
|
8122
|
-
/** @type {JpegFrame} */
|
|
8123
7594
|
const frame = {
|
|
8124
7595
|
extended: (fileMarker === 0xFFC1),
|
|
8125
7596
|
progressive: (fileMarker === 0xFFC2),
|
|
8126
7597
|
precision: data[offset++],
|
|
8127
7598
|
scanLines: readUint16(),
|
|
8128
7599
|
samplesPerLine: readUint16(),
|
|
8129
|
-
/** @type {Object.<string, JpegComponent>} */
|
|
8130
7600
|
components: {},
|
|
8131
|
-
/** @type {
|
|
7601
|
+
/** @type {any[]} */
|
|
8132
7602
|
componentsOrder: [],
|
|
8133
|
-
maxH: 0,
|
|
8134
|
-
maxV: 0,
|
|
8135
|
-
mcusPerLine: 0,
|
|
8136
|
-
mcusPerColumn: 0,
|
|
8137
7603
|
};
|
|
8138
7604
|
const componentsCount = data[offset++];
|
|
8139
7605
|
let componentId;
|
|
@@ -8149,9 +7615,6 @@ class JpegStreamReader {
|
|
|
8149
7615
|
h,
|
|
8150
7616
|
v,
|
|
8151
7617
|
quantizationIdx: qId,
|
|
8152
|
-
blocksPerLine: 0,
|
|
8153
|
-
blocksPerColumn: 0,
|
|
8154
|
-
blocks: [],
|
|
8155
7618
|
};
|
|
8156
7619
|
offset += 3;
|
|
8157
7620
|
}
|
|
@@ -8236,17 +7699,11 @@ class JpegStreamReader {
|
|
|
8236
7699
|
for (let i = 0; i < this.frames.length; i++) {
|
|
8237
7700
|
const cp = this.frames[i].components;
|
|
8238
7701
|
for (const j of Object.keys(cp)) {
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
cp[j].quantizationTable = this.quantizationTables[qIdx];
|
|
8242
|
-
delete cp[j].quantizationIdx;
|
|
8243
|
-
}
|
|
7702
|
+
cp[j].quantizationTable = this.quantizationTables[cp[j].quantizationIdx];
|
|
7703
|
+
delete cp[j].quantizationIdx;
|
|
8244
7704
|
}
|
|
8245
7705
|
}
|
|
8246
7706
|
const frame = frames[0];
|
|
8247
|
-
if (!frame.maxH || !frame.maxV) {
|
|
8248
|
-
throw new Error('Invalid frame dimensions');
|
|
8249
|
-
}
|
|
8250
7707
|
const { components, componentsOrder } = frame;
|
|
8251
7708
|
const outComponents = [];
|
|
8252
7709
|
const width = frame.samplesPerLine;
|
|
@@ -8254,7 +7711,7 @@ class JpegStreamReader {
|
|
|
8254
7711
|
for (let i = 0; i < componentsOrder.length; i++) {
|
|
8255
7712
|
const component = components[componentsOrder[i]];
|
|
8256
7713
|
outComponents.push({
|
|
8257
|
-
lines: buildComponentData(component),
|
|
7714
|
+
lines: buildComponentData(frame, component),
|
|
8258
7715
|
scaleX: component.h / frame.maxH,
|
|
8259
7716
|
scaleY: component.v / frame.maxV,
|
|
8260
7717
|
});
|
|
@@ -8274,9 +7731,6 @@ class JpegStreamReader {
|
|
|
8274
7731
|
}
|
|
8275
7732
|
}
|
|
8276
7733
|
class JpegDecoder extends BaseDecoder {
|
|
8277
|
-
/**
|
|
8278
|
-
* @param {import('./basedecoder.js').BaseDecoderParameters & { JPEGTables?: Uint8Array }} parameters
|
|
8279
|
-
*/
|
|
8280
7734
|
constructor(parameters) {
|
|
8281
7735
|
super(parameters);
|
|
8282
7736
|
this.reader = new JpegStreamReader();
|
|
@@ -8284,7 +7738,6 @@ class JpegDecoder extends BaseDecoder {
|
|
|
8284
7738
|
this.reader.parse(parameters.JPEGTables);
|
|
8285
7739
|
}
|
|
8286
7740
|
}
|
|
8287
|
-
/** @param {ArrayBuffer} buffer */
|
|
8288
7741
|
decodeBlock(buffer) {
|
|
8289
7742
|
this.reader.resetFrames();
|
|
8290
7743
|
this.reader.parse(new Uint8Array(buffer));
|
|
@@ -11533,7 +10986,6 @@ const { inflate} = inflate_1$1;
|
|
|
11533
10986
|
var inflate_1 = inflate;
|
|
11534
10987
|
|
|
11535
10988
|
class DeflateDecoder extends BaseDecoder {
|
|
11536
|
-
/** @param {ArrayBuffer} buffer */
|
|
11537
10989
|
decodeBlock(buffer) {
|
|
11538
10990
|
return inflate_1(new Uint8Array(buffer)).buffer;
|
|
11539
10991
|
}
|
|
@@ -11545,7 +10997,6 @@ var deflate = /*#__PURE__*/Object.freeze({
|
|
|
11545
10997
|
});
|
|
11546
10998
|
|
|
11547
10999
|
class PackbitsDecoder extends BaseDecoder {
|
|
11548
|
-
/** @param {ArrayBuffer} buffer */
|
|
11549
11000
|
decodeBlock(buffer) {
|
|
11550
11001
|
const dataView = new DataView(buffer);
|
|
11551
11002
|
const out = [];
|
|
@@ -13993,33 +13444,23 @@ let ZSTDDecoder$1 = class ZSTDDecoder {
|
|
|
13993
13444
|
// wasm:begin
|
|
13994
13445
|
const wasm$1 = 'AGFzbQEAAAABoAEUYAF/AGADf39/AGACf38AYAF/AX9gBX9/f39/AX9gA39/fwF/YAR/f39/AX9gAn9/AX9gAAF/YAd/f39/f39/AX9gB39/f39/f38AYAR/f39/AX5gAn9/AX5gBn9/f39/fwBgDn9/f39/f39/f39/f39/AX9gCH9/f39/f39/AX9gCX9/f39/f39/fwF/YAN+f38BfmAFf39/f38AYAAAAicBA2Vudh9lbXNjcmlwdGVuX25vdGlmeV9tZW1vcnlfZ3Jvd3RoAAADJyYDAAMACAQJBQEHBwADBgoLBAQDBAEABgUMBQ0OAQEBDxAREgYAEwQFAXABAgIFBwEBggKAgAIGCAF/AUGgnwQLB9MBCgZtZW1vcnkCAAxaU1REX2lzRXJyb3IADRlaU1REX2ZpbmREZWNvbXByZXNzZWRTaXplABkPWlNURF9kZWNvbXByZXNzACQGbWFsbG9jAAEEZnJlZQACGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBABlfZW1zY3JpcHRlbl9zdGFja19yZXN0b3JlAAQcZW1zY3JpcHRlbl9zdGFja19nZXRfY3VycmVudAAFIl9fY3hhX2luY3JlbWVudF9leGNlcHRpb25fcmVmY291bnQAJQkHAQBBAQsBJgwBCgqtkgMm1ScBC38jAEEQayIKJAACQAJAAkACQAJAAkACQAJAAkACQCAAQfQBTQRAQagbKAIAIgRBECAAQQtqQfgDcSAAQQtJGyIGQQN2IgB2IgFBA3EEQAJAIAFBf3NBAXEgAGoiAkEDdCIBQdAbaiIAIAFB2BtqKAIAIgEoAggiBUYEQEGoGyAEQX4gAndxNgIADAELIAUgADYCDCAAIAU2AggLIAFBCGohACABIAJBA3QiAkEDcjYCBCABIAJqIgEgASgCBEEBcjYCBAwLCyAGQbAbKAIAIghNDQEgAQRAAkBBAiAAdCICQQAgAmtyIAEgAHRxaCIBQQN0IgBB0BtqIgIgAEHYG2ooAgAiACgCCCIFRgRAQagbIARBfiABd3EiBDYCAAwBCyAFIAI2AgwgAiAFNgIICyAAIAZBA3I2AgQgACAGaiIHIAFBA3QiASAGayIFQQFyNgIEIAAgAWogBTYCACAIBEAgCEF4cUHQG2ohAUG8GygCACECAn8gBEEBIAhBA3Z0IgNxRQRAQagbIAMgBHI2AgAgAQwBCyABKAIICyEDIAEgAjYCCCADIAI2AgwgAiABNgIMIAIgAzYCCAsgAEEIaiEAQbwbIAc2AgBBsBsgBTYCAAwLC0GsGygCACILRQ0BIAtoQQJ0QdgdaigCACICKAIEQXhxIAZrIQMgAiEBA0ACQCABKAIQIgBFBEAgASgCFCIARQ0BCyAAKAIEQXhxIAZrIgEgAyABIANJIgEbIQMgACACIAEbIQIgACEBDAELCyACKAIYIQkgAiACKAIMIgBHBEAgAigCCCIBIAA2AgwgACABNgIIDAoLIAIoAhQiAQR/IAJBFGoFIAIoAhAiAUUNAyACQRBqCyEFA0AgBSEHIAEiAEEUaiEFIAAoAhQiAQ0AIABBEGohBSAAKAIQIgENAAsgB0EANgIADAkLQX8hBiAAQb9/Sw0AIABBC2oiAUF4cSEGQawbKAIAIgdFDQBBHyEIQQAgBmshAyAAQfT//wdNBEAgBkEmIAFBCHZnIgBrdkEBcSAAQQF0a0E+aiEICwJAAkACQCAIQQJ0QdgdaigCACIBRQRAQQAhAAwBC0EAIQAgBkEZIAhBAXZrQQAgCEEfRxt0IQIDQAJAIAEoAgRBeHEgBmsiBCADTw0AIAEhBSAEIgMNAEEAIQMgASEADAMLIAAgASgCFCIEIAQgASACQR12QQRxaigCECIBRhsgACAEGyEAIAJBAXQhAiABDQALCyAAIAVyRQRAQQAhBUECIAh0IgBBACAAa3IgB3EiAEUNAyAAaEECdEHYHWooAgAhAAsgAEUNAQsDQCAAKAIEQXhxIAZrIgIgA0khASACIAMgARshAyAAIAUgARshBSAAKAIQIgEEfyABBSAAKAIUCyIADQALCyAFRQ0AIANBsBsoAgAgBmtPDQAgBSgCGCEIIAUgBSgCDCIARwRAIAUoAggiASAANgIMIAAgATYCCAwICyAFKAIUIgEEfyAFQRRqBSAFKAIQIgFFDQMgBUEQagshAgNAIAIhBCABIgBBFGohAiAAKAIUIgENACAAQRBqIQIgACgCECIBDQALIARBADYCAAwHCyAGQbAbKAIAIgVNBEBBvBsoAgAhAAJAIAUgBmsiAUEQTwRAIAAgBmoiAiABQQFyNgIEIAAgBWogATYCACAAIAZBA3I2AgQMAQsgACAFQQNyNgIEIAAgBWoiASABKAIEQQFyNgIEQQAhAkEAIQELQbAbIAE2AgBBvBsgAjYCACAAQQhqIQAMCQsgBkG0GygCACICSQRAQbQbIAIgBmsiATYCAEHAG0HAGygCACIAIAZqIgI2AgAgAiABQQFyNgIEIAAgBkEDcjYCBCAAQQhqIQAMCQtBACEAIAZBL2oiAwJ/QYAfKAIABEBBiB8oAgAMAQtBjB9CfzcCAEGEH0KAoICAgIAENwIAQYAfIApBDGpBcHFB2KrVqgVzNgIAQZQfQQA2AgBB5B5BADYCAEGAIAsiAWoiBEEAIAFrIgdxIgEgBk0NCEHgHigCACIFBEBB2B4oAgAiCCABaiIJIAhNIAUgCUlyDQkLAkBB5B4tAABBBHFFBEACQAJAAkACQEHAGygCACIFBEBB6B4hAANAIAAoAgAiCCAFTQRAIAUgCCAAKAIEakkNAwsgACgCCCIADQALC0EAEAMiAkF/Rg0DIAEhBEGEHygCACIAQQFrIgUgAnEEQCABIAJrIAIgBWpBACAAa3FqIQQLIAQgBk0NA0HgHigCACIABEBB2B4oAgAiBSAEaiIHIAVNIAAgB0lyDQQLIAQQAyIAIAJHDQEMBQsgBCACayAHcSIEEAMiAiAAKAIAIAAoAgRqRg0BIAIhAAsgAEF/Rg0BIAZBMGogBE0EQCAAIQIMBAtBiB8oAgAiAiADIARrakEAIAJrcSICEANBf0YNASACIARqIQQgACECDAMLIAJBf0cNAgtB5B5B5B4oAgBBBHI2AgALIAEQAyICQX9GQQAQAyIAQX9GciAAIAJNcg0FIAAgAmsiBCAGQShqTQ0FC0HYHkHYHigCACAEaiIANgIAQdweKAIAIABJBEBB3B4gADYCAAsCQEHAGygCACIDBEBB6B4hAANAIAIgACgCACIBIAAoAgQiBWpGDQIgACgCCCIADQALDAQLQbgbKAIAIgBBACAAIAJNG0UEQEG4GyACNgIAC0EAIQBB7B4gBDYCAEHoHiACNgIAQcgbQX82AgBBzBtBgB8oAgA2AgBB9B5BADYCAANAIABBA3QiAUHYG2ogAUHQG2oiBTYCACABQdwbaiAFNgIAIABBAWoiAEEgRw0AC0G0GyAEQShrIgBBeCACa0EHcSIBayIFNgIAQcAbIAEgAmoiATYCACABIAVBAXI2AgQgACACakEoNgIEQcQbQZAfKAIANgIADAQLIAIgA00gASADS3INAiAAKAIMQQhxDQIgACAEIAVqNgIEQcAbIANBeCADa0EHcSIAaiIBNgIAQbQbQbQbKAIAIARqIgIgAGsiADYCACABIABBAXI2AgQgAiADakEoNgIEQcQbQZAfKAIANgIADAMLQQAhAAwGC0EAIQAMBAtBuBsoAgAgAksEQEG4GyACNgIACyACIARqIQVB6B4hAAJAA0AgBSAAKAIAIgFHBEAgACgCCCIADQEMAgsLIAAtAAxBCHFFDQMLQegeIQADQAJAIAAoAgAiASADTQRAIAMgASAAKAIEaiIFSQ0BCyAAKAIIIQAMAQsLQbQbIARBKGsiAEF4IAJrQQdxIgFrIgc2AgBBwBsgASACaiIBNgIAIAEgB0EBcjYCBCAAIAJqQSg2AgRBxBtBkB8oAgA2AgAgAyAFQScgBWtBB3FqQS9rIgAgACADQRBqSRsiAUEbNgIEIAFB8B4pAgA3AhAgAUHoHikCADcCCEHwHiABQQhqNgIAQeweIAQ2AgBB6B4gAjYCAEH0HkEANgIAIAFBGGohAANAIABBBzYCBCAAQQhqIQIgAEEEaiEAIAIgBUkNAAsgASADRg0AIAEgASgCBEF+cTYCBCADIAEgA2siAkEBcjYCBCABIAI2AgACfyACQf8BTQRAIAJBeHFB0BtqIQACf0GoGygCACIBQQEgAkEDdnQiAnFFBEBBqBsgASACcjYCACAADAELIAAoAggLIQEgACADNgIIIAEgAzYCDEEMIQJBCAwBC0EfIQAgAkH///8HTQRAIAJBJiACQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAAsgAyAANgIcIANCADcCECAAQQJ0QdgdaiEBAkACQEGsGygCACIFQQEgAHQiBHFFBEBBrBsgBCAFcjYCACABIAM2AgAMAQsgAkEZIABBAXZrQQAgAEEfRxt0IQAgASgCACEFA0AgBSIBKAIEQXhxIAJGDQIgAEEddiEFIABBAXQhACABIAVBBHFqIgQoAhAiBQ0ACyAEIAM2AhALIAMgATYCGEEIIQIgAyIBIQBBDAwBCyABKAIIIgAgAzYCDCABIAM2AgggAyAANgIIQQAhAEEYIQJBDAsgA2ogATYCACACIANqIAA2AgALQbQbKAIAIgAgBk0NAEG0GyAAIAZrIgE2AgBBwBtBwBsoAgAiACAGaiICNgIAIAIgAUEBcjYCBCAAIAZBA3I2AgQgAEEIaiEADAQLQaQbQTA2AgBBACEADAMLIAAgAjYCACAAIAAoAgQgBGo2AgQgAkF4IAJrQQdxaiIIIAZBA3I2AgQgAUF4IAFrQQdxaiIEIAYgCGoiA2shBwJAQcAbKAIAIARGBEBBwBsgAzYCAEG0G0G0GygCACAHaiIANgIAIAMgAEEBcjYCBAwBC0G8GygCACAERgRAQbwbIAM2AgBBsBtBsBsoAgAgB2oiADYCACADIABBAXI2AgQgACADaiAANgIADAELIAQoAgQiAEEDcUEBRgRAIABBeHEhCSAEKAIMIQICQCAAQf8BTQRAIAQoAggiASACRgRAQagbQagbKAIAQX4gAEEDdndxNgIADAILIAEgAjYCDCACIAE2AggMAQsgBCgCGCEGAkAgAiAERwRAIAQoAggiACACNgIMIAIgADYCCAwBCwJAIAQoAhQiAAR/IARBFGoFIAQoAhAiAEUNASAEQRBqCyEBA0AgASEFIAAiAkEUaiEBIAAoAhQiAA0AIAJBEGohASACKAIQIgANAAsgBUEANgIADAELQQAhAgsgBkUNAAJAIAQoAhwiAEECdEHYHWoiASgCACAERgRAIAEgAjYCACACDQFBrBtBrBsoAgBBfiAAd3E2AgAMAgsCQCAEIAYoAhBGBEAgBiACNgIQDAELIAYgAjYCFAsgAkUNAQsgAiAGNgIYIAQoAhAiAARAIAIgADYCECAAIAI2AhgLIAQoAhQiAEUNACACIAA2AhQgACACNgIYCyAHIAlqIQcgBCAJaiIEKAIEIQALIAQgAEF+cTYCBCADIAdBAXI2AgQgAyAHaiAHNgIAIAdB/wFNBEAgB0F4cUHQG2ohAAJ/QagbKAIAIgFBASAHQQN2dCICcUUEQEGoGyABIAJyNgIAIAAMAQsgACgCCAshASAAIAM2AgggASADNgIMIAMgADYCDCADIAE2AggMAQtBHyECIAdB////B00EQCAHQSYgB0EIdmciAGt2QQFxIABBAXRrQT5qIQILIAMgAjYCHCADQgA3AhAgAkECdEHYHWohAAJAAkBBrBsoAgAiAUEBIAJ0IgVxRQRAQawbIAEgBXI2AgAgACADNgIADAELIAdBGSACQQF2a0EAIAJBH0cbdCECIAAoAgAhAQNAIAEiACgCBEF4cSAHRg0CIAJBHXYhASACQQF0IQIgACABQQRxaiIFKAIQIgENAAsgBSADNgIQCyADIAA2AhggAyADNgIMIAMgAzYCCAwBCyAAKAIIIgEgAzYCDCAAIAM2AgggA0EANgIYIAMgADYCDCADIAE2AggLIAhBCGohAAwCCwJAIAhFDQACQCAFKAIcIgFBAnRB2B1qIgIoAgAgBUYEQCACIAA2AgAgAA0BQawbIAdBfiABd3EiBzYCAAwCCwJAIAUgCCgCEEYEQCAIIAA2AhAMAQsgCCAANgIUCyAARQ0BCyAAIAg2AhggBSgCECIBBEAgACABNgIQIAEgADYCGAsgBSgCFCIBRQ0AIAAgATYCFCABIAA2AhgLAkAgA0EPTQRAIAUgAyAGaiIAQQNyNgIEIAAgBWoiACAAKAIEQQFyNgIEDAELIAUgBkEDcjYCBCAFIAZqIgQgA0EBcjYCBCADIARqIAM2AgAgA0H/AU0EQCADQXhxQdAbaiEAAn9BqBsoAgAiAUEBIANBA3Z0IgJxRQRAQagbIAEgAnI2AgAgAAwBCyAAKAIICyEBIAAgBDYCCCABIAQ2AgwgBCAANgIMIAQgATYCCAwBC0EfIQAgA0H///8HTQRAIANBJiADQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAAsgBCAANgIcIARCADcCECAAQQJ0QdgdaiEBAkACQCAHQQEgAHQiAnFFBEBBrBsgAiAHcjYCACABIAQ2AgAgBCABNgIYDAELIANBGSAAQQF2a0EAIABBH0cbdCEAIAEoAgAhAQNAIAEiAigCBEF4cSADRg0CIABBHXYhASAAQQF0IQAgAiABQQRxaiIHKAIQIgENAAsgByAENgIQIAQgAjYCGAsgBCAENgIMIAQgBDYCCAwBCyACKAIIIgAgBDYCDCACIAQ2AgggBEEANgIYIAQgAjYCDCAEIAA2AggLIAVBCGohAAwBCwJAIAlFDQACQCACKAIcIgFBAnRB2B1qIgUoAgAgAkYEQCAFIAA2AgAgAA0BQawbIAtBfiABd3E2AgAMAgsCQCACIAkoAhBGBEAgCSAANgIQDAELIAkgADYCFAsgAEUNAQsgACAJNgIYIAIoAhAiAQRAIAAgATYCECABIAA2AhgLIAIoAhQiAUUNACAAIAE2AhQgASAANgIYCwJAIANBD00EQCACIAMgBmoiAEEDcjYCBCAAIAJqIgAgACgCBEEBcjYCBAwBCyACIAZBA3I2AgQgAiAGaiIFIANBAXI2AgQgAyAFaiADNgIAIAgEQCAIQXhxQdAbaiEAQbwbKAIAIQECf0EBIAhBA3Z0IgcgBHFFBEBBqBsgBCAHcjYCACAADAELIAAoAggLIQQgACABNgIIIAQgATYCDCABIAA2AgwgASAENgIIC0G8GyAFNgIAQbAbIAM2AgALIAJBCGohAAsgCkEQaiQAIAAL3AsBCH8CQCAARQ0AIABBCGsiAyAAQQRrKAIAIgJBeHEiAGohBQJAIAJBAXENACACQQJxRQ0BIAMgAygCACIEayIDQbgbKAIASQ0BIAAgBGohAAJAAkACQEG8GygCACADRwRAIAMoAgwhASAEQf8BTQRAIAEgAygCCCICRw0CQagbQagbKAIAQX4gBEEDdndxNgIADAULIAMoAhghByABIANHBEAgAygCCCICIAE2AgwgASACNgIIDAQLIAMoAhQiAgR/IANBFGoFIAMoAhAiAkUNAyADQRBqCyEEA0AgBCEGIAIiAUEUaiEEIAEoAhQiAg0AIAFBEGohBCABKAIQIgINAAsgBkEANgIADAMLIAUoAgQiAkEDcUEDRw0DQbAbIAA2AgAgBSACQX5xNgIEIAMgAEEBcjYCBCAFIAA2AgAPCyACIAE2AgwgASACNgIIDAILQQAhAQsgB0UNAAJAIAMoAhwiBEECdEHYHWoiAigCACADRgRAIAIgATYCACABDQFBrBtBrBsoAgBBfiAEd3E2AgAMAgsCQCADIAcoAhBGBEAgByABNgIQDAELIAcgATYCFAsgAUUNAQsgASAHNgIYIAMoAhAiAgRAIAEgAjYCECACIAE2AhgLIAMoAhQiAkUNACABIAI2AhQgAiABNgIYCyADIAVPDQAgBSgCBCIEQQFxRQ0AAkACQAJAAkAgBEECcUUEQEHAGygCACAFRgRAQcAbIAM2AgBBtBtBtBsoAgAgAGoiADYCACADIABBAXI2AgQgA0G8GygCAEcNBkGwG0EANgIAQbwbQQA2AgAPC0G8GygCACIHIAVGBEBBvBsgAzYCAEGwG0GwGygCACAAaiIANgIAIAMgAEEBcjYCBCAAIANqIAA2AgAPCyAEQXhxIABqIQAgBSgCDCEBIARB/wFNBEAgBSgCCCICIAFGBEBBqBtBqBsoAgBBfiAEQQN2d3E2AgAMBQsgAiABNgIMIAEgAjYCCAwECyAFKAIYIQggASAFRwRAIAUoAggiAiABNgIMIAEgAjYCCAwDCyAFKAIUIgIEfyAFQRRqBSAFKAIQIgJFDQIgBUEQagshBANAIAQhBiACIgFBFGohBCABKAIUIgINACABQRBqIQQgASgCECICDQALIAZBADYCAAwCCyAFIARBfnE2AgQgAyAAQQFyNgIEIAAgA2ogADYCAAwDC0EAIQELIAhFDQACQCAFKAIcIgRBAnRB2B1qIgIoAgAgBUYEQCACIAE2AgAgAQ0BQawbQawbKAIAQX4gBHdxNgIADAILAkAgBSAIKAIQRgRAIAggATYCEAwBCyAIIAE2AhQLIAFFDQELIAEgCDYCGCAFKAIQIgIEQCABIAI2AhAgAiABNgIYCyAFKAIUIgJFDQAgASACNgIUIAIgATYCGAsgAyAAQQFyNgIEIAAgA2ogADYCACADIAdHDQBBsBsgADYCAA8LIABB/wFNBEAgAEF4cUHQG2ohAgJ/QagbKAIAIgRBASAAQQN2dCIAcUUEQEGoGyAAIARyNgIAIAIMAQsgAigCCAshACACIAM2AgggACADNgIMIAMgAjYCDCADIAA2AggPC0EfIQEgAEH///8HTQRAIABBJiAAQQh2ZyICa3ZBAXEgAkEBdGtBPmohAQsgAyABNgIcIANCADcCECABQQJ0QdgdaiEEAn8CQAJ/QawbKAIAIgZBASABdCICcUUEQEGsGyACIAZyNgIAIAQgAzYCAEEYIQFBCAwBCyAAQRkgAUEBdmtBACABQR9HG3QhASAEKAIAIQQDQCAEIgIoAgRBeHEgAEYNAiABQR12IQQgAUEBdCEBIAIgBEEEcWoiBigCECIEDQALIAYgAzYCEEEYIQEgAiEEQQgLIQAgAyICDAELIAIoAggiBCADNgIMIAIgAzYCCEEYIQBBCCEBQQALIQYgASADaiAENgIAIAMgAjYCDCAAIANqIAY2AgBByBtByBsoAgBBAWsiAEF/IAAbNgIACwtsAQJ/QaAbKAIAIgEgAEEHakF4cSICaiEAAkAgAkEAIAAgAU0bRQRAIAA/AEEQdE0NASAAPwBBEHRrQf//A2pBEHZAAEF/RgR/QQAFQQAQAEEBCw0BC0GkG0EwNgIAQX8PC0GgGyAANgIAIAELBgAgACQACwQAIwALuQUBDH8jAEEQayIMJAACQCAEQQdNBEAgDEIANwMIIAQEQCAMQQhqIAMgBPwKAAALQWwgACABIAIgDEEIakEIEAYiACAAIARLGyAAIABBiX9JGyEFDAELIAEoAgBBAWoiDkEBdCIIBEAgAEEAIAj8CwALIAMoAAAiBUEPcSIHQQpLBEBBVCEFDAELIAIgB0EFajYCACADIARqIgJBBGshCCACQQdrIQ0gB0EGaiEPQQQhBiAFQQR2IQVBICAHdCIJQQFyIQpBACECQQEhByADIQQDQAJAIAdBAXFFBEADQCAFQX9zQYCAgIB4cmgiB0EYSUUEQCACQSRqIQIgBCANTQR/IARBA2oFIAQgDWtBA3QgBmpBH3EhBiAICyIEKAAAIAZ2IQUMAQsLIAYgB0EecSILakECaiEGIAdBAXZBA2wgAmogBSALdkEDcWoiAiAOTw0BAn8gBCANSyAGQQN2IARqIgUgCEtxRQRAIAZBB3EhBiAFDAELIAQgCGtBA3QgBmpBH3EhBiAICyIEKAAAIAZ2IQULIAUgCUEBa3EiByAJQQF0QQFrIgsgCmsiEEkEfyAPQQFrBSAFIAtxIgUgEEEAIAUgCU4bayEHIA8LIQUgACACQQF0aiAHQQFrIgs7AQAgAkEBaiECIAUgBmohBiAJQQEgB2sgCyAHQQBKGyAKaiIKSgRAIApBAkgNAUEgIApnIgVrIQ9BASAFQR9zdCEJCyACIA5PDQAgC0EARyEHAn8gBCANSyAGQQN1IARqIgUgCEtxRQRAIAZBB3EhBiAFDAELIAYgBCAIa0EDdGpBH3EhBiAICyIEKAAAIAZ2IQUMAQsLQWwhBSAKQQFHDQAgAiAOSwRAQVAhBQwBCyAGQSBKDQAgASACQQFrNgIAIAQgBkEHakEDdWogA2shBQsgDEEQaiQAIAULrRkCEX8BfiMAQTBrIgckAEG4fyEIAkAgBUUNACAELAAAIglB/wFxIQ0CQAJAIAlBAEgEQCANQf4Aa0EBdiIGIAVPDQMgDUH/AGsiCEH/AUsNAiAEQQFqIQRBACEFA0AgBSAITwRAIAYhDQwDBSAAIAVqIg0gBCAFQQF2aiIJLQAAQQR2OgAAIA0gCS0AAEEPcToAASAFQQJqIQUMAQsACwALIAUgDU0NAiAHQf8BNgIEIAYgB0EEaiAHQQhqIARBAWoiCiANEAYiBEGIf0sEQCAEIQgMAwtBVCEIIAcoAggiC0EGSw0CIAcoAgQiBUEBdCIMQQJqrUIBIAuthiIYQQQgC3QiCUEIaq18fEILfEL8//////////8Ag0LoAlYNAkFSIQggBUH/AUsNAkHoAiAJa60gBUEBaiIQQQF0rSAYfEIIfFQNAiANIARrIRQgBCAKaiEVIAwgBkGABGoiDCAJakEEaiIWakECaiERIAZBhARqIRcgBkGGBGohE0GAgAIgC3RBEHYhCEEAIQVBASEOQQEgC3QiCkEBayISIQQDQCAFIBBGRQRAAkAgBiAFQQF0Ig9qLwEAIglB//8DRgRAIBMgBEECdGogBToAACAEQQFrIQRBASEJDAELIA5BACAIIAnBShshDgsgDyAWaiAJOwEAIAVBAWohBQwBCwsgBiAOOwGCBCAGIAs7AYAEAkAgBCASRgRAQgAhGEEAIQlBACEIA0AgCSAQRgRAIApBA3YgCkEBdmpBA2oiBkEBdCEJQQAhBEEAIQgDQCAIIApPDQQgCCARaiEQQQAhBQNAIAVBAkZFBEAgEyAFIAZsIARqIBJxQQJ0aiAFIBBqLQAAOgAAIAVBAWohBQwBCwsgCEECaiEIIAQgCWogEnEhBAwACwAFIAYgCUEBdGouAQAhBCAIIBFqIg8gGDcAAEEIIQUDQCAEIAVMRQRAIAUgD2ogGDcAACAFQQhqIQUMAQsLIBhCgYKEiJCgwIABfCEYIAlBAWohCSAEIAhqIQgMAQsACwALIApBA3YgCkEBdmpBA2ohEUEAIQhBACEFA0AgCCAQRkUEQEEAIQkgBiAIQQF0ai4BACIPQQAgD0EAShshDwNAIAkgD0ZFBEAgEyAFQQJ0aiAIOgAAA0AgBSARaiAScSIFIARLDQALIAlBAWohCQwBCwsgCEEBaiEIDAELC0F/IQggBQ0DCyALQR9rIQhBACEFA0AgBSAKRkUEQCAWIBcgBUECdGoiBC0AAkEBdGoiBiAGLwEAIgZBAWo7AQAgBCAIIAZnaiIJOgADIAQgBiAJdCAKazsBACAFQQFqIQUMAQsLAkACQCAOQf//A3EEQCAHQRxqIgQgFSAUEAgiCEGIf0sNAiAHQRRqIAQgDBAJIAdBDGogBCAMEAkgBygCICIIQSBLDQECQCAHAn8gBygCJCIEIAcoAixPBEAgByAEIAhBA3ZrIgU2AiQgCEEHcQwBCyAEIAcoAigiBUYNASAHIAQgBCAFayAIQQN2IgYgBCAGayAFSRsiBGsiBTYCJCAIIARBA3RrCyIINgIgIAcgBSgAADYCHAtBACEFA0ACQAJAIAhBIU8EQCAHQbAaNgIkDAELIAcCfyAHKAIkIgQgBygCLE8EQCAHIAQgCEEDdmsiBDYCJEEBIQkgCEEHcQwBCyAEIAcoAigiBkYNASAHIAQgCEEDdiIJIAQgBmsgBCAJayAGTyIJGyIGayIENgIkIAggBkEDdGsLNgIgIAcgBCgAADYCHCAJRSAFQfsBS3INACAAIAVqIgggB0EUaiAHQRxqIgQQCjoAACAIIAdBDGogBBAKOgABAkAgBygCICIGQSFPBEAgB0GwGjYCJAwBCyAHKAIkIgQgBygCLE8EQCAHIAZBB3E2AiAgByAEIAZBA3ZrIgQ2AiQgByAEKAAANgIcDAMLIAQgBygCKCIJRg0AIAcgBiAEIAlrIAZBA3YiBiAEIAZrIgYgCUkbIgpBA3RrNgIgIAcgBCAKayIENgIkIAcgBCgAADYCHCAGIAlPDQILIAVBAnIhBQsgAEEBaiEMAn8CQANAQbp/IQggBUH9AUsNByAAIAVqIgogB0EUaiAHQRxqEAo6AAAgBSAMaiELIAcoAiAiBkEgSw0BAkAgBwJ/IAcoAiQiBCAHKAIsTwRAIAcgBCAGQQN2ayIENgIkIAZBB3EMAQsgBCAHKAIoIglGDQEgByAEIAQgCWsgBkEDdiIOIAQgDmsgCUkbIglrIgQ2AiQgBiAJQQN0aws2AiAgByAEKAAANgIcCyAFQf0BRg0HIAsgB0EMaiAHQRxqEAo6AAAgBUECaiEFIAcoAiAiBkEgTQRAIAcCfyAHKAIkIgQgBygCLE8EQCAHIAQgBkEDdmsiCDYCJCAGQQdxDAELIAQgBygCKCIIRg0CIAcgBCAEIAhrIAZBA3YiCSAEIAlrIAhJGyIEayIINgIkIAYgBEEDdGsLNgIgIAcgCCgAADYCHAwBCwsgB0GwGjYCJCAAIAVqIAdBFGogB0EcahAKOgAAIApBA2oMAQsgB0GwGjYCJCALIAdBDGogB0EcahAKOgAAIApBAmoLIABrIQgMBAsgCCAHQRRqIAdBHGoiBBAKOgACIAggB0EMaiAEEAo6AAMgBUEEaiEFIAcoAiAhCAwACwALIAdBHGoiBCAVIBQQCCIIQYh/Sw0BIAdBFGogBCAMEAkgB0EMaiAEIAwQCSAHKAIgIghBIEsNAAJAIAcCfyAHKAIkIgQgBygCLE8EQCAHIAQgCEEDdmsiBTYCJCAIQQdxDAELIAQgBygCKCIFRg0BIAcgBCAEIAVrIAhBA3YiBiAEIAZrIAVJGyIEayIFNgIkIAggBEEDdGsLIgg2AiAgByAFKAAANgIcC0EAIQUDQAJAAkAgCEEhTwRAIAdBsBo2AiQMAQsgBwJ/IAcoAiQiBCAHKAIsTwRAIAcgBCAIQQN2ayIENgIkQQEhCSAIQQdxDAELIAQgBygCKCIGRg0BIAcgBCAIQQN2IgkgBCAGayAEIAlrIAZPIgkbIgZrIgQ2AiQgCCAGQQN0aws2AiAgByAEKAAANgIcIAlFIAVB+wFLcg0AIAAgBWoiCCAHQRRqIAdBHGoiBBALOgAAIAggB0EMaiAEEAs6AAECQCAHKAIgIgZBIU8EQCAHQbAaNgIkDAELIAcoAiQiBCAHKAIsTwRAIAcgBkEHcTYCICAHIAQgBkEDdmsiBDYCJCAHIAQoAAA2AhwMAwsgBCAHKAIoIglGDQAgByAGIAQgCWsgBkEDdiIGIAQgBmsiBiAJSRsiCkEDdGs2AiAgByAEIAprIgQ2AiQgByAEKAAANgIcIAYgCU8NAgsgBUECciEFCyAAQQFqIQwCfwJAA0BBun8hCCAFQf0BSw0GIAAgBWoiCiAHQRRqIAdBHGoQCzoAACAFIAxqIQsgBygCICIGQSBLDQECQCAHAn8gBygCJCIEIAcoAixPBEAgByAEIAZBA3ZrIgQ2AiQgBkEHcQwBCyAEIAcoAigiCUYNASAHIAQgBCAJayAGQQN2Ig4gBCAOayAJSRsiCWsiBDYCJCAGIAlBA3RrCzYCICAHIAQoAAA2AhwLIAVB/QFGDQYgCyAHQQxqIAdBHGoQCzoAACAFQQJqIQUgBygCICIGQSBNBEAgBwJ/IAcoAiQiBCAHKAIsTwRAIAcgBCAGQQN2ayIINgIkIAZBB3EMAQsgBCAHKAIoIghGDQIgByAEIAQgCGsgBkEDdiIJIAQgCWsgCEkbIgRrIgg2AiQgBiAEQQN0aws2AiAgByAIKAAANgIcDAELCyAHQbAaNgIkIAAgBWogB0EUaiAHQRxqEAs6AAAgCkEDagwBCyAHQbAaNgIkIAsgB0EMaiAHQRxqEAs6AAAgCkECagsgAGshCAwDCyAIIAdBFGogB0EcaiIEEAs6AAIgCCAHQQxqIAQQCzoAAyAFQQRqIQUgBygCICEIDAALAAtBbCEICyAIQYh/Sw0CC0EAIQUgAUEAQTT8CwAgCCEGQQAhBANAIAUgBkcEQCAAIAVqIggtAAAiCUEMSw0CIAEgCUECdGoiCSAJKAIAQQFqNgIAIAVBAWohBUEBIAgtAAB0QQF1IARqIQQMAQsLQWwhCCAERQ0BIARnIgVBHHNBC0sNASADQSAgBWsiAzYCAEGAgICAeEEBIAN0IARrIgNnIgR2IANHDQEgACAGakEgIARrIgA6AAAgASAAQQJ0aiIAIAAoAgBBAWo2AgAgASgCBCIAQQJJIABBAXFyDQEgAiAGQQFqNgIAIA1BAWohCAwBC0FsIQgLIAdBMGokACAIC/UBAQF/IAJFBEAgAEIANwIAIABBADYCECAAQgA3AghBuH8PCyAAIAE2AgwgACABQQRqNgIQIAJBBE8EQCAAIAEgAmoiAUEEayIDNgIIIAAgAygAADYCACABQQFrLQAAIgEEQCAAQQggAWdBH3NrNgIEIAIPCyAAQQA2AgRBfw8LIAAgATYCCCAAIAEtAAAiAzYCAAJAAkACQCACQQJrDgIBAAILIAAgAS0AAkEQdCADciIDNgIACyAAIAEtAAFBCHQgA2o2AgALIAEgAmpBAWstAAAiAUUEQCAAQQA2AgRBbA8LIAAgAWcgAkEDdGtBCWo2AgQgAguuAQEEfyABIAIvAQAiAyABKAIEaiIENgIEIAAgA0ECdEGwGWooAgAgASgCAEEAIARrdnE2AgACQCAEQSFPBEAgAUGwGjYCCAwBCyABKAIIIgMgASgCEE8EQCABEAwMAQsgAyABKAIMIgVGDQAgASADIAMgBWsgBEEDdiIGIAMgBmsgBUkbIgNrIgU2AgggASAEIANBA3RrNgIEIAEgBSgAADYCAAsgACACQQRqNgIEC0wBBH8gACgCBCAAKAIAQQJ0aiICLQACIQMgAi8BACEEIAEgASgCBCIFIAItAAMiAmo2AgQgACAEIAEoAgAgBXRBACACa3ZqNgIAIAMLVgEEfyAAKAIEIAAoAgBBAnRqIgItAAIhAyACLwEAIQQgASACLQADIgIgASgCBGoiBTYCBCAAIAQgAkECdEGwGWooAgAgASgCAEEAIAVrdnFqNgIAIAMLLwEBfyAAIAAoAgQiAUEHcTYCBCAAIAAoAgggAUEDdmsiATYCCCAAIAEoAAA2AgALCAAgAEGIf0sLxQkCDX8CfiMAQRBrIgskACALQQA2AgwgC0EANgIIAn8CQCADQdQJaiIFIAMgC0EIaiALQQxqIAEgAiADQegAahAHIhBBiH9LDQAgCygCCCEIQQogACgCACIJQf8BcSIHIAdBCk8bQQFqIgQgCygCDCIBTwRAAkAgASAETw0AIAQgAWshAkEAIQEDQCABIAhGBEAgBCEBA0AgASACTQRAA0AgAkUNBSADIAJBAnRqQQA2AgAgAkEBayECDAALAAUgAyABQQJ0aiADIAEgAmtBAnRqKAIANgIAIAFBAWshAQwBCwALAAUgASAFaiIKIAJBACAKLQAAIgobIApqOgAAIAFBAWohAQwBCwALAAsgBCEBC0FUIAEgB0EBaksNARogAEEEaiEKIAAgCUH/gYB4cSABQRB0QYCA/AdxcjYCACABQQFqIQ4gA0E0aiEEQQAhAUEAIQIDQCACIA5GRQRAIAMgAkECdCIAaigCACEHIAAgBGogATYCACACQQFqIQIgASAHaiEBDAELCyADQdQHaiEHIAhBA2shAUEAIQADQAJAQQAhAiAAIAFOBEADQCAAIAhODQIgBCAAIAVqLQAAQQJ0aiIBIAEoAgAiAUEBajYCACABIAdqIAA6AAAgAEEBaiEADAALAAUDQCACQQRGRQRAIAQgBSAAIAJyIglqLQAAQQJ0aiIMIAwoAgAiDEEBajYCACAHIAxqIAk6AAAgAkEBaiECDAELCyAAQQRqIQAMAgsACwsgAygCACEIQQAhAEEBIQkDQCAJIA5GDQEgDiAJayEEIAMgCUECdGooAgAhBQJAAkACQAJAAkACQEEBIAl0QQF1IgxBAWsOCAABBAIEBAQDBAtBACECIAVBACAFQQBKGyEGIAAhAQNAIAIgBkYNBSAKIAFBAXRqIg0gByACIAhqai0AADoAASANIAQ6AAAgAkEBaiECIAFBAWohAQwACwALQQAhAiAFQQAgBUEAShshDSAAIQEDQCACIA1GDQQgCiABQQF0aiIGIAcgAiAIamotAAAiDzoAAyAGIAQ6AAIgBiAPOgABIAYgBDoAACACQQFqIQIgAUECaiEBDAALAAtBACECIAVBACAFQQBKGyEGIARB/wFxrSERIAAhAQNAIAIgBkYNAyAKIAFBAXRqIAcgAiAIamoxAABCCIYgEYRCgYCEgJCAwAB+NwAAIAJBAWohAiABQQRqIQEMAAsAC0EAIQIgBUEAIAVBAEobIQYgBEH/AXGtIREgACEBA0AgAiAGRg0CIAogAUEBdGoiBCAHIAIgCGpqMQAAQgiGIBGEQoGAhICQgMAAfiISNwAIIAQgEjcAACACQQFqIQIgAUEIaiEBDAALAAtBACEBIAVBACAFQQBKGyENIARB/wFxrSESIAAhBANAIAEgDUYNASAKIARBAXRqIQ8gByABIAhqajEAAEIIhiAShEKBgISAkIDAAH4hEUEAIQIDQCACIAxORQRAIA8gAkEBdGoiBiARNwAYIAYgETcAECAGIBE3AAggBiARNwAAIAJBEGohAgwBCwsgAUEBaiEBIAQgDGohBAwACwALIAlBAWohCSAFIAhqIQggBSAMbCAAaiEADAALAAsgEAshAiALQRBqJAAgAgufAwIBfgF/AkACQAJAAkACQAJAQQEgBCADa3QiCEEBaw4IAAEEAgQEBAMECyAGQRh0IANBEHRqIQMDQCABIAJGDQUgACABLQAAIgQgBEEIdCAFciAGQQFGGyADcjYBACABQQFqIQEgAEEEaiEADAALAAsgBkEYdCADQRB0aiEDA0AgASACRg0EIAAgAS0AACIEIARBCHQgBXIgBkEBRhsgA3IiBDYBBCAAIAQ2AQAgAUEBaiEBIABBCGohAAwACwALA0AgASACRg0DIAAgAS0AACADIAUgBhAQIgc3AQggACAHNwEAIAFBAWohASAAQRBqIQAMAAsACwNAIAEgAkYNAiAAIAEtAAAgAyAFIAYQECIHNwEYIAAgBzcBECAAIAc3AQggACAHNwEAIAFBAWohASAAQSBqIQAMAAsACwNAIAEgAkYNASAAIAhBAnRqIQQgAS0AACADIAUgBhAQIQcDQCAAIARGRQRAIAAgBzcBGCAAIAc3ARAgACAHNwEIIAAgBzcBACAAQSBqIQAMAQsLIAFBAWohASAEIQAMAAsACwsmACADQRh0IAFBEHRqIAAgAEEIdCACciADQQFGG3KtQoGAgIAQfgu7BgEKfyMAQSBrIgUkACAELwECIQsgBUEMaiACIAMQCCIDQYh/TQRAIARBBGohCCAAIAFqIQkCQAJAAkAgAUEETwRAIAlBA2shDUEAIAtrQR9xIQwgBSgCFCEDIAUoAhghByAFKAIcIQ4gBSgCDCEGIAUoAhAhBANAIARBIEsEQEGwGiEDDAQLAkAgAyAOTwRAIARBB3EhAiAEQQN2IQZBASEEDAELIAMgB0YNBCAEIARBA3YiAiADIAdrIAMgAmsgB08iBBsiBkEDdGshAgsgAyAGayIDKAAAIQYgBEUgACANT3INAiAIIAYgAnQgDHZBAXRqIgQtAAAhCiAAIAQtAAE6AAAgCCAGIAIgCmoiAnQgDHZBAXRqIgQtAAAhCiAAIAQtAAE6AAEgAiAKaiEEIABBAmohAAwACwALIAUoAhAiBEEhTwRAIAVBsBo2AhQMAwsgBSgCFCIDIAUoAhxPBEAgBSAEQQdxIgI2AhAgBSADIARBA3ZrIgM2AhQgBSADKAAANgIMIAIhBAwDCyADIAUoAhgiAkYNAiAFIAQgAyACayAEQQN2IgQgAyAEayACSRsiAkEDdGsiBDYCECAFIAMgAmsiAjYCFCAFIAIoAAA2AgwMAgsgAiEECyAFIAQ2AhAgBSADNgIUIAUgBjYCDAtBACALa0EfcSEHA0ACQCAEQSFPBEAgBUGwGjYCFAwBCyAFAn8gBSgCFCICIAUoAhxPBEAgBSACIARBA3ZrIgM2AhRBASEGIARBB3EMAQsgAiAFKAIYIgNGDQEgBSACIARBA3YiBiACIANrIAIgBmsgA08iBhsiAmsiAzYCFCAEIAJBA3RrCyIENgIQIAUgAygAACICNgIMIAZFIAAgCU9yDQAgCCACIAR0IAd2QQF0aiICLQABIQMgBSAEIAItAABqNgIQIAAgAzoAACAAQQFqIQAgBSgCECEEDAELCwNAIAAgCU9FBEAgCCAFKAIMIAUoAhAiAnQgB3ZBAXRqIgMtAAEhBCAFIAIgAy0AAGo2AhAgACAEOgAAIABBAWohAAwBCwtBbEFsIAEgBSgCEEEgRxsgBSgCFCAFKAIYRxshAwsgBUEgaiQAIAML/SEBGX8jAEHQAGsiBSQAQWwhBgJAIAFBBkkgA0EKSXINAAJAIAMgAi8ABCIHIAIvAAAiCiACLwACIglqakEGaiILSQ0AIAAgAUEDakECdiIMaiIIIAxqIg0gDGoiDCAAIAFqIhFLDQAgBC8BAiEOIAVBPGogAkEGaiICIAoQCCIGQYh/Sw0BIAVBKGogAiAKaiICIAkQCCIGQYh/Sw0BIAVBFGogAiAJaiICIAcQCCIGQYh/Sw0BIAUgAiAHaiADIAtrEAgiBkGIf0sNASAEQQRqIQogEUEDayESAkAgESAMa0EESQRAIAwhAyANIQIgCCEEDAELQQAgDmtBH3EhBkEAIQkgDCEDIA0hAiAIIQQDQCAJQQFxIAMgEk9yDQEgACAKIAUoAjwiCSAFKAJAIgt0IAZ2QQJ0aiIHLwEAOwAAIActAAIhECAHLQADIQ8gBCAKIAUoAigiEyAFKAIsIhR0IAZ2QQJ0aiIHLwEAOwAAIActAAIhFSAHLQADIRYgAiAKIAUoAhQiFyAFKAIYIhh0IAZ2QQJ0aiIHLwEAOwAAIActAAIhGSAHLQADIRogAyAKIAUoAgAiGyAFKAIEIhx0IAZ2QQJ0aiIHLwEAOwAAIActAAIhHSAHLQADIQcgACAPaiIPIAogCSALIBBqIgl0IAZ2QQJ0aiIALwEAOwAAIAUgCSAALQACajYCQCAALQADIQkgBCAWaiIEIAogEyAUIBVqIgt0IAZ2QQJ0aiIALwEAOwAAIAUgCyAALQACajYCLCAALQADIQsgAiAaaiICIAogFyAYIBlqIhB0IAZ2QQJ0aiIALwEAOwAAIAUgECAALQACajYCGCAALQADIRAgAyAHaiIHIAogGyAcIB1qIgB0IAZ2QQJ0aiIDLwEAOwAAIAUgACADLQACajYCBCAJIA9qIQAgBCALaiEEIAIgEGohAiAHIAMtAANqIQMgBUE8ahATIAVBKGoQE3IgBUEUahATciAFEBNyQQBHIQkMAAsACyAAIAhLIAQgDUtyDQBBbCEGIAIgDEsNAQJAAkAgCCAAayIJQQRPBEAgCEEDayEQQQAgDmtBH3EhCyAFKAJAIQYDQCAGQSFPBEAgBUGwGjYCRAwDCyAFAn8gBSgCRCIHIAUoAkxPBEAgBSAHIAZBA3ZrIgk2AkRBASEHIAZBB3EMAQsgByAFKAJIIglGDQMgBSAHIAZBA3YiDyAHIAlrIAcgD2sgCU8iBxsiD2siCTYCRCAGIA9BA3RrCyIGNgJAIAUgCSgAACIJNgI8IAdFIAAgEE9yDQIgACAKIAkgBnQgC3ZBAnRqIgYvAQA7AAAgBSAFKAJAIAYtAAJqIgc2AkAgACAGLQADaiIJIAogBSgCPCAHdCALdkECdGoiAC8BADsAACAFIAUoAkAgAC0AAmoiBjYCQCAJIAAtAANqIQAMAAsACyAFKAJAIgZBIU8EQCAFQbAaNgJEDAILIAUoAkQiCyAFKAJMTwRAIAUgBkEHcSIHNgJAIAUgCyAGQQN2ayIGNgJEIAUgBigAADYCPCAHIQYMAgsgCyAFKAJIIgdGDQEgBSAGIAsgB2sgBkEDdiIGIAsgBmsgB0kbIgdBA3RrIgY2AkAgBSALIAdrIgc2AkQgBSAHKAAANgI8DAELIAggAGshCQsCQCAJQQJJDQAgCEECayELQQAgDmtBH3EhEANAAkAgBkEhTwRAIAVBsBo2AkQMAQsgBQJ/IAUoAkQiByAFKAJMTwRAIAUgByAGQQN2ayIJNgJEQQEhByAGQQdxDAELIAcgBSgCSCIJRg0BIAUgByAGQQN2Ig8gByAJayAHIA9rIAlPIgcbIg9rIgk2AkQgBiAPQQN0awsiBjYCQCAFIAkoAAAiCTYCPCAHRSAAIAtLcg0AIAAgCiAJIAZ0IBB2QQJ0aiIHLwEAOwAAIAUgBSgCQCAHLQACaiIGNgJAIAAgBy0AA2ohAAwBCwsDQCAAIAtLDQEgACAKIAUoAjwgBnQgEHZBAnRqIgcvAQA7AAAgBSAFKAJAIActAAJqIgY2AkAgACAHLQADaiEADAALAAsCQCAAIAhPDQAgACAKIAUoAjwgBnRBACAOa3ZBAnRqIgAtAAA6AAAgBQJ/IAAtAANBAUYEQCAFKAJAIAAtAAJqDAELIAUoAkAiCEEfSw0BQSAgCCAALQACaiIAIABBIE8bCzYCQAsCQAJAIA0gBGsiBkEETwRAIA1BA2shCUEAIA5rQR9xIQcgBSgCLCEAA0AgAEEhTwRAIAVBsBo2AjAMAwsgBQJ/IAUoAjAiCCAFKAI4TwRAIAUgCCAAQQN2ayIGNgIwQQEhCCAAQQdxDAELIAggBSgCNCIGRg0DIAUgCCAAQQN2IgsgCCAGayAIIAtrIAZPIggbIgtrIgY2AjAgACALQQN0awsiADYCLCAFIAYoAAAiBjYCKCAIRSAEIAlPcg0CIAQgCiAGIAB0IAd2QQJ0aiIALwEAOwAAIAUgBSgCLCAALQACaiIINgIsIAQgAC0AA2oiBiAKIAUoAiggCHQgB3ZBAnRqIgQvAQA7AAAgBSAFKAIsIAQtAAJqIgA2AiwgBiAELQADaiEEDAALAAsgBSgCLCIAQSFPBEAgBUGwGjYCMAwCCyAFKAIwIgcgBSgCOE8EQCAFIABBB3EiCDYCLCAFIAcgAEEDdmsiADYCMCAFIAAoAAA2AiggCCEADAILIAcgBSgCNCIIRg0BIAUgACAHIAhrIABBA3YiACAHIABrIAhJGyIIQQN0ayIANgIsIAUgByAIayIINgIwIAUgCCgAADYCKAwBCyANIARrIQYLAkAgBkECSQ0AIA1BAmshCUEAIA5rQR9xIQsDQAJAIABBIU8EQCAFQbAaNgIwDAELIAUCfyAFKAIwIgggBSgCOE8EQCAFIAggAEEDdmsiBjYCMEEBIQcgAEEHcQwBCyAIIAUoAjQiBkYNASAFIAggAEEDdiIHIAggBmsgCCAHayAGTyIHGyIIayIGNgIwIAAgCEEDdGsLIgA2AiwgBSAGKAAAIgg2AiggB0UgBCAJS3INACAEIAogCCAAdCALdkECdGoiCC8BADsAACAFIAUoAiwgCC0AAmoiADYCLCAEIAgtAANqIQQMAQsLA0AgBCAJSw0BIAQgCiAFKAIoIAB0IAt2QQJ0aiIILwEAOwAAIAUgBSgCLCAILQACaiIANgIsIAQgCC0AA2ohBAwACwALAkAgBCANTw0AIAQgCiAFKAIoIAB0QQAgDmt2QQJ0aiIALQAAOgAAIAUCfyAALQADQQFGBEAgBSgCLCAALQACagwBCyAFKAIsIgRBH0sNAUEgIAQgAC0AAmoiACAAQSBPGws2AiwLAkACQCAMIAJrIgZBBE8EQCAMQQNrIQdBACAOa0EfcSEIIAUoAhghAANAIABBIU8EQCAFQbAaNgIcDAMLIAUCfyAFKAIcIgQgBSgCJE8EQCAFIAQgAEEDdmsiBjYCHEEBIQkgAEEHcQwBCyAEIAUoAiAiDUYNAyAFIAQgAEEDdiIGIAQgDWsgBCAGayANTyIJGyIEayIGNgIcIAAgBEEDdGsLIgA2AhggBSAGKAAAIgQ2AhQgCUUgAiAHT3INAiACIAogBCAAdCAIdkECdGoiAC8BADsAACAFIAUoAhggAC0AAmoiBDYCGCACIAAtAANqIg0gCiAFKAIUIAR0IAh2QQJ0aiICLwEAOwAAIAUgBSgCGCACLQACaiIANgIYIA0gAi0AA2ohAgwACwALIAUoAhgiAEEhTwRAIAVBsBo2AhwMAgsgBSgCHCIIIAUoAiRPBEAgBSAAQQdxIgQ2AhggBSAIIABBA3ZrIgA2AhwgBSAAKAAANgIUIAQhAAwCCyAIIAUoAiAiBEYNASAFIAAgCCAEayAAQQN2IgAgCCAAayAESRsiBEEDdGsiADYCGCAFIAggBGsiBDYCHCAFIAQoAAA2AhQMAQsgDCACayEGCwJAIAZBAkkNACAMQQJrIQ1BACAOa0EfcSEHA0ACQCAAQSFPBEAgBUGwGjYCHAwBCyAFAn8gBSgCHCIEIAUoAiRPBEAgBSAEIABBA3ZrIgY2AhxBASEIIABBB3EMAQsgBCAFKAIgIghGDQEgBSAEIABBA3YiBiAEIAhrIAQgBmsgCE8iCBsiBGsiBjYCHCAAIARBA3RrCyIANgIYIAUgBigAACIENgIUIAhFIAIgDUtyDQAgAiAKIAQgAHQgB3ZBAnRqIgQvAQA7AAAgBSAFKAIYIAQtAAJqIgA2AhggAiAELQADaiECDAELCwNAIAIgDUsNASACIAogBSgCFCAAdCAHdkECdGoiBC8BADsAACAFIAUoAhggBC0AAmoiADYCGCACIAQtAANqIQIMAAsACwJAIAIgDE8NACACIAogBSgCFCAAdEEAIA5rdkECdGoiAC0AADoAACAFAn8gAC0AA0EBRgRAIAUoAhggAC0AAmoMAQsgBSgCGCICQR9LDQFBICACIAAtAAJqIgAgAEEgTxsLNgIYCwJAIBEgA2tBBE8EQEEAIA5rQR9xIQQgBSgCBCEAA0AgAEEhTwRAIAVBsBo2AggMAwsgBQJ/IAUoAggiAiAFKAIQTwRAIAUgAiAAQQN2ayIGNgIIQQEhAiAAQQdxDAELIAIgBSgCDCIMRg0DIAUgAiAAQQN2IgggAiAMayACIAhrIAxPIgIbIgxrIgY2AgggACAMQQN0awsiADYCBCAFIAYoAAAiDDYCACACRSADIBJPcg0CIAMgCiAMIAB0IAR2QQJ0aiIALwEAOwAAIAUgBSgCBCAALQACaiICNgIEIAMgAC0AA2oiAyAKIAUoAgAgAnQgBHZBAnRqIgIvAQA7AAAgBSAFKAIEIAItAAJqIgA2AgQgAyACLQADaiEDDAALAAsgBSgCBCIAQSFPBEAgBUGwGjYCCAwBCyAFKAIIIgQgBSgCEE8EQCAFIABBB3EiAjYCBCAFIAQgAEEDdmsiADYCCCAFIAAoAAA2AgAgAiEADAELIAQgBSgCDCICRg0AIAUgACAEIAJrIABBA3YiACAEIABrIAJJGyICQQN0ayIANgIEIAUgBCACayICNgIIIAUgAigAADYCAAsCQCARIANrQQJJDQAgEUECayEEQQAgDmtBH3EhDANAAkAgAEEhTwRAIAVBsBo2AggMAQsgBQJ/IAUoAggiAiAFKAIQTwRAIAUgAiAAQQN2ayIGNgIIQQEhCSAAQQdxDAELIAIgBSgCDCIIRg0BIAUgAiAAQQN2Ig0gAiAIayACIA1rIAhPIgkbIgJrIgY2AgggACACQQN0awsiADYCBCAFIAYoAAAiAjYCACAJRSADIARLcg0AIAMgCiACIAB0IAx2QQJ0aiICLwEAOwAAIAUgBSgCBCACLQACaiIANgIEIAMgAi0AA2ohAwwBCwsDQCADIARLDQEgAyAKIAUoAgAgAHQgDHZBAnRqIgIvAQA7AAAgBSAFKAIEIAItAAJqIgA2AgQgAyACLQADaiEDDAALAAsCQCADIBFPDQAgAyAKIAUoAgAgAHRBACAOa3ZBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAUoAgQgAi0AAmohAAwBCyAFKAIEIgBBH0sNAEEgIAAgAi0AAmoiACAAQSBPGyEAC0FsQWxBbEFsQWxBbEFsQWwgASAAQSBHGyAFKAIIIAUoAgxHGyAFKAIYQSBHGyAFKAIcIAUoAiBHGyAFKAIsQSBHGyAFKAIwIAUoAjRHGyAFKAJAQSBHGyAFKAJEIAUoAkhHGyEGDAELQWwhBgsgBUHQAGokACAGCxkAIAAoAgggACgCEEkEQEEDDwsgABAMQQAL8xwBFn8jAEHQAGsiBSQAQWwhCAJAIAFBBkkgA0EKSXINAAJAIAMgAi8ABCIGIAIvAAAiCiACLwACIglqakEGaiISSQ0AIAAgAUEDakECdiILaiIHIAtqIg4gC2oiCyAAIAFqIg9LDQAgBC8BAiEMIAVBPGogAkEGaiICIAoQCCIIQYh/Sw0BIAVBKGogAiAKaiICIAkQCCIIQYh/Sw0BIAVBFGogAiAJaiICIAYQCCIIQYh/Sw0BIAUgAiAGaiADIBJrEAgiCEGIf0sNASAEQQRqIQogD0EDayESAkAgDyALa0EESQRAIAshAyAOIQIgByEEDAELQQAgDGtBH3EhCEEAIQYgCyEDIA4hAiAHIQQDQCAGQQFxIAMgEk9yDQEgCiAFKAI8IgYgBSgCQCIJdCAIdkEBdGoiDS0AACEQIAAgDS0AAToAACAKIAUoAigiDSAFKAIsIhF0IAh2QQF0aiITLQAAIRUgBCATLQABOgAAIAogBSgCFCITIAUoAhgiFnQgCHZBAXRqIhQtAAAhFyACIBQtAAE6AAAgCiAFKAIAIhQgBSgCBCIYdCAIdkEBdGoiGS0AACEaIAMgGS0AAToAACAKIAYgCSAQaiIGdCAIdkEBdGoiCS0AASEQIAUgBiAJLQAAajYCQCAAIBA6AAEgCiANIBEgFWoiBnQgCHZBAXRqIgktAAEhDSAFIAYgCS0AAGo2AiwgBCANOgABIAogEyAWIBdqIgZ0IAh2QQF0aiIJLQABIQ0gBSAGIAktAABqNgIYIAIgDToAASAKIBQgGCAaaiIGdCAIdkEBdGoiCS0AASENIAUgBiAJLQAAajYCBCADIA06AAEgA0ECaiEDIAJBAmohAiAEQQJqIQQgAEECaiEAIAVBPGoQEyAFQShqEBNyIAVBFGoQE3IgBRATckEARyEGDAALAAsgACAHSyAEIA5Lcg0AQWwhCCACIAtLDQECQCAHIABrQQROBEAgB0EDayEQQQAgDGtBH3EhDQNAIAUoAkAiBkEhTwRAIAVBsBo2AkQMAwsgBQJ/IAUoAkQiCCAFKAJMTwRAIAUgCCAGQQN2ayIINgJEQQEhCSAGQQdxDAELIAggBSgCSCIJRg0DIAUgCCAGQQN2IhEgCCAJayAIIBFrIAlPIgkbIhFrIgg2AkQgBiARQQN0awsiBjYCQCAFIAgoAAAiCDYCPCAJRSAAIBBPcg0CIAogCCAGdCANdkEBdGoiCC0AASEJIAUgBiAILQAAajYCQCAAIAk6AAAgCiAFKAI8IAUoAkAiBnQgDXZBAXRqIggtAAEhCSAFIAYgCC0AAGo2AkAgACAJOgABIABBAmohAAwACwALIAUoAkAiBkEhTwRAIAVBsBo2AkQMAQsgBSgCRCIJIAUoAkxPBEAgBSAGQQdxIgg2AkAgBSAJIAZBA3ZrIgY2AkQgBSAGKAAANgI8IAghBgwBCyAJIAUoAkgiCEYNACAFIAYgCSAIayAGQQN2IgYgCSAGayAISRsiCEEDdGsiBjYCQCAFIAkgCGsiCDYCRCAFIAgoAAA2AjwLQQAgDGtBH3EhCANAAkAgBkEhTwRAIAVBsBo2AkQMAQsgBQJ/IAUoAkQiCSAFKAJMTwRAIAUgCSAGQQN2ayIMNgJEQQEhCSAGQQdxDAELIAkgBSgCSCIMRg0BIAUgCSAGQQN2Ig0gCSAMayAJIA1rIAxPIgkbIg1rIgw2AkQgBiANQQN0awsiBjYCQCAFIAwoAAAiDDYCPCAJRSAAIAdPcg0AIAogDCAGdCAIdkEBdGoiCS0AASEMIAUgBiAJLQAAajYCQCAAIAw6AAAgAEEBaiEAIAUoAkAhBgwBCwsDQCAAIAdPRQRAIAogBSgCPCAFKAJAIgZ0IAh2QQF0aiIJLQABIQwgBSAGIAktAABqNgJAIAAgDDoAACAAQQFqIQAMAQsLAkAgDiAEa0EETgRAIA5BA2shCQNAIAUoAiwiAEEhTwRAIAVBsBo2AjAMAwsgBQJ/IAUoAjAiByAFKAI4TwRAIAUgByAAQQN2ayIGNgIwQQEhByAAQQdxDAELIAcgBSgCNCIGRg0DIAUgByAAQQN2IgwgByAGayAHIAxrIAZPIgcbIgxrIgY2AjAgACAMQQN0awsiADYCLCAFIAYoAAAiBjYCKCAHRSAEIAlPcg0CIAogBiAAdCAIdkEBdGoiBy0AASEGIAUgACAHLQAAajYCLCAEIAY6AAAgCiAFKAIoIAUoAiwiAHQgCHZBAXRqIgctAAEhBiAFIAAgBy0AAGo2AiwgBCAGOgABIARBAmohBAwACwALIAUoAiwiAEEhTwRAIAVBsBo2AjAMAQsgBSgCMCIGIAUoAjhPBEAgBSAAQQdxIgc2AiwgBSAGIABBA3ZrIgA2AjAgBSAAKAAANgIoIAchAAwBCyAGIAUoAjQiB0YNACAFIAAgBiAHayAAQQN2IgAgBiAAayAHSRsiB0EDdGsiADYCLCAFIAYgB2siBzYCMCAFIAcoAAA2AigLA0ACQCAAQSFPBEAgBUGwGjYCMAwBCyAFAn8gBSgCMCIHIAUoAjhPBEAgBSAHIABBA3ZrIgY2AjBBASEHIABBB3EMAQsgByAFKAI0IgZGDQEgBSAHIABBA3YiCSAHIAZrIAcgCWsgBk8iBxsiCWsiBjYCMCAAIAlBA3RrCyIANgIsIAUgBigAACIGNgIoIAdFIAQgDk9yDQAgCiAGIAB0IAh2QQF0aiIHLQABIQYgBSAAIActAABqNgIsIAQgBjoAACAEQQFqIQQgBSgCLCEADAELCwNAIAQgDk9FBEAgCiAFKAIoIAUoAiwiAHQgCHZBAXRqIgctAAEhBiAFIAAgBy0AAGo2AiwgBCAGOgAAIARBAWohBAwBCwsCQCALIAJrQQROBEAgC0EDayEOA0AgBSgCGCIAQSFPBEAgBUGwGjYCHAwDCyAFAn8gBSgCHCIEIAUoAiRPBEAgBSAEIABBA3ZrIgQ2AhxBASEGIABBB3EMAQsgBCAFKAIgIgdGDQMgBSAEIABBA3YiBiAEIAdrIAQgBmsgB08iBhsiB2siBDYCHCAAIAdBA3RrCyIANgIYIAUgBCgAACIENgIUIAZFIAIgDk9yDQIgCiAEIAB0IAh2QQF0aiIELQABIQcgBSAAIAQtAABqNgIYIAIgBzoAACAKIAUoAhQgBSgCGCIAdCAIdkEBdGoiBC0AASEHIAUgACAELQAAajYCGCACIAc6AAEgAkECaiECDAALAAsgBSgCGCIAQSFPBEAgBUGwGjYCHAwBCyAFKAIcIgcgBSgCJE8EQCAFIABBB3EiBDYCGCAFIAcgAEEDdmsiADYCHCAFIAAoAAA2AhQgBCEADAELIAcgBSgCICIERg0AIAUgACAHIARrIABBA3YiACAHIABrIARJGyIEQQN0ayIANgIYIAUgByAEayIENgIcIAUgBCgAADYCFAsDQAJAIABBIU8EQCAFQbAaNgIcDAELIAUCfyAFKAIcIgQgBSgCJE8EQCAFIAQgAEEDdmsiBDYCHEEBIQYgAEEHcQwBCyAEIAUoAiAiB0YNASAFIAQgAEEDdiIOIAQgB2sgBCAOayAHTyIGGyIHayIENgIcIAAgB0EDdGsLIgA2AhggBSAEKAAAIgQ2AhQgBkUgAiALT3INACAKIAQgAHQgCHZBAXRqIgQtAAEhByAFIAAgBC0AAGo2AhggAiAHOgAAIAJBAWohAiAFKAIYIQAMAQsLA0AgAiALT0UEQCAKIAUoAhQgBSgCGCIAdCAIdkEBdGoiBC0AASEHIAUgACAELQAAajYCGCACIAc6AAAgAkEBaiECDAELCwJAIA8gA2tBBE4EQANAIAUoAgQiAEEhTwRAIAVBsBo2AggMAwsgBQJ/IAUoAggiAiAFKAIQTwRAIAUgAiAAQQN2ayIENgIIQQEhAiAAQQdxDAELIAIgBSgCDCIERg0DIAUgAiAAQQN2IgsgAiAEayACIAtrIARPIgIbIgtrIgQ2AgggACALQQN0awsiADYCBCAFIAQoAAAiBDYCACACRSADIBJPcg0CIAogBCAAdCAIdkEBdGoiAi0AASEEIAUgACACLQAAajYCBCADIAQ6AAAgCiAFKAIAIAUoAgQiAHQgCHZBAXRqIgItAAEhBCAFIAAgAi0AAGo2AgQgAyAEOgABIANBAmohAwwACwALIAUoAgQiAEEhTwRAIAVBsBo2AggMAQsgBSgCCCIEIAUoAhBPBEAgBSAAQQdxIgI2AgQgBSAEIABBA3ZrIgA2AgggBSAAKAAANgIAIAIhAAwBCyAEIAUoAgwiAkYNACAFIAAgBCACayAAQQN2IgAgBCAAayACSRsiAkEDdGsiADYCBCAFIAQgAmsiAjYCCCAFIAIoAAA2AgALA0ACQCAAQSFPBEAgBUGwGjYCCAwBCyAFAn8gBSgCCCICIAUoAhBPBEAgBSACIABBA3ZrIgQ2AghBASECIABBB3EMAQsgAiAFKAIMIgRGDQEgBSACIABBA3YiCyACIARrIAIgC2sgBE8iAhsiC2siBDYCCCAAIAtBA3RrCyIANgIEIAUgBCgAACIENgIAIAJFIAMgD09yDQAgCiAEIAB0IAh2QQF0aiICLQABIQQgBSAAIAItAABqNgIEIAMgBDoAACADQQFqIQMgBSgCBCEADAELCwNAIAMgD09FBEAgCiAFKAIAIAUoAgQiAHQgCHZBAXRqIgItAAEhBCAFIAAgAi0AAGo2AgQgAyAEOgAAIANBAWohAwwBCwtBbEFsQWxBbEFsQWxBbEFsIAEgBSgCBEEgRxsgBSgCCCAFKAIMRxsgBSgCGEEgRxsgBSgCHCAFKAIgRxsgBSgCLEEgRxsgBSgCMCAFKAI0RxsgBSgCQEEgRxsgBSgCRCAFKAJIRxshCAwBC0FsIQgLIAVB0ABqJAAgCAsaACAABEAgAQRAIAIgACABEQIADwsgABACCwtSAQN/AkAgACgCmOsBIgFFDQAgASgCACABKAK01QEiAiABKAK41QEiAxAVIAIEQCADIAEgAhECAAwBCyABEAILIABBADYCqOsBIABCADcDmOsBC5QFAgR/An4jAEEQayIGJAACQCABIAJFckUEQEF/IQQMAQsCQEEBQQUgAxsiBCACSwRAIAJFIANBAUZyDQIgBkGo6r5pNgIMIAJFIgBFBEAgBkEMaiABIAL8CgAACyAGKAIMQajqvmlGDQIgBkHQ1LTCATYCDCAARQRAIAZBDGogASAC/AoAAAsgBigCDEFwcUHQ1LTCAUYNAgwBCyAAQQBBMPwLAEEBIQUCQCADQQFGDQAgAyEFIAEoAAAiA0Go6r5pRg0AIANBcHFB0NS0wgFHDQFBCCEEIAJBCEkNAiAAQQE2AhQgASgAACECIABBCDYCGCAAIAJB0NS0wgFrNgIcIAAgATUABDcDAEEAIQQMAgsgAiABIAIgBRAYIgJJBEAgAiEEDAILIAAgAjYCGCABIARqIgVBAWstAAAiAkEIcQRAQXIhBAwCCyACQSBxIgNFBEAgBS0AACIFQacBSwRAQXAhBAwDCyAFQQdxrUIBIAVBA3ZBCmqthiIIQgOIfiAIfCEJIARBAWohBAsgAkEGdiEFIAJBAnYhBwJAAkACQAJAIAJBA3EiAkEBaw4DAAECAwsgASAEai0AACECIARBAWohBAwCCyABIARqLwAAIQIgBEECaiEEDAELIAEgBGooAAAhAiAEQQRqIQQLIAdBAXEhBwJ+AkACQAJAAkAgBUEBaw4DAQIDAAtCfyADRQ0DGiABIARqMQAADAMLIAEgBGozAABCgAJ8DAILIAEgBGo1AAAMAQsgASAEaikAAAshCCAAIAc2AiAgACACNgIcIAAgCDcDAEEAIQQgAEEANgIUIAAgCCAJIAMbIgg3AwggAEKAgAggCCAIQoCACFobPgIQDAELQXYhBAsgBkEQaiQAIAQLXwEBf0G4fyEDIAFBAUEFIAIbIgFPBH8gACABakEBay0AACIAQQNxQQJ0QcAaaigCACABaiAAQQR2QQxxQdAaaigCAGogAEEgcSIBRWogAUEFdiAAQcAASXFqBUG4fwsLxAICBH8CfiMAQUBqIgQkAAJAA0AgAUEFTwRAAkAgACgAAEFwcUHQ1LTCAUYEQEJ+IQYgAUEISQ0EIAAoAAQiA0F3Sw0EIANBCGoiAiABSw0EIANBgX9JDQEMBAsgBEEQaiIDIAAgAUEAEBchAkJ+IAQpAxBCACAEKAIkQQFHGyACGyIGQn1WDQMgBiAHfCIHIAZUIQJCfiEGIAINAyADIAAgAUEAEBciAkGIf0sgAnINAyABIAQoAigiA2shAiAAIANqIQMDQCADIAIgBEEEahAaIgVBiH9LDQQgAiAFQQNqIgVJDQQgAiAFayECIAMgBWohAyAEKAIIRQ0ACyAEKAIwBH8gAkEESQ0EIANBBGoFIAMLIABrIgJBiH9LDQMLIAEgAmshASAAIAJqIQAMAQsLQn4gByABGyEGCyAEQUBrJAAgBgtkAQF/Qbh/IQMCQCABQQNJDQAgAC0AAiEBIAIgAC8AACIAQQFxNgIEIAIgAEEBdkEDcSIDNgIAIAIgACABQRB0ckEDdiIANgIIAkACQCADQQFrDgMCAQABC0FsDwsgACEDCyADC7ABAAJ/IAIgACgClOsBBH8gACgC0OkBBUGAgAgLIgIgA2pBQGtLBEAgACABIAJqQSBqIgE2AvzrAUEBIQIgASADagwBCyADQYCABE0EQCAAIABBiOwBaiIBNgL86wFBACECIAEgA2oMAQsgACABIARqIgEgA2siAkHg/wNqIgQgAiAFGzYC/OsBQQIhAiADIARqQYCABGsgASAFGwshAyAAIAI2AoTsASAAIAM2AoDsAQuyBwIEfwF+IwBBgAFrIg4kACAOIAM2AnwCQAJAAkACQAJAAkAgAkEBaw4DAAMCAQsgBkUEQEG4fyEKDAULIAMgBS0AACICSQ0DIAIgCGotAAAhAyAHIAJBAnRqKAIAIQIgAEEAOgALIABCADcCACAAIAI2AgwgACADOgAKIABBADsBCCABIAA2AgBBASEKDAQLIAEgCTYCAEEAIQoMAwsgCkUNAUEAIQogC0UgDEEZSXINAkEIIAR0QQhyIQBBACEDA0AgACADTQ0DIANBQGshAwwACwALQWwhCiAOIA5B/ABqIA5B+ABqIAUgBhAGIgNBiH9LDQEgDigCeCICIARLDQEgAEEMaiEMIA4oAnxBAWohEUGAgAIgAnRBEHYhEEEAIQRBASEFQQEgAnQiCkEBayILIQkDQCAEIBFHBEACQCAOIARBAXQiD2ovAQAiBkH//wNGBEAgDCAJQQN0aiAENgIAIAlBAWshCUEBIQYMAQsgBUEAIBAgBsFKGyEFCyANIA9qIAY7AQAgBEEBaiEEDAELCyAAIAI2AgQgACAFNgIAAkAgCSALRgRAIA1B6gBqIRBBACEJQQAhBQNAIAkgEUYEQCAKQQN2IApBAXZqQQNqIglBAXQhEUEAIQZBACEFA0AgBSAKTw0EIAUgEGohD0EAIQQDQCAEQQJHBEAgDCAEIAlsIAZqIAtxQQN0aiAEIA9qLQAANgIAIARBAWohBAwBCwsgBUECaiEFIAYgEWogC3EhBgwACwAFIA4gCUEBdGouAQAhBiAFIBBqIg8gEjcAAEEIIQQDQCAEIAZIBEAgBCAPaiASNwAAIARBCGohBAwBCwsgEkKBgoSIkKDAgAF8IRIgCUEBaiEJIAUgBmohBQwBCwALAAsgCkEDdiAKQQF2akEDaiEQQQAhBUEAIQYDQCAFIBFGDQFBACEEIA4gBUEBdGouAQAiD0EAIA9BAEobIQ8DQCAEIA9HBEAgDCAGQQN0aiAFNgIAA0AgBiAQaiALcSIGIAlLDQALIARBAWohBAwBCwsgBUEBaiEFDAALAAsgAEEIaiEJIAJBH2shC0EAIQYDQCAGIApHBEAgDSAJIAZBA3RqIgIoAgQiBEEBdGoiBSAFLwEAIgVBAWo7AQAgAiALIAVnaiIMOgADIAIgBSAMdCAKazsBACACIAQgCGotAAA6AAIgAiAHIARBAnRqKAIANgIEIAZBAWohBgwBCwsgASAANgIAIAMhCgwBC0FsIQoLIA5BgAFqJAAgCgtwAQR/IABCADcCACACBEAgAUEKaiEGIAEoAgQhBEEAIQJBACEBA0AgASAEdkUEQCACIAYgAUEDdGotAAAiBSACIAVLGyECIAFBAWohASADIAVBFktqIQMMAQsLIAAgAjYCBCAAIANBCCAEa3Q2AgALC64BAQR/IAEgAigCBCIDIAEoAgRqIgQ2AgQgACADQQJ0QbAZaigCACABKAIAQQAgBGt2cTYCAAJAIARBIU8EQCABQbAaNgIIDAELIAEoAggiAyABKAIQTwRAIAEQDAwBCyADIAEoAgwiBUYNACABIAMgAyAFayAEQQN2IgYgAyAGayAFSRsiA2siBTYCCCABIAQgA0EDdGs2AgQgASAFKAAANgIACyAAIAJBCGo2AgQLjQICA38BfiAAIAJqIQQCQAJAIAJBCE4EQCAAIAFrIgJBeUgNAQsDQCAAIARPDQIgACABLQAAOgAAIABBAWohACABQQFqIQEMAAsACwJAAkAgAkFvSw0AIAAgBEEgayICSw0AIAEpAAAhBiAAIAEpAAg3AAggACAGNwAAIAIgAGsiBUERTgRAIABBEGohACABIQMDQCADKQAQIQYgACADKQAYNwAIIAAgBjcAACADKQAgIQYgACADKQAoNwAYIAAgBjcAECADQSBqIQMgAEEgaiIAIAJJDQALCyABIAVqIQEMAQsgACECCwNAIAIgBE8NASACIAEtAAA6AAAgAkEBaiECIAFBAWohAQwACwALC98BAQZ/Qbp/IQoCQCACKAIEIgggAigCACIJaiINIAEgAGtLDQBBbCEKIAkgBCADKAIAIgtrSw0AIAAgCWoiBCACKAIIIgxrIQIgACABQSBrIgEgCyAJQQAQIyADIAkgC2o2AgACQAJAIAQgBWsgDE8EQCACIQUMAQsgDCAEIAZrSw0CIAcgByACIAVrIgNqIgIgCGpPBEAgCEUNAiAEIAIgCPwKAAAMAgtBACADayIABEAgBCACIAD8CgAACyADIAhqIQggBCADayEECyAEIAEgBSAIQQEQIwsgDSEKCyAKC+sBAQZ/Qbp/IQsCQCADKAIEIgkgAygCACIKaiINIAEgAGtLDQAgBSAEKAIAIgVrIApJBEBBbA8LIAMoAgghDCAAIAVLIAUgCmoiDiAAS3ENACAAIApqIgMgDGshASAAIAUgChAfIAQgDjYCAAJAAkAgAyAGayAMTwRAIAEhBgwBC0FsIQsgDCADIAdrSw0CIAggCCABIAZrIgBqIgEgCWpPBEAgCUUNAiADIAEgCfwKAAAMAgtBACAAayIEBEAgAyABIAT8CgAACyAAIAlqIQkgAyAAayEDCyADIAIgBiAJQQEQIwsgDSELCyALC6sCAQJ/IAJBH3EhAyABIQQDQCADQQhJRQRAIANBCGshAyAEKQAAQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef34gAIVCG4lCh5Wvr5i23puef35CnaO16oOxjYr6AH0hACAEQQhqIQQMAQsLIAEgAkEYcWohASACQQdxIgNBBEkEfyABBSADQQRrIQMgATUAAEKHla+vmLbem55/fiAAhUIXiULP1tO+0ser2UJ+Qvnz3fGZ9pmrFnwhACABQQRqCyEEA0AgAwRAIANBAWshAyAEMQAAQsXP2bLx5brqJ34gAIVCC4lCh5Wvr5i23puef34hACAEQQFqIQQMAQsLIABCIYggAIVCz9bTvtLHq9lCfiIAQh2IIACFQvnz3fGZ9pmrFn4iAEIgiCAAhQvhBAIBfgJ/IAAgA2ohBwJAIANBB0wEQANAIAAgB08NAiAAIAItAAA6AAAgAEEBaiEAIAJBAWohAgwACwALIAQEQAJAIAAgAmsiBkEHTQRAIAAgAi0AADoAACAAIAItAAE6AAEgACACLQACOgACIAAgAi0AAzoAAyAAIAIgBkECdCIGQeAaaigCAGoiAigAADYABCACIAZBgBtqKAIAayECDAELIAAgAikAADcAAAsgA0EIayEDIAJBCGohAiAAQQhqIQALIAEgB08EQCAAIANqIQEgBEUgACACa0EPSnJFBEADQCAAIAIpAAA3AAAgAkEIaiECIABBCGoiACABSQ0ADAMLAAsgAikAACEFIAAgAikACDcACCAAIAU3AAAgA0ERSQ0BIABBEGohAANAIAIpABAhBSAAIAIpABg3AAggACAFNwAAIAIpACAhBSAAIAIpACg3ABggACAFNwAQIAJBIGohAiAAQSBqIgAgAUkNAAsMAQsCQCAAIAFLBEAgACEBDAELIAEgAGshBgJAIARFIAAgAmtBD0pyRQRAIAIhAwNAIAAgAykAADcAACADQQhqIQMgAEEIaiIAIAFJDQALDAELIAIpAAAhBSAAIAIpAAg3AAggACAFNwAAIAZBEUgNACAAQRBqIQAgAiEDA0AgAykAECEFIAAgAykAGDcACCAAIAU3AAAgAykAICEFIAAgAykAKDcAGCAAIAU3ABAgA0EgaiEDIABBIGoiACABSQ0ACwsgAiAGaiECCwNAIAEgB08NASABIAItAAA6AAAgAUEBaiEBIAJBAWohAgwACwALC6HFAQI2fwV+IwBBEGsiMSQAAkBBwOwFEAEiCEUEQEFAIQYMAQsgCEIANwL86gEgCEEANgKc6wEgCEEANgKQ6wEgCEEANgLU6wEgCEEANgLE6wEgCEIANwKk6wEgCEEANgK46QEgCEEANgK87AUgCEIANwK86wEgCEEANgKs6wEgCEIBNwKU6wEgCEIANwPo6wEgCEGBgIDAADYCzOsBIAhCADcC7OoBIAhCADcDsOsBIAhBADYCuOsBIAhBhOsBakEANgIAIAgQFiAIQbjqAWohNCAIQcDpAWohNiAIQZDqAWohNyAAISwCQAJAAkACQANAQQFBBSAIKALs6gEiCxshEwJAA0AgAyATSQ0BAkAgA0EESSALcg0AIAIoAABBcHFB0NS0wgFHDQBBuH8hBiADQQhJDQcgAigABCIHQXdLBEBBciEGDAgLIAMgB0EIaiIESQ0HIAdBgH9LBEAgBCEGDAgLIAMgBGshAyACIARqIQIMAQsLIAhCADcCrOkBIAhCADcD8OkBIAhBjICA4AA2AqhQIAhBADYCoOsBIAhCADcDiOoBIAhBATYClOsBIAhCAzcDgOoBIAhBtOkBakIANwIAIAhB+OkBakIANwMAIAhB9A4pAgA3AqzQASAIQbTQAWpB/A4oAgA2AgAgCCAIQRBqNgIAIAggCEGgMGo2AgQgCCAIQZggajYCCCAIIAhBqNAAajYCDCAIQQFBBSAIKALs6gEbNgK86QECQCABRQ0AICwgCCgCrOkBIgZGDQAgCCAGNgK46QEgCCAsNgKs6QEgCCgCsOkBIQQgCCAsNgKw6QEgCCAsIAQgBmtqNgK06QELQbh/IQYgA0EFQQkgCCgC7OoBIhMbSQ0FIAJBAUEFIBMbIBMQGCIEQYh/Sw0EIAMgBEEDakkNBSA2IAIgBCATEBciBkGIf0sEQCAGIQQMBQsgBg0DAkACQCAIKAKw6wFBAUcNACAIKAKs6wEiC0UNACAIKAKc6wFFDQAgCygCBCEGIDEgCCgC3OkBIgo2AgQgBkEBayIHQsnP2bLx5brqJyAxQQRqQQQQIqdxIRMgCygCACELA0AgCiALIBNBAnRqKAIAIgwEfyAMKAKo1QEFQQALIgZHBEAgByATcUEBaiETIAYNAQsLIAxFDQAgCBAWIAhBfzYCqOsBIAggDDYCnOsBIAggCCgC3OkBIhM2AqDrAQwBCyAIKALc6QEhEwsCQCATRQ0AIAgoAqDrASATRg0AQWAhBAwFCwJAIAgoAuDpAQRAIAggCCgC8OoBIgZFNgL06gEgBg0BIDdBAEHYAPwLACAIQvnq0NDnyaHk4QA3A7DqASAIQs/W077Sx6vZQjcDoOoBIAhC1uuC7ur9ifXgADcDmOoBDAELIAhBADYC9OoBCyAIIAgpA/DpASAErXw3A/DpASAIKAK46wEiEwRAIAggCCgC0OkBIgYgEyAGIBNJGzYC0OkBCyABICxqITUgAyAEayEDIAIgBGohAiAsIRMDQCACIAMgMUEEahAaIiBBiH9LBEAgICEEDAYLIANBA2siOCAgSQ0EIAJBA2oiHSA1IB0gNUkbIDUgEyAdTRshAkFsIQQCQAJAAkACQAJAAkACQAJAIDEoAgQOAwECAA0LIAIgE2shFEEAITMjAEHQAmsiBSQAAkACQCAIKAKU6wEiAgR/IAgoAtDpAQVBgIAICyAgSQ0AAkAgIEECSQ0AIB0tAAAiA0EDcSEaIAIEfyAIKALQ6QEFQYCACAshBgJAAkACQAJAAkACQAJAAkACQAJAIBpBAWsOAwMBAAILIAgoAojqAQ0AQWIhAwwLCyAgQQVJDQhBAyEMIB0oAAAhBAJ/An8CQAJAAkAgA0ECdkEDcSICQQJrDgIBAgALIARBDnZB/wdxIQ0gBEEEdkH/B3EhECACQQBHDAMLIARBEnYhDSAEQQR2Qf//AHEhEEEEDAELIB0tAARBCnQgBEEWdnIhDSAEQQR2Qf//D3EhEEEFCyEMQQELIQRBun8hAyATQQEgEBtFDQogBiAQSQ0IIBBBBkkgBHEEQEFoIQMMCwsgDCANaiIKICBLDQggBiAUIAYgFEkbIgIgEEkNCiAIIBMgFCAQIAJBABAbAkAgCCgCpOsBRSAQQYEGSXINAEEAIQMDQCADQYOAAUsNASADQUBrIQMMAAsACyAaQQNGBEAgDCAdaiEGIAgoAgwiCy0AAUEIdCECIAgoAvzrASEDIARFBEAgAgRAIAVB4AFqIAYgDRAIIg5BiH9LDQkgC0EEaiEZIAMgEGohESALLwECIQkgEEEETwRAIBFBA2shBkEAIAlrQR9xIQcgBSgC6AEhDCAFKALsASEPIAUoAvABIQQgBSgC4AEhDSAFKALkASEOA0AgDkEgSwRAQbAaIQwMCgsCQCAEIAxNBEAgDkEHcSESIA5BA3YhDUEBIQ4MAQsgDCAPRg0KIA4gDkEDdiICIAwgD2sgDCACayAPTyIOGyINQQN0ayESCyAMIA1rIgwoAAAhDSAORSADIAZPcg0IIAMgGSANIBJ0IAd2QQJ0aiICLwEAOwAAIAMgAi0AA2oiAyAZIA0gEiACLQACaiICdCAHdkECdGoiCy8BADsAACADIAstAANqIQMgAiALLQACaiEODAALAAsgBSgC5AEiDkEhTwRAIAVBsBo2AugBDAkLIAUoAugBIgYgBSgC8AFPBEAgBSAOQQdxIgI2AuQBIAUgBiAOQQN2ayIENgLoASAFIAQoAAA2AuABIAIhDgwJCyAGIAUoAuwBIgRGDQggBSAOIAYgBGsgDkEDdiICIAYgAmsgBEkbIgJBA3RrIg42AuQBIAUgBiACayICNgLoASAFIAIoAAA2AuABDAgLIAMgECAGIA0gCxARIQ4MCAsgAgRAIAMgECAGIA0gCxASIQ4MCAsgAyAQIAYgDSALEBQhDgwHCyAIQazVAWohFyAMIB1qISEgCEGo0ABqIQcgCCgC/OsBIRYgBEUEQCAHICEgDSAXEA4iDkGIf0sNByANIA5NDQMgFiAQIA4gIWogDSAOayAHEBEhDgwHCyAQRQRAQbp/IQ4MBwsgDUUEQEFsIQ4MBwsgEEEIdiIDIA0gEEkEfyANQQR0IBBuBUEPC0EEdCIEQYwIaigCAGwgBEGICGooAgBqIgJBBXYgAmogBEGACGooAgAgBEGECGooAgAgA2xqSQRAIwBBEGsiLSQAIAcoAgAhESAXQfAEaiIeQQBB8AD8CwBBVCEDAkAgEUH/AXEiL0EMSw0AIBdB4AdqIgkgHiAtQQhqIC1BDGogISANIBdB4AlqEAciBEGIf00EQCAtKAIMIgsgL0sNASAXQagFaiEZIBdBpAVqITAgB0EEaiEbIBFBgICAeHEhJCALQQFqIjIhAyALIQYDQCADIgJBAWshAyAGIgxBAWshBiAeIAxBAnRqKAIARQ0AC0EBIAIgAkEBTRshDkEAIQZBASEDA0AgAyAORwRAIB4gA0ECdCIPaigCACECIA8gGWogBjYCACADQQFqIQMgAiAGaiEGDAELCyAXIAY2AqgFIBkgDEEBaiIfQQJ0aiAGNgIAIBdB4AVqISZBACEDIC0oAgghBgNAIAMgBkcEQCAZIAMgCWotAABBAnRqIgIgAigCACICQQFqNgIAIAIgJmogAzoAACADQQFqIQMMAQsLQQAhBiAZQQA2AgBBCyAvIBFB/wFxQQxGGyAvIAtBDEkbIikgC0F/c2ohD0EBIQMDQCADIA5HBEAgHiADQQJ0IgtqKAIAIQIgCyAXaiAGNgIAIAIgAyAPanQgBmohBiADQQFqIQMMAQsLICkgMiAMayILa0EBaiEJIAshBgNAIAYgCUkEQCAXIAZBNGxqIQ9BASEDA0AgAyAORwRAIA8gA0ECdCICaiACIBdqKAIAIAZ2NgIAIANBAWohAwwBCwsgBkEBaiEGDAELCyAyIClrIRUgDEEAIAxBAEobQQFqISdBASEuA0AgJyAuRwRAIDIgLmshBiAXIC5BAnQiAmooAgAhJSACIDBqKAIAISogMCAuQQFqIi5BAnRqKAIAIRggCyApIAZrIgNNBEAgHyAGIBVqIgJBASACQQFKIhIbIgIgAiAfSBshHCAXIAZBNGxqIh4gAkECdGohGSAGIDJqIREgBkEQdEGAgIAIaiEOQQEgA3QiCUECayEPA0AgGCAqRg0DIBsgJUECdGohKCAmICpqLQAAISsgAiEDIBIEQCAOICtyrUKBgICAEH4hOiAZKAIAIQZBACEDAkACQAJAAkAgDw4DAQIAAgsgKCA6NwEICyAoIDo3AQAMAQsDQCADIAZODQEgKCADQQJ0aiIMIDo3ARggDCA6NwEQIAwgOjcBCCAMIDo3AQAgA0EIaiEDDAALAAsgAiEDCwNAIAMgHEcEQCARIANrIQwgKCAeIANBAnQiBmooAgBBAnRqICYgBiAwaigCAGogJiAwIANBAWoiA0ECdGooAgBqIAwgKSArQQIQDwwBCwsgKkEBaiEqIAkgJWohJQwACwAFIBsgJUECdGogJiAqaiAYICZqIAYgKUEAQQEQDwwCCwALCyAHIClBEHQgJHIgL3JBgAJyNgIACyAEIQMLIC1BEGokACADIg5BiH9LDQcgAyANTw0DIBYgECADICFqIA0gA2sgBxASIQ4MBwsgByAhIA0gFxAOIg5BiH9LDQYgDSAOTQ0CIBYgECAOICFqIA0gDmsgBxAUIQ4MBgtBAiEQAn8CQAJAAkAgA0ECdkEDcUEBaw4DAQACAAtBASEQIANBA3YMAgsgHS8AAEEEdgwBCyAgQQJGDQhBAyEQIB0vAAAgHS0AAkEQdHJBBHYLIQtBun8hAyATQQEgCxtFDQkgBiALSQ0HIAsgFEsNCSAIIBMgFCALIAYgFCAGIBRJG0EBEBsgICALIBBqIgpBIGpJBEAgCiAgSw0IIBAgHWohBCAIKAL86wEhAwJAIAgoAoTsAUECRgRAIAtBgIAEayICBEAgAyAEIAL8CgAACyAIQYjsAWogAiAEakGAgAT8CgAADAELIAtFDQAgAyAEIAv8CgAACyAIIAs2AojrASAIIAgoAvzrATYC+OoBDAcLIAhBADYChOwBIAggCzYCiOsBIAggECAdaiICNgL46gEgCCACIAtqNgKA7AEMBgsCfwJAAkACQCADQQJ2QQNxQQFrDgMBAAIAC0EBIRAgA0EDdgwCCyAgQQJGDQhBAiEQIB0vAABBBHYMAQsgIEEESQ0HQQMhECAdLwAAIB0tAAJBEHRyQQR2CyELQbp/IQMgE0EBIAsbRQ0IIAYgC0kNBiALIBRLDQggCCATIBQgCyAGIBQgBiAUSRtBARAbIBAgHWoiAy0AACEGIAgoAvzrASEEAkAgCCgChOwBQQJGBEAgC0GAgARrIgIEQCAEIAYgAvwLAAsgCEGI7AFqIAMtAABBgIAE/AsADAELIAtFDQAgBCAGIAv8CwALIAggCzYCiOsBIAggCCgC/OsBNgL46gEgEEEBaiEKDAULQbh/IQ4MAwsgEiEOCyAFIA42AuQBIAUgDDYC6AEgBSANNgLgAQsCQCARIANrQQJJDQAgEUECayELQQAgCWtBH3EhBgNAAkAgDkEhTwRAIAVBsBo2AugBDAELIAUCfyAFKALoASIHIAUoAvABTwRAIAUgByAOQQN2ayIMNgLoAUEBISUgDkEHcQwBCyAHIAUoAuwBIgRGDQEgBSAHIA5BA3YiAiAHIARrIAcgAmsgBE8iJRsiAmsiDDYC6AEgDiACQQN0awsiDjYC5AEgBSAMKAAAIgI2AuABICVFIAMgC0tyDQAgAyAZIAIgDnQgBnZBAnRqIgIvAQA7AAAgBSAFKALkASACLQACaiIONgLkASADIAItAANqIQMMAQsLA0AgAyALSw0BIAMgGSAFKALgASAOdCAGdkECdGoiAi8BADsAACAFIAUoAuQBIAItAAJqIg42AuQBIAMgAi0AA2ohAwwACwALAkAgAyARTw0AIAMgGSAFKALgASAOdEEAIAlrdkECdGoiAi0AADoAACACLQADQQFGBEAgBSgC5AEgAi0AAmohDgwBCyAFKALkASIOQR9LDQBBICAOIAItAAJqIgIgAkEgTxshDgtBbEFsIBAgDkEgRxsgBSgC6AEgBSgC7AFHGyEOCyAIKAKE7AFBAkYEQCAIQYjsAWogCCgCgOwBQYCABGtBgIAE/AoAACAQQYCABGsiAwRAIAgoAvzrASICQeD/A2ogAiAD/AoAAAsgCCAIKAL86wFB4P8DajYC/OsBIAggCCgCgOwBQSBrNgKA7AELIA5BiH9LDQEgCCAQNgKI6wEgCEEBNgKI6gEgCCAIKAL86wE2AvjqASAaQQJGBEAgCCAIQajQAGo2AgwLIAoiA0GIf0sNAwsgCCgClOsBBH8gCCgC0OkBBUGAgAgLIQwgCiAgRg0BICAgCmshCSAIKAK06QEhCyAdICBqIQ0gCCgCpOsBIQYCfwJAAn8gCiAdaiIRLQAAIg7AIgJBAE4EQCARQQFqDAELIAJBf0YEQCAJQQNJDQUgEUEDaiEEIBEvAAFBgP4BaiEODAILIAlBAUYNBCARLQABIA5BCHRyQYCAAmshDiARQQJqCyEEIA4NAEFsIQMgBCANRw0EQQAhDiAJDAELQbh/IQMgBEEBaiIPIA1LDQMgBC0AACIKQQNxDQEgCEEQaiAIIApBBnZBI0EJIA8gDSAPa0HADUHQDkGADyAIKAKM6gEgBiAOIAhBrNUBaiIHEBwiAkGIf0sNASAIQZggaiAIQQhqIApBBHZBA3FBH0EIIAIgD2oiBCANIARrQYAKQYALQZATIAgoAozqASAIKAKk6wEgDiAHEBwiAkGIf0sNAUFsIQMgCEGgMGogCEEEaiAKQQJ2QQNxQTRBCSACIARqIgQgDSAEa0GgC0GADUGgFSAIKAKM6gEgCCgCpOsBIA4gBxAcIgJBiH9LDQMgAiAEaiARawsiA0GIf0sNAgJAIBNBAEcgFEEAR3FFIA5BAEpxDQACQAJAIBMgFCAMIAwgFEsbIgJBACACQQBKG2ogC2siAkH8//8fTQRAIAYgAkGBgIAISXIgDkEJSHINAiAFQeABaiAIKAIIIA4QHQwBCyAFQeABaiAIKAIIIA4QHSAFKALkAUEZSyEzIAYNAQsgBSgC4AFBE0shBgsgCSADayEHIAMgEWohBCAIQQA2AqTrASAIKAKE7AEhAgJAIAYEQAJ/IAJBAUYEQCAIKAL86wEMAQsgEyAUQQAgFEEAShtqCyEUIAUgCCgC+OoBIgM2AswCIAgoAoDsASEcIA5FBEAgEyEJDAILIAgoArjpASEiIAgoArTpASEXIAgoArDpASELIAhBATYCjOoBIAhBrNABaiEyIAVB1AFqISZBACECA0AgAkEDRwRAICYgAkECdCIDaiADIDJqKAIANgIAIAJBAWohAgwBCwtBbCEDIAVBqAFqIgIgBCAHEAhBiH9LDQUgBUG8AWogAiAIKAIAEB4gBUHEAWogAiAIKAIIEB4gBUHMAWogAiAIKAIEEB5BCCAOIA5BCE4bIihBACAoQQBKGyElIA5BAWshGiATIAtrIS0gBSgCsAEhAiAFKALYASEGIAUoAtQBIRIgBSgCrAEhBCAFKAK0ASEjIAUoArgBISkgBSgCyAEhGCAFKALQASErIAUoAsABISQgBSgCqAEhCSAFKALEASEhIAUoAswBISogBSgCvAEhMCAzRSEVQQAhEANAIBIhESAQICVGBEAgBSAqNgLMASAFIDA2ArwBIAUgAjYCsAEgBSAhNgLEASAFIAk2AqgBIAhBmOwBaiEeIAhBiOwFaiEZIAhBiOwBaiEWIBRBIGshGyAzRSEnIBMhCQNAIA4gJUcEQCAFKALAASAFKAK8AUEDdGoiBi0AAiEfIAUoAtABIAUoAswBQQN0aiIELQACIRggBSgCyAEgBSgCxAFBA3RqIgItAAMhKyAELQADISQgBi0AAyEVIAIvAQAhEiAELwEAIREgBi8BACEKIAIoAgQhByAGKAIEIRAgBCgCBCEMAkAgAi0AAiINQQJPBEACQCAnIA1BGUlyRQRAIAcgBSgCqAEiDyAFKAKsASICdEEFIA1rdkEFdGohBwJAIAIgDWpBBWsiAkEhTwRAIAVBsBo2ArABDAELIAUoArABIgYgBSgCuAFPBEAgBSACQQdxIgQ2AqwBIAUgBiACQQN2ayICNgKwASAFIAIoAAAiDzYCqAEgBCECDAELIAYgBSgCtAEiBEYNACAFIAIgBiAEayACQQN2IgIgBiACayAESRsiBEEDdGsiAjYCrAEgBSAGIARrIgQ2ArABIAUgBCgAACIPNgKoAQsgBSACQQVqIgY2AqwBIAcgDyACdEEbdmohDQwBCyAFIAUoAqwBIgIgDWoiBjYCrAEgBSgCqAEgAnRBACANa3YgB2ohDSAGQSFPBEAgBUGwGjYCsAEMAQsgBSgCsAEiByAFKAK4AU8EQCAFIAZBB3EiAjYCrAEgBSAHIAZBA3ZrIgQ2ArABIAUgBCgAADYCqAEgAiEGDAELIAcgBSgCtAEiBEYNACAFIAYgByAEayAGQQN2IgIgByACayAESRsiAkEDdGsiBjYCrAEgBSAHIAJrIgI2ArABIAUgAigAADYCqAELIAUpAtQBITogBSANNgLUASAFIDo3AtgBDAELIBBFIQQgDUUEQCAmIBBBAEdBAnRqKAIAIQIgBSAmIARBAnRqKAIAIg02AtQBIAUgAjYC2AEgBSgCrAEhBgwBCyAFIAUoAqwBIgJBAWoiBjYCrAECQAJAIAQgB2ogBSgCqAEgAnRBH3ZqIgRBA0YEQCAFKALUAUEBayICQX8gAhshDQwBCyAmIARBAnRqKAIAIgJBfyACGyENIARBAUYNAQsgBSAFKALYATYC3AELIAUgBSgC1AE2AtgBIAUgDTYC1AELIBggH2ohBAJAIBhFBEAgBiECDAELIAUgBiAYaiICNgKsASAFKAKoASAGdEEAIBhrdiAMaiEMCwJAIARBFEkNACACQSFPBEAgBUGwGjYCsAEMAQsgBSgCsAEiBiAFKAK4AU8EQCAFIAJBB3EiBDYCrAEgBSAGIAJBA3ZrIgI2ArABIAUgAigAADYCqAEgBCECDAELIAYgBSgCtAEiBEYNACAFIAIgBiAEayACQQN2IgIgBiACayAESRsiBEEDdGsiAjYCrAEgBSAGIARrIgQ2ArABIAUgBCgAADYCqAELAkAgH0UEQCACIQQMAQsgBSACIB9qIgQ2AqwBIAUoAqgBIAJ0QQAgH2t2IBBqIRALAkAgBEEhTwRAQbAaIQIgBUGwGjYCsAEMAQsgBSgCsAEiAiAFKAK4AU8EQCAFIARBB3EiBjYCrAEgBSACIARBA3ZrIgI2ArABIAUgAigAADYCqAEgBiEEDAELIAIgBSgCtAEiB0YNACAFIAIgAiAHayAEQQN2IgYgAiAGayAHSRsiBmsiAjYCsAEgBSAEIAZBA3RrIgQ2AqwBIAUgAigAADYCqAELAkAgGiAlRg0AIAUgFUECdEGwGWooAgAgBSgCqAEiB0EAIAQgFWoiBGt2cSAKajYCvAEgBSAkQQJ0QbAZaigCACAHQQAgBCAkaiIEa3ZxIBFqNgLMAQJAIARBIU8EQEGwGiECIAVBsBo2ArABDAELIAUoArgBIAJNBEAgBSAEQQdxIgY2AqwBIAUgAiAEQQN2ayICNgKwASAFIAIoAAAiBzYCqAEgBiEEDAELIAIgBSgCtAEiCkYNACAFIAIgAiAKayAEQQN2IgYgAiAGayAKSRsiBmsiAjYCsAEgBSAEIAZBA3RrIgQ2AqwBIAUgAigAACIHNgKoAQsgBSAEICtqIgQ2AqwBIAUgK0ECdEGwGWooAgAgB0EAIARrdnEgEmo2AsQBIARBIU8EQCAFQbAaNgKwAQwBCyAFKAK4ASACTQRAIAUgBEEHcTYCrAEgBSACIARBA3ZrIgI2ArABIAUgAigAADYCqAEMAQsgAiAFKAK0ASIGRg0AIAUgBCACIAZrIARBA3YiBCACIARrIAZJGyIEQQN0azYCrAEgBSACIARrIgI2ArABIAUgAigAADYCqAELAkACQCAIKAKE7AFBAkYEQCAFKALMAiIHIAVB4AFqICVBB3FBDGxqIhUoAgAiAmoiCiAIKAKA7AEiBEsEQCAEIAdHBEAgBCAHayIEIBQgCWtLDQsgCSAHIAQQHyAVIAIgBGsiAjYCACAEIAlqIQkLIAUgFjYCzAIgCEEANgKE7AECQAJAAkAgAkGAgARKDQAgCSAVKAIEIhIgAmoiBmogG0sNACAGQSBqIBQgCWtNDQELIAUgFSgCCDYCgAEgBSAVKQIANwN4IAkgFCAFQfgAaiAFQcwCaiAZIAsgFyAiECAhBgwBCyACIBZqIQcgAiAJaiEEIBUoAgghESAWKQAAITogCSAWKQAINwAIIAkgOjcAAAJAIAJBEUkNACAeKQAAITogCSAeKQAINwAYIAkgOjcAECACQRBrQRFIDQAgCUEgaiECIB4hDwNAIA8pABAhOiACIA8pABg3AAggAiA6NwAAIA8pACAhOiACIA8pACg3ABggAiA6NwAQIA9BIGohDyACQSBqIgIgBEkNAAsLIAQgEWshAiAFIAc2AswCIAQgC2sgEUkEQCARIAQgF2tLDQ8gIiAiIAIgC2siCmoiByASak8EQCASRQ0CIAQgByAS/AoAAAwCC0EAIAprIgIEQCAEIAcgAvwKAAALIAogEmohEiAEIAprIQQgCyECCyARQRBPBEAgAikAACE6IAQgAikACDcACCAEIDo3AAAgEkERSA0BIAQgEmohByAEQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAdJDQALDAELAkAgEUEHTQRAIAQgAi0AADoAACAEIAItAAE6AAEgBCACLQACOgACIAQgAi0AAzoAAyAEIAIgEUECdCIHQeAaaigCAGoiAigAADYABCACIAdBgBtqKAIAayECDAELIAQgAikAADcAAAsgEkEJSQ0AIAQgEmohCiAEQQhqIgcgAkEIaiICa0EPTARAA0AgByACKQAANwAAIAJBCGohAiAHQQhqIgcgCkkNAAwCCwALIAIpAAAhOiAHIAIpAAg3AAggByA6NwAAIBJBGUgNACAEQRhqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIApJDQALCyAGQYh/SwRAIAYhAwwOCyAVIA02AgggFSAMNgIEIBUgEDYCACAZIRwMAwsgCkEgayEEAkACQCAKIBxLDQAgCSAVKAIEIhEgAmoiBmogBEsNACAGQSBqIBQgCWtNDQELIAUgFSgCCDYCkAEgBSAVKQIANwOIASAJIBQgBCAFQYgBaiAFQcwCaiAcIAsgFyAiECEhBgwCCyACIAlqIQQgFSgCCCEPIAcpAAAhOiAJIAcpAAg3AAggCSA6NwAAAkAgAkERSQ0AIAcpABAhOiAJIAcpABg3ABggCSA6NwAQIAJBEGtBEUgNACAHQRBqIQIgCUEgaiEHA0AgAikAECE6IAcgAikAGDcACCAHIDo3AAAgAikAICE6IAcgAikAKDcAGCAHIDo3ABAgAkEgaiECIAdBIGoiByAESQ0ACwsgBCAPayECIAUgCjYCzAIgBCALayAPSQRAIA8gBCAXa0sNDSAiICIgAiALayIKaiIHIBFqTwRAIBFFDQMgBCAHIBH8CgAADAMLQQAgCmsiAgRAIAQgByAC/AoAAAsgCiARaiERIAQgCmshBCALIQILIA9BEE8EQCACKQAAITogBCACKQAINwAIIAQgOjcAACARQRFIDQIgBCARaiEHIARBEGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgB0kNAAsMAgsCQCAPQQdNBEAgBCACLQAAOgAAIAQgAi0AAToAASAEIAItAAI6AAIgBCACLQADOgADIAQgAiAPQQJ0IgdB4BpqKAIAaiICKAAANgAEIAIgB0GAG2ooAgBrIQIMAQsgBCACKQAANwAACyARQQlJDQEgBCARaiEKIARBCGoiByACQQhqIgJrQQ9MBEADQCAHIAIpAAA3AAAgAkEIaiECIAdBCGoiByAKSQ0ADAMLAAsgAikAACE6IAcgAikACDcACCAHIDo3AAAgEUEZSA0BIARBGGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgCkkNAAsMAQsCQAJAIAUoAswCIhEgBUHgAWogJUEHcUEMbGoiDygCACICaiIHIBxLDQAgCSAPKAIEIgogAmoiBmogG0sNACAGQSBqIBQgCWtNDQELIAUgDygCCDYCoAEgBSAPKQIANwOYASAJIBQgBUGYAWogBUHMAmogHCALIBcgIhAgIQYMAQsgAiAJaiEEIA8oAgghFSARKQAAITogCSARKQAINwAIIAkgOjcAAAJAIAJBEUkNACARKQAQITogCSARKQAYNwAYIAkgOjcAECACQRBrQRFIDQAgEUEQaiECIAlBIGohEgNAIAIpABAhOiASIAIpABg3AAggEiA6NwAAIAIpACAhOiASIAIpACg3ABggEiA6NwAQIAJBIGohAiASQSBqIhIgBEkNAAsLIAQgFWshAiAFIAc2AswCIAQgC2sgFUkEQCAVIAQgF2tLDQwgIiAiIAIgC2siD2oiByAKak8EQCAKRQ0CIAQgByAK/AoAAAwCC0EAIA9rIgIEQCAEIAcgAvwKAAALIAogD2ohCiAEIA9rIQQgCyECCyAVQRBPBEAgAikAACE6IAQgAikACDcACCAEIDo3AAAgCkERSA0BIAQgCmohByAEQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAdJDQALDAELAkAgFUEHTQRAIAQgAi0AADoAACAEIAItAAE6AAEgBCACLQACOgACIAQgAi0AAzoAAyAEIAIgFUECdCIHQeAaaigCAGoiAigAADYABCACIAdBgBtqKAIAayECDAELIAQgAikAADcAAAsgCkEJSQ0AIAQgCmohDyAEQQhqIgcgAkEIaiICa0EPTARAA0AgByACKQAANwAAIAJBCGohAiAHQQhqIgcgD0kNAAwCCwALIAIpAAAhOiAHIAIpAAg3AAggByA6NwAAIApBGUgNACAEQRhqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIA9JDQALCyAGQYh/SwRAIAYhAwwLCyAFQeABaiAlQQdxQQxsaiICIA02AgggAiAMNgIEIAIgEDYCAAsgBiAJaiEJICVBAWohJSAQIC1qIAxqIS0MAQsLIAUoArABIAUoArQBRw0HIAUoAqwBQSBHDQcgDiAoayEQA0ACQCAOIBBMBEBBACECA0AgAkEDRg0CIDIgAkECdCIDaiADICZqKAIANgIAIAJBAWohAgwACwALIAVB4AFqIBBBB3FBDGxqIQoCfwJAIAgoAoTsAUECRgRAIAUoAswCIg8gCigCACIEaiIHIAgoAoDsASICSwRAIAIgD0cEQCACIA9rIgIgFCAJa0sNCyAJIA8gAhAfIAogBCACayIENgIAIAIgCWohCQsgBSAWNgLMAiAIQQA2AoTsAQJAAkACQCAEQYCABEoNACAJIAooAgQiDSAEaiIGaiAbSw0AIAZBIGogFCAJa00NAQsgBSAKKAIINgJQIAUgCikCADcDSCAJIBQgBUHIAGogBUHMAmogGSALIBcgIhAgIQYMAQsgBCAWaiEHIAQgCWohDCAKKAIIIQogFikAACE6IAkgFikACDcACCAJIDo3AAACQCAEQRFJDQAgHikAACE6IAkgHikACDcAGCAJIDo3ABAgBEEQa0ERSA0AIAlBIGohAiAeIQQDQCAEKQAQITogAiAEKQAYNwAIIAIgOjcAACAEKQAgITogAiAEKQAoNwAYIAIgOjcAECAEQSBqIQQgAkEgaiICIAxJDQALCyAMIAprIQIgBSAHNgLMAiAMIAtrIApJBEAgCiAMIBdrSw0PICIgIiACIAtrIgdqIgQgDWpPBEAgDUUNAiAMIAQgDfwKAAAMAgtBACAHayICBEAgDCAEIAL8CgAACyAHIA1qIQ0gDCAHayEMIAshAgsgCkEQTwRAIAIpAAAhOiAMIAIpAAg3AAggDCA6NwAAIA1BEUgNASAMIA1qIQcgDEEQaiEEA0AgAikAECE6IAQgAikAGDcACCAEIDo3AAAgAikAICE6IAQgAikAKDcAGCAEIDo3ABAgAkEgaiECIARBIGoiBCAHSQ0ACwwBCwJAIApBB00EQCAMIAItAAA6AAAgDCACLQABOgABIAwgAi0AAjoAAiAMIAItAAM6AAMgDCACIApBAnQiBEHgGmooAgBqIgIoAAA2AAQgAiAEQYAbaigCAGshAgwBCyAMIAIpAAA3AAALIA1BCUkNACAMIA1qIQcgDEEIaiIEIAJBCGoiAmtBD0wEQANAIAQgAikAADcAACACQQhqIQIgBEEIaiIEIAdJDQAMAgsACyACKQAAITogBCACKQAINwAIIAQgOjcAACANQRlIDQAgDEEYaiEEA0AgAikAECE6IAQgAikAGDcACCAEIDo3AAAgAikAICE6IAQgAikAKDcAGCAEIDo3ABAgAkEgaiECIARBIGoiBCAHSQ0ACwsgBkGJf08EQCAGIQMMDgsgGSEcIAYgCWoMAwsgB0EgayECAkACQCAHIBxLDQAgCSAKKAIEIhIgBGoiDGogAksNACAMQSBqIBQgCWtNDQELIAUgCigCCDYCYCAFIAopAgA3A1ggCSAUIAIgBUHYAGogBUHMAmogHCALIBcgIhAhIQwMAgsgBCAJaiEGIAooAgghCiAPKQAAITogCSAPKQAINwAIIAkgOjcAAAJAIARBEUkNACAPKQAQITogCSAPKQAYNwAYIAkgOjcAECAEQRBrQRFIDQAgD0EQaiECIAlBIGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgBkkNAAsLIAYgCmshAiAFIAc2AswCIAYgC2sgCkkEQCAKIAYgF2tLDQ0gIiAiIAIgC2siB2oiBCASak8EQCASRQ0DIAYgBCAS/AoAAAwDC0EAIAdrIgIEQCAGIAQgAvwKAAALIAcgEmohEiAGIAdrIQYgCyECCyAKQRBPBEAgAikAACE6IAYgAikACDcACCAGIDo3AAAgEkERSA0CIAYgEmohByAGQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAdJDQALDAILAkAgCkEHTQRAIAYgAi0AADoAACAGIAItAAE6AAEgBiACLQACOgACIAYgAi0AAzoAAyAGIAIgCkECdCIEQeAaaigCAGoiAigAADYABCACIARBgBtqKAIAayECDAELIAYgAikAADcAAAsgEkEJSQ0BIAYgEmohByAGQQhqIgQgAkEIaiICa0EPTARAA0AgBCACKQAANwAAIAJBCGohAiAEQQhqIgQgB0kNAAwDCwALIAIpAAAhOiAEIAIpAAg3AAggBCA6NwAAIBJBGUgNASAGQRhqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAdJDQALDAELAkACQCAFKALMAiIGIAooAgAiAmoiByAcSw0AIAkgCigCBCINIAJqIgxqIBtLDQAgDEEgaiAUIAlrTQ0BCyAFIAooAgg2AnAgBSAKKQIANwNoIAkgFCAFQegAaiAFQcwCaiAcIAsgFyAiECAhDAwBCyACIAlqIQQgCigCCCEKIAYpAAAhOiAJIAYpAAg3AAggCSA6NwAAAkAgAkERSQ0AIAYpABAhOiAJIAYpABg3ABggCSA6NwAQIAJBEGtBEUgNACAGQRBqIQIgCUEgaiEGA0AgAikAECE6IAYgAikAGDcACCAGIDo3AAAgAikAICE6IAYgAikAKDcAGCAGIDo3ABAgAkEgaiECIAZBIGoiBiAESQ0ACwsgBCAKayECIAUgBzYCzAIgBCALayAKSQRAIAogBCAXa0sNDCAiICIgAiALayIHaiIGIA1qTwRAIA1FDQIgBCAGIA38CgAADAILQQAgB2siAgRAIAQgBiAC/AoAAAsgByANaiENIAQgB2shBCALIQILIApBEE8EQCACKQAAITogBCACKQAINwAIIAQgOjcAACANQRFIDQEgBCANaiEGIARBEGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgBkkNAAsMAQsCQCAKQQdNBEAgBCACLQAAOgAAIAQgAi0AAToAASAEIAItAAI6AAIgBCACLQADOgADIAQgAiAKQQJ0IgZB4BpqKAIAaiICKAAANgAEIAIgBkGAG2ooAgBrIQIMAQsgBCACKQAANwAACyANQQlJDQAgBCANaiEGIARBCGoiByACQQhqIgJrQQ9MBEADQCAHIAIpAAA3AAAgAkEIaiECIAdBCGoiByAGSQ0ADAILAAsgAikAACE6IAcgAikACDcACCAHIDo3AAAgDUEZSA0AIARBGGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgBkkNAAsLIAxBiH9LBEAgDCEDDAsLIAkgDGoLIQkgEEEBaiEQDAELCyAIKAKE7AEhAiAFKALMAiEDDAMFICQgMEEDdGoiBy0AAiEuICsgKkEDdGoiCi0AAiEvIBggIUEDdGoiDC0AAyEWIAotAAMhGyAHLQADIR8gDC8BACEnIAovAQAhHiAHLwEAIRkgDCgCBCENIAcoAgQhByAKKAIEIQoCQAJAIAwtAAIiEkECTwRAIAkgBHQhDCAVIBJBGUlyRQRAIAxBBSASa3ZBBXQgDWohDQJAIAQgEmpBBWsiBEEgSwRAQbAaIQIMAQsgAiApTwRAIAUgBEEHcSIMNgKsASACIARBA3ZrIgIoAAAhCSAMIQQMAQsgAiAjRg0AIAUgBCACICNrIARBA3YiBCACIARrICNJGyIMQQN0ayIENgKsASACIAxrIgIoAAAhCQsgBSAEQQVqIg82AqwBIA0gCSAEdEEbdmohEgwCCyAFIAQgEmoiDzYCrAEgDEEAIBJrdiANaiESIA9BIEsEQEGwGiECDAILIAIgKU8EQCAFIA9BB3EiBDYCrAEgAiAPQQN2ayICKAAAIQkgBCEPDAILIAIgI0YNASAFIA8gAiAjayAPQQN2IgQgAiAEayAjSRsiBEEDdGsiDzYCrAEgAiAEayICKAAAIQkMAQsgB0UhDCASRQRAICYgDEECdGooAgAhEiAmIAdBAEdBAnRqKAIAIREgBCEPDAILIAUgBEEBaiIPNgKsASANIAkgBHRBH3ZqIAxqIgxBA0YEQCARQQFrIgRBfyAEGyESDAELICYgDEECdGooAgAiBEF/IAQbIRIgDEEBRg0BCyAFIAY2AtwBCyAuIC9qIQQgBSASNgLUASAFIBE2AtgBAkAgL0UEQCAPIQwMAQsgBSAPIC9qIgw2AqwBIAkgD3RBACAva3YgCmohCgsCQCAEQRRJDQAgDEEgSwRAQbAaIQIMAQsgAiApTwRAIAUgDEEHcSIENgKsASACIAxBA3ZrIgIoAAAhCSAEIQwMAQsgAiAjRg0AIAUgDCACICNrIAxBA3YiBCACIARrICNJGyIEQQN0ayIMNgKsASACIARrIgIoAAAhCQsCQCAuRQRAIAwhBAwBCyAFIAwgLmoiBDYCrAEgCSAMdEEAIC5rdiAHaiEHCwJAIARBIEsEQEGwGiECDAELIAIgKU8EQCAFIARBB3EiBjYCrAEgAiAEQQN2ayICKAAAIQkgBiEEDAELIAIgI0YNACAFIAQgAiAjayAEQQN2IgQgAiAEayAjSRsiBkEDdGsiBDYCrAEgAiAGayICKAAAIQkLAkAgECAaRg0AIB9BAnRBsBlqKAIAIAlBACAEIB9qIgRrdnEhDyAbQQJ0QbAZaigCACAJQQAgBCAbaiIEa3ZxIQYCQAJ/AkACQCAEQSBLBEBBsBohAgwBCyACIClPBEAgBSAEQQdxIgw2AqwBIAIgBEEDdmsMAwsgAiAjRw0BCyAEIQwMAgsgBSAEIAIgI2sgBEEDdiIEIAIgBGsgI0kbIgRBA3RrIgw2AqwBIAIgBGsLIgIoAAAhCQsgDyAZaiEwIAYgHmohKiAFIAwgFmoiBjYCrAEgFkECdEGwGWooAgAgCUEAIAZrdnEgJ2ohIQJ/AkACQCAGQSBLBEBBsBohAgwBCyACIClPBEAgBSAGQQdxIgQ2AqwBIAIgBkEDdmsMAwsgAiAjRw0BCyAGIQQMAgsgBSAGIAIgI2sgBkEDdiIEIAIgBGsgI0kbIgZBA3RrIgQ2AqwBIAIgBmsLIgIoAAAhCQsgBUHgAWogEEEMbGoiBiASNgIIIAYgCjYCBCAGIAc2AgAgEEEBaiEQIAcgLWogCmohLSARIQYMAQsACwALAn8CQAJAAkAgAg4DAQIAAgsgBSAIKAL46gEiAzYCzAJBACECIBMgFEEAIBRBAEobaiEaIAgoAoDsASERAn8CQCAORQRAIBMhBwwBCyAIKAK46QEhFiAIKAK06QEhHyAIKAKw6QEhCyAIQQE2AozqASAIQazQAWohKyAFQYwCaiEbA0AgAkEDRwRAIBsgAkECdCIDaiADICtqKAIANgIAIAJBAWohAgwBCwsgBUHgAWoiAiAEIAcQCEGIf0sNByAFQfQBaiACIAgoAgAQHiAFQfwBaiACIAgoAggQHiAFQYQCaiACIAgoAgQQHiAzRSEeIBMhBwJAA0AgDkUNASAFKAL4ASAFKAL0AUEDdGoiBC0AAiEkIAUoAogCIAUoAoQCQQN0aiIDLQACIRUgBSgCgAIgBSgC/AFBA3RqIgItAAMhJyADLQADIRIgBC0AAyEcIAIvAQAhGSADLwEAIQ8gBC8BACEMIAIoAgQhBiAEKAIEIQQgAygCBCEJAkAgAi0AAiINQQJPBEACQCAeIA1BGUlyRQRAIAUoAuABIiEgBSgC5AEiAnRBBSANa3ZBBXQgBmohBgJAIAIgDWpBBWsiAkEhTwRAIAVBsBo2AugBDAELIAUoAugBIgogBSgC8AFPBEAgBSACQQdxIgM2AuQBIAUgCiACQQN2ayICNgLoASAFIAIoAAAiITYC4AEgAyECDAELIAogBSgC7AEiA0YNACAFIAIgCiADayACQQN2IgIgCiACayADSRsiA0EDdGsiAjYC5AEgBSAKIANrIgM2AugBIAUgAygAACIhNgLgAQsgBSACQQVqIgo2AuQBIAYgISACdEEbdmohDQwBCyAFIAUoAuQBIgIgDWoiCjYC5AEgBSgC4AEgAnRBACANa3YgBmohDSAKQSFPBEAgBUGwGjYC6AEMAQsgBSgC6AEiBiAFKALwAU8EQCAFIApBB3EiAjYC5AEgBSAGIApBA3ZrIgM2AugBIAUgAygAADYC4AEgAiEKDAELIAYgBSgC7AEiA0YNACAFIAogBiADayAKQQN2IgIgBiACayADSRsiAkEDdGsiCjYC5AEgBSAGIAJrIgI2AugBIAUgAigAADYC4AELIAUpAowCITogBSANNgKMAiAFIDo3ApACDAELIARFIQMgDUUEQCAbIARBAEdBAnRqKAIAIQIgBSAbIANBAnRqKAIAIg02AowCIAUgAjYCkAIgBSgC5AEhCgwBCyAFIAUoAuQBIgJBAWoiCjYC5AECQAJAIAMgBmogBSgC4AEgAnRBH3ZqIgNBA0YEQCAFKAKMAkEBayICQX8gAhshDQwBCyAbIANBAnRqKAIAIgJBfyACGyENIANBAUYNAQsgBSAFKAKQAjYClAILIAUgBSgCjAI2ApACIAUgDTYCjAILIBUgJGohAwJAIBVFBEAgCiECDAELIAUgCiAVaiICNgLkASAFKALgASAKdEEAIBVrdiAJaiEJCwJAIANBFEkNACACQSFPBEAgBUGwGjYC6AEMAQsgBSgC6AEiBiAFKALwAU8EQCAFIAJBB3EiAzYC5AEgBSAGIAJBA3ZrIgI2AugBIAUgAigAADYC4AEgAyECDAELIAYgBSgC7AEiA0YNACAFIAIgBiADayACQQN2IgIgBiACayADSRsiA0EDdGsiAjYC5AEgBSAGIANrIgM2AugBIAUgAygAADYC4AELAkAgJEUEQCACIQMMAQsgBSACICRqIgM2AuQBIAUoAuABIAJ0QQAgJGt2IARqIQQLAkAgA0EhTwRAQbAaIQIgBUGwGjYC6AEMAQsgBSgC6AEiAiAFKALwAU8EQCAFIANBB3EiBjYC5AEgBSACIANBA3ZrIgI2AugBIAUgAigAADYC4AEgBiEDDAELIAIgBSgC7AEiCkYNACAFIAIgAiAKayADQQN2IgYgAiAGayAKSRsiBmsiAjYC6AEgBSADIAZBA3RrIgM2AuQBIAUgAigAADYC4AELAkAgDkEBRg0AIAUgHEECdEGwGWooAgAgBSgC4AEiBkEAIAMgHGoiA2t2cSAMajYC9AEgBSASQQJ0QbAZaigCACAGQQAgAyASaiIDa3ZxIA9qNgKEAgJAIANBIU8EQEGwGiECIAVBsBo2AugBDAELIAUoAvABIAJNBEAgBSADQQdxIgo2AuQBIAUgAiADQQN2ayICNgLoASAFIAIoAAAiBjYC4AEgCiEDDAELIAIgBSgC7AEiCkYNACAFIAIgAiAKayADQQN2IgYgAiAGayAKSRsiBmsiAjYC6AEgBSADIAZBA3RrIgM2AuQBIAUgAigAACIGNgLgAQsgBSADICdqIgM2AuQBIAUgJ0ECdEGwGWooAgAgBkEAIANrdnEgGWo2AvwBIANBIU8EQCAFQbAaNgLoAQwBCyAFKALwASACTQRAIAUgA0EHcTYC5AEgBSACIANBA3ZrIgI2AugBIAUgAigAADYC4AEMAQsgAiAFKALsASIGRg0AIAUgAyACIAZrIANBA3YiAyACIANrIAZJGyIDQQN0azYC5AEgBSACIANrIgI2AugBIAUgAigAADYC4AELIAUoAswCIgwgBGoiCiAIKAKA7AEiAk0EQCAKQSBrIQIgBSAENgKoASAFIAk2AqwBIAUgDTYCsAECQAJAAkAgCiARSw0AIAcgBCAJaiIDaiACSw0AIANBIGogGiAHa00NAQsgBUFAayAFKAKwATYCACAFIAUpA6gBNwM4IAcgGiACIAVBOGogBUHMAmogESALIB8gFhAhIQMMAQsgBCAHaiEGIAwpAAAhOiAHIAwpAAg3AAggByA6NwAAAkAgBEERSQ0AIAwpABAhOiAHIAwpABg3ABggByA6NwAQIARBEGtBEUgNACAMQRBqIQIgB0EgaiEEA0AgAikAECE6IAQgAikAGDcACCAEIDo3AAAgAikAICE6IAQgAikAKDcAGCAEIDo3ABAgAkEgaiECIARBIGoiBCAGSQ0ACwsgBiANayECIAUgCjYCzAIgBiALayANSQRAIA0gBiAfa0sNDCAWIBYgAiALayIKaiIEIAlqTwRAIAlFDQIgBiAEIAn8CgAADAILQQAgCmsiAgRAIAYgBCAC/AoAAAsgBSAJIApqIgk2AqwBIAYgCmshBiALIQILIA1BEE8EQCACKQAAITogBiACKQAINwAIIAYgOjcAACAJQRFIDQEgBiAJaiEKIAZBEGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgCkkNAAsMAQsCQCANQQdNBEAgBiACLQAAOgAAIAYgAi0AAToAASAGIAItAAI6AAIgBiACLQADOgADIAYgAiANQQJ0IgRB4BpqKAIAaiICKAAANgAEIAIgBEGAG2ooAgBrIQIMAQsgBiACKQAANwAACyAJQQlJDQAgBiAJaiEKIAZBCGoiBCACQQhqIgJrQQ9MBEADQCAEIAIpAAA3AAAgAkEIaiECIARBCGoiBCAKSQ0ADAILAAsgAikAACE6IAQgAikACDcACCAEIDo3AAAgCUEZSA0AIAZBGGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgCkkNAAsLIANBiH9LDQwgDkEBayEOIAMgB2ohBwwBCwsgDkEATA0IIAIgDEcEQEG6fyEDIAIgDGsiAiAaIAdrSw0LIAcgDCACEB8gAiAHaiEHIAQgAmshBAsgBSAIQYjsAWoiAjYCzAIgCEEANgKE7AEgCEGI7AVqIREgBSAENgKoASAFIAk2AqwBIAUgDTYCsAECQAJAAkAgBEGAgARKDQAgByAEIAlqIgNqIBpBIGtLDQAgA0EgaiAaIAdrTQ0BCyAFIAUoArABNgIwIAUgBSkDqAE3AyggByAaIAVBKGogBUHMAmogESALIB8gFhAgIQMMAQsgAiAEaiEKIAQgB2ohBiACKQAAITogByACKQAINwAIIAcgOjcAAAJAIARBEUkNACAIKQCY7AEhOiAHIAhBoOwBaikAADcAGCAHIDo3ABAgBEEQa0ERSA0AIAhBmOwBaiECIAdBIGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgBkkNAAsLIAYgDWshAiAFIAo2AswCIAYgC2sgDUkEQCANIAYgH2tLDQogFiAWIAIgC2siCmoiBCAJak8EQCAJRQ0CIAYgBCAJ/AoAAAwCC0EAIAprIgIEQCAGIAQgAvwKAAALIAUgCSAKaiIJNgKsASAGIAprIQYgCyECCyANQRBPBEAgAikAACE6IAYgAikACDcACCAGIDo3AAAgCUERSA0BIAYgCWohCiAGQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIApJDQALDAELAkAgDUEHTQRAIAYgAi0AADoAACAGIAItAAE6AAEgBiACLQACOgACIAYgAi0AAzoAAyAGIAIgDUECdCIEQeAaaigCAGoiAigAADYABCACIARBgBtqKAIAayECDAELIAYgAikAADcAAAsgCUEJSQ0AIAYgCWohCiAGQQhqIgQgAkEIaiICa0EPTARAA0AgBCACKQAANwAAIAJBCGohAiAEQQhqIgQgCkkNAAwCCwALIAIpAAAhOiAEIAIpAAg3AAggBCA6NwAAIAlBGUgNACAGQRhqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIApJDQALCyADQYh/Sw0KIAMgB2ohByAOQQFrIgpFDQAgGkEgayESIDNFIRwDQCAFKAL4ASAFKAL0AUEDdGoiBC0AAiEJIAUoAogCIAUoAoQCQQN0aiIDLQACIQwgBSgCgAIgBSgC/AFBA3RqIgItAAMhJCADLQADIRUgBC0AAyEnIAIvAQAhHiADLwEAIRkgBC8BACEPIAIoAgQhBiAEKAIEIQQgAygCBCEOAkAgAi0AAiIYQQJPBEACQCAcIBhBGUlyRQRAIAUoAuABIiogBSgC5AEiAnRBBSAYa3ZBBXQgBmohBgJAIAIgGGpBBWsiAkEhTwRAIAVBsBo2AugBDAELIAUoAugBIg0gBSgC8AFPBEAgBSACQQdxIgM2AuQBIAUgDSACQQN2ayICNgLoASAFIAIoAAAiKjYC4AEgAyECDAELIA0gBSgC7AEiA0YNACAFIAIgDSADayACQQN2IgIgDSACayADSRsiA0EDdGsiAjYC5AEgBSANIANrIgM2AugBIAUgAygAACIqNgLgAQsgBSACQQVqIg02AuQBIAYgKiACdEEbdmohBgwBCyAFIAUoAuQBIgIgGGoiDTYC5AEgBSgC4AEgAnRBACAYa3YgBmohBiANQSFPBEAgBUGwGjYC6AEMAQsgBSgC6AEiGCAFKALwAU8EQCAFIA1BB3EiAjYC5AEgBSAYIA1BA3ZrIgM2AugBIAUgAygAADYC4AEgAiENDAELIBggBSgC7AEiA0YNACAFIA0gGCADayANQQN2IgIgGCACayADSRsiAkEDdGsiDTYC5AEgBSAYIAJrIgI2AugBIAUgAigAADYC4AELIAUpAowCITogBSAGNgKMAiAFIDo3ApACDAELIARFIQMgGEUEQCAbIARBAEdBAnRqKAIAIQIgBSAbIANBAnRqKAIAIgY2AowCIAUgAjYCkAIgBSgC5AEhDQwBCyAFIAUoAuQBIgJBAWoiDTYC5AECQAJAIAMgBmogBSgC4AEgAnRBH3ZqIgNBA0YEQCAFKAKMAkEBayICQX8gAhshBgwBCyAbIANBAnRqKAIAIgJBfyACGyEGIANBAUYNAQsgBSAFKAKQAjYClAILIAUgBSgCjAI2ApACIAUgBjYCjAILIAkgDGohAwJAIAxFBEAgDSECDAELIAUgDCANaiICNgLkASAFKALgASANdEEAIAxrdiAOaiEOCwJAIANBFEkNACACQSFPBEAgBUGwGjYC6AEMAQsgBSgC6AEiDCAFKALwAU8EQCAFIAJBB3EiAzYC5AEgBSAMIAJBA3ZrIgI2AugBIAUgAigAADYC4AEgAyECDAELIAwgBSgC7AEiA0YNACAFIAIgDCADayACQQN2IgIgDCACayADSRsiA0EDdGsiAjYC5AEgBSAMIANrIgM2AugBIAUgAygAADYC4AELAkAgCUUEQCACIQMMAQsgBSACIAlqIgM2AuQBIAUoAuABIAJ0QQAgCWt2IARqIQQLAkAgA0EhTwRAQbAaIQIgBUGwGjYC6AEMAQsgBSgC6AEiAiAFKALwAU8EQCAFIANBB3EiDDYC5AEgBSACIANBA3ZrIgI2AugBIAUgAigAADYC4AEgDCEDDAELIAIgBSgC7AEiCUYNACAFIAIgAiAJayADQQN2IgwgAiAMayAJSRsiDGsiAjYC6AEgBSADIAxBA3RrIgM2AuQBIAUgAigAADYC4AELAkAgCkEBRg0AIAUgJ0ECdEGwGWooAgAgBSgC4AEiCUEAIAMgJ2oiA2t2cSAPajYC9AEgBSAVQQJ0QbAZaigCACAJQQAgAyAVaiIDa3ZxIBlqNgKEAgJAIANBIU8EQEGwGiECIAVBsBo2AugBDAELIAUoAvABIAJNBEAgBSADQQdxIgw2AuQBIAUgAiADQQN2ayICNgLoASAFIAIoAAAiCTYC4AEgDCEDDAELIAIgBSgC7AEiD0YNACAFIAIgAiAPayADQQN2IgwgAiAMayAPSRsiDGsiAjYC6AEgBSADIAxBA3RrIgM2AuQBIAUgAigAACIJNgLgAQsgBSADICRqIgM2AuQBIAUgJEECdEGwGWooAgAgCUEAIANrdnEgHmo2AvwBIANBIU8EQCAFQbAaNgLoAQwBCyAFKALwASACTQRAIAUgA0EHcTYC5AEgBSACIANBA3ZrIgI2AugBIAUgAigAADYC4AEMAQsgAiAFKALsASIMRg0AIAUgAyACIAxrIANBA3YiAyACIANrIAxJGyIDQQN0azYC5AEgBSACIANrIgI2AugBIAUgAigAADYC4AELIAUgBDYCqAEgBSAONgKsASAFIAY2ArABAkACQAJAIAUoAswCIgIgBGoiDCARSw0AIAcgBCAOaiIDaiASSw0AIANBIGogGiAHa00NAQsgBSAFKAKwATYCICAFIAUpA6gBNwMYIAcgGiAFQRhqIAVBzAJqIBEgCyAfIBYQICEDDAELIAQgB2ohCSACKQAAITogByACKQAINwAIIAcgOjcAAAJAIARBEUkNACACKQAQITogByACKQAYNwAYIAcgOjcAECAEQRBrQRFIDQAgAkEQaiECIAdBIGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgCUkNAAsLIAkgBmshAiAFIAw2AswCIAkgC2sgBkkEQCAGIAkgH2tLDQsgFiAWIAIgC2siDGoiBCAOak8EQCAORQ0CIAkgBCAO/AoAAAwCC0EAIAxrIgIEQCAJIAQgAvwKAAALIAUgDCAOaiIONgKsASAJIAxrIQkgCyECCyAGQRBPBEAgAikAACE6IAkgAikACDcACCAJIDo3AAAgDkERSA0BIAkgDmohBiAJQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAZJDQALDAELAkAgBkEHTQRAIAkgAi0AADoAACAJIAItAAE6AAEgCSACLQACOgACIAkgAi0AAzoAAyAJIAIgBkECdCIEQeAaaigCAGoiAigAADYABCACIARBgBtqKAIAayECDAELIAkgAikAADcAAAsgDkEJSQ0AIAkgDmohBiAJQQhqIgQgAkEIaiICa0EPTARAA0AgBCACKQAANwAAIAJBCGohAiAEQQhqIgQgBkkNAAwCCwALIAIpAAAhOiAEIAIpAAg3AAggBCA6NwAAIA5BGUgNACAJQRhqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAZJDQALCyADQYh/Sw0LIAMgB2ohByAKQQFrIgoNAAsLIAUoAugBIAUoAuwBRw0HQWwhAyAFKALkAUEgRw0JQQAhAgNAIAJBA0cEQCArIAJBAnQiA2ogAyAbaigCADYCACACQQFqIQIMAQsLIAUoAswCIgMgCCgChOwBQQJHDQEaCyARIANrIgIgGiAHa0sNBUEAIQQgBwRAIAIEQCAHIAMgAvwKAAALIAIgB2ohBAsgCEEANgKE7AEgCEGI7AVqIREgBCEHIAhBiOwBagshAiARIAJrIgMgGiAHa0sNBCAHBH8gAwRAIAcgAiAD/AoAAAsgAyAHagVBAAsgE2shAwwHCyATIBRBACAUQQBKG2oMAQsgCCgC/OsBCyEWIAUgCCgC+OoBIgI2AswCIAIgCCgCiOsBaiEfAkAgDkUEQCATIQkMAQsgCCgCuOkBIRggCCgCtOkBISsgCCgCsOkBIQwgCEEBNgKM6gEgCEGs0AFqISQgBUGMAmohGkEAIQIDQCACQQNHBEAgGiACQQJ0IgNqIAMgJGooAgA2AgAgAkEBaiECDAELC0FsIQMgBUHgAWoiAiAEIAcQCEGIf0sNBSAFQfQBaiACIAgoAgAQHiAFQfwBaiACIAgoAggQHiAFQYQCaiACIAgoAgQQHiAWQSBrIRwgM0UhHiATIQkDQCAOBEAgBSgC+AEgBSgC9AFBA3RqIgItAAIhGyAFKAKIAiAFKAKEAkEDdGoiBC0AAiENIAUoAoACIAUoAvwBQQN0aiIGLQADIRUgBC0AAyEnIAItAAMhEiAGLwEAIRkgBC8BACERIAIvAQAhDyAGKAIEIQcgAigCBCECIAQoAgQhBAJAIAYtAAIiKEECTwRAAkAgHiAoQRlJckUEQCAFKALgASIhIAUoAuQBIgZ0QQUgKGt2QQV0IAdqIQcCQCAGIChqQQVrIgZBIU8EQCAFQbAaNgLoAQwBCyAFKALoASIKIAUoAvABTwRAIAUgBkEHcSILNgLkASAFIAogBkEDdmsiBjYC6AEgBSAGKAAAIiE2AuABIAshBgwBCyAKIAUoAuwBIgtGDQAgBSAGIAogC2sgBkEDdiIGIAogBmsgC0kbIgtBA3RrIgY2AuQBIAUgCiALayILNgLoASAFIAsoAAAiITYC4AELIAUgBkEFaiIKNgLkASAHICEgBnRBG3ZqIRAMAQsgBSAFKALkASIGIChqIgo2AuQBIAUoAuABIAZ0QQAgKGt2IAdqIRAgCkEhTwRAIAVBsBo2AugBDAELIAUoAugBIgcgBSgC8AFPBEAgBSAKQQdxIgY2AuQBIAUgByAKQQN2ayILNgLoASAFIAsoAAA2AuABIAYhCgwBCyAHIAUoAuwBIgtGDQAgBSAKIAcgC2sgCkEDdiIGIAcgBmsgC0kbIgZBA3RrIgo2AuQBIAUgByAGayIGNgLoASAFIAYoAAA2AuABCyAFKQKMAiE6IAUgEDYCjAIgBSA6NwKQAgwBCyACRSELIChFBEAgGiACQQBHQQJ0aigCACEGIAUgGiALQQJ0aigCACIQNgKMAiAFIAY2ApACIAUoAuQBIQoMAQsgBSAFKALkASIGQQFqIgo2AuQBAkACQCAHIAtqIAUoAuABIAZ0QR92aiILQQNGBEAgBSgCjAJBAWsiBkF/IAYbIRAMAQsgGiALQQJ0aigCACIGQX8gBhshECALQQFGDQELIAUgBSgCkAI2ApQCCyAFIAUoAowCNgKQAiAFIBA2AowCCyANIBtqIQsCQCANRQRAIAohBgwBCyAFIAogDWoiBjYC5AEgBSgC4AEgCnRBACANa3YgBGohBAsCQCALQRRJDQAgBkEhTwRAIAVBsBo2AugBDAELIAUoAugBIgcgBSgC8AFPBEAgBSAGQQdxIgs2AuQBIAUgByAGQQN2ayIGNgLoASAFIAYoAAA2AuABIAshBgwBCyAHIAUoAuwBIgtGDQAgBSAGIAcgC2sgBkEDdiIGIAcgBmsgC0kbIgtBA3RrIgY2AuQBIAUgByALayILNgLoASAFIAsoAAA2AuABCwJAIBtFBEAgBiEHDAELIAUgBiAbaiIHNgLkASAFKALgASAGdEEAIBtrdiACaiECCwJAIAdBIU8EQEGwGiEGIAVBsBo2AugBDAELIAUoAugBIgYgBSgC8AFPBEAgBSAHQQdxIgs2AuQBIAUgBiAHQQN2ayIGNgLoASAFIAYoAAA2AuABIAshBwwBCyAGIAUoAuwBIgpGDQAgBSAGIAYgCmsgB0EDdiILIAYgC2sgCkkbIgtrIgY2AugBIAUgByALQQN0ayIHNgLkASAFIAYoAAA2AuABCwJAIA5BAUYNACAFIBJBAnRBsBlqKAIAIAUoAuABIg1BACAHIBJqIgtrdnEgD2o2AvQBIAUgJ0ECdEGwGWooAgAgDUEAIAsgJ2oiB2t2cSARajYChAICQCAHQSFPBEBBsBohBiAFQbAaNgLoAQwBCyAFKALwASAGTQRAIAUgB0EHcSILNgLkASAFIAYgB0EDdmsiBjYC6AEgBSAGKAAAIg02AuABIAshBwwBCyAGIAUoAuwBIgpGDQAgBSAGIAYgCmsgB0EDdiILIAYgC2sgCkkbIgtrIgY2AugBIAUgByALQQN0ayIHNgLkASAFIAYoAAAiDTYC4AELIAUgByAVaiILNgLkASAFIBVBAnRBsBlqKAIAIA1BACALa3ZxIBlqNgL8ASALQSFPBEAgBUGwGjYC6AEMAQsgBSgC8AEgBk0EQCAFIAtBB3E2AuQBIAUgBiALQQN2ayIGNgLoASAFIAYoAAA2AuABDAELIAYgBSgC7AEiB0YNACAFIAsgBiAHayALQQN2IgsgBiALayAHSRsiC0EDdGs2AuQBIAUgBiALayIGNgLoASAFIAYoAAA2AuABCyAFIAI2AqgBIAUgBDYCrAEgBSAQNgKwAQJAAkACQCAFKALMAiIGIAJqIgsgH0sNACAJIAIgBGoiDWogHEsNACANQSBqIBYgCWtNDQELIAUgBSgCsAE2AhAgBSAFKQOoATcDCCAJIBYgBUEIaiAFQcwCaiAfIAwgKyAYECAhDQwBCyACIAlqIQcgBikAACE6IAkgBikACDcACCAJIDo3AAACQCACQRFJDQAgBikAECE6IAkgBikAGDcAGCAJIDo3ABAgAkEQa0ERSA0AIAZBEGohBiAJQSBqIQIDQCAGKQAQITogAiAGKQAYNwAIIAIgOjcAACAGKQAgITogAiAGKQAoNwAYIAIgOjcAECAGQSBqIQYgAkEgaiICIAdJDQALCyAHIBBrIQYgBSALNgLMAiAHIAxrIBBJBEAgECAHICtrSw0JIBggGCAGIAxrIgtqIgYgBGpPBEAgBEUNAiAHIAYgBPwKAAAMAgtBACALayICBEAgByAGIAL8CgAACyAFIAQgC2oiBDYCrAEgByALayEHIAwhBgsgEEEQTwRAIAYpAAAhOiAHIAYpAAg3AAggByA6NwAAIARBEUgNASAEIAdqIQQgB0EQaiECA0AgBikAECE6IAIgBikAGDcACCACIDo3AAAgBikAICE6IAIgBikAKDcAGCACIDo3ABAgBkEgaiEGIAJBIGoiAiAESQ0ACwwBCwJAIBBBB00EQCAHIAYtAAA6AAAgByAGLQABOgABIAcgBi0AAjoAAiAHIAYtAAM6AAMgByAGIBBBAnQiC0HgGmooAgBqIgIoAAA2AAQgAiALQYAbaigCAGshBgwBCyAHIAYpAAA3AAALIARBCUkNACAEIAdqIQsgB0EIaiICIAZBCGoiBmtBD0wEQANAIAIgBikAADcAACAGQQhqIQYgAkEIaiICIAtJDQAMAgsACyAGKQAAITogAiAGKQAINwAIIAIgOjcAACAEQRlIDQAgB0EYaiECA0AgBikAECE6IAIgBikAGDcACCACIDo3AAAgBikAICE6IAIgBikAKDcAGCACIDo3ABAgBkEgaiEGIAJBIGoiAiALSQ0ACwsgDUGIf0sEQCANIQMMCAUgDkEBayEOIAkgDWohCQwCCwALCyAFKALoASAFKALsAUcNBSAFKALkAUEgRw0FQQAhBgNAIAZBA0cEQCAkIAZBAnQiAmogAiAaaigCADYCACAGQQFqIQYMAQsLIAUoAswCIQILQbp/IQMgHyACayIEIBYgCWtLDQQgCQR/IAQEQCAJIAIgBPwKAAALIAQgCWoFQQALIBNrIQMMBAsgAkECRgRAIBwgA2siAiAUIAlrSw0BIAkEfyACBEAgCSADIAL8CgAACyACIAlqBUEACyEJIAhBiOwFaiEcIAhBiOwBaiEDCyAcIANrIgIgFCAJa0sNACAJBH8gAgRAIAkgAyAC/AoAAAsgAiAJagVBAAsgE2shAwwDC0G6fyEDDAILQWwhAwwBC0G4fyEDCyAFQdACaiQAIAMhBAwECyAgIDUgE2tLDQkgE0UEQCAgDQIMBQsgICIERQ0FIBMgHSAE/AoAAAwFCyAxKAIMIgQgAiATa0sNCCATDQEgBEUNAwtBtn8hBAwJCyAERQ0AIBMgHS0AACAE/AsACyAEQYh/Sw0HDAELQQAhBAsCQCAIKAL06gFFIBNFcg0AIAggCCkDkOoBIAStfDcDkOoBIAgoAtjqASIGIARqQR9NBEAgBARAIAYgNGogEyAE/AoAAAsgCCAIKALY6gEgBGo2AtjqAQwBCyATIQMgBgRAQSAgBmsiAgRAIAYgNGogAyAC/AoAAAsgCCgC2OoBIQIgCEEANgLY6gEgCCAIKQOY6gEgCCkAuOoBQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+NwOY6gEgCCAIKQOg6gEgCCkAwOoBQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+NwOg6gEgCCAIKQOo6gEgCCkAyOoBQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+NwOo6gEgCCAIKQOw6gEgCCkA0OoBQs/W077Sx6vZQn58Qh+JQoeVr6+Ytt6bnn9+NwOw6gEgEyACa0EgaiEDCyAEIBNqIgYgA0Egak8EQCAGQSBrIQIgCCkDsOoBITsgCCkDqOoBITwgCCkDoOoBIT0gCCkDmOoBIToDQCAIIAMpAABCz9bTvtLHq9lCfiA6fEIfiUKHla+vmLbem55/fiI6NwOY6gEgCCADKQAIQs/W077Sx6vZQn4gPXxCH4lCh5Wvr5i23puef34iPTcDoOoBIAggAykAEELP1tO+0ser2UJ+IDx8Qh+JQoeVr6+Ytt6bnn9+Ijw3A6jqASAIIAMpABhCz9bTvtLHq9lCfiA7fEIfiUKHla+vmLbem55/fiI7NwOw6gEgA0EgaiIDIAJNDQALCyADIAZPDQAgBiADayICBEAgNCADIAL8CgAACyAIIAI2AtjqAQsgOCAgayEDIB0gIGohAiAEIBNqIRMgMSgCCEUNAAsgNikDACI6Qn9RIDogEyAsa6xRckUEQEFsIQYMBgsgCCgC4OkBBEBBaiEGIANBBEkNBiAIKALw6gFFBEAgAigAAAJ+IDcpAwAiPkIgWgRAIAgpA6DqASI7QgeJIAgpA5jqASI8QgGJfCAIKQOo6gEiPUIMiXwgCCkDsOoBIjpCEol8IDxCz9bTvtLHq9lCfkIfiUKHla+vmLbem55/foVCh5Wvr5i23puef35CnaO16oOxjYr6AH0gO0LP1tO+0ser2UJ+Qh+JQoeVr6+Ytt6bnn9+hUKHla+vmLbem55/fkKdo7Xqg7GNivoAfSA9Qs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9IDpCz9bTvtLHq9lCfkIfiUKHla+vmLbem55/foVCh5Wvr5i23puef35CnaO16oOxjYr6AH0MAQsgCCkDqOoBQsXP2bLx5brqJ3wLID58IDQgPqcQIqdHDQcLIANBBGshAyACQQRqIQILIBMgLGsiBEGJf08NBCABIARrIQEgBCAsaiEsQQEhOQwBCwsgAwRAQbh/IQYMBAsgLCAAayEGDAMLQbp/IQQMAQtBuH8hBAtBuH8gBCAEQXZGGyAEIDkbIQYLIAgoApDrAQ0AIAgoAoTrASECIAgoAoDrASEDIAgQFiAIKALA6wEgAyACEBUgCEEANgLA6wEgCCgCrOsBIgEEQAJAAkACQAJAIAEoAgAiAARAIANFDQIgAiAAIAMRAgAMAQsgA0UNAgsgAiABIAMRAgAMAgsgABACCyABEAILIAhBADYCrOsBCyADBEAgAiAIIAMRAgAMAQsgCBACCyAxQRBqJAAgBgsKACAABEAQJgALCwMAAAsLzRIKAEGICAsFAQAAAAEAQZgIC9sEAQAAAAEAAACWAAAA2AAAAH0BAAB3AAAAqgAAAM0AAAACAgAAcAAAALEAAADHAAAAGwIAAG4AAADFAAAAwgAAAIQCAABrAAAA3QAAAMAAAADfAgAAawAAAAABAAC9AAAAcQMAAGoAAABnAQAAvAAAAI8EAABtAAAARgIAALsAAAAiBgAAcgAAALACAAC7AAAAsAYAAHoAAAA5AwAAugAAAK0HAACIAAAA0AMAALkAAABTCAAAlgAAAJwEAAC6AAAAFggAAK8AAABhBQAAuQAAAMMGAADKAAAAhAUAALkAAACfBgAAygAAAAAAAAABAAAAAQAAAAUAAAANAAAAHQAAAD0AAAB9AAAA/QAAAP0BAAD9AwAA/QcAAP0PAAD9HwAA/T8AAP1/AAD9/wAA/f8BAP3/AwD9/wcA/f8PAP3/HwD9/z8A/f9/AP3//wD9//8B/f//A/3//wf9//8P/f//H/3//z/9//9/AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8DAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAACAAAAAhAAAAIgAAACMAAAAlAAAAJwAAACkAAAArAAAALwAAADMAAAA7AAAAQwAAAFMAAABjAAAAgwAAAAMBAAADAgAAAwQAAAMIAAADEAAAAyAAAANAAAADgAAAAwABAEGgDQsVAQEBAQICAwMEBAUHCAkKCwwNDg8QAEHEDQuLAQEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAASAAAAFAAAABYAAAAYAAAAHAAAACAAAAAoAAAAMAAAAEAAAACAAAAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAACAAAAAAAEAQeAOC6YEAQEBAQICAwMEBgcICQoLDA0ODxABAAAABAAAAAgAAAABAAEBBgAAAAAAAAQAAAAAEAAABAAAAAAgAAAFAQAAAAAAAAUDAAAAAAAABQQAAAAAAAAFBgAAAAAAAAUHAAAAAAAABQkAAAAAAAAFCgAAAAAAAAUMAAAAAAAABg4AAAAAAAEFEAAAAAAAAQUUAAAAAAABBRYAAAAAAAIFHAAAAAAAAwUgAAAAAAAEBTAAAAAgAAYFQAAAAAAABwWAAAAAAAAIBgABAAAAAAoGAAQAAAAADAYAEAAAIAAABAAAAAAAAAAEAQAAAAAAAAUCAAAAIAAABQQAAAAAAAAFBQAAACAAAAUHAAAAAAAABQgAAAAgAAAFCgAAAAAAAAULAAAAAAAABg0AAAAgAAEFEAAAAAAAAQUSAAAAIAABBRYAAAAAAAIFGAAAACAAAwUgAAAAAAADBSgAAAAAAAYEQAAAABAABgRAAAAAIAAHBYAAAAAAAAkGAAIAAAAACwYACAAAMAAABAAAAAAQAAAEAQAAACAAAAUCAAAAIAAABQMAAAAgAAAFBQAAACAAAAUGAAAAIAAABQgAAAAgAAAFCQAAACAAAAULAAAAIAAABQwAAAAAAAAGDwAAACAAAQUSAAAAIAABBRQAAAAgAAIFGAAAACAAAgUcAAAAIAADBSgAAAAgAAQFMAAAAAAAEAYAAAEAAAAPBgCAAAAAAA4GAEAAAAAADQYAIABBkBMLhwIBAAEBBQAAAAAAAAUAAAAAAAAGBD0AAAAAAAkF/QEAAAAADwX9fwAAAAAVBf3/HwAAAAMFBQAAAAAABwR9AAAAAAAMBf0PAAAAABIF/f8DAAAAFwX9/38AAAAFBR0AAAAAAAgE/QAAAAAADgX9PwAAAAAUBf3/DwAAAAIFAQAAABAABwR9AAAAAAALBf0HAAAAABEF/f8BAAAAFgX9/z8AAAAEBQ0AAAAQAAgE/QAAAAAADQX9HwAAAAATBf3/BwAAAAEFAQAAABAABgQ9AAAAAAAKBf0DAAAAABAF/f8AAAAAHAX9//8PAAAbBf3//wcAABoF/f//AwAAGQX9//8BAAAYBf3//wBBoBULhgQBAAEBBgAAAAAAAAYDAAAAAAAABAQAAAAgAAAFBQAAAAAAAAUGAAAAAAAABQgAAAAAAAAFCQAAAAAAAAULAAAAAAAABg0AAAAAAAAGEAAAAAAAAAYTAAAAAAAABhYAAAAAAAAGGQAAAAAAAAYcAAAAAAAABh8AAAAAAAAGIgAAAAAAAQYlAAAAAAABBikAAAAAAAIGLwAAAAAAAwY7AAAAAAAEBlMAAAAAAAcGgwAAAAAACQYDAgAAEAAABAQAAAAAAAAEBQAAACAAAAUGAAAAAAAABQcAAAAgAAAFCQAAAAAAAAUKAAAAAAAABgwAAAAAAAAGDwAAAAAAAAYSAAAAAAAABhUAAAAAAAAGGAAAAAAAAAYbAAAAAAAABh4AAAAAAAAGIQAAAAAAAQYjAAAAAAABBicAAAAAAAIGKwAAAAAAAwYzAAAAAAAEBkMAAAAAAAUGYwAAAAAACAYDAQAAIAAABAQAAAAwAAAEBAAAABAAAAQFAAAAIAAABQcAAAAgAAAFCAAAACAAAAUKAAAAIAAABQsAAAAAAAAGDgAAAAAAAAYRAAAAAAAABhQAAAAAAAAGFwAAAAAAAAYaAAAAAAAABh0AAAAAAAAGIAAAAAAAEAYDAAEAAAAPBgOAAAAAAA4GA0AAAAAADQYDIAAAAAAMBgMQAAAAAAsGAwgAAAAACgYDBABBtBkLfAEAAAADAAAABwAAAA8AAAAfAAAAPwAAAH8AAAD/AAAA/wEAAP8DAAD/BwAA/w8AAP8fAAD/PwAA/38AAP//AAD//wEA//8DAP//BwD//w8A//8fAP//PwD//38A////AP///wH///8D////B////w////8f////P////38AQcQaC1kBAAAAAgAAAAQAAAAAAAAAAgAAAAQAAAAIAAAAAAAAAAEAAAACAAAAAQAAAAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAHAAAACAAAAAkAAAAKAAAACwBBoBsLA6APAQ==';
|
|
13995
13446
|
|
|
13996
|
-
/**
|
|
13997
|
-
* @typedef {import('./basedecoder.js').BaseDecoderParameters & { LercParameters?: any }} LercDecoderParameters
|
|
13998
|
-
*/
|
|
13999
13447
|
const zstd$2 = new ZSTDDecoder$1();
|
|
14000
13448
|
class LercDecoder extends BaseDecoder {
|
|
14001
|
-
/**
|
|
14002
|
-
* @param {ArrayBufferLike} buffer
|
|
14003
|
-
* @returns {ArrayBufferLike}
|
|
14004
|
-
*/
|
|
14005
13449
|
decodeBlock(buffer) {
|
|
14006
|
-
const
|
|
14007
|
-
const addCompression = params.LercParameters?.[LercParameters.AddCompression];
|
|
14008
|
-
/** @type {ArrayBufferLike} */
|
|
14009
|
-
let decoded = buffer;
|
|
13450
|
+
const addCompression = this.parameters.LercParameters[LercParameters.AddCompression];
|
|
14010
13451
|
switch (addCompression) {
|
|
14011
13452
|
case LercAddCompression.None:
|
|
14012
13453
|
break;
|
|
14013
13454
|
case LercAddCompression.Deflate:
|
|
14014
|
-
|
|
13455
|
+
buffer = inflate_1(new Uint8Array(buffer)).buffer; // eslint-disable-line no-param-reassign, prefer-destructuring
|
|
14015
13456
|
break;
|
|
14016
13457
|
case LercAddCompression.Zstandard:
|
|
14017
|
-
|
|
13458
|
+
buffer = zstd$2.decode(new Uint8Array(buffer)).buffer; // eslint-disable-line no-param-reassign, prefer-destructuring
|
|
14018
13459
|
break;
|
|
14019
13460
|
default:
|
|
14020
13461
|
throw new Error(`Unsupported LERC additional compression method identifier: ${addCompression}`);
|
|
14021
13462
|
}
|
|
14022
|
-
const lercResult = Lerc.decode(
|
|
13463
|
+
const lercResult = Lerc.decode(buffer, { returnPixelInterleavedDims: this.parameters.planarConfiguration === 1 });
|
|
14023
13464
|
const lercData = lercResult.pixels[0];
|
|
14024
13465
|
return lercData.buffer;
|
|
14025
13466
|
}
|
|
@@ -14195,9 +13636,8 @@ const wasm = 'AGFzbQEAAAABpgEVYAF/AGADf39/AX9gA39/fwBgAX8Bf2AFf39/f38Bf2ACf38AYA
|
|
|
14195
13636
|
|
|
14196
13637
|
const zstd = new ZSTDDecoder();
|
|
14197
13638
|
class ZstdDecoder extends BaseDecoder {
|
|
14198
|
-
/** @param {ArrayBuffer} buffer */
|
|
14199
13639
|
decodeBlock(buffer) {
|
|
14200
|
-
return
|
|
13640
|
+
return zstd.decode(new Uint8Array(buffer)).buffer;
|
|
14201
13641
|
}
|
|
14202
13642
|
}
|
|
14203
13643
|
|
|
@@ -14214,9 +13654,6 @@ var zstd$1 = /*#__PURE__*/Object.freeze({
|
|
|
14214
13654
|
* formats like WebP when supported.
|
|
14215
13655
|
*/
|
|
14216
13656
|
class WebImageDecoder extends BaseDecoder {
|
|
14217
|
-
/**
|
|
14218
|
-
* @param {import('./basedecoder.js').BaseDecoderParameters} parameters
|
|
14219
|
-
*/
|
|
14220
13657
|
constructor(parameters) {
|
|
14221
13658
|
super(parameters);
|
|
14222
13659
|
if (typeof createImageBitmap === 'undefined') {
|
|
@@ -14226,7 +13663,6 @@ class WebImageDecoder extends BaseDecoder {
|
|
|
14226
13663
|
throw new Error('Cannot decode WebImage as neither `document` nor `OffscreenCanvas` is not available');
|
|
14227
13664
|
}
|
|
14228
13665
|
}
|
|
14229
|
-
/** @param {ArrayBuffer} buffer */
|
|
14230
13666
|
async decodeBlock(buffer) {
|
|
14231
13667
|
const blob = new Blob([buffer]);
|
|
14232
13668
|
const imageBitmap = await createImageBitmap(blob);
|