@brightspot/ui 1.9.0 → 1.10.0

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 (107) hide show
  1. package/dist/components/copy-to-clipboard/CopyToClipboard.d.ts.map +1 -1
  2. package/dist/components/copy-to-clipboard/CopyToClipboard.js +4 -0
  3. package/dist/components/copy-to-clipboard/CopyToClipboard.js.map +1 -1
  4. package/dist/components/switch/Switch.d.ts +92 -0
  5. package/dist/components/switch/Switch.d.ts.map +1 -0
  6. package/dist/components/switch/Switch.js +189 -0
  7. package/dist/components/switch/Switch.js.map +1 -0
  8. package/dist/custom-elements.json +512 -210
  9. package/dist/effects/celebrate.d.ts +18 -0
  10. package/dist/effects/celebrate.d.ts.map +1 -0
  11. package/dist/effects/celebrate.js +81 -0
  12. package/dist/effects/celebrate.js.map +1 -0
  13. package/dist/effects/ripple.d.ts +31 -0
  14. package/dist/effects/ripple.d.ts.map +1 -0
  15. package/dist/effects/ripple.js +131 -0
  16. package/dist/effects/ripple.js.map +1 -0
  17. package/dist/effects/sparkle-worklet.d.ts +7 -0
  18. package/dist/effects/sparkle-worklet.d.ts.map +1 -0
  19. package/dist/effects/sparkle-worklet.js +211 -0
  20. package/dist/effects/sparkle-worklet.js.map +1 -0
  21. package/dist/effects/sparkle.d.ts +6 -0
  22. package/dist/effects/sparkle.d.ts.map +1 -0
  23. package/dist/effects/sparkle.js +91 -0
  24. package/dist/effects/sparkle.js.map +1 -0
  25. package/dist/storybook/BSPLogoMark.svg +3 -0
  26. package/dist/storybook/WelcomeBG.svg +292 -0
  27. package/dist/storybook/assets/{Avatar.stories-Du1qM73U.js → Avatar.stories-B26mRkkZ.js} +1 -1
  28. package/dist/storybook/assets/{AvatarGroup.stories-DxwZQE-q.js → AvatarGroup.stories-J7lVGsMY.js} +1 -1
  29. package/dist/storybook/assets/{Badge.stories-CfvkMIx2.js → Badge.stories-BpTIV61M.js} +1 -1
  30. package/dist/storybook/assets/Button-Dg-fIrzT.js +10 -0
  31. package/dist/storybook/assets/Button.stories-gPKRVbxk.js +54 -0
  32. package/dist/storybook/assets/Celebrate.stories-DbY-sKEe.js +184 -0
  33. package/dist/storybook/assets/{CircularProgress.stories-rPzKwQYD.js → CircularProgress.stories-DeH5JYX_.js} +1 -1
  34. package/dist/storybook/assets/{ClipboardMixin.stories-BlUeYDSi.js → ClipboardMixin.stories-C-lZ4uuw.js} +1 -1
  35. package/dist/storybook/assets/Color-6BZIO3FS-Cu6zVIuG.js +1 -0
  36. package/dist/storybook/assets/{Colors.stories-BspfjZ5q.js → Colors.stories-D6XYMrTD.js} +1 -1
  37. package/dist/storybook/assets/CombinedEffects.stories-jFekKTYg.js +355 -0
  38. package/dist/storybook/assets/{ComponentStatesMixin-eTV7XXqB.js → ComponentStatesMixin-g50hRCPT.js} +1 -1
  39. package/dist/storybook/assets/{ComponentStatesMixin.stories-BbLSY3df.js → ComponentStatesMixin.stories-D3Q5pR38.js} +1 -1
  40. package/dist/storybook/assets/{CopyToClipboard.stories-B2ailiFF.js → CopyToClipboard.stories-COZZ1VC2.js} +1 -1
  41. package/dist/storybook/assets/{Debounce.stories-DJmp4eNo.js → Debounce.stories-Dl10LAnx.js} +1 -1
  42. package/dist/storybook/assets/DocsRenderer-LL677BLK-CFLtMbUx.js +10 -0
  43. package/dist/storybook/assets/{Dropdown.stories-Dd6vKiDd.js → Dropdown.stories-Drwq-0Z2.js} +1 -1
  44. package/dist/storybook/assets/{Events.stories-Byj-VOM9.js → Events.stories-dODeR-g-.js} +1 -1
  45. package/dist/storybook/assets/{Heading.stories-Dqw-wzpx.js → Heading.stories-CH7_-_q3.js} +1 -1
  46. package/dist/storybook/assets/HueRipple.stories-CH1Y739k.js +310 -0
  47. package/dist/storybook/assets/{Icon.stories-Bp1nvWER.js → Icon.stories-CPjM-jTU.js} +1 -1
  48. package/dist/storybook/assets/{IconButton.stories-o9g9mGdh.js → IconButton.stories-DuzqvcnN.js} +1 -1
  49. package/dist/storybook/assets/{LinearProgress.stories-DnXQVpzX.js → LinearProgress.stories-C7IdnJd3.js} +1 -1
  50. package/dist/storybook/assets/{Pagination.stories-DQD8uvDc.js → Pagination.stories-C4cLjS_9.js} +1 -1
  51. package/dist/storybook/assets/{Popover.stories-BvavsRfq.js → Popover.stories-Ca1F-wrI.js} +3 -11
  52. package/dist/storybook/assets/{ReadyMixin-6On1MFFr.js → ReadyMixin-DNZ5dCsZ.js} +1 -1
  53. package/dist/storybook/assets/{Rtc.stories-Bb5Y-908.js → Rtc.stories-BVJc1vCA.js} +1 -1
  54. package/dist/storybook/assets/{ScrollShadow.stories-ZovRXpte.js → ScrollShadow.stories-C3W5o9ZW.js} +1 -1
  55. package/dist/storybook/assets/Switch.stories-BEEHP8mD.js +312 -0
  56. package/dist/storybook/assets/{Throttle.stories-DmP-yKke.js → Throttle.stories-C4xsYeAb.js} +1 -1
  57. package/dist/storybook/assets/{Tooltip.stories-Dl6xHBaM.js → Tooltip.stories-Ccm4AnSv.js} +3 -7
  58. package/dist/storybook/assets/Welcome.stories-Degjk-M0.js +215 -0
  59. package/dist/storybook/assets/{Widget.stories-BjXfgNjZ.js → Widget.stories-OKnZ9sDs.js} +1 -1
  60. package/dist/storybook/assets/WithTooltip-65CFNBJE-CXL3TyJ2.js +9 -0
  61. package/dist/storybook/assets/blocks-DLdUKG_W.js +707 -0
  62. package/dist/storybook/assets/celebrate-KwPoF1K3.js +21 -0
  63. package/dist/storybook/assets/formatter-EIJCOSYU-29NCxjfM.js +1 -0
  64. package/dist/storybook/assets/if-defined-BZFPaJjl.js +1 -0
  65. package/dist/storybook/assets/iframe-BqvwP3or.js +1104 -0
  66. package/dist/storybook/assets/{iframe-CNxIA3cQ.css → iframe-C5bIZMJ5.css} +1 -1
  67. package/dist/storybook/assets/index-BIyTv1BF.js +1 -0
  68. package/dist/storybook/assets/onFind-1l3EPW-I.js +1 -0
  69. package/dist/storybook/assets/{onFind.stories-B2GYLrjV.js → onFind.stories-D64-QZqf.js} +2 -2
  70. package/dist/storybook/assets/{onRemove.stories-CoLJFkWa.js → onRemove.stories-BICsnIJL.js} +1 -1
  71. package/dist/storybook/assets/{onVisible.stories-DOeZx7wi.js → onVisible.stories-DpDZP9_5.js} +2 -2
  72. package/dist/storybook/assets/position-CFNQy3J6.js +1 -0
  73. package/dist/storybook/assets/ripple-DQbyyRUw.js +251 -0
  74. package/dist/storybook/assets/{style-map-CmHqpCu1.js → style-map-CBrSnxRe.js} +1 -1
  75. package/dist/storybook/assets/syntaxhighlighter-ED5Y7EFY-Bz_DuQj8.js +6 -0
  76. package/dist/storybook/brightspot-logo.svg +19 -0
  77. package/dist/storybook/iframe.html +23 -3
  78. package/dist/storybook/index.html +42 -1
  79. package/dist/storybook/index.json +1 -1
  80. package/dist/storybook/project.json +1 -1
  81. package/dist/storybook/sb-addons/storybook-3/manager-bundle.js +3 -0
  82. package/dist/tailwind-plugin-switch.d.ts +2 -0
  83. package/dist/tailwind-plugin-switch.d.ts.map +1 -0
  84. package/dist/tailwind-plugin-switch.js +223 -0
  85. package/dist/tailwind-plugin-switch.js.map +1 -0
  86. package/dist/tailwind-plugin-switch.ts +252 -0
  87. package/dist/util/EventEmitterMixin.d.ts +5 -0
  88. package/dist/util/EventEmitterMixin.d.ts.map +1 -1
  89. package/dist/util/EventEmitterMixin.js.map +1 -1
  90. package/dist/util/position.d.ts +9 -0
  91. package/dist/util/position.d.ts.map +1 -0
  92. package/dist/util/position.js +11 -0
  93. package/dist/util/position.js.map +1 -0
  94. package/docs/components/README.md +1 -0
  95. package/docs/components/Switch.md +79 -0
  96. package/package.json +2 -1
  97. package/dist/storybook/assets/Button.stories-hDMDDh81.js +0 -63
  98. package/dist/storybook/assets/Color-6BZIO3FS-C_nQSB2u.js +0 -1
  99. package/dist/storybook/assets/DocsRenderer-LL677BLK-56Pige1J.js +0 -758
  100. package/dist/storybook/assets/WithTooltip-65CFNBJE-CGB5q-AN.js +0 -9
  101. package/dist/storybook/assets/_commonjsHelpers-CqkleIqs.js +0 -1
  102. package/dist/storybook/assets/formatter-EIJCOSYU-BhNtSFM9.js +0 -1
  103. package/dist/storybook/assets/if-defined-BFyUeSVF.js +0 -1
  104. package/dist/storybook/assets/iframe-BeKreX-l.js +0 -1061
  105. package/dist/storybook/assets/index-Uz2kGy8J.js +0 -1
  106. package/dist/storybook/assets/onFind-DqriYjEB.js +0 -1
  107. package/dist/storybook/assets/syntaxhighlighter-ED5Y7EFY-BqFfcc7x.js +0 -6
