html2canvas-pro 2.6.0 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * html2canvas-pro 2.6.0 <https://yorickshan.github.io/html2canvas-pro/>
2
+ * html2canvas-pro 2.6.2 <https://yorickshan.github.io/html2canvas-pro/>
3
3
  * Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
4
4
  * Released under MIT License
5
5
  */
@@ -10,7 +10,7 @@
10
10
  __esModule: { value: true },
11
11
  [Symbol.toStringTag]: { value: "Module" }
12
12
  });
13
- //#region src/config.ts
13
+ // src/config.ts
14
14
  /**
15
15
  * Html2Canvas Configuration
16
16
  *
@@ -53,8 +53,7 @@
53
53
  });
54
54
  }
55
55
  };
56
- //#endregion
57
- //#region src/core/validator.ts
56
+ // src/core/validator.ts
58
57
  /**
59
58
  * Input Validator
60
59
  *
@@ -442,8 +441,7 @@
442
441
  ...config
443
442
  });
444
443
  }
445
- //#endregion
446
- //#region src/core/performance-monitor.ts
444
+ // src/core/performance-monitor.ts
447
445
  /**
448
446
  * Performance Monitor
449
447
  *
@@ -452,7 +450,8 @@
452
450
  *
453
451
  * Usage:
454
452
  * ```typescript
455
- * const monitor = new PerformanceMonitor(context);
453
+ * // Standalone (logs disabled) or with the render pipeline's context.
454
+ * const monitor = new PerformanceMonitor(null);
456
455
  *
457
456
  * monitor.start('clone');
458
457
  * await cloneDocument();
@@ -462,13 +461,13 @@
462
461
  * ```
463
462
  */
464
463
  var PerformanceMonitor = class {
465
- context;
464
+ logger;
466
465
  activeMetrics = /* @__PURE__ */ new Map();
467
466
  completedMetrics = [];
468
467
  enabled;
469
468
  getTime;
470
- constructor(context, enabled = true) {
471
- this.context = context;
469
+ constructor(logger, enabled = true) {
470
+ this.logger = logger;
472
471
  this.enabled = enabled;
473
472
  this.getTime = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
474
473
  }
@@ -480,7 +479,7 @@
480
479
  */
481
480
  start(name, metadata) {
482
481
  if (!this.enabled) return;
483
- if (this.activeMetrics.has(name)) this.context?.logger.warn(`Performance metric '${name}' already started. Overwriting.`);
482
+ if (this.activeMetrics.has(name)) this.logger?.warn(`Performance metric '${name}' already started. Overwriting.`);
484
483
  this.activeMetrics.set(name, {
485
484
  name,
486
485
  startTime: this.getTime(),
@@ -497,14 +496,14 @@
497
496
  if (!this.enabled) return;
498
497
  const metric = this.activeMetrics.get(name);
499
498
  if (!metric) {
500
- this.context?.logger.warn(`Performance metric '${name}' not found. Was start() called?`);
499
+ this.logger?.warn(`Performance metric '${name}' not found. Was start() called?`);
501
500
  return;
502
501
  }
503
502
  metric.endTime = this.getTime();
504
503
  metric.duration = metric.endTime - metric.startTime;
505
504
  this.completedMetrics.push(metric);
506
505
  this.activeMetrics.delete(name);
507
- this.context?.logger.debug(`⏱️ ${name}: ${metric.duration.toFixed(2)}ms`, metric.metadata);
506
+ this.logger?.debug(`⏱️ ${name}: ${metric.duration.toFixed(2)}ms`, metric.metadata);
508
507
  return metric;
509
508
  }
510
509
  /**
@@ -584,11 +583,12 @@
584
583
  * Log performance summary to console
585
584
  */
586
585
  logSummary() {
587
- if (!this.enabled || this.completedMetrics.length === 0 || !this.context) return;
586
+ if (!this.enabled || this.completedMetrics.length === 0 || !this.logger) return;
587
+ const logger = this.logger;
588
588
  const summary = this.getSummary();
589
- this.context.logger.info(`\n📊 Performance Summary (Total: ${summary.totalDuration.toFixed(2)}ms):`);
589
+ logger.info(`\n📊 Performance Summary (Total: ${summary.totalDuration.toFixed(2)}ms):`);
590
590
  summary.breakdown.sort((a, b) => b.duration - a.duration).forEach((item) => {
591
- this.context.logger.info(` ${item.name.padEnd(20)} ${item.duration.toFixed(2).padStart(8)}ms ${item.percentage.padStart(6)}`);
591
+ logger.info(` ${item.name.padEnd(20)} ${item.duration.toFixed(2).padStart(8)}ms ${item.percentage.padStart(6)}`);
592
592
  });
593
593
  }
594
594
  /**
@@ -612,8 +612,7 @@
612
612
  return Array.from(this.activeMetrics.keys());
613
613
  }
614
614
  };
615
- //#endregion
616
- //#region src/css/layout/bounds.ts
615
+ // src/css/layout/bounds.ts
617
616
  var Bounds = class Bounds {
618
617
  left;
619
618
  top;
@@ -649,8 +648,7 @@
649
648
  if (!body || !documentElement) throw new Error(`Unable to get document size`);
650
649
  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)));
651
650
  };
652
- //#endregion
653
- //#region src/core/util.ts
651
+ // src/core/util.ts
654
652
  /**
655
653
  * Indexed access where the shape/arity is guaranteed by construction (the CSS
656
654
  * grammar or a preceding length check). Throws on the impossible case instead
@@ -728,8 +726,7 @@
728
726
  const exp = exponent.length ? parseInt(String.fromCodePoint(...exponent), 10) : 0;
729
727
  return sign * (int + frac * Math.pow(10, -fracd)) * Math.pow(10, expsign * exp);
730
728
  };
731
- //#endregion
732
- //#region src/css/syntax/token-singletons.ts
729
+ // src/css/syntax/token-singletons.ts
733
730
  const LEFT_PARENTHESIS_TOKEN = { type: 2 };
734
731
  const RIGHT_PARENTHESIS_TOKEN = { type: 3 };
735
732
  const COMMA_TOKEN = { type: 4 };
@@ -751,8 +748,7 @@
751
748
  const RIGHT_SQUARE_BRACKET_TOKEN = { type: 29 };
752
749
  const WHITESPACE_TOKEN = { type: 31 };
753
750
  const EOF_TOKEN = { type: 32 };
754
- //#endregion
755
- //#region src/css/syntax/tokenizer.ts
751
+ // src/css/syntax/tokenizer.ts
756
752
  var Tokenizer = class Tokenizer {
757
753
  static _pool = [];
758
754
  static MAX_POOL_SIZE = 40;
@@ -1208,8 +1204,7 @@
1208
1204
  }
1209
1205
  }
1210
1206
  };
1211
- //#endregion
1212
- //#region src/css/syntax/parser.ts
1207
+ // src/css/syntax/parser.ts
1213
1208
  var Parser = class Parser {
1214
1209
  _tokens;
1215
1210
  constructor(tokens) {
@@ -1318,8 +1313,7 @@
1318
1313
  if (type === 28 && token.type === 29) return true;
1319
1314
  return type === 2 && token.type === 3;
1320
1315
  };
1321
- //#endregion
1322
- //#region src/css/types/safe-eval.ts
1316
+ // src/css/types/safe-eval.ts
1323
1317
  /**
1324
1318
  * Safe arithmetic expression evaluator — replaces `new Function()`.
1325
1319
  *
@@ -1377,8 +1371,7 @@
1377
1371
  }
1378
1372
  return stack.length === 1 ? stack[0] ?? NaN : NaN;
1379
1373
  };
1380
- //#endregion
1381
- //#region src/css/types/color-math.ts
1374
+ // src/css/types/color-math.ts
1382
1375
  /**
1383
1376
  * Color mathematics utilities
1384
1377
  * Extracted to break circular dependency between srgb.ts and color-utilities.ts
@@ -1399,8 +1392,7 @@
1399
1392
  A[6] * B[0] + A[7] * B[1] + A[8] * B[2]
1400
1393
  ];
1401
1394
  };
1402
- //#endregion
1403
- //#region src/css/types/color-spaces/srgb.ts
1395
+ // src/css/types/color-spaces/srgb.ts
1404
1396
  /**
1405
1397
  * SRGB related functions
1406
1398
  */
@@ -1509,11 +1501,9 @@
1509
1501
  args[3]
1510
1502
  ];
1511
1503
  };
1512
- //#endregion
1513
- //#region src/css/types/length.ts
1504
+ // src/css/types/length.ts
1514
1505
  const isLength = (token) => token.type === 17 || token.type === 15;
1515
- //#endregion
1516
- //#region src/css/types/length-percentage.ts
1506
+ // src/css/types/length-percentage.ts
1517
1507
  const isLengthPercentage = (token) => token.type === 16 || isLength(token) || isCalcWithPercentage(token);
1518
1508
  /**
1519
1509
  * Check if a token is a CalcWithPercentage deferred token.
@@ -1637,8 +1627,7 @@
1637
1627
  }
1638
1628
  return token.number;
1639
1629
  };
1640
- //#endregion
1641
- //#region src/css/types/angle.ts
1630
+ // src/css/types/angle.ts
1642
1631
  const DEG = "deg";
1643
1632
  const GRAD = "grad";
1644
1633
  const RAD = "rad";
@@ -1691,8 +1680,7 @@
1691
1680
  return 0;
1692
1681
  };
1693
1682
  const deg = (deg) => Math.PI * deg / 180;
1694
- //#endregion
1695
- //#region src/css/types/color-utilities.ts
1683
+ // src/css/types/color-utilities.ts
1696
1684
  const isTransparent = (color) => (255 & color) === 0;
1697
1685
  const asString = (color) => {
1698
1686
  const alpha = 255 & color;
@@ -2147,8 +2135,7 @@
2147
2135
  args[3]
2148
2136
  ]);
2149
2137
  };
2150
- //#endregion
2151
- //#region src/css/types/color-spaces/p3.ts
2138
+ // src/css/types/color-spaces/p3.ts
2152
2139
  /**
2153
2140
  * Display-P3 related functions
2154
2141
  */
@@ -2266,8 +2253,7 @@
2266
2253
  args[3]
2267
2254
  ]);
2268
2255
  };
2269
- //#endregion
2270
- //#region src/css/types/color-spaces/a98.ts
2256
+ // src/css/types/color-spaces/a98.ts
2271
2257
  /**
2272
2258
  * A98-RGB related functions
2273
2259
  */
@@ -2373,8 +2359,7 @@
2373
2359
  args[3]
2374
2360
  ]);
2375
2361
  };
2376
- //#endregion
2377
- //#region src/css/types/color-spaces/pro-photo.ts
2362
+ // src/css/types/color-spaces/pro-photo.ts
2378
2363
  /**
2379
2364
  * Pro Photo related functions
2380
2365
  */
@@ -2499,8 +2484,7 @@
2499
2484
  args[3]
2500
2485
  ]);
2501
2486
  };
2502
- //#endregion
2503
- //#region src/css/types/color-spaces/rec2020.ts
2487
+ // src/css/types/color-spaces/rec2020.ts
2504
2488
  /**
2505
2489
  * REC2020 related functions
2506
2490
  */
@@ -2621,8 +2605,7 @@
2621
2605
  args[3]
2622
2606
  ]);
2623
2607
  };
2624
- //#endregion
2625
- //#region src/css/types/functions/color-mix.ts
2608
+ // src/css/types/functions/color-mix.ts
2626
2609
  const HUE_DEG_INDEX = {
2627
2610
  lch: 2,
2628
2611
  oklch: 2,
@@ -3008,8 +2991,7 @@
3008
2991
  return 0;
3009
2992
  }
3010
2993
  };
3011
- //#endregion
3012
- //#region src/css/types/color.ts
2994
+ // src/css/types/color.ts
3013
2995
  const color$1 = {
3014
2996
  name: "color",
3015
2997
  parse: (context, value) => {
@@ -3413,8 +3395,7 @@
3413
3395
  YELLOW: 4294902015,
3414
3396
  YELLOWGREEN: 2597139199
3415
3397
  };
3416
- //#endregion
3417
- //#region src/dom/node-type-guards.ts
3398
+ // src/dom/node-type-guards.ts
3418
3399
  /**
3419
3400
  * DOM Node Type Guards
3420
3401
  *
@@ -3470,8 +3451,7 @@
3470
3451
  * SVG elements also do not support pseudo-elements.
3471
3452
  */
3472
3453
  const canHavePseudoElements = (element) => !isSVGElementNode(element) && !VOID_OR_REPLACED_TAGS.has(element.tagName);
3473
- //#endregion
3474
- //#region src/css/property-descriptors/list-style-type.ts
3454
+ // src/css/property-descriptors/list-style-type.ts
3475
3455
  const listStyleType = {
3476
3456
  name: "list-style-type",
3477
3457
  initialValue: "none",
@@ -3536,11 +3516,9 @@
3536
3516
  }
3537
3517
  }
3538
3518
  };
3539
- //#endregion
3540
- //#region src/core/bitwise.ts
3519
+ // src/core/bitwise.ts
3541
3520
  const contains = (bit, value) => (bit & value) !== 0;
3542
- //#endregion
3543
- //#region src/css/types/functions/counter.ts
3521
+ // src/css/types/functions/counter.ts
3544
3522
  var CounterState = class {
3545
3523
  counters = {};
3546
3524
  getCounterValue(name) {
@@ -3956,8 +3934,7 @@
3956
3934
  default: return createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);
3957
3935
  }
3958
3936
  };
3959
- //#endregion
3960
- //#region src/css/property-descriptors/display.ts
3937
+ // src/css/property-descriptors/display.ts
3961
3938
  const display = {
3962
3939
  name: "display",
3963
3940
  initialValue: "inline-block",
@@ -4006,8 +3983,7 @@
4006
3983
  }
4007
3984
  return 0;
4008
3985
  };
4009
- //#endregion
4010
- //#region src/css/property-descriptors/float.ts
3986
+ // src/css/property-descriptors/float.ts
4011
3987
  const float = {
4012
3988
  name: "float",
4013
3989
  initialValue: "none",
@@ -4023,8 +3999,7 @@
4023
3999
  return 0;
4024
4000
  }
4025
4001
  };
4026
- //#endregion
4027
- //#region src/css/property-descriptors/overflow.ts
4002
+ // src/css/property-descriptors/overflow.ts
4028
4003
  const overflow = {
4029
4004
  name: "overflow",
4030
4005
  initialValue: "visible",
@@ -4042,8 +4017,7 @@
4042
4017
  });
4043
4018
  }
4044
4019
  };
4045
- //#endregion
4046
- //#region src/css/property-descriptors/text-decoration-color.ts
4020
+ // src/css/property-descriptors/text-decoration-color.ts
4047
4021
  const textDecorationColor = {
4048
4022
  name: `text-decoration-color`,
4049
4023
  initialValue: "transparent",
@@ -4051,8 +4025,7 @@
4051
4025
  type: 3,
4052
4026
  format: "color"
4053
4027
  };
4054
- //#endregion
4055
- //#region src/css/property-descriptors/text-decoration-line.ts
4028
+ // src/css/property-descriptors/text-decoration-line.ts
4056
4029
  const textDecorationLine = {
4057
4030
  name: "text-decoration-line",
4058
4031
  initialValue: "none",
@@ -4070,8 +4043,7 @@
4070
4043
  }).filter((line) => line !== 0);
4071
4044
  }
4072
4045
  };
4073
- //#endregion
4074
- //#region src/css/property-descriptors/content.ts
4046
+ // src/css/property-descriptors/content.ts
4075
4047
  const content = {
4076
4048
  name: "content",
4077
4049
  initialValue: "none",
@@ -4084,8 +4056,7 @@
4084
4056
  return tokens;
4085
4057
  }
4086
4058
  };
