pixi-effects 0.47.3 → 0.47.5

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +5 -5
  3. package/ai/chat-template.html +3 -3
  4. package/dist/Composition-PMWLJQPI.cjs +16 -0
  5. package/dist/{Composition-IC274CKO.cjs.map → Composition-PMWLJQPI.cjs.map} +1 -1
  6. package/dist/Composition-ZCRJHBB5.js +7 -0
  7. package/dist/{Composition-6TXRN65C.js.map → Composition-ZCRJHBB5.js.map} +1 -1
  8. package/dist/Controller.cjs +3 -3
  9. package/dist/Controller.d.cts +1 -1
  10. package/dist/Controller.d.ts +1 -1
  11. package/dist/Controller.js +1 -1
  12. package/dist/{Movie-sV8nJr_f.d.ts → Movie--qSYKgAQ.d.ts} +2 -2
  13. package/dist/{Movie-BqrAWN0g.d.cts → Movie-svZQF-9Z.d.cts} +2 -2
  14. package/dist/{Spans-3T6ZEEN4.js → Spans-FMAVPATS.js} +7 -7
  15. package/dist/{Spans-3T6ZEEN4.js.map → Spans-FMAVPATS.js.map} +1 -1
  16. package/dist/{Spans-M5KMHT6K.cjs → Spans-KTUPDFSR.cjs} +12 -12
  17. package/dist/{Spans-M5KMHT6K.cjs.map → Spans-KTUPDFSR.cjs.map} +1 -1
  18. package/dist/{blendModes-S72MBYKY.js → blendModes-535EMYGK.js} +5 -5
  19. package/dist/{blendModes-S72MBYKY.js.map → blendModes-535EMYGK.js.map} +1 -1
  20. package/dist/{blendModes-Y56QAMC4.cjs → blendModes-V5XHC7U4.cjs} +6 -6
  21. package/dist/{blendModes-Y56QAMC4.cjs.map → blendModes-V5XHC7U4.cjs.map} +1 -1
  22. package/dist/{chunk-VTGJRKW4.cjs → chunk-2AT5WSSV.cjs} +105 -92
  23. package/dist/chunk-2AT5WSSV.cjs.map +1 -0
  24. package/dist/{chunk-HGKXEPDJ.js → chunk-4PYVHLIK.js} +31 -9
  25. package/dist/chunk-4PYVHLIK.js.map +1 -0
  26. package/dist/{chunk-JVO2W77G.js → chunk-BFRWSV3R.js} +3 -3
  27. package/dist/{chunk-JVO2W77G.js.map → chunk-BFRWSV3R.js.map} +1 -1
  28. package/dist/{chunk-TWZNOUM7.cjs → chunk-DOLTCXCL.cjs} +7 -2
  29. package/dist/chunk-DOLTCXCL.cjs.map +1 -0
  30. package/dist/{chunk-33OVRSXF.cjs → chunk-ECLBZV4N.cjs} +66 -44
  31. package/dist/chunk-ECLBZV4N.cjs.map +1 -0
  32. package/dist/{chunk-PC7DFDCV.js → chunk-JBDBICS2.js} +5 -5
  33. package/dist/{chunk-PC7DFDCV.js.map → chunk-JBDBICS2.js.map} +1 -1
  34. package/dist/{chunk-6LA7W362.js → chunk-LHUIEFMH.js} +23 -10
  35. package/dist/chunk-LHUIEFMH.js.map +1 -0
  36. package/dist/{chunk-YSTOH5PC.cjs → chunk-NGJXVJB7.cjs} +6 -6
  37. package/dist/{chunk-YSTOH5PC.cjs.map → chunk-NGJXVJB7.cjs.map} +1 -1
  38. package/dist/{chunk-GDY56V74.cjs → chunk-OGLRSR6C.cjs} +96 -96
  39. package/dist/{chunk-GDY56V74.cjs.map → chunk-OGLRSR6C.cjs.map} +1 -1
  40. package/dist/{chunk-HX73PCVU.js → chunk-UI7CEUTP.js} +6 -6
  41. package/dist/{chunk-HX73PCVU.js.map → chunk-UI7CEUTP.js.map} +1 -1
  42. package/dist/{chunk-BXOCEZ4U.js → chunk-WGRWFQOB.js} +7 -2
  43. package/dist/chunk-WGRWFQOB.js.map +1 -0
  44. package/dist/{chunk-RU4N3B5B.cjs → chunk-WYR2AU4W.cjs} +7 -7
  45. package/dist/{chunk-RU4N3B5B.cjs.map → chunk-WYR2AU4W.cjs.map} +1 -1
  46. package/dist/index.cjs +37 -37
  47. package/dist/index.d.cts +1 -1
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +6 -6
  50. package/dist/loader.css +1 -1
  51. package/dist/{music-JKOM5YK6.js → music-P4JRT73P.js} +3 -3
  52. package/dist/{music-JKOM5YK6.js.map → music-P4JRT73P.js.map} +1 -1
  53. package/dist/{music-6WFTPVHU.cjs → music-XQEPBIDT.cjs} +7 -7
  54. package/dist/{music-6WFTPVHU.cjs.map → music-XQEPBIDT.cjs.map} +1 -1
  55. package/dist/present.cjs +13 -13
  56. package/dist/present.d.cts +1 -1
  57. package/dist/present.d.ts +1 -1
  58. package/dist/present.js +6 -6
  59. package/dist/{sfx-2O6UQEUP.cjs → sfx-G2XAMD7K.cjs} +8 -8
  60. package/dist/{sfx-2O6UQEUP.cjs.map → sfx-G2XAMD7K.cjs.map} +1 -1
  61. package/dist/{sfx-VUKARHDX.js → sfx-Z7OQIKHG.js} +3 -3
  62. package/dist/{sfx-VUKARHDX.js.map → sfx-Z7OQIKHG.js.map} +1 -1
  63. package/dist/three.cjs +7 -7
  64. package/dist/three.js +3 -3
  65. package/docs/api.md +4 -4
  66. package/docs/dsl.md +11 -10
  67. package/llms-full.txt +19 -18
  68. package/package.json +1 -1
  69. package/skills/pixi-effects/SKILL.md +1 -1
  70. package/skills/pixi-effects/reference/cheatsheet.md +2 -2
  71. package/skills/pixi-effects/reference/pitfalls.md +1 -1
  72. package/skills/pixi-effects/template.html +6 -6
  73. package/dist/Composition-6TXRN65C.js +0 -7
  74. package/dist/Composition-IC274CKO.cjs +0 -16
  75. package/dist/chunk-33OVRSXF.cjs.map +0 -1
  76. package/dist/chunk-6LA7W362.js.map +0 -1
  77. package/dist/chunk-BXOCEZ4U.js.map +0 -1
  78. package/dist/chunk-HGKXEPDJ.js.map +0 -1
  79. package/dist/chunk-TWZNOUM7.cjs.map +0 -1
  80. package/dist/chunk-VTGJRKW4.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.47.5