@@ -0,0 +1,18 @@
1
+ import type { EffectPosition } from '../util/position.js';
2
+ export interface CelebrateOptions {
3
+ position: EffectPosition;
4
+ duration?: number;
5
+ size?: number;
6
+ }
7
+ export declare const BTU_CELEBRATE_EVENT = "btu-effect-celebrate";
8
+ export declare function btuCelebrate(options: CelebrateOptions): void;
9
+ export declare namespace btuCelebrate {
10
+ var setDefaults: (newDefaults: Partial<Omit<CelebrateOptions, "position">>) => void;
11
+ var listen: () => (() => void);
12
+ }
13
+ declare global {
14
+ interface DocumentEventMap {
15
+ 'btu-effect-celebrate': CustomEvent<CelebrateOptions>;
16
+ }
17
+ }
18
+ //# sourceMappingURL=celebrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"celebrate.d.ts","sourceRoot":"","sources":["../../src/effects/celebrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,mBAAmB,yBAAyB,CAAA;AA8CzD,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CA2B5D;yBA3Be,YAAY;mCA6Ba,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,KAAG,IAAI;sBAIjE,CAAC,MAAM,IAAI,CAAC;;AActC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,gBAAgB;QACxB,sBAAsB,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAA;KACtD;CACF"}
@@ -0,0 +1,81 @@
1
+ import { resolvePosition } from '../util/position.js';
2
+ export const BTU_CELEBRATE_EVENT = 'btu-effect-celebrate';
3
+ let defaults = {};
4
+ let container = null;
5
+ const templateCache = new Map();
6
+ function getTemplate(duration, size) {
7
+ const key = `${duration}-${size}`;
8
+ let tpl = templateCache.get(key);
9
+ if (!tpl) {
10
+ tpl = document.createElement('template');
11
+ tpl.innerHTML = defaultSparkleSvg(duration, size);
12
+ templateCache.set(key, tpl);
13
+ }
14
+ return tpl.content.cloneNode(true);
15
+ }
16
+ function defaultSparkleSvg(duration, size) {
17
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" shape-rendering="optimizeSpeed" text-rendering="optimizeSpeed" width="${size}" height="${size}" style="will-change: transform; transform: translateZ(0);">
18
+ <style><![CDATA[
19
+ #ejX6QuT4CUp2_to {animation: ejX6QuT4CUp2_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp2_to__to { 0% {offset-distance: 0%;animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 37.5% {offset-distance: 100%} 100% {offset-distance: 100%}} #ejX6QuT4CUp2_ts {animation: ejX6QuT4CUp2_ts__ts ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp2_ts__ts { 0% {transform: scale(-0.966656,0.966656);animation-timing-function: cubic-bezier(0,0,0.58,1)} 25% {transform: scale(-2.192693,2.192693);animation-timing-function: cubic-bezier(0,0,0.58,1)} 37.5% {transform: scale(-1.551673,1.551673)} 100% {transform: scale(-1.551673,1.551673)}} #ejX6QuT4CUp2 {animation: ejX6QuT4CUp2_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp2_c_o { 0% {opacity: 1} 25% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 37.5% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp3_to {animation: ejX6QuT4CUp3_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp3_to__to { 0% {offset-distance: 0%;animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 50% {offset-distance: 100%} 100% {offset-distance: 100%}} #ejX6QuT4CUp3_tr {animation: ejX6QuT4CUp3_tr__tr ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp3_tr__tr { 0% {transform: rotate(0deg);animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 50% {transform: rotate(305.83deg)} 100% {transform: rotate(305.83deg)}} #ejX6QuT4CUp3_ts {animation: ejX6QuT4CUp3_ts__ts ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp3_ts__ts { 0% {transform: scale(0.43962,0.43962)} 37.5% {transform: scale(1,1)} 100% {transform: scale(1,1)}} #ejX6QuT4CUp3 {animation: ejX6QuT4CUp3_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp3_c_o { 0% {opacity: 1} 37.5% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 50% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp4_to {animation: ejX6QuT4CUp4_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp4_to__to { 0% {offset-distance: 0%;animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 50% {offset-distance: 100%} 100% {offset-distance: 100%}} #ejX6QuT4CUp4_tr {animation: ejX6QuT4CUp4_tr__tr ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp4_tr__tr { 0% {transform: rotate(0deg);animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 37.5% {transform: rotate(-414.17deg)} 100% {transform: rotate(-414.17deg)}} #ejX6QuT4CUp4_ts {animation: ejX6QuT4CUp4_ts__ts ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp4_ts__ts { 0% {transform: scale(0.43962,0.43962)} 36.25% {transform: scale(0.75,0.75)} 50% {transform: scale(1,1)} 100% {transform: scale(1,1)}} #ejX6QuT4CUp4 {animation: ejX6QuT4CUp4_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp4_c_o { 0% {opacity: 1} 25% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 50% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp5_to {animation: ejX6QuT4CUp5_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp5_to__to { 0% {offset-distance: 0%;animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 50% {offset-distance: 100%} 100% {offset-distance: 100%}} #ejX6QuT4CUp5 {animation: ejX6QuT4CUp5_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp5_c_o { 0% {opacity: 1} 37.5% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 50% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp6_to {animation: ejX6QuT4CUp6_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp6_to__to { 0% {transform: translate(150px,150px);animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 25% {transform: translate(200px,170px)} 100% {transform: translate(200px,170px)}} #ejX6QuT4CUp6 {animation: ejX6QuT4CUp6_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp6_c_o { 0% {opacity: 1} 12.5% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 25% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp7_to {animation: ejX6QuT4CUp7_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp7_to__to { 0% {transform: translate(150px,150px);animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 50% {transform: translate(210px,100px)} 100% {transform: translate(210px,100px)}} #ejX6QuT4CUp7 {animation: ejX6QuT4CUp7_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp7_c_o { 0% {opacity: 1} 25% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 50% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp8_ts {animation: ejX6QuT4CUp8_ts__ts ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp8_ts__ts { 0% {transform: translate(150px,150px) scale(0.2,0.2);animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 16.25% {transform: translate(150px,150px) scale(4,4)} 100% {transform: translate(150px,150px) scale(4,4)}} #ejX6QuT4CUp8 {animation-name: ejX6QuT4CUp8_c_o, ejX6QuT4CUp8_f_p;animation-duration: ${duration}ms;animation-fill-mode: forwards;animation-timing-function: linear;animation-direction: normal;animation-iteration-count: 1;}@keyframes ejX6QuT4CUp8_c_o { 0% {opacity: 0.75} 21.25% {opacity: 0} 100% {opacity: 0}}@keyframes ejX6QuT4CUp8_f_p { 0% {fill: #ffcba0} 11.25% {fill: #fdf900} 20% {fill: #fafafa} 100% {fill: #fafafa}} #ejX6QuT4CUp9_to {animation: ejX6QuT4CUp9_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp9_to__to { 0% {offset-distance: 0%;animation-timing-function: cubic-bezier(0.165,0.84,0.44,1)} 50% {offset-distance: 100%} 100% {offset-distance: 100%}} #ejX6QuT4CUp9 {animation: ejX6QuT4CUp9_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp9_c_o { 0% {opacity: 1} 25% {opacity: 1;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 50% {opacity: 0} 100% {opacity: 0}} #ejX6QuT4CUp10_to {animation: ejX6QuT4CUp10_to__to ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp10_to__to { 0% {offset-distance: 0%;animation-timing-function: cubic-bezier(0.25,0.46,0.45,0.94)} 50% {offset-distance: 100%} 100% {offset-distance: 100%}} #ejX6QuT4CUp10 {animation: ejX6QuT4CUp10_c_o ${duration}ms linear 1 normal forwards}@keyframes ejX6QuT4CUp10_c_o { 0% {opacity: 1} 25% {opacity: 1} 50% {opacity: 0} 100% {opacity: 0}}
20
+ ]]></style>
21
+ <g id="ejX6QuT4CUp2_to" style="offset-path:path('M150,150C151.487307,98.723346,98.424658,83.160356,84.036214,131.511063');offset-rotate:0deg"><g id="ejX6QuT4CUp2_ts" transform="scale(-0.966656,0.966656)"><ellipse id="ejX6QuT4CUp2" rx="4.445235" ry="4.445235" transform="translate(0,0)" fill="none" stroke="#ed0606" stroke-width="2"/></g></g><g id="ejX6QuT4CUp3_to" style="offset-path:path('M150,150C170.853084,85.497808,215.912715,88.678086,240,150');offset-rotate:0deg"><g id="ejX6QuT4CUp3_tr" transform="rotate(0)"><g id="ejX6QuT4CUp3_ts" transform="scale(0.43962,0.43962)"><ellipse id="ejX6QuT4CUp3" rx="10.645289" ry="10.645289" transform="translate(0,0)" fill="none" stroke="#670bf4" stroke-width="6" stroke-dashoffset="280" stroke-dasharray="3"/></g></g></g><g id="ejX6QuT4CUp4_to" style="offset-path:path('M150,150C111.631802,121.393491,76.521788,145.563306,76,198');offset-rotate:0deg"><g id="ejX6QuT4CUp4_tr" transform="rotate(0)"><g id="ejX6QuT4CUp4_ts" transform="scale(0.43962,0.43962)"><ellipse id="ejX6QuT4CUp4" rx="10.645289" ry="10.645289" transform="translate(0,0)" fill="none" stroke="#1f0bf4" stroke-width="6" stroke-miterlimit="13" stroke-dashoffset="45" stroke-dasharray="8"/></g></g></g><g id="ejX6QuT4CUp5_to" style="offset-path:path('M150,150C159.106533,163.173822,180.909148,207.870275,179.358177,213.36311');offset-rotate:0deg"><ellipse id="ejX6QuT4CUp5" rx="30" ry="30" transform="scale(0.155996,0.155996) translate(0,0)" fill="#fff400" stroke-width="0"/></g><g id="ejX6QuT4CUp6_to" transform="translate(150,150)"><ellipse id="ejX6QuT4CUp6" rx="30" ry="30" transform="scale(0.094146,0.094146) translate(0,0)" fill="#fc0" stroke-width="0"/></g><g id="ejX6QuT4CUp7_to" transform="translate(150,150)"><ellipse id="ejX6QuT4CUp7" rx="30" ry="30" transform="scale(0.069628,0.069628) translate(0,0)" fill="#fc0" stroke-width="0"/></g><g id="ejX6QuT4CUp8_ts" transform="translate(150,150) scale(0.2,0.2)"><ellipse id="ejX6QuT4CUp8" style="mix-blend-mode:multiply" rx="7.86004" ry="7.86004" transform="translate(0,0)" opacity="0.75" fill="#ffcba0" stroke-width="0"/></g><g id="ejX6QuT4CUp9_to" style="offset-path:path('M150,150C137.037773,122.096076,120.091659,81.569132,106,74');offset-rotate:0deg"><ellipse id="ejX6QuT4CUp9" rx="30" ry="30" transform="scale(0.069628,0.069628) translate(0,0)" fill="#5800ff" stroke-width="0"/></g><g id="ejX6QuT4CUp10_to" style="offset-path:path('M152,153C128.044643,113.553169,69.737409,121.442089,39.459312,122.665002');offset-rotate:0deg"><ellipse id="ejX6QuT4CUp10" rx="30" ry="30" transform="scale(0.04,0.04) translate(0,0)" fill="#ff2100" stroke-width="0"/></g></svg>`;
22
+ }
23
+ function ensureContainer() {
24
+ if (!container || !container.isConnected) {
25
+ container = document.createElement('div');
26
+ container.popover = 'manual';
27
+ container.style.cssText = `
28
+ background: transparent;
29
+ position: fixed;
30
+ inset: 0;
31
+ pointer-events: none;
32
+ margin: 0;
33
+ padding: 0;
34
+ border: 0;
35
+ overflow: visible;
36
+ `;
37
+ document.body.appendChild(container);
38
+ container.showPopover();
39
+ }
40
+ return container;
41
+ }
42
+ export function btuCelebrate(options) {
43
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
44
+ return;
45
+ const { duration = 2000, size = 300 } = { ...defaults, ...options };
46
+ const host = ensureContainer();
47
+ const { x, y } = resolvePosition(options.position);
48
+ const half = size / 2;
49
+ const instance = document.createElement('div');
50
+ instance.style.cssText = `
51
+ position: fixed;
52
+ left: ${x - half}px;
53
+ top: ${y - half}px;
54
+ width: ${size}px;
55
+ height: ${size}px;
56
+ pointer-events: none;
57
+ `;
58
+ const shadow = instance.attachShadow({ mode: 'closed' });
59
+ shadow.appendChild(getTemplate(duration, size));
60
+ host.appendChild(instance);
61
+ setTimeout(() => {
62
+ instance.remove();
63
+ }, duration);
64
+ }
65
+ btuCelebrate.setDefaults = (newDefaults) => {
66
+ defaults = { ...defaults, ...newDefaults };
67
+ };
68
+ btuCelebrate.listen = () => {
69
+ const handler = (e) => {
70
+ const detail = e.detail;
71
+ if (detail?.position)
72
+ btuCelebrate(detail);
73
+ };
74
+ document.addEventListener(BTU_CELEBRATE_EVENT, handler);
75
+ return () => document.removeEventListener(BTU_CELEBRATE_EVENT, handler);
76
+ };
77
+ // Pre-warm the default template during idle time so the first click is instant
78
+ if (typeof requestIdleCallback === 'function') {
79
+ requestIdleCallback(() => getTemplate(2000, 300));
80
+ }
81
+ //# sourceMappingURL=celebrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"celebrate.js","sourceRoot":"","sources":["../../src/effects/celebrate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAQrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAAsB,CAAA;AAEzD,IAAI,QAAQ,GAAgD,EAAE,CAAA;AAC9D,IAAI,SAAS,GAA0B,IAAI,CAAA;AAE3C,MAAM,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAA;AAE5D,SAAS,WAAW,CAAC,QAAgB,EAAE,IAAY;IACjD,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAA;IACjC,IAAI,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAChC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAA;QACxC,GAAG,CAAC,SAAS,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QACjD,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAqB,CAAA;AACxD,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB,EAAE,IAAY;IACvD,OAAO,uIAAuI,IAAI,aAAa,IAAI;;mDAElH,QAAQ,iQAAiQ,QAAQ,kYAAkY,QAAQ,kPAAkP,QAAQ,+PAA+P,QAAQ,iRAAiR,QAAQ,8MAA8M,QAAQ,kPAAkP,QAAQ,+PAA+P,QAAQ,qRAAqR,QAAQ,iPAAiP,QAAQ,gPAAgP,QAAQ,yPAAyP,QAAQ,kPAAkP,QAAQ,+RAA+R,QAAQ,kPAAkP,QAAQ,+RAA+R,QAAQ,gPAAgP,QAAQ,kXAAkX,QAAQ,0XAA0X,QAAQ,yPAAyP,QAAQ,kPAAkP,QAAQ,8PAA8P,QAAQ;;mkFAEl8G,CAAA;AACnkF,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QACzC,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QACzC,SAAS,CAAC,OAAO,GAAG,QAAQ,CAAA;QAC5B,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;;;;;;;;;KASzB,CAAA;QACD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;QACpC,SAAS,CAAC,WAAW,EAAE,CAAA;IACzB,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAyB;IACpD,IAAI,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC,OAAO;QAAE,OAAM;IAEzE,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAA;IACnE,MAAM,IAAI,GAAG,eAAe,EAAE,CAAA;IAE9B,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAA;IAErB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IAC9C,QAAQ,CAAC,KAAK,CAAC,OAAO,GAAG;;YAEf,CAAC,GAAG,IAAI;WACT,CAAC,GAAG,IAAI;aACN,IAAI;cACH,IAAI;;GAEf,CAAA;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IACxD,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;IAE/C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;IAE1B,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,CAAC,MAAM,EAAE,CAAA;IACnB,CAAC,EAAE,QAAQ,CAAC,CAAA;AACd,CAAC;AAED,YAAY,CAAC,WAAW,GAAG,CAAC,WAAwD,EAAQ,EAAE;IAC5F,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,WAAW,EAAE,CAAA;AAC5C,CAAC,CAAA;AAED,YAAY,CAAC,MAAM,GAAG,GAAiB,EAAE;IACvC,MAAM,OAAO,GAAG,CAAC,CAAQ,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAI,CAAmC,CAAC,MAAM,CAAA;QAC1D,IAAI,MAAM,EAAE,QAAQ;YAAE,YAAY,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC,CAAA;IACD,QAAQ,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAA;IACvD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAA;AACzE,CAAC,CAAA;AAED,+EAA+E;AAC/E,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAAE,CAAC;IAC9C,mBAAmB,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;AACnD,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { EffectPosition } from '../util/position.js';
2
+ export interface RippleOptions {
3
+ position: EffectPosition;
4
+ duration?: number;
5
+ ringWidth?: number;
6
+ feather?: number;
7
+ hueShift?: number;
8
+ contrast?: number;
9
+ saturate?: number;
10
+ hueProperties?: Record<string, number>;
11
+ sparkle?: boolean | {
12
+ size?: number;
13
+ duration?: number;
14
+ };
15
+ }
16
+ export declare const BTU_RIPPLE_EVENT = "btu-effect-ripple";
17
+ export interface RippleResult {
18
+ ready: Promise<void>;
19
+ finished: Promise<void>;
20
+ }
21
+ export declare function btuRipple(options: RippleOptions): RippleResult;
22
+ export declare namespace btuRipple {
23
+ var setDefaults: (newDefaults: Partial<Omit<RippleOptions, "position">>) => void;
24
+ var listen: () => (() => void);
25
+ }
26
+ declare global {
27
+ interface DocumentEventMap {
28
+ 'btu-effect-ripple': CustomEvent<RippleOptions>;
29
+ }
30
+ }
31
+ //# sourceMappingURL=ripple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../src/effects/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAIzD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,OAAO,CAAC,EAAE,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACzD;AAED,eAAO,MAAM,gBAAgB,sBAAsB,CAAA;AA2BnD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CACxB;AAID,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CA+G9D;yBA/Ge,SAAS;mCAiHa,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,KAAG,IAAI;sBAI9D,CAAC,MAAM,IAAI,CAAC;;AASnC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,gBAAgB;QACxB,mBAAmB,EAAE,WAAW,CAAC,aAAa,CAAC,CAAA;KAChD;CACF"}
@@ -0,0 +1,131 @@
1
+ import { resolvePosition } from '../util/position.js';
2
+ import { cleanupSparkle, ensureOverlay, generateSparkleCSS, isSparkleSupported, isWorkletReady } from './sparkle.js';
3
+ export const BTU_RIPPLE_EVENT = 'btu-effect-ripple';
4
+ const DEFAULT_HUE_PROPERTIES = {
5
+ '--btu-theme-primary-hue': 264,
6
+ '--btu-theme-error-hue': 27,
7
+ '--btu-theme-success-hue': 157,
8
+ };
9
+ let defaults = {};
10
+ let restoreTimer;
11
+ let propertyRegistered = false;
12
+ function registerProperty() {
13
+ if (propertyRegistered)
14
+ return;
15
+ try {
16
+ CSS.registerProperty({
17
+ name: '--ripple-r',
18
+ syntax: '<length>',
19
+ inherits: false,
20
+ initialValue: '0px',
21
+ });
22
+ }
23
+ catch {
24
+ // Already registered (e.g. via @property in CSS) or unsupported
25
+ }
26
+ propertyRegistered = true;
27
+ }
28
+ const RESOLVED = { ready: Promise.resolve(), finished: Promise.resolve() };
29
+ export function btuRipple(options) {
30
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
31
+ return RESOLVED;
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ const doc = document;
34
+ if (!doc.startViewTransition)
35
+ return RESOLVED;
36
+ registerProperty();
37
+ const { duration = 1200, ringWidth = 40, feather = 75, hueShift = 0, contrast = 1.8, saturate = 1.5, hueProperties = DEFAULT_HUE_PROPERTIES, } = { ...defaults, ...options };
38
+ const isDark = document.documentElement.classList.contains('dark') || window.matchMedia('(prefers-color-scheme: dark)').matches;
39
+ const effectiveContrast = isDark ? Math.min(contrast, 1.3) : contrast;
40
+ const effectiveBrightness = isDark ? 1.4 : 1;
41
+ if (restoreTimer)
42
+ clearTimeout(restoreTimer);
43
+ const { x, y } = resolvePosition(options.position);
44
+ const maxRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
45
+ const halfBand = ringWidth / 2;
46
+ const endRadius = maxRadius + feather + halfBand;
47
+ const root = document.documentElement;
48
+ const useSparkle = !!options.sparkle && isSparkleSupported() && isWorkletReady();
49
+ const sparkleOpts = typeof options.sparkle === 'object' ? options.sparkle : {};
50
+ const sparkleSize = sparkleOpts.size ?? 300;
51
+ const sparkleDuration = sparkleOpts.duration ?? duration;
52
+ if (useSparkle) {
53
+ ensureOverlay();
54
+ }
55
+ root.style.setProperty('view-transition-name', 'root');
56
+ const style = document.createElement('style');
57
+ let css = `
58
+ ::view-transition-old(root) {
59
+ animation: none;
60
+ }
61
+ ::view-transition-new(root) {
62
+ mix-blend-mode: normal;
63
+ filter: contrast(${effectiveContrast}) saturate(${saturate}) brightness(${effectiveBrightness});
64
+ animation: btu-ripple-ring ${duration}ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
65
+ mask-image: radial-gradient(
66
+ circle at ${x}px ${y}px,
67
+ transparent 0,
68
+ transparent calc(var(--ripple-r) - ${feather + halfBand}px),
69
+ black calc(var(--ripple-r) - ${halfBand}px),
70
+ black calc(var(--ripple-r) + ${halfBand}px),
71
+ transparent calc(var(--ripple-r) + ${feather + halfBand}px)
72
+ );
73
+ -webkit-mask-image: radial-gradient(
74
+ circle at ${x}px ${y}px,
75
+ transparent 0,
76
+ transparent calc(var(--ripple-r) - ${feather + halfBand}px),
77
+ black calc(var(--ripple-r) - ${halfBand}px),
78
+ black calc(var(--ripple-r) + ${halfBand}px),
79
+ transparent calc(var(--ripple-r) + ${feather + halfBand}px)
80
+ );
81
+ }
82
+ @keyframes btu-ripple-ring {
83
+ from { --ripple-r: 0px; }
84
+ to { --ripple-r: ${endRadius}px; }
85
+ }
86
+ `;
87
+ if (useSparkle) {
88
+ css += generateSparkleCSS(x, y, sparkleSize, sparkleDuration);
89
+ }
90
+ style.textContent = css;
91
+ document.head.appendChild(style);
92
+ const transition = doc.startViewTransition(() => {
93
+ for (const [prop, base] of Object.entries(hueProperties)) {
94
+ root.style.setProperty(prop, `${base + hueShift}`);
95
+ }
96
+ });
97
+ const restoreHues = () => {
98
+ for (const prop of Object.keys(hueProperties)) {
99
+ root.style.removeProperty(prop);
100
+ }
101
+ };
102
+ const cleanup = () => {
103
+ if (restoreTimer)
104
+ clearTimeout(restoreTimer);
105
+ restoreHues();
106
+ style.remove();
107
+ root.style.removeProperty('view-transition-name');
108
+ if (useSparkle)
109
+ cleanupSparkle();
110
+ };
111
+ const ready = transition.ready
112
+ .then(() => {
113
+ restoreTimer = setTimeout(restoreHues, Math.max(0, duration - 100));
114
+ })
115
+ .catch(() => { });
116
+ const finished = transition.finished.then(cleanup).catch(cleanup);
117
+ return { ready, finished };
118
+ }
119
+ btuRipple.setDefaults = (newDefaults) => {
120
+ defaults = { ...defaults, ...newDefaults };
121
+ };
122
+ btuRipple.listen = () => {
123
+ const handler = (e) => {
124
+ const detail = e.detail;
125
+ if (detail?.position)
126
+ btuRipple(detail);
127
+ };
128
+ document.addEventListener(BTU_RIPPLE_EVENT, handler);
129
+ return () => document.removeEventListener(BTU_RIPPLE_EVENT, handler);
130
+ };
131
+ //# sourceMappingURL=ripple.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../src/effects/ripple.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * CSS Paint Worklet source for the sparkle effect.
3
+ * Faithfully reproduces the 9 particles from the celebrate SVG animation.
4
+ * Exported as a string — loaded via blob URL at runtime.
5
+ */
6
+ export declare const SPARKLE_WORKLET_SOURCE = "\n// Cubic bezier easing (no closure allocation for hot-path performance)\nfunction ease(x1, y1, x2, y2, t) {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n var lo = 0, hi = 1, s, u;\n for (var i = 0; i < 16; i++) {\n s = (lo + hi) * 0.5;\n u = 1 - s;\n if (3 * s * u * (u * x1 + s * x2) + s * s * s < t) lo = s; else hi = s;\n }\n s = (lo + hi) * 0.5;\n u = 1 - s;\n return 3 * s * u * (u * y1 + s * y2) + s * s * s;\n}\n\n// Evaluate cubic bezier path at parameter t in [0,1]\nfunction bp(p, t) {\n var u = 1 - t, uu = u * u, tt = t * t;\n return [\n uu * u * p[0][0] + 3 * uu * t * p[1][0] + 3 * u * tt * p[2][0] + tt * t * p[3][0],\n uu * u * p[0][1] + 3 * uu * t * p[1][1] + 3 * u * tt * p[2][1] + tt * t * p[3][1]\n ];\n}\n\n// Keyframe interpolation with per-segment easing\n// Frame format: [time, value] or [time, value, bezX1, bezY1, bezX2, bezY2]\n// Easing on a keyframe affects transition FROM that keyframe to the next\nfunction kf(f, t) {\n var n = f.length;\n if (t <= f[0][0]) return f[0][1];\n if (t >= f[n - 1][0]) return f[n - 1][1];\n for (var i = 0; i < n - 1; i++) {\n if (t < f[i + 1][0]) {\n var k = f[i];\n var st = (t - k[0]) / (f[i + 1][0] - k[0]);\n if (k.length > 2) st = ease(k[2], k[3], k[4], k[5], st);\n return k[1] + (f[i + 1][1] - k[1]) * st;\n }\n }\n return f[n - 1][1];\n}\n\n// Parse hex color to [r, g, b]\nfunction hr(h) {\n return [parseInt(h.slice(1, 3), 16), parseInt(h.slice(3, 5), 16), parseInt(h.slice(5, 7), 16)];\n}\n\n// Color keyframe interpolation: [[time, hexColor], ...]\nfunction ckf(f, t) {\n var n = f.length;\n if (t <= f[0][0]) return f[0][1];\n if (t >= f[n - 1][0]) return f[n - 1][1];\n for (var i = 0; i < n - 1; i++) {\n if (t < f[i + 1][0]) {\n var st = (t - f[i][0]) / (f[i + 1][0] - f[i][0]);\n var a = hr(f[i][1]), b = hr(f[i + 1][1]);\n return 'rgb(' + (a[0] + (b[0] - a[0]) * st + 0.5 | 0) + ','\n + (a[1] + (b[1] - a[1]) * st + 0.5 | 0) + ','\n + (a[2] + (b[2] - a[2]) * st + 0.5 | 0) + ')';\n }\n }\n return f[n - 1][1];\n}\n\n// 9 particles from the celebrate SVG animation\n// All coordinates relative to center (0,0) in 300x300 viewBox space\n// t: 0=fill, 1=stroke | p: bezier path | pe: path end fraction\n// pz: path easing | r: radius | sw: strokeWidth | d: dashArray | df: dashOffset\n// sk: scale keyframes | ok: opacity keyframes | rot: rotation | ck: color keyframes\nvar P = [\n // 0: red stroked circle \u2014 arcs up-left\n {t:1, c:'#ed0606',\n p:[[0,0],[1.487,-51.277],[-51.575,-66.84],[-65.964,-18.489]],\n pe:0.375, pz:[0.165,0.84,0.44,1], r:4.445, sw:2,\n sk:[[0,0.967,0,0,0.58,1],[0.25,2.193,0,0,0.58,1],[0.375,1.552]],\n ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.375,0]]},\n\n // 1: purple stroked dashed \u2014 arcs up-right with 306deg rotation\n {t:1, c:'#670bf4',\n p:[[0,0],[20.853,-64.502],[65.913,-61.322],[90,0]],\n pe:0.5, pz:[0.165,0.84,0.44,1], r:10.645, sw:6, d:[3,3], df:280,\n sk:[[0,0.44],[0.375,1]],\n ok:[[0,1],[0.375,1,0.25,0.46,0.45,0.94],[0.5,0]],\n rot:{dg:305.83, e:0.5, z:[0.165,0.84,0.44,1]}},\n\n // 2: blue stroked dashed \u2014 arcs down-left with -414deg rotation\n {t:1, c:'#1f0bf4',\n p:[[0,0],[-38.368,-28.607],[-73.478,-4.437],[-74,48]],\n pe:0.5, pz:[0.165,0.84,0.44,1], r:10.645, sw:6, d:[8,8], df:45,\n sk:[[0,0.44],[0.3625,0.75],[0.5,1]],\n ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.5,0]],\n rot:{dg:-414.17, e:0.5, z:[0.165,0.84,0.44,1]}},\n\n // 3: yellow filled dot \u2014 drifts down-right\n {t:0, c:'#fff400',\n p:[[0,0],[9.107,13.174],[30.909,57.87],[29.358,63.363]],\n pe:0.5, pz:[0.165,0.84,0.44,1], r:4.68,\n sk:[[0,1]],\n ok:[[0,1],[0.375,1,0.25,0.46,0.45,0.94],[0.5,0]]},\n\n // 4: gold dot \u2014 quick burst to the right\n {t:0, c:'#ffcc00',\n p:[[0,0],[16.67,6.67],[33.33,13.33],[50,20]],\n pe:0.25, pz:[0.165,0.84,0.44,1], r:2.82,\n sk:[[0,1]],\n ok:[[0,1],[0.125,1,0.25,0.46,0.45,0.94],[0.25,0]]},\n\n // 5: gold dot \u2014 drifts up-right\n {t:0, c:'#ffcc00',\n p:[[0,0],[20,-16.67],[40,-33.33],[60,-50]],\n pe:0.5, pz:[0.165,0.84,0.44,1], r:2.09,\n sk:[[0,1]],\n ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.5,0]]},\n\n // 6: center flash \u2014 expanding warm glow that shifts to white\n {t:0, c:'#ffcba0',\n p:[[0,0],[0,0],[0,0],[0,0]],\n pe:1, pz:[0,0,1,1], r:7.86,\n sk:[[0,0.2,0.165,0.84,0.44,1],[0.1625,4]],\n ok:[[0,0.75],[0.2125,0]],\n ck:[[0,'#ffcba0'],[0.1125,'#fdf900'],[0.2,'#fafafa']]},\n\n // 7: violet dot \u2014 shoots up-left\n {t:0, c:'#5800ff',\n p:[[0,0],[-12.962,-27.904],[-29.908,-68.431],[-44,-76]],\n pe:0.5, pz:[0.165,0.84,0.44,1], r:2.09,\n sk:[[0,1]],\n ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.5,0]]},\n\n // 8: red dot \u2014 sweeps far left\n {t:0, c:'#ff2100',\n p:[[2,3],[-21.955,-36.447],[-80.263,-28.558],[-110.541,-27.335]],\n pe:0.5, pz:[0.25,0.46,0.45,0.94], r:1.2,\n sk:[[0,1]],\n ok:[[0,1],[0.25,1],[0.5,0]]}\n];\n\nclass BtuSparkle {\n static get inputProperties() {\n return ['--sparkle-progress', '--sparkle-cx', '--sparkle-cy', '--sparkle-size'];\n }\n\n paint(ctx, geom, props) {\n var progress = parseFloat(String(props.get('--sparkle-progress'))) || 0;\n if (progress <= 0) return;\n\n var cx = parseFloat(String(props.get('--sparkle-cx'))) || 0;\n var cy = parseFloat(String(props.get('--sparkle-cy'))) || 0;\n var size = parseFloat(String(props.get('--sparkle-size'))) || 300;\n var sc = size / 300;\n\n for (var i = 0; i < P.length; i++) {\n var p = P[i];\n\n // Skip invisible particles\n var alpha = kf(p.ok, progress);\n if (alpha <= 0.01) continue;\n\n // Position along bezier path\n var pt = p.pe < 1 ? Math.min(progress / p.pe, 1) : progress;\n var et = ease(p.pz[0], p.pz[1], p.pz[2], p.pz[3], pt);\n var pos = bp(p.p, et);\n\n // Per-particle scale\n var s = kf(p.sk, progress);\n if (s <= 0) continue;\n\n ctx.save();\n ctx.translate(cx + pos[0] * sc, cy + pos[1] * sc);\n\n // Rotation (particles 1 and 2)\n if (p.rot) {\n var rt = Math.min(progress / p.rot.e, 1);\n var er = ease(p.rot.z[0], p.rot.z[1], p.rot.z[2], p.rot.z[3], rt);\n ctx.rotate(p.rot.dg * er * Math.PI / 180);\n }\n\n ctx.scale(s * sc, s * sc);\n ctx.globalAlpha = alpha;\n ctx.beginPath();\n ctx.arc(0, 0, p.r, 0, 6.2832);\n\n if (p.t) {\n // Stroked circle\n ctx.strokeStyle = p.c;\n ctx.lineWidth = p.sw;\n if (p.d) {\n ctx.setLineDash(p.d);\n ctx.lineDashOffset = p.df || 0;\n }\n ctx.stroke();\n } else {\n // Filled circle (with optional color animation)\n ctx.fillStyle = p.ck ? ckf(p.ck, progress) : p.c;\n ctx.fill();\n }\n\n ctx.restore();\n }\n }\n}\n\nregisterPaint('btu-sparkle', BtuSparkle);\n";
7
+ //# sourceMappingURL=sparkle-worklet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkle-worklet.d.ts","sourceRoot":"","sources":["../../src/effects/sparkle-worklet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,ozNA4MlC,CAAA"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * CSS Paint Worklet source for the sparkle effect.
3
+ * Faithfully reproduces the 9 particles from the celebrate SVG animation.
4
+ * Exported as a string — loaded via blob URL at runtime.
5
+ */
6
+ export const SPARKLE_WORKLET_SOURCE = `
7
+ // Cubic bezier easing (no closure allocation for hot-path performance)
8
+ function ease(x1, y1, x2, y2, t) {
9
+ if (t <= 0) return 0;
10
+ if (t >= 1) return 1;
11
+ var lo = 0, hi = 1, s, u;
12
+ for (var i = 0; i < 16; i++) {
13
+ s = (lo + hi) * 0.5;
14
+ u = 1 - s;
15
+ if (3 * s * u * (u * x1 + s * x2) + s * s * s < t) lo = s; else hi = s;
16
+ }
17
+ s = (lo + hi) * 0.5;
18
+ u = 1 - s;
19
+ return 3 * s * u * (u * y1 + s * y2) + s * s * s;
20
+ }
21
+
22
+ // Evaluate cubic bezier path at parameter t in [0,1]
23
+ function bp(p, t) {
24
+ var u = 1 - t, uu = u * u, tt = t * t;
25
+ return [
26
+ uu * u * p[0][0] + 3 * uu * t * p[1][0] + 3 * u * tt * p[2][0] + tt * t * p[3][0],
27
+ uu * u * p[0][1] + 3 * uu * t * p[1][1] + 3 * u * tt * p[2][1] + tt * t * p[3][1]
28
+ ];
29
+ }
30
+
31
+ // Keyframe interpolation with per-segment easing
32
+ // Frame format: [time, value] or [time, value, bezX1, bezY1, bezX2, bezY2]
33
+ // Easing on a keyframe affects transition FROM that keyframe to the next
34
+ function kf(f, t) {
35
+ var n = f.length;
36
+ if (t <= f[0][0]) return f[0][1];
37
+ if (t >= f[n - 1][0]) return f[n - 1][1];
38
+ for (var i = 0; i < n - 1; i++) {
39
+ if (t < f[i + 1][0]) {
40
+ var k = f[i];
41
+ var st = (t - k[0]) / (f[i + 1][0] - k[0]);
42
+ if (k.length > 2) st = ease(k[2], k[3], k[4], k[5], st);
43
+ return k[1] + (f[i + 1][1] - k[1]) * st;
44
+ }
45
+ }
46
+ return f[n - 1][1];
47
+ }
48
+
49
+ // Parse hex color to [r, g, b]
50
+ function hr(h) {
51
+ return [parseInt(h.slice(1, 3), 16), parseInt(h.slice(3, 5), 16), parseInt(h.slice(5, 7), 16)];
52
+ }
53
+
54
+ // Color keyframe interpolation: [[time, hexColor], ...]
55
+ function ckf(f, t) {
56
+ var n = f.length;
57
+ if (t <= f[0][0]) return f[0][1];
58
+ if (t >= f[n - 1][0]) return f[n - 1][1];
59
+ for (var i = 0; i < n - 1; i++) {
60
+ if (t < f[i + 1][0]) {
61
+ var st = (t - f[i][0]) / (f[i + 1][0] - f[i][0]);
62
+ var a = hr(f[i][1]), b = hr(f[i + 1][1]);
63
+ return 'rgb(' + (a[0] + (b[0] - a[0]) * st + 0.5 | 0) + ','
64
+ + (a[1] + (b[1] - a[1]) * st + 0.5 | 0) + ','
65
+ + (a[2] + (b[2] - a[2]) * st + 0.5 | 0) + ')';
66
+ }
67
+ }
68
+ return f[n - 1][1];
69
+ }
70
+
71
+ // 9 particles from the celebrate SVG animation
72
+ // All coordinates relative to center (0,0) in 300x300 viewBox space
73
+ // t: 0=fill, 1=stroke | p: bezier path | pe: path end fraction
74
+ // pz: path easing | r: radius | sw: strokeWidth | d: dashArray | df: dashOffset
75
+ // sk: scale keyframes | ok: opacity keyframes | rot: rotation | ck: color keyframes
76
+ var P = [
77
+ // 0: red stroked circle — arcs up-left
78
+ {t:1, c:'#ed0606',
79
+ p:[[0,0],[1.487,-51.277],[-51.575,-66.84],[-65.964,-18.489]],
80
+ pe:0.375, pz:[0.165,0.84,0.44,1], r:4.445, sw:2,
81
+ sk:[[0,0.967,0,0,0.58,1],[0.25,2.193,0,0,0.58,1],[0.375,1.552]],
82
+ ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.375,0]]},
83
+
84
+ // 1: purple stroked dashed — arcs up-right with 306deg rotation
85
+ {t:1, c:'#670bf4',
86
+ p:[[0,0],[20.853,-64.502],[65.913,-61.322],[90,0]],
87
+ pe:0.5, pz:[0.165,0.84,0.44,1], r:10.645, sw:6, d:[3,3], df:280,
88
+ sk:[[0,0.44],[0.375,1]],
89
+ ok:[[0,1],[0.375,1,0.25,0.46,0.45,0.94],[0.5,0]],
90
+ rot:{dg:305.83, e:0.5, z:[0.165,0.84,0.44,1]}},
91
+
92
+ // 2: blue stroked dashed — arcs down-left with -414deg rotation
93
+ {t:1, c:'#1f0bf4',
94
+ p:[[0,0],[-38.368,-28.607],[-73.478,-4.437],[-74,48]],
95
+ pe:0.5, pz:[0.165,0.84,0.44,1], r:10.645, sw:6, d:[8,8], df:45,
96
+ sk:[[0,0.44],[0.3625,0.75],[0.5,1]],
97
+ ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.5,0]],
98
+ rot:{dg:-414.17, e:0.5, z:[0.165,0.84,0.44,1]}},
99
+
100
+ // 3: yellow filled dot — drifts down-right
101
+ {t:0, c:'#fff400',
102
+ p:[[0,0],[9.107,13.174],[30.909,57.87],[29.358,63.363]],
103
+ pe:0.5, pz:[0.165,0.84,0.44,1], r:4.68,
104
+ sk:[[0,1]],
105
+ ok:[[0,1],[0.375,1,0.25,0.46,0.45,0.94],[0.5,0]]},
106
+
107
+ // 4: gold dot — quick burst to the right
108
+ {t:0, c:'#ffcc00',
109
+ p:[[0,0],[16.67,6.67],[33.33,13.33],[50,20]],
110
+ pe:0.25, pz:[0.165,0.84,0.44,1], r:2.82,
111
+ sk:[[0,1]],
112
+ ok:[[0,1],[0.125,1,0.25,0.46,0.45,0.94],[0.25,0]]},
113
+
114
+ // 5: gold dot — drifts up-right
115
+ {t:0, c:'#ffcc00',
116
+ p:[[0,0],[20,-16.67],[40,-33.33],[60,-50]],
117
+ pe:0.5, pz:[0.165,0.84,0.44,1], r:2.09,
118
+ sk:[[0,1]],
119
+ ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.5,0]]},
120
+
121
+ // 6: center flash — expanding warm glow that shifts to white
122
+ {t:0, c:'#ffcba0',
123
+ p:[[0,0],[0,0],[0,0],[0,0]],
124
+ pe:1, pz:[0,0,1,1], r:7.86,
125
+ sk:[[0,0.2,0.165,0.84,0.44,1],[0.1625,4]],
126
+ ok:[[0,0.75],[0.2125,0]],
127
+ ck:[[0,'#ffcba0'],[0.1125,'#fdf900'],[0.2,'#fafafa']]},
128
+
129
+ // 7: violet dot — shoots up-left
130
+ {t:0, c:'#5800ff',
131
+ p:[[0,0],[-12.962,-27.904],[-29.908,-68.431],[-44,-76]],
132
+ pe:0.5, pz:[0.165,0.84,0.44,1], r:2.09,
133
+ sk:[[0,1]],
134
+ ok:[[0,1],[0.25,1,0.25,0.46,0.45,0.94],[0.5,0]]},
135
+
136
+ // 8: red dot — sweeps far left
137
+ {t:0, c:'#ff2100',
138
+ p:[[2,3],[-21.955,-36.447],[-80.263,-28.558],[-110.541,-27.335]],
139
+ pe:0.5, pz:[0.25,0.46,0.45,0.94], r:1.2,
140
+ sk:[[0,1]],
141
+ ok:[[0,1],[0.25,1],[0.5,0]]}
142
+ ];
143
+
144
+ class BtuSparkle {
145
+ static get inputProperties() {
146
+ return ['--sparkle-progress', '--sparkle-cx', '--sparkle-cy', '--sparkle-size'];
147
+ }
148
+
149
+ paint(ctx, geom, props) {
150
+ var progress = parseFloat(String(props.get('--sparkle-progress'))) || 0;
151
+ if (progress <= 0) return;
152
+
153
+ var cx = parseFloat(String(props.get('--sparkle-cx'))) || 0;
154
+ var cy = parseFloat(String(props.get('--sparkle-cy'))) || 0;
155
+ var size = parseFloat(String(props.get('--sparkle-size'))) || 300;
156
+ var sc = size / 300;
157
+
158
+ for (var i = 0; i < P.length; i++) {
159
+ var p = P[i];
160
+
161
+ // Skip invisible particles
162
+ var alpha = kf(p.ok, progress);
163
+ if (alpha <= 0.01) continue;
164
+
165
+ // Position along bezier path
166
+ var pt = p.pe < 1 ? Math.min(progress / p.pe, 1) : progress;
167
+ var et = ease(p.pz[0], p.pz[1], p.pz[2], p.pz[3], pt);
168
+ var pos = bp(p.p, et);
169
+
170
+ // Per-particle scale
171
+ var s = kf(p.sk, progress);
172
+ if (s <= 0) continue;
173
+
174
+ ctx.save();
175
+ ctx.translate(cx + pos[0] * sc, cy + pos[1] * sc);
176
+
177
+ // Rotation (particles 1 and 2)
178
+ if (p.rot) {
179
+ var rt = Math.min(progress / p.rot.e, 1);
180
+ var er = ease(p.rot.z[0], p.rot.z[1], p.rot.z[2], p.rot.z[3], rt);
181
+ ctx.rotate(p.rot.dg * er * Math.PI / 180);
182
+ }
183
+
184
+ ctx.scale(s * sc, s * sc);
185
+ ctx.globalAlpha = alpha;
186
+ ctx.beginPath();
187
+ ctx.arc(0, 0, p.r, 0, 6.2832);
188
+
189
+ if (p.t) {
190
+ // Stroked circle
191
+ ctx.strokeStyle = p.c;
192
+ ctx.lineWidth = p.sw;
193
+ if (p.d) {
194
+ ctx.setLineDash(p.d);
195
+ ctx.lineDashOffset = p.df || 0;
196
+ }
197
+ ctx.stroke();
198
+ } else {
199
+ // Filled circle (with optional color animation)
200
+ ctx.fillStyle = p.ck ? ckf(p.ck, progress) : p.c;
201
+ ctx.fill();
202
+ }
203
+
204
+ ctx.restore();
205
+ }
206
+ }
207
+ }
208
+
209
+ registerPaint('btu-sparkle', BtuSparkle);
210
+ `;
211
+ //# sourceMappingURL=sparkle-worklet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkle-worklet.js","sourceRoot":"","sources":["../../src/effects/sparkle-worklet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4MrC,CAAA"}
@@ -0,0 +1,6 @@
1
+ export declare function ensureOverlay(): void;
2
+ export declare function generateSparkleCSS(x: number, y: number, size: number, duration: number): string;
3
+ export declare function cleanupSparkle(): void;
4
+ export declare function isSparkleSupported(): boolean;
5
+ export declare function isWorkletReady(): boolean;
6
+ //# sourceMappingURL=sparkle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkle.d.ts","sourceRoot":"","sources":["../../src/effects/sparkle.ts"],"names":[],"mappings":"AAoDA,wBAAgB,aAAa,IAAI,IAAI,CAOpC;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB/F;AAED,wBAAgB,cAAc,IAAI,IAAI,CAIrC;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAG5C;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC"}
@@ -0,0 +1,91 @@
1
+ import { SPARKLE_WORKLET_SOURCE } from './sparkle-worklet.js';
2
+ let workletReady = false;
3
+ let workletLoading = null;
4
+ let propertiesRegistered = false;
5
+ let overlay = null;
6
+ function registerProperties() {
7
+ if (propertiesRegistered)
8
+ return;
9
+ propertiesRegistered = true;
10
+ const defs = [
11
+ ['--sparkle-progress', '<number>', '0'],
12
+ ['--sparkle-cx', '<number>', '0'],
13
+ ['--sparkle-cy', '<number>', '0'],
14
+ ['--sparkle-size', '<number>', '300'],
15
+ ];
16
+ for (const [name, syntax, initialValue] of defs) {
17
+ try {
18
+ CSS.registerProperty({ name, syntax, inherits: false, initialValue });
19
+ }
20
+ catch {
21
+ // Already registered or unsupported
22
+ }
23
+ }
24
+ }
25
+ function loadWorklet() {
26
+ if (workletReady)
27
+ return Promise.resolve();
28
+ if (workletLoading)
29
+ return workletLoading;
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ const paintWorklet = CSS.paintWorklet;
32
+ if (!paintWorklet)
33
+ return Promise.resolve();
34
+ const blob = new Blob([SPARKLE_WORKLET_SOURCE], { type: 'text/javascript' });
35
+ const url = URL.createObjectURL(blob);
36
+ const promise = paintWorklet
37
+ .addModule(url)
38
+ .then(() => {
39
+ workletReady = true;
40
+ })
41
+ .catch(() => { })
42
+ .finally(() => {
43
+ URL.revokeObjectURL(url);
44
+ });
45
+ workletLoading = promise;
46
+ return promise;
47
+ }
48
+ export function ensureOverlay() {
49
+ if (!overlay) {
50
+ overlay = document.createElement('div');
51
+ overlay.style.cssText = 'position:fixed;inset:0;pointer-events:none;background:transparent;z-index:2147483647;';
52
+ document.body.appendChild(overlay);
53
+ }
54
+ overlay.style.viewTransitionName = 'sparkle-overlay';
55
+ }
56
+ export function generateSparkleCSS(x, y, size, duration) {
57
+ return `
58
+ ::view-transition-group(sparkle-overlay) {
59
+ z-index: 2147483647;
60
+ background-image: paint(btu-sparkle);
61
+ animation: btu-sparkle-anim ${duration}ms linear forwards;
62
+ --sparkle-cx: ${x};
63
+ --sparkle-cy: ${y};
64
+ --sparkle-size: ${size};
65
+ --sparkle-progress: 0;
66
+ }
67
+ ::view-transition-image-pair(sparkle-overlay) {
68
+ display: none;
69
+ }
70
+ @keyframes btu-sparkle-anim {
71
+ from { --sparkle-progress: 0; }
72
+ to { --sparkle-progress: 1; }
73
+ }
74
+ `;
75
+ }
76
+ export function cleanupSparkle() {
77
+ if (overlay) {
78
+ overlay.style.viewTransitionName = '';
79
+ }
80
+ }
81
+ export function isSparkleSupported() {
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ return !!CSS.paintWorklet;
84
+ }
85
+ export function isWorkletReady() {
86
+ return workletReady;
87
+ }
88
+ // Pre-load worklet and register properties at import time
89
+ registerProperties();
90
+ loadWorklet();
91
+ //# sourceMappingURL=sparkle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkle.js","sourceRoot":"","sources":["../../src/effects/sparkle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,IAAI,YAAY,GAAG,KAAK,CAAA;AACxB,IAAI,cAAc,GAAyB,IAAI,CAAA;AAC/C,IAAI,oBAAoB,GAAG,KAAK,CAAA;AAChC,IAAI,OAAO,GAA0B,IAAI,CAAA;AAEzC,SAAS,kBAAkB;IACzB,IAAI,oBAAoB;QAAE,OAAM;IAChC,oBAAoB,GAAG,IAAI,CAAA;IAE3B,MAAM,IAAI,GAA+B;QACvC,CAAC,oBAAoB,EAAE,UAAU,EAAE,GAAG,CAAC;QACvC,CAAC,cAAc,EAAE,UAAU,EAAE,GAAG,CAAC;QACjC,CAAC,cAAc,EAAE,UAAU,EAAE,GAAG,CAAC;QACjC,CAAC,gBAAgB,EAAE,UAAU,EAAE,KAAK,CAAC;KACtC,CAAA;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAA;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,WAAW;IAClB,IAAI,YAAY;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1C,IAAI,cAAc;QAAE,OAAO,cAAc,CAAA;IAEzC,8DAA8D;IAC9D,MAAM,YAAY,GAAI,GAAW,CAAC,YAAY,CAAA;IAC9C,IAAI,CAAC,YAAY;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAE3C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,sBAAsB,CAAC,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAA;IAC5E,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAErC,MAAM,OAAO,GAAkB,YAAY;SACxC,SAAS,CAAC,GAAG,CAAC;SACd,IAAI,CAAC,GAAG,EAAE;QACT,YAAY,GAAG,IAAI,CAAA;IACrB,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;SACf,OAAO,CAAC,GAAG,EAAE;QACZ,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEJ,cAAc,GAAG,OAAO,CAAA;IACxB,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QACvC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,uFAAuF,CAAA;QAC/G,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACpC,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,iBAAiB,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,CAAS,EAAE,CAAS,EAAE,IAAY,EAAE,QAAgB;IACrF,OAAO;;;;oCAI2B,QAAQ;sBACtB,CAAC;sBACD,CAAC;wBACC,IAAI;;;;;;;;;;GAUzB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAA;IACvC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,8DAA8D;IAC9D,OAAO,CAAC,CAAE,GAAW,CAAC,YAAY,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,0DAA0D;AAC1D,kBAAkB,EAAE,CAAA;AACpB,WAAW,EAAE,CAAA"}