4087
- //#endregion
4088
- //#region src/css/property-descriptors/quotes.ts
4059
+ // src/css/property-descriptors/quotes.ts
4089
4060
  const quotes = {
4090
4061
  name: "quotes",
4091
4062
  initialValue: "none",
@@ -4115,8 +4086,7 @@
4115
4086
  if (!quote) return "";
4116
4087
  return open ? quote.open : quote.close;
4117
4088
  };
4118
- //#endregion
4119
- //#region src/css/property-descriptors/counter-increment.ts
4089
+ // src/css/property-descriptors/counter-increment.ts
4120
4090
  /** Shared counter-ID parsing: returns next number or a fallback default. */
4121
4091
  const parseCounterValue = (tokens, defaultNumber) => {
4122
4092
  const entries = [];
@@ -4146,8 +4116,7 @@
4146
4116
  }));
4147
4117
  }
4148
4118
  };
4149
- //#endregion
4150
- //#region src/css/property-descriptors/counter-reset.ts
4119
+ // src/css/property-descriptors/counter-reset.ts
4151
4120
  const counterReset = {
4152
4121
  name: "counter-reset",
4153
4122
  initialValue: "none",
@@ -4161,8 +4130,7 @@
4161
4130
  }));
4162
4131
  }
4163
4132
  };
4164
- //#endregion
4165
- //#region src/css/property-descriptors/background-clip.ts
4133
+ // src/css/property-descriptors/background-clip.ts
4166
4134
  const backgroundClip = {
4167
4135
  name: "background-clip",
4168
4136
  initialValue: "border-box",
@@ -4179,8 +4147,7 @@
4179
4147
  });
4180
4148
  }
4181
4149
  };
4182
- //#endregion
4183
- //#region src/css/property-descriptors/background-color.ts
4150
+ // src/css/property-descriptors/background-color.ts
4184
4151
  const backgroundColor = {
4185
4152
  name: `background-color`,
4186
4153
  initialValue: "transparent",
@@ -4188,8 +4155,7 @@
4188
4155
  type: 3,
4189
4156
  format: "color"
4190
4157
  };
4191
- //#endregion
4192
- //#region src/css/types/functions/gradient.ts
4158
+ // src/css/types/functions/gradient.ts
4193
4159
  const parseColorStop = (context, args) => {
4194
4160
  const color = color$1.parse(context, at(args, 0));
4195
4161
  const stop = args[1];
@@ -4325,8 +4291,7 @@
4325
4291
  }
4326
4292
  return [rx, ry];
4327
4293
  };
4328
- //#endregion
4329
- //#region src/css/types/functions/linear-gradient.ts
4294
+ // src/css/types/functions/linear-gradient.ts
4330
4295
  const linearGradient = (context, tokens) => {
4331
4296
  let angle$2 = deg(180);
4332
4297
  const stops = [];
@@ -4350,8 +4315,7 @@
4350
4315
  type: 1
4351
4316
  };
4352
4317
  };
4353
- //#endregion
4354
- //#region src/css/types/functions/-prefix-linear-gradient.ts
4318
+ // src/css/types/functions/-prefix-linear-gradient.ts
4355
4319
  const prefixLinearGradient = (context, tokens) => {
4356
4320
  let angle$1 = deg(180);
4357
4321
  const stops = [];
@@ -4380,8 +4344,7 @@
4380
4344
  type: 1
4381
4345
  };
4382
4346
  };
4383
- //#endregion
4384
- //#region src/css/types/functions/-webkit-gradient.ts
4347
+ // src/css/types/functions/-webkit-gradient.ts
4385
4348
  const webkitGradient = (context, tokens) => {
4386
4349
  const angle = deg(180);
4387
4350
  const stops = [];
@@ -4443,8 +4406,7 @@
4443
4406
  type
4444
4407
  };
4445
4408
  };
4446
- //#endregion
4447
- //#region src/css/types/functions/radial-gradient.ts
4409
+ // src/css/types/functions/radial-gradient.ts
4448
4410
  const CLOSEST_SIDE = "closest-side";
4449
4411
  const FARTHEST_SIDE = "farthest-side";
4450
4412
  const CLOSEST_CORNER = "closest-corner";
@@ -4524,8 +4486,7 @@
4524
4486
  type: 2
4525
4487
  };
4526
4488
  };
4527
- //#endregion
4528
- //#region src/css/types/functions/-prefix-radial-gradient.ts
4489
+ // src/css/types/functions/-prefix-radial-gradient.ts
4529
4490
  const prefixRadialGradient = (context, tokens) => {
4530
4491
  let shape = 1;
4531
4492
  let size = 3;
@@ -4596,16 +4557,14 @@
4596
4557
  type: 2
4597
4558
  };
4598
4559
  };
4599
- //#endregion
4600
- //#region src/css/types/functions/repeating-linear-gradient.ts
4560
+ // src/css/types/functions/repeating-linear-gradient.ts
4601
4561
  const repeatingLinearGradient = (context, tokens) => {
4602
4562
  return {
4603
4563
  ...linearGradient(context, tokens),
4604
4564
  type: 3
4605
4565
  };
4606
4566
  };