4
+
5
+ An island inside a hole no longer draws a wedge, and `init({ loudness })` is never quieter than the plain gain. Nothing breaks.
6
+
7
+ Eight more test films (playback against seek, same-`at` keyframes and `speed`, the sound in an exported file, a stroke round holes, the loudness target, two more warning families, a matte under a crossfade, what `check` leaves alone).
8
+
9
+ - **Fixed: an island inside a hole of an `evenodd` path drew a wedge of the fill inside the hole** (cutting a shape out of a hole that was already cut). The island is now neither filled nor cut nor stroked, as the docs say.
10
+ - **Fixed: `init({ loudness })` could leave a mix QUIETER than with no option** when a loud click carried the plain mix's loudness: limiting the click let the very quiet bed back into the loudness gate and the integrated loudness fell. The limiter result is compared with the plain gain and the plain gain is used when the limiter would be worse.
11
+ - **Docs, each pinned by a film:** a frame drawn while playing is the snapshot of that frame; keyframes with the same `at`; the loudness of an exported file against the mix (an mp4's sound is padded to a whole AAC frame); the stroke of a shape is centred on its outline; crossfade is not a linear mix and a composition's `alpha` goes into each child; where a wipe starts and ends; `canvas`'s build warning for `Math.random` catches only a direct call; what `check` samples (every 0.25 s) and the layout sentences; the `loudness` JSDoc and the out-of-reach note were stale.
12
+
13
+ ## 0.47.4
14
+
15
+ A morph between two quads keeps its corners when one is written with a closing line, and `style.colour` points at `fill`. Nothing breaks.
16
+
17
+ Eight more test films from the coverage plan (keyframe order, nested compositions, morph, perspective, image size, silences, two warning families, WebGL against WebGPU).
18
+
19
+ - **Fixed: a quad written with a line back to its start before `Z` was counted as having five corners,** so morphing it into another quad fell back to resampling and cut the corners half way (the docs promise corner-to-corner pairing for two quads).
20
+ - **Fixed: `style.colour` / `style.color` (and `fontcolor`, `textcolor`) got no did-you-mean;** the warning now says `fill`.
21
+ - **Docs, each pinned by a film:** keyframes of one property run in the order of their `at` (not of the list) and an overlap makes the picture jump; a positive `rotation` is clockwise and a composition scales first, then rotates, about its pivot; what counts as a corner for a morph; the perspective scale of a flat layer is `camZ / (camZ − z)` and a layer at the camera plane is hidden with a warning; an image's `width` alone stretches, `scale` keeps the ratio, `cover` / `contain` work for images; what a silence is (1 s below −60 dBFS) and what the note says; the sentences of the property and style-key warnings and the PixiJS shorthands that are valid properties; the measured difference of 2D layers between the two backends.
22
+
3
23
  ## 0.47.3
4
24
 
5
25
  `measureText().lines` counts the lines a wrapped text draws, and the docs say what `skew` does. Nothing breaks.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # pixi-effects
2
2
 
3
- > **Status**: experimental — current release `0.47.3`. The API may still change between minor versions; see the [CHANGELOG](./CHANGELOG.md) for what each release changed.
3
+ > **Status**: experimental — current release `0.47.5`. The API may still change between minor versions; see the [CHANGELOG](./CHANGELOG.md) for what each release changed.
4
4
 
5
5
  **[Gallery →](https://yjmtmtk.github.io/pixi-effects/examples/gallery/)** · 43 pieces written as plain data by AI models · **[For AI →](https://yjmtmtk.github.io/pixi-effects/for-ai.html)** · what an AI reads and runs · **[Playground →](https://yjmtmtk.github.io/pixi-effects/examples/playground.html)** in the browser.
6
6
 
@@ -49,8 +49,8 @@ Drop the imports into an [importmap](https://developer.mozilla.org/docs/Web/HTML
49
49
  "imports": {
50
50
  "pixi.js": "https://esm.sh/pixi.js@8.22.0?bundle-deps",
51
51
  "mediabunny": "https://esm.sh/mediabunny",
52
- "pixi-effects": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.3/dist/index.js",
53
- "pixi-effects/controller": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.3/dist/Controller.js"
52
+ "pixi-effects": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.5/dist/index.js",
53
+ "pixi-effects/controller": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.5/dist/Controller.js"
54
54
  }
55
55
  }
56
56
  </script>
@@ -61,7 +61,7 @@ Drop the imports into an [importmap](https://developer.mozilla.org/docs/Web/HTML
61
61
  </script>
62
62
  ```
63
63
 
64
- Load the `dist/` files **as they are** (jsDelivr's `/npm/…/dist/…`, or unpkg's `https://unpkg.com/pixi-effects@0.47.3/dist/index.js`) rather than a CDN-rebundled build such as `esm.sh/pixi-effects` or jsDelivr's `+esm`: the entries (`pixi-effects`, `…/controller`, `…/three`) share internal chunks, which only works when each file is served untouched.
64
+ Load the `dist/` files **as they are** (jsDelivr's `/npm/…/dist/…`, or unpkg's `https://unpkg.com/pixi-effects@0.47.5/dist/index.js`) rather than a CDN-rebundled build such as `esm.sh/pixi-effects` or jsDelivr's `+esm`: the entries (`pixi-effects`, `…/controller`, `…/three`) share internal chunks, which only works when each file is served untouched.
65
65
 
66
66
  > **Using three.js?** Add two more entries (`three` and `pixi-effects/three`) to this importmap — see [Adding three.js](#adding-threejs-optional) below.
67
67
  >
@@ -78,7 +78,7 @@ Add two more entries to the importmap above: three.js itself, and the `pixi-effe
78
78
  "...": "(everything from the importmap above)",
79
79
  "three": "https://esm.sh/three@0.178.0",
80
80
  "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.178.0/examples/jsm/",
81
- "pixi-effects/three": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.3/dist/three.js"
81
+ "pixi-effects/three": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.5/dist/three.js"
82
82
  }
83
83
  }
84
84
  </script>
@@ -59,9 +59,9 @@
59
59
  "imports": {
60
60
  "pixi.js": "https://cdn.jsdelivr.net/npm/pixi.js@8.22.0/dist/pixi.min.mjs",
61
61
  "mediabunny": "https://cdn.jsdelivr.net/npm/mediabunny@1.61.3/+esm",
62
- "pixi-effects": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.3/dist/index.js",
63
- "pixi-effects/controller": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.3/dist/Controller.js",
64
- "pixi-effects/present": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.3/dist/present.js"
62
+ "pixi-effects": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.5/dist/index.js",
63
+ "pixi-effects/controller": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.5/dist/Controller.js",
64
+ "pixi-effects/present": "https://cdn.jsdelivr.net/npm/pixi-effects@0.47.5/dist/present.js"
65
65
  }
66
66
  }
67
67
  </script>
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var chunkOGLRSR6C_cjs = require('./chunk-OGLRSR6C.cjs');
4
+ require('./chunk-ECLBZV4N.cjs');
5
+ require('./chunk-WYR2AU4W.cjs');
6
+ require('./chunk-NGJXVJB7.cjs');
7
+ require('./chunk-DOLTCXCL.cjs');
8
+
9
+
10
+
11
+ Object.defineProperty(exports, "CompositionSequence", {
12
+ enumerable: true,
13
+ get: function () { return chunkOGLRSR6C_cjs.CompositionSequence; }
14
+ });
15
+ //# sourceMappingURL=Composition-PMWLJQPI.cjs.map
16
+ //# sourceMappingURL=Composition-PMWLJQPI.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Composition-IC274CKO.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"Composition-PMWLJQPI.cjs"}
@@ -0,0 +1,7 @@
1
+ export { CompositionSequence } from './chunk-UI7CEUTP.js';
2
+ import './chunk-4PYVHLIK.js';
3
+ import './chunk-JBDBICS2.js';
4
+ import './chunk-BFRWSV3R.js';
5
+ import './chunk-WGRWFQOB.js';
6
+ //# sourceMappingURL=Composition-ZCRJHBB5.js.map
7
+ //# sourceMappingURL=Composition-ZCRJHBB5.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Composition-6TXRN65C.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"Composition-ZCRJHBB5.js"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
3
+ var chunkDOLTCXCL_cjs = require('./chunk-DOLTCXCL.cjs');
4
4
 
5
5
  // src/controller/css.ts
6
6
  var CONTROLLER_CSS = `
@@ -401,7 +401,7 @@ var Controller = class _Controller {
401
401
  if (!options || !options.canvas) {
402
402
  throw new Error("Controller requires options.canvas (HTMLCanvasElement).");
403
403
  }
404
- chunkTWZNOUM7_cjs.warnUnknownOptions("Controller", options, CONTROLLER_OPTION_KEYS);
404
+ chunkDOLTCXCL_cjs.warnUnknownOptions("Controller", options, CONTROLLER_OPTION_KEYS);
405
405
  this.movie = movie;
406
406
  this.options = {
407
407
  canvas: options.canvas,
@@ -507,7 +507,7 @@ var Controller = class _Controller {
507
507
  }
508
508
  /** Change the look of the bar (see {@link ControllerTheme}): only the keys you give change, `null` restores the default. */
509
509
  setTheme(theme) {
510
- chunkTWZNOUM7_cjs.warnUnknownOptions("Controller theme", theme, Object.keys(THEME_PROPERTIES));
510
+ chunkDOLTCXCL_cjs.warnUnknownOptions("Controller theme", theme, Object.keys(THEME_PROPERTIES));
511
511
  for (const key of Object.keys(THEME_PROPERTIES)) {
512
512
  if (!(key in theme)) continue;
513
513
  const value = theme[key];
@@ -1,4 +1,4 @@
1
- import { M as Movie } from './Movie-BqrAWN0g.cjs';
1
+ import { M as Movie } from './Movie-svZQF-9Z.cjs';
2
2
  import 'pixi.js';
3
3
  import './soundEntry-DT13DNt8.cjs';
4
4
  import './types-CTSrPvY3.cjs';
@@ -1,4 +1,4 @@
1
- import { M as Movie } from './Movie-sV8nJr_f.js';
1
+ import { M as Movie } from './Movie--qSYKgAQ.js';
2
2
  import 'pixi.js';
3
3
  import './soundEntry-DT13DNt8.js';
4
4
  import './types-CTSrPvY3.js';
@@ -1,4 +1,4 @@
1
- import { warnUnknownOptions } from './chunk-BXOCEZ4U.js';
1
+ import { warnUnknownOptions } from './chunk-WGRWFQOB.js';
2
2
 
3
3
  // src/controller/css.ts
4
4
  var CONTROLLER_CSS = `
@@ -434,8 +434,8 @@ interface MovieOptions {
434
434
  /** Start with `movie.loop` on: playing goes back to the start at the end instead of stopping. Default false (like a `<video>`). */
435
435
  loop?: boolean;
436
436
  /**
437
- * The loudness of the whole mix in LUFS (ITU-R BS.1770): `-16` is usual for web video. The finished mix gets one gain (up or down) so its integrated loudness is that number, but the loudest sample
438
- * never passes -1 dBFS: a mix with one loud click in a quiet bed stops short, and `inspectAudio()` / `check` say how far it got. Default: off (the mix is what the layers make; `check` says when it is quiet).
437
+ * The loudness of the whole mix in LUFS (ITU-R BS.1770): `-16` is usual for web video. The finished mix gets one gain (up or down) so its integrated loudness is that number: a look-ahead limiter takes a click or a hit on top of a quiet bed down (by up to 10 dB) and the true peak
438
+ * never passes -1 dBTP. A mix whose peaks are out of that reach stops short, and `inspectAudio()` / `check` say how far it got and why. Default: off (the mix is what the layers make; `check` says when it is quiet).
439
439
  * A number of 0 or below, or `false`.
440
440
  */
441
441
  loudness?: number | false;
@@ -434,8 +434,8 @@ interface MovieOptions {
434
434
  /** Start with `movie.loop` on: playing goes back to the start at the end instead of stopping. Default false (like a `<video>`). */
435
435
  loop?: boolean;
436
436
  /**
437
- * The loudness of the whole mix in LUFS (ITU-R BS.1770): `-16` is usual for web video. The finished mix gets one gain (up or down) so its integrated loudness is that number, but the loudest sample
438
- * never passes -1 dBFS: a mix with one loud click in a quiet bed stops short, and `inspectAudio()` / `check` say how far it got. Default: off (the mix is what the layers make; `check` says when it is quiet).
437
+ * The loudness of the whole mix in LUFS (ITU-R BS.1770): `-16` is usual for web video. The finished mix gets one gain (up or down) so its integrated loudness is that number: a look-ahead limiter takes a click or a hit on top of a quiet bed down (by up to 10 dB) and the true peak
438
+ * never passes -1 dBTP. A mix whose peaks are out of that reach stops short, and `inspectAudio()` / `check` say how far it got and why. Default: off (the mix is what the layers make; `check` says when it is quiet).
439
439
  * A number of 0 or below, or `false`.
440
440
  */
441
441
  loudness?: number | false;
@@ -1,8 +1,8 @@
1
- import { CompositionSequence } from './chunk-HX73PCVU.js';
2
- import { spansMeta, resolveNumber, bindCounterKeyframes, TextSequence } from './chunk-HGKXEPDJ.js';
3
- import './chunk-PC7DFDCV.js';
4
- import './chunk-JVO2W77G.js';
5
- import './chunk-BXOCEZ4U.js';
1
+ import { CompositionSequence } from './chunk-UI7CEUTP.js';
2
+ import { spansMeta, resolveNumber, bindCounterKeyframes, TextSequence } from './chunk-4PYVHLIK.js';
3
+ import './chunk-JBDBICS2.js';
4
+ import './chunk-BFRWSV3R.js';
5
+ import './chunk-WGRWFQOB.js';
6
6
 
7
7
  // src/sequences/Spans.ts
8
8
  var strip = (props) => {
@@ -49,5 +49,5 @@ var SpansSequence = class extends CompositionSequence {
49
49
  };
50
50
 
51
51
  export { SpansSequence };
52
- //# sourceMappingURL=Spans-3T6ZEEN4.js.map
53
- //# sourceMappingURL=Spans-3T6ZEEN4.js.map
52
+ //# sourceMappingURL=Spans-FMAVPATS.js.map
53
+ //# sourceMappingURL=Spans-FMAVPATS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sequences/Spans.ts"],"names":[],"mappings":";;;;;;;AAQA,IAAM,KAAA,GAAQ,CAAC,KAAA,KAAgD;AAC7D,EAAA,IAAI,CAAC,KAAA,IAAS,EAAE,cAAA,IAAkB,QAAQ,OAAO,KAAA;AACjD,EAAA,MAAM,EAAE,YAAA,EAAc,KAAA,EAAO,GAAG,MAAK,GAAI,KAAA;AACzC,EAAA,OAAO,IAAA;AACT,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4B,mBAAA,CAAoB;AAAA,EACpC,KAAA;AAAA,EACA,MAAA,GAAuB,EAAE,KAAA,EAAO,CAAA,EAAG,cAAc,CAAA,EAAE;AAAA,EAEpE,WAAA,CAAY,IAAA,EAAoB,MAAA,EAAiC,IAAA,EAAwB;AACvF,IAAA,KAAA,CAAM,IAAA,EAAM,QAAQ,IAAI,CAAA;AACxB,IAAA,IAAA,CAAK,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,EACjC;AAAA;AAAA,EAGmB,YAAA,GAAyH;AAC1I,IAAA,MAAM,CAAA,GAAI,MAAM,YAAA,EAAa;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,OAAO,CAAA;AAC/B,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA,CAAM,CAAA,CAAE,OAA4B,CAAA;AAAA,MAC7C,SAAA,EAAW,EAAE,SAAA,EAAW,GAAA,CAAI,SAAO,EAAE,GAAG,EAAA,EAAI,GAAA,EAAK,KAAA,CAAM,EAAA,CAAG,GAAG,CAAA,EAAG,EAAA,EAAI,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,EAAG,MAAM,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,EAAE,CAAE;AAAA,KAC3G;AAAA,EACF;AAAA,EAES,YAAA,CAAa,QAAA,EAAoB,MAAA,GAAS,CAAA,EAAS;AAC1D,IAAA,KAAA,CAAM,YAAA,CAAa,UAAU,MAAM,CAAA;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO;AACxB,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,EAAM;AACzB,IAAA,MAAM,KAAA,GAAS,IAAA,CAAK,IAAA,CAAK,OAAA,EAAiD,YAAA;AAC1E,IAAA,IAAA,CAAK,OAAO,YAAA,GAAe,KAAA,KAAU,SAAY,CAAA,GAAI,aAAA,CAAc,OAAO,KAAK,CAAA;AAC/E,IAAA,oBAAA,CAAqB,UAAU,IAAA,CAAK,MAAA,EAAQ,gBAAgB,MAAM,IAAA,CAAK,aAAY,EAAG,IAAA,CAAK,IAAA,CAAK,SAAA,IAAa,EAAC,EAAG,IAAA,CAAK,UAAW,MAAA,GAAS,IAAA,CAAK,IAAI,KAAK,CAAA;AACxJ,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA;AAAA,EAGQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAO,MAAA;AAC3B,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,YAAY,CAAC,CAAA;AAC9D,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,SAAA,EAAW;AAClC,MAAA,IAAI,EAAE,iBAAiB,YAAA,CAAA,EAAe;AACtC,MAAA,MAAM,CAAA,GAAI,OAAO,CAAA,EAAG,CAAA;AACpB,MAAA,IAAI,CAAA,EAAG,KAAA,CAAM,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA;AAAA,IAC/E;AAAA,EACF;AACF","file":"Spans-3T6ZEEN4.js","sourcesContent":["// The sequence behind a text layer with `spans`: a composition of ordinary text layers (see src/text/spans.ts) that also owns the typewriter\n// (`visibleChars`) of the whole text: it counts over every character of every piece, and tells each piece how many of its own to show.\nimport { CompositionSequence } from './Composition';\nimport { TextSequence, bindCounterKeyframes, resolveNumber, type CounterState } from './Text';\nimport { spansMeta, type SpansMeta } from '../text/spans';\nimport type { CompositionShape, SequenceSpec, Props } from '../types';\nimport type { Timeline } from '../core/timelineEngine';\n\nconst strip = (props: Props | undefined): Props | undefined => {\n if (!props || !('visibleChars' in props)) return props;\n const { visibleChars: _gone, ...rest } = props as Record<string, unknown>;\n return rest as unknown as Props;\n};\n\nexport class SpansSequence extends CompositionSequence {\n private readonly _meta: SpansMeta | undefined;\n private readonly _count: CounterState = { value: 0, visibleChars: 0 };\n\n constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape) {\n super(spec, parent, root);\n this._meta = spansMeta.get(spec);\n }\n\n /** `visibleChars` is the group's own counter, not a property to write on the container. */\n protected override displayProps(): { initial: CompositionSequence['spec']['initial']; keyframes: CompositionSequence['spec']['keyframes'] } {\n const p = super.displayProps();\n if (!this._meta?.typed) return p;\n return {\n initial: strip(p.initial as Props | undefined) as never,\n keyframes: p.keyframes?.map(kf => ({ ...kf, set: strip(kf.set), to: strip(kf.to), from: strip(kf.from) })),\n };\n }\n\n override bindTimeline(timeline: Timeline, offset = 0): void {\n super.bindTimeline(timeline, offset);\n if (!this._meta?.typed) return;\n const scope = this.scope();\n const first = (this.spec.initial as Record<string, unknown> | undefined)?.visibleChars;\n this._count.visibleChars = first === undefined ? 0 : resolveNumber(first, scope); // like a text: it starts at 0 once it is animated\n bindCounterKeyframes(timeline, this._count, 'visibleChars', () => this._distribute(), this.spec.keyframes ?? [], this.duration!, offset + this.at, scope);\n this._distribute();\n }\n\n /** Every piece shows its part of the first N characters of the whole text. */\n private _distribute(): void {\n const pieces = this._meta!.pieces;\n const total = Math.max(0, Math.floor(this._count.visibleChars));\n let i = 0;\n for (const child of this._children) {\n if (!(child instanceof TextSequence)) continue;\n const p = pieces[i++];\n if (p) child.setVisibleChars(Math.min(p.length, Math.max(0, total - p.start)));\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/sequences/Spans.ts"],"names":[],"mappings":";;;;;;;AAQA,IAAM,KAAA,GAAQ,CAAC,KAAA,KAAgD;AAC7D,EAAA,IAAI,CAAC,KAAA,IAAS,EAAE,cAAA,IAAkB,QAAQ,OAAO,KAAA;AACjD,EAAA,MAAM,EAAE,YAAA,EAAc,KAAA,EAAO,GAAG,MAAK,GAAI,KAAA;AACzC,EAAA,OAAO,IAAA;AACT,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4B,mBAAA,CAAoB;AAAA,EACpC,KAAA;AAAA,EACA,MAAA,GAAuB,EAAE,KAAA,EAAO,CAAA,EAAG,cAAc,CAAA,EAAE;AAAA,EAEpE,WAAA,CAAY,IAAA,EAAoB,MAAA,EAAiC,IAAA,EAAwB;AACvF,IAAA,KAAA,CAAM,IAAA,EAAM,QAAQ,IAAI,CAAA;AACxB,IAAA,IAAA,CAAK,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,EACjC;AAAA;AAAA,EAGmB,YAAA,GAAyH;AAC1I,IAAA,MAAM,CAAA,GAAI,MAAM,YAAA,EAAa;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,OAAO,CAAA;AAC/B,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA,CAAM,CAAA,CAAE,OAA4B,CAAA;AAAA,MAC7C,SAAA,EAAW,EAAE,SAAA,EAAW,GAAA,CAAI,SAAO,EAAE,GAAG,EAAA,EAAI,GAAA,EAAK,KAAA,CAAM,EAAA,CAAG,GAAG,CAAA,EAAG,EAAA,EAAI,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,EAAG,MAAM,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,EAAE,CAAE;AAAA,KAC3G;AAAA,EACF;AAAA,EAES,YAAA,CAAa,QAAA,EAAoB,MAAA,GAAS,CAAA,EAAS;AAC1D,IAAA,KAAA,CAAM,YAAA,CAAa,UAAU,MAAM,CAAA;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO;AACxB,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,EAAM;AACzB,IAAA,MAAM,KAAA,GAAS,IAAA,CAAK,IAAA,CAAK,OAAA,EAAiD,YAAA;AAC1E,IAAA,IAAA,CAAK,OAAO,YAAA,GAAe,KAAA,KAAU,SAAY,CAAA,GAAI,aAAA,CAAc,OAAO,KAAK,CAAA;AAC/E,IAAA,oBAAA,CAAqB,UAAU,IAAA,CAAK,MAAA,EAAQ,gBAAgB,MAAM,IAAA,CAAK,aAAY,EAAG,IAAA,CAAK,IAAA,CAAK,SAAA,IAAa,EAAC,EAAG,IAAA,CAAK,UAAW,MAAA,GAAS,IAAA,CAAK,IAAI,KAAK,CAAA;AACxJ,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA;AAAA,EAGQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAO,MAAA;AAC3B,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,YAAY,CAAC,CAAA;AAC9D,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,SAAA,EAAW;AAClC,MAAA,IAAI,EAAE,iBAAiB,YAAA,CAAA,EAAe;AACtC,MAAA,MAAM,CAAA,GAAI,OAAO,CAAA,EAAG,CAAA;AACpB,MAAA,IAAI,CAAA,EAAG,KAAA,CAAM,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA;AAAA,IAC/E;AAAA,EACF;AACF","file":"Spans-FMAVPATS.js","sourcesContent":["// The sequence behind a text layer with `spans`: a composition of ordinary text layers (see src/text/spans.ts) that also owns the typewriter\n// (`visibleChars`) of the whole text: it counts over every character of every piece, and tells each piece how many of its own to show.\nimport { CompositionSequence } from './Composition';\nimport { TextSequence, bindCounterKeyframes, resolveNumber, type CounterState } from './Text';\nimport { spansMeta, type SpansMeta } from '../text/spans';\nimport type { CompositionShape, SequenceSpec, Props } from '../types';\nimport type { Timeline } from '../core/timelineEngine';\n\nconst strip = (props: Props | undefined): Props | undefined => {\n if (!props || !('visibleChars' in props)) return props;\n const { visibleChars: _gone, ...rest } = props as Record<string, unknown>;\n return rest as unknown as Props;\n};\n\nexport class SpansSequence extends CompositionSequence {\n private readonly _meta: SpansMeta | undefined;\n private readonly _count: CounterState = { value: 0, visibleChars: 0 };\n\n constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape) {\n super(spec, parent, root);\n this._meta = spansMeta.get(spec);\n }\n\n /** `visibleChars` is the group's own counter, not a property to write on the container. */\n protected override displayProps(): { initial: CompositionSequence['spec']['initial']; keyframes: CompositionSequence['spec']['keyframes'] } {\n const p = super.displayProps();\n if (!this._meta?.typed) return p;\n return {\n initial: strip(p.initial as Props | undefined) as never,\n keyframes: p.keyframes?.map(kf => ({ ...kf, set: strip(kf.set), to: strip(kf.to), from: strip(kf.from) })),\n };\n }\n\n override bindTimeline(timeline: Timeline, offset = 0): void {\n super.bindTimeline(timeline, offset);\n if (!this._meta?.typed) return;\n const scope = this.scope();\n const first = (this.spec.initial as Record<string, unknown> | undefined)?.visibleChars;\n this._count.visibleChars = first === undefined ? 0 : resolveNumber(first, scope); // like a text: it starts at 0 once it is animated\n bindCounterKeyframes(timeline, this._count, 'visibleChars', () => this._distribute(), this.spec.keyframes ?? [], this.duration!, offset + this.at, scope);\n this._distribute();\n }\n\n /** Every piece shows its part of the first N characters of the whole text. */\n private _distribute(): void {\n const pieces = this._meta!.pieces;\n const total = Math.max(0, Math.floor(this._count.visibleChars));\n let i = 0;\n for (const child of this._children) {\n if (!(child instanceof TextSequence)) continue;\n const p = pieces[i++];\n if (p) child.setVisibleChars(Math.min(p.length, Math.max(0, total - p.start)));\n }\n }\n}\n"]}
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunkGDY56V74_cjs = require('./chunk-GDY56V74.cjs');
4
- var chunk33OVRSXF_cjs = require('./chunk-33OVRSXF.cjs');
5
- require('./chunk-RU4N3B5B.cjs');
6
- require('./chunk-YSTOH5PC.cjs');
7
- require('./chunk-TWZNOUM7.cjs');
3
+ var chunkOGLRSR6C_cjs = require('./chunk-OGLRSR6C.cjs');
4
+ var chunkECLBZV4N_cjs = require('./chunk-ECLBZV4N.cjs');
5
+ require('./chunk-WYR2AU4W.cjs');
6
+ require('./chunk-NGJXVJB7.cjs');
7
+ require('./chunk-DOLTCXCL.cjs');
8
8
 
9
9
  // src/sequences/Spans.ts
10
10
  var strip = (props) => {
@@ -12,12 +12,12 @@ var strip = (props) => {
12
12
  const { visibleChars: _gone, ...rest } = props;
13
13
  return rest;
14
14
  };
15
- var SpansSequence = class extends chunkGDY56V74_cjs.CompositionSequence {
15
+ var SpansSequence = class extends chunkOGLRSR6C_cjs.CompositionSequence {
16
16
  _meta;
17
17
  _count = { value: 0, visibleChars: 0 };
18
18
  constructor(spec, parent, root) {
19
19
  super(spec, parent, root);
20
- this._meta = chunk33OVRSXF_cjs.spansMeta.get(spec);
20
+ this._meta = chunkECLBZV4N_cjs.spansMeta.get(spec);
21
21
  }
22
22
  /** `visibleChars` is the group's own counter, not a property to write on the container. */
23
23
  displayProps() {
@@ -33,8 +33,8 @@ var SpansSequence = class extends chunkGDY56V74_cjs.CompositionSequence {
33
33
  if (!this._meta?.typed) return;
34
34
  const scope = this.scope();
35
35
  const first = this.spec.initial?.visibleChars;
36
- this._count.visibleChars = first === void 0 ? 0 : chunk33OVRSXF_cjs.resolveNumber(first, scope);
37
- chunk33OVRSXF_cjs.bindCounterKeyframes(timeline, this._count, "visibleChars", () => this._distribute(), this.spec.keyframes ?? [], this.duration, offset + this.at, scope);
36
+ this._count.visibleChars = first === void 0 ? 0 : chunkECLBZV4N_cjs.resolveNumber(first, scope);
37
+ chunkECLBZV4N_cjs.bindCounterKeyframes(timeline, this._count, "visibleChars", () => this._distribute(), this.spec.keyframes ?? [], this.duration, offset + this.at, scope);
38
38
  this._distribute();
39
39
  }
40
40
  /** Every piece shows its part of the first N characters of the whole text. */
@@ -43,7 +43,7 @@ var SpansSequence = class extends chunkGDY56V74_cjs.CompositionSequence {
43
43
  const total = Math.max(0, Math.floor(this._count.visibleChars));
44
44
  let i = 0;
45
45
  for (const child of this._children) {
46
- if (!(child instanceof chunk33OVRSXF_cjs.TextSequence)) continue;
46
+ if (!(child instanceof chunkECLBZV4N_cjs.TextSequence)) continue;
47
47
  const p = pieces[i++];
48
48
  if (p) child.setVisibleChars(Math.min(p.length, Math.max(0, total - p.start)));
49
49
  }
@@ -51,5 +51,5 @@ var SpansSequence = class extends chunkGDY56V74_cjs.CompositionSequence {
51
51
  };
52
52
 
53
53
  exports.SpansSequence = SpansSequence;
54
- //# sourceMappingURL=Spans-M5KMHT6K.cjs.map
55
- //# sourceMappingURL=Spans-M5KMHT6K.cjs.map
54
+ //# sourceMappingURL=Spans-KTUPDFSR.cjs.map
55
+ //# sourceMappingURL=Spans-KTUPDFSR.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sequences/Spans.ts"],"names":["CompositionSequence","spansMeta","resolveNumber","bindCounterKeyframes","TextSequence"],"mappings":";;;;;;;;;AAQA,IAAM,KAAA,GAAQ,CAAC,KAAA,KAAgD;AAC7D,EAAA,IAAI,CAAC,KAAA,IAAS,EAAE,cAAA,IAAkB,QAAQ,OAAO,KAAA;AACjD,EAAA,MAAM,EAAE,YAAA,EAAc,KAAA,EAAO,GAAG,MAAK,GAAI,KAAA;AACzC,EAAA,OAAO,IAAA;AACT,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4BA,qCAAA,CAAoB;AAAA,EACpC,KAAA;AAAA,EACA,MAAA,GAAuB,EAAE,KAAA,EAAO,CAAA,EAAG,cAAc,CAAA,EAAE;AAAA,EAEpE,WAAA,CAAY,IAAA,EAAoB,MAAA,EAAiC,IAAA,EAAwB;AACvF,IAAA,KAAA,CAAM,IAAA,EAAM,QAAQ,IAAI,CAAA;AACxB,IAAA,IAAA,CAAK,KAAA,GAAQC,2BAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,EACjC;AAAA;AAAA,EAGmB,YAAA,GAAyH;AAC1I,IAAA,MAAM,CAAA,GAAI,MAAM,YAAA,EAAa;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,OAAO,CAAA;AAC/B,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA,CAAM,CAAA,CAAE,OAA4B,CAAA;AAAA,MAC7C,SAAA,EAAW,EAAE,SAAA,EAAW,GAAA,CAAI,SAAO,EAAE,GAAG,EAAA,EAAI,GAAA,EAAK,KAAA,CAAM,EAAA,CAAG,GAAG,CAAA,EAAG,EAAA,EAAI,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,EAAG,MAAM,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,EAAE,CAAE;AAAA,KAC3G;AAAA,EACF;AAAA,EAES,YAAA,CAAa,QAAA,EAAoB,MAAA,GAAS,CAAA,EAAS;AAC1D,IAAA,KAAA,CAAM,YAAA,CAAa,UAAU,MAAM,CAAA;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO;AACxB,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,EAAM;AACzB,IAAA,MAAM,KAAA,GAAS,IAAA,CAAK,IAAA,CAAK,OAAA,EAAiD,YAAA;AAC1E,IAAA,IAAA,CAAK,OAAO,YAAA,GAAe,KAAA,KAAU,SAAY,CAAA,GAAIC,+BAAA,CAAc,OAAO,KAAK,CAAA;AAC/E,IAAAC,sCAAA,CAAqB,UAAU,IAAA,CAAK,MAAA,EAAQ,gBAAgB,MAAM,IAAA,CAAK,aAAY,EAAG,IAAA,CAAK,IAAA,CAAK,SAAA,IAAa,EAAC,EAAG,IAAA,CAAK,UAAW,MAAA,GAAS,IAAA,CAAK,IAAI,KAAK,CAAA;AACxJ,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA;AAAA,EAGQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAO,MAAA;AAC3B,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,YAAY,CAAC,CAAA;AAC9D,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,SAAA,EAAW;AAClC,MAAA,IAAI,EAAE,iBAAiBC,8BAAA,CAAA,EAAe;AACtC,MAAA,MAAM,CAAA,GAAI,OAAO,CAAA,EAAG,CAAA;AACpB,MAAA,IAAI,CAAA,EAAG,KAAA,CAAM,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA;AAAA,IAC/E;AAAA,EACF;AACF","file":"Spans-M5KMHT6K.cjs","sourcesContent":["// The sequence behind a text layer with `spans`: a composition of ordinary text layers (see src/text/spans.ts) that also owns the typewriter\n// (`visibleChars`) of the whole text: it counts over every character of every piece, and tells each piece how many of its own to show.\nimport { CompositionSequence } from './Composition';\nimport { TextSequence, bindCounterKeyframes, resolveNumber, type CounterState } from './Text';\nimport { spansMeta, type SpansMeta } from '../text/spans';\nimport type { CompositionShape, SequenceSpec, Props } from '../types';\nimport type { Timeline } from '../core/timelineEngine';\n\nconst strip = (props: Props | undefined): Props | undefined => {\n if (!props || !('visibleChars' in props)) return props;\n const { visibleChars: _gone, ...rest } = props as Record<string, unknown>;\n return rest as unknown as Props;\n};\n\nexport class SpansSequence extends CompositionSequence {\n private readonly _meta: SpansMeta | undefined;\n private readonly _count: CounterState = { value: 0, visibleChars: 0 };\n\n constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape) {\n super(spec, parent, root);\n this._meta = spansMeta.get(spec);\n }\n\n /** `visibleChars` is the group's own counter, not a property to write on the container. */\n protected override displayProps(): { initial: CompositionSequence['spec']['initial']; keyframes: CompositionSequence['spec']['keyframes'] } {\n const p = super.displayProps();\n if (!this._meta?.typed) return p;\n return {\n initial: strip(p.initial as Props | undefined) as never,\n keyframes: p.keyframes?.map(kf => ({ ...kf, set: strip(kf.set), to: strip(kf.to), from: strip(kf.from) })),\n };\n }\n\n override bindTimeline(timeline: Timeline, offset = 0): void {\n super.bindTimeline(timeline, offset);\n if (!this._meta?.typed) return;\n const scope = this.scope();\n const first = (this.spec.initial as Record<string, unknown> | undefined)?.visibleChars;\n this._count.visibleChars = first === undefined ? 0 : resolveNumber(first, scope); // like a text: it starts at 0 once it is animated\n bindCounterKeyframes(timeline, this._count, 'visibleChars', () => this._distribute(), this.spec.keyframes ?? [], this.duration!, offset + this.at, scope);\n this._distribute();\n }\n\n /** Every piece shows its part of the first N characters of the whole text. */\n private _distribute(): void {\n const pieces = this._meta!.pieces;\n const total = Math.max(0, Math.floor(this._count.visibleChars));\n let i = 0;\n for (const child of this._children) {\n if (!(child instanceof TextSequence)) continue;\n const p = pieces[i++];\n if (p) child.setVisibleChars(Math.min(p.length, Math.max(0, total - p.start)));\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/sequences/Spans.ts"],"names":["CompositionSequence","spansMeta","resolveNumber","bindCounterKeyframes","TextSequence"],"mappings":";;;;;;;;;AAQA,IAAM,KAAA,GAAQ,CAAC,KAAA,KAAgD;AAC7D,EAAA,IAAI,CAAC,KAAA,IAAS,EAAE,cAAA,IAAkB,QAAQ,OAAO,KAAA;AACjD,EAAA,MAAM,EAAE,YAAA,EAAc,KAAA,EAAO,GAAG,MAAK,GAAI,KAAA;AACzC,EAAA,OAAO,IAAA;AACT,CAAA;AAEO,IAAM,aAAA,GAAN,cAA4BA,qCAAA,CAAoB;AAAA,EACpC,KAAA;AAAA,EACA,MAAA,GAAuB,EAAE,KAAA,EAAO,CAAA,EAAG,cAAc,CAAA,EAAE;AAAA,EAEpE,WAAA,CAAY,IAAA,EAAoB,MAAA,EAAiC,IAAA,EAAwB;AACvF,IAAA,KAAA,CAAM,IAAA,EAAM,QAAQ,IAAI,CAAA;AACxB,IAAA,IAAA,CAAK,KAAA,GAAQC,2BAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,EACjC;AAAA;AAAA,EAGmB,YAAA,GAAyH;AAC1I,IAAA,MAAM,CAAA,GAAI,MAAM,YAAA,EAAa;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,OAAO,CAAA;AAC/B,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA,CAAM,CAAA,CAAE,OAA4B,CAAA;AAAA,MAC7C,SAAA,EAAW,EAAE,SAAA,EAAW,GAAA,CAAI,SAAO,EAAE,GAAG,EAAA,EAAI,GAAA,EAAK,KAAA,CAAM,EAAA,CAAG,GAAG,CAAA,EAAG,EAAA,EAAI,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,EAAG,MAAM,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,EAAE,CAAE;AAAA,KAC3G;AAAA,EACF;AAAA,EAES,YAAA,CAAa,QAAA,EAAoB,MAAA,GAAS,CAAA,EAAS;AAC1D,IAAA,KAAA,CAAM,YAAA,CAAa,UAAU,MAAM,CAAA;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO;AACxB,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,EAAM;AACzB,IAAA,MAAM,KAAA,GAAS,IAAA,CAAK,IAAA,CAAK,OAAA,EAAiD,YAAA;AAC1E,IAAA,IAAA,CAAK,OAAO,YAAA,GAAe,KAAA,KAAU,SAAY,CAAA,GAAIC,+BAAA,CAAc,OAAO,KAAK,CAAA;AAC/E,IAAAC,sCAAA,CAAqB,UAAU,IAAA,CAAK,MAAA,EAAQ,gBAAgB,MAAM,IAAA,CAAK,aAAY,EAAG,IAAA,CAAK,IAAA,CAAK,SAAA,IAAa,EAAC,EAAG,IAAA,CAAK,UAAW,MAAA,GAAS,IAAA,CAAK,IAAI,KAAK,CAAA;AACxJ,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA;AAAA,EAGQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAO,MAAA;AAC3B,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,YAAY,CAAC,CAAA;AAC9D,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,SAAA,EAAW;AAClC,MAAA,IAAI,EAAE,iBAAiBC,8BAAA,CAAA,EAAe;AACtC,MAAA,MAAM,CAAA,GAAI,OAAO,CAAA,EAAG,CAAA;AACpB,MAAA,IAAI,CAAA,EAAG,KAAA,CAAM,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA;AAAA,IAC/E;AAAA,EACF;AACF","file":"Spans-KTUPDFSR.cjs","sourcesContent":["// The sequence behind a text layer with `spans`: a composition of ordinary text layers (see src/text/spans.ts) that also owns the typewriter\n// (`visibleChars`) of the whole text: it counts over every character of every piece, and tells each piece how many of its own to show.\nimport { CompositionSequence } from './Composition';\nimport { TextSequence, bindCounterKeyframes, resolveNumber, type CounterState } from './Text';\nimport { spansMeta, type SpansMeta } from '../text/spans';\nimport type { CompositionShape, SequenceSpec, Props } from '../types';\nimport type { Timeline } from '../core/timelineEngine';\n\nconst strip = (props: Props | undefined): Props | undefined => {\n if (!props || !('visibleChars' in props)) return props;\n const { visibleChars: _gone, ...rest } = props as Record<string, unknown>;\n return rest as unknown as Props;\n};\n\nexport class SpansSequence extends CompositionSequence {\n private readonly _meta: SpansMeta | undefined;\n private readonly _count: CounterState = { value: 0, visibleChars: 0 };\n\n constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape) {\n super(spec, parent, root);\n this._meta = spansMeta.get(spec);\n }\n\n /** `visibleChars` is the group's own counter, not a property to write on the container. */\n protected override displayProps(): { initial: CompositionSequence['spec']['initial']; keyframes: CompositionSequence['spec']['keyframes'] } {\n const p = super.displayProps();\n if (!this._meta?.typed) return p;\n return {\n initial: strip(p.initial as Props | undefined) as never,\n keyframes: p.keyframes?.map(kf => ({ ...kf, set: strip(kf.set), to: strip(kf.to), from: strip(kf.from) })),\n };\n }\n\n override bindTimeline(timeline: Timeline, offset = 0): void {\n super.bindTimeline(timeline, offset);\n if (!this._meta?.typed) return;\n const scope = this.scope();\n const first = (this.spec.initial as Record<string, unknown> | undefined)?.visibleChars;\n this._count.visibleChars = first === undefined ? 0 : resolveNumber(first, scope); // like a text: it starts at 0 once it is animated\n bindCounterKeyframes(timeline, this._count, 'visibleChars', () => this._distribute(), this.spec.keyframes ?? [], this.duration!, offset + this.at, scope);\n this._distribute();\n }\n\n /** Every piece shows its part of the first N characters of the whole text. */\n private _distribute(): void {\n const pieces = this._meta!.pieces;\n const total = Math.max(0, Math.floor(this._count.visibleChars));\n let i = 0;\n for (const child of this._children) {\n if (!(child instanceof TextSequence)) continue;\n const p = pieces[i++];\n if (p) child.setVisibleChars(Math.min(p.length, Math.max(0, total - p.start)));\n }\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { setBlendFilterFactory } from './chunk-PC7DFDCV.js';
2
- import './chunk-JVO2W77G.js';
3
- import './chunk-BXOCEZ4U.js';
1
+ import { setBlendFilterFactory } from './chunk-JBDBICS2.js';
2
+ import './chunk-BFRWSV3R.js';
3
+ import './chunk-WGRWFQOB.js';
4
4
  import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';
5
5
 
6
6
  var SEPARABLE = {
@@ -86,5 +86,5 @@ fn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);
86
86
  }
87
87
 
88
88
  export { OWN_MODES, createBlendFilter, registerBlendModes };
89
- //# sourceMappingURL=blendModes-S72MBYKY.js.map
90
- //# sourceMappingURL=blendModes-S72MBYKY.js.map
89
+ //# sourceMappingURL=blendModes-535EMYGK.js.map
90
+ //# sourceMappingURL=blendModes-535EMYGK.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filters/blendModes.ts"],"names":[],"mappings":"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","file":"blendModes-S72MBYKY.js","sourcesContent":["import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';\nimport { setBlendFilterFactory, type BlendFilterLike } from '../core/blend';\n\n/**\n * The W3C compositing blend modes as our own `BlendModeFilter`s, registered on the SAME pixi instance the movie uses (this file imports\n * 'pixi.js' like the rest of the library; `import 'pixi.js/advanced-blend-modes'` would register on its own copy of `extensions` when\n * the page maps pixi.js to an esm.sh bundle, and then nothing is registered and the layer silently draws as `normal`). It also avoids\n * what pixi 8.22's own versions get wrong: the source colour is premultiplied (a half-transparent layer was blended with its darkened\n * colour and then faded again), the backdrop's alpha is ignored, soft-light is inverted on WebGPU (`select` arguments swapped),\n * linear-light and saturation are wrong. Loaded by `Movie.init` only when a layer uses one of these (see `usesAdvancedBlend`).\n */\ntype Sep = { gl: string; gpu: string }; // a separable blend: the body of B(b, s) for one channel\n\nconst SEPARABLE: Record<string, Sep> = {\n overlay: { gl: 'return b <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, b <= 0.5);' },\n 'hard-light': { gl: 'return s <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, s <= 0.5);' },\n 'soft-light': {\n gl: 'if (s <= 0.5) return b - (1.0 - 2.0 * s) * b * (1.0 - b); float d = b <= 0.25 ? ((16.0 * b - 12.0) * b + 4.0) * b : sqrt(b); return b + (2.0 * s - 1.0) * (d - b);',\n gpu: 'let d = select(sqrt(b), ((16.0 * b - 12.0) * b + 4.0) * b, b <= 0.25); return select(b + (2.0 * s - 1.0) * (d - b), b - (1.0 - 2.0 * s) * b * (1.0 - b), s <= 0.5);',\n },\n 'color-dodge': { gl: 'if (b <= 0.0) return 0.0; return s >= 1.0 ? 1.0 : min(1.0, b / (1.0 - s));', gpu: 'if (b <= 0.0) { return 0.0; } return select(min(1.0, b / (1.0 - s)), 1.0, s >= 1.0);' },\n 'color-burn': { gl: 'if (b >= 1.0) return 1.0; return s <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - b) / s);', gpu: 'if (b >= 1.0) { return 1.0; } return select(1.0 - min(1.0, (1.0 - b) / s), 0.0, s <= 0.0);' },\n darken: { gl: 'return min(b, s);', gpu: 'return min(b, s);' },\n lighten: { gl: 'return max(b, s);', gpu: 'return max(b, s);' },\n difference: { gl: 'return abs(b - s);', gpu: 'return abs(b - s);' },\n exclusion: { gl: 'return b + s - 2.0 * b * s;', gpu: 'return b + s - 2.0 * b * s;' },\n 'linear-burn': { gl: 'return max(0.0, b + s - 1.0);', gpu: 'return max(0.0, b + s - 1.0);' },\n};\n\nconst GL_NONSEP = `\nfloat lum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nvec3 clipColor(vec3 c) { float l = lum(c); float n = min(c.r, min(c.g, c.b)); float x = max(c.r, max(c.g, c.b));\n if (n < 0.0) c = l + (c - l) * l / (l - n); if (x > 1.0) c = l + (c - l) * (1.0 - l) / (x - l); return c; }\nvec3 setLum(vec3 c, float l) { return clipColor(c + (l - lum(c))); }\nfloat sat(vec3 c) { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nvec3 setSat(vec3 c, float s) { float mx = max(c.r, max(c.g, c.b)); float mn = min(c.r, min(c.g, c.b)); return mx > mn ? (c - mn) * s / (mx - mn) : vec3(0.0); }`;\nconst GPU_NONSEP = `\nfn lum(c: vec3<f32>) -> f32 { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nfn clipColor(c0: vec3<f32>) -> vec3<f32> { var c = c0; let l = lum(c); let n = min(c.r, min(c.g, c.b)); let x = max(c.r, max(c.g, c.b));\n if (n < 0.0) { c = l + (c - l) * l / (l - n); } if (x > 1.0) { c = l + (c - l) * (1.0 - l) / (x - l); } return c; }\nfn setLum(c: vec3<f32>, l: f32) -> vec3<f32> { return clipColor(c + (l - lum(c))); }\nfn sat(c: vec3<f32>) -> f32 { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nfn setSat(c: vec3<f32>, s: f32) -> vec3<f32> { let mx = max(c.r, max(c.g, c.b)); let mn = min(c.r, min(c.g, c.b)); if (mx > mn) { return (c - vec3<f32>(mn)) * s / (mx - mn); } return vec3<f32>(0.0); }`;\nconst NONSEP: Record<string, { gl: string; gpu: string }> = {\n hue: { gl: 'return setLum(setSat(cs, sat(cb)), lum(cb));', gpu: 'return setLum(setSat(cs, sat(cb)), lum(cb));' },\n saturation: { gl: 'return setLum(setSat(cb, sat(cs)), lum(cb));', gpu: 'return setLum(setSat(cb, sat(cs)), lum(cb));' },\n color: { gl: 'return setLum(cs, lum(cb));', gpu: 'return setLum(cs, lum(cb));' },\n luminosity: { gl: 'return setLum(cb, lum(cs));', gpu: 'return setLum(cb, lum(cs));' },\n};\n\nconst GL_MAIN = `\n vec3 cs = front.a > 0.0 ? front.rgb / front.a : vec3(0.0);\n vec3 cb = back.a > 0.0 ? back.rgb / back.a : vec3(0.0);\n vec3 mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n finalColor = vec4(mixed, blendedAlpha) * uBlend;`;\nconst GPU_MAIN = `\n let cs = select(vec3<f32>(0.0), front.rgb / front.a, front.a > 0.0);\n let cb = select(vec3<f32>(0.0), back.rgb / back.a, back.a > 0.0);\n let mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n out = vec4<f32>(mixed, blendedAlpha) * blendUniforms.uBlend;`;\n\nconst CLASSES = new Map<string, new () => BlendModeFilter>();\n\n/** A fresh blend filter for a layer that has filters of its own (it goes last in the chain and reads the backdrop). */\nexport function createBlendFilter(name: string): BlendFilterLike | null {\n const C = CLASSES.get(name);\n return C ? (new C() as unknown as BlendFilterLike) : null;\n}\n\nfunction make(name: string, gl: string, gpu: string): void {\n const C = class extends BlendModeFilter {\n static extension = { name, type: ExtensionType.BlendMode };\n constructor() { super({ gl: { functions: gl, main: GL_MAIN }, gpu: { functions: gpu, main: GPU_MAIN } }); }\n };\n CLASSES.set(name, C);\n extensions.add(C as never);\n}\n\nexport const OWN_MODES: readonly string[] = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];\n\nlet done = false;\n/** Register the blends (once per page), and give `core/blend.ts` the maker for the filter chain case. */\nexport function registerBlendModes(): void {\n setBlendFilterFactory(createBlendFilter); // every call: the registration below is once per page, the maker is cheap to hand over again\n if (done) return;\n done = true;\n for (const [name, s] of Object.entries(SEPARABLE)) {\n make(name,\n `float B(float b, float s) { ${s.gl} }\\nvec3 blendRGB(vec3 cb, vec3 cs) { return vec3(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`,\n `fn B(b: f32, s: f32) -> f32 { ${s.gpu} }\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { return vec3<f32>(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`);\n }\n for (const [name, s] of Object.entries(NONSEP)) {\n make(name, `${GL_NONSEP}\\nvec3 blendRGB(vec3 cb, vec3 cs) { ${s.gl} }`, `${GPU_NONSEP}\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/filters/blendModes.ts"],"names":[],"mappings":";;;;;AAaA,IAAM,SAAA,GAAiC;AAAA,EACrC,OAAA,EAAe,EAAE,EAAA,EAAI,oEAAA,EAAsE,KAAK,0EAAA,EAA2E;AAAA,EAC3K,YAAA,EAAe,EAAE,EAAA,EAAI,oEAAA,EAAsE,KAAK,0EAAA,EAA2E;AAAA,EAC3K,YAAA,EAAe;AAAA,IACb,EAAA,EAAI,oKAAA;AAAA,IACJ,GAAA,EAAK;AAAA,GACP;AAAA,EACA,aAAA,EAAe,EAAE,EAAA,EAAI,4EAAA,EAA8E,KAAK,sFAAA,EAAuF;AAAA,EAC/L,YAAA,EAAe,EAAE,EAAA,EAAI,kFAAA,EAAoF,KAAK,4FAAA,EAA6F;AAAA,EAC3M,MAAA,EAAe,EAAE,EAAA,EAAI,mBAAA,EAAqB,KAAK,mBAAA,EAAoB;AAAA,EACnE,OAAA,EAAe,EAAE,EAAA,EAAI,mBAAA,EAAqB,KAAK,mBAAA,EAAoB;AAAA,EACnE,UAAA,EAAe,EAAE,EAAA,EAAI,oBAAA,EAAsB,KAAK,oBAAA,EAAqB;AAAA,EACrE,SAAA,EAAe,EAAE,EAAA,EAAI,6BAAA,EAA+B,KAAK,6BAAA,EAA8B;AAAA,EACvF,aAAA,EAAe,EAAE,EAAA,EAAI,+BAAA,EAAiC,KAAK,+BAAA;AAC7D,CAAA;AAEA,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+JAAA,CAAA;AAOlB,IAAM,UAAA,GAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wMAAA,CAAA;AAOnB,IAAM,MAAA,GAAsD;AAAA,EAC1D,GAAA,EAAY,EAAE,EAAA,EAAI,8CAAA,EAAgD,KAAK,8CAAA,EAA+C;AAAA,EACtH,UAAA,EAAY,EAAE,EAAA,EAAI,8CAAA,EAAgD,KAAK,8CAAA,EAA+C;AAAA,EACtH,KAAA,EAAY,EAAE,EAAA,EAAI,6BAAA,EAA+B,KAAK,6BAAA,EAA8B;AAAA,EACpF,UAAA,EAAY,EAAE,EAAA,EAAI,6BAAA,EAA+B,KAAK,6BAAA;AACxD,CAAA;AAEA,IAAM,OAAA,GAAU;AAAA;AAAA;AAAA;AAAA,kDAAA,CAAA;AAKhB,IAAM,QAAA,GAAW;AAAA;AAAA;AAAA;AAAA,8DAAA,CAAA;AAMjB,IAAM,OAAA,uBAAc,GAAA,EAAuC;AAGpD,SAAS,kBAAkB,IAAA,EAAsC;AACtE,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAC1B,EAAA,OAAO,CAAA,GAAK,IAAI,CAAA,EAAE,GAAmC,IAAA;AACvD;AAEA,SAAS,IAAA,CAAK,IAAA,EAAc,EAAA,EAAY,GAAA,EAAmB;AACzD,EAAA,MAAM,CAAA,GAAI,cAAc,eAAA,CAAgB;AAAA,IACtC,OAAO,SAAA,GAAY,EAAE,IAAA,EAAM,IAAA,EAAM,cAAc,SAAA,EAAU;AAAA,IACzD,WAAA,GAAc;AAAE,MAAA,KAAA,CAAM,EAAE,EAAA,EAAI,EAAE,SAAA,EAAW,IAAI,IAAA,EAAM,OAAA,EAAQ,EAAG,GAAA,EAAK,EAAE,SAAA,EAAW,GAAA,EAAK,IAAA,EAAM,QAAA,IAAY,CAAA;AAAA,IAAG;AAAA,GAC5G;AACA,EAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAC,CAAA;AACnB,EAAA,UAAA,CAAW,IAAI,CAAU,CAAA;AAC3B;AAEO,IAAM,SAAA,GAA+B,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG,GAAG,MAAA,CAAO,IAAA,CAAK,MAAM,CAAC;AAE9F,IAAI,IAAA,GAAO,KAAA;AAEJ,SAAS,kBAAA,GAA2B;AACzC,EAAA,qBAAA,CAAsB,iBAAiB,CAAA;AACvC,EAAA,IAAI,IAAA,EAAM;AACV,EAAA,IAAA,GAAO,IAAA;AACP,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AACjD,IAAA,IAAA;AAAA,MAAK,IAAA;AAAA,MACH,CAAA,4BAAA,EAA+B,EAAE,EAAE,CAAA;AAAA,6FAAA,CAAA;AAAA,MACnC,CAAA,8BAAA,EAAiC,EAAE,GAAG,CAAA;AAAA,yHAAA;AAAA,KAA+H;AAAA,EACzK;AACA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC9C,IAAA,IAAA,CAAK,IAAA,EAAM,GAAG,SAAS;AAAA,kCAAA,EAAuC,CAAA,CAAE,EAAE,CAAA,EAAA,CAAA,EAAM,CAAA,EAAG,UAAU;AAAA,yDAAA,EAA8D,CAAA,CAAE,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,EAC9J;AACF","file":"blendModes-535EMYGK.js","sourcesContent":["import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';\nimport { setBlendFilterFactory, type BlendFilterLike } from '../core/blend';\n\n/**\n * The W3C compositing blend modes as our own `BlendModeFilter`s, registered on the SAME pixi instance the movie uses (this file imports\n * 'pixi.js' like the rest of the library; `import 'pixi.js/advanced-blend-modes'` would register on its own copy of `extensions` when\n * the page maps pixi.js to an esm.sh bundle, and then nothing is registered and the layer silently draws as `normal`). It also avoids\n * what pixi 8.22's own versions get wrong: the source colour is premultiplied (a half-transparent layer was blended with its darkened\n * colour and then faded again), the backdrop's alpha is ignored, soft-light is inverted on WebGPU (`select` arguments swapped),\n * linear-light and saturation are wrong. Loaded by `Movie.init` only when a layer uses one of these (see `usesAdvancedBlend`).\n */\ntype Sep = { gl: string; gpu: string }; // a separable blend: the body of B(b, s) for one channel\n\nconst SEPARABLE: Record<string, Sep> = {\n overlay: { gl: 'return b <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, b <= 0.5);' },\n 'hard-light': { gl: 'return s <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, s <= 0.5);' },\n 'soft-light': {\n gl: 'if (s <= 0.5) return b - (1.0 - 2.0 * s) * b * (1.0 - b); float d = b <= 0.25 ? ((16.0 * b - 12.0) * b + 4.0) * b : sqrt(b); return b + (2.0 * s - 1.0) * (d - b);',\n gpu: 'let d = select(sqrt(b), ((16.0 * b - 12.0) * b + 4.0) * b, b <= 0.25); return select(b + (2.0 * s - 1.0) * (d - b), b - (1.0 - 2.0 * s) * b * (1.0 - b), s <= 0.5);',\n },\n 'color-dodge': { gl: 'if (b <= 0.0) return 0.0; return s >= 1.0 ? 1.0 : min(1.0, b / (1.0 - s));', gpu: 'if (b <= 0.0) { return 0.0; } return select(min(1.0, b / (1.0 - s)), 1.0, s >= 1.0);' },\n 'color-burn': { gl: 'if (b >= 1.0) return 1.0; return s <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - b) / s);', gpu: 'if (b >= 1.0) { return 1.0; } return select(1.0 - min(1.0, (1.0 - b) / s), 0.0, s <= 0.0);' },\n darken: { gl: 'return min(b, s);', gpu: 'return min(b, s);' },\n lighten: { gl: 'return max(b, s);', gpu: 'return max(b, s);' },\n difference: { gl: 'return abs(b - s);', gpu: 'return abs(b - s);' },\n exclusion: { gl: 'return b + s - 2.0 * b * s;', gpu: 'return b + s - 2.0 * b * s;' },\n 'linear-burn': { gl: 'return max(0.0, b + s - 1.0);', gpu: 'return max(0.0, b + s - 1.0);' },\n};\n\nconst GL_NONSEP = `\nfloat lum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nvec3 clipColor(vec3 c) { float l = lum(c); float n = min(c.r, min(c.g, c.b)); float x = max(c.r, max(c.g, c.b));\n if (n < 0.0) c = l + (c - l) * l / (l - n); if (x > 1.0) c = l + (c - l) * (1.0 - l) / (x - l); return c; }\nvec3 setLum(vec3 c, float l) { return clipColor(c + (l - lum(c))); }\nfloat sat(vec3 c) { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nvec3 setSat(vec3 c, float s) { float mx = max(c.r, max(c.g, c.b)); float mn = min(c.r, min(c.g, c.b)); return mx > mn ? (c - mn) * s / (mx - mn) : vec3(0.0); }`;\nconst GPU_NONSEP = `\nfn lum(c: vec3<f32>) -> f32 { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nfn clipColor(c0: vec3<f32>) -> vec3<f32> { var c = c0; let l = lum(c); let n = min(c.r, min(c.g, c.b)); let x = max(c.r, max(c.g, c.b));\n if (n < 0.0) { c = l + (c - l) * l / (l - n); } if (x > 1.0) { c = l + (c - l) * (1.0 - l) / (x - l); } return c; }\nfn setLum(c: vec3<f32>, l: f32) -> vec3<f32> { return clipColor(c + (l - lum(c))); }\nfn sat(c: vec3<f32>) -> f32 { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nfn setSat(c: vec3<f32>, s: f32) -> vec3<f32> { let mx = max(c.r, max(c.g, c.b)); let mn = min(c.r, min(c.g, c.b)); if (mx > mn) { return (c - vec3<f32>(mn)) * s / (mx - mn); } return vec3<f32>(0.0); }`;\nconst NONSEP: Record<string, { gl: string; gpu: string }> = {\n hue: { gl: 'return setLum(setSat(cs, sat(cb)), lum(cb));', gpu: 'return setLum(setSat(cs, sat(cb)), lum(cb));' },\n saturation: { gl: 'return setLum(setSat(cb, sat(cs)), lum(cb));', gpu: 'return setLum(setSat(cb, sat(cs)), lum(cb));' },\n color: { gl: 'return setLum(cs, lum(cb));', gpu: 'return setLum(cs, lum(cb));' },\n luminosity: { gl: 'return setLum(cb, lum(cs));', gpu: 'return setLum(cb, lum(cs));' },\n};\n\nconst GL_MAIN = `\n vec3 cs = front.a > 0.0 ? front.rgb / front.a : vec3(0.0);\n vec3 cb = back.a > 0.0 ? back.rgb / back.a : vec3(0.0);\n vec3 mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n finalColor = vec4(mixed, blendedAlpha) * uBlend;`;\nconst GPU_MAIN = `\n let cs = select(vec3<f32>(0.0), front.rgb / front.a, front.a > 0.0);\n let cb = select(vec3<f32>(0.0), back.rgb / back.a, back.a > 0.0);\n let mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n out = vec4<f32>(mixed, blendedAlpha) * blendUniforms.uBlend;`;\n\nconst CLASSES = new Map<string, new () => BlendModeFilter>();\n\n/** A fresh blend filter for a layer that has filters of its own (it goes last in the chain and reads the backdrop). */\nexport function createBlendFilter(name: string): BlendFilterLike | null {\n const C = CLASSES.get(name);\n return C ? (new C() as unknown as BlendFilterLike) : null;\n}\n\nfunction make(name: string, gl: string, gpu: string): void {\n const C = class extends BlendModeFilter {\n static extension = { name, type: ExtensionType.BlendMode };\n constructor() { super({ gl: { functions: gl, main: GL_MAIN }, gpu: { functions: gpu, main: GPU_MAIN } }); }\n };\n CLASSES.set(name, C);\n extensions.add(C as never);\n}\n\nexport const OWN_MODES: readonly string[] = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];\n\nlet done = false;\n/** Register the blends (once per page), and give `core/blend.ts` the maker for the filter chain case. */\nexport function registerBlendModes(): void {\n setBlendFilterFactory(createBlendFilter); // every call: the registration below is once per page, the maker is cheap to hand over again\n if (done) return;\n done = true;\n for (const [name, s] of Object.entries(SEPARABLE)) {\n make(name,\n `float B(float b, float s) { ${s.gl} }\\nvec3 blendRGB(vec3 cb, vec3 cs) { return vec3(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`,\n `fn B(b: f32, s: f32) -> f32 { ${s.gpu} }\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { return vec3<f32>(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`);\n }\n for (const [name, s] of Object.entries(NONSEP)) {\n make(name, `${GL_NONSEP}\\nvec3 blendRGB(vec3 cb, vec3 cs) { ${s.gl} }`, `${GPU_NONSEP}\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);\n }\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkRU4N3B5B_cjs = require('./chunk-RU4N3B5B.cjs');
4
- require('./chunk-YSTOH5PC.cjs');
5
- require('./chunk-TWZNOUM7.cjs');
3
+ var chunkWYR2AU4W_cjs = require('./chunk-WYR2AU4W.cjs');
4
+ require('./chunk-NGJXVJB7.cjs');
5
+ require('./chunk-DOLTCXCL.cjs');
6
6
  var pixi_js = require('pixi.js');
7
7
 
8
8
  var SEPARABLE = {
@@ -68,7 +68,7 @@ function make(name, gl, gpu) {
68
68
  var OWN_MODES = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];
69
69
  var done = false;
70
70
  function registerBlendModes() {
71
- chunkRU4N3B5B_cjs.setBlendFilterFactory(createBlendFilter);
71
+ chunkWYR2AU4W_cjs.setBlendFilterFactory(createBlendFilter);
72
72
  if (done) return;
73
73
  done = true;
74
74
  for (const [name, s] of Object.entries(SEPARABLE)) {
@@ -90,5 +90,5 @@ fn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);
90
90
  exports.OWN_MODES = OWN_MODES;
91
91
  exports.createBlendFilter = createBlendFilter;
92
92
  exports.registerBlendModes = registerBlendModes;
93
- //# sourceMappingURL=blendModes-Y56QAMC4.cjs.map
94
- //# sourceMappingURL=blendModes-Y56QAMC4.cjs.map
93
+ //# sourceMappingURL=blendModes-V5XHC7U4.cjs.map
94
+ //# sourceMappingURL=blendModes-V5XHC7U4.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filters/blendModes.ts"],"names":["BlendModeFilter","ExtensionType","extensions","setBlendFilterFactory"],"mappings":"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","file":"blendModes-Y56QAMC4.cjs","sourcesContent":["import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';\nimport { setBlendFilterFactory, type BlendFilterLike } from '../core/blend';\n\n/**\n * The W3C compositing blend modes as our own `BlendModeFilter`s, registered on the SAME pixi instance the movie uses (this file imports\n * 'pixi.js' like the rest of the library; `import 'pixi.js/advanced-blend-modes'` would register on its own copy of `extensions` when\n * the page maps pixi.js to an esm.sh bundle, and then nothing is registered and the layer silently draws as `normal`). It also avoids\n * what pixi 8.22's own versions get wrong: the source colour is premultiplied (a half-transparent layer was blended with its darkened\n * colour and then faded again), the backdrop's alpha is ignored, soft-light is inverted on WebGPU (`select` arguments swapped),\n * linear-light and saturation are wrong. Loaded by `Movie.init` only when a layer uses one of these (see `usesAdvancedBlend`).\n */\ntype Sep = { gl: string; gpu: string }; // a separable blend: the body of B(b, s) for one channel\n\nconst SEPARABLE: Record<string, Sep> = {\n overlay: { gl: 'return b <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, b <= 0.5);' },\n 'hard-light': { gl: 'return s <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, s <= 0.5);' },\n 'soft-light': {\n gl: 'if (s <= 0.5) return b - (1.0 - 2.0 * s) * b * (1.0 - b); float d = b <= 0.25 ? ((16.0 * b - 12.0) * b + 4.0) * b : sqrt(b); return b + (2.0 * s - 1.0) * (d - b);',\n gpu: 'let d = select(sqrt(b), ((16.0 * b - 12.0) * b + 4.0) * b, b <= 0.25); return select(b + (2.0 * s - 1.0) * (d - b), b - (1.0 - 2.0 * s) * b * (1.0 - b), s <= 0.5);',\n },\n 'color-dodge': { gl: 'if (b <= 0.0) return 0.0; return s >= 1.0 ? 1.0 : min(1.0, b / (1.0 - s));', gpu: 'if (b <= 0.0) { return 0.0; } return select(min(1.0, b / (1.0 - s)), 1.0, s >= 1.0);' },\n 'color-burn': { gl: 'if (b >= 1.0) return 1.0; return s <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - b) / s);', gpu: 'if (b >= 1.0) { return 1.0; } return select(1.0 - min(1.0, (1.0 - b) / s), 0.0, s <= 0.0);' },\n darken: { gl: 'return min(b, s);', gpu: 'return min(b, s);' },\n lighten: { gl: 'return max(b, s);', gpu: 'return max(b, s);' },\n difference: { gl: 'return abs(b - s);', gpu: 'return abs(b - s);' },\n exclusion: { gl: 'return b + s - 2.0 * b * s;', gpu: 'return b + s - 2.0 * b * s;' },\n 'linear-burn': { gl: 'return max(0.0, b + s - 1.0);', gpu: 'return max(0.0, b + s - 1.0);' },\n};\n\nconst GL_NONSEP = `\nfloat lum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nvec3 clipColor(vec3 c) { float l = lum(c); float n = min(c.r, min(c.g, c.b)); float x = max(c.r, max(c.g, c.b));\n if (n < 0.0) c = l + (c - l) * l / (l - n); if (x > 1.0) c = l + (c - l) * (1.0 - l) / (x - l); return c; }\nvec3 setLum(vec3 c, float l) { return clipColor(c + (l - lum(c))); }\nfloat sat(vec3 c) { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nvec3 setSat(vec3 c, float s) { float mx = max(c.r, max(c.g, c.b)); float mn = min(c.r, min(c.g, c.b)); return mx > mn ? (c - mn) * s / (mx - mn) : vec3(0.0); }`;\nconst GPU_NONSEP = `\nfn lum(c: vec3<f32>) -> f32 { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nfn clipColor(c0: vec3<f32>) -> vec3<f32> { var c = c0; let l = lum(c); let n = min(c.r, min(c.g, c.b)); let x = max(c.r, max(c.g, c.b));\n if (n < 0.0) { c = l + (c - l) * l / (l - n); } if (x > 1.0) { c = l + (c - l) * (1.0 - l) / (x - l); } return c; }\nfn setLum(c: vec3<f32>, l: f32) -> vec3<f32> { return clipColor(c + (l - lum(c))); }\nfn sat(c: vec3<f32>) -> f32 { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nfn setSat(c: vec3<f32>, s: f32) -> vec3<f32> { let mx = max(c.r, max(c.g, c.b)); let mn = min(c.r, min(c.g, c.b)); if (mx > mn) { return (c - vec3<f32>(mn)) * s / (mx - mn); } return vec3<f32>(0.0); }`;\nconst NONSEP: Record<string, { gl: string; gpu: string }> = {\n hue: { gl: 'return setLum(setSat(cs, sat(cb)), lum(cb));', gpu: 'return setLum(setSat(cs, sat(cb)), lum(cb));' },\n saturation: { gl: 'return setLum(setSat(cb, sat(cs)), lum(cb));', gpu: 'return setLum(setSat(cb, sat(cs)), lum(cb));' },\n color: { gl: 'return setLum(cs, lum(cb));', gpu: 'return setLum(cs, lum(cb));' },\n luminosity: { gl: 'return setLum(cb, lum(cs));', gpu: 'return setLum(cb, lum(cs));' },\n};\n\nconst GL_MAIN = `\n vec3 cs = front.a > 0.0 ? front.rgb / front.a : vec3(0.0);\n vec3 cb = back.a > 0.0 ? back.rgb / back.a : vec3(0.0);\n vec3 mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n finalColor = vec4(mixed, blendedAlpha) * uBlend;`;\nconst GPU_MAIN = `\n let cs = select(vec3<f32>(0.0), front.rgb / front.a, front.a > 0.0);\n let cb = select(vec3<f32>(0.0), back.rgb / back.a, back.a > 0.0);\n let mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n out = vec4<f32>(mixed, blendedAlpha) * blendUniforms.uBlend;`;\n\nconst CLASSES = new Map<string, new () => BlendModeFilter>();\n\n/** A fresh blend filter for a layer that has filters of its own (it goes last in the chain and reads the backdrop). */\nexport function createBlendFilter(name: string): BlendFilterLike | null {\n const C = CLASSES.get(name);\n return C ? (new C() as unknown as BlendFilterLike) : null;\n}\n\nfunction make(name: string, gl: string, gpu: string): void {\n const C = class extends BlendModeFilter {\n static extension = { name, type: ExtensionType.BlendMode };\n constructor() { super({ gl: { functions: gl, main: GL_MAIN }, gpu: { functions: gpu, main: GPU_MAIN } }); }\n };\n CLASSES.set(name, C);\n extensions.add(C as never);\n}\n\nexport const OWN_MODES: readonly string[] = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];\n\nlet done = false;\n/** Register the blends (once per page), and give `core/blend.ts` the maker for the filter chain case. */\nexport function registerBlendModes(): void {\n setBlendFilterFactory(createBlendFilter); // every call: the registration below is once per page, the maker is cheap to hand over again\n if (done) return;\n done = true;\n for (const [name, s] of Object.entries(SEPARABLE)) {\n make(name,\n `float B(float b, float s) { ${s.gl} }\\nvec3 blendRGB(vec3 cb, vec3 cs) { return vec3(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`,\n `fn B(b: f32, s: f32) -> f32 { ${s.gpu} }\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { return vec3<f32>(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`);\n }\n for (const [name, s] of Object.entries(NONSEP)) {\n make(name, `${GL_NONSEP}\\nvec3 blendRGB(vec3 cb, vec3 cs) { ${s.gl} }`, `${GPU_NONSEP}\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/filters/blendModes.ts"],"names":["BlendModeFilter","ExtensionType","extensions","setBlendFilterFactory"],"mappings":";;;;;;;AAaA,IAAM,SAAA,GAAiC;AAAA,EACrC,OAAA,EAAe,EAAE,EAAA,EAAI,oEAAA,EAAsE,KAAK,0EAAA,EAA2E;AAAA,EAC3K,YAAA,EAAe,EAAE,EAAA,EAAI,oEAAA,EAAsE,KAAK,0EAAA,EAA2E;AAAA,EAC3K,YAAA,EAAe;AAAA,IACb,EAAA,EAAI,oKAAA;AAAA,IACJ,GAAA,EAAK;AAAA,GACP;AAAA,EACA,aAAA,EAAe,EAAE,EAAA,EAAI,4EAAA,EAA8E,KAAK,sFAAA,EAAuF;AAAA,EAC/L,YAAA,EAAe,EAAE,EAAA,EAAI,kFAAA,EAAoF,KAAK,4FAAA,EAA6F;AAAA,EAC3M,MAAA,EAAe,EAAE,EAAA,EAAI,mBAAA,EAAqB,KAAK,mBAAA,EAAoB;AAAA,EACnE,OAAA,EAAe,EAAE,EAAA,EAAI,mBAAA,EAAqB,KAAK,mBAAA,EAAoB;AAAA,EACnE,UAAA,EAAe,EAAE,EAAA,EAAI,oBAAA,EAAsB,KAAK,oBAAA,EAAqB;AAAA,EACrE,SAAA,EAAe,EAAE,EAAA,EAAI,6BAAA,EAA+B,KAAK,6BAAA,EAA8B;AAAA,EACvF,aAAA,EAAe,EAAE,EAAA,EAAI,+BAAA,EAAiC,KAAK,+BAAA;AAC7D,CAAA;AAEA,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+JAAA,CAAA;AAOlB,IAAM,UAAA,GAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wMAAA,CAAA;AAOnB,IAAM,MAAA,GAAsD;AAAA,EAC1D,GAAA,EAAY,EAAE,EAAA,EAAI,8CAAA,EAAgD,KAAK,8CAAA,EAA+C;AAAA,EACtH,UAAA,EAAY,EAAE,EAAA,EAAI,8CAAA,EAAgD,KAAK,8CAAA,EAA+C;AAAA,EACtH,KAAA,EAAY,EAAE,EAAA,EAAI,6BAAA,EAA+B,KAAK,6BAAA,EAA8B;AAAA,EACpF,UAAA,EAAY,EAAE,EAAA,EAAI,6BAAA,EAA+B,KAAK,6BAAA;AACxD,CAAA;AAEA,IAAM,OAAA,GAAU;AAAA;AAAA;AAAA;AAAA,kDAAA,CAAA;AAKhB,IAAM,QAAA,GAAW;AAAA;AAAA;AAAA;AAAA,8DAAA,CAAA;AAMjB,IAAM,OAAA,uBAAc,GAAA,EAAuC;AAGpD,SAAS,kBAAkB,IAAA,EAAsC;AACtE,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAC1B,EAAA,OAAO,CAAA,GAAK,IAAI,CAAA,EAAE,GAAmC,IAAA;AACvD;AAEA,SAAS,IAAA,CAAK,IAAA,EAAc,EAAA,EAAY,GAAA,EAAmB;AACzD,EAAA,MAAM,CAAA,GAAI,cAAcA,uBAAA,CAAgB;AAAA,IACtC,OAAO,SAAA,GAAY,EAAE,IAAA,EAAM,IAAA,EAAMC,sBAAc,SAAA,EAAU;AAAA,IACzD,WAAA,GAAc;AAAE,MAAA,KAAA,CAAM,EAAE,EAAA,EAAI,EAAE,SAAA,EAAW,IAAI,IAAA,EAAM,OAAA,EAAQ,EAAG,GAAA,EAAK,EAAE,SAAA,EAAW,GAAA,EAAK,IAAA,EAAM,QAAA,IAAY,CAAA;AAAA,IAAG;AAAA,GAC5G;AACA,EAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAC,CAAA;AACnB,EAAAC,kBAAA,CAAW,IAAI,CAAU,CAAA;AAC3B;AAEO,IAAM,SAAA,GAA+B,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG,GAAG,MAAA,CAAO,IAAA,CAAK,MAAM,CAAC;AAE9F,IAAI,IAAA,GAAO,KAAA;AAEJ,SAAS,kBAAA,GAA2B;AACzC,EAAAC,uCAAA,CAAsB,iBAAiB,CAAA;AACvC,EAAA,IAAI,IAAA,EAAM;AACV,EAAA,IAAA,GAAO,IAAA;AACP,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AACjD,IAAA,IAAA;AAAA,MAAK,IAAA;AAAA,MACH,CAAA,4BAAA,EAA+B,EAAE,EAAE,CAAA;AAAA,6FAAA,CAAA;AAAA,MACnC,CAAA,8BAAA,EAAiC,EAAE,GAAG,CAAA;AAAA,yHAAA;AAAA,KAA+H;AAAA,EACzK;AACA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC9C,IAAA,IAAA,CAAK,IAAA,EAAM,GAAG,SAAS;AAAA,kCAAA,EAAuC,CAAA,CAAE,EAAE,CAAA,EAAA,CAAA,EAAM,CAAA,EAAG,UAAU;AAAA,yDAAA,EAA8D,CAAA,CAAE,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,EAC9J;AACF","file":"blendModes-V5XHC7U4.cjs","sourcesContent":["import { BlendModeFilter, ExtensionType, extensions } from 'pixi.js';\nimport { setBlendFilterFactory, type BlendFilterLike } from '../core/blend';\n\n/**\n * The W3C compositing blend modes as our own `BlendModeFilter`s, registered on the SAME pixi instance the movie uses (this file imports\n * 'pixi.js' like the rest of the library; `import 'pixi.js/advanced-blend-modes'` would register on its own copy of `extensions` when\n * the page maps pixi.js to an esm.sh bundle, and then nothing is registered and the layer silently draws as `normal`). It also avoids\n * what pixi 8.22's own versions get wrong: the source colour is premultiplied (a half-transparent layer was blended with its darkened\n * colour and then faded again), the backdrop's alpha is ignored, soft-light is inverted on WebGPU (`select` arguments swapped),\n * linear-light and saturation are wrong. Loaded by `Movie.init` only when a layer uses one of these (see `usesAdvancedBlend`).\n */\ntype Sep = { gl: string; gpu: string }; // a separable blend: the body of B(b, s) for one channel\n\nconst SEPARABLE: Record<string, Sep> = {\n overlay: { gl: 'return b <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, b <= 0.5);' },\n 'hard-light': { gl: 'return s <= 0.5 ? 2.0 * b * s : 1.0 - 2.0 * (1.0 - b) * (1.0 - s);', gpu: 'return select(1.0 - 2.0 * (1.0 - b) * (1.0 - s), 2.0 * b * s, s <= 0.5);' },\n 'soft-light': {\n gl: 'if (s <= 0.5) return b - (1.0 - 2.0 * s) * b * (1.0 - b); float d = b <= 0.25 ? ((16.0 * b - 12.0) * b + 4.0) * b : sqrt(b); return b + (2.0 * s - 1.0) * (d - b);',\n gpu: 'let d = select(sqrt(b), ((16.0 * b - 12.0) * b + 4.0) * b, b <= 0.25); return select(b + (2.0 * s - 1.0) * (d - b), b - (1.0 - 2.0 * s) * b * (1.0 - b), s <= 0.5);',\n },\n 'color-dodge': { gl: 'if (b <= 0.0) return 0.0; return s >= 1.0 ? 1.0 : min(1.0, b / (1.0 - s));', gpu: 'if (b <= 0.0) { return 0.0; } return select(min(1.0, b / (1.0 - s)), 1.0, s >= 1.0);' },\n 'color-burn': { gl: 'if (b >= 1.0) return 1.0; return s <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - b) / s);', gpu: 'if (b >= 1.0) { return 1.0; } return select(1.0 - min(1.0, (1.0 - b) / s), 0.0, s <= 0.0);' },\n darken: { gl: 'return min(b, s);', gpu: 'return min(b, s);' },\n lighten: { gl: 'return max(b, s);', gpu: 'return max(b, s);' },\n difference: { gl: 'return abs(b - s);', gpu: 'return abs(b - s);' },\n exclusion: { gl: 'return b + s - 2.0 * b * s;', gpu: 'return b + s - 2.0 * b * s;' },\n 'linear-burn': { gl: 'return max(0.0, b + s - 1.0);', gpu: 'return max(0.0, b + s - 1.0);' },\n};\n\nconst GL_NONSEP = `\nfloat lum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nvec3 clipColor(vec3 c) { float l = lum(c); float n = min(c.r, min(c.g, c.b)); float x = max(c.r, max(c.g, c.b));\n if (n < 0.0) c = l + (c - l) * l / (l - n); if (x > 1.0) c = l + (c - l) * (1.0 - l) / (x - l); return c; }\nvec3 setLum(vec3 c, float l) { return clipColor(c + (l - lum(c))); }\nfloat sat(vec3 c) { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nvec3 setSat(vec3 c, float s) { float mx = max(c.r, max(c.g, c.b)); float mn = min(c.r, min(c.g, c.b)); return mx > mn ? (c - mn) * s / (mx - mn) : vec3(0.0); }`;\nconst GPU_NONSEP = `\nfn lum(c: vec3<f32>) -> f32 { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; }\nfn clipColor(c0: vec3<f32>) -> vec3<f32> { var c = c0; let l = lum(c); let n = min(c.r, min(c.g, c.b)); let x = max(c.r, max(c.g, c.b));\n if (n < 0.0) { c = l + (c - l) * l / (l - n); } if (x > 1.0) { c = l + (c - l) * (1.0 - l) / (x - l); } return c; }\nfn setLum(c: vec3<f32>, l: f32) -> vec3<f32> { return clipColor(c + (l - lum(c))); }\nfn sat(c: vec3<f32>) -> f32 { return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); }\nfn setSat(c: vec3<f32>, s: f32) -> vec3<f32> { let mx = max(c.r, max(c.g, c.b)); let mn = min(c.r, min(c.g, c.b)); if (mx > mn) { return (c - vec3<f32>(mn)) * s / (mx - mn); } return vec3<f32>(0.0); }`;\nconst NONSEP: Record<string, { gl: string; gpu: string }> = {\n hue: { gl: 'return setLum(setSat(cs, sat(cb)), lum(cb));', gpu: 'return setLum(setSat(cs, sat(cb)), lum(cb));' },\n saturation: { gl: 'return setLum(setSat(cb, sat(cs)), lum(cb));', gpu: 'return setLum(setSat(cb, sat(cs)), lum(cb));' },\n color: { gl: 'return setLum(cs, lum(cb));', gpu: 'return setLum(cs, lum(cb));' },\n luminosity: { gl: 'return setLum(cb, lum(cs));', gpu: 'return setLum(cb, lum(cs));' },\n};\n\nconst GL_MAIN = `\n vec3 cs = front.a > 0.0 ? front.rgb / front.a : vec3(0.0);\n vec3 cb = back.a > 0.0 ? back.rgb / back.a : vec3(0.0);\n vec3 mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n finalColor = vec4(mixed, blendedAlpha) * uBlend;`;\nconst GPU_MAIN = `\n let cs = select(vec3<f32>(0.0), front.rgb / front.a, front.a > 0.0);\n let cb = select(vec3<f32>(0.0), back.rgb / back.a, back.a > 0.0);\n let mixed = front.rgb * (1.0 - back.a) + front.a * back.a * blendRGB(cb, cs) + (1.0 - front.a) * back.rgb;\n out = vec4<f32>(mixed, blendedAlpha) * blendUniforms.uBlend;`;\n\nconst CLASSES = new Map<string, new () => BlendModeFilter>();\n\n/** A fresh blend filter for a layer that has filters of its own (it goes last in the chain and reads the backdrop). */\nexport function createBlendFilter(name: string): BlendFilterLike | null {\n const C = CLASSES.get(name);\n return C ? (new C() as unknown as BlendFilterLike) : null;\n}\n\nfunction make(name: string, gl: string, gpu: string): void {\n const C = class extends BlendModeFilter {\n static extension = { name, type: ExtensionType.BlendMode };\n constructor() { super({ gl: { functions: gl, main: GL_MAIN }, gpu: { functions: gpu, main: GPU_MAIN } }); }\n };\n CLASSES.set(name, C);\n extensions.add(C as never);\n}\n\nexport const OWN_MODES: readonly string[] = [...Object.keys(SEPARABLE), ...Object.keys(NONSEP)];\n\nlet done = false;\n/** Register the blends (once per page), and give `core/blend.ts` the maker for the filter chain case. */\nexport function registerBlendModes(): void {\n setBlendFilterFactory(createBlendFilter); // every call: the registration below is once per page, the maker is cheap to hand over again\n if (done) return;\n done = true;\n for (const [name, s] of Object.entries(SEPARABLE)) {\n make(name,\n `float B(float b, float s) { ${s.gl} }\\nvec3 blendRGB(vec3 cb, vec3 cs) { return vec3(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`,\n `fn B(b: f32, s: f32) -> f32 { ${s.gpu} }\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { return vec3<f32>(B(cb.r, cs.r), B(cb.g, cs.g), B(cb.b, cs.b)); }`);\n }\n for (const [name, s] of Object.entries(NONSEP)) {\n make(name, `${GL_NONSEP}\\nvec3 blendRGB(vec3 cb, vec3 cs) { ${s.gl} }`, `${GPU_NONSEP}\\nfn blendRGB(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> { ${s.gpu} }`);\n }\n}\n"]}