html2canvas-pro 2.5.1 → 2.5.3
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 +13 -3
- package/dist/html2canvas-pro.cjs +1903 -1478
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +1903 -1478
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +1907 -1479
- 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 +36 -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 +25 -48
- 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.3 <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,29 +8037,105 @@ const imageReady = (img) => {
|
|
|
7844
8037
|
const imagesReady = (document) => {
|
|
7845
8038
|
return Promise.all([].slice.call(document.images, 0).map(imageReady));
|
|
7846
8039
|
};
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
8040
|
+
/**
|
|
8041
|
+
* Wait until every external stylesheet link of the clone has been applied or
|
|
8042
|
+
* definitively failed, or the readiness budget expires.
|
|
8043
|
+
*
|
|
8044
|
+
* The clone is mounted by adoptNode() into an already-closed document
|
|
8045
|
+
* (close() must precede adoptNode for Chrome uppercase class-name matching,
|
|
8046
|
+
* see the mount sequence below), so the cloned <link rel="stylesheet">
|
|
8047
|
+
* elements are inserted after the document finished loading: they neither
|
|
8048
|
+
* delay the iframe load event nor change readyState, and the iframeLoader
|
|
8049
|
+
* readiness poll cannot observe them. On a cold cache the first capture
|
|
8050
|
+
* could then measure the clone before its external CSS arrived and render
|
|
8051
|
+
* an unstyled layout (issue #245). Inline <style> clones apply
|
|
8052
|
+
* synchronously and document-level adopted stylesheets are serialised at
|
|
8053
|
+
* clone time, so neither needs this wait.
|
|
8054
|
+
* @internal – exported for testing only.
|
|
8055
|
+
*/
|
|
8056
|
+
const stylesheetsReady = (documentClone, logger, signal) => {
|
|
8057
|
+
if (signal?.aborted) return Promise.resolve();
|
|
8058
|
+
const pending = [];
|
|
8059
|
+
const links = documentClone.getElementsByTagName("link");
|
|
8060
|
+
for (let i = 0; i < links.length; i++) {
|
|
8061
|
+
const link = links[i];
|
|
8062
|
+
if (!link || link.sheet) continue;
|
|
8063
|
+
const rel = (link.getAttribute("rel") ?? "").trim().toLowerCase().split(/\s+/);
|
|
8064
|
+
if (!rel.includes("stylesheet") || rel.includes("alternate") || link.disabled || !link.getAttribute("href")) continue;
|
|
8065
|
+
pending.push(new Promise((resolve) => {
|
|
8066
|
+
let timer;
|
|
8067
|
+
const settle = () => {
|
|
8068
|
+
link.removeEventListener("load", settle);
|
|
8069
|
+
link.removeEventListener("error", settle);
|
|
8070
|
+
signal?.removeEventListener("abort", onAbort);
|
|
8071
|
+
clearTimeout(timer);
|
|
8072
|
+
resolve();
|
|
8073
|
+
};
|
|
8074
|
+
const onAbort = () => settle();
|
|
8075
|
+
timer = setTimeout(() => {
|
|
8076
|
+
logger?.warn(`Stylesheet ${link.href} did not finish loading within ${CLONE_READY_TIMEOUT_MS / 1e3}s; continuing with a possibly unstyled clone`);
|
|
8077
|
+
settle();
|
|
8078
|
+
}, CLONE_READY_TIMEOUT_MS);
|
|
8079
|
+
link.addEventListener("load", settle);
|
|
8080
|
+
link.addEventListener("error", settle);
|
|
8081
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
8082
|
+
if (link.sheet) settle();
|
|
8083
|
+
}));
|
|
8084
|
+
}
|
|
8085
|
+
if (pending.length === 0) return Promise.resolve();
|
|
8086
|
+
return Promise.all(pending).then(() => void 0);
|
|
8087
|
+
};
|
|
8088
|
+
const iframeLoader = (iframe, logger, signal) => {
|
|
8089
|
+
return new Promise((resolve, reject) => {
|
|
8090
|
+
const cloneWindow = iframe.contentWindow;
|
|
8091
|
+
if (!cloneWindow) return reject(`No window assigned for iframe`);
|
|
8092
|
+
const documentClone = cloneWindow.document;
|
|
8093
|
+
let interval;
|
|
8094
|
+
const watchdog = setTimeout(() => {
|
|
8095
|
+
if (interval) clearInterval(interval);
|
|
8096
|
+
reject(/* @__PURE__ */ new Error(`Cloned iframe did not fire its load event within ${IFRAME_LOAD_WATCHDOG_MS}ms`));
|
|
8097
|
+
}, IFRAME_LOAD_WATCHDOG_MS);
|
|
8098
|
+
const onAbort = () => {
|
|
8099
|
+
if (interval) clearInterval(interval);
|
|
8100
|
+
clearTimeout(watchdog);
|
|
8101
|
+
reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
8102
|
+
};
|
|
8103
|
+
cloneWindow.onload = iframe.onload = () => {
|
|
7853
8104
|
cloneWindow.onload = iframe.onload = null;
|
|
7854
|
-
const
|
|
8105
|
+
const maxAttempts = Math.ceil(CLONE_READY_TIMEOUT_MS / 50);
|
|
7855
8106
|
let attempts = 0;
|
|
7856
|
-
|
|
8107
|
+
interval = setInterval(() => {
|
|
7857
8108
|
attempts++;
|
|
7858
|
-
if (
|
|
8109
|
+
if (signal?.aborted) onAbort();
|
|
8110
|
+
else if (documentClone.body.childNodes.length > 0 && documentClone.readyState === "complete") {
|
|
7859
8111
|
clearInterval(interval);
|
|
8112
|
+
interval = void 0;
|
|
8113
|
+
clearTimeout(watchdog);
|
|
7860
8114
|
resolve(iframe);
|
|
7861
|
-
} else if (attempts >=
|
|
8115
|
+
} else if (attempts >= maxAttempts) {
|
|
7862
8116
|
clearInterval(interval);
|
|
8117
|
+
interval = void 0;
|
|
8118
|
+
logger?.warn(`Cloned iframe did not become ready within ${CLONE_READY_TIMEOUT_MS / 1e3} seconds; continuing with a possibly incomplete document`);
|
|
7863
8119
|
resolve(iframe);
|
|
7864
8120
|
}
|
|
7865
8121
|
}, 50);
|
|
7866
8122
|
};
|
|
8123
|
+
if (signal) {
|
|
8124
|
+
if (signal.aborted) onAbort();
|
|
8125
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
8126
|
+
}
|
|
7867
8127
|
});
|
|
7868
8128
|
};
|
|
7869
8129
|
/**
|
|
8130
|
+
* Reduce a doctype component to characters that are inert inside a
|
|
8131
|
+
* <!DOCTYPE ...> declaration. Doctype content is parsed as a declaration
|
|
8132
|
+
* token, never as HTML markup, but the fields originate from the captured
|
|
8133
|
+
* document — stripping markup delimiters and control characters here makes
|
|
8134
|
+
* that property locally verifiable (and keeps the sanitizer guarantee even
|
|
8135
|
+
* if a future serializer ever embeds the result elsewhere).
|
|
8136
|
+
*/
|
|
8137
|
+
const sanitizeDoctypePart = (value) => value.replace(/[<>&"'`\\]|[\u0000-\u001f\u007f]/g, "");
|
|
8138
|
+
/**
|
|
7870
8139
|
* Serialise a document type declaration to an HTML string.
|
|
7871
8140
|
* @internal – exported for testing only, not part of the public API.
|
|
7872
8141
|
*/
|
|
@@ -7874,12 +8143,12 @@ const serializeDoctype = (doctype) => {
|
|
|
7874
8143
|
let str = "";
|
|
7875
8144
|
if (doctype) {
|
|
7876
8145
|
str += "<!DOCTYPE ";
|
|
7877
|
-
if (doctype.name) str += doctype.name;
|
|
7878
|
-
if (doctype.internalSubset) str += " " + doctype.internalSubset
|
|
8146
|
+
if (doctype.name) str += sanitizeDoctypePart(doctype.name);
|
|
8147
|
+
if (doctype.internalSubset) str += " " + sanitizeDoctypePart(doctype.internalSubset);
|
|
7879
8148
|
if (doctype.publicId) {
|
|
7880
|
-
str += " PUBLIC \"" + doctype.publicId
|
|
7881
|
-
if (doctype.systemId) str += " \"" + doctype.systemId
|
|
7882
|
-
} else if (doctype.systemId) str += " SYSTEM \"" + doctype.systemId
|
|
8149
|
+
str += " PUBLIC \"" + sanitizeDoctypePart(doctype.publicId) + "\"";
|
|
8150
|
+
if (doctype.systemId) str += " \"" + sanitizeDoctypePart(doctype.systemId) + "\"";
|
|
8151
|
+
} else if (doctype.systemId) str += " SYSTEM \"" + sanitizeDoctypePart(doctype.systemId) + "\"";
|
|
7883
8152
|
str += ">";
|
|
7884
8153
|
}
|
|
7885
8154
|
return str;
|
|
@@ -7908,14 +8177,21 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7908
8177
|
const scrollY = ownerDocument.defaultView.pageYOffset;
|
|
7909
8178
|
const cloneWindow = iframe.contentWindow;
|
|
7910
8179
|
const documentClone = cloneWindow.document;
|
|
7911
|
-
const iframeLoad = iframeLoader(iframe).then(async () => {
|
|
8180
|
+
const iframeLoad = iframeLoader(iframe, context.logger, mount.signal).then(async () => {
|
|
7912
8181
|
mount.scrolledElements.forEach(restoreNodeScroll);
|
|
7913
8182
|
if (cloneWindow) cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7914
8183
|
const onclone = mount.onclone;
|
|
7915
8184
|
const referenceElement = mount.clonedReferenceElement;
|
|
7916
8185
|
if (typeof referenceElement === "undefined") throw new Error(`Error finding the ${mount.referenceElementName} in the cloned document`);
|
|
8186
|
+
throwIfAborted(mount.signal);
|
|
8187
|
+
await stylesheetWait;
|
|
8188
|
+
throwIfAborted(mount.signal);
|
|
7917
8189
|
if (documentClone.fonts && documentClone.fonts.ready) await documentClone.fonts.ready;
|
|
7918
|
-
|
|
8190
|
+
throwIfAborted(mount.signal);
|
|
8191
|
+
if (/(AppleWebKit)/g.test(navigator.userAgent)) {
|
|
8192
|
+
await imagesReady(documentClone);
|
|
8193
|
+
throwIfAborted(mount.signal);
|
|
8194
|
+
}
|
|
7919
8195
|
if (typeof onclone === "function") await Promise.resolve().then(() => onclone(documentClone, referenceElement));
|
|
7920
8196
|
cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7921
8197
|
if (/AppleWebKit/g.test(navigator.userAgent) && (cloneWindow.scrollY !== windowSize.top || cloneWindow.scrollX !== windowSize.left)) {
|
|
@@ -7931,12 +8207,9 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7931
8207
|
*/
|
|
7932
8208
|
const baseUri = ownerDocument.baseURI;
|
|
7933
8209
|
documentClone.open();
|
|
7934
|
-
const rawHTML = serializeDoctype(
|
|
8210
|
+
const rawHTML = serializeDoctype(ownerDocument.doctype) + "<html></html>";
|
|
7935
8211
|
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 });
|
|
8212
|
+
const policy = resolveTrustedTypesPolicy(ownerDocument.defaultView);
|
|
7940
8213
|
const html = policy ? policy.createHTML(rawHTML) : rawHTML;
|
|
7941
8214
|
documentClone.write(html);
|
|
7942
8215
|
} catch (_e) {
|
|
@@ -7963,6 +8236,7 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7963
8236
|
const adoptedNode = documentClone.adoptNode(mount.documentElement);
|
|
7964
8237
|
addBase(adoptedNode, baseUri);
|
|
7965
8238
|
documentClone.replaceChild(adoptedNode, documentClone.documentElement);
|
|
8239
|
+
const stylesheetWait = stylesheetsReady(documentClone, context.logger, mount.signal);
|
|
7966
8240
|
return iframeLoad;
|
|
7967
8241
|
};
|
|
7968
8242
|
//#endregion
|
|
@@ -7983,6 +8257,15 @@ const findParentShadowRoot = (element) => {
|
|
|
7983
8257
|
return null;
|
|
7984
8258
|
};
|
|
7985
8259
|
var DocumentCloner = class {
|
|
8260
|
+
context;
|
|
8261
|
+
options;
|
|
8262
|
+
scrolledElements;
|
|
8263
|
+
referenceElement;
|
|
8264
|
+
clonedReferenceElement;
|
|
8265
|
+
documentElement;
|
|
8266
|
+
counters;
|
|
8267
|
+
pseudoContents;
|
|
8268
|
+
slotCloner;
|
|
7986
8269
|
constructor(context, element, options) {
|
|
7987
8270
|
this.context = context;
|
|
7988
8271
|
this.options = options;
|
|
@@ -7992,7 +8275,8 @@ var DocumentCloner = class {
|
|
|
7992
8275
|
this.pseudoContents = new PseudoContentResolver(context, this.counters);
|
|
7993
8276
|
this.slotCloner = new SlotCloner((node, copyStyles) => this.cloneNode(node, copyStyles), {
|
|
7994
8277
|
ignoreElements: options.ignoreElements,
|
|
7995
|
-
copyStyles: options.copyStyles ?? true
|
|
8278
|
+
copyStyles: options.copyStyles ?? true,
|
|
8279
|
+
cspNonce: options.cspNonce
|
|
7996
8280
|
}, context);
|
|
7997
8281
|
if (!element.ownerDocument) throw new Error("Cloned element does not have an owner document");
|
|
7998
8282
|
if (!this.options.iframeContainer) {
|
|
@@ -8000,6 +8284,25 @@ var DocumentCloner = class {
|
|
|
8000
8284
|
if (shadowRoot) this.options.iframeContainer = shadowRoot;
|
|
8001
8285
|
}
|
|
8002
8286
|
this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false);
|
|
8287
|
+
this.appendDocumentAdoptedStyles(element.ownerDocument);
|
|
8288
|
+
}
|
|
8289
|
+
/**
|
|
8290
|
+
* Re-materialise the source document's constructable stylesheets
|
|
8291
|
+
* (document.adoptedStyleSheets) as a <style> at the end of the clone's
|
|
8292
|
+
* <head>: cloneNode never carries them, and they cascade after all author
|
|
8293
|
+
* sheets, which appending last approximates.
|
|
8294
|
+
*
|
|
8295
|
+
* Skipped when computed styles are inlined per element (copyStyles), like
|
|
8296
|
+
* the other stylesheet-cloning paths.
|
|
8297
|
+
*/
|
|
8298
|
+
appendDocumentAdoptedStyles(ownerDocument) {
|
|
8299
|
+
if (this.options.copyStyles) return;
|
|
8300
|
+
const sheets = ownerDocument.adoptedStyleSheets;
|
|
8301
|
+
if (!sheets || sheets.length === 0) return;
|
|
8302
|
+
const head = this.documentElement.getElementsByTagName("head").item(0);
|
|
8303
|
+
if (!head) return;
|
|
8304
|
+
const style = createAdoptedStylesElement(this.documentElement.ownerDocument ?? ownerDocument, sheets, this.options.cspNonce);
|
|
8305
|
+
if (style) head.appendChild(style);
|
|
8003
8306
|
}
|
|
8004
8307
|
toIFrame(ownerDocument, windowSize) {
|
|
8005
8308
|
return mountCloneInIFrame(this.context, ownerDocument, windowSize, {
|
|
@@ -8008,7 +8311,8 @@ var DocumentCloner = class {
|
|
|
8008
8311
|
referenceElementName: this.referenceElement.nodeName,
|
|
8009
8312
|
scrolledElements: this.scrolledElements,
|
|
8010
8313
|
onclone: this.options.onclone,
|
|
8011
|
-
container: this.options.iframeContainer
|
|
8314
|
+
container: this.options.iframeContainer,
|
|
8315
|
+
signal: this.options.signal
|
|
8012
8316
|
});
|
|
8013
8317
|
}
|
|
8014
8318
|
createElementClone(node) {
|
|
@@ -8126,7 +8430,7 @@ var DocumentCloner = class {
|
|
|
8126
8430
|
this.slotCloner.cloneChildNodes(node, clone, copyStyles);
|
|
8127
8431
|
}
|
|
8128
8432
|
cloneNode(node, copyStyles) {
|
|
8129
|
-
if (isTextNode(node)) return document.createTextNode(node.data);
|
|
8433
|
+
if (isTextNode(node)) return (node.ownerDocument ?? document).createTextNode(node.data);
|
|
8130
8434
|
if (!node.ownerDocument) return node.cloneNode(false);
|
|
8131
8435
|
const window = node.ownerDocument.defaultView;
|
|
8132
8436
|
if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {
|
|
@@ -8212,7 +8516,7 @@ var DOMNormalizer = class {
|
|
|
8212
8516
|
*/
|
|
8213
8517
|
static normalizeElement(element, styles) {
|
|
8214
8518
|
const originalStyles = {};
|
|
8215
|
-
if (!isHTMLElementNode(element)) return originalStyles;
|
|
8519
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return originalStyles;
|
|
8216
8520
|
if (styles.animationDuration.some((duration) => duration > 0)) {
|
|
8217
8521
|
originalStyles.animationDuration = element.style.animationDuration;
|
|
8218
8522
|
element.style.animationDuration = "0s";
|
|
@@ -8221,13 +8525,25 @@ var DOMNormalizer = class {
|
|
|
8221
8525
|
originalStyles.transform = element.style.transform;
|
|
8222
8526
|
element.style.transform = "translate(0, 0)";
|
|
8223
8527
|
}
|
|
8528
|
+
let needsContainingBlockFallback = false;
|
|
8224
8529
|
if (styles.rotate !== null) {
|
|
8225
8530
|
originalStyles.rotate = element.style.rotate;
|
|
8226
8531
|
element.style.rotate = "0deg";
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8532
|
+
needsContainingBlockFallback = true;
|
|
8533
|
+
}
|
|
8534
|
+
if (styles.translate !== null) {
|
|
8535
|
+
originalStyles.translate = element.style.translate;
|
|
8536
|
+
element.style.translate = "0px";
|
|
8537
|
+
needsContainingBlockFallback = true;
|
|
8538
|
+
}
|
|
8539
|
+
if (styles.scale !== null) {
|
|
8540
|
+
originalStyles.scale = element.style.scale;
|
|
8541
|
+
element.style.scale = "1";
|
|
8542
|
+
needsContainingBlockFallback = true;
|
|
8543
|
+
}
|
|
8544
|
+
if (needsContainingBlockFallback && originalStyles.transform === void 0) {
|
|
8545
|
+
originalStyles.transform = element.style.transform;
|
|
8546
|
+
element.style.transform = "translate(0, 0)";
|
|
8231
8547
|
}
|
|
8232
8548
|
return originalStyles;
|
|
8233
8549
|
}
|
|
@@ -8238,26 +8554,39 @@ var DOMNormalizer = class {
|
|
|
8238
8554
|
* @param originalStyles - Original styles to restore
|
|
8239
8555
|
*/
|
|
8240
8556
|
static restoreElement(element, originalStyles) {
|
|
8241
|
-
if (!isHTMLElementNode(element)) return;
|
|
8557
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return;
|
|
8242
8558
|
if (originalStyles.animationDuration !== void 0) element.style.animationDuration = originalStyles.animationDuration;
|
|
8243
8559
|
if (originalStyles.transform !== void 0) element.style.transform = originalStyles.transform;
|
|
8244
8560
|
if (originalStyles.rotate !== void 0) element.style.rotate = originalStyles.rotate;
|
|
8561
|
+
if (originalStyles.translate !== void 0) element.style.translate = originalStyles.translate;
|
|
8562
|
+
if (originalStyles.scale !== void 0) element.style.scale = originalStyles.scale;
|
|
8245
8563
|
}
|
|
8246
8564
|
};
|
|
8247
8565
|
//#endregion
|
|
8248
8566
|
//#region src/dom/element-container.ts
|
|
8249
8567
|
var ElementContainer = class {
|
|
8568
|
+
context;
|
|
8569
|
+
styles;
|
|
8570
|
+
textNodes = [];
|
|
8571
|
+
elements = [];
|
|
8572
|
+
bounds;
|
|
8573
|
+
/**
|
|
8574
|
+
* Bounds of the <legend> child of a <fieldset>, when present. Browsers break
|
|
8575
|
+
* the fieldset's top border where the legend sits; the renderer uses these
|
|
8576
|
+
* bounds to leave a matching gap (issue #227).
|
|
8577
|
+
*/
|
|
8578
|
+
legendBounds;
|
|
8579
|
+
createsStackingContext = false;
|
|
8580
|
+
createsRealStackingContext = false;
|
|
8581
|
+
isListOwner = false;
|
|
8582
|
+
debugRender = false;
|
|
8583
|
+
originalStyles;
|
|
8584
|
+
originalElement;
|
|
8250
8585
|
constructor(context, element, options = {}) {
|
|
8251
8586
|
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
8587
|
if (isDebugging(element, 3)) debugger;
|
|
8259
8588
|
this.styles = new CSSParsedDeclaration(context, context.config.window.getComputedStyle(element, null));
|
|
8260
|
-
if (options.normalizeDom !== false && isHTMLElementNode(element)) {
|
|
8589
|
+
if (options.normalizeDom !== false && (isHTMLElementNode(element) || isSVGElementNode(element))) {
|
|
8261
8590
|
this.originalStyles = DOMNormalizer.normalizeElement(element, this.styles);
|
|
8262
8591
|
this.originalElement = element;
|
|
8263
8592
|
}
|
|
@@ -8294,278 +8623,16 @@ var ElementContainer = class {
|
|
|
8294
8623
|
}
|
|
8295
8624
|
};
|
|
8296
8625
|
//#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
8626
|
//#region src/core/features.ts
|
|
8627
|
+
/**
|
|
8628
|
+
* Runtime feature detection.
|
|
8629
|
+
*
|
|
8630
|
+
* Only checks that still gate real behaviour are kept: range-bounds
|
|
8631
|
+
* measurement (iOS 13 quirk), SVG drawing and CORS image support.
|
|
8632
|
+
* Dead probes (IE-era CORS XHR / XHR response-type checks) were removed —
|
|
8633
|
+
* every supported browser exposes `crossOrigin`, `responseType` and
|
|
8634
|
+
* `withCredentials`; Intl.Segmenter is used unconditionally.
|
|
8635
|
+
*/
|
|
8569
8636
|
const testRangeBounds = (document) => {
|
|
8570
8637
|
const TEST_HEIGHT = 123;
|
|
8571
8638
|
if (document.createRange) {
|
|
@@ -8584,35 +8651,7 @@ const testRangeBounds = (document) => {
|
|
|
8584
8651
|
}
|
|
8585
8652
|
return false;
|
|
8586
8653
|
};
|
|
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
8654
|
const testCORS = () => typeof new Image().crossOrigin !== "undefined";
|
|
8615
|
-
const testResponseType = () => typeof new XMLHttpRequest().responseType === "string";
|
|
8616
8655
|
const testSVG = (document) => {
|
|
8617
8656
|
const img = new Image();
|
|
8618
8657
|
const canvas = document.createElement("canvas");
|
|
@@ -8627,36 +8666,6 @@ const testSVG = (document) => {
|
|
|
8627
8666
|
}
|
|
8628
8667
|
return true;
|
|
8629
8668
|
};
|
|
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
8669
|
const createForeignObjectSVG = (width, height, x, y, node) => {
|
|
8661
8670
|
const xmlns = "http://www.w3.org/2000/svg";
|
|
8662
8671
|
const svg = document.createElementNS(xmlns, "svg");
|
|
@@ -8687,52 +8696,24 @@ const FEATURES = {
|
|
|
8687
8696
|
Object.defineProperty(FEATURES, "SUPPORT_RANGE_BOUNDS", { value });
|
|
8688
8697
|
return value;
|
|
8689
8698
|
},
|
|
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
8699
|
get SUPPORT_SVG_DRAWING() {
|
|
8697
8700
|
"use strict";
|
|
8698
8701
|
const value = testSVG(document);
|
|
8699
8702
|
Object.defineProperty(FEATURES, "SUPPORT_SVG_DRAWING", { value });
|
|
8700
8703
|
return value;
|
|
8701
8704
|
},
|
|
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
8705
|
get SUPPORT_CORS_IMAGES() {
|
|
8709
8706
|
"use strict";
|
|
8710
8707
|
const value = testCORS();
|
|
8711
8708
|
Object.defineProperty(FEATURES, "SUPPORT_CORS_IMAGES", { value });
|
|
8712
8709
|
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
8710
|
}
|
|
8732
8711
|
};
|
|
8733
8712
|
//#endregion
|
|
8734
8713
|
//#region src/css/layout/text.ts
|
|
8735
8714
|
var TextBounds = class {
|
|
8715
|
+
text;
|
|
8716
|
+
bounds;
|
|
8736
8717
|
constructor(text, bounds) {
|
|
8737
8718
|
this.text = text;
|
|
8738
8719
|
this.bounds = bounds;
|
|
@@ -8791,58 +8772,24 @@ const segmenterCache = /* @__PURE__ */ new Map();
|
|
|
8791
8772
|
const getSegmenter = (granularity) => {
|
|
8792
8773
|
let segmenter = segmenterCache.get(granularity);
|
|
8793
8774
|
if (!segmenter) {
|
|
8794
|
-
|
|
8795
|
-
segmenter = new Segmenter(void 0, { granularity });
|
|
8775
|
+
segmenter = new Intl.Segmenter(void 0, { granularity });
|
|
8796
8776
|
segmenterCache.set(granularity, segmenter);
|
|
8797
8777
|
}
|
|
8798
8778
|
return segmenter;
|
|
8799
8779
|
};
|
|
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);
|
|
8780
|
+
const segmentGraphemes = (value) => Array.from(getSegmenter("grapheme").segment(value), (s) => s.segment);
|
|
8781
|
+
const segmentWords = (value) => {
|
|
8782
|
+
return Array.from(getSegmenter("word").segment(value), (s) => s.segment);
|
|
8807
8783
|
};
|
|
8808
8784
|
const breakText = (value, styles) => {
|
|
8809
8785
|
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;
|
|
8786
|
+
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value);
|
|
8842
8787
|
};
|
|
8843
8788
|
//#endregion
|
|
8844
8789
|
//#region src/dom/text-container.ts
|
|
8845
8790
|
var TextContainer = class {
|
|
8791
|
+
text;
|
|
8792
|
+
textBounds;
|
|
8846
8793
|
constructor(context, node, styles) {
|
|
8847
8794
|
this.text = transform(node.data, styles.textTransform);
|
|
8848
8795
|
if (this.text.length !== node.data.length) node.data = this.text;
|
|
@@ -8865,8 +8812,11 @@ const capitalize = (m, p1, p2) => {
|
|
|
8865
8812
|
//#endregion
|
|
8866
8813
|
//#region src/dom/replaced-elements/image-element-container.ts
|
|
8867
8814
|
var ImageElementContainer = class extends ElementContainer {
|
|
8868
|
-
|
|
8869
|
-
|
|
8815
|
+
src;
|
|
8816
|
+
intrinsicWidth;
|
|
8817
|
+
intrinsicHeight;
|
|
8818
|
+
constructor(context, img, options = {}) {
|
|
8819
|
+
super(context, img, options);
|
|
8870
8820
|
this.src = img.currentSrc || img.src;
|
|
8871
8821
|
this.intrinsicWidth = img.naturalWidth;
|
|
8872
8822
|
this.intrinsicHeight = img.naturalHeight;
|
|
@@ -8876,8 +8826,11 @@ var ImageElementContainer = class extends ElementContainer {
|
|
|
8876
8826
|
//#endregion
|
|
8877
8827
|
//#region src/dom/replaced-elements/canvas-element-container.ts
|
|
8878
8828
|
var CanvasElementContainer = class extends ElementContainer {
|
|
8879
|
-
|
|
8880
|
-
|
|
8829
|
+
canvas;
|
|
8830
|
+
intrinsicWidth;
|
|
8831
|
+
intrinsicHeight;
|
|
8832
|
+
constructor(context, canvas, options = {}) {
|
|
8833
|
+
super(context, canvas, options);
|
|
8881
8834
|
this.canvas = canvas;
|
|
8882
8835
|
this.intrinsicWidth = canvas.width;
|
|
8883
8836
|
this.intrinsicHeight = canvas.height;
|
|
@@ -8919,8 +8872,11 @@ const serializeWithoutBoxOffsets = (serializer, img) => {
|
|
|
8919
8872
|
return serialized;
|
|
8920
8873
|
};
|
|
8921
8874
|
var SVGElementContainer = class extends ElementContainer {
|
|
8922
|
-
|
|
8923
|
-
|
|
8875
|
+
svg;
|
|
8876
|
+
intrinsicWidth;
|
|
8877
|
+
intrinsicHeight;
|
|
8878
|
+
constructor(context, img, options = {}) {
|
|
8879
|
+
super(context, img, options);
|
|
8924
8880
|
const s = new XMLSerializer();
|
|
8925
8881
|
const bounds = parseBounds(context, img);
|
|
8926
8882
|
img.setAttribute("width", `${bounds.width}px`);
|
|
@@ -8934,16 +8890,19 @@ var SVGElementContainer = class extends ElementContainer {
|
|
|
8934
8890
|
//#endregion
|
|
8935
8891
|
//#region src/dom/elements/li-element-container.ts
|
|
8936
8892
|
var LIElementContainer = class extends ElementContainer {
|
|
8937
|
-
|
|
8938
|
-
|
|
8893
|
+
value;
|
|
8894
|
+
constructor(context, element, options = {}) {
|
|
8895
|
+
super(context, element, options);
|
|
8939
8896
|
this.value = element.value;
|
|
8940
8897
|
}
|
|
8941
8898
|
};
|
|
8942
8899
|
//#endregion
|
|
8943
8900
|
//#region src/dom/elements/ol-element-container.ts
|
|
8944
8901
|
var OLElementContainer = class extends ElementContainer {
|
|
8945
|
-
|
|
8946
|
-
|
|
8902
|
+
start;
|
|
8903
|
+
reversed;
|
|
8904
|
+
constructor(context, element, options = {}) {
|
|
8905
|
+
super(context, element, options);
|
|
8947
8906
|
this.start = element.start;
|
|
8948
8907
|
this.reversed = typeof element.reversed === "boolean" && element.reversed === true;
|
|
8949
8908
|
}
|
|
@@ -8977,8 +8936,12 @@ const CHECKBOX = "checkbox";
|
|
|
8977
8936
|
const RADIO = "radio";
|
|
8978
8937
|
const PLACEHOLDER_COLOR = 1970632191;
|
|
8979
8938
|
var InputElementContainer = class extends ElementContainer {
|
|
8980
|
-
|
|
8981
|
-
|
|
8939
|
+
type;
|
|
8940
|
+
checked;
|
|
8941
|
+
value;
|
|
8942
|
+
isPlaceholder;
|
|
8943
|
+
constructor(context, input, options = {}) {
|
|
8944
|
+
super(context, input, options);
|
|
8982
8945
|
this.type = input.type.toLowerCase();
|
|
8983
8946
|
this.checked = input.checked;
|
|
8984
8947
|
this.value = getInputValue(input);
|
|
@@ -9003,8 +8966,9 @@ var InputElementContainer = class extends ElementContainer {
|
|
|
9003
8966
|
//#endregion
|
|
9004
8967
|
//#region src/dom/elements/select-element-container.ts
|
|
9005
8968
|
var SelectElementContainer = class extends ElementContainer {
|
|
9006
|
-
|
|
9007
|
-
|
|
8969
|
+
value;
|
|
8970
|
+
constructor(context, element, options = {}) {
|
|
8971
|
+
super(context, element, options);
|
|
9008
8972
|
const option = element.options[element.selectedIndex || 0];
|
|
9009
8973
|
this.value = option ? option.text || "" : "";
|
|
9010
8974
|
}
|
|
@@ -9012,29 +8976,42 @@ var SelectElementContainer = class extends ElementContainer {
|
|
|
9012
8976
|
//#endregion
|
|
9013
8977
|
//#region src/dom/elements/textarea-element-container.ts
|
|
9014
8978
|
var TextareaElementContainer = class extends ElementContainer {
|
|
9015
|
-
|
|
9016
|
-
|
|
8979
|
+
value;
|
|
8980
|
+
constructor(context, element, options = {}) {
|
|
8981
|
+
super(context, element, options);
|
|
9017
8982
|
this.value = element.value;
|
|
9018
8983
|
}
|
|
9019
8984
|
};
|
|
9020
8985
|
//#endregion
|
|
9021
8986
|
//#region src/dom/replaced-elements/iframe-element-container.ts
|
|
9022
8987
|
var IFrameElementContainer = class extends ElementContainer {
|
|
9023
|
-
|
|
9024
|
-
|
|
8988
|
+
src;
|
|
8989
|
+
width;
|
|
8990
|
+
height;
|
|
8991
|
+
tree;
|
|
8992
|
+
backgroundColor;
|
|
8993
|
+
parseTreeFn;
|
|
8994
|
+
constructor(context, iframe, parseTreeFn, options = {}) {
|
|
8995
|
+
super(context, iframe, options);
|
|
9025
8996
|
this.src = iframe.src;
|
|
9026
8997
|
this.width = parseInt(iframe.width, 10) || 0;
|
|
9027
8998
|
this.height = parseInt(iframe.height, 10) || 0;
|
|
9028
8999
|
this.backgroundColor = this.styles.backgroundColor;
|
|
9029
9000
|
this.parseTreeFn = parseTreeFn;
|
|
9030
9001
|
try {
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9002
|
+
const contentWindow = iframe.contentWindow;
|
|
9003
|
+
const contentDocument = contentWindow?.document;
|
|
9004
|
+
if (contentWindow && contentDocument && contentDocument.documentElement && this.parseTreeFn) {
|
|
9005
|
+
this.tree = this.parseTreeFn(context, contentDocument.documentElement);
|
|
9006
|
+
const documentBackgroundColor = parseColor(context, contentWindow.getComputedStyle(contentDocument.documentElement).backgroundColor);
|
|
9007
|
+
const bodyBackgroundColor = contentDocument.body ? parseColor(context, contentWindow.getComputedStyle(contentDocument.body).backgroundColor) : 0;
|
|
9035
9008
|
this.backgroundColor = isTransparent(documentBackgroundColor) ? isTransparent(bodyBackgroundColor) ? this.styles.backgroundColor : bodyBackgroundColor : documentBackgroundColor;
|
|
9036
9009
|
}
|
|
9037
|
-
} catch (e) {
|
|
9010
|
+
} catch (e) {
|
|
9011
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
9012
|
+
this.context.logger.warn(`Unable to render iframe content${this.src ? ` from ${this.src}` : ""}: ${error.message}`);
|
|
9013
|
+
this.context.onError?.(error);
|
|
9014
|
+
}
|
|
9038
9015
|
}
|
|
9039
9016
|
};
|
|
9040
9017
|
//#endregion
|
|
@@ -9044,10 +9021,10 @@ const LIST_OWNERS = [
|
|
|
9044
9021
|
"UL",
|
|
9045
9022
|
"MENU"
|
|
9046
9023
|
];
|
|
9047
|
-
const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
9024
|
+
const parseNodeTree = (context, node, parent, root, zoomScale = 1, options = {}) => {
|
|
9048
9025
|
for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
|
|
9049
9026
|
nextNode = childNode.nextSibling;
|
|
9050
|
-
parseChildNode(context, childNode, parent, root, zoomScale);
|
|
9027
|
+
parseChildNode(context, childNode, parent, root, zoomScale, options);
|
|
9051
9028
|
}
|
|
9052
9029
|
};
|
|
9053
9030
|
/**
|
|
@@ -9058,7 +9035,7 @@ const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
|
9058
9035
|
* this, slotted shadow-DOM content such as web component labels was silently
|
|
9059
9036
|
* dropped because `parseNodeTree` only iterates `node.firstChild` (issue #226).
|
|
9060
9037
|
*/
|
|
9061
|
-
const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
9038
|
+
const parseChildNode = (context, childNode, parent, root, zoomScale = 1, options = {}) => {
|
|
9062
9039
|
if (isTextNode(childNode) && childNode.data.length > 0) {
|
|
9063
9040
|
const textContainer = new TextContainer(context, childNode, parent.styles);
|
|
9064
9041
|
if (zoomScale !== 1) {
|
|
@@ -9068,9 +9045,9 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9068
9045
|
}
|
|
9069
9046
|
parent.textNodes.push(textContainer);
|
|
9070
9047
|
} else if (isElementNode(childNode)) {
|
|
9071
|
-
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale));
|
|
9048
|
+
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale, options));
|
|
9072
9049
|
else {
|
|
9073
|
-
const container = createContainer(context, childNode);
|
|
9050
|
+
const container = createContainer(context, childNode, options);
|
|
9074
9051
|
const ownZoom = container.styles.zoom || 1;
|
|
9075
9052
|
if (ownZoom !== 1) container.bounds = new Bounds(container.bounds.left, container.bounds.top, container.bounds.width / ownZoom, container.bounds.height / ownZoom);
|
|
9076
9053
|
if (container.styles.isVisible()) {
|
|
@@ -9079,28 +9056,28 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9079
9056
|
if (LIST_OWNERS.indexOf(childNode.tagName) !== -1) container.isListOwner = true;
|
|
9080
9057
|
parent.elements.push(container);
|
|
9081
9058
|
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);
|
|
9059
|
+
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom, options);
|
|
9060
|
+
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom, options);
|
|
9084
9061
|
}
|
|
9085
9062
|
}
|
|
9086
9063
|
}
|
|
9087
9064
|
};
|
|
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);
|
|
9065
|
+
const createContainer = (context, element, options = {}) => {
|
|
9066
|
+
if (isImageElement(element)) return new ImageElementContainer(context, element, options);
|
|
9067
|
+
if (isCanvasElement(element)) return new CanvasElementContainer(context, element, options);
|
|
9068
|
+
if (isSVGElement(element)) return new SVGElementContainer(context, element, options);
|
|
9069
|
+
if (isLIElement(element)) return new LIElementContainer(context, element, options);
|
|
9070
|
+
if (isOLElement(element)) return new OLElementContainer(context, element, options);
|
|
9071
|
+
if (isInputElement(element)) return new InputElementContainer(context, element, options);
|
|
9072
|
+
if (isSelectElement(element)) return new SelectElementContainer(context, element, options);
|
|
9073
|
+
if (isTextareaElement(element)) return new TextareaElementContainer(context, element, options);
|
|
9074
|
+
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, (ctx, node) => parseTree(ctx, node, options), options);
|
|
9075
|
+
return new ElementContainer(context, element, options);
|
|
9099
9076
|
};
|
|
9100
|
-
const parseTree = (context, element) => {
|
|
9101
|
-
const container = createContainer(context, element);
|
|
9077
|
+
const parseTree = (context, element, options = {}) => {
|
|
9078
|
+
const container = createContainer(context, element, options);
|
|
9102
9079
|
container.createsRealStackingContext = true;
|
|
9103
|
-
parseNodeTree(context, element, container, container);
|
|
9080
|
+
parseNodeTree(context, element, container, container, 1, options);
|
|
9104
9081
|
return container;
|
|
9105
9082
|
};
|
|
9106
9083
|
const createsRealStackingContext = (node, container, root) => {
|
|
@@ -9131,6 +9108,9 @@ const transformPath = (path, deltaX, deltaY, deltaW, deltaH) => {
|
|
|
9131
9108
|
//#endregion
|
|
9132
9109
|
//#region src/render/vector.ts
|
|
9133
9110
|
var Vector = class Vector {
|
|
9111
|
+
type;
|
|
9112
|
+
x;
|
|
9113
|
+
y;
|
|
9134
9114
|
constructor(x, y) {
|
|
9135
9115
|
this.type = 0;
|
|
9136
9116
|
this.x = x;
|
|
@@ -9146,6 +9126,11 @@ const lerp = (a, b, t) => {
|
|
|
9146
9126
|
return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
|
|
9147
9127
|
};
|
|
9148
9128
|
var BezierCurve = class BezierCurve {
|
|
9129
|
+
type;
|
|
9130
|
+
start;
|
|
9131
|
+
startControl;
|
|
9132
|
+
endControl;
|
|
9133
|
+
end;
|
|
9149
9134
|
constructor(start, startControl, endControl, end) {
|
|
9150
9135
|
this.type = 1;
|
|
9151
9136
|
this.start = start;
|
|
@@ -9173,6 +9158,30 @@ const isBezierCurve = (path) => path.type === 1;
|
|
|
9173
9158
|
//#endregion
|
|
9174
9159
|
//#region src/render/bound-curves.ts
|
|
9175
9160
|
var BoundCurves = class {
|
|
9161
|
+
topLeftBorderDoubleOuterBox;
|
|
9162
|
+
topRightBorderDoubleOuterBox;
|
|
9163
|
+
bottomRightBorderDoubleOuterBox;
|
|
9164
|
+
bottomLeftBorderDoubleOuterBox;
|
|
9165
|
+
topLeftBorderDoubleInnerBox;
|
|
9166
|
+
topRightBorderDoubleInnerBox;
|
|
9167
|
+
bottomRightBorderDoubleInnerBox;
|
|
9168
|
+
bottomLeftBorderDoubleInnerBox;
|
|
9169
|
+
topLeftBorderStroke;
|
|
9170
|
+
topRightBorderStroke;
|
|
9171
|
+
bottomRightBorderStroke;
|
|
9172
|
+
bottomLeftBorderStroke;
|
|
9173
|
+
topLeftBorderBox;
|
|
9174
|
+
topRightBorderBox;
|
|
9175
|
+
bottomRightBorderBox;
|
|
9176
|
+
bottomLeftBorderBox;
|
|
9177
|
+
topLeftPaddingBox;
|
|
9178
|
+
topRightPaddingBox;
|
|
9179
|
+
bottomRightPaddingBox;
|
|
9180
|
+
bottomLeftPaddingBox;
|
|
9181
|
+
topLeftContentBox;
|
|
9182
|
+
topRightContentBox;
|
|
9183
|
+
bottomRightContentBox;
|
|
9184
|
+
bottomLeftContentBox;
|
|
9176
9185
|
constructor(element) {
|
|
9177
9186
|
const styles = element.styles;
|
|
9178
9187
|
const bounds = element.bounds;
|
|
@@ -9209,15 +9218,15 @@ var BoundCurves = class {
|
|
|
9209
9218
|
const paddingBottom = getAbsoluteValue(styles.paddingBottom, element.bounds.width);
|
|
9210
9219
|
const paddingLeft = getAbsoluteValue(styles.paddingLeft, element.bounds.width);
|
|
9211
9220
|
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 =
|
|
9221
|
+
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
9222
|
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
9223
|
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
9224
|
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 =
|
|
9225
|
+
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
9226
|
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
9227
|
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
9228
|
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 =
|
|
9229
|
+
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
9230
|
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
9231
|
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
9232
|
this.topLeftBorderBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, 0) : new Vector(bounds.left, bounds.top);
|
|
@@ -9274,26 +9283,32 @@ const calculatePaddingBoxPath = (curves) => {
|
|
|
9274
9283
|
//#endregion
|
|
9275
9284
|
//#region src/render/effects.ts
|
|
9276
9285
|
var TransformEffect = class {
|
|
9286
|
+
offsetX;
|
|
9287
|
+
offsetY;
|
|
9288
|
+
matrix;
|
|
9289
|
+
type = 0;
|
|
9290
|
+
target = 6;
|
|
9277
9291
|
constructor(offsetX, offsetY, matrix) {
|
|
9278
9292
|
this.offsetX = offsetX;
|
|
9279
9293
|
this.offsetY = offsetY;
|
|
9280
9294
|
this.matrix = matrix;
|
|
9281
|
-
this.type = 0;
|
|
9282
|
-
this.target = 6;
|
|
9283
9295
|
}
|
|
9284
9296
|
};
|
|
9285
9297
|
var ClipEffect = class {
|
|
9298
|
+
path;
|
|
9299
|
+
target;
|
|
9300
|
+
type = 1;
|
|
9286
9301
|
constructor(path, target) {
|
|
9287
9302
|
this.path = path;
|
|
9288
9303
|
this.target = target;
|
|
9289
|
-
this.type = 1;
|
|
9290
9304
|
}
|
|
9291
9305
|
};
|
|
9292
9306
|
var OpacityEffect = class {
|
|
9307
|
+
opacity;
|
|
9308
|
+
type = 2;
|
|
9309
|
+
target = 6;
|
|
9293
9310
|
constructor(opacity) {
|
|
9294
9311
|
this.opacity = opacity;
|
|
9295
|
-
this.type = 2;
|
|
9296
|
-
this.target = 6;
|
|
9297
9312
|
}
|
|
9298
9313
|
};
|
|
9299
9314
|
/**
|
|
@@ -9303,10 +9318,11 @@ var OpacityEffect = class {
|
|
|
9303
9318
|
* the path is constructed (arc, ellipse, lineTo, Path2D, etc.).
|
|
9304
9319
|
*/
|
|
9305
9320
|
var ClipPathEffect = class {
|
|
9321
|
+
applyClip;
|
|
9322
|
+
type = 3;
|
|
9323
|
+
target = 6;
|
|
9306
9324
|
constructor(applyClip) {
|
|
9307
9325
|
this.applyClip = applyClip;
|
|
9308
|
-
this.type = 3;
|
|
9309
|
-
this.target = 6;
|
|
9310
9326
|
}
|
|
9311
9327
|
};
|
|
9312
9328
|
/**
|
|
@@ -9333,17 +9349,23 @@ const MIX_BLEND_MODE_TO_COMPOSITE = {
|
|
|
9333
9349
|
[MIX_BLEND_MODE$1.LUMINOSITY]: "luminosity"
|
|
9334
9350
|
};
|
|
9335
9351
|
var BlendEffect = class {
|
|
9352
|
+
mixBlendMode;
|
|
9353
|
+
type = 4;
|
|
9354
|
+
target = 6;
|
|
9355
|
+
compositeOperation;
|
|
9336
9356
|
constructor(mixBlendMode) {
|
|
9337
9357
|
this.mixBlendMode = mixBlendMode;
|
|
9338
|
-
this.type = 4;
|
|
9339
|
-
this.target = 6;
|
|
9340
9358
|
this.compositeOperation = MIX_BLEND_MODE_TO_COMPOSITE[mixBlendMode];
|
|
9341
9359
|
}
|
|
9342
9360
|
};
|
|
9343
9361
|
var FilterEffect = class FilterEffect {
|
|
9362
|
+
type = 5;
|
|
9363
|
+
target = 6;
|
|
9364
|
+
/** CSS filter string with drop-shadow() stripped (safe for ctx.filter). */
|
|
9365
|
+
safeFilterString;
|
|
9366
|
+
/** Shadow params for drop-shadow(), if present and successfully parsed. */
|
|
9367
|
+
shadow;
|
|
9344
9368
|
constructor(filterString) {
|
|
9345
|
-
this.type = 5;
|
|
9346
|
-
this.target = 6;
|
|
9347
9369
|
const parsed = FilterEffect.parseDropShadow(filterString);
|
|
9348
9370
|
this.shadow = parsed.shadow;
|
|
9349
9371
|
this.safeFilterString = parsed.safeFilterString;
|
|
@@ -9469,6 +9491,14 @@ const isFilterEffect = (effect) => effect.type === 5;
|
|
|
9469
9491
|
//#endregion
|
|
9470
9492
|
//#region src/render/stacking-context.ts
|
|
9471
9493
|
var StackingContext = class {
|
|
9494
|
+
element;
|
|
9495
|
+
negativeZIndex;
|
|
9496
|
+
zeroOrAutoZIndexOrTransformedOrOpacity;
|
|
9497
|
+
positiveZIndex;
|
|
9498
|
+
nonPositionedFloats;
|
|
9499
|
+
nonPositionedInlineLevel;
|
|
9500
|
+
inlineLevel;
|
|
9501
|
+
nonInlineLevel;
|
|
9472
9502
|
constructor(container) {
|
|
9473
9503
|
this.element = container;
|
|
9474
9504
|
this.inlineLevel = [];
|
|
@@ -9481,13 +9511,34 @@ var StackingContext = class {
|
|
|
9481
9511
|
}
|
|
9482
9512
|
};
|
|
9483
9513
|
var ElementPaint = class {
|
|
9514
|
+
container;
|
|
9515
|
+
parent;
|
|
9516
|
+
effects = [];
|
|
9517
|
+
curves;
|
|
9518
|
+
listValue;
|
|
9519
|
+
/** Memoised getEffects results for the plain (surfaceRoot-less) render path. */
|
|
9520
|
+
plainEffectsCache = null;
|
|
9484
9521
|
constructor(container, parent) {
|
|
9485
9522
|
this.container = container;
|
|
9486
9523
|
this.parent = parent;
|
|
9487
|
-
this.effects = [];
|
|
9488
|
-
this.plainEffectsCache = null;
|
|
9489
9524
|
this.curves = new BoundCurves(this.container);
|
|
9490
9525
|
if (this.container.styles.opacity < 1) this.effects.push(new OpacityEffect(this.container.styles.opacity));
|
|
9526
|
+
if (this.container.styles.translate !== null) {
|
|
9527
|
+
const origin = this.container.styles.transformOrigin;
|
|
9528
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9529
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9530
|
+
const [tx, ty] = this.container.styles.translate;
|
|
9531
|
+
const dx = getAbsoluteValue(tx, this.container.bounds.width);
|
|
9532
|
+
const dy = getAbsoluteValue(ty, this.container.bounds.height);
|
|
9533
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9534
|
+
1,
|
|
9535
|
+
0,
|
|
9536
|
+
0,
|
|
9537
|
+
1,
|
|
9538
|
+
dx,
|
|
9539
|
+
dy
|
|
9540
|
+
]));
|
|
9541
|
+
}
|
|
9491
9542
|
if (this.container.styles.rotate !== null) {
|
|
9492
9543
|
const origin = this.container.styles.transformOrigin;
|
|
9493
9544
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9505,6 +9556,20 @@ var ElementPaint = class {
|
|
|
9505
9556
|
];
|
|
9506
9557
|
this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
|
|
9507
9558
|
}
|
|
9559
|
+
if (this.container.styles.scale !== null) {
|
|
9560
|
+
const origin = this.container.styles.transformOrigin;
|
|
9561
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9562
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9563
|
+
const [sx, sy] = this.container.styles.scale;
|
|
9564
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9565
|
+
sx,
|
|
9566
|
+
0,
|
|
9567
|
+
0,
|
|
9568
|
+
sy,
|
|
9569
|
+
0,
|
|
9570
|
+
0
|
|
9571
|
+
]));
|
|
9572
|
+
}
|
|
9508
9573
|
if (this.container.styles.transform !== null) {
|
|
9509
9574
|
const origin = this.container.styles.transformOrigin;
|
|
9510
9575
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9700,8 +9765,8 @@ const parseStackTree = (parent, stackingContext, realStackingContext, listItems)
|
|
|
9700
9765
|
if (order < 0) {
|
|
9701
9766
|
let index = 0;
|
|
9702
9767
|
parentStack.negativeZIndex.some((current, i) => {
|
|
9703
|
-
if (order
|
|
9704
|
-
index = i;
|
|
9768
|
+
if (order >= current.element.container.styles.zIndex.order) {
|
|
9769
|
+
index = i + 1;
|
|
9705
9770
|
return false;
|
|
9706
9771
|
} else if (index > 0) return true;
|
|
9707
9772
|
return false;
|
|
@@ -9748,6 +9813,86 @@ const parseStackingContexts = (container) => {
|
|
|
9748
9813
|
return root;
|
|
9749
9814
|
};
|
|
9750
9815
|
//#endregion
|
|
9816
|
+
//#region src/render/canvas/gradient-rasterizer.ts
|
|
9817
|
+
const clampStop = (stop) => Math.min(1, Math.max(0, stop));
|
|
9818
|
+
/**
|
|
9819
|
+
* Stack the one-cycle stop list periodically across [0, 1]. Returns null for
|
|
9820
|
+
* a degenerate period (all stops clamped to one point) — CSS renders the
|
|
9821
|
+
* last colour across the whole area in that case, and callers should paint
|
|
9822
|
+
* the last colour instead of stacking.
|
|
9823
|
+
*/
|
|
9824
|
+
const stackRepeatingStops = (processed) => {
|
|
9825
|
+
const first = at(processed, 0);
|
|
9826
|
+
const last = at(processed, processed.length - 1);
|
|
9827
|
+
if (last.stop - first.stop < 1e-6) return null;
|
|
9828
|
+
const period = Math.max(last.stop - first.stop, .01);
|
|
9829
|
+
const stops = [];
|
|
9830
|
+
const cycles = Math.ceil(1 / period);
|
|
9831
|
+
for (let k = 0; k < cycles; k++) for (const s of processed) {
|
|
9832
|
+
const stop = k * period + (s.stop - first.stop);
|
|
9833
|
+
if (stop > 1) break;
|
|
9834
|
+
stops.push({
|
|
9835
|
+
stop,
|
|
9836
|
+
color: asString(s.color)
|
|
9837
|
+
});
|
|
9838
|
+
}
|
|
9839
|
+
const lastPushed = stops[stops.length - 1];
|
|
9840
|
+
if (!lastPushed || lastPushed.stop < 1) stops.push({
|
|
9841
|
+
stop: 1,
|
|
9842
|
+
color: asString(last.color)
|
|
9843
|
+
});
|
|
9844
|
+
return stops;
|
|
9845
|
+
};
|
|
9846
|
+
/** Map parsed stops to string-colour stops clamped into the canvas [0, 1] range. */
|
|
9847
|
+
const toCanvasStops = (processed) => processed.map((s) => ({
|
|
9848
|
+
stop: clampStop(s.stop),
|
|
9849
|
+
color: asString(s.color)
|
|
9850
|
+
}));
|
|
9851
|
+
/**
|
|
9852
|
+
* Rasterise a radial gradient's ending-shape ellipse to an offscreen canvas.
|
|
9853
|
+
*
|
|
9854
|
+
* The ellipse is a circle of radius rx scaled vertically by ry / rx around
|
|
9855
|
+
* the canvas centre, so the offscreen canvas is the ellipse's full 2rx × 2ry
|
|
9856
|
+
* bounding box and callers draw it at (centre - rx, centre - ry). Handles the
|
|
9857
|
+
* repeating variant by stacking stops across the [0, 1] gradient range.
|
|
9858
|
+
*/
|
|
9859
|
+
const rasterizeRadialGradient = (ownerDocument, rx, ry, stops, repeating = false) => {
|
|
9860
|
+
const processed = processColorStops(stops, rx);
|
|
9861
|
+
const last = at(processed, processed.length - 1);
|
|
9862
|
+
const lastColor = asString(last.color);
|
|
9863
|
+
const canvas = ownerDocument.createElement("canvas");
|
|
9864
|
+
canvas.width = Math.max(1, Math.ceil(rx * 2));
|
|
9865
|
+
canvas.height = Math.max(1, Math.ceil(ry * 2));
|
|
9866
|
+
const ctx = canvas.getContext("2d");
|
|
9867
|
+
if (!ctx) return null;
|
|
9868
|
+
let colorStops;
|
|
9869
|
+
if (repeating) {
|
|
9870
|
+
const stacked = stackRepeatingStops(processed);
|
|
9871
|
+
if (!stacked) {
|
|
9872
|
+
ctx.fillStyle = lastColor;
|
|
9873
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
9874
|
+
return {
|
|
9875
|
+
canvas,
|
|
9876
|
+
lastColor,
|
|
9877
|
+
rx,
|
|
9878
|
+
ry
|
|
9879
|
+
};
|
|
9880
|
+
}
|
|
9881
|
+
colorStops = stacked;
|
|
9882
|
+
} else colorStops = toCanvasStops(processed);
|
|
9883
|
+
const gradient = ctx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
9884
|
+
colorStops.forEach((s) => gradient.addColorStop(clampStop(s.stop), s.color));
|
|
9885
|
+
ctx.fillStyle = gradient;
|
|
9886
|
+
if (rx !== ry) ctx.scale(1, ry / rx);
|
|
9887
|
+
ctx.fillRect(0, 0, rx * 2, rx * 2);
|
|
9888
|
+
return {
|
|
9889
|
+
canvas,
|
|
9890
|
+
lastColor,
|
|
9891
|
+
rx,
|
|
9892
|
+
ry
|
|
9893
|
+
};
|
|
9894
|
+
};
|
|
9895
|
+
//#endregion
|
|
9751
9896
|
//#region src/render/box-sizing.ts
|
|
9752
9897
|
const paddingBox = (element) => {
|
|
9753
9898
|
const bounds = element.bounds;
|
|
@@ -9866,67 +10011,184 @@ const calculateBackgroundRepeatPath = (repeat, [x, y], [width, height], backgrou
|
|
|
9866
10011
|
}
|
|
9867
10012
|
};
|
|
9868
10013
|
//#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
10014
|
//#region src/render/canvas/filter-surface.ts
|
|
9886
10015
|
var FilterSurfaceError = class extends Error {};
|
|
9887
10016
|
const releaseSurface = (canvas) => {
|
|
9888
10017
|
canvas.width = canvas.height = 0;
|
|
9889
10018
|
};
|
|
9890
|
-
const
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
10019
|
+
const UNITLESS_NAMES = [
|
|
10020
|
+
"brightness",
|
|
10021
|
+
"contrast",
|
|
10022
|
+
"grayscale",
|
|
10023
|
+
"hue-rotate",
|
|
10024
|
+
"invert",
|
|
10025
|
+
"opacity",
|
|
10026
|
+
"saturate",
|
|
10027
|
+
"sepia"
|
|
10028
|
+
];
|
|
10029
|
+
const PARSED_FILTER_CACHE_MAX = 256;
|
|
10030
|
+
const parsedFilterCache = /* @__PURE__ */ new Map();
|
|
10031
|
+
const EMPTY_FILTER = { functions: [] };
|
|
10032
|
+
function parseFilterChain(value) {
|
|
10033
|
+
if (!value || value === "none") return EMPTY_FILTER;
|
|
10034
|
+
const cached = parsedFilterCache.get(value);
|
|
9895
10035
|
if (cached !== void 0) {
|
|
9896
|
-
|
|
9897
|
-
|
|
10036
|
+
parsedFilterCache.delete(value);
|
|
10037
|
+
parsedFilterCache.set(value, cached);
|
|
9898
10038
|
return cached;
|
|
9899
10039
|
}
|
|
9900
|
-
const parsed =
|
|
9901
|
-
if (
|
|
9902
|
-
const oldest =
|
|
9903
|
-
if (oldest !== void 0)
|
|
10040
|
+
const parsed = computeFilterChain(value);
|
|
10041
|
+
if (parsedFilterCache.size >= PARSED_FILTER_CACHE_MAX) {
|
|
10042
|
+
const oldest = parsedFilterCache.keys().next().value;
|
|
10043
|
+
if (oldest !== void 0) parsedFilterCache.delete(oldest);
|
|
9904
10044
|
}
|
|
9905
|
-
|
|
10045
|
+
parsedFilterCache.set(value, parsed);
|
|
9906
10046
|
return parsed;
|
|
9907
10047
|
}
|
|
9908
|
-
|
|
9909
|
-
const
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
10048
|
+
const computeFilterChain = (value) => {
|
|
10049
|
+
const functions = [];
|
|
10050
|
+
let index = 0;
|
|
10051
|
+
while (index < value.length) {
|
|
10052
|
+
const char = value[index];
|
|
10053
|
+
if (char === " " || char === "\n" || char === " ") {
|
|
10054
|
+
index++;
|
|
10055
|
+
continue;
|
|
10056
|
+
}
|
|
10057
|
+
const open = value.indexOf("(", index);
|
|
10058
|
+
if (open === -1) return null;
|
|
10059
|
+
const name = value.slice(index, open).trim();
|
|
10060
|
+
if (!/^[a-zA-Z-]+$/.test(name)) return null;
|
|
10061
|
+
const bodyEnd = matchingParenthesis(value, open);
|
|
10062
|
+
if (bodyEnd === -1) return null;
|
|
10063
|
+
const fn = parseFilterFunction(name, value.slice(open + 1, bodyEnd).trim());
|
|
10064
|
+
if (!fn) return null;
|
|
10065
|
+
functions.push(fn);
|
|
10066
|
+
index = bodyEnd + 1;
|
|
10067
|
+
}
|
|
10068
|
+
return { functions };
|
|
10069
|
+
};
|
|
10070
|
+
/** Index of the ')' matching the '(' at `open`, or -1. */
|
|
10071
|
+
const matchingParenthesis = (value, open) => {
|
|
10072
|
+
let depth = 1;
|
|
10073
|
+
for (let i = open + 1; i < value.length; i++) {
|
|
10074
|
+
const char = value[i];
|
|
10075
|
+
if (char === "(") depth++;
|
|
10076
|
+
else if (char === ")") {
|
|
10077
|
+
depth--;
|
|
10078
|
+
if (depth === 0) return i;
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
return -1;
|
|
10082
|
+
};
|
|
10083
|
+
const PX_LENGTH_RE = /^-?\d+(?:\.\d+)?px$/;
|
|
10084
|
+
const parseFilterFunction = (name, body) => {
|
|
10085
|
+
if (name === "blur") {
|
|
10086
|
+
if (body === "0") return {
|
|
10087
|
+
kind: "blur",
|
|
10088
|
+
value: 0
|
|
10089
|
+
};
|
|
10090
|
+
if (!PX_LENGTH_RE.test(body)) return null;
|
|
10091
|
+
const value = Number.parseFloat(body);
|
|
10092
|
+
return value < 0 ? null : {
|
|
10093
|
+
kind: "blur",
|
|
10094
|
+
value
|
|
10095
|
+
};
|
|
10096
|
+
}
|
|
10097
|
+
if (name === "drop-shadow") return parseDropShadowBody(body);
|
|
10098
|
+
if (UNITLESS_NAMES.indexOf(name) !== -1) {
|
|
10099
|
+
const unitless = name;
|
|
10100
|
+
if (unitless === "hue-rotate") {
|
|
10101
|
+
const degrees = parseAngleDegrees(body);
|
|
10102
|
+
return degrees === null ? null : {
|
|
10103
|
+
kind: "unitless",
|
|
10104
|
+
name: unitless,
|
|
10105
|
+
value: degrees
|
|
10106
|
+
};
|
|
10107
|
+
}
|
|
10108
|
+
const trimmed = body.trim();
|
|
10109
|
+
const percentage = trimmed.endsWith("%");
|
|
10110
|
+
const numeric = percentage ? trimmed.slice(0, -1) : trimmed;
|
|
10111
|
+
if (!/^-?\d+(?:\.\d+)?$/.test(numeric)) return null;
|
|
10112
|
+
return {
|
|
10113
|
+
kind: "unitless",
|
|
10114
|
+
name: unitless,
|
|
10115
|
+
value: Number.parseFloat(numeric) * (percentage ? 1 / 100 : 1)
|
|
10116
|
+
};
|
|
10117
|
+
}
|
|
10118
|
+
return null;
|
|
10119
|
+
};
|
|
10120
|
+
/** Split on whitespace outside parentheses so rgba(...) colours stay one token. */
|
|
10121
|
+
const splitTopLevel = (body) => {
|
|
10122
|
+
const parts = [];
|
|
10123
|
+
let depth = 0;
|
|
10124
|
+
let current = "";
|
|
10125
|
+
for (const char of body) {
|
|
10126
|
+
if (char === "(") depth++;
|
|
10127
|
+
else if (char === ")") depth--;
|
|
10128
|
+
if (char === " " && depth === 0) {
|
|
10129
|
+
if (current) parts.push(current);
|
|
10130
|
+
current = "";
|
|
10131
|
+
continue;
|
|
10132
|
+
}
|
|
10133
|
+
current += char;
|
|
10134
|
+
}
|
|
10135
|
+
if (current) parts.push(current);
|
|
10136
|
+
return parts;
|
|
10137
|
+
};
|
|
10138
|
+
const parseDropShadowBody = (body) => {
|
|
10139
|
+
const parts = splitTopLevel(body);
|
|
10140
|
+
const lengths = parts.filter((part) => PX_LENGTH_RE.test(part)).map((part) => Number.parseFloat(part));
|
|
10141
|
+
if (lengths.length < 2 || lengths.length > 3) return null;
|
|
10142
|
+
const colors = parts.filter((part) => !PX_LENGTH_RE.test(part));
|
|
10143
|
+
if (parts.length - colors.length !== lengths.length) return null;
|
|
9915
10144
|
return {
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
color: effect.shadow.color
|
|
9922
|
-
} : void 0
|
|
10145
|
+
kind: "drop-shadow",
|
|
10146
|
+
x: lengths[0],
|
|
10147
|
+
y: lengths[1],
|
|
10148
|
+
blur: lengths[2] ?? 0,
|
|
10149
|
+
color: colors.join(" ") || "rgba(0, 0, 0, 0)"
|
|
9923
10150
|
};
|
|
9924
|
-
}
|
|
10151
|
+
};
|
|
10152
|
+
const parseAngleDegrees = (body) => {
|
|
10153
|
+
const trimmed = body.trim();
|
|
10154
|
+
if (trimmed === "0") return 0;
|
|
10155
|
+
const numeric = Number.parseFloat(trimmed);
|
|
10156
|
+
if (Number.isNaN(numeric)) return null;
|
|
10157
|
+
if (trimmed.endsWith("deg")) return numeric;
|
|
10158
|
+
if (trimmed.endsWith("grad")) return numeric * .9;
|
|
10159
|
+
if (trimmed.endsWith("rad")) return numeric * 180 / Math.PI;
|
|
10160
|
+
if (trimmed.endsWith("turn")) return numeric * 360;
|
|
10161
|
+
return null;
|
|
10162
|
+
};
|
|
10163
|
+
/**
|
|
10164
|
+
* Render the chain as a canvas ctx.filter string, scaling all device-space
|
|
10165
|
+
* lengths (blur radii, shadow offsets) by the capture scale. Unitless
|
|
10166
|
+
* functions and hue angles are scale-invariant.
|
|
10167
|
+
*/
|
|
10168
|
+
const nativeFilterString = (filter, scale) => filter.functions.map((fn) => {
|
|
10169
|
+
switch (fn.kind) {
|
|
10170
|
+
case "blur": return `blur(${fn.value * scale}px)`;
|
|
10171
|
+
case "drop-shadow": return `drop-shadow(${fn.x * scale}px ${fn.y * scale}px ${fn.blur * scale}px ${fn.color})`;
|
|
10172
|
+
case "unitless": return fn.name === "hue-rotate" ? `hue-rotate(${fn.value}deg)` : `${fn.name}(${fn.value})`;
|
|
10173
|
+
}
|
|
10174
|
+
}).join(" ");
|
|
10175
|
+
/**
|
|
10176
|
+
* Outset (in CSS pixels) a surface must grow so blur/shadow spillover is not
|
|
10177
|
+
* cropped. Unitless functions never spread beyond the bounds. Consecutive
|
|
10178
|
+
* blurs compound, so their radii sum.
|
|
10179
|
+
*/
|
|
9925
10180
|
function filterOutset(filter) {
|
|
9926
|
-
|
|
10181
|
+
let blurSum = 0;
|
|
10182
|
+
let maxShadowOffset = 0;
|
|
10183
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurSum += fn.value;
|
|
10184
|
+
else if (fn.kind === "drop-shadow") {
|
|
10185
|
+
blurSum += fn.blur;
|
|
10186
|
+
maxShadowOffset = Math.max(maxShadowOffset, Math.abs(fn.x), Math.abs(fn.y));
|
|
10187
|
+
}
|
|
10188
|
+
return Math.ceil(3 * blurSum + maxShadowOffset);
|
|
9927
10189
|
}
|
|
9928
10190
|
function canvasLike(source) {
|
|
9929
|
-
const canvas = document.createElement("canvas");
|
|
10191
|
+
const canvas = (source.ownerDocument ?? document).createElement("canvas");
|
|
9930
10192
|
canvas.width = source.width;
|
|
9931
10193
|
canvas.height = source.height;
|
|
9932
10194
|
return canvas;
|
|
@@ -9974,7 +10236,7 @@ function supportsNativeFilters(owner = document) {
|
|
|
9974
10236
|
canvasFilterSupport.set(owner, supported);
|
|
9975
10237
|
return supported;
|
|
9976
10238
|
}
|
|
9977
|
-
function tryNativeFilterSurface(source,
|
|
10239
|
+
function tryNativeFilterSurface(source, filter, opacity, scale, signal) {
|
|
9978
10240
|
let filtered;
|
|
9979
10241
|
let output;
|
|
9980
10242
|
let complete = false;
|
|
@@ -9983,11 +10245,8 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
9983
10245
|
filtered = canvasLike(source);
|
|
9984
10246
|
const context = filtered.getContext("2d");
|
|
9985
10247
|
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;
|
|
10248
|
+
context.filter = nativeFilterString(filter, scale);
|
|
10249
|
+
if (context.filter === "none" || context.filter === "") return null;
|
|
9991
10250
|
context.drawImage(source, 0, 0);
|
|
9992
10251
|
throwIfAborted(signal);
|
|
9993
10252
|
output = canvasLike(source);
|
|
@@ -10006,17 +10265,43 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
10006
10265
|
if (output && !complete) releaseSurface(output);
|
|
10007
10266
|
}
|
|
10008
10267
|
}
|
|
10268
|
+
/**
|
|
10269
|
+
* The SVG fallback predates the ordered-chain parser and only expresses the
|
|
10270
|
+
* blur + single drop-shadow subset (at most one of each, blur before the
|
|
10271
|
+
* shadow). Chains outside that subset reject with FilterSurfaceError so the
|
|
10272
|
+
* caller keeps its legacy renderer instead of rendering a wrong filter.
|
|
10273
|
+
*/
|
|
10274
|
+
const isSvgExpressible = (filter) => {
|
|
10275
|
+
let blurs = 0;
|
|
10276
|
+
let shadows = 0;
|
|
10277
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurs++;
|
|
10278
|
+
else if (fn.kind === "drop-shadow") shadows++;
|
|
10279
|
+
else return false;
|
|
10280
|
+
if (blurs > 1 || shadows > 1) return false;
|
|
10281
|
+
if (blurs > 0 && shadows > 0) return filter.functions.findIndex((fn) => fn.kind === "blur") < filter.functions.findIndex((fn) => fn.kind === "drop-shadow");
|
|
10282
|
+
return true;
|
|
10283
|
+
};
|
|
10009
10284
|
async function renderFilterSurface(source, filter, opacity, scale, signal) {
|
|
10010
10285
|
throwIfAborted(signal);
|
|
10011
|
-
if (
|
|
10286
|
+
if (filter.functions.length > 0 && supportsNativeFilters(source.ownerDocument ?? document)) {
|
|
10012
10287
|
const output = tryNativeFilterSurface(source, filter, opacity, scale, signal);
|
|
10013
10288
|
if (output) return output;
|
|
10014
10289
|
}
|
|
10290
|
+
if (!isSvgExpressible(filter)) throw new FilterSurfaceError("Filter chain requires native canvas filters");
|
|
10015
10291
|
return renderSvgFilterSurface(source, filter, opacity, scale, signal);
|
|
10016
10292
|
}
|
|
10017
|
-
async function renderSvgFilterSurface(source,
|
|
10293
|
+
async function renderSvgFilterSurface(source, filter, opacity, scale, signal) {
|
|
10018
10294
|
throwIfAborted(signal);
|
|
10019
|
-
|
|
10295
|
+
const blur = filter.functions.find((fn) => fn.kind === "blur");
|
|
10296
|
+
const shadow = filter.functions.find((fn) => fn.kind === "drop-shadow");
|
|
10297
|
+
const blurValue = blur && blur.kind === "blur" ? blur.value : 0;
|
|
10298
|
+
const shadowValue = shadow && shadow.kind === "drop-shadow" ? {
|
|
10299
|
+
x: shadow.x,
|
|
10300
|
+
y: shadow.y,
|
|
10301
|
+
blur: shadow.blur,
|
|
10302
|
+
color: shadow.color
|
|
10303
|
+
} : void 0;
|
|
10304
|
+
if (!blurValue && !shadowValue) {
|
|
10020
10305
|
const output = canvasLike(source);
|
|
10021
10306
|
const context = output.getContext("2d");
|
|
10022
10307
|
if (!context) {
|
|
@@ -10033,8 +10318,9 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10033
10318
|
}
|
|
10034
10319
|
}
|
|
10035
10320
|
const namespace = "http://www.w3.org/2000/svg";
|
|
10321
|
+
const svgDocument = source.ownerDocument ?? document;
|
|
10036
10322
|
const element = (tag, attributes = {}) => {
|
|
10037
|
-
const node =
|
|
10323
|
+
const node = svgDocument.createElementNS(namespace, tag);
|
|
10038
10324
|
Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
|
|
10039
10325
|
return node;
|
|
10040
10326
|
};
|
|
@@ -10044,7 +10330,7 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10044
10330
|
viewBox: `0 0 ${source.width} ${source.height}`
|
|
10045
10331
|
});
|
|
10046
10332
|
const defs = element("defs");
|
|
10047
|
-
const
|
|
10333
|
+
const filterElement = element("filter", {
|
|
10048
10334
|
id: "composited-filter",
|
|
10049
10335
|
filterUnits: "userSpaceOnUse",
|
|
10050
10336
|
x: 0,
|
|
@@ -10053,31 +10339,31 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10053
10339
|
height: source.height,
|
|
10054
10340
|
"color-interpolation-filters": "sRGB"
|
|
10055
10341
|
});
|
|
10056
|
-
if (
|
|
10057
|
-
stdDeviation:
|
|
10342
|
+
if (blurValue) filterElement.appendChild(element("feGaussianBlur", {
|
|
10343
|
+
stdDeviation: blurValue * scale,
|
|
10058
10344
|
result: "blurred-source"
|
|
10059
10345
|
}));
|
|
10060
|
-
if (
|
|
10061
|
-
|
|
10062
|
-
in:
|
|
10063
|
-
stdDeviation:
|
|
10346
|
+
if (shadowValue) {
|
|
10347
|
+
filterElement.appendChild(element("feGaussianBlur", {
|
|
10348
|
+
in: blurValue ? "blurred-source" : "SourceAlpha",
|
|
10349
|
+
stdDeviation: shadowValue.blur * scale
|
|
10064
10350
|
}));
|
|
10065
|
-
|
|
10066
|
-
dx:
|
|
10067
|
-
dy:
|
|
10351
|
+
filterElement.appendChild(element("feOffset", {
|
|
10352
|
+
dx: shadowValue.x * scale,
|
|
10353
|
+
dy: shadowValue.y * scale,
|
|
10068
10354
|
result: "offset-shadow"
|
|
10069
10355
|
}));
|
|
10070
|
-
|
|
10071
|
-
|
|
10356
|
+
filterElement.appendChild(element("feFlood", { "flood-color": shadowValue.color }));
|
|
10357
|
+
filterElement.appendChild(element("feComposite", {
|
|
10072
10358
|
in2: "offset-shadow",
|
|
10073
10359
|
operator: "in"
|
|
10074
10360
|
}));
|
|
10075
10361
|
const merge = element("feMerge");
|
|
10076
10362
|
merge.appendChild(element("feMergeNode"));
|
|
10077
|
-
merge.appendChild(element("feMergeNode", { in:
|
|
10078
|
-
|
|
10363
|
+
merge.appendChild(element("feMergeNode", { in: blurValue ? "blurred-source" : "SourceGraphic" }));
|
|
10364
|
+
filterElement.appendChild(merge);
|
|
10079
10365
|
}
|
|
10080
|
-
defs.appendChild(
|
|
10366
|
+
defs.appendChild(filterElement);
|
|
10081
10367
|
svg.appendChild(defs);
|
|
10082
10368
|
let sourceUrl;
|
|
10083
10369
|
try {
|
|
@@ -10092,7 +10378,8 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10092
10378
|
href: sourceUrl,
|
|
10093
10379
|
filter: "url(#composited-filter)"
|
|
10094
10380
|
}));
|
|
10095
|
-
const
|
|
10381
|
+
const imageWindow = svgDocument.defaultView;
|
|
10382
|
+
const image = imageWindow?.Image ? new imageWindow.Image() : new Image();
|
|
10096
10383
|
let output;
|
|
10097
10384
|
try {
|
|
10098
10385
|
image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
|
|
@@ -10133,7 +10420,7 @@ function surfaceBounds(container) {
|
|
|
10133
10420
|
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
10421
|
}
|
|
10135
10422
|
for (const child of container.elements) if (child.styles.isVisible()) bounds = union(bounds, surfaceBounds(child));
|
|
10136
|
-
const filter =
|
|
10423
|
+
const filter = parseFilterChain(styles.filter);
|
|
10137
10424
|
return expand(bounds, filter ? filterOutset(filter) : 0);
|
|
10138
10425
|
}
|
|
10139
10426
|
function cropSurface(bounds, viewport, margin, scale) {
|
|
@@ -10147,11 +10434,12 @@ function cropSurface(bounds, viewport, margin, scale) {
|
|
|
10147
10434
|
//#endregion
|
|
10148
10435
|
//#region src/render/canvas/text/text-decoration-renderer.ts
|
|
10149
10436
|
var TextDecorationRenderer = class {
|
|
10437
|
+
ctx;
|
|
10150
10438
|
constructor(ctx) {
|
|
10151
10439
|
this.ctx = ctx;
|
|
10152
10440
|
}
|
|
10153
10441
|
render(bounds, styles) {
|
|
10154
|
-
this.ctx.fillStyle = asString(styles.textDecorationColor
|
|
10442
|
+
this.ctx.fillStyle = asString(styles.textDecorationColor ?? styles.color);
|
|
10155
10443
|
let thickness = 1;
|
|
10156
10444
|
if (typeof styles.textDecorationThickness === "number") thickness = styles.textDecorationThickness;
|
|
10157
10445
|
else if (styles.textDecorationThickness === "from-font") thickness = Math.max(1, Math.floor(styles.fontSize.number * .05));
|
|
@@ -10270,7 +10558,6 @@ const measureBaseline = (ctx, fallback) => {
|
|
|
10270
10558
|
};
|
|
10271
10559
|
//#endregion
|
|
10272
10560
|
//#region src/render/canvas/text-renderer.ts
|
|
10273
|
-
const iOSBrokenFonts = ["-apple-system", "system-ui"];
|
|
10274
10561
|
const TEXT_OVERFLOW_EPSILON = 1;
|
|
10275
10562
|
/**
|
|
10276
10563
|
* Detect CJK (Chinese, Japanese, Korean) characters in a string.
|
|
@@ -10289,29 +10576,19 @@ const TEXT_OVERFLOW_EPSILON = 1;
|
|
|
10289
10576
|
const CJK_CHAR_REGEX = /[\u2E80-\u2FFF\u3000-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF01-\uFFEF]/;
|
|
10290
10577
|
const hasCJKCharacters = (text) => CJK_CHAR_REGEX.test(text);
|
|
10291
10578
|
/**
|
|
10292
|
-
*
|
|
10293
|
-
*
|
|
10579
|
+
* Chromium-based engines render stroked text with visibly sharper joins when
|
|
10580
|
+
* `miter` is requested, closely matching their own -webkit-text-stroke
|
|
10581
|
+
* output; other engines need `round` joins to avoid glyph spikes. No CSS or
|
|
10582
|
+
* platform API expresses this behavioural difference, so engine detection is
|
|
10583
|
+
* the only reliable signal: `navigator.userAgentData` is Chromium-only, with
|
|
10584
|
+
* the legacy `window.chrome` marker as a fallback for older webviews.
|
|
10294
10585
|
*/
|
|
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";
|
|
10586
|
+
const isChromiumEngine = () => {
|
|
10587
|
+
if (typeof navigator === "undefined") return false;
|
|
10588
|
+
if (navigator.userAgentData !== void 0) return true;
|
|
10589
|
+
return (typeof window !== "undefined" ? window : void 0)?.chrome !== void 0;
|
|
10314
10590
|
};
|
|
10591
|
+
const getTextStrokeLineJoin = () => isChromiumEngine() ? "miter" : "round";
|
|
10315
10592
|
/**
|
|
10316
10593
|
* Text Renderer
|
|
10317
10594
|
*
|
|
@@ -10319,9 +10596,23 @@ const getTextStrokeLineJoin = () => {
|
|
|
10319
10596
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10320
10597
|
*/
|
|
10321
10598
|
var TextRenderer = class {
|
|
10599
|
+
ctx;
|
|
10600
|
+
options;
|
|
10601
|
+
decorationRenderer;
|
|
10602
|
+
/**
|
|
10603
|
+
* Baseline ascent per font string. Consecutive text nodes overwhelmingly
|
|
10604
|
+
* share a font, and each measureBaseline call issues a canvas measureText,
|
|
10605
|
+
* so repeated fonts are memoised (bounded; cleared if the working set
|
|
10606
|
+
* exceeds the cap).
|
|
10607
|
+
*/
|
|
10608
|
+
baselineCache = /* @__PURE__ */ new Map();
|
|
10609
|
+
/**
|
|
10610
|
+
* Per-render glyph width cache. Keyed by glyph + font string,
|
|
10611
|
+
* avoids redundant `measureText` calls when letter-spacing is non-zero.
|
|
10612
|
+
* Cleared at the start of each renderTextNode call.
|
|
10613
|
+
*/
|
|
10614
|
+
glyphWidthCache = null;
|
|
10322
10615
|
constructor(deps) {
|
|
10323
|
-
this.baselineCache = /* @__PURE__ */ new Map();
|
|
10324
|
-
this.glyphWidthCache = null;
|
|
10325
10616
|
this.ctx = deps.ctx;
|
|
10326
10617
|
this.options = deps.options;
|
|
10327
10618
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
@@ -10514,7 +10805,7 @@ var TextRenderer = class {
|
|
|
10514
10805
|
*/
|
|
10515
10806
|
createFontStyle(styles) {
|
|
10516
10807
|
const fontVariant = styles.fontVariant.filter((variant) => variant === "normal" || variant === "small-caps").join("");
|
|
10517
|
-
const fontFamily =
|
|
10808
|
+
const fontFamily = styles.fontFamily.join(", ");
|
|
10518
10809
|
const fontSize = isDimensionToken(styles.fontSize) ? `${styles.fontSize.number}${styles.fontSize.unit}` : `${styles.fontSize.number}px`;
|
|
10519
10810
|
return [
|
|
10520
10811
|
[
|
|
@@ -10543,7 +10834,7 @@ var TextRenderer = class {
|
|
|
10543
10834
|
* only the first N-1 complete lines followed by an ellipsis on the Nth line.
|
|
10544
10835
|
*/
|
|
10545
10836
|
renderLineClampedText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10546
|
-
const lineHeight = styles.fontSize.number
|
|
10837
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10547
10838
|
const lines = [];
|
|
10548
10839
|
let currentLine = [];
|
|
10549
10840
|
let currentLineTop = at(text.textBounds, 0).bounds.top;
|
|
@@ -10576,7 +10867,7 @@ var TextRenderer = class {
|
|
|
10576
10867
|
* Returns true if ellipsis was applied (caller should skip normal rendering).
|
|
10577
10868
|
*/
|
|
10578
10869
|
renderEllipsisText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10579
|
-
const lineHeight = styles.fontSize.number
|
|
10870
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10580
10871
|
const firstTop = at(text.textBounds, 0).bounds.top;
|
|
10581
10872
|
if (!text.textBounds.every((tb) => Math.abs(tb.bounds.top - firstTop) < lineHeight * .5)) return false;
|
|
10582
10873
|
let fullText = text.textBounds.map((tb) => tb.text).join("").replace(/\s+/g, " ").trim();
|
|
@@ -10725,6 +11016,8 @@ const createCanvasPath = (ctx, paths) => {
|
|
|
10725
11016
|
* ```
|
|
10726
11017
|
*/
|
|
10727
11018
|
var LRUMap = class {
|
|
11019
|
+
maxSize;
|
|
11020
|
+
_map;
|
|
10728
11021
|
constructor(maxSize) {
|
|
10729
11022
|
this.maxSize = maxSize;
|
|
10730
11023
|
this._map = /* @__PURE__ */ new Map();
|
|
@@ -10773,8 +11066,17 @@ var LRUMap = class {
|
|
|
10773
11066
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10774
11067
|
*/
|
|
10775
11068
|
var BackgroundRenderer = class {
|
|
11069
|
+
ctx;
|
|
11070
|
+
context;
|
|
11071
|
+
canvas;
|
|
11072
|
+
/**
|
|
11073
|
+
* Instance-level LRU cache for background-image patterns.
|
|
11074
|
+
* CanvasPatterns are tied to the rendering context and must not be
|
|
11075
|
+
* shared across different render passes. This cache lives for the
|
|
11076
|
+
* duration of one html2canvas() call.
|
|
11077
|
+
*/
|
|
11078
|
+
patternCache = new LRUMap(50);
|
|
10776
11079
|
constructor(deps) {
|
|
10777
|
-
this.patternCache = new LRUMap(50);
|
|
10778
11080
|
this.ctx = deps.ctx;
|
|
10779
11081
|
this.context = deps.context;
|
|
10780
11082
|
this.canvas = deps.canvas;
|
|
@@ -10821,7 +11123,6 @@ var BackgroundRenderer = class {
|
|
|
10821
11123
|
image = await this.context.cache.match(url);
|
|
10822
11124
|
} catch (e) {
|
|
10823
11125
|
this.context.logger.error(`Error loading background-image ${url}`);
|
|
10824
|
-
this.context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
10825
11126
|
}
|
|
10826
11127
|
if (image) {
|
|
10827
11128
|
const imageWidth = isNaN(image.width) || image.width === 0 ? 1 : image.width;
|
|
@@ -10860,34 +11161,13 @@ var BackgroundRenderer = class {
|
|
|
10860
11161
|
const gy0 = y + ly0;
|
|
10861
11162
|
const gy1 = y + ly1;
|
|
10862
11163
|
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
|
-
});
|
|
11164
|
+
const stacked = stackRepeatingStops(processedStops);
|
|
10889
11165
|
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10890
|
-
|
|
11166
|
+
if (!stacked) {
|
|
11167
|
+
const lastColor = asString(at(processedStops, processedStops.length - 1).color);
|
|
11168
|
+
gradient.addColorStop(0, lastColor);
|
|
11169
|
+
gradient.addColorStop(1, lastColor);
|
|
11170
|
+
} else stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
10891
11171
|
this.path(path);
|
|
10892
11172
|
this.ctx.fillStyle = gradient;
|
|
10893
11173
|
this.ctx.fill();
|
|
@@ -10940,37 +11220,25 @@ var BackgroundRenderer = class {
|
|
|
10940
11220
|
}
|
|
10941
11221
|
if (rx > 0 && ry > 0) {
|
|
10942
11222
|
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
|
|
11223
|
+
const processed = processColorStops(backgroundImage.stops, rx);
|
|
11224
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
10945
11225
|
let pattern = this.patternCache.get(cacheKey);
|
|
10946
11226
|
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();
|
|
11227
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11228
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, false);
|
|
11229
|
+
if (!rasterized) return;
|
|
11230
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11231
|
+
this.patternCache.set(cacheKey, pattern);
|
|
10973
11232
|
}
|
|
11233
|
+
this.path(path);
|
|
11234
|
+
this.ctx.save();
|
|
11235
|
+
this.ctx.clip();
|
|
11236
|
+
this.ctx.fillStyle = lastColor;
|
|
11237
|
+
this.ctx.fill();
|
|
11238
|
+
this.ctx.translate(left + x - rx, top + y - ry);
|
|
11239
|
+
this.ctx.fillStyle = pattern;
|
|
11240
|
+
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11241
|
+
this.ctx.restore();
|
|
10974
11242
|
}
|
|
10975
11243
|
}
|
|
10976
11244
|
/**
|
|
@@ -10997,40 +11265,14 @@ var BackgroundRenderer = class {
|
|
|
10997
11265
|
ry = Math.max(ry, .01);
|
|
10998
11266
|
}
|
|
10999
11267
|
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)}`;
|
|
11268
|
+
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11019
11269
|
let pattern = this.patternCache.get(cacheKey);
|
|
11020
11270
|
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
|
-
}
|
|
11271
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11272
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, true);
|
|
11273
|
+
if (!rasterized) return;
|
|
11274
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11275
|
+
this.patternCache.set(cacheKey, pattern);
|
|
11034
11276
|
}
|
|
11035
11277
|
if (pattern) {
|
|
11036
11278
|
this.path(path);
|
|
@@ -11242,6 +11484,8 @@ const createPathFromCurves = (outer1, inner1, outer2, inner2) => {
|
|
|
11242
11484
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
11243
11485
|
*/
|
|
11244
11486
|
var BorderRenderer = class {
|
|
11487
|
+
ctx;
|
|
11488
|
+
pathCallbacks;
|
|
11245
11489
|
constructor(deps, pathCallbacks) {
|
|
11246
11490
|
this.ctx = deps.ctx;
|
|
11247
11491
|
this.pathCallbacks = pathCallbacks;
|
|
@@ -11418,6 +11662,7 @@ const resolveBorderImageOutset = (outset, borderWidths) => {
|
|
|
11418
11662
|
};
|
|
11419
11663
|
};
|
|
11420
11664
|
var BorderImageRenderer = class {
|
|
11665
|
+
ctx;
|
|
11421
11666
|
constructor(ctx) {
|
|
11422
11667
|
this.ctx = ctx;
|
|
11423
11668
|
}
|
|
@@ -11455,7 +11700,8 @@ var BorderImageRenderer = class {
|
|
|
11455
11700
|
dy: top,
|
|
11456
11701
|
dw: width - dL - dR,
|
|
11457
11702
|
dh: dT,
|
|
11458
|
-
repeat: repeat.horizontal
|
|
11703
|
+
repeat: repeat.horizontal,
|
|
11704
|
+
horizontal: true
|
|
11459
11705
|
},
|
|
11460
11706
|
{
|
|
11461
11707
|
sx: imgW - sR,
|
|
@@ -11466,7 +11712,8 @@ var BorderImageRenderer = class {
|
|
|
11466
11712
|
dy: top + dT,
|
|
11467
11713
|
dw: dR,
|
|
11468
11714
|
dh: height - dT - dB,
|
|
11469
|
-
repeat: repeat.vertical
|
|
11715
|
+
repeat: repeat.vertical,
|
|
11716
|
+
horizontal: false
|
|
11470
11717
|
},
|
|
11471
11718
|
{
|
|
11472
11719
|
sx: sL,
|
|
@@ -11477,7 +11724,8 @@ var BorderImageRenderer = class {
|
|
|
11477
11724
|
dy: top + height - dB,
|
|
11478
11725
|
dw: width - dL - dR,
|
|
11479
11726
|
dh: dB,
|
|
11480
|
-
repeat: repeat.horizontal
|
|
11727
|
+
repeat: repeat.horizontal,
|
|
11728
|
+
horizontal: true
|
|
11481
11729
|
},
|
|
11482
11730
|
{
|
|
11483
11731
|
sx: 0,
|
|
@@ -11488,33 +11736,33 @@ var BorderImageRenderer = class {
|
|
|
11488
11736
|
dy: top + dT,
|
|
11489
11737
|
dw: dL,
|
|
11490
11738
|
dh: height - dT - dB,
|
|
11491
|
-
repeat: repeat.vertical
|
|
11739
|
+
repeat: repeat.vertical,
|
|
11740
|
+
horizontal: false
|
|
11492
11741
|
}
|
|
11493
11742
|
];
|
|
11494
11743
|
for (const edge of edges) {
|
|
11495
11744
|
if (edge.sw <= 0 || edge.sh <= 0 || edge.dw <= 0 || edge.dh <= 0) continue;
|
|
11496
|
-
const isHorizontal = edge.dw >= edge.dh;
|
|
11497
11745
|
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
|
-
}
|
|
11746
|
+
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge, edge.horizontal, edge.repeat === 2);
|
|
11747
|
+
}
|
|
11748
|
+
if (slice.fill) this.drawCenterRegion(image, {
|
|
11749
|
+
sx: sL,
|
|
11750
|
+
sy: sT,
|
|
11751
|
+
sw: imgW - sL - sR,
|
|
11752
|
+
sh: imgH - sT - sB
|
|
11753
|
+
}, {
|
|
11754
|
+
dx: left + dL,
|
|
11755
|
+
dy: top + dT,
|
|
11756
|
+
dw: width - dL - dR,
|
|
11757
|
+
dh: height - dT - dB
|
|
11758
|
+
}, repeat);
|
|
11511
11759
|
}
|
|
11512
11760
|
drawRegion(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
11513
11761
|
if (sw > 0 && sh > 0 && dw > 0 && dh > 0) this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
11514
11762
|
}
|
|
11515
|
-
drawRepeatedEdge(image, edge,
|
|
11516
|
-
const srcLength =
|
|
11517
|
-
const tgLength =
|
|
11763
|
+
drawRepeatedEdge(image, edge, horizontal, round) {
|
|
11764
|
+
const srcLength = horizontal ? edge.sw : edge.sh;
|
|
11765
|
+
const tgLength = horizontal ? edge.dw : edge.dh;
|
|
11518
11766
|
if (srcLength <= 0 || tgLength <= 0) return;
|
|
11519
11767
|
let tileSize;
|
|
11520
11768
|
let tileCount;
|
|
@@ -11531,14 +11779,45 @@ var BorderImageRenderer = class {
|
|
|
11531
11779
|
this.ctx.clip();
|
|
11532
11780
|
for (let i = 0; i < tileCount; i++) {
|
|
11533
11781
|
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);
|
|
11782
|
+
if (horizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, tileSize, edge.dh);
|
|
11783
|
+
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, tileSize);
|
|
11539
11784
|
}
|
|
11540
11785
|
this.ctx.restore();
|
|
11541
11786
|
}
|
|
11787
|
+
/**
|
|
11788
|
+
* Draw the center region of the border image, tiling each axis per its
|
|
11789
|
+
* border-image-repeat keyword (stretch spans the whole axis, repeat
|
|
11790
|
+
* tiles at source size with the overflow cropped, round scales the tile
|
|
11791
|
+
* to divide the axis evenly).
|
|
11792
|
+
*/
|
|
11793
|
+
drawCenterRegion(image, src, dst, repeat) {
|
|
11794
|
+
if (src.sw <= 0 || src.sh <= 0 || dst.dw <= 0 || dst.dh <= 0) return;
|
|
11795
|
+
const axis = (mode, srcLen, dstLen) => {
|
|
11796
|
+
if (mode === 0) return {
|
|
11797
|
+
size: dstLen,
|
|
11798
|
+
count: 1
|
|
11799
|
+
};
|
|
11800
|
+
if (mode === 2) {
|
|
11801
|
+
const count = Math.max(1, Math.round(dstLen / srcLen));
|
|
11802
|
+
return {
|
|
11803
|
+
size: dstLen / count,
|
|
11804
|
+
count
|
|
11805
|
+
};
|
|
11806
|
+
}
|
|
11807
|
+
return {
|
|
11808
|
+
size: srcLen,
|
|
11809
|
+
count: Math.max(1, Math.ceil(dstLen / srcLen))
|
|
11810
|
+
};
|
|
11811
|
+
};
|
|
11812
|
+
const columns = axis(repeat.horizontal, src.sw, dst.dw);
|
|
11813
|
+
const rows = axis(repeat.vertical, src.sh, dst.dh);
|
|
11814
|
+
this.ctx.save();
|
|
11815
|
+
this.ctx.beginPath();
|
|
11816
|
+
this.ctx.rect(dst.dx, dst.dy, dst.dw, dst.dh);
|
|
11817
|
+
this.ctx.clip();
|
|
11818
|
+
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);
|
|
11819
|
+
this.ctx.restore();
|
|
11820
|
+
}
|
|
11542
11821
|
};
|
|
11543
11822
|
//#endregion
|
|
11544
11823
|
//#region src/render/canvas/effects-renderer.ts
|
|
@@ -11592,10 +11871,17 @@ const scaleFilterBlur = (filter, scale) => scale === 1 ? filter : filter.replace
|
|
|
11592
11871
|
* `restore()` **once** when that effect is popped.
|
|
11593
11872
|
*/
|
|
11594
11873
|
var EffectsRenderer = class {
|
|
11874
|
+
ctx;
|
|
11875
|
+
pathCallback;
|
|
11876
|
+
scale;
|
|
11877
|
+
activeEffects = [];
|
|
11878
|
+
/** Whether a canvas state save was performed for the current batch. */
|
|
11879
|
+
didSave = false;
|
|
11880
|
+
/** Index (0-based, from start of activeEffects array) of the last
|
|
11881
|
+
* heavyweight effect in the batch — the one whose pop triggers
|
|
11882
|
+
* restore(). Set to -1 when no save was performed. */
|
|
11883
|
+
saveAtDepth = -1;
|
|
11595
11884
|
constructor(deps, pathCallback) {
|
|
11596
|
-
this.activeEffects = [];
|
|
11597
|
-
this.didSave = false;
|
|
11598
|
-
this.saveAtDepth = -1;
|
|
11599
11885
|
this.ctx = deps.ctx;
|
|
11600
11886
|
this.pathCallback = pathCallback;
|
|
11601
11887
|
this.scale = deps.scale ?? 1;
|
|
@@ -11696,8 +11982,11 @@ var EffectsRenderer = class {
|
|
|
11696
11982
|
* always fills the whole area — a mask surface is about alpha coverage, not
|
|
11697
11983
|
* about what is visible underneath.
|
|
11698
11984
|
*
|
|
11699
|
-
*
|
|
11700
|
-
*
|
|
11985
|
+
* Gradient layers share the rasterisation primitives of the background
|
|
11986
|
+
* renderer (gradient-rasterizer.ts): repeating gradients stack their stop
|
|
11987
|
+
* cycles, and the area beyond a radial gradient's ending shape keeps the
|
|
11988
|
+
* last stop's colour. Limitations (v1): mask-mode is alpha-only; layers
|
|
11989
|
+
* composite with source-over (≈ the spec-default `add`).
|
|
11701
11990
|
*/
|
|
11702
11991
|
/**
|
|
11703
11992
|
* CSS layer lists cycle: a single mask-size applies to every mask-image
|
|
@@ -11763,17 +12052,12 @@ const paintRadialLayer = (ctx, layer, area) => {
|
|
|
11763
12052
|
let [rx, ry] = calculateRadius(layer, cx, cy, width, height);
|
|
11764
12053
|
rx = Math.max(rx, .01);
|
|
11765
12054
|
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);
|
|
12055
|
+
const ownerDocument = ctx.canvas.ownerDocument ?? document;
|
|
12056
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, layer.stops, isRepeatingRadialGradient(layer));
|
|
12057
|
+
if (!rasterized) return;
|
|
12058
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
12059
|
+
ctx.fillRect(area.left, area.top, area.width, area.height);
|
|
12060
|
+
ctx.drawImage(rasterized.canvas, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
11777
12061
|
};
|
|
11778
12062
|
/** Draw one gradient layer filling the whole mask area. */
|
|
11779
12063
|
const paintGradientLayer = (ctx, layer, area) => {
|
|
@@ -11787,12 +12071,31 @@ const paintGradientLayer = (ctx, layer, area) => {
|
|
|
11787
12071
|
if (layer.type === 1 || layer.type === 3) {
|
|
11788
12072
|
const linear = layer;
|
|
11789
12073
|
const [lineLength, lx0, lx1, ly0, ly1] = calculateGradientDirection(linear.angle || 0, width, height);
|
|
11790
|
-
|
|
11791
|
-
|
|
11792
|
-
|
|
12074
|
+
const processed = processColorStops(linear.stops, lineLength || 1);
|
|
12075
|
+
if (layer.type === 3) {
|
|
12076
|
+
const stacked = stackRepeatingStops(processed);
|
|
12077
|
+
if (!stacked) {
|
|
12078
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12079
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12080
|
+
return;
|
|
12081
|
+
}
|
|
12082
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12083
|
+
stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
12084
|
+
} else {
|
|
12085
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12086
|
+
toCanvasStops(processed).forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
12087
|
+
}
|
|
12088
|
+
} else if (layer.type === 5 || layer.type === 6) {
|
|
11793
12089
|
const conic = layer;
|
|
12090
|
+
const processed = processColorStops(conic.stops, 1);
|
|
12091
|
+
const repeating = layer.type === 6;
|
|
12092
|
+
if (repeating && !stackRepeatingStops(processed)) {
|
|
12093
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12094
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12095
|
+
return;
|
|
12096
|
+
}
|
|
11794
12097
|
gradient = ctx.createConicGradient(conic.angle - Math.PI / 2, area.left + width / 2, area.top + height / 2);
|
|
11795
|
-
|
|
12098
|
+
((repeating ? stackRepeatingStops(processed) : null) ?? toCanvasStops(processed)).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
11796
12099
|
}
|
|
11797
12100
|
if (gradient) {
|
|
11798
12101
|
ctx.fillStyle = gradient;
|
|
@@ -11859,7 +12162,11 @@ const calculateObjectFitRendering = (intrinsicWidth, intrinsicHeight, box, objec
|
|
|
11859
12162
|
dh = sh;
|
|
11860
12163
|
}
|
|
11861
12164
|
} else if (objectFit === 16) {
|
|
11862
|
-
|
|
12165
|
+
const containW = imgRatio > boxRatio ? dw : dh * imgRatio;
|
|
12166
|
+
const containH = imgRatio > boxRatio ? dw / imgRatio : dh;
|
|
12167
|
+
const noneW = Math.min(sw, dw);
|
|
12168
|
+
const noneH = Math.min(sh, dh);
|
|
12169
|
+
if (containW * containH < noneW * noneH) {
|
|
11863
12170
|
if (imgRatio > boxRatio) {
|
|
11864
12171
|
dh = dw / imgRatio;
|
|
11865
12172
|
dy += (box.height - dh) * posY;
|
|
@@ -11910,14 +12217,12 @@ async function renderReplacedElements(ctx, context, options, iframeRendererFacto
|
|
|
11910
12217
|
ctx.imageSmoothingEnabled = prevSmoothing;
|
|
11911
12218
|
} catch (e) {
|
|
11912
12219
|
context.logger.error(`Error loading image ${container.src}`);
|
|
11913
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11914
12220
|
}
|
|
11915
12221
|
if (container instanceof CanvasElementContainer) renderReplacedElementFn(container, curves, container.canvas);
|
|
11916
12222
|
if (container instanceof SVGElementContainer) try {
|
|
11917
12223
|
renderReplacedElementFn(container, curves, await context.cache.match(container.svg));
|
|
11918
12224
|
} catch (e) {
|
|
11919
12225
|
context.logger.error(`Error loading svg ${container.svg.substring(0, 255)}`);
|
|
11920
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11921
12226
|
}
|
|
11922
12227
|
if (container instanceof IFrameElementContainer && container.tree) {
|
|
11923
12228
|
const canvas = await iframeRendererFactory(context, {
|
|
@@ -12065,7 +12370,6 @@ async function renderListMarker(ctx, context, textRenderer, paint, container, st
|
|
|
12065
12370
|
ctx.drawImage(image, container.bounds.left - (markerWidth + 10), markerCenterY - markerHeight / 2, markerWidth, markerHeight);
|
|
12066
12371
|
} catch (e) {
|
|
12067
12372
|
context.logger.error(`Error loading list-style-image ${url}`);
|
|
12068
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
12069
12373
|
}
|
|
12070
12374
|
}
|
|
12071
12375
|
} else if (paint.listValue && container.styles.listStyleType !== -1) {
|
|
@@ -12252,7 +12556,10 @@ const paintShadowSurface = async (ctx, paint, shadow, options, budget, space) =>
|
|
|
12252
12556
|
else createCanvasPath(sourceCtx, path);
|
|
12253
12557
|
sourceCtx.fillStyle = asString(shadow.color);
|
|
12254
12558
|
sourceCtx.fill(shadow.inset ? "evenodd" : "nonzero");
|
|
12255
|
-
filtered = await renderFilterSurface(source, {
|
|
12559
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
12560
|
+
kind: "blur",
|
|
12561
|
+
value: blur
|
|
12562
|
+
}] }, 1, space.scale, options.signal);
|
|
12256
12563
|
ctx.save();
|
|
12257
12564
|
try {
|
|
12258
12565
|
if (shadow.inset) {
|
|
@@ -12338,6 +12645,10 @@ const paintBoxShadow = async (ctx, paint, shadow, options, budget) => {
|
|
|
12338
12645
|
//#endregion
|
|
12339
12646
|
//#region src/render/canvas/text-clip-renderer.ts
|
|
12340
12647
|
var TextClipRenderer = class {
|
|
12648
|
+
ctx;
|
|
12649
|
+
context;
|
|
12650
|
+
scale;
|
|
12651
|
+
createFontStyle;
|
|
12341
12652
|
constructor(deps) {
|
|
12342
12653
|
this.ctx = deps.ctx;
|
|
12343
12654
|
this.context = deps.context;
|
|
@@ -12357,59 +12668,69 @@ var TextClipRenderer = class {
|
|
|
12357
12668
|
const deviceHeight = Math.ceil(bounds.height * scale);
|
|
12358
12669
|
const offscreen = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12359
12670
|
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
|
-
|
|
12671
|
+
let mask = null;
|
|
12672
|
+
let composite = null;
|
|
12673
|
+
let shadowCanvases = null;
|
|
12674
|
+
try {
|
|
12675
|
+
offscreen.ctx.scale(scale, scale);
|
|
12676
|
+
const [fontString] = this.createFontStyle(styles);
|
|
12677
|
+
offscreen.ctx.font = fontString ?? "";
|
|
12678
|
+
offscreen.ctx.textBaseline = "alphabetic";
|
|
12679
|
+
offscreen.ctx.textAlign = "left";
|
|
12680
|
+
offscreen.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
12681
|
+
const baseline = measureBaseline(offscreen.ctx, styles.fontSize.number);
|
|
12682
|
+
const bgRenderer = new BackgroundRenderer({
|
|
12683
|
+
ctx: offscreen.ctx,
|
|
12684
|
+
context: this.context,
|
|
12685
|
+
canvas: offscreen.canvas,
|
|
12686
|
+
options: {
|
|
12687
|
+
width,
|
|
12688
|
+
height,
|
|
12689
|
+
scale: 1
|
|
12690
|
+
}
|
|
12691
|
+
});
|
|
12692
|
+
if (!isTransparent(styles.backgroundColor)) {
|
|
12693
|
+
offscreen.ctx.fillStyle = asString(styles.backgroundColor);
|
|
12694
|
+
offscreen.ctx.fillRect(0, 0, width, height);
|
|
12695
|
+
}
|
|
12696
|
+
offscreen.ctx.save();
|
|
12697
|
+
offscreen.ctx.translate(-bounds.left, -bounds.top);
|
|
12698
|
+
await bgRenderer.renderBackgroundImage(container);
|
|
12699
|
+
offscreen.ctx.restore();
|
|
12700
|
+
const drawOptions = {
|
|
12701
|
+
bounds,
|
|
12702
|
+
baseline,
|
|
12703
|
+
letterSpacing: styles.letterSpacing,
|
|
12704
|
+
writingMode: styles.writingMode
|
|
12705
|
+
};
|
|
12706
|
+
mask = this.createGlyphLayer(ownerDocument, deviceWidth, deviceHeight, offscreen.ctx);
|
|
12707
|
+
if (!mask) return;
|
|
12708
|
+
const hasStroke = !!styles.webkitTextStrokeWidth;
|
|
12709
|
+
if (hasStroke) {
|
|
12710
|
+
mask.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);
|
|
12711
|
+
mask.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
12712
|
+
mask.ctx.lineJoin = getTextStrokeLineJoin();
|
|
12713
|
+
}
|
|
12714
|
+
for (const textNode of container.textNodes) for (const textBound of textNode.textBounds) this.drawGlyphs(mask, textBound, drawOptions, (ctx, text, x, y) => {
|
|
12715
|
+
ctx.fillText(text, x, y);
|
|
12716
|
+
if (hasStroke) ctx.strokeText(text, x, y);
|
|
12717
|
+
});
|
|
12718
|
+
offscreen.ctx.globalCompositeOperation = "destination-in";
|
|
12719
|
+
offscreen.ctx.drawImage(mask.canvas, 0, 0, width, height);
|
|
12720
|
+
shadowCanvases = this.renderShadowSilhouettes(paint, ownerDocument, deviceWidth, deviceHeight, offscreen.ctx, styles, drawOptions);
|
|
12721
|
+
if (shadowCanvases) {
|
|
12722
|
+
composite = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12723
|
+
if (!composite) return;
|
|
12724
|
+
for (const shadowCanvas of shadowCanvases) composite.ctx.drawImage(shadowCanvas, 0, 0);
|
|
12725
|
+
composite.ctx.drawImage(offscreen.canvas, 0, 0);
|
|
12726
|
+
this.ctx.drawImage(composite.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12727
|
+
} else this.ctx.drawImage(offscreen.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12728
|
+
} finally {
|
|
12729
|
+
releaseSurface(offscreen.canvas);
|
|
12730
|
+
if (mask) releaseSurface(mask.canvas);
|
|
12731
|
+
if (composite) releaseSurface(composite.canvas);
|
|
12732
|
+
if (shadowCanvases) shadowCanvases.forEach(releaseSurface);
|
|
12733
|
+
}
|
|
12413
12734
|
}
|
|
12414
12735
|
createLayer(ownerDocument, width, height) {
|
|
12415
12736
|
const canvas = ownerDocument.createElement("canvas");
|
|
@@ -12481,20 +12802,29 @@ var TextClipRenderer = class {
|
|
|
12481
12802
|
}
|
|
12482
12803
|
return canvases.length ? canvases : null;
|
|
12483
12804
|
}
|
|
12484
|
-
getTextStrokeLineJoin() {
|
|
12485
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
12486
|
-
}
|
|
12487
12805
|
};
|
|
12488
12806
|
//#endregion
|
|
12489
12807
|
//#region src/render/canvas/canvas-renderer.ts
|
|
12490
12808
|
var CanvasRenderer = class CanvasRenderer {
|
|
12809
|
+
surfaceRoot;
|
|
12810
|
+
surfaceBudget;
|
|
12811
|
+
canvas;
|
|
12812
|
+
ctx;
|
|
12813
|
+
context;
|
|
12814
|
+
options;
|
|
12815
|
+
backgroundRenderer;
|
|
12816
|
+
borderRenderer;
|
|
12817
|
+
borderImageRenderer;
|
|
12818
|
+
effectsRenderer;
|
|
12819
|
+
textRenderer;
|
|
12820
|
+
textClipRenderer;
|
|
12821
|
+
legacySubtree = false;
|
|
12491
12822
|
constructor(context, options, surfaceRoot, surfaceBudget = { pixels: 0 }) {
|
|
12492
12823
|
this.surfaceRoot = surfaceRoot;
|
|
12493
12824
|
this.surfaceBudget = surfaceBudget;
|
|
12494
|
-
this.legacySubtree = false;
|
|
12495
12825
|
this.context = context;
|
|
12496
12826
|
this.options = options;
|
|
12497
|
-
this.canvas = options.canvas ? options.canvas :
|
|
12827
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
12498
12828
|
const ctx = this.canvas.getContext("2d");
|
|
12499
12829
|
if (!ctx) {
|
|
12500
12830
|
if (!options.canvas) releaseSurface(this.canvas);
|
|
@@ -12547,11 +12877,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12547
12877
|
async renderStack(stack) {
|
|
12548
12878
|
const styles = stack.element.container.styles;
|
|
12549
12879
|
if (styles.isVisible()) {
|
|
12550
|
-
const filter =
|
|
12880
|
+
const filter = parseFilterChain(styles.filter);
|
|
12881
|
+
const hasFilter = filter !== null && filter.functions.length > 0;
|
|
12551
12882
|
const hasMask = styles.maskImage.length > 0;
|
|
12552
12883
|
const reflect = styles.webkitBoxReflect;
|
|
12553
12884
|
const hasBlend = styles.mixBlendMode !== MIX_BLEND_MODE$1.NORMAL;
|
|
12554
|
-
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter && (
|
|
12885
|
+
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter !== null && (hasFilter || styles.opacity < 1)) && this.canComposite(stack.element)) {
|
|
12555
12886
|
if (!await this.renderCompositedStack(stack, filter, hasMask, reflect, hasBlend)) {
|
|
12556
12887
|
this.legacySubtree = true;
|
|
12557
12888
|
try {
|
|
@@ -12568,7 +12899,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12568
12899
|
canComposite(paint) {
|
|
12569
12900
|
const supported = (container) => {
|
|
12570
12901
|
const styles = container.styles;
|
|
12571
|
-
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) &&
|
|
12902
|
+
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) && parseFilterChain(styles.filter) !== null;
|
|
12572
12903
|
};
|
|
12573
12904
|
const subtree = (container) => supported(container) && container.elements.every(subtree);
|
|
12574
12905
|
let ancestor = paint.parent;
|
|
@@ -12636,7 +12967,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12636
12967
|
async applyMask(surface, styles, bounds) {
|
|
12637
12968
|
const ctx = surface.getContext("2d");
|
|
12638
12969
|
if (!ctx) return;
|
|
12639
|
-
const maskCanvas =
|
|
12970
|
+
const maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12640
12971
|
maskCanvas.width = surface.width;
|
|
12641
12972
|
maskCanvas.height = surface.height;
|
|
12642
12973
|
const maskCtx = maskCanvas.getContext("2d");
|
|
@@ -12678,7 +13009,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12678
13009
|
let refCanvas;
|
|
12679
13010
|
let maskCanvas;
|
|
12680
13011
|
try {
|
|
12681
|
-
refCanvas =
|
|
13012
|
+
refCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12682
13013
|
refCanvas.width = w;
|
|
12683
13014
|
refCanvas.height = h;
|
|
12684
13015
|
const ctx = refCanvas.getContext("2d");
|
|
@@ -12700,7 +13031,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12700
13031
|
ctx.restore();
|
|
12701
13032
|
}
|
|
12702
13033
|
if (reflect.mask) {
|
|
12703
|
-
maskCanvas =
|
|
13034
|
+
maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12704
13035
|
maskCanvas.width = w;
|
|
12705
13036
|
maskCanvas.height = h;
|
|
12706
13037
|
const mctx = maskCanvas.getContext("2d");
|
|
@@ -12824,18 +13155,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12824
13155
|
await this.renderStack(child);
|
|
12825
13156
|
}
|
|
12826
13157
|
}
|
|
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
13158
|
path(paths) {
|
|
12840
13159
|
createCanvasPath(this.ctx, paths);
|
|
12841
13160
|
}
|
|
@@ -12857,7 +13176,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12857
13176
|
let source;
|
|
12858
13177
|
let filtered;
|
|
12859
13178
|
try {
|
|
12860
|
-
source =
|
|
13179
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
12861
13180
|
source.width = width;
|
|
12862
13181
|
source.height = height;
|
|
12863
13182
|
const ctx = source.getContext("2d");
|
|
@@ -12867,7 +13186,10 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12867
13186
|
createCanvasPath(ctx, transformPath(calculateBorderBoxPath(paint.curves), -spread, -spread, 2 * spread, 2 * spread));
|
|
12868
13187
|
ctx.fillStyle = asString(shadow.color);
|
|
12869
13188
|
ctx.fill();
|
|
12870
|
-
filtered = await renderFilterSurface(source, {
|
|
13189
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
13190
|
+
kind: "blur",
|
|
13191
|
+
value: blur
|
|
13192
|
+
}] }, 1, scale, this.options.signal);
|
|
12871
13193
|
this.ctx.save();
|
|
12872
13194
|
try {
|
|
12873
13195
|
this.ctx.beginPath();
|
|
@@ -13043,9 +13365,19 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13043
13365
|
if (source.type === 1 || source.type === 3) {
|
|
13044
13366
|
const gradientImage = source;
|
|
13045
13367
|
const [lineLength, x0, y0, x1, y1] = calculateGradientDirection(gradientImage.angle, width, height);
|
|
13368
|
+
const processed = processColorStops(gradientImage.stops, lineLength || width);
|
|
13369
|
+
const repeating = source.type === 3;
|
|
13370
|
+
const stacked = repeating ? stackRepeatingStops(processed) : null;
|
|
13046
13371
|
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
13047
|
-
|
|
13048
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)),
|
|
13372
|
+
if (stacked) stacked.forEach((colorStop) => {
|
|
13373
|
+
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), colorStop.color);
|
|
13374
|
+
});
|
|
13375
|
+
else if (repeating) {
|
|
13376
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
13377
|
+
gradient.addColorStop(0, lastColor);
|
|
13378
|
+
gradient.addColorStop(1, lastColor);
|
|
13379
|
+
} else toCanvasStops(processed).forEach((colorStop) => {
|
|
13380
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
13049
13381
|
});
|
|
13050
13382
|
ctx.fillStyle = gradient;
|
|
13051
13383
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -13053,21 +13385,17 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13053
13385
|
}
|
|
13054
13386
|
if (source.type === 2 || source.type === 4) {
|
|
13055
13387
|
const gradientImage = source;
|
|
13056
|
-
const
|
|
13057
|
-
const
|
|
13388
|
+
const position = gradientImage.position.length === 0 ? [FIFTY_PERCENT] : gradientImage.position;
|
|
13389
|
+
const cx = getAbsoluteValue(at(position, 0), width);
|
|
13390
|
+
const cy = getAbsoluteValue(at(position, position.length - 1), height);
|
|
13058
13391
|
const [rx, ry] = calculateRadius(gradientImage, cx, cy, width, height);
|
|
13059
13392
|
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;
|
|
13393
|
+
const ownerDocument = this.ctx.canvas.ownerDocument ?? document;
|
|
13394
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, gradientImage.stops, source.type === 4);
|
|
13395
|
+
if (!rasterized) return null;
|
|
13396
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
13069
13397
|
ctx.fillRect(0, 0, width, height);
|
|
13070
|
-
ctx.
|
|
13398
|
+
ctx.drawImage(rasterized.canvas, cx - rx, cy - ry, rx * 2, ry * 2);
|
|
13071
13399
|
return canvas;
|
|
13072
13400
|
}
|
|
13073
13401
|
if (source.type === 5 || source.type === 6) {
|
|
@@ -13112,12 +13440,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13112
13440
|
}
|
|
13113
13441
|
/**
|
|
13114
13442
|
* Filter the already-painted content beneath the element's border box and
|
|
13115
|
-
* paint the result back, approximating CSS backdrop-filter for the
|
|
13116
|
-
*
|
|
13443
|
+
* paint the result back, approximating CSS backdrop-filter for the chain
|
|
13444
|
+
* subset the filter surface backends support.
|
|
13117
13445
|
*/
|
|
13118
13446
|
async renderBackdropFilter(paint) {
|
|
13119
|
-
const filter =
|
|
13120
|
-
if (!filter ||
|
|
13447
|
+
const filter = parseFilterChain(paint.container.styles.backdropFilter);
|
|
13448
|
+
if (!filter || filter.functions.length === 0) return;
|
|
13121
13449
|
const bounds = paint.container.bounds;
|
|
13122
13450
|
if (bounds.width <= 0 || bounds.height <= 0) return;
|
|
13123
13451
|
const scale = this.options.scale;
|
|
@@ -13129,7 +13457,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13129
13457
|
let source;
|
|
13130
13458
|
let filtered;
|
|
13131
13459
|
try {
|
|
13132
|
-
source =
|
|
13460
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
13133
13461
|
source.width = width;
|
|
13134
13462
|
source.height = height;
|
|
13135
13463
|
const srcCtx = source.getContext("2d");
|
|
@@ -13137,7 +13465,15 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13137
13465
|
const sx = Math.round((bounds.left - this.options.x) * scale);
|
|
13138
13466
|
const sy = Math.round((bounds.top - this.options.y) * scale);
|
|
13139
13467
|
srcCtx.drawImage(this.canvas, sx, sy, width, height, 0, 0, width, height);
|
|
13140
|
-
|
|
13468
|
+
try {
|
|
13469
|
+
filtered = await renderFilterSurface(source, filter, 1, scale, this.options.signal);
|
|
13470
|
+
} catch (error) {
|
|
13471
|
+
if (error instanceof FilterSurfaceError) {
|
|
13472
|
+
this.context.logger.info(`${error.message}; rendering without the backdrop effect`);
|
|
13473
|
+
return;
|
|
13474
|
+
}
|
|
13475
|
+
throw error;
|
|
13476
|
+
}
|
|
13141
13477
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13142
13478
|
this.ctx.save();
|
|
13143
13479
|
try {
|
|
@@ -13184,10 +13520,14 @@ const hasTextBackgroundClip = (styles) => {
|
|
|
13184
13520
|
//#endregion
|
|
13185
13521
|
//#region src/render/canvas/foreignobject-renderer.ts
|
|
13186
13522
|
var ForeignObjectRenderer = class {
|
|
13523
|
+
canvas;
|
|
13524
|
+
ctx;
|
|
13525
|
+
options;
|
|
13526
|
+
context;
|
|
13187
13527
|
constructor(context, options) {
|
|
13188
13528
|
this.context = context;
|
|
13189
13529
|
this.options = options;
|
|
13190
|
-
this.canvas = options.canvas ? options.canvas :
|
|
13530
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
13191
13531
|
const ctx = this.canvas.getContext("2d");
|
|
13192
13532
|
if (!ctx) throw new Error("Failed to get 2D rendering context from canvas");
|
|
13193
13533
|
this.ctx = ctx;
|
|
@@ -13201,19 +13541,49 @@ var ForeignObjectRenderer = class {
|
|
|
13201
13541
|
}
|
|
13202
13542
|
async render(element) {
|
|
13203
13543
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13204
|
-
const
|
|
13205
|
-
const
|
|
13544
|
+
const restoreRootOffsets = stripRootOffsets(element);
|
|
13545
|
+
const svg = createForeignObjectSVG(this.options.width, this.options.height, 0, 0, element);
|
|
13546
|
+
const imagePromise = loadSerializedSVG(svg);
|
|
13547
|
+
restoreRootOffsets();
|
|
13548
|
+
const img = await imagePromise;
|
|
13549
|
+
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13206
13550
|
if (this.options.backgroundColor) {
|
|
13207
13551
|
this.ctx.fillStyle = asString(this.options.backgroundColor);
|
|
13208
|
-
this.ctx.fillRect(
|
|
13552
|
+
this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13209
13553
|
}
|
|
13210
|
-
this.ctx.drawImage(img,
|
|
13554
|
+
this.ctx.drawImage(img, this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13211
13555
|
return this.canvas;
|
|
13212
13556
|
}
|
|
13213
13557
|
};
|
|
13558
|
+
/**
|
|
13559
|
+
* Temporarily neutralize the root element's layout offsets for SVG
|
|
13560
|
+
* serialization. `top/right/bottom/left` reset to `auto` (inset values of
|
|
13561
|
+
* positioned elements are baked into the capture rect); margins to `0`.
|
|
13562
|
+
*/
|
|
13563
|
+
const ROOT_OFFSET_PROPERTIES = [
|
|
13564
|
+
"marginTop",
|
|
13565
|
+
"marginRight",
|
|
13566
|
+
"marginBottom",
|
|
13567
|
+
"marginLeft",
|
|
13568
|
+
"top",
|
|
13569
|
+
"right",
|
|
13570
|
+
"bottom",
|
|
13571
|
+
"left"
|
|
13572
|
+
];
|
|
13573
|
+
const stripRootOffsets = (element) => {
|
|
13574
|
+
const style = element.style;
|
|
13575
|
+
const previous = ROOT_OFFSET_PROPERTIES.map((property) => [property, style[property]]);
|
|
13576
|
+
for (const property of ROOT_OFFSET_PROPERTIES) style[property] = property.startsWith("margin") ? "0px" : "auto";
|
|
13577
|
+
return () => {
|
|
13578
|
+
for (const [property, value] of previous) style[property] = value;
|
|
13579
|
+
};
|
|
13580
|
+
};
|
|
13214
13581
|
//#endregion
|
|
13215
13582
|
//#region src/core/logger.ts
|
|
13216
13583
|
var Logger = class {
|
|
13584
|
+
id;
|
|
13585
|
+
enabled;
|
|
13586
|
+
start;
|
|
13217
13587
|
constructor({ id, enabled }) {
|
|
13218
13588
|
this.id = id;
|
|
13219
13589
|
this.enabled = enabled;
|
|
@@ -13249,17 +13619,33 @@ var Logger = class {
|
|
|
13249
13619
|
//#endregion
|
|
13250
13620
|
//#region src/core/cache-storage.ts
|
|
13251
13621
|
var Cache = class {
|
|
13622
|
+
context;
|
|
13623
|
+
_options;
|
|
13624
|
+
_cache = /* @__PURE__ */ new Map();
|
|
13625
|
+
maxSize;
|
|
13626
|
+
_pendingOperations = /* @__PURE__ */ new Map();
|
|
13627
|
+
/** When true, addImage() collects URLs without starting loads. */
|
|
13628
|
+
_deferMode = false;
|
|
13629
|
+
/** URLs collected during defer mode, pending batch preload. */
|
|
13630
|
+
_collectedUrls = /* @__PURE__ */ new Set();
|
|
13631
|
+
/**
|
|
13632
|
+
* Eviction is suspended between startDefer() and the end of preloadAll():
|
|
13633
|
+
* the render pipeline loads every image it is going to paint inside that
|
|
13634
|
+
* window, and match() never reloads, so an LRU eviction there would
|
|
13635
|
+
* silently drop images from the output on pages with more unique images
|
|
13636
|
+
* than maxSize.
|
|
13637
|
+
*
|
|
13638
|
+
* A counter (not a flag) keeps nested/overlapping defer windows — e.g.
|
|
13639
|
+
* two renders sharing one cache via `config.cache` — suspended until the
|
|
13640
|
+
* last one finishes preloading.
|
|
13641
|
+
*/
|
|
13642
|
+
_evictionSuspendCount = 0;
|
|
13252
13643
|
get _evictionEnabled() {
|
|
13253
13644
|
return this._evictionSuspendCount === 0;
|
|
13254
13645
|
}
|
|
13255
13646
|
constructor(context, _options) {
|
|
13256
13647
|
this.context = context;
|
|
13257
13648
|
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
13649
|
this.maxSize = _options.maxCacheSize ?? 100;
|
|
13264
13650
|
if (this.maxSize < 1) throw new Error("Cache maxSize must be at least 1");
|
|
13265
13651
|
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 +13663,18 @@ var Cache = class {
|
|
|
13277
13663
|
* an optional concurrency cap to avoid overwhelming the browser's network
|
|
13278
13664
|
* stack (default: 10 concurrent loads).
|
|
13279
13665
|
* After this call returns, all images are either loaded (cache hit) or
|
|
13280
|
-
* failed (logged). Subsequent cache.match()
|
|
13666
|
+
* failed (logged and reported via onError). Subsequent cache.match()
|
|
13667
|
+
* calls return immediately.
|
|
13281
13668
|
*
|
|
13282
13669
|
* @param concurrency - Max concurrent image loads (1–100, default 10).
|
|
13283
13670
|
* @param onProgress - Invoked once before loading and after each settled
|
|
13284
13671
|
* batch with (settledCount, totalCount), enabling coarse progress UI.
|
|
13285
13672
|
* Not invoked when there is nothing to load.
|
|
13673
|
+
* @param signal - Checked before each batch; aborting rejects the whole
|
|
13674
|
+
* preload with an AbortError instead of waiting for the remaining
|
|
13675
|
+
* batches to finish.
|
|
13286
13676
|
*/
|
|
13287
|
-
async preloadAll(concurrency = 10, onProgress) {
|
|
13677
|
+
async preloadAll(concurrency = 10, onProgress, signal) {
|
|
13288
13678
|
this._deferMode = false;
|
|
13289
13679
|
const urls = Array.from(this._collectedUrls);
|
|
13290
13680
|
this._collectedUrls.clear();
|
|
@@ -13293,11 +13683,19 @@ var Cache = class {
|
|
|
13293
13683
|
const limit = Math.max(1, Math.min(concurrency, 100));
|
|
13294
13684
|
this.context.logger.debug(`Preloading ${urls.length} image(s) with concurrency ${limit}`);
|
|
13295
13685
|
let settled = 0;
|
|
13686
|
+
const abortPromise = signal ? new Promise((_, reject) => {
|
|
13687
|
+
const onAbort = () => reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
13688
|
+
if (signal.aborted) onAbort();
|
|
13689
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
13690
|
+
}) : null;
|
|
13691
|
+
abortPromise?.catch(() => void 0);
|
|
13296
13692
|
onProgress?.(0, urls.length);
|
|
13297
13693
|
for (let i = 0; i < urls.length; i += limit) {
|
|
13694
|
+
throwIfAborted(signal);
|
|
13298
13695
|
const batch = urls.slice(i, i + limit);
|
|
13299
|
-
|
|
13300
|
-
|
|
13696
|
+
batch.map((url) => this._addImageWithPending(url));
|
|
13697
|
+
const batchSettled = Promise.allSettled(batch.map((url) => this._cache.get(url)?.value ?? Promise.resolve()));
|
|
13698
|
+
await (abortPromise ? Promise.race([batchSettled, abortPromise]) : batchSettled);
|
|
13301
13699
|
settled += batch.length;
|
|
13302
13700
|
onProgress?.(settled, urls.length);
|
|
13303
13701
|
}
|
|
@@ -13340,7 +13738,10 @@ var Cache = class {
|
|
|
13340
13738
|
const timeoutMs = this._options.imageTimeout ?? 15e3;
|
|
13341
13739
|
const imageWithTimeout = this.withTimeout(this.loadImage(src), timeoutMs, `Timed out (${timeoutMs}ms) loading image`);
|
|
13342
13740
|
imageWithTimeout.catch((error) => {
|
|
13343
|
-
|
|
13741
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
13742
|
+
const message = `Failed to load image ${src.substring(0, 256)}: ${reason}`;
|
|
13743
|
+
this.context.logger.error(message);
|
|
13744
|
+
this.context.onError?.(new Error(message));
|
|
13344
13745
|
});
|
|
13345
13746
|
this.set(src, imageWithTimeout);
|
|
13346
13747
|
}
|
|
@@ -13402,18 +13803,22 @@ var Cache = class {
|
|
|
13402
13803
|
const isSameOrigin = typeof this._options.customIsSameOrigin === "function" ? await this._options.customIsSameOrigin(key, defaultIsSameOrigin) : defaultIsSameOrigin(key);
|
|
13403
13804
|
const canAttemptCors = !isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && typeof this._options.proxy !== "string";
|
|
13404
13805
|
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" &&
|
|
13806
|
+
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" && !useCORS;
|
|
13406
13807
|
if (!isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && !useProxy && !useCORS) return;
|
|
13407
13808
|
let src = key;
|
|
13408
13809
|
if (useProxy) src = await this.proxy(src);
|
|
13409
13810
|
this.context.logger.debug(`Added image ${key.substring(0, 256)}`);
|
|
13811
|
+
const imageConstructor = this.context.config.window.Image ?? Image;
|
|
13410
13812
|
return await new Promise((resolve, reject) => {
|
|
13411
|
-
const img = new
|
|
13813
|
+
const img = new imageConstructor();
|
|
13412
13814
|
img.onload = () => resolve(img);
|
|
13413
13815
|
img.onerror = reject;
|
|
13414
13816
|
if (isInlineBase64Image(src) || useCORS) img.crossOrigin = "anonymous";
|
|
13415
13817
|
img.src = src;
|
|
13416
|
-
if (img.complete === true)
|
|
13818
|
+
if (img.complete === true) {
|
|
13819
|
+
if (typeof img.decode === "function") img.decode().then(() => resolve(img), () => reject(/* @__PURE__ */ new Error(`Failed to decode image ${src.substring(0, 256)}`)));
|
|
13820
|
+
else setTimeout(() => resolve(img), 500);
|
|
13821
|
+
}
|
|
13417
13822
|
});
|
|
13418
13823
|
}
|
|
13419
13824
|
has(key) {
|
|
@@ -13427,23 +13832,19 @@ var Cache = class {
|
|
|
13427
13832
|
if (!proxy) throw new Error("No proxy defined");
|
|
13428
13833
|
const key = src.substring(0, 256);
|
|
13429
13834
|
return new Promise((resolve, reject) => {
|
|
13430
|
-
const responseType = FEATURES.SUPPORT_RESPONSE_TYPE ? "blob" : "text";
|
|
13431
13835
|
const xhr = new XMLHttpRequest();
|
|
13432
13836
|
xhr.onload = () => {
|
|
13433
13837
|
if (xhr.status === 200) {
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
reader.addEventListener("error", (e) => reject(e), false);
|
|
13439
|
-
reader.readAsDataURL(xhr.response);
|
|
13440
|
-
}
|
|
13838
|
+
const reader = new FileReader();
|
|
13839
|
+
reader.addEventListener("load", () => resolve(reader.result), false);
|
|
13840
|
+
reader.addEventListener("error", (e) => reject(e), false);
|
|
13841
|
+
reader.readAsDataURL(xhr.response);
|
|
13441
13842
|
} else reject(`Failed to proxy resource ${key} with status code ${xhr.status}`);
|
|
13442
13843
|
};
|
|
13443
13844
|
xhr.onerror = reject;
|
|
13444
13845
|
const queryString = proxy.indexOf("?") > -1 ? "&" : "?";
|
|
13445
|
-
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType
|
|
13446
|
-
|
|
13846
|
+
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType=blob`);
|
|
13847
|
+
xhr.responseType = "blob";
|
|
13447
13848
|
if (this._options.imageTimeout) {
|
|
13448
13849
|
const timeout = this._options.imageTimeout;
|
|
13449
13850
|
xhr.timeout = timeout;
|
|
@@ -13467,27 +13868,34 @@ const isSVG = (src) => src.slice(-3).toLowerCase() === "svg" || INLINE_SVG.test(
|
|
|
13467
13868
|
* Origin Checker
|
|
13468
13869
|
*
|
|
13469
13870
|
* Provides origin checking functionality without global static state.
|
|
13470
|
-
* Each instance maintains its own
|
|
13871
|
+
* Each instance maintains its own base URI and origin reference.
|
|
13471
13872
|
*
|
|
13472
13873
|
* Replaces the static methods in CacheStorage with instance-based approach.
|
|
13473
13874
|
*/
|
|
13474
13875
|
var OriginChecker = class {
|
|
13876
|
+
baseUri;
|
|
13877
|
+
origin;
|
|
13475
13878
|
constructor(window) {
|
|
13476
13879
|
if (!window || !window.document) throw new Error("Valid window object required for OriginChecker");
|
|
13477
13880
|
if (!window.location || !window.location.href) throw new Error("Window object must have valid location");
|
|
13478
|
-
this.
|
|
13881
|
+
this.baseUri = window.location.href;
|
|
13479
13882
|
this.origin = this.getOrigin(window.location.href);
|
|
13480
13883
|
}
|
|
13481
13884
|
/**
|
|
13482
13885
|
* Get the origin (protocol + hostname + port) of a URL
|
|
13483
13886
|
*
|
|
13484
|
-
* @param url - URL to parse
|
|
13485
|
-
*
|
|
13887
|
+
* @param url - URL to parse; relative URLs resolve against the context
|
|
13888
|
+
* window's location, as the anchor element used to
|
|
13889
|
+
* @returns Origin string (e.g. "https://example.com:8080"), or an empty
|
|
13890
|
+
* string for unparseable URLs — which never matches and is
|
|
13891
|
+
* therefore treated as cross-origin
|
|
13486
13892
|
*/
|
|
13487
13893
|
getOrigin(url) {
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13894
|
+
try {
|
|
13895
|
+
return new URL(url, this.baseUri).origin;
|
|
13896
|
+
} catch (e) {
|
|
13897
|
+
return "";
|
|
13898
|
+
}
|
|
13491
13899
|
}
|
|
13492
13900
|
/**
|
|
13493
13901
|
* Check if a URL is from the same origin as the context
|
|
@@ -13510,11 +13918,15 @@ var OriginChecker = class {
|
|
|
13510
13918
|
//#endregion
|
|
13511
13919
|
//#region src/core/context.ts
|
|
13512
13920
|
var Context = class Context {
|
|
13513
|
-
static
|
|
13514
|
-
|
|
13515
|
-
|
|
13921
|
+
static instanceCount = 1;
|
|
13922
|
+
instanceName = `#${Context.instanceCount++}`;
|
|
13923
|
+
logger;
|
|
13924
|
+
cache;
|
|
13925
|
+
originChecker;
|
|
13926
|
+
config;
|
|
13927
|
+
onError;
|
|
13928
|
+
_windowBounds;
|
|
13516
13929
|
constructor(options, windowBounds, config) {
|
|
13517
|
-
this.instanceName = `#${Context.instanceCount++}`;
|
|
13518
13930
|
this.config = config;
|
|
13519
13931
|
this.logger = new Logger({
|
|
13520
13932
|
id: this.instanceName,
|
|
@@ -13530,6 +13942,18 @@ var Context = class Context {
|
|
|
13530
13942
|
return this._windowBounds;
|
|
13531
13943
|
}
|
|
13532
13944
|
/**
|
|
13945
|
+
* Document used to allocate offscreen resources (offscreen canvases,
|
|
13946
|
+
* images, measurement elements). Prefers the configured window's document
|
|
13947
|
+
* so resources live in the captured realm; falls back to the global
|
|
13948
|
+
* document, which keeps mock environments without a window document
|
|
13949
|
+
* working.
|
|
13950
|
+
*/
|
|
13951
|
+
get resourceDocument() {
|
|
13952
|
+
const windowDocument = this.config.window.document;
|
|
13953
|
+
if (windowDocument) return windowDocument;
|
|
13954
|
+
return typeof document !== "undefined" ? document : void 0;
|
|
13955
|
+
}
|
|
13956
|
+
/**
|
|
13533
13957
|
* Compensate window bounds for a page scroll that the browser performed
|
|
13534
13958
|
* underneath us. Used by the document cloner: WebKit's scroll anchoring can
|
|
13535
13959
|
* scroll the cloned iframe after `onclone`, and the offset must be applied
|
|
@@ -13601,7 +14025,8 @@ const assembleCloneOptions = (opts, config, foreignObjectRendering) => ({
|
|
|
13601
14025
|
iframeContainer: opts.iframeContainer,
|
|
13602
14026
|
inlineImages: foreignObjectRendering,
|
|
13603
14027
|
copyStyles: foreignObjectRendering,
|
|
13604
|
-
cspNonce: opts.cspNonce ?? config.cspNonce
|
|
14028
|
+
cspNonce: opts.cspNonce ?? config.cspNonce,
|
|
14029
|
+
signal: opts.signal
|
|
13605
14030
|
});
|
|
13606
14031
|
/** Assemble canvas rendering options. */
|
|
13607
14032
|
const assembleRenderOptions = (opts, backgroundColor, left, top, width, height, devicePixelRatio) => ({
|
|
@@ -13707,13 +14132,13 @@ const renderElement = async (element, opts, config) => {
|
|
|
13707
14132
|
perfMonitor.start("parse");
|
|
13708
14133
|
throwIfAborted(signal);
|
|
13709
14134
|
context.cache.startDefer();
|
|
13710
|
-
root = parseTree(context, clonedElement);
|
|
14135
|
+
root = parseTree(context, clonedElement, { normalizeDom: opts.normalizeDom });
|
|
13711
14136
|
perfMonitor.end("parse");
|
|
13712
14137
|
emitProgress(opts.onProgress, context, "parse", 50);
|
|
13713
14138
|
perfMonitor.start("preload");
|
|
13714
14139
|
await context.cache.preloadAll(10, (loaded, total) => {
|
|
13715
14140
|
emitProgress(opts.onProgress, context, "preload", 50 + Math.round(loaded / total * 10));
|
|
13716
|
-
});
|
|
14141
|
+
}, signal);
|
|
13717
14142
|
perfMonitor.end("preload");
|
|
13718
14143
|
emitProgress(opts.onProgress, context, "layout", 60);
|
|
13719
14144
|
if (backgroundColor === root.styles.backgroundColor) root.styles.backgroundColor = 0;
|