4607
- //#endregion
4608
- //#region src/css/types/functions/repeating-radial-gradient.ts
4567
+ // src/css/types/functions/repeating-radial-gradient.ts
4609
4568
  /**
4610
4569
  * repeating-radial-gradient shares the radial-gradient grammar exactly; only
4611
4570
  * the image type differs, which switches the renderer to periodic stops.
@@ -4616,8 +4575,7 @@
4616
4575
  type: 4
4617
4576
  };
4618
4577
  };
4619
- //#endregion
4620
- //#region src/css/types/functions/conic-gradient.ts
4578
+ // src/css/types/functions/conic-gradient.ts
4621
4579
  /**
4622
4580
  * conic-gradient( [ from <angle> ]? [ at <position> ]?, <color-stop-list> )
4623
4581
  *
@@ -4687,8 +4645,7 @@
4687
4645
  type: 6
4688
4646
  };
4689
4647
  };
4690
- //#endregion
4691
- //#region src/css/types/functions/image-set.ts
4648
+ // src/css/types/functions/image-set.ts
4692
4649
  const parseResolution = (token) => {
4693
4650
  if (!token) return 1;
4694
4651
  if (isDimensionToken(token)) {
@@ -4722,8 +4679,7 @@
4722
4679
  const chosen = at(satisfying.length > 0 ? satisfying : candidates.slice().sort((a, b) => b.resolution - a.resolution), 0);
4723
4680
  return image.parse(context, chosen.imageToken);
4724
4681
  };
4725
- //#endregion
4726
- //#region src/css/types/image.ts
4682
+ // src/css/types/image.ts
4727
4683
  const isLinearGradient = (background) => {
4728
4684
  return background.type === 1;
4729
4685
  };
@@ -4793,8 +4749,7 @@
4793
4749
  "image-set": imageSet,
4794
4750
  "-webkit-image-set": imageSet
4795
4751
  };
4796
- //#endregion
4797
- //#region src/css/property-descriptors/background-image.ts
4752
+ // src/css/property-descriptors/background-image.ts
4798
4753
  const backgroundImage = {
4799
4754
  name: "background-image",
4800
4755
  initialValue: "none",
@@ -4808,8 +4763,7 @@
4808
4763
  return tokens.filter((value) => nonFunctionArgSeparator(value) && isSupportedImage(value)).map((value) => image.parse(context, value));
4809
4764
  }
4810
4765
  };
4811
- //#endregion
4812
- //#region src/css/property-descriptors/background-origin.ts
4766
+ // src/css/property-descriptors/background-origin.ts
4813
4767
  const backgroundOrigin = {
4814
4768
  name: "background-origin",
4815
4769
  initialValue: "border-box",
@@ -4825,8 +4779,7 @@
4825
4779
  });
4826
4780
  }
4827
4781
  };
4828
- //#endregion
4829
- //#region src/css/property-descriptors/background-position.ts
4782
+ // src/css/property-descriptors/background-position.ts
4830
4783
  const backgroundPosition = {
4831
4784
  name: "background-position",
4832
4785
  initialValue: "0% 0%",
@@ -4838,8 +4791,7 @@
4838
4791
  }).map(parseLengthPercentageTuple);
4839
4792
  }
4840
4793
  };
4841
- //#endregion
4842
- //#region src/css/property-descriptors/background-repeat.ts
4794
+ // src/css/property-descriptors/background-repeat.ts
4843
4795
  const backgroundRepeat = {
4844
4796
  name: "background-repeat",
4845
4797
  initialValue: "repeat",
@@ -4859,8 +4811,7 @@
4859
4811
  default: return 0;
4860
4812
  }
4861
4813
  };
4862
- //#endregion
4863
- //#region src/css/property-descriptors/background-size.ts
4814
+ // src/css/property-descriptors/background-size.ts
4864
4815
  const backgroundSize = {
4865
4816
  name: "background-size",
4866
4817
  initialValue: "0",
@@ -4871,8 +4822,7 @@
4871
4822
  }
4872
4823
  };
4873
4824
  const isBackgroundSizeInfoToken = (value) => isIdentToken(value) || isLengthPercentage(value);
4874
- //#endregion
4875
- //#region src/css/property-descriptors/border-color.ts
4825
+ // src/css/property-descriptors/border-color.ts
4876
4826
  const borderColorForSide = (side) => ({
4877
4827
  name: `border-${side}-color`,
4878
4828
  initialValue: "transparent",
@@ -4884,8 +4834,7 @@
4884
4834
  const borderRightColor = borderColorForSide("right");
4885
4835
  const borderBottomColor = borderColorForSide("bottom");
4886
4836
  const borderLeftColor = borderColorForSide("left");
4887
- //#endregion
4888
- //#region src/css/property-descriptors/border-radius.ts
4837
+ // src/css/property-descriptors/border-radius.ts
4889
4838
  const borderRadiusForSide = (side) => ({
4890
4839
  name: `border-${side}-radius`,
4891
4840
  initialValue: "0 0",
@@ -4897,8 +4846,7 @@
4897
4846
  const borderTopRightRadius = borderRadiusForSide("top-right");
4898
4847
  const borderBottomRightRadius = borderRadiusForSide("bottom-right");
4899
4848
  const borderBottomLeftRadius = borderRadiusForSide("bottom-left");
4900
- //#endregion
4901
- //#region src/css/property-descriptors/border-style.ts
4849
+ // src/css/property-descriptors/border-style.ts
4902
4850
  const borderStyleForSide = (side) => ({
4903
4851
  name: `border-${side}-style`,
4904
4852
  initialValue: "solid",
@@ -4918,8 +4866,7 @@
4918
4866
  const borderRightStyle = borderStyleForSide("right");
4919
4867
  const borderBottomStyle = borderStyleForSide("bottom");
4920
4868
  const borderLeftStyle = borderStyleForSide("left");
4921
- //#endregion
4922
- //#region src/css/property-descriptors/border-width.ts
4869
+ // src/css/property-descriptors/border-width.ts
4923
4870
  const borderWidthForSide = (side) => ({
4924
4871
  name: `border-${side}-width`,
4925
4872
  initialValue: "0",
@@ -4934,8 +4881,7 @@
4934
4881
  const borderRightWidth = borderWidthForSide("right");
4935
4882
  const borderBottomWidth = borderWidthForSide("bottom");
4936
4883
  const borderLeftWidth = borderWidthForSide("left");
4937
- //#endregion
4938
- //#region src/css/property-descriptors/clip-path.ts
4884
+ // src/css/property-descriptors/clip-path.ts
4939
4885
  const NONE = { type: 0 };
4940
4886
  /**
4941
4887
  * Parse a shape-radius token: <length-percentage> | closest-side | farthest-side.
@@ -5156,8 +5102,7 @@
5156
5102
  return NONE;
5157
5103
  }
5158
5104
  };
5159
- //#endregion
5160
- //#region src/css/property-descriptors/color.ts
5105
+ // src/css/property-descriptors/color.ts
5161
5106
  const color = {
5162
5107
  name: `color`,
5163
5108
  initialValue: "transparent",
@@ -5165,8 +5110,7 @@
5165
5110
  type: 3,
5166
5111
  format: "color"
5167
5112
  };
5168
- //#endregion
5169
- //#region src/css/property-descriptors/direction.ts
5113
+ // src/css/property-descriptors/direction.ts
5170
5114
  const direction = {
5171
5115
  name: "direction",
5172
5116
  initialValue: "ltr",
@@ -5179,8 +5123,7 @@
5179
5123
  }
5180
5124
  }
5181
5125
  };
5182
- //#endregion
5183
- //#region src/css/property-descriptors/font-family.ts
5126
+ // src/css/property-descriptors/font-family.ts
5184
5127
  const fontFamily = {
5185
5128
  name: `font-family`,
5186
5129
  initialValue: "",
@@ -5217,8 +5160,7 @@
5217
5160
  return results.map((result, index) => quoted[index] || result.indexOf(" ") !== -1 ? `'${result.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\a ").replace(/\r/g, "\\d ").replace(/\f/g, "\\c ")}'` : result);
5218
5161
  }
5219
5162
  };
5220
- //#endregion
5221
- //#region src/css/property-descriptors/font-size.ts
5163
+ // src/css/property-descriptors/font-size.ts
5222
5164
  const fontSize = {
5223
5165
  name: `font-size`,
5224
5166
  initialValue: "0",
@@ -5226,8 +5168,7 @@
5226
5168
  type: 3,
5227
5169
  format: "length"
5228
5170
  };
5229
- //#endregion
5230
- //#region src/css/property-descriptors/letter-spacing.ts
5171
+ // src/css/property-descriptors/letter-spacing.ts
5231
5172
  const letterSpacing = {
5232
5173
  name: "letter-spacing",
5233
5174
  initialValue: "0",
@@ -5240,8 +5181,7 @@
5240
5181
  return 0;
5241
5182
  }
5242
5183
  };
5243
- //#endregion
5244
- //#region src/css/property-descriptors/line-break.ts
5184
+ // src/css/property-descriptors/line-break.ts
5245
5185
  const lineBreak = {
5246
5186
  name: "line-break",
5247
5187
  initialValue: "normal",
@@ -5254,8 +5194,7 @@
5254
5194
  }
5255
5195
  }
5256
5196
  };
5257
- //#endregion
5258
- //#region src/css/property-descriptors/line-height.ts
5197
+ // src/css/property-descriptors/line-height.ts
5259
5198
  const lineHeight = {
5260
5199
  name: "line-height",
5261
5200
  initialValue: "normal",
@@ -5268,8 +5207,7 @@
5268
5207
  else if (isLengthPercentage(token)) return getAbsoluteValue(token, fontSize);
5269
5208
  return fontSize;
5270
5209
  };
5271
- //#endregion
5272
- //#region src/css/property-descriptors/list-style-image.ts
5210
+ // src/css/property-descriptors/list-style-image.ts
5273
5211
  const listStyleImage = {
5274
5212
  name: "list-style-image",
5275
5213
  initialValue: "none",
@@ -5282,8 +5220,7 @@
5282
5220
  return image.parse(context, token);
5283
5221
  }
5284
5222
  };
5285
- //#endregion
5286
- //#region src/css/property-descriptors/list-style-position.ts
5223
+ // src/css/property-descriptors/list-style-position.ts
5287
5224
  const listStylePosition = {
5288
5225
  name: "list-style-position",
5289
5226
  initialValue: "outside",
@@ -5296,8 +5233,7 @@
5296
5233
  }
5297
5234
  }
5298
5235
  };
5299
- //#endregion
5300
- //#region src/css/property-descriptors/margin.ts
5236
+ // src/css/property-descriptors/margin.ts
5301
5237
  const marginForSide = (side) => ({
5302
5238
  name: `margin-${side}`,
5303
5239
  initialValue: "0",
@@ -5308,8 +5244,7 @@
5308
5244
  const marginRight = marginForSide("right");
5309
5245
  const marginBottom = marginForSide("bottom");
5310
5246
  const marginLeft = marginForSide("left");
5311
- //#endregion
5312
- //#region src/css/property-descriptors/overflow-wrap.ts
5247
+ // src/css/property-descriptors/overflow-wrap.ts
5313
5248
  const overflowWrap = {
5314
5249
  name: "overflow-wrap",
5315
5250
  initialValue: "normal",
@@ -5322,8 +5257,7 @@
5322
5257
  }
5323
5258
  }
5324
5259
  };
5325
- //#endregion
5326
- //#region src/css/property-descriptors/padding.ts
5260
+ // src/css/property-descriptors/padding.ts
5327
5261
  const paddingForSide = (side) => ({
5328
5262
  name: `padding-${side}`,
5329
5263
  initialValue: "0",
@@ -5335,8 +5269,7 @@
5335
5269
  const paddingRight = paddingForSide("right");
5336
5270
  const paddingBottom = paddingForSide("bottom");
5337
5271
  const paddingLeft = paddingForSide("left");
5338
- //#endregion
5339
- //#region src/css/property-descriptors/text-align.ts
5272
+ // src/css/property-descriptors/text-align.ts
5340
5273
  const textAlign = {
5341
5274
  name: "text-align",
5342
5275
  initialValue: "left",
@@ -5351,8 +5284,7 @@
5351
5284
  }
5352
5285
  }
5353
5286
  };
5354
- //#endregion
5355
- //#region src/css/property-descriptors/position.ts
5287
+ // src/css/property-descriptors/position.ts
5356
5288
  const position = {
5357
5289
  name: "position",
5358
5290
  initialValue: "static",
@@ -5368,8 +5300,7 @@
5368
5300
  return 0;
5369
5301
  }
5370
5302
  };
5371
- //#endregion
5372
- //#region src/css/property-descriptors/text-shadow.ts
5303
+ // src/css/property-descriptors/text-shadow.ts
5373
5304
  const textShadow = {
5374
5305
  name: "text-shadow",
5375
5306
  initialValue: "none",
@@ -5399,8 +5330,7 @@
5399
5330
  });
5400
5331
  }
5401
5332
  };
5402
- //#endregion
5403
- //#region src/css/property-descriptors/text-transform.ts
5333
+ // src/css/property-descriptors/text-transform.ts
5404
5334
  const textTransform = {
5405
5335
  name: "text-transform",
5406
5336
  initialValue: "none",
@@ -5415,8 +5345,7 @@
5415
5345
  return 0;
5416
5346
  }
5417
5347
  };
5418
- //#endregion
5419
- //#region src/css/property-descriptors/transform.ts
5348
+ // src/css/property-descriptors/transform.ts
5420
5349
  const transform$1 = {
5421
5350
  name: "transform",
5422
5351
  initialValue: "none",
@@ -5471,8 +5400,7 @@
5471
5400
  matrix3d,
5472
5401
  rotate: rotate$1
5473
5402
  };
5474
- //#endregion
5475
- //#region src/css/property-descriptors/transform-origin.ts
5403
+ // src/css/property-descriptors/transform-origin.ts
5476
5404
  const DEFAULT_VALUE = {
5477
5405
  type: 16,
5478
5406
  number: 50,
@@ -5490,8 +5418,7 @@
5490
5418
  return [at(origins, 0), at(origins, 1)];
5491
5419
  }
5492
5420
  };
5493
- //#endregion
5494
- //#region src/css/property-descriptors/rotate.ts
5421
+ // src/css/property-descriptors/rotate.ts
5495
5422
  const rotate = {
5496
5423
  name: "rotate",
5497
5424
  initialValue: "none",
@@ -5506,8 +5433,7 @@
5506
5433
  return null;
5507
5434
  }
5508
5435
  };
5509
- //#endregion
5510
- //#region src/css/property-descriptors/visibility.ts
5436
+ // src/css/property-descriptors/visibility.ts
5511
5437
  const visibility = {
5512
5438
  name: "visibility",
5513
5439
  initialValue: "none",
@@ -5521,8 +5447,7 @@
5521
5447
  }
5522
5448
  }
5523
5449
  };
5524
- //#endregion
5525
- //#region src/css/property-descriptors/word-break.ts
5450
+ // src/css/property-descriptors/word-break.ts
5526
5451
  const wordBreak = {
5527
5452
  name: "word-break",
5528
5453
  initialValue: "normal",
@@ -5536,8 +5461,7 @@
5536
5461
  }
5537
5462
  }
5538
5463
  };
5539
- //#endregion
5540
- //#region src/css/property-descriptors/white-space.ts
5464
+ // src/css/property-descriptors/white-space.ts
5541
5465
  const whiteSpace = {
5542
5466
  name: "white-space",
5543
5467
  initialValue: "normal",
@@ -5553,8 +5477,7 @@
5553
5477
  }
5554
5478
  }
5555
5479
  };
5556
- //#endregion
5557
- //#region src/css/property-descriptors/writing-mode.ts
5480
+ // src/css/property-descriptors/writing-mode.ts
5558
5481
  const isVerticalWritingMode = (writingMode) => writingMode !== 0;
5559
5482
  const isSidewaysWritingMode = (writingMode) => writingMode === 3 || writingMode === 4;
5560
5483
  const writingMode = {
@@ -5572,8 +5495,7 @@
5572
5495
  }
5573
5496
  }
5574
5497
  };
5575
- //#endregion
5576
- //#region src/css/property-descriptors/z-index.ts
5498
+ // src/css/property-descriptors/z-index.ts
5577
5499
  const zIndex = {
5578
5500
  name: "z-index",
5579
5501
  initialValue: "auto",
@@ -5591,8 +5513,7 @@
5591
5513
  throw new Error(`Invalid z-index number parsed`);
5592
5514
  }
5593
5515
  };
5594
- //#endregion
5595
- //#region src/css/types/time.ts
5516
+ // src/css/types/time.ts
5596
5517
  const time = {
5597
5518
  name: "time",
5598
5519
  parse: (_context, value) => {
@@ -5603,8 +5524,7 @@
5603
5524
  throw new Error(`Unsupported time type`);
5604
5525
  }
5605
5526
  };
5606
- //#endregion
5607
- //#region src/css/property-descriptors/opacity.ts
5527
+ // src/css/property-descriptors/opacity.ts
5608
5528
  const opacity = {
5609
5529
  name: "opacity",
5610
5530
  initialValue: "1",
@@ -5615,8 +5535,7 @@
5615
5535
  return 1;
5616
5536
  }
5617
5537
  };
5618
- //#endregion
5619
- //#region src/css/property-descriptors/text-decoration-style.ts
5538
+ // src/css/property-descriptors/text-decoration-style.ts
5620
5539
  const textDecorationStyle = {
5621
5540
  name: "text-decoration-style",
5622
5541
  initialValue: "solid",
@@ -5632,8 +5551,7 @@
5632
5551
  }
5633
5552
  }
5634
5553
  };
5635
- //#endregion
5636
- //#region src/css/property-descriptors/text-decoration-thickness.ts
5554
+ // src/css/property-descriptors/text-decoration-thickness.ts
5637
5555
  const textDecorationThickness = {
5638
5556
  name: "text-decoration-thickness",
5639
5557
  initialValue: "auto",
@@ -5648,8 +5566,7 @@
5648
5566
  return "auto";
5649
5567
  }
5650
5568
  };
5651
- //#endregion
5652
- //#region src/css/property-descriptors/text-underline-offset.ts
5569
+ // src/css/property-descriptors/text-underline-offset.ts
5653
5570
  const textUnderlineOffset = {
5654
5571
  name: "text-underline-offset",
5655
5572
  initialValue: "auto",
@@ -5663,8 +5580,7 @@
5663
5580
  return "auto";
5664
5581
  }
5665
5582
  };
5666
- //#endregion
5667
- //#region src/css/property-descriptors/font-weight.ts
5583
+ // src/css/property-descriptors/font-weight.ts
5668
5584
  const fontWeight = {
5669
5585
  name: "font-weight",
5670
5586
  initialValue: "normal",
@@ -5679,8 +5595,7 @@
5679
5595
  return 400;
5680
5596
  }
5681
5597
  };
5682
- //#endregion
5683
- //#region src/css/property-descriptors/font-variant.ts
5598
+ // src/css/property-descriptors/font-variant.ts
5684
5599
  const fontVariant = {
5685
5600
  name: "font-variant",
5686
5601
  initialValue: "none",
@@ -5690,8 +5605,7 @@
5690
5605
  return tokens.filter(isIdentToken).map((token) => token.value);
5691
5606
  }
5692
5607
  };
5693
- //#endregion
5694
- //#region src/css/property-descriptors/font-style.ts
5608
+ // src/css/property-descriptors/font-style.ts
5695
5609
  const fontStyle = {
5696
5610
  name: "font-style",
5697
5611
  initialValue: "normal",
@@ -5705,8 +5619,7 @@
5705
5619
  }
5706
5620
  }
5707
5621
  };
5708
- //#endregion
5709
- //#region src/css/property-descriptors/duration.ts
5622
+ // src/css/property-descriptors/duration.ts
5710
5623
  const duration = {
5711
5624
  name: "duration",
5712
5625
  initialValue: "0s",
@@ -5716,8 +5629,7 @@
5716
5629
  return tokens.filter(isDimensionToken).map((token) => time.parse(context, token));
5717
5630
  }
5718
5631
  };
5719
- //#endregion
5720
- //#region src/css/property-descriptors/box-shadow.ts
5632
+ // src/css/property-descriptors/box-shadow.ts
5721
5633
  const boxShadow = {
5722
5634
  name: "box-shadow",
5723
5635
  initialValue: "none",
@@ -5751,8 +5663,7 @@
5751
5663
  });
5752
5664
  }
5753
5665
  };
5754
- //#endregion
5755
- //#region src/css/property-descriptors/paint-order.ts
5666
+ // src/css/property-descriptors/paint-order.ts
5756
5667
  const paintOrder = {
5757
5668
  name: "paint-order",
5758
5669
  initialValue: "normal",
@@ -5782,8 +5693,7 @@
5782
5693
  return layers;
5783
5694
  }
5784
5695
  };
5785
- //#endregion
5786
- //#region src/css/property-descriptors/webkit-text-stroke-color.ts
5696
+ // src/css/property-descriptors/webkit-text-stroke-color.ts
5787
5697
  const webkitTextStrokeColor = {
5788
5698
  name: `-webkit-text-stroke-color`,
5789
5699
  initialValue: "currentcolor",
@@ -5791,8 +5701,7 @@
5791
5701
  type: 3,
5792
5702
  format: "color"
5793
5703
  };
5794
- //#endregion
5795
- //#region src/css/property-descriptors/webkit-text-stroke-width.ts
5704
+ // src/css/property-descriptors/webkit-text-stroke-width.ts
5796
5705
  const webkitTextStrokeWidth = {
5797
5706
  name: `-webkit-text-stroke-width`,
5798
5707
  initialValue: "0",
@@ -5803,8 +5712,7 @@
5803
5712
  return 0;
5804
5713
  }
5805
5714
  };
5806
- //#endregion
5807
- //#region src/css/property-descriptors/webkit-line-clamp.ts
5715
+ // src/css/property-descriptors/webkit-line-clamp.ts
5808
5716
  /**
5809
5717
  * -webkit-line-clamp property descriptor
5810
5718
  * Used with display: -webkit-box and -webkit-box-orient: vertical
@@ -5821,8 +5729,7 @@
5821
5729
  return 0;
5822
5730
  }
5823
5731
  };
5824
- //#endregion
5825
- //#region src/css/property-descriptors/object-fit.ts
5732
+ // src/css/property-descriptors/object-fit.ts
5826
5733
  const objectFit = {
5827
5734
  name: "object-fit",
5828
5735
  initialValue: "fill",
@@ -5843,8 +5750,7 @@
5843
5750
  }
5844
5751
  return 0;
5845
5752
  };
5846
- //#endregion
5847
- //#region src/css/property-descriptors/text-overflow.ts
5753
+ // src/css/property-descriptors/text-overflow.ts
5848
5754
  const textOverflow = {
5849
5755
  name: "text-overflow",
5850
5756
  initialValue: "clip",
@@ -5857,8 +5763,7 @@
5857
5763
  }
5858
5764
  }
5859
5765
  };
5860
- //#endregion
5861
- //#region src/css/property-descriptors/image-rendering.ts
5766
+ // src/css/property-descriptors/image-rendering.ts
5862
5767
  const imageRendering = {
5863
5768
  name: "image-rendering",
5864
5769
  initialValue: "auto",
@@ -5877,8 +5782,7 @@
5877
5782
  }
5878
5783
  }
5879
5784
  };
5880
- //#endregion
5881
- //#region src/css/property-descriptors/mix-blend-mode.ts
5785
+ // src/css/property-descriptors/mix-blend-mode.ts
5882
5786
  const MIX_BLEND_MODE$1 = {
5883
5787
  NORMAL: "normal",
5884
5788
  MULTIPLY: "multiply",
@@ -5907,8 +5811,7 @@
5907
5811
  return VALID_VALUES$1.has(token) ? token : MIX_BLEND_MODE$1.NORMAL;
5908
5812
  }
5909
5813
  };
5910
- //#endregion
5911
- //#region src/css/property-descriptors/filter.ts
5814
+ // src/css/property-descriptors/filter.ts
5912
5815
  const filter = {
5913
5816
  name: "filter",
5914
5817
  initialValue: "none",
@@ -5978,8 +5881,7 @@
5978
5881
  }
5979
5882
  return parts.join("").trim();
5980
5883
  };
5981
- //#endregion
5982
- //#region src/css/property-descriptors/font-variant-ligatures.ts
5884
+ // src/css/property-descriptors/font-variant-ligatures.ts
5983
5885
  const fontVariantLigatures = {
5984
5886
  name: "font-variant-ligatures",
5985
5887
  initialValue: "normal",
@@ -6000,8 +5902,7 @@
6000
5902
  }
6001
5903
  }
6002
5904
  };
6003
- //#endregion
6004
- //#region src/css/property-descriptors/zoom.ts
5905
+ // src/css/property-descriptors/zoom.ts
6005
5906
  const zoom = {
6006
5907
  name: "zoom",
6007
5908
  initialValue: "1",
@@ -6013,8 +5914,7 @@
6013
5914
  return 1;
6014
5915
  }
6015
5916
  };
6016
- //#endregion
6017
- //#region src/css/property-descriptors/object-position.ts
5917
+ // src/css/property-descriptors/object-position.ts
6018
5918
  const objectPosition = {
6019
5919
  name: "object-position",
6020
5920
  initialValue: "50% 50%",
@@ -6076,8 +5976,7 @@
6076
5976
  return modes.length > 0 ? modes : ["normal"];
6077
5977
  }
6078
5978
  };
6079
- //#endregion
6080
- //#region src/css/property-descriptors/border-image-source.ts
5979
+ // src/css/property-descriptors/border-image-source.ts
6081
5980
  const borderImageSource = {
6082
5981
  name: "border-image-source",
6083
5982
  initialValue: "none",
@@ -6091,8 +5990,7 @@
6091
5990
  return image.parse(context, at(filtered, 0));
6092
5991
  }
6093
5992
  };
6094
- //#endregion
6095
- //#region src/css/property-descriptors/border-image-slice.ts
5993
+ // src/css/property-descriptors/border-image-slice.ts
6096
5994
  const fillSides$1 = (sides) => {
6097
5995
  const result = [...sides];
6098
5996
  if (result.length === 1) {
@@ -6141,8 +6039,7 @@
6141
6039
  };
6142
6040
  }
6143
6041
  };
6144
- //#endregion
6145
- //#region src/css/property-descriptors/border-image-repeat.ts
6042
+ // src/css/property-descriptors/border-image-repeat.ts
6146
6043
  const parseRepeatValue = (value) => {
6147
6044
  switch (value) {
6148
6045
  case "repeat": return 1;
@@ -6167,8 +6064,7 @@
6167
6064
  };
6168
6065
  }
6169
6066
  };
6170
- //#endregion
6171
- //#region src/css/property-descriptors/box-decoration-break.ts
6067
+ // src/css/property-descriptors/box-decoration-break.ts
6172
6068
  const boxDecorationBreak = {
6173
6069
  name: "box-decoration-break",
6174
6070
  initialValue: "slice",
@@ -6181,8 +6077,7 @@
6181
6077
  }
6182
6078
  }
6183
6079
  };
6184
- //#endregion
6185
- //#region src/css/property-descriptors/accent-color.ts
6080
+ // src/css/property-descriptors/accent-color.ts
6186
6081
  const accentColor = {
6187
6082
  name: "accent-color",
6188
6083
  initialValue: "auto",
@@ -6193,8 +6088,7 @@
6193
6088
  return color$1.parse(context, token);
6194
6089
  }
6195
6090
  };
6196
- //#endregion
6197
- //#region src/css/property-descriptors/webkit-text-fill-color.ts
6091
+ // src/css/property-descriptors/webkit-text-fill-color.ts
6198
6092
  const webkitTextFillColor = {
6199
6093
  name: "-webkit-text-fill-color",
6200
6094
  initialValue: "currentcolor",
@@ -6205,8 +6099,7 @@
6205
6099
  return color$1.parse(context, token);
6206
6100
  }
6207
6101
  };
6208
- //#endregion
6209
- //#region src/css/property-descriptors/isolation.ts
6102
+ // src/css/property-descriptors/isolation.ts
6210
6103
  const isolation = {
6211
6104
  name: "isolation",
6212
6105
  initialValue: "auto",
@@ -6216,8 +6109,52 @@
6216
6109
  return value === "isolate" ? 1 : 0;
6217
6110
  }
6218
6111
  };
6219
- //#endregion
6220
- //#region src/css/property-descriptors/outline.ts
6112
+ // src/css/property-descriptors/will-change.ts
6113
+ const STACKING_HINTS = /* @__PURE__ */ new Set([
6114
+ "transform",
6115
+ "translate",
6116
+ "rotate",
6117
+ "scale",
6118
+ "opacity",
6119
+ "filter",
6120
+ "backdrop-filter",
6121
+ "mix-blend-mode",
6122
+ "isolation",
6123
+ "clip-path",
6124
+ "mask",
6125
+ "mask-image",
6126
+ "mask-border",
6127
+ "perspective",
6128
+ "contain",
6129
+ "offset-path",
6130
+ "offset-distance",
6131
+ "offset-rotate",
6132
+ "top",
6133
+ "left",
6134
+ "bottom",
6135
+ "right",
6136
+ "z-index"
6137
+ ]);
6138
+ const willChange = {
6139
+ name: "will-change",
6140
+ initialValue: "auto",
6141
+ prefix: false,
6142
+ type: 1,
6143
+ parse: (_context, tokens) => {
6144
+ return tokens.some((token) => isIdentToken(token) && STACKING_HINTS.has(token.value)) ? 1 : 0;
6145
+ }
6146
+ };
6147
+ // src/css/property-descriptors/contain.ts
6148
+ const contain = {
6149
+ name: "contain",
6150
+ initialValue: "none",
6151
+ prefix: false,
6152
+ type: 2,
6153
+ parse: (_context, value) => {
6154
+ return /\b(paint|strict|content)\b/.test(value) ? 1 : 0;
6155
+ }
6156
+ };
6157
+ // src/css/property-descriptors/outline.ts
6221
6158
  const outlineStyle = {
6222
6159
  name: "outline-style",
6223
6160
  initialValue: "none",
@@ -6260,8 +6197,7 @@
6260
6197
  return isDimensionToken(token) || isNumberToken(token) ? token.number : 0;
6261
6198
  }
