html2canvas-pro 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- package/dist/html2canvas-pro.cjs +1835 -1470
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +1835 -1470
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +1839 -1471
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +6 -5
- package/dist/types/core/cache-storage.d.ts +6 -2
- package/dist/types/core/constants.d.ts +11 -0
- package/dist/types/core/context.d.ts +9 -1
- package/dist/types/core/features.d.ts +9 -5
- package/dist/types/core/origin-checker.d.ts +7 -4
- package/dist/types/core/validator.d.ts +0 -2
- package/dist/types/css/grouped/background-styles.d.ts +4 -0
- package/dist/types/css/grouped/border-styles.d.ts +4 -0
- package/dist/types/css/grouped/font-styles.d.ts +4 -0
- package/dist/types/css/grouped/layout-styles.d.ts +4 -0
- package/dist/types/css/index.d.ts +4 -0
- package/dist/types/css/property-descriptor.d.ts +11 -3
- package/dist/types/css/property-descriptors/scale.d.ts +9 -0
- package/dist/types/css/property-descriptors/translate.d.ts +10 -0
- package/dist/types/css/syntax/tokenizer.d.ts +8 -0
- package/dist/types/css/types/color-utilities.d.ts +21 -0
- package/dist/types/css/types/functions/color-mix.d.ts +17 -0
- package/dist/types/dom/adopted-styles.d.ts +23 -0
- package/dist/types/dom/document-cloner.d.ts +12 -0
- package/dist/types/dom/dom-normalizer.d.ts +2 -0
- package/dist/types/dom/elements/li-element-container.d.ts +2 -2
- package/dist/types/dom/elements/ol-element-container.d.ts +2 -2
- package/dist/types/dom/elements/select-element-container.d.ts +2 -2
- package/dist/types/dom/elements/textarea-element-container.d.ts +2 -2
- package/dist/types/dom/iframe-mount.d.ts +17 -0
- package/dist/types/dom/node-parser.d.ts +2 -2
- package/dist/types/dom/replaced-elements/canvas-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/image-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/input-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/svg-element-container.d.ts +2 -2
- package/dist/types/dom/slot-cloner.d.ts +10 -0
- package/dist/types/options.d.ts +24 -0
- package/dist/types/render/canvas/border-image-renderer.d.ts +7 -0
- package/dist/types/render/canvas/canvas-renderer.d.ts +2 -3
- package/dist/types/render/canvas/filter-surface.d.ts +37 -11
- package/dist/types/render/canvas/gradient-rasterizer.d.ts +53 -0
- package/dist/types/render/canvas/mask-renderer.d.ts +5 -2
- package/dist/types/render/canvas/text-clip-renderer.d.ts +0 -1
- package/dist/types/render/canvas/text-renderer.d.ts +1 -0
- package/package.json +9 -31
- package/dist/types/render/font-metrics.d.ts +0 -11
- package/dist/types/render/renderer-interface.d.ts +0 -28
package/dist/html2canvas-pro.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.5.
|
|
2
|
+
* html2canvas-pro 2.5.2 <https://yorickshan.github.io/html2canvas-pro/>
|
|
3
3
|
* Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
|
|
4
4
|
* Released under MIT License
|
|
5
5
|
*/
|
|
@@ -15,6 +15,9 @@ Object.defineProperties(exports, {
|
|
|
15
15
|
* Eliminates the need for global static variables.
|
|
16
16
|
*/
|
|
17
17
|
var Html2CanvasConfig = class Html2CanvasConfig {
|
|
18
|
+
window;
|
|
19
|
+
cspNonce;
|
|
20
|
+
cache;
|
|
18
21
|
constructor(options = {}) {
|
|
19
22
|
const resolvedWindow = options.window || (typeof window !== "undefined" ? window : void 0);
|
|
20
23
|
if (!resolvedWindow) throw new Error("Window object is required but not available");
|
|
@@ -55,6 +58,7 @@ var Html2CanvasConfig = class Html2CanvasConfig {
|
|
|
55
58
|
* Validates and sanitizes user inputs for security and correctness.
|
|
56
59
|
*/
|
|
57
60
|
var Validator = class {
|
|
61
|
+
config;
|
|
58
62
|
constructor(config = {}) {
|
|
59
63
|
this.config = {
|
|
60
64
|
maxImageTimeout: 3e5,
|
|
@@ -122,8 +126,7 @@ var Validator = class {
|
|
|
122
126
|
}
|
|
123
127
|
return {
|
|
124
128
|
valid: true,
|
|
125
|
-
sanitized: url
|
|
126
|
-
requiresRuntimeCheck: true
|
|
129
|
+
sanitized: url
|
|
127
130
|
};
|
|
128
131
|
}
|
|
129
132
|
return {
|
|
@@ -428,10 +431,13 @@ function createDefaultValidator(config = {}) {
|
|
|
428
431
|
* ```
|
|
429
432
|
*/
|
|
430
433
|
var PerformanceMonitor = class {
|
|
434
|
+
context;
|
|
435
|
+
activeMetrics = /* @__PURE__ */ new Map();
|
|
436
|
+
completedMetrics = [];
|
|
437
|
+
enabled;
|
|
438
|
+
getTime;
|
|
431
439
|
constructor(context, enabled = true) {
|
|
432
440
|
this.context = context;
|
|
433
|
-
this.activeMetrics = /* @__PURE__ */ new Map();
|
|
434
|
-
this.completedMetrics = [];
|
|
435
441
|
this.enabled = enabled;
|
|
436
442
|
this.getTime = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
|
|
437
443
|
}
|
|
@@ -578,6 +584,10 @@ var PerformanceMonitor = class {
|
|
|
578
584
|
//#endregion
|
|
579
585
|
//#region src/css/layout/bounds.ts
|
|
580
586
|
var Bounds = class Bounds {
|
|
587
|
+
left;
|
|
588
|
+
top;
|
|
589
|
+
width;
|
|
590
|
+
height;
|
|
581
591
|
constructor(left, top, width, height) {
|
|
582
592
|
this.left = left;
|
|
583
593
|
this.top = top;
|
|
@@ -597,9 +607,7 @@ var Bounds = class Bounds {
|
|
|
597
607
|
if (!domRect && rects.length > 0) domRect = rects[0];
|
|
598
608
|
return domRect ? new Bounds(domRect.left + context.windowBounds.left, domRect.top + context.windowBounds.top, domRect.width, domRect.height) : Bounds.EMPTY;
|
|
599
609
|
}
|
|
600
|
-
static
|
|
601
|
-
this.EMPTY = new Bounds(0, 0, 0, 0);
|
|
602
|
-
}
|
|
610
|
+
static EMPTY = new Bounds(0, 0, 0, 0);
|
|
603
611
|
};
|
|
604
612
|
const parseBounds = (context, node) => {
|
|
605
613
|
return Bounds.fromClientRect(context, node.getBoundingClientRect());
|
|
@@ -611,522 +619,6 @@ const parseDocumentSize = (document) => {
|
|
|
611
619
|
return new Bounds(0, 0, Math.max(Math.max(body.scrollWidth, documentElement.scrollWidth), Math.max(body.offsetWidth, documentElement.offsetWidth), Math.max(body.clientWidth, documentElement.clientWidth)), Math.max(Math.max(body.scrollHeight, documentElement.scrollHeight), Math.max(body.offsetHeight, documentElement.offsetHeight), Math.max(body.clientHeight, documentElement.clientHeight)));
|
|
612
620
|
};
|
|
613
621
|
//#endregion
|
|
614
|
-
//#region node_modules/.pnpm/css-line-break@2.1.0/node_modules/css-line-break/dist/css-line-break.es5.js
|
|
615
|
-
var toCodePoints$1 = function(str) {
|
|
616
|
-
var codePoints = [];
|
|
617
|
-
var i = 0;
|
|
618
|
-
var length = str.length;
|
|
619
|
-
while (i < length) {
|
|
620
|
-
var value = str.charCodeAt(i++);
|
|
621
|
-
if (value >= 55296 && value <= 56319 && i < length) {
|
|
622
|
-
var extra = str.charCodeAt(i++);
|
|
623
|
-
if ((extra & 64512) === 56320) codePoints.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
|
624
|
-
else {
|
|
625
|
-
codePoints.push(value);
|
|
626
|
-
i--;
|
|
627
|
-
}
|
|
628
|
-
} else codePoints.push(value);
|
|
629
|
-
}
|
|
630
|
-
return codePoints;
|
|
631
|
-
};
|
|
632
|
-
var fromCodePoint$1 = function() {
|
|
633
|
-
var codePoints = [];
|
|
634
|
-
for (var _i = 0; _i < arguments.length; _i++) codePoints[_i] = arguments[_i];
|
|
635
|
-
if (String.fromCodePoint) return String.fromCodePoint.apply(String, codePoints);
|
|
636
|
-
var length = codePoints.length;
|
|
637
|
-
if (!length) return "";
|
|
638
|
-
var codeUnits = [];
|
|
639
|
-
var index = -1;
|
|
640
|
-
var result = "";
|
|
641
|
-
while (++index < length) {
|
|
642
|
-
var codePoint = codePoints[index];
|
|
643
|
-
if (codePoint <= 65535) codeUnits.push(codePoint);
|
|
644
|
-
else {
|
|
645
|
-
codePoint -= 65536;
|
|
646
|
-
codeUnits.push((codePoint >> 10) + 55296, codePoint % 1024 + 56320);
|
|
647
|
-
}
|
|
648
|
-
if (index + 1 === length || codeUnits.length > 16384) {
|
|
649
|
-
result += String.fromCharCode.apply(String, codeUnits);
|
|
650
|
-
codeUnits.length = 0;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
return result;
|
|
654
|
-
};
|
|
655
|
-
var chars$2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
656
|
-
var lookup$2 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
657
|
-
for (var i$2 = 0; i$2 < chars$2.length; i$2++) lookup$2[chars$2.charCodeAt(i$2)] = i$2;
|
|
658
|
-
var chars$1$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
659
|
-
var lookup$1$1 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
660
|
-
for (var i$1$1 = 0; i$1$1 < chars$1$1.length; i$1$1++) lookup$1$1[chars$1$1.charCodeAt(i$1$1)] = i$1$1;
|
|
661
|
-
var decode$1 = function(base64) {
|
|
662
|
-
var bufferLength = base64.length * .75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
|
|
663
|
-
if (base64[base64.length - 1] === "=") {
|
|
664
|
-
bufferLength--;
|
|
665
|
-
if (base64[base64.length - 2] === "=") bufferLength--;
|
|
666
|
-
}
|
|
667
|
-
var buffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.slice !== "undefined" ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
|
|
668
|
-
var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
|
|
669
|
-
for (i = 0; i < len; i += 4) {
|
|
670
|
-
encoded1 = lookup$1$1[base64.charCodeAt(i)];
|
|
671
|
-
encoded2 = lookup$1$1[base64.charCodeAt(i + 1)];
|
|
672
|
-
encoded3 = lookup$1$1[base64.charCodeAt(i + 2)];
|
|
673
|
-
encoded4 = lookup$1$1[base64.charCodeAt(i + 3)];
|
|
674
|
-
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
|
675
|
-
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
|
676
|
-
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
|
677
|
-
}
|
|
678
|
-
return buffer;
|
|
679
|
-
};
|
|
680
|
-
var polyUint16Array$1 = function(buffer) {
|
|
681
|
-
var length = buffer.length;
|
|
682
|
-
var bytes = [];
|
|
683
|
-
for (var i = 0; i < length; i += 2) bytes.push(buffer[i + 1] << 8 | buffer[i]);
|
|
684
|
-
return bytes;
|
|
685
|
-
};
|
|
686
|
-
var polyUint32Array$1 = function(buffer) {
|
|
687
|
-
var length = buffer.length;
|
|
688
|
-
var bytes = [];
|
|
689
|
-
for (var i = 0; i < length; i += 4) bytes.push(buffer[i + 3] << 24 | buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i]);
|
|
690
|
-
return bytes;
|
|
691
|
-
};
|
|
692
|
-
/** Shift size for getting the index-2 table offset. */
|
|
693
|
-
var UTRIE2_SHIFT_2$1 = 5;
|
|
694
|
-
/** Shift size for getting the index-1 table offset. */
|
|
695
|
-
var UTRIE2_SHIFT_1$1 = 11;
|
|
696
|
-
/**
|
|
697
|
-
* Shift size for shifting left the index array values.
|
|
698
|
-
* Increases possible data size with 16-bit index values at the cost
|
|
699
|
-
* of compactability.
|
|
700
|
-
* This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
|
|
701
|
-
*/
|
|
702
|
-
var UTRIE2_INDEX_SHIFT$1 = 2;
|
|
703
|
-
/**
|
|
704
|
-
* Difference between the two shift sizes,
|
|
705
|
-
* for getting an index-1 offset from an index-2 offset. 6=11-5
|
|
706
|
-
*/
|
|
707
|
-
var UTRIE2_SHIFT_1_2$1 = UTRIE2_SHIFT_1$1 - UTRIE2_SHIFT_2$1;
|
|
708
|
-
/**
|
|
709
|
-
* The part of the index-2 table for U+D800..U+DBFF stores values for
|
|
710
|
-
* lead surrogate code _units_ not code _points_.
|
|
711
|
-
* Values for lead surrogate code _points_ are indexed with this portion of the table.
|
|
712
|
-
* Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
|
|
713
|
-
*/
|
|
714
|
-
var UTRIE2_LSCP_INDEX_2_OFFSET$1 = 65536 >> UTRIE2_SHIFT_2$1;
|
|
715
|
-
/** Mask for getting the lower bits for the in-data-block offset. */
|
|
716
|
-
var UTRIE2_DATA_MASK$1 = (1 << UTRIE2_SHIFT_2$1) - 1;
|
|
717
|
-
/**
|
|
718
|
-
* The index-1 table, only used for supplementary code points, at offset 2112=0x840.
|
|
719
|
-
* Variable length, for code points up to highStart, where the last single-value range starts.
|
|
720
|
-
* Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
|
|
721
|
-
* (For 0x100000 supplementary code points U+10000..U+10ffff.)
|
|
722
|
-
*
|
|
723
|
-
* The part of the index-2 table for supplementary code points starts
|
|
724
|
-
* after this index-1 table.
|
|
725
|
-
*
|
|
726
|
-
* Both the index-1 table and the following part of the index-2 table
|
|
727
|
-
* are omitted completely if there is only BMP data.
|
|
728
|
-
*/
|
|
729
|
-
var UTRIE2_INDEX_1_OFFSET$1 = UTRIE2_LSCP_INDEX_2_OFFSET$1 + (1024 >> UTRIE2_SHIFT_2$1) + 32;
|
|
730
|
-
/**
|
|
731
|
-
* Number of index-1 entries for the BMP. 32=0x20
|
|
732
|
-
* This part of the index-1 table is omitted from the serialized form.
|
|
733
|
-
*/
|
|
734
|
-
var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 = 65536 >> UTRIE2_SHIFT_1$1;
|
|
735
|
-
/** Mask for getting the lower bits for the in-index-2-block offset. */
|
|
736
|
-
var UTRIE2_INDEX_2_MASK$1 = (1 << UTRIE2_SHIFT_1_2$1) - 1;
|
|
737
|
-
var slice16$1 = function(view, start, end) {
|
|
738
|
-
if (view.slice) return view.slice(start, end);
|
|
739
|
-
return new Uint16Array(Array.prototype.slice.call(view, start, end));
|
|
740
|
-
};
|
|
741
|
-
var slice32$1 = function(view, start, end) {
|
|
742
|
-
if (view.slice) return view.slice(start, end);
|
|
743
|
-
return new Uint32Array(Array.prototype.slice.call(view, start, end));
|
|
744
|
-
};
|
|
745
|
-
var createTrieFromBase64$1 = function(base64, _byteLength) {
|
|
746
|
-
var buffer = decode$1(base64);
|
|
747
|
-
var view32 = Array.isArray(buffer) ? polyUint32Array$1(buffer) : new Uint32Array(buffer);
|
|
748
|
-
var view16 = Array.isArray(buffer) ? polyUint16Array$1(buffer) : new Uint16Array(buffer);
|
|
749
|
-
var headerLength = 24;
|
|
750
|
-
var index = slice16$1(view16, headerLength / 2, view32[4] / 2);
|
|
751
|
-
var data = view32[5] === 2 ? slice16$1(view16, (headerLength + view32[4]) / 2) : slice32$1(view32, Math.ceil((headerLength + view32[4]) / 4));
|
|
752
|
-
return new Trie$1(view32[0], view32[1], view32[2], view32[3], index, data);
|
|
753
|
-
};
|
|
754
|
-
var Trie$1 = function() {
|
|
755
|
-
function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
|
|
756
|
-
this.initialValue = initialValue;
|
|
757
|
-
this.errorValue = errorValue;
|
|
758
|
-
this.highStart = highStart;
|
|
759
|
-
this.highValueIndex = highValueIndex;
|
|
760
|
-
this.index = index;
|
|
761
|
-
this.data = data;
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* Get the value for a code point as stored in the Trie.
|
|
765
|
-
*
|
|
766
|
-
* @param codePoint the code point
|
|
767
|
-
* @return the value
|
|
768
|
-
*/
|
|
769
|
-
Trie.prototype.get = function(codePoint) {
|
|
770
|
-
var ix;
|
|
771
|
-
if (codePoint >= 0) {
|
|
772
|
-
if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {
|
|
773
|
-
ix = this.index[codePoint >> UTRIE2_SHIFT_2$1];
|
|
774
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
775
|
-
return this.data[ix];
|
|
776
|
-
}
|
|
777
|
-
if (codePoint <= 65535) {
|
|
778
|
-
ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET$1 + (codePoint - 55296 >> UTRIE2_SHIFT_2$1)];
|
|
779
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
780
|
-
return this.data[ix];
|
|
781
|
-
}
|
|
782
|
-
if (codePoint < this.highStart) {
|
|
783
|
-
ix = UTRIE2_INDEX_1_OFFSET$1 - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 + (codePoint >> UTRIE2_SHIFT_1$1);
|
|
784
|
-
ix = this.index[ix];
|
|
785
|
-
ix += codePoint >> UTRIE2_SHIFT_2$1 & UTRIE2_INDEX_2_MASK$1;
|
|
786
|
-
ix = this.index[ix];
|
|
787
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
788
|
-
return this.data[ix];
|
|
789
|
-
}
|
|
790
|
-
if (codePoint <= 1114111) return this.data[this.highValueIndex];
|
|
791
|
-
}
|
|
792
|
-
return this.errorValue;
|
|
793
|
-
};
|
|
794
|
-
return Trie;
|
|
795
|
-
}();
|
|
796
|
-
var chars$3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
797
|
-
var lookup$3 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
798
|
-
for (var i$3 = 0; i$3 < chars$3.length; i$3++) lookup$3[chars$3.charCodeAt(i$3)] = i$3;
|
|
799
|
-
var base64$1 = "KwAAAAAAAAAACA4AUD0AADAgAAACAAAAAAAIABAAGABAAEgAUABYAGAAaABgAGgAYgBqAF8AZwBgAGgAcQB5AHUAfQCFAI0AlQCdAKIAqgCyALoAYABoAGAAaABgAGgAwgDKAGAAaADGAM4A0wDbAOEA6QDxAPkAAQEJAQ8BFwF1AH0AHAEkASwBNAE6AUIBQQFJAVEBWQFhAWgBcAF4ATAAgAGGAY4BlQGXAZ8BpwGvAbUBvQHFAc0B0wHbAeMB6wHxAfkBAQIJAvEBEQIZAiECKQIxAjgCQAJGAk4CVgJeAmQCbAJ0AnwCgQKJApECmQKgAqgCsAK4ArwCxAIwAMwC0wLbAjAA4wLrAvMC+AIAAwcDDwMwABcDHQMlAy0DNQN1AD0DQQNJA0kDSQNRA1EDVwNZA1kDdQB1AGEDdQBpA20DdQN1AHsDdQCBA4kDkQN1AHUAmQOhA3UAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AKYDrgN1AHUAtgO+A8YDzgPWAxcD3gPjA+sD8wN1AHUA+wMDBAkEdQANBBUEHQQlBCoEFwMyBDgEYABABBcDSARQBFgEYARoBDAAcAQzAXgEgASIBJAEdQCXBHUAnwSnBK4EtgS6BMIEyAR1AHUAdQB1AHUAdQCVANAEYABgAGAAYABgAGAAYABgANgEYADcBOQEYADsBPQE/AQEBQwFFAUcBSQFLAU0BWQEPAVEBUsFUwVbBWAAYgVgAGoFcgV6BYIFigWRBWAAmQWfBaYFYABgAGAAYABgAKoFYACxBbAFuQW6BcEFwQXHBcEFwQXPBdMF2wXjBeoF8gX6BQIGCgYSBhoGIgYqBjIGOgZgAD4GRgZMBmAAUwZaBmAAYABgAGAAYABgAGAAYABgAGAAYABgAGIGYABpBnAGYABgAGAAYABgAGAAYABgAGAAYAB4Bn8GhQZgAGAAYAB1AHcDFQSLBmAAYABgAJMGdQA9A3UAmwajBqsGqwaVALMGuwbDBjAAywbSBtIG1QbSBtIG0gbSBtIG0gbdBuMG6wbzBvsGAwcLBxMHAwcbByMHJwcsBywHMQcsB9IGOAdAB0gHTgfSBkgHVgfSBtIG0gbSBtIG0gbSBtIG0gbSBiwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdgAGAALAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdbB2MHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB2kH0gZwB64EdQB1AHUAdQB1AHUAdQB1AHUHfQdgAIUHjQd1AHUAlQedB2AAYAClB6sHYACzB7YHvgfGB3UAzgfWBzMB3gfmB1EB7gf1B/0HlQENAQUIDQh1ABUIHQglCBcDLQg1CD0IRQhNCEEDUwh1AHUAdQBbCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIcAh3CHoIMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIgggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAALAcsBywHLAcsBywHLAcsBywHLAcsB4oILAcsB44I0gaWCJ4Ipgh1AHUAqgiyCHUAdQB1AHUAdQB1AHUAdQB1AHUAtwh8AXUAvwh1AMUIyQjRCNkI4AjoCHUAdQB1AO4I9gj+CAYJDgkTCS0HGwkjCYIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiAAIAAAAFAAYABgAGIAXwBgAHEAdQBFAJUAogCyAKAAYABgAEIA4ABGANMA4QDxAMEBDwE1AFwBLAE6AQEBUQF4QkhCmEKoQrhCgAHIQsAB0MLAAcABwAHAAeDC6ABoAHDCwMMAAcABwAHAAdDDGMMAAcAB6MM4wwjDWMNow3jDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEjDqABWw6bDqABpg6gAaABoAHcDvwOPA+gAaABfA/8DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DpcPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB9cPKwkyCToJMAB1AHUAdQBCCUoJTQl1AFUJXAljCWcJawkwADAAMAAwAHMJdQB2CX4JdQCECYoJjgmWCXUAngkwAGAAYABxAHUApgn3A64JtAl1ALkJdQDACTAAMAAwADAAdQB1AHUAdQB1AHUAdQB1AHUAowYNBMUIMAAwADAAMADICcsJ0wnZCRUE4QkwAOkJ8An4CTAAMAB1AAAKvwh1AAgKDwoXCh8KdQAwACcKLgp1ADYKqAmICT4KRgowADAAdQB1AE4KMAB1AFYKdQBeCnUAZQowADAAMAAwADAAMAAwADAAMAAVBHUAbQowADAAdQC5CXUKMAAwAHwBxAijBogEMgF9CoQKiASMCpQKmgqIBKIKqgquCogEDQG2Cr4KxgrLCjAAMADTCtsKCgHjCusK8Qr5CgELMAAwADAAMAB1AIsECQsRC3UANAEZCzAAMAAwADAAMAB1ACELKQswAHUANAExCzkLdQBBC0kLMABRC1kLMAAwADAAMAAwADAAdQBhCzAAMAAwAGAAYABpC3ELdwt/CzAAMACHC4sLkwubC58Lpwt1AK4Ltgt1APsDMAAwADAAMAAwADAAMAAwAL4LwwvLC9IL1wvdCzAAMADlC+kL8Qv5C/8LSQswADAAMAAwADAAMAAwADAAMAAHDDAAMAAwADAAMAAODBYMHgx1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1ACYMMAAwADAAdQB1AHUALgx1AHUAdQB1AHUAdQA2DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AD4MdQBGDHUAdQB1AHUAdQB1AEkMdQB1AHUAdQB1AFAMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQBYDHUAdQB1AF8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA+wMVBGcMMAAwAHwBbwx1AHcMfwyHDI8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAYABgAJcMMAAwADAAdQB1AJ8MlQClDDAAMACtDCwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB7UMLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA0EMAC9DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAsBywHLAcsBywHLAcsBywHLQcwAMEMyAwsBywHLAcsBywHLAcsBywHLAcsBywHzAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1ANQM2QzhDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMABgAGAAYABgAGAAYABgAOkMYADxDGAA+AwADQYNYABhCWAAYAAODTAAMAAwADAAFg1gAGAAHg37AzAAMAAwADAAYABgACYNYAAsDTQNPA1gAEMNPg1LDWAAYABgAGAAYABgAGAAYABgAGAAUg1aDYsGVglhDV0NcQBnDW0NdQ15DWAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAlQCBDZUAiA2PDZcNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAnw2nDTAAMAAwADAAMAAwAHUArw23DTAAMAAwADAAMAAwADAAMAAwADAAMAB1AL8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQDHDTAAYABgAM8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA1w11ANwNMAAwAD0B5A0wADAAMAAwADAAMADsDfQN/A0EDgwOFA4wABsOMAAwADAAMAAwADAAMAAwANIG0gbSBtIG0gbSBtIG0gYjDigOwQUuDsEFMw7SBjoO0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGQg5KDlIOVg7SBtIGXg5lDm0OdQ7SBtIGfQ6EDooOjQ6UDtIGmg6hDtIG0gaoDqwO0ga0DrwO0gZgAGAAYADEDmAAYAAkBtIGzA5gANIOYADaDokO0gbSBt8O5w7SBu8O0gb1DvwO0gZgAGAAxA7SBtIG0gbSBtIGYABgAGAAYAAED2AAsAUMD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHJA8sBywHLAcsBywHLAccDywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywPLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAc0D9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHPA/SBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gYUD0QPlQCVAJUAMAAwADAAMACVAJUAlQCVAJUAlQCVAEwPMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA//8EAAQABAAEAAQABAAEAAQABAANAAMAAQABAAIABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQACgATABcAHgAbABoAHgAXABYAEgAeABsAGAAPABgAHABLAEsASwBLAEsASwBLAEsASwBLABgAGAAeAB4AHgATAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAGwASAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWAA0AEQAeAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAFAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJABYAGgAbABsAGwAeAB0AHQAeAE8AFwAeAA0AHgAeABoAGwBPAE8ADgBQAB0AHQAdAE8ATwAXAE8ATwBPABYAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwBWAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsABAAbABsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEAA0ADQBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABABQACsAKwArACsAKwArACsAKwAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUAAaABoAUABQAFAAUABQAEwAHgAbAFAAHgAEACsAKwAEAAQABAArAFAAUABQAFAAUABQACsAKwArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQACsAUABQACsAKwAEACsABAAEAAQABAAEACsAKwArACsABAAEACsAKwAEAAQABAArACsAKwAEACsAKwArACsAKwArACsAUABQAFAAUAArAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAAQABABQAFAAUAAEAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAArACsAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AGwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAKwArACsAKwArAAQABAAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAAQAUAArAFAAUABQAFAAUABQACsAKwArAFAAUABQACsAUABQAFAAUAArACsAKwBQAFAAKwBQACsAUABQACsAKwArAFAAUAArACsAKwBQAFAAUAArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAArACsAKwAEAAQABAArAAQABAAEAAQAKwArAFAAKwArACsAKwArACsABAArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAHgAeAB4AHgAeAB4AGwAeACsAKwArACsAKwAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAUABQAFAAKwArACsAKwArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwAOAFAAUABQAFAAUABQAFAAHgBQAAQABAAEAA4AUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAKwArAAQAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAKwArACsAKwArACsAUAArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAXABcAFwAXABcACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAXAArAFwAXABcAFwAXABcAFwAXABcAFwAKgBcAFwAKgAqACoAKgAqACoAKgAqACoAXAArACsAXABcAFwAXABcACsAXAArACoAKgAqACoAKgAqACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwBcAFwAXABcAFAADgAOAA4ADgAeAA4ADgAJAA4ADgANAAkAEwATABMAEwATAAkAHgATAB4AHgAeAAQABAAeAB4AHgAeAB4AHgBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAADQAEAB4ABAAeAAQAFgARABYAEQAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAAQABAAEAAQADQAEAAQAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAA0ADQAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeACsAHgAeAA4ADgANAA4AHgAeAB4AHgAeAAkACQArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgBcAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4AHgAeAB4AXABcAFwAXABcAFwAKgAqACoAKgBcAFwAXABcACoAKgAqAFwAKgAqACoAXABcACoAKgAqACoAKgAqACoAXABcAFwAKgAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwAKgBLAEsASwBLAEsASwBLAEsASwBLACoAKgAqACoAKgAqAFAAUABQAFAAUABQACsAUAArACsAKwArACsAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAKwBQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsABAAEAAQAHgANAB4AHgAeAB4AHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUAArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWABEAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAANAA0AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUAArAAQABAArACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAA0ADQAVAFwADQAeAA0AGwBcACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwAeAB4AEwATAA0ADQAOAB4AEwATAB4ABAAEAAQACQArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAHgArACsAKwATABMASwBLAEsASwBLAEsASwBLAEsASwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAXABcAFwAXABcACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXAArACsAKwAqACoAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsAHgAeAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKwArAAQASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACoAKgAqACoAKgAqACoAXAAqACoAKgAqACoAKgArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABABQAFAAUABQAFAAUABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgANAA0ADQANAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwAeAB4AHgAeAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArAA0ADQANAA0ADQBLAEsASwBLAEsASwBLAEsASwBLACsAKwArAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUAAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAAQAUABQAFAAUABQAFAABABQAFAABAAEAAQAUAArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQACsAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQACsAKwAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQACsAHgAeAB4AHgAeAB4AHgAOAB4AKwANAA0ADQANAA0ADQANAAkADQANAA0ACAAEAAsABAAEAA0ACQANAA0ADAAdAB0AHgAXABcAFgAXABcAFwAWABcAHQAdAB4AHgAUABQAFAANAAEAAQAEAAQABAAEAAQACQAaABoAGgAaABoAGgAaABoAHgAXABcAHQAVABUAHgAeAB4AHgAeAB4AGAAWABEAFQAVABUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ADQAeAA0ADQANAA0AHgANAA0ADQAHAB4AHgAeAB4AKwAEAAQABAAEAAQABAAEAAQABAAEAFAAUAArACsATwBQAFAAUABQAFAAHgAeAB4AFgARAE8AUABPAE8ATwBPAFAAUABQAFAAUAAeAB4AHgAWABEAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArABsAGwAbABsAGwAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGgAbABsAGwAbABoAGwAbABoAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAFAAGgAeAB0AHgBQAB4AGgAeAB4AHgAeAB4AHgAeAB4AHgBPAB4AUAAbAB4AHgBQAFAAUABQAFAAHgAeAB4AHQAdAB4AUAAeAFAAHgBQAB4AUABPAFAAUAAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgBQAFAAUABQAE8ATwBQAFAAUABQAFAATwBQAFAATwBQAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAUABQAFAATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABPAB4AHgArACsAKwArAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAdAB4AHgAeAB0AHQAeAB4AHQAeAB4AHgAdAB4AHQAbABsAHgAdAB4AHgAeAB4AHQAeAB4AHQAdAB0AHQAeAB4AHQAeAB0AHgAdAB0AHQAdAB0AHQAeAB0AHgAeAB4AHgAeAB0AHQAdAB0AHgAeAB4AHgAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB0AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAdAB0AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHQAdAB0AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHQAdAB4AHgAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AJQAlAB0AHQAlAB4AJQAlACUAIAAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAeAB0AJQAdAB0AHgAdAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAdAB0AHQAdACUAHgAlACUAJQAdACUAJQAdAB0AHQAlACUAHQAdACUAHQAdACUAJQAlAB4AHQAeAB4AHgAeAB0AHQAlAB0AHQAdAB0AHQAdACUAJQAlACUAJQAdACUAJQAgACUAHQAdACUAJQAlACUAJQAlACUAJQAeAB4AHgAlACUAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AFwAXABcAFwAXABcAHgATABMAJQAeAB4AHgAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARABYAEQAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANAA0AHgANAB4ADQANAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwAlACUAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACsAKwArACsAKwArACsAKwArACsAKwArAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBPAE8ATwBPAE8ATwBPAE8AJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeAAQAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUABQAAQAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAUABQAFAAUABQAAQABAAEACsABAAEACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAKwBQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAA0ADQANAA0ADQANAA0ADQAeACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAArACsAKwArAFAAUABQAFAAUAANAA0ADQANAA0ADQAUACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQANAA0ADQANAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAANACsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAB4AHgAeAB4AHgArACsAKwArACsAKwAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANAFAABAAEAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAEAAQABAAEAB4ABAAEAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsABAAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLAA0ADQArAB4ABABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUAAeAFAAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAAEAAQADgANAA0AEwATAB4AHgAeAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAFAAUABQAFAABAAEACsAKwAEAA0ADQAeAFAAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcAFwADQANAA0AKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQAKwAEAAQAKwArAAQABAAEAAQAUAAEAFAABAAEAA0ADQANACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABABQAA4AUAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANAFAADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAaABoAGgAaAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAJAAkACQAJAAkACQAJABYAEQArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AHgAeACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAARwBHABUARwAJACsAKwArACsAKwArACsAKwArACsAKwAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAKwArACsAKwArACsAKwArACsAKwArACsAKwBRAFEAUQBRACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAHgAEAAQADQAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAeAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQAHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAKwArAFAAKwArAFAAUAArACsAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAHgAeAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeACsAKwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4ABAAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAHgAeAA0ADQANAA0AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArAAQABAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwBQAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArABsAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAB4AHgAeAB4ABAAEAAQABAAEAAQABABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArABYAFgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAGgBQAFAAUAAaAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUAArACsAKwArACsAKwBQACsAKwArACsAUAArAFAAKwBQACsAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUAArAFAAKwBQACsAUAArAFAAUAArAFAAKwArAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAKwBQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeACUAJQAlAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAHgAlACUAJQAlACUAIAAgACAAJQAlACAAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACEAIQAhACEAIQAlACUAIAAgACUAJQAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAlACUAJQAlACAAIAAgACUAIAAgACAAJQAlACUAJQAlACUAJQAgACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAlAB4AJQAeACUAJQAlACUAJQAgACUAJQAlACUAHgAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACAAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABcAFwAXABUAFQAVAB4AHgAeAB4AJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAgACUAJQAgACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAIAAgACUAJQAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACAAIAAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACAAIAAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAA==";
|
|
800
|
-
var LETTER_NUMBER_MODIFIER = 50;
|
|
801
|
-
var BK = 1;
|
|
802
|
-
var CR$1 = 2;
|
|
803
|
-
var LF$1 = 3;
|
|
804
|
-
var CM = 4;
|
|
805
|
-
var NL = 5;
|
|
806
|
-
var WJ = 7;
|
|
807
|
-
var ZW = 8;
|
|
808
|
-
var GL = 9;
|
|
809
|
-
var SP = 10;
|
|
810
|
-
var ZWJ$1 = 11;
|
|
811
|
-
var B2 = 12;
|
|
812
|
-
var BA = 13;
|
|
813
|
-
var BB = 14;
|
|
814
|
-
var HY = 15;
|
|
815
|
-
var CB = 16;
|
|
816
|
-
var CL = 17;
|
|
817
|
-
var CP = 18;
|
|
818
|
-
var EX = 19;
|
|
819
|
-
var IN = 20;
|
|
820
|
-
var NS = 21;
|
|
821
|
-
var OP = 22;
|
|
822
|
-
var QU = 23;
|
|
823
|
-
var IS = 24;
|
|
824
|
-
var NU = 25;
|
|
825
|
-
var PO = 26;
|
|
826
|
-
var PR = 27;
|
|
827
|
-
var SY = 28;
|
|
828
|
-
var AI = 29;
|
|
829
|
-
var AL = 30;
|
|
830
|
-
var CJ = 31;
|
|
831
|
-
var EB = 32;
|
|
832
|
-
var EM = 33;
|
|
833
|
-
var H2 = 34;
|
|
834
|
-
var H3 = 35;
|
|
835
|
-
var HL = 36;
|
|
836
|
-
var ID = 37;
|
|
837
|
-
var JL = 38;
|
|
838
|
-
var JV = 39;
|
|
839
|
-
var JT = 40;
|
|
840
|
-
var RI$1 = 41;
|
|
841
|
-
var SA = 42;
|
|
842
|
-
var XX = 43;
|
|
843
|
-
var ea_OP = [9001, 65288];
|
|
844
|
-
var BREAK_MANDATORY = "!";
|
|
845
|
-
var BREAK_NOT_ALLOWED$1 = "×";
|
|
846
|
-
var BREAK_ALLOWED$1 = "÷";
|
|
847
|
-
var UnicodeTrie$1 = createTrieFromBase64$1(base64$1);
|
|
848
|
-
var ALPHABETICS = [AL, HL];
|
|
849
|
-
var HARD_LINE_BREAKS = [
|
|
850
|
-
BK,
|
|
851
|
-
CR$1,
|
|
852
|
-
LF$1,
|
|
853
|
-
NL
|
|
854
|
-
];
|
|
855
|
-
var SPACE$1 = [SP, ZW];
|
|
856
|
-
var PREFIX_POSTFIX = [PR, PO];
|
|
857
|
-
var LINE_BREAKS = HARD_LINE_BREAKS.concat(SPACE$1);
|
|
858
|
-
var KOREAN_SYLLABLE_BLOCK = [
|
|
859
|
-
JL,
|
|
860
|
-
JV,
|
|
861
|
-
JT,
|
|
862
|
-
H2,
|
|
863
|
-
H3
|
|
864
|
-
];
|
|
865
|
-
var HYPHEN = [HY, BA];
|
|
866
|
-
var codePointsToCharacterClasses = function(codePoints, lineBreak) {
|
|
867
|
-
if (lineBreak === void 0) lineBreak = "strict";
|
|
868
|
-
var types = [];
|
|
869
|
-
var indices = [];
|
|
870
|
-
var categories = [];
|
|
871
|
-
codePoints.forEach(function(codePoint, index) {
|
|
872
|
-
var classType = UnicodeTrie$1.get(codePoint);
|
|
873
|
-
if (classType > LETTER_NUMBER_MODIFIER) {
|
|
874
|
-
categories.push(true);
|
|
875
|
-
classType -= LETTER_NUMBER_MODIFIER;
|
|
876
|
-
} else categories.push(false);
|
|
877
|
-
if ([
|
|
878
|
-
"normal",
|
|
879
|
-
"auto",
|
|
880
|
-
"loose"
|
|
881
|
-
].indexOf(lineBreak) !== -1) {
|
|
882
|
-
if ([
|
|
883
|
-
8208,
|
|
884
|
-
8211,
|
|
885
|
-
12316,
|
|
886
|
-
12448
|
|
887
|
-
].indexOf(codePoint) !== -1) {
|
|
888
|
-
indices.push(index);
|
|
889
|
-
return types.push(CB);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
if (classType === CM || classType === ZWJ$1) {
|
|
893
|
-
if (index === 0) {
|
|
894
|
-
indices.push(index);
|
|
895
|
-
return types.push(AL);
|
|
896
|
-
}
|
|
897
|
-
var prev = types[index - 1];
|
|
898
|
-
if (LINE_BREAKS.indexOf(prev) === -1) {
|
|
899
|
-
indices.push(indices[index - 1]);
|
|
900
|
-
return types.push(prev);
|
|
901
|
-
}
|
|
902
|
-
indices.push(index);
|
|
903
|
-
return types.push(AL);
|
|
904
|
-
}
|
|
905
|
-
indices.push(index);
|
|
906
|
-
if (classType === CJ) return types.push(lineBreak === "strict" ? NS : ID);
|
|
907
|
-
if (classType === SA) return types.push(AL);
|
|
908
|
-
if (classType === AI) return types.push(AL);
|
|
909
|
-
if (classType === XX) {
|
|
910
|
-
if (codePoint >= 131072 && codePoint <= 196605 || codePoint >= 196608 && codePoint <= 262141) return types.push(ID);
|
|
911
|
-
else return types.push(AL);
|
|
912
|
-
}
|
|
913
|
-
types.push(classType);
|
|
914
|
-
});
|
|
915
|
-
return [
|
|
916
|
-
indices,
|
|
917
|
-
types,
|
|
918
|
-
categories
|
|
919
|
-
];
|
|
920
|
-
};
|
|
921
|
-
var isAdjacentWithSpaceIgnored = function(a, b, currentIndex, classTypes) {
|
|
922
|
-
var current = classTypes[currentIndex];
|
|
923
|
-
if (Array.isArray(a) ? a.indexOf(current) !== -1 : a === current) {
|
|
924
|
-
var i = currentIndex;
|
|
925
|
-
while (i <= classTypes.length) {
|
|
926
|
-
i++;
|
|
927
|
-
var next = classTypes[i];
|
|
928
|
-
if (next === b) return true;
|
|
929
|
-
if (next !== SP) break;
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
if (current === SP) {
|
|
933
|
-
var i = currentIndex;
|
|
934
|
-
while (i > 0) {
|
|
935
|
-
i--;
|
|
936
|
-
var prev = classTypes[i];
|
|
937
|
-
if (Array.isArray(a) ? a.indexOf(prev) !== -1 : a === prev) {
|
|
938
|
-
var n = currentIndex;
|
|
939
|
-
while (n <= classTypes.length) {
|
|
940
|
-
n++;
|
|
941
|
-
var next = classTypes[n];
|
|
942
|
-
if (next === b) return true;
|
|
943
|
-
if (next !== SP) break;
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
if (prev !== SP) break;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
return false;
|
|
950
|
-
};
|
|
951
|
-
var previousNonSpaceClassType = function(currentIndex, classTypes) {
|
|
952
|
-
var i = currentIndex;
|
|
953
|
-
while (i >= 0) {
|
|
954
|
-
var type = classTypes[i];
|
|
955
|
-
if (type === SP) i--;
|
|
956
|
-
else return type;
|
|
957
|
-
}
|
|
958
|
-
return 0;
|
|
959
|
-
};
|
|
960
|
-
var _lineBreakAtIndex = function(codePoints, classTypes, indicies, index, forbiddenBreaks) {
|
|
961
|
-
if (indicies[index] === 0) return BREAK_NOT_ALLOWED$1;
|
|
962
|
-
var currentIndex = index - 1;
|
|
963
|
-
if (Array.isArray(forbiddenBreaks) && forbiddenBreaks[currentIndex] === true) return BREAK_NOT_ALLOWED$1;
|
|
964
|
-
var beforeIndex = currentIndex - 1;
|
|
965
|
-
var afterIndex = currentIndex + 1;
|
|
966
|
-
var current = classTypes[currentIndex];
|
|
967
|
-
var before = beforeIndex >= 0 ? classTypes[beforeIndex] : 0;
|
|
968
|
-
var next = classTypes[afterIndex];
|
|
969
|
-
if (current === CR$1 && next === LF$1) return BREAK_NOT_ALLOWED$1;
|
|
970
|
-
if (HARD_LINE_BREAKS.indexOf(current) !== -1) return BREAK_MANDATORY;
|
|
971
|
-
if (HARD_LINE_BREAKS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
972
|
-
if (SPACE$1.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
973
|
-
if (previousNonSpaceClassType(currentIndex, classTypes) === ZW) return BREAK_ALLOWED$1;
|
|
974
|
-
if (UnicodeTrie$1.get(codePoints[currentIndex]) === ZWJ$1) return BREAK_NOT_ALLOWED$1;
|
|
975
|
-
if ((current === EB || current === EM) && UnicodeTrie$1.get(codePoints[afterIndex]) === ZWJ$1) return BREAK_NOT_ALLOWED$1;
|
|
976
|
-
if (current === WJ || next === WJ) return BREAK_NOT_ALLOWED$1;
|
|
977
|
-
if (current === GL) return BREAK_NOT_ALLOWED$1;
|
|
978
|
-
if ([
|
|
979
|
-
SP,
|
|
980
|
-
BA,
|
|
981
|
-
HY
|
|
982
|
-
].indexOf(current) === -1 && next === GL) return BREAK_NOT_ALLOWED$1;
|
|
983
|
-
if ([
|
|
984
|
-
CL,
|
|
985
|
-
CP,
|
|
986
|
-
EX,
|
|
987
|
-
IS,
|
|
988
|
-
SY
|
|
989
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
990
|
-
if (previousNonSpaceClassType(currentIndex, classTypes) === OP) return BREAK_NOT_ALLOWED$1;
|
|
991
|
-
if (isAdjacentWithSpaceIgnored(QU, OP, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
992
|
-
if (isAdjacentWithSpaceIgnored([CL, CP], NS, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
993
|
-
if (isAdjacentWithSpaceIgnored(B2, B2, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
994
|
-
if (current === SP) return BREAK_ALLOWED$1;
|
|
995
|
-
if (current === QU || next === QU) return BREAK_NOT_ALLOWED$1;
|
|
996
|
-
if (next === CB || current === CB) return BREAK_ALLOWED$1;
|
|
997
|
-
if ([
|
|
998
|
-
BA,
|
|
999
|
-
HY,
|
|
1000
|
-
NS
|
|
1001
|
-
].indexOf(next) !== -1 || current === BB) return BREAK_NOT_ALLOWED$1;
|
|
1002
|
-
if (before === HL && HYPHEN.indexOf(current) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1003
|
-
if (current === SY && next === HL) return BREAK_NOT_ALLOWED$1;
|
|
1004
|
-
if (next === IN) return BREAK_NOT_ALLOWED$1;
|
|
1005
|
-
if (ALPHABETICS.indexOf(next) !== -1 && current === NU || ALPHABETICS.indexOf(current) !== -1 && next === NU) return BREAK_NOT_ALLOWED$1;
|
|
1006
|
-
if (current === PR && [
|
|
1007
|
-
ID,
|
|
1008
|
-
EB,
|
|
1009
|
-
EM
|
|
1010
|
-
].indexOf(next) !== -1 || [
|
|
1011
|
-
ID,
|
|
1012
|
-
EB,
|
|
1013
|
-
EM
|
|
1014
|
-
].indexOf(current) !== -1 && next === PO) return BREAK_NOT_ALLOWED$1;
|
|
1015
|
-
if (ALPHABETICS.indexOf(current) !== -1 && PREFIX_POSTFIX.indexOf(next) !== -1 || PREFIX_POSTFIX.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1016
|
-
if ([PR, PO].indexOf(current) !== -1 && (next === NU || [OP, HY].indexOf(next) !== -1 && classTypes[afterIndex + 1] === NU) || [OP, HY].indexOf(current) !== -1 && next === NU || current === NU && [
|
|
1017
|
-
NU,
|
|
1018
|
-
SY,
|
|
1019
|
-
IS
|
|
1020
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1021
|
-
if ([
|
|
1022
|
-
NU,
|
|
1023
|
-
SY,
|
|
1024
|
-
IS,
|
|
1025
|
-
CL,
|
|
1026
|
-
CP
|
|
1027
|
-
].indexOf(next) !== -1) {
|
|
1028
|
-
var prevIndex = currentIndex;
|
|
1029
|
-
while (prevIndex >= 0) {
|
|
1030
|
-
var type = classTypes[prevIndex];
|
|
1031
|
-
if (type === NU) return BREAK_NOT_ALLOWED$1;
|
|
1032
|
-
else if ([SY, IS].indexOf(type) !== -1) prevIndex--;
|
|
1033
|
-
else break;
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
if ([PR, PO].indexOf(next) !== -1) {
|
|
1037
|
-
var prevIndex = [CL, CP].indexOf(current) !== -1 ? beforeIndex : currentIndex;
|
|
1038
|
-
while (prevIndex >= 0) {
|
|
1039
|
-
var type = classTypes[prevIndex];
|
|
1040
|
-
if (type === NU) return BREAK_NOT_ALLOWED$1;
|
|
1041
|
-
else if ([SY, IS].indexOf(type) !== -1) prevIndex--;
|
|
1042
|
-
else break;
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
if (JL === current && [
|
|
1046
|
-
JL,
|
|
1047
|
-
JV,
|
|
1048
|
-
H2,
|
|
1049
|
-
H3
|
|
1050
|
-
].indexOf(next) !== -1 || [JV, H2].indexOf(current) !== -1 && [JV, JT].indexOf(next) !== -1 || [JT, H3].indexOf(current) !== -1 && next === JT) return BREAK_NOT_ALLOWED$1;
|
|
1051
|
-
if (KOREAN_SYLLABLE_BLOCK.indexOf(current) !== -1 && [IN, PO].indexOf(next) !== -1 || KOREAN_SYLLABLE_BLOCK.indexOf(next) !== -1 && current === PR) return BREAK_NOT_ALLOWED$1;
|
|
1052
|
-
if (ALPHABETICS.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1053
|
-
if (current === IS && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1054
|
-
if (ALPHABETICS.concat(NU).indexOf(current) !== -1 && next === OP && ea_OP.indexOf(codePoints[afterIndex]) === -1 || ALPHABETICS.concat(NU).indexOf(next) !== -1 && current === CP) return BREAK_NOT_ALLOWED$1;
|
|
1055
|
-
if (current === RI$1 && next === RI$1) {
|
|
1056
|
-
var i = indicies[currentIndex];
|
|
1057
|
-
var count = 1;
|
|
1058
|
-
while (i > 0) {
|
|
1059
|
-
i--;
|
|
1060
|
-
if (classTypes[i] === RI$1) count++;
|
|
1061
|
-
else break;
|
|
1062
|
-
}
|
|
1063
|
-
if (count % 2 !== 0) return BREAK_NOT_ALLOWED$1;
|
|
1064
|
-
}
|
|
1065
|
-
if (current === EB && next === EM) return BREAK_NOT_ALLOWED$1;
|
|
1066
|
-
return BREAK_ALLOWED$1;
|
|
1067
|
-
};
|
|
1068
|
-
var cssFormattedClasses = function(codePoints, options) {
|
|
1069
|
-
if (!options) options = {
|
|
1070
|
-
lineBreak: "normal",
|
|
1071
|
-
wordBreak: "normal"
|
|
1072
|
-
};
|
|
1073
|
-
var _a = codePointsToCharacterClasses(codePoints, options.lineBreak), indicies = _a[0], classTypes = _a[1], isLetterNumber = _a[2];
|
|
1074
|
-
if (options.wordBreak === "break-all" || options.wordBreak === "break-word") classTypes = classTypes.map(function(type) {
|
|
1075
|
-
return [
|
|
1076
|
-
NU,
|
|
1077
|
-
AL,
|
|
1078
|
-
SA
|
|
1079
|
-
].indexOf(type) !== -1 ? ID : type;
|
|
1080
|
-
});
|
|
1081
|
-
var forbiddenBreakpoints = options.wordBreak === "keep-all" ? isLetterNumber.map(function(letterNumber, i) {
|
|
1082
|
-
return letterNumber && codePoints[i] >= 19968 && codePoints[i] <= 40959;
|
|
1083
|
-
}) : void 0;
|
|
1084
|
-
return [
|
|
1085
|
-
indicies,
|
|
1086
|
-
classTypes,
|
|
1087
|
-
forbiddenBreakpoints
|
|
1088
|
-
];
|
|
1089
|
-
};
|
|
1090
|
-
var Break = function() {
|
|
1091
|
-
function Break(codePoints, lineBreak, start, end) {
|
|
1092
|
-
this.codePoints = codePoints;
|
|
1093
|
-
this.required = lineBreak === BREAK_MANDATORY;
|
|
1094
|
-
this.start = start;
|
|
1095
|
-
this.end = end;
|
|
1096
|
-
}
|
|
1097
|
-
Break.prototype.slice = function() {
|
|
1098
|
-
return fromCodePoint$1.apply(void 0, this.codePoints.slice(this.start, this.end));
|
|
1099
|
-
};
|
|
1100
|
-
return Break;
|
|
1101
|
-
}();
|
|
1102
|
-
var LineBreaker = function(str, options) {
|
|
1103
|
-
var codePoints = toCodePoints$1(str);
|
|
1104
|
-
var _a = cssFormattedClasses(codePoints, options), indicies = _a[0], classTypes = _a[1], forbiddenBreakpoints = _a[2];
|
|
1105
|
-
var length = codePoints.length;
|
|
1106
|
-
var lastEnd = 0;
|
|
1107
|
-
var nextIndex = 0;
|
|
1108
|
-
return { next: function() {
|
|
1109
|
-
if (nextIndex >= length) return {
|
|
1110
|
-
done: true,
|
|
1111
|
-
value: null
|
|
1112
|
-
};
|
|
1113
|
-
var lineBreak = BREAK_NOT_ALLOWED$1;
|
|
1114
|
-
while (nextIndex < length && (lineBreak = _lineBreakAtIndex(codePoints, classTypes, indicies, ++nextIndex, forbiddenBreakpoints)) === BREAK_NOT_ALLOWED$1);
|
|
1115
|
-
if (lineBreak !== BREAK_NOT_ALLOWED$1 || nextIndex === length) {
|
|
1116
|
-
var value = new Break(codePoints, lineBreak, lastEnd, nextIndex);
|
|
1117
|
-
lastEnd = nextIndex;
|
|
1118
|
-
return {
|
|
1119
|
-
value,
|
|
1120
|
-
done: false
|
|
1121
|
-
};
|
|
1122
|
-
}
|
|
1123
|
-
return {
|
|
1124
|
-
done: true,
|
|
1125
|
-
value: null
|
|
1126
|
-
};
|
|
1127
|
-
} };
|
|
1128
|
-
};
|
|
1129
|
-
//#endregion
|
|
1130
622
|
//#region src/core/util.ts
|
|
1131
623
|
/**
|
|
1132
624
|
* Indexed access where the shape/arity is guaranteed by construction (the CSS
|
|
@@ -1182,7 +674,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1182
674
|
integers.push(at(codePoints, c));
|
|
1183
675
|
c++;
|
|
1184
676
|
}
|
|
1185
|
-
const int = integers.length ? parseInt(fromCodePoint
|
|
677
|
+
const int = integers.length ? parseInt(String.fromCodePoint(...integers), 10) : 0;
|
|
1186
678
|
if (codePoints[c] === 46) c++;
|
|
1187
679
|
const fraction = [];
|
|
1188
680
|
while (isDigit(codePoints[c] ?? NaN)) {
|
|
@@ -1190,7 +682,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1190
682
|
c++;
|
|
1191
683
|
}
|
|
1192
684
|
const fracd = fraction.length;
|
|
1193
|
-
const frac = fracd ? parseInt(fromCodePoint
|
|
685
|
+
const frac = fracd ? parseInt(String.fromCodePoint(...fraction), 10) : 0;
|
|
1194
686
|
if (codePoints[c] === 69 || codePoints[c] === 101) c++;
|
|
1195
687
|
let expsign = 1;
|
|
1196
688
|
if (codePoints[c] === 43 || codePoints[c] === 45) {
|
|
@@ -1202,7 +694,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1202
694
|
exponent.push(at(codePoints, c));
|
|
1203
695
|
c++;
|
|
1204
696
|
}
|
|
1205
|
-
const exp = exponent.length ? parseInt(fromCodePoint
|
|
697
|
+
const exp = exponent.length ? parseInt(String.fromCodePoint(...exponent), 10) : 0;
|
|
1206
698
|
return sign * (int + frac * Math.pow(10, -fracd)) * Math.pow(10, expsign * exp);
|
|
1207
699
|
};
|
|
1208
700
|
//#endregion
|
|
@@ -1231,12 +723,8 @@ const EOF_TOKEN = { type: 32 };
|
|
|
1231
723
|
//#endregion
|
|
1232
724
|
//#region src/css/syntax/tokenizer.ts
|
|
1233
725
|
var Tokenizer = class Tokenizer {
|
|
1234
|
-
static
|
|
1235
|
-
|
|
1236
|
-
}
|
|
1237
|
-
static {
|
|
1238
|
-
this.MAX_POOL_SIZE = 40;
|
|
1239
|
-
}
|
|
726
|
+
static _pool = [];
|
|
727
|
+
static MAX_POOL_SIZE = 40;
|
|
1240
728
|
static get() {
|
|
1241
729
|
return Tokenizer._pool.pop() || new Tokenizer();
|
|
1242
730
|
}
|
|
@@ -1246,14 +734,29 @@ var Tokenizer = class Tokenizer {
|
|
|
1246
734
|
Tokenizer._pool.push(tokenizer);
|
|
1247
735
|
}
|
|
1248
736
|
}
|
|
737
|
+
_value;
|
|
738
|
+
/**
|
|
739
|
+
* Read cursor into `_value`. Consumption advances the cursor instead of
|
|
740
|
+
* shifting the array — `Array.shift()` per code point makes tokenising a
|
|
741
|
+
* long value O(n²) (a 200 KB inline data-URI background alone would cost
|
|
742
|
+
* billions of operations, and background-image values are never parse-
|
|
743
|
+
* cached). `write()` compacts already-consumed prefix bytes.
|
|
744
|
+
*/
|
|
745
|
+
_cursor;
|
|
1249
746
|
constructor() {
|
|
1250
747
|
this._value = [];
|
|
748
|
+
this._cursor = 0;
|
|
1251
749
|
}
|
|
1252
750
|
_reset() {
|
|
1253
751
|
this._value = [];
|
|
752
|
+
this._cursor = 0;
|
|
1254
753
|
}
|
|
1255
754
|
write(chunk) {
|
|
1256
|
-
this.
|
|
755
|
+
if (this._cursor > 0) {
|
|
756
|
+
this._value = this._value.slice(this._cursor);
|
|
757
|
+
this._cursor = 0;
|
|
758
|
+
}
|
|
759
|
+
this._value = this._value.concat([...chunk].map((char) => char.codePointAt(0)));
|
|
1257
760
|
}
|
|
1258
761
|
read() {
|
|
1259
762
|
const tokens = [];
|
|
@@ -1421,19 +924,21 @@ var Tokenizer = class Tokenizer {
|
|
|
1421
924
|
}
|
|
1422
925
|
return {
|
|
1423
926
|
type: 6,
|
|
1424
|
-
value: fromCodePoint
|
|
927
|
+
value: String.fromCodePoint(codePoint)
|
|
1425
928
|
};
|
|
1426
929
|
}
|
|
1427
930
|
consumeCodePoint() {
|
|
1428
|
-
const value = this._value.
|
|
1429
|
-
|
|
931
|
+
const value = this._value[this._cursor];
|
|
932
|
+
if (value === void 0) return -1;
|
|
933
|
+
this._cursor++;
|
|
934
|
+
return value;
|
|
1430
935
|
}
|
|
1431
936
|
reconsumeCodePoint(codePoint) {
|
|
1432
|
-
this._value.
|
|
937
|
+
if (this._cursor > 0 && this._value[this._cursor - 1] === codePoint) this._cursor--;
|
|
938
|
+
else this._value.splice(this._cursor, 0, codePoint);
|
|
1433
939
|
}
|
|
1434
940
|
peekCodePoint(delta) {
|
|
1435
|
-
|
|
1436
|
-
const codePoint = this._value[delta];
|
|
941
|
+
const codePoint = this._value[this._cursor + delta];
|
|
1437
942
|
return codePoint !== void 0 ? codePoint : -1;
|
|
1438
943
|
}
|
|
1439
944
|
consumeUnicodeRangeToken() {
|
|
@@ -1451,10 +956,10 @@ var Tokenizer = class Tokenizer {
|
|
|
1451
956
|
}
|
|
1452
957
|
if (questionMarks) return {
|
|
1453
958
|
type: 30,
|
|
1454
|
-
start: parseInt(fromCodePoint
|
|
1455
|
-
end: parseInt(fromCodePoint
|
|
959
|
+
start: parseInt(String.fromCodePoint(...digits.map((digit) => digit === 63 ? 48 : digit)), 16),
|
|
960
|
+
end: parseInt(String.fromCodePoint(...digits.map((digit) => digit === 63 ? 70 : digit)), 16)
|
|
1456
961
|
};
|
|
1457
|
-
const start = parseInt(fromCodePoint
|
|
962
|
+
const start = parseInt(String.fromCodePoint(...digits), 16);
|
|
1458
963
|
if (codePoint === 45 && isHex(this.peekCodePoint(0))) {
|
|
1459
964
|
codePoint = this.consumeCodePoint();
|
|
1460
965
|
const endDigits = [];
|
|
@@ -1465,7 +970,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1465
970
|
return {
|
|
1466
971
|
type: 30,
|
|
1467
972
|
start,
|
|
1468
|
-
end: parseInt(fromCodePoint
|
|
973
|
+
end: parseInt(String.fromCodePoint(...endDigits), 16)
|
|
1469
974
|
};
|
|
1470
975
|
} else return {
|
|
1471
976
|
type: 30,
|
|
@@ -1517,7 +1022,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1517
1022
|
const codePoint = this.consumeCodePoint();
|
|
1518
1023
|
if (codePoint === -1 || codePoint === 41) return {
|
|
1519
1024
|
type: 22,
|
|
1520
|
-
value: fromCodePoint
|
|
1025
|
+
value: String.fromCodePoint(...value)
|
|
1521
1026
|
};
|
|
1522
1027
|
else if (isWhiteSpace(codePoint)) {
|
|
1523
1028
|
this.consumeWhiteSpace();
|
|
@@ -1525,7 +1030,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1525
1030
|
this.consumeCodePoint();
|
|
1526
1031
|
return {
|
|
1527
1032
|
type: 22,
|
|
1528
|
-
value: fromCodePoint
|
|
1033
|
+
value: String.fromCodePoint(...value)
|
|
1529
1034
|
};
|
|
1530
1035
|
}
|
|
1531
1036
|
this.consumeBadUrlRemnants();
|
|
@@ -1555,19 +1060,21 @@ var Tokenizer = class Tokenizer {
|
|
|
1555
1060
|
consumeStringSlice(count) {
|
|
1556
1061
|
const SLICE_STACK_SIZE = 5e4;
|
|
1557
1062
|
let value = "";
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1063
|
+
const end = this._cursor + count;
|
|
1064
|
+
let from = this._cursor;
|
|
1065
|
+
while (from < end) {
|
|
1066
|
+
const to = Math.min(end, from + SLICE_STACK_SIZE);
|
|
1067
|
+
value += String.fromCodePoint(...this._value.slice(from, to));
|
|
1068
|
+
from = to;
|
|
1069
|
+
}
|
|
1070
|
+
this._cursor = end + 1;
|
|
1564
1071
|
return value;
|
|
1565
1072
|
}
|
|
1566
1073
|
consumeStringToken(endingCodePoint) {
|
|
1567
1074
|
let value = "";
|
|
1568
1075
|
let i = 0;
|
|
1569
1076
|
do {
|
|
1570
|
-
const codePoint = this._value[i];
|
|
1077
|
+
const codePoint = this._value[this._cursor + i];
|
|
1571
1078
|
if (codePoint === -1 || codePoint === void 0 || codePoint === endingCodePoint) {
|
|
1572
1079
|
value += this.consumeStringSlice(i);
|
|
1573
1080
|
return {
|
|
@@ -1576,19 +1083,19 @@ var Tokenizer = class Tokenizer {
|
|
|
1576
1083
|
};
|
|
1577
1084
|
}
|
|
1578
1085
|
if (codePoint === 10) {
|
|
1579
|
-
this.
|
|
1086
|
+
this._cursor += i;
|
|
1580
1087
|
return BAD_STRING_TOKEN;
|
|
1581
1088
|
}
|
|
1582
1089
|
if (codePoint === 92) {
|
|
1583
|
-
const next = this._value[i + 1];
|
|
1090
|
+
const next = this._value[this._cursor + i + 1];
|
|
1584
1091
|
if (next !== -1 && next !== void 0) {
|
|
1585
1092
|
if (next === 10) {
|
|
1586
1093
|
value += this.consumeStringSlice(i);
|
|
1587
1094
|
i = -1;
|
|
1588
|
-
this.
|
|
1095
|
+
this._cursor++;
|
|
1589
1096
|
} else if (isValidEscape(codePoint, next)) {
|
|
1590
1097
|
value += this.consumeStringSlice(i);
|
|
1591
|
-
value += fromCodePoint
|
|
1098
|
+
value += String.fromCodePoint(this.consumeEscapedCodePoint());
|
|
1592
1099
|
i = -1;
|
|
1593
1100
|
}
|
|
1594
1101
|
}
|
|
@@ -1647,8 +1154,8 @@ var Tokenizer = class Tokenizer {
|
|
|
1647
1154
|
consumeEscapedCodePoint() {
|
|
1648
1155
|
const codePoint = this.consumeCodePoint();
|
|
1649
1156
|
if (isHex(codePoint)) {
|
|
1650
|
-
let hex = fromCodePoint
|
|
1651
|
-
while (isHex(this.peekCodePoint(0)) && hex.length < 6) hex += fromCodePoint
|
|
1157
|
+
let hex = String.fromCodePoint(codePoint);
|
|
1158
|
+
while (isHex(this.peekCodePoint(0)) && hex.length < 6) hex += String.fromCodePoint(this.consumeCodePoint());
|
|
1652
1159
|
if (isWhiteSpace(this.peekCodePoint(0))) this.consumeCodePoint();
|
|
1653
1160
|
const hexCodePoint = parseInt(hex, 16);
|
|
1654
1161
|
if (hexCodePoint === 0 || isSurrogateCodePoint(hexCodePoint) || hexCodePoint > 1114111) return REPLACEMENT_CHARACTER;
|
|
@@ -1661,8 +1168,8 @@ var Tokenizer = class Tokenizer {
|
|
|
1661
1168
|
let result = "";
|
|
1662
1169
|
while (true) {
|
|
1663
1170
|
const codePoint = this.consumeCodePoint();
|
|
1664
|
-
if (isNameCodePoint(codePoint)) result += fromCodePoint
|
|
1665
|
-
else if (isValidEscape(codePoint, this.peekCodePoint(0))) result += fromCodePoint
|
|
1171
|
+
if (isNameCodePoint(codePoint)) result += String.fromCodePoint(codePoint);
|
|
1172
|
+
else if (isValidEscape(codePoint, this.peekCodePoint(0))) result += String.fromCodePoint(this.consumeEscapedCodePoint());
|
|
1666
1173
|
else {
|
|
1667
1174
|
this.reconsumeCodePoint(codePoint);
|
|
1668
1175
|
return result;
|
|
@@ -1673,6 +1180,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1673
1180
|
//#endregion
|
|
1674
1181
|
//#region src/css/syntax/parser.ts
|
|
1675
1182
|
var Parser = class Parser {
|
|
1183
|
+
_tokens;
|
|
1676
1184
|
constructor(tokens) {
|
|
1677
1185
|
this._tokens = tokens;
|
|
1678
1186
|
}
|
|
@@ -2202,13 +1710,17 @@ const packXYZ = (args) => {
|
|
|
2202
1710
|
};
|
|
2203
1711
|
const packLab = (_context, args) => {
|
|
2204
1712
|
if (isRelativeTransform(args.filter(nonFunctionArgSeparator))) throw new Error("Relative color not supported for lab()");
|
|
2205
|
-
const [
|
|
1713
|
+
const [extractedL, a, b, alpha] = extractLabComponents(args), l = isPercentageLightness(args) ? extractedL * 100 : extractedL, rgb = srgbLinear2rgb(xyz2rgbLinear(lab2xyz([
|
|
2206
1714
|
l,
|
|
2207
1715
|
a,
|
|
2208
1716
|
b
|
|
2209
1717
|
])));
|
|
2210
1718
|
return pack(clamp(Math.round(rgb[0] * 255), 0, 255), clamp(Math.round(rgb[1] * 255), 0, 255), clamp(Math.round(rgb[2] * 255), 0, 255), alpha);
|
|
2211
1719
|
};
|
|
1720
|
+
const isPercentageLightness = (args) => {
|
|
1721
|
+
const t0 = args.filter(nonFunctionArgSeparator)[0];
|
|
1722
|
+
return t0 !== void 0 && t0.type === 16;
|
|
1723
|
+
};
|
|
2212
1724
|
const packOkLab = (_context, args) => {
|
|
2213
1725
|
if (isRelativeTransform(args.filter(nonFunctionArgSeparator))) throw new Error("Relative color not supported for oklab()");
|
|
2214
1726
|
const [l, a, b, alpha] = extractLabComponents(args), rgb = srgbLinear2rgb(xyz2rgbLinear(oklab2xyz([
|
|
@@ -2237,7 +1749,7 @@ const packLch = (_context, args) => {
|
|
|
2237
1749
|
return pack(clamp(Math.round(rgb[0] * 255), 0, 255), clamp(Math.round(rgb[1] * 255), 0, 255), clamp(Math.round(rgb[2] * 255), 0, 255), a);
|
|
2238
1750
|
};
|
|
2239
1751
|
const extractHslComponents = (context, args) => {
|
|
2240
|
-
const tokens = args.filter(nonFunctionArgSeparator), hue = tokens[0], saturation = tokens[1], lightness = tokens[2], alpha = tokens[3];
|
|
1752
|
+
const tokens = args.filter(nonFunctionArgSeparator), hue = tokens[0], saturation = tokens[1], lightness = tokens[2], slash = tokens[3], alpha = slash !== void 0 && slash.type === 6 && slash.value === "/" ? tokens[4] : tokens[3];
|
|
2241
1753
|
return [
|
|
2242
1754
|
hue ? (hue.type === 17 ? deg(hue.number) : angle.parse(context, hue)) / (Math.PI * 2) : 0,
|
|
2243
1755
|
saturation !== void 0 && isLengthPercentage(saturation) ? saturation.number / 100 : 0,
|
|
@@ -2252,7 +1764,7 @@ const packHSL = (context, args) => {
|
|
|
2252
1764
|
s,
|
|
2253
1765
|
l
|
|
2254
1766
|
]);
|
|
2255
|
-
return pack(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255,
|
|
1767
|
+
return pack(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255, a);
|
|
2256
1768
|
};
|
|
2257
1769
|
const extractLchComponents = (args) => {
|
|
2258
1770
|
const tokens = args.filter(nonFunctionArgSeparator), t0 = tokens[0], t1 = tokens[1], t2 = tokens[2], t4 = tokens[4];
|
|
@@ -2327,9 +1839,9 @@ const hue2rgb = (t1, t2, hue) => {
|
|
|
2327
1839
|
};
|
|
2328
1840
|
const hsl2rgb = ([h, s, l]) => {
|
|
2329
1841
|
if (s === 0) return [
|
|
2330
|
-
l
|
|
2331
|
-
l
|
|
2332
|
-
l
|
|
1842
|
+
l,
|
|
1843
|
+
l,
|
|
1844
|
+
l
|
|
2333
1845
|
];
|
|
2334
1846
|
const t2 = l <= .5 ? l * (s + 1) : l + s - l * s, t1 = l * 2 - t2;
|
|
2335
1847
|
return [
|
|
@@ -3079,6 +2591,393 @@ const convertRec2020 = (args) => {
|
|
|
3079
2591
|
]);
|
|
3080
2592
|
};
|
|
3081
2593
|
//#endregion
|
|
2594
|
+
//#region src/css/types/functions/color-mix.ts
|
|
2595
|
+
const HUE_DEG_INDEX = {
|
|
2596
|
+
lch: 2,
|
|
2597
|
+
oklch: 2,
|
|
2598
|
+
hsl: 0
|
|
2599
|
+
};
|
|
2600
|
+
const XYZ_FROM_LMS = [
|
|
2601
|
+
1.2268798758459243,
|
|
2602
|
+
-.5578149944602171,
|
|
2603
|
+
.2813910456659647,
|
|
2604
|
+
-.0405757452148008,
|
|
2605
|
+
1.112286803280317,
|
|
2606
|
+
-.0717110580655164,
|
|
2607
|
+
-.0763729366746601,
|
|
2608
|
+
-.4214933324022432,
|
|
2609
|
+
1.5869240198367816
|
|
2610
|
+
];
|
|
2611
|
+
const LMS_FROM_OKLAB = [
|
|
2612
|
+
1,
|
|
2613
|
+
.3963377773761749,
|
|
2614
|
+
.2158037573099136,
|
|
2615
|
+
1,
|
|
2616
|
+
-.1055613458156586,
|
|
2617
|
+
-.0638541728258133,
|
|
2618
|
+
1,
|
|
2619
|
+
-.0894841775298119,
|
|
2620
|
+
-1.2914855480194092
|
|
2621
|
+
];
|
|
2622
|
+
const matrix3Inverse = (m) => {
|
|
2623
|
+
const a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5], g = m[6], h = m[7], i = m[8];
|
|
2624
|
+
const det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
|
|
2625
|
+
return [
|
|
2626
|
+
(e * i - f * h) / det,
|
|
2627
|
+
(c * h - b * i) / det,
|
|
2628
|
+
(b * f - c * e) / det,
|
|
2629
|
+
(f * g - d * i) / det,
|
|
2630
|
+
(a * i - c * g) / det,
|
|
2631
|
+
(c * d - a * f) / det,
|
|
2632
|
+
(d * h - e * g) / det,
|
|
2633
|
+
(b * g - a * h) / det,
|
|
2634
|
+
(a * e - b * d) / det
|
|
2635
|
+
];
|
|
2636
|
+
};
|
|
2637
|
+
const XYZ_TO_LMS = matrix3Inverse(XYZ_FROM_LMS);
|
|
2638
|
+
const OKLAB_FROM_LMS = matrix3Inverse(LMS_FROM_OKLAB);
|
|
2639
|
+
const LAB_K = 24389 / 27;
|
|
2640
|
+
const LAB_E = 24 / 116;
|
|
2641
|
+
const LAB_E3 = LAB_E * LAB_E * LAB_E;
|
|
2642
|
+
const LAB_X_SCALE = .3457 / .3585;
|
|
2643
|
+
const LAB_Z_SCALE = .2958 / .3585;
|
|
2644
|
+
const unpackSrgb = (color) => [
|
|
2645
|
+
(255 & color >> 24) / 255,
|
|
2646
|
+
(255 & color >> 16) / 255,
|
|
2647
|
+
(255 & color >> 8) / 255
|
|
2648
|
+
];
|
|
2649
|
+
/** Inverse of color-utilities' lab2xyz: D65 XYZ → CIE Lab (0..100 scale). */
|
|
2650
|
+
const xyzD65ToLab = (xyz) => {
|
|
2651
|
+
const [x50, y50, z50] = d65toD50([
|
|
2652
|
+
xyz[0],
|
|
2653
|
+
xyz[1],
|
|
2654
|
+
xyz[2]
|
|
2655
|
+
]);
|
|
2656
|
+
const xi = x50 / LAB_X_SCALE;
|
|
2657
|
+
const yi = y50;
|
|
2658
|
+
const zi = z50 / LAB_Z_SCALE;
|
|
2659
|
+
const fx = xi > LAB_E3 ? Math.cbrt(xi) : (LAB_K * xi + 16) / 116;
|
|
2660
|
+
const fy = yi > LAB_E3 ? Math.cbrt(yi) : (LAB_K * yi + 16) / 116;
|
|
2661
|
+
const fz = zi > LAB_E3 ? Math.cbrt(zi) : (LAB_K * zi + 16) / 116;
|
|
2662
|
+
return [
|
|
2663
|
+
116 * fy - 16,
|
|
2664
|
+
500 * (fx - fy),
|
|
2665
|
+
200 * (fy - fz)
|
|
2666
|
+
];
|
|
2667
|
+
};
|
|
2668
|
+
/** D65 XYZ → OKLab via the inverted forward matrices. */
|
|
2669
|
+
const xyzD65ToOklab = (xyz) => {
|
|
2670
|
+
const lms = multiplyMatrices(XYZ_TO_LMS, xyz);
|
|
2671
|
+
const lmsCbrt = [
|
|
2672
|
+
Math.cbrt(lms[0]),
|
|
2673
|
+
Math.cbrt(lms[1]),
|
|
2674
|
+
Math.cbrt(lms[2])
|
|
2675
|
+
];
|
|
2676
|
+
return multiplyMatrices(OKLAB_FROM_LMS, lmsCbrt);
|
|
2677
|
+
};
|
|
2678
|
+
/** Lab/Oklab rectangular coordinates → polar LCH (hue in degrees). */
|
|
2679
|
+
const labToLch = (lab) => {
|
|
2680
|
+
const c = Math.hypot(lab[1], lab[2]);
|
|
2681
|
+
const h = Math.atan2(lab[2], lab[1]) * 180 / Math.PI;
|
|
2682
|
+
return [
|
|
2683
|
+
lab[0],
|
|
2684
|
+
c,
|
|
2685
|
+
(h + 360) % 360
|
|
2686
|
+
];
|
|
2687
|
+
};
|
|
2688
|
+
/** Gamma sRGB (0..1) → HSL with hue in turns (0..1), matching hsl2rgb input. */
|
|
2689
|
+
const rgbToHslTurns = (rgb) => {
|
|
2690
|
+
const r = rgb[0], g = rgb[1], b = rgb[2];
|
|
2691
|
+
const max = Math.max(r, g, b);
|
|
2692
|
+
const min = Math.min(r, g, b);
|
|
2693
|
+
const l = (max + min) / 2;
|
|
2694
|
+
if (max === min) return [
|
|
2695
|
+
0,
|
|
2696
|
+
0,
|
|
2697
|
+
l
|
|
2698
|
+
];
|
|
2699
|
+
const d = max - min;
|
|
2700
|
+
const s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
2701
|
+
let h;
|
|
2702
|
+
if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
2703
|
+
else if (max === g) h = ((b - r) / d + 2) / 6;
|
|
2704
|
+
else h = ((r - g) / d + 4) / 6;
|
|
2705
|
+
return [
|
|
2706
|
+
h,
|
|
2707
|
+
s,
|
|
2708
|
+
l
|
|
2709
|
+
];
|
|
2710
|
+
};
|
|
2711
|
+
/** Packed color → coordinates in the given space, alpha kept on a 0..1 scale. */
|
|
2712
|
+
const toCoords = (color, space) => {
|
|
2713
|
+
const a = (255 & color) / 255;
|
|
2714
|
+
const rgb = unpackSrgb(color);
|
|
2715
|
+
const linear = rgb2rgbLinear(rgb);
|
|
2716
|
+
const xyz = rgbLinear2xyz(linear);
|
|
2717
|
+
let coords;
|
|
2718
|
+
switch (space) {
|
|
2719
|
+
case "srgb":
|
|
2720
|
+
coords = rgb;
|
|
2721
|
+
break;
|
|
2722
|
+
case "srgb-linear":
|
|
2723
|
+
coords = linear;
|
|
2724
|
+
break;
|
|
2725
|
+
case "xyz":
|
|
2726
|
+
case "xyz-d65":
|
|
2727
|
+
coords = xyz;
|
|
2728
|
+
break;
|
|
2729
|
+
case "xyz-d50":
|
|
2730
|
+
coords = d65toD50(xyz);
|
|
2731
|
+
break;
|
|
2732
|
+
case "lab":
|
|
2733
|
+
coords = xyzD65ToLab(xyz);
|
|
2734
|
+
break;
|
|
2735
|
+
case "oklab":
|
|
2736
|
+
coords = xyzD65ToOklab(xyz);
|
|
2737
|
+
break;
|
|
2738
|
+
case "lch":
|
|
2739
|
+
coords = labToLch(xyzD65ToLab(xyz));
|
|
2740
|
+
break;
|
|
2741
|
+
case "oklch":
|
|
2742
|
+
coords = labToLch(xyzD65ToOklab(xyz));
|
|
2743
|
+
break;
|
|
2744
|
+
case "hsl": coords = [
|
|
2745
|
+
rgbToHslTurns(rgb)[0] * 360,
|
|
2746
|
+
rgbToHslTurns(rgb)[1],
|
|
2747
|
+
rgbToHslTurns(rgb)[2]
|
|
2748
|
+
];
|
|
2749
|
+
}
|
|
2750
|
+
return [
|
|
2751
|
+
coords[0],
|
|
2752
|
+
coords[1],
|
|
2753
|
+
coords[2],
|
|
2754
|
+
a
|
|
2755
|
+
];
|
|
2756
|
+
};
|
|
2757
|
+
/** Coordinates in the given space → packed color. */
|
|
2758
|
+
const fromCoords = (coords, space) => {
|
|
2759
|
+
const c0 = coords[0], c1 = coords[1], c2 = coords[2], a = coords[3];
|
|
2760
|
+
switch (space) {
|
|
2761
|
+
case "srgb": return packSrgb([
|
|
2762
|
+
c0,
|
|
2763
|
+
c1,
|
|
2764
|
+
c2,
|
|
2765
|
+
a
|
|
2766
|
+
]);
|
|
2767
|
+
case "srgb-linear": return packSrgbLinear([
|
|
2768
|
+
c0,
|
|
2769
|
+
c1,
|
|
2770
|
+
c2,
|
|
2771
|
+
a
|
|
2772
|
+
]);
|
|
2773
|
+
case "xyz":
|
|
2774
|
+
case "xyz-d65": return packXYZ([
|
|
2775
|
+
c0,
|
|
2776
|
+
c1,
|
|
2777
|
+
c2,
|
|
2778
|
+
a
|
|
2779
|
+
]);
|
|
2780
|
+
case "xyz-d50": return packXYZ([...d50toD65([
|
|
2781
|
+
c0,
|
|
2782
|
+
c1,
|
|
2783
|
+
c2
|
|
2784
|
+
]), a]);
|
|
2785
|
+
case "lab": return packViaXyz(lab2xyz([
|
|
2786
|
+
c0,
|
|
2787
|
+
c1,
|
|
2788
|
+
c2
|
|
2789
|
+
]), a);
|
|
2790
|
+
case "oklab": return packViaXyz(oklab2xyz([
|
|
2791
|
+
c0,
|
|
2792
|
+
c1,
|
|
2793
|
+
c2
|
|
2794
|
+
]), a);
|
|
2795
|
+
case "lch": return packViaXyz(lab2xyz(lch2lab([
|
|
2796
|
+
c0,
|
|
2797
|
+
c1,
|
|
2798
|
+
c2
|
|
2799
|
+
])), a);
|
|
2800
|
+
case "oklch": return packViaXyz(oklab2xyz(lch2lab([
|
|
2801
|
+
c0,
|
|
2802
|
+
c1,
|
|
2803
|
+
c2
|
|
2804
|
+
])), a);
|
|
2805
|
+
case "hsl": {
|
|
2806
|
+
const rgb = hsl2rgb([
|
|
2807
|
+
c0 / 360,
|
|
2808
|
+
c1,
|
|
2809
|
+
c2
|
|
2810
|
+
]);
|
|
2811
|
+
return packSrgb([
|
|
2812
|
+
rgb[0],
|
|
2813
|
+
rgb[1],
|
|
2814
|
+
rgb[2],
|
|
2815
|
+
a
|
|
2816
|
+
]);
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
const packViaXyz = (xyz, a) => {
|
|
2821
|
+
const rgb = srgbLinear2rgb(xyz2rgbLinear(xyz));
|
|
2822
|
+
return packSrgb([
|
|
2823
|
+
rgb[0],
|
|
2824
|
+
rgb[1],
|
|
2825
|
+
rgb[2],
|
|
2826
|
+
a
|
|
2827
|
+
]);
|
|
2828
|
+
};
|
|
2829
|
+
/**
|
|
2830
|
+
* Interpolate a hue angle in degrees per css-color-4 §12.4. `weight1` and
|
|
2831
|
+
* `weight2` are the (normalized) mix weights; the hue travels from h1 towards
|
|
2832
|
+
* h2 by the shared fraction. Exported for unit tests.
|
|
2833
|
+
*/
|
|
2834
|
+
const interpolateHue = (h1, h2, weight1, weight2, method = "shorter") => {
|
|
2835
|
+
const wSum = weight1 + weight2;
|
|
2836
|
+
if (wSum === 0) return h1;
|
|
2837
|
+
let d = ((h2 - h1) % 360 + 360) % 360;
|
|
2838
|
+
switch (method) {
|
|
2839
|
+
case "shorter":
|
|
2840
|
+
if (d > 180) d -= 360;
|
|
2841
|
+
break;
|
|
2842
|
+
case "longer":
|
|
2843
|
+
if (d < 180) d -= 360;
|
|
2844
|
+
break;
|
|
2845
|
+
case "increasing": break;
|
|
2846
|
+
case "decreasing": if (d > 0) d -= 360;
|
|
2847
|
+
}
|
|
2848
|
+
return h1 + d * (weight2 / wSum);
|
|
2849
|
+
};
|
|
2850
|
+
const parseMixComponent = (context, tokens) => {
|
|
2851
|
+
let colorToken;
|
|
2852
|
+
let percentage = null;
|
|
2853
|
+
for (const token of tokens) {
|
|
2854
|
+
if (token.type === 31 || token.type === 4) continue;
|
|
2855
|
+
if (token.type === 16) percentage = token.number;
|
|
2856
|
+
else if (isIdentToken(token) && token.value === "none") {
|
|
2857
|
+
if (percentage === null) percentage = 0;
|
|
2858
|
+
} else if (colorToken === void 0) colorToken = token;
|
|
2859
|
+
else throw new Error(`Unexpected token in color-mix() component`);
|
|
2860
|
+
}
|
|
2861
|
+
if (colorToken === void 0) throw new Error("color-mix() component is missing a color");
|
|
2862
|
+
const token = colorToken;
|
|
2863
|
+
return {
|
|
2864
|
+
color: color$1.parse(context, token),
|
|
2865
|
+
percentage
|
|
2866
|
+
};
|
|
2867
|
+
};
|
|
2868
|
+
const SUPPORTED_SPACES = [
|
|
2869
|
+
"srgb",
|
|
2870
|
+
"srgb-linear",
|
|
2871
|
+
"lab",
|
|
2872
|
+
"oklab",
|
|
2873
|
+
"lch",
|
|
2874
|
+
"oklch",
|
|
2875
|
+
"hsl",
|
|
2876
|
+
"xyz",
|
|
2877
|
+
"xyz-d50",
|
|
2878
|
+
"xyz-d65"
|
|
2879
|
+
];
|
|
2880
|
+
const mixCoords = (c1, c2, w1, w2, space, hueMethod) => {
|
|
2881
|
+
const hueIdx = HUE_DEG_INDEX[space];
|
|
2882
|
+
const p1 = [
|
|
2883
|
+
c1[0] * c1[3],
|
|
2884
|
+
c1[1] * c1[3],
|
|
2885
|
+
c1[2] * c1[3],
|
|
2886
|
+
c1[3]
|
|
2887
|
+
];
|
|
2888
|
+
const p2 = [
|
|
2889
|
+
c2[0] * c2[3],
|
|
2890
|
+
c2[1] * c2[3],
|
|
2891
|
+
c2[2] * c2[3],
|
|
2892
|
+
c2[3]
|
|
2893
|
+
];
|
|
2894
|
+
const alpha = w1 * p1[3] + w2 * p2[3];
|
|
2895
|
+
if (alpha <= 0) return [
|
|
2896
|
+
0,
|
|
2897
|
+
0,
|
|
2898
|
+
0,
|
|
2899
|
+
0
|
|
2900
|
+
];
|
|
2901
|
+
const out = [
|
|
2902
|
+
0,
|
|
2903
|
+
0,
|
|
2904
|
+
0,
|
|
2905
|
+
alpha
|
|
2906
|
+
];
|
|
2907
|
+
for (let i = 0; i < 3; i++) {
|
|
2908
|
+
if (i === hueIdx) continue;
|
|
2909
|
+
out[i] = (w1 * at(p1, i) + w2 * at(p2, i)) / alpha;
|
|
2910
|
+
}
|
|
2911
|
+
if (hueIdx !== void 0) {
|
|
2912
|
+
let h1 = at(c1, hueIdx);
|
|
2913
|
+
let h2 = at(c2, hueIdx);
|
|
2914
|
+
if (c1[1] === 0) h1 = h2;
|
|
2915
|
+
if (c2[1] === 0) h2 = h1;
|
|
2916
|
+
out[hueIdx] = interpolateHue(h1, h2, w1, w2, hueMethod);
|
|
2917
|
+
}
|
|
2918
|
+
return out;
|
|
2919
|
+
};
|
|
2920
|
+
const computeColorMix = (context, args) => {
|
|
2921
|
+
const groups = [[]];
|
|
2922
|
+
for (const token of args) if (token.type === 4) groups.push([]);
|
|
2923
|
+
else groups[groups.length - 1].push(token);
|
|
2924
|
+
const meaningful = groups.map((group) => group.filter((t) => t.type !== 31));
|
|
2925
|
+
if (meaningful.length !== 3) throw new Error("color-mix() requires exactly two color components");
|
|
2926
|
+
const header = meaningful[0];
|
|
2927
|
+
const inKeyword = header ? header[0] : void 0;
|
|
2928
|
+
const hasInKeyword = inKeyword !== void 0 && isIdentToken(inKeyword) && inKeyword.value === "in";
|
|
2929
|
+
if (!header || header.length < 2 || !hasInKeyword) throw new Error("color-mix() requires an interpolation space after `in`");
|
|
2930
|
+
const spaceIdent = header[1];
|
|
2931
|
+
if (!spaceIdent || !isIdentToken(spaceIdent)) throw new Error("color-mix() space must be an identifier");
|
|
2932
|
+
const space = spaceIdent.value;
|
|
2933
|
+
if (SUPPORTED_SPACES.indexOf(space) === -1) throw new Error(`Unsupported color-mix() interpolation space "${space}"`);
|
|
2934
|
+
let hueMethod = "shorter";
|
|
2935
|
+
const rest = header.slice(2);
|
|
2936
|
+
if (rest.length > 0) {
|
|
2937
|
+
const method = rest[0];
|
|
2938
|
+
const hueKeyword = rest[1];
|
|
2939
|
+
if (!method || !hueKeyword || !isIdentToken(method) || !isIdentToken(hueKeyword) || hueKeyword.value !== "hue") throw new Error("Unsupported color-mix() hue method syntax");
|
|
2940
|
+
if ([
|
|
2941
|
+
"shorter",
|
|
2942
|
+
"longer",
|
|
2943
|
+
"increasing",
|
|
2944
|
+
"decreasing"
|
|
2945
|
+
].indexOf(method.value) === -1) throw new Error(`Unsupported color-mix() hue method "${method.value}"`);
|
|
2946
|
+
hueMethod = method.value;
|
|
2947
|
+
}
|
|
2948
|
+
const group1 = meaningful[1];
|
|
2949
|
+
const group2 = meaningful[2];
|
|
2950
|
+
if (!group1 || !group2) throw new Error("color-mix() requires exactly two color components");
|
|
2951
|
+
const component1 = parseMixComponent(context, group1);
|
|
2952
|
+
const component2 = parseMixComponent(context, group2);
|
|
2953
|
+
let p1 = component1.percentage;
|
|
2954
|
+
let p2 = component2.percentage;
|
|
2955
|
+
if (p1 === null && p2 === null) {
|
|
2956
|
+
p1 = 50;
|
|
2957
|
+
p2 = 50;
|
|
2958
|
+
} else if (p1 === null) p1 = 100 - (p2 ?? 0);
|
|
2959
|
+
else if (p2 === null) p2 = 100 - p1;
|
|
2960
|
+
else {
|
|
2961
|
+
const sum = p1 + p2;
|
|
2962
|
+
if (sum > 0) {
|
|
2963
|
+
p1 = p1 / sum * 100;
|
|
2964
|
+
p2 = p2 / sum * 100;
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
const weight1 = (p1 ?? 0) / 100;
|
|
2968
|
+
const weight2 = (p2 ?? 0) / 100;
|
|
2969
|
+
const mixed = mixCoords(toCoords(component1.color, space), toCoords(component2.color, space), weight1, weight2, space, hueMethod);
|
|
2970
|
+
return fromCoords(mixed, space);
|
|
2971
|
+
};
|
|
2972
|
+
const colorMix = (context, args) => {
|
|
2973
|
+
try {
|
|
2974
|
+
return computeColorMix(context, args);
|
|
2975
|
+
} catch (e) {
|
|
2976
|
+
context.logger.warn(`Unsupported color-mix() value: ${e instanceof Error ? e.message : e}`);
|
|
2977
|
+
return 0;
|
|
2978
|
+
}
|
|
2979
|
+
};
|
|
2980
|
+
//#endregion
|
|
3082
2981
|
//#region src/css/types/color.ts
|
|
3083
2982
|
const color$1 = {
|
|
3084
2983
|
name: "color",
|
|
@@ -3328,7 +3227,8 @@ const SUPPORTED_COLOR_FUNCTIONS = {
|
|
|
3328
3227
|
oklch: packOkLch,
|
|
3329
3228
|
oklab: packOkLab,
|
|
3330
3229
|
lab: packLab,
|
|
3331
|
-
color: _color
|
|
3230
|
+
color: _color,
|
|
3231
|
+
"color-mix": colorMix
|
|
3332
3232
|
};
|
|
3333
3233
|
const parseColor = (context, value) => color$1.parse(context, Parser.create(value).parseComponentValue());
|
|
3334
3234
|
const COLORS = {
|
|
@@ -3611,9 +3511,7 @@ const contains = (bit, value) => (bit & value) !== 0;
|
|
|
3611
3511
|
//#endregion
|
|
3612
3512
|
//#region src/css/types/functions/counter.ts
|
|
3613
3513
|
var CounterState = class {
|
|
3614
|
-
|
|
3615
|
-
this.counters = {};
|
|
3616
|
-
}
|
|
3514
|
+
counters = {};
|
|
3617
3515
|
getCounterValue(name) {
|
|
3618
3516
|
const counter = this.counters[name];
|
|
3619
3517
|
if (counter && counter.length) return at(counter, counter.length - 1);
|
|
@@ -3940,7 +3838,7 @@ const createCounterStyleWithSymbolResolver = (value, codePointRangeLength, isNum
|
|
|
3940
3838
|
};
|
|
3941
3839
|
const createCounterStyleFromRange = (value, codePointRangeStart, codePointRangeEnd, isNumeric, suffix) => {
|
|
3942
3840
|
const codePointRangeLength = codePointRangeEnd - codePointRangeStart + 1;
|
|
3943
|
-
return (value < 0 ? "-" : "") + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, (codePoint) => fromCodePoint
|
|
3841
|
+
return (value < 0 ? "-" : "") + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, (codePoint) => String.fromCodePoint(Math.floor(codePoint % codePointRangeLength) + codePointRangeStart)) + suffix);
|
|
3944
3842
|
};
|
|
3945
3843
|
const createCounterStyleFromSymbols = (value, symbols, suffix = ". ") => {
|
|
3946
3844
|
const codePointRangeLength = symbols.length;
|
|
@@ -4525,7 +4423,7 @@ const ELLIPSE = "ellipse";
|
|
|
4525
4423
|
const COVER = "cover";
|
|
4526
4424
|
const CONTAIN = "contain";
|
|
4527
4425
|
const radialGradient = (context, tokens) => {
|
|
4528
|
-
let shape =
|
|
4426
|
+
let shape = 1;
|
|
4529
4427
|
let size = 3;
|
|
4530
4428
|
const stops = [];
|
|
4531
4429
|
const position = [];
|
|
@@ -4598,7 +4496,7 @@ const radialGradient = (context, tokens) => {
|
|
|
4598
4496
|
//#endregion
|
|
4599
4497
|
//#region src/css/types/functions/-prefix-radial-gradient.ts
|
|
4600
4498
|
const prefixRadialGradient = (context, tokens) => {
|
|
4601
|
-
let shape =
|
|
4499
|
+
let shape = 1;
|
|
4602
4500
|
let size = 3;
|
|
4603
4501
|
const stops = [];
|
|
4604
4502
|
const position = [];
|
|
@@ -5991,28 +5889,37 @@ const filter = {
|
|
|
5991
5889
|
if (first.type === 20 && first.value === "none") return null;
|
|
5992
5890
|
}
|
|
5993
5891
|
const parts = [];
|
|
5994
|
-
for (const token of tokens)
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
5892
|
+
for (const token of tokens) {
|
|
5893
|
+
if (token.type === 22) {
|
|
5894
|
+
parts.push(`url("${token.value}")`);
|
|
5895
|
+
continue;
|
|
5896
|
+
}
|
|
5897
|
+
if (token.type === 18) {
|
|
5898
|
+
const fn = token;
|
|
5899
|
+
const renderedArgs = renderFilterArgs(fn.values);
|
|
5900
|
+
switch (fn.name) {
|
|
5901
|
+
case "blur":
|
|
5902
|
+
parts.push(`blur(${renderedArgs})`);
|
|
5903
|
+
break;
|
|
5904
|
+
case "brightness":
|
|
5905
|
+
case "contrast":
|
|
5906
|
+
case "invert":
|
|
5907
|
+
case "opacity":
|
|
5908
|
+
case "saturate":
|
|
5909
|
+
case "sepia":
|
|
5910
|
+
parts.push(`${fn.name}(${renderedArgs})`);
|
|
5911
|
+
break;
|
|
5912
|
+
case "grayscale":
|
|
5913
|
+
parts.push(`grayscale(${renderedArgs})`);
|
|
5914
|
+
break;
|
|
5915
|
+
case "hue-rotate":
|
|
5916
|
+
parts.push(`hue-rotate(${renderedArgs})`);
|
|
5917
|
+
break;
|
|
5918
|
+
case "drop-shadow":
|
|
5919
|
+
parts.push(`drop-shadow(${renderedArgs})`);
|
|
5920
|
+
break;
|
|
5921
|
+
default: parts.push(`${fn.name}(${renderedArgs})`);
|
|
5922
|
+
}
|
|
6016
5923
|
}
|
|
6017
5924
|
}
|
|
6018
5925
|
return parts.length > 0 ? parts.join(" ") : null;
|
|
@@ -6581,8 +6488,47 @@ const webkitBoxReflect = {
|
|
|
6581
6488
|
};
|
|
6582
6489
|
}
|
|
6583
6490
|
};
|
|
6491
|
+
//#endregion
|
|
6492
|
+
//#region src/css/property-descriptors/translate.ts
|
|
6493
|
+
const translate = {
|
|
6494
|
+
name: "translate",
|
|
6495
|
+
initialValue: "none",
|
|
6496
|
+
prefix: false,
|
|
6497
|
+
type: 1,
|
|
6498
|
+
parse: (_context, tokens) => {
|
|
6499
|
+
const values = [];
|
|
6500
|
+
for (const token of tokens) if (isLengthPercentage(token)) values.push(token);
|
|
6501
|
+
if (values.length === 0) return null;
|
|
6502
|
+
return [at(values, 0), values.length > 1 ? at(values, 1) : ZERO_LENGTH];
|
|
6503
|
+
}
|
|
6504
|
+
};
|
|
6505
|
+
//#endregion
|
|
6506
|
+
//#region src/css/property-descriptors/scale.ts
|
|
6507
|
+
const scale = {
|
|
6508
|
+
name: "scale",
|
|
6509
|
+
initialValue: "none",
|
|
6510
|
+
prefix: false,
|
|
6511
|
+
type: 1,
|
|
6512
|
+
parse: (_context, tokens) => {
|
|
6513
|
+
const numbers = [];
|
|
6514
|
+
for (const token of tokens) if (isNumberToken(token)) numbers.push(token.number);
|
|
6515
|
+
if (numbers.length === 0) return null;
|
|
6516
|
+
return [at(numbers, 0), numbers.length > 1 ? at(numbers, 1) : at(numbers, 0)];
|
|
6517
|
+
}
|
|
6518
|
+
};
|
|
6584
6519
|
/** Z-axis mask offset used during box-shadow rendering. */
|
|
6585
6520
|
const SHADOW_MASK_OFFSET = 1e4;
|
|
6521
|
+
/**
|
|
6522
|
+
* Total time (ms) to wait for the cloned iframe document to become ready
|
|
6523
|
+
* after its load event. A missed deadline resolves with a warning (the
|
|
6524
|
+
* capture continues with a possibly incomplete document).
|
|
6525
|
+
*/
|
|
6526
|
+
const CLONE_READY_TIMEOUT_MS = 3e4;
|
|
6527
|
+
/**
|
|
6528
|
+
* Hard ceiling (ms) for the cloned iframe's load event itself. If the event
|
|
6529
|
+
* never fires, the mount is rejected instead of hanging forever.
|
|
6530
|
+
*/
|
|
6531
|
+
const IFRAME_LOAD_WATCHDOG_MS = 6e4;
|
|
6586
6532
|
//#endregion
|
|
6587
6533
|
//#region src/css/parse.ts
|
|
6588
6534
|
const STANDARD_PROPERTIES = [
|
|
@@ -6896,6 +6842,16 @@ const STANDARD_PROPERTIES = [
|
|
|
6896
6842
|
rotate,
|
|
6897
6843
|
"rotate"
|
|
6898
6844
|
],
|
|
6845
|
+
[
|
|
6846
|
+
"translate",
|
|
6847
|
+
translate,
|
|
6848
|
+
"translate"
|
|
6849
|
+
],
|
|
6850
|
+
[
|
|
6851
|
+
"scale",
|
|
6852
|
+
scale,
|
|
6853
|
+
"scale"
|
|
6854
|
+
],
|
|
6899
6855
|
[
|
|
6900
6856
|
"visibility",
|
|
6901
6857
|
visibility,
|
|
@@ -7147,10 +7103,15 @@ const parse = (context, descriptor, style) => {
|
|
|
7147
7103
|
/**
|
|
7148
7104
|
* Read-only grouped accessor for border-related CSS properties.
|
|
7149
7105
|
*
|
|
7106
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7107
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7108
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7109
|
+
*
|
|
7150
7110
|
* Provides structured access: `styles.border.topColor` as an alternative
|
|
7151
7111
|
* to the flat `styles.borderTopColor`. Both forms remain valid.
|
|
7152
7112
|
*/
|
|
7153
7113
|
var BorderStyles = class {
|
|
7114
|
+
styles;
|
|
7154
7115
|
constructor(styles) {
|
|
7155
7116
|
this.styles = styles;
|
|
7156
7117
|
}
|
|
@@ -7219,8 +7180,13 @@ var BorderStyles = class {
|
|
|
7219
7180
|
//#region src/css/grouped/background-styles.ts
|
|
7220
7181
|
/**
|
|
7221
7182
|
* Read-only grouped accessor for background-related CSS properties.
|
|
7183
|
+
*
|
|
7184
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7185
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7186
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7222
7187
|
*/
|
|
7223
7188
|
var BackgroundStyles = class {
|
|
7189
|
+
styles;
|
|
7224
7190
|
constructor(styles) {
|
|
7225
7191
|
this.styles = styles;
|
|
7226
7192
|
}
|
|
@@ -7253,8 +7219,13 @@ var BackgroundStyles = class {
|
|
|
7253
7219
|
//#region src/css/grouped/font-styles.ts
|
|
7254
7220
|
/**
|
|
7255
7221
|
* Read-only grouped accessor for font/text-related CSS properties.
|
|
7222
|
+
*
|
|
7223
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7224
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7225
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7256
7226
|
*/
|
|
7257
7227
|
var FontStyles = class {
|
|
7228
|
+
styles;
|
|
7258
7229
|
constructor(styles) {
|
|
7259
7230
|
this.styles = styles;
|
|
7260
7231
|
}
|
|
@@ -7344,8 +7315,13 @@ var FontStyles = class {
|
|
|
7344
7315
|
//#region src/css/grouped/layout-styles.ts
|
|
7345
7316
|
/**
|
|
7346
7317
|
* Read-only grouped accessor for layout/display/positioning CSS properties.
|
|
7318
|
+
*
|
|
7319
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7320
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7321
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7347
7322
|
*/
|
|
7348
7323
|
var LayoutStyles = class {
|
|
7324
|
+
styles;
|
|
7349
7325
|
constructor(styles) {
|
|
7350
7326
|
this.styles = styles;
|
|
7351
7327
|
}
|
|
@@ -7467,6 +7443,117 @@ var LayoutStyles = class {
|
|
|
7467
7443
|
//#endregion
|
|
7468
7444
|
//#region src/css/index.ts
|
|
7469
7445
|
var CSSParsedDeclaration = class {
|
|
7446
|
+
animationDuration;
|
|
7447
|
+
backgroundClip;
|
|
7448
|
+
backgroundColor;
|
|
7449
|
+
backgroundImage;
|
|
7450
|
+
backgroundOrigin;
|
|
7451
|
+
backgroundPosition;
|
|
7452
|
+
backgroundRepeat;
|
|
7453
|
+
backgroundSize;
|
|
7454
|
+
borderTopColor;
|
|
7455
|
+
borderRightColor;
|
|
7456
|
+
borderBottomColor;
|
|
7457
|
+
borderLeftColor;
|
|
7458
|
+
borderTopLeftRadius;
|
|
7459
|
+
borderTopRightRadius;
|
|
7460
|
+
borderBottomRightRadius;
|
|
7461
|
+
borderBottomLeftRadius;
|
|
7462
|
+
borderTopStyle;
|
|
7463
|
+
borderRightStyle;
|
|
7464
|
+
borderBottomStyle;
|
|
7465
|
+
borderLeftStyle;
|
|
7466
|
+
borderTopWidth;
|
|
7467
|
+
borderRightWidth;
|
|
7468
|
+
borderBottomWidth;
|
|
7469
|
+
borderLeftWidth;
|
|
7470
|
+
boxShadow;
|
|
7471
|
+
clipPath;
|
|
7472
|
+
color;
|
|
7473
|
+
direction;
|
|
7474
|
+
display;
|
|
7475
|
+
float;
|
|
7476
|
+
fontFamily;
|
|
7477
|
+
fontSize;
|
|
7478
|
+
fontStyle;
|
|
7479
|
+
fontVariant;
|
|
7480
|
+
fontWeight;
|
|
7481
|
+
letterSpacing;
|
|
7482
|
+
lineBreak;
|
|
7483
|
+
lineHeight;
|
|
7484
|
+
listStyleImage;
|
|
7485
|
+
listStylePosition;
|
|
7486
|
+
listStyleType;
|
|
7487
|
+
marginTop;
|
|
7488
|
+
marginRight;
|
|
7489
|
+
marginBottom;
|
|
7490
|
+
marginLeft;
|
|
7491
|
+
opacity;
|
|
7492
|
+
overflowX;
|
|
7493
|
+
overflowY;
|
|
7494
|
+
overflowWrap;
|
|
7495
|
+
paddingTop;
|
|
7496
|
+
paddingRight;
|
|
7497
|
+
paddingBottom;
|
|
7498
|
+
paddingLeft;
|
|
7499
|
+
paintOrder;
|
|
7500
|
+
position;
|
|
7501
|
+
textAlign;
|
|
7502
|
+
textDecorationColor;
|
|
7503
|
+
textDecorationLine;
|
|
7504
|
+
textDecorationStyle;
|
|
7505
|
+
textDecorationThickness;
|
|
7506
|
+
textUnderlineOffset;
|
|
7507
|
+
textShadow;
|
|
7508
|
+
textTransform;
|
|
7509
|
+
textOverflow;
|
|
7510
|
+
transform;
|
|
7511
|
+
transformOrigin;
|
|
7512
|
+
rotate;
|
|
7513
|
+
translate;
|
|
7514
|
+
scale;
|
|
7515
|
+
visibility;
|
|
7516
|
+
webkitTextStrokeColor;
|
|
7517
|
+
webkitTextStrokeWidth;
|
|
7518
|
+
webkitLineClamp;
|
|
7519
|
+
wordBreak;
|
|
7520
|
+
whiteSpace;
|
|
7521
|
+
writingMode;
|
|
7522
|
+
zIndex;
|
|
7523
|
+
objectFit;
|
|
7524
|
+
imageRendering;
|
|
7525
|
+
mixBlendMode;
|
|
7526
|
+
filter;
|
|
7527
|
+
fontVariantLigatures;
|
|
7528
|
+
zoom;
|
|
7529
|
+
objectPosition;
|
|
7530
|
+
backgroundBlendMode;
|
|
7531
|
+
borderImageSource;
|
|
7532
|
+
borderImageSlice;
|
|
7533
|
+
borderImageRepeat;
|
|
7534
|
+
boxDecorationBreak;
|
|
7535
|
+
accentColor;
|
|
7536
|
+
webkitTextFillColor;
|
|
7537
|
+
isolation;
|
|
7538
|
+
outlineColor;
|
|
7539
|
+
outlineStyle;
|
|
7540
|
+
outlineWidth;
|
|
7541
|
+
outlineOffset;
|
|
7542
|
+
backdropFilter;
|
|
7543
|
+
maskImage;
|
|
7544
|
+
maskPosition;
|
|
7545
|
+
maskRepeat;
|
|
7546
|
+
maskSize;
|
|
7547
|
+
textEmphasisStyle;
|
|
7548
|
+
textEmphasisColor;
|
|
7549
|
+
textEmphasisPosition;
|
|
7550
|
+
borderImageWidth;
|
|
7551
|
+
borderImageOutset;
|
|
7552
|
+
webkitBoxReflect;
|
|
7553
|
+
_border;
|
|
7554
|
+
_background;
|
|
7555
|
+
_font;
|
|
7556
|
+
_layout;
|
|
7470
7557
|
get border() {
|
|
7471
7558
|
return this._border ?? (this._border = new BorderStyles(this));
|
|
7472
7559
|
}
|
|
@@ -7496,7 +7583,7 @@ var CSSParsedDeclaration = class {
|
|
|
7496
7583
|
return isTransparent(this.backgroundColor);
|
|
7497
7584
|
}
|
|
7498
7585
|
isTransformed() {
|
|
7499
|
-
return this.transform !== null || this.rotate !== null;
|
|
7586
|
+
return this.transform !== null || this.rotate !== null || this.translate !== null || this.scale !== null;
|
|
7500
7587
|
}
|
|
7501
7588
|
isPositioned() {
|
|
7502
7589
|
return this.position !== 0;
|
|
@@ -7531,12 +7618,16 @@ const parseSpecialDeclarations = (context, declaration) => {
|
|
|
7531
7618
|
};
|
|
7532
7619
|
};
|
|
7533
7620
|
var CSSParsedPseudoDeclaration = class {
|
|
7621
|
+
content;
|
|
7622
|
+
quotes;
|
|
7534
7623
|
constructor(context, declaration) {
|
|
7535
7624
|
this.content = parse(context, content, declaration.content);
|
|
7536
7625
|
this.quotes = parse(context, quotes, declaration.quotes);
|
|
7537
7626
|
}
|
|
7538
7627
|
};
|
|
7539
7628
|
var CSSParsedCounterDeclaration = class {
|
|
7629
|
+
counterIncrement;
|
|
7630
|
+
counterReset;
|
|
7540
7631
|
constructor(context, declaration) {
|
|
7541
7632
|
this.counterIncrement = parse(context, counterIncrement, declaration.counterIncrement);
|
|
7542
7633
|
this.counterReset = parse(context, counterReset, declaration.counterReset);
|
|
@@ -7560,6 +7651,48 @@ const isDebugging = (element, type) => {
|
|
|
7560
7651
|
return elementType === 1 || type === elementType;
|
|
7561
7652
|
};
|
|
7562
7653
|
//#endregion
|
|
7654
|
+
//#region src/dom/adopted-styles.ts
|
|
7655
|
+
/**
|
|
7656
|
+
* Constructable stylesheet cloning (adoptedStyleSheets).
|
|
7657
|
+
*
|
|
7658
|
+
* `adoptedStyleSheets` on a Document or ShadowRoot is the standard way Lit,
|
|
7659
|
+
* React and other frameworks inject component styles, but the sheets are not
|
|
7660
|
+
* part of the node tree — cloneNode never carries them. A shadow root that
|
|
7661
|
+
* relies on adopted sheets (and whose computed styles are not inlined per
|
|
7662
|
+
* element, i.e. copyStyles is false) would otherwise lose those rules in the
|
|
7663
|
+
* clone. The rules are re-materialised as a regular <style> element, which
|
|
7664
|
+
* also cascades last like the spec treats adopted sheets.
|
|
7665
|
+
*/
|
|
7666
|
+
/**
|
|
7667
|
+
* Serialize the CSS rules of the given sheets into one stylesheet string.
|
|
7668
|
+
* Sheets that cannot be read (e.g. detached) are skipped rather than failing
|
|
7669
|
+
* the render.
|
|
7670
|
+
*/
|
|
7671
|
+
const serializeStyleSheetRules = (sheets) => {
|
|
7672
|
+
let css = "";
|
|
7673
|
+
for (const sheet of sheets) try {
|
|
7674
|
+
const rules = sheet.cssRules;
|
|
7675
|
+
for (let i = 0; i < rules.length; i++) {
|
|
7676
|
+
const rule = rules[i];
|
|
7677
|
+
if (rule && typeof rule.cssText === "string") css += rule.cssText;
|
|
7678
|
+
}
|
|
7679
|
+
} catch (e) {}
|
|
7680
|
+
return css;
|
|
7681
|
+
};
|
|
7682
|
+
/**
|
|
7683
|
+
* Build a <style> element carrying the rules of the given adopted sheets, or
|
|
7684
|
+
* null when there is nothing to clone. `styleDocument` must be the document
|
|
7685
|
+
* the clone lives in.
|
|
7686
|
+
*/
|
|
7687
|
+
const createAdoptedStylesElement = (styleDocument, sheets, nonce) => {
|
|
7688
|
+
const css = serializeStyleSheetRules(sheets);
|
|
7689
|
+
if (!css) return null;
|
|
7690
|
+
const style = styleDocument.createElement("style");
|
|
7691
|
+
style.textContent = css;
|
|
7692
|
+
if (nonce) style.nonce = nonce;
|
|
7693
|
+
return style;
|
|
7694
|
+
};
|
|
7695
|
+
//#endregion
|
|
7563
7696
|
//#region src/dom/slot-cloner.ts
|
|
7564
7697
|
/** Exported for reuse in document-cloner.ts */
|
|
7565
7698
|
const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
|
|
@@ -7568,6 +7701,9 @@ const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
|
|
|
7568
7701
|
* Extracted from DocumentCloner to reduce file size and improve separation of concerns.
|
|
7569
7702
|
*/
|
|
7570
7703
|
var SlotCloner = class {
|
|
7704
|
+
cloneNodeFn;
|
|
7705
|
+
options;
|
|
7706
|
+
context;
|
|
7571
7707
|
constructor(cloneNodeFn, options, context) {
|
|
7572
7708
|
this.cloneNodeFn = cloneNodeFn;
|
|
7573
7709
|
this.options = options;
|
|
@@ -7646,6 +7782,7 @@ var SlotCloner = class {
|
|
|
7646
7782
|
cloneShadowDOMChildren(shadowRoot, targetShadowRoot, copyStyles) {
|
|
7647
7783
|
for (let child = shadowRoot.firstChild; child; child = child.nextSibling) if (isElementNode(child) && isSlotElement(child)) this.cloneSlotElement(child, targetShadowRoot, copyStyles);
|
|
7648
7784
|
else this.safeAppendClonedChild(targetShadowRoot, child, copyStyles);
|
|
7785
|
+
this.appendAdoptedStyleSheets(shadowRoot, targetShadowRoot, copyStyles);
|
|
7649
7786
|
}
|
|
7650
7787
|
/**
|
|
7651
7788
|
* Clone light DOM children to the target element.
|
|
@@ -7674,6 +7811,23 @@ var SlotCloner = class {
|
|
|
7674
7811
|
cloneShadowDOMAsLightDOM(shadowRoot, clone, copyStyles) {
|
|
7675
7812
|
for (let child = shadowRoot.firstChild; child; child = child.nextSibling) if (isElementNode(child) && isSlotElement(child)) this.cloneSlotElementAsLightDOM(child, clone, copyStyles);
|
|
7676
7813
|
else this.appendChildNode(clone, child, copyStyles);
|
|
7814
|
+
this.appendAdoptedStyleSheets(shadowRoot, clone, copyStyles);
|
|
7815
|
+
}
|
|
7816
|
+
/**
|
|
7817
|
+
* Re-materialise the shadow root's constructable stylesheets (adoptedStyleSheets)
|
|
7818
|
+
* as a <style> element in the clone — cloneNode never carries them.
|
|
7819
|
+
*
|
|
7820
|
+
* Skipped when computed styles are inlined per element (copyStyles), mirroring
|
|
7821
|
+
* how <style> elements inside shadow roots are dropped in that mode.
|
|
7822
|
+
*/
|
|
7823
|
+
appendAdoptedStyleSheets(shadowRoot, target, copyStyles) {
|
|
7824
|
+
if (copyStyles) return;
|
|
7825
|
+
const sheets = shadowRoot.adoptedStyleSheets;
|
|
7826
|
+
if (!sheets || sheets.length === 0) return;
|
|
7827
|
+
const styleDocument = "host" in target ? target.host.ownerDocument : target.ownerDocument;
|
|
7828
|
+
if (!styleDocument) return;
|
|
7829
|
+
const style = createAdoptedStylesElement(styleDocument, sheets, this.options.cspNonce);
|
|
7830
|
+
if (style) target.appendChild(style);
|
|
7677
7831
|
}
|
|
7678
7832
|
};
|
|
7679
7833
|
//#endregion
|
|
@@ -7748,10 +7902,12 @@ const createStyles = (body, styles, cspNonce) => {
|
|
|
7748
7902
|
* pairing across the whole clone walk, shared with the cloner's counter state.
|
|
7749
7903
|
*/
|
|
7750
7904
|
var PseudoContentResolver = class {
|
|
7905
|
+
context;
|
|
7906
|
+
counters;
|
|
7907
|
+
quoteDepth = 0;
|
|
7751
7908
|
constructor(context, counters) {
|
|
7752
7909
|
this.context = context;
|
|
7753
7910
|
this.counters = counters;
|
|
7754
|
-
this.quoteDepth = 0;
|
|
7755
7911
|
}
|
|
7756
7912
|
resolvePseudoContent(node, clone, style, pseudoElt) {
|
|
7757
7913
|
if (!style) return;
|
|
@@ -7811,7 +7967,44 @@ var PseudoContentResolver = class {
|
|
|
7811
7967
|
}
|
|
7812
7968
|
};
|
|
7813
7969
|
//#endregion
|
|
7970
|
+
//#region src/core/abort-helper.ts
|
|
7971
|
+
/**
|
|
7972
|
+
* AbortSignal helper utilities.
|
|
7973
|
+
*/
|
|
7974
|
+
/**
|
|
7975
|
+
* Throw a DOMException if the given AbortSignal is already aborted.
|
|
7976
|
+
* Used at checkpoints throughout the rendering pipeline to support
|
|
7977
|
+
* cancellable renders.
|
|
7978
|
+
*
|
|
7979
|
+
* @param signal - The AbortSignal to check. If undefined or not aborted, this is a no-op.
|
|
7980
|
+
* @throws {DOMException} With name 'AbortError' if the signal has been aborted.
|
|
7981
|
+
*/
|
|
7982
|
+
const throwIfAborted = (signal) => {
|
|
7983
|
+
if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
7984
|
+
};
|
|
7985
|
+
//#endregion
|
|
7814
7986
|
//#region src/dom/iframe-mount.ts
|
|
7987
|
+
const trustedTypePolicies = /* @__PURE__ */ new WeakMap();
|
|
7988
|
+
/**
|
|
7989
|
+
* Resolve the Trusted Types policy used for writing the clone document.
|
|
7990
|
+
* Returns null when Trusted Types are unavailable or the policy could not be
|
|
7991
|
+
* created — document.write is not a Trusted Types sink, so the plain string
|
|
7992
|
+
* stays functional in both cases.
|
|
7993
|
+
* @internal – exported for testing only.
|
|
7994
|
+
*/
|
|
7995
|
+
const resolveTrustedTypesPolicy = (ownerWindow) => {
|
|
7996
|
+
const factory = ownerWindow && ownerWindow.trustedTypes;
|
|
7997
|
+
if (!factory) return null;
|
|
7998
|
+
if (trustedTypePolicies.has(factory)) return trustedTypePolicies.get(factory) ?? null;
|
|
7999
|
+
let policy = null;
|
|
8000
|
+
try {
|
|
8001
|
+
policy = factory.getPolicy?.("html2canvas-pro") ?? factory.createPolicy("html2canvas-pro", { createHTML: (s) => s });
|
|
8002
|
+
} catch (e) {
|
|
8003
|
+
policy = null;
|
|
8004
|
+
}
|
|
8005
|
+
trustedTypePolicies.set(factory, policy);
|
|
8006
|
+
return policy;
|
|
8007
|
+
};
|
|
7815
8008
|
const createIFrameContainer = (ownerDocument, bounds, customContainer) => {
|
|
7816
8009
|
const cloneIframeContainer = ownerDocument.createElement("iframe");
|
|
7817
8010
|
cloneIframeContainer.className = "html2canvas-container";
|
|
@@ -7844,26 +8037,45 @@ const imageReady = (img) => {
|
|
|
7844
8037
|
const imagesReady = (document) => {
|
|
7845
8038
|
return Promise.all([].slice.call(document.images, 0).map(imageReady));
|
|
7846
8039
|
};
|
|
7847
|
-
const iframeLoader = (iframe) => {
|
|
8040
|
+
const iframeLoader = (iframe, logger, signal) => {
|
|
7848
8041
|
return new Promise((resolve, reject) => {
|
|
7849
8042
|
const cloneWindow = iframe.contentWindow;
|
|
7850
8043
|
if (!cloneWindow) return reject(`No window assigned for iframe`);
|
|
7851
8044
|
const documentClone = cloneWindow.document;
|
|
8045
|
+
let interval;
|
|
8046
|
+
const watchdog = setTimeout(() => {
|
|
8047
|
+
if (interval) clearInterval(interval);
|
|
8048
|
+
reject(/* @__PURE__ */ new Error(`Cloned iframe did not fire its load event within ${IFRAME_LOAD_WATCHDOG_MS}ms`));
|
|
8049
|
+
}, IFRAME_LOAD_WATCHDOG_MS);
|
|
8050
|
+
const onAbort = () => {
|
|
8051
|
+
if (interval) clearInterval(interval);
|
|
8052
|
+
clearTimeout(watchdog);
|
|
8053
|
+
reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
8054
|
+
};
|
|
7852
8055
|
cloneWindow.onload = iframe.onload = () => {
|
|
7853
8056
|
cloneWindow.onload = iframe.onload = null;
|
|
7854
|
-
const
|
|
8057
|
+
const maxAttempts = Math.ceil(CLONE_READY_TIMEOUT_MS / 50);
|
|
7855
8058
|
let attempts = 0;
|
|
7856
|
-
|
|
8059
|
+
interval = setInterval(() => {
|
|
7857
8060
|
attempts++;
|
|
7858
|
-
if (
|
|
8061
|
+
if (signal?.aborted) onAbort();
|
|
8062
|
+
else if (documentClone.body.childNodes.length > 0 && documentClone.readyState === "complete") {
|
|
7859
8063
|
clearInterval(interval);
|
|
8064
|
+
interval = void 0;
|
|
8065
|
+
clearTimeout(watchdog);
|
|
7860
8066
|
resolve(iframe);
|
|
7861
|
-
} else if (attempts >=
|
|
8067
|
+
} else if (attempts >= maxAttempts) {
|
|
7862
8068
|
clearInterval(interval);
|
|
8069
|
+
interval = void 0;
|
|
8070
|
+
logger?.warn(`Cloned iframe did not become ready within ${CLONE_READY_TIMEOUT_MS / 1e3} seconds; continuing with a possibly incomplete document`);
|
|
7863
8071
|
resolve(iframe);
|
|
7864
8072
|
}
|
|
7865
8073
|
}, 50);
|
|
7866
8074
|
};
|
|
8075
|
+
if (signal) {
|
|
8076
|
+
if (signal.aborted) onAbort();
|
|
8077
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
8078
|
+
}
|
|
7867
8079
|
});
|
|
7868
8080
|
};
|
|
7869
8081
|
/**
|
|
@@ -7908,14 +8120,19 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7908
8120
|
const scrollY = ownerDocument.defaultView.pageYOffset;
|
|
7909
8121
|
const cloneWindow = iframe.contentWindow;
|
|
7910
8122
|
const documentClone = cloneWindow.document;
|
|
7911
|
-
const iframeLoad = iframeLoader(iframe).then(async () => {
|
|
8123
|
+
const iframeLoad = iframeLoader(iframe, context.logger, mount.signal).then(async () => {
|
|
7912
8124
|
mount.scrolledElements.forEach(restoreNodeScroll);
|
|
7913
8125
|
if (cloneWindow) cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7914
8126
|
const onclone = mount.onclone;
|
|
7915
8127
|
const referenceElement = mount.clonedReferenceElement;
|
|
7916
8128
|
if (typeof referenceElement === "undefined") throw new Error(`Error finding the ${mount.referenceElementName} in the cloned document`);
|
|
8129
|
+
throwIfAborted(mount.signal);
|
|
7917
8130
|
if (documentClone.fonts && documentClone.fonts.ready) await documentClone.fonts.ready;
|
|
7918
|
-
|
|
8131
|
+
throwIfAborted(mount.signal);
|
|
8132
|
+
if (/(AppleWebKit)/g.test(navigator.userAgent)) {
|
|
8133
|
+
await imagesReady(documentClone);
|
|
8134
|
+
throwIfAborted(mount.signal);
|
|
8135
|
+
}
|
|
7919
8136
|
if (typeof onclone === "function") await Promise.resolve().then(() => onclone(documentClone, referenceElement));
|
|
7920
8137
|
cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7921
8138
|
if (/AppleWebKit/g.test(navigator.userAgent) && (cloneWindow.scrollY !== windowSize.top || cloneWindow.scrollX !== windowSize.left)) {
|
|
@@ -7931,12 +8148,9 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7931
8148
|
*/
|
|
7932
8149
|
const baseUri = ownerDocument.baseURI;
|
|
7933
8150
|
documentClone.open();
|
|
7934
|
-
const rawHTML = serializeDoctype(
|
|
8151
|
+
const rawHTML = serializeDoctype(ownerDocument.doctype) + "<html></html>";
|
|
7935
8152
|
try {
|
|
7936
|
-
const
|
|
7937
|
-
const trustedTypesFactory = ownerWindow && ownerWindow.trustedTypes;
|
|
7938
|
-
let policy = trustedTypesFactory?.getPolicy?.("html2canvas-pro");
|
|
7939
|
-
if (!policy && trustedTypesFactory) policy = trustedTypesFactory.createPolicy("html2canvas-pro", { createHTML: (s) => s });
|
|
8153
|
+
const policy = resolveTrustedTypesPolicy(ownerDocument.defaultView);
|
|
7940
8154
|
const html = policy ? policy.createHTML(rawHTML) : rawHTML;
|
|
7941
8155
|
documentClone.write(html);
|
|
7942
8156
|
} catch (_e) {
|
|
@@ -7983,6 +8197,15 @@ const findParentShadowRoot = (element) => {
|
|
|
7983
8197
|
return null;
|
|
7984
8198
|
};
|
|
7985
8199
|
var DocumentCloner = class {
|
|
8200
|
+
context;
|
|
8201
|
+
options;
|
|
8202
|
+
scrolledElements;
|
|
8203
|
+
referenceElement;
|
|
8204
|
+
clonedReferenceElement;
|
|
8205
|
+
documentElement;
|
|
8206
|
+
counters;
|
|
8207
|
+
pseudoContents;
|
|
8208
|
+
slotCloner;
|
|
7986
8209
|
constructor(context, element, options) {
|
|
7987
8210
|
this.context = context;
|
|
7988
8211
|
this.options = options;
|
|
@@ -7992,7 +8215,8 @@ var DocumentCloner = class {
|
|
|
7992
8215
|
this.pseudoContents = new PseudoContentResolver(context, this.counters);
|
|
7993
8216
|
this.slotCloner = new SlotCloner((node, copyStyles) => this.cloneNode(node, copyStyles), {
|
|
7994
8217
|
ignoreElements: options.ignoreElements,
|
|
7995
|
-
copyStyles: options.copyStyles ?? true
|
|
8218
|
+
copyStyles: options.copyStyles ?? true,
|
|
8219
|
+
cspNonce: options.cspNonce
|
|
7996
8220
|
}, context);
|
|
7997
8221
|
if (!element.ownerDocument) throw new Error("Cloned element does not have an owner document");
|
|
7998
8222
|
if (!this.options.iframeContainer) {
|
|
@@ -8000,15 +8224,35 @@ var DocumentCloner = class {
|
|
|
8000
8224
|
if (shadowRoot) this.options.iframeContainer = shadowRoot;
|
|
8001
8225
|
}
|
|
8002
8226
|
this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false);
|
|
8227
|
+
this.appendDocumentAdoptedStyles(element.ownerDocument);
|
|
8003
8228
|
}
|
|
8004
|
-
|
|
8005
|
-
|
|
8229
|
+
/**
|
|
8230
|
+
* Re-materialise the source document's constructable stylesheets
|
|
8231
|
+
* (document.adoptedStyleSheets) as a <style> at the end of the clone's
|
|
8232
|
+
* <head>: cloneNode never carries them, and they cascade after all author
|
|
8233
|
+
* sheets, which appending last approximates.
|
|
8234
|
+
*
|
|
8235
|
+
* Skipped when computed styles are inlined per element (copyStyles), like
|
|
8236
|
+
* the other stylesheet-cloning paths.
|
|
8237
|
+
*/
|
|
8238
|
+
appendDocumentAdoptedStyles(ownerDocument) {
|
|
8239
|
+
if (this.options.copyStyles) return;
|
|
8240
|
+
const sheets = ownerDocument.adoptedStyleSheets;
|
|
8241
|
+
if (!sheets || sheets.length === 0) return;
|
|
8242
|
+
const head = this.documentElement.getElementsByTagName("head").item(0);
|
|
8243
|
+
if (!head) return;
|
|
8244
|
+
const style = createAdoptedStylesElement(this.documentElement.ownerDocument ?? ownerDocument, sheets, this.options.cspNonce);
|
|
8245
|
+
if (style) head.appendChild(style);
|
|
8246
|
+
}
|
|
8247
|
+
toIFrame(ownerDocument, windowSize) {
|
|
8248
|
+
return mountCloneInIFrame(this.context, ownerDocument, windowSize, {
|
|
8006
8249
|
documentElement: this.documentElement,
|
|
8007
8250
|
clonedReferenceElement: this.clonedReferenceElement,
|
|
8008
8251
|
referenceElementName: this.referenceElement.nodeName,
|
|
8009
8252
|
scrolledElements: this.scrolledElements,
|
|
8010
8253
|
onclone: this.options.onclone,
|
|
8011
|
-
container: this.options.iframeContainer
|
|
8254
|
+
container: this.options.iframeContainer,
|
|
8255
|
+
signal: this.options.signal
|
|
8012
8256
|
});
|
|
8013
8257
|
}
|
|
8014
8258
|
createElementClone(node) {
|
|
@@ -8126,7 +8370,7 @@ var DocumentCloner = class {
|
|
|
8126
8370
|
this.slotCloner.cloneChildNodes(node, clone, copyStyles);
|
|
8127
8371
|
}
|
|
8128
8372
|
cloneNode(node, copyStyles) {
|
|
8129
|
-
if (isTextNode(node)) return document.createTextNode(node.data);
|
|
8373
|
+
if (isTextNode(node)) return (node.ownerDocument ?? document).createTextNode(node.data);
|
|
8130
8374
|
if (!node.ownerDocument) return node.cloneNode(false);
|
|
8131
8375
|
const window = node.ownerDocument.defaultView;
|
|
8132
8376
|
if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {
|
|
@@ -8212,7 +8456,7 @@ var DOMNormalizer = class {
|
|
|
8212
8456
|
*/
|
|
8213
8457
|
static normalizeElement(element, styles) {
|
|
8214
8458
|
const originalStyles = {};
|
|
8215
|
-
if (!isHTMLElementNode(element)) return originalStyles;
|
|
8459
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return originalStyles;
|
|
8216
8460
|
if (styles.animationDuration.some((duration) => duration > 0)) {
|
|
8217
8461
|
originalStyles.animationDuration = element.style.animationDuration;
|
|
8218
8462
|
element.style.animationDuration = "0s";
|
|
@@ -8221,13 +8465,25 @@ var DOMNormalizer = class {
|
|
|
8221
8465
|
originalStyles.transform = element.style.transform;
|
|
8222
8466
|
element.style.transform = "translate(0, 0)";
|
|
8223
8467
|
}
|
|
8468
|
+
let needsContainingBlockFallback = false;
|
|
8224
8469
|
if (styles.rotate !== null) {
|
|
8225
8470
|
originalStyles.rotate = element.style.rotate;
|
|
8226
8471
|
element.style.rotate = "0deg";
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8472
|
+
needsContainingBlockFallback = true;
|
|
8473
|
+
}
|
|
8474
|
+
if (styles.translate !== null) {
|
|
8475
|
+
originalStyles.translate = element.style.translate;
|
|
8476
|
+
element.style.translate = "0px";
|
|
8477
|
+
needsContainingBlockFallback = true;
|
|
8478
|
+
}
|
|
8479
|
+
if (styles.scale !== null) {
|
|
8480
|
+
originalStyles.scale = element.style.scale;
|
|
8481
|
+
element.style.scale = "1";
|
|
8482
|
+
needsContainingBlockFallback = true;
|
|
8483
|
+
}
|
|
8484
|
+
if (needsContainingBlockFallback && originalStyles.transform === void 0) {
|
|
8485
|
+
originalStyles.transform = element.style.transform;
|
|
8486
|
+
element.style.transform = "translate(0, 0)";
|
|
8231
8487
|
}
|
|
8232
8488
|
return originalStyles;
|
|
8233
8489
|
}
|
|
@@ -8238,26 +8494,39 @@ var DOMNormalizer = class {
|
|
|
8238
8494
|
* @param originalStyles - Original styles to restore
|
|
8239
8495
|
*/
|
|
8240
8496
|
static restoreElement(element, originalStyles) {
|
|
8241
|
-
if (!isHTMLElementNode(element)) return;
|
|
8497
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return;
|
|
8242
8498
|
if (originalStyles.animationDuration !== void 0) element.style.animationDuration = originalStyles.animationDuration;
|
|
8243
8499
|
if (originalStyles.transform !== void 0) element.style.transform = originalStyles.transform;
|
|
8244
8500
|
if (originalStyles.rotate !== void 0) element.style.rotate = originalStyles.rotate;
|
|
8501
|
+
if (originalStyles.translate !== void 0) element.style.translate = originalStyles.translate;
|
|
8502
|
+
if (originalStyles.scale !== void 0) element.style.scale = originalStyles.scale;
|
|
8245
8503
|
}
|
|
8246
8504
|
};
|
|
8247
8505
|
//#endregion
|
|
8248
8506
|
//#region src/dom/element-container.ts
|
|
8249
8507
|
var ElementContainer = class {
|
|
8508
|
+
context;
|
|
8509
|
+
styles;
|
|
8510
|
+
textNodes = [];
|
|
8511
|
+
elements = [];
|
|
8512
|
+
bounds;
|
|
8513
|
+
/**
|
|
8514
|
+
* Bounds of the <legend> child of a <fieldset>, when present. Browsers break
|
|
8515
|
+
* the fieldset's top border where the legend sits; the renderer uses these
|
|
8516
|
+
* bounds to leave a matching gap (issue #227).
|
|
8517
|
+
*/
|
|
8518
|
+
legendBounds;
|
|
8519
|
+
createsStackingContext = false;
|
|
8520
|
+
createsRealStackingContext = false;
|
|
8521
|
+
isListOwner = false;
|
|
8522
|
+
debugRender = false;
|
|
8523
|
+
originalStyles;
|
|
8524
|
+
originalElement;
|
|
8250
8525
|
constructor(context, element, options = {}) {
|
|
8251
8526
|
this.context = context;
|
|
8252
|
-
this.textNodes = [];
|
|
8253
|
-
this.elements = [];
|
|
8254
|
-
this.createsStackingContext = false;
|
|
8255
|
-
this.createsRealStackingContext = false;
|
|
8256
|
-
this.isListOwner = false;
|
|
8257
|
-
this.debugRender = false;
|
|
8258
8527
|
if (isDebugging(element, 3)) debugger;
|
|
8259
8528
|
this.styles = new CSSParsedDeclaration(context, context.config.window.getComputedStyle(element, null));
|
|
8260
|
-
if (options.normalizeDom !== false && isHTMLElementNode(element)) {
|
|
8529
|
+
if (options.normalizeDom !== false && (isHTMLElementNode(element) || isSVGElementNode(element))) {
|
|
8261
8530
|
this.originalStyles = DOMNormalizer.normalizeElement(element, this.styles);
|
|
8262
8531
|
this.originalElement = element;
|
|
8263
8532
|
}
|
|
@@ -8294,278 +8563,16 @@ var ElementContainer = class {
|
|
|
8294
8563
|
}
|
|
8295
8564
|
};
|
|
8296
8565
|
//#endregion
|
|
8297
|
-
//#region node_modules/.pnpm/text-segmentation@1.0.3/node_modules/text-segmentation/dist/text-segmentation.es5.js
|
|
8298
|
-
var base64 = "AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAABQAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA=";
|
|
8299
|
-
var chars$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8300
|
-
var lookup$1 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
8301
|
-
for (var i$1 = 0; i$1 < chars$1.length; i$1++) lookup$1[chars$1.charCodeAt(i$1)] = i$1;
|
|
8302
|
-
var decode = function(base64) {
|
|
8303
|
-
var bufferLength = base64.length * .75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
|
|
8304
|
-
if (base64[base64.length - 1] === "=") {
|
|
8305
|
-
bufferLength--;
|
|
8306
|
-
if (base64[base64.length - 2] === "=") bufferLength--;
|
|
8307
|
-
}
|
|
8308
|
-
var buffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.slice !== "undefined" ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
|
|
8309
|
-
var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
|
|
8310
|
-
for (i = 0; i < len; i += 4) {
|
|
8311
|
-
encoded1 = lookup$1[base64.charCodeAt(i)];
|
|
8312
|
-
encoded2 = lookup$1[base64.charCodeAt(i + 1)];
|
|
8313
|
-
encoded3 = lookup$1[base64.charCodeAt(i + 2)];
|
|
8314
|
-
encoded4 = lookup$1[base64.charCodeAt(i + 3)];
|
|
8315
|
-
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
|
8316
|
-
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
|
8317
|
-
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
|
8318
|
-
}
|
|
8319
|
-
return buffer;
|
|
8320
|
-
};
|
|
8321
|
-
var polyUint16Array = function(buffer) {
|
|
8322
|
-
var length = buffer.length;
|
|
8323
|
-
var bytes = [];
|
|
8324
|
-
for (var i = 0; i < length; i += 2) bytes.push(buffer[i + 1] << 8 | buffer[i]);
|
|
8325
|
-
return bytes;
|
|
8326
|
-
};
|
|
8327
|
-
var polyUint32Array = function(buffer) {
|
|
8328
|
-
var length = buffer.length;
|
|
8329
|
-
var bytes = [];
|
|
8330
|
-
for (var i = 0; i < length; i += 4) bytes.push(buffer[i + 3] << 24 | buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i]);
|
|
8331
|
-
return bytes;
|
|
8332
|
-
};
|
|
8333
|
-
/** Shift size for getting the index-2 table offset. */
|
|
8334
|
-
var UTRIE2_SHIFT_2 = 5;
|
|
8335
|
-
/** Shift size for getting the index-1 table offset. */
|
|
8336
|
-
var UTRIE2_SHIFT_1 = 11;
|
|
8337
|
-
/**
|
|
8338
|
-
* Shift size for shifting left the index array values.
|
|
8339
|
-
* Increases possible data size with 16-bit index values at the cost
|
|
8340
|
-
* of compactability.
|
|
8341
|
-
* This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
|
|
8342
|
-
*/
|
|
8343
|
-
var UTRIE2_INDEX_SHIFT = 2;
|
|
8344
|
-
/**
|
|
8345
|
-
* Difference between the two shift sizes,
|
|
8346
|
-
* for getting an index-1 offset from an index-2 offset. 6=11-5
|
|
8347
|
-
*/
|
|
8348
|
-
var UTRIE2_SHIFT_1_2 = UTRIE2_SHIFT_1 - UTRIE2_SHIFT_2;
|
|
8349
|
-
/**
|
|
8350
|
-
* The part of the index-2 table for U+D800..U+DBFF stores values for
|
|
8351
|
-
* lead surrogate code _units_ not code _points_.
|
|
8352
|
-
* Values for lead surrogate code _points_ are indexed with this portion of the table.
|
|
8353
|
-
* Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
|
|
8354
|
-
*/
|
|
8355
|
-
var UTRIE2_LSCP_INDEX_2_OFFSET = 65536 >> UTRIE2_SHIFT_2;
|
|
8356
|
-
/** Mask for getting the lower bits for the in-data-block offset. */
|
|
8357
|
-
var UTRIE2_DATA_MASK = (1 << UTRIE2_SHIFT_2) - 1;
|
|
8358
|
-
/**
|
|
8359
|
-
* The index-1 table, only used for supplementary code points, at offset 2112=0x840.
|
|
8360
|
-
* Variable length, for code points up to highStart, where the last single-value range starts.
|
|
8361
|
-
* Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
|
|
8362
|
-
* (For 0x100000 supplementary code points U+10000..U+10ffff.)
|
|
8363
|
-
*
|
|
8364
|
-
* The part of the index-2 table for supplementary code points starts
|
|
8365
|
-
* after this index-1 table.
|
|
8366
|
-
*
|
|
8367
|
-
* Both the index-1 table and the following part of the index-2 table
|
|
8368
|
-
* are omitted completely if there is only BMP data.
|
|
8369
|
-
*/
|
|
8370
|
-
var UTRIE2_INDEX_1_OFFSET = UTRIE2_LSCP_INDEX_2_OFFSET + (1024 >> UTRIE2_SHIFT_2) + 32;
|
|
8371
|
-
/**
|
|
8372
|
-
* Number of index-1 entries for the BMP. 32=0x20
|
|
8373
|
-
* This part of the index-1 table is omitted from the serialized form.
|
|
8374
|
-
*/
|
|
8375
|
-
var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = 65536 >> UTRIE2_SHIFT_1;
|
|
8376
|
-
/** Mask for getting the lower bits for the in-index-2-block offset. */
|
|
8377
|
-
var UTRIE2_INDEX_2_MASK = (1 << UTRIE2_SHIFT_1_2) - 1;
|
|
8378
|
-
var slice16 = function(view, start, end) {
|
|
8379
|
-
if (view.slice) return view.slice(start, end);
|
|
8380
|
-
return new Uint16Array(Array.prototype.slice.call(view, start, end));
|
|
8381
|
-
};
|
|
8382
|
-
var slice32 = function(view, start, end) {
|
|
8383
|
-
if (view.slice) return view.slice(start, end);
|
|
8384
|
-
return new Uint32Array(Array.prototype.slice.call(view, start, end));
|
|
8385
|
-
};
|
|
8386
|
-
var createTrieFromBase64 = function(base64, _byteLength) {
|
|
8387
|
-
var buffer = decode(base64);
|
|
8388
|
-
var view32 = Array.isArray(buffer) ? polyUint32Array(buffer) : new Uint32Array(buffer);
|
|
8389
|
-
var view16 = Array.isArray(buffer) ? polyUint16Array(buffer) : new Uint16Array(buffer);
|
|
8390
|
-
var headerLength = 24;
|
|
8391
|
-
var index = slice16(view16, headerLength / 2, view32[4] / 2);
|
|
8392
|
-
var data = view32[5] === 2 ? slice16(view16, (headerLength + view32[4]) / 2) : slice32(view32, Math.ceil((headerLength + view32[4]) / 4));
|
|
8393
|
-
return new Trie(view32[0], view32[1], view32[2], view32[3], index, data);
|
|
8394
|
-
};
|
|
8395
|
-
var Trie = function() {
|
|
8396
|
-
function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
|
|
8397
|
-
this.initialValue = initialValue;
|
|
8398
|
-
this.errorValue = errorValue;
|
|
8399
|
-
this.highStart = highStart;
|
|
8400
|
-
this.highValueIndex = highValueIndex;
|
|
8401
|
-
this.index = index;
|
|
8402
|
-
this.data = data;
|
|
8403
|
-
}
|
|
8404
|
-
/**
|
|
8405
|
-
* Get the value for a code point as stored in the Trie.
|
|
8406
|
-
*
|
|
8407
|
-
* @param codePoint the code point
|
|
8408
|
-
* @return the value
|
|
8409
|
-
*/
|
|
8410
|
-
Trie.prototype.get = function(codePoint) {
|
|
8411
|
-
var ix;
|
|
8412
|
-
if (codePoint >= 0) {
|
|
8413
|
-
if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {
|
|
8414
|
-
ix = this.index[codePoint >> UTRIE2_SHIFT_2];
|
|
8415
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8416
|
-
return this.data[ix];
|
|
8417
|
-
}
|
|
8418
|
-
if (codePoint <= 65535) {
|
|
8419
|
-
ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET + (codePoint - 55296 >> UTRIE2_SHIFT_2)];
|
|
8420
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8421
|
-
return this.data[ix];
|
|
8422
|
-
}
|
|
8423
|
-
if (codePoint < this.highStart) {
|
|
8424
|
-
ix = UTRIE2_INDEX_1_OFFSET - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH + (codePoint >> UTRIE2_SHIFT_1);
|
|
8425
|
-
ix = this.index[ix];
|
|
8426
|
-
ix += codePoint >> UTRIE2_SHIFT_2 & UTRIE2_INDEX_2_MASK;
|
|
8427
|
-
ix = this.index[ix];
|
|
8428
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8429
|
-
return this.data[ix];
|
|
8430
|
-
}
|
|
8431
|
-
if (codePoint <= 1114111) return this.data[this.highValueIndex];
|
|
8432
|
-
}
|
|
8433
|
-
return this.errorValue;
|
|
8434
|
-
};
|
|
8435
|
-
return Trie;
|
|
8436
|
-
}();
|
|
8437
|
-
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8438
|
-
var lookup = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
8439
|
-
for (var i = 0; i < chars.length; i++) lookup[chars.charCodeAt(i)] = i;
|
|
8440
|
-
var Prepend = 1;
|
|
8441
|
-
var CR = 2;
|
|
8442
|
-
var LF = 3;
|
|
8443
|
-
var Control = 4;
|
|
8444
|
-
var Extend = 5;
|
|
8445
|
-
var SpacingMark = 7;
|
|
8446
|
-
var L = 8;
|
|
8447
|
-
var V = 9;
|
|
8448
|
-
var T = 10;
|
|
8449
|
-
var LV = 11;
|
|
8450
|
-
var LVT = 12;
|
|
8451
|
-
var ZWJ = 13;
|
|
8452
|
-
var Extended_Pictographic = 14;
|
|
8453
|
-
var RI = 15;
|
|
8454
|
-
var toCodePoints = function(str) {
|
|
8455
|
-
var codePoints = [];
|
|
8456
|
-
var i = 0;
|
|
8457
|
-
var length = str.length;
|
|
8458
|
-
while (i < length) {
|
|
8459
|
-
var value = str.charCodeAt(i++);
|
|
8460
|
-
if (value >= 55296 && value <= 56319 && i < length) {
|
|
8461
|
-
var extra = str.charCodeAt(i++);
|
|
8462
|
-
if ((extra & 64512) === 56320) codePoints.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
|
8463
|
-
else {
|
|
8464
|
-
codePoints.push(value);
|
|
8465
|
-
i--;
|
|
8466
|
-
}
|
|
8467
|
-
} else codePoints.push(value);
|
|
8468
|
-
}
|
|
8469
|
-
return codePoints;
|
|
8470
|
-
};
|
|
8471
|
-
var fromCodePoint = function() {
|
|
8472
|
-
var codePoints = [];
|
|
8473
|
-
for (var _i = 0; _i < arguments.length; _i++) codePoints[_i] = arguments[_i];
|
|
8474
|
-
if (String.fromCodePoint) return String.fromCodePoint.apply(String, codePoints);
|
|
8475
|
-
var length = codePoints.length;
|
|
8476
|
-
if (!length) return "";
|
|
8477
|
-
var codeUnits = [];
|
|
8478
|
-
var index = -1;
|
|
8479
|
-
var result = "";
|
|
8480
|
-
while (++index < length) {
|
|
8481
|
-
var codePoint = codePoints[index];
|
|
8482
|
-
if (codePoint <= 65535) codeUnits.push(codePoint);
|
|
8483
|
-
else {
|
|
8484
|
-
codePoint -= 65536;
|
|
8485
|
-
codeUnits.push((codePoint >> 10) + 55296, codePoint % 1024 + 56320);
|
|
8486
|
-
}
|
|
8487
|
-
if (index + 1 === length || codeUnits.length > 16384) {
|
|
8488
|
-
result += String.fromCharCode.apply(String, codeUnits);
|
|
8489
|
-
codeUnits.length = 0;
|
|
8490
|
-
}
|
|
8491
|
-
}
|
|
8492
|
-
return result;
|
|
8493
|
-
};
|
|
8494
|
-
var UnicodeTrie = createTrieFromBase64(base64);
|
|
8495
|
-
var BREAK_NOT_ALLOWED = "×";
|
|
8496
|
-
var BREAK_ALLOWED = "÷";
|
|
8497
|
-
var codePointToClass = function(codePoint) {
|
|
8498
|
-
return UnicodeTrie.get(codePoint);
|
|
8499
|
-
};
|
|
8500
|
-
var _graphemeBreakAtIndex = function(_codePoints, classTypes, index) {
|
|
8501
|
-
var prevIndex = index - 2;
|
|
8502
|
-
var prev = classTypes[prevIndex];
|
|
8503
|
-
var current = classTypes[index - 1];
|
|
8504
|
-
var next = classTypes[index];
|
|
8505
|
-
if (current === CR && next === LF) return BREAK_NOT_ALLOWED;
|
|
8506
|
-
if (current === CR || current === LF || current === Control) return BREAK_ALLOWED;
|
|
8507
|
-
if (next === CR || next === LF || next === Control) return BREAK_ALLOWED;
|
|
8508
|
-
if (current === L && [
|
|
8509
|
-
L,
|
|
8510
|
-
V,
|
|
8511
|
-
LV,
|
|
8512
|
-
LVT
|
|
8513
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED;
|
|
8514
|
-
if ((current === LV || current === V) && (next === V || next === T)) return BREAK_NOT_ALLOWED;
|
|
8515
|
-
if ((current === LVT || current === T) && next === T) return BREAK_NOT_ALLOWED;
|
|
8516
|
-
if (next === ZWJ || next === Extend) return BREAK_NOT_ALLOWED;
|
|
8517
|
-
if (next === SpacingMark) return BREAK_NOT_ALLOWED;
|
|
8518
|
-
if (current === Prepend) return BREAK_NOT_ALLOWED;
|
|
8519
|
-
if (current === ZWJ && next === Extended_Pictographic) {
|
|
8520
|
-
while (prev === Extend) prev = classTypes[--prevIndex];
|
|
8521
|
-
if (prev === Extended_Pictographic) return BREAK_NOT_ALLOWED;
|
|
8522
|
-
}
|
|
8523
|
-
if (current === RI && next === RI) {
|
|
8524
|
-
var countRI = 0;
|
|
8525
|
-
while (prev === RI) {
|
|
8526
|
-
countRI++;
|
|
8527
|
-
prev = classTypes[--prevIndex];
|
|
8528
|
-
}
|
|
8529
|
-
if (countRI % 2 === 0) return BREAK_NOT_ALLOWED;
|
|
8530
|
-
}
|
|
8531
|
-
return BREAK_ALLOWED;
|
|
8532
|
-
};
|
|
8533
|
-
var GraphemeBreaker = function(str) {
|
|
8534
|
-
var codePoints = toCodePoints(str);
|
|
8535
|
-
var length = codePoints.length;
|
|
8536
|
-
var index = 0;
|
|
8537
|
-
var lastEnd = 0;
|
|
8538
|
-
var classTypes = codePoints.map(codePointToClass);
|
|
8539
|
-
return { next: function() {
|
|
8540
|
-
if (index >= length) return {
|
|
8541
|
-
done: true,
|
|
8542
|
-
value: null
|
|
8543
|
-
};
|
|
8544
|
-
var graphemeBreak = BREAK_NOT_ALLOWED;
|
|
8545
|
-
while (index < length && (graphemeBreak = _graphemeBreakAtIndex(codePoints, classTypes, ++index)) === BREAK_NOT_ALLOWED);
|
|
8546
|
-
if (graphemeBreak !== BREAK_NOT_ALLOWED || index === length) {
|
|
8547
|
-
var value = fromCodePoint.apply(null, codePoints.slice(lastEnd, index));
|
|
8548
|
-
lastEnd = index;
|
|
8549
|
-
return {
|
|
8550
|
-
value,
|
|
8551
|
-
done: false
|
|
8552
|
-
};
|
|
8553
|
-
}
|
|
8554
|
-
return {
|
|
8555
|
-
done: true,
|
|
8556
|
-
value: null
|
|
8557
|
-
};
|
|
8558
|
-
} };
|
|
8559
|
-
};
|
|
8560
|
-
var splitGraphemes = function(str) {
|
|
8561
|
-
var breaker = GraphemeBreaker(str);
|
|
8562
|
-
var graphemes = [];
|
|
8563
|
-
var bk;
|
|
8564
|
-
while (!(bk = breaker.next()).done) if (bk.value) graphemes.push(bk.value.slice());
|
|
8565
|
-
return graphemes;
|
|
8566
|
-
};
|
|
8567
|
-
//#endregion
|
|
8568
8566
|
//#region src/core/features.ts
|
|
8567
|
+
/**
|
|
8568
|
+
* Runtime feature detection.
|
|
8569
|
+
*
|
|
8570
|
+
* Only checks that still gate real behaviour are kept: range-bounds
|
|
8571
|
+
* measurement (iOS 13 quirk), SVG drawing and CORS image support.
|
|
8572
|
+
* Dead probes (IE-era CORS XHR / XHR response-type checks) were removed —
|
|
8573
|
+
* every supported browser exposes `crossOrigin`, `responseType` and
|
|
8574
|
+
* `withCredentials`; Intl.Segmenter is used unconditionally.
|
|
8575
|
+
*/
|
|
8569
8576
|
const testRangeBounds = (document) => {
|
|
8570
8577
|
const TEST_HEIGHT = 123;
|
|
8571
8578
|
if (document.createRange) {
|
|
@@ -8584,35 +8591,7 @@ const testRangeBounds = (document) => {
|
|
|
8584
8591
|
}
|
|
8585
8592
|
return false;
|
|
8586
8593
|
};
|
|
8587
|
-
const testIOSLineBreak = (document) => {
|
|
8588
|
-
const testElement = document.createElement("boundtest");
|
|
8589
|
-
testElement.style.width = "50px";
|
|
8590
|
-
testElement.style.display = "block";
|
|
8591
|
-
testElement.style.fontSize = "12px";
|
|
8592
|
-
testElement.style.letterSpacing = "0px";
|
|
8593
|
-
testElement.style.wordSpacing = "0px";
|
|
8594
|
-
document.body.appendChild(testElement);
|
|
8595
|
-
const range = document.createRange();
|
|
8596
|
-
testElement.innerHTML = typeof "".repeat === "function" ? "👨".repeat(10) : "";
|
|
8597
|
-
const node = testElement.firstChild;
|
|
8598
|
-
const textList = toCodePoints$1(node.data).map((i) => fromCodePoint$1(i));
|
|
8599
|
-
let offset = 0;
|
|
8600
|
-
let prev = {};
|
|
8601
|
-
const supports = textList.every((text, i) => {
|
|
8602
|
-
range.setStart(node, offset);
|
|
8603
|
-
range.setEnd(node, offset + text.length);
|
|
8604
|
-
const rect = range.getBoundingClientRect();
|
|
8605
|
-
offset += text.length;
|
|
8606
|
-
const boundAhead = rect.x > prev.x || rect.y > prev.y;
|
|
8607
|
-
prev = rect;
|
|
8608
|
-
if (i === 0) return true;
|
|
8609
|
-
return boundAhead;
|
|
8610
|
-
});
|
|
8611
|
-
document.body.removeChild(testElement);
|
|
8612
|
-
return supports;
|
|
8613
|
-
};
|
|
8614
8594
|
const testCORS = () => typeof new Image().crossOrigin !== "undefined";
|
|
8615
|
-
const testResponseType = () => typeof new XMLHttpRequest().responseType === "string";
|
|
8616
8595
|
const testSVG = (document) => {
|
|
8617
8596
|
const img = new Image();
|
|
8618
8597
|
const canvas = document.createElement("canvas");
|
|
@@ -8627,36 +8606,6 @@ const testSVG = (document) => {
|
|
|
8627
8606
|
}
|
|
8628
8607
|
return true;
|
|
8629
8608
|
};
|
|
8630
|
-
const isGreenPixel = (data) => data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255;
|
|
8631
|
-
const testForeignObject = (document) => {
|
|
8632
|
-
const canvas = document.createElement("canvas");
|
|
8633
|
-
const size = 100;
|
|
8634
|
-
canvas.width = size;
|
|
8635
|
-
canvas.height = size;
|
|
8636
|
-
const ctx = canvas.getContext("2d");
|
|
8637
|
-
if (!ctx) return Promise.reject(/* @__PURE__ */ new Error("Failed to get 2D rendering context"));
|
|
8638
|
-
ctx.fillStyle = "rgb(0, 255, 0)";
|
|
8639
|
-
ctx.fillRect(0, 0, size, size);
|
|
8640
|
-
const img = new Image();
|
|
8641
|
-
const greenImageSrc = canvas.toDataURL();
|
|
8642
|
-
img.src = greenImageSrc;
|
|
8643
|
-
const svg = createForeignObjectSVG(size, size, 0, 0, img);
|
|
8644
|
-
ctx.fillStyle = "red";
|
|
8645
|
-
ctx.fillRect(0, 0, size, size);
|
|
8646
|
-
return loadSerializedSVG(svg).then((img) => {
|
|
8647
|
-
ctx.drawImage(img, 0, 0);
|
|
8648
|
-
const data = ctx.getImageData(0, 0, size, size).data;
|
|
8649
|
-
ctx.fillStyle = "red";
|
|
8650
|
-
ctx.fillRect(0, 0, size, size);
|
|
8651
|
-
const node = document.createElement("div");
|
|
8652
|
-
node.style.backgroundImage = `url(${greenImageSrc})`;
|
|
8653
|
-
node.style.height = `${size}px`;
|
|
8654
|
-
return isGreenPixel(data) ? loadSerializedSVG(createForeignObjectSVG(size, size, 0, 0, node)) : Promise.reject(/* @__PURE__ */ new Error("ForeignObject rendering not supported"));
|
|
8655
|
-
}).then((img) => {
|
|
8656
|
-
ctx.drawImage(img, 0, 0);
|
|
8657
|
-
return isGreenPixel(ctx.getImageData(0, 0, size, size).data);
|
|
8658
|
-
}).catch(() => false);
|
|
8659
|
-
};
|
|
8660
8609
|
const createForeignObjectSVG = (width, height, x, y, node) => {
|
|
8661
8610
|
const xmlns = "http://www.w3.org/2000/svg";
|
|
8662
8611
|
const svg = document.createElementNS(xmlns, "svg");
|
|
@@ -8687,52 +8636,24 @@ const FEATURES = {
|
|
|
8687
8636
|
Object.defineProperty(FEATURES, "SUPPORT_RANGE_BOUNDS", { value });
|
|
8688
8637
|
return value;
|
|
8689
8638
|
},
|
|
8690
|
-
get SUPPORT_WORD_BREAKING() {
|
|
8691
|
-
"use strict";
|
|
8692
|
-
const value = FEATURES.SUPPORT_RANGE_BOUNDS && testIOSLineBreak(document);
|
|
8693
|
-
Object.defineProperty(FEATURES, "SUPPORT_WORD_BREAKING", { value });
|
|
8694
|
-
return value;
|
|
8695
|
-
},
|
|
8696
8639
|
get SUPPORT_SVG_DRAWING() {
|
|
8697
8640
|
"use strict";
|
|
8698
8641
|
const value = testSVG(document);
|
|
8699
8642
|
Object.defineProperty(FEATURES, "SUPPORT_SVG_DRAWING", { value });
|
|
8700
8643
|
return value;
|
|
8701
8644
|
},
|
|
8702
|
-
get SUPPORT_FOREIGNOBJECT_DRAWING() {
|
|
8703
|
-
"use strict";
|
|
8704
|
-
const value = typeof Array.from === "function" && typeof window.fetch === "function" ? testForeignObject(document) : Promise.resolve(false);
|
|
8705
|
-
Object.defineProperty(FEATURES, "SUPPORT_FOREIGNOBJECT_DRAWING", { value });
|
|
8706
|
-
return value;
|
|
8707
|
-
},
|
|
8708
8645
|
get SUPPORT_CORS_IMAGES() {
|
|
8709
8646
|
"use strict";
|
|
8710
8647
|
const value = testCORS();
|
|
8711
8648
|
Object.defineProperty(FEATURES, "SUPPORT_CORS_IMAGES", { value });
|
|
8712
8649
|
return value;
|
|
8713
|
-
},
|
|
8714
|
-
get SUPPORT_RESPONSE_TYPE() {
|
|
8715
|
-
"use strict";
|
|
8716
|
-
const value = testResponseType();
|
|
8717
|
-
Object.defineProperty(FEATURES, "SUPPORT_RESPONSE_TYPE", { value });
|
|
8718
|
-
return value;
|
|
8719
|
-
},
|
|
8720
|
-
get SUPPORT_CORS_XHR() {
|
|
8721
|
-
"use strict";
|
|
8722
|
-
const value = "withCredentials" in new XMLHttpRequest();
|
|
8723
|
-
Object.defineProperty(FEATURES, "SUPPORT_CORS_XHR", { value });
|
|
8724
|
-
return value;
|
|
8725
|
-
},
|
|
8726
|
-
get SUPPORT_NATIVE_TEXT_SEGMENTATION() {
|
|
8727
|
-
"use strict";
|
|
8728
|
-
const value = !!(typeof Intl !== "undefined" && Intl.Segmenter);
|
|
8729
|
-
Object.defineProperty(FEATURES, "SUPPORT_NATIVE_TEXT_SEGMENTATION", { value });
|
|
8730
|
-
return value;
|
|
8731
8650
|
}
|
|
8732
8651
|
};
|
|
8733
8652
|
//#endregion
|
|
8734
8653
|
//#region src/css/layout/text.ts
|
|
8735
8654
|
var TextBounds = class {
|
|
8655
|
+
text;
|
|
8656
|
+
bounds;
|
|
8736
8657
|
constructor(text, bounds) {
|
|
8737
8658
|
this.text = text;
|
|
8738
8659
|
this.bounds = bounds;
|
|
@@ -8791,58 +8712,24 @@ const segmenterCache = /* @__PURE__ */ new Map();
|
|
|
8791
8712
|
const getSegmenter = (granularity) => {
|
|
8792
8713
|
let segmenter = segmenterCache.get(granularity);
|
|
8793
8714
|
if (!segmenter) {
|
|
8794
|
-
|
|
8795
|
-
segmenter = new Segmenter(void 0, { granularity });
|
|
8715
|
+
segmenter = new Intl.Segmenter(void 0, { granularity });
|
|
8796
8716
|
segmenterCache.set(granularity, segmenter);
|
|
8797
8717
|
}
|
|
8798
8718
|
return segmenter;
|
|
8799
8719
|
};
|
|
8800
|
-
const segmentGraphemes = (value) =>
|
|
8801
|
-
|
|
8802
|
-
return
|
|
8803
|
-
};
|
|
8804
|
-
const segmentWords = (value, styles) => {
|
|
8805
|
-
if (FEATURES.SUPPORT_NATIVE_TEXT_SEGMENTATION) return Array.from(getSegmenter("word").segment(value)).map((s) => s.segment);
|
|
8806
|
-
return breakWords(value, styles);
|
|
8720
|
+
const segmentGraphemes = (value) => Array.from(getSegmenter("grapheme").segment(value), (s) => s.segment);
|
|
8721
|
+
const segmentWords = (value) => {
|
|
8722
|
+
return Array.from(getSegmenter("word").segment(value), (s) => s.segment);
|
|
8807
8723
|
};
|
|
8808
8724
|
const breakText = (value, styles) => {
|
|
8809
8725
|
if (isVerticalWritingMode(styles.writingMode)) return segmentGraphemes(value);
|
|
8810
|
-
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value
|
|
8811
|
-
};
|
|
8812
|
-
const wordSeparators = [
|
|
8813
|
-
32,
|
|
8814
|
-
160,
|
|
8815
|
-
4961,
|
|
8816
|
-
65792,
|
|
8817
|
-
65793,
|
|
8818
|
-
4153,
|
|
8819
|
-
4241
|
|
8820
|
-
];
|
|
8821
|
-
const breakWords = (str, styles) => {
|
|
8822
|
-
const breaker = LineBreaker(str, {
|
|
8823
|
-
lineBreak: styles.lineBreak,
|
|
8824
|
-
wordBreak: styles.overflowWrap === "break-word" ? "break-word" : styles.wordBreak
|
|
8825
|
-
});
|
|
8826
|
-
const words = [];
|
|
8827
|
-
let bk;
|
|
8828
|
-
while (!(bk = breaker.next()).done) if (bk.value) {
|
|
8829
|
-
const codePoints = toCodePoints$1(bk.value.slice());
|
|
8830
|
-
let word = "";
|
|
8831
|
-
codePoints.forEach((codePoint) => {
|
|
8832
|
-
if (wordSeparators.indexOf(codePoint) === -1) word += fromCodePoint$1(codePoint);
|
|
8833
|
-
else {
|
|
8834
|
-
if (word.length) words.push(word);
|
|
8835
|
-
words.push(fromCodePoint$1(codePoint));
|
|
8836
|
-
word = "";
|
|
8837
|
-
}
|
|
8838
|
-
});
|
|
8839
|
-
if (word.length) words.push(word);
|
|
8840
|
-
}
|
|
8841
|
-
return words;
|
|
8726
|
+
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value);
|
|
8842
8727
|
};
|
|
8843
8728
|
//#endregion
|
|
8844
8729
|
//#region src/dom/text-container.ts
|
|
8845
8730
|
var TextContainer = class {
|
|
8731
|
+
text;
|
|
8732
|
+
textBounds;
|
|
8846
8733
|
constructor(context, node, styles) {
|
|
8847
8734
|
this.text = transform(node.data, styles.textTransform);
|
|
8848
8735
|
if (this.text.length !== node.data.length) node.data = this.text;
|
|
@@ -8865,8 +8752,11 @@ const capitalize = (m, p1, p2) => {
|
|
|
8865
8752
|
//#endregion
|
|
8866
8753
|
//#region src/dom/replaced-elements/image-element-container.ts
|
|
8867
8754
|
var ImageElementContainer = class extends ElementContainer {
|
|
8868
|
-
|
|
8869
|
-
|
|
8755
|
+
src;
|
|
8756
|
+
intrinsicWidth;
|
|
8757
|
+
intrinsicHeight;
|
|
8758
|
+
constructor(context, img, options = {}) {
|
|
8759
|
+
super(context, img, options);
|
|
8870
8760
|
this.src = img.currentSrc || img.src;
|
|
8871
8761
|
this.intrinsicWidth = img.naturalWidth;
|
|
8872
8762
|
this.intrinsicHeight = img.naturalHeight;
|
|
@@ -8876,8 +8766,11 @@ var ImageElementContainer = class extends ElementContainer {
|
|
|
8876
8766
|
//#endregion
|
|
8877
8767
|
//#region src/dom/replaced-elements/canvas-element-container.ts
|
|
8878
8768
|
var CanvasElementContainer = class extends ElementContainer {
|
|
8879
|
-
|
|
8880
|
-
|
|
8769
|
+
canvas;
|
|
8770
|
+
intrinsicWidth;
|
|
8771
|
+
intrinsicHeight;
|
|
8772
|
+
constructor(context, canvas, options = {}) {
|
|
8773
|
+
super(context, canvas, options);
|
|
8881
8774
|
this.canvas = canvas;
|
|
8882
8775
|
this.intrinsicWidth = canvas.width;
|
|
8883
8776
|
this.intrinsicHeight = canvas.height;
|
|
@@ -8919,8 +8812,11 @@ const serializeWithoutBoxOffsets = (serializer, img) => {
|
|
|
8919
8812
|
return serialized;
|
|
8920
8813
|
};
|
|
8921
8814
|
var SVGElementContainer = class extends ElementContainer {
|
|
8922
|
-
|
|
8923
|
-
|
|
8815
|
+
svg;
|
|
8816
|
+
intrinsicWidth;
|
|
8817
|
+
intrinsicHeight;
|
|
8818
|
+
constructor(context, img, options = {}) {
|
|
8819
|
+
super(context, img, options);
|
|
8924
8820
|
const s = new XMLSerializer();
|
|
8925
8821
|
const bounds = parseBounds(context, img);
|
|
8926
8822
|
img.setAttribute("width", `${bounds.width}px`);
|
|
@@ -8934,16 +8830,19 @@ var SVGElementContainer = class extends ElementContainer {
|
|
|
8934
8830
|
//#endregion
|
|
8935
8831
|
//#region src/dom/elements/li-element-container.ts
|
|
8936
8832
|
var LIElementContainer = class extends ElementContainer {
|
|
8937
|
-
|
|
8938
|
-
|
|
8833
|
+
value;
|
|
8834
|
+
constructor(context, element, options = {}) {
|
|
8835
|
+
super(context, element, options);
|
|
8939
8836
|
this.value = element.value;
|
|
8940
8837
|
}
|
|
8941
8838
|
};
|
|
8942
8839
|
//#endregion
|
|
8943
8840
|
//#region src/dom/elements/ol-element-container.ts
|
|
8944
8841
|
var OLElementContainer = class extends ElementContainer {
|
|
8945
|
-
|
|
8946
|
-
|
|
8842
|
+
start;
|
|
8843
|
+
reversed;
|
|
8844
|
+
constructor(context, element, options = {}) {
|
|
8845
|
+
super(context, element, options);
|
|
8947
8846
|
this.start = element.start;
|
|
8948
8847
|
this.reversed = typeof element.reversed === "boolean" && element.reversed === true;
|
|
8949
8848
|
}
|
|
@@ -8977,8 +8876,12 @@ const CHECKBOX = "checkbox";
|
|
|
8977
8876
|
const RADIO = "radio";
|
|
8978
8877
|
const PLACEHOLDER_COLOR = 1970632191;
|
|
8979
8878
|
var InputElementContainer = class extends ElementContainer {
|
|
8980
|
-
|
|
8981
|
-
|
|
8879
|
+
type;
|
|
8880
|
+
checked;
|
|
8881
|
+
value;
|
|
8882
|
+
isPlaceholder;
|
|
8883
|
+
constructor(context, input, options = {}) {
|
|
8884
|
+
super(context, input, options);
|
|
8982
8885
|
this.type = input.type.toLowerCase();
|
|
8983
8886
|
this.checked = input.checked;
|
|
8984
8887
|
this.value = getInputValue(input);
|
|
@@ -9003,8 +8906,9 @@ var InputElementContainer = class extends ElementContainer {
|
|
|
9003
8906
|
//#endregion
|
|
9004
8907
|
//#region src/dom/elements/select-element-container.ts
|
|
9005
8908
|
var SelectElementContainer = class extends ElementContainer {
|
|
9006
|
-
|
|
9007
|
-
|
|
8909
|
+
value;
|
|
8910
|
+
constructor(context, element, options = {}) {
|
|
8911
|
+
super(context, element, options);
|
|
9008
8912
|
const option = element.options[element.selectedIndex || 0];
|
|
9009
8913
|
this.value = option ? option.text || "" : "";
|
|
9010
8914
|
}
|
|
@@ -9012,29 +8916,42 @@ var SelectElementContainer = class extends ElementContainer {
|
|
|
9012
8916
|
//#endregion
|
|
9013
8917
|
//#region src/dom/elements/textarea-element-container.ts
|
|
9014
8918
|
var TextareaElementContainer = class extends ElementContainer {
|
|
9015
|
-
|
|
9016
|
-
|
|
8919
|
+
value;
|
|
8920
|
+
constructor(context, element, options = {}) {
|
|
8921
|
+
super(context, element, options);
|
|
9017
8922
|
this.value = element.value;
|
|
9018
8923
|
}
|
|
9019
8924
|
};
|
|
9020
8925
|
//#endregion
|
|
9021
8926
|
//#region src/dom/replaced-elements/iframe-element-container.ts
|
|
9022
8927
|
var IFrameElementContainer = class extends ElementContainer {
|
|
9023
|
-
|
|
9024
|
-
|
|
8928
|
+
src;
|
|
8929
|
+
width;
|
|
8930
|
+
height;
|
|
8931
|
+
tree;
|
|
8932
|
+
backgroundColor;
|
|
8933
|
+
parseTreeFn;
|
|
8934
|
+
constructor(context, iframe, parseTreeFn, options = {}) {
|
|
8935
|
+
super(context, iframe, options);
|
|
9025
8936
|
this.src = iframe.src;
|
|
9026
8937
|
this.width = parseInt(iframe.width, 10) || 0;
|
|
9027
8938
|
this.height = parseInt(iframe.height, 10) || 0;
|
|
9028
8939
|
this.backgroundColor = this.styles.backgroundColor;
|
|
9029
8940
|
this.parseTreeFn = parseTreeFn;
|
|
9030
8941
|
try {
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
8942
|
+
const contentWindow = iframe.contentWindow;
|
|
8943
|
+
const contentDocument = contentWindow?.document;
|
|
8944
|
+
if (contentWindow && contentDocument && contentDocument.documentElement && this.parseTreeFn) {
|
|
8945
|
+
this.tree = this.parseTreeFn(context, contentDocument.documentElement);
|
|
8946
|
+
const documentBackgroundColor = parseColor(context, contentWindow.getComputedStyle(contentDocument.documentElement).backgroundColor);
|
|
8947
|
+
const bodyBackgroundColor = contentDocument.body ? parseColor(context, contentWindow.getComputedStyle(contentDocument.body).backgroundColor) : 0;
|
|
9035
8948
|
this.backgroundColor = isTransparent(documentBackgroundColor) ? isTransparent(bodyBackgroundColor) ? this.styles.backgroundColor : bodyBackgroundColor : documentBackgroundColor;
|
|
9036
8949
|
}
|
|
9037
|
-
} catch (e) {
|
|
8950
|
+
} catch (e) {
|
|
8951
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
8952
|
+
this.context.logger.warn(`Unable to render iframe content${this.src ? ` from ${this.src}` : ""}: ${error.message}`);
|
|
8953
|
+
this.context.onError?.(error);
|
|
8954
|
+
}
|
|
9038
8955
|
}
|
|
9039
8956
|
};
|
|
9040
8957
|
//#endregion
|
|
@@ -9044,10 +8961,10 @@ const LIST_OWNERS = [
|
|
|
9044
8961
|
"UL",
|
|
9045
8962
|
"MENU"
|
|
9046
8963
|
];
|
|
9047
|
-
const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
8964
|
+
const parseNodeTree = (context, node, parent, root, zoomScale = 1, options = {}) => {
|
|
9048
8965
|
for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
|
|
9049
8966
|
nextNode = childNode.nextSibling;
|
|
9050
|
-
parseChildNode(context, childNode, parent, root, zoomScale);
|
|
8967
|
+
parseChildNode(context, childNode, parent, root, zoomScale, options);
|
|
9051
8968
|
}
|
|
9052
8969
|
};
|
|
9053
8970
|
/**
|
|
@@ -9058,7 +8975,7 @@ const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
|
9058
8975
|
* this, slotted shadow-DOM content such as web component labels was silently
|
|
9059
8976
|
* dropped because `parseNodeTree` only iterates `node.firstChild` (issue #226).
|
|
9060
8977
|
*/
|
|
9061
|
-
const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
8978
|
+
const parseChildNode = (context, childNode, parent, root, zoomScale = 1, options = {}) => {
|
|
9062
8979
|
if (isTextNode(childNode) && childNode.data.length > 0) {
|
|
9063
8980
|
const textContainer = new TextContainer(context, childNode, parent.styles);
|
|
9064
8981
|
if (zoomScale !== 1) {
|
|
@@ -9068,9 +8985,9 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9068
8985
|
}
|
|
9069
8986
|
parent.textNodes.push(textContainer);
|
|
9070
8987
|
} else if (isElementNode(childNode)) {
|
|
9071
|
-
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale));
|
|
8988
|
+
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale, options));
|
|
9072
8989
|
else {
|
|
9073
|
-
const container = createContainer(context, childNode);
|
|
8990
|
+
const container = createContainer(context, childNode, options);
|
|
9074
8991
|
const ownZoom = container.styles.zoom || 1;
|
|
9075
8992
|
if (ownZoom !== 1) container.bounds = new Bounds(container.bounds.left, container.bounds.top, container.bounds.width / ownZoom, container.bounds.height / ownZoom);
|
|
9076
8993
|
if (container.styles.isVisible()) {
|
|
@@ -9079,28 +8996,28 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9079
8996
|
if (LIST_OWNERS.indexOf(childNode.tagName) !== -1) container.isListOwner = true;
|
|
9080
8997
|
parent.elements.push(container);
|
|
9081
8998
|
const childZoom = zoomScale * (container.styles.zoom || 1);
|
|
9082
|
-
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom);
|
|
9083
|
-
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom);
|
|
8999
|
+
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom, options);
|
|
9000
|
+
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom, options);
|
|
9084
9001
|
}
|
|
9085
9002
|
}
|
|
9086
9003
|
}
|
|
9087
9004
|
};
|
|
9088
|
-
const createContainer = (context, element) => {
|
|
9089
|
-
if (isImageElement(element)) return new ImageElementContainer(context, element);
|
|
9090
|
-
if (isCanvasElement(element)) return new CanvasElementContainer(context, element);
|
|
9091
|
-
if (isSVGElement(element)) return new SVGElementContainer(context, element);
|
|
9092
|
-
if (isLIElement(element)) return new LIElementContainer(context, element);
|
|
9093
|
-
if (isOLElement(element)) return new OLElementContainer(context, element);
|
|
9094
|
-
if (isInputElement(element)) return new InputElementContainer(context, element);
|
|
9095
|
-
if (isSelectElement(element)) return new SelectElementContainer(context, element);
|
|
9096
|
-
if (isTextareaElement(element)) return new TextareaElementContainer(context, element);
|
|
9097
|
-
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, parseTree);
|
|
9098
|
-
return new ElementContainer(context, element);
|
|
9005
|
+
const createContainer = (context, element, options = {}) => {
|
|
9006
|
+
if (isImageElement(element)) return new ImageElementContainer(context, element, options);
|
|
9007
|
+
if (isCanvasElement(element)) return new CanvasElementContainer(context, element, options);
|
|
9008
|
+
if (isSVGElement(element)) return new SVGElementContainer(context, element, options);
|
|
9009
|
+
if (isLIElement(element)) return new LIElementContainer(context, element, options);
|
|
9010
|
+
if (isOLElement(element)) return new OLElementContainer(context, element, options);
|
|
9011
|
+
if (isInputElement(element)) return new InputElementContainer(context, element, options);
|
|
9012
|
+
if (isSelectElement(element)) return new SelectElementContainer(context, element, options);
|
|
9013
|
+
if (isTextareaElement(element)) return new TextareaElementContainer(context, element, options);
|
|
9014
|
+
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, (ctx, node) => parseTree(ctx, node, options), options);
|
|
9015
|
+
return new ElementContainer(context, element, options);
|
|
9099
9016
|
};
|
|
9100
|
-
const parseTree = (context, element) => {
|
|
9101
|
-
const container = createContainer(context, element);
|
|
9017
|
+
const parseTree = (context, element, options = {}) => {
|
|
9018
|
+
const container = createContainer(context, element, options);
|
|
9102
9019
|
container.createsRealStackingContext = true;
|
|
9103
|
-
parseNodeTree(context, element, container, container);
|
|
9020
|
+
parseNodeTree(context, element, container, container, 1, options);
|
|
9104
9021
|
return container;
|
|
9105
9022
|
};
|
|
9106
9023
|
const createsRealStackingContext = (node, container, root) => {
|
|
@@ -9131,6 +9048,9 @@ const transformPath = (path, deltaX, deltaY, deltaW, deltaH) => {
|
|
|
9131
9048
|
//#endregion
|
|
9132
9049
|
//#region src/render/vector.ts
|
|
9133
9050
|
var Vector = class Vector {
|
|
9051
|
+
type;
|
|
9052
|
+
x;
|
|
9053
|
+
y;
|
|
9134
9054
|
constructor(x, y) {
|
|
9135
9055
|
this.type = 0;
|
|
9136
9056
|
this.x = x;
|
|
@@ -9146,6 +9066,11 @@ const lerp = (a, b, t) => {
|
|
|
9146
9066
|
return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
|
|
9147
9067
|
};
|
|
9148
9068
|
var BezierCurve = class BezierCurve {
|
|
9069
|
+
type;
|
|
9070
|
+
start;
|
|
9071
|
+
startControl;
|
|
9072
|
+
endControl;
|
|
9073
|
+
end;
|
|
9149
9074
|
constructor(start, startControl, endControl, end) {
|
|
9150
9075
|
this.type = 1;
|
|
9151
9076
|
this.start = start;
|
|
@@ -9173,6 +9098,30 @@ const isBezierCurve = (path) => path.type === 1;
|
|
|
9173
9098
|
//#endregion
|
|
9174
9099
|
//#region src/render/bound-curves.ts
|
|
9175
9100
|
var BoundCurves = class {
|
|
9101
|
+
topLeftBorderDoubleOuterBox;
|
|
9102
|
+
topRightBorderDoubleOuterBox;
|
|
9103
|
+
bottomRightBorderDoubleOuterBox;
|
|
9104
|
+
bottomLeftBorderDoubleOuterBox;
|
|
9105
|
+
topLeftBorderDoubleInnerBox;
|
|
9106
|
+
topRightBorderDoubleInnerBox;
|
|
9107
|
+
bottomRightBorderDoubleInnerBox;
|
|
9108
|
+
bottomLeftBorderDoubleInnerBox;
|
|
9109
|
+
topLeftBorderStroke;
|
|
9110
|
+
topRightBorderStroke;
|
|
9111
|
+
bottomRightBorderStroke;
|
|
9112
|
+
bottomLeftBorderStroke;
|
|
9113
|
+
topLeftBorderBox;
|
|
9114
|
+
topRightBorderBox;
|
|
9115
|
+
bottomRightBorderBox;
|
|
9116
|
+
bottomLeftBorderBox;
|
|
9117
|
+
topLeftPaddingBox;
|
|
9118
|
+
topRightPaddingBox;
|
|
9119
|
+
bottomRightPaddingBox;
|
|
9120
|
+
bottomLeftPaddingBox;
|
|
9121
|
+
topLeftContentBox;
|
|
9122
|
+
topRightContentBox;
|
|
9123
|
+
bottomRightContentBox;
|
|
9124
|
+
bottomLeftContentBox;
|
|
9176
9125
|
constructor(element) {
|
|
9177
9126
|
const styles = element.styles;
|
|
9178
9127
|
const bounds = element.bounds;
|
|
@@ -9209,15 +9158,15 @@ var BoundCurves = class {
|
|
|
9209
9158
|
const paddingBottom = getAbsoluteValue(styles.paddingBottom, element.bounds.width);
|
|
9210
9159
|
const paddingLeft = getAbsoluteValue(styles.paddingLeft, element.bounds.width);
|
|
9211
9160
|
this.topLeftBorderDoubleOuterBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 3, bounds.top + borderTopWidth / 3, tlh - borderLeftWidth / 3, tlv - borderTopWidth / 3, 0) : new Vector(bounds.left + borderLeftWidth / 3, bounds.top + borderTopWidth / 3);
|
|
9212
|
-
this.topRightBorderDoubleOuterBox =
|
|
9161
|
+
this.topRightBorderDoubleOuterBox = trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth / 3, trh - borderRightWidth / 3, trv - borderTopWidth / 3, 1) : new Vector(bounds.left + bounds.width - borderRightWidth / 3, bounds.top + borderTopWidth / 3);
|
|
9213
9162
|
this.bottomRightBorderDoubleOuterBox = brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth / 3, brv - borderBottomWidth / 3, 2) : new Vector(bounds.left + bounds.width - borderRightWidth / 3, bounds.top + bounds.height - borderBottomWidth / 3);
|
|
9214
9163
|
this.bottomLeftBorderDoubleOuterBox = blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 3, bounds.top + leftHeight, blh - borderLeftWidth / 3, blv - borderBottomWidth / 3, 3) : new Vector(bounds.left + borderLeftWidth / 3, bounds.top + bounds.height - borderBottomWidth / 3);
|
|
9215
9164
|
this.topLeftBorderDoubleInnerBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borderLeftWidth * 2 / 3, bounds.top + borderTopWidth * 2 / 3, tlh - borderLeftWidth * 2 / 3, tlv - borderTopWidth * 2 / 3, 0) : new Vector(bounds.left + borderLeftWidth * 2 / 3, bounds.top + borderTopWidth * 2 / 3);
|
|
9216
|
-
this.topRightBorderDoubleInnerBox =
|
|
9165
|
+
this.topRightBorderDoubleInnerBox = trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth * 2 / 3, trh - borderRightWidth * 2 / 3, trv - borderTopWidth * 2 / 3, 1) : new Vector(bounds.left + bounds.width - borderRightWidth * 2 / 3, bounds.top + borderTopWidth * 2 / 3);
|
|
9217
9166
|
this.bottomRightBorderDoubleInnerBox = brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth * 2 / 3, brv - borderBottomWidth * 2 / 3, 2) : new Vector(bounds.left + bounds.width - borderRightWidth * 2 / 3, bounds.top + bounds.height - borderBottomWidth * 2 / 3);
|
|
9218
9167
|
this.bottomLeftBorderDoubleInnerBox = blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borderLeftWidth * 2 / 3, bounds.top + leftHeight, blh - borderLeftWidth * 2 / 3, blv - borderBottomWidth * 2 / 3, 3) : new Vector(bounds.left + borderLeftWidth * 2 / 3, bounds.top + bounds.height - borderBottomWidth * 2 / 3);
|
|
9219
9168
|
this.topLeftBorderStroke = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 2, bounds.top + borderTopWidth / 2, tlh - borderLeftWidth / 2, tlv - borderTopWidth / 2, 0) : new Vector(bounds.left + borderLeftWidth / 2, bounds.top + borderTopWidth / 2);
|
|
9220
|
-
this.topRightBorderStroke =
|
|
9169
|
+
this.topRightBorderStroke = trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth / 2, trh - borderRightWidth / 2, trv - borderTopWidth / 2, 1) : new Vector(bounds.left + bounds.width - borderRightWidth / 2, bounds.top + borderTopWidth / 2);
|
|
9221
9170
|
this.bottomRightBorderStroke = brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth / 2, brv - borderBottomWidth / 2, 2) : new Vector(bounds.left + bounds.width - borderRightWidth / 2, bounds.top + bounds.height - borderBottomWidth / 2);
|
|
9222
9171
|
this.bottomLeftBorderStroke = blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 2, bounds.top + leftHeight, blh - borderLeftWidth / 2, blv - borderBottomWidth / 2, 3) : new Vector(bounds.left + borderLeftWidth / 2, bounds.top + bounds.height - borderBottomWidth / 2);
|
|
9223
9172
|
this.topLeftBorderBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, 0) : new Vector(bounds.left, bounds.top);
|
|
@@ -9274,26 +9223,32 @@ const calculatePaddingBoxPath = (curves) => {
|
|
|
9274
9223
|
//#endregion
|
|
9275
9224
|
//#region src/render/effects.ts
|
|
9276
9225
|
var TransformEffect = class {
|
|
9226
|
+
offsetX;
|
|
9227
|
+
offsetY;
|
|
9228
|
+
matrix;
|
|
9229
|
+
type = 0;
|
|
9230
|
+
target = 6;
|
|
9277
9231
|
constructor(offsetX, offsetY, matrix) {
|
|
9278
9232
|
this.offsetX = offsetX;
|
|
9279
9233
|
this.offsetY = offsetY;
|
|
9280
9234
|
this.matrix = matrix;
|
|
9281
|
-
this.type = 0;
|
|
9282
|
-
this.target = 6;
|
|
9283
9235
|
}
|
|
9284
9236
|
};
|
|
9285
9237
|
var ClipEffect = class {
|
|
9238
|
+
path;
|
|
9239
|
+
target;
|
|
9240
|
+
type = 1;
|
|
9286
9241
|
constructor(path, target) {
|
|
9287
9242
|
this.path = path;
|
|
9288
9243
|
this.target = target;
|
|
9289
|
-
this.type = 1;
|
|
9290
9244
|
}
|
|
9291
9245
|
};
|
|
9292
9246
|
var OpacityEffect = class {
|
|
9247
|
+
opacity;
|
|
9248
|
+
type = 2;
|
|
9249
|
+
target = 6;
|
|
9293
9250
|
constructor(opacity) {
|
|
9294
9251
|
this.opacity = opacity;
|
|
9295
|
-
this.type = 2;
|
|
9296
|
-
this.target = 6;
|
|
9297
9252
|
}
|
|
9298
9253
|
};
|
|
9299
9254
|
/**
|
|
@@ -9303,10 +9258,11 @@ var OpacityEffect = class {
|
|
|
9303
9258
|
* the path is constructed (arc, ellipse, lineTo, Path2D, etc.).
|
|
9304
9259
|
*/
|
|
9305
9260
|
var ClipPathEffect = class {
|
|
9261
|
+
applyClip;
|
|
9262
|
+
type = 3;
|
|
9263
|
+
target = 6;
|
|
9306
9264
|
constructor(applyClip) {
|
|
9307
9265
|
this.applyClip = applyClip;
|
|
9308
|
-
this.type = 3;
|
|
9309
|
-
this.target = 6;
|
|
9310
9266
|
}
|
|
9311
9267
|
};
|
|
9312
9268
|
/**
|
|
@@ -9333,17 +9289,23 @@ const MIX_BLEND_MODE_TO_COMPOSITE = {
|
|
|
9333
9289
|
[MIX_BLEND_MODE$1.LUMINOSITY]: "luminosity"
|
|
9334
9290
|
};
|
|
9335
9291
|
var BlendEffect = class {
|
|
9292
|
+
mixBlendMode;
|
|
9293
|
+
type = 4;
|
|
9294
|
+
target = 6;
|
|
9295
|
+
compositeOperation;
|
|
9336
9296
|
constructor(mixBlendMode) {
|
|
9337
9297
|
this.mixBlendMode = mixBlendMode;
|
|
9338
|
-
this.type = 4;
|
|
9339
|
-
this.target = 6;
|
|
9340
9298
|
this.compositeOperation = MIX_BLEND_MODE_TO_COMPOSITE[mixBlendMode];
|
|
9341
9299
|
}
|
|
9342
9300
|
};
|
|
9343
9301
|
var FilterEffect = class FilterEffect {
|
|
9302
|
+
type = 5;
|
|
9303
|
+
target = 6;
|
|
9304
|
+
/** CSS filter string with drop-shadow() stripped (safe for ctx.filter). */
|
|
9305
|
+
safeFilterString;
|
|
9306
|
+
/** Shadow params for drop-shadow(), if present and successfully parsed. */
|
|
9307
|
+
shadow;
|
|
9344
9308
|
constructor(filterString) {
|
|
9345
|
-
this.type = 5;
|
|
9346
|
-
this.target = 6;
|
|
9347
9309
|
const parsed = FilterEffect.parseDropShadow(filterString);
|
|
9348
9310
|
this.shadow = parsed.shadow;
|
|
9349
9311
|
this.safeFilterString = parsed.safeFilterString;
|
|
@@ -9469,6 +9431,14 @@ const isFilterEffect = (effect) => effect.type === 5;
|
|
|
9469
9431
|
//#endregion
|
|
9470
9432
|
//#region src/render/stacking-context.ts
|
|
9471
9433
|
var StackingContext = class {
|
|
9434
|
+
element;
|
|
9435
|
+
negativeZIndex;
|
|
9436
|
+
zeroOrAutoZIndexOrTransformedOrOpacity;
|
|
9437
|
+
positiveZIndex;
|
|
9438
|
+
nonPositionedFloats;
|
|
9439
|
+
nonPositionedInlineLevel;
|
|
9440
|
+
inlineLevel;
|
|
9441
|
+
nonInlineLevel;
|
|
9472
9442
|
constructor(container) {
|
|
9473
9443
|
this.element = container;
|
|
9474
9444
|
this.inlineLevel = [];
|
|
@@ -9481,13 +9451,34 @@ var StackingContext = class {
|
|
|
9481
9451
|
}
|
|
9482
9452
|
};
|
|
9483
9453
|
var ElementPaint = class {
|
|
9454
|
+
container;
|
|
9455
|
+
parent;
|
|
9456
|
+
effects = [];
|
|
9457
|
+
curves;
|
|
9458
|
+
listValue;
|
|
9459
|
+
/** Memoised getEffects results for the plain (surfaceRoot-less) render path. */
|
|
9460
|
+
plainEffectsCache = null;
|
|
9484
9461
|
constructor(container, parent) {
|
|
9485
9462
|
this.container = container;
|
|
9486
9463
|
this.parent = parent;
|
|
9487
|
-
this.effects = [];
|
|
9488
|
-
this.plainEffectsCache = null;
|
|
9489
9464
|
this.curves = new BoundCurves(this.container);
|
|
9490
9465
|
if (this.container.styles.opacity < 1) this.effects.push(new OpacityEffect(this.container.styles.opacity));
|
|
9466
|
+
if (this.container.styles.translate !== null) {
|
|
9467
|
+
const origin = this.container.styles.transformOrigin;
|
|
9468
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9469
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9470
|
+
const [tx, ty] = this.container.styles.translate;
|
|
9471
|
+
const dx = getAbsoluteValue(tx, this.container.bounds.width);
|
|
9472
|
+
const dy = getAbsoluteValue(ty, this.container.bounds.height);
|
|
9473
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9474
|
+
1,
|
|
9475
|
+
0,
|
|
9476
|
+
0,
|
|
9477
|
+
1,
|
|
9478
|
+
dx,
|
|
9479
|
+
dy
|
|
9480
|
+
]));
|
|
9481
|
+
}
|
|
9491
9482
|
if (this.container.styles.rotate !== null) {
|
|
9492
9483
|
const origin = this.container.styles.transformOrigin;
|
|
9493
9484
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9505,6 +9496,20 @@ var ElementPaint = class {
|
|
|
9505
9496
|
];
|
|
9506
9497
|
this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
|
|
9507
9498
|
}
|
|
9499
|
+
if (this.container.styles.scale !== null) {
|
|
9500
|
+
const origin = this.container.styles.transformOrigin;
|
|
9501
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9502
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9503
|
+
const [sx, sy] = this.container.styles.scale;
|
|
9504
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9505
|
+
sx,
|
|
9506
|
+
0,
|
|
9507
|
+
0,
|
|
9508
|
+
sy,
|
|
9509
|
+
0,
|
|
9510
|
+
0
|
|
9511
|
+
]));
|
|
9512
|
+
}
|
|
9508
9513
|
if (this.container.styles.transform !== null) {
|
|
9509
9514
|
const origin = this.container.styles.transformOrigin;
|
|
9510
9515
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9700,8 +9705,8 @@ const parseStackTree = (parent, stackingContext, realStackingContext, listItems)
|
|
|
9700
9705
|
if (order < 0) {
|
|
9701
9706
|
let index = 0;
|
|
9702
9707
|
parentStack.negativeZIndex.some((current, i) => {
|
|
9703
|
-
if (order
|
|
9704
|
-
index = i;
|
|
9708
|
+
if (order >= current.element.container.styles.zIndex.order) {
|
|
9709
|
+
index = i + 1;
|
|
9705
9710
|
return false;
|
|
9706
9711
|
} else if (index > 0) return true;
|
|
9707
9712
|
return false;
|
|
@@ -9748,6 +9753,86 @@ const parseStackingContexts = (container) => {
|
|
|
9748
9753
|
return root;
|
|
9749
9754
|
};
|
|
9750
9755
|
//#endregion
|
|
9756
|
+
//#region src/render/canvas/gradient-rasterizer.ts
|
|
9757
|
+
const clampStop = (stop) => Math.min(1, Math.max(0, stop));
|
|
9758
|
+
/**
|
|
9759
|
+
* Stack the one-cycle stop list periodically across [0, 1]. Returns null for
|
|
9760
|
+
* a degenerate period (all stops clamped to one point) — CSS renders the
|
|
9761
|
+
* last colour across the whole area in that case, and callers should paint
|
|
9762
|
+
* the last colour instead of stacking.
|
|
9763
|
+
*/
|
|
9764
|
+
const stackRepeatingStops = (processed) => {
|
|
9765
|
+
const first = at(processed, 0);
|
|
9766
|
+
const last = at(processed, processed.length - 1);
|
|
9767
|
+
if (last.stop - first.stop < 1e-6) return null;
|
|
9768
|
+
const period = Math.max(last.stop - first.stop, .01);
|
|
9769
|
+
const stops = [];
|
|
9770
|
+
const cycles = Math.ceil(1 / period);
|
|
9771
|
+
for (let k = 0; k < cycles; k++) for (const s of processed) {
|
|
9772
|
+
const stop = k * period + (s.stop - first.stop);
|
|
9773
|
+
if (stop > 1) break;
|
|
9774
|
+
stops.push({
|
|
9775
|
+
stop,
|
|
9776
|
+
color: asString(s.color)
|
|
9777
|
+
});
|
|
9778
|
+
}
|
|
9779
|
+
const lastPushed = stops[stops.length - 1];
|
|
9780
|
+
if (!lastPushed || lastPushed.stop < 1) stops.push({
|
|
9781
|
+
stop: 1,
|
|
9782
|
+
color: asString(last.color)
|
|
9783
|
+
});
|
|
9784
|
+
return stops;
|
|
9785
|
+
};
|
|
9786
|
+
/** Map parsed stops to string-colour stops clamped into the canvas [0, 1] range. */
|
|
9787
|
+
const toCanvasStops = (processed) => processed.map((s) => ({
|
|
9788
|
+
stop: clampStop(s.stop),
|
|
9789
|
+
color: asString(s.color)
|
|
9790
|
+
}));
|
|
9791
|
+
/**
|
|
9792
|
+
* Rasterise a radial gradient's ending-shape ellipse to an offscreen canvas.
|
|
9793
|
+
*
|
|
9794
|
+
* The ellipse is a circle of radius rx scaled vertically by ry / rx around
|
|
9795
|
+
* the canvas centre, so the offscreen canvas is the ellipse's full 2rx × 2ry
|
|
9796
|
+
* bounding box and callers draw it at (centre - rx, centre - ry). Handles the
|
|
9797
|
+
* repeating variant by stacking stops across the [0, 1] gradient range.
|
|
9798
|
+
*/
|
|
9799
|
+
const rasterizeRadialGradient = (ownerDocument, rx, ry, stops, repeating = false) => {
|
|
9800
|
+
const processed = processColorStops(stops, rx);
|
|
9801
|
+
const last = at(processed, processed.length - 1);
|
|
9802
|
+
const lastColor = asString(last.color);
|
|
9803
|
+
const canvas = ownerDocument.createElement("canvas");
|
|
9804
|
+
canvas.width = Math.max(1, Math.ceil(rx * 2));
|
|
9805
|
+
canvas.height = Math.max(1, Math.ceil(ry * 2));
|
|
9806
|
+
const ctx = canvas.getContext("2d");
|
|
9807
|
+
if (!ctx) return null;
|
|
9808
|
+
let colorStops;
|
|
9809
|
+
if (repeating) {
|
|
9810
|
+
const stacked = stackRepeatingStops(processed);
|
|
9811
|
+
if (!stacked) {
|
|
9812
|
+
ctx.fillStyle = lastColor;
|
|
9813
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
9814
|
+
return {
|
|
9815
|
+
canvas,
|
|
9816
|
+
lastColor,
|
|
9817
|
+
rx,
|
|
9818
|
+
ry
|
|
9819
|
+
};
|
|
9820
|
+
}
|
|
9821
|
+
colorStops = stacked;
|
|
9822
|
+
} else colorStops = toCanvasStops(processed);
|
|
9823
|
+
const gradient = ctx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
9824
|
+
colorStops.forEach((s) => gradient.addColorStop(clampStop(s.stop), s.color));
|
|
9825
|
+
ctx.fillStyle = gradient;
|
|
9826
|
+
if (rx !== ry) ctx.scale(1, ry / rx);
|
|
9827
|
+
ctx.fillRect(0, 0, rx * 2, rx * 2);
|
|
9828
|
+
return {
|
|
9829
|
+
canvas,
|
|
9830
|
+
lastColor,
|
|
9831
|
+
rx,
|
|
9832
|
+
ry
|
|
9833
|
+
};
|
|
9834
|
+
};
|
|
9835
|
+
//#endregion
|
|
9751
9836
|
//#region src/render/box-sizing.ts
|
|
9752
9837
|
const paddingBox = (element) => {
|
|
9753
9838
|
const bounds = element.bounds;
|
|
@@ -9866,67 +9951,184 @@ const calculateBackgroundRepeatPath = (repeat, [x, y], [width, height], backgrou
|
|
|
9866
9951
|
}
|
|
9867
9952
|
};
|
|
9868
9953
|
//#endregion
|
|
9869
|
-
//#region src/core/abort-helper.ts
|
|
9870
|
-
/**
|
|
9871
|
-
* AbortSignal helper utilities.
|
|
9872
|
-
*/
|
|
9873
|
-
/**
|
|
9874
|
-
* Throw a DOMException if the given AbortSignal is already aborted.
|
|
9875
|
-
* Used at checkpoints throughout the rendering pipeline to support
|
|
9876
|
-
* cancellable renders.
|
|
9877
|
-
*
|
|
9878
|
-
* @param signal - The AbortSignal to check. If undefined or not aborted, this is a no-op.
|
|
9879
|
-
* @throws {DOMException} With name 'AbortError' if the signal has been aborted.
|
|
9880
|
-
*/
|
|
9881
|
-
const throwIfAborted = (signal) => {
|
|
9882
|
-
if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
9883
|
-
};
|
|
9884
|
-
//#endregion
|
|
9885
9954
|
//#region src/render/canvas/filter-surface.ts
|
|
9886
9955
|
var FilterSurfaceError = class extends Error {};
|
|
9887
9956
|
const releaseSurface = (canvas) => {
|
|
9888
9957
|
canvas.width = canvas.height = 0;
|
|
9889
9958
|
};
|
|
9890
|
-
const
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9959
|
+
const UNITLESS_NAMES = [
|
|
9960
|
+
"brightness",
|
|
9961
|
+
"contrast",
|
|
9962
|
+
"grayscale",
|
|
9963
|
+
"hue-rotate",
|
|
9964
|
+
"invert",
|
|
9965
|
+
"opacity",
|
|
9966
|
+
"saturate",
|
|
9967
|
+
"sepia"
|
|
9968
|
+
];
|
|
9969
|
+
const PARSED_FILTER_CACHE_MAX = 256;
|
|
9970
|
+
const parsedFilterCache = /* @__PURE__ */ new Map();
|
|
9971
|
+
const EMPTY_FILTER = { functions: [] };
|
|
9972
|
+
function parseFilterChain(value) {
|
|
9973
|
+
if (!value || value === "none") return EMPTY_FILTER;
|
|
9974
|
+
const cached = parsedFilterCache.get(value);
|
|
9895
9975
|
if (cached !== void 0) {
|
|
9896
|
-
|
|
9897
|
-
|
|
9976
|
+
parsedFilterCache.delete(value);
|
|
9977
|
+
parsedFilterCache.set(value, cached);
|
|
9898
9978
|
return cached;
|
|
9899
9979
|
}
|
|
9900
|
-
const parsed =
|
|
9901
|
-
if (
|
|
9902
|
-
const oldest =
|
|
9903
|
-
if (oldest !== void 0)
|
|
9980
|
+
const parsed = computeFilterChain(value);
|
|
9981
|
+
if (parsedFilterCache.size >= PARSED_FILTER_CACHE_MAX) {
|
|
9982
|
+
const oldest = parsedFilterCache.keys().next().value;
|
|
9983
|
+
if (oldest !== void 0) parsedFilterCache.delete(oldest);
|
|
9904
9984
|
}
|
|
9905
|
-
|
|
9985
|
+
parsedFilterCache.set(value, parsed);
|
|
9906
9986
|
return parsed;
|
|
9907
9987
|
}
|
|
9908
|
-
|
|
9909
|
-
const
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9988
|
+
const computeFilterChain = (value) => {
|
|
9989
|
+
const functions = [];
|
|
9990
|
+
let index = 0;
|
|
9991
|
+
while (index < value.length) {
|
|
9992
|
+
const char = value[index];
|
|
9993
|
+
if (char === " " || char === "\n" || char === " ") {
|
|
9994
|
+
index++;
|
|
9995
|
+
continue;
|
|
9996
|
+
}
|
|
9997
|
+
const open = value.indexOf("(", index);
|
|
9998
|
+
if (open === -1) return null;
|
|
9999
|
+
const name = value.slice(index, open).trim();
|
|
10000
|
+
if (!/^[a-zA-Z-]+$/.test(name)) return null;
|
|
10001
|
+
const bodyEnd = matchingParenthesis(value, open);
|
|
10002
|
+
if (bodyEnd === -1) return null;
|
|
10003
|
+
const fn = parseFilterFunction(name, value.slice(open + 1, bodyEnd).trim());
|
|
10004
|
+
if (!fn) return null;
|
|
10005
|
+
functions.push(fn);
|
|
10006
|
+
index = bodyEnd + 1;
|
|
10007
|
+
}
|
|
10008
|
+
return { functions };
|
|
10009
|
+
};
|
|
10010
|
+
/** Index of the ')' matching the '(' at `open`, or -1. */
|
|
10011
|
+
const matchingParenthesis = (value, open) => {
|
|
10012
|
+
let depth = 1;
|
|
10013
|
+
for (let i = open + 1; i < value.length; i++) {
|
|
10014
|
+
const char = value[i];
|
|
10015
|
+
if (char === "(") depth++;
|
|
10016
|
+
else if (char === ")") {
|
|
10017
|
+
depth--;
|
|
10018
|
+
if (depth === 0) return i;
|
|
10019
|
+
}
|
|
10020
|
+
}
|
|
10021
|
+
return -1;
|
|
10022
|
+
};
|
|
10023
|
+
const PX_LENGTH_RE = /^-?\d+(?:\.\d+)?px$/;
|
|
10024
|
+
const parseFilterFunction = (name, body) => {
|
|
10025
|
+
if (name === "blur") {
|
|
10026
|
+
if (body === "0") return {
|
|
10027
|
+
kind: "blur",
|
|
10028
|
+
value: 0
|
|
10029
|
+
};
|
|
10030
|
+
if (!PX_LENGTH_RE.test(body)) return null;
|
|
10031
|
+
const value = Number.parseFloat(body);
|
|
10032
|
+
return value < 0 ? null : {
|
|
10033
|
+
kind: "blur",
|
|
10034
|
+
value
|
|
10035
|
+
};
|
|
10036
|
+
}
|
|
10037
|
+
if (name === "drop-shadow") return parseDropShadowBody(body);
|
|
10038
|
+
if (UNITLESS_NAMES.indexOf(name) !== -1) {
|
|
10039
|
+
const unitless = name;
|
|
10040
|
+
if (unitless === "hue-rotate") {
|
|
10041
|
+
const degrees = parseAngleDegrees(body);
|
|
10042
|
+
return degrees === null ? null : {
|
|
10043
|
+
kind: "unitless",
|
|
10044
|
+
name: unitless,
|
|
10045
|
+
value: degrees
|
|
10046
|
+
};
|
|
10047
|
+
}
|
|
10048
|
+
const trimmed = body.trim();
|
|
10049
|
+
const percentage = trimmed.endsWith("%");
|
|
10050
|
+
const numeric = percentage ? trimmed.slice(0, -1) : trimmed;
|
|
10051
|
+
if (!/^-?\d+(?:\.\d+)?$/.test(numeric)) return null;
|
|
10052
|
+
return {
|
|
10053
|
+
kind: "unitless",
|
|
10054
|
+
name: unitless,
|
|
10055
|
+
value: Number.parseFloat(numeric) * (percentage ? 1 / 100 : 1)
|
|
10056
|
+
};
|
|
10057
|
+
}
|
|
10058
|
+
return null;
|
|
10059
|
+
};
|
|
10060
|
+
/** Split on whitespace outside parentheses so rgba(...) colours stay one token. */
|
|
10061
|
+
const splitTopLevel = (body) => {
|
|
10062
|
+
const parts = [];
|
|
10063
|
+
let depth = 0;
|
|
10064
|
+
let current = "";
|
|
10065
|
+
for (const char of body) {
|
|
10066
|
+
if (char === "(") depth++;
|
|
10067
|
+
else if (char === ")") depth--;
|
|
10068
|
+
if (char === " " && depth === 0) {
|
|
10069
|
+
if (current) parts.push(current);
|
|
10070
|
+
current = "";
|
|
10071
|
+
continue;
|
|
10072
|
+
}
|
|
10073
|
+
current += char;
|
|
10074
|
+
}
|
|
10075
|
+
if (current) parts.push(current);
|
|
10076
|
+
return parts;
|
|
10077
|
+
};
|
|
10078
|
+
const parseDropShadowBody = (body) => {
|
|
10079
|
+
const parts = splitTopLevel(body);
|
|
10080
|
+
const lengths = parts.filter((part) => PX_LENGTH_RE.test(part)).map((part) => Number.parseFloat(part));
|
|
10081
|
+
if (lengths.length < 2 || lengths.length > 3) return null;
|
|
10082
|
+
const colors = parts.filter((part) => !PX_LENGTH_RE.test(part));
|
|
10083
|
+
if (parts.length - colors.length !== lengths.length) return null;
|
|
9915
10084
|
return {
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
color: effect.shadow.color
|
|
9922
|
-
} : void 0
|
|
10085
|
+
kind: "drop-shadow",
|
|
10086
|
+
x: lengths[0],
|
|
10087
|
+
y: lengths[1],
|
|
10088
|
+
blur: lengths[2] ?? 0,
|
|
10089
|
+
color: colors.join(" ") || "rgba(0, 0, 0, 0)"
|
|
9923
10090
|
};
|
|
9924
|
-
}
|
|
10091
|
+
};
|
|
10092
|
+
const parseAngleDegrees = (body) => {
|
|
10093
|
+
const trimmed = body.trim();
|
|
10094
|
+
if (trimmed === "0") return 0;
|
|
10095
|
+
const numeric = Number.parseFloat(trimmed);
|
|
10096
|
+
if (Number.isNaN(numeric)) return null;
|
|
10097
|
+
if (trimmed.endsWith("deg")) return numeric;
|
|
10098
|
+
if (trimmed.endsWith("grad")) return numeric * .9;
|
|
10099
|
+
if (trimmed.endsWith("rad")) return numeric * 180 / Math.PI;
|
|
10100
|
+
if (trimmed.endsWith("turn")) return numeric * 360;
|
|
10101
|
+
return null;
|
|
10102
|
+
};
|
|
10103
|
+
/**
|
|
10104
|
+
* Render the chain as a canvas ctx.filter string, scaling all device-space
|
|
10105
|
+
* lengths (blur radii, shadow offsets) by the capture scale. Unitless
|
|
10106
|
+
* functions and hue angles are scale-invariant.
|
|
10107
|
+
*/
|
|
10108
|
+
const nativeFilterString = (filter, scale) => filter.functions.map((fn) => {
|
|
10109
|
+
switch (fn.kind) {
|
|
10110
|
+
case "blur": return `blur(${fn.value * scale}px)`;
|
|
10111
|
+
case "drop-shadow": return `drop-shadow(${fn.x * scale}px ${fn.y * scale}px ${fn.blur * scale}px ${fn.color})`;
|
|
10112
|
+
case "unitless": return fn.name === "hue-rotate" ? `hue-rotate(${fn.value}deg)` : `${fn.name}(${fn.value})`;
|
|
10113
|
+
}
|
|
10114
|
+
}).join(" ");
|
|
10115
|
+
/**
|
|
10116
|
+
* Outset (in CSS pixels) a surface must grow so blur/shadow spillover is not
|
|
10117
|
+
* cropped. Unitless functions never spread beyond the bounds. Consecutive
|
|
10118
|
+
* blurs compound, so their radii sum.
|
|
10119
|
+
*/
|
|
9925
10120
|
function filterOutset(filter) {
|
|
9926
|
-
|
|
10121
|
+
let blurSum = 0;
|
|
10122
|
+
let maxShadowOffset = 0;
|
|
10123
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurSum += fn.value;
|
|
10124
|
+
else if (fn.kind === "drop-shadow") {
|
|
10125
|
+
blurSum += fn.blur;
|
|
10126
|
+
maxShadowOffset = Math.max(maxShadowOffset, Math.abs(fn.x), Math.abs(fn.y));
|
|
10127
|
+
}
|
|
10128
|
+
return Math.ceil(3 * blurSum + maxShadowOffset);
|
|
9927
10129
|
}
|
|
9928
10130
|
function canvasLike(source) {
|
|
9929
|
-
const canvas = document.createElement("canvas");
|
|
10131
|
+
const canvas = (source.ownerDocument ?? document).createElement("canvas");
|
|
9930
10132
|
canvas.width = source.width;
|
|
9931
10133
|
canvas.height = source.height;
|
|
9932
10134
|
return canvas;
|
|
@@ -9974,7 +10176,7 @@ function supportsNativeFilters(owner = document) {
|
|
|
9974
10176
|
canvasFilterSupport.set(owner, supported);
|
|
9975
10177
|
return supported;
|
|
9976
10178
|
}
|
|
9977
|
-
function tryNativeFilterSurface(source,
|
|
10179
|
+
function tryNativeFilterSurface(source, filter, opacity, scale, signal) {
|
|
9978
10180
|
let filtered;
|
|
9979
10181
|
let output;
|
|
9980
10182
|
let complete = false;
|
|
@@ -9983,11 +10185,8 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
9983
10185
|
filtered = canvasLike(source);
|
|
9984
10186
|
const context = filtered.getContext("2d");
|
|
9985
10187
|
if (!context || !("filter" in context)) return null;
|
|
9986
|
-
|
|
9987
|
-
if (
|
|
9988
|
-
if (shadow) functions.push(`drop-shadow(${shadow.x * scale}px ${shadow.y * scale}px ${shadow.blur * scale}px ${shadow.color})`);
|
|
9989
|
-
context.filter = functions.join(" ");
|
|
9990
|
-
if (context.filter === "none") return null;
|
|
10188
|
+
context.filter = nativeFilterString(filter, scale);
|
|
10189
|
+
if (context.filter === "none" || context.filter === "") return null;
|
|
9991
10190
|
context.drawImage(source, 0, 0);
|
|
9992
10191
|
throwIfAborted(signal);
|
|
9993
10192
|
output = canvasLike(source);
|
|
@@ -10006,17 +10205,43 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
10006
10205
|
if (output && !complete) releaseSurface(output);
|
|
10007
10206
|
}
|
|
10008
10207
|
}
|
|
10208
|
+
/**
|
|
10209
|
+
* The SVG fallback predates the ordered-chain parser and only expresses the
|
|
10210
|
+
* blur + single drop-shadow subset (at most one of each, blur before the
|
|
10211
|
+
* shadow). Chains outside that subset reject with FilterSurfaceError so the
|
|
10212
|
+
* caller keeps its legacy renderer instead of rendering a wrong filter.
|
|
10213
|
+
*/
|
|
10214
|
+
const isSvgExpressible = (filter) => {
|
|
10215
|
+
let blurs = 0;
|
|
10216
|
+
let shadows = 0;
|
|
10217
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurs++;
|
|
10218
|
+
else if (fn.kind === "drop-shadow") shadows++;
|
|
10219
|
+
else return false;
|
|
10220
|
+
if (blurs > 1 || shadows > 1) return false;
|
|
10221
|
+
if (blurs > 0 && shadows > 0) return filter.functions.findIndex((fn) => fn.kind === "blur") < filter.functions.findIndex((fn) => fn.kind === "drop-shadow");
|
|
10222
|
+
return true;
|
|
10223
|
+
};
|
|
10009
10224
|
async function renderFilterSurface(source, filter, opacity, scale, signal) {
|
|
10010
10225
|
throwIfAborted(signal);
|
|
10011
|
-
if (
|
|
10226
|
+
if (filter.functions.length > 0 && supportsNativeFilters(source.ownerDocument ?? document)) {
|
|
10012
10227
|
const output = tryNativeFilterSurface(source, filter, opacity, scale, signal);
|
|
10013
10228
|
if (output) return output;
|
|
10014
10229
|
}
|
|
10230
|
+
if (!isSvgExpressible(filter)) throw new FilterSurfaceError("Filter chain requires native canvas filters");
|
|
10015
10231
|
return renderSvgFilterSurface(source, filter, opacity, scale, signal);
|
|
10016
10232
|
}
|
|
10017
|
-
async function renderSvgFilterSurface(source,
|
|
10233
|
+
async function renderSvgFilterSurface(source, filter, opacity, scale, signal) {
|
|
10018
10234
|
throwIfAborted(signal);
|
|
10019
|
-
|
|
10235
|
+
const blur = filter.functions.find((fn) => fn.kind === "blur");
|
|
10236
|
+
const shadow = filter.functions.find((fn) => fn.kind === "drop-shadow");
|
|
10237
|
+
const blurValue = blur && blur.kind === "blur" ? blur.value : 0;
|
|
10238
|
+
const shadowValue = shadow && shadow.kind === "drop-shadow" ? {
|
|
10239
|
+
x: shadow.x,
|
|
10240
|
+
y: shadow.y,
|
|
10241
|
+
blur: shadow.blur,
|
|
10242
|
+
color: shadow.color
|
|
10243
|
+
} : void 0;
|
|
10244
|
+
if (!blurValue && !shadowValue) {
|
|
10020
10245
|
const output = canvasLike(source);
|
|
10021
10246
|
const context = output.getContext("2d");
|
|
10022
10247
|
if (!context) {
|
|
@@ -10033,8 +10258,9 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10033
10258
|
}
|
|
10034
10259
|
}
|
|
10035
10260
|
const namespace = "http://www.w3.org/2000/svg";
|
|
10261
|
+
const svgDocument = source.ownerDocument ?? document;
|
|
10036
10262
|
const element = (tag, attributes = {}) => {
|
|
10037
|
-
const node =
|
|
10263
|
+
const node = svgDocument.createElementNS(namespace, tag);
|
|
10038
10264
|
Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
|
|
10039
10265
|
return node;
|
|
10040
10266
|
};
|
|
@@ -10044,7 +10270,7 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10044
10270
|
viewBox: `0 0 ${source.width} ${source.height}`
|
|
10045
10271
|
});
|
|
10046
10272
|
const defs = element("defs");
|
|
10047
|
-
const
|
|
10273
|
+
const filterElement = element("filter", {
|
|
10048
10274
|
id: "composited-filter",
|
|
10049
10275
|
filterUnits: "userSpaceOnUse",
|
|
10050
10276
|
x: 0,
|
|
@@ -10053,31 +10279,31 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10053
10279
|
height: source.height,
|
|
10054
10280
|
"color-interpolation-filters": "sRGB"
|
|
10055
10281
|
});
|
|
10056
|
-
if (
|
|
10057
|
-
stdDeviation:
|
|
10282
|
+
if (blurValue) filterElement.appendChild(element("feGaussianBlur", {
|
|
10283
|
+
stdDeviation: blurValue * scale,
|
|
10058
10284
|
result: "blurred-source"
|
|
10059
10285
|
}));
|
|
10060
|
-
if (
|
|
10061
|
-
|
|
10062
|
-
in:
|
|
10063
|
-
stdDeviation:
|
|
10286
|
+
if (shadowValue) {
|
|
10287
|
+
filterElement.appendChild(element("feGaussianBlur", {
|
|
10288
|
+
in: blurValue ? "blurred-source" : "SourceAlpha",
|
|
10289
|
+
stdDeviation: shadowValue.blur * scale
|
|
10064
10290
|
}));
|
|
10065
|
-
|
|
10066
|
-
dx:
|
|
10067
|
-
dy:
|
|
10291
|
+
filterElement.appendChild(element("feOffset", {
|
|
10292
|
+
dx: shadowValue.x * scale,
|
|
10293
|
+
dy: shadowValue.y * scale,
|
|
10068
10294
|
result: "offset-shadow"
|
|
10069
10295
|
}));
|
|
10070
|
-
|
|
10071
|
-
|
|
10296
|
+
filterElement.appendChild(element("feFlood", { "flood-color": shadowValue.color }));
|
|
10297
|
+
filterElement.appendChild(element("feComposite", {
|
|
10072
10298
|
in2: "offset-shadow",
|
|
10073
10299
|
operator: "in"
|
|
10074
10300
|
}));
|
|
10075
10301
|
const merge = element("feMerge");
|
|
10076
10302
|
merge.appendChild(element("feMergeNode"));
|
|
10077
|
-
merge.appendChild(element("feMergeNode", { in:
|
|
10078
|
-
|
|
10303
|
+
merge.appendChild(element("feMergeNode", { in: blurValue ? "blurred-source" : "SourceGraphic" }));
|
|
10304
|
+
filterElement.appendChild(merge);
|
|
10079
10305
|
}
|
|
10080
|
-
defs.appendChild(
|
|
10306
|
+
defs.appendChild(filterElement);
|
|
10081
10307
|
svg.appendChild(defs);
|
|
10082
10308
|
let sourceUrl;
|
|
10083
10309
|
try {
|
|
@@ -10092,7 +10318,8 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10092
10318
|
href: sourceUrl,
|
|
10093
10319
|
filter: "url(#composited-filter)"
|
|
10094
10320
|
}));
|
|
10095
|
-
const
|
|
10321
|
+
const imageWindow = svgDocument.defaultView;
|
|
10322
|
+
const image = imageWindow?.Image ? new imageWindow.Image() : new Image();
|
|
10096
10323
|
let output;
|
|
10097
10324
|
try {
|
|
10098
10325
|
image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
|
|
@@ -10133,7 +10360,7 @@ function surfaceBounds(container) {
|
|
|
10133
10360
|
for (const shadow of styles.textShadow) bounds = union(bounds, expand(ink.add(shadow.offsetX.number, shadow.offsetY.number, 0, 0), 3 * shadow.blur.number));
|
|
10134
10361
|
}
|
|
10135
10362
|
for (const child of container.elements) if (child.styles.isVisible()) bounds = union(bounds, surfaceBounds(child));
|
|
10136
|
-
const filter =
|
|
10363
|
+
const filter = parseFilterChain(styles.filter);
|
|
10137
10364
|
return expand(bounds, filter ? filterOutset(filter) : 0);
|
|
10138
10365
|
}
|
|
10139
10366
|
function cropSurface(bounds, viewport, margin, scale) {
|
|
@@ -10147,11 +10374,12 @@ function cropSurface(bounds, viewport, margin, scale) {
|
|
|
10147
10374
|
//#endregion
|
|
10148
10375
|
//#region src/render/canvas/text/text-decoration-renderer.ts
|
|
10149
10376
|
var TextDecorationRenderer = class {
|
|
10377
|
+
ctx;
|
|
10150
10378
|
constructor(ctx) {
|
|
10151
10379
|
this.ctx = ctx;
|
|
10152
10380
|
}
|
|
10153
10381
|
render(bounds, styles) {
|
|
10154
|
-
this.ctx.fillStyle = asString(styles.textDecorationColor
|
|
10382
|
+
this.ctx.fillStyle = asString(styles.textDecorationColor ?? styles.color);
|
|
10155
10383
|
let thickness = 1;
|
|
10156
10384
|
if (typeof styles.textDecorationThickness === "number") thickness = styles.textDecorationThickness;
|
|
10157
10385
|
else if (styles.textDecorationThickness === "from-font") thickness = Math.max(1, Math.floor(styles.fontSize.number * .05));
|
|
@@ -10270,7 +10498,6 @@ const measureBaseline = (ctx, fallback) => {
|
|
|
10270
10498
|
};
|
|
10271
10499
|
//#endregion
|
|
10272
10500
|
//#region src/render/canvas/text-renderer.ts
|
|
10273
|
-
const iOSBrokenFonts = ["-apple-system", "system-ui"];
|
|
10274
10501
|
const TEXT_OVERFLOW_EPSILON = 1;
|
|
10275
10502
|
/**
|
|
10276
10503
|
* Detect CJK (Chinese, Japanese, Korean) characters in a string.
|
|
@@ -10289,29 +10516,19 @@ const TEXT_OVERFLOW_EPSILON = 1;
|
|
|
10289
10516
|
const CJK_CHAR_REGEX = /[\u2E80-\u2FFF\u3000-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF01-\uFFEF]/;
|
|
10290
10517
|
const hasCJKCharacters = (text) => CJK_CHAR_REGEX.test(text);
|
|
10291
10518
|
/**
|
|
10292
|
-
*
|
|
10293
|
-
*
|
|
10519
|
+
* Chromium-based engines render stroked text with visibly sharper joins when
|
|
10520
|
+
* `miter` is requested, closely matching their own -webkit-text-stroke
|
|
10521
|
+
* output; other engines need `round` joins to avoid glyph spikes. No CSS or
|
|
10522
|
+
* platform API expresses this behavioural difference, so engine detection is
|
|
10523
|
+
* the only reliable signal: `navigator.userAgentData` is Chromium-only, with
|
|
10524
|
+
* the legacy `window.chrome` marker as a fallback for older webviews.
|
|
10294
10525
|
*/
|
|
10295
|
-
const
|
|
10296
|
-
if (typeof navigator === "undefined") return
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
const isIPadOS = /Macintosh/.test(userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
|
|
10300
|
-
if (!isIOS && !isIPadOS) return null;
|
|
10301
|
-
for (const pattern of [/(?:iPhone|CPU(?:\siPhone)?)\sOS\s(\d+)[\._](\d+)/, /Version\/(\d+)\.(\d+)/]) {
|
|
10302
|
-
const match = userAgent.match(pattern);
|
|
10303
|
-
if (match && match[1]) return parseInt(match[1], 10);
|
|
10304
|
-
}
|
|
10305
|
-
return null;
|
|
10306
|
-
};
|
|
10307
|
-
const fixIOSSystemFonts = (fontFamilies) => {
|
|
10308
|
-
const iosVersion = getIOSVersion();
|
|
10309
|
-
if (iosVersion !== null && iosVersion >= 15 && iosVersion < 17) return fontFamilies.map((fontFamily) => iOSBrokenFonts.indexOf(fontFamily) !== -1 ? `-apple-system, "Helvetica Neue", Arial, sans-serif` : fontFamily);
|
|
10310
|
-
return fontFamilies;
|
|
10311
|
-
};
|
|
10312
|
-
const getTextStrokeLineJoin = () => {
|
|
10313
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
10526
|
+
const isChromiumEngine = () => {
|
|
10527
|
+
if (typeof navigator === "undefined") return false;
|
|
10528
|
+
if (navigator.userAgentData !== void 0) return true;
|
|
10529
|
+
return (typeof window !== "undefined" ? window : void 0)?.chrome !== void 0;
|
|
10314
10530
|
};
|
|
10531
|
+
const getTextStrokeLineJoin = () => isChromiumEngine() ? "miter" : "round";
|
|
10315
10532
|
/**
|
|
10316
10533
|
* Text Renderer
|
|
10317
10534
|
*
|
|
@@ -10319,9 +10536,23 @@ const getTextStrokeLineJoin = () => {
|
|
|
10319
10536
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10320
10537
|
*/
|
|
10321
10538
|
var TextRenderer = class {
|
|
10539
|
+
ctx;
|
|
10540
|
+
options;
|
|
10541
|
+
decorationRenderer;
|
|
10542
|
+
/**
|
|
10543
|
+
* Baseline ascent per font string. Consecutive text nodes overwhelmingly
|
|
10544
|
+
* share a font, and each measureBaseline call issues a canvas measureText,
|
|
10545
|
+
* so repeated fonts are memoised (bounded; cleared if the working set
|
|
10546
|
+
* exceeds the cap).
|
|
10547
|
+
*/
|
|
10548
|
+
baselineCache = /* @__PURE__ */ new Map();
|
|
10549
|
+
/**
|
|
10550
|
+
* Per-render glyph width cache. Keyed by glyph + font string,
|
|
10551
|
+
* avoids redundant `measureText` calls when letter-spacing is non-zero.
|
|
10552
|
+
* Cleared at the start of each renderTextNode call.
|
|
10553
|
+
*/
|
|
10554
|
+
glyphWidthCache = null;
|
|
10322
10555
|
constructor(deps) {
|
|
10323
|
-
this.baselineCache = /* @__PURE__ */ new Map();
|
|
10324
|
-
this.glyphWidthCache = null;
|
|
10325
10556
|
this.ctx = deps.ctx;
|
|
10326
10557
|
this.options = deps.options;
|
|
10327
10558
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
@@ -10514,7 +10745,7 @@ var TextRenderer = class {
|
|
|
10514
10745
|
*/
|
|
10515
10746
|
createFontStyle(styles) {
|
|
10516
10747
|
const fontVariant = styles.fontVariant.filter((variant) => variant === "normal" || variant === "small-caps").join("");
|
|
10517
|
-
const fontFamily =
|
|
10748
|
+
const fontFamily = styles.fontFamily.join(", ");
|
|
10518
10749
|
const fontSize = isDimensionToken(styles.fontSize) ? `${styles.fontSize.number}${styles.fontSize.unit}` : `${styles.fontSize.number}px`;
|
|
10519
10750
|
return [
|
|
10520
10751
|
[
|
|
@@ -10543,7 +10774,7 @@ var TextRenderer = class {
|
|
|
10543
10774
|
* only the first N-1 complete lines followed by an ellipsis on the Nth line.
|
|
10544
10775
|
*/
|
|
10545
10776
|
renderLineClampedText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10546
|
-
const lineHeight = styles.fontSize.number
|
|
10777
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10547
10778
|
const lines = [];
|
|
10548
10779
|
let currentLine = [];
|
|
10549
10780
|
let currentLineTop = at(text.textBounds, 0).bounds.top;
|
|
@@ -10576,7 +10807,7 @@ var TextRenderer = class {
|
|
|
10576
10807
|
* Returns true if ellipsis was applied (caller should skip normal rendering).
|
|
10577
10808
|
*/
|
|
10578
10809
|
renderEllipsisText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10579
|
-
const lineHeight = styles.fontSize.number
|
|
10810
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10580
10811
|
const firstTop = at(text.textBounds, 0).bounds.top;
|
|
10581
10812
|
if (!text.textBounds.every((tb) => Math.abs(tb.bounds.top - firstTop) < lineHeight * .5)) return false;
|
|
10582
10813
|
let fullText = text.textBounds.map((tb) => tb.text).join("").replace(/\s+/g, " ").trim();
|
|
@@ -10725,6 +10956,8 @@ const createCanvasPath = (ctx, paths) => {
|
|
|
10725
10956
|
* ```
|
|
10726
10957
|
*/
|
|
10727
10958
|
var LRUMap = class {
|
|
10959
|
+
maxSize;
|
|
10960
|
+
_map;
|
|
10728
10961
|
constructor(maxSize) {
|
|
10729
10962
|
this.maxSize = maxSize;
|
|
10730
10963
|
this._map = /* @__PURE__ */ new Map();
|
|
@@ -10773,8 +11006,17 @@ var LRUMap = class {
|
|
|
10773
11006
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10774
11007
|
*/
|
|
10775
11008
|
var BackgroundRenderer = class {
|
|
11009
|
+
ctx;
|
|
11010
|
+
context;
|
|
11011
|
+
canvas;
|
|
11012
|
+
/**
|
|
11013
|
+
* Instance-level LRU cache for background-image patterns.
|
|
11014
|
+
* CanvasPatterns are tied to the rendering context and must not be
|
|
11015
|
+
* shared across different render passes. This cache lives for the
|
|
11016
|
+
* duration of one html2canvas() call.
|
|
11017
|
+
*/
|
|
11018
|
+
patternCache = new LRUMap(50);
|
|
10776
11019
|
constructor(deps) {
|
|
10777
|
-
this.patternCache = new LRUMap(50);
|
|
10778
11020
|
this.ctx = deps.ctx;
|
|
10779
11021
|
this.context = deps.context;
|
|
10780
11022
|
this.canvas = deps.canvas;
|
|
@@ -10821,7 +11063,6 @@ var BackgroundRenderer = class {
|
|
|
10821
11063
|
image = await this.context.cache.match(url);
|
|
10822
11064
|
} catch (e) {
|
|
10823
11065
|
this.context.logger.error(`Error loading background-image ${url}`);
|
|
10824
|
-
this.context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
10825
11066
|
}
|
|
10826
11067
|
if (image) {
|
|
10827
11068
|
const imageWidth = isNaN(image.width) || image.width === 0 ? 1 : image.width;
|
|
@@ -10860,34 +11101,13 @@ var BackgroundRenderer = class {
|
|
|
10860
11101
|
const gy0 = y + ly0;
|
|
10861
11102
|
const gy1 = y + ly1;
|
|
10862
11103
|
const processedStops = processColorStops(backgroundImage.stops, lineLength || 1);
|
|
10863
|
-
const
|
|
10864
|
-
const firstStop = at(processedStops, 0);
|
|
10865
|
-
const period = Math.max(lastStop.stop - firstStop.stop, .01);
|
|
10866
|
-
if (lastStop.stop - firstStop.stop < 1e-6) {
|
|
10867
|
-
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10868
|
-
gradient.addColorStop(0, asString(lastStop.color));
|
|
10869
|
-
gradient.addColorStop(1, asString(lastStop.color));
|
|
10870
|
-
this.path(path);
|
|
10871
|
-
this.ctx.fillStyle = gradient;
|
|
10872
|
-
this.ctx.fill();
|
|
10873
|
-
return;
|
|
10874
|
-
}
|
|
10875
|
-
const stops = [];
|
|
10876
|
-
const cycles = Math.ceil(1 / period);
|
|
10877
|
-
for (let k = 0; k < cycles; k++) for (const s of processedStops) {
|
|
10878
|
-
const stop = k * period + (s.stop - firstStop.stop);
|
|
10879
|
-
if (stop > 1) break;
|
|
10880
|
-
stops.push({
|
|
10881
|
-
stop,
|
|
10882
|
-
color: asString(s.color)
|
|
10883
|
-
});
|
|
10884
|
-
}
|
|
10885
|
-
stops.push({
|
|
10886
|
-
stop: 1,
|
|
10887
|
-
color: asString(lastStop.color)
|
|
10888
|
-
});
|
|
11104
|
+
const stacked = stackRepeatingStops(processedStops);
|
|
10889
11105
|
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10890
|
-
|
|
11106
|
+
if (!stacked) {
|
|
11107
|
+
const lastColor = asString(at(processedStops, processedStops.length - 1).color);
|
|
11108
|
+
gradient.addColorStop(0, lastColor);
|
|
11109
|
+
gradient.addColorStop(1, lastColor);
|
|
11110
|
+
} else stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
10891
11111
|
this.path(path);
|
|
10892
11112
|
this.ctx.fillStyle = gradient;
|
|
10893
11113
|
this.ctx.fill();
|
|
@@ -10940,37 +11160,25 @@ var BackgroundRenderer = class {
|
|
|
10940
11160
|
}
|
|
10941
11161
|
if (rx > 0 && ry > 0) {
|
|
10942
11162
|
const cacheKey = `rg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
10943
|
-
const
|
|
10944
|
-
const
|
|
11163
|
+
const processed = processColorStops(backgroundImage.stops, rx);
|
|
11164
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
10945
11165
|
let pattern = this.patternCache.get(cacheKey);
|
|
10946
11166
|
if (!pattern) {
|
|
10947
|
-
const
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
10953
|
-
stops.forEach((s) => gradient.addColorStop(s.stop, asString(s.color)));
|
|
10954
|
-
offCtx.fillStyle = gradient;
|
|
10955
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
10956
|
-
offCtx.fillRect(0, 0, rx * 2, rx * 2);
|
|
10957
|
-
pattern = this.ctx.createPattern(offscreen, "no-repeat");
|
|
10958
|
-
this.patternCache.set(cacheKey, pattern);
|
|
10959
|
-
}
|
|
10960
|
-
}
|
|
10961
|
-
if (pattern) {
|
|
10962
|
-
this.path(path);
|
|
10963
|
-
this.ctx.save();
|
|
10964
|
-
this.ctx.clip();
|
|
10965
|
-
if (lastStop) {
|
|
10966
|
-
this.ctx.fillStyle = asString(lastStop.color);
|
|
10967
|
-
this.ctx.fill();
|
|
10968
|
-
}
|
|
10969
|
-
this.ctx.translate(left + x - rx, top + y - ry);
|
|
10970
|
-
this.ctx.fillStyle = pattern;
|
|
10971
|
-
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
10972
|
-
this.ctx.restore();
|
|
11167
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11168
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, false);
|
|
11169
|
+
if (!rasterized) return;
|
|
11170
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11171
|
+
this.patternCache.set(cacheKey, pattern);
|
|
10973
11172
|
}
|
|
11173
|
+
this.path(path);
|
|
11174
|
+
this.ctx.save();
|
|
11175
|
+
this.ctx.clip();
|
|
11176
|
+
this.ctx.fillStyle = lastColor;
|
|
11177
|
+
this.ctx.fill();
|
|
11178
|
+
this.ctx.translate(left + x - rx, top + y - ry);
|
|
11179
|
+
this.ctx.fillStyle = pattern;
|
|
11180
|
+
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11181
|
+
this.ctx.restore();
|
|
10974
11182
|
}
|
|
10975
11183
|
}
|
|
10976
11184
|
/**
|
|
@@ -10997,40 +11205,14 @@ var BackgroundRenderer = class {
|
|
|
10997
11205
|
ry = Math.max(ry, .01);
|
|
10998
11206
|
}
|
|
10999
11207
|
if (!(rx > 0 && ry > 0)) return;
|
|
11000
|
-
const
|
|
11001
|
-
const firstStop = at(processed, 0);
|
|
11002
|
-
const lastStop = at(processed, processed.length - 1);
|
|
11003
|
-
const period = Math.max(lastStop.stop - firstStop.stop, .01);
|
|
11004
|
-
const stops = [];
|
|
11005
|
-
const rings = Math.ceil(1 / period);
|
|
11006
|
-
for (let k = 0; k < rings; k++) for (const s of processed) {
|
|
11007
|
-
const stop = k * period + (s.stop - firstStop.stop);
|
|
11008
|
-
if (stop > 1) break;
|
|
11009
|
-
stops.push({
|
|
11010
|
-
stop,
|
|
11011
|
-
color: asString(s.color)
|
|
11012
|
-
});
|
|
11013
|
-
}
|
|
11014
|
-
stops.push({
|
|
11015
|
-
stop: 1,
|
|
11016
|
-
color: asString(lastStop.color)
|
|
11017
|
-
});
|
|
11018
|
-
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${stops.length}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11208
|
+
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11019
11209
|
let pattern = this.patternCache.get(cacheKey);
|
|
11020
11210
|
if (!pattern) {
|
|
11021
|
-
const
|
|
11022
|
-
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
11027
|
-
stops.forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
11028
|
-
offCtx.fillStyle = gradient;
|
|
11029
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
11030
|
-
offCtx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11031
|
-
pattern = this.ctx.createPattern(offscreen, "no-repeat");
|
|
11032
|
-
this.patternCache.set(cacheKey, pattern);
|
|
11033
|
-
}
|
|
11211
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11212
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, true);
|
|
11213
|
+
if (!rasterized) return;
|
|
11214
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11215
|
+
this.patternCache.set(cacheKey, pattern);
|
|
11034
11216
|
}
|
|
11035
11217
|
if (pattern) {
|
|
11036
11218
|
this.path(path);
|
|
@@ -11242,6 +11424,8 @@ const createPathFromCurves = (outer1, inner1, outer2, inner2) => {
|
|
|
11242
11424
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
11243
11425
|
*/
|
|
11244
11426
|
var BorderRenderer = class {
|
|
11427
|
+
ctx;
|
|
11428
|
+
pathCallbacks;
|
|
11245
11429
|
constructor(deps, pathCallbacks) {
|
|
11246
11430
|
this.ctx = deps.ctx;
|
|
11247
11431
|
this.pathCallbacks = pathCallbacks;
|
|
@@ -11418,6 +11602,7 @@ const resolveBorderImageOutset = (outset, borderWidths) => {
|
|
|
11418
11602
|
};
|
|
11419
11603
|
};
|
|
11420
11604
|
var BorderImageRenderer = class {
|
|
11605
|
+
ctx;
|
|
11421
11606
|
constructor(ctx) {
|
|
11422
11607
|
this.ctx = ctx;
|
|
11423
11608
|
}
|
|
@@ -11455,7 +11640,8 @@ var BorderImageRenderer = class {
|
|
|
11455
11640
|
dy: top,
|
|
11456
11641
|
dw: width - dL - dR,
|
|
11457
11642
|
dh: dT,
|
|
11458
|
-
repeat: repeat.horizontal
|
|
11643
|
+
repeat: repeat.horizontal,
|
|
11644
|
+
horizontal: true
|
|
11459
11645
|
},
|
|
11460
11646
|
{
|
|
11461
11647
|
sx: imgW - sR,
|
|
@@ -11466,7 +11652,8 @@ var BorderImageRenderer = class {
|
|
|
11466
11652
|
dy: top + dT,
|
|
11467
11653
|
dw: dR,
|
|
11468
11654
|
dh: height - dT - dB,
|
|
11469
|
-
repeat: repeat.vertical
|
|
11655
|
+
repeat: repeat.vertical,
|
|
11656
|
+
horizontal: false
|
|
11470
11657
|
},
|
|
11471
11658
|
{
|
|
11472
11659
|
sx: sL,
|
|
@@ -11477,7 +11664,8 @@ var BorderImageRenderer = class {
|
|
|
11477
11664
|
dy: top + height - dB,
|
|
11478
11665
|
dw: width - dL - dR,
|
|
11479
11666
|
dh: dB,
|
|
11480
|
-
repeat: repeat.horizontal
|
|
11667
|
+
repeat: repeat.horizontal,
|
|
11668
|
+
horizontal: true
|
|
11481
11669
|
},
|
|
11482
11670
|
{
|
|
11483
11671
|
sx: 0,
|
|
@@ -11488,33 +11676,33 @@ var BorderImageRenderer = class {
|
|
|
11488
11676
|
dy: top + dT,
|
|
11489
11677
|
dw: dL,
|
|
11490
11678
|
dh: height - dT - dB,
|
|
11491
|
-
repeat: repeat.vertical
|
|
11679
|
+
repeat: repeat.vertical,
|
|
11680
|
+
horizontal: false
|
|
11492
11681
|
}
|
|
11493
11682
|
];
|
|
11494
11683
|
for (const edge of edges) {
|
|
11495
11684
|
if (edge.sw <= 0 || edge.sh <= 0 || edge.dw <= 0 || edge.dh <= 0) continue;
|
|
11496
|
-
const isHorizontal = edge.dw >= edge.dh;
|
|
11497
11685
|
if (edge.repeat === 0) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy, edge.dw, edge.dh);
|
|
11498
|
-
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge,
|
|
11499
|
-
}
|
|
11500
|
-
if (slice.fill) {
|
|
11501
|
-
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
}
|
|
11686
|
+
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge, edge.horizontal, edge.repeat === 2);
|
|
11687
|
+
}
|
|
11688
|
+
if (slice.fill) this.drawCenterRegion(image, {
|
|
11689
|
+
sx: sL,
|
|
11690
|
+
sy: sT,
|
|
11691
|
+
sw: imgW - sL - sR,
|
|
11692
|
+
sh: imgH - sT - sB
|
|
11693
|
+
}, {
|
|
11694
|
+
dx: left + dL,
|
|
11695
|
+
dy: top + dT,
|
|
11696
|
+
dw: width - dL - dR,
|
|
11697
|
+
dh: height - dT - dB
|
|
11698
|
+
}, repeat);
|
|
11511
11699
|
}
|
|
11512
11700
|
drawRegion(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
11513
11701
|
if (sw > 0 && sh > 0 && dw > 0 && dh > 0) this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
11514
11702
|
}
|
|
11515
|
-
drawRepeatedEdge(image, edge,
|
|
11516
|
-
const srcLength =
|
|
11517
|
-
const tgLength =
|
|
11703
|
+
drawRepeatedEdge(image, edge, horizontal, round) {
|
|
11704
|
+
const srcLength = horizontal ? edge.sw : edge.sh;
|
|
11705
|
+
const tgLength = horizontal ? edge.dw : edge.dh;
|
|
11518
11706
|
if (srcLength <= 0 || tgLength <= 0) return;
|
|
11519
11707
|
let tileSize;
|
|
11520
11708
|
let tileCount;
|
|
@@ -11531,14 +11719,45 @@ var BorderImageRenderer = class {
|
|
|
11531
11719
|
this.ctx.clip();
|
|
11532
11720
|
for (let i = 0; i < tileCount; i++) {
|
|
11533
11721
|
const offset = i * tileSize;
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
if (clampedSize <= 0) break;
|
|
11537
|
-
if (isHorizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, clampedSize, edge.dh);
|
|
11538
|
-
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, clampedSize);
|
|
11722
|
+
if (horizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, tileSize, edge.dh);
|
|
11723
|
+
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, tileSize);
|
|
11539
11724
|
}
|
|
11540
11725
|
this.ctx.restore();
|
|
11541
11726
|
}
|
|
11727
|
+
/**
|
|
11728
|
+
* Draw the center region of the border image, tiling each axis per its
|
|
11729
|
+
* border-image-repeat keyword (stretch spans the whole axis, repeat
|
|
11730
|
+
* tiles at source size with the overflow cropped, round scales the tile
|
|
11731
|
+
* to divide the axis evenly).
|
|
11732
|
+
*/
|
|
11733
|
+
drawCenterRegion(image, src, dst, repeat) {
|
|
11734
|
+
if (src.sw <= 0 || src.sh <= 0 || dst.dw <= 0 || dst.dh <= 0) return;
|
|
11735
|
+
const axis = (mode, srcLen, dstLen) => {
|
|
11736
|
+
if (mode === 0) return {
|
|
11737
|
+
size: dstLen,
|
|
11738
|
+
count: 1
|
|
11739
|
+
};
|
|
11740
|
+
if (mode === 2) {
|
|
11741
|
+
const count = Math.max(1, Math.round(dstLen / srcLen));
|
|
11742
|
+
return {
|
|
11743
|
+
size: dstLen / count,
|
|
11744
|
+
count
|
|
11745
|
+
};
|
|
11746
|
+
}
|
|
11747
|
+
return {
|
|
11748
|
+
size: srcLen,
|
|
11749
|
+
count: Math.max(1, Math.ceil(dstLen / srcLen))
|
|
11750
|
+
};
|
|
11751
|
+
};
|
|
11752
|
+
const columns = axis(repeat.horizontal, src.sw, dst.dw);
|
|
11753
|
+
const rows = axis(repeat.vertical, src.sh, dst.dh);
|
|
11754
|
+
this.ctx.save();
|
|
11755
|
+
this.ctx.beginPath();
|
|
11756
|
+
this.ctx.rect(dst.dx, dst.dy, dst.dw, dst.dh);
|
|
11757
|
+
this.ctx.clip();
|
|
11758
|
+
for (let row = 0; row < rows.count; row++) for (let column = 0; column < columns.count; column++) this.ctx.drawImage(image, src.sx, src.sy, src.sw, src.sh, dst.dx + column * columns.size, dst.dy + row * rows.size, columns.size, rows.size);
|
|
11759
|
+
this.ctx.restore();
|
|
11760
|
+
}
|
|
11542
11761
|
};
|
|
11543
11762
|
//#endregion
|
|
11544
11763
|
//#region src/render/canvas/effects-renderer.ts
|
|
@@ -11592,10 +11811,17 @@ const scaleFilterBlur = (filter, scale) => scale === 1 ? filter : filter.replace
|
|
|
11592
11811
|
* `restore()` **once** when that effect is popped.
|
|
11593
11812
|
*/
|
|
11594
11813
|
var EffectsRenderer = class {
|
|
11814
|
+
ctx;
|
|
11815
|
+
pathCallback;
|
|
11816
|
+
scale;
|
|
11817
|
+
activeEffects = [];
|
|
11818
|
+
/** Whether a canvas state save was performed for the current batch. */
|
|
11819
|
+
didSave = false;
|
|
11820
|
+
/** Index (0-based, from start of activeEffects array) of the last
|
|
11821
|
+
* heavyweight effect in the batch — the one whose pop triggers
|
|
11822
|
+
* restore(). Set to -1 when no save was performed. */
|
|
11823
|
+
saveAtDepth = -1;
|
|
11595
11824
|
constructor(deps, pathCallback) {
|
|
11596
|
-
this.activeEffects = [];
|
|
11597
|
-
this.didSave = false;
|
|
11598
|
-
this.saveAtDepth = -1;
|
|
11599
11825
|
this.ctx = deps.ctx;
|
|
11600
11826
|
this.pathCallback = pathCallback;
|
|
11601
11827
|
this.scale = deps.scale ?? 1;
|
|
@@ -11696,8 +11922,11 @@ var EffectsRenderer = class {
|
|
|
11696
11922
|
* always fills the whole area — a mask surface is about alpha coverage, not
|
|
11697
11923
|
* about what is visible underneath.
|
|
11698
11924
|
*
|
|
11699
|
-
*
|
|
11700
|
-
*
|
|
11925
|
+
* Gradient layers share the rasterisation primitives of the background
|
|
11926
|
+
* renderer (gradient-rasterizer.ts): repeating gradients stack their stop
|
|
11927
|
+
* cycles, and the area beyond a radial gradient's ending shape keeps the
|
|
11928
|
+
* last stop's colour. Limitations (v1): mask-mode is alpha-only; layers
|
|
11929
|
+
* composite with source-over (≈ the spec-default `add`).
|
|
11701
11930
|
*/
|
|
11702
11931
|
/**
|
|
11703
11932
|
* CSS layer lists cycle: a single mask-size applies to every mask-image
|
|
@@ -11763,17 +11992,12 @@ const paintRadialLayer = (ctx, layer, area) => {
|
|
|
11763
11992
|
let [rx, ry] = calculateRadius(layer, cx, cy, width, height);
|
|
11764
11993
|
rx = Math.max(rx, .01);
|
|
11765
11994
|
ry = Math.max(ry, .01);
|
|
11766
|
-
const
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
|
|
11770
|
-
|
|
11771
|
-
|
|
11772
|
-
processColorStops(layer.stops, rx * 2).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), asString(s.color)));
|
|
11773
|
-
offCtx.fillStyle = gradient;
|
|
11774
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
11775
|
-
offCtx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11776
|
-
ctx.drawImage(offscreen, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
11995
|
+
const ownerDocument = ctx.canvas.ownerDocument ?? document;
|
|
11996
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, layer.stops, isRepeatingRadialGradient(layer));
|
|
11997
|
+
if (!rasterized) return;
|
|
11998
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
11999
|
+
ctx.fillRect(area.left, area.top, area.width, area.height);
|
|
12000
|
+
ctx.drawImage(rasterized.canvas, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
11777
12001
|
};
|
|
11778
12002
|
/** Draw one gradient layer filling the whole mask area. */
|
|
11779
12003
|
const paintGradientLayer = (ctx, layer, area) => {
|
|
@@ -11787,12 +12011,31 @@ const paintGradientLayer = (ctx, layer, area) => {
|
|
|
11787
12011
|
if (layer.type === 1 || layer.type === 3) {
|
|
11788
12012
|
const linear = layer;
|
|
11789
12013
|
const [lineLength, lx0, lx1, ly0, ly1] = calculateGradientDirection(linear.angle || 0, width, height);
|
|
11790
|
-
|
|
11791
|
-
|
|
11792
|
-
|
|
12014
|
+
const processed = processColorStops(linear.stops, lineLength || 1);
|
|
12015
|
+
if (layer.type === 3) {
|
|
12016
|
+
const stacked = stackRepeatingStops(processed);
|
|
12017
|
+
if (!stacked) {
|
|
12018
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12019
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12020
|
+
return;
|
|
12021
|
+
}
|
|
12022
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12023
|
+
stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
12024
|
+
} else {
|
|
12025
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12026
|
+
toCanvasStops(processed).forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
12027
|
+
}
|
|
12028
|
+
} else if (layer.type === 5 || layer.type === 6) {
|
|
11793
12029
|
const conic = layer;
|
|
12030
|
+
const processed = processColorStops(conic.stops, 1);
|
|
12031
|
+
const repeating = layer.type === 6;
|
|
12032
|
+
if (repeating && !stackRepeatingStops(processed)) {
|
|
12033
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12034
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12035
|
+
return;
|
|
12036
|
+
}
|
|
11794
12037
|
gradient = ctx.createConicGradient(conic.angle - Math.PI / 2, area.left + width / 2, area.top + height / 2);
|
|
11795
|
-
|
|
12038
|
+
((repeating ? stackRepeatingStops(processed) : null) ?? toCanvasStops(processed)).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
11796
12039
|
}
|
|
11797
12040
|
if (gradient) {
|
|
11798
12041
|
ctx.fillStyle = gradient;
|
|
@@ -11859,7 +12102,11 @@ const calculateObjectFitRendering = (intrinsicWidth, intrinsicHeight, box, objec
|
|
|
11859
12102
|
dh = sh;
|
|
11860
12103
|
}
|
|
11861
12104
|
} else if (objectFit === 16) {
|
|
11862
|
-
|
|
12105
|
+
const containW = imgRatio > boxRatio ? dw : dh * imgRatio;
|
|
12106
|
+
const containH = imgRatio > boxRatio ? dw / imgRatio : dh;
|
|
12107
|
+
const noneW = Math.min(sw, dw);
|
|
12108
|
+
const noneH = Math.min(sh, dh);
|
|
12109
|
+
if (containW * containH < noneW * noneH) {
|
|
11863
12110
|
if (imgRatio > boxRatio) {
|
|
11864
12111
|
dh = dw / imgRatio;
|
|
11865
12112
|
dy += (box.height - dh) * posY;
|
|
@@ -11910,14 +12157,12 @@ async function renderReplacedElements(ctx, context, options, iframeRendererFacto
|
|
|
11910
12157
|
ctx.imageSmoothingEnabled = prevSmoothing;
|
|
11911
12158
|
} catch (e) {
|
|
11912
12159
|
context.logger.error(`Error loading image ${container.src}`);
|
|
11913
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11914
12160
|
}
|
|
11915
12161
|
if (container instanceof CanvasElementContainer) renderReplacedElementFn(container, curves, container.canvas);
|
|
11916
12162
|
if (container instanceof SVGElementContainer) try {
|
|
11917
12163
|
renderReplacedElementFn(container, curves, await context.cache.match(container.svg));
|
|
11918
12164
|
} catch (e) {
|
|
11919
12165
|
context.logger.error(`Error loading svg ${container.svg.substring(0, 255)}`);
|
|
11920
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11921
12166
|
}
|
|
11922
12167
|
if (container instanceof IFrameElementContainer && container.tree) {
|
|
11923
12168
|
const canvas = await iframeRendererFactory(context, {
|
|
@@ -12065,7 +12310,6 @@ async function renderListMarker(ctx, context, textRenderer, paint, container, st
|
|
|
12065
12310
|
ctx.drawImage(image, container.bounds.left - (markerWidth + 10), markerCenterY - markerHeight / 2, markerWidth, markerHeight);
|
|
12066
12311
|
} catch (e) {
|
|
12067
12312
|
context.logger.error(`Error loading list-style-image ${url}`);
|
|
12068
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
12069
12313
|
}
|
|
12070
12314
|
}
|
|
12071
12315
|
} else if (paint.listValue && container.styles.listStyleType !== -1) {
|
|
@@ -12252,7 +12496,10 @@ const paintShadowSurface = async (ctx, paint, shadow, options, budget, space) =>
|
|
|
12252
12496
|
else createCanvasPath(sourceCtx, path);
|
|
12253
12497
|
sourceCtx.fillStyle = asString(shadow.color);
|
|
12254
12498
|
sourceCtx.fill(shadow.inset ? "evenodd" : "nonzero");
|
|
12255
|
-
filtered = await renderFilterSurface(source, {
|
|
12499
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
12500
|
+
kind: "blur",
|
|
12501
|
+
value: blur
|
|
12502
|
+
}] }, 1, space.scale, options.signal);
|
|
12256
12503
|
ctx.save();
|
|
12257
12504
|
try {
|
|
12258
12505
|
if (shadow.inset) {
|
|
@@ -12338,6 +12585,10 @@ const paintBoxShadow = async (ctx, paint, shadow, options, budget) => {
|
|
|
12338
12585
|
//#endregion
|
|
12339
12586
|
//#region src/render/canvas/text-clip-renderer.ts
|
|
12340
12587
|
var TextClipRenderer = class {
|
|
12588
|
+
ctx;
|
|
12589
|
+
context;
|
|
12590
|
+
scale;
|
|
12591
|
+
createFontStyle;
|
|
12341
12592
|
constructor(deps) {
|
|
12342
12593
|
this.ctx = deps.ctx;
|
|
12343
12594
|
this.context = deps.context;
|
|
@@ -12357,59 +12608,69 @@ var TextClipRenderer = class {
|
|
|
12357
12608
|
const deviceHeight = Math.ceil(bounds.height * scale);
|
|
12358
12609
|
const offscreen = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12359
12610
|
if (!offscreen) return;
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
bounds,
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
mask
|
|
12396
|
-
mask
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12611
|
+
let mask = null;
|
|
12612
|
+
let composite = null;
|
|
12613
|
+
let shadowCanvases = null;
|
|
12614
|
+
try {
|
|
12615
|
+
offscreen.ctx.scale(scale, scale);
|
|
12616
|
+
const [fontString] = this.createFontStyle(styles);
|
|
12617
|
+
offscreen.ctx.font = fontString ?? "";
|
|
12618
|
+
offscreen.ctx.textBaseline = "alphabetic";
|
|
12619
|
+
offscreen.ctx.textAlign = "left";
|
|
12620
|
+
offscreen.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
12621
|
+
const baseline = measureBaseline(offscreen.ctx, styles.fontSize.number);
|
|
12622
|
+
const bgRenderer = new BackgroundRenderer({
|
|
12623
|
+
ctx: offscreen.ctx,
|
|
12624
|
+
context: this.context,
|
|
12625
|
+
canvas: offscreen.canvas,
|
|
12626
|
+
options: {
|
|
12627
|
+
width,
|
|
12628
|
+
height,
|
|
12629
|
+
scale: 1
|
|
12630
|
+
}
|
|
12631
|
+
});
|
|
12632
|
+
if (!isTransparent(styles.backgroundColor)) {
|
|
12633
|
+
offscreen.ctx.fillStyle = asString(styles.backgroundColor);
|
|
12634
|
+
offscreen.ctx.fillRect(0, 0, width, height);
|
|
12635
|
+
}
|
|
12636
|
+
offscreen.ctx.save();
|
|
12637
|
+
offscreen.ctx.translate(-bounds.left, -bounds.top);
|
|
12638
|
+
await bgRenderer.renderBackgroundImage(container);
|
|
12639
|
+
offscreen.ctx.restore();
|
|
12640
|
+
const drawOptions = {
|
|
12641
|
+
bounds,
|
|
12642
|
+
baseline,
|
|
12643
|
+
letterSpacing: styles.letterSpacing,
|
|
12644
|
+
writingMode: styles.writingMode
|
|
12645
|
+
};
|
|
12646
|
+
mask = this.createGlyphLayer(ownerDocument, deviceWidth, deviceHeight, offscreen.ctx);
|
|
12647
|
+
if (!mask) return;
|
|
12648
|
+
const hasStroke = !!styles.webkitTextStrokeWidth;
|
|
12649
|
+
if (hasStroke) {
|
|
12650
|
+
mask.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);
|
|
12651
|
+
mask.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
12652
|
+
mask.ctx.lineJoin = getTextStrokeLineJoin();
|
|
12653
|
+
}
|
|
12654
|
+
for (const textNode of container.textNodes) for (const textBound of textNode.textBounds) this.drawGlyphs(mask, textBound, drawOptions, (ctx, text, x, y) => {
|
|
12655
|
+
ctx.fillText(text, x, y);
|
|
12656
|
+
if (hasStroke) ctx.strokeText(text, x, y);
|
|
12657
|
+
});
|
|
12658
|
+
offscreen.ctx.globalCompositeOperation = "destination-in";
|
|
12659
|
+
offscreen.ctx.drawImage(mask.canvas, 0, 0, width, height);
|
|
12660
|
+
shadowCanvases = this.renderShadowSilhouettes(paint, ownerDocument, deviceWidth, deviceHeight, offscreen.ctx, styles, drawOptions);
|
|
12661
|
+
if (shadowCanvases) {
|
|
12662
|
+
composite = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12663
|
+
if (!composite) return;
|
|
12664
|
+
for (const shadowCanvas of shadowCanvases) composite.ctx.drawImage(shadowCanvas, 0, 0);
|
|
12665
|
+
composite.ctx.drawImage(offscreen.canvas, 0, 0);
|
|
12666
|
+
this.ctx.drawImage(composite.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12667
|
+
} else this.ctx.drawImage(offscreen.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12668
|
+
} finally {
|
|
12669
|
+
releaseSurface(offscreen.canvas);
|
|
12670
|
+
if (mask) releaseSurface(mask.canvas);
|
|
12671
|
+
if (composite) releaseSurface(composite.canvas);
|
|
12672
|
+
if (shadowCanvases) shadowCanvases.forEach(releaseSurface);
|
|
12673
|
+
}
|
|
12413
12674
|
}
|
|
12414
12675
|
createLayer(ownerDocument, width, height) {
|
|
12415
12676
|
const canvas = ownerDocument.createElement("canvas");
|
|
@@ -12481,20 +12742,29 @@ var TextClipRenderer = class {
|
|
|
12481
12742
|
}
|
|
12482
12743
|
return canvases.length ? canvases : null;
|
|
12483
12744
|
}
|
|
12484
|
-
getTextStrokeLineJoin() {
|
|
12485
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
12486
|
-
}
|
|
12487
12745
|
};
|
|
12488
12746
|
//#endregion
|
|
12489
12747
|
//#region src/render/canvas/canvas-renderer.ts
|
|
12490
12748
|
var CanvasRenderer = class CanvasRenderer {
|
|
12749
|
+
surfaceRoot;
|
|
12750
|
+
surfaceBudget;
|
|
12751
|
+
canvas;
|
|
12752
|
+
ctx;
|
|
12753
|
+
context;
|
|
12754
|
+
options;
|
|
12755
|
+
backgroundRenderer;
|
|
12756
|
+
borderRenderer;
|
|
12757
|
+
borderImageRenderer;
|
|
12758
|
+
effectsRenderer;
|
|
12759
|
+
textRenderer;
|
|
12760
|
+
textClipRenderer;
|
|
12761
|
+
legacySubtree = false;
|
|
12491
12762
|
constructor(context, options, surfaceRoot, surfaceBudget = { pixels: 0 }) {
|
|
12492
12763
|
this.surfaceRoot = surfaceRoot;
|
|
12493
12764
|
this.surfaceBudget = surfaceBudget;
|
|
12494
|
-
this.legacySubtree = false;
|
|
12495
12765
|
this.context = context;
|
|
12496
12766
|
this.options = options;
|
|
12497
|
-
this.canvas = options.canvas ? options.canvas :
|
|
12767
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
12498
12768
|
const ctx = this.canvas.getContext("2d");
|
|
12499
12769
|
if (!ctx) {
|
|
12500
12770
|
if (!options.canvas) releaseSurface(this.canvas);
|
|
@@ -12547,11 +12817,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12547
12817
|
async renderStack(stack) {
|
|
12548
12818
|
const styles = stack.element.container.styles;
|
|
12549
12819
|
if (styles.isVisible()) {
|
|
12550
|
-
const filter =
|
|
12820
|
+
const filter = parseFilterChain(styles.filter);
|
|
12821
|
+
const hasFilter = filter !== null && filter.functions.length > 0;
|
|
12551
12822
|
const hasMask = styles.maskImage.length > 0;
|
|
12552
12823
|
const reflect = styles.webkitBoxReflect;
|
|
12553
12824
|
const hasBlend = styles.mixBlendMode !== MIX_BLEND_MODE$1.NORMAL;
|
|
12554
|
-
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter && (
|
|
12825
|
+
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter !== null && (hasFilter || styles.opacity < 1)) && this.canComposite(stack.element)) {
|
|
12555
12826
|
if (!await this.renderCompositedStack(stack, filter, hasMask, reflect, hasBlend)) {
|
|
12556
12827
|
this.legacySubtree = true;
|
|
12557
12828
|
try {
|
|
@@ -12568,7 +12839,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12568
12839
|
canComposite(paint) {
|
|
12569
12840
|
const supported = (container) => {
|
|
12570
12841
|
const styles = container.styles;
|
|
12571
|
-
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) &&
|
|
12842
|
+
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) && parseFilterChain(styles.filter) !== null;
|
|
12572
12843
|
};
|
|
12573
12844
|
const subtree = (container) => supported(container) && container.elements.every(subtree);
|
|
12574
12845
|
let ancestor = paint.parent;
|
|
@@ -12636,7 +12907,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12636
12907
|
async applyMask(surface, styles, bounds) {
|
|
12637
12908
|
const ctx = surface.getContext("2d");
|
|
12638
12909
|
if (!ctx) return;
|
|
12639
|
-
const maskCanvas =
|
|
12910
|
+
const maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12640
12911
|
maskCanvas.width = surface.width;
|
|
12641
12912
|
maskCanvas.height = surface.height;
|
|
12642
12913
|
const maskCtx = maskCanvas.getContext("2d");
|
|
@@ -12678,7 +12949,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12678
12949
|
let refCanvas;
|
|
12679
12950
|
let maskCanvas;
|
|
12680
12951
|
try {
|
|
12681
|
-
refCanvas =
|
|
12952
|
+
refCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12682
12953
|
refCanvas.width = w;
|
|
12683
12954
|
refCanvas.height = h;
|
|
12684
12955
|
const ctx = refCanvas.getContext("2d");
|
|
@@ -12700,7 +12971,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12700
12971
|
ctx.restore();
|
|
12701
12972
|
}
|
|
12702
12973
|
if (reflect.mask) {
|
|
12703
|
-
maskCanvas =
|
|
12974
|
+
maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12704
12975
|
maskCanvas.width = w;
|
|
12705
12976
|
maskCanvas.height = h;
|
|
12706
12977
|
const mctx = maskCanvas.getContext("2d");
|
|
@@ -12824,18 +13095,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12824
13095
|
await this.renderStack(child);
|
|
12825
13096
|
}
|
|
12826
13097
|
}
|
|
12827
|
-
mask(paths) {
|
|
12828
|
-
this.ctx.beginPath();
|
|
12829
|
-
const x = this.options.x;
|
|
12830
|
-
const y = this.options.y;
|
|
12831
|
-
this.ctx.moveTo(x, y);
|
|
12832
|
-
this.ctx.lineTo(x + this.options.width, y);
|
|
12833
|
-
this.ctx.lineTo(x + this.options.width, y + this.options.height);
|
|
12834
|
-
this.ctx.lineTo(x, y + this.options.height);
|
|
12835
|
-
this.ctx.lineTo(x, y);
|
|
12836
|
-
this.formatPath(paths.slice(0).reverse());
|
|
12837
|
-
this.ctx.closePath();
|
|
12838
|
-
}
|
|
12839
13098
|
path(paths) {
|
|
12840
13099
|
createCanvasPath(this.ctx, paths);
|
|
12841
13100
|
}
|
|
@@ -12857,7 +13116,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12857
13116
|
let source;
|
|
12858
13117
|
let filtered;
|
|
12859
13118
|
try {
|
|
12860
|
-
source =
|
|
13119
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
12861
13120
|
source.width = width;
|
|
12862
13121
|
source.height = height;
|
|
12863
13122
|
const ctx = source.getContext("2d");
|
|
@@ -12867,7 +13126,10 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12867
13126
|
createCanvasPath(ctx, transformPath(calculateBorderBoxPath(paint.curves), -spread, -spread, 2 * spread, 2 * spread));
|
|
12868
13127
|
ctx.fillStyle = asString(shadow.color);
|
|
12869
13128
|
ctx.fill();
|
|
12870
|
-
filtered = await renderFilterSurface(source, {
|
|
13129
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
13130
|
+
kind: "blur",
|
|
13131
|
+
value: blur
|
|
13132
|
+
}] }, 1, scale, this.options.signal);
|
|
12871
13133
|
this.ctx.save();
|
|
12872
13134
|
try {
|
|
12873
13135
|
this.ctx.beginPath();
|
|
@@ -13043,9 +13305,19 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13043
13305
|
if (source.type === 1 || source.type === 3) {
|
|
13044
13306
|
const gradientImage = source;
|
|
13045
13307
|
const [lineLength, x0, y0, x1, y1] = calculateGradientDirection(gradientImage.angle, width, height);
|
|
13308
|
+
const processed = processColorStops(gradientImage.stops, lineLength || width);
|
|
13309
|
+
const repeating = source.type === 3;
|
|
13310
|
+
const stacked = repeating ? stackRepeatingStops(processed) : null;
|
|
13046
13311
|
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
13047
|
-
|
|
13048
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)),
|
|
13312
|
+
if (stacked) stacked.forEach((colorStop) => {
|
|
13313
|
+
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), colorStop.color);
|
|
13314
|
+
});
|
|
13315
|
+
else if (repeating) {
|
|
13316
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
13317
|
+
gradient.addColorStop(0, lastColor);
|
|
13318
|
+
gradient.addColorStop(1, lastColor);
|
|
13319
|
+
} else toCanvasStops(processed).forEach((colorStop) => {
|
|
13320
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
13049
13321
|
});
|
|
13050
13322
|
ctx.fillStyle = gradient;
|
|
13051
13323
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -13053,21 +13325,17 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13053
13325
|
}
|
|
13054
13326
|
if (source.type === 2 || source.type === 4) {
|
|
13055
13327
|
const gradientImage = source;
|
|
13056
|
-
const
|
|
13057
|
-
const
|
|
13328
|
+
const position = gradientImage.position.length === 0 ? [FIFTY_PERCENT] : gradientImage.position;
|
|
13329
|
+
const cx = getAbsoluteValue(at(position, 0), width);
|
|
13330
|
+
const cy = getAbsoluteValue(at(position, position.length - 1), height);
|
|
13058
13331
|
const [rx, ry] = calculateRadius(gradientImage, cx, cy, width, height);
|
|
13059
13332
|
if (rx <= 0 || ry <= 0) return null;
|
|
13060
|
-
ctx.
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
ctx.
|
|
13064
|
-
const gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, rx);
|
|
13065
|
-
processColorStops(gradientImage.stops, rx).forEach((colorStop) => {
|
|
13066
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), asString(colorStop.color));
|
|
13067
|
-
});
|
|
13068
|
-
ctx.fillStyle = gradient;
|
|
13333
|
+
const ownerDocument = this.ctx.canvas.ownerDocument ?? document;
|
|
13334
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, gradientImage.stops, source.type === 4);
|
|
13335
|
+
if (!rasterized) return null;
|
|
13336
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
13069
13337
|
ctx.fillRect(0, 0, width, height);
|
|
13070
|
-
ctx.
|
|
13338
|
+
ctx.drawImage(rasterized.canvas, cx - rx, cy - ry, rx * 2, ry * 2);
|
|
13071
13339
|
return canvas;
|
|
13072
13340
|
}
|
|
13073
13341
|
if (source.type === 5 || source.type === 6) {
|
|
@@ -13112,12 +13380,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13112
13380
|
}
|
|
13113
13381
|
/**
|
|
13114
13382
|
* Filter the already-painted content beneath the element's border box and
|
|
13115
|
-
* paint the result back, approximating CSS backdrop-filter for the
|
|
13116
|
-
*
|
|
13383
|
+
* paint the result back, approximating CSS backdrop-filter for the chain
|
|
13384
|
+
* subset the filter surface backends support.
|
|
13117
13385
|
*/
|
|
13118
13386
|
async renderBackdropFilter(paint) {
|
|
13119
|
-
const filter =
|
|
13120
|
-
if (!filter ||
|
|
13387
|
+
const filter = parseFilterChain(paint.container.styles.backdropFilter);
|
|
13388
|
+
if (!filter || filter.functions.length === 0) return;
|
|
13121
13389
|
const bounds = paint.container.bounds;
|
|
13122
13390
|
if (bounds.width <= 0 || bounds.height <= 0) return;
|
|
13123
13391
|
const scale = this.options.scale;
|
|
@@ -13129,7 +13397,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13129
13397
|
let source;
|
|
13130
13398
|
let filtered;
|
|
13131
13399
|
try {
|
|
13132
|
-
source =
|
|
13400
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
13133
13401
|
source.width = width;
|
|
13134
13402
|
source.height = height;
|
|
13135
13403
|
const srcCtx = source.getContext("2d");
|
|
@@ -13137,7 +13405,15 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13137
13405
|
const sx = Math.round((bounds.left - this.options.x) * scale);
|
|
13138
13406
|
const sy = Math.round((bounds.top - this.options.y) * scale);
|
|
13139
13407
|
srcCtx.drawImage(this.canvas, sx, sy, width, height, 0, 0, width, height);
|
|
13140
|
-
|
|
13408
|
+
try {
|
|
13409
|
+
filtered = await renderFilterSurface(source, filter, 1, scale, this.options.signal);
|
|
13410
|
+
} catch (error) {
|
|
13411
|
+
if (error instanceof FilterSurfaceError) {
|
|
13412
|
+
this.context.logger.info(`${error.message}; rendering without the backdrop effect`);
|
|
13413
|
+
return;
|
|
13414
|
+
}
|
|
13415
|
+
throw error;
|
|
13416
|
+
}
|
|
13141
13417
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13142
13418
|
this.ctx.save();
|
|
13143
13419
|
try {
|
|
@@ -13184,10 +13460,14 @@ const hasTextBackgroundClip = (styles) => {
|
|
|
13184
13460
|
//#endregion
|
|
13185
13461
|
//#region src/render/canvas/foreignobject-renderer.ts
|
|
13186
13462
|
var ForeignObjectRenderer = class {
|
|
13463
|
+
canvas;
|
|
13464
|
+
ctx;
|
|
13465
|
+
options;
|
|
13466
|
+
context;
|
|
13187
13467
|
constructor(context, options) {
|
|
13188
13468
|
this.context = context;
|
|
13189
13469
|
this.options = options;
|
|
13190
|
-
this.canvas = options.canvas ? options.canvas :
|
|
13470
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
13191
13471
|
const ctx = this.canvas.getContext("2d");
|
|
13192
13472
|
if (!ctx) throw new Error("Failed to get 2D rendering context from canvas");
|
|
13193
13473
|
this.ctx = ctx;
|
|
@@ -13201,19 +13481,49 @@ var ForeignObjectRenderer = class {
|
|
|
13201
13481
|
}
|
|
13202
13482
|
async render(element) {
|
|
13203
13483
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13204
|
-
const
|
|
13205
|
-
const
|
|
13484
|
+
const restoreRootOffsets = stripRootOffsets(element);
|
|
13485
|
+
const svg = createForeignObjectSVG(this.options.width, this.options.height, 0, 0, element);
|
|
13486
|
+
const imagePromise = loadSerializedSVG(svg);
|
|
13487
|
+
restoreRootOffsets();
|
|
13488
|
+
const img = await imagePromise;
|
|
13489
|
+
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13206
13490
|
if (this.options.backgroundColor) {
|
|
13207
13491
|
this.ctx.fillStyle = asString(this.options.backgroundColor);
|
|
13208
|
-
this.ctx.fillRect(
|
|
13492
|
+
this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13209
13493
|
}
|
|
13210
|
-
this.ctx.drawImage(img,
|
|
13494
|
+
this.ctx.drawImage(img, this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13211
13495
|
return this.canvas;
|
|
13212
13496
|
}
|
|
13213
13497
|
};
|
|
13498
|
+
/**
|
|
13499
|
+
* Temporarily neutralize the root element's layout offsets for SVG
|
|
13500
|
+
* serialization. `top/right/bottom/left` reset to `auto` (inset values of
|
|
13501
|
+
* positioned elements are baked into the capture rect); margins to `0`.
|
|
13502
|
+
*/
|
|
13503
|
+
const ROOT_OFFSET_PROPERTIES = [
|
|
13504
|
+
"marginTop",
|
|
13505
|
+
"marginRight",
|
|
13506
|
+
"marginBottom",
|
|
13507
|
+
"marginLeft",
|
|
13508
|
+
"top",
|
|
13509
|
+
"right",
|
|
13510
|
+
"bottom",
|
|
13511
|
+
"left"
|
|
13512
|
+
];
|
|
13513
|
+
const stripRootOffsets = (element) => {
|
|
13514
|
+
const style = element.style;
|
|
13515
|
+
const previous = ROOT_OFFSET_PROPERTIES.map((property) => [property, style[property]]);
|
|
13516
|
+
for (const property of ROOT_OFFSET_PROPERTIES) style[property] = property.startsWith("margin") ? "0px" : "auto";
|
|
13517
|
+
return () => {
|
|
13518
|
+
for (const [property, value] of previous) style[property] = value;
|
|
13519
|
+
};
|
|
13520
|
+
};
|
|
13214
13521
|
//#endregion
|
|
13215
13522
|
//#region src/core/logger.ts
|
|
13216
13523
|
var Logger = class {
|
|
13524
|
+
id;
|
|
13525
|
+
enabled;
|
|
13526
|
+
start;
|
|
13217
13527
|
constructor({ id, enabled }) {
|
|
13218
13528
|
this.id = id;
|
|
13219
13529
|
this.enabled = enabled;
|
|
@@ -13249,17 +13559,33 @@ var Logger = class {
|
|
|
13249
13559
|
//#endregion
|
|
13250
13560
|
//#region src/core/cache-storage.ts
|
|
13251
13561
|
var Cache = class {
|
|
13562
|
+
context;
|
|
13563
|
+
_options;
|
|
13564
|
+
_cache = /* @__PURE__ */ new Map();
|
|
13565
|
+
maxSize;
|
|
13566
|
+
_pendingOperations = /* @__PURE__ */ new Map();
|
|
13567
|
+
/** When true, addImage() collects URLs without starting loads. */
|
|
13568
|
+
_deferMode = false;
|
|
13569
|
+
/** URLs collected during defer mode, pending batch preload. */
|
|
13570
|
+
_collectedUrls = /* @__PURE__ */ new Set();
|
|
13571
|
+
/**
|
|
13572
|
+
* Eviction is suspended between startDefer() and the end of preloadAll():
|
|
13573
|
+
* the render pipeline loads every image it is going to paint inside that
|
|
13574
|
+
* window, and match() never reloads, so an LRU eviction there would
|
|
13575
|
+
* silently drop images from the output on pages with more unique images
|
|
13576
|
+
* than maxSize.
|
|
13577
|
+
*
|
|
13578
|
+
* A counter (not a flag) keeps nested/overlapping defer windows — e.g.
|
|
13579
|
+
* two renders sharing one cache via `config.cache` — suspended until the
|
|
13580
|
+
* last one finishes preloading.
|
|
13581
|
+
*/
|
|
13582
|
+
_evictionSuspendCount = 0;
|
|
13252
13583
|
get _evictionEnabled() {
|
|
13253
13584
|
return this._evictionSuspendCount === 0;
|
|
13254
13585
|
}
|
|
13255
13586
|
constructor(context, _options) {
|
|
13256
13587
|
this.context = context;
|
|
13257
13588
|
this._options = _options;
|
|
13258
|
-
this._cache = /* @__PURE__ */ new Map();
|
|
13259
|
-
this._pendingOperations = /* @__PURE__ */ new Map();
|
|
13260
|
-
this._deferMode = false;
|
|
13261
|
-
this._collectedUrls = /* @__PURE__ */ new Set();
|
|
13262
|
-
this._evictionSuspendCount = 0;
|
|
13263
13589
|
this.maxSize = _options.maxCacheSize ?? 100;
|
|
13264
13590
|
if (this.maxSize < 1) throw new Error("Cache maxSize must be at least 1");
|
|
13265
13591
|
if (this.maxSize > 1e4) this.context.logger.warn(`Cache maxSize ${this.maxSize} is very large and may cause memory issues. Consider using a smaller value (recommended: 100-1000).`);
|
|
@@ -13277,14 +13603,18 @@ var Cache = class {
|
|
|
13277
13603
|
* an optional concurrency cap to avoid overwhelming the browser's network
|
|
13278
13604
|
* stack (default: 10 concurrent loads).
|
|
13279
13605
|
* After this call returns, all images are either loaded (cache hit) or
|
|
13280
|
-
* failed (logged). Subsequent cache.match()
|
|
13606
|
+
* failed (logged and reported via onError). Subsequent cache.match()
|
|
13607
|
+
* calls return immediately.
|
|
13281
13608
|
*
|
|
13282
13609
|
* @param concurrency - Max concurrent image loads (1–100, default 10).
|
|
13283
13610
|
* @param onProgress - Invoked once before loading and after each settled
|
|
13284
13611
|
* batch with (settledCount, totalCount), enabling coarse progress UI.
|
|
13285
13612
|
* Not invoked when there is nothing to load.
|
|
13613
|
+
* @param signal - Checked before each batch; aborting rejects the whole
|
|
13614
|
+
* preload with an AbortError instead of waiting for the remaining
|
|
13615
|
+
* batches to finish.
|
|
13286
13616
|
*/
|
|
13287
|
-
async preloadAll(concurrency = 10, onProgress) {
|
|
13617
|
+
async preloadAll(concurrency = 10, onProgress, signal) {
|
|
13288
13618
|
this._deferMode = false;
|
|
13289
13619
|
const urls = Array.from(this._collectedUrls);
|
|
13290
13620
|
this._collectedUrls.clear();
|
|
@@ -13293,11 +13623,19 @@ var Cache = class {
|
|
|
13293
13623
|
const limit = Math.max(1, Math.min(concurrency, 100));
|
|
13294
13624
|
this.context.logger.debug(`Preloading ${urls.length} image(s) with concurrency ${limit}`);
|
|
13295
13625
|
let settled = 0;
|
|
13626
|
+
const abortPromise = signal ? new Promise((_, reject) => {
|
|
13627
|
+
const onAbort = () => reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
13628
|
+
if (signal.aborted) onAbort();
|
|
13629
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
13630
|
+
}) : null;
|
|
13631
|
+
abortPromise?.catch(() => void 0);
|
|
13296
13632
|
onProgress?.(0, urls.length);
|
|
13297
13633
|
for (let i = 0; i < urls.length; i += limit) {
|
|
13634
|
+
throwIfAborted(signal);
|
|
13298
13635
|
const batch = urls.slice(i, i + limit);
|
|
13299
|
-
|
|
13300
|
-
|
|
13636
|
+
batch.map((url) => this._addImageWithPending(url));
|
|
13637
|
+
const batchSettled = Promise.allSettled(batch.map((url) => this._cache.get(url)?.value ?? Promise.resolve()));
|
|
13638
|
+
await (abortPromise ? Promise.race([batchSettled, abortPromise]) : batchSettled);
|
|
13301
13639
|
settled += batch.length;
|
|
13302
13640
|
onProgress?.(settled, urls.length);
|
|
13303
13641
|
}
|
|
@@ -13340,7 +13678,10 @@ var Cache = class {
|
|
|
13340
13678
|
const timeoutMs = this._options.imageTimeout ?? 15e3;
|
|
13341
13679
|
const imageWithTimeout = this.withTimeout(this.loadImage(src), timeoutMs, `Timed out (${timeoutMs}ms) loading image`);
|
|
13342
13680
|
imageWithTimeout.catch((error) => {
|
|
13343
|
-
|
|
13681
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
13682
|
+
const message = `Failed to load image ${src.substring(0, 256)}: ${reason}`;
|
|
13683
|
+
this.context.logger.error(message);
|
|
13684
|
+
this.context.onError?.(new Error(message));
|
|
13344
13685
|
});
|
|
13345
13686
|
this.set(src, imageWithTimeout);
|
|
13346
13687
|
}
|
|
@@ -13402,18 +13743,22 @@ var Cache = class {
|
|
|
13402
13743
|
const isSameOrigin = typeof this._options.customIsSameOrigin === "function" ? await this._options.customIsSameOrigin(key, defaultIsSameOrigin) : defaultIsSameOrigin(key);
|
|
13403
13744
|
const canAttemptCors = !isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && typeof this._options.proxy !== "string";
|
|
13404
13745
|
const useCORS = !isInlineImage(key) && (this._options.useCORS === true || canAttemptCors) && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
|
|
13405
|
-
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" &&
|
|
13746
|
+
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" && !useCORS;
|
|
13406
13747
|
if (!isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && !useProxy && !useCORS) return;
|
|
13407
13748
|
let src = key;
|
|
13408
13749
|
if (useProxy) src = await this.proxy(src);
|
|
13409
13750
|
this.context.logger.debug(`Added image ${key.substring(0, 256)}`);
|
|
13751
|
+
const imageConstructor = this.context.config.window.Image ?? Image;
|
|
13410
13752
|
return await new Promise((resolve, reject) => {
|
|
13411
|
-
const img = new
|
|
13753
|
+
const img = new imageConstructor();
|
|
13412
13754
|
img.onload = () => resolve(img);
|
|
13413
13755
|
img.onerror = reject;
|
|
13414
13756
|
if (isInlineBase64Image(src) || useCORS) img.crossOrigin = "anonymous";
|
|
13415
13757
|
img.src = src;
|
|
13416
|
-
if (img.complete === true)
|
|
13758
|
+
if (img.complete === true) {
|
|
13759
|
+
if (typeof img.decode === "function") img.decode().then(() => resolve(img), () => reject(/* @__PURE__ */ new Error(`Failed to decode image ${src.substring(0, 256)}`)));
|
|
13760
|
+
else setTimeout(() => resolve(img), 500);
|
|
13761
|
+
}
|
|
13417
13762
|
});
|
|
13418
13763
|
}
|
|
13419
13764
|
has(key) {
|
|
@@ -13427,23 +13772,19 @@ var Cache = class {
|
|
|
13427
13772
|
if (!proxy) throw new Error("No proxy defined");
|
|
13428
13773
|
const key = src.substring(0, 256);
|
|
13429
13774
|
return new Promise((resolve, reject) => {
|
|
13430
|
-
const responseType = FEATURES.SUPPORT_RESPONSE_TYPE ? "blob" : "text";
|
|
13431
13775
|
const xhr = new XMLHttpRequest();
|
|
13432
13776
|
xhr.onload = () => {
|
|
13433
13777
|
if (xhr.status === 200) {
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
reader.addEventListener("error", (e) => reject(e), false);
|
|
13439
|
-
reader.readAsDataURL(xhr.response);
|
|
13440
|
-
}
|
|
13778
|
+
const reader = new FileReader();
|
|
13779
|
+
reader.addEventListener("load", () => resolve(reader.result), false);
|
|
13780
|
+
reader.addEventListener("error", (e) => reject(e), false);
|
|
13781
|
+
reader.readAsDataURL(xhr.response);
|
|
13441
13782
|
} else reject(`Failed to proxy resource ${key} with status code ${xhr.status}`);
|
|
13442
13783
|
};
|
|
13443
13784
|
xhr.onerror = reject;
|
|
13444
13785
|
const queryString = proxy.indexOf("?") > -1 ? "&" : "?";
|
|
13445
|
-
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType
|
|
13446
|
-
|
|
13786
|
+
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType=blob`);
|
|
13787
|
+
xhr.responseType = "blob";
|
|
13447
13788
|
if (this._options.imageTimeout) {
|
|
13448
13789
|
const timeout = this._options.imageTimeout;
|
|
13449
13790
|
xhr.timeout = timeout;
|
|
@@ -13467,27 +13808,34 @@ const isSVG = (src) => src.slice(-3).toLowerCase() === "svg" || INLINE_SVG.test(
|
|
|
13467
13808
|
* Origin Checker
|
|
13468
13809
|
*
|
|
13469
13810
|
* Provides origin checking functionality without global static state.
|
|
13470
|
-
* Each instance maintains its own
|
|
13811
|
+
* Each instance maintains its own base URI and origin reference.
|
|
13471
13812
|
*
|
|
13472
13813
|
* Replaces the static methods in CacheStorage with instance-based approach.
|
|
13473
13814
|
*/
|
|
13474
13815
|
var OriginChecker = class {
|
|
13816
|
+
baseUri;
|
|
13817
|
+
origin;
|
|
13475
13818
|
constructor(window) {
|
|
13476
13819
|
if (!window || !window.document) throw new Error("Valid window object required for OriginChecker");
|
|
13477
13820
|
if (!window.location || !window.location.href) throw new Error("Window object must have valid location");
|
|
13478
|
-
this.
|
|
13821
|
+
this.baseUri = window.location.href;
|
|
13479
13822
|
this.origin = this.getOrigin(window.location.href);
|
|
13480
13823
|
}
|
|
13481
13824
|
/**
|
|
13482
13825
|
* Get the origin (protocol + hostname + port) of a URL
|
|
13483
13826
|
*
|
|
13484
|
-
* @param url - URL to parse
|
|
13485
|
-
*
|
|
13827
|
+
* @param url - URL to parse; relative URLs resolve against the context
|
|
13828
|
+
* window's location, as the anchor element used to
|
|
13829
|
+
* @returns Origin string (e.g. "https://example.com:8080"), or an empty
|
|
13830
|
+
* string for unparseable URLs — which never matches and is
|
|
13831
|
+
* therefore treated as cross-origin
|
|
13486
13832
|
*/
|
|
13487
13833
|
getOrigin(url) {
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13834
|
+
try {
|
|
13835
|
+
return new URL(url, this.baseUri).origin;
|
|
13836
|
+
} catch (e) {
|
|
13837
|
+
return "";
|
|
13838
|
+
}
|
|
13491
13839
|
}
|
|
13492
13840
|
/**
|
|
13493
13841
|
* Check if a URL is from the same origin as the context
|
|
@@ -13510,11 +13858,15 @@ var OriginChecker = class {
|
|
|
13510
13858
|
//#endregion
|
|
13511
13859
|
//#region src/core/context.ts
|
|
13512
13860
|
var Context = class Context {
|
|
13513
|
-
static
|
|
13514
|
-
|
|
13515
|
-
|
|
13861
|
+
static instanceCount = 1;
|
|
13862
|
+
instanceName = `#${Context.instanceCount++}`;
|
|
13863
|
+
logger;
|
|
13864
|
+
cache;
|
|
13865
|
+
originChecker;
|
|
13866
|
+
config;
|
|
13867
|
+
onError;
|
|
13868
|
+
_windowBounds;
|
|
13516
13869
|
constructor(options, windowBounds, config) {
|
|
13517
|
-
this.instanceName = `#${Context.instanceCount++}`;
|
|
13518
13870
|
this.config = config;
|
|
13519
13871
|
this.logger = new Logger({
|
|
13520
13872
|
id: this.instanceName,
|
|
@@ -13530,6 +13882,18 @@ var Context = class Context {
|
|
|
13530
13882
|
return this._windowBounds;
|
|
13531
13883
|
}
|
|
13532
13884
|
/**
|
|
13885
|
+
* Document used to allocate offscreen resources (offscreen canvases,
|
|
13886
|
+
* images, measurement elements). Prefers the configured window's document
|
|
13887
|
+
* so resources live in the captured realm; falls back to the global
|
|
13888
|
+
* document, which keeps mock environments without a window document
|
|
13889
|
+
* working.
|
|
13890
|
+
*/
|
|
13891
|
+
get resourceDocument() {
|
|
13892
|
+
const windowDocument = this.config.window.document;
|
|
13893
|
+
if (windowDocument) return windowDocument;
|
|
13894
|
+
return typeof document !== "undefined" ? document : void 0;
|
|
13895
|
+
}
|
|
13896
|
+
/**
|
|
13533
13897
|
* Compensate window bounds for a page scroll that the browser performed
|
|
13534
13898
|
* underneath us. Used by the document cloner: WebKit's scroll anchoring can
|
|
13535
13899
|
* scroll the cloned iframe after `onclone`, and the offset must be applied
|
|
@@ -13601,7 +13965,8 @@ const assembleCloneOptions = (opts, config, foreignObjectRendering) => ({
|
|
|
13601
13965
|
iframeContainer: opts.iframeContainer,
|
|
13602
13966
|
inlineImages: foreignObjectRendering,
|
|
13603
13967
|
copyStyles: foreignObjectRendering,
|
|
13604
|
-
cspNonce: opts.cspNonce ?? config.cspNonce
|
|
13968
|
+
cspNonce: opts.cspNonce ?? config.cspNonce,
|
|
13969
|
+
signal: opts.signal
|
|
13605
13970
|
});
|
|
13606
13971
|
/** Assemble canvas rendering options. */
|
|
13607
13972
|
const assembleRenderOptions = (opts, backgroundColor, left, top, width, height, devicePixelRatio) => ({
|
|
@@ -13707,13 +14072,13 @@ const renderElement = async (element, opts, config) => {
|
|
|
13707
14072
|
perfMonitor.start("parse");
|
|
13708
14073
|
throwIfAborted(signal);
|
|
13709
14074
|
context.cache.startDefer();
|
|
13710
|
-
root = parseTree(context, clonedElement);
|
|
14075
|
+
root = parseTree(context, clonedElement, { normalizeDom: opts.normalizeDom });
|
|
13711
14076
|
perfMonitor.end("parse");
|
|
13712
14077
|
emitProgress(opts.onProgress, context, "parse", 50);
|
|
13713
14078
|
perfMonitor.start("preload");
|
|
13714
14079
|
await context.cache.preloadAll(10, (loaded, total) => {
|
|
13715
14080
|
emitProgress(opts.onProgress, context, "preload", 50 + Math.round(loaded / total * 10));
|
|
13716
|
-
});
|
|
14081
|
+
}, signal);
|
|
13717
14082
|
perfMonitor.end("preload");
|
|
13718
14083
|
emitProgress(opts.onProgress, context, "layout", 60);
|
|
13719
14084
|
if (backgroundColor === root.styles.backgroundColor) root.styles.backgroundColor = 0;
|