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
|
@@ -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
|
*/
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
* Eliminates the need for global static variables.
|
|
12
12
|
*/
|
|
13
13
|
var Html2CanvasConfig = class Html2CanvasConfig {
|
|
14
|
+
window;
|
|
15
|
+
cspNonce;
|
|
16
|
+
cache;
|
|
14
17
|
constructor(options = {}) {
|
|
15
18
|
const resolvedWindow = options.window || (typeof window !== "undefined" ? window : void 0);
|
|
16
19
|
if (!resolvedWindow) throw new Error("Window object is required but not available");
|
|
@@ -51,6 +54,7 @@ var Html2CanvasConfig = class Html2CanvasConfig {
|
|
|
51
54
|
* Validates and sanitizes user inputs for security and correctness.
|
|
52
55
|
*/
|
|
53
56
|
var Validator = class {
|
|
57
|
+
config;
|
|
54
58
|
constructor(config = {}) {
|
|
55
59
|
this.config = {
|
|
56
60
|
maxImageTimeout: 3e5,
|
|
@@ -118,8 +122,7 @@ var Validator = class {
|
|
|
118
122
|
}
|
|
119
123
|
return {
|
|
120
124
|
valid: true,
|
|
121
|
-
sanitized: url
|
|
122
|
-
requiresRuntimeCheck: true
|
|
125
|
+
sanitized: url
|
|
123
126
|
};
|
|
124
127
|
}
|
|
125
128
|
return {
|
|
@@ -424,10 +427,13 @@ function createDefaultValidator(config = {}) {
|
|
|
424
427
|
* ```
|
|
425
428
|
*/
|
|
426
429
|
var PerformanceMonitor = class {
|
|
430
|
+
context;
|
|
431
|
+
activeMetrics = /* @__PURE__ */ new Map();
|
|
432
|
+
completedMetrics = [];
|
|
433
|
+
enabled;
|
|
434
|
+
getTime;
|
|
427
435
|
constructor(context, enabled = true) {
|
|
428
436
|
this.context = context;
|
|
429
|
-
this.activeMetrics = /* @__PURE__ */ new Map();
|
|
430
|
-
this.completedMetrics = [];
|
|
431
437
|
this.enabled = enabled;
|
|
432
438
|
this.getTime = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
|
|
433
439
|
}
|
|
@@ -574,6 +580,10 @@ var PerformanceMonitor = class {
|
|
|
574
580
|
//#endregion
|
|
575
581
|
//#region src/css/layout/bounds.ts
|
|
576
582
|
var Bounds = class Bounds {
|
|
583
|
+
left;
|
|
584
|
+
top;
|
|
585
|
+
width;
|
|
586
|
+
height;
|
|
577
587
|
constructor(left, top, width, height) {
|
|
578
588
|
this.left = left;
|
|
579
589
|
this.top = top;
|
|
@@ -593,9 +603,7 @@ var Bounds = class Bounds {
|
|
|
593
603
|
if (!domRect && rects.length > 0) domRect = rects[0];
|
|
594
604
|
return domRect ? new Bounds(domRect.left + context.windowBounds.left, domRect.top + context.windowBounds.top, domRect.width, domRect.height) : Bounds.EMPTY;
|
|
595
605
|
}
|
|
596
|
-
static
|
|
597
|
-
this.EMPTY = new Bounds(0, 0, 0, 0);
|
|
598
|
-
}
|
|
606
|
+
static EMPTY = new Bounds(0, 0, 0, 0);
|
|
599
607
|
};
|
|
600
608
|
const parseBounds = (context, node) => {
|
|
601
609
|
return Bounds.fromClientRect(context, node.getBoundingClientRect());
|
|
@@ -607,522 +615,6 @@ const parseDocumentSize = (document) => {
|
|
|
607
615
|
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)));
|
|
608
616
|
};
|
|
609
617
|
//#endregion
|
|
610
|
-
//#region node_modules/.pnpm/css-line-break@2.1.0/node_modules/css-line-break/dist/css-line-break.es5.js
|
|
611
|
-
var toCodePoints$1 = function(str) {
|
|
612
|
-
var codePoints = [];
|
|
613
|
-
var i = 0;
|
|
614
|
-
var length = str.length;
|
|
615
|
-
while (i < length) {
|
|
616
|
-
var value = str.charCodeAt(i++);
|
|
617
|
-
if (value >= 55296 && value <= 56319 && i < length) {
|
|
618
|
-
var extra = str.charCodeAt(i++);
|
|
619
|
-
if ((extra & 64512) === 56320) codePoints.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
|
620
|
-
else {
|
|
621
|
-
codePoints.push(value);
|
|
622
|
-
i--;
|
|
623
|
-
}
|
|
624
|
-
} else codePoints.push(value);
|
|
625
|
-
}
|
|
626
|
-
return codePoints;
|
|
627
|
-
};
|
|
628
|
-
var fromCodePoint$1 = function() {
|
|
629
|
-
var codePoints = [];
|
|
630
|
-
for (var _i = 0; _i < arguments.length; _i++) codePoints[_i] = arguments[_i];
|
|
631
|
-
if (String.fromCodePoint) return String.fromCodePoint.apply(String, codePoints);
|
|
632
|
-
var length = codePoints.length;
|
|
633
|
-
if (!length) return "";
|
|
634
|
-
var codeUnits = [];
|
|
635
|
-
var index = -1;
|
|
636
|
-
var result = "";
|
|
637
|
-
while (++index < length) {
|
|
638
|
-
var codePoint = codePoints[index];
|
|
639
|
-
if (codePoint <= 65535) codeUnits.push(codePoint);
|
|
640
|
-
else {
|
|
641
|
-
codePoint -= 65536;
|
|
642
|
-
codeUnits.push((codePoint >> 10) + 55296, codePoint % 1024 + 56320);
|
|
643
|
-
}
|
|
644
|
-
if (index + 1 === length || codeUnits.length > 16384) {
|
|
645
|
-
result += String.fromCharCode.apply(String, codeUnits);
|
|
646
|
-
codeUnits.length = 0;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return result;
|
|
650
|
-
};
|
|
651
|
-
var chars$2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
652
|
-
var lookup$2 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
653
|
-
for (var i$2 = 0; i$2 < chars$2.length; i$2++) lookup$2[chars$2.charCodeAt(i$2)] = i$2;
|
|
654
|
-
var chars$1$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
655
|
-
var lookup$1$1 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
656
|
-
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;
|
|
657
|
-
var decode$1 = function(base64) {
|
|
658
|
-
var bufferLength = base64.length * .75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
|
|
659
|
-
if (base64[base64.length - 1] === "=") {
|
|
660
|
-
bufferLength--;
|
|
661
|
-
if (base64[base64.length - 2] === "=") bufferLength--;
|
|
662
|
-
}
|
|
663
|
-
var buffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.slice !== "undefined" ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
|
|
664
|
-
var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
|
|
665
|
-
for (i = 0; i < len; i += 4) {
|
|
666
|
-
encoded1 = lookup$1$1[base64.charCodeAt(i)];
|
|
667
|
-
encoded2 = lookup$1$1[base64.charCodeAt(i + 1)];
|
|
668
|
-
encoded3 = lookup$1$1[base64.charCodeAt(i + 2)];
|
|
669
|
-
encoded4 = lookup$1$1[base64.charCodeAt(i + 3)];
|
|
670
|
-
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
|
671
|
-
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
|
672
|
-
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
|
673
|
-
}
|
|
674
|
-
return buffer;
|
|
675
|
-
};
|
|
676
|
-
var polyUint16Array$1 = function(buffer) {
|
|
677
|
-
var length = buffer.length;
|
|
678
|
-
var bytes = [];
|
|
679
|
-
for (var i = 0; i < length; i += 2) bytes.push(buffer[i + 1] << 8 | buffer[i]);
|
|
680
|
-
return bytes;
|
|
681
|
-
};
|
|
682
|
-
var polyUint32Array$1 = function(buffer) {
|
|
683
|
-
var length = buffer.length;
|
|
684
|
-
var bytes = [];
|
|
685
|
-
for (var i = 0; i < length; i += 4) bytes.push(buffer[i + 3] << 24 | buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i]);
|
|
686
|
-
return bytes;
|
|
687
|
-
};
|
|
688
|
-
/** Shift size for getting the index-2 table offset. */
|
|
689
|
-
var UTRIE2_SHIFT_2$1 = 5;
|
|
690
|
-
/** Shift size for getting the index-1 table offset. */
|
|
691
|
-
var UTRIE2_SHIFT_1$1 = 11;
|
|
692
|
-
/**
|
|
693
|
-
* Shift size for shifting left the index array values.
|
|
694
|
-
* Increases possible data size with 16-bit index values at the cost
|
|
695
|
-
* of compactability.
|
|
696
|
-
* This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
|
|
697
|
-
*/
|
|
698
|
-
var UTRIE2_INDEX_SHIFT$1 = 2;
|
|
699
|
-
/**
|
|
700
|
-
* Difference between the two shift sizes,
|
|
701
|
-
* for getting an index-1 offset from an index-2 offset. 6=11-5
|
|
702
|
-
*/
|
|
703
|
-
var UTRIE2_SHIFT_1_2$1 = UTRIE2_SHIFT_1$1 - UTRIE2_SHIFT_2$1;
|
|
704
|
-
/**
|
|
705
|
-
* The part of the index-2 table for U+D800..U+DBFF stores values for
|
|
706
|
-
* lead surrogate code _units_ not code _points_.
|
|
707
|
-
* Values for lead surrogate code _points_ are indexed with this portion of the table.
|
|
708
|
-
* Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
|
|
709
|
-
*/
|
|
710
|
-
var UTRIE2_LSCP_INDEX_2_OFFSET$1 = 65536 >> UTRIE2_SHIFT_2$1;
|
|
711
|
-
/** Mask for getting the lower bits for the in-data-block offset. */
|
|
712
|
-
var UTRIE2_DATA_MASK$1 = (1 << UTRIE2_SHIFT_2$1) - 1;
|
|
713
|
-
/**
|
|
714
|
-
* The index-1 table, only used for supplementary code points, at offset 2112=0x840.
|
|
715
|
-
* Variable length, for code points up to highStart, where the last single-value range starts.
|
|
716
|
-
* Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
|
|
717
|
-
* (For 0x100000 supplementary code points U+10000..U+10ffff.)
|
|
718
|
-
*
|
|
719
|
-
* The part of the index-2 table for supplementary code points starts
|
|
720
|
-
* after this index-1 table.
|
|
721
|
-
*
|
|
722
|
-
* Both the index-1 table and the following part of the index-2 table
|
|
723
|
-
* are omitted completely if there is only BMP data.
|
|
724
|
-
*/
|
|
725
|
-
var UTRIE2_INDEX_1_OFFSET$1 = UTRIE2_LSCP_INDEX_2_OFFSET$1 + (1024 >> UTRIE2_SHIFT_2$1) + 32;
|
|
726
|
-
/**
|
|
727
|
-
* Number of index-1 entries for the BMP. 32=0x20
|
|
728
|
-
* This part of the index-1 table is omitted from the serialized form.
|
|
729
|
-
*/
|
|
730
|
-
var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 = 65536 >> UTRIE2_SHIFT_1$1;
|
|
731
|
-
/** Mask for getting the lower bits for the in-index-2-block offset. */
|
|
732
|
-
var UTRIE2_INDEX_2_MASK$1 = (1 << UTRIE2_SHIFT_1_2$1) - 1;
|
|
733
|
-
var slice16$1 = function(view, start, end) {
|
|
734
|
-
if (view.slice) return view.slice(start, end);
|
|
735
|
-
return new Uint16Array(Array.prototype.slice.call(view, start, end));
|
|
736
|
-
};
|
|
737
|
-
var slice32$1 = function(view, start, end) {
|
|
738
|
-
if (view.slice) return view.slice(start, end);
|
|
739
|
-
return new Uint32Array(Array.prototype.slice.call(view, start, end));
|
|
740
|
-
};
|
|
741
|
-
var createTrieFromBase64$1 = function(base64, _byteLength) {
|
|
742
|
-
var buffer = decode$1(base64);
|
|
743
|
-
var view32 = Array.isArray(buffer) ? polyUint32Array$1(buffer) : new Uint32Array(buffer);
|
|
744
|
-
var view16 = Array.isArray(buffer) ? polyUint16Array$1(buffer) : new Uint16Array(buffer);
|
|
745
|
-
var headerLength = 24;
|
|
746
|
-
var index = slice16$1(view16, headerLength / 2, view32[4] / 2);
|
|
747
|
-
var data = view32[5] === 2 ? slice16$1(view16, (headerLength + view32[4]) / 2) : slice32$1(view32, Math.ceil((headerLength + view32[4]) / 4));
|
|
748
|
-
return new Trie$1(view32[0], view32[1], view32[2], view32[3], index, data);
|
|
749
|
-
};
|
|
750
|
-
var Trie$1 = function() {
|
|
751
|
-
function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
|
|
752
|
-
this.initialValue = initialValue;
|
|
753
|
-
this.errorValue = errorValue;
|
|
754
|
-
this.highStart = highStart;
|
|
755
|
-
this.highValueIndex = highValueIndex;
|
|
756
|
-
this.index = index;
|
|
757
|
-
this.data = data;
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Get the value for a code point as stored in the Trie.
|
|
761
|
-
*
|
|
762
|
-
* @param codePoint the code point
|
|
763
|
-
* @return the value
|
|
764
|
-
*/
|
|
765
|
-
Trie.prototype.get = function(codePoint) {
|
|
766
|
-
var ix;
|
|
767
|
-
if (codePoint >= 0) {
|
|
768
|
-
if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {
|
|
769
|
-
ix = this.index[codePoint >> UTRIE2_SHIFT_2$1];
|
|
770
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
771
|
-
return this.data[ix];
|
|
772
|
-
}
|
|
773
|
-
if (codePoint <= 65535) {
|
|
774
|
-
ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET$1 + (codePoint - 55296 >> UTRIE2_SHIFT_2$1)];
|
|
775
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
776
|
-
return this.data[ix];
|
|
777
|
-
}
|
|
778
|
-
if (codePoint < this.highStart) {
|
|
779
|
-
ix = UTRIE2_INDEX_1_OFFSET$1 - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 + (codePoint >> UTRIE2_SHIFT_1$1);
|
|
780
|
-
ix = this.index[ix];
|
|
781
|
-
ix += codePoint >> UTRIE2_SHIFT_2$1 & UTRIE2_INDEX_2_MASK$1;
|
|
782
|
-
ix = this.index[ix];
|
|
783
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
784
|
-
return this.data[ix];
|
|
785
|
-
}
|
|
786
|
-
if (codePoint <= 1114111) return this.data[this.highValueIndex];
|
|
787
|
-
}
|
|
788
|
-
return this.errorValue;
|
|
789
|
-
};
|
|
790
|
-
return Trie;
|
|
791
|
-
}();
|
|
792
|
-
var chars$3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
793
|
-
var lookup$3 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
794
|
-
for (var i$3 = 0; i$3 < chars$3.length; i$3++) lookup$3[chars$3.charCodeAt(i$3)] = i$3;
|
|
795
|
-
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==";
|
|
796
|
-
var LETTER_NUMBER_MODIFIER = 50;
|
|
797
|
-
var BK = 1;
|
|
798
|
-
var CR$1 = 2;
|
|
799
|
-
var LF$1 = 3;
|
|
800
|
-
var CM = 4;
|
|
801
|
-
var NL = 5;
|
|
802
|
-
var WJ = 7;
|
|
803
|
-
var ZW = 8;
|
|
804
|
-
var GL = 9;
|
|
805
|
-
var SP = 10;
|
|
806
|
-
var ZWJ$1 = 11;
|
|
807
|
-
var B2 = 12;
|
|
808
|
-
var BA = 13;
|
|
809
|
-
var BB = 14;
|
|
810
|
-
var HY = 15;
|
|
811
|
-
var CB = 16;
|
|
812
|
-
var CL = 17;
|
|
813
|
-
var CP = 18;
|
|
814
|
-
var EX = 19;
|
|
815
|
-
var IN = 20;
|
|
816
|
-
var NS = 21;
|
|
817
|
-
var OP = 22;
|
|
818
|
-
var QU = 23;
|
|
819
|
-
var IS = 24;
|
|
820
|
-
var NU = 25;
|
|
821
|
-
var PO = 26;
|
|
822
|
-
var PR = 27;
|
|
823
|
-
var SY = 28;
|
|
824
|
-
var AI = 29;
|
|
825
|
-
var AL = 30;
|
|
826
|
-
var CJ = 31;
|
|
827
|
-
var EB = 32;
|
|
828
|
-
var EM = 33;
|
|
829
|
-
var H2 = 34;
|
|
830
|
-
var H3 = 35;
|
|
831
|
-
var HL = 36;
|
|
832
|
-
var ID = 37;
|
|
833
|
-
var JL = 38;
|
|
834
|
-
var JV = 39;
|
|
835
|
-
var JT = 40;
|
|
836
|
-
var RI$1 = 41;
|
|
837
|
-
var SA = 42;
|
|
838
|
-
var XX = 43;
|
|
839
|
-
var ea_OP = [9001, 65288];
|
|
840
|
-
var BREAK_MANDATORY = "!";
|
|
841
|
-
var BREAK_NOT_ALLOWED$1 = "×";
|
|
842
|
-
var BREAK_ALLOWED$1 = "÷";
|
|
843
|
-
var UnicodeTrie$1 = createTrieFromBase64$1(base64$1);
|
|
844
|
-
var ALPHABETICS = [AL, HL];
|
|
845
|
-
var HARD_LINE_BREAKS = [
|
|
846
|
-
BK,
|
|
847
|
-
CR$1,
|
|
848
|
-
LF$1,
|
|
849
|
-
NL
|
|
850
|
-
];
|
|
851
|
-
var SPACE$1 = [SP, ZW];
|
|
852
|
-
var PREFIX_POSTFIX = [PR, PO];
|
|
853
|
-
var LINE_BREAKS = HARD_LINE_BREAKS.concat(SPACE$1);
|
|
854
|
-
var KOREAN_SYLLABLE_BLOCK = [
|
|
855
|
-
JL,
|
|
856
|
-
JV,
|
|
857
|
-
JT,
|
|
858
|
-
H2,
|
|
859
|
-
H3
|
|
860
|
-
];
|
|
861
|
-
var HYPHEN = [HY, BA];
|
|
862
|
-
var codePointsToCharacterClasses = function(codePoints, lineBreak) {
|
|
863
|
-
if (lineBreak === void 0) lineBreak = "strict";
|
|
864
|
-
var types = [];
|
|
865
|
-
var indices = [];
|
|
866
|
-
var categories = [];
|
|
867
|
-
codePoints.forEach(function(codePoint, index) {
|
|
868
|
-
var classType = UnicodeTrie$1.get(codePoint);
|
|
869
|
-
if (classType > LETTER_NUMBER_MODIFIER) {
|
|
870
|
-
categories.push(true);
|
|
871
|
-
classType -= LETTER_NUMBER_MODIFIER;
|
|
872
|
-
} else categories.push(false);
|
|
873
|
-
if ([
|
|
874
|
-
"normal",
|
|
875
|
-
"auto",
|
|
876
|
-
"loose"
|
|
877
|
-
].indexOf(lineBreak) !== -1) {
|
|
878
|
-
if ([
|
|
879
|
-
8208,
|
|
880
|
-
8211,
|
|
881
|
-
12316,
|
|
882
|
-
12448
|
|
883
|
-
].indexOf(codePoint) !== -1) {
|
|
884
|
-
indices.push(index);
|
|
885
|
-
return types.push(CB);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
if (classType === CM || classType === ZWJ$1) {
|
|
889
|
-
if (index === 0) {
|
|
890
|
-
indices.push(index);
|
|
891
|
-
return types.push(AL);
|
|
892
|
-
}
|
|
893
|
-
var prev = types[index - 1];
|
|
894
|
-
if (LINE_BREAKS.indexOf(prev) === -1) {
|
|
895
|
-
indices.push(indices[index - 1]);
|
|
896
|
-
return types.push(prev);
|
|
897
|
-
}
|
|
898
|
-
indices.push(index);
|
|
899
|
-
return types.push(AL);
|
|
900
|
-
}
|
|
901
|
-
indices.push(index);
|
|
902
|
-
if (classType === CJ) return types.push(lineBreak === "strict" ? NS : ID);
|
|
903
|
-
if (classType === SA) return types.push(AL);
|
|
904
|
-
if (classType === AI) return types.push(AL);
|
|
905
|
-
if (classType === XX) {
|
|
906
|
-
if (codePoint >= 131072 && codePoint <= 196605 || codePoint >= 196608 && codePoint <= 262141) return types.push(ID);
|
|
907
|
-
else return types.push(AL);
|
|
908
|
-
}
|
|
909
|
-
types.push(classType);
|
|
910
|
-
});
|
|
911
|
-
return [
|
|
912
|
-
indices,
|
|
913
|
-
types,
|
|
914
|
-
categories
|
|
915
|
-
];
|
|
916
|
-
};
|
|
917
|
-
var isAdjacentWithSpaceIgnored = function(a, b, currentIndex, classTypes) {
|
|
918
|
-
var current = classTypes[currentIndex];
|
|
919
|
-
if (Array.isArray(a) ? a.indexOf(current) !== -1 : a === current) {
|
|
920
|
-
var i = currentIndex;
|
|
921
|
-
while (i <= classTypes.length) {
|
|
922
|
-
i++;
|
|
923
|
-
var next = classTypes[i];
|
|
924
|
-
if (next === b) return true;
|
|
925
|
-
if (next !== SP) break;
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
if (current === SP) {
|
|
929
|
-
var i = currentIndex;
|
|
930
|
-
while (i > 0) {
|
|
931
|
-
i--;
|
|
932
|
-
var prev = classTypes[i];
|
|
933
|
-
if (Array.isArray(a) ? a.indexOf(prev) !== -1 : a === prev) {
|
|
934
|
-
var n = currentIndex;
|
|
935
|
-
while (n <= classTypes.length) {
|
|
936
|
-
n++;
|
|
937
|
-
var next = classTypes[n];
|
|
938
|
-
if (next === b) return true;
|
|
939
|
-
if (next !== SP) break;
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
if (prev !== SP) break;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
return false;
|
|
946
|
-
};
|
|
947
|
-
var previousNonSpaceClassType = function(currentIndex, classTypes) {
|
|
948
|
-
var i = currentIndex;
|
|
949
|
-
while (i >= 0) {
|
|
950
|
-
var type = classTypes[i];
|
|
951
|
-
if (type === SP) i--;
|
|
952
|
-
else return type;
|
|
953
|
-
}
|
|
954
|
-
return 0;
|
|
955
|
-
};
|
|
956
|
-
var _lineBreakAtIndex = function(codePoints, classTypes, indicies, index, forbiddenBreaks) {
|
|
957
|
-
if (indicies[index] === 0) return BREAK_NOT_ALLOWED$1;
|
|
958
|
-
var currentIndex = index - 1;
|
|
959
|
-
if (Array.isArray(forbiddenBreaks) && forbiddenBreaks[currentIndex] === true) return BREAK_NOT_ALLOWED$1;
|
|
960
|
-
var beforeIndex = currentIndex - 1;
|
|
961
|
-
var afterIndex = currentIndex + 1;
|
|
962
|
-
var current = classTypes[currentIndex];
|
|
963
|
-
var before = beforeIndex >= 0 ? classTypes[beforeIndex] : 0;
|
|
964
|
-
var next = classTypes[afterIndex];
|
|
965
|
-
if (current === CR$1 && next === LF$1) return BREAK_NOT_ALLOWED$1;
|
|
966
|
-
if (HARD_LINE_BREAKS.indexOf(current) !== -1) return BREAK_MANDATORY;
|
|
967
|
-
if (HARD_LINE_BREAKS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
968
|
-
if (SPACE$1.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
969
|
-
if (previousNonSpaceClassType(currentIndex, classTypes) === ZW) return BREAK_ALLOWED$1;
|
|
970
|
-
if (UnicodeTrie$1.get(codePoints[currentIndex]) === ZWJ$1) return BREAK_NOT_ALLOWED$1;
|
|
971
|
-
if ((current === EB || current === EM) && UnicodeTrie$1.get(codePoints[afterIndex]) === ZWJ$1) return BREAK_NOT_ALLOWED$1;
|
|
972
|
-
if (current === WJ || next === WJ) return BREAK_NOT_ALLOWED$1;
|
|
973
|
-
if (current === GL) return BREAK_NOT_ALLOWED$1;
|
|
974
|
-
if ([
|
|
975
|
-
SP,
|
|
976
|
-
BA,
|
|
977
|
-
HY
|
|
978
|
-
].indexOf(current) === -1 && next === GL) return BREAK_NOT_ALLOWED$1;
|
|
979
|
-
if ([
|
|
980
|
-
CL,
|
|
981
|
-
CP,
|
|
982
|
-
EX,
|
|
983
|
-
IS,
|
|
984
|
-
SY
|
|
985
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
986
|
-
if (previousNonSpaceClassType(currentIndex, classTypes) === OP) return BREAK_NOT_ALLOWED$1;
|
|
987
|
-
if (isAdjacentWithSpaceIgnored(QU, OP, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
988
|
-
if (isAdjacentWithSpaceIgnored([CL, CP], NS, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
989
|
-
if (isAdjacentWithSpaceIgnored(B2, B2, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
990
|
-
if (current === SP) return BREAK_ALLOWED$1;
|
|
991
|
-
if (current === QU || next === QU) return BREAK_NOT_ALLOWED$1;
|
|
992
|
-
if (next === CB || current === CB) return BREAK_ALLOWED$1;
|
|
993
|
-
if ([
|
|
994
|
-
BA,
|
|
995
|
-
HY,
|
|
996
|
-
NS
|
|
997
|
-
].indexOf(next) !== -1 || current === BB) return BREAK_NOT_ALLOWED$1;
|
|
998
|
-
if (before === HL && HYPHEN.indexOf(current) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
999
|
-
if (current === SY && next === HL) return BREAK_NOT_ALLOWED$1;
|
|
1000
|
-
if (next === IN) return BREAK_NOT_ALLOWED$1;
|
|
1001
|
-
if (ALPHABETICS.indexOf(next) !== -1 && current === NU || ALPHABETICS.indexOf(current) !== -1 && next === NU) return BREAK_NOT_ALLOWED$1;
|
|
1002
|
-
if (current === PR && [
|
|
1003
|
-
ID,
|
|
1004
|
-
EB,
|
|
1005
|
-
EM
|
|
1006
|
-
].indexOf(next) !== -1 || [
|
|
1007
|
-
ID,
|
|
1008
|
-
EB,
|
|
1009
|
-
EM
|
|
1010
|
-
].indexOf(current) !== -1 && next === PO) return BREAK_NOT_ALLOWED$1;
|
|
1011
|
-
if (ALPHABETICS.indexOf(current) !== -1 && PREFIX_POSTFIX.indexOf(next) !== -1 || PREFIX_POSTFIX.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1012
|
-
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 && [
|
|
1013
|
-
NU,
|
|
1014
|
-
SY,
|
|
1015
|
-
IS
|
|
1016
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1017
|
-
if ([
|
|
1018
|
-
NU,
|
|
1019
|
-
SY,
|
|
1020
|
-
IS,
|
|
1021
|
-
CL,
|
|
1022
|
-
CP
|
|
1023
|
-
].indexOf(next) !== -1) {
|
|
1024
|
-
var prevIndex = currentIndex;
|
|
1025
|
-
while (prevIndex >= 0) {
|
|
1026
|
-
var type = classTypes[prevIndex];
|
|
1027
|
-
if (type === NU) return BREAK_NOT_ALLOWED$1;
|
|
1028
|
-
else if ([SY, IS].indexOf(type) !== -1) prevIndex--;
|
|
1029
|
-
else break;
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
if ([PR, PO].indexOf(next) !== -1) {
|
|
1033
|
-
var prevIndex = [CL, CP].indexOf(current) !== -1 ? beforeIndex : currentIndex;
|
|
1034
|
-
while (prevIndex >= 0) {
|
|
1035
|
-
var type = classTypes[prevIndex];
|
|
1036
|
-
if (type === NU) return BREAK_NOT_ALLOWED$1;
|
|
1037
|
-
else if ([SY, IS].indexOf(type) !== -1) prevIndex--;
|
|
1038
|
-
else break;
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
if (JL === current && [
|
|
1042
|
-
JL,
|
|
1043
|
-
JV,
|
|
1044
|
-
H2,
|
|
1045
|
-
H3
|
|
1046
|
-
].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;
|
|
1047
|
-
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;
|
|
1048
|
-
if (ALPHABETICS.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1049
|
-
if (current === IS && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1050
|
-
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;
|
|
1051
|
-
if (current === RI$1 && next === RI$1) {
|
|
1052
|
-
var i = indicies[currentIndex];
|
|
1053
|
-
var count = 1;
|
|
1054
|
-
while (i > 0) {
|
|
1055
|
-
i--;
|
|
1056
|
-
if (classTypes[i] === RI$1) count++;
|
|
1057
|
-
else break;
|
|
1058
|
-
}
|
|
1059
|
-
if (count % 2 !== 0) return BREAK_NOT_ALLOWED$1;
|
|
1060
|
-
}
|
|
1061
|
-
if (current === EB && next === EM) return BREAK_NOT_ALLOWED$1;
|
|
1062
|
-
return BREAK_ALLOWED$1;
|
|
1063
|
-
};
|
|
1064
|
-
var cssFormattedClasses = function(codePoints, options) {
|
|
1065
|
-
if (!options) options = {
|
|
1066
|
-
lineBreak: "normal",
|
|
1067
|
-
wordBreak: "normal"
|
|
1068
|
-
};
|
|
1069
|
-
var _a = codePointsToCharacterClasses(codePoints, options.lineBreak), indicies = _a[0], classTypes = _a[1], isLetterNumber = _a[2];
|
|
1070
|
-
if (options.wordBreak === "break-all" || options.wordBreak === "break-word") classTypes = classTypes.map(function(type) {
|
|
1071
|
-
return [
|
|
1072
|
-
NU,
|
|
1073
|
-
AL,
|
|
1074
|
-
SA
|
|
1075
|
-
].indexOf(type) !== -1 ? ID : type;
|
|
1076
|
-
});
|
|
1077
|
-
var forbiddenBreakpoints = options.wordBreak === "keep-all" ? isLetterNumber.map(function(letterNumber, i) {
|
|
1078
|
-
return letterNumber && codePoints[i] >= 19968 && codePoints[i] <= 40959;
|
|
1079
|
-
}) : void 0;
|
|
1080
|
-
return [
|
|
1081
|
-
indicies,
|
|
1082
|
-
classTypes,
|
|
1083
|
-
forbiddenBreakpoints
|
|
1084
|
-
];
|
|
1085
|
-
};
|
|
1086
|
-
var Break = function() {
|
|
1087
|
-
function Break(codePoints, lineBreak, start, end) {
|
|
1088
|
-
this.codePoints = codePoints;
|
|
1089
|
-
this.required = lineBreak === BREAK_MANDATORY;
|
|
1090
|
-
this.start = start;
|
|
1091
|
-
this.end = end;
|
|
1092
|
-
}
|
|
1093
|
-
Break.prototype.slice = function() {
|
|
1094
|
-
return fromCodePoint$1.apply(void 0, this.codePoints.slice(this.start, this.end));
|
|
1095
|
-
};
|
|
1096
|
-
return Break;
|
|
1097
|
-
}();
|
|
1098
|
-
var LineBreaker = function(str, options) {
|
|
1099
|
-
var codePoints = toCodePoints$1(str);
|
|
1100
|
-
var _a = cssFormattedClasses(codePoints, options), indicies = _a[0], classTypes = _a[1], forbiddenBreakpoints = _a[2];
|
|
1101
|
-
var length = codePoints.length;
|
|
1102
|
-
var lastEnd = 0;
|
|
1103
|
-
var nextIndex = 0;
|
|
1104
|
-
return { next: function() {
|
|
1105
|
-
if (nextIndex >= length) return {
|
|
1106
|
-
done: true,
|
|
1107
|
-
value: null
|
|
1108
|
-
};
|
|
1109
|
-
var lineBreak = BREAK_NOT_ALLOWED$1;
|
|
1110
|
-
while (nextIndex < length && (lineBreak = _lineBreakAtIndex(codePoints, classTypes, indicies, ++nextIndex, forbiddenBreakpoints)) === BREAK_NOT_ALLOWED$1);
|
|
1111
|
-
if (lineBreak !== BREAK_NOT_ALLOWED$1 || nextIndex === length) {
|
|
1112
|
-
var value = new Break(codePoints, lineBreak, lastEnd, nextIndex);
|
|
1113
|
-
lastEnd = nextIndex;
|
|
1114
|
-
return {
|
|
1115
|
-
value,
|
|
1116
|
-
done: false
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
return {
|
|
1120
|
-
done: true,
|
|
1121
|
-
value: null
|
|
1122
|
-
};
|
|
1123
|
-
} };
|
|
1124
|
-
};
|
|
1125
|
-
//#endregion
|
|
1126
618
|
//#region src/core/util.ts
|
|
1127
619
|
/**
|
|
1128
620
|
* Indexed access where the shape/arity is guaranteed by construction (the CSS
|
|
@@ -1178,7 +670,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1178
670
|
integers.push(at(codePoints, c));
|
|
1179
671
|
c++;
|
|
1180
672
|
}
|
|
1181
|
-
const int = integers.length ? parseInt(fromCodePoint
|
|
673
|
+
const int = integers.length ? parseInt(String.fromCodePoint(...integers), 10) : 0;
|
|
1182
674
|
if (codePoints[c] === 46) c++;
|
|
1183
675
|
const fraction = [];
|
|
1184
676
|
while (isDigit(codePoints[c] ?? NaN)) {
|
|
@@ -1186,7 +678,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1186
678
|
c++;
|
|
1187
679
|
}
|
|
1188
680
|
const fracd = fraction.length;
|
|
1189
|
-
const frac = fracd ? parseInt(fromCodePoint
|
|
681
|
+
const frac = fracd ? parseInt(String.fromCodePoint(...fraction), 10) : 0;
|
|
1190
682
|
if (codePoints[c] === 69 || codePoints[c] === 101) c++;
|
|
1191
683
|
let expsign = 1;
|
|
1192
684
|
if (codePoints[c] === 43 || codePoints[c] === 45) {
|
|
@@ -1198,7 +690,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1198
690
|
exponent.push(at(codePoints, c));
|
|
1199
691
|
c++;
|
|
1200
692
|
}
|
|
1201
|
-
const exp = exponent.length ? parseInt(fromCodePoint
|
|
693
|
+
const exp = exponent.length ? parseInt(String.fromCodePoint(...exponent), 10) : 0;
|
|
1202
694
|
return sign * (int + frac * Math.pow(10, -fracd)) * Math.pow(10, expsign * exp);
|
|
1203
695
|
};
|
|
1204
696
|
//#endregion
|
|
@@ -1227,12 +719,8 @@ const EOF_TOKEN = { type: 32 };
|
|
|
1227
719
|
//#endregion
|
|
1228
720
|
//#region src/css/syntax/tokenizer.ts
|
|
1229
721
|
var Tokenizer = class Tokenizer {
|
|
1230
|
-
static
|
|
1231
|
-
|
|
1232
|
-
}
|
|
1233
|
-
static {
|
|
1234
|
-
this.MAX_POOL_SIZE = 40;
|
|
1235
|
-
}
|
|
722
|
+
static _pool = [];
|
|
723
|
+
static MAX_POOL_SIZE = 40;
|
|
1236
724
|
static get() {
|
|
1237
725
|
return Tokenizer._pool.pop() || new Tokenizer();
|
|
1238
726
|
}
|
|
@@ -1242,14 +730,29 @@ var Tokenizer = class Tokenizer {
|
|
|
1242
730
|
Tokenizer._pool.push(tokenizer);
|
|
1243
731
|
}
|
|
1244
732
|
}
|
|
733
|
+
_value;
|
|
734
|
+
/**
|
|
735
|
+
* Read cursor into `_value`. Consumption advances the cursor instead of
|
|
736
|
+
* shifting the array — `Array.shift()` per code point makes tokenising a
|
|
737
|
+
* long value O(n²) (a 200 KB inline data-URI background alone would cost
|
|
738
|
+
* billions of operations, and background-image values are never parse-
|
|
739
|
+
* cached). `write()` compacts already-consumed prefix bytes.
|
|
740
|
+
*/
|
|
741
|
+
_cursor;
|
|
1245
742
|
constructor() {
|
|
1246
743
|
this._value = [];
|
|
744
|
+
this._cursor = 0;
|
|
1247
745
|
}
|
|
1248
746
|
_reset() {
|
|
1249
747
|
this._value = [];
|
|
748
|
+
this._cursor = 0;
|
|
1250
749
|
}
|
|
1251
750
|
write(chunk) {
|
|
1252
|
-
this.
|
|
751
|
+
if (this._cursor > 0) {
|
|
752
|
+
this._value = this._value.slice(this._cursor);
|
|
753
|
+
this._cursor = 0;
|
|
754
|
+
}
|
|
755
|
+
this._value = this._value.concat([...chunk].map((char) => char.codePointAt(0)));
|
|
1253
756
|
}
|
|
1254
757
|
read() {
|
|
1255
758
|
const tokens = [];
|
|
@@ -1417,19 +920,21 @@ var Tokenizer = class Tokenizer {
|
|
|
1417
920
|
}
|
|
1418
921
|
return {
|
|
1419
922
|
type: 6,
|
|
1420
|
-
value: fromCodePoint
|
|
923
|
+
value: String.fromCodePoint(codePoint)
|
|
1421
924
|
};
|
|
1422
925
|
}
|
|
1423
926
|
consumeCodePoint() {
|
|
1424
|
-
const value = this._value.
|
|
1425
|
-
|
|
927
|
+
const value = this._value[this._cursor];
|
|
928
|
+
if (value === void 0) return -1;
|
|
929
|
+
this._cursor++;
|
|
930
|
+
return value;
|
|
1426
931
|
}
|
|
1427
932
|
reconsumeCodePoint(codePoint) {
|
|
1428
|
-
this._value.
|
|
933
|
+
if (this._cursor > 0 && this._value[this._cursor - 1] === codePoint) this._cursor--;
|
|
934
|
+
else this._value.splice(this._cursor, 0, codePoint);
|
|
1429
935
|
}
|
|
1430
936
|
peekCodePoint(delta) {
|
|
1431
|
-
|
|
1432
|
-
const codePoint = this._value[delta];
|
|
937
|
+
const codePoint = this._value[this._cursor + delta];
|
|
1433
938
|
return codePoint !== void 0 ? codePoint : -1;
|
|
1434
939
|
}
|
|
1435
940
|
consumeUnicodeRangeToken() {
|
|
@@ -1447,10 +952,10 @@ var Tokenizer = class Tokenizer {
|
|
|
1447
952
|
}
|
|
1448
953
|
if (questionMarks) return {
|
|
1449
954
|
type: 30,
|
|
1450
|
-
start: parseInt(fromCodePoint
|
|
1451
|
-
end: parseInt(fromCodePoint
|
|
955
|
+
start: parseInt(String.fromCodePoint(...digits.map((digit) => digit === 63 ? 48 : digit)), 16),
|
|
956
|
+
end: parseInt(String.fromCodePoint(...digits.map((digit) => digit === 63 ? 70 : digit)), 16)
|
|
1452
957
|
};
|
|
1453
|
-
const start = parseInt(fromCodePoint
|
|
958
|
+
const start = parseInt(String.fromCodePoint(...digits), 16);
|
|
1454
959
|
if (codePoint === 45 && isHex(this.peekCodePoint(0))) {
|
|
1455
960
|
codePoint = this.consumeCodePoint();
|
|
1456
961
|
const endDigits = [];
|
|
@@ -1461,7 +966,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1461
966
|
return {
|
|
1462
967
|
type: 30,
|
|
1463
968
|
start,
|
|
1464
|
-
end: parseInt(fromCodePoint
|
|
969
|
+
end: parseInt(String.fromCodePoint(...endDigits), 16)
|
|
1465
970
|
};
|
|
1466
971
|
} else return {
|
|
1467
972
|
type: 30,
|
|
@@ -1513,7 +1018,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1513
1018
|
const codePoint = this.consumeCodePoint();
|
|
1514
1019
|
if (codePoint === -1 || codePoint === 41) return {
|
|
1515
1020
|
type: 22,
|
|
1516
|
-
value: fromCodePoint
|
|
1021
|
+
value: String.fromCodePoint(...value)
|
|
1517
1022
|
};
|
|
1518
1023
|
else if (isWhiteSpace(codePoint)) {
|
|
1519
1024
|
this.consumeWhiteSpace();
|
|
@@ -1521,7 +1026,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1521
1026
|
this.consumeCodePoint();
|
|
1522
1027
|
return {
|
|
1523
1028
|
type: 22,
|
|
1524
|
-
value: fromCodePoint
|
|
1029
|
+
value: String.fromCodePoint(...value)
|
|
1525
1030
|
};
|
|
1526
1031
|
}
|
|
1527
1032
|
this.consumeBadUrlRemnants();
|
|
@@ -1551,19 +1056,21 @@ var Tokenizer = class Tokenizer {
|
|
|
1551
1056
|
consumeStringSlice(count) {
|
|
1552
1057
|
const SLICE_STACK_SIZE = 5e4;
|
|
1553
1058
|
let value = "";
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1059
|
+
const end = this._cursor + count;
|
|
1060
|
+
let from = this._cursor;
|
|
1061
|
+
while (from < end) {
|
|
1062
|
+
const to = Math.min(end, from + SLICE_STACK_SIZE);
|
|
1063
|
+
value += String.fromCodePoint(...this._value.slice(from, to));
|
|
1064
|
+
from = to;
|
|
1065
|
+
}
|
|
1066
|
+
this._cursor = end + 1;
|
|
1560
1067
|
return value;
|
|
1561
1068
|
}
|
|
1562
1069
|
consumeStringToken(endingCodePoint) {
|
|
1563
1070
|
let value = "";
|
|
1564
1071
|
let i = 0;
|
|
1565
1072
|
do {
|
|
1566
|
-
const codePoint = this._value[i];
|
|
1073
|
+
const codePoint = this._value[this._cursor + i];
|
|
1567
1074
|
if (codePoint === -1 || codePoint === void 0 || codePoint === endingCodePoint) {
|
|
1568
1075
|
value += this.consumeStringSlice(i);
|
|
1569
1076
|
return {
|
|
@@ -1572,19 +1079,19 @@ var Tokenizer = class Tokenizer {
|
|
|
1572
1079
|
};
|
|
1573
1080
|
}
|
|
1574
1081
|
if (codePoint === 10) {
|
|
1575
|
-
this.
|
|
1082
|
+
this._cursor += i;
|
|
1576
1083
|
return BAD_STRING_TOKEN;
|
|
1577
1084
|
}
|
|
1578
1085
|
if (codePoint === 92) {
|
|
1579
|
-
const next = this._value[i + 1];
|
|
1086
|
+
const next = this._value[this._cursor + i + 1];
|
|
1580
1087
|
if (next !== -1 && next !== void 0) {
|
|
1581
1088
|
if (next === 10) {
|
|
1582
1089
|
value += this.consumeStringSlice(i);
|
|
1583
1090
|
i = -1;
|
|
1584
|
-
this.
|
|
1091
|
+
this._cursor++;
|
|
1585
1092
|
} else if (isValidEscape(codePoint, next)) {
|
|
1586
1093
|
value += this.consumeStringSlice(i);
|
|
1587
|
-
value += fromCodePoint
|
|
1094
|
+
value += String.fromCodePoint(this.consumeEscapedCodePoint());
|
|
1588
1095
|
i = -1;
|
|
1589
1096
|
}
|
|
1590
1097
|
}
|
|
@@ -1643,8 +1150,8 @@ var Tokenizer = class Tokenizer {
|
|
|
1643
1150
|
consumeEscapedCodePoint() {
|
|
1644
1151
|
const codePoint = this.consumeCodePoint();
|
|
1645
1152
|
if (isHex(codePoint)) {
|
|
1646
|
-
let hex = fromCodePoint
|
|
1647
|
-
while (isHex(this.peekCodePoint(0)) && hex.length < 6) hex += fromCodePoint
|
|
1153
|
+
let hex = String.fromCodePoint(codePoint);
|
|
1154
|
+
while (isHex(this.peekCodePoint(0)) && hex.length < 6) hex += String.fromCodePoint(this.consumeCodePoint());
|
|
1648
1155
|
if (isWhiteSpace(this.peekCodePoint(0))) this.consumeCodePoint();
|
|
1649
1156
|
const hexCodePoint = parseInt(hex, 16);
|
|
1650
1157
|
if (hexCodePoint === 0 || isSurrogateCodePoint(hexCodePoint) || hexCodePoint > 1114111) return REPLACEMENT_CHARACTER;
|
|
@@ -1657,8 +1164,8 @@ var Tokenizer = class Tokenizer {
|
|
|
1657
1164
|
let result = "";
|
|
1658
1165
|
while (true) {
|
|
1659
1166
|
const codePoint = this.consumeCodePoint();
|
|
1660
|
-
if (isNameCodePoint(codePoint)) result += fromCodePoint
|
|
1661
|
-
else if (isValidEscape(codePoint, this.peekCodePoint(0))) result += fromCodePoint
|
|
1167
|
+
if (isNameCodePoint(codePoint)) result += String.fromCodePoint(codePoint);
|
|
1168
|
+
else if (isValidEscape(codePoint, this.peekCodePoint(0))) result += String.fromCodePoint(this.consumeEscapedCodePoint());
|
|
1662
1169
|
else {
|
|
1663
1170
|
this.reconsumeCodePoint(codePoint);
|
|
1664
1171
|
return result;
|
|
@@ -1669,6 +1176,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1669
1176
|
//#endregion
|
|
1670
1177
|
//#region src/css/syntax/parser.ts
|
|
1671
1178
|
var Parser = class Parser {
|
|
1179
|
+
_tokens;
|
|
1672
1180
|
constructor(tokens) {
|
|
1673
1181
|
this._tokens = tokens;
|
|
1674
1182
|
}
|
|
@@ -2198,13 +1706,17 @@ const packXYZ = (args) => {
|
|
|
2198
1706
|
};
|
|
2199
1707
|
const packLab = (_context, args) => {
|
|
2200
1708
|
if (isRelativeTransform(args.filter(nonFunctionArgSeparator))) throw new Error("Relative color not supported for lab()");
|
|
2201
|
-
const [
|
|
1709
|
+
const [extractedL, a, b, alpha] = extractLabComponents(args), l = isPercentageLightness(args) ? extractedL * 100 : extractedL, rgb = srgbLinear2rgb(xyz2rgbLinear(lab2xyz([
|
|
2202
1710
|
l,
|
|
2203
1711
|
a,
|
|
2204
1712
|
b
|
|
2205
1713
|
])));
|
|
2206
1714
|
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);
|
|
2207
1715
|
};
|
|
1716
|
+
const isPercentageLightness = (args) => {
|
|
1717
|
+
const t0 = args.filter(nonFunctionArgSeparator)[0];
|
|
1718
|
+
return t0 !== void 0 && t0.type === 16;
|
|
1719
|
+
};
|
|
2208
1720
|
const packOkLab = (_context, args) => {
|
|
2209
1721
|
if (isRelativeTransform(args.filter(nonFunctionArgSeparator))) throw new Error("Relative color not supported for oklab()");
|
|
2210
1722
|
const [l, a, b, alpha] = extractLabComponents(args), rgb = srgbLinear2rgb(xyz2rgbLinear(oklab2xyz([
|
|
@@ -2233,7 +1745,7 @@ const packLch = (_context, args) => {
|
|
|
2233
1745
|
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);
|
|
2234
1746
|
};
|
|
2235
1747
|
const extractHslComponents = (context, args) => {
|
|
2236
|
-
const tokens = args.filter(nonFunctionArgSeparator), hue = tokens[0], saturation = tokens[1], lightness = tokens[2], alpha = tokens[3];
|
|
1748
|
+
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];
|
|
2237
1749
|
return [
|
|
2238
1750
|
hue ? (hue.type === 17 ? deg(hue.number) : angle.parse(context, hue)) / (Math.PI * 2) : 0,
|
|
2239
1751
|
saturation !== void 0 && isLengthPercentage(saturation) ? saturation.number / 100 : 0,
|
|
@@ -2248,7 +1760,7 @@ const packHSL = (context, args) => {
|
|
|
2248
1760
|
s,
|
|
2249
1761
|
l
|
|
2250
1762
|
]);
|
|
2251
|
-
return pack(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255,
|
|
1763
|
+
return pack(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255, a);
|
|
2252
1764
|
};
|
|
2253
1765
|
const extractLchComponents = (args) => {
|
|
2254
1766
|
const tokens = args.filter(nonFunctionArgSeparator), t0 = tokens[0], t1 = tokens[1], t2 = tokens[2], t4 = tokens[4];
|
|
@@ -2323,9 +1835,9 @@ const hue2rgb = (t1, t2, hue) => {
|
|
|
2323
1835
|
};
|
|
2324
1836
|
const hsl2rgb = ([h, s, l]) => {
|
|
2325
1837
|
if (s === 0) return [
|
|
2326
|
-
l
|
|
2327
|
-
l
|
|
2328
|
-
l
|
|
1838
|
+
l,
|
|
1839
|
+
l,
|
|
1840
|
+
l
|
|
2329
1841
|
];
|
|
2330
1842
|
const t2 = l <= .5 ? l * (s + 1) : l + s - l * s, t1 = l * 2 - t2;
|
|
2331
1843
|
return [
|
|
@@ -3075,6 +2587,393 @@ const convertRec2020 = (args) => {
|
|
|
3075
2587
|
]);
|
|
3076
2588
|
};
|
|
3077
2589
|
//#endregion
|
|
2590
|
+
//#region src/css/types/functions/color-mix.ts
|
|
2591
|
+
const HUE_DEG_INDEX = {
|
|
2592
|
+
lch: 2,
|
|
2593
|
+
oklch: 2,
|
|
2594
|
+
hsl: 0
|
|
2595
|
+
};
|
|
2596
|
+
const XYZ_FROM_LMS = [
|
|
2597
|
+
1.2268798758459243,
|
|
2598
|
+
-.5578149944602171,
|
|
2599
|
+
.2813910456659647,
|
|
2600
|
+
-.0405757452148008,
|
|
2601
|
+
1.112286803280317,
|
|
2602
|
+
-.0717110580655164,
|
|
2603
|
+
-.0763729366746601,
|
|
2604
|
+
-.4214933324022432,
|
|
2605
|
+
1.5869240198367816
|
|
2606
|
+
];
|
|
2607
|
+
const LMS_FROM_OKLAB = [
|
|
2608
|
+
1,
|
|
2609
|
+
.3963377773761749,
|
|
2610
|
+
.2158037573099136,
|
|
2611
|
+
1,
|
|
2612
|
+
-.1055613458156586,
|
|
2613
|
+
-.0638541728258133,
|
|
2614
|
+
1,
|
|
2615
|
+
-.0894841775298119,
|
|
2616
|
+
-1.2914855480194092
|
|
2617
|
+
];
|
|
2618
|
+
const matrix3Inverse = (m) => {
|
|
2619
|
+
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];
|
|
2620
|
+
const det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
|
|
2621
|
+
return [
|
|
2622
|
+
(e * i - f * h) / det,
|
|
2623
|
+
(c * h - b * i) / det,
|
|
2624
|
+
(b * f - c * e) / det,
|
|
2625
|
+
(f * g - d * i) / det,
|
|
2626
|
+
(a * i - c * g) / det,
|
|
2627
|
+
(c * d - a * f) / det,
|
|
2628
|
+
(d * h - e * g) / det,
|
|
2629
|
+
(b * g - a * h) / det,
|
|
2630
|
+
(a * e - b * d) / det
|
|
2631
|
+
];
|
|
2632
|
+
};
|
|
2633
|
+
const XYZ_TO_LMS = matrix3Inverse(XYZ_FROM_LMS);
|
|
2634
|
+
const OKLAB_FROM_LMS = matrix3Inverse(LMS_FROM_OKLAB);
|
|
2635
|
+
const LAB_K = 24389 / 27;
|
|
2636
|
+
const LAB_E = 24 / 116;
|
|
2637
|
+
const LAB_E3 = LAB_E * LAB_E * LAB_E;
|
|
2638
|
+
const LAB_X_SCALE = .3457 / .3585;
|
|
2639
|
+
const LAB_Z_SCALE = .2958 / .3585;
|
|
2640
|
+
const unpackSrgb = (color) => [
|
|
2641
|
+
(255 & color >> 24) / 255,
|
|
2642
|
+
(255 & color >> 16) / 255,
|
|
2643
|
+
(255 & color >> 8) / 255
|
|
2644
|
+
];
|
|
2645
|
+
/** Inverse of color-utilities' lab2xyz: D65 XYZ → CIE Lab (0..100 scale). */
|
|
2646
|
+
const xyzD65ToLab = (xyz) => {
|
|
2647
|
+
const [x50, y50, z50] = d65toD50([
|
|
2648
|
+
xyz[0],
|
|
2649
|
+
xyz[1],
|
|
2650
|
+
xyz[2]
|
|
2651
|
+
]);
|
|
2652
|
+
const xi = x50 / LAB_X_SCALE;
|
|
2653
|
+
const yi = y50;
|
|
2654
|
+
const zi = z50 / LAB_Z_SCALE;
|
|
2655
|
+
const fx = xi > LAB_E3 ? Math.cbrt(xi) : (LAB_K * xi + 16) / 116;
|
|
2656
|
+
const fy = yi > LAB_E3 ? Math.cbrt(yi) : (LAB_K * yi + 16) / 116;
|
|
2657
|
+
const fz = zi > LAB_E3 ? Math.cbrt(zi) : (LAB_K * zi + 16) / 116;
|
|
2658
|
+
return [
|
|
2659
|
+
116 * fy - 16,
|
|
2660
|
+
500 * (fx - fy),
|
|
2661
|
+
200 * (fy - fz)
|
|
2662
|
+
];
|
|
2663
|
+
};
|
|
2664
|
+
/** D65 XYZ → OKLab via the inverted forward matrices. */
|
|
2665
|
+
const xyzD65ToOklab = (xyz) => {
|
|
2666
|
+
const lms = multiplyMatrices(XYZ_TO_LMS, xyz);
|
|
2667
|
+
const lmsCbrt = [
|
|
2668
|
+
Math.cbrt(lms[0]),
|
|
2669
|
+
Math.cbrt(lms[1]),
|
|
2670
|
+
Math.cbrt(lms[2])
|
|
2671
|
+
];
|
|
2672
|
+
return multiplyMatrices(OKLAB_FROM_LMS, lmsCbrt);
|
|
2673
|
+
};
|
|
2674
|
+
/** Lab/Oklab rectangular coordinates → polar LCH (hue in degrees). */
|
|
2675
|
+
const labToLch = (lab) => {
|
|
2676
|
+
const c = Math.hypot(lab[1], lab[2]);
|
|
2677
|
+
const h = Math.atan2(lab[2], lab[1]) * 180 / Math.PI;
|
|
2678
|
+
return [
|
|
2679
|
+
lab[0],
|
|
2680
|
+
c,
|
|
2681
|
+
(h + 360) % 360
|
|
2682
|
+
];
|
|
2683
|
+
};
|
|
2684
|
+
/** Gamma sRGB (0..1) → HSL with hue in turns (0..1), matching hsl2rgb input. */
|
|
2685
|
+
const rgbToHslTurns = (rgb) => {
|
|
2686
|
+
const r = rgb[0], g = rgb[1], b = rgb[2];
|
|
2687
|
+
const max = Math.max(r, g, b);
|
|
2688
|
+
const min = Math.min(r, g, b);
|
|
2689
|
+
const l = (max + min) / 2;
|
|
2690
|
+
if (max === min) return [
|
|
2691
|
+
0,
|
|
2692
|
+
0,
|
|
2693
|
+
l
|
|
2694
|
+
];
|
|
2695
|
+
const d = max - min;
|
|
2696
|
+
const s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
2697
|
+
let h;
|
|
2698
|
+
if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
2699
|
+
else if (max === g) h = ((b - r) / d + 2) / 6;
|
|
2700
|
+
else h = ((r - g) / d + 4) / 6;
|
|
2701
|
+
return [
|
|
2702
|
+
h,
|
|
2703
|
+
s,
|
|
2704
|
+
l
|
|
2705
|
+
];
|
|
2706
|
+
};
|
|
2707
|
+
/** Packed color → coordinates in the given space, alpha kept on a 0..1 scale. */
|
|
2708
|
+
const toCoords = (color, space) => {
|
|
2709
|
+
const a = (255 & color) / 255;
|
|
2710
|
+
const rgb = unpackSrgb(color);
|
|
2711
|
+
const linear = rgb2rgbLinear(rgb);
|
|
2712
|
+
const xyz = rgbLinear2xyz(linear);
|
|
2713
|
+
let coords;
|
|
2714
|
+
switch (space) {
|
|
2715
|
+
case "srgb":
|
|
2716
|
+
coords = rgb;
|
|
2717
|
+
break;
|
|
2718
|
+
case "srgb-linear":
|
|
2719
|
+
coords = linear;
|
|
2720
|
+
break;
|
|
2721
|
+
case "xyz":
|
|
2722
|
+
case "xyz-d65":
|
|
2723
|
+
coords = xyz;
|
|
2724
|
+
break;
|
|
2725
|
+
case "xyz-d50":
|
|
2726
|
+
coords = d65toD50(xyz);
|
|
2727
|
+
break;
|
|
2728
|
+
case "lab":
|
|
2729
|
+
coords = xyzD65ToLab(xyz);
|
|
2730
|
+
break;
|
|
2731
|
+
case "oklab":
|
|
2732
|
+
coords = xyzD65ToOklab(xyz);
|
|
2733
|
+
break;
|
|
2734
|
+
case "lch":
|
|
2735
|
+
coords = labToLch(xyzD65ToLab(xyz));
|
|
2736
|
+
break;
|
|
2737
|
+
case "oklch":
|
|
2738
|
+
coords = labToLch(xyzD65ToOklab(xyz));
|
|
2739
|
+
break;
|
|
2740
|
+
case "hsl": coords = [
|
|
2741
|
+
rgbToHslTurns(rgb)[0] * 360,
|
|
2742
|
+
rgbToHslTurns(rgb)[1],
|
|
2743
|
+
rgbToHslTurns(rgb)[2]
|
|
2744
|
+
];
|
|
2745
|
+
}
|
|
2746
|
+
return [
|
|
2747
|
+
coords[0],
|
|
2748
|
+
coords[1],
|
|
2749
|
+
coords[2],
|
|
2750
|
+
a
|
|
2751
|
+
];
|
|
2752
|
+
};
|
|
2753
|
+
/** Coordinates in the given space → packed color. */
|
|
2754
|
+
const fromCoords = (coords, space) => {
|
|
2755
|
+
const c0 = coords[0], c1 = coords[1], c2 = coords[2], a = coords[3];
|
|
2756
|
+
switch (space) {
|
|
2757
|
+
case "srgb": return packSrgb([
|
|
2758
|
+
c0,
|
|
2759
|
+
c1,
|
|
2760
|
+
c2,
|
|
2761
|
+
a
|
|
2762
|
+
]);
|
|
2763
|
+
case "srgb-linear": return packSrgbLinear([
|
|
2764
|
+
c0,
|
|
2765
|
+
c1,
|
|
2766
|
+
c2,
|
|
2767
|
+
a
|
|
2768
|
+
]);
|
|
2769
|
+
case "xyz":
|
|
2770
|
+
case "xyz-d65": return packXYZ([
|
|
2771
|
+
c0,
|
|
2772
|
+
c1,
|
|
2773
|
+
c2,
|
|
2774
|
+
a
|
|
2775
|
+
]);
|
|
2776
|
+
case "xyz-d50": return packXYZ([...d50toD65([
|
|
2777
|
+
c0,
|
|
2778
|
+
c1,
|
|
2779
|
+
c2
|
|
2780
|
+
]), a]);
|
|
2781
|
+
case "lab": return packViaXyz(lab2xyz([
|
|
2782
|
+
c0,
|
|
2783
|
+
c1,
|
|
2784
|
+
c2
|
|
2785
|
+
]), a);
|
|
2786
|
+
case "oklab": return packViaXyz(oklab2xyz([
|
|
2787
|
+
c0,
|
|
2788
|
+
c1,
|
|
2789
|
+
c2
|
|
2790
|
+
]), a);
|
|
2791
|
+
case "lch": return packViaXyz(lab2xyz(lch2lab([
|
|
2792
|
+
c0,
|
|
2793
|
+
c1,
|
|
2794
|
+
c2
|
|
2795
|
+
])), a);
|
|
2796
|
+
case "oklch": return packViaXyz(oklab2xyz(lch2lab([
|
|
2797
|
+
c0,
|
|
2798
|
+
c1,
|
|
2799
|
+
c2
|
|
2800
|
+
])), a);
|
|
2801
|
+
case "hsl": {
|
|
2802
|
+
const rgb = hsl2rgb([
|
|
2803
|
+
c0 / 360,
|
|
2804
|
+
c1,
|
|
2805
|
+
c2
|
|
2806
|
+
]);
|
|
2807
|
+
return packSrgb([
|
|
2808
|
+
rgb[0],
|
|
2809
|
+
rgb[1],
|
|
2810
|
+
rgb[2],
|
|
2811
|
+
a
|
|
2812
|
+
]);
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
};
|
|
2816
|
+
const packViaXyz = (xyz, a) => {
|
|
2817
|
+
const rgb = srgbLinear2rgb(xyz2rgbLinear(xyz));
|
|
2818
|
+
return packSrgb([
|
|
2819
|
+
rgb[0],
|
|
2820
|
+
rgb[1],
|
|
2821
|
+
rgb[2],
|
|
2822
|
+
a
|
|
2823
|
+
]);
|
|
2824
|
+
};
|
|
2825
|
+
/**
|
|
2826
|
+
* Interpolate a hue angle in degrees per css-color-4 §12.4. `weight1` and
|
|
2827
|
+
* `weight2` are the (normalized) mix weights; the hue travels from h1 towards
|
|
2828
|
+
* h2 by the shared fraction. Exported for unit tests.
|
|
2829
|
+
*/
|
|
2830
|
+
const interpolateHue = (h1, h2, weight1, weight2, method = "shorter") => {
|
|
2831
|
+
const wSum = weight1 + weight2;
|
|
2832
|
+
if (wSum === 0) return h1;
|
|
2833
|
+
let d = ((h2 - h1) % 360 + 360) % 360;
|
|
2834
|
+
switch (method) {
|
|
2835
|
+
case "shorter":
|
|
2836
|
+
if (d > 180) d -= 360;
|
|
2837
|
+
break;
|
|
2838
|
+
case "longer":
|
|
2839
|
+
if (d < 180) d -= 360;
|
|
2840
|
+
break;
|
|
2841
|
+
case "increasing": break;
|
|
2842
|
+
case "decreasing": if (d > 0) d -= 360;
|
|
2843
|
+
}
|
|
2844
|
+
return h1 + d * (weight2 / wSum);
|
|
2845
|
+
};
|
|
2846
|
+
const parseMixComponent = (context, tokens) => {
|
|
2847
|
+
let colorToken;
|
|
2848
|
+
let percentage = null;
|
|
2849
|
+
for (const token of tokens) {
|
|
2850
|
+
if (token.type === 31 || token.type === 4) continue;
|
|
2851
|
+
if (token.type === 16) percentage = token.number;
|
|
2852
|
+
else if (isIdentToken(token) && token.value === "none") {
|
|
2853
|
+
if (percentage === null) percentage = 0;
|
|
2854
|
+
} else if (colorToken === void 0) colorToken = token;
|
|
2855
|
+
else throw new Error(`Unexpected token in color-mix() component`);
|
|
2856
|
+
}
|
|
2857
|
+
if (colorToken === void 0) throw new Error("color-mix() component is missing a color");
|
|
2858
|
+
const token = colorToken;
|
|
2859
|
+
return {
|
|
2860
|
+
color: color$1.parse(context, token),
|
|
2861
|
+
percentage
|
|
2862
|
+
};
|
|
2863
|
+
};
|
|
2864
|
+
const SUPPORTED_SPACES = [
|
|
2865
|
+
"srgb",
|
|
2866
|
+
"srgb-linear",
|
|
2867
|
+
"lab",
|
|
2868
|
+
"oklab",
|
|
2869
|
+
"lch",
|
|
2870
|
+
"oklch",
|
|
2871
|
+
"hsl",
|
|
2872
|
+
"xyz",
|
|
2873
|
+
"xyz-d50",
|
|
2874
|
+
"xyz-d65"
|
|
2875
|
+
];
|
|
2876
|
+
const mixCoords = (c1, c2, w1, w2, space, hueMethod) => {
|
|
2877
|
+
const hueIdx = HUE_DEG_INDEX[space];
|
|
2878
|
+
const p1 = [
|
|
2879
|
+
c1[0] * c1[3],
|
|
2880
|
+
c1[1] * c1[3],
|
|
2881
|
+
c1[2] * c1[3],
|
|
2882
|
+
c1[3]
|
|
2883
|
+
];
|
|
2884
|
+
const p2 = [
|
|
2885
|
+
c2[0] * c2[3],
|
|
2886
|
+
c2[1] * c2[3],
|
|
2887
|
+
c2[2] * c2[3],
|
|
2888
|
+
c2[3]
|
|
2889
|
+
];
|
|
2890
|
+
const alpha = w1 * p1[3] + w2 * p2[3];
|
|
2891
|
+
if (alpha <= 0) return [
|
|
2892
|
+
0,
|
|
2893
|
+
0,
|
|
2894
|
+
0,
|
|
2895
|
+
0
|
|
2896
|
+
];
|
|
2897
|
+
const out = [
|
|
2898
|
+
0,
|
|
2899
|
+
0,
|
|
2900
|
+
0,
|
|
2901
|
+
alpha
|
|
2902
|
+
];
|
|
2903
|
+
for (let i = 0; i < 3; i++) {
|
|
2904
|
+
if (i === hueIdx) continue;
|
|
2905
|
+
out[i] = (w1 * at(p1, i) + w2 * at(p2, i)) / alpha;
|
|
2906
|
+
}
|
|
2907
|
+
if (hueIdx !== void 0) {
|
|
2908
|
+
let h1 = at(c1, hueIdx);
|
|
2909
|
+
let h2 = at(c2, hueIdx);
|
|
2910
|
+
if (c1[1] === 0) h1 = h2;
|
|
2911
|
+
if (c2[1] === 0) h2 = h1;
|
|
2912
|
+
out[hueIdx] = interpolateHue(h1, h2, w1, w2, hueMethod);
|
|
2913
|
+
}
|
|
2914
|
+
return out;
|
|
2915
|
+
};
|
|
2916
|
+
const computeColorMix = (context, args) => {
|
|
2917
|
+
const groups = [[]];
|
|
2918
|
+
for (const token of args) if (token.type === 4) groups.push([]);
|
|
2919
|
+
else groups[groups.length - 1].push(token);
|
|
2920
|
+
const meaningful = groups.map((group) => group.filter((t) => t.type !== 31));
|
|
2921
|
+
if (meaningful.length !== 3) throw new Error("color-mix() requires exactly two color components");
|
|
2922
|
+
const header = meaningful[0];
|
|
2923
|
+
const inKeyword = header ? header[0] : void 0;
|
|
2924
|
+
const hasInKeyword = inKeyword !== void 0 && isIdentToken(inKeyword) && inKeyword.value === "in";
|
|
2925
|
+
if (!header || header.length < 2 || !hasInKeyword) throw new Error("color-mix() requires an interpolation space after `in`");
|
|
2926
|
+
const spaceIdent = header[1];
|
|
2927
|
+
if (!spaceIdent || !isIdentToken(spaceIdent)) throw new Error("color-mix() space must be an identifier");
|
|
2928
|
+
const space = spaceIdent.value;
|
|
2929
|
+
if (SUPPORTED_SPACES.indexOf(space) === -1) throw new Error(`Unsupported color-mix() interpolation space "${space}"`);
|
|
2930
|
+
let hueMethod = "shorter";
|
|
2931
|
+
const rest = header.slice(2);
|
|
2932
|
+
if (rest.length > 0) {
|
|
2933
|
+
const method = rest[0];
|
|
2934
|
+
const hueKeyword = rest[1];
|
|
2935
|
+
if (!method || !hueKeyword || !isIdentToken(method) || !isIdentToken(hueKeyword) || hueKeyword.value !== "hue") throw new Error("Unsupported color-mix() hue method syntax");
|
|
2936
|
+
if ([
|
|
2937
|
+
"shorter",
|
|
2938
|
+
"longer",
|
|
2939
|
+
"increasing",
|
|
2940
|
+
"decreasing"
|
|
2941
|
+
].indexOf(method.value) === -1) throw new Error(`Unsupported color-mix() hue method "${method.value}"`);
|
|
2942
|
+
hueMethod = method.value;
|
|
2943
|
+
}
|
|
2944
|
+
const group1 = meaningful[1];
|
|
2945
|
+
const group2 = meaningful[2];
|
|
2946
|
+
if (!group1 || !group2) throw new Error("color-mix() requires exactly two color components");
|
|
2947
|
+
const component1 = parseMixComponent(context, group1);
|
|
2948
|
+
const component2 = parseMixComponent(context, group2);
|
|
2949
|
+
let p1 = component1.percentage;
|
|
2950
|
+
let p2 = component2.percentage;
|
|
2951
|
+
if (p1 === null && p2 === null) {
|
|
2952
|
+
p1 = 50;
|
|
2953
|
+
p2 = 50;
|
|
2954
|
+
} else if (p1 === null) p1 = 100 - (p2 ?? 0);
|
|
2955
|
+
else if (p2 === null) p2 = 100 - p1;
|
|
2956
|
+
else {
|
|
2957
|
+
const sum = p1 + p2;
|
|
2958
|
+
if (sum > 0) {
|
|
2959
|
+
p1 = p1 / sum * 100;
|
|
2960
|
+
p2 = p2 / sum * 100;
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
const weight1 = (p1 ?? 0) / 100;
|
|
2964
|
+
const weight2 = (p2 ?? 0) / 100;
|
|
2965
|
+
const mixed = mixCoords(toCoords(component1.color, space), toCoords(component2.color, space), weight1, weight2, space, hueMethod);
|
|
2966
|
+
return fromCoords(mixed, space);
|
|
2967
|
+
};
|
|
2968
|
+
const colorMix = (context, args) => {
|
|
2969
|
+
try {
|
|
2970
|
+
return computeColorMix(context, args);
|
|
2971
|
+
} catch (e) {
|
|
2972
|
+
context.logger.warn(`Unsupported color-mix() value: ${e instanceof Error ? e.message : e}`);
|
|
2973
|
+
return 0;
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
//#endregion
|
|
3078
2977
|
//#region src/css/types/color.ts
|
|
3079
2978
|
const color$1 = {
|
|
3080
2979
|
name: "color",
|
|
@@ -3324,7 +3223,8 @@ const SUPPORTED_COLOR_FUNCTIONS = {
|
|
|
3324
3223
|
oklch: packOkLch,
|
|
3325
3224
|
oklab: packOkLab,
|
|
3326
3225
|
lab: packLab,
|
|
3327
|
-
color: _color
|
|
3226
|
+
color: _color,
|
|
3227
|
+
"color-mix": colorMix
|
|
3328
3228
|
};
|
|
3329
3229
|
const parseColor = (context, value) => color$1.parse(context, Parser.create(value).parseComponentValue());
|
|
3330
3230
|
const COLORS = {
|
|
@@ -3607,9 +3507,7 @@ const contains = (bit, value) => (bit & value) !== 0;
|
|
|
3607
3507
|
//#endregion
|
|
3608
3508
|
//#region src/css/types/functions/counter.ts
|
|
3609
3509
|
var CounterState = class {
|
|
3610
|
-
|
|
3611
|
-
this.counters = {};
|
|
3612
|
-
}
|
|
3510
|
+
counters = {};
|
|
3613
3511
|
getCounterValue(name) {
|
|
3614
3512
|
const counter = this.counters[name];
|
|
3615
3513
|
if (counter && counter.length) return at(counter, counter.length - 1);
|
|
@@ -3936,7 +3834,7 @@ const createCounterStyleWithSymbolResolver = (value, codePointRangeLength, isNum
|
|
|
3936
3834
|
};
|
|
3937
3835
|
const createCounterStyleFromRange = (value, codePointRangeStart, codePointRangeEnd, isNumeric, suffix) => {
|
|
3938
3836
|
const codePointRangeLength = codePointRangeEnd - codePointRangeStart + 1;
|
|
3939
|
-
return (value < 0 ? "-" : "") + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, (codePoint) => fromCodePoint
|
|
3837
|
+
return (value < 0 ? "-" : "") + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, (codePoint) => String.fromCodePoint(Math.floor(codePoint % codePointRangeLength) + codePointRangeStart)) + suffix);
|
|
3940
3838
|
};
|
|
3941
3839
|
const createCounterStyleFromSymbols = (value, symbols, suffix = ". ") => {
|
|
3942
3840
|
const codePointRangeLength = symbols.length;
|
|
@@ -4521,7 +4419,7 @@ const ELLIPSE = "ellipse";
|
|
|
4521
4419
|
const COVER = "cover";
|
|
4522
4420
|
const CONTAIN = "contain";
|
|
4523
4421
|
const radialGradient = (context, tokens) => {
|
|
4524
|
-
let shape =
|
|
4422
|
+
let shape = 1;
|
|
4525
4423
|
let size = 3;
|
|
4526
4424
|
const stops = [];
|
|
4527
4425
|
const position = [];
|
|
@@ -4594,7 +4492,7 @@ const radialGradient = (context, tokens) => {
|
|
|
4594
4492
|
//#endregion
|
|
4595
4493
|
//#region src/css/types/functions/-prefix-radial-gradient.ts
|
|
4596
4494
|
const prefixRadialGradient = (context, tokens) => {
|
|
4597
|
-
let shape =
|
|
4495
|
+
let shape = 1;
|
|
4598
4496
|
let size = 3;
|
|
4599
4497
|
const stops = [];
|
|
4600
4498
|
const position = [];
|
|
@@ -5987,28 +5885,37 @@ const filter = {
|
|
|
5987
5885
|
if (first.type === 20 && first.value === "none") return null;
|
|
5988
5886
|
}
|
|
5989
5887
|
const parts = [];
|
|
5990
|
-
for (const token of tokens)
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
5888
|
+
for (const token of tokens) {
|
|
5889
|
+
if (token.type === 22) {
|
|
5890
|
+
parts.push(`url("${token.value}")`);
|
|
5891
|
+
continue;
|
|
5892
|
+
}
|
|
5893
|
+
if (token.type === 18) {
|
|
5894
|
+
const fn = token;
|
|
5895
|
+
const renderedArgs = renderFilterArgs(fn.values);
|
|
5896
|
+
switch (fn.name) {
|
|
5897
|
+
case "blur":
|
|
5898
|
+
parts.push(`blur(${renderedArgs})`);
|
|
5899
|
+
break;
|
|
5900
|
+
case "brightness":
|
|
5901
|
+
case "contrast":
|
|
5902
|
+
case "invert":
|
|
5903
|
+
case "opacity":
|
|
5904
|
+
case "saturate":
|
|
5905
|
+
case "sepia":
|
|
5906
|
+
parts.push(`${fn.name}(${renderedArgs})`);
|
|
5907
|
+
break;
|
|
5908
|
+
case "grayscale":
|
|
5909
|
+
parts.push(`grayscale(${renderedArgs})`);
|
|
5910
|
+
break;
|
|
5911
|
+
case "hue-rotate":
|
|
5912
|
+
parts.push(`hue-rotate(${renderedArgs})`);
|
|
5913
|
+
break;
|
|
5914
|
+
case "drop-shadow":
|
|
5915
|
+
parts.push(`drop-shadow(${renderedArgs})`);
|
|
5916
|
+
break;
|
|
5917
|
+
default: parts.push(`${fn.name}(${renderedArgs})`);
|
|
5918
|
+
}
|
|
6012
5919
|
}
|
|
6013
5920
|
}
|
|
6014
5921
|
return parts.length > 0 ? parts.join(" ") : null;
|
|
@@ -6577,8 +6484,47 @@ const webkitBoxReflect = {
|
|
|
6577
6484
|
};
|
|
6578
6485
|
}
|
|
6579
6486
|
};
|
|
6487
|
+
//#endregion
|
|
6488
|
+
//#region src/css/property-descriptors/translate.ts
|
|
6489
|
+
const translate = {
|
|
6490
|
+
name: "translate",
|
|
6491
|
+
initialValue: "none",
|
|
6492
|
+
prefix: false,
|
|
6493
|
+
type: 1,
|
|
6494
|
+
parse: (_context, tokens) => {
|
|
6495
|
+
const values = [];
|
|
6496
|
+
for (const token of tokens) if (isLengthPercentage(token)) values.push(token);
|
|
6497
|
+
if (values.length === 0) return null;
|
|
6498
|
+
return [at(values, 0), values.length > 1 ? at(values, 1) : ZERO_LENGTH];
|
|
6499
|
+
}
|
|
6500
|
+
};
|
|
6501
|
+
//#endregion
|
|
6502
|
+
//#region src/css/property-descriptors/scale.ts
|
|
6503
|
+
const scale = {
|
|
6504
|
+
name: "scale",
|
|
6505
|
+
initialValue: "none",
|
|
6506
|
+
prefix: false,
|
|
6507
|
+
type: 1,
|
|
6508
|
+
parse: (_context, tokens) => {
|
|
6509
|
+
const numbers = [];
|
|
6510
|
+
for (const token of tokens) if (isNumberToken(token)) numbers.push(token.number);
|
|
6511
|
+
if (numbers.length === 0) return null;
|
|
6512
|
+
return [at(numbers, 0), numbers.length > 1 ? at(numbers, 1) : at(numbers, 0)];
|
|
6513
|
+
}
|
|
6514
|
+
};
|
|
6580
6515
|
/** Z-axis mask offset used during box-shadow rendering. */
|
|
6581
6516
|
const SHADOW_MASK_OFFSET = 1e4;
|
|
6517
|
+
/**
|
|
6518
|
+
* Total time (ms) to wait for the cloned iframe document to become ready
|
|
6519
|
+
* after its load event. A missed deadline resolves with a warning (the
|
|
6520
|
+
* capture continues with a possibly incomplete document).
|
|
6521
|
+
*/
|
|
6522
|
+
const CLONE_READY_TIMEOUT_MS = 3e4;
|
|
6523
|
+
/**
|
|
6524
|
+
* Hard ceiling (ms) for the cloned iframe's load event itself. If the event
|
|
6525
|
+
* never fires, the mount is rejected instead of hanging forever.
|
|
6526
|
+
*/
|
|
6527
|
+
const IFRAME_LOAD_WATCHDOG_MS = 6e4;
|
|
6582
6528
|
//#endregion
|
|
6583
6529
|
//#region src/css/parse.ts
|
|
6584
6530
|
const STANDARD_PROPERTIES = [
|
|
@@ -6892,6 +6838,16 @@ const STANDARD_PROPERTIES = [
|
|
|
6892
6838
|
rotate,
|
|
6893
6839
|
"rotate"
|
|
6894
6840
|
],
|
|
6841
|
+
[
|
|
6842
|
+
"translate",
|
|
6843
|
+
translate,
|
|
6844
|
+
"translate"
|
|
6845
|
+
],
|
|
6846
|
+
[
|
|
6847
|
+
"scale",
|
|
6848
|
+
scale,
|
|
6849
|
+
"scale"
|
|
6850
|
+
],
|
|
6895
6851
|
[
|
|
6896
6852
|
"visibility",
|
|
6897
6853
|
visibility,
|
|
@@ -7143,10 +7099,15 @@ const parse = (context, descriptor, style) => {
|
|
|
7143
7099
|
/**
|
|
7144
7100
|
* Read-only grouped accessor for border-related CSS properties.
|
|
7145
7101
|
*
|
|
7102
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7103
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7104
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7105
|
+
*
|
|
7146
7106
|
* Provides structured access: `styles.border.topColor` as an alternative
|
|
7147
7107
|
* to the flat `styles.borderTopColor`. Both forms remain valid.
|
|
7148
7108
|
*/
|
|
7149
7109
|
var BorderStyles = class {
|
|
7110
|
+
styles;
|
|
7150
7111
|
constructor(styles) {
|
|
7151
7112
|
this.styles = styles;
|
|
7152
7113
|
}
|
|
@@ -7215,8 +7176,13 @@ var BorderStyles = class {
|
|
|
7215
7176
|
//#region src/css/grouped/background-styles.ts
|
|
7216
7177
|
/**
|
|
7217
7178
|
* Read-only grouped accessor for background-related CSS properties.
|
|
7179
|
+
*
|
|
7180
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7181
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7182
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7218
7183
|
*/
|
|
7219
7184
|
var BackgroundStyles = class {
|
|
7185
|
+
styles;
|
|
7220
7186
|
constructor(styles) {
|
|
7221
7187
|
this.styles = styles;
|
|
7222
7188
|
}
|
|
@@ -7249,8 +7215,13 @@ var BackgroundStyles = class {
|
|
|
7249
7215
|
//#region src/css/grouped/font-styles.ts
|
|
7250
7216
|
/**
|
|
7251
7217
|
* Read-only grouped accessor for font/text-related CSS properties.
|
|
7218
|
+
*
|
|
7219
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7220
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7221
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7252
7222
|
*/
|
|
7253
7223
|
var FontStyles = class {
|
|
7224
|
+
styles;
|
|
7254
7225
|
constructor(styles) {
|
|
7255
7226
|
this.styles = styles;
|
|
7256
7227
|
}
|
|
@@ -7340,8 +7311,13 @@ var FontStyles = class {
|
|
|
7340
7311
|
//#region src/css/grouped/layout-styles.ts
|
|
7341
7312
|
/**
|
|
7342
7313
|
* Read-only grouped accessor for layout/display/positioning CSS properties.
|
|
7314
|
+
*
|
|
7315
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7316
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7317
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7343
7318
|
*/
|
|
7344
7319
|
var LayoutStyles = class {
|
|
7320
|
+
styles;
|
|
7345
7321
|
constructor(styles) {
|
|
7346
7322
|
this.styles = styles;
|
|
7347
7323
|
}
|
|
@@ -7463,6 +7439,117 @@ var LayoutStyles = class {
|
|
|
7463
7439
|
//#endregion
|
|
7464
7440
|
//#region src/css/index.ts
|
|
7465
7441
|
var CSSParsedDeclaration = class {
|
|
7442
|
+
animationDuration;
|
|
7443
|
+
backgroundClip;
|
|
7444
|
+
backgroundColor;
|
|
7445
|
+
backgroundImage;
|
|
7446
|
+
backgroundOrigin;
|
|
7447
|
+
backgroundPosition;
|
|
7448
|
+
backgroundRepeat;
|
|
7449
|
+
backgroundSize;
|
|
7450
|
+
borderTopColor;
|
|
7451
|
+
borderRightColor;
|
|
7452
|
+
borderBottomColor;
|
|
7453
|
+
borderLeftColor;
|
|
7454
|
+
borderTopLeftRadius;
|
|
7455
|
+
borderTopRightRadius;
|
|
7456
|
+
borderBottomRightRadius;
|
|
7457
|
+
borderBottomLeftRadius;
|
|
7458
|
+
borderTopStyle;
|
|
7459
|
+
borderRightStyle;
|
|
7460
|
+
borderBottomStyle;
|
|
7461
|
+
borderLeftStyle;
|
|
7462
|
+
borderTopWidth;
|
|
7463
|
+
borderRightWidth;
|
|
7464
|
+
borderBottomWidth;
|
|
7465
|
+
borderLeftWidth;
|
|
7466
|
+
boxShadow;
|
|
7467
|
+
clipPath;
|
|
7468
|
+
color;
|
|
7469
|
+
direction;
|
|
7470
|
+
display;
|
|
7471
|
+
float;
|
|
7472
|
+
fontFamily;
|
|
7473
|
+
fontSize;
|
|
7474
|
+
fontStyle;
|
|
7475
|
+
fontVariant;
|
|
7476
|
+
fontWeight;
|
|
7477
|
+
letterSpacing;
|
|
7478
|
+
lineBreak;
|
|
7479
|
+
lineHeight;
|
|
7480
|
+
listStyleImage;
|
|
7481
|
+
listStylePosition;
|
|
7482
|
+
listStyleType;
|
|
7483
|
+
marginTop;
|
|
7484
|
+
marginRight;
|
|
7485
|
+
marginBottom;
|
|
7486
|
+
marginLeft;
|
|
7487
|
+
opacity;
|
|
7488
|
+
overflowX;
|
|
7489
|
+
overflowY;
|
|
7490
|
+
overflowWrap;
|
|
7491
|
+
paddingTop;
|
|
7492
|
+
paddingRight;
|
|
7493
|
+
paddingBottom;
|
|
7494
|
+
paddingLeft;
|
|
7495
|
+
paintOrder;
|
|
7496
|
+
position;
|
|
7497
|
+
textAlign;
|
|
7498
|
+
textDecorationColor;
|
|
7499
|
+
textDecorationLine;
|
|
7500
|
+
textDecorationStyle;
|
|
7501
|
+
textDecorationThickness;
|
|
7502
|
+
textUnderlineOffset;
|
|
7503
|
+
textShadow;
|
|
7504
|
+
textTransform;
|
|
7505
|
+
textOverflow;
|
|
7506
|
+
transform;
|
|
7507
|
+
transformOrigin;
|
|
7508
|
+
rotate;
|
|
7509
|
+
translate;
|
|
7510
|
+
scale;
|
|
7511
|
+
visibility;
|
|
7512
|
+
webkitTextStrokeColor;
|
|
7513
|
+
webkitTextStrokeWidth;
|
|
7514
|
+
webkitLineClamp;
|
|
7515
|
+
wordBreak;
|
|
7516
|
+
whiteSpace;
|
|
7517
|
+
writingMode;
|
|
7518
|
+
zIndex;
|
|
7519
|
+
objectFit;
|
|
7520
|
+
imageRendering;
|
|
7521
|
+
mixBlendMode;
|
|
7522
|
+
filter;
|
|
7523
|
+
fontVariantLigatures;
|
|
7524
|
+
zoom;
|
|
7525
|
+
objectPosition;
|
|
7526
|
+
backgroundBlendMode;
|
|
7527
|
+
borderImageSource;
|
|
7528
|
+
borderImageSlice;
|
|
7529
|
+
borderImageRepeat;
|
|
7530
|
+
boxDecorationBreak;
|
|
7531
|
+
accentColor;
|
|
7532
|
+
webkitTextFillColor;
|
|
7533
|
+
isolation;
|
|
7534
|
+
outlineColor;
|
|
7535
|
+
outlineStyle;
|
|
7536
|
+
outlineWidth;
|
|
7537
|
+
outlineOffset;
|
|
7538
|
+
backdropFilter;
|
|
7539
|
+
maskImage;
|
|
7540
|
+
maskPosition;
|
|
7541
|
+
maskRepeat;
|
|
7542
|
+
maskSize;
|
|
7543
|
+
textEmphasisStyle;
|
|
7544
|
+
textEmphasisColor;
|
|
7545
|
+
textEmphasisPosition;
|
|
7546
|
+
borderImageWidth;
|
|
7547
|
+
borderImageOutset;
|
|
7548
|
+
webkitBoxReflect;
|
|
7549
|
+
_border;
|
|
7550
|
+
_background;
|
|
7551
|
+
_font;
|
|
7552
|
+
_layout;
|
|
7466
7553
|
get border() {
|
|
7467
7554
|
return this._border ?? (this._border = new BorderStyles(this));
|
|
7468
7555
|
}
|
|
@@ -7492,7 +7579,7 @@ var CSSParsedDeclaration = class {
|
|
|
7492
7579
|
return isTransparent(this.backgroundColor);
|
|
7493
7580
|
}
|
|
7494
7581
|
isTransformed() {
|
|
7495
|
-
return this.transform !== null || this.rotate !== null;
|
|
7582
|
+
return this.transform !== null || this.rotate !== null || this.translate !== null || this.scale !== null;
|
|
7496
7583
|
}
|
|
7497
7584
|
isPositioned() {
|
|
7498
7585
|
return this.position !== 0;
|
|
@@ -7527,12 +7614,16 @@ const parseSpecialDeclarations = (context, declaration) => {
|
|
|
7527
7614
|
};
|
|
7528
7615
|
};
|
|
7529
7616
|
var CSSParsedPseudoDeclaration = class {
|
|
7617
|
+
content;
|
|
7618
|
+
quotes;
|
|
7530
7619
|
constructor(context, declaration) {
|
|
7531
7620
|
this.content = parse(context, content, declaration.content);
|
|
7532
7621
|
this.quotes = parse(context, quotes, declaration.quotes);
|
|
7533
7622
|
}
|
|
7534
7623
|
};
|
|
7535
7624
|
var CSSParsedCounterDeclaration = class {
|
|
7625
|
+
counterIncrement;
|
|
7626
|
+
counterReset;
|
|
7536
7627
|
constructor(context, declaration) {
|
|
7537
7628
|
this.counterIncrement = parse(context, counterIncrement, declaration.counterIncrement);
|
|
7538
7629
|
this.counterReset = parse(context, counterReset, declaration.counterReset);
|
|
@@ -7556,6 +7647,48 @@ const isDebugging = (element, type) => {
|
|
|
7556
7647
|
return elementType === 1 || type === elementType;
|
|
7557
7648
|
};
|
|
7558
7649
|
//#endregion
|
|
7650
|
+
//#region src/dom/adopted-styles.ts
|
|
7651
|
+
/**
|
|
7652
|
+
* Constructable stylesheet cloning (adoptedStyleSheets).
|
|
7653
|
+
*
|
|
7654
|
+
* `adoptedStyleSheets` on a Document or ShadowRoot is the standard way Lit,
|
|
7655
|
+
* React and other frameworks inject component styles, but the sheets are not
|
|
7656
|
+
* part of the node tree — cloneNode never carries them. A shadow root that
|
|
7657
|
+
* relies on adopted sheets (and whose computed styles are not inlined per
|
|
7658
|
+
* element, i.e. copyStyles is false) would otherwise lose those rules in the
|
|
7659
|
+
* clone. The rules are re-materialised as a regular <style> element, which
|
|
7660
|
+
* also cascades last like the spec treats adopted sheets.
|
|
7661
|
+
*/
|
|
7662
|
+
/**
|
|
7663
|
+
* Serialize the CSS rules of the given sheets into one stylesheet string.
|
|
7664
|
+
* Sheets that cannot be read (e.g. detached) are skipped rather than failing
|
|
7665
|
+
* the render.
|
|
7666
|
+
*/
|
|
7667
|
+
const serializeStyleSheetRules = (sheets) => {
|
|
7668
|
+
let css = "";
|
|
7669
|
+
for (const sheet of sheets) try {
|
|
7670
|
+
const rules = sheet.cssRules;
|
|
7671
|
+
for (let i = 0; i < rules.length; i++) {
|
|
7672
|
+
const rule = rules[i];
|
|
7673
|
+
if (rule && typeof rule.cssText === "string") css += rule.cssText;
|
|
7674
|
+
}
|
|
7675
|
+
} catch (e) {}
|
|
7676
|
+
return css;
|
|
7677
|
+
};
|
|
7678
|
+
/**
|
|
7679
|
+
* Build a <style> element carrying the rules of the given adopted sheets, or
|
|
7680
|
+
* null when there is nothing to clone. `styleDocument` must be the document
|
|
7681
|
+
* the clone lives in.
|
|
7682
|
+
*/
|
|
7683
|
+
const createAdoptedStylesElement = (styleDocument, sheets, nonce) => {
|
|
7684
|
+
const css = serializeStyleSheetRules(sheets);
|
|
7685
|
+
if (!css) return null;
|
|
7686
|
+
const style = styleDocument.createElement("style");
|
|
7687
|
+
style.textContent = css;
|
|
7688
|
+
if (nonce) style.nonce = nonce;
|
|
7689
|
+
return style;
|
|
7690
|
+
};
|
|
7691
|
+
//#endregion
|
|
7559
7692
|
//#region src/dom/slot-cloner.ts
|
|
7560
7693
|
/** Exported for reuse in document-cloner.ts */
|
|
7561
7694
|
const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
|
|
@@ -7564,6 +7697,9 @@ const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
|
|
|
7564
7697
|
* Extracted from DocumentCloner to reduce file size and improve separation of concerns.
|
|
7565
7698
|
*/
|
|
7566
7699
|
var SlotCloner = class {
|
|
7700
|
+
cloneNodeFn;
|
|
7701
|
+
options;
|
|
7702
|
+
context;
|
|
7567
7703
|
constructor(cloneNodeFn, options, context) {
|
|
7568
7704
|
this.cloneNodeFn = cloneNodeFn;
|
|
7569
7705
|
this.options = options;
|
|
@@ -7642,6 +7778,7 @@ var SlotCloner = class {
|
|
|
7642
7778
|
cloneShadowDOMChildren(shadowRoot, targetShadowRoot, copyStyles) {
|
|
7643
7779
|
for (let child = shadowRoot.firstChild; child; child = child.nextSibling) if (isElementNode(child) && isSlotElement(child)) this.cloneSlotElement(child, targetShadowRoot, copyStyles);
|
|
7644
7780
|
else this.safeAppendClonedChild(targetShadowRoot, child, copyStyles);
|
|
7781
|
+
this.appendAdoptedStyleSheets(shadowRoot, targetShadowRoot, copyStyles);
|
|
7645
7782
|
}
|
|
7646
7783
|
/**
|
|
7647
7784
|
* Clone light DOM children to the target element.
|
|
@@ -7670,6 +7807,23 @@ var SlotCloner = class {
|
|
|
7670
7807
|
cloneShadowDOMAsLightDOM(shadowRoot, clone, copyStyles) {
|
|
7671
7808
|
for (let child = shadowRoot.firstChild; child; child = child.nextSibling) if (isElementNode(child) && isSlotElement(child)) this.cloneSlotElementAsLightDOM(child, clone, copyStyles);
|
|
7672
7809
|
else this.appendChildNode(clone, child, copyStyles);
|
|
7810
|
+
this.appendAdoptedStyleSheets(shadowRoot, clone, copyStyles);
|
|
7811
|
+
}
|
|
7812
|
+
/**
|
|
7813
|
+
* Re-materialise the shadow root's constructable stylesheets (adoptedStyleSheets)
|
|
7814
|
+
* as a <style> element in the clone — cloneNode never carries them.
|
|
7815
|
+
*
|
|
7816
|
+
* Skipped when computed styles are inlined per element (copyStyles), mirroring
|
|
7817
|
+
* how <style> elements inside shadow roots are dropped in that mode.
|
|
7818
|
+
*/
|
|
7819
|
+
appendAdoptedStyleSheets(shadowRoot, target, copyStyles) {
|
|
7820
|
+
if (copyStyles) return;
|
|
7821
|
+
const sheets = shadowRoot.adoptedStyleSheets;
|
|
7822
|
+
if (!sheets || sheets.length === 0) return;
|
|
7823
|
+
const styleDocument = "host" in target ? target.host.ownerDocument : target.ownerDocument;
|
|
7824
|
+
if (!styleDocument) return;
|
|
7825
|
+
const style = createAdoptedStylesElement(styleDocument, sheets, this.options.cspNonce);
|
|
7826
|
+
if (style) target.appendChild(style);
|
|
7673
7827
|
}
|
|
7674
7828
|
};
|
|
7675
7829
|
//#endregion
|
|
@@ -7744,10 +7898,12 @@ const createStyles = (body, styles, cspNonce) => {
|
|
|
7744
7898
|
* pairing across the whole clone walk, shared with the cloner's counter state.
|
|
7745
7899
|
*/
|
|
7746
7900
|
var PseudoContentResolver = class {
|
|
7901
|
+
context;
|
|
7902
|
+
counters;
|
|
7903
|
+
quoteDepth = 0;
|
|
7747
7904
|
constructor(context, counters) {
|
|
7748
7905
|
this.context = context;
|
|
7749
7906
|
this.counters = counters;
|
|
7750
|
-
this.quoteDepth = 0;
|
|
7751
7907
|
}
|
|
7752
7908
|
resolvePseudoContent(node, clone, style, pseudoElt) {
|
|
7753
7909
|
if (!style) return;
|
|
@@ -7807,7 +7963,44 @@ var PseudoContentResolver = class {
|
|
|
7807
7963
|
}
|
|
7808
7964
|
};
|
|
7809
7965
|
//#endregion
|
|
7966
|
+
//#region src/core/abort-helper.ts
|
|
7967
|
+
/**
|
|
7968
|
+
* AbortSignal helper utilities.
|
|
7969
|
+
*/
|
|
7970
|
+
/**
|
|
7971
|
+
* Throw a DOMException if the given AbortSignal is already aborted.
|
|
7972
|
+
* Used at checkpoints throughout the rendering pipeline to support
|
|
7973
|
+
* cancellable renders.
|
|
7974
|
+
*
|
|
7975
|
+
* @param signal - The AbortSignal to check. If undefined or not aborted, this is a no-op.
|
|
7976
|
+
* @throws {DOMException} With name 'AbortError' if the signal has been aborted.
|
|
7977
|
+
*/
|
|
7978
|
+
const throwIfAborted = (signal) => {
|
|
7979
|
+
if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
7980
|
+
};
|
|
7981
|
+
//#endregion
|
|
7810
7982
|
//#region src/dom/iframe-mount.ts
|
|
7983
|
+
const trustedTypePolicies = /* @__PURE__ */ new WeakMap();
|
|
7984
|
+
/**
|
|
7985
|
+
* Resolve the Trusted Types policy used for writing the clone document.
|
|
7986
|
+
* Returns null when Trusted Types are unavailable or the policy could not be
|
|
7987
|
+
* created — document.write is not a Trusted Types sink, so the plain string
|
|
7988
|
+
* stays functional in both cases.
|
|
7989
|
+
* @internal – exported for testing only.
|
|
7990
|
+
*/
|
|
7991
|
+
const resolveTrustedTypesPolicy = (ownerWindow) => {
|
|
7992
|
+
const factory = ownerWindow && ownerWindow.trustedTypes;
|
|
7993
|
+
if (!factory) return null;
|
|
7994
|
+
if (trustedTypePolicies.has(factory)) return trustedTypePolicies.get(factory) ?? null;
|
|
7995
|
+
let policy = null;
|
|
7996
|
+
try {
|
|
7997
|
+
policy = factory.getPolicy?.("html2canvas-pro") ?? factory.createPolicy("html2canvas-pro", { createHTML: (s) => s });
|
|
7998
|
+
} catch (e) {
|
|
7999
|
+
policy = null;
|
|
8000
|
+
}
|
|
8001
|
+
trustedTypePolicies.set(factory, policy);
|
|
8002
|
+
return policy;
|
|
8003
|
+
};
|
|
7811
8004
|
const createIFrameContainer = (ownerDocument, bounds, customContainer) => {
|
|
7812
8005
|
const cloneIframeContainer = ownerDocument.createElement("iframe");
|
|
7813
8006
|
cloneIframeContainer.className = "html2canvas-container";
|
|
@@ -7840,29 +8033,105 @@ const imageReady = (img) => {
|
|
|
7840
8033
|
const imagesReady = (document) => {
|
|
7841
8034
|
return Promise.all([].slice.call(document.images, 0).map(imageReady));
|
|
7842
8035
|
};
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
8036
|
+
/**
|
|
8037
|
+
* Wait until every external stylesheet link of the clone has been applied or
|
|
8038
|
+
* definitively failed, or the readiness budget expires.
|
|
8039
|
+
*
|
|
8040
|
+
* The clone is mounted by adoptNode() into an already-closed document
|
|
8041
|
+
* (close() must precede adoptNode for Chrome uppercase class-name matching,
|
|
8042
|
+
* see the mount sequence below), so the cloned <link rel="stylesheet">
|
|
8043
|
+
* elements are inserted after the document finished loading: they neither
|
|
8044
|
+
* delay the iframe load event nor change readyState, and the iframeLoader
|
|
8045
|
+
* readiness poll cannot observe them. On a cold cache the first capture
|
|
8046
|
+
* could then measure the clone before its external CSS arrived and render
|
|
8047
|
+
* an unstyled layout (issue #245). Inline <style> clones apply
|
|
8048
|
+
* synchronously and document-level adopted stylesheets are serialised at
|
|
8049
|
+
* clone time, so neither needs this wait.
|
|
8050
|
+
* @internal – exported for testing only.
|
|
8051
|
+
*/
|
|
8052
|
+
const stylesheetsReady = (documentClone, logger, signal) => {
|
|
8053
|
+
if (signal?.aborted) return Promise.resolve();
|
|
8054
|
+
const pending = [];
|
|
8055
|
+
const links = documentClone.getElementsByTagName("link");
|
|
8056
|
+
for (let i = 0; i < links.length; i++) {
|
|
8057
|
+
const link = links[i];
|
|
8058
|
+
if (!link || link.sheet) continue;
|
|
8059
|
+
const rel = (link.getAttribute("rel") ?? "").trim().toLowerCase().split(/\s+/);
|
|
8060
|
+
if (!rel.includes("stylesheet") || rel.includes("alternate") || link.disabled || !link.getAttribute("href")) continue;
|
|
8061
|
+
pending.push(new Promise((resolve) => {
|
|
8062
|
+
let timer;
|
|
8063
|
+
const settle = () => {
|
|
8064
|
+
link.removeEventListener("load", settle);
|
|
8065
|
+
link.removeEventListener("error", settle);
|
|
8066
|
+
signal?.removeEventListener("abort", onAbort);
|
|
8067
|
+
clearTimeout(timer);
|
|
8068
|
+
resolve();
|
|
8069
|
+
};
|
|
8070
|
+
const onAbort = () => settle();
|
|
8071
|
+
timer = setTimeout(() => {
|
|
8072
|
+
logger?.warn(`Stylesheet ${link.href} did not finish loading within ${CLONE_READY_TIMEOUT_MS / 1e3}s; continuing with a possibly unstyled clone`);
|
|
8073
|
+
settle();
|
|
8074
|
+
}, CLONE_READY_TIMEOUT_MS);
|
|
8075
|
+
link.addEventListener("load", settle);
|
|
8076
|
+
link.addEventListener("error", settle);
|
|
8077
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
8078
|
+
if (link.sheet) settle();
|
|
8079
|
+
}));
|
|
8080
|
+
}
|
|
8081
|
+
if (pending.length === 0) return Promise.resolve();
|
|
8082
|
+
return Promise.all(pending).then(() => void 0);
|
|
8083
|
+
};
|
|
8084
|
+
const iframeLoader = (iframe, logger, signal) => {
|
|
8085
|
+
return new Promise((resolve, reject) => {
|
|
8086
|
+
const cloneWindow = iframe.contentWindow;
|
|
8087
|
+
if (!cloneWindow) return reject(`No window assigned for iframe`);
|
|
8088
|
+
const documentClone = cloneWindow.document;
|
|
8089
|
+
let interval;
|
|
8090
|
+
const watchdog = setTimeout(() => {
|
|
8091
|
+
if (interval) clearInterval(interval);
|
|
8092
|
+
reject(/* @__PURE__ */ new Error(`Cloned iframe did not fire its load event within ${IFRAME_LOAD_WATCHDOG_MS}ms`));
|
|
8093
|
+
}, IFRAME_LOAD_WATCHDOG_MS);
|
|
8094
|
+
const onAbort = () => {
|
|
8095
|
+
if (interval) clearInterval(interval);
|
|
8096
|
+
clearTimeout(watchdog);
|
|
8097
|
+
reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
8098
|
+
};
|
|
8099
|
+
cloneWindow.onload = iframe.onload = () => {
|
|
7849
8100
|
cloneWindow.onload = iframe.onload = null;
|
|
7850
|
-
const
|
|
8101
|
+
const maxAttempts = Math.ceil(CLONE_READY_TIMEOUT_MS / 50);
|
|
7851
8102
|
let attempts = 0;
|
|
7852
|
-
|
|
8103
|
+
interval = setInterval(() => {
|
|
7853
8104
|
attempts++;
|
|
7854
|
-
if (
|
|
8105
|
+
if (signal?.aborted) onAbort();
|
|
8106
|
+
else if (documentClone.body.childNodes.length > 0 && documentClone.readyState === "complete") {
|
|
7855
8107
|
clearInterval(interval);
|
|
8108
|
+
interval = void 0;
|
|
8109
|
+
clearTimeout(watchdog);
|
|
7856
8110
|
resolve(iframe);
|
|
7857
|
-
} else if (attempts >=
|
|
8111
|
+
} else if (attempts >= maxAttempts) {
|
|
7858
8112
|
clearInterval(interval);
|
|
8113
|
+
interval = void 0;
|
|
8114
|
+
logger?.warn(`Cloned iframe did not become ready within ${CLONE_READY_TIMEOUT_MS / 1e3} seconds; continuing with a possibly incomplete document`);
|
|
7859
8115
|
resolve(iframe);
|
|
7860
8116
|
}
|
|
7861
8117
|
}, 50);
|
|
7862
8118
|
};
|
|
8119
|
+
if (signal) {
|
|
8120
|
+
if (signal.aborted) onAbort();
|
|
8121
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
8122
|
+
}
|
|
7863
8123
|
});
|
|
7864
8124
|
};
|
|
7865
8125
|
/**
|
|
8126
|
+
* Reduce a doctype component to characters that are inert inside a
|
|
8127
|
+
* <!DOCTYPE ...> declaration. Doctype content is parsed as a declaration
|
|
8128
|
+
* token, never as HTML markup, but the fields originate from the captured
|
|
8129
|
+
* document — stripping markup delimiters and control characters here makes
|
|
8130
|
+
* that property locally verifiable (and keeps the sanitizer guarantee even
|
|
8131
|
+
* if a future serializer ever embeds the result elsewhere).
|
|
8132
|
+
*/
|
|
8133
|
+
const sanitizeDoctypePart = (value) => value.replace(/[<>&"'`\\]|[\u0000-\u001f\u007f]/g, "");
|
|
8134
|
+
/**
|
|
7866
8135
|
* Serialise a document type declaration to an HTML string.
|
|
7867
8136
|
* @internal – exported for testing only, not part of the public API.
|
|
7868
8137
|
*/
|
|
@@ -7870,12 +8139,12 @@ const serializeDoctype = (doctype) => {
|
|
|
7870
8139
|
let str = "";
|
|
7871
8140
|
if (doctype) {
|
|
7872
8141
|
str += "<!DOCTYPE ";
|
|
7873
|
-
if (doctype.name) str += doctype.name;
|
|
7874
|
-
if (doctype.internalSubset) str += " " + doctype.internalSubset
|
|
8142
|
+
if (doctype.name) str += sanitizeDoctypePart(doctype.name);
|
|
8143
|
+
if (doctype.internalSubset) str += " " + sanitizeDoctypePart(doctype.internalSubset);
|
|
7875
8144
|
if (doctype.publicId) {
|
|
7876
|
-
str += " PUBLIC \"" + doctype.publicId
|
|
7877
|
-
if (doctype.systemId) str += " \"" + doctype.systemId
|
|
7878
|
-
} else if (doctype.systemId) str += " SYSTEM \"" + doctype.systemId
|
|
8145
|
+
str += " PUBLIC \"" + sanitizeDoctypePart(doctype.publicId) + "\"";
|
|
8146
|
+
if (doctype.systemId) str += " \"" + sanitizeDoctypePart(doctype.systemId) + "\"";
|
|
8147
|
+
} else if (doctype.systemId) str += " SYSTEM \"" + sanitizeDoctypePart(doctype.systemId) + "\"";
|
|
7879
8148
|
str += ">";
|
|
7880
8149
|
}
|
|
7881
8150
|
return str;
|
|
@@ -7904,14 +8173,21 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7904
8173
|
const scrollY = ownerDocument.defaultView.pageYOffset;
|
|
7905
8174
|
const cloneWindow = iframe.contentWindow;
|
|
7906
8175
|
const documentClone = cloneWindow.document;
|
|
7907
|
-
const iframeLoad = iframeLoader(iframe).then(async () => {
|
|
8176
|
+
const iframeLoad = iframeLoader(iframe, context.logger, mount.signal).then(async () => {
|
|
7908
8177
|
mount.scrolledElements.forEach(restoreNodeScroll);
|
|
7909
8178
|
if (cloneWindow) cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7910
8179
|
const onclone = mount.onclone;
|
|
7911
8180
|
const referenceElement = mount.clonedReferenceElement;
|
|
7912
8181
|
if (typeof referenceElement === "undefined") throw new Error(`Error finding the ${mount.referenceElementName} in the cloned document`);
|
|
8182
|
+
throwIfAborted(mount.signal);
|
|
8183
|
+
await stylesheetWait;
|
|
8184
|
+
throwIfAborted(mount.signal);
|
|
7913
8185
|
if (documentClone.fonts && documentClone.fonts.ready) await documentClone.fonts.ready;
|
|
7914
|
-
|
|
8186
|
+
throwIfAborted(mount.signal);
|
|
8187
|
+
if (/(AppleWebKit)/g.test(navigator.userAgent)) {
|
|
8188
|
+
await imagesReady(documentClone);
|
|
8189
|
+
throwIfAborted(mount.signal);
|
|
8190
|
+
}
|
|
7915
8191
|
if (typeof onclone === "function") await Promise.resolve().then(() => onclone(documentClone, referenceElement));
|
|
7916
8192
|
cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7917
8193
|
if (/AppleWebKit/g.test(navigator.userAgent) && (cloneWindow.scrollY !== windowSize.top || cloneWindow.scrollX !== windowSize.left)) {
|
|
@@ -7927,12 +8203,9 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7927
8203
|
*/
|
|
7928
8204
|
const baseUri = ownerDocument.baseURI;
|
|
7929
8205
|
documentClone.open();
|
|
7930
|
-
const rawHTML = serializeDoctype(
|
|
8206
|
+
const rawHTML = serializeDoctype(ownerDocument.doctype) + "<html></html>";
|
|
7931
8207
|
try {
|
|
7932
|
-
const
|
|
7933
|
-
const trustedTypesFactory = ownerWindow && ownerWindow.trustedTypes;
|
|
7934
|
-
let policy = trustedTypesFactory?.getPolicy?.("html2canvas-pro");
|
|
7935
|
-
if (!policy && trustedTypesFactory) policy = trustedTypesFactory.createPolicy("html2canvas-pro", { createHTML: (s) => s });
|
|
8208
|
+
const policy = resolveTrustedTypesPolicy(ownerDocument.defaultView);
|
|
7936
8209
|
const html = policy ? policy.createHTML(rawHTML) : rawHTML;
|
|
7937
8210
|
documentClone.write(html);
|
|
7938
8211
|
} catch (_e) {
|
|
@@ -7959,6 +8232,7 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7959
8232
|
const adoptedNode = documentClone.adoptNode(mount.documentElement);
|
|
7960
8233
|
addBase(adoptedNode, baseUri);
|
|
7961
8234
|
documentClone.replaceChild(adoptedNode, documentClone.documentElement);
|
|
8235
|
+
const stylesheetWait = stylesheetsReady(documentClone, context.logger, mount.signal);
|
|
7962
8236
|
return iframeLoad;
|
|
7963
8237
|
};
|
|
7964
8238
|
//#endregion
|
|
@@ -7979,6 +8253,15 @@ const findParentShadowRoot = (element) => {
|
|
|
7979
8253
|
return null;
|
|
7980
8254
|
};
|
|
7981
8255
|
var DocumentCloner = class {
|
|
8256
|
+
context;
|
|
8257
|
+
options;
|
|
8258
|
+
scrolledElements;
|
|
8259
|
+
referenceElement;
|
|
8260
|
+
clonedReferenceElement;
|
|
8261
|
+
documentElement;
|
|
8262
|
+
counters;
|
|
8263
|
+
pseudoContents;
|
|
8264
|
+
slotCloner;
|
|
7982
8265
|
constructor(context, element, options) {
|
|
7983
8266
|
this.context = context;
|
|
7984
8267
|
this.options = options;
|
|
@@ -7988,7 +8271,8 @@ var DocumentCloner = class {
|
|
|
7988
8271
|
this.pseudoContents = new PseudoContentResolver(context, this.counters);
|
|
7989
8272
|
this.slotCloner = new SlotCloner((node, copyStyles) => this.cloneNode(node, copyStyles), {
|
|
7990
8273
|
ignoreElements: options.ignoreElements,
|
|
7991
|
-
copyStyles: options.copyStyles ?? true
|
|
8274
|
+
copyStyles: options.copyStyles ?? true,
|
|
8275
|
+
cspNonce: options.cspNonce
|
|
7992
8276
|
}, context);
|
|
7993
8277
|
if (!element.ownerDocument) throw new Error("Cloned element does not have an owner document");
|
|
7994
8278
|
if (!this.options.iframeContainer) {
|
|
@@ -7996,6 +8280,25 @@ var DocumentCloner = class {
|
|
|
7996
8280
|
if (shadowRoot) this.options.iframeContainer = shadowRoot;
|
|
7997
8281
|
}
|
|
7998
8282
|
this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false);
|
|
8283
|
+
this.appendDocumentAdoptedStyles(element.ownerDocument);
|
|
8284
|
+
}
|
|
8285
|
+
/**
|
|
8286
|
+
* Re-materialise the source document's constructable stylesheets
|
|
8287
|
+
* (document.adoptedStyleSheets) as a <style> at the end of the clone's
|
|
8288
|
+
* <head>: cloneNode never carries them, and they cascade after all author
|
|
8289
|
+
* sheets, which appending last approximates.
|
|
8290
|
+
*
|
|
8291
|
+
* Skipped when computed styles are inlined per element (copyStyles), like
|
|
8292
|
+
* the other stylesheet-cloning paths.
|
|
8293
|
+
*/
|
|
8294
|
+
appendDocumentAdoptedStyles(ownerDocument) {
|
|
8295
|
+
if (this.options.copyStyles) return;
|
|
8296
|
+
const sheets = ownerDocument.adoptedStyleSheets;
|
|
8297
|
+
if (!sheets || sheets.length === 0) return;
|
|
8298
|
+
const head = this.documentElement.getElementsByTagName("head").item(0);
|
|
8299
|
+
if (!head) return;
|
|
8300
|
+
const style = createAdoptedStylesElement(this.documentElement.ownerDocument ?? ownerDocument, sheets, this.options.cspNonce);
|
|
8301
|
+
if (style) head.appendChild(style);
|
|
7999
8302
|
}
|
|
8000
8303
|
toIFrame(ownerDocument, windowSize) {
|
|
8001
8304
|
return mountCloneInIFrame(this.context, ownerDocument, windowSize, {
|
|
@@ -8004,7 +8307,8 @@ var DocumentCloner = class {
|
|
|
8004
8307
|
referenceElementName: this.referenceElement.nodeName,
|
|
8005
8308
|
scrolledElements: this.scrolledElements,
|
|
8006
8309
|
onclone: this.options.onclone,
|
|
8007
|
-
container: this.options.iframeContainer
|
|
8310
|
+
container: this.options.iframeContainer,
|
|
8311
|
+
signal: this.options.signal
|
|
8008
8312
|
});
|
|
8009
8313
|
}
|
|
8010
8314
|
createElementClone(node) {
|
|
@@ -8122,7 +8426,7 @@ var DocumentCloner = class {
|
|
|
8122
8426
|
this.slotCloner.cloneChildNodes(node, clone, copyStyles);
|
|
8123
8427
|
}
|
|
8124
8428
|
cloneNode(node, copyStyles) {
|
|
8125
|
-
if (isTextNode(node)) return document.createTextNode(node.data);
|
|
8429
|
+
if (isTextNode(node)) return (node.ownerDocument ?? document).createTextNode(node.data);
|
|
8126
8430
|
if (!node.ownerDocument) return node.cloneNode(false);
|
|
8127
8431
|
const window = node.ownerDocument.defaultView;
|
|
8128
8432
|
if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {
|
|
@@ -8208,7 +8512,7 @@ var DOMNormalizer = class {
|
|
|
8208
8512
|
*/
|
|
8209
8513
|
static normalizeElement(element, styles) {
|
|
8210
8514
|
const originalStyles = {};
|
|
8211
|
-
if (!isHTMLElementNode(element)) return originalStyles;
|
|
8515
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return originalStyles;
|
|
8212
8516
|
if (styles.animationDuration.some((duration) => duration > 0)) {
|
|
8213
8517
|
originalStyles.animationDuration = element.style.animationDuration;
|
|
8214
8518
|
element.style.animationDuration = "0s";
|
|
@@ -8217,13 +8521,25 @@ var DOMNormalizer = class {
|
|
|
8217
8521
|
originalStyles.transform = element.style.transform;
|
|
8218
8522
|
element.style.transform = "translate(0, 0)";
|
|
8219
8523
|
}
|
|
8524
|
+
let needsContainingBlockFallback = false;
|
|
8220
8525
|
if (styles.rotate !== null) {
|
|
8221
8526
|
originalStyles.rotate = element.style.rotate;
|
|
8222
8527
|
element.style.rotate = "0deg";
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8528
|
+
needsContainingBlockFallback = true;
|
|
8529
|
+
}
|
|
8530
|
+
if (styles.translate !== null) {
|
|
8531
|
+
originalStyles.translate = element.style.translate;
|
|
8532
|
+
element.style.translate = "0px";
|
|
8533
|
+
needsContainingBlockFallback = true;
|
|
8534
|
+
}
|
|
8535
|
+
if (styles.scale !== null) {
|
|
8536
|
+
originalStyles.scale = element.style.scale;
|
|
8537
|
+
element.style.scale = "1";
|
|
8538
|
+
needsContainingBlockFallback = true;
|
|
8539
|
+
}
|
|
8540
|
+
if (needsContainingBlockFallback && originalStyles.transform === void 0) {
|
|
8541
|
+
originalStyles.transform = element.style.transform;
|
|
8542
|
+
element.style.transform = "translate(0, 0)";
|
|
8227
8543
|
}
|
|
8228
8544
|
return originalStyles;
|
|
8229
8545
|
}
|
|
@@ -8234,26 +8550,39 @@ var DOMNormalizer = class {
|
|
|
8234
8550
|
* @param originalStyles - Original styles to restore
|
|
8235
8551
|
*/
|
|
8236
8552
|
static restoreElement(element, originalStyles) {
|
|
8237
|
-
if (!isHTMLElementNode(element)) return;
|
|
8553
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return;
|
|
8238
8554
|
if (originalStyles.animationDuration !== void 0) element.style.animationDuration = originalStyles.animationDuration;
|
|
8239
8555
|
if (originalStyles.transform !== void 0) element.style.transform = originalStyles.transform;
|
|
8240
8556
|
if (originalStyles.rotate !== void 0) element.style.rotate = originalStyles.rotate;
|
|
8557
|
+
if (originalStyles.translate !== void 0) element.style.translate = originalStyles.translate;
|
|
8558
|
+
if (originalStyles.scale !== void 0) element.style.scale = originalStyles.scale;
|
|
8241
8559
|
}
|
|
8242
8560
|
};
|
|
8243
8561
|
//#endregion
|
|
8244
8562
|
//#region src/dom/element-container.ts
|
|
8245
8563
|
var ElementContainer = class {
|
|
8564
|
+
context;
|
|
8565
|
+
styles;
|
|
8566
|
+
textNodes = [];
|
|
8567
|
+
elements = [];
|
|
8568
|
+
bounds;
|
|
8569
|
+
/**
|
|
8570
|
+
* Bounds of the <legend> child of a <fieldset>, when present. Browsers break
|
|
8571
|
+
* the fieldset's top border where the legend sits; the renderer uses these
|
|
8572
|
+
* bounds to leave a matching gap (issue #227).
|
|
8573
|
+
*/
|
|
8574
|
+
legendBounds;
|
|
8575
|
+
createsStackingContext = false;
|
|
8576
|
+
createsRealStackingContext = false;
|
|
8577
|
+
isListOwner = false;
|
|
8578
|
+
debugRender = false;
|
|
8579
|
+
originalStyles;
|
|
8580
|
+
originalElement;
|
|
8246
8581
|
constructor(context, element, options = {}) {
|
|
8247
8582
|
this.context = context;
|
|
8248
|
-
this.textNodes = [];
|
|
8249
|
-
this.elements = [];
|
|
8250
|
-
this.createsStackingContext = false;
|
|
8251
|
-
this.createsRealStackingContext = false;
|
|
8252
|
-
this.isListOwner = false;
|
|
8253
|
-
this.debugRender = false;
|
|
8254
8583
|
if (isDebugging(element, 3)) debugger;
|
|
8255
8584
|
this.styles = new CSSParsedDeclaration(context, context.config.window.getComputedStyle(element, null));
|
|
8256
|
-
if (options.normalizeDom !== false && isHTMLElementNode(element)) {
|
|
8585
|
+
if (options.normalizeDom !== false && (isHTMLElementNode(element) || isSVGElementNode(element))) {
|
|
8257
8586
|
this.originalStyles = DOMNormalizer.normalizeElement(element, this.styles);
|
|
8258
8587
|
this.originalElement = element;
|
|
8259
8588
|
}
|
|
@@ -8290,278 +8619,16 @@ var ElementContainer = class {
|
|
|
8290
8619
|
}
|
|
8291
8620
|
};
|
|
8292
8621
|
//#endregion
|
|
8293
|
-
//#region node_modules/.pnpm/text-segmentation@1.0.3/node_modules/text-segmentation/dist/text-segmentation.es5.js
|
|
8294
|
-
var base64 = "AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAABQAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA=";
|
|
8295
|
-
var chars$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8296
|
-
var lookup$1 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
8297
|
-
for (var i$1 = 0; i$1 < chars$1.length; i$1++) lookup$1[chars$1.charCodeAt(i$1)] = i$1;
|
|
8298
|
-
var decode = function(base64) {
|
|
8299
|
-
var bufferLength = base64.length * .75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
|
|
8300
|
-
if (base64[base64.length - 1] === "=") {
|
|
8301
|
-
bufferLength--;
|
|
8302
|
-
if (base64[base64.length - 2] === "=") bufferLength--;
|
|
8303
|
-
}
|
|
8304
|
-
var buffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.slice !== "undefined" ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
|
|
8305
|
-
var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
|
|
8306
|
-
for (i = 0; i < len; i += 4) {
|
|
8307
|
-
encoded1 = lookup$1[base64.charCodeAt(i)];
|
|
8308
|
-
encoded2 = lookup$1[base64.charCodeAt(i + 1)];
|
|
8309
|
-
encoded3 = lookup$1[base64.charCodeAt(i + 2)];
|
|
8310
|
-
encoded4 = lookup$1[base64.charCodeAt(i + 3)];
|
|
8311
|
-
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
|
8312
|
-
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
|
8313
|
-
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
|
8314
|
-
}
|
|
8315
|
-
return buffer;
|
|
8316
|
-
};
|
|
8317
|
-
var polyUint16Array = function(buffer) {
|
|
8318
|
-
var length = buffer.length;
|
|
8319
|
-
var bytes = [];
|
|
8320
|
-
for (var i = 0; i < length; i += 2) bytes.push(buffer[i + 1] << 8 | buffer[i]);
|
|
8321
|
-
return bytes;
|
|
8322
|
-
};
|
|
8323
|
-
var polyUint32Array = function(buffer) {
|
|
8324
|
-
var length = buffer.length;
|
|
8325
|
-
var bytes = [];
|
|
8326
|
-
for (var i = 0; i < length; i += 4) bytes.push(buffer[i + 3] << 24 | buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i]);
|
|
8327
|
-
return bytes;
|
|
8328
|
-
};
|
|
8329
|
-
/** Shift size for getting the index-2 table offset. */
|
|
8330
|
-
var UTRIE2_SHIFT_2 = 5;
|
|
8331
|
-
/** Shift size for getting the index-1 table offset. */
|
|
8332
|
-
var UTRIE2_SHIFT_1 = 11;
|
|
8333
|
-
/**
|
|
8334
|
-
* Shift size for shifting left the index array values.
|
|
8335
|
-
* Increases possible data size with 16-bit index values at the cost
|
|
8336
|
-
* of compactability.
|
|
8337
|
-
* This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
|
|
8338
|
-
*/
|
|
8339
|
-
var UTRIE2_INDEX_SHIFT = 2;
|
|
8340
|
-
/**
|
|
8341
|
-
* Difference between the two shift sizes,
|
|
8342
|
-
* for getting an index-1 offset from an index-2 offset. 6=11-5
|
|
8343
|
-
*/
|
|
8344
|
-
var UTRIE2_SHIFT_1_2 = UTRIE2_SHIFT_1 - UTRIE2_SHIFT_2;
|
|
8345
|
-
/**
|
|
8346
|
-
* The part of the index-2 table for U+D800..U+DBFF stores values for
|
|
8347
|
-
* lead surrogate code _units_ not code _points_.
|
|
8348
|
-
* Values for lead surrogate code _points_ are indexed with this portion of the table.
|
|
8349
|
-
* Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
|
|
8350
|
-
*/
|
|
8351
|
-
var UTRIE2_LSCP_INDEX_2_OFFSET = 65536 >> UTRIE2_SHIFT_2;
|
|
8352
|
-
/** Mask for getting the lower bits for the in-data-block offset. */
|
|
8353
|
-
var UTRIE2_DATA_MASK = (1 << UTRIE2_SHIFT_2) - 1;
|
|
8354
|
-
/**
|
|
8355
|
-
* The index-1 table, only used for supplementary code points, at offset 2112=0x840.
|
|
8356
|
-
* Variable length, for code points up to highStart, where the last single-value range starts.
|
|
8357
|
-
* Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
|
|
8358
|
-
* (For 0x100000 supplementary code points U+10000..U+10ffff.)
|
|
8359
|
-
*
|
|
8360
|
-
* The part of the index-2 table for supplementary code points starts
|
|
8361
|
-
* after this index-1 table.
|
|
8362
|
-
*
|
|
8363
|
-
* Both the index-1 table and the following part of the index-2 table
|
|
8364
|
-
* are omitted completely if there is only BMP data.
|
|
8365
|
-
*/
|
|
8366
|
-
var UTRIE2_INDEX_1_OFFSET = UTRIE2_LSCP_INDEX_2_OFFSET + (1024 >> UTRIE2_SHIFT_2) + 32;
|
|
8367
|
-
/**
|
|
8368
|
-
* Number of index-1 entries for the BMP. 32=0x20
|
|
8369
|
-
* This part of the index-1 table is omitted from the serialized form.
|
|
8370
|
-
*/
|
|
8371
|
-
var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = 65536 >> UTRIE2_SHIFT_1;
|
|
8372
|
-
/** Mask for getting the lower bits for the in-index-2-block offset. */
|
|
8373
|
-
var UTRIE2_INDEX_2_MASK = (1 << UTRIE2_SHIFT_1_2) - 1;
|
|
8374
|
-
var slice16 = function(view, start, end) {
|
|
8375
|
-
if (view.slice) return view.slice(start, end);
|
|
8376
|
-
return new Uint16Array(Array.prototype.slice.call(view, start, end));
|
|
8377
|
-
};
|
|
8378
|
-
var slice32 = function(view, start, end) {
|
|
8379
|
-
if (view.slice) return view.slice(start, end);
|
|
8380
|
-
return new Uint32Array(Array.prototype.slice.call(view, start, end));
|
|
8381
|
-
};
|
|
8382
|
-
var createTrieFromBase64 = function(base64, _byteLength) {
|
|
8383
|
-
var buffer = decode(base64);
|
|
8384
|
-
var view32 = Array.isArray(buffer) ? polyUint32Array(buffer) : new Uint32Array(buffer);
|
|
8385
|
-
var view16 = Array.isArray(buffer) ? polyUint16Array(buffer) : new Uint16Array(buffer);
|
|
8386
|
-
var headerLength = 24;
|
|
8387
|
-
var index = slice16(view16, headerLength / 2, view32[4] / 2);
|
|
8388
|
-
var data = view32[5] === 2 ? slice16(view16, (headerLength + view32[4]) / 2) : slice32(view32, Math.ceil((headerLength + view32[4]) / 4));
|
|
8389
|
-
return new Trie(view32[0], view32[1], view32[2], view32[3], index, data);
|
|
8390
|
-
};
|
|
8391
|
-
var Trie = function() {
|
|
8392
|
-
function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
|
|
8393
|
-
this.initialValue = initialValue;
|
|
8394
|
-
this.errorValue = errorValue;
|
|
8395
|
-
this.highStart = highStart;
|
|
8396
|
-
this.highValueIndex = highValueIndex;
|
|
8397
|
-
this.index = index;
|
|
8398
|
-
this.data = data;
|
|
8399
|
-
}
|
|
8400
|
-
/**
|
|
8401
|
-
* Get the value for a code point as stored in the Trie.
|
|
8402
|
-
*
|
|
8403
|
-
* @param codePoint the code point
|
|
8404
|
-
* @return the value
|
|
8405
|
-
*/
|
|
8406
|
-
Trie.prototype.get = function(codePoint) {
|
|
8407
|
-
var ix;
|
|
8408
|
-
if (codePoint >= 0) {
|
|
8409
|
-
if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {
|
|
8410
|
-
ix = this.index[codePoint >> UTRIE2_SHIFT_2];
|
|
8411
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8412
|
-
return this.data[ix];
|
|
8413
|
-
}
|
|
8414
|
-
if (codePoint <= 65535) {
|
|
8415
|
-
ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET + (codePoint - 55296 >> UTRIE2_SHIFT_2)];
|
|
8416
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8417
|
-
return this.data[ix];
|
|
8418
|
-
}
|
|
8419
|
-
if (codePoint < this.highStart) {
|
|
8420
|
-
ix = UTRIE2_INDEX_1_OFFSET - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH + (codePoint >> UTRIE2_SHIFT_1);
|
|
8421
|
-
ix = this.index[ix];
|
|
8422
|
-
ix += codePoint >> UTRIE2_SHIFT_2 & UTRIE2_INDEX_2_MASK;
|
|
8423
|
-
ix = this.index[ix];
|
|
8424
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8425
|
-
return this.data[ix];
|
|
8426
|
-
}
|
|
8427
|
-
if (codePoint <= 1114111) return this.data[this.highValueIndex];
|
|
8428
|
-
}
|
|
8429
|
-
return this.errorValue;
|
|
8430
|
-
};
|
|
8431
|
-
return Trie;
|
|
8432
|
-
}();
|
|
8433
|
-
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8434
|
-
var lookup = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
8435
|
-
for (var i = 0; i < chars.length; i++) lookup[chars.charCodeAt(i)] = i;
|
|
8436
|
-
var Prepend = 1;
|
|
8437
|
-
var CR = 2;
|
|
8438
|
-
var LF = 3;
|
|
8439
|
-
var Control = 4;
|
|
8440
|
-
var Extend = 5;
|
|
8441
|
-
var SpacingMark = 7;
|
|
8442
|
-
var L = 8;
|
|
8443
|
-
var V = 9;
|
|
8444
|
-
var T = 10;
|
|
8445
|
-
var LV = 11;
|
|
8446
|
-
var LVT = 12;
|
|
8447
|
-
var ZWJ = 13;
|
|
8448
|
-
var Extended_Pictographic = 14;
|
|
8449
|
-
var RI = 15;
|
|
8450
|
-
var toCodePoints = function(str) {
|
|
8451
|
-
var codePoints = [];
|
|
8452
|
-
var i = 0;
|
|
8453
|
-
var length = str.length;
|
|
8454
|
-
while (i < length) {
|
|
8455
|
-
var value = str.charCodeAt(i++);
|
|
8456
|
-
if (value >= 55296 && value <= 56319 && i < length) {
|
|
8457
|
-
var extra = str.charCodeAt(i++);
|
|
8458
|
-
if ((extra & 64512) === 56320) codePoints.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
|
8459
|
-
else {
|
|
8460
|
-
codePoints.push(value);
|
|
8461
|
-
i--;
|
|
8462
|
-
}
|
|
8463
|
-
} else codePoints.push(value);
|
|
8464
|
-
}
|
|
8465
|
-
return codePoints;
|
|
8466
|
-
};
|
|
8467
|
-
var fromCodePoint = function() {
|
|
8468
|
-
var codePoints = [];
|
|
8469
|
-
for (var _i = 0; _i < arguments.length; _i++) codePoints[_i] = arguments[_i];
|
|
8470
|
-
if (String.fromCodePoint) return String.fromCodePoint.apply(String, codePoints);
|
|
8471
|
-
var length = codePoints.length;
|
|
8472
|
-
if (!length) return "";
|
|
8473
|
-
var codeUnits = [];
|
|
8474
|
-
var index = -1;
|
|
8475
|
-
var result = "";
|
|
8476
|
-
while (++index < length) {
|
|
8477
|
-
var codePoint = codePoints[index];
|
|
8478
|
-
if (codePoint <= 65535) codeUnits.push(codePoint);
|
|
8479
|
-
else {
|
|
8480
|
-
codePoint -= 65536;
|
|
8481
|
-
codeUnits.push((codePoint >> 10) + 55296, codePoint % 1024 + 56320);
|
|
8482
|
-
}
|
|
8483
|
-
if (index + 1 === length || codeUnits.length > 16384) {
|
|
8484
|
-
result += String.fromCharCode.apply(String, codeUnits);
|
|
8485
|
-
codeUnits.length = 0;
|
|
8486
|
-
}
|
|
8487
|
-
}
|
|
8488
|
-
return result;
|
|
8489
|
-
};
|
|
8490
|
-
var UnicodeTrie = createTrieFromBase64(base64);
|
|
8491
|
-
var BREAK_NOT_ALLOWED = "×";
|
|
8492
|
-
var BREAK_ALLOWED = "÷";
|
|
8493
|
-
var codePointToClass = function(codePoint) {
|
|
8494
|
-
return UnicodeTrie.get(codePoint);
|
|
8495
|
-
};
|
|
8496
|
-
var _graphemeBreakAtIndex = function(_codePoints, classTypes, index) {
|
|
8497
|
-
var prevIndex = index - 2;
|
|
8498
|
-
var prev = classTypes[prevIndex];
|
|
8499
|
-
var current = classTypes[index - 1];
|
|
8500
|
-
var next = classTypes[index];
|
|
8501
|
-
if (current === CR && next === LF) return BREAK_NOT_ALLOWED;
|
|
8502
|
-
if (current === CR || current === LF || current === Control) return BREAK_ALLOWED;
|
|
8503
|
-
if (next === CR || next === LF || next === Control) return BREAK_ALLOWED;
|
|
8504
|
-
if (current === L && [
|
|
8505
|
-
L,
|
|
8506
|
-
V,
|
|
8507
|
-
LV,
|
|
8508
|
-
LVT
|
|
8509
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED;
|
|
8510
|
-
if ((current === LV || current === V) && (next === V || next === T)) return BREAK_NOT_ALLOWED;
|
|
8511
|
-
if ((current === LVT || current === T) && next === T) return BREAK_NOT_ALLOWED;
|
|
8512
|
-
if (next === ZWJ || next === Extend) return BREAK_NOT_ALLOWED;
|
|
8513
|
-
if (next === SpacingMark) return BREAK_NOT_ALLOWED;
|
|
8514
|
-
if (current === Prepend) return BREAK_NOT_ALLOWED;
|
|
8515
|
-
if (current === ZWJ && next === Extended_Pictographic) {
|
|
8516
|
-
while (prev === Extend) prev = classTypes[--prevIndex];
|
|
8517
|
-
if (prev === Extended_Pictographic) return BREAK_NOT_ALLOWED;
|
|
8518
|
-
}
|
|
8519
|
-
if (current === RI && next === RI) {
|
|
8520
|
-
var countRI = 0;
|
|
8521
|
-
while (prev === RI) {
|
|
8522
|
-
countRI++;
|
|
8523
|
-
prev = classTypes[--prevIndex];
|
|
8524
|
-
}
|
|
8525
|
-
if (countRI % 2 === 0) return BREAK_NOT_ALLOWED;
|
|
8526
|
-
}
|
|
8527
|
-
return BREAK_ALLOWED;
|
|
8528
|
-
};
|
|
8529
|
-
var GraphemeBreaker = function(str) {
|
|
8530
|
-
var codePoints = toCodePoints(str);
|
|
8531
|
-
var length = codePoints.length;
|
|
8532
|
-
var index = 0;
|
|
8533
|
-
var lastEnd = 0;
|
|
8534
|
-
var classTypes = codePoints.map(codePointToClass);
|
|
8535
|
-
return { next: function() {
|
|
8536
|
-
if (index >= length) return {
|
|
8537
|
-
done: true,
|
|
8538
|
-
value: null
|
|
8539
|
-
};
|
|
8540
|
-
var graphemeBreak = BREAK_NOT_ALLOWED;
|
|
8541
|
-
while (index < length && (graphemeBreak = _graphemeBreakAtIndex(codePoints, classTypes, ++index)) === BREAK_NOT_ALLOWED);
|
|
8542
|
-
if (graphemeBreak !== BREAK_NOT_ALLOWED || index === length) {
|
|
8543
|
-
var value = fromCodePoint.apply(null, codePoints.slice(lastEnd, index));
|
|
8544
|
-
lastEnd = index;
|
|
8545
|
-
return {
|
|
8546
|
-
value,
|
|
8547
|
-
done: false
|
|
8548
|
-
};
|
|
8549
|
-
}
|
|
8550
|
-
return {
|
|
8551
|
-
done: true,
|
|
8552
|
-
value: null
|
|
8553
|
-
};
|
|
8554
|
-
} };
|
|
8555
|
-
};
|
|
8556
|
-
var splitGraphemes = function(str) {
|
|
8557
|
-
var breaker = GraphemeBreaker(str);
|
|
8558
|
-
var graphemes = [];
|
|
8559
|
-
var bk;
|
|
8560
|
-
while (!(bk = breaker.next()).done) if (bk.value) graphemes.push(bk.value.slice());
|
|
8561
|
-
return graphemes;
|
|
8562
|
-
};
|
|
8563
|
-
//#endregion
|
|
8564
8622
|
//#region src/core/features.ts
|
|
8623
|
+
/**
|
|
8624
|
+
* Runtime feature detection.
|
|
8625
|
+
*
|
|
8626
|
+
* Only checks that still gate real behaviour are kept: range-bounds
|
|
8627
|
+
* measurement (iOS 13 quirk), SVG drawing and CORS image support.
|
|
8628
|
+
* Dead probes (IE-era CORS XHR / XHR response-type checks) were removed —
|
|
8629
|
+
* every supported browser exposes `crossOrigin`, `responseType` and
|
|
8630
|
+
* `withCredentials`; Intl.Segmenter is used unconditionally.
|
|
8631
|
+
*/
|
|
8565
8632
|
const testRangeBounds = (document) => {
|
|
8566
8633
|
const TEST_HEIGHT = 123;
|
|
8567
8634
|
if (document.createRange) {
|
|
@@ -8580,35 +8647,7 @@ const testRangeBounds = (document) => {
|
|
|
8580
8647
|
}
|
|
8581
8648
|
return false;
|
|
8582
8649
|
};
|
|
8583
|
-
const testIOSLineBreak = (document) => {
|
|
8584
|
-
const testElement = document.createElement("boundtest");
|
|
8585
|
-
testElement.style.width = "50px";
|
|
8586
|
-
testElement.style.display = "block";
|
|
8587
|
-
testElement.style.fontSize = "12px";
|
|
8588
|
-
testElement.style.letterSpacing = "0px";
|
|
8589
|
-
testElement.style.wordSpacing = "0px";
|
|
8590
|
-
document.body.appendChild(testElement);
|
|
8591
|
-
const range = document.createRange();
|
|
8592
|
-
testElement.innerHTML = typeof "".repeat === "function" ? "👨".repeat(10) : "";
|
|
8593
|
-
const node = testElement.firstChild;
|
|
8594
|
-
const textList = toCodePoints$1(node.data).map((i) => fromCodePoint$1(i));
|
|
8595
|
-
let offset = 0;
|
|
8596
|
-
let prev = {};
|
|
8597
|
-
const supports = textList.every((text, i) => {
|
|
8598
|
-
range.setStart(node, offset);
|
|
8599
|
-
range.setEnd(node, offset + text.length);
|
|
8600
|
-
const rect = range.getBoundingClientRect();
|
|
8601
|
-
offset += text.length;
|
|
8602
|
-
const boundAhead = rect.x > prev.x || rect.y > prev.y;
|
|
8603
|
-
prev = rect;
|
|
8604
|
-
if (i === 0) return true;
|
|
8605
|
-
return boundAhead;
|
|
8606
|
-
});
|
|
8607
|
-
document.body.removeChild(testElement);
|
|
8608
|
-
return supports;
|
|
8609
|
-
};
|
|
8610
8650
|
const testCORS = () => typeof new Image().crossOrigin !== "undefined";
|
|
8611
|
-
const testResponseType = () => typeof new XMLHttpRequest().responseType === "string";
|
|
8612
8651
|
const testSVG = (document) => {
|
|
8613
8652
|
const img = new Image();
|
|
8614
8653
|
const canvas = document.createElement("canvas");
|
|
@@ -8623,36 +8662,6 @@ const testSVG = (document) => {
|
|
|
8623
8662
|
}
|
|
8624
8663
|
return true;
|
|
8625
8664
|
};
|
|
8626
|
-
const isGreenPixel = (data) => data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255;
|
|
8627
|
-
const testForeignObject = (document) => {
|
|
8628
|
-
const canvas = document.createElement("canvas");
|
|
8629
|
-
const size = 100;
|
|
8630
|
-
canvas.width = size;
|
|
8631
|
-
canvas.height = size;
|
|
8632
|
-
const ctx = canvas.getContext("2d");
|
|
8633
|
-
if (!ctx) return Promise.reject(/* @__PURE__ */ new Error("Failed to get 2D rendering context"));
|
|
8634
|
-
ctx.fillStyle = "rgb(0, 255, 0)";
|
|
8635
|
-
ctx.fillRect(0, 0, size, size);
|
|
8636
|
-
const img = new Image();
|
|
8637
|
-
const greenImageSrc = canvas.toDataURL();
|
|
8638
|
-
img.src = greenImageSrc;
|
|
8639
|
-
const svg = createForeignObjectSVG(size, size, 0, 0, img);
|
|
8640
|
-
ctx.fillStyle = "red";
|
|
8641
|
-
ctx.fillRect(0, 0, size, size);
|
|
8642
|
-
return loadSerializedSVG(svg).then((img) => {
|
|
8643
|
-
ctx.drawImage(img, 0, 0);
|
|
8644
|
-
const data = ctx.getImageData(0, 0, size, size).data;
|
|
8645
|
-
ctx.fillStyle = "red";
|
|
8646
|
-
ctx.fillRect(0, 0, size, size);
|
|
8647
|
-
const node = document.createElement("div");
|
|
8648
|
-
node.style.backgroundImage = `url(${greenImageSrc})`;
|
|
8649
|
-
node.style.height = `${size}px`;
|
|
8650
|
-
return isGreenPixel(data) ? loadSerializedSVG(createForeignObjectSVG(size, size, 0, 0, node)) : Promise.reject(/* @__PURE__ */ new Error("ForeignObject rendering not supported"));
|
|
8651
|
-
}).then((img) => {
|
|
8652
|
-
ctx.drawImage(img, 0, 0);
|
|
8653
|
-
return isGreenPixel(ctx.getImageData(0, 0, size, size).data);
|
|
8654
|
-
}).catch(() => false);
|
|
8655
|
-
};
|
|
8656
8665
|
const createForeignObjectSVG = (width, height, x, y, node) => {
|
|
8657
8666
|
const xmlns = "http://www.w3.org/2000/svg";
|
|
8658
8667
|
const svg = document.createElementNS(xmlns, "svg");
|
|
@@ -8683,52 +8692,24 @@ const FEATURES = {
|
|
|
8683
8692
|
Object.defineProperty(FEATURES, "SUPPORT_RANGE_BOUNDS", { value });
|
|
8684
8693
|
return value;
|
|
8685
8694
|
},
|
|
8686
|
-
get SUPPORT_WORD_BREAKING() {
|
|
8687
|
-
"use strict";
|
|
8688
|
-
const value = FEATURES.SUPPORT_RANGE_BOUNDS && testIOSLineBreak(document);
|
|
8689
|
-
Object.defineProperty(FEATURES, "SUPPORT_WORD_BREAKING", { value });
|
|
8690
|
-
return value;
|
|
8691
|
-
},
|
|
8692
8695
|
get SUPPORT_SVG_DRAWING() {
|
|
8693
8696
|
"use strict";
|
|
8694
8697
|
const value = testSVG(document);
|
|
8695
8698
|
Object.defineProperty(FEATURES, "SUPPORT_SVG_DRAWING", { value });
|
|
8696
8699
|
return value;
|
|
8697
8700
|
},
|
|
8698
|
-
get SUPPORT_FOREIGNOBJECT_DRAWING() {
|
|
8699
|
-
"use strict";
|
|
8700
|
-
const value = typeof Array.from === "function" && typeof window.fetch === "function" ? testForeignObject(document) : Promise.resolve(false);
|
|
8701
|
-
Object.defineProperty(FEATURES, "SUPPORT_FOREIGNOBJECT_DRAWING", { value });
|
|
8702
|
-
return value;
|
|
8703
|
-
},
|
|
8704
8701
|
get SUPPORT_CORS_IMAGES() {
|
|
8705
8702
|
"use strict";
|
|
8706
8703
|
const value = testCORS();
|
|
8707
8704
|
Object.defineProperty(FEATURES, "SUPPORT_CORS_IMAGES", { value });
|
|
8708
8705
|
return value;
|
|
8709
|
-
},
|
|
8710
|
-
get SUPPORT_RESPONSE_TYPE() {
|
|
8711
|
-
"use strict";
|
|
8712
|
-
const value = testResponseType();
|
|
8713
|
-
Object.defineProperty(FEATURES, "SUPPORT_RESPONSE_TYPE", { value });
|
|
8714
|
-
return value;
|
|
8715
|
-
},
|
|
8716
|
-
get SUPPORT_CORS_XHR() {
|
|
8717
|
-
"use strict";
|
|
8718
|
-
const value = "withCredentials" in new XMLHttpRequest();
|
|
8719
|
-
Object.defineProperty(FEATURES, "SUPPORT_CORS_XHR", { value });
|
|
8720
|
-
return value;
|
|
8721
|
-
},
|
|
8722
|
-
get SUPPORT_NATIVE_TEXT_SEGMENTATION() {
|
|
8723
|
-
"use strict";
|
|
8724
|
-
const value = !!(typeof Intl !== "undefined" && Intl.Segmenter);
|
|
8725
|
-
Object.defineProperty(FEATURES, "SUPPORT_NATIVE_TEXT_SEGMENTATION", { value });
|
|
8726
|
-
return value;
|
|
8727
8706
|
}
|
|
8728
8707
|
};
|
|
8729
8708
|
//#endregion
|
|
8730
8709
|
//#region src/css/layout/text.ts
|
|
8731
8710
|
var TextBounds = class {
|
|
8711
|
+
text;
|
|
8712
|
+
bounds;
|
|
8732
8713
|
constructor(text, bounds) {
|
|
8733
8714
|
this.text = text;
|
|
8734
8715
|
this.bounds = bounds;
|
|
@@ -8787,58 +8768,24 @@ const segmenterCache = /* @__PURE__ */ new Map();
|
|
|
8787
8768
|
const getSegmenter = (granularity) => {
|
|
8788
8769
|
let segmenter = segmenterCache.get(granularity);
|
|
8789
8770
|
if (!segmenter) {
|
|
8790
|
-
|
|
8791
|
-
segmenter = new Segmenter(void 0, { granularity });
|
|
8771
|
+
segmenter = new Intl.Segmenter(void 0, { granularity });
|
|
8792
8772
|
segmenterCache.set(granularity, segmenter);
|
|
8793
8773
|
}
|
|
8794
8774
|
return segmenter;
|
|
8795
8775
|
};
|
|
8796
|
-
const segmentGraphemes = (value) =>
|
|
8797
|
-
|
|
8798
|
-
return
|
|
8799
|
-
};
|
|
8800
|
-
const segmentWords = (value, styles) => {
|
|
8801
|
-
if (FEATURES.SUPPORT_NATIVE_TEXT_SEGMENTATION) return Array.from(getSegmenter("word").segment(value)).map((s) => s.segment);
|
|
8802
|
-
return breakWords(value, styles);
|
|
8776
|
+
const segmentGraphemes = (value) => Array.from(getSegmenter("grapheme").segment(value), (s) => s.segment);
|
|
8777
|
+
const segmentWords = (value) => {
|
|
8778
|
+
return Array.from(getSegmenter("word").segment(value), (s) => s.segment);
|
|
8803
8779
|
};
|
|
8804
8780
|
const breakText = (value, styles) => {
|
|
8805
8781
|
if (isVerticalWritingMode(styles.writingMode)) return segmentGraphemes(value);
|
|
8806
|
-
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value
|
|
8807
|
-
};
|
|
8808
|
-
const wordSeparators = [
|
|
8809
|
-
32,
|
|
8810
|
-
160,
|
|
8811
|
-
4961,
|
|
8812
|
-
65792,
|
|
8813
|
-
65793,
|
|
8814
|
-
4153,
|
|
8815
|
-
4241
|
|
8816
|
-
];
|
|
8817
|
-
const breakWords = (str, styles) => {
|
|
8818
|
-
const breaker = LineBreaker(str, {
|
|
8819
|
-
lineBreak: styles.lineBreak,
|
|
8820
|
-
wordBreak: styles.overflowWrap === "break-word" ? "break-word" : styles.wordBreak
|
|
8821
|
-
});
|
|
8822
|
-
const words = [];
|
|
8823
|
-
let bk;
|
|
8824
|
-
while (!(bk = breaker.next()).done) if (bk.value) {
|
|
8825
|
-
const codePoints = toCodePoints$1(bk.value.slice());
|
|
8826
|
-
let word = "";
|
|
8827
|
-
codePoints.forEach((codePoint) => {
|
|
8828
|
-
if (wordSeparators.indexOf(codePoint) === -1) word += fromCodePoint$1(codePoint);
|
|
8829
|
-
else {
|
|
8830
|
-
if (word.length) words.push(word);
|
|
8831
|
-
words.push(fromCodePoint$1(codePoint));
|
|
8832
|
-
word = "";
|
|
8833
|
-
}
|
|
8834
|
-
});
|
|
8835
|
-
if (word.length) words.push(word);
|
|
8836
|
-
}
|
|
8837
|
-
return words;
|
|
8782
|
+
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value);
|
|
8838
8783
|
};
|
|
8839
8784
|
//#endregion
|
|
8840
8785
|
//#region src/dom/text-container.ts
|
|
8841
8786
|
var TextContainer = class {
|
|
8787
|
+
text;
|
|
8788
|
+
textBounds;
|
|
8842
8789
|
constructor(context, node, styles) {
|
|
8843
8790
|
this.text = transform(node.data, styles.textTransform);
|
|
8844
8791
|
if (this.text.length !== node.data.length) node.data = this.text;
|
|
@@ -8861,8 +8808,11 @@ const capitalize = (m, p1, p2) => {
|
|
|
8861
8808
|
//#endregion
|
|
8862
8809
|
//#region src/dom/replaced-elements/image-element-container.ts
|
|
8863
8810
|
var ImageElementContainer = class extends ElementContainer {
|
|
8864
|
-
|
|
8865
|
-
|
|
8811
|
+
src;
|
|
8812
|
+
intrinsicWidth;
|
|
8813
|
+
intrinsicHeight;
|
|
8814
|
+
constructor(context, img, options = {}) {
|
|
8815
|
+
super(context, img, options);
|
|
8866
8816
|
this.src = img.currentSrc || img.src;
|
|
8867
8817
|
this.intrinsicWidth = img.naturalWidth;
|
|
8868
8818
|
this.intrinsicHeight = img.naturalHeight;
|
|
@@ -8872,8 +8822,11 @@ var ImageElementContainer = class extends ElementContainer {
|
|
|
8872
8822
|
//#endregion
|
|
8873
8823
|
//#region src/dom/replaced-elements/canvas-element-container.ts
|
|
8874
8824
|
var CanvasElementContainer = class extends ElementContainer {
|
|
8875
|
-
|
|
8876
|
-
|
|
8825
|
+
canvas;
|
|
8826
|
+
intrinsicWidth;
|
|
8827
|
+
intrinsicHeight;
|
|
8828
|
+
constructor(context, canvas, options = {}) {
|
|
8829
|
+
super(context, canvas, options);
|
|
8877
8830
|
this.canvas = canvas;
|
|
8878
8831
|
this.intrinsicWidth = canvas.width;
|
|
8879
8832
|
this.intrinsicHeight = canvas.height;
|
|
@@ -8915,8 +8868,11 @@ const serializeWithoutBoxOffsets = (serializer, img) => {
|
|
|
8915
8868
|
return serialized;
|
|
8916
8869
|
};
|
|
8917
8870
|
var SVGElementContainer = class extends ElementContainer {
|
|
8918
|
-
|
|
8919
|
-
|
|
8871
|
+
svg;
|
|
8872
|
+
intrinsicWidth;
|
|
8873
|
+
intrinsicHeight;
|
|
8874
|
+
constructor(context, img, options = {}) {
|
|
8875
|
+
super(context, img, options);
|
|
8920
8876
|
const s = new XMLSerializer();
|
|
8921
8877
|
const bounds = parseBounds(context, img);
|
|
8922
8878
|
img.setAttribute("width", `${bounds.width}px`);
|
|
@@ -8930,16 +8886,19 @@ var SVGElementContainer = class extends ElementContainer {
|
|
|
8930
8886
|
//#endregion
|
|
8931
8887
|
//#region src/dom/elements/li-element-container.ts
|
|
8932
8888
|
var LIElementContainer = class extends ElementContainer {
|
|
8933
|
-
|
|
8934
|
-
|
|
8889
|
+
value;
|
|
8890
|
+
constructor(context, element, options = {}) {
|
|
8891
|
+
super(context, element, options);
|
|
8935
8892
|
this.value = element.value;
|
|
8936
8893
|
}
|
|
8937
8894
|
};
|
|
8938
8895
|
//#endregion
|
|
8939
8896
|
//#region src/dom/elements/ol-element-container.ts
|
|
8940
8897
|
var OLElementContainer = class extends ElementContainer {
|
|
8941
|
-
|
|
8942
|
-
|
|
8898
|
+
start;
|
|
8899
|
+
reversed;
|
|
8900
|
+
constructor(context, element, options = {}) {
|
|
8901
|
+
super(context, element, options);
|
|
8943
8902
|
this.start = element.start;
|
|
8944
8903
|
this.reversed = typeof element.reversed === "boolean" && element.reversed === true;
|
|
8945
8904
|
}
|
|
@@ -8973,8 +8932,12 @@ const CHECKBOX = "checkbox";
|
|
|
8973
8932
|
const RADIO = "radio";
|
|
8974
8933
|
const PLACEHOLDER_COLOR = 1970632191;
|
|
8975
8934
|
var InputElementContainer = class extends ElementContainer {
|
|
8976
|
-
|
|
8977
|
-
|
|
8935
|
+
type;
|
|
8936
|
+
checked;
|
|
8937
|
+
value;
|
|
8938
|
+
isPlaceholder;
|
|
8939
|
+
constructor(context, input, options = {}) {
|
|
8940
|
+
super(context, input, options);
|
|
8978
8941
|
this.type = input.type.toLowerCase();
|
|
8979
8942
|
this.checked = input.checked;
|
|
8980
8943
|
this.value = getInputValue(input);
|
|
@@ -8999,8 +8962,9 @@ var InputElementContainer = class extends ElementContainer {
|
|
|
8999
8962
|
//#endregion
|
|
9000
8963
|
//#region src/dom/elements/select-element-container.ts
|
|
9001
8964
|
var SelectElementContainer = class extends ElementContainer {
|
|
9002
|
-
|
|
9003
|
-
|
|
8965
|
+
value;
|
|
8966
|
+
constructor(context, element, options = {}) {
|
|
8967
|
+
super(context, element, options);
|
|
9004
8968
|
const option = element.options[element.selectedIndex || 0];
|
|
9005
8969
|
this.value = option ? option.text || "" : "";
|
|
9006
8970
|
}
|
|
@@ -9008,29 +8972,42 @@ var SelectElementContainer = class extends ElementContainer {
|
|
|
9008
8972
|
//#endregion
|
|
9009
8973
|
//#region src/dom/elements/textarea-element-container.ts
|
|
9010
8974
|
var TextareaElementContainer = class extends ElementContainer {
|
|
9011
|
-
|
|
9012
|
-
|
|
8975
|
+
value;
|
|
8976
|
+
constructor(context, element, options = {}) {
|
|
8977
|
+
super(context, element, options);
|
|
9013
8978
|
this.value = element.value;
|
|
9014
8979
|
}
|
|
9015
8980
|
};
|
|
9016
8981
|
//#endregion
|
|
9017
8982
|
//#region src/dom/replaced-elements/iframe-element-container.ts
|
|
9018
8983
|
var IFrameElementContainer = class extends ElementContainer {
|
|
9019
|
-
|
|
9020
|
-
|
|
8984
|
+
src;
|
|
8985
|
+
width;
|
|
8986
|
+
height;
|
|
8987
|
+
tree;
|
|
8988
|
+
backgroundColor;
|
|
8989
|
+
parseTreeFn;
|
|
8990
|
+
constructor(context, iframe, parseTreeFn, options = {}) {
|
|
8991
|
+
super(context, iframe, options);
|
|
9021
8992
|
this.src = iframe.src;
|
|
9022
8993
|
this.width = parseInt(iframe.width, 10) || 0;
|
|
9023
8994
|
this.height = parseInt(iframe.height, 10) || 0;
|
|
9024
8995
|
this.backgroundColor = this.styles.backgroundColor;
|
|
9025
8996
|
this.parseTreeFn = parseTreeFn;
|
|
9026
8997
|
try {
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
8998
|
+
const contentWindow = iframe.contentWindow;
|
|
8999
|
+
const contentDocument = contentWindow?.document;
|
|
9000
|
+
if (contentWindow && contentDocument && contentDocument.documentElement && this.parseTreeFn) {
|
|
9001
|
+
this.tree = this.parseTreeFn(context, contentDocument.documentElement);
|
|
9002
|
+
const documentBackgroundColor = parseColor(context, contentWindow.getComputedStyle(contentDocument.documentElement).backgroundColor);
|
|
9003
|
+
const bodyBackgroundColor = contentDocument.body ? parseColor(context, contentWindow.getComputedStyle(contentDocument.body).backgroundColor) : 0;
|
|
9031
9004
|
this.backgroundColor = isTransparent(documentBackgroundColor) ? isTransparent(bodyBackgroundColor) ? this.styles.backgroundColor : bodyBackgroundColor : documentBackgroundColor;
|
|
9032
9005
|
}
|
|
9033
|
-
} catch (e) {
|
|
9006
|
+
} catch (e) {
|
|
9007
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
9008
|
+
this.context.logger.warn(`Unable to render iframe content${this.src ? ` from ${this.src}` : ""}: ${error.message}`);
|
|
9009
|
+
this.context.onError?.(error);
|
|
9010
|
+
}
|
|
9034
9011
|
}
|
|
9035
9012
|
};
|
|
9036
9013
|
//#endregion
|
|
@@ -9040,10 +9017,10 @@ const LIST_OWNERS = [
|
|
|
9040
9017
|
"UL",
|
|
9041
9018
|
"MENU"
|
|
9042
9019
|
];
|
|
9043
|
-
const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
9020
|
+
const parseNodeTree = (context, node, parent, root, zoomScale = 1, options = {}) => {
|
|
9044
9021
|
for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
|
|
9045
9022
|
nextNode = childNode.nextSibling;
|
|
9046
|
-
parseChildNode(context, childNode, parent, root, zoomScale);
|
|
9023
|
+
parseChildNode(context, childNode, parent, root, zoomScale, options);
|
|
9047
9024
|
}
|
|
9048
9025
|
};
|
|
9049
9026
|
/**
|
|
@@ -9054,7 +9031,7 @@ const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
|
9054
9031
|
* this, slotted shadow-DOM content such as web component labels was silently
|
|
9055
9032
|
* dropped because `parseNodeTree` only iterates `node.firstChild` (issue #226).
|
|
9056
9033
|
*/
|
|
9057
|
-
const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
9034
|
+
const parseChildNode = (context, childNode, parent, root, zoomScale = 1, options = {}) => {
|
|
9058
9035
|
if (isTextNode(childNode) && childNode.data.length > 0) {
|
|
9059
9036
|
const textContainer = new TextContainer(context, childNode, parent.styles);
|
|
9060
9037
|
if (zoomScale !== 1) {
|
|
@@ -9064,9 +9041,9 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9064
9041
|
}
|
|
9065
9042
|
parent.textNodes.push(textContainer);
|
|
9066
9043
|
} else if (isElementNode(childNode)) {
|
|
9067
|
-
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale));
|
|
9044
|
+
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale, options));
|
|
9068
9045
|
else {
|
|
9069
|
-
const container = createContainer(context, childNode);
|
|
9046
|
+
const container = createContainer(context, childNode, options);
|
|
9070
9047
|
const ownZoom = container.styles.zoom || 1;
|
|
9071
9048
|
if (ownZoom !== 1) container.bounds = new Bounds(container.bounds.left, container.bounds.top, container.bounds.width / ownZoom, container.bounds.height / ownZoom);
|
|
9072
9049
|
if (container.styles.isVisible()) {
|
|
@@ -9075,28 +9052,28 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9075
9052
|
if (LIST_OWNERS.indexOf(childNode.tagName) !== -1) container.isListOwner = true;
|
|
9076
9053
|
parent.elements.push(container);
|
|
9077
9054
|
const childZoom = zoomScale * (container.styles.zoom || 1);
|
|
9078
|
-
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom);
|
|
9079
|
-
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom);
|
|
9055
|
+
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom, options);
|
|
9056
|
+
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom, options);
|
|
9080
9057
|
}
|
|
9081
9058
|
}
|
|
9082
9059
|
}
|
|
9083
9060
|
};
|
|
9084
|
-
const createContainer = (context, element) => {
|
|
9085
|
-
if (isImageElement(element)) return new ImageElementContainer(context, element);
|
|
9086
|
-
if (isCanvasElement(element)) return new CanvasElementContainer(context, element);
|
|
9087
|
-
if (isSVGElement(element)) return new SVGElementContainer(context, element);
|
|
9088
|
-
if (isLIElement(element)) return new LIElementContainer(context, element);
|
|
9089
|
-
if (isOLElement(element)) return new OLElementContainer(context, element);
|
|
9090
|
-
if (isInputElement(element)) return new InputElementContainer(context, element);
|
|
9091
|
-
if (isSelectElement(element)) return new SelectElementContainer(context, element);
|
|
9092
|
-
if (isTextareaElement(element)) return new TextareaElementContainer(context, element);
|
|
9093
|
-
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, parseTree);
|
|
9094
|
-
return new ElementContainer(context, element);
|
|
9061
|
+
const createContainer = (context, element, options = {}) => {
|
|
9062
|
+
if (isImageElement(element)) return new ImageElementContainer(context, element, options);
|
|
9063
|
+
if (isCanvasElement(element)) return new CanvasElementContainer(context, element, options);
|
|
9064
|
+
if (isSVGElement(element)) return new SVGElementContainer(context, element, options);
|
|
9065
|
+
if (isLIElement(element)) return new LIElementContainer(context, element, options);
|
|
9066
|
+
if (isOLElement(element)) return new OLElementContainer(context, element, options);
|
|
9067
|
+
if (isInputElement(element)) return new InputElementContainer(context, element, options);
|
|
9068
|
+
if (isSelectElement(element)) return new SelectElementContainer(context, element, options);
|
|
9069
|
+
if (isTextareaElement(element)) return new TextareaElementContainer(context, element, options);
|
|
9070
|
+
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, (ctx, node) => parseTree(ctx, node, options), options);
|
|
9071
|
+
return new ElementContainer(context, element, options);
|
|
9095
9072
|
};
|
|
9096
|
-
const parseTree = (context, element) => {
|
|
9097
|
-
const container = createContainer(context, element);
|
|
9073
|
+
const parseTree = (context, element, options = {}) => {
|
|
9074
|
+
const container = createContainer(context, element, options);
|
|
9098
9075
|
container.createsRealStackingContext = true;
|
|
9099
|
-
parseNodeTree(context, element, container, container);
|
|
9076
|
+
parseNodeTree(context, element, container, container, 1, options);
|
|
9100
9077
|
return container;
|
|
9101
9078
|
};
|
|
9102
9079
|
const createsRealStackingContext = (node, container, root) => {
|
|
@@ -9127,6 +9104,9 @@ const transformPath = (path, deltaX, deltaY, deltaW, deltaH) => {
|
|
|
9127
9104
|
//#endregion
|
|
9128
9105
|
//#region src/render/vector.ts
|
|
9129
9106
|
var Vector = class Vector {
|
|
9107
|
+
type;
|
|
9108
|
+
x;
|
|
9109
|
+
y;
|
|
9130
9110
|
constructor(x, y) {
|
|
9131
9111
|
this.type = 0;
|
|
9132
9112
|
this.x = x;
|
|
@@ -9142,6 +9122,11 @@ const lerp = (a, b, t) => {
|
|
|
9142
9122
|
return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
|
|
9143
9123
|
};
|
|
9144
9124
|
var BezierCurve = class BezierCurve {
|
|
9125
|
+
type;
|
|
9126
|
+
start;
|
|
9127
|
+
startControl;
|
|
9128
|
+
endControl;
|
|
9129
|
+
end;
|
|
9145
9130
|
constructor(start, startControl, endControl, end) {
|
|
9146
9131
|
this.type = 1;
|
|
9147
9132
|
this.start = start;
|
|
@@ -9169,6 +9154,30 @@ const isBezierCurve = (path) => path.type === 1;
|
|
|
9169
9154
|
//#endregion
|
|
9170
9155
|
//#region src/render/bound-curves.ts
|
|
9171
9156
|
var BoundCurves = class {
|
|
9157
|
+
topLeftBorderDoubleOuterBox;
|
|
9158
|
+
topRightBorderDoubleOuterBox;
|
|
9159
|
+
bottomRightBorderDoubleOuterBox;
|
|
9160
|
+
bottomLeftBorderDoubleOuterBox;
|
|
9161
|
+
topLeftBorderDoubleInnerBox;
|
|
9162
|
+
topRightBorderDoubleInnerBox;
|
|
9163
|
+
bottomRightBorderDoubleInnerBox;
|
|
9164
|
+
bottomLeftBorderDoubleInnerBox;
|
|
9165
|
+
topLeftBorderStroke;
|
|
9166
|
+
topRightBorderStroke;
|
|
9167
|
+
bottomRightBorderStroke;
|
|
9168
|
+
bottomLeftBorderStroke;
|
|
9169
|
+
topLeftBorderBox;
|
|
9170
|
+
topRightBorderBox;
|
|
9171
|
+
bottomRightBorderBox;
|
|
9172
|
+
bottomLeftBorderBox;
|
|
9173
|
+
topLeftPaddingBox;
|
|
9174
|
+
topRightPaddingBox;
|
|
9175
|
+
bottomRightPaddingBox;
|
|
9176
|
+
bottomLeftPaddingBox;
|
|
9177
|
+
topLeftContentBox;
|
|
9178
|
+
topRightContentBox;
|
|
9179
|
+
bottomRightContentBox;
|
|
9180
|
+
bottomLeftContentBox;
|
|
9172
9181
|
constructor(element) {
|
|
9173
9182
|
const styles = element.styles;
|
|
9174
9183
|
const bounds = element.bounds;
|
|
@@ -9205,15 +9214,15 @@ var BoundCurves = class {
|
|
|
9205
9214
|
const paddingBottom = getAbsoluteValue(styles.paddingBottom, element.bounds.width);
|
|
9206
9215
|
const paddingLeft = getAbsoluteValue(styles.paddingLeft, element.bounds.width);
|
|
9207
9216
|
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);
|
|
9208
|
-
this.topRightBorderDoubleOuterBox =
|
|
9217
|
+
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);
|
|
9209
9218
|
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);
|
|
9210
9219
|
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);
|
|
9211
9220
|
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);
|
|
9212
|
-
this.topRightBorderDoubleInnerBox =
|
|
9221
|
+
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);
|
|
9213
9222
|
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);
|
|
9214
9223
|
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);
|
|
9215
9224
|
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);
|
|
9216
|
-
this.topRightBorderStroke =
|
|
9225
|
+
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);
|
|
9217
9226
|
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);
|
|
9218
9227
|
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);
|
|
9219
9228
|
this.topLeftBorderBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, 0) : new Vector(bounds.left, bounds.top);
|
|
@@ -9270,26 +9279,32 @@ const calculatePaddingBoxPath = (curves) => {
|
|
|
9270
9279
|
//#endregion
|
|
9271
9280
|
//#region src/render/effects.ts
|
|
9272
9281
|
var TransformEffect = class {
|
|
9282
|
+
offsetX;
|
|
9283
|
+
offsetY;
|
|
9284
|
+
matrix;
|
|
9285
|
+
type = 0;
|
|
9286
|
+
target = 6;
|
|
9273
9287
|
constructor(offsetX, offsetY, matrix) {
|
|
9274
9288
|
this.offsetX = offsetX;
|
|
9275
9289
|
this.offsetY = offsetY;
|
|
9276
9290
|
this.matrix = matrix;
|
|
9277
|
-
this.type = 0;
|
|
9278
|
-
this.target = 6;
|
|
9279
9291
|
}
|
|
9280
9292
|
};
|
|
9281
9293
|
var ClipEffect = class {
|
|
9294
|
+
path;
|
|
9295
|
+
target;
|
|
9296
|
+
type = 1;
|
|
9282
9297
|
constructor(path, target) {
|
|
9283
9298
|
this.path = path;
|
|
9284
9299
|
this.target = target;
|
|
9285
|
-
this.type = 1;
|
|
9286
9300
|
}
|
|
9287
9301
|
};
|
|
9288
9302
|
var OpacityEffect = class {
|
|
9303
|
+
opacity;
|
|
9304
|
+
type = 2;
|
|
9305
|
+
target = 6;
|
|
9289
9306
|
constructor(opacity) {
|
|
9290
9307
|
this.opacity = opacity;
|
|
9291
|
-
this.type = 2;
|
|
9292
|
-
this.target = 6;
|
|
9293
9308
|
}
|
|
9294
9309
|
};
|
|
9295
9310
|
/**
|
|
@@ -9299,10 +9314,11 @@ var OpacityEffect = class {
|
|
|
9299
9314
|
* the path is constructed (arc, ellipse, lineTo, Path2D, etc.).
|
|
9300
9315
|
*/
|
|
9301
9316
|
var ClipPathEffect = class {
|
|
9317
|
+
applyClip;
|
|
9318
|
+
type = 3;
|
|
9319
|
+
target = 6;
|
|
9302
9320
|
constructor(applyClip) {
|
|
9303
9321
|
this.applyClip = applyClip;
|
|
9304
|
-
this.type = 3;
|
|
9305
|
-
this.target = 6;
|
|
9306
9322
|
}
|
|
9307
9323
|
};
|
|
9308
9324
|
/**
|
|
@@ -9329,17 +9345,23 @@ const MIX_BLEND_MODE_TO_COMPOSITE = {
|
|
|
9329
9345
|
[MIX_BLEND_MODE$1.LUMINOSITY]: "luminosity"
|
|
9330
9346
|
};
|
|
9331
9347
|
var BlendEffect = class {
|
|
9348
|
+
mixBlendMode;
|
|
9349
|
+
type = 4;
|
|
9350
|
+
target = 6;
|
|
9351
|
+
compositeOperation;
|
|
9332
9352
|
constructor(mixBlendMode) {
|
|
9333
9353
|
this.mixBlendMode = mixBlendMode;
|
|
9334
|
-
this.type = 4;
|
|
9335
|
-
this.target = 6;
|
|
9336
9354
|
this.compositeOperation = MIX_BLEND_MODE_TO_COMPOSITE[mixBlendMode];
|
|
9337
9355
|
}
|
|
9338
9356
|
};
|
|
9339
9357
|
var FilterEffect = class FilterEffect {
|
|
9358
|
+
type = 5;
|
|
9359
|
+
target = 6;
|
|
9360
|
+
/** CSS filter string with drop-shadow() stripped (safe for ctx.filter). */
|
|
9361
|
+
safeFilterString;
|
|
9362
|
+
/** Shadow params for drop-shadow(), if present and successfully parsed. */
|
|
9363
|
+
shadow;
|
|
9340
9364
|
constructor(filterString) {
|
|
9341
|
-
this.type = 5;
|
|
9342
|
-
this.target = 6;
|
|
9343
9365
|
const parsed = FilterEffect.parseDropShadow(filterString);
|
|
9344
9366
|
this.shadow = parsed.shadow;
|
|
9345
9367
|
this.safeFilterString = parsed.safeFilterString;
|
|
@@ -9465,6 +9487,14 @@ const isFilterEffect = (effect) => effect.type === 5;
|
|
|
9465
9487
|
//#endregion
|
|
9466
9488
|
//#region src/render/stacking-context.ts
|
|
9467
9489
|
var StackingContext = class {
|
|
9490
|
+
element;
|
|
9491
|
+
negativeZIndex;
|
|
9492
|
+
zeroOrAutoZIndexOrTransformedOrOpacity;
|
|
9493
|
+
positiveZIndex;
|
|
9494
|
+
nonPositionedFloats;
|
|
9495
|
+
nonPositionedInlineLevel;
|
|
9496
|
+
inlineLevel;
|
|
9497
|
+
nonInlineLevel;
|
|
9468
9498
|
constructor(container) {
|
|
9469
9499
|
this.element = container;
|
|
9470
9500
|
this.inlineLevel = [];
|
|
@@ -9477,13 +9507,34 @@ var StackingContext = class {
|
|
|
9477
9507
|
}
|
|
9478
9508
|
};
|
|
9479
9509
|
var ElementPaint = class {
|
|
9510
|
+
container;
|
|
9511
|
+
parent;
|
|
9512
|
+
effects = [];
|
|
9513
|
+
curves;
|
|
9514
|
+
listValue;
|
|
9515
|
+
/** Memoised getEffects results for the plain (surfaceRoot-less) render path. */
|
|
9516
|
+
plainEffectsCache = null;
|
|
9480
9517
|
constructor(container, parent) {
|
|
9481
9518
|
this.container = container;
|
|
9482
9519
|
this.parent = parent;
|
|
9483
|
-
this.effects = [];
|
|
9484
|
-
this.plainEffectsCache = null;
|
|
9485
9520
|
this.curves = new BoundCurves(this.container);
|
|
9486
9521
|
if (this.container.styles.opacity < 1) this.effects.push(new OpacityEffect(this.container.styles.opacity));
|
|
9522
|
+
if (this.container.styles.translate !== null) {
|
|
9523
|
+
const origin = this.container.styles.transformOrigin;
|
|
9524
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9525
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9526
|
+
const [tx, ty] = this.container.styles.translate;
|
|
9527
|
+
const dx = getAbsoluteValue(tx, this.container.bounds.width);
|
|
9528
|
+
const dy = getAbsoluteValue(ty, this.container.bounds.height);
|
|
9529
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9530
|
+
1,
|
|
9531
|
+
0,
|
|
9532
|
+
0,
|
|
9533
|
+
1,
|
|
9534
|
+
dx,
|
|
9535
|
+
dy
|
|
9536
|
+
]));
|
|
9537
|
+
}
|
|
9487
9538
|
if (this.container.styles.rotate !== null) {
|
|
9488
9539
|
const origin = this.container.styles.transformOrigin;
|
|
9489
9540
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9501,6 +9552,20 @@ var ElementPaint = class {
|
|
|
9501
9552
|
];
|
|
9502
9553
|
this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
|
|
9503
9554
|
}
|
|
9555
|
+
if (this.container.styles.scale !== null) {
|
|
9556
|
+
const origin = this.container.styles.transformOrigin;
|
|
9557
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9558
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9559
|
+
const [sx, sy] = this.container.styles.scale;
|
|
9560
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9561
|
+
sx,
|
|
9562
|
+
0,
|
|
9563
|
+
0,
|
|
9564
|
+
sy,
|
|
9565
|
+
0,
|
|
9566
|
+
0
|
|
9567
|
+
]));
|
|
9568
|
+
}
|
|
9504
9569
|
if (this.container.styles.transform !== null) {
|
|
9505
9570
|
const origin = this.container.styles.transformOrigin;
|
|
9506
9571
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9696,8 +9761,8 @@ const parseStackTree = (parent, stackingContext, realStackingContext, listItems)
|
|
|
9696
9761
|
if (order < 0) {
|
|
9697
9762
|
let index = 0;
|
|
9698
9763
|
parentStack.negativeZIndex.some((current, i) => {
|
|
9699
|
-
if (order
|
|
9700
|
-
index = i;
|
|
9764
|
+
if (order >= current.element.container.styles.zIndex.order) {
|
|
9765
|
+
index = i + 1;
|
|
9701
9766
|
return false;
|
|
9702
9767
|
} else if (index > 0) return true;
|
|
9703
9768
|
return false;
|
|
@@ -9744,6 +9809,86 @@ const parseStackingContexts = (container) => {
|
|
|
9744
9809
|
return root;
|
|
9745
9810
|
};
|
|
9746
9811
|
//#endregion
|
|
9812
|
+
//#region src/render/canvas/gradient-rasterizer.ts
|
|
9813
|
+
const clampStop = (stop) => Math.min(1, Math.max(0, stop));
|
|
9814
|
+
/**
|
|
9815
|
+
* Stack the one-cycle stop list periodically across [0, 1]. Returns null for
|
|
9816
|
+
* a degenerate period (all stops clamped to one point) — CSS renders the
|
|
9817
|
+
* last colour across the whole area in that case, and callers should paint
|
|
9818
|
+
* the last colour instead of stacking.
|
|
9819
|
+
*/
|
|
9820
|
+
const stackRepeatingStops = (processed) => {
|
|
9821
|
+
const first = at(processed, 0);
|
|
9822
|
+
const last = at(processed, processed.length - 1);
|
|
9823
|
+
if (last.stop - first.stop < 1e-6) return null;
|
|
9824
|
+
const period = Math.max(last.stop - first.stop, .01);
|
|
9825
|
+
const stops = [];
|
|
9826
|
+
const cycles = Math.ceil(1 / period);
|
|
9827
|
+
for (let k = 0; k < cycles; k++) for (const s of processed) {
|
|
9828
|
+
const stop = k * period + (s.stop - first.stop);
|
|
9829
|
+
if (stop > 1) break;
|
|
9830
|
+
stops.push({
|
|
9831
|
+
stop,
|
|
9832
|
+
color: asString(s.color)
|
|
9833
|
+
});
|
|
9834
|
+
}
|
|
9835
|
+
const lastPushed = stops[stops.length - 1];
|
|
9836
|
+
if (!lastPushed || lastPushed.stop < 1) stops.push({
|
|
9837
|
+
stop: 1,
|
|
9838
|
+
color: asString(last.color)
|
|
9839
|
+
});
|
|
9840
|
+
return stops;
|
|
9841
|
+
};
|
|
9842
|
+
/** Map parsed stops to string-colour stops clamped into the canvas [0, 1] range. */
|
|
9843
|
+
const toCanvasStops = (processed) => processed.map((s) => ({
|
|
9844
|
+
stop: clampStop(s.stop),
|
|
9845
|
+
color: asString(s.color)
|
|
9846
|
+
}));
|
|
9847
|
+
/**
|
|
9848
|
+
* Rasterise a radial gradient's ending-shape ellipse to an offscreen canvas.
|
|
9849
|
+
*
|
|
9850
|
+
* The ellipse is a circle of radius rx scaled vertically by ry / rx around
|
|
9851
|
+
* the canvas centre, so the offscreen canvas is the ellipse's full 2rx × 2ry
|
|
9852
|
+
* bounding box and callers draw it at (centre - rx, centre - ry). Handles the
|
|
9853
|
+
* repeating variant by stacking stops across the [0, 1] gradient range.
|
|
9854
|
+
*/
|
|
9855
|
+
const rasterizeRadialGradient = (ownerDocument, rx, ry, stops, repeating = false) => {
|
|
9856
|
+
const processed = processColorStops(stops, rx);
|
|
9857
|
+
const last = at(processed, processed.length - 1);
|
|
9858
|
+
const lastColor = asString(last.color);
|
|
9859
|
+
const canvas = ownerDocument.createElement("canvas");
|
|
9860
|
+
canvas.width = Math.max(1, Math.ceil(rx * 2));
|
|
9861
|
+
canvas.height = Math.max(1, Math.ceil(ry * 2));
|
|
9862
|
+
const ctx = canvas.getContext("2d");
|
|
9863
|
+
if (!ctx) return null;
|
|
9864
|
+
let colorStops;
|
|
9865
|
+
if (repeating) {
|
|
9866
|
+
const stacked = stackRepeatingStops(processed);
|
|
9867
|
+
if (!stacked) {
|
|
9868
|
+
ctx.fillStyle = lastColor;
|
|
9869
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
9870
|
+
return {
|
|
9871
|
+
canvas,
|
|
9872
|
+
lastColor,
|
|
9873
|
+
rx,
|
|
9874
|
+
ry
|
|
9875
|
+
};
|
|
9876
|
+
}
|
|
9877
|
+
colorStops = stacked;
|
|
9878
|
+
} else colorStops = toCanvasStops(processed);
|
|
9879
|
+
const gradient = ctx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
9880
|
+
colorStops.forEach((s) => gradient.addColorStop(clampStop(s.stop), s.color));
|
|
9881
|
+
ctx.fillStyle = gradient;
|
|
9882
|
+
if (rx !== ry) ctx.scale(1, ry / rx);
|
|
9883
|
+
ctx.fillRect(0, 0, rx * 2, rx * 2);
|
|
9884
|
+
return {
|
|
9885
|
+
canvas,
|
|
9886
|
+
lastColor,
|
|
9887
|
+
rx,
|
|
9888
|
+
ry
|
|
9889
|
+
};
|
|
9890
|
+
};
|
|
9891
|
+
//#endregion
|
|
9747
9892
|
//#region src/render/box-sizing.ts
|
|
9748
9893
|
const paddingBox = (element) => {
|
|
9749
9894
|
const bounds = element.bounds;
|
|
@@ -9862,67 +10007,184 @@ const calculateBackgroundRepeatPath = (repeat, [x, y], [width, height], backgrou
|
|
|
9862
10007
|
}
|
|
9863
10008
|
};
|
|
9864
10009
|
//#endregion
|
|
9865
|
-
//#region src/core/abort-helper.ts
|
|
9866
|
-
/**
|
|
9867
|
-
* AbortSignal helper utilities.
|
|
9868
|
-
*/
|
|
9869
|
-
/**
|
|
9870
|
-
* Throw a DOMException if the given AbortSignal is already aborted.
|
|
9871
|
-
* Used at checkpoints throughout the rendering pipeline to support
|
|
9872
|
-
* cancellable renders.
|
|
9873
|
-
*
|
|
9874
|
-
* @param signal - The AbortSignal to check. If undefined or not aborted, this is a no-op.
|
|
9875
|
-
* @throws {DOMException} With name 'AbortError' if the signal has been aborted.
|
|
9876
|
-
*/
|
|
9877
|
-
const throwIfAborted = (signal) => {
|
|
9878
|
-
if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
9879
|
-
};
|
|
9880
|
-
//#endregion
|
|
9881
10010
|
//#region src/render/canvas/filter-surface.ts
|
|
9882
10011
|
var FilterSurfaceError = class extends Error {};
|
|
9883
10012
|
const releaseSurface = (canvas) => {
|
|
9884
10013
|
canvas.width = canvas.height = 0;
|
|
9885
10014
|
};
|
|
9886
|
-
const
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
10015
|
+
const UNITLESS_NAMES = [
|
|
10016
|
+
"brightness",
|
|
10017
|
+
"contrast",
|
|
10018
|
+
"grayscale",
|
|
10019
|
+
"hue-rotate",
|
|
10020
|
+
"invert",
|
|
10021
|
+
"opacity",
|
|
10022
|
+
"saturate",
|
|
10023
|
+
"sepia"
|
|
10024
|
+
];
|
|
10025
|
+
const PARSED_FILTER_CACHE_MAX = 256;
|
|
10026
|
+
const parsedFilterCache = /* @__PURE__ */ new Map();
|
|
10027
|
+
const EMPTY_FILTER = { functions: [] };
|
|
10028
|
+
function parseFilterChain(value) {
|
|
10029
|
+
if (!value || value === "none") return EMPTY_FILTER;
|
|
10030
|
+
const cached = parsedFilterCache.get(value);
|
|
9891
10031
|
if (cached !== void 0) {
|
|
9892
|
-
|
|
9893
|
-
|
|
10032
|
+
parsedFilterCache.delete(value);
|
|
10033
|
+
parsedFilterCache.set(value, cached);
|
|
9894
10034
|
return cached;
|
|
9895
10035
|
}
|
|
9896
|
-
const parsed =
|
|
9897
|
-
if (
|
|
9898
|
-
const oldest =
|
|
9899
|
-
if (oldest !== void 0)
|
|
10036
|
+
const parsed = computeFilterChain(value);
|
|
10037
|
+
if (parsedFilterCache.size >= PARSED_FILTER_CACHE_MAX) {
|
|
10038
|
+
const oldest = parsedFilterCache.keys().next().value;
|
|
10039
|
+
if (oldest !== void 0) parsedFilterCache.delete(oldest);
|
|
9900
10040
|
}
|
|
9901
|
-
|
|
10041
|
+
parsedFilterCache.set(value, parsed);
|
|
9902
10042
|
return parsed;
|
|
9903
10043
|
}
|
|
9904
|
-
|
|
9905
|
-
const
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
10044
|
+
const computeFilterChain = (value) => {
|
|
10045
|
+
const functions = [];
|
|
10046
|
+
let index = 0;
|
|
10047
|
+
while (index < value.length) {
|
|
10048
|
+
const char = value[index];
|
|
10049
|
+
if (char === " " || char === "\n" || char === " ") {
|
|
10050
|
+
index++;
|
|
10051
|
+
continue;
|
|
10052
|
+
}
|
|
10053
|
+
const open = value.indexOf("(", index);
|
|
10054
|
+
if (open === -1) return null;
|
|
10055
|
+
const name = value.slice(index, open).trim();
|
|
10056
|
+
if (!/^[a-zA-Z-]+$/.test(name)) return null;
|
|
10057
|
+
const bodyEnd = matchingParenthesis(value, open);
|
|
10058
|
+
if (bodyEnd === -1) return null;
|
|
10059
|
+
const fn = parseFilterFunction(name, value.slice(open + 1, bodyEnd).trim());
|
|
10060
|
+
if (!fn) return null;
|
|
10061
|
+
functions.push(fn);
|
|
10062
|
+
index = bodyEnd + 1;
|
|
10063
|
+
}
|
|
10064
|
+
return { functions };
|
|
10065
|
+
};
|
|
10066
|
+
/** Index of the ')' matching the '(' at `open`, or -1. */
|
|
10067
|
+
const matchingParenthesis = (value, open) => {
|
|
10068
|
+
let depth = 1;
|
|
10069
|
+
for (let i = open + 1; i < value.length; i++) {
|
|
10070
|
+
const char = value[i];
|
|
10071
|
+
if (char === "(") depth++;
|
|
10072
|
+
else if (char === ")") {
|
|
10073
|
+
depth--;
|
|
10074
|
+
if (depth === 0) return i;
|
|
10075
|
+
}
|
|
10076
|
+
}
|
|
10077
|
+
return -1;
|
|
10078
|
+
};
|
|
10079
|
+
const PX_LENGTH_RE = /^-?\d+(?:\.\d+)?px$/;
|
|
10080
|
+
const parseFilterFunction = (name, body) => {
|
|
10081
|
+
if (name === "blur") {
|
|
10082
|
+
if (body === "0") return {
|
|
10083
|
+
kind: "blur",
|
|
10084
|
+
value: 0
|
|
10085
|
+
};
|
|
10086
|
+
if (!PX_LENGTH_RE.test(body)) return null;
|
|
10087
|
+
const value = Number.parseFloat(body);
|
|
10088
|
+
return value < 0 ? null : {
|
|
10089
|
+
kind: "blur",
|
|
10090
|
+
value
|
|
10091
|
+
};
|
|
10092
|
+
}
|
|
10093
|
+
if (name === "drop-shadow") return parseDropShadowBody(body);
|
|
10094
|
+
if (UNITLESS_NAMES.indexOf(name) !== -1) {
|
|
10095
|
+
const unitless = name;
|
|
10096
|
+
if (unitless === "hue-rotate") {
|
|
10097
|
+
const degrees = parseAngleDegrees(body);
|
|
10098
|
+
return degrees === null ? null : {
|
|
10099
|
+
kind: "unitless",
|
|
10100
|
+
name: unitless,
|
|
10101
|
+
value: degrees
|
|
10102
|
+
};
|
|
10103
|
+
}
|
|
10104
|
+
const trimmed = body.trim();
|
|
10105
|
+
const percentage = trimmed.endsWith("%");
|
|
10106
|
+
const numeric = percentage ? trimmed.slice(0, -1) : trimmed;
|
|
10107
|
+
if (!/^-?\d+(?:\.\d+)?$/.test(numeric)) return null;
|
|
10108
|
+
return {
|
|
10109
|
+
kind: "unitless",
|
|
10110
|
+
name: unitless,
|
|
10111
|
+
value: Number.parseFloat(numeric) * (percentage ? 1 / 100 : 1)
|
|
10112
|
+
};
|
|
10113
|
+
}
|
|
10114
|
+
return null;
|
|
10115
|
+
};
|
|
10116
|
+
/** Split on whitespace outside parentheses so rgba(...) colours stay one token. */
|
|
10117
|
+
const splitTopLevel = (body) => {
|
|
10118
|
+
const parts = [];
|
|
10119
|
+
let depth = 0;
|
|
10120
|
+
let current = "";
|
|
10121
|
+
for (const char of body) {
|
|
10122
|
+
if (char === "(") depth++;
|
|
10123
|
+
else if (char === ")") depth--;
|
|
10124
|
+
if (char === " " && depth === 0) {
|
|
10125
|
+
if (current) parts.push(current);
|
|
10126
|
+
current = "";
|
|
10127
|
+
continue;
|
|
10128
|
+
}
|
|
10129
|
+
current += char;
|
|
10130
|
+
}
|
|
10131
|
+
if (current) parts.push(current);
|
|
10132
|
+
return parts;
|
|
10133
|
+
};
|
|
10134
|
+
const parseDropShadowBody = (body) => {
|
|
10135
|
+
const parts = splitTopLevel(body);
|
|
10136
|
+
const lengths = parts.filter((part) => PX_LENGTH_RE.test(part)).map((part) => Number.parseFloat(part));
|
|
10137
|
+
if (lengths.length < 2 || lengths.length > 3) return null;
|
|
10138
|
+
const colors = parts.filter((part) => !PX_LENGTH_RE.test(part));
|
|
10139
|
+
if (parts.length - colors.length !== lengths.length) return null;
|
|
9911
10140
|
return {
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
color: effect.shadow.color
|
|
9918
|
-
} : void 0
|
|
10141
|
+
kind: "drop-shadow",
|
|
10142
|
+
x: lengths[0],
|
|
10143
|
+
y: lengths[1],
|
|
10144
|
+
blur: lengths[2] ?? 0,
|
|
10145
|
+
color: colors.join(" ") || "rgba(0, 0, 0, 0)"
|
|
9919
10146
|
};
|
|
9920
|
-
}
|
|
10147
|
+
};
|
|
10148
|
+
const parseAngleDegrees = (body) => {
|
|
10149
|
+
const trimmed = body.trim();
|
|
10150
|
+
if (trimmed === "0") return 0;
|
|
10151
|
+
const numeric = Number.parseFloat(trimmed);
|
|
10152
|
+
if (Number.isNaN(numeric)) return null;
|
|
10153
|
+
if (trimmed.endsWith("deg")) return numeric;
|
|
10154
|
+
if (trimmed.endsWith("grad")) return numeric * .9;
|
|
10155
|
+
if (trimmed.endsWith("rad")) return numeric * 180 / Math.PI;
|
|
10156
|
+
if (trimmed.endsWith("turn")) return numeric * 360;
|
|
10157
|
+
return null;
|
|
10158
|
+
};
|
|
10159
|
+
/**
|
|
10160
|
+
* Render the chain as a canvas ctx.filter string, scaling all device-space
|
|
10161
|
+
* lengths (blur radii, shadow offsets) by the capture scale. Unitless
|
|
10162
|
+
* functions and hue angles are scale-invariant.
|
|
10163
|
+
*/
|
|
10164
|
+
const nativeFilterString = (filter, scale) => filter.functions.map((fn) => {
|
|
10165
|
+
switch (fn.kind) {
|
|
10166
|
+
case "blur": return `blur(${fn.value * scale}px)`;
|
|
10167
|
+
case "drop-shadow": return `drop-shadow(${fn.x * scale}px ${fn.y * scale}px ${fn.blur * scale}px ${fn.color})`;
|
|
10168
|
+
case "unitless": return fn.name === "hue-rotate" ? `hue-rotate(${fn.value}deg)` : `${fn.name}(${fn.value})`;
|
|
10169
|
+
}
|
|
10170
|
+
}).join(" ");
|
|
10171
|
+
/**
|
|
10172
|
+
* Outset (in CSS pixels) a surface must grow so blur/shadow spillover is not
|
|
10173
|
+
* cropped. Unitless functions never spread beyond the bounds. Consecutive
|
|
10174
|
+
* blurs compound, so their radii sum.
|
|
10175
|
+
*/
|
|
9921
10176
|
function filterOutset(filter) {
|
|
9922
|
-
|
|
10177
|
+
let blurSum = 0;
|
|
10178
|
+
let maxShadowOffset = 0;
|
|
10179
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurSum += fn.value;
|
|
10180
|
+
else if (fn.kind === "drop-shadow") {
|
|
10181
|
+
blurSum += fn.blur;
|
|
10182
|
+
maxShadowOffset = Math.max(maxShadowOffset, Math.abs(fn.x), Math.abs(fn.y));
|
|
10183
|
+
}
|
|
10184
|
+
return Math.ceil(3 * blurSum + maxShadowOffset);
|
|
9923
10185
|
}
|
|
9924
10186
|
function canvasLike(source) {
|
|
9925
|
-
const canvas = document.createElement("canvas");
|
|
10187
|
+
const canvas = (source.ownerDocument ?? document).createElement("canvas");
|
|
9926
10188
|
canvas.width = source.width;
|
|
9927
10189
|
canvas.height = source.height;
|
|
9928
10190
|
return canvas;
|
|
@@ -9970,7 +10232,7 @@ function supportsNativeFilters(owner = document) {
|
|
|
9970
10232
|
canvasFilterSupport.set(owner, supported);
|
|
9971
10233
|
return supported;
|
|
9972
10234
|
}
|
|
9973
|
-
function tryNativeFilterSurface(source,
|
|
10235
|
+
function tryNativeFilterSurface(source, filter, opacity, scale, signal) {
|
|
9974
10236
|
let filtered;
|
|
9975
10237
|
let output;
|
|
9976
10238
|
let complete = false;
|
|
@@ -9979,11 +10241,8 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
9979
10241
|
filtered = canvasLike(source);
|
|
9980
10242
|
const context = filtered.getContext("2d");
|
|
9981
10243
|
if (!context || !("filter" in context)) return null;
|
|
9982
|
-
|
|
9983
|
-
if (
|
|
9984
|
-
if (shadow) functions.push(`drop-shadow(${shadow.x * scale}px ${shadow.y * scale}px ${shadow.blur * scale}px ${shadow.color})`);
|
|
9985
|
-
context.filter = functions.join(" ");
|
|
9986
|
-
if (context.filter === "none") return null;
|
|
10244
|
+
context.filter = nativeFilterString(filter, scale);
|
|
10245
|
+
if (context.filter === "none" || context.filter === "") return null;
|
|
9987
10246
|
context.drawImage(source, 0, 0);
|
|
9988
10247
|
throwIfAborted(signal);
|
|
9989
10248
|
output = canvasLike(source);
|
|
@@ -10002,17 +10261,43 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
10002
10261
|
if (output && !complete) releaseSurface(output);
|
|
10003
10262
|
}
|
|
10004
10263
|
}
|
|
10264
|
+
/**
|
|
10265
|
+
* The SVG fallback predates the ordered-chain parser and only expresses the
|
|
10266
|
+
* blur + single drop-shadow subset (at most one of each, blur before the
|
|
10267
|
+
* shadow). Chains outside that subset reject with FilterSurfaceError so the
|
|
10268
|
+
* caller keeps its legacy renderer instead of rendering a wrong filter.
|
|
10269
|
+
*/
|
|
10270
|
+
const isSvgExpressible = (filter) => {
|
|
10271
|
+
let blurs = 0;
|
|
10272
|
+
let shadows = 0;
|
|
10273
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurs++;
|
|
10274
|
+
else if (fn.kind === "drop-shadow") shadows++;
|
|
10275
|
+
else return false;
|
|
10276
|
+
if (blurs > 1 || shadows > 1) return false;
|
|
10277
|
+
if (blurs > 0 && shadows > 0) return filter.functions.findIndex((fn) => fn.kind === "blur") < filter.functions.findIndex((fn) => fn.kind === "drop-shadow");
|
|
10278
|
+
return true;
|
|
10279
|
+
};
|
|
10005
10280
|
async function renderFilterSurface(source, filter, opacity, scale, signal) {
|
|
10006
10281
|
throwIfAborted(signal);
|
|
10007
|
-
if (
|
|
10282
|
+
if (filter.functions.length > 0 && supportsNativeFilters(source.ownerDocument ?? document)) {
|
|
10008
10283
|
const output = tryNativeFilterSurface(source, filter, opacity, scale, signal);
|
|
10009
10284
|
if (output) return output;
|
|
10010
10285
|
}
|
|
10286
|
+
if (!isSvgExpressible(filter)) throw new FilterSurfaceError("Filter chain requires native canvas filters");
|
|
10011
10287
|
return renderSvgFilterSurface(source, filter, opacity, scale, signal);
|
|
10012
10288
|
}
|
|
10013
|
-
async function renderSvgFilterSurface(source,
|
|
10289
|
+
async function renderSvgFilterSurface(source, filter, opacity, scale, signal) {
|
|
10014
10290
|
throwIfAborted(signal);
|
|
10015
|
-
|
|
10291
|
+
const blur = filter.functions.find((fn) => fn.kind === "blur");
|
|
10292
|
+
const shadow = filter.functions.find((fn) => fn.kind === "drop-shadow");
|
|
10293
|
+
const blurValue = blur && blur.kind === "blur" ? blur.value : 0;
|
|
10294
|
+
const shadowValue = shadow && shadow.kind === "drop-shadow" ? {
|
|
10295
|
+
x: shadow.x,
|
|
10296
|
+
y: shadow.y,
|
|
10297
|
+
blur: shadow.blur,
|
|
10298
|
+
color: shadow.color
|
|
10299
|
+
} : void 0;
|
|
10300
|
+
if (!blurValue && !shadowValue) {
|
|
10016
10301
|
const output = canvasLike(source);
|
|
10017
10302
|
const context = output.getContext("2d");
|
|
10018
10303
|
if (!context) {
|
|
@@ -10029,8 +10314,9 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10029
10314
|
}
|
|
10030
10315
|
}
|
|
10031
10316
|
const namespace = "http://www.w3.org/2000/svg";
|
|
10317
|
+
const svgDocument = source.ownerDocument ?? document;
|
|
10032
10318
|
const element = (tag, attributes = {}) => {
|
|
10033
|
-
const node =
|
|
10319
|
+
const node = svgDocument.createElementNS(namespace, tag);
|
|
10034
10320
|
Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
|
|
10035
10321
|
return node;
|
|
10036
10322
|
};
|
|
@@ -10040,7 +10326,7 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10040
10326
|
viewBox: `0 0 ${source.width} ${source.height}`
|
|
10041
10327
|
});
|
|
10042
10328
|
const defs = element("defs");
|
|
10043
|
-
const
|
|
10329
|
+
const filterElement = element("filter", {
|
|
10044
10330
|
id: "composited-filter",
|
|
10045
10331
|
filterUnits: "userSpaceOnUse",
|
|
10046
10332
|
x: 0,
|
|
@@ -10049,31 +10335,31 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10049
10335
|
height: source.height,
|
|
10050
10336
|
"color-interpolation-filters": "sRGB"
|
|
10051
10337
|
});
|
|
10052
|
-
if (
|
|
10053
|
-
stdDeviation:
|
|
10338
|
+
if (blurValue) filterElement.appendChild(element("feGaussianBlur", {
|
|
10339
|
+
stdDeviation: blurValue * scale,
|
|
10054
10340
|
result: "blurred-source"
|
|
10055
10341
|
}));
|
|
10056
|
-
if (
|
|
10057
|
-
|
|
10058
|
-
in:
|
|
10059
|
-
stdDeviation:
|
|
10342
|
+
if (shadowValue) {
|
|
10343
|
+
filterElement.appendChild(element("feGaussianBlur", {
|
|
10344
|
+
in: blurValue ? "blurred-source" : "SourceAlpha",
|
|
10345
|
+
stdDeviation: shadowValue.blur * scale
|
|
10060
10346
|
}));
|
|
10061
|
-
|
|
10062
|
-
dx:
|
|
10063
|
-
dy:
|
|
10347
|
+
filterElement.appendChild(element("feOffset", {
|
|
10348
|
+
dx: shadowValue.x * scale,
|
|
10349
|
+
dy: shadowValue.y * scale,
|
|
10064
10350
|
result: "offset-shadow"
|
|
10065
10351
|
}));
|
|
10066
|
-
|
|
10067
|
-
|
|
10352
|
+
filterElement.appendChild(element("feFlood", { "flood-color": shadowValue.color }));
|
|
10353
|
+
filterElement.appendChild(element("feComposite", {
|
|
10068
10354
|
in2: "offset-shadow",
|
|
10069
10355
|
operator: "in"
|
|
10070
10356
|
}));
|
|
10071
10357
|
const merge = element("feMerge");
|
|
10072
10358
|
merge.appendChild(element("feMergeNode"));
|
|
10073
|
-
merge.appendChild(element("feMergeNode", { in:
|
|
10074
|
-
|
|
10359
|
+
merge.appendChild(element("feMergeNode", { in: blurValue ? "blurred-source" : "SourceGraphic" }));
|
|
10360
|
+
filterElement.appendChild(merge);
|
|
10075
10361
|
}
|
|
10076
|
-
defs.appendChild(
|
|
10362
|
+
defs.appendChild(filterElement);
|
|
10077
10363
|
svg.appendChild(defs);
|
|
10078
10364
|
let sourceUrl;
|
|
10079
10365
|
try {
|
|
@@ -10088,7 +10374,8 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10088
10374
|
href: sourceUrl,
|
|
10089
10375
|
filter: "url(#composited-filter)"
|
|
10090
10376
|
}));
|
|
10091
|
-
const
|
|
10377
|
+
const imageWindow = svgDocument.defaultView;
|
|
10378
|
+
const image = imageWindow?.Image ? new imageWindow.Image() : new Image();
|
|
10092
10379
|
let output;
|
|
10093
10380
|
try {
|
|
10094
10381
|
image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
|
|
@@ -10129,7 +10416,7 @@ function surfaceBounds(container) {
|
|
|
10129
10416
|
for (const shadow of styles.textShadow) bounds = union(bounds, expand(ink.add(shadow.offsetX.number, shadow.offsetY.number, 0, 0), 3 * shadow.blur.number));
|
|
10130
10417
|
}
|
|
10131
10418
|
for (const child of container.elements) if (child.styles.isVisible()) bounds = union(bounds, surfaceBounds(child));
|
|
10132
|
-
const filter =
|
|
10419
|
+
const filter = parseFilterChain(styles.filter);
|
|
10133
10420
|
return expand(bounds, filter ? filterOutset(filter) : 0);
|
|
10134
10421
|
}
|
|
10135
10422
|
function cropSurface(bounds, viewport, margin, scale) {
|
|
@@ -10143,11 +10430,12 @@ function cropSurface(bounds, viewport, margin, scale) {
|
|
|
10143
10430
|
//#endregion
|
|
10144
10431
|
//#region src/render/canvas/text/text-decoration-renderer.ts
|
|
10145
10432
|
var TextDecorationRenderer = class {
|
|
10433
|
+
ctx;
|
|
10146
10434
|
constructor(ctx) {
|
|
10147
10435
|
this.ctx = ctx;
|
|
10148
10436
|
}
|
|
10149
10437
|
render(bounds, styles) {
|
|
10150
|
-
this.ctx.fillStyle = asString(styles.textDecorationColor
|
|
10438
|
+
this.ctx.fillStyle = asString(styles.textDecorationColor ?? styles.color);
|
|
10151
10439
|
let thickness = 1;
|
|
10152
10440
|
if (typeof styles.textDecorationThickness === "number") thickness = styles.textDecorationThickness;
|
|
10153
10441
|
else if (styles.textDecorationThickness === "from-font") thickness = Math.max(1, Math.floor(styles.fontSize.number * .05));
|
|
@@ -10266,7 +10554,6 @@ const measureBaseline = (ctx, fallback) => {
|
|
|
10266
10554
|
};
|
|
10267
10555
|
//#endregion
|
|
10268
10556
|
//#region src/render/canvas/text-renderer.ts
|
|
10269
|
-
const iOSBrokenFonts = ["-apple-system", "system-ui"];
|
|
10270
10557
|
const TEXT_OVERFLOW_EPSILON = 1;
|
|
10271
10558
|
/**
|
|
10272
10559
|
* Detect CJK (Chinese, Japanese, Korean) characters in a string.
|
|
@@ -10285,29 +10572,19 @@ const TEXT_OVERFLOW_EPSILON = 1;
|
|
|
10285
10572
|
const CJK_CHAR_REGEX = /[\u2E80-\u2FFF\u3000-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF01-\uFFEF]/;
|
|
10286
10573
|
const hasCJKCharacters = (text) => CJK_CHAR_REGEX.test(text);
|
|
10287
10574
|
/**
|
|
10288
|
-
*
|
|
10289
|
-
*
|
|
10575
|
+
* Chromium-based engines render stroked text with visibly sharper joins when
|
|
10576
|
+
* `miter` is requested, closely matching their own -webkit-text-stroke
|
|
10577
|
+
* output; other engines need `round` joins to avoid glyph spikes. No CSS or
|
|
10578
|
+
* platform API expresses this behavioural difference, so engine detection is
|
|
10579
|
+
* the only reliable signal: `navigator.userAgentData` is Chromium-only, with
|
|
10580
|
+
* the legacy `window.chrome` marker as a fallback for older webviews.
|
|
10290
10581
|
*/
|
|
10291
|
-
const
|
|
10292
|
-
if (typeof navigator === "undefined") return
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
const isIPadOS = /Macintosh/.test(userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
|
|
10296
|
-
if (!isIOS && !isIPadOS) return null;
|
|
10297
|
-
for (const pattern of [/(?:iPhone|CPU(?:\siPhone)?)\sOS\s(\d+)[\._](\d+)/, /Version\/(\d+)\.(\d+)/]) {
|
|
10298
|
-
const match = userAgent.match(pattern);
|
|
10299
|
-
if (match && match[1]) return parseInt(match[1], 10);
|
|
10300
|
-
}
|
|
10301
|
-
return null;
|
|
10302
|
-
};
|
|
10303
|
-
const fixIOSSystemFonts = (fontFamilies) => {
|
|
10304
|
-
const iosVersion = getIOSVersion();
|
|
10305
|
-
if (iosVersion !== null && iosVersion >= 15 && iosVersion < 17) return fontFamilies.map((fontFamily) => iOSBrokenFonts.indexOf(fontFamily) !== -1 ? `-apple-system, "Helvetica Neue", Arial, sans-serif` : fontFamily);
|
|
10306
|
-
return fontFamilies;
|
|
10307
|
-
};
|
|
10308
|
-
const getTextStrokeLineJoin = () => {
|
|
10309
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
10582
|
+
const isChromiumEngine = () => {
|
|
10583
|
+
if (typeof navigator === "undefined") return false;
|
|
10584
|
+
if (navigator.userAgentData !== void 0) return true;
|
|
10585
|
+
return (typeof window !== "undefined" ? window : void 0)?.chrome !== void 0;
|
|
10310
10586
|
};
|
|
10587
|
+
const getTextStrokeLineJoin = () => isChromiumEngine() ? "miter" : "round";
|
|
10311
10588
|
/**
|
|
10312
10589
|
* Text Renderer
|
|
10313
10590
|
*
|
|
@@ -10315,9 +10592,23 @@ const getTextStrokeLineJoin = () => {
|
|
|
10315
10592
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10316
10593
|
*/
|
|
10317
10594
|
var TextRenderer = class {
|
|
10595
|
+
ctx;
|
|
10596
|
+
options;
|
|
10597
|
+
decorationRenderer;
|
|
10598
|
+
/**
|
|
10599
|
+
* Baseline ascent per font string. Consecutive text nodes overwhelmingly
|
|
10600
|
+
* share a font, and each measureBaseline call issues a canvas measureText,
|
|
10601
|
+
* so repeated fonts are memoised (bounded; cleared if the working set
|
|
10602
|
+
* exceeds the cap).
|
|
10603
|
+
*/
|
|
10604
|
+
baselineCache = /* @__PURE__ */ new Map();
|
|
10605
|
+
/**
|
|
10606
|
+
* Per-render glyph width cache. Keyed by glyph + font string,
|
|
10607
|
+
* avoids redundant `measureText` calls when letter-spacing is non-zero.
|
|
10608
|
+
* Cleared at the start of each renderTextNode call.
|
|
10609
|
+
*/
|
|
10610
|
+
glyphWidthCache = null;
|
|
10318
10611
|
constructor(deps) {
|
|
10319
|
-
this.baselineCache = /* @__PURE__ */ new Map();
|
|
10320
|
-
this.glyphWidthCache = null;
|
|
10321
10612
|
this.ctx = deps.ctx;
|
|
10322
10613
|
this.options = deps.options;
|
|
10323
10614
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
@@ -10510,7 +10801,7 @@ var TextRenderer = class {
|
|
|
10510
10801
|
*/
|
|
10511
10802
|
createFontStyle(styles) {
|
|
10512
10803
|
const fontVariant = styles.fontVariant.filter((variant) => variant === "normal" || variant === "small-caps").join("");
|
|
10513
|
-
const fontFamily =
|
|
10804
|
+
const fontFamily = styles.fontFamily.join(", ");
|
|
10514
10805
|
const fontSize = isDimensionToken(styles.fontSize) ? `${styles.fontSize.number}${styles.fontSize.unit}` : `${styles.fontSize.number}px`;
|
|
10515
10806
|
return [
|
|
10516
10807
|
[
|
|
@@ -10539,7 +10830,7 @@ var TextRenderer = class {
|
|
|
10539
10830
|
* only the first N-1 complete lines followed by an ellipsis on the Nth line.
|
|
10540
10831
|
*/
|
|
10541
10832
|
renderLineClampedText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10542
|
-
const lineHeight = styles.fontSize.number
|
|
10833
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10543
10834
|
const lines = [];
|
|
10544
10835
|
let currentLine = [];
|
|
10545
10836
|
let currentLineTop = at(text.textBounds, 0).bounds.top;
|
|
@@ -10572,7 +10863,7 @@ var TextRenderer = class {
|
|
|
10572
10863
|
* Returns true if ellipsis was applied (caller should skip normal rendering).
|
|
10573
10864
|
*/
|
|
10574
10865
|
renderEllipsisText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10575
|
-
const lineHeight = styles.fontSize.number
|
|
10866
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10576
10867
|
const firstTop = at(text.textBounds, 0).bounds.top;
|
|
10577
10868
|
if (!text.textBounds.every((tb) => Math.abs(tb.bounds.top - firstTop) < lineHeight * .5)) return false;
|
|
10578
10869
|
let fullText = text.textBounds.map((tb) => tb.text).join("").replace(/\s+/g, " ").trim();
|
|
@@ -10721,6 +11012,8 @@ const createCanvasPath = (ctx, paths) => {
|
|
|
10721
11012
|
* ```
|
|
10722
11013
|
*/
|
|
10723
11014
|
var LRUMap = class {
|
|
11015
|
+
maxSize;
|
|
11016
|
+
_map;
|
|
10724
11017
|
constructor(maxSize) {
|
|
10725
11018
|
this.maxSize = maxSize;
|
|
10726
11019
|
this._map = /* @__PURE__ */ new Map();
|
|
@@ -10769,8 +11062,17 @@ var LRUMap = class {
|
|
|
10769
11062
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10770
11063
|
*/
|
|
10771
11064
|
var BackgroundRenderer = class {
|
|
11065
|
+
ctx;
|
|
11066
|
+
context;
|
|
11067
|
+
canvas;
|
|
11068
|
+
/**
|
|
11069
|
+
* Instance-level LRU cache for background-image patterns.
|
|
11070
|
+
* CanvasPatterns are tied to the rendering context and must not be
|
|
11071
|
+
* shared across different render passes. This cache lives for the
|
|
11072
|
+
* duration of one html2canvas() call.
|
|
11073
|
+
*/
|
|
11074
|
+
patternCache = new LRUMap(50);
|
|
10772
11075
|
constructor(deps) {
|
|
10773
|
-
this.patternCache = new LRUMap(50);
|
|
10774
11076
|
this.ctx = deps.ctx;
|
|
10775
11077
|
this.context = deps.context;
|
|
10776
11078
|
this.canvas = deps.canvas;
|
|
@@ -10817,7 +11119,6 @@ var BackgroundRenderer = class {
|
|
|
10817
11119
|
image = await this.context.cache.match(url);
|
|
10818
11120
|
} catch (e) {
|
|
10819
11121
|
this.context.logger.error(`Error loading background-image ${url}`);
|
|
10820
|
-
this.context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
10821
11122
|
}
|
|
10822
11123
|
if (image) {
|
|
10823
11124
|
const imageWidth = isNaN(image.width) || image.width === 0 ? 1 : image.width;
|
|
@@ -10856,34 +11157,13 @@ var BackgroundRenderer = class {
|
|
|
10856
11157
|
const gy0 = y + ly0;
|
|
10857
11158
|
const gy1 = y + ly1;
|
|
10858
11159
|
const processedStops = processColorStops(backgroundImage.stops, lineLength || 1);
|
|
10859
|
-
const
|
|
10860
|
-
const firstStop = at(processedStops, 0);
|
|
10861
|
-
const period = Math.max(lastStop.stop - firstStop.stop, .01);
|
|
10862
|
-
if (lastStop.stop - firstStop.stop < 1e-6) {
|
|
10863
|
-
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10864
|
-
gradient.addColorStop(0, asString(lastStop.color));
|
|
10865
|
-
gradient.addColorStop(1, asString(lastStop.color));
|
|
10866
|
-
this.path(path);
|
|
10867
|
-
this.ctx.fillStyle = gradient;
|
|
10868
|
-
this.ctx.fill();
|
|
10869
|
-
return;
|
|
10870
|
-
}
|
|
10871
|
-
const stops = [];
|
|
10872
|
-
const cycles = Math.ceil(1 / period);
|
|
10873
|
-
for (let k = 0; k < cycles; k++) for (const s of processedStops) {
|
|
10874
|
-
const stop = k * period + (s.stop - firstStop.stop);
|
|
10875
|
-
if (stop > 1) break;
|
|
10876
|
-
stops.push({
|
|
10877
|
-
stop,
|
|
10878
|
-
color: asString(s.color)
|
|
10879
|
-
});
|
|
10880
|
-
}
|
|
10881
|
-
stops.push({
|
|
10882
|
-
stop: 1,
|
|
10883
|
-
color: asString(lastStop.color)
|
|
10884
|
-
});
|
|
11160
|
+
const stacked = stackRepeatingStops(processedStops);
|
|
10885
11161
|
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10886
|
-
|
|
11162
|
+
if (!stacked) {
|
|
11163
|
+
const lastColor = asString(at(processedStops, processedStops.length - 1).color);
|
|
11164
|
+
gradient.addColorStop(0, lastColor);
|
|
11165
|
+
gradient.addColorStop(1, lastColor);
|
|
11166
|
+
} else stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
10887
11167
|
this.path(path);
|
|
10888
11168
|
this.ctx.fillStyle = gradient;
|
|
10889
11169
|
this.ctx.fill();
|
|
@@ -10936,37 +11216,25 @@ var BackgroundRenderer = class {
|
|
|
10936
11216
|
}
|
|
10937
11217
|
if (rx > 0 && ry > 0) {
|
|
10938
11218
|
const cacheKey = `rg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
10939
|
-
const
|
|
10940
|
-
const
|
|
11219
|
+
const processed = processColorStops(backgroundImage.stops, rx);
|
|
11220
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
10941
11221
|
let pattern = this.patternCache.get(cacheKey);
|
|
10942
11222
|
if (!pattern) {
|
|
10943
|
-
const
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
10949
|
-
stops.forEach((s) => gradient.addColorStop(s.stop, asString(s.color)));
|
|
10950
|
-
offCtx.fillStyle = gradient;
|
|
10951
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
10952
|
-
offCtx.fillRect(0, 0, rx * 2, rx * 2);
|
|
10953
|
-
pattern = this.ctx.createPattern(offscreen, "no-repeat");
|
|
10954
|
-
this.patternCache.set(cacheKey, pattern);
|
|
10955
|
-
}
|
|
10956
|
-
}
|
|
10957
|
-
if (pattern) {
|
|
10958
|
-
this.path(path);
|
|
10959
|
-
this.ctx.save();
|
|
10960
|
-
this.ctx.clip();
|
|
10961
|
-
if (lastStop) {
|
|
10962
|
-
this.ctx.fillStyle = asString(lastStop.color);
|
|
10963
|
-
this.ctx.fill();
|
|
10964
|
-
}
|
|
10965
|
-
this.ctx.translate(left + x - rx, top + y - ry);
|
|
10966
|
-
this.ctx.fillStyle = pattern;
|
|
10967
|
-
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
10968
|
-
this.ctx.restore();
|
|
11223
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11224
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, false);
|
|
11225
|
+
if (!rasterized) return;
|
|
11226
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11227
|
+
this.patternCache.set(cacheKey, pattern);
|
|
10969
11228
|
}
|
|
11229
|
+
this.path(path);
|
|
11230
|
+
this.ctx.save();
|
|
11231
|
+
this.ctx.clip();
|
|
11232
|
+
this.ctx.fillStyle = lastColor;
|
|
11233
|
+
this.ctx.fill();
|
|
11234
|
+
this.ctx.translate(left + x - rx, top + y - ry);
|
|
11235
|
+
this.ctx.fillStyle = pattern;
|
|
11236
|
+
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11237
|
+
this.ctx.restore();
|
|
10970
11238
|
}
|
|
10971
11239
|
}
|
|
10972
11240
|
/**
|
|
@@ -10993,40 +11261,14 @@ var BackgroundRenderer = class {
|
|
|
10993
11261
|
ry = Math.max(ry, .01);
|
|
10994
11262
|
}
|
|
10995
11263
|
if (!(rx > 0 && ry > 0)) return;
|
|
10996
|
-
const
|
|
10997
|
-
const firstStop = at(processed, 0);
|
|
10998
|
-
const lastStop = at(processed, processed.length - 1);
|
|
10999
|
-
const period = Math.max(lastStop.stop - firstStop.stop, .01);
|
|
11000
|
-
const stops = [];
|
|
11001
|
-
const rings = Math.ceil(1 / period);
|
|
11002
|
-
for (let k = 0; k < rings; k++) for (const s of processed) {
|
|
11003
|
-
const stop = k * period + (s.stop - firstStop.stop);
|
|
11004
|
-
if (stop > 1) break;
|
|
11005
|
-
stops.push({
|
|
11006
|
-
stop,
|
|
11007
|
-
color: asString(s.color)
|
|
11008
|
-
});
|
|
11009
|
-
}
|
|
11010
|
-
stops.push({
|
|
11011
|
-
stop: 1,
|
|
11012
|
-
color: asString(lastStop.color)
|
|
11013
|
-
});
|
|
11014
|
-
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${stops.length}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11264
|
+
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11015
11265
|
let pattern = this.patternCache.get(cacheKey);
|
|
11016
11266
|
if (!pattern) {
|
|
11017
|
-
const
|
|
11018
|
-
|
|
11019
|
-
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
11023
|
-
stops.forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
11024
|
-
offCtx.fillStyle = gradient;
|
|
11025
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
11026
|
-
offCtx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11027
|
-
pattern = this.ctx.createPattern(offscreen, "no-repeat");
|
|
11028
|
-
this.patternCache.set(cacheKey, pattern);
|
|
11029
|
-
}
|
|
11267
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11268
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, true);
|
|
11269
|
+
if (!rasterized) return;
|
|
11270
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11271
|
+
this.patternCache.set(cacheKey, pattern);
|
|
11030
11272
|
}
|
|
11031
11273
|
if (pattern) {
|
|
11032
11274
|
this.path(path);
|
|
@@ -11238,6 +11480,8 @@ const createPathFromCurves = (outer1, inner1, outer2, inner2) => {
|
|
|
11238
11480
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
11239
11481
|
*/
|
|
11240
11482
|
var BorderRenderer = class {
|
|
11483
|
+
ctx;
|
|
11484
|
+
pathCallbacks;
|
|
11241
11485
|
constructor(deps, pathCallbacks) {
|
|
11242
11486
|
this.ctx = deps.ctx;
|
|
11243
11487
|
this.pathCallbacks = pathCallbacks;
|
|
@@ -11414,6 +11658,7 @@ const resolveBorderImageOutset = (outset, borderWidths) => {
|
|
|
11414
11658
|
};
|
|
11415
11659
|
};
|
|
11416
11660
|
var BorderImageRenderer = class {
|
|
11661
|
+
ctx;
|
|
11417
11662
|
constructor(ctx) {
|
|
11418
11663
|
this.ctx = ctx;
|
|
11419
11664
|
}
|
|
@@ -11451,7 +11696,8 @@ var BorderImageRenderer = class {
|
|
|
11451
11696
|
dy: top,
|
|
11452
11697
|
dw: width - dL - dR,
|
|
11453
11698
|
dh: dT,
|
|
11454
|
-
repeat: repeat.horizontal
|
|
11699
|
+
repeat: repeat.horizontal,
|
|
11700
|
+
horizontal: true
|
|
11455
11701
|
},
|
|
11456
11702
|
{
|
|
11457
11703
|
sx: imgW - sR,
|
|
@@ -11462,7 +11708,8 @@ var BorderImageRenderer = class {
|
|
|
11462
11708
|
dy: top + dT,
|
|
11463
11709
|
dw: dR,
|
|
11464
11710
|
dh: height - dT - dB,
|
|
11465
|
-
repeat: repeat.vertical
|
|
11711
|
+
repeat: repeat.vertical,
|
|
11712
|
+
horizontal: false
|
|
11466
11713
|
},
|
|
11467
11714
|
{
|
|
11468
11715
|
sx: sL,
|
|
@@ -11473,7 +11720,8 @@ var BorderImageRenderer = class {
|
|
|
11473
11720
|
dy: top + height - dB,
|
|
11474
11721
|
dw: width - dL - dR,
|
|
11475
11722
|
dh: dB,
|
|
11476
|
-
repeat: repeat.horizontal
|
|
11723
|
+
repeat: repeat.horizontal,
|
|
11724
|
+
horizontal: true
|
|
11477
11725
|
},
|
|
11478
11726
|
{
|
|
11479
11727
|
sx: 0,
|
|
@@ -11484,33 +11732,33 @@ var BorderImageRenderer = class {
|
|
|
11484
11732
|
dy: top + dT,
|
|
11485
11733
|
dw: dL,
|
|
11486
11734
|
dh: height - dT - dB,
|
|
11487
|
-
repeat: repeat.vertical
|
|
11735
|
+
repeat: repeat.vertical,
|
|
11736
|
+
horizontal: false
|
|
11488
11737
|
}
|
|
11489
11738
|
];
|
|
11490
11739
|
for (const edge of edges) {
|
|
11491
11740
|
if (edge.sw <= 0 || edge.sh <= 0 || edge.dw <= 0 || edge.dh <= 0) continue;
|
|
11492
|
-
const isHorizontal = edge.dw >= edge.dh;
|
|
11493
11741
|
if (edge.repeat === 0) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy, edge.dw, edge.dh);
|
|
11494
|
-
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge,
|
|
11495
|
-
}
|
|
11496
|
-
if (slice.fill) {
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
}
|
|
11742
|
+
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge, edge.horizontal, edge.repeat === 2);
|
|
11743
|
+
}
|
|
11744
|
+
if (slice.fill) this.drawCenterRegion(image, {
|
|
11745
|
+
sx: sL,
|
|
11746
|
+
sy: sT,
|
|
11747
|
+
sw: imgW - sL - sR,
|
|
11748
|
+
sh: imgH - sT - sB
|
|
11749
|
+
}, {
|
|
11750
|
+
dx: left + dL,
|
|
11751
|
+
dy: top + dT,
|
|
11752
|
+
dw: width - dL - dR,
|
|
11753
|
+
dh: height - dT - dB
|
|
11754
|
+
}, repeat);
|
|
11507
11755
|
}
|
|
11508
11756
|
drawRegion(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
11509
11757
|
if (sw > 0 && sh > 0 && dw > 0 && dh > 0) this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
11510
11758
|
}
|
|
11511
|
-
drawRepeatedEdge(image, edge,
|
|
11512
|
-
const srcLength =
|
|
11513
|
-
const tgLength =
|
|
11759
|
+
drawRepeatedEdge(image, edge, horizontal, round) {
|
|
11760
|
+
const srcLength = horizontal ? edge.sw : edge.sh;
|
|
11761
|
+
const tgLength = horizontal ? edge.dw : edge.dh;
|
|
11514
11762
|
if (srcLength <= 0 || tgLength <= 0) return;
|
|
11515
11763
|
let tileSize;
|
|
11516
11764
|
let tileCount;
|
|
@@ -11527,14 +11775,45 @@ var BorderImageRenderer = class {
|
|
|
11527
11775
|
this.ctx.clip();
|
|
11528
11776
|
for (let i = 0; i < tileCount; i++) {
|
|
11529
11777
|
const offset = i * tileSize;
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
if (clampedSize <= 0) break;
|
|
11533
|
-
if (isHorizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, clampedSize, edge.dh);
|
|
11534
|
-
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, clampedSize);
|
|
11778
|
+
if (horizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, tileSize, edge.dh);
|
|
11779
|
+
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, tileSize);
|
|
11535
11780
|
}
|
|
11536
11781
|
this.ctx.restore();
|
|
11537
11782
|
}
|
|
11783
|
+
/**
|
|
11784
|
+
* Draw the center region of the border image, tiling each axis per its
|
|
11785
|
+
* border-image-repeat keyword (stretch spans the whole axis, repeat
|
|
11786
|
+
* tiles at source size with the overflow cropped, round scales the tile
|
|
11787
|
+
* to divide the axis evenly).
|
|
11788
|
+
*/
|
|
11789
|
+
drawCenterRegion(image, src, dst, repeat) {
|
|
11790
|
+
if (src.sw <= 0 || src.sh <= 0 || dst.dw <= 0 || dst.dh <= 0) return;
|
|
11791
|
+
const axis = (mode, srcLen, dstLen) => {
|
|
11792
|
+
if (mode === 0) return {
|
|
11793
|
+
size: dstLen,
|
|
11794
|
+
count: 1
|
|
11795
|
+
};
|
|
11796
|
+
if (mode === 2) {
|
|
11797
|
+
const count = Math.max(1, Math.round(dstLen / srcLen));
|
|
11798
|
+
return {
|
|
11799
|
+
size: dstLen / count,
|
|
11800
|
+
count
|
|
11801
|
+
};
|
|
11802
|
+
}
|
|
11803
|
+
return {
|
|
11804
|
+
size: srcLen,
|
|
11805
|
+
count: Math.max(1, Math.ceil(dstLen / srcLen))
|
|
11806
|
+
};
|
|
11807
|
+
};
|
|
11808
|
+
const columns = axis(repeat.horizontal, src.sw, dst.dw);
|
|
11809
|
+
const rows = axis(repeat.vertical, src.sh, dst.dh);
|
|
11810
|
+
this.ctx.save();
|
|
11811
|
+
this.ctx.beginPath();
|
|
11812
|
+
this.ctx.rect(dst.dx, dst.dy, dst.dw, dst.dh);
|
|
11813
|
+
this.ctx.clip();
|
|
11814
|
+
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);
|
|
11815
|
+
this.ctx.restore();
|
|
11816
|
+
}
|
|
11538
11817
|
};
|
|
11539
11818
|
//#endregion
|
|
11540
11819
|
//#region src/render/canvas/effects-renderer.ts
|
|
@@ -11588,10 +11867,17 @@ const scaleFilterBlur = (filter, scale) => scale === 1 ? filter : filter.replace
|
|
|
11588
11867
|
* `restore()` **once** when that effect is popped.
|
|
11589
11868
|
*/
|
|
11590
11869
|
var EffectsRenderer = class {
|
|
11870
|
+
ctx;
|
|
11871
|
+
pathCallback;
|
|
11872
|
+
scale;
|
|
11873
|
+
activeEffects = [];
|
|
11874
|
+
/** Whether a canvas state save was performed for the current batch. */
|
|
11875
|
+
didSave = false;
|
|
11876
|
+
/** Index (0-based, from start of activeEffects array) of the last
|
|
11877
|
+
* heavyweight effect in the batch — the one whose pop triggers
|
|
11878
|
+
* restore(). Set to -1 when no save was performed. */
|
|
11879
|
+
saveAtDepth = -1;
|
|
11591
11880
|
constructor(deps, pathCallback) {
|
|
11592
|
-
this.activeEffects = [];
|
|
11593
|
-
this.didSave = false;
|
|
11594
|
-
this.saveAtDepth = -1;
|
|
11595
11881
|
this.ctx = deps.ctx;
|
|
11596
11882
|
this.pathCallback = pathCallback;
|
|
11597
11883
|
this.scale = deps.scale ?? 1;
|
|
@@ -11692,8 +11978,11 @@ var EffectsRenderer = class {
|
|
|
11692
11978
|
* always fills the whole area — a mask surface is about alpha coverage, not
|
|
11693
11979
|
* about what is visible underneath.
|
|
11694
11980
|
*
|
|
11695
|
-
*
|
|
11696
|
-
*
|
|
11981
|
+
* Gradient layers share the rasterisation primitives of the background
|
|
11982
|
+
* renderer (gradient-rasterizer.ts): repeating gradients stack their stop
|
|
11983
|
+
* cycles, and the area beyond a radial gradient's ending shape keeps the
|
|
11984
|
+
* last stop's colour. Limitations (v1): mask-mode is alpha-only; layers
|
|
11985
|
+
* composite with source-over (≈ the spec-default `add`).
|
|
11697
11986
|
*/
|
|
11698
11987
|
/**
|
|
11699
11988
|
* CSS layer lists cycle: a single mask-size applies to every mask-image
|
|
@@ -11759,17 +12048,12 @@ const paintRadialLayer = (ctx, layer, area) => {
|
|
|
11759
12048
|
let [rx, ry] = calculateRadius(layer, cx, cy, width, height);
|
|
11760
12049
|
rx = Math.max(rx, .01);
|
|
11761
12050
|
ry = Math.max(ry, .01);
|
|
11762
|
-
const
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
processColorStops(layer.stops, rx * 2).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), asString(s.color)));
|
|
11769
|
-
offCtx.fillStyle = gradient;
|
|
11770
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
11771
|
-
offCtx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11772
|
-
ctx.drawImage(offscreen, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
12051
|
+
const ownerDocument = ctx.canvas.ownerDocument ?? document;
|
|
12052
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, layer.stops, isRepeatingRadialGradient(layer));
|
|
12053
|
+
if (!rasterized) return;
|
|
12054
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
12055
|
+
ctx.fillRect(area.left, area.top, area.width, area.height);
|
|
12056
|
+
ctx.drawImage(rasterized.canvas, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
11773
12057
|
};
|
|
11774
12058
|
/** Draw one gradient layer filling the whole mask area. */
|
|
11775
12059
|
const paintGradientLayer = (ctx, layer, area) => {
|
|
@@ -11783,12 +12067,31 @@ const paintGradientLayer = (ctx, layer, area) => {
|
|
|
11783
12067
|
if (layer.type === 1 || layer.type === 3) {
|
|
11784
12068
|
const linear = layer;
|
|
11785
12069
|
const [lineLength, lx0, lx1, ly0, ly1] = calculateGradientDirection(linear.angle || 0, width, height);
|
|
11786
|
-
|
|
11787
|
-
|
|
11788
|
-
|
|
12070
|
+
const processed = processColorStops(linear.stops, lineLength || 1);
|
|
12071
|
+
if (layer.type === 3) {
|
|
12072
|
+
const stacked = stackRepeatingStops(processed);
|
|
12073
|
+
if (!stacked) {
|
|
12074
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12075
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12076
|
+
return;
|
|
12077
|
+
}
|
|
12078
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12079
|
+
stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
12080
|
+
} else {
|
|
12081
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12082
|
+
toCanvasStops(processed).forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
12083
|
+
}
|
|
12084
|
+
} else if (layer.type === 5 || layer.type === 6) {
|
|
11789
12085
|
const conic = layer;
|
|
12086
|
+
const processed = processColorStops(conic.stops, 1);
|
|
12087
|
+
const repeating = layer.type === 6;
|
|
12088
|
+
if (repeating && !stackRepeatingStops(processed)) {
|
|
12089
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12090
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12091
|
+
return;
|
|
12092
|
+
}
|
|
11790
12093
|
gradient = ctx.createConicGradient(conic.angle - Math.PI / 2, area.left + width / 2, area.top + height / 2);
|
|
11791
|
-
|
|
12094
|
+
((repeating ? stackRepeatingStops(processed) : null) ?? toCanvasStops(processed)).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
11792
12095
|
}
|
|
11793
12096
|
if (gradient) {
|
|
11794
12097
|
ctx.fillStyle = gradient;
|
|
@@ -11855,7 +12158,11 @@ const calculateObjectFitRendering = (intrinsicWidth, intrinsicHeight, box, objec
|
|
|
11855
12158
|
dh = sh;
|
|
11856
12159
|
}
|
|
11857
12160
|
} else if (objectFit === 16) {
|
|
11858
|
-
|
|
12161
|
+
const containW = imgRatio > boxRatio ? dw : dh * imgRatio;
|
|
12162
|
+
const containH = imgRatio > boxRatio ? dw / imgRatio : dh;
|
|
12163
|
+
const noneW = Math.min(sw, dw);
|
|
12164
|
+
const noneH = Math.min(sh, dh);
|
|
12165
|
+
if (containW * containH < noneW * noneH) {
|
|
11859
12166
|
if (imgRatio > boxRatio) {
|
|
11860
12167
|
dh = dw / imgRatio;
|
|
11861
12168
|
dy += (box.height - dh) * posY;
|
|
@@ -11906,14 +12213,12 @@ async function renderReplacedElements(ctx, context, options, iframeRendererFacto
|
|
|
11906
12213
|
ctx.imageSmoothingEnabled = prevSmoothing;
|
|
11907
12214
|
} catch (e) {
|
|
11908
12215
|
context.logger.error(`Error loading image ${container.src}`);
|
|
11909
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11910
12216
|
}
|
|
11911
12217
|
if (container instanceof CanvasElementContainer) renderReplacedElementFn(container, curves, container.canvas);
|
|
11912
12218
|
if (container instanceof SVGElementContainer) try {
|
|
11913
12219
|
renderReplacedElementFn(container, curves, await context.cache.match(container.svg));
|
|
11914
12220
|
} catch (e) {
|
|
11915
12221
|
context.logger.error(`Error loading svg ${container.svg.substring(0, 255)}`);
|
|
11916
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11917
12222
|
}
|
|
11918
12223
|
if (container instanceof IFrameElementContainer && container.tree) {
|
|
11919
12224
|
const canvas = await iframeRendererFactory(context, {
|
|
@@ -12061,7 +12366,6 @@ async function renderListMarker(ctx, context, textRenderer, paint, container, st
|
|
|
12061
12366
|
ctx.drawImage(image, container.bounds.left - (markerWidth + 10), markerCenterY - markerHeight / 2, markerWidth, markerHeight);
|
|
12062
12367
|
} catch (e) {
|
|
12063
12368
|
context.logger.error(`Error loading list-style-image ${url}`);
|
|
12064
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
12065
12369
|
}
|
|
12066
12370
|
}
|
|
12067
12371
|
} else if (paint.listValue && container.styles.listStyleType !== -1) {
|
|
@@ -12248,7 +12552,10 @@ const paintShadowSurface = async (ctx, paint, shadow, options, budget, space) =>
|
|
|
12248
12552
|
else createCanvasPath(sourceCtx, path);
|
|
12249
12553
|
sourceCtx.fillStyle = asString(shadow.color);
|
|
12250
12554
|
sourceCtx.fill(shadow.inset ? "evenodd" : "nonzero");
|
|
12251
|
-
filtered = await renderFilterSurface(source, {
|
|
12555
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
12556
|
+
kind: "blur",
|
|
12557
|
+
value: blur
|
|
12558
|
+
}] }, 1, space.scale, options.signal);
|
|
12252
12559
|
ctx.save();
|
|
12253
12560
|
try {
|
|
12254
12561
|
if (shadow.inset) {
|
|
@@ -12334,6 +12641,10 @@ const paintBoxShadow = async (ctx, paint, shadow, options, budget) => {
|
|
|
12334
12641
|
//#endregion
|
|
12335
12642
|
//#region src/render/canvas/text-clip-renderer.ts
|
|
12336
12643
|
var TextClipRenderer = class {
|
|
12644
|
+
ctx;
|
|
12645
|
+
context;
|
|
12646
|
+
scale;
|
|
12647
|
+
createFontStyle;
|
|
12337
12648
|
constructor(deps) {
|
|
12338
12649
|
this.ctx = deps.ctx;
|
|
12339
12650
|
this.context = deps.context;
|
|
@@ -12353,59 +12664,69 @@ var TextClipRenderer = class {
|
|
|
12353
12664
|
const deviceHeight = Math.ceil(bounds.height * scale);
|
|
12354
12665
|
const offscreen = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12355
12666
|
if (!offscreen) return;
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
bounds,
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
mask
|
|
12392
|
-
mask
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12667
|
+
let mask = null;
|
|
12668
|
+
let composite = null;
|
|
12669
|
+
let shadowCanvases = null;
|
|
12670
|
+
try {
|
|
12671
|
+
offscreen.ctx.scale(scale, scale);
|
|
12672
|
+
const [fontString] = this.createFontStyle(styles);
|
|
12673
|
+
offscreen.ctx.font = fontString ?? "";
|
|
12674
|
+
offscreen.ctx.textBaseline = "alphabetic";
|
|
12675
|
+
offscreen.ctx.textAlign = "left";
|
|
12676
|
+
offscreen.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
12677
|
+
const baseline = measureBaseline(offscreen.ctx, styles.fontSize.number);
|
|
12678
|
+
const bgRenderer = new BackgroundRenderer({
|
|
12679
|
+
ctx: offscreen.ctx,
|
|
12680
|
+
context: this.context,
|
|
12681
|
+
canvas: offscreen.canvas,
|
|
12682
|
+
options: {
|
|
12683
|
+
width,
|
|
12684
|
+
height,
|
|
12685
|
+
scale: 1
|
|
12686
|
+
}
|
|
12687
|
+
});
|
|
12688
|
+
if (!isTransparent(styles.backgroundColor)) {
|
|
12689
|
+
offscreen.ctx.fillStyle = asString(styles.backgroundColor);
|
|
12690
|
+
offscreen.ctx.fillRect(0, 0, width, height);
|
|
12691
|
+
}
|
|
12692
|
+
offscreen.ctx.save();
|
|
12693
|
+
offscreen.ctx.translate(-bounds.left, -bounds.top);
|
|
12694
|
+
await bgRenderer.renderBackgroundImage(container);
|
|
12695
|
+
offscreen.ctx.restore();
|
|
12696
|
+
const drawOptions = {
|
|
12697
|
+
bounds,
|
|
12698
|
+
baseline,
|
|
12699
|
+
letterSpacing: styles.letterSpacing,
|
|
12700
|
+
writingMode: styles.writingMode
|
|
12701
|
+
};
|
|
12702
|
+
mask = this.createGlyphLayer(ownerDocument, deviceWidth, deviceHeight, offscreen.ctx);
|
|
12703
|
+
if (!mask) return;
|
|
12704
|
+
const hasStroke = !!styles.webkitTextStrokeWidth;
|
|
12705
|
+
if (hasStroke) {
|
|
12706
|
+
mask.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);
|
|
12707
|
+
mask.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
12708
|
+
mask.ctx.lineJoin = getTextStrokeLineJoin();
|
|
12709
|
+
}
|
|
12710
|
+
for (const textNode of container.textNodes) for (const textBound of textNode.textBounds) this.drawGlyphs(mask, textBound, drawOptions, (ctx, text, x, y) => {
|
|
12711
|
+
ctx.fillText(text, x, y);
|
|
12712
|
+
if (hasStroke) ctx.strokeText(text, x, y);
|
|
12713
|
+
});
|
|
12714
|
+
offscreen.ctx.globalCompositeOperation = "destination-in";
|
|
12715
|
+
offscreen.ctx.drawImage(mask.canvas, 0, 0, width, height);
|
|
12716
|
+
shadowCanvases = this.renderShadowSilhouettes(paint, ownerDocument, deviceWidth, deviceHeight, offscreen.ctx, styles, drawOptions);
|
|
12717
|
+
if (shadowCanvases) {
|
|
12718
|
+
composite = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12719
|
+
if (!composite) return;
|
|
12720
|
+
for (const shadowCanvas of shadowCanvases) composite.ctx.drawImage(shadowCanvas, 0, 0);
|
|
12721
|
+
composite.ctx.drawImage(offscreen.canvas, 0, 0);
|
|
12722
|
+
this.ctx.drawImage(composite.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12723
|
+
} else this.ctx.drawImage(offscreen.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12724
|
+
} finally {
|
|
12725
|
+
releaseSurface(offscreen.canvas);
|
|
12726
|
+
if (mask) releaseSurface(mask.canvas);
|
|
12727
|
+
if (composite) releaseSurface(composite.canvas);
|
|
12728
|
+
if (shadowCanvases) shadowCanvases.forEach(releaseSurface);
|
|
12729
|
+
}
|
|
12409
12730
|
}
|
|
12410
12731
|
createLayer(ownerDocument, width, height) {
|
|
12411
12732
|
const canvas = ownerDocument.createElement("canvas");
|
|
@@ -12477,20 +12798,29 @@ var TextClipRenderer = class {
|
|
|
12477
12798
|
}
|
|
12478
12799
|
return canvases.length ? canvases : null;
|
|
12479
12800
|
}
|
|
12480
|
-
getTextStrokeLineJoin() {
|
|
12481
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
12482
|
-
}
|
|
12483
12801
|
};
|
|
12484
12802
|
//#endregion
|
|
12485
12803
|
//#region src/render/canvas/canvas-renderer.ts
|
|
12486
12804
|
var CanvasRenderer = class CanvasRenderer {
|
|
12805
|
+
surfaceRoot;
|
|
12806
|
+
surfaceBudget;
|
|
12807
|
+
canvas;
|
|
12808
|
+
ctx;
|
|
12809
|
+
context;
|
|
12810
|
+
options;
|
|
12811
|
+
backgroundRenderer;
|
|
12812
|
+
borderRenderer;
|
|
12813
|
+
borderImageRenderer;
|
|
12814
|
+
effectsRenderer;
|
|
12815
|
+
textRenderer;
|
|
12816
|
+
textClipRenderer;
|
|
12817
|
+
legacySubtree = false;
|
|
12487
12818
|
constructor(context, options, surfaceRoot, surfaceBudget = { pixels: 0 }) {
|
|
12488
12819
|
this.surfaceRoot = surfaceRoot;
|
|
12489
12820
|
this.surfaceBudget = surfaceBudget;
|
|
12490
|
-
this.legacySubtree = false;
|
|
12491
12821
|
this.context = context;
|
|
12492
12822
|
this.options = options;
|
|
12493
|
-
this.canvas = options.canvas ? options.canvas :
|
|
12823
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
12494
12824
|
const ctx = this.canvas.getContext("2d");
|
|
12495
12825
|
if (!ctx) {
|
|
12496
12826
|
if (!options.canvas) releaseSurface(this.canvas);
|
|
@@ -12543,11 +12873,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12543
12873
|
async renderStack(stack) {
|
|
12544
12874
|
const styles = stack.element.container.styles;
|
|
12545
12875
|
if (styles.isVisible()) {
|
|
12546
|
-
const filter =
|
|
12876
|
+
const filter = parseFilterChain(styles.filter);
|
|
12877
|
+
const hasFilter = filter !== null && filter.functions.length > 0;
|
|
12547
12878
|
const hasMask = styles.maskImage.length > 0;
|
|
12548
12879
|
const reflect = styles.webkitBoxReflect;
|
|
12549
12880
|
const hasBlend = styles.mixBlendMode !== MIX_BLEND_MODE$1.NORMAL;
|
|
12550
|
-
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter && (
|
|
12881
|
+
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter !== null && (hasFilter || styles.opacity < 1)) && this.canComposite(stack.element)) {
|
|
12551
12882
|
if (!await this.renderCompositedStack(stack, filter, hasMask, reflect, hasBlend)) {
|
|
12552
12883
|
this.legacySubtree = true;
|
|
12553
12884
|
try {
|
|
@@ -12564,7 +12895,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12564
12895
|
canComposite(paint) {
|
|
12565
12896
|
const supported = (container) => {
|
|
12566
12897
|
const styles = container.styles;
|
|
12567
|
-
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) &&
|
|
12898
|
+
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) && parseFilterChain(styles.filter) !== null;
|
|
12568
12899
|
};
|
|
12569
12900
|
const subtree = (container) => supported(container) && container.elements.every(subtree);
|
|
12570
12901
|
let ancestor = paint.parent;
|
|
@@ -12632,7 +12963,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12632
12963
|
async applyMask(surface, styles, bounds) {
|
|
12633
12964
|
const ctx = surface.getContext("2d");
|
|
12634
12965
|
if (!ctx) return;
|
|
12635
|
-
const maskCanvas =
|
|
12966
|
+
const maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12636
12967
|
maskCanvas.width = surface.width;
|
|
12637
12968
|
maskCanvas.height = surface.height;
|
|
12638
12969
|
const maskCtx = maskCanvas.getContext("2d");
|
|
@@ -12674,7 +13005,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12674
13005
|
let refCanvas;
|
|
12675
13006
|
let maskCanvas;
|
|
12676
13007
|
try {
|
|
12677
|
-
refCanvas =
|
|
13008
|
+
refCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12678
13009
|
refCanvas.width = w;
|
|
12679
13010
|
refCanvas.height = h;
|
|
12680
13011
|
const ctx = refCanvas.getContext("2d");
|
|
@@ -12696,7 +13027,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12696
13027
|
ctx.restore();
|
|
12697
13028
|
}
|
|
12698
13029
|
if (reflect.mask) {
|
|
12699
|
-
maskCanvas =
|
|
13030
|
+
maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12700
13031
|
maskCanvas.width = w;
|
|
12701
13032
|
maskCanvas.height = h;
|
|
12702
13033
|
const mctx = maskCanvas.getContext("2d");
|
|
@@ -12820,18 +13151,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12820
13151
|
await this.renderStack(child);
|
|
12821
13152
|
}
|
|
12822
13153
|
}
|
|
12823
|
-
mask(paths) {
|
|
12824
|
-
this.ctx.beginPath();
|
|
12825
|
-
const x = this.options.x;
|
|
12826
|
-
const y = this.options.y;
|
|
12827
|
-
this.ctx.moveTo(x, y);
|
|
12828
|
-
this.ctx.lineTo(x + this.options.width, y);
|
|
12829
|
-
this.ctx.lineTo(x + this.options.width, y + this.options.height);
|
|
12830
|
-
this.ctx.lineTo(x, y + this.options.height);
|
|
12831
|
-
this.ctx.lineTo(x, y);
|
|
12832
|
-
this.formatPath(paths.slice(0).reverse());
|
|
12833
|
-
this.ctx.closePath();
|
|
12834
|
-
}
|
|
12835
13154
|
path(paths) {
|
|
12836
13155
|
createCanvasPath(this.ctx, paths);
|
|
12837
13156
|
}
|
|
@@ -12853,7 +13172,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12853
13172
|
let source;
|
|
12854
13173
|
let filtered;
|
|
12855
13174
|
try {
|
|
12856
|
-
source =
|
|
13175
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
12857
13176
|
source.width = width;
|
|
12858
13177
|
source.height = height;
|
|
12859
13178
|
const ctx = source.getContext("2d");
|
|
@@ -12863,7 +13182,10 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12863
13182
|
createCanvasPath(ctx, transformPath(calculateBorderBoxPath(paint.curves), -spread, -spread, 2 * spread, 2 * spread));
|
|
12864
13183
|
ctx.fillStyle = asString(shadow.color);
|
|
12865
13184
|
ctx.fill();
|
|
12866
|
-
filtered = await renderFilterSurface(source, {
|
|
13185
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
13186
|
+
kind: "blur",
|
|
13187
|
+
value: blur
|
|
13188
|
+
}] }, 1, scale, this.options.signal);
|
|
12867
13189
|
this.ctx.save();
|
|
12868
13190
|
try {
|
|
12869
13191
|
this.ctx.beginPath();
|
|
@@ -13039,9 +13361,19 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13039
13361
|
if (source.type === 1 || source.type === 3) {
|
|
13040
13362
|
const gradientImage = source;
|
|
13041
13363
|
const [lineLength, x0, y0, x1, y1] = calculateGradientDirection(gradientImage.angle, width, height);
|
|
13364
|
+
const processed = processColorStops(gradientImage.stops, lineLength || width);
|
|
13365
|
+
const repeating = source.type === 3;
|
|
13366
|
+
const stacked = repeating ? stackRepeatingStops(processed) : null;
|
|
13042
13367
|
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
13043
|
-
|
|
13044
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)),
|
|
13368
|
+
if (stacked) stacked.forEach((colorStop) => {
|
|
13369
|
+
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), colorStop.color);
|
|
13370
|
+
});
|
|
13371
|
+
else if (repeating) {
|
|
13372
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
13373
|
+
gradient.addColorStop(0, lastColor);
|
|
13374
|
+
gradient.addColorStop(1, lastColor);
|
|
13375
|
+
} else toCanvasStops(processed).forEach((colorStop) => {
|
|
13376
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
13045
13377
|
});
|
|
13046
13378
|
ctx.fillStyle = gradient;
|
|
13047
13379
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -13049,21 +13381,17 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13049
13381
|
}
|
|
13050
13382
|
if (source.type === 2 || source.type === 4) {
|
|
13051
13383
|
const gradientImage = source;
|
|
13052
|
-
const
|
|
13053
|
-
const
|
|
13384
|
+
const position = gradientImage.position.length === 0 ? [FIFTY_PERCENT] : gradientImage.position;
|
|
13385
|
+
const cx = getAbsoluteValue(at(position, 0), width);
|
|
13386
|
+
const cy = getAbsoluteValue(at(position, position.length - 1), height);
|
|
13054
13387
|
const [rx, ry] = calculateRadius(gradientImage, cx, cy, width, height);
|
|
13055
13388
|
if (rx <= 0 || ry <= 0) return null;
|
|
13056
|
-
ctx.
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
ctx.
|
|
13060
|
-
const gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, rx);
|
|
13061
|
-
processColorStops(gradientImage.stops, rx).forEach((colorStop) => {
|
|
13062
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), asString(colorStop.color));
|
|
13063
|
-
});
|
|
13064
|
-
ctx.fillStyle = gradient;
|
|
13389
|
+
const ownerDocument = this.ctx.canvas.ownerDocument ?? document;
|
|
13390
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, gradientImage.stops, source.type === 4);
|
|
13391
|
+
if (!rasterized) return null;
|
|
13392
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
13065
13393
|
ctx.fillRect(0, 0, width, height);
|
|
13066
|
-
ctx.
|
|
13394
|
+
ctx.drawImage(rasterized.canvas, cx - rx, cy - ry, rx * 2, ry * 2);
|
|
13067
13395
|
return canvas;
|
|
13068
13396
|
}
|
|
13069
13397
|
if (source.type === 5 || source.type === 6) {
|
|
@@ -13108,12 +13436,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13108
13436
|
}
|
|
13109
13437
|
/**
|
|
13110
13438
|
* Filter the already-painted content beneath the element's border box and
|
|
13111
|
-
* paint the result back, approximating CSS backdrop-filter for the
|
|
13112
|
-
*
|
|
13439
|
+
* paint the result back, approximating CSS backdrop-filter for the chain
|
|
13440
|
+
* subset the filter surface backends support.
|
|
13113
13441
|
*/
|
|
13114
13442
|
async renderBackdropFilter(paint) {
|
|
13115
|
-
const filter =
|
|
13116
|
-
if (!filter ||
|
|
13443
|
+
const filter = parseFilterChain(paint.container.styles.backdropFilter);
|
|
13444
|
+
if (!filter || filter.functions.length === 0) return;
|
|
13117
13445
|
const bounds = paint.container.bounds;
|
|
13118
13446
|
if (bounds.width <= 0 || bounds.height <= 0) return;
|
|
13119
13447
|
const scale = this.options.scale;
|
|
@@ -13125,7 +13453,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13125
13453
|
let source;
|
|
13126
13454
|
let filtered;
|
|
13127
13455
|
try {
|
|
13128
|
-
source =
|
|
13456
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
13129
13457
|
source.width = width;
|
|
13130
13458
|
source.height = height;
|
|
13131
13459
|
const srcCtx = source.getContext("2d");
|
|
@@ -13133,7 +13461,15 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13133
13461
|
const sx = Math.round((bounds.left - this.options.x) * scale);
|
|
13134
13462
|
const sy = Math.round((bounds.top - this.options.y) * scale);
|
|
13135
13463
|
srcCtx.drawImage(this.canvas, sx, sy, width, height, 0, 0, width, height);
|
|
13136
|
-
|
|
13464
|
+
try {
|
|
13465
|
+
filtered = await renderFilterSurface(source, filter, 1, scale, this.options.signal);
|
|
13466
|
+
} catch (error) {
|
|
13467
|
+
if (error instanceof FilterSurfaceError) {
|
|
13468
|
+
this.context.logger.info(`${error.message}; rendering without the backdrop effect`);
|
|
13469
|
+
return;
|
|
13470
|
+
}
|
|
13471
|
+
throw error;
|
|
13472
|
+
}
|
|
13137
13473
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13138
13474
|
this.ctx.save();
|
|
13139
13475
|
try {
|
|
@@ -13180,10 +13516,14 @@ const hasTextBackgroundClip = (styles) => {
|
|
|
13180
13516
|
//#endregion
|
|
13181
13517
|
//#region src/render/canvas/foreignobject-renderer.ts
|
|
13182
13518
|
var ForeignObjectRenderer = class {
|
|
13519
|
+
canvas;
|
|
13520
|
+
ctx;
|
|
13521
|
+
options;
|
|
13522
|
+
context;
|
|
13183
13523
|
constructor(context, options) {
|
|
13184
13524
|
this.context = context;
|
|
13185
13525
|
this.options = options;
|
|
13186
|
-
this.canvas = options.canvas ? options.canvas :
|
|
13526
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
13187
13527
|
const ctx = this.canvas.getContext("2d");
|
|
13188
13528
|
if (!ctx) throw new Error("Failed to get 2D rendering context from canvas");
|
|
13189
13529
|
this.ctx = ctx;
|
|
@@ -13197,19 +13537,49 @@ var ForeignObjectRenderer = class {
|
|
|
13197
13537
|
}
|
|
13198
13538
|
async render(element) {
|
|
13199
13539
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13200
|
-
const
|
|
13201
|
-
const
|
|
13540
|
+
const restoreRootOffsets = stripRootOffsets(element);
|
|
13541
|
+
const svg = createForeignObjectSVG(this.options.width, this.options.height, 0, 0, element);
|
|
13542
|
+
const imagePromise = loadSerializedSVG(svg);
|
|
13543
|
+
restoreRootOffsets();
|
|
13544
|
+
const img = await imagePromise;
|
|
13545
|
+
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13202
13546
|
if (this.options.backgroundColor) {
|
|
13203
13547
|
this.ctx.fillStyle = asString(this.options.backgroundColor);
|
|
13204
|
-
this.ctx.fillRect(
|
|
13548
|
+
this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13205
13549
|
}
|
|
13206
|
-
this.ctx.drawImage(img,
|
|
13550
|
+
this.ctx.drawImage(img, this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13207
13551
|
return this.canvas;
|
|
13208
13552
|
}
|
|
13209
13553
|
};
|
|
13554
|
+
/**
|
|
13555
|
+
* Temporarily neutralize the root element's layout offsets for SVG
|
|
13556
|
+
* serialization. `top/right/bottom/left` reset to `auto` (inset values of
|
|
13557
|
+
* positioned elements are baked into the capture rect); margins to `0`.
|
|
13558
|
+
*/
|
|
13559
|
+
const ROOT_OFFSET_PROPERTIES = [
|
|
13560
|
+
"marginTop",
|
|
13561
|
+
"marginRight",
|
|
13562
|
+
"marginBottom",
|
|
13563
|
+
"marginLeft",
|
|
13564
|
+
"top",
|
|
13565
|
+
"right",
|
|
13566
|
+
"bottom",
|
|
13567
|
+
"left"
|
|
13568
|
+
];
|
|
13569
|
+
const stripRootOffsets = (element) => {
|
|
13570
|
+
const style = element.style;
|
|
13571
|
+
const previous = ROOT_OFFSET_PROPERTIES.map((property) => [property, style[property]]);
|
|
13572
|
+
for (const property of ROOT_OFFSET_PROPERTIES) style[property] = property.startsWith("margin") ? "0px" : "auto";
|
|
13573
|
+
return () => {
|
|
13574
|
+
for (const [property, value] of previous) style[property] = value;
|
|
13575
|
+
};
|
|
13576
|
+
};
|
|
13210
13577
|
//#endregion
|
|
13211
13578
|
//#region src/core/logger.ts
|
|
13212
13579
|
var Logger = class {
|
|
13580
|
+
id;
|
|
13581
|
+
enabled;
|
|
13582
|
+
start;
|
|
13213
13583
|
constructor({ id, enabled }) {
|
|
13214
13584
|
this.id = id;
|
|
13215
13585
|
this.enabled = enabled;
|
|
@@ -13245,17 +13615,33 @@ var Logger = class {
|
|
|
13245
13615
|
//#endregion
|
|
13246
13616
|
//#region src/core/cache-storage.ts
|
|
13247
13617
|
var Cache = class {
|
|
13618
|
+
context;
|
|
13619
|
+
_options;
|
|
13620
|
+
_cache = /* @__PURE__ */ new Map();
|
|
13621
|
+
maxSize;
|
|
13622
|
+
_pendingOperations = /* @__PURE__ */ new Map();
|
|
13623
|
+
/** When true, addImage() collects URLs without starting loads. */
|
|
13624
|
+
_deferMode = false;
|
|
13625
|
+
/** URLs collected during defer mode, pending batch preload. */
|
|
13626
|
+
_collectedUrls = /* @__PURE__ */ new Set();
|
|
13627
|
+
/**
|
|
13628
|
+
* Eviction is suspended between startDefer() and the end of preloadAll():
|
|
13629
|
+
* the render pipeline loads every image it is going to paint inside that
|
|
13630
|
+
* window, and match() never reloads, so an LRU eviction there would
|
|
13631
|
+
* silently drop images from the output on pages with more unique images
|
|
13632
|
+
* than maxSize.
|
|
13633
|
+
*
|
|
13634
|
+
* A counter (not a flag) keeps nested/overlapping defer windows — e.g.
|
|
13635
|
+
* two renders sharing one cache via `config.cache` — suspended until the
|
|
13636
|
+
* last one finishes preloading.
|
|
13637
|
+
*/
|
|
13638
|
+
_evictionSuspendCount = 0;
|
|
13248
13639
|
get _evictionEnabled() {
|
|
13249
13640
|
return this._evictionSuspendCount === 0;
|
|
13250
13641
|
}
|
|
13251
13642
|
constructor(context, _options) {
|
|
13252
13643
|
this.context = context;
|
|
13253
13644
|
this._options = _options;
|
|
13254
|
-
this._cache = /* @__PURE__ */ new Map();
|
|
13255
|
-
this._pendingOperations = /* @__PURE__ */ new Map();
|
|
13256
|
-
this._deferMode = false;
|
|
13257
|
-
this._collectedUrls = /* @__PURE__ */ new Set();
|
|
13258
|
-
this._evictionSuspendCount = 0;
|
|
13259
13645
|
this.maxSize = _options.maxCacheSize ?? 100;
|
|
13260
13646
|
if (this.maxSize < 1) throw new Error("Cache maxSize must be at least 1");
|
|
13261
13647
|
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).`);
|
|
@@ -13273,14 +13659,18 @@ var Cache = class {
|
|
|
13273
13659
|
* an optional concurrency cap to avoid overwhelming the browser's network
|
|
13274
13660
|
* stack (default: 10 concurrent loads).
|
|
13275
13661
|
* After this call returns, all images are either loaded (cache hit) or
|
|
13276
|
-
* failed (logged). Subsequent cache.match()
|
|
13662
|
+
* failed (logged and reported via onError). Subsequent cache.match()
|
|
13663
|
+
* calls return immediately.
|
|
13277
13664
|
*
|
|
13278
13665
|
* @param concurrency - Max concurrent image loads (1–100, default 10).
|
|
13279
13666
|
* @param onProgress - Invoked once before loading and after each settled
|
|
13280
13667
|
* batch with (settledCount, totalCount), enabling coarse progress UI.
|
|
13281
13668
|
* Not invoked when there is nothing to load.
|
|
13669
|
+
* @param signal - Checked before each batch; aborting rejects the whole
|
|
13670
|
+
* preload with an AbortError instead of waiting for the remaining
|
|
13671
|
+
* batches to finish.
|
|
13282
13672
|
*/
|
|
13283
|
-
async preloadAll(concurrency = 10, onProgress) {
|
|
13673
|
+
async preloadAll(concurrency = 10, onProgress, signal) {
|
|
13284
13674
|
this._deferMode = false;
|
|
13285
13675
|
const urls = Array.from(this._collectedUrls);
|
|
13286
13676
|
this._collectedUrls.clear();
|
|
@@ -13289,11 +13679,19 @@ var Cache = class {
|
|
|
13289
13679
|
const limit = Math.max(1, Math.min(concurrency, 100));
|
|
13290
13680
|
this.context.logger.debug(`Preloading ${urls.length} image(s) with concurrency ${limit}`);
|
|
13291
13681
|
let settled = 0;
|
|
13682
|
+
const abortPromise = signal ? new Promise((_, reject) => {
|
|
13683
|
+
const onAbort = () => reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
13684
|
+
if (signal.aborted) onAbort();
|
|
13685
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
13686
|
+
}) : null;
|
|
13687
|
+
abortPromise?.catch(() => void 0);
|
|
13292
13688
|
onProgress?.(0, urls.length);
|
|
13293
13689
|
for (let i = 0; i < urls.length; i += limit) {
|
|
13690
|
+
throwIfAborted(signal);
|
|
13294
13691
|
const batch = urls.slice(i, i + limit);
|
|
13295
|
-
|
|
13296
|
-
|
|
13692
|
+
batch.map((url) => this._addImageWithPending(url));
|
|
13693
|
+
const batchSettled = Promise.allSettled(batch.map((url) => this._cache.get(url)?.value ?? Promise.resolve()));
|
|
13694
|
+
await (abortPromise ? Promise.race([batchSettled, abortPromise]) : batchSettled);
|
|
13297
13695
|
settled += batch.length;
|
|
13298
13696
|
onProgress?.(settled, urls.length);
|
|
13299
13697
|
}
|
|
@@ -13336,7 +13734,10 @@ var Cache = class {
|
|
|
13336
13734
|
const timeoutMs = this._options.imageTimeout ?? 15e3;
|
|
13337
13735
|
const imageWithTimeout = this.withTimeout(this.loadImage(src), timeoutMs, `Timed out (${timeoutMs}ms) loading image`);
|
|
13338
13736
|
imageWithTimeout.catch((error) => {
|
|
13339
|
-
|
|
13737
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
13738
|
+
const message = `Failed to load image ${src.substring(0, 256)}: ${reason}`;
|
|
13739
|
+
this.context.logger.error(message);
|
|
13740
|
+
this.context.onError?.(new Error(message));
|
|
13340
13741
|
});
|
|
13341
13742
|
this.set(src, imageWithTimeout);
|
|
13342
13743
|
}
|
|
@@ -13398,18 +13799,22 @@ var Cache = class {
|
|
|
13398
13799
|
const isSameOrigin = typeof this._options.customIsSameOrigin === "function" ? await this._options.customIsSameOrigin(key, defaultIsSameOrigin) : defaultIsSameOrigin(key);
|
|
13399
13800
|
const canAttemptCors = !isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && typeof this._options.proxy !== "string";
|
|
13400
13801
|
const useCORS = !isInlineImage(key) && (this._options.useCORS === true || canAttemptCors) && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
|
|
13401
|
-
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" &&
|
|
13802
|
+
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" && !useCORS;
|
|
13402
13803
|
if (!isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && !useProxy && !useCORS) return;
|
|
13403
13804
|
let src = key;
|
|
13404
13805
|
if (useProxy) src = await this.proxy(src);
|
|
13405
13806
|
this.context.logger.debug(`Added image ${key.substring(0, 256)}`);
|
|
13807
|
+
const imageConstructor = this.context.config.window.Image ?? Image;
|
|
13406
13808
|
return await new Promise((resolve, reject) => {
|
|
13407
|
-
const img = new
|
|
13809
|
+
const img = new imageConstructor();
|
|
13408
13810
|
img.onload = () => resolve(img);
|
|
13409
13811
|
img.onerror = reject;
|
|
13410
13812
|
if (isInlineBase64Image(src) || useCORS) img.crossOrigin = "anonymous";
|
|
13411
13813
|
img.src = src;
|
|
13412
|
-
if (img.complete === true)
|
|
13814
|
+
if (img.complete === true) {
|
|
13815
|
+
if (typeof img.decode === "function") img.decode().then(() => resolve(img), () => reject(/* @__PURE__ */ new Error(`Failed to decode image ${src.substring(0, 256)}`)));
|
|
13816
|
+
else setTimeout(() => resolve(img), 500);
|
|
13817
|
+
}
|
|
13413
13818
|
});
|
|
13414
13819
|
}
|
|
13415
13820
|
has(key) {
|
|
@@ -13423,23 +13828,19 @@ var Cache = class {
|
|
|
13423
13828
|
if (!proxy) throw new Error("No proxy defined");
|
|
13424
13829
|
const key = src.substring(0, 256);
|
|
13425
13830
|
return new Promise((resolve, reject) => {
|
|
13426
|
-
const responseType = FEATURES.SUPPORT_RESPONSE_TYPE ? "blob" : "text";
|
|
13427
13831
|
const xhr = new XMLHttpRequest();
|
|
13428
13832
|
xhr.onload = () => {
|
|
13429
13833
|
if (xhr.status === 200) {
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13433
|
-
|
|
13434
|
-
reader.addEventListener("error", (e) => reject(e), false);
|
|
13435
|
-
reader.readAsDataURL(xhr.response);
|
|
13436
|
-
}
|
|
13834
|
+
const reader = new FileReader();
|
|
13835
|
+
reader.addEventListener("load", () => resolve(reader.result), false);
|
|
13836
|
+
reader.addEventListener("error", (e) => reject(e), false);
|
|
13837
|
+
reader.readAsDataURL(xhr.response);
|
|
13437
13838
|
} else reject(`Failed to proxy resource ${key} with status code ${xhr.status}`);
|
|
13438
13839
|
};
|
|
13439
13840
|
xhr.onerror = reject;
|
|
13440
13841
|
const queryString = proxy.indexOf("?") > -1 ? "&" : "?";
|
|
13441
|
-
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType
|
|
13442
|
-
|
|
13842
|
+
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType=blob`);
|
|
13843
|
+
xhr.responseType = "blob";
|
|
13443
13844
|
if (this._options.imageTimeout) {
|
|
13444
13845
|
const timeout = this._options.imageTimeout;
|
|
13445
13846
|
xhr.timeout = timeout;
|
|
@@ -13463,27 +13864,34 @@ const isSVG = (src) => src.slice(-3).toLowerCase() === "svg" || INLINE_SVG.test(
|
|
|
13463
13864
|
* Origin Checker
|
|
13464
13865
|
*
|
|
13465
13866
|
* Provides origin checking functionality without global static state.
|
|
13466
|
-
* Each instance maintains its own
|
|
13867
|
+
* Each instance maintains its own base URI and origin reference.
|
|
13467
13868
|
*
|
|
13468
13869
|
* Replaces the static methods in CacheStorage with instance-based approach.
|
|
13469
13870
|
*/
|
|
13470
13871
|
var OriginChecker = class {
|
|
13872
|
+
baseUri;
|
|
13873
|
+
origin;
|
|
13471
13874
|
constructor(window) {
|
|
13472
13875
|
if (!window || !window.document) throw new Error("Valid window object required for OriginChecker");
|
|
13473
13876
|
if (!window.location || !window.location.href) throw new Error("Window object must have valid location");
|
|
13474
|
-
this.
|
|
13877
|
+
this.baseUri = window.location.href;
|
|
13475
13878
|
this.origin = this.getOrigin(window.location.href);
|
|
13476
13879
|
}
|
|
13477
13880
|
/**
|
|
13478
13881
|
* Get the origin (protocol + hostname + port) of a URL
|
|
13479
13882
|
*
|
|
13480
|
-
* @param url - URL to parse
|
|
13481
|
-
*
|
|
13883
|
+
* @param url - URL to parse; relative URLs resolve against the context
|
|
13884
|
+
* window's location, as the anchor element used to
|
|
13885
|
+
* @returns Origin string (e.g. "https://example.com:8080"), or an empty
|
|
13886
|
+
* string for unparseable URLs — which never matches and is
|
|
13887
|
+
* therefore treated as cross-origin
|
|
13482
13888
|
*/
|
|
13483
13889
|
getOrigin(url) {
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13890
|
+
try {
|
|
13891
|
+
return new URL(url, this.baseUri).origin;
|
|
13892
|
+
} catch (e) {
|
|
13893
|
+
return "";
|
|
13894
|
+
}
|
|
13487
13895
|
}
|
|
13488
13896
|
/**
|
|
13489
13897
|
* Check if a URL is from the same origin as the context
|
|
@@ -13506,11 +13914,15 @@ var OriginChecker = class {
|
|
|
13506
13914
|
//#endregion
|
|
13507
13915
|
//#region src/core/context.ts
|
|
13508
13916
|
var Context = class Context {
|
|
13509
|
-
static
|
|
13510
|
-
|
|
13511
|
-
|
|
13917
|
+
static instanceCount = 1;
|
|
13918
|
+
instanceName = `#${Context.instanceCount++}`;
|
|
13919
|
+
logger;
|
|
13920
|
+
cache;
|
|
13921
|
+
originChecker;
|
|
13922
|
+
config;
|
|
13923
|
+
onError;
|
|
13924
|
+
_windowBounds;
|
|
13512
13925
|
constructor(options, windowBounds, config) {
|
|
13513
|
-
this.instanceName = `#${Context.instanceCount++}`;
|
|
13514
13926
|
this.config = config;
|
|
13515
13927
|
this.logger = new Logger({
|
|
13516
13928
|
id: this.instanceName,
|
|
@@ -13526,6 +13938,18 @@ var Context = class Context {
|
|
|
13526
13938
|
return this._windowBounds;
|
|
13527
13939
|
}
|
|
13528
13940
|
/**
|
|
13941
|
+
* Document used to allocate offscreen resources (offscreen canvases,
|
|
13942
|
+
* images, measurement elements). Prefers the configured window's document
|
|
13943
|
+
* so resources live in the captured realm; falls back to the global
|
|
13944
|
+
* document, which keeps mock environments without a window document
|
|
13945
|
+
* working.
|
|
13946
|
+
*/
|
|
13947
|
+
get resourceDocument() {
|
|
13948
|
+
const windowDocument = this.config.window.document;
|
|
13949
|
+
if (windowDocument) return windowDocument;
|
|
13950
|
+
return typeof document !== "undefined" ? document : void 0;
|
|
13951
|
+
}
|
|
13952
|
+
/**
|
|
13529
13953
|
* Compensate window bounds for a page scroll that the browser performed
|
|
13530
13954
|
* underneath us. Used by the document cloner: WebKit's scroll anchoring can
|
|
13531
13955
|
* scroll the cloned iframe after `onclone`, and the offset must be applied
|
|
@@ -13597,7 +14021,8 @@ const assembleCloneOptions = (opts, config, foreignObjectRendering) => ({
|
|
|
13597
14021
|
iframeContainer: opts.iframeContainer,
|
|
13598
14022
|
inlineImages: foreignObjectRendering,
|
|
13599
14023
|
copyStyles: foreignObjectRendering,
|
|
13600
|
-
cspNonce: opts.cspNonce ?? config.cspNonce
|
|
14024
|
+
cspNonce: opts.cspNonce ?? config.cspNonce,
|
|
14025
|
+
signal: opts.signal
|
|
13601
14026
|
});
|
|
13602
14027
|
/** Assemble canvas rendering options. */
|
|
13603
14028
|
const assembleRenderOptions = (opts, backgroundColor, left, top, width, height, devicePixelRatio) => ({
|
|
@@ -13703,13 +14128,13 @@ const renderElement = async (element, opts, config) => {
|
|
|
13703
14128
|
perfMonitor.start("parse");
|
|
13704
14129
|
throwIfAborted(signal);
|
|
13705
14130
|
context.cache.startDefer();
|
|
13706
|
-
root = parseTree(context, clonedElement);
|
|
14131
|
+
root = parseTree(context, clonedElement, { normalizeDom: opts.normalizeDom });
|
|
13707
14132
|
perfMonitor.end("parse");
|
|
13708
14133
|
emitProgress(opts.onProgress, context, "parse", 50);
|
|
13709
14134
|
perfMonitor.start("preload");
|
|
13710
14135
|
await context.cache.preloadAll(10, (loaded, total) => {
|
|
13711
14136
|
emitProgress(opts.onProgress, context, "preload", 50 + Math.round(loaded / total * 10));
|
|
13712
|
-
});
|
|
14137
|
+
}, signal);
|
|
13713
14138
|
perfMonitor.end("preload");
|
|
13714
14139
|
emitProgress(opts.onProgress, context, "layout", 60);
|
|
13715
14140
|
if (backgroundColor === root.styles.backgroundColor) root.styles.backgroundColor = 0;
|