6262
6199
  };
6263
- //#endregion
6264
- //#region src/css/property-descriptors/backdrop-filter.ts
6200
+ // src/css/property-descriptors/backdrop-filter.ts
6265
6201
  const backdropFilter = {
6266
6202
  name: "backdrop-filter",
6267
6203
  initialValue: "none",
@@ -6269,8 +6205,7 @@
6269
6205
  type: 1,
6270
6206
  parse: (context, tokens) => filter.parse(context, tokens)
6271
6207
  };
6272
- //#endregion
6273
- //#region src/css/property-descriptors/mask.ts
6208
+ // src/css/property-descriptors/mask.ts
6274
6209
  const maskImage = {
6275
6210
  name: "mask-image",
6276
6211
  initialValue: "none",
@@ -6300,8 +6235,7 @@
6300
6235
  type: 1,
6301
6236
  parse: backgroundSize.parse
6302
6237
  };
6303
- //#endregion
6304
- //#region src/css/property-descriptors/text-emphasis.ts
6238
+ // src/css/property-descriptors/text-emphasis.ts
6305
6239
  const SHAPES = [
6306
6240
  "dot",
6307
6241
  "circle",
@@ -6376,8 +6310,7 @@
6376
6310
  };
6377
6311
  }
6378
6312
  };
6379
- //#endregion
6380
- //#region src/css/property-descriptors/border-image-width.ts
6313
+ // src/css/property-descriptors/border-image-width.ts
6381
6314
  const fillSides = (sides) => {
6382
6315
  const result = [...sides];
6383
6316
  if (result.length === 1) {
@@ -6474,8 +6407,7 @@
6474
6407
  };
6475
6408
  }
6476
6409
  };
6477
- //#endregion
6478
- //#region src/css/property-descriptors/webkit-box-reflect.ts
6410
+ // src/css/property-descriptors/webkit-box-reflect.ts
6479
6411
  /**
6480
6412
  * -webkit-box-reflect: <direction> <offset>? <mask-image>?
6481
6413
  *
@@ -6519,8 +6451,7 @@
6519
6451
  };
6520
6452
  }
6521
6453
  };
6522
- //#endregion
6523
- //#region src/css/property-descriptors/translate.ts
6454
+ // src/css/property-descriptors/translate.ts
6524
6455
  const translate = {
6525
6456
  name: "translate",
6526
6457
  initialValue: "none",
@@ -6533,8 +6464,7 @@
6533
6464
  return [at(values, 0), values.length > 1 ? at(values, 1) : ZERO_LENGTH];
6534
6465
  }
6535
6466
  };
6536
- //#endregion
6537
- //#region src/css/property-descriptors/scale.ts
6467
+ // src/css/property-descriptors/scale.ts
6538
6468
  const scale = {
6539
6469
  name: "scale",
6540
6470
  initialValue: "none",
@@ -6569,8 +6499,7 @@
6569
6499
  * never fires, the mount is rejected instead of hanging forever.
6570
6500
  */
6571
6501
  const IFRAME_LOAD_WATCHDOG_MS = 6e4;
6572
- //#endregion
6573
- //#region src/css/parse.ts
6502
+ // src/css/parse.ts
6574
6503
  const STANDARD_PROPERTIES = [
6575
6504
  [
6576
6505
  "animationDuration",
@@ -7007,6 +6936,16 @@
7007
6936
  isolation,
7008
6937
  "isolation"
7009
6938
  ],
6939
+ [
6940
+ "willChange",
6941
+ willChange,
6942
+ "will-change"
6943
+ ],
6944
+ [
6945
+ "contain",
6946
+ contain,
6947
+ "contain"
6948
+ ],
7010
6949
  [
7011
6950
  "outlineColor",
7012
6951
  outlineColor,
@@ -7138,8 +7077,7 @@
7138
7077
  }
7139
7078
  return result;
7140
7079
  };
7141
- //#endregion
7142
- //#region src/css/grouped/border-styles.ts
7080
+ // src/css/grouped/border-styles.ts
7143
7081
  /**
7144
7082
  * Read-only grouped accessor for border-related CSS properties.
7145
7083
  *
@@ -7216,8 +7154,7 @@
7216
7154
  return this.styles.boxShadow;
7217
7155
  }
7218
7156
  };
7219
- //#endregion
7220
- //#region src/css/grouped/background-styles.ts
7157
+ // src/css/grouped/background-styles.ts
7221
7158
  /**
7222
7159
  * Read-only grouped accessor for background-related CSS properties.
7223
7160
  *
@@ -7255,8 +7192,7 @@
7255
7192
  return this.styles.backgroundBlendMode;
7256
7193
  }
7257
7194
  };
7258
- //#endregion
7259
- //#region src/css/grouped/font-styles.ts
7195
+ // src/css/grouped/font-styles.ts
7260
7196
  /**
7261
7197
  * Read-only grouped accessor for font/text-related CSS properties.
7262
7198
  *
@@ -7351,8 +7287,7 @@
7351
7287
  return this.styles.paintOrder;
7352
7288
  }
7353
7289
  };
7354
- //#endregion
7355
- //#region src/css/grouped/layout-styles.ts
7290
+ // src/css/grouped/layout-styles.ts
7356
7291
  /**
7357
7292
  * Read-only grouped accessor for layout/display/positioning CSS properties.
7358
7293
  *
@@ -7480,8 +7415,7 @@
7480
7415
  return this.styles.isInlineLevel();
7481
7416
  }
7482
7417
  };
7483
- //#endregion
7484
- //#region src/css/index.ts
7418
+ // src/css/index.ts
7485
7419
  var CSSParsedDeclaration = class {
7486
7420
  animationDuration;
7487
7421
  backgroundClip;
@@ -7575,6 +7509,8 @@
7575
7509
  accentColor;
7576
7510
  webkitTextFillColor;
7577
7511
  isolation;
7512
+ willChange;
7513
+ contain;
7578
7514
  outlineColor;
7579
7515
  outlineStyle;
7580
7516
  outlineWidth;
@@ -7673,8 +7609,7 @@
7673
7609
  this.counterReset = parse(context, counterReset, declaration.counterReset);
7674
7610
  }
7675
7611
  };
7676
- //#endregion
7677
- //#region src/core/debugger.ts
7612
+ // src/core/debugger.ts
7678
7613
  const elementDebuggerAttribute = "data-html2canvas-debug";
7679
7614
  const getElementDebugType = (element) => {
7680
7615
  if (typeof element.getAttribute !== "function") return 0;
@@ -7690,8 +7625,7 @@
7690
7625
  const elementType = getElementDebugType(element);
7691
7626
  return elementType === 1 || type === elementType;
7692
7627
  };
7693
- //#endregion
7694
- //#region src/dom/adopted-styles.ts
7628
+ // src/dom/adopted-styles.ts
7695
7629
  /**
7696
7630
  * Constructable stylesheet cloning (adoptedStyleSheets).
7697
7631
  *
@@ -7732,8 +7666,7 @@
7732
7666
  if (nonce) style.nonce = nonce;
7733
7667
  return style;
7734
7668
  };
7735
- //#endregion
7736
- //#region src/dom/slot-cloner.ts
7669
+ // src/dom/slot-cloner.ts
7737
7670
  /** Exported for reuse in document-cloner.ts */
7738
7671
  const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
7739
7672
  /**
@@ -7870,8 +7803,7 @@
7870
7803
  if (style) target.appendChild(style);
7871
7804
  }
7872
7805
  };
7873
- //#endregion
7874
- //#region src/dom/copy-css-styles.ts
7806
+ // src/dom/copy-css-styles.ts
7875
7807
  /**
7876
7808
  * Computed-style copying for cloned elements.
7877
7809
  *
@@ -7899,8 +7831,7 @@
7899
7831
  if (parts.length > 0) target.style.cssText = parts.join(";") + ";";
7900
7832
  return target;
7901
7833
  };
7902
- //#endregion
7903
- //#region src/dom/pseudo-content.ts
7834
+ // src/dom/pseudo-content.ts
7904
7835
  /**
7905
7836
  * Pseudo-element (::before / ::after) content resolution.
7906
7837
  *
@@ -7920,19 +7851,19 @@
7920
7851
  }`;
7921
7852
  /**
7922
7853
  * Inject the stylesheet that hides pseudo-element surrogate containers.
7923
- * Called on the cloned <body> so the surrogates themselves never render.
7854
+ * Added to the cloned <head> so the surrogates themselves never render.
7924
7855
  */
7925
- const createPseudoHideStyles = (body, cspNonce) => {
7926
- createStyles(body, `.${PSEUDO_HIDE_ELEMENT_CLASS_BEFORE}${PSEUDO_BEFORE}${PSEUDO_HIDE_ELEMENT_STYLE}
7856
+ const createPseudoHideStyles = (parent, cspNonce) => {
7857
+ createStyles(parent, `.${PSEUDO_HIDE_ELEMENT_CLASS_BEFORE}${PSEUDO_BEFORE}${PSEUDO_HIDE_ELEMENT_STYLE}
7927
7858
  .${PSEUDO_HIDE_ELEMENT_CLASS_AFTER}${PSEUDO_AFTER}${PSEUDO_HIDE_ELEMENT_STYLE}`, cspNonce);
7928
7859
  };
7929
- const createStyles = (body, styles, cspNonce) => {
7930
- const document = body.ownerDocument;
7860
+ const createStyles = (parent, styles, cspNonce) => {
7861
+ const document = parent.ownerDocument;
7931
7862
  if (document) {
7932
7863
  const style = document.createElement("style");
7933
7864
  style.textContent = styles;
7934
7865
  if (cspNonce) style.nonce = cspNonce;
7935
- body.appendChild(style);
7866
+ parent.appendChild(style);
7936
7867
  }
7937
7868
  };
7938
7869
  /**
@@ -8006,8 +7937,7 @@
8006
7937
  return anonymousReplacedElement;
8007
7938
  }
8008
7939
  };
8009
- //#endregion
8010
- //#region src/core/abort-helper.ts
7940
+ // src/core/abort-helper.ts
8011
7941
  /**
8012
7942
  * AbortSignal helper utilities.
8013
7943
  */
@@ -8022,8 +7952,7 @@
8022
7952
  const throwIfAborted = (signal) => {
8023
7953
  if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
8024
7954
  };
8025
- //#endregion
8026
- //#region src/dom/iframe-mount.ts
7955
+ // src/dom/iframe-mount.ts
8027
7956
  const trustedTypePolicies = /* @__PURE__ */ new WeakMap();
8028
7957
  /**
8029
7958
  * Resolve the Trusted Types policy used for writing the clone document.
@@ -8052,9 +7981,20 @@
8052
7981
  cloneIframeContainer.style.position = "fixed";
8053
7982
  cloneIframeContainer.style.left = "-10000px";
8054
7983
  cloneIframeContainer.style.top = "0px";
8055
- cloneIframeContainer.style.border = "0";
8056
7984
  cloneIframeContainer.width = bounds.width.toString();
8057
7985
  cloneIframeContainer.height = bounds.height.toString();
7986
+ const contentBox = [
7987
+ ["width", `${bounds.width}px`],
7988
+ ["height", `${bounds.height}px`],
7989
+ ["min-width", "0px"],
7990
+ ["max-width", "none"],
7991
+ ["min-height", "0px"],
7992
+ ["max-height", "none"],
7993
+ ["box-sizing", "content-box"],
7994
+ ["padding", "0px"],
7995
+ ["border", "0"]
7996
+ ];
7997
+ for (const [property, value] of contentBox) cloneIframeContainer.style.setProperty(property, value, "important");
8058
7998
  cloneIframeContainer.scrolling = "no";
8059
7999
  cloneIframeContainer.setAttribute(IGNORE_ATTRIBUTE, "true");
8060
8000
  (customContainer || ownerDocument.body).appendChild(cloneIframeContainer);
@@ -8187,6 +8127,11 @@
8187
8127
  pending.push(new Promise((resolve) => {
8188
8128
  let elapsed = 0;
8189
8129
  const timer = setInterval(() => {
8130
+ if (signal?.aborted) {
8131
+ clearInterval(timer);
8132
+ resolve();
8133
+ return;
8134
+ }
8190
8135
  elapsed += 50;
8191
8136
  const currentSheet = style.sheet;
8192
8137
  if (currentSheet && isSheetFullyApplied(currentSheet) || elapsed >= timeoutMs) {
@@ -8357,8 +8302,7 @@
8357
8302
  throw error;
8358
8303
  });
8359
8304
  };
8360
- //#endregion
8361
- //#region src/dom/document-cloner.ts
8305
+ // src/dom/document-cloner.ts
8362
8306
  /**
8363
8307
  * Find the parent ShadowRoot of an element, if any
8364
8308
  * @param element - The element to check
@@ -8403,6 +8347,7 @@
8403
8347
  }
8404
8348
  this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false);
8405
8349
  this.appendDocumentAdoptedStyles(element.ownerDocument);
8350
+ this.appendPseudoHideStyles();
8406
8351
  }
8407
8352
  /**
8408
8353
  * Re-materialise the source document's constructable stylesheets
@@ -8422,6 +8367,16 @@
8422
8367
  const style = createAdoptedStylesElement(this.documentElement.ownerDocument ?? ownerDocument, sheets, this.options.cspNonce);
8423
8368
  if (style) head.appendChild(style);
8424
8369
  }
8370
+ /**
8371
+ * Add the rules that hide the source ::before / ::after (the clone draws
8372
+ * them as surrogate elements) to the clone's <head>. Inside <body> the
8373
+ * <style> would be one of its children, and `body > :first-child`,
8374
+ * `:nth-child()` and sibling selectors would match the wrong elements.
8375
+ */
8376
+ appendPseudoHideStyles() {
8377
+ const head = this.documentElement.getElementsByTagName("head").item(0);
8378
+ createPseudoHideStyles(head ?? this.documentElement, this.options.cspNonce);
8379
+ }
8425
8380
  toIFrame(ownerDocument, windowSize) {
8426
8381
  return mountCloneInIFrame(this.context, ownerDocument, windowSize, {
8427
8382
  documentElement: this.documentElement,
@@ -8557,7 +8512,6 @@
8557
8512
  const style = window.getComputedStyle(node);
8558
8513
  const checkPseudoElements = canHavePseudoElements(node);
8559
8514
  if (this.referenceElement === node && isHTMLElementNode(clone)) this.clonedReferenceElement = clone;
8560
- if (isBodyElement(clone)) createPseudoHideStyles(clone, this.options.cspNonce);
8561
8515
  const counters = this.counters.parse(new CSSParsedCounterDeclaration(this.context, style));
8562
8516
  if (checkPseudoElements) {
8563
8517
  const styleBefore = window.getComputedStyle(node, ":before");
@@ -8591,8 +8545,7 @@
8591
8545
  return false;
8592
8546
  }
8593
8547
  };
8594
- //#endregion
8595
- //#region src/dom/dom-normalizer.ts
8548
+ // src/dom/dom-normalizer.ts
8596
8549
  /**
8597
8550
  * Normalize element styles for accurate rendering
8598
8551
  * This includes disabling animations and neutralizing transforms.
@@ -8680,8 +8633,115 @@
8680
8633
  if (originalStyles.scale !== void 0) element.style.scale = originalStyles.scale;
8681
8634
  }
8682
8635
  };
8683
- //#endregion
8684
- //#region src/dom/element-container.ts
8636
+ // src/dom/filter-reference.ts
8637
+ const SVG_NS$1 = "http://www.w3.org/2000/svg";
8638
+ const XLINK_NS = "http://www.w3.org/1999/xlink";
8639
+ const REGION_DEFAULTS = {
8640
+ x: "-10%",
8641
+ y: "-10%",
8642
+ width: "120%",
8643
+ height: "120%"
8644
+ };
8645
+ const PRESENTATION_PROPERTIES = [
8646
+ "color-interpolation-filters",
8647
+ "flood-color",
8648
+ "flood-opacity",
8649
+ "lighting-color"
8650
+ ];
8651
+ const REFERENCE_RE = /^(["']?)(#[^"'\s()]+)\1$/;
8652
+ const URL_RE = /url\(\s*([^)]*?)\s*\)/g;
8653
+ /** The `#id` of a same-document url() body (`"#id"`, `'#id'` or `#id`), or null. */
8654
+ const parseFilterReference = (body) => {
8655
+ const match = REFERENCE_RE.exec(body.trim());
8656
+ return match ? match[2] : null;
8657
+ };
8658
+ /**
8659
+ * Resolve every same-document url() reference of a computed filter value.
8660
+ * References that cannot be expressed in the serialized SVG are left out, so
8661
+ * the compositor rejects the chain and the subtree keeps the legacy renderer.
8662
+ */
8663
+ function resolveFilterReferences(element, filter, box) {
8664
+ if (!filter || filter.indexOf("url(") === -1) return void 0;
8665
+ const references = /* @__PURE__ */ new Map();
8666
+ const seen = /* @__PURE__ */ new Set();
8667
+ for (const match of filter.matchAll(URL_RE)) {
8668
+ const ref = parseFilterReference(match[1]);
8669
+ if (!ref || seen.has(ref)) continue;
8670
+ seen.add(ref);
8671
+ const reference = resolveFilterReference(element.ownerDocument, ref, box);
8672
+ if (reference) references.set(ref, reference);
8673
+ }
8674
+ return references;
8675
+ }
8676
+ function resolveFilterReference(document, ref, box) {
8677
+ const source = document.getElementById(ref.slice(1));
8678
+ if (!source || source.namespaceURI !== SVG_NS$1 || source.localName !== "filter") return null;
8679
+ if (!isSelfContained(source)) return null;
8680
+ const region = filterRegion(source, box);
8681
+ if (!region) return null;
8682
+ const copy = source.cloneNode(true);
8683
+ inlinePresentation(source, copy);
8684
+ copy.removeAttribute("id");
8685
+ copy.setAttribute("filterUnits", "userSpaceOnUse");
8686
+ Object.keys(region).forEach((name) => copy.setAttribute(name, String(region[name])));
8687
+ const outset = Math.max(0, -region.x, -region.y, region.x + region.width - box.width, region.y + region.height - box.height);
8688
+ return {
8689
+ element: copy,
8690
+ region,
8691
+ outset: Math.ceil(outset)
8692
+ };
8693
+ }
8694
+ const hasHref = (node) => node.hasAttribute("href") || node.hasAttributeNS(XLINK_NS, "href");
8695
+ function isSelfContained(source) {
8696
+ if (source.getAttribute("primitiveUnits") === "objectBoundingBox" || hasHref(source)) return false;
8697
+ for (const primitive of Array.from(source.querySelectorAll("*"))) {
8698
+ if (primitive.localName === "feImage" || hasHref(primitive)) return false;
8699
+ for (const name of [
8700
+ "x",
8701
+ "y",
8702
+ "width",
8703
+ "height"
8704
+ ]) if ((primitive.getAttribute(name) ?? "").indexOf("%") !== -1) return false;
8705
+ }
8706
+ return true;
8707
+ }
8708
+ function filterRegion(source, box) {
8709
+ const boundingBox = source.getAttribute("filterUnits") !== "userSpaceOnUse";
8710
+ const read = (name, size) => {
8711
+ const raw = (source.getAttribute(name) ?? (boundingBox ? REGION_DEFAULTS[name] : "")).trim();
8712
+ if (raw === "") return null;
8713
+ const percentage = raw.endsWith("%");
8714
+ const value = Number(percentage ? raw.slice(0, -1) : raw.replace(/px$/, ""));
8715
+ if (!Number.isFinite(value)) return null;
8716
+ if (boundingBox) return (percentage ? value / 100 : value) * size;
8717
+ return percentage ? null : value;
8718
+ };
8719
+ const x = read("x", box.width);
8720
+ const y = read("y", box.height);
8721
+ const width = read("width", box.width);
8722
+ const height = read("height", box.height);
8723
+ if (x === null || y === null || width === null || height === null || width <= 0 || height <= 0) return null;
8724
+ return {
8725
+ x,
8726
+ y,
8727
+ width,
8728
+ height
8729
+ };
8730
+ }
8731
+ function inlinePresentation(source, copy) {
8732
+ const view = source.ownerDocument.defaultView;
8733
+ if (!view) return;
8734
+ const sources = [source, ...Array.from(source.querySelectorAll("*"))];
8735
+ const copies = [copy, ...Array.from(copy.querySelectorAll("*"))];
8736
+ sources.forEach((node, index) => {
8737
+ const style = view.getComputedStyle(node);
8738
+ for (const property of PRESENTATION_PROPERTIES) {
8739
+ const value = style.getPropertyValue(property);
8740
+ if (value) copies[index]?.setAttribute(property, value);
8741
+ }
8742
+ });
8743
+ }
8744
+ // src/dom/element-container.ts
8685
8745
  var ElementContainer = class {
8686
8746
  context;
8687
8747
  styles;
@@ -8694,6 +8754,11 @@
8694
8754
  * bounds to leave a matching gap (issue #227).
8695
8755
  */
8696
8756
  legendBounds;
8757
+ /**
8758
+ * Same-document `filter: url(#id)` references, resolved while the cloned
8759
+ * DOM is available. The surface compositor renders them in an SVG pass.
8760
+ */
8761
+ filterReferences;
8697
8762
  createsStackingContext = false;
8698
8763
  createsRealStackingContext = false;
8699
8764
  isListOwner = false;
@@ -8718,6 +8783,7 @@
8718
8783
  this.bounds = new Bounds(this.bounds.left, borderBoxTop, this.bounds.width, this.bounds.height - (borderBoxTop - this.bounds.top));
8719
8784
  }
8720
8785
  }
8786
+ this.filterReferences = resolveFilterReferences(element, this.styles.filter, this.bounds);
8721
8787
  if (isDebugging(element, 4)) this.debugRender = true;
8722
8788
  }
8723
8789
  /**
@@ -8740,8 +8806,7 @@
8740
8806
  for (const child of this.elements) child.restoreTree();
8741
8807
  }
8742
8808
  };
8743
- //#endregion
8744
- //#region src/core/features.ts
8809
+ // src/core/features.ts
8745
8810
  /**
8746
8811
  * Runtime feature detection.
8747
8812
  *
@@ -8827,8 +8892,7 @@
8827
8892
  return value;
8828
8893
  }
8829
8894
  };
8830
- //#endregion
8831
- //#region src/css/layout/text.ts
8895
+ // src/css/layout/text.ts
8832
8896
  var TextBounds = class {
8833
8897
  text;
8834
8898
  bounds;
@@ -8903,8 +8967,7 @@
8903
8967
  if (isVerticalWritingMode(styles.writingMode)) return segmentGraphemes(value);
8904
8968
  return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value);
8905
8969
  };
8906
- //#endregion
8907
- //#region src/dom/text-container.ts
8970
+ // src/dom/text-container.ts
8908
8971
  var TextContainer = class {
8909
8972
  text;
8910
8973
  textBounds;
@@ -8927,8 +8990,7 @@
8927
8990
  if (m.length > 0) return p1 + p2.toUpperCase();
8928
8991
  return m;
8929
8992
  };
8930
- //#endregion
8931
- //#region src/dom/replaced-elements/image-element-container.ts
8993
+ // src/dom/replaced-elements/image-element-container.ts
8932
8994
  var ImageElementContainer = class extends ElementContainer {
8933
8995
  src;
8934
8996
  intrinsicWidth;
@@ -8941,8 +9003,7 @@
8941
9003
  this.context.cache.addImage(this.src);
8942
9004
  }
8943
9005
  };
8944
- //#endregion
8945
- //#region src/dom/replaced-elements/canvas-element-container.ts
9006
+ // src/dom/replaced-elements/canvas-element-container.ts
8946
9007
  var CanvasElementContainer = class extends ElementContainer {
8947
9008
  canvas;
8948
9009
  intrinsicWidth;
@@ -8954,8 +9015,7 @@
8954
9015
  this.intrinsicHeight = canvas.height;
8955
9016
  }
8956
9017
  };
8957
- //#endregion
8958
- //#region src/dom/replaced-elements/svg-element-container.ts
9018
+ // src/dom/replaced-elements/svg-element-container.ts
8959
9019
  const BOX_OFFSET_PROPERTIES = [
8960
9020
  "position",
8961
9021
  "inset",
@@ -9005,8 +9065,7 @@
9005
9065
  this.context.cache.addImage(this.svg);
9006
9066
  }
9007
9067
  };
9008
- //#endregion
9009
- //#region src/dom/elements/li-element-container.ts
9068
+ // src/dom/elements/li-element-container.ts
9010
9069
  var LIElementContainer = class extends ElementContainer {
9011
9070
  value;
9012
9071
  constructor(context, element, options = {}) {
@@ -9014,8 +9073,7 @@
9014
9073
  this.value = element.value;
9015
9074
  }
9016
9075
  };
9017
- //#endregion
9018
- //#region src/dom/elements/ol-element-container.ts
9076
+ // src/dom/elements/ol-element-container.ts
9019
9077
  var OLElementContainer = class extends ElementContainer {
9020
9078
  start;
9021
9079
  reversed;
@@ -9025,8 +9083,7 @@
9025
9083
  this.reversed = typeof element.reversed === "boolean" && element.reversed === true;
9026
9084
  }
9027
9085
  };
9028
- //#endregion
9029
- //#region src/dom/replaced-elements/input-element-container.ts
9086
+ // src/dom/replaced-elements/input-element-container.ts
9030
9087
  const CHECKBOX_BORDER_RADIUS = [{
9031
9088
  type: 15,
9032
9089
  flags: 0,
@@ -9081,8 +9138,7 @@
9081
9138
  }
9082
9139
  }
9083
9140
  };
9084
- //#endregion
9085
- //#region src/dom/elements/select-element-container.ts
9141
+ // src/dom/elements/select-element-container.ts
9086
9142
  var SelectElementContainer = class extends ElementContainer {
9087
9143
  value;
9088
9144
  constructor(context, element, options = {}) {
@@ -9091,8 +9147,7 @@
9091
9147
  this.value = option ? option.text || "" : "";
9092
9148
  }
9093
9149
  };
9094
- //#endregion
9095
- //#region src/dom/elements/textarea-element-container.ts
9150
+ // src/dom/elements/textarea-element-container.ts
9096
9151
  var TextareaElementContainer = class extends ElementContainer {
9097
9152
  value;
9098
9153
  constructor(context, element, options = {}) {
@@ -9100,8 +9155,7 @@
9100
9155
  this.value = element.value;
9101
9156
  }
9102
9157
  };
9103
- //#endregion
9104
- //#region src/dom/replaced-elements/iframe-element-container.ts
9158
+ // src/dom/replaced-elements/iframe-element-container.ts
9105
9159
  var IFrameElementContainer = class extends ElementContainer {
9106
9160
  src;
9107
9161
  width;
@@ -9132,8 +9186,7 @@
9132
9186
  }
9133
9187
  }
9134
9188
  };
9135
- //#endregion
9136
- //#region src/dom/node-parser.ts
9189
+ // src/dom/node-parser.ts
9137
9190
  const LIST_OWNERS = [
9138
9191
  "OL",
9139
9192
  "UL",
@@ -9199,15 +9252,14 @@
9199
9252
  return container;
9200
9253
  };
9201
9254
  const createsRealStackingContext = (node, container, root) => {
9202
- return container.styles.isPositionedWithZIndex() || container.styles.opacity < 1 || Boolean(container.styles.filter) || Boolean(container.styles.backdropFilter) || container.styles.maskImage.length > 0 || Boolean(container.styles.webkitBoxReflect) || container.styles.isolation === 1 || container.styles.isTransformed() || isBodyElement(node) && root.styles.isTransparent();
9255
+ return container.styles.isPositionedWithZIndex() || container.styles.opacity < 1 || Boolean(container.styles.filter) || Boolean(container.styles.backdropFilter) || container.styles.maskImage.length > 0 || Boolean(container.styles.webkitBoxReflect) || container.styles.isolation === 1 || container.styles.willChange === 1 || container.styles.contain === 1 || container.styles.isTransformed() || isBodyElement(node) && root.styles.isTransparent();
9203
9256
  };
9204
9257
  const createsStackingContext = (styles) => {
9205
9258
  if (styles.isPositioned() || styles.isFloating()) return true;
9206
9259
  if (styles.mixBlendMode !== MIX_BLEND_MODE$1.NORMAL) return true;
9207
9260
  return contains(styles.display, 268435456) || contains(styles.display, 33554432) || contains(styles.display, 536870912) || contains(styles.display, 134217728);
9208
9261
  };
9209
- //#endregion
9210
- //#region src/render/path.ts
9262
+ // src/render/path.ts
9211
9263
  const equalPath = (a, b) => {
9212
9264
  if (a.length === b.length) return a.some((v, i) => v === b[i]);
9213
9265
  return false;
@@ -9223,8 +9275,7 @@
9223
9275
  return point;
9224
9276
  });
9225
9277
  };
9226
- //#endregion
9227
- //#region src/render/vector.ts
9278
+ // src/render/vector.ts
9228
9279
  var Vector = class Vector {
9229
9280
  type;
9230
9281
  x;
@@ -9238,8 +9289,7 @@
9238
9289
  return new Vector(this.x + deltaX, this.y + deltaY);
9239
9290
  }
9240
9291
  };
9241
- //#endregion
9242
- //#region src/render/bezier-curve.ts
9292
+ // src/render/bezier-curve.ts
9243
9293
  const lerp = (a, b, t) => {
9244
9294
  return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
9245
9295
  };
@@ -9273,8 +9323,7 @@
9273
9323
  }
9274
9324
  };
9275
9325
  const isBezierCurve = (path) => path.type === 1;
9276
- //#endregion
9277
- //#region src/render/bound-curves.ts
9326
+ // src/render/bound-curves.ts
9278
9327
  var BoundCurves = class {
9279
9328
  topLeftBorderDoubleOuterBox;
9280
9329
  topRightBorderDoubleOuterBox;
@@ -9398,8 +9447,7 @@
9398
9447
  curves.bottomLeftPaddingBox
9399
9448
  ];
9400
9449
  };
9401
- //#endregion
9402
- //#region src/render/effects.ts
9450
+ // src/render/effects.ts
9403
9451
  var TransformEffect = class {
9404
9452
  offsetX;
9405
9453
  offsetY;
@@ -9606,8 +9654,7 @@
9606
9654
  const isClipPathEffect = (effect) => effect.type === 3;
9607
9655
  const isBlendEffect = (effect) => effect.type === 4;
9608
9656
  const isFilterEffect = (effect) => effect.type === 5;
9609
- //#endregion
9610
- //#region src/render/stacking-context.ts
9657
+ // src/render/stacking-context.ts
9611
9658
  var StackingContext = class {
9612
9659
  element;
9613
9660
  negativeZIndex;
@@ -9930,8 +9977,7 @@
9930
9977
  processListItems(paintContainer.container, listItems);
9931
9978
  return root;
9932
9979
  };
9933
- //#endregion
9934
- //#region src/render/canvas/gradient-rasterizer.ts
9980
+ // src/render/canvas/gradient-rasterizer.ts
9935
9981
  const clampStop = (stop) => Math.min(1, Math.max(0, stop));
9936
9982
  /**
9937
9983
  * Stack the one-cycle stop list periodically across [0, 1]. Returns null for
@@ -10010,8 +10056,7 @@
10010
10056
  ry
10011
10057
  };
10012
10058
  };
10013
- //#endregion
10014
- //#region src/render/box-sizing.ts
10059
+ // src/render/box-sizing.ts
10015
10060
  const paddingBox = (element) => {
10016
10061
  const bounds = element.bounds;
10017
10062
  const styles = element.styles;
@@ -10026,8 +10071,7 @@
10026
10071
  const paddingBottom = getAbsoluteValue(styles.paddingBottom, bounds.width);
10027
10072
  return bounds.add(paddingLeft + styles.borderLeftWidth, paddingTop + styles.borderTopWidth, -(styles.borderRightWidth + styles.borderLeftWidth + paddingLeft + paddingRight), -(styles.borderTopWidth + styles.borderBottomWidth + paddingTop + paddingBottom));
10028
10073
  };
10029
- //#endregion
10030
- //#region src/render/background.ts
10074
+ // src/render/background.ts
10031
10075
  const calculateBackgroundPositioningArea = (backgroundOrigin, element) => {
10032
10076
  if (backgroundOrigin === 0) return element.bounds;
10033
10077
  if (backgroundOrigin === 2) return contentBox(element);
@@ -10128,8 +10172,7 @@
10128
10172
  ];
10129
10173
  }
10130
10174
  };
10131
- //#endregion
10132
- //#region src/render/canvas/filter-surface.ts
10175
+ // src/render/canvas/filter-surface.ts
10133
10176
  var FilterSurfaceError = class extends Error {};
10134
10177
  const releaseSurface = (canvas) => {
10135
10178
  canvas.width = canvas.height = 0;
@@ -10233,6 +10276,13 @@
10233
10276
  value: Number.parseFloat(numeric) * (percentage ? 1 / 100 : 1)
10234
10277
  };
10235
10278
  }
10279
+ if (name === "url") {
10280
+ const ref = parseFilterReference(body);
10281
+ return ref ? {
10282
+ kind: "url",
10283
+ ref
10284
+ } : null;
10285
+ }
10236
10286
  return null;
10237
10287
  };
10238
10288
  /** Split on whitespace outside parentheses so rgba(...) colours stay one token. */
@@ -10288,22 +10338,25 @@
10288
10338
  case "blur": return `blur(${fn.value * scale}px)`;
10289
10339
  case "drop-shadow": return `drop-shadow(${fn.x * scale}px ${fn.y * scale}px ${fn.blur * scale}px ${fn.color})`;
10290
10340
  case "unitless": return fn.name === "hue-rotate" ? `hue-rotate(${fn.value}deg)` : `${fn.name}(${fn.value})`;
10341
+ case "url": return `url("${fn.ref}")`;
10291
10342
  }
10292
10343
  }).join(" ");
10293
10344
  /**
10294
10345
  * Outset (in CSS pixels) a surface must grow so blur/shadow spillover is not
10295
10346
  * cropped. Unitless functions never spread beyond the bounds. Consecutive
10296
- * blurs compound, so their radii sum.
10347
+ * blurs compound, so their radii sum. A url() reference can paint up to its
10348
+ * filter region, which may extend beyond the border box.
10297
10349
  */
10298
- function filterOutset(filter) {
10350
+ function filterOutset(filter, references) {
10299
10351
  let blurSum = 0;
10300
10352
  let maxShadowOffset = 0;
10353
+ let referenceOutset = 0;
10301
10354
  for (const fn of filter.functions) if (fn.kind === "blur") blurSum += fn.value;
10302
10355
  else if (fn.kind === "drop-shadow") {
10303
10356
  blurSum += fn.blur;
10304
10357
  maxShadowOffset = Math.max(maxShadowOffset, Math.abs(fn.x), Math.abs(fn.y));
10305
- }
10306
- return Math.ceil(3 * blurSum + maxShadowOffset);
10358
+ } else if (fn.kind === "url") referenceOutset += references?.get(fn.ref)?.outset ?? 0;
10359
+ return Math.ceil(3 * blurSum + maxShadowOffset + referenceOutset);
10307
10360
  }
10308
10361
  function canvasLike(source) {
10309
10362
  const canvas = (source.ownerDocument ?? document).createElement("canvas");
@@ -10399,8 +10452,9 @@
10399
10452
  if (blurs > 0 && shadows > 0) return filter.functions.findIndex((fn) => fn.kind === "blur") < filter.functions.findIndex((fn) => fn.kind === "drop-shadow");
10400
10453
  return true;
10401
10454
  };
10402
- async function renderFilterSurface(source, filter, opacity, scale, signal) {
10455
+ async function renderFilterSurface(source, filter, opacity, scale, signal, references) {
10403
10456
  throwIfAborted(signal);
10457
+ if (filter.functions.some((fn) => fn.kind === "url")) return renderReferencedFilterSurface(source, filter, opacity, scale, signal, references);
10404
10458
  if (filter.functions.length > 0 && supportsNativeFilters(source.ownerDocument ?? document)) {
10405
10459
  const output = tryNativeFilterSurface(source, filter, opacity, scale, signal);
10406
10460
  if (output) return output;
@@ -10408,6 +10462,136 @@
10408
10462
  if (!isSvgExpressible(filter)) throw new FilterSurfaceError("Filter chain requires native canvas filters");
10409
10463
  return renderSvgFilterSurface(source, filter, opacity, scale, signal);
10410
10464
  }
10465
+ /**
10466
+ * Split a chain at its url() references: each reference is one SVG pass, and
10467
+ * the standard functions between them run through the usual backends. Every
10468
+ * step filters the previous step's complete output at alpha 1, then CSS
10469
+ * opacity is applied once, as for any other chain.
10470
+ */
10471
+ async function renderReferencedFilterSurface(source, filter, opacity, scale, signal, context) {
10472
+ const steps = [];
10473
+ for (const fn of filter.functions) {
10474
+ if (fn.kind === "url") {
10475
+ const reference = context?.references?.get(fn.ref);
10476
+ if (!reference) throw new FilterSurfaceError(`Filter reference ${fn.ref} cannot be resolved`);
10477
+ steps.push(reference);
10478
+ continue;
10479
+ }
10480
+ const last = steps[steps.length - 1];
10481
+ if (Array.isArray(last)) last.push(fn);
10482
+ else steps.push([fn]);
10483
+ }
10484
+ const origin = context?.origin ?? {
10485
+ x: 0,
10486
+ y: 0
10487
+ };
10488
+ const last = steps[steps.length - 1];
10489
+ const opacityApplied = Array.isArray(last);
10490
+ let current = source;
10491
+ try {
10492
+ for (const step of steps) {
10493
+ const next = Array.isArray(step) ? await renderFilterSurface(current, { functions: step }, step === last ? opacity : 1, scale, signal) : await renderReferenceSurface(current, step, origin, scale, signal);
10494
+ if (current !== source) releaseSurface(current);
10495
+ current = next;
10496
+ }
10497
+ if (opacityApplied || opacity === 1) {
10498
+ const output = current;
10499
+ current = source;
10500
+ return output;
10501
+ }
10502
+ return drawWithOpacity(current, opacity);
10503
+ } finally {
10504
+ if (current !== source) releaseSurface(current);
10505
+ }
10506
+ }
10507
+ function drawWithOpacity(source, opacity) {
10508
+ const output = canvasLike(source);
10509
+ const context = output.getContext("2d");
10510
+ if (!context) {
10511
+ releaseSurface(output);
10512
+ throw new FilterSurfaceError("Filter surface canvas is unavailable");
10513
+ }
10514
+ context.globalAlpha = opacity;
10515
+ try {
10516
+ context.drawImage(source, 0, 0);
10517
+ return output;
10518
+ } catch {
10519
+ releaseSurface(output);
10520
+ throw new FilterSurfaceError("Filter surface image cannot be drawn");
10521
+ }
10522
+ }
10523
+ const SVG_NS = "http://www.w3.org/2000/svg";
10524
+ function createSvgElement(owner, tag, attributes = {}) {
10525
+ const node = owner.createElementNS(SVG_NS, tag);
10526
+ Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
10527
+ return node;
10528
+ }
10529
+ function serializeSurface(source) {
10530
+ try {
10531
+ const url = source.toDataURL("image/png");
10532
+ if (url === "data:,") throw new Error("Canvas size is unsupported");
10533
+ return url;
10534
+ } catch {
10535
+ throw new FilterSurfaceError("Filter surface pixels cannot be serialized");
10536
+ }
10537
+ }
10538
+ /** Decode a filtered SVG image and draw it onto a surface-sized canvas. */
10539
+ async function drawSvgSurface(svg, source, opacity, signal) {
10540
+ const imageWindow = (source.ownerDocument ?? document).defaultView;
10541
+ const image = imageWindow?.Image ? new imageWindow.Image() : new Image();
10542
+ let output;
10543
+ try {
10544
+ image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
10545
+ await decodeSurface(image, signal);
10546
+ throwIfAborted(signal);
10547
+ output = canvasLike(source);
10548
+ const context = output.getContext("2d");
10549
+ if (!context) throw new FilterSurfaceError("Filter surface canvas is unavailable");
10550
+ context.globalAlpha = opacity;
10551
+ context.drawImage(image, 0, 0);
10552
+ return output;
10553
+ } catch (error) {
10554
+ if (output) releaseSurface(output);
10555
+ if (signal?.aborted) throwIfAborted(signal);
10556
+ throw error instanceof FilterSurfaceError ? error : new FilterSurfaceError("Filter surface image cannot be drawn");
10557
+ } finally {
10558
+ image.removeAttribute("src");
10559
+ }
10560
+ }
10561
+ /**
10562
+ * Apply a referenced SVG filter to the complete surface. The viewBox is in CSS
10563
+ * pixels, so the filter's user units scale with the capture, and the image is
10564
+ * placed so user space starts at the element's border box, as it does for the
10565
+ * live element. Canvas filters cannot express either: their lengths are in
10566
+ * device pixels and their bounding box is the whole canvas.
10567
+ */
10568
+ async function renderReferenceSurface(source, reference, origin, scale, signal) {
10569
+ throwIfAborted(signal);
10570
+ const owner = source.ownerDocument ?? document;
10571
+ const width = source.width / scale;
10572
+ const height = source.height / scale;
10573
+ const svg = createSvgElement(owner, "svg", {
10574
+ width: source.width,
10575
+ height: source.height,
10576
+ viewBox: `0 0 ${width} ${height}`
10577
+ });
10578
+ const defs = createSvgElement(owner, "defs");
10579
+ const filterElement = owner.importNode(reference.element, true);
10580
+ filterElement.setAttribute("id", "composited-reference");
10581
+ defs.appendChild(filterElement);
10582
+ svg.appendChild(defs);
10583
+ const group = createSvgElement(owner, "g", { transform: `translate(${origin.x} ${origin.y})` });
10584
+ group.appendChild(createSvgElement(owner, "image", {
10585
+ x: -origin.x,
10586
+ y: -origin.y,
10587
+ width,
10588
+ height,
10589
+ href: serializeSurface(source),
10590
+ filter: "url(#composited-reference)"
10591
+ }));
10592
+ svg.appendChild(group);
10593
+ return drawSvgSurface(svg, source, 1, signal);
10594
+ }
10411
10595
  async function renderSvgFilterSurface(source, filter, opacity, scale, signal) {
10412
10596
  throwIfAborted(signal);
10413
10597
  const blur = filter.functions.find((fn) => fn.kind === "blur");
@@ -10419,29 +10603,9 @@
10419
10603
  blur: shadow.blur,
10420
10604
  color: shadow.color
10421
10605
  } : void 0;
10422
- if (!blurValue && !shadowValue) {
10423
- const output = canvasLike(source);
10424
- const context = output.getContext("2d");
10425
- if (!context) {
10426
- releaseSurface(output);
10427
- throw new FilterSurfaceError("Filter surface canvas is unavailable");
10428
- }
10429
- context.globalAlpha = opacity;
10430
- try {
10431
- context.drawImage(source, 0, 0);
10432
- return output;
10433
- } catch {
10434
- releaseSurface(output);
10435
- throw new FilterSurfaceError("Filter surface image cannot be drawn");
10436
- }
10437
- }
10438
- const namespace = "http://www.w3.org/2000/svg";
10606
+ if (!blurValue && !shadowValue) return drawWithOpacity(source, opacity);
10439
10607
  const svgDocument = source.ownerDocument ?? document;
10440
- const element = (tag, attributes = {}) => {
10441
- const node = svgDocument.createElementNS(namespace, tag);
10442
- Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
10443
- return node;
10444
- };
10608
+ const element = (tag, attributes = {}) => createSvgElement(svgDocument, tag, attributes);
10445
10609
  const svg = element("svg", {
10446
10610
  width: source.width,
10447
10611
  height: source.height,
@@ -10483,39 +10647,13 @@
10483
10647
  }
10484
10648
  defs.appendChild(filterElement);
10485
10649
  svg.appendChild(defs);
10486
- let sourceUrl;
10487
- try {
10488
- sourceUrl = source.toDataURL("image/png");
10489
- if (sourceUrl === "data:,") throw new Error("Canvas size is unsupported");
10490
- } catch {
10491
- throw new FilterSurfaceError("Filter surface pixels cannot be serialized");
10492
- }
10493
10650
  svg.appendChild(element("image", {
10494
10651
  width: source.width,
10495
10652
  height: source.height,
10496
- href: sourceUrl,
10653
+ href: serializeSurface(source),
10497
10654
  filter: "url(#composited-filter)"
10498
10655
  }));
10499
- const imageWindow = svgDocument.defaultView;
10500
- const image = imageWindow?.Image ? new imageWindow.Image() : new Image();
10501
- let output;
10502
- try {
10503
- image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
10504
- await decodeSurface(image, signal);
10505
- throwIfAborted(signal);
10506
- output = canvasLike(source);
10507
- const context = output.getContext("2d");
10508
- if (!context) throw new FilterSurfaceError("Filter surface canvas is unavailable");
10509
- context.globalAlpha = opacity;
10510
- context.drawImage(image, 0, 0);
10511
- return output;
10512
- } catch (error) {
10513
- if (output) releaseSurface(output);
10514
- if (signal?.aborted) throwIfAborted(signal);
10515
- throw error instanceof FilterSurfaceError ? error : new FilterSurfaceError("Filter surface image cannot be drawn");
10516
- } finally {
10517
- image.removeAttribute("src");
10518
- }
10656
+ return drawSvgSurface(svg, source, opacity, signal);
10519
10657
  }
10520
10658
  function reserveSurface(budget, width, height) {
10521
10659
  const pixels = width * height * 4;
@@ -10539,7 +10677,7 @@
10539
10677
  }
10540
10678
  for (const child of container.elements) if (child.styles.isVisible()) bounds = union(bounds, surfaceBounds(child));
10541
10679
  const filter = parseFilterChain(styles.filter);
10542
- return expand(bounds, filter ? filterOutset(filter) : 0);
10680
+ return expand(bounds, filter ? filterOutset(filter, container.filterReferences) : 0);
10543
10681
  }
10544
10682
  function cropSurface(bounds, viewport, margin, scale) {
10545
10683
  const area = expand(viewport, margin);
@@ -10549,8 +10687,91 @@
10549
10687
  const bottom = Math.ceil(Math.min(bounds.top + bounds.height, area.top + area.height) * scale) / scale;
10550
10688
  return new Bounds(left, top, Math.max(0, right - left), Math.max(0, bottom - top));
10551
10689
  }
10552
- //#endregion
10553
- //#region src/render/canvas/text/text-decoration-renderer.ts
10690
+ // src/render/matrix.ts
10691
+ /**
10692
+ * 2D affine matrix utilities for the composited-surface render path.
10693
+ *
10694
+ * Matrices use the canvas `transform(a, b, c, d, e, f)` column-vector
10695
+ * convention:
10696
+ *
10697
+ * | a c e | | x' | | a·x + c·y + e |
10698
+ * | b d f | × | y' | = | b·x + d·y + f |
10699
+ * | 0 0 1 | | 1 | | 1 |
10700
+ *
10701
+ * `TransformEffect` carries the same tuple order, so effects and bounds can
10702
+ * share these helpers. Composition follows the canvas post-multiply rule:
10703
+ * `multiplyMatrix(ancestor, own)` equals `ancestor` followed by `own`.
10704
+ */
10705
+ const IDENTITY_MATRIX = [
10706
+ 1,
10707
+ 0,
10708
+ 0,
10709
+ 1,
10710
+ 0,
10711
+ 0
10712
+ ];
10713
+ const isIdentityMatrix = (m) => m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1 && m[4] === 0 && m[5] === 0;
10714
+ /**
10715
+ * Compose two transforms: the result applies `a` first, then `b`
10716
+ * (canvas post-multiply, matching successive `ctx.transform` calls).
10717
+ */
10718
+ const multiplyMatrix = (a, b) => [
10719
+ a[0] * b[0] + a[2] * b[1],
10720
+ a[1] * b[0] + a[3] * b[1],
10721
+ a[0] * b[2] + a[2] * b[3],
10722
+ a[1] * b[2] + a[3] * b[3],
10723
+ a[0] * b[4] + a[2] * b[5] + a[4],
10724
+ a[1] * b[4] + a[3] * b[5] + a[5]
10725
+ ];
10726
+ /** Apply a matrix to a point, returning the mapped [x, y]. */
10727
+ const applyMatrixToPoint = (m, x, y) => [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
10728
+ /**
10729
+ * Map a layout-space Bounds through the matrix and return the axis-aligned
10730
+ * bounding box of the four transformed corners. Non-uniform scales and
10731
+ * rotations grow the box; this is intentionally conservative.
10732
+ */
10733
+ const transformBoundsToAabb = (m, bounds) => {
10734
+ const corners = [
10735
+ applyMatrixToPoint(m, bounds.left, bounds.top),
10736
+ applyMatrixToPoint(m, bounds.left + bounds.width, bounds.top),
10737
+ applyMatrixToPoint(m, bounds.left, bounds.top + bounds.height),
10738
+ applyMatrixToPoint(m, bounds.left + bounds.width, bounds.top + bounds.height)
10739
+ ];
10740
+ const left = Math.min(...corners.map((p) => p[0]));
10741
+ const right = Math.max(...corners.map((p) => p[0]));
10742
+ const top = Math.min(...corners.map((p) => p[1]));
10743
+ const bottom = Math.max(...corners.map((p) => p[1]));
10744
+ return new Bounds(left, top, right - left, bottom - top);
10745
+ };
10746
+ /**
10747
+ * Invert an affine matrix. Returns null for singular matrices
10748
+ * (zero-scale transforms have no meaningful inverse).
10749
+ */
10750
+ const invertMatrix = (m) => {
10751
+ const det = m[0] * m[3] - m[1] * m[2];
10752
+ if (!Number.isFinite(det) || det === 0) return null;
10753
+ const invDet = 1 / det;
10754
+ return [
10755
+ m[3] * invDet,
10756
+ -m[1] * invDet,
10757
+ -m[2] * invDet,
10758
+ m[0] * invDet,
10759
+ (m[2] * m[5] - m[3] * m[4]) * invDet,
10760
+ (m[1] * m[4] - m[0] * m[5]) * invDet
10761
+ ];
10762
+ };
10763
+ /**
10764
+ * Map a visual-space viewport back into the layout space of `m`'s inputs.
10765
+ * Used where a crop window (visual coordinates) must select content measured
10766
+ * in layout coordinates: the conservative answer is the AABB of the inverse
10767
+ * viewport corners.
10768
+ */
10769
+ const inverseTransformBoundsToAabb = (m, bounds) => {
10770
+ const inverse = invertMatrix(m);
10771
+ if (!inverse) return null;
10772
+ return transformBoundsToAabb(inverse, bounds);
10773
+ };
10774
+ // src/render/canvas/text/text-decoration-renderer.ts
10554
10775
  var TextDecorationRenderer = class {
10555
10776
  ctx;
10556
10777
  constructor(ctx) {
@@ -10638,8 +10859,7 @@
10638
10859
  this.ctx.restore();
10639
10860
  }
10640
10861
  };
10641
- //#endregion
10642
- //#region src/render/canvas/font-utils.ts
10862
+ // src/render/canvas/font-utils.ts
10643
10863
  /**
10644
10864
  * Font measurement utility
10645
10865
  *
@@ -10674,8 +10894,7 @@
10674
10894
  const measureBaseline = (ctx, fallback) => {
10675
10895
  return measureFontMetrics(ctx, fallback).baseline;
10676
10896
  };
10677
- //#endregion
10678
- //#region src/render/canvas/text-renderer.ts
10897
+ // src/render/canvas/text-renderer.ts
10679
10898
  const TEXT_OVERFLOW_EPSILON = 1;
10680
10899
  /**
10681
10900
  * Detect CJK (Chinese, Japanese, Korean) characters in a string.
@@ -11101,8 +11320,7 @@
11101
11320
  }
11102
11321
  }
11103
11322
  };
11104
- //#endregion
11105
- //#region src/render/canvas/canvas-path.ts
11323
+ // src/render/canvas/canvas-path.ts
11106
11324
  const formatCanvasPath = (ctx, paths) => {
11107
11325
  paths.forEach((point, index) => {
11108
11326
  const start = isBezierCurve(point) ? point.start : point;
@@ -11116,8 +11334,7 @@
11116
11334
  formatCanvasPath(ctx, paths);
11117
11335
  ctx.closePath();
11118
11336
  };
11119
- //#endregion
11120
- //#region src/core/lru-map.ts
11337
+ // src/core/lru-map.ts
11121
11338
  /**
11122
11339
  * Generic LRU (Least-Recently-Used) wrapper over a native `Map`.
11123
11340
  *
@@ -11175,8 +11392,7 @@
11175
11392
  this._map.clear();
11176
11393
  }
11177
11394
  };
11178
- //#endregion
11179
- //#region src/render/canvas/background-renderer.ts
11395
+ // src/render/canvas/background-renderer.ts
11180
11396
  /**
11181
11397
  * Background Renderer
11182
11398
  *
@@ -11539,8 +11755,7 @@
11539
11755
  createCanvasPath(this.ctx, paths);
11540
11756
  }
11541
11757
  };
11542
- //#endregion
11543
- //#region src/render/border.ts
11758
+ // src/render/border.ts
11544
11759
  const parsePathForBorder = (curves, borderSide) => {
11545
11760
  switch (borderSide) {
11546
11761
  case 0: return createPathFromCurves(curves.topLeftBorderBox, curves.topLeftPaddingBox, curves.topRightBorderBox, curves.topRightPaddingBox);
@@ -11593,8 +11808,7 @@
11593
11808
  else path.push(inner1);
11594
11809
  return path;
11595
11810
  };
11596
- //#endregion
11597
- //#region src/render/canvas/border-renderer.ts
11811
+ // src/render/canvas/border-renderer.ts
11598
11812
  /**
11599
11813
  * Border Renderer
11600
11814
  *
@@ -11728,8 +11942,7 @@
11728
11942
  this.ctx.restore();
11729
11943
  }
11730
11944
  };
11731
- //#endregion
11732
- //#region src/render/canvas/border-image-renderer.ts
11945
+ // src/render/canvas/border-image-renderer.ts
11733
11946
  /**
11734
11947
  * Resolve border-image-width to per-side pixel widths. `auto` uses the
11735
11948
  * corresponding border width, numbers multiply it, lengths are absolute and
@@ -11937,8 +12150,7 @@
11937
12150
  this.ctx.restore();
11938
12151
  }
11939
12152
  };
11940
- //#endregion
11941
- //#region src/render/canvas/effects-renderer.ts
12153
+ // src/render/canvas/effects-renderer.ts
11942
12154
  /**
11943
12155
  * Effects Renderer
11944
12156
  *
@@ -12086,8 +12298,7 @@
12086
12298
  return this.activeEffects.length > 0;
12087
12299
  }
12088
12300
  };
12089
- //#endregion
12090
- //#region src/render/canvas/mask-renderer.ts
12301
+ // src/render/canvas/mask-renderer.ts
12091
12302
  /**
12092
12303
  * Mask Renderer
12093
12304
  *
@@ -12234,8 +12445,7 @@
12234
12445
  } else paintGradientLayer(ctx, layer, area);
12235
12446
  }
12236
12447
  };
12237
- //#endregion
12238
- //#region src/render/object-fit.ts
12448
+ // src/render/object-fit.ts
12239
12449
  const calculateObjectFitRendering = (intrinsicWidth, intrinsicHeight, box, objectFit, objectPosition) => {
12240
12450
  let sx = 0;
12241
12451
  let sy = 0;
@@ -12321,8 +12531,7 @@
12321
12531
  dh
12322
12532
  };
12323
12533
  };
12324
- //#endregion
12325
- //#region src/render/canvas/content-renderer.ts
12534
+ // src/render/canvas/content-renderer.ts
12326
12535
  /**
12327
12536
  * Render replaced elements: Image, Canvas, SVG, IFrame.
12328
12537
  */
@@ -12543,8 +12752,7 @@
12543
12752
  default: return "left";
12544
12753
  }
12545
12754
  };
12546
- //#endregion
12547
- //#region src/render/canvas/box-shadow-geometry.ts
12755
+ // src/render/canvas/box-shadow-geometry.ts
12548
12756
  const shadowRadius = (radius, spread) => {
12549
12757
  const delta = spread > radius ? spread * (1 + Math.pow(radius / spread - 1, 3)) : spread;
12550
12758
  return Math.max(0, radius + delta);
@@ -12588,8 +12796,7 @@
12588
12796
  return new BezierCurve(resize(point.start), resize(point.startControl), resize(point.endControl), resize(point.end));
12589
12797
  });
12590
12798
  };
12591
- //#endregion
12592
- //#region src/render/canvas/box-shadow-transform.ts
12799
+ // src/render/canvas/box-shadow-transform.ts
12593
12800
  const shadowSpace = (matrix, width, height) => {
12594
12801
  const { a, b, c, d, e, f } = matrix;
12595
12802
  if (![
@@ -12632,8 +12839,7 @@
12632
12839
  uniform: Math.abs(xx - yy) <= tolerance && Math.abs(xy) <= tolerance
12633
12840
  };
12634
12841
  };
12635
- //#endregion
12636
- //#region src/render/canvas/box-shadow-painter.ts
12842
+ // src/render/canvas/box-shadow-painter.ts
12637
12843
  const complement = (ctx, rect, hole) => {
12638
12844
  ctx.beginPath();
12639
12845
  ctx.rect(rect.left, rect.top, rect.width, rect.height);
@@ -12761,8 +12967,7 @@
12761
12967
  ctx.restore();
12762
12968
  }
12763
12969
  };
12764
- //#endregion
12765
- //#region src/render/canvas/text-clip-renderer.ts
12970
+ // src/render/canvas/text-clip-renderer.ts
12766
12971
  var TextClipRenderer = class {
12767
12972
  ctx;
12768
12973
  context;
@@ -12922,8 +13127,7 @@
12922
13127
  return canvases.length ? canvases : null;
12923
13128
  }
12924
13129
  };
12925
- //#endregion
12926
- //#region src/render/canvas/canvas-renderer.ts
13130
+ // src/render/canvas/canvas-renderer.ts
12927
13131
  var CanvasRenderer = class CanvasRenderer {
12928
13132
  surfaceRoot;
12929
13133
  surfaceBudget;
@@ -13001,7 +13205,9 @@
13001
13205
  const hasMask = styles.maskImage.length > 0;
13002
13206
  const reflect = styles.webkitBoxReflect;
13003
13207
  const hasBlend = styles.mixBlendMode !== MIX_BLEND_MODE$1.NORMAL;
13004
- if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter !== null && (hasFilter || styles.opacity < 1)) && this.canComposite(stack.element)) {
13208
+ const reflectTransformed = reflect && !isIdentityMatrix(this.ancestorTransform(stack.element));
13209
+ if (reflectTransformed) this.context.logger.warn("-webkit-box-reflect under an ancestor transform is not supported; the reflection is skipped for this subtree");
13210
+ if (stack.element !== this.surfaceRoot && !this.legacySubtree && !reflectTransformed && (hasMask || reflect || hasBlend || filter !== null && (hasFilter || styles.opacity < 1)) && this.canComposite(stack.element)) {
13005
13211
  if (!await this.renderCompositedStack(stack, filter, hasMask, reflect, hasBlend)) {
13006
13212
  this.legacySubtree = true;
13007
13213
  try {
@@ -13018,7 +13224,7 @@
13018
13224
  canComposite(paint) {
13019
13225
  const supported = (container) => {
13020
13226
  const styles = container.styles;
13021
- return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) && parseFilterChain(styles.filter) !== null;
13227
+ return styles.clipPath.type === 0 && !contains(styles.display, 2048) && parseFilterChain(styles.filter) !== null;
13022
13228
  };
13023
13229
  const subtree = (container) => supported(container) && container.elements.every(subtree);
13024
13230
  let ancestor = paint.parent;
@@ -13028,24 +13234,82 @@
13028
13234
  }
13029
13235
  return subtree(paint.container);
13030
13236
  }
13237
+ /**
13238
+ * Root-to-element transform accumulated from the ancestor chain's
13239
+ * TransformEffects (including zoom), stopping at the surface root. The
13240
+ * element's own TransformEffect is intentionally excluded: inside the
13241
+ * offscreen surface it is still applied by the normal effects pass, and
13242
+ * at composition time it is filtered from the recomposed effect list.
13243
+ */
13244
+ ancestorTransform(paint) {
13245
+ const chain = [];
13246
+ let node = paint;
13247
+ while (node && node !== this.surfaceRoot) {
13248
+ for (const effect of node.effects) if (isTransformEffect(effect)) chain.push(effect);
13249
+ node = node.parent;
13250
+ }
13251
+ if (chain.length === 0) return IDENTITY_MATRIX;
13252
+ let matrix = IDENTITY_MATRIX;
13253
+ for (let i = chain.length - 1; i >= 0; i--) {
13254
+ const effect = at(chain, i);
13255
+ const anchored = multiplyMatrix(multiplyMatrix([
13256
+ 1,
13257
+ 0,
13258
+ 0,
13259
+ 1,
13260
+ effect.offsetX,
13261
+ effect.offsetY
13262
+ ], effect.matrix), [
13263
+ 1,
13264
+ 0,
13265
+ 0,
13266
+ 1,
13267
+ -effect.offsetX,
13268
+ -effect.offsetY
13269
+ ]);
13270
+ matrix = multiplyMatrix(matrix, anchored);
13271
+ }
13272
+ return matrix;
13273
+ }
13031
13274
  async renderCompositedStack(stack, filter, hasMask, reflect, hasBlend = false) {
13032
13275
  const signal = this.options.signal;
13033
13276
  if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
13034
- const bounds = cropSurface(surfaceBounds(stack.element.container), new Bounds(this.options.x, this.options.y, this.options.width, this.options.height), filter ? filterOutset(filter) : 0, this.options.scale);
13277
+ const container = stack.element.container;
13278
+ const ancestorMatrix = this.ancestorTransform(stack.element);
13279
+ const ownTransforms = stack.element.effects.filter(isTransformEffect);
13280
+ let chainMatrix = ancestorMatrix;
13281
+ for (const effect of ownTransforms) chainMatrix = multiplyMatrix(chainMatrix, multiplyMatrix(multiplyMatrix([
13282
+ 1,
13283
+ 0,
13284
+ 0,
13285
+ 1,
13286
+ effect.offsetX,
13287
+ effect.offsetY
13288
+ ], effect.matrix), [
13289
+ 1,
13290
+ 0,
13291
+ 0,
13292
+ 1,
13293
+ -effect.offsetX,
13294
+ -effect.offsetY
13295
+ ]));
13296
+ const layoutBounds = surfaceBounds(container);
13297
+ const bounds = cropSurface(isIdentityMatrix(chainMatrix) ? layoutBounds : transformBoundsToAabb(chainMatrix, layoutBounds), new Bounds(this.options.x, this.options.y, this.options.width, this.options.height), filter ? filterOutset(filter, container.filterReferences) : 0, this.options.scale);
13035
13298
  if (!bounds.width || !bounds.height) return true;
13036
13299
  const reserved = reserveSurface(this.surfaceBudget, Math.ceil(bounds.width * this.options.scale), Math.ceil(bounds.height * this.options.scale));
13037
13300
  if (!reserved) {
13038
- this.context.logger.info("Filter surface budget exceeded; using the existing renderer");
13301
+ this.context.logger.warn("Filter surface budget exceeded; mask/filter/blend effects are dropped for this subtree");
13039
13302
  return false;
13040
13303
  }
13304
+ const surfaceWindow = isIdentityMatrix(ancestorMatrix) || !hasMask ? bounds : inverseTransformBoundsToAabb(ancestorMatrix, bounds) ?? bounds;
13041
13305
  const options = {
13042
13306
  ...this.options,
13043
13307
  canvas: void 0,
13044
13308
  backgroundColor: null,
13045
- x: bounds.left,
13046
- y: bounds.top,
13047
- width: bounds.width,
13048
- height: bounds.height
13309
+ x: surfaceWindow.left,
13310
+ y: surfaceWindow.top,
13311
+ width: surfaceWindow.width,
13312
+ height: surfaceWindow.height
13049
13313
  };
13050
13314
  let source;
13051
13315
  let filtered;
@@ -13053,12 +13317,18 @@
13053
13317
  source = new CanvasRenderer(this.context, options, stack.element, this.surfaceBudget);
13054
13318
  await source.renderStackContent(stack);
13055
13319
  source.effectsRenderer.applyEffects([]);
13056
- if (filter) filtered = await renderFilterSurface(source.canvas, filter, stack.element.container.styles.opacity, options.scale, signal);
13320
+ if (filter) filtered = await renderFilterSurface(source.canvas, filter, container.styles.opacity, options.scale, signal, {
13321
+ references: container.filterReferences,
13322
+ origin: {
13323
+ x: container.bounds.left - surfaceWindow.left,
13324
+ y: container.bounds.top - surfaceWindow.top
13325
+ }
13326
+ });
13057
13327
  const composited = filtered ?? source.canvas;
13058
- if (hasMask) await this.applyMask(composited, stack.element.container.styles, bounds);
13328
+ if (hasMask) await this.applyMask(composited, stack.element.container.styles, surfaceWindow, container.bounds, ownTransforms);
13059
13329
  if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
13060
13330
  const own = stack.element.effects;
13061
- const effects = stack.element.getEffects(4, this.surfaceRoot).filter((effect) => !own.includes(effect) || !isFilterEffect(effect) && !isOpacityEffect(effect) && !isBlendEffect(effect) && !isClipEffect(effect));
13331
+ const effects = stack.element.getEffects(4, this.surfaceRoot).filter((effect) => !own.includes(effect) || !isFilterEffect(effect) && !isOpacityEffect(effect) && !isBlendEffect(effect) && !isClipEffect(effect) && !isTransformEffect(effect));
13062
13332
  this.effectsRenderer.applyEffects(effects);
13063
13333
  if (hasBlend) {
13064
13334
  this.ctx.save();
@@ -13082,8 +13352,15 @@
13082
13352
  * Composite an alpha mask onto a finished element surface: all mask
13083
13353
  * layers are painted additively into a mask surface, then kept pixels are
13084
13354
  * selected with destination-in.
13355
+ *
13356
+ * Coordinate spaces: the source surface paints in LAYOUT space (the
13357
+ * ancestor TransformEffects stay active on the main canvas and transform
13358
+ * the draw-back), so the mask must be painted in layout space too —
13359
+ * anchored to the element's border box (containerBounds) — riding ONLY
13360
+ * the element's own transform effects, which apply inside the surface
13361
+ * rather than at draw-back.
13085
13362
  */
13086
- async applyMask(surface, styles, bounds) {
13363
+ async applyMask(surface, styles, surfaceWindow, containerBounds, ownTransforms) {
13087
13364
  const ctx = surface.getContext("2d");
13088
13365
  if (!ctx) return;
13089
13366
  const maskCanvas = this.context.resourceDocument.createElement("canvas");
@@ -13095,14 +13372,21 @@
13095
13372
  return;
13096
13373
  }
13097
13374
  maskCtx.scale(this.options.scale, this.options.scale);
13098
- maskCtx.translate(-bounds.left, -bounds.top);
13375
+ maskCtx.translate(-surfaceWindow.left, -surfaceWindow.top);
13376
+ for (let i = ownTransforms.length - 1; i >= 0; i--) {
13377
+ const effect = at(ownTransforms, i);
13378
+ maskCtx.translate(effect.offsetX, effect.offsetY);
13379
+ maskCtx.transform(...effect.matrix);
13380
+ maskCtx.translate(-effect.offsetX, -effect.offsetY);
13381
+ }
13382
+ const layoutArea = {
13383
+ left: containerBounds.left,
13384
+ top: containerBounds.top,
13385
+ width: containerBounds.width,
13386
+ height: containerBounds.height
13387
+ };
13099
13388
  try {
13100
- await paintMaskLayers(maskCtx, styles.maskImage, styles, {
13101
- left: bounds.left,
13102
- top: bounds.top,
13103
- width: bounds.width,
13104
- height: bounds.height
13105
- }, async (url) => await this.context.cache.match(url));
13389
+ await paintMaskLayers(maskCtx, styles.maskImage, styles, layoutArea, async (url) => await this.context.cache.match(url));
13106
13390
  } catch (error) {
13107
13391
  this.context.logger.error(`Error rendering mask-image: ${error instanceof Error ? error.message : error}`);
13108
13392
  releaseSurface(maskCanvas);
@@ -13246,7 +13530,7 @@
13246
13530
  y: this.options.y,
13247
13531
  width: this.options.width,
13248
13532
  height: this.options.height
13249
- }, (ctx, opts) => new CanvasRenderer(ctx, opts), container, curves, styles, (c, cv, img) => this.renderReplacedElement(c, cv, img));
13533
+ }, (ctx, opts) => new CanvasRenderer(ctx, opts, void 0, this.surfaceBudget), container, curves, styles, (c, cv, img) => this.renderReplacedElement(c, cv, img));
13250
13534
  renderFormElements(this.ctx, this.textRenderer, this.path.bind(this), container, styles);
13251
13535
  await renderListMarker(this.ctx, this.context, this.textRenderer, paint, container, styles);
13252
13536
  }
@@ -13642,8 +13926,7 @@
13642
13926
  const hasTextBackgroundClip = (styles) => {
13643
13927
  return styles.backgroundClip.some((clip) => clip === 3);
13644
13928
  };
13645
- //#endregion
13646
- //#region src/render/canvas/foreignobject-renderer.ts
13929
+ // src/render/canvas/foreignobject-renderer.ts
13647
13930
  var ForeignObjectRenderer = class {
13648
13931
  canvas;
13649
13932
  ctx;
@@ -13708,8 +13991,7 @@
13708
13991
  for (const [property, value] of previous) style[property] = value;
13709
13992
  };
13710
13993
  };
13711
- //#endregion
13712
- //#region src/core/logger.ts
13994
+ // src/core/logger.ts
13713
13995
  var Logger = class {
13714
13996
  id;
13715
13997
  enabled;
@@ -13746,8 +14028,7 @@
13746
14028
  }
13747
14029
  }
13748
14030
  };
13749
- //#endregion
13750
- //#region src/core/cache-storage.ts
14031
+ // src/core/cache-storage.ts
13751
14032
  var Cache = class {
13752
14033
  context;
13753
14034
  _options;
@@ -13992,8 +14273,7 @@
13992
14273
  const isInlineBase64Image = (src) => INLINE_BASE64.test(src);
13993
14274
  const isBlobImage = (src) => src.substring(0, 4) === "blob";
13994
14275
  const isSVG = (src) => src.slice(-3).toLowerCase() === "svg" || INLINE_SVG.test(src);
13995
- //#endregion
13996
- //#region src/core/origin-checker.ts
14276
+ // src/core/origin-checker.ts
13997
14277
  /**
13998
14278
  * Origin Checker
13999
14279
  *
@@ -14045,8 +14325,7 @@
14045
14325
  return this.origin;
14046
14326
  }
14047
14327
  };
14048
- //#endregion
14049
- //#region src/core/context.ts
14328
+ // src/core/context.ts
14050
14329
  var Context = class Context {
14051
14330
  static instanceCount = 1;
14052
14331
  instanceName = `#${Context.instanceCount++}`;
@@ -14093,8 +14372,7 @@
14093
14372
  this._windowBounds = this._windowBounds.add(left, top, 0, 0);
14094
14373
  }
14095
14374
  };
14096
- //#endregion
14097
- //#region src/core/config-assembler.ts
14375
+ // src/core/config-assembler.ts
14098
14376
  /**
14099
14377
  * Coerce known numeric options from string (or other) values to actual numbers.
14100
14378
  * Mutates the opts object in place — this is intentionally a normalisation
@@ -14171,8 +14449,7 @@
14171
14449
  imageSmoothing: opts.imageSmoothing,
14172
14450
  imageSmoothingQuality: opts.imageSmoothingQuality
14173
14451
  });
14174
- //#endregion
14175
- //#region src/core/background-parser.ts
14452
+ // src/core/background-parser.ts
14176
14453
  /**
14177
14454
  * Resolve the background colour for the rendered canvas, following CSS
14178
14455
  * background propagation rules:
@@ -14193,8 +14470,7 @@
14193
14470
  const defaultBackgroundColor = typeof backgroundColorOverride === "string" ? parseColor(context, backgroundColorOverride) : backgroundColorOverride === null ? 0 : 4294967295;
14194
14471
  return element === ownerDocument.documentElement ? isTransparent(documentBackgroundColor) ? isTransparent(bodyBackgroundColor) ? defaultBackgroundColor : bodyBackgroundColor : documentBackgroundColor : defaultBackgroundColor;
14195
14472
  };
14196
- //#endregion
14197
- //#region src/core/render-element.ts
14473
+ // src/core/render-element.ts
14198
14474
  const emitProgress = (onProgress, context, phase, progress) => {
14199
14475
  if (!onProgress) return;
14200
14476
  try {
@@ -14223,7 +14499,7 @@
14223
14499
  const windowBounds = new Bounds(windowOptions.scrollX, windowOptions.scrollY, windowOptions.windowWidth, windowOptions.windowHeight);
14224
14500
  const context = new Context(contextOptions, windowBounds, config);
14225
14501
  const performanceMonitoring = opts.enablePerformanceMonitoring ?? opts.logging ?? false;
14226
- const perfMonitor = new PerformanceMonitor(context, performanceMonitoring);
14502
+ const perfMonitor = new PerformanceMonitor(context.logger, performanceMonitoring);
14227
14503
  perfMonitor.start("total", {
14228
14504
  width: windowOptions.windowWidth,
14229
14505
  height: windowOptions.windowHeight
@@ -14292,8 +14568,7 @@
14292
14568
  emitProgress(opts.onProgress, context, "render", 100);
14293
14569
  return canvas;
14294
14570
  };
14295
- //#endregion
14296
- //#region src/index.ts
14571
+ // src/index.ts
14297
14572
  /**
14298
14573
  * Renders an HTML element to a `<canvas>` element.
14299
14574
  *
@@ -14329,7 +14604,6 @@
14329
14604
  });
14330
14605
  return renderElement(element, options, finalConfig);
14331
14606
  };
14332
- //#endregion
14333
14607
  exports.Html2CanvasConfig = Html2CanvasConfig;
14334
14608
  exports.PerformanceMonitor = PerformanceMonitor;
14335
14609
  exports.Validator = Validator;