Merge branch 'main' into feat/picture-component

This commit is contained in:
Erika 2023-09-22 12:06:17 +02:00 committed by GitHub
commit 3809a452ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
170 changed files with 819 additions and 1314 deletions

View file

@ -1,20 +0,0 @@
---
'@astrojs/cloudflare': minor
---
Add support for the following Node.js Runtime APIs, which are availabe in [Cloudflare](https://developers.cloudflare.com/workers/runtime-apis/nodejs) using the `node:` syntax.
- assert
- AsyncLocalStorage
- Buffer
- Diagnostics Channel
- EventEmitter
- path
- process
- Streams
- StringDecoder
- util
```js
import { Buffer } from 'node:buffer';
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

@ -1,11 +1 @@
<svg width="240" height="40" viewBox="0 0 240 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M31 40L27 29.4L23 40H21L26 26.8L22 16.3L13 40H11L21 13.6L16.5 1.8L2 40H0L15.2 0H17.8L22 11L26.2 0H28.8L32.5 9.7L36.2 0H38.8L43 11L47.2 0H49.8L65 40H63L48.5 1.8L44 13.6L54 40H52L43 16.3L39 26.8L44 40H42L38 29.4L34 40H31ZM32.5 15L28 26.7L32.5 38.6L37 26.8L32.5 15ZM27.5 1.8L23 13.6L27 24.2L31.5 12.3L27.5 1.8ZM37.5 1.8L33.5 12.3L38 24.2L42 13.6L37.5 1.8Z" fill="#FFFFFF"/>
<path d="M97.7259 17.956V29H100.432V13.6H97.5499L92.8639 20.882L88.1779 13.6H85.2959V29H87.9579V18L92.7759 25.216H92.8639L97.7259 17.956Z" fill="#FFFFFF"/>
<path d="M121.687 21.278C121.687 20.1927 121.489 19.166 121.093 18.198C120.697 17.23 120.147 16.3867 119.443 15.668C118.739 14.9493 117.896 14.3847 116.913 13.974C115.931 13.5487 114.845 13.336 113.657 13.336C112.469 13.336 111.384 13.5487 110.401 13.974C109.419 14.3993 108.568 14.9787 107.849 15.712C107.131 16.4307 106.573 17.274 106.177 18.242C105.781 19.21 105.583 20.2367 105.583 21.322C105.583 22.4073 105.781 23.434 106.177 24.402C106.573 25.37 107.123 26.2133 107.827 26.932C108.531 27.6507 109.375 28.2227 110.357 28.648C111.34 29.0587 112.425 29.264 113.613 29.264C114.801 29.264 115.887 29.0513 116.869 28.626C117.852 28.2007 118.703 27.6287 119.421 26.91C120.14 26.1767 120.697 25.326 121.093 24.358C121.489 23.39 121.687 22.3633 121.687 21.278ZM118.849 21.322C118.849 22.07 118.717 22.7813 118.453 23.456C118.204 24.116 117.852 24.6953 117.397 25.194C116.943 25.678 116.393 26.0667 115.747 26.36C115.117 26.6387 114.42 26.778 113.657 26.778C112.895 26.778 112.191 26.6313 111.545 26.338C110.9 26.0447 110.343 25.6487 109.873 25.15C109.419 24.6513 109.059 24.072 108.795 23.412C108.546 22.7373 108.421 22.026 108.421 21.278C108.421 20.53 108.546 19.826 108.795 19.166C109.059 18.4913 109.419 17.912 109.873 17.428C110.328 16.9293 110.871 16.5407 111.501 16.262C112.147 15.9687 112.851 15.822 113.613 15.822C114.376 15.822 115.08 15.9687 115.725 16.262C116.371 16.5553 116.921 16.9513 117.375 17.45C117.845 17.9487 118.204 18.5353 118.453 19.21C118.717 19.87 118.849 20.574 118.849 21.322Z" fill="#FFFFFF"/>
<path d="M137.585 24.248L129.335 13.6H126.827V29H129.489V18.044L137.981 29H140.247V13.6H137.585V24.248Z" fill="#FFFFFF"/>
<path d="M161.5 21.278C161.5 20.1927 161.302 19.166 160.906 18.198C160.51 17.23 159.96 16.3867 159.256 15.668C158.552 14.9493 157.708 14.3847 156.726 13.974C155.743 13.5487 154.658 13.336 153.47 13.336C152.282 13.336 151.196 13.5487 150.214 13.974C149.231 14.3993 148.38 14.9787 147.662 15.712C146.943 16.4307 146.386 17.274 145.99 18.242C145.594 19.21 145.396 20.2367 145.396 21.322C145.396 22.4073 145.594 23.434 145.99 24.402C146.386 25.37 146.936 26.2133 147.64 26.932C148.344 27.6507 149.187 28.2227 150.17 28.648C151.152 29.0587 152.238 29.264 153.426 29.264C154.614 29.264 155.699 29.0513 156.682 28.626C157.664 28.2007 158.515 27.6287 159.234 26.91C159.952 26.1767 160.51 25.326 160.906 24.358C161.302 23.39 161.5 22.3633 161.5 21.278ZM158.662 21.322C158.662 22.07 158.53 22.7813 158.266 23.456C158.016 24.116 157.664 24.6953 157.21 25.194C156.755 25.678 156.205 26.0667 155.56 26.36C154.929 26.6387 154.232 26.778 153.47 26.778C152.707 26.778 152.003 26.6313 151.358 26.338C150.712 26.0447 150.155 25.6487 149.686 25.15C149.231 24.6513 148.872 24.072 148.608 23.412C148.358 22.7373 148.234 22.026 148.234 21.278C148.234 20.53 148.358 19.826 148.608 19.166C148.872 18.4913 149.231 17.912 149.686 17.428C150.14 16.9293 150.683 16.5407 151.314 16.262C151.959 15.9687 152.663 15.822 153.426 15.822C154.188 15.822 154.892 15.9687 155.538 16.262C156.183 16.5553 156.733 16.9513 157.188 17.45C157.657 17.9487 158.016 18.5353 158.266 19.21C158.53 19.87 158.662 20.574 158.662 21.322Z" fill="#FFFFFF"/>
<path d="M180.367 26.866V20.398H173.811V22.752H177.749V25.634C177.28 25.986 176.722 26.272 176.077 26.492C175.446 26.6973 174.764 26.8 174.031 26.8C173.239 26.8 172.52 26.6607 171.875 26.382C171.244 26.1033 170.694 25.722 170.225 25.238C169.77 24.7393 169.418 24.1527 169.169 23.478C168.92 22.8033 168.795 22.07 168.795 21.278C168.795 20.53 168.92 19.826 169.169 19.166C169.433 18.506 169.785 17.9267 170.225 17.428C170.68 16.9293 171.208 16.5407 171.809 16.262C172.425 15.9687 173.085 15.822 173.789 15.822C174.273 15.822 174.713 15.866 175.109 15.954C175.52 16.0273 175.894 16.1373 176.231 16.284C176.568 16.416 176.891 16.5847 177.199 16.79C177.507 16.9953 177.808 17.2227 178.101 17.472L179.817 15.426C179.421 15.0887 179.01 14.7953 178.585 14.546C178.174 14.282 177.734 14.062 177.265 13.886C176.796 13.71 176.282 13.578 175.725 13.49C175.182 13.3873 174.574 13.336 173.899 13.336C172.74 13.336 171.67 13.5487 170.687 13.974C169.719 14.3993 168.883 14.9787 168.179 15.712C167.475 16.4307 166.925 17.274 166.529 18.242C166.148 19.21 165.957 20.2367 165.957 21.322C165.957 22.4513 166.148 23.5 166.529 24.468C166.91 25.436 167.446 26.2793 168.135 26.998C168.839 27.702 169.682 28.2593 170.665 28.67C171.648 29.066 172.74 29.264 173.943 29.264C174.618 29.264 175.263 29.198 175.879 29.066C176.495 28.9487 177.067 28.78 177.595 28.56C178.138 28.34 178.636 28.0833 179.091 27.79C179.56 27.4967 179.986 27.1887 180.367 26.866Z" fill="#FFFFFF"/>
<path d="M198.829 29L194.671 23.17C195.214 23.0233 195.705 22.818 196.145 22.554C196.6 22.2753 196.988 21.9453 197.311 21.564C197.634 21.168 197.883 20.7207 198.059 20.222C198.25 19.7087 198.345 19.1293 198.345 18.484C198.345 17.736 198.213 17.0613 197.949 16.46C197.685 15.844 197.304 15.3307 196.805 14.92C196.321 14.4947 195.72 14.172 195.001 13.952C194.297 13.7173 193.505 13.6 192.625 13.6H185.761V29H188.467V23.632H191.855L195.639 29H198.829ZM195.595 18.638C195.595 19.43 195.309 20.0607 194.737 20.53C194.165 20.9993 193.395 21.234 192.427 21.234H188.467V16.064H192.405C193.417 16.064 194.202 16.284 194.759 16.724C195.316 17.1493 195.595 17.7873 195.595 18.638Z" fill="#FFFFFF"/>
<path d="M211.934 13.49H209.426L202.65 29H205.422L207.006 25.282H214.288L215.85 29H218.71L211.934 13.49ZM213.298 22.884H207.996L210.636 16.724L213.298 22.884Z" fill="#FFFFFF"/>
<path d="M236.31 17.956V29H239.016V13.6H236.134L231.448 20.882L226.762 13.6H223.88V29H226.542V18L231.36 25.216H231.448L236.31 17.956Z" fill="#FFFFFF"/>
</svg>
<svg fill="none" height="40" viewBox="0 0 240 40" width="240" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path clip-rule="evenodd" d="m31 40-4-10.6-4 10.6h-2l5-13.2-4-10.5-9 23.7h-2l10-26.4-4.5-11.8-14.5 38.2h-2l15.2-40h2.6l4.2 11 4.2-11h2.6l3.7 9.7 3.7-9.7h2.6l4.2 11 4.2-11h2.6l15.2 40h-2l-14.5-38.2-4.5 11.8 10 26.4h-2l-9-23.7-4 10.5 5 13.2h-2l-4-10.6-4 10.6zm1.5-25-4.5 11.7 4.5 11.9 4.5-11.8zm-5-13.2-4.5 11.8 4 10.6 4.5-11.9zm10 0-4 10.5 4.5 11.9 4-10.6z" fill-rule="evenodd"/><path d="m97.7259 17.956v11.044h2.7061v-15.4h-2.8821l-4.686 7.282-4.686-7.282h-2.882v15.4h2.662v-11l4.818 7.216h.088z"/><path d="m121.687 21.278c0-1.0853-.198-2.112-.594-3.08s-.946-1.8113-1.65-2.53-1.547-1.2833-2.53-1.694c-.982-.4253-2.068-.638-3.256-.638s-2.273.2127-3.256.638c-.982.4253-1.833 1.0047-2.552 1.738-.718.7187-1.276 1.562-1.672 2.53s-.594 1.9947-.594 3.08.198 2.112.594 3.08.946 1.8113 1.65 2.53 1.548 1.2907 2.53 1.716c.983.4107 2.068.616 3.256.616s2.274-.2127 3.256-.638c.983-.4253 1.834-.9973 2.552-1.716.719-.7333 1.276-1.584 1.672-2.552s.594-1.9947.594-3.08zm-2.838.044c0 .748-.132 1.4593-.396 2.134-.249.66-.601 1.2393-1.056 1.738-.454.484-1.004.8727-1.65 1.166-.63.2787-1.327.418-2.09.418-.762 0-1.466-.1467-2.112-.44-.645-.2933-1.202-.6893-1.672-1.188-.454-.4987-.814-1.078-1.078-1.738-.249-.6747-.374-1.386-.374-2.134s.125-1.452.374-2.112c.264-.6747.624-1.254 1.078-1.738.455-.4987.998-.8873 1.628-1.166.646-.2933 1.35-.44 2.112-.44.763 0 1.467.1467 2.112.44.646.2933 1.196.6893 1.65 1.188.47.4987.829 1.0853 1.078 1.76.264.66.396 1.364.396 2.112z"/><path d="m137.585 24.248-8.25-10.648h-2.508v15.4h2.662v-10.956l8.492 10.956h2.266v-15.4h-2.662z"/><path d="m161.5 21.278c0-1.0853-.198-2.112-.594-3.08s-.946-1.8113-1.65-2.53-1.548-1.2833-2.53-1.694c-.983-.4253-2.068-.638-3.256-.638s-2.274.2127-3.256.638c-.983.4253-1.834 1.0047-2.552 1.738-.719.7187-1.276 1.562-1.672 2.53s-.594 1.9947-.594 3.08.198 2.112.594 3.08.946 1.8113 1.65 2.53 1.547 1.2907 2.53 1.716c.982.4107 2.068.616 3.256.616s2.273-.2127 3.256-.638c.982-.4253 1.833-.9973 2.552-1.716.718-.7333 1.276-1.584 1.672-2.552s.594-1.9947.594-3.08zm-2.838.044c0 .748-.132 1.4593-.396 2.134-.25.66-.602 1.2393-1.056 1.738-.455.484-1.005.8727-1.65 1.166-.631.2787-1.328.418-2.09.418-.763 0-1.467-.1467-2.112-.44-.646-.2933-1.203-.6893-1.672-1.188-.455-.4987-.814-1.078-1.078-1.738-.25-.6747-.374-1.386-.374-2.134s.124-1.452.374-2.112c.264-.6747.623-1.254 1.078-1.738.454-.4987.997-.8873 1.628-1.166.645-.2933 1.349-.44 2.112-.44.762 0 1.466.1467 2.112.44.645.2933 1.195.6893 1.65 1.188.469.4987.828 1.0853 1.078 1.76.264.66.396 1.364.396 2.112z"/><path d="m180.367 26.866v-6.468h-6.556v2.354h3.938v2.882c-.469.352-1.027.638-1.672.858-.631.2053-1.313.308-2.046.308-.792 0-1.511-.1393-2.156-.418-.631-.2787-1.181-.66-1.65-1.144-.455-.4987-.807-1.0853-1.056-1.76s-.374-1.408-.374-2.2c0-.748.125-1.452.374-2.112.264-.66.616-1.2393 1.056-1.738.455-.4987.983-.8873 1.584-1.166.616-.2933 1.276-.44 1.98-.44.484 0 .924.044 1.32.132.411.0733.785.1833 1.122.33.337.132.66.3007.968.506s.609.4327.902.682l1.716-2.046c-.396-.3373-.807-.6307-1.232-.88-.411-.264-.851-.484-1.32-.66s-.983-.308-1.54-.396c-.543-.1027-1.151-.154-1.826-.154-1.159 0-2.229.2127-3.212.638-.968.4253-1.804 1.0047-2.508 1.738-.704.7187-1.254 1.562-1.65 2.53-.381.968-.572 1.9947-.572 3.08 0 1.1293.191 2.178.572 3.146s.917 1.8113 1.606 2.53c.704.704 1.547 1.2613 2.53 1.672.983.396 2.075.594 3.278.594.675 0 1.32-.066 1.936-.198.616-.1173 1.188-.286 1.716-.506.543-.22 1.041-.4767 1.496-.77.469-.2933.895-.6013 1.276-.924z"/><path d="m198.829 29-4.158-5.83c.543-.1467 1.034-.352 1.474-.616.455-.2787.843-.6087 1.166-.99.323-.396.572-.8433.748-1.342.191-.5133.286-1.0927.286-1.738 0-.748-.132-1.4227-.396-2.024-.264-.616-.645-1.1293-1.144-1.54-.484-.4253-1.085-.748-1.804-.968-.704-.2347-1.496-.352-2.376-.352h-6.864v15.4h2.706v-5.368h3.388l3.784 5.368zm-3.234-10.362c0 .792-.286 1.4227-.858 1.892s-1.342.704-2.31.704h-3.96v-5.17h3.938c1.012 0 1.797.22 2.354.66.557.4253.836 1.0633.836 1.914z"/><path d="m211.934 13.49h-2.508l-6.776 15.51h2.772l1.584-3.718h7.282l1.562 3.718h2.86zm1.364 9.394h-5.302l2.64-6.16z"/><path d="m236.31 17.956v11.044h2.706v-15.4h-2.882l-4.686 7.282-4.686-7.282h-2.882v15.4h2.662v-11l4.818 7.216h.088z"/></g></svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1,11 +1 @@
<svg width="240" height="40" viewBox="0 0 240 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M31 40L27 29.4L23 40H21L26 26.8L22 16.3L13 40H11L21 13.6L16.5 1.8L2 40H0L15.2 0H17.8L22 11L26.2 0H28.8L32.5 9.7L36.2 0H38.8L43 11L47.2 0H49.8L65 40H63L48.5 1.8L44 13.6L54 40H52L43 16.3L39 26.8L44 40H42L38 29.4L34 40H31ZM32.5 15L28 26.7L32.5 38.6L37 26.8L32.5 15ZM27.5 1.8L23 13.6L27 24.2L31.5 12.3L27.5 1.8ZM37.5 1.8L33.5 12.3L38 24.2L42 13.6L37.5 1.8Z" fill="#000000"/>
<path d="M97.7259 17.956V29H100.432V13.6H97.5499L92.8639 20.882L88.1779 13.6H85.2959V29H87.9579V18L92.7759 25.216H92.8639L97.7259 17.956Z" fill="#000000"/>
<path d="M121.687 21.278C121.687 20.1927 121.489 19.166 121.093 18.198C120.697 17.23 120.147 16.3867 119.443 15.668C118.739 14.9493 117.896 14.3847 116.913 13.974C115.931 13.5487 114.845 13.336 113.657 13.336C112.469 13.336 111.384 13.5487 110.401 13.974C109.419 14.3993 108.568 14.9787 107.849 15.712C107.131 16.4307 106.573 17.274 106.177 18.242C105.781 19.21 105.583 20.2367 105.583 21.322C105.583 22.4073 105.781 23.434 106.177 24.402C106.573 25.37 107.123 26.2133 107.827 26.932C108.531 27.6507 109.375 28.2227 110.357 28.648C111.34 29.0587 112.425 29.264 113.613 29.264C114.801 29.264 115.887 29.0513 116.869 28.626C117.852 28.2007 118.703 27.6287 119.421 26.91C120.14 26.1767 120.697 25.326 121.093 24.358C121.489 23.39 121.687 22.3633 121.687 21.278ZM118.849 21.322C118.849 22.07 118.717 22.7813 118.453 23.456C118.204 24.116 117.852 24.6953 117.397 25.194C116.943 25.678 116.393 26.0667 115.747 26.36C115.117 26.6387 114.42 26.778 113.657 26.778C112.895 26.778 112.191 26.6313 111.545 26.338C110.9 26.0447 110.343 25.6487 109.873 25.15C109.419 24.6513 109.059 24.072 108.795 23.412C108.546 22.7373 108.421 22.026 108.421 21.278C108.421 20.53 108.546 19.826 108.795 19.166C109.059 18.4913 109.419 17.912 109.873 17.428C110.328 16.9293 110.871 16.5407 111.501 16.262C112.147 15.9687 112.851 15.822 113.613 15.822C114.376 15.822 115.08 15.9687 115.725 16.262C116.371 16.5553 116.921 16.9513 117.375 17.45C117.845 17.9487 118.204 18.5353 118.453 19.21C118.717 19.87 118.849 20.574 118.849 21.322Z" fill="#000000"/>
<path d="M137.585 24.248L129.335 13.6H126.827V29H129.489V18.044L137.981 29H140.247V13.6H137.585V24.248Z" fill="#000000"/>
<path d="M161.5 21.278C161.5 20.1927 161.302 19.166 160.906 18.198C160.51 17.23 159.96 16.3867 159.256 15.668C158.552 14.9493 157.708 14.3847 156.726 13.974C155.743 13.5487 154.658 13.336 153.47 13.336C152.282 13.336 151.196 13.5487 150.214 13.974C149.231 14.3993 148.38 14.9787 147.662 15.712C146.943 16.4307 146.386 17.274 145.99 18.242C145.594 19.21 145.396 20.2367 145.396 21.322C145.396 22.4073 145.594 23.434 145.99 24.402C146.386 25.37 146.936 26.2133 147.64 26.932C148.344 27.6507 149.187 28.2227 150.17 28.648C151.152 29.0587 152.238 29.264 153.426 29.264C154.614 29.264 155.699 29.0513 156.682 28.626C157.664 28.2007 158.515 27.6287 159.234 26.91C159.952 26.1767 160.51 25.326 160.906 24.358C161.302 23.39 161.5 22.3633 161.5 21.278ZM158.662 21.322C158.662 22.07 158.53 22.7813 158.266 23.456C158.016 24.116 157.664 24.6953 157.21 25.194C156.755 25.678 156.205 26.0667 155.56 26.36C154.929 26.6387 154.232 26.778 153.47 26.778C152.707 26.778 152.003 26.6313 151.358 26.338C150.712 26.0447 150.155 25.6487 149.686 25.15C149.231 24.6513 148.872 24.072 148.608 23.412C148.358 22.7373 148.234 22.026 148.234 21.278C148.234 20.53 148.358 19.826 148.608 19.166C148.872 18.4913 149.231 17.912 149.686 17.428C150.14 16.9293 150.683 16.5407 151.314 16.262C151.959 15.9687 152.663 15.822 153.426 15.822C154.188 15.822 154.892 15.9687 155.538 16.262C156.183 16.5553 156.733 16.9513 157.188 17.45C157.657 17.9487 158.016 18.5353 158.266 19.21C158.53 19.87 158.662 20.574 158.662 21.322Z" fill="#000000"/>
<path d="M180.367 26.866V20.398H173.811V22.752H177.749V25.634C177.28 25.986 176.722 26.272 176.077 26.492C175.446 26.6973 174.764 26.8 174.031 26.8C173.239 26.8 172.52 26.6607 171.875 26.382C171.244 26.1033 170.694 25.722 170.225 25.238C169.77 24.7393 169.418 24.1527 169.169 23.478C168.92 22.8033 168.795 22.07 168.795 21.278C168.795 20.53 168.92 19.826 169.169 19.166C169.433 18.506 169.785 17.9267 170.225 17.428C170.68 16.9293 171.208 16.5407 171.809 16.262C172.425 15.9687 173.085 15.822 173.789 15.822C174.273 15.822 174.713 15.866 175.109 15.954C175.52 16.0273 175.894 16.1373 176.231 16.284C176.568 16.416 176.891 16.5847 177.199 16.79C177.507 16.9953 177.808 17.2227 178.101 17.472L179.817 15.426C179.421 15.0887 179.01 14.7953 178.585 14.546C178.174 14.282 177.734 14.062 177.265 13.886C176.796 13.71 176.282 13.578 175.725 13.49C175.182 13.3873 174.574 13.336 173.899 13.336C172.74 13.336 171.67 13.5487 170.687 13.974C169.719 14.3993 168.883 14.9787 168.179 15.712C167.475 16.4307 166.925 17.274 166.529 18.242C166.148 19.21 165.957 20.2367 165.957 21.322C165.957 22.4513 166.148 23.5 166.529 24.468C166.91 25.436 167.446 26.2793 168.135 26.998C168.839 27.702 169.682 28.2593 170.665 28.67C171.648 29.066 172.74 29.264 173.943 29.264C174.618 29.264 175.263 29.198 175.879 29.066C176.495 28.9487 177.067 28.78 177.595 28.56C178.138 28.34 178.636 28.0833 179.091 27.79C179.56 27.4967 179.986 27.1887 180.367 26.866Z" fill="#000000"/>
<path d="M198.829 29L194.671 23.17C195.214 23.0233 195.705 22.818 196.145 22.554C196.6 22.2753 196.988 21.9453 197.311 21.564C197.634 21.168 197.883 20.7207 198.059 20.222C198.25 19.7087 198.345 19.1293 198.345 18.484C198.345 17.736 198.213 17.0613 197.949 16.46C197.685 15.844 197.304 15.3307 196.805 14.92C196.321 14.4947 195.72 14.172 195.001 13.952C194.297 13.7173 193.505 13.6 192.625 13.6H185.761V29H188.467V23.632H191.855L195.639 29H198.829ZM195.595 18.638C195.595 19.43 195.309 20.0607 194.737 20.53C194.165 20.9993 193.395 21.234 192.427 21.234H188.467V16.064H192.405C193.417 16.064 194.202 16.284 194.759 16.724C195.316 17.1493 195.595 17.7873 195.595 18.638Z" fill="#000000"/>
<path d="M211.934 13.49H209.426L202.65 29H205.422L207.006 25.282H214.288L215.85 29H218.71L211.934 13.49ZM213.298 22.884H207.996L210.636 16.724L213.298 22.884Z" fill="#000000"/>
<path d="M236.31 17.956V29H239.016V13.6H236.134L231.448 20.882L226.762 13.6H223.88V29H226.542V18L231.36 25.216H231.448L236.31 17.956Z" fill="#000000"/>
</svg>
<svg fill="none" height="40" viewBox="0 0 240 40" width="240" xmlns="http://www.w3.org/2000/svg"><g fill="#000"><path clip-rule="evenodd" d="m31 40-4-10.6-4 10.6h-2l5-13.2-4-10.5-9 23.7h-2l10-26.4-4.5-11.8-14.5 38.2h-2l15.2-40h2.6l4.2 11 4.2-11h2.6l3.7 9.7 3.7-9.7h2.6l4.2 11 4.2-11h2.6l15.2 40h-2l-14.5-38.2-4.5 11.8 10 26.4h-2l-9-23.7-4 10.5 5 13.2h-2l-4-10.6-4 10.6zm1.5-25-4.5 11.7 4.5 11.9 4.5-11.8zm-5-13.2-4.5 11.8 4 10.6 4.5-11.9zm10 0-4 10.5 4.5 11.9 4-10.6z" fill-rule="evenodd"/><path d="m97.7259 17.956v11.044h2.7061v-15.4h-2.8821l-4.686 7.282-4.686-7.282h-2.882v15.4h2.662v-11l4.818 7.216h.088z"/><path d="m121.687 21.278c0-1.0853-.198-2.112-.594-3.08s-.946-1.8113-1.65-2.53-1.547-1.2833-2.53-1.694c-.982-.4253-2.068-.638-3.256-.638s-2.273.2127-3.256.638c-.982.4253-1.833 1.0047-2.552 1.738-.718.7187-1.276 1.562-1.672 2.53s-.594 1.9947-.594 3.08.198 2.112.594 3.08.946 1.8113 1.65 2.53 1.548 1.2907 2.53 1.716c.983.4107 2.068.616 3.256.616s2.274-.2127 3.256-.638c.983-.4253 1.834-.9973 2.552-1.716.719-.7333 1.276-1.584 1.672-2.552s.594-1.9947.594-3.08zm-2.838.044c0 .748-.132 1.4593-.396 2.134-.249.66-.601 1.2393-1.056 1.738-.454.484-1.004.8727-1.65 1.166-.63.2787-1.327.418-2.09.418-.762 0-1.466-.1467-2.112-.44-.645-.2933-1.202-.6893-1.672-1.188-.454-.4987-.814-1.078-1.078-1.738-.249-.6747-.374-1.386-.374-2.134s.125-1.452.374-2.112c.264-.6747.624-1.254 1.078-1.738.455-.4987.998-.8873 1.628-1.166.646-.2933 1.35-.44 2.112-.44.763 0 1.467.1467 2.112.44.646.2933 1.196.6893 1.65 1.188.47.4987.829 1.0853 1.078 1.76.264.66.396 1.364.396 2.112z"/><path d="m137.585 24.248-8.25-10.648h-2.508v15.4h2.662v-10.956l8.492 10.956h2.266v-15.4h-2.662z"/><path d="m161.5 21.278c0-1.0853-.198-2.112-.594-3.08s-.946-1.8113-1.65-2.53-1.548-1.2833-2.53-1.694c-.983-.4253-2.068-.638-3.256-.638s-2.274.2127-3.256.638c-.983.4253-1.834 1.0047-2.552 1.738-.719.7187-1.276 1.562-1.672 2.53s-.594 1.9947-.594 3.08.198 2.112.594 3.08.946 1.8113 1.65 2.53 1.547 1.2907 2.53 1.716c.982.4107 2.068.616 3.256.616s2.273-.2127 3.256-.638c.982-.4253 1.833-.9973 2.552-1.716.718-.7333 1.276-1.584 1.672-2.552s.594-1.9947.594-3.08zm-2.838.044c0 .748-.132 1.4593-.396 2.134-.25.66-.602 1.2393-1.056 1.738-.455.484-1.005.8727-1.65 1.166-.631.2787-1.328.418-2.09.418-.763 0-1.467-.1467-2.112-.44-.646-.2933-1.203-.6893-1.672-1.188-.455-.4987-.814-1.078-1.078-1.738-.25-.6747-.374-1.386-.374-2.134s.124-1.452.374-2.112c.264-.6747.623-1.254 1.078-1.738.454-.4987.997-.8873 1.628-1.166.645-.2933 1.349-.44 2.112-.44.762 0 1.466.1467 2.112.44.645.2933 1.195.6893 1.65 1.188.469.4987.828 1.0853 1.078 1.76.264.66.396 1.364.396 2.112z"/><path d="m180.367 26.866v-6.468h-6.556v2.354h3.938v2.882c-.469.352-1.027.638-1.672.858-.631.2053-1.313.308-2.046.308-.792 0-1.511-.1393-2.156-.418-.631-.2787-1.181-.66-1.65-1.144-.455-.4987-.807-1.0853-1.056-1.76s-.374-1.408-.374-2.2c0-.748.125-1.452.374-2.112.264-.66.616-1.2393 1.056-1.738.455-.4987.983-.8873 1.584-1.166.616-.2933 1.276-.44 1.98-.44.484 0 .924.044 1.32.132.411.0733.785.1833 1.122.33.337.132.66.3007.968.506s.609.4327.902.682l1.716-2.046c-.396-.3373-.807-.6307-1.232-.88-.411-.264-.851-.484-1.32-.66s-.983-.308-1.54-.396c-.543-.1027-1.151-.154-1.826-.154-1.159 0-2.229.2127-3.212.638-.968.4253-1.804 1.0047-2.508 1.738-.704.7187-1.254 1.562-1.65 2.53-.381.968-.572 1.9947-.572 3.08 0 1.1293.191 2.178.572 3.146s.917 1.8113 1.606 2.53c.704.704 1.547 1.2613 2.53 1.672.983.396 2.075.594 3.278.594.675 0 1.32-.066 1.936-.198.616-.1173 1.188-.286 1.716-.506.543-.22 1.041-.4767 1.496-.77.469-.2933.895-.6013 1.276-.924z"/><path d="m198.829 29-4.158-5.83c.543-.1467 1.034-.352 1.474-.616.455-.2787.843-.6087 1.166-.99.323-.396.572-.8433.748-1.342.191-.5133.286-1.0927.286-1.738 0-.748-.132-1.4227-.396-2.024-.264-.616-.645-1.1293-1.144-1.54-.484-.4253-1.085-.748-1.804-.968-.704-.2347-1.496-.352-2.376-.352h-6.864v15.4h2.706v-5.368h3.388l3.784 5.368zm-3.234-10.362c0 .792-.286 1.4227-.858 1.892s-1.342.704-2.31.704h-3.96v-5.17h3.938c1.012 0 1.797.22 2.354.66.557.4253.836 1.0633.836 1.914z"/><path d="m211.934 13.49h-2.508l-6.776 15.51h2.772l1.584-3.718h7.282l1.562 3.718h2.86zm1.364 9.394h-5.302l2.64-6.16z"/><path d="m236.31 17.956v11.044h2.706v-15.4h-2.882l-4.686 7.282-4.686-7.282h-2.882v15.4h2.662v-11l4.818 7.216h.088z"/></g></svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1 +1 @@
<svg viewBox="0 0 147 40" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="-779.0521" cy="1839.7205" gradientTransform="matrix(0 38.301 44.1228 0 -81154.2578 29839.2441)" gradientUnits="userSpaceOnUse" r="1.0011"><stop offset="0" stop-color="#20c6b7"/><stop offset="1" stop-color="#4d9abf"/></radialGradient><path clip-rule="evenodd" d="m53.37 12.98.12 2.2c1.4-1.7 3.24-2.55 5.53-2.55 3.95 0 5.96 2.27 6.03 6.8v12.57h-4.26v-12.32c0-1.21-.26-2.1-.78-2.68s-1.37-.87-2.55-.87c-1.72 0-3 .78-3.84 2.34v13.53h-4.26v-19.02zm24.38 19.37c-2.7 0-4.89-.85-6.57-2.56-1.68-1.7-2.52-3.98-2.52-6.81v-.53c0-1.9.36-3.59 1.1-5.09.73-1.49 1.76-2.66 3.08-3.49s2.79-1.25 4.42-1.25c2.58 0 4.58.83 5.99 2.48s2.11 3.99 2.11 7.01v1.72h-12.4c.13 1.57.65 2.81 1.57 3.73s2.07 1.37 3.46 1.37c1.95 0 3.54-.79 4.77-2.37l2.3 2.2c-.76 1.14-1.77 2.02-3.04 2.65s-2.69.94-4.27.94zm-.51-16.29c-1.17 0-2.11.41-2.83 1.23s-1.18 1.96-1.38 3.43h8.12v-.32c-.09-1.43-.47-2.51-1.14-3.24-.67-.74-1.59-1.1-2.77-1.1zm16.76-7.7v4.62h3.35v3.16h-3.35v10.62c0 .73.14 1.25.43 1.57s.8.48 1.54.48c.5 0 1-.06 1.49-.18v3.31c-.97.27-1.9.4-2.81.4-3.27 0-4.91-1.81-4.91-5.43v-10.77h-3.12v-3.16h3.12v-4.63zm11.14 23.64h-4.26v-27h4.26zm9.17 0h-4.26v-19.02h4.26zm-4.52-23.96c0-.65.21-1.2.62-1.63.42-.43 1.01-.65 1.78-.65s1.37.22 1.79.65.63.98.63 1.64c0 .64-.21 1.18-.63 1.61s-1.02.64-1.79.64-1.36-.21-1.78-.64c-.41-.44-.62-.98-.62-1.62zm10.66 23.96v-15.86h-2.89v-3.16h2.89v-1.74c0-2.11.58-3.74 1.75-4.89s2.81-1.72 4.91-1.72c.75 0 1.54.11 2.39.32l-.1 3.34c-.54-.1-1.08-.15-1.63-.14-2.04 0-3.05 1.05-3.05 3.15v1.69h3.86v3.16h-3.86v15.85zm17.87-6.12 3.86-12.9h4.54l-7.54 21.9c-1.16 3.2-3.12 4.8-5.89 4.8-.62 0-1.3-.11-2.05-.32v-3.31l.81.05c1.07 0 1.88-.2 2.43-.59.54-.39.97-1.05 1.29-1.98l.61-1.64-6.66-18.93h4.6z" fill="#ffffff" fill-rule="evenodd"/><path d="m27.89 14.14-.01-.01c-.01 0-.02-.01-.02-.01-.02-.02-.03-.06-.03-.09l.77-4.73 3.62 3.63-3.77 1.6c-.01 0-.02.01-.03.01h-.02s-.01-.01-.02-.02c-.14-.16-.31-.29-.49-.38zm5.26-.29 3.88 3.88c.81.81 1.21 1.21 1.35 1.67.02.07.04.14.05.21l-9.26-3.92s-.01 0-.01-.01c-.04-.02-.08-.03-.08-.07s.04-.06.08-.07l.01-.01zm5.12 7c-.2.38-.59.77-1.25 1.43l-4.37 4.37-5.65-1.18-.03-.01c-.05-.01-.1-.02-.1-.06-.04-.47-.28-.9-.66-1.19-.02-.02-.02-.06-.01-.09v-.01l1.06-6.53v-.02c.01-.05.01-.11.06-.11.46-.06.88-.3 1.16-.67.01-.01.01-.02.03-.03.03-.01.07 0 .1.01zm-6.62 6.8-7.19 7.19 1.23-7.56v-.01c0-.01 0-.02.01-.03.01-.02.04-.03.06-.04h.01c.27-.11.51-.29.69-.52.02-.03.05-.06.09-.06h.03zm-8.71 8.71-.81.81-8.95-12.94s-.01-.01-.01-.01c-.01-.02-.03-.04-.03-.06s.01-.03.02-.04l.01-.01c.03-.04.05-.08.07-.12l.02-.03c.01-.02.03-.05.05-.06s.05-.01.07 0l9.92 2.05c.03 0 .05.02.08.03.01.01.02.03.02.04.14.53.52.97 1.03 1.17.03.01.02.05 0 .08-.01.01-.01.03-.01.05-.12.74-1.19 7.27-1.48 9.04zm-1.69 1.69c-.6.59-.95.9-1.35 1.03-.39.12-.81.12-1.21 0-.47-.15-.87-.55-1.67-1.36l-8.99-8.99 2.35-3.64c.01-.02.02-.03.04-.05s.06-.01.09 0c.54.16 1.12.13 1.64-.08.03-.01.05-.02.07 0l.03.03zm-14.09-10.19-2.06-2.06 4.07-1.74c.01 0 .02-.01.03-.01.03 0 .05.03.07.07.04.06.08.12.13.18l.01.02c.01.02 0 .03-.01.05zm-2.98-2.97-2.61-2.61c-.44-.44-.77-.77-.99-1.04l7.94 1.65h.03c.05.01.1.02.1.06 0 .05-.06.07-.11.09l-.02.01zm-4.05-5c.01-.17.04-.33.09-.5.15-.47.55-.87 1.36-1.67l3.34-3.34c1.54 2.23 3.08 4.46 4.63 6.69.03.04.06.08.03.11-.15.16-.29.34-.4.53-.01.02-.03.05-.05.06-.01.01-.03 0-.04 0zm5.68-6.4 4.49-4.49c.42.19 1.96.83 3.33 1.41 1.04.44 1.99.84 2.29.97.03.01.06.02.07.05.01.02 0 .04 0 .06-.14.66.05 1.35.52 1.83.03.03 0 .07-.03.11l-.01.02-4.56 7.06c-.01.02-.02.04-.04.05s-.06.01-.09 0c-.18-.05-.36-.07-.54-.07-.16 0-.34.03-.52.06-.02 0-.04.01-.05 0-.02-.01-.03-.03-.05-.05zm5.4-5.4 5.81-5.81c.81-.81 1.21-1.21 1.67-1.36.39-.12.81-.12 1.21 0 .47.15.87.55 1.67 1.36l1.26 1.26-4.14 6.4c-.01.02-.02.03-.04.05s-.06.01-.09 0c-.66-.2-1.38-.06-1.92.37-.03.03-.07.01-.1 0-.53-.24-4.73-2.01-5.33-2.27zm12.5-3.67 3.82 3.82-.92 5.7v.02c0 .01 0 .03-.01.04-.01.02-.03.02-.05.03-.2.06-.38.15-.55.27-.01.01-.01.01-.02.02s-.02.02-.04.02c-.01 0-.03 0-.04-.01l-5.82-2.47-.01-.01c-.04-.02-.08-.03-.08-.07-.03-.32-.14-.64-.31-.91-.03-.05-.06-.09-.03-.14zm-3.93 8.6 5.45 2.31c.03.01.06.03.08.06.01.02.01.04 0 .06-.02.08-.03.17-.03.26v.15c0 .04-.04.05-.08.07h-.01c-.86.37-12.13 5.17-12.15 5.17s-.03 0-.05-.02c-.03-.03 0-.07.03-.11 0-.01.01-.01.01-.02l4.48-6.94.01-.01c.03-.04.06-.09.1-.09l.05.01c.1.01.19.03.28.03.68 0 1.31-.33 1.69-.9.01-.02.02-.03.03-.04.04-.01.08 0 .11.01zm-6.25 9.19 12.28-5.24s.02 0 .03.02c.07.07.12.11.18.15l.03.02c.02.01.05.03.05.06v.02l-1.05 6.46v.03c-.01.05-.01.11-.06.11-.57.04-1.08.36-1.37.85v.01c-.01.02-.03.05-.05.06s-.05.01-.07 0l-9.79-2.02c-.02-.02-.16-.53-.18-.53z" fill="url(#a)"/></svg>
<svg viewBox="0 0 147 40" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="-779.0521" cy="1839.7205" gradientTransform="matrix(0 38.301 44.1228 0 -81154.2578 29839.2441)" gradientUnits="userSpaceOnUse" r="1.0011"><stop offset="0" stop-color="#20c6b7"/><stop offset="1" stop-color="#4d9abf"/></radialGradient><path clip-rule="evenodd" d="m53.37 12.98.12 2.2c1.4-1.7 3.24-2.55 5.53-2.55 3.95 0 5.96 2.27 6.03 6.8v12.57h-4.26v-12.32c0-1.21-.26-2.1-.78-2.68s-1.37-.87-2.55-.87c-1.72 0-3 .78-3.84 2.34v13.53h-4.26v-19.02zm24.38 19.37c-2.7 0-4.89-.85-6.57-2.56-1.68-1.7-2.52-3.98-2.52-6.81v-.53c0-1.9.36-3.59 1.1-5.09.73-1.49 1.76-2.66 3.08-3.49s2.79-1.25 4.42-1.25c2.58 0 4.58.83 5.99 2.48s2.11 3.99 2.11 7.01v1.72h-12.4c.13 1.57.65 2.81 1.57 3.73s2.07 1.37 3.46 1.37c1.95 0 3.54-.79 4.77-2.37l2.3 2.2c-.76 1.14-1.77 2.02-3.04 2.65s-2.69.94-4.27.94zm-.51-16.29c-1.17 0-2.11.41-2.83 1.23s-1.18 1.96-1.38 3.43h8.12v-.32c-.09-1.43-.47-2.51-1.14-3.24-.67-.74-1.59-1.1-2.77-1.1zm16.76-7.7v4.62h3.35v3.16h-3.35v10.62c0 .73.14 1.25.43 1.57s.8.48 1.54.48c.5 0 1-.06 1.49-.18v3.31c-.97.27-1.9.4-2.81.4-3.27 0-4.91-1.81-4.91-5.43v-10.77h-3.12v-3.16h3.12v-4.63zm11.14 23.64h-4.26v-27h4.26zm9.17 0h-4.26v-19.02h4.26zm-4.52-23.96c0-.65.21-1.2.62-1.63.42-.43 1.01-.65 1.78-.65s1.37.22 1.79.65.63.98.63 1.64c0 .64-.21 1.18-.63 1.61s-1.02.64-1.79.64-1.36-.21-1.78-.64c-.41-.44-.62-.98-.62-1.62zm10.66 23.96v-15.86h-2.89v-3.16h2.89v-1.74c0-2.11.58-3.74 1.75-4.89s2.81-1.72 4.91-1.72c.75 0 1.54.11 2.39.32l-.1 3.34c-.54-.1-1.08-.15-1.63-.14-2.04 0-3.05 1.05-3.05 3.15v1.69h3.86v3.16h-3.86v15.85zm17.87-6.12 3.86-12.9h4.54l-7.54 21.9c-1.16 3.2-3.12 4.8-5.89 4.8-.62 0-1.3-.11-2.05-.32v-3.31l.81.05c1.07 0 1.88-.2 2.43-.59.54-.39.97-1.05 1.29-1.98l.61-1.64-6.66-18.93h4.6z" fill="#fff" fill-rule="evenodd"/><path d="m27.89 14.14-.01-.01c-.01 0-.02-.01-.02-.01-.02-.02-.03-.06-.03-.09l.77-4.73 3.62 3.63-3.77 1.6c-.01 0-.02.01-.03.01h-.02s-.01-.01-.02-.02c-.14-.16-.31-.29-.49-.38zm5.26-.29 3.88 3.88c.81.81 1.21 1.21 1.35 1.67.02.07.04.14.05.21l-9.26-3.92s-.01 0-.01-.01c-.04-.02-.08-.03-.08-.07s.04-.06.08-.07l.01-.01zm5.12 7c-.2.38-.59.77-1.25 1.43l-4.37 4.37-5.65-1.18-.03-.01c-.05-.01-.1-.02-.1-.06-.04-.47-.28-.9-.66-1.19-.02-.02-.02-.06-.01-.09v-.01l1.06-6.53v-.02c.01-.05.01-.11.06-.11.46-.06.88-.3 1.16-.67.01-.01.01-.02.03-.03.03-.01.07 0 .1.01zm-6.62 6.8-7.19 7.19 1.23-7.56v-.01c0-.01 0-.02.01-.03.01-.02.04-.03.06-.04h.01c.27-.11.51-.29.69-.52.02-.03.05-.06.09-.06h.03zm-8.71 8.71-.81.81-8.95-12.94s-.01-.01-.01-.01c-.01-.02-.03-.04-.03-.06s.01-.03.02-.04l.01-.01c.03-.04.05-.08.07-.12l.02-.03c.01-.02.03-.05.05-.06s.05-.01.07 0l9.92 2.05c.03 0 .05.02.08.03.01.01.02.03.02.04.14.53.52.97 1.03 1.17.03.01.02.05 0 .08-.01.01-.01.03-.01.05-.12.74-1.19 7.27-1.48 9.04zm-1.69 1.69c-.6.59-.95.9-1.35 1.03-.39.12-.81.12-1.21 0-.47-.15-.87-.55-1.67-1.36l-8.99-8.99 2.35-3.64c.01-.02.02-.03.04-.05s.06-.01.09 0c.54.16 1.12.13 1.64-.08.03-.01.05-.02.07 0l.03.03zm-14.09-10.19-2.06-2.06 4.07-1.74c.01 0 .02-.01.03-.01.03 0 .05.03.07.07.04.06.08.12.13.18l.01.02c.01.02 0 .03-.01.05zm-2.98-2.97-2.61-2.61c-.44-.44-.77-.77-.99-1.04l7.94 1.65h.03c.05.01.1.02.1.06 0 .05-.06.07-.11.09l-.02.01zm-4.05-5c.01-.17.04-.33.09-.5.15-.47.55-.87 1.36-1.67l3.34-3.34c1.54 2.23 3.08 4.46 4.63 6.69.03.04.06.08.03.11-.15.16-.29.34-.4.53-.01.02-.03.05-.05.06-.01.01-.03 0-.04 0zm5.68-6.4 4.49-4.49c.42.19 1.96.83 3.33 1.41 1.04.44 1.99.84 2.29.97.03.01.06.02.07.05.01.02 0 .04 0 .06-.14.66.05 1.35.52 1.83.03.03 0 .07-.03.11l-.01.02-4.56 7.06c-.01.02-.02.04-.04.05s-.06.01-.09 0c-.18-.05-.36-.07-.54-.07-.16 0-.34.03-.52.06-.02 0-.04.01-.05 0-.02-.01-.03-.03-.05-.05zm5.4-5.4 5.81-5.81c.81-.81 1.21-1.21 1.67-1.36.39-.12.81-.12 1.21 0 .47.15.87.55 1.67 1.36l1.26 1.26-4.14 6.4c-.01.02-.02.03-.04.05s-.06.01-.09 0c-.66-.2-1.38-.06-1.92.37-.03.03-.07.01-.1 0-.53-.24-4.73-2.01-5.33-2.27zm12.5-3.67 3.82 3.82-.92 5.7v.02c0 .01 0 .03-.01.04-.01.02-.03.02-.05.03-.2.06-.38.15-.55.27-.01.01-.01.01-.02.02s-.02.02-.04.02c-.01 0-.03 0-.04-.01l-5.82-2.47-.01-.01c-.04-.02-.08-.03-.08-.07-.03-.32-.14-.64-.31-.91-.03-.05-.06-.09-.03-.14zm-3.93 8.6 5.45 2.31c.03.01.06.03.08.06.01.02.01.04 0 .06-.02.08-.03.17-.03.26v.15c0 .04-.04.05-.08.07h-.01c-.86.37-12.13 5.17-12.15 5.17s-.03 0-.05-.02c-.03-.03 0-.07.03-.11 0-.01.01-.01.01-.02l4.48-6.94.01-.01c.03-.04.06-.09.1-.09l.05.01c.1.01.19.03.28.03.68 0 1.31-.33 1.69-.9.01-.02.02-.03.03-.04.04-.01.08 0 .11.01zm-6.25 9.19 12.28-5.24s.02 0 .03.02c.07.07.12.11.18.15l.03.02c.02.01.05.03.05.06v.02l-1.05 6.46v.03c-.01.05-.01.11-.06.11-.57.04-1.08.36-1.37.85v.01c-.01.02-.03.05-.05.06s-.05.01-.07 0l-9.79-2.02c-.02-.02-.16-.53-.18-.53z" fill="url(#a)"/></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -1 +1 @@
<svg viewBox="0 0 360.27 79.35" xmlns="http://www.w3.org/2000/svg"><g fill="#FFFFFF"><path d="m52.16 4.07c-2.4-3.98-7.57-5.26-11.55-2.86-1.17.71-2.16 1.69-2.86 2.86l-11.86 20.31c18.43 9.2 30.6 27.48 31.98 48.04h-8.32c-1.38-17.62-11.98-33.19-27.86-40.94l-10.97 18.97c8.92 4 15.18 12.26 16.63 21.93h-19.12c-.75-.05-1.32-.71-1.27-1.46.01-.19.07-.37.15-.54l5.3-9.01c-1.79-1.5-3.85-2.66-6.05-3.42l-5.24 9.01c-2.28 3.9-.96 8.91 2.95 11.19.03.02.07.04.1.06 1.24.7 2.64 1.07 4.07 1.08h26.18c.98-12.21-4.49-24.04-14.42-31.2l4.16-7.21c12.54 8.61 19.6 23.22 18.56 38.4h22.18c1.05-23-10.21-44.83-29.57-57.3l8.41-14.41c.39-.65 1.23-.87 1.89-.49.96.52 36.57 62.65 37.23 63.37.37.66.13 1.49-.53 1.86-.21.12-.45.18-.7.17h-8.58c.11 2.29.11 4.58 0 6.86h8.61c4.57.03 8.29-3.65 8.32-8.22 0-.03 0-.06 0-.09 0-1.44-.38-2.86-1.12-4.11z"/><path d="m223.91 50.96-26.59-34.34h-6.63v46.04h6.72v-35.29l27.35 35.28h5.87v-46.04h-6.72zm-66.98-8.54h23.84v-5.98h-23.86v-13.86h26.9v-5.98h-33.75v46.05h34.09v-5.98h-27.24zm-28.03-5.84c-9.28-2.23-11.87-4-11.87-8.29 0-3.86 3.41-6.47 8.49-6.47 4.63.14 9.09 1.75 12.74 4.59l3.6-5.1c-4.62-3.62-10.35-5.53-16.22-5.41-9.12 0-15.48 5.41-15.48 13.1 0 8.29 5.41 11.15 15.24 13.55 8.76 2.02 11.44 3.89 11.44 8.09s-3.6 6.79-9.17 6.79c-5.54-.03-10.88-2.12-14.95-5.87l-4.05 4.85c5.22 4.49 11.89 6.95 18.77 6.94 9.87 0 16.22-5.32 16.22-13.53-.06-6.95-4.17-10.68-14.76-13.24zm223.62-19.97-13.86 21.62-13.76-21.62h-8.04l18.18 27.84v18.22h6.92v-18.43l18.31-27.62zm-116.45 6.24h15.08v39.82h6.92v-39.82h15.08v-6.23h-37.06zm69.08 21.84c6.95-1.93 10.81-6.79 10.81-13.75 0-8.85-6.47-14.41-16.9-14.41h-20.47v46.11h6.85v-16.55h11.62l11.68 16.58h8l-12.61-17.69zm-19.73-4.51v-17.48h12.92c6.74 0 10.59 3.19 10.59 8.72s-4.13 8.76-10.52 8.76z"/></g></svg>
<svg viewBox="0 0 360.27 79.35" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="m52.16 4.07c-2.4-3.98-7.57-5.26-11.55-2.86-1.17.71-2.16 1.69-2.86 2.86l-11.86 20.31c18.43 9.2 30.6 27.48 31.98 48.04h-8.32c-1.38-17.62-11.98-33.19-27.86-40.94l-10.97 18.97c8.92 4 15.18 12.26 16.63 21.93h-19.12c-.75-.05-1.32-.71-1.27-1.46.01-.19.07-.37.15-.54l5.3-9.01c-1.79-1.5-3.85-2.66-6.05-3.42l-5.24 9.01c-2.28 3.9-.96 8.91 2.95 11.19.03.02.07.04.1.06 1.24.7 2.64 1.07 4.07 1.08h26.18c.98-12.21-4.49-24.04-14.42-31.2l4.16-7.21c12.54 8.61 19.6 23.22 18.56 38.4h22.18c1.05-23-10.21-44.83-29.57-57.3l8.41-14.41c.39-.65 1.23-.87 1.89-.49.96.52 36.57 62.65 37.23 63.37.37.66.13 1.49-.53 1.86-.21.12-.45.18-.7.17h-8.58c.11 2.29.11 4.58 0 6.86h8.61c4.57.03 8.29-3.65 8.32-8.22 0-.03 0-.06 0-.09 0-1.44-.38-2.86-1.12-4.11z"/><path d="m223.91 50.96-26.59-34.34h-6.63v46.04h6.72v-35.29l27.35 35.28h5.87v-46.04h-6.72zm-66.98-8.54h23.84v-5.98h-23.86v-13.86h26.9v-5.98h-33.75v46.05h34.09v-5.98h-27.24zm-28.03-5.84c-9.28-2.23-11.87-4-11.87-8.29 0-3.86 3.41-6.47 8.49-6.47 4.63.14 9.09 1.75 12.74 4.59l3.6-5.1c-4.62-3.62-10.35-5.53-16.22-5.41-9.12 0-15.48 5.41-15.48 13.1 0 8.29 5.41 11.15 15.24 13.55 8.76 2.02 11.44 3.89 11.44 8.09s-3.6 6.79-9.17 6.79c-5.54-.03-10.88-2.12-14.95-5.87l-4.05 4.85c5.22 4.49 11.89 6.95 18.77 6.94 9.87 0 16.22-5.32 16.22-13.53-.06-6.95-4.17-10.68-14.76-13.24zm223.62-19.97-13.86 21.62-13.76-21.62h-8.04l18.18 27.84v18.22h6.92v-18.43l18.31-27.62zm-116.45 6.24h15.08v39.82h6.92v-39.82h15.08v-6.23h-37.06zm69.08 21.84c6.95-1.93 10.81-6.79 10.81-13.75 0-8.85-6.47-14.41-16.9-14.41h-20.47v46.11h6.85v-16.55h11.62l11.68 16.58h8l-12.61-17.69zm-19.73-4.51v-17.48h12.92c6.74 0 10.59 3.19 10.59 8.72s-4.13 8.76-10.52 8.76z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

@ -1 +1 @@
<svg fill="#ffffff" viewBox="0 0 284 65" xmlns="http://www.w3.org/2000/svg"><path d="m37.59.25 36.95 64h-73.9z"/><path d="m129.97 5.25-27.71 48-27.71-48h10.39l17.32 30 17.32-30z"/><path d="m188.88 17.25v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10v14.8h-9v-34h9v9.2c0-5.08 5.91-9.2 13.2-9.2z"/><path d="m200.88 34.25c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10z"/><path d="m274.36 5.25h9v46h-9z"/><path d="m268.36 34.24c0-10.79-7.96-17.99-19-17.99-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5zm-28.45-3.49c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/><path d="m141.68 16.25c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/></svg>
<svg fill="#fff" viewBox="0 0 284 65" xmlns="http://www.w3.org/2000/svg"><path d="m37.59.25 36.95 64h-73.9z"/><path d="m129.97 5.25-27.71 48-27.71-48h10.39l17.32 30 17.32-30z"/><path d="m188.88 17.25v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10v14.8h-9v-34h9v9.2c0-5.08 5.91-9.2 13.2-9.2z"/><path d="m200.88 34.25c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10z"/><path d="m274.36 5.25h9v46h-9z"/><path d="m268.36 34.24c0-10.79-7.96-17.99-19-17.99s-19 7.2-19 18 8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5zm-28.45-3.49c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/><path d="m141.68 16.25c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1 +1 @@
<svg viewBox="0 0 284 65" xmlns="http://www.w3.org/2000/svg"><path d="m37.59.25 36.95 64h-73.9z"/><path d="m129.97 5.25-27.71 48-27.71-48h10.39l17.32 30 17.32-30z"/><path d="m188.88 17.25v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10v14.8h-9v-34h9v9.2c0-5.08 5.91-9.2 13.2-9.2z"/><path d="m200.88 34.25c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10z"/><path d="m274.36 5.25h9v46h-9z"/><path d="m268.36 34.24c0-10.79-7.96-17.99-19-17.99-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5zm-28.45-3.49c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/><path d="m141.68 16.25c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/></svg>
<svg viewBox="0 0 284 65" xmlns="http://www.w3.org/2000/svg"><path d="m37.59.25 36.95 64h-73.9z"/><path d="m129.97 5.25-27.71 48-27.71-48h10.39l17.32 30 17.32-30z"/><path d="m188.88 17.25v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10v14.8h-9v-34h9v9.2c0-5.08 5.91-9.2 13.2-9.2z"/><path d="m200.88 34.25c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10z"/><path d="m274.36 5.25h9v46h-9z"/><path d="m268.36 34.24c0-10.79-7.96-17.99-19-17.99s-19 7.2-19 18 8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5zm-28.45-3.49c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/><path d="m141.68 16.25c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

View file

@ -14,6 +14,6 @@
"@astrojs/mdx": "^1.1.0",
"@astrojs/rss": "^3.0.0",
"@astrojs/sitemap": "^3.0.0",
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -15,7 +15,7 @@
],
"scripts": {},
"devDependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
},
"peerDependencies": {
"astro": "^2.0.0-beta.0"

View file

@ -10,7 +10,7 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
},
"devDependencies": {
"@astrojs/deno": "^5.0.0"

View file

@ -14,6 +14,6 @@
"@astrojs/alpinejs": "^0.3.0",
"@types/alpinejs": "^3.7.2",
"alpinejs": "^3.12.3",
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

View file

@ -13,7 +13,7 @@
"dependencies": {
"@astrojs/lit": "^3.0.0",
"@webcomponents/template-shadowroot": "^0.2.1",
"astro": "^3.1.1",
"astro": "^3.1.2",
"lit": "^2.8.0"
}
}

View file

@ -16,7 +16,7 @@
"@astrojs/solid-js": "^3.0.1",
"@astrojs/svelte": "^4.0.2",
"@astrojs/vue": "^3.0.0",
"astro": "^3.1.1",
"astro": "^3.1.2",
"preact": "^10.17.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View file

@ -13,7 +13,7 @@
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@preact/signals": "^1.2.1",
"astro": "^3.1.1",
"astro": "^3.1.2",
"preact": "^10.17.1"
}
}

View file

@ -14,7 +14,7 @@
"@astrojs/react": "^3.0.2",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"astro": "^3.1.1",
"astro": "^3.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}

View file

@ -12,7 +12,7 @@
},
"dependencies": {
"@astrojs/solid-js": "^3.0.1",
"astro": "^3.1.1",
"astro": "^3.1.2",
"solid-js": "^1.7.11"
}
}

View file

@ -12,7 +12,7 @@
},
"dependencies": {
"@astrojs/svelte": "^4.0.2",
"astro": "^3.1.1",
"astro": "^3.1.2",
"svelte": "^4.2.0"
}
}

View file

@ -12,7 +12,7 @@
},
"dependencies": {
"@astrojs/vue": "^3.0.0",
"astro": "^3.1.1",
"astro": "^3.1.2",
"vue": "^3.3.4"
}
}

View file

@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/node": "^6.0.0",
"astro": "^3.1.1"
"@astrojs/node": "^6.0.1",
"astro": "^3.1.2"
}
}

View file

@ -15,7 +15,7 @@
],
"scripts": {},
"devDependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
},
"peerDependencies": {
"astro": "^2.0.0-beta.0"

View file

@ -12,8 +12,8 @@
"server": "node dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^6.0.0",
"astro": "^3.1.1",
"@astrojs/node": "^6.0.1",
"astro": "^3.1.2",
"html-minifier": "^4.0.0"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -12,9 +12,9 @@
"server": "node dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^6.0.0",
"@astrojs/node": "^6.0.1",
"@astrojs/svelte": "^4.0.2",
"astro": "^3.1.1",
"astro": "^3.1.2",
"svelte": "^4.2.0"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 KiB

After

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View file

@ -12,6 +12,6 @@
},
"dependencies": {
"@astrojs/markdoc": "^0.5.0",
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

View file

@ -12,7 +12,7 @@
},
"dependencies": {
"@astrojs/markdown-remark": "^3.2.0",
"astro": "^3.1.1",
"astro": "^3.1.2",
"hast-util-select": "^5.0.5",
"rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.1.0",

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1"
"astro": "^3.1.2"
}
}

View file

@ -13,7 +13,7 @@
"dependencies": {
"@astrojs/mdx": "^1.1.0",
"@astrojs/preact": "^3.0.0",
"astro": "^3.1.1",
"astro": "^3.1.2",
"preact": "^10.17.1"
}
}

View file

@ -13,7 +13,7 @@
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@nanostores/preact": "^0.5.0",
"astro": "^3.1.1",
"astro": "^3.1.2",
"nanostores": "^0.9.3",
"preact": "^10.17.1"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 KiB

After

Width:  |  Height:  |  Size: 487 KiB

View file

@ -14,7 +14,7 @@
"@astrojs/mdx": "^1.1.0",
"@astrojs/tailwind": "^5.0.0",
"@types/canvas-confetti": "^1.6.0",
"astro": "^3.1.1",
"astro": "^3.1.2",
"autoprefixer": "^10.4.15",
"canvas-confetti": "^1.6.0",
"postcss": "^8.4.28",

View file

@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.1",
"astro": "^3.1.2",
"vite-plugin-pwa": "0.16.4",
"workbox-window": "^7.0.0"
}

View file

@ -12,7 +12,7 @@
"test": "vitest"
},
"dependencies": {
"astro": "^3.1.1",
"astro": "^3.1.2",
"vitest": "^0.34.2"
}
}

View file

@ -1,5 +1,28 @@
# astro
## 3.1.2
### Patch Changes
- [#8612](https://github.com/withastro/astro/pull/8612) [`bcad715ce`](https://github.com/withastro/astro/commit/bcad715ce67bc73a7927c941d1e7f02a82d638c2) Thanks [@matthewp](https://github.com/matthewp)! - Ensure cookies are attached when middleware changes the Response
- [#8598](https://github.com/withastro/astro/pull/8598) [`bdd267d08`](https://github.com/withastro/astro/commit/bdd267d08937611984d074a2872af11ecf3e1a12) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix relative images in Markdown breaking the build process in certain circumstances
- [#8382](https://github.com/withastro/astro/pull/8382) [`e522a5eb4`](https://github.com/withastro/astro/commit/e522a5eb41c7df1e62c307c84cd14d53777439ff) Thanks [@DerTimonius](https://github.com/DerTimonius)! - Do not throw an error for an empty collection directory.
- [#8600](https://github.com/withastro/astro/pull/8600) [`ed54d4644`](https://github.com/withastro/astro/commit/ed54d46449accc99ad117d6b0d50a8905e4d65d7) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Improve config info telemetry
- [#8592](https://github.com/withastro/astro/pull/8592) [`70f2a8003`](https://github.com/withastro/astro/commit/70f2a80039d232731f63ea735e896997ec0eac7a) Thanks [@bluwy](https://github.com/bluwy)! - Fix alias plugin causing CSS ordering issue
- [#8614](https://github.com/withastro/astro/pull/8614) [`4398e9298`](https://github.com/withastro/astro/commit/4398e929877dfadd2067af28413284afdfde9d8b) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue where spaces and unicode characters in project path prevented middleware from running.
- [#8603](https://github.com/withastro/astro/pull/8603) [`8f8b9069d`](https://github.com/withastro/astro/commit/8f8b9069ddd21cf57d37955ab3a92710492226f5) Thanks [@matthewp](https://github.com/matthewp)! - Prevent body scripts from re-executing on navigation
- [#8609](https://github.com/withastro/astro/pull/8609) [`5a988eaf6`](https://github.com/withastro/astro/commit/5a988eaf609ddc1b9609acb0cdc2dda43d10a5c2) Thanks [@bluwy](https://github.com/bluwy)! - Fix Astro HMR from a CSS dependency
- Updated dependencies [[`ed54d4644`](https://github.com/withastro/astro/commit/ed54d46449accc99ad117d6b0d50a8905e4d65d7)]:
- @astrojs/telemetry@3.0.2
## 3.1.1
### Patch Changes

View file

@ -17,18 +17,26 @@ const { fallback = 'animate' } = Astro.props as Props;
index: number;
scrollX: number;
scrollY: number;
intraPage?: boolean;
};
type Events = 'astro:page-load' | 'astro:after-swap';
// only update history entries that are managed by us
// leave other entries alone and do not accidently add state.
const persistState = (state: State) => history.state && history.replaceState(state, '');
// @ts-expect-error: startViewTransition might exist
const supportsViewTransitions = !!document.startViewTransition;
const transitionEnabledOnThisPage = () =>
!!document.querySelector('[name="astro-view-transitions-enabled"]');
const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
const onPageLoad = () => triggerEvent('astro:page-load');
const PERSIST_ATTR = 'data-astro-transition-persist';
const parser = new DOMParser();
// explained at its usage
let noopEl: HTMLDivElement;
if (import.meta.env.DEV) {
noopEl = document.createElement('div');
}
// The History API does not tell you if navigation is forward or back, so
// you can figure it using an index. On pushState the index is incremented so you
@ -40,7 +48,7 @@ const { fallback = 'animate' } = Astro.props as Props;
currentHistoryIndex = history.state.index;
scrollTo({ left: history.state.scrollX, top: history.state.scrollY });
} else if (transitionEnabledOnThisPage()) {
history.replaceState({ index: currentHistoryIndex, scrollX, scrollY }, '');
history.replaceState({ index: currentHistoryIndex, scrollX, scrollY, intraPage: false }, '');
}
const throttle = (cb: (...args: any[]) => any, delay: number) => {
let wait = false;
@ -64,19 +72,28 @@ const { fallback = 'animate' } = Astro.props as Props;
};
};
async function getHTML(href: string) {
// returns the contents of the page or null if the router can't deal with it.
async function fetchHTML(
href: string
): Promise<null | { html: string; redirected?: string; mediaType: DOMParserSupportedType }> {
try {
const res = await fetch(href);
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
const mediaType = res.headers.get('content-type')?.replace(/;.*$/, '');
// the DOMParser can handle two types of HTML
if (mediaType !== 'text/html' && mediaType !== 'application/xhtml+xml') {
// everything else (e.g. audio/mp3) will be handled by the browser but not by us
return null;
}
const html = await res.text();
return {
ok: res.ok,
html,
redirected: res.redirected ? res.url : undefined,
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
mediaType: res.headers.get('content-type')?.replace(/;.*$/, ''),
mediaType,
};
} catch (err) {
return { ok: false };
// can't fetch, let someone else deal with it.
return null;
}
}
@ -98,19 +115,19 @@ const { fallback = 'animate' } = Astro.props as Props;
let wait = Promise.resolve();
for (const script of Array.from(document.scripts)) {
if (script.dataset.astroExec === '') continue;
const s = document.createElement('script');
s.innerHTML = script.innerHTML;
const newScript = document.createElement('script');
newScript.innerHTML = script.innerHTML;
for (const attr of script.attributes) {
if (attr.name === 'src') {
const p = new Promise((r) => {
s.onload = r;
newScript.onload = r;
});
wait = wait.then(() => p as any);
}
s.setAttribute(attr.name, attr.value);
newScript.setAttribute(attr.name, attr.value);
}
s.dataset.astroExec = '';
script.replaceWith(s);
newScript.dataset.astroExec = '';
script.replaceWith(newScript);
}
return wait;
}
@ -122,46 +139,60 @@ const { fallback = 'animate' } = Astro.props as Props;
return style.animationIterationCount === 'infinite';
}
const parser = new DOMParser();
const updateHistoryAndScrollPosition = (toLocation) => {
if (toLocation.href !== location.href) {
history.pushState(
{ index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
'',
toLocation.href
);
// now we are on the new page for non-history navigations!
// (with history navigation page change happens before popstate is fired)
}
// freshly loaded pages start from the top
scrollTo({ left: 0, top: 0, behavior: 'instant' });
// A noop element used to prevent styles from being removed
if (import.meta.env.DEV) {
var noopEl = document.createElement('div');
}
if (toLocation.hash) {
// because we are already on the target page ...
// ... what comes next is a intra-page navigation
// that won't reload the page but instead scroll to the fragment
location.href = toLocation.href;
}
};
async function updateDOM(doc: Document, loc: URL, state?: State, fallback?: Fallback) {
// Check for a head element that should persist, either because it has the data
// attribute or is a link el.
// replace head and body of the windows document with contents from newDocument
// if !popstate, update the history entry and scroll position according to toLocation
// if popState is given, this holds the scroll position for history navigation
// if fallback === "animate" then simulate view transitions
async function updateDOM(
newDocument: Document,
toLocation: URL,
popState?: State,
fallback?: Fallback
) {
// Check for a head element that should persist and returns it,
// either because it has the data attribute or is a link el.
const persistedHeadElement = (el: HTMLElement): Element | null => {
const id = el.getAttribute(PERSIST_ATTR);
const newEl = id && doc.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
const newEl = id && newDocument.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
if (newEl) {
return newEl;
}
if (el.matches('link[rel=stylesheet]')) {
const href = el.getAttribute('href');
return doc.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
return newDocument.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
}
if (el.tagName === 'SCRIPT') {
let s1 = el as HTMLScriptElement;
for (const s2 of doc.scripts) {
if (
// Inline
(s1.textContent && s1.textContent === s2.textContent) ||
// External
(s1.type === s2.type && s1.src === s2.src)
) {
return s2;
}
}
}
// Only run this in dev. This will get stripped from production builds and is not needed.
// What follows is a fix for an issue (#8472) with missing client:only styles after transition.
// That problem exists only in dev mode where styles are injected into the page by Vite.
// Returning a noop element ensures that the styles are not removed from the old document.
// Guarding the code below with the dev mode check
// allows tree shaking to remove this code in production.
if (import.meta.env.DEV) {
if (el.tagName === 'STYLE' && el.dataset.viteDevId) {
const devId = el.dataset.viteDevId;
// If this same style tag exists, remove it from the new page
return (
doc.querySelector(`style[data-astro-dev-id="${devId}"]`) ||
newDocument.querySelector(`style[data-astro-dev-id="${devId}"]`) ||
// Otherwise, keep it anyways. This is client:only styles.
noopEl
);
@ -171,10 +202,6 @@ const { fallback = 'animate' } = Astro.props as Props;
};
const swap = () => {
// noscript tags inside head element are not honored on swap (#7969).
// Remove them before swapping.
doc.querySelectorAll('head noscript').forEach((el) => el.remove());
// swap attributes of the html element
// - delete all attributes from the current document
// - insert all attributes from doc
@ -183,10 +210,26 @@ const { fallback = 'animate' } = Astro.props as Props;
const astro = [...html.attributes].filter(
({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-'))
);
[...doc.documentElement.attributes, ...astro].forEach(({ name, value }) =>
[...newDocument.documentElement.attributes, ...astro].forEach(({ name, value }) =>
html.setAttribute(name, value)
);
// Replace scripts in both the head and body.
for (const s1 of document.scripts) {
for (const s2 of newDocument.scripts) {
if (
// Inline
(s1.textContent && s1.textContent === s2.textContent) ||
// External
(s1.type === s2.type && s1.src === s2.src)
) {
s2.remove();
} else {
s1.remove();
}
}
}
// Swap head
for (const el of Array.from(document.head.children)) {
const newEl = persistedHeadElement(el as HTMLElement);
@ -199,12 +242,15 @@ const { fallback = 'animate' } = Astro.props as Props;
el.remove();
}
}
// Everything left in the new head is new, append it all.
document.head.append(...doc.head.children);
document.head.append(...newDocument.head.children);
// Persist elements in the existing body
const oldBody = document.body;
document.body.replaceWith(doc.body);
// this will reset scroll Position
document.body.replaceWith(newDocument.body);
for (const el of oldBody.querySelectorAll(`[${PERSIST_ATTR}]`)) {
const id = el.getAttribute(PERSIST_ATTR);
const newEl = document.querySelector(`[${PERSIST_ATTR}="${id}"]`);
@ -215,39 +261,18 @@ const { fallback = 'animate' } = Astro.props as Props;
}
}
// Simulate scroll behavior of Safari and
// Chromium based browsers (Chrome, Edge, Opera, ...)
scrollTo({ left: 0, top: 0, behavior: 'instant' });
let initialScrollX = 0;
let initialScrollY = 0;
if (!state && loc.hash) {
const id = decodeURIComponent(loc.hash.slice(1));
const elem = document.getElementById(id);
// prefer scrollIntoView() over scrollTo() because it takes scroll-padding into account
if (elem) {
elem.scrollIntoView();
initialScrollX = Math.max(
0,
elem.offsetLeft + elem.offsetWidth - document.documentElement.clientWidth
);
initialScrollY = elem.offsetTop;
}
} else if (state) {
scrollTo(state.scrollX, state.scrollY); // usings default scrollBehavior
if (popState) {
scrollTo(popState.scrollX, popState.scrollY); // usings 'auto' scrollBehavior
} else {
updateHistoryAndScrollPosition(toLocation);
}
!state &&
history.pushState(
{ index: ++currentHistoryIndex, scrollX: initialScrollX, scrollY: initialScrollY },
'',
loc.href
);
triggerEvent('astro:after-swap');
};
// Wait on links to finish, to prevent FOUC
const links: Promise<any>[] = [];
for (const el of doc.querySelectorAll('head link[rel=stylesheet]')) {
for (const el of newDocument.querySelectorAll('head link[rel=stylesheet]')) {
// Do not preload links that are already on the page.
if (
!document.querySelector(
@ -287,32 +312,44 @@ const { fallback = 'animate' } = Astro.props as Props;
}
}
async function navigate(dir: Direction, loc: URL, state?: State) {
async function transition(direction: Direction, toLocation: URL, popState?: State) {
let finished: Promise<void>;
const href = loc.href;
const { html, ok, mediaType, redirected } = await getHTML(href);
// if there was a redirection, show the final URL in the browser's address bar
redirected && (loc = new URL(redirected));
const href = toLocation.href;
const response = await fetchHTML(href);
// If there is a problem fetching the new page, just do an MPA navigation to it.
if (!ok || !(mediaType === 'text/html' || mediaType === 'application/xhtml+xml')) {
if (response === null) {
location.href = href;
return;
}
// if there was a redirection, show the final URL in the browser's address bar
if (response.redirected) {
toLocation = new URL(response.redirected);
}
const newDocument = parser.parseFromString(response.html, response.mediaType);
// The next line might look like a hack,
// but it is actually necessary as noscript elements
// and their contents are returned as markup by the parser,
// see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
newDocument.querySelectorAll('noscript').forEach((el) => el.remove());
if (!newDocument.querySelector('[name="astro-view-transitions-enabled"]')) {
location.href = href;
return;
}
const doc = parser.parseFromString(html, mediaType);
if (!doc.querySelector('[name="astro-view-transitions-enabled"]')) {
location.href = href;
return;
if (!popState) {
// save the current scroll position before we change the DOM and transition to the new page
history.replaceState({ ...history.state, scrollX, scrollY }, '');
}
// Now we are sure that we will push state, and it is time to create a state if it is still missing.
!state && history.replaceState({ index: currentHistoryIndex, scrollX, scrollY }, '');
document.documentElement.dataset.astroTransition = dir;
document.documentElement.dataset.astroTransition = direction;
if (supportsViewTransitions) {
finished = document.startViewTransition(() => updateDOM(doc, loc, state)).finished;
// @ts-expect-error: startViewTransition exist
finished = document.startViewTransition(() =>
updateDOM(newDocument, toLocation, popState)
).finished;
} else {
finished = updateDOM(doc, loc, state, getFallback());
finished = updateDOM(newDocument, toLocation, popState, getFallback());
}
try {
await finished;
@ -328,7 +365,9 @@ const { fallback = 'animate' } = Astro.props as Props;
// Prefetching
function maybePrefetch(pathname: string) {
if (document.querySelector(`link[rel=prefetch][href="${pathname}"]`)) return;
// @ts-expect-error: connection might exist
if (navigator.connection) {
// @ts-expect-error: connection does exist
let conn = navigator.connection;
if (conn.saveData || /(2|3)g/.test(conn.effectiveType || '')) return;
}
@ -339,8 +378,6 @@ const { fallback = 'animate' } = Astro.props as Props;
}
if (supportsViewTransitions || getFallback() !== 'none') {
markScriptsExec();
document.addEventListener('click', (ev) => {
let link = ev.target;
if (link instanceof Element && link.tagName !== 'A') {
@ -362,51 +399,59 @@ const { fallback = 'animate' } = Astro.props as Props;
ev.ctrlKey || // new tab (windows)
ev.altKey || // download
ev.shiftKey || // new window
ev.defaultPrevented ||
!transitionEnabledOnThisPage()
ev.defaultPrevented
) {
// No page transitions in these cases,
// Let the browser standard action handle this
return;
}
// We do not need to handle same page links because there are no page transitions
// Same page means same path and same query params (but different hash)
if (location.pathname === link.pathname && location.search === link.search) {
if (link.hash) {
// The browser default action will handle navigations with hash fragments
return;
} else {
// Special case: self link without hash
// If handed to the browser it will reload the page
// But we want to handle it like any other same page navigation
// So we scroll to the top of the page but do not start page transitions
ev.preventDefault();
// push state on the first navigation but not if we were here already
if (location.hash) {
history.replaceState(
{ index: currentHistoryIndex, scrollX, scrollY: -(scrollY + 1) },
''
);
const newState: State = { index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 };
history.pushState(newState, '', link.href);
}
scrollTo({ left: 0, top: 0, behavior: 'instant' });
return;
}
}
// these are the cases we will handle: same origin, different page
ev.preventDefault();
navigate('forward', new URL(link.href));
navigate(link.href);
});
function navigate(href) {
// not ours
if (!transitionEnabledOnThisPage()) {
location.href = href;
return;
}
const toLocation = new URL(href, location.href);
// We do not have page transitions on navigations to the same page (intra-page navigation)
// but we want to handle prevent reload on navigation to the same page
// Same page means same origin, path and query params (but maybe different hash)
if (
location.origin === toLocation.origin &&
location.pathname === toLocation.pathname &&
location.search === toLocation.search
) {
// mark current position as non transition intra-page scrolling
if (location.href !== toLocation.href) {
history.replaceState({ ...history.state, intraPage: true }, '');
history.pushState(
{ index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
'',
toLocation.href
);
}
if (toLocation.hash) {
location.href = toLocation.href;
} else {
scrollTo({ left: 0, top: 0, behavior: 'instant' });
}
} else {
transition('forward', toLocation);
}
}
addEventListener('popstate', (ev) => {
if (!transitionEnabledOnThisPage() && ev.state) {
// The current page doesn't have View Transitions enabled
// but the page we navigate to does (because it set the state).
// Do a full page refresh to reload the client-side router from the new page.
// Scroll restauration will then happen during the reload when the router's code is re-executed
history.scrollRestoration && (history.scrollRestoration = 'manual');
if (history.scrollRestoration) {
history.scrollRestoration = 'manual';
}
location.reload();
return;
}
@ -429,13 +474,14 @@ const { fallback = 'animate' } = Astro.props as Props;
}
const state: State = history.state;
const nextIndex = state.index;
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
currentHistoryIndex = nextIndex;
if (state.scrollY < 0) {
scrollTo(state.scrollX, -(state.scrollY + 1));
if (state.intraPage) {
// this is non transition intra-page scrolling
scrollTo(state.scrollX, state.scrollY);
} else {
navigate(direction, new URL(location.href), state);
const nextIndex = state.index;
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
currentHistoryIndex = nextIndex;
transition(direction, new URL(location.href), state);
}
});
@ -457,6 +503,7 @@ const { fallback = 'animate' } = Astro.props as Props;
{ passive: true, capture: true }
);
});
addEventListener('load', onPageLoad);
// There's not a good way to record scroll position before a back button.
// So the way we do it is by listening to scrollend if supported, and if not continuously record the scroll position.
@ -466,5 +513,7 @@ const { fallback = 'animate' } = Astro.props as Props;
if ('onscrollend' in window) addEventListener('scrollend', updateState);
else addEventListener('scroll', throttle(updateState, 300));
markScriptsExec();
}
</script>

View file

@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import { getColor, testFactory } from './test-utils.js';
import { testFactory } from './test-utils.js';
const test = testFactory({ root: './fixtures/astro-component/' });
@ -99,7 +99,7 @@ test.describe('Astro component HMR', () => {
test('update linked dep Astro style', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));
let h1 = page.locator('#astro-linked-lib');
expect(await getColor(h1)).toBe('rgb(255, 0, 0)');
await expect(h1).toHaveCSS('color', 'rgb(255, 0, 0)');
await Promise.all([
page.waitForLoadState('networkidle'),
await astro.editFile('../_deps/astro-linked-lib/Component.astro', (content) =>
@ -107,6 +107,6 @@ test.describe('Astro component HMR', () => {
),
]);
h1 = page.locator('#astro-linked-lib');
expect(await getColor(h1)).toBe('rgb(0, 128, 0)');
await expect(h1).toHaveCSS('color', 'rgb(0, 128, 0)');
});
});

View file

@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import { getColor, testFactory } from './test-utils.js';
import { testFactory } from './test-utils.js';
const test = testFactory({
root: './fixtures/css/',
@ -20,13 +20,13 @@ test.describe('CSS HMR', () => {
await page.goto(astro.resolveUrl('/'));
const h = page.locator('h1');
expect(await getColor(h)).toBe('rgb(255, 0, 0)');
await expect(h).toHaveCSS('color', 'rgb(255, 0, 0)');
await astro.editFile('./src/styles/main.css', (original) =>
original.replace('--h1-color: red;', '--h1-color: green;')
);
expect(await getColor(h)).toBe('rgb(0, 128, 0)');
await expect(h).toHaveCSS('color', 'rgb(0, 128, 0)');
});
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => {

View file

@ -1,8 +1,9 @@
{
"name": "@e2e/invalidate-script-deps",
"name": "@e2e/hmr",
"version": "0.0.0",
"private": true,
"devDependencies": {
"astro": "workspace:*"
"astro": "workspace:*",
"sass": "^1.66.1"
}
}

View file

@ -0,0 +1,14 @@
<html>
<head>
<title>Test</title>
</head>
<body>
<h1 class="css-dep">This is blue</h1>
<style lang="scss">
@use "../styles/vars.scss" as *;
.css-dep {
color: $color;
}
</style>
</body>
</html>

View file

@ -0,0 +1 @@
$color: blue;

View file

@ -1,13 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="363" height="102" viewBox="0 0 363 102" fill="none" aria-hidden="true" class="astro-2W66RQV5">
<style>
.text {
fill: white;
}
.hover {
fill: white;
}
</style>
<path class="text astro-2W66RQV5" fill-rule="evenodd" d="M55.07 14.216l16.81 54.865a72.6 72.6 0 00-20.765-6.984L39.808 24.135a1.475 1.475 0 00-2.827.005L25.81 62.078a72.598 72.598 0 00-20.859 6.995L21.847 14.2c.998-3.243 1.497-4.865 2.47-6.066a8 8 0 013.239-2.392c1.434-.576 3.13-.576 6.524-.576h8.751c3.398 0 5.097 0 6.532.577a8 8 0 013.241 2.397c.972 1.203 1.47 2.827 2.465 6.076z" clip-rule="evenodd"></path>
<path fill="#FF5D01" fill-rule="evenodd" d="M54.618 71.779c-2.863 2.432-8.578 4.091-15.161 4.091-8.08 0-14.852-2.499-16.649-5.86-.642 1.926-.786 4.13-.786 5.539 0 0-.423 6.915 4.418 11.725 0-2.498 2.037-4.522 4.551-4.522 4.309 0 4.304 3.734 4.3 6.764v.27c0 4.6 2.829 8.541 6.852 10.203a9.22 9.22 0 01-.938-4.064c0-4.386 2.592-6.02 5.604-7.917 2.396-1.51 5.06-3.188 6.894-6.554a12.297 12.297 0 001.502-5.905c0-1.314-.206-2.581-.587-3.77z" clip-rule="evenodd" class="astro-2W66RQV5"></path>
<path class="text astro-2W66RQV5" d="M126.554 69c13.115 0 21.047-3.14 25.68-9.654 0 2.904.157 5.651.55 8.163h7.774c-.706-4.082-.863-6.75-.863-14.128V43.334c0-10.831-8.403-16.56-24.424-16.56-15.47 0-25.522 5.964-26.779 14.598h8.246c1.256-5.808 7.774-8.87 18.533-8.87 10.602 0 16.885 3.69 16.885 9.969v.785l-24.502 1.413c-9.974.549-13.665 1.962-16.492 4.003-2.67 1.962-4.162 5.023-4.162 8.555C107 64.683 114.696 69 126.554 69zm2.513-5.573c-9.109 0-14.135-2.119-14.135-6.357 0-4.553 3.141-6.593 14.214-7.3l23.01-1.412v1.805c0 8.241-9.66 13.264-23.089 13.264zM196.086 69c16.256 0 22.775-5.337 22.775-13.108 0-6.436-4.006-9.732-14.215-10.596l-19.083-1.49c-5.183-.393-8.088-1.884-8.088-5.102 0-4.082 4.476-6.201 14.135-6.201 10.995 0 16.727 2.198 20.497 7.064l6.361-3.061c-3.927-6.122-12.644-9.733-26.151-9.733-13.9 0-22.224 4.631-22.224 12.244 0 6.829 4.947 10.125 14.292 10.91l18.926 1.492c6.204.47 8.089 1.726 8.089 4.944 0 4.631-4.79 6.829-14.293 6.829-11.544 0-18.847-3.14-22.381-8.87l-6.204 3.376C173.312 64.918 181.715 69 196.086 69zM234.929 34.151v18.916c0 7.77 2.67 15.54 17.198 15.54 3.691 0 8.167-.706 10.131-1.57V60.68c-2.749.628-6.047 1.1-9.267 1.1-6.832 0-10.523-2.67-10.523-9.42V34.151h19.633v-5.887h-19.633V15l-7.539 3.061v10.204h-12.33v5.886h12.33zM280.823 28.265h-6.911v39.244h7.461V52.83c0-5.65 1.099-10.439 4.24-13.735 2.749-3.061 6.283-4.788 12.487-4.788 2.12 0 3.455.157 5.262.471v-7.22c-1.65-.393-3.063-.472-5.184-.472-8.402 0-15.078 4.945-17.355 12.558v-11.38zM334.807 69C351.534 69 363 60.523 363 47.887c0-12.637-11.466-21.114-28.193-21.114-16.727 0-28.193 8.477-28.193 21.114C306.614 60.523 318.08 69 334.807 69zm0-6.2c-12.329 0-20.261-5.809-20.261-14.913 0-9.105 7.932-14.913 20.261-14.913 12.251 0 20.261 5.808 20.261 14.913 0 9.104-8.01 14.912-20.261 14.912z"></path>
</svg>
<svg fill="none" height="102" viewBox="0 0 363 102" width="363" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m55.07 14.216 16.81 54.865a72.6 72.6 0 0 0 -20.765-6.984l-11.307-37.962a1.475 1.475 0 0 0 -2.827.005l-11.171 37.938a72.598 72.598 0 0 0 -20.859 6.995l16.896-54.873c.998-3.243 1.497-4.865 2.47-6.066a8 8 0 0 1 3.239-2.392c1.434-.576 3.13-.576 6.524-.576h8.751c3.398 0 5.097 0 6.532.577a8 8 0 0 1 3.241 2.397c.972 1.203 1.47 2.827 2.465 6.076z" fill="#fff" fill-rule="evenodd"/><path clip-rule="evenodd" d="m54.618 71.779c-2.863 2.432-8.578 4.091-15.161 4.091-8.08 0-14.852-2.499-16.649-5.86-.642 1.926-.786 4.13-.786 5.539 0 0-.423 6.915 4.418 11.725 0-2.498 2.037-4.522 4.551-4.522 4.309 0 4.304 3.734 4.3 6.764v.27c0 4.6 2.829 8.541 6.852 10.203a9.22 9.22 0 0 1 -.938-4.064c0-4.386 2.592-6.02 5.604-7.917 2.396-1.51 5.06-3.188 6.894-6.554a12.297 12.297 0 0 0 1.502-5.905c0-1.314-.206-2.581-.587-3.77z" fill="#ff5d01" fill-rule="evenodd"/><path d="m126.554 69c13.115 0 21.047-3.14 25.68-9.654 0 2.904.157 5.651.55 8.163h7.774c-.706-4.082-.863-6.75-.863-14.128v-10.047c0-10.831-8.403-16.56-24.424-16.56-15.47 0-25.522 5.964-26.779 14.598h8.246c1.256-5.808 7.774-8.87 18.533-8.87 10.602 0 16.885 3.69 16.885 9.969v.785l-24.502 1.413c-9.974.549-13.665 1.962-16.492 4.003-2.67 1.962-4.162 5.023-4.162 8.555 0 7.456 7.696 11.773 19.554 11.773zm2.513-5.573c-9.109 0-14.135-2.119-14.135-6.357 0-4.553 3.141-6.593 14.214-7.3l23.01-1.412v1.805c0 8.241-9.66 13.264-23.089 13.264zm67.019 5.573c16.256 0 22.775-5.337 22.775-13.108 0-6.436-4.006-9.732-14.215-10.596l-19.083-1.49c-5.183-.393-8.088-1.884-8.088-5.102 0-4.082 4.476-6.201 14.135-6.201 10.995 0 16.727 2.198 20.497 7.064l6.361-3.061c-3.927-6.122-12.644-9.733-26.151-9.733-13.9 0-22.224 4.631-22.224 12.244 0 6.829 4.947 10.125 14.292 10.91l18.926 1.492c6.204.47 8.089 1.726 8.089 4.944 0 4.631-4.79 6.829-14.293 6.829-11.544 0-18.847-3.14-22.381-8.87l-6.204 3.376c4.79 7.22 13.193 11.302 27.564 11.302zm38.843-34.849v18.916c0 7.77 2.67 15.54 17.198 15.54 3.691 0 8.167-.706 10.131-1.57v-6.357c-2.749.628-6.047 1.1-9.267 1.1-6.832 0-10.523-2.67-10.523-9.42v-18.209h19.633v-5.887h-19.633v-13.264l-7.539 3.061v10.204h-12.33v5.886zm45.894-5.886h-6.911v39.244h7.461v-14.679c0-5.65 1.099-10.439 4.24-13.735 2.749-3.061 6.283-4.788 12.487-4.788 2.12 0 3.455.157 5.262.471v-7.22c-1.65-.393-3.063-.472-5.184-.472-8.402 0-15.078 4.945-17.355 12.558v-11.38zm53.984 40.735c16.727 0 28.193-8.477 28.193-21.113 0-12.637-11.466-21.114-28.193-21.114s-28.193 8.477-28.193 21.114c0 12.636 11.466 21.113 28.193 21.113zm0-6.2c-12.329 0-20.261-5.809-20.261-14.913 0-9.105 7.932-14.913 20.261-14.913 12.251 0 20.261 5.808 20.261 14.913 0 9.104-8.01 14.912-20.261 14.912z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 KiB

After

Width:  |  Height:  |  Size: 311 KiB

View file

@ -0,0 +1,9 @@
<div id="counter">Count</div>
<script is:inline>
let count = 1;
const onAfterSwap = () => {
count++;
document.querySelector('#counter').textContent = `Count: ${count}`;
}
document.addEventListener('astro:page-load', onAfterSwap);
</script>

View file

@ -11,4 +11,5 @@ import Layout from '../components/Layout.astro';
</a>
<a id="click-two" href="/two" data-astro-reload>load page / no navigation</a>
<a id="click-logo" href="/logo.svg" download>load page / no navigation</a>
<a id="click-svg" href="/logo.svg">load page / no navigation</a>
</Layout>

View file

@ -0,0 +1,8 @@
---
import Layout from '../components/Layout.astro';
import InlineScript from '../components/InlineScript.astro';
---
<Layout>
<InlineScript />
<a id="click-one" href="/inline-script-two">Go to 2</a>
</Layout>

View file

@ -0,0 +1,8 @@
---
import Layout from '../components/Layout.astro';
import InlineScript from '../components/InlineScript.astro';
---
<Layout>
<InlineScript />
<a id="click-two" href="/inline-script-one">Go to 1</a>
</Layout>

View file

@ -2,7 +2,7 @@ import { expect } from '@playwright/test';
import { testFactory } from './test-utils.js';
const test = testFactory({
root: './fixtures/invalidate-script-deps/',
root: './fixtures/hmr/',
});
let devServer;
@ -17,7 +17,7 @@ test.afterAll(async () => {
test.describe('Scripts with dependencies', () => {
test('refresh with HMR', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));
await page.goto(astro.resolveUrl('/script-dep'));
const h = page.locator('h1');
await expect(h, 'original text set').toHaveText('before');
@ -29,3 +29,16 @@ test.describe('Scripts with dependencies', () => {
await expect(h, 'text changed').toHaveText('after');
});
});
test.describe('Styles with dependencies', () => {
test('refresh with HMR', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/css-dep'));
const h = page.locator('h1');
await expect(h).toHaveCSS('color', 'rgb(0, 0, 255)');
await astro.editFile('./src/styles/vars.scss', (original) => original.replace('blue', 'red'));
await expect(h).toHaveCSS('color', 'rgb(255, 0, 0)');
});
});

View file

@ -71,13 +71,6 @@ export async function getErrorOverlayContent(page) {
return { message, hint, absoluteFileLocation, fileLocation };
}
/**
* @returns {Promise<string>}
*/
export async function getColor(el) {
return await el.evaluate((e) => getComputedStyle(e).color);
}
/**
* Wait for `astro-island` that contains the `el` to hydrate
* @param {import('@playwright/test').Page} page

View file

@ -293,12 +293,12 @@ test.describe('View Transitions', () => {
locator = page.locator('#click-one-again');
await expect(locator).toBeInViewport();
// Scroll up to top fragment
// goto page 1
await page.click('#click-one-again');
locator = page.locator('#one');
await expect(locator).toHaveText('Page 1');
// Back to middle of the page
// Back to middle of the previous page
await page.goBack();
locator = page.locator('#click-one-again');
await expect(locator).toBeInViewport();
@ -520,6 +520,22 @@ test.describe('View Transitions', () => {
await downloadPromise;
});
test('data-astro-reload not required for non-html content', async ({ page, astro }) => {
const loads = [];
page.addListener('load', (p) => {
loads.push(p.title());
});
// Go to page 4
await page.goto(astro.resolveUrl('/four'));
let p = page.locator('#four');
await expect(p, 'should have content').toHaveText('Page 4');
await page.click('#click-svg');
p = page.locator('svg');
await expect(p).toBeVisible();
expect(loads.length, 'There should be 2 page load').toEqual(2);
});
test('Scroll position is restored on back navigation from page w/o ViewTransitions', async ({
page,
astro,
@ -663,4 +679,22 @@ test.describe('View Transitions', () => {
locator = page.locator('#click-one');
await expect(locator).not.toBeInViewport();
});
test('body inline scripts do not re-execute on navigation', async ({ page, astro }) => {
const errors = [];
page.addListener('pageerror', (err) => {
errors.push(err);
});
await page.goto(astro.resolveUrl('/inline-script-one'));
let article = page.locator('#counter');
await expect(article, 'should have script content').toBeVisible('exists');
await page.click('#click-one');
article = page.locator('#counter');
await expect(article, 'should have script content').toHaveText('Count: 3');
expect(errors).toHaveLength(0);
});
});

View file

@ -1,6 +1,6 @@
{
"name": "astro",
"version": "3.1.1",
"version": "3.1.2",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
"type": "module",
"author": "withastro",

View file

@ -29,8 +29,11 @@ const qualityTable: Record<
// Squoosh's PNG encoder does not support a quality setting, so we can skip that here
};
async function getRotationForEXIF(inputBuffer: Buffer): Promise<Operation | undefined> {
const meta = await imageMetadata(inputBuffer);
async function getRotationForEXIF(
inputBuffer: Buffer,
src?: string
): Promise<Operation | undefined> {
const meta = await imageMetadata(inputBuffer, src);
if (!meta) return undefined;
// EXIF orientations are a bit hard to read, but the numbers are actually standard. See https://exiftool.org/TagNames/EXIF.html for a list.
@ -64,7 +67,7 @@ const service: LocalImageService = {
const operations: Operation[] = [];
const rotation = await getRotationForEXIF(inputBuffer);
const rotation = await getRotationForEXIF(inputBuffer, transform.src);
if (rotation) {
operations.push(rotation);

View file

@ -22,11 +22,7 @@ export async function emitESMImage(
return undefined;
}
const fileMetadata = await imageMetadata(fileData);
if (!fileMetadata) {
return undefined;
}
const fileMetadata = await imageMetadata(fileData, id);
const emittedImage: ImageMetadata = {
src: '',

View file

@ -1,19 +1,23 @@
import probe from 'probe-image-size';
import { AstroError, AstroErrorData } from '../../core/errors/index.js';
import type { ImageInputFormat, ImageMetadata } from '../types.js';
export async function imageMetadata(data: Buffer): Promise<Omit<ImageMetadata, 'src'> | undefined> {
export async function imageMetadata(
data: Buffer,
src?: string
): Promise<Omit<ImageMetadata, 'src'>> {
const result = probe.sync(data);
if (result === null) {
throw new Error('Failed to probe image size.');
throw new AstroError({
...AstroErrorData.NoImageMetadata,
message: AstroErrorData.NoImageMetadata.message(src),
});
}
const { width, height, type, orientation } = result;
const isPortrait = (orientation || 0) >= 5;
if (!width || !height || !type) {
return undefined;
}
return {
width: isPortrait ? height : width,
height: isPortrait ? width : height,

View file

@ -2,6 +2,8 @@ import MagicString from 'magic-string';
import type * as vite from 'vite';
import { normalizePath } from 'vite';
import type { AstroPluginOptions, ImageTransform } from '../@types/astro.js';
import { extendManualChunks } from '../core/build/plugins/util.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js';
import {
appendForwardSlash,
joinPaths,
@ -28,6 +30,18 @@ export default function assets({
// Expose the components and different utilities from `astro:assets` and handle serving images from `/_image` in dev
{
name: 'astro:assets',
outputOptions(outputOptions) {
// Specifically split out chunk for asset files to prevent TLA deadlock
// caused by `getImage()` for markdown components.
// https://github.com/rollup/rollup/issues/4708
extendManualChunks(outputOptions, {
after(id) {
if (id.includes('astro/dist/assets/services/')) {
return `astro-assets-services`;
}
},
});
},
async resolveId(id) {
if (id === VIRTUAL_SERVICE_ID) {
return await this.resolve(settings.config.image.service.entrypoint);
@ -126,6 +140,14 @@ export default function assets({
}
if (assetRegex.test(id)) {
const meta = await emitESMImage(id, this.meta.watchMode, this.emitFile);
if (!meta) {
throw new AstroError({
...AstroErrorData.ImageNotFound,
message: AstroErrorData.ImageNotFound.message(id),
});
}
return `export default ${JSON.stringify(meta)}`;
}
},

View file

@ -9,7 +9,12 @@ import ora from 'ora';
import preferredPM from 'preferred-pm';
import prompts from 'prompts';
import type yargs from 'yargs-parser';
import { loadTSConfig, resolveConfigPath, resolveRoot } from '../../core/config/index.js';
import {
loadTSConfig,
resolveConfig,
resolveConfigPath,
resolveRoot,
} from '../../core/config/index.js';
import {
defaultTSConfig,
presets,
@ -23,7 +28,7 @@ import { appendForwardSlash } from '../../core/path.js';
import { apply as applyPolyfill } from '../../core/polyfill.js';
import { parseNpmName } from '../../core/util.js';
import { eventCliSession, telemetry } from '../../events/index.js';
import { createLoggerFromFlags } from '../flags.js';
import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js';
import { generate, parse, t, visit } from './babel.js';
import { ensureImport } from './imports.js';
import { wrapDefaultExport } from './wrapper.js';
@ -87,7 +92,9 @@ async function getRegistry(): Promise<string> {
}
export async function add(names: string[], { flags }: AddOptions) {
telemetry.record(eventCliSession('add'));
const inlineConfig = flagsToAstroInlineConfig(flags);
const { userConfig } = await resolveConfig(inlineConfig, 'add');
telemetry.record(eventCliSession('add', userConfig));
applyPolyfill();
if (flags.help || names.length === 0) {
printHelp({

View file

@ -1,5 +1,6 @@
import type { MarkdownHeading } from '@astrojs/markdown-remark';
import { ZodIssueCode, string as zodString } from 'zod';
import type { AstroIntegration } from '../@types/astro.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js';
import { prependForwardSlash } from '../core/path.js';
import {
@ -55,10 +56,7 @@ export function createGetCollection({
} else if (collection in dataCollectionToEntryMap) {
type = 'data';
} else {
throw new AstroError({
...AstroErrorData.CollectionDoesNotExistError,
message: AstroErrorData.CollectionDoesNotExistError.message(collection),
});
return warnOfEmptyCollection(collection);
}
const lazyImports = Object.values(
type === 'content'
@ -392,3 +390,16 @@ type PropagatedAssetsModule = {
function isPropagatedAssetsModule(module: any): module is PropagatedAssetsModule {
return typeof module === 'object' && module != null && '__astroPropagation' in module;
}
function warnOfEmptyCollection(collection: string): AstroIntegration {
return {
name: 'astro-collection',
hooks: {
'astro:server:start': ({ logger }) => {
logger.warn(
`The collection **${collection}** does not exist or is empty. Ensure a collection directory with this name exists.`
);
},
},
};
}

View file

@ -25,7 +25,7 @@ export function vitePluginMiddleware(
async resolveId(id) {
if (id === MIDDLEWARE_MODULE_ID) {
const middlewareId = await this.resolve(
`${opts.settings.config.srcDir.pathname}/${MIDDLEWARE_PATH_SEGMENT_NAME}`
`${decodeURI(opts.settings.config.srcDir.pathname)}${MIDDLEWARE_PATH_SEGMENT_NAME}`
);
if (middlewareId) {
resolvedMiddlewareId = middlewareId.id;

View file

@ -140,7 +140,6 @@ export const AstroConfigSchema = z.object({
.optional()
.default(ASTRO_CONFIG_DEFAULTS.build.excludeMiddleware),
})
.optional()
.default({}),
server: z.preprocess(
// preprocess
@ -158,7 +157,6 @@ export const AstroConfigSchema = z.object({
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
headers: z.custom<OutgoingHttpHeaders>().optional(),
})
.optional()
.default({})
),
redirects: z
@ -274,27 +272,11 @@ export const AstroConfigSchema = z.object({
.optional()
.default(ASTRO_CONFIG_DEFAULTS.experimental.optimizeHoistedScript),
})
.passthrough()
.refine(
(d) => {
const validKeys = Object.keys(ASTRO_CONFIG_DEFAULTS.experimental);
const invalidKeys = Object.keys(d).filter((key) => !validKeys.includes(key));
if (invalidKeys.length > 0) return false;
return true;
},
(d) => {
const validKeys = Object.keys(ASTRO_CONFIG_DEFAULTS.experimental);
const invalidKeys = Object.keys(d).filter((key) => !validKeys.includes(key));
return {
message: `Invalid experimental key: \`${invalidKeys.join(
', '
)}\`. \nMake sure the spelling is correct, and that your Astro version supports this experiment.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for more information.`,
};
}
.strict(
`Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.`
)
.optional()
.default({}),
legacy: z.object({}).optional().default({}),
legacy: z.object({}).default({}),
});
export type AstroConfigType = z.infer<typeof AstroConfigSchema>;

View file

@ -1,2 +1,6 @@
export { AstroCookies } from './cookies.js';
export { attachCookiesToResponse, getSetCookiesFromResponse } from './response.js';
export {
attachCookiesToResponse,
getSetCookiesFromResponse,
responseHasCookies,
} from './response.js';

View file

@ -6,6 +6,10 @@ export function attachCookiesToResponse(response: Response, cookies: AstroCookie
Reflect.set(response, astroCookiesSymbol, cookies);
}
export function responseHasCookies(response: Response): boolean {
return Reflect.has(response, astroCookiesSymbol);
}
function getFromResponse(response: Response): AstroCookies | undefined {
let cookies = Reflect.get(response, astroCookiesSymbol);
if (cookies != null) {

View file

@ -620,8 +620,42 @@ export const ExpectedImageOptions = {
message: (options: string) =>
`Expected getImage() parameter to be an object. Received \`${options}\`.`,
} satisfies ErrorData;
/**
* @docs
* @see
* - [Images](https://docs.astro.build/en/guides/images/)
* @description
* Astro could not find an image you imported. Often, this is simply caused by a typo in the path.
*
* Images in Markdown are relative to the current file. To refer to an image that is located in the same folder as the `.md` file, the path should start with `./`
*/
export const ImageNotFound = {
name: 'ImageNotFound',
title: 'Image not found.',
message: (imagePath: string) => `Could not find requested image \`${imagePath}\`. Does it exist?`,
hint: 'This is often caused by a typo in the image path. Please make sure the file exists, and is spelled correctly.',
} satisfies ErrorData;
/**
* @docs
* @message Could not process image metadata for `IMAGE_PATH`.
* @see
* - [Images](https://docs.astro.build/en/guides/images/)
* @description
* Astro could not process the metadata of an image you imported. This is often caused by a corrupted or malformed image and re-exporting the image from your image editor may fix this issue.
*/
export const NoImageMetadata = {
name: 'NoImageMetadata',
title: 'Could not process image metadata.',
message: (imagePath: string | undefined) =>
`Could not process image metadata${imagePath ? ' for `${imagePath}`' : ''}.`,
hint: 'This is often caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue.',
} satisfies ErrorData;
/**
* @docs
* @deprecated This error is no longer Markdown specific and as such, as been replaced by `ImageNotFound`
* @message
* Could not find requested image `IMAGE_PATH` at `FULL_IMAGE_PATH`.
* @see
@ -640,6 +674,7 @@ export const MarkdownImageNotFound = {
}`,
hint: 'This is often caused by a typo in the image path. Please make sure the file exists, and is spelled correctly.',
} satisfies ErrorData;
/**
* @docs
* @description

View file

@ -5,6 +5,7 @@ import type {
MiddlewareHandler,
MiddlewareNext,
} from '../../@types/astro.js';
import { attachCookiesToResponse, responseHasCookies } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import type { Environment } from '../render/index.js';
@ -82,7 +83,7 @@ export async function callMiddleware<R>(
if (value instanceof Response === false) {
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
}
return value as R;
return ensureCookiesAttached(apiContext, value as Response);
} else {
/**
* Here we handle the case where `next` was called and returned nothing.
@ -105,11 +106,18 @@ export async function callMiddleware<R>(
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
} else {
// Middleware did not call resolve and returned a value
return value as R;
return ensureCookiesAttached(apiContext, value as Response);
}
});
}
function ensureCookiesAttached(apiContext: APIContext, response: Response): Response {
if (apiContext.cookies !== undefined && !responseHasCookies(response)) {
attachCookiesToResponse(response, apiContext.cookies);
}
return response;
}
function isEndpointOutput(endpointResult: any): endpointResult is EndpointOutput {
return (
!(endpointResult instanceof Response) &&

View file

@ -12,7 +12,7 @@ export async function loadMiddleware(
srcDir: AstroSettings['config']['srcDir']
) {
// can't use node Node.js builtins
let middlewarePath = srcDir.pathname + '/' + MIDDLEWARE_PATH_SEGMENT_NAME;
let middlewarePath = `${decodeURI(srcDir.pathname)}${MIDDLEWARE_PATH_SEGMENT_NAME}`;
try {
const module = await moduleLoader.import(middlewarePath);
return module;

View file

@ -1,25 +1,8 @@
import type { AstroUserConfig } from '../@types/astro.js';
import type { AstroIntegration, AstroUserConfig } from '../@types/astro.js';
import { AstroConfigSchema } from '../core/config/schema.js';
const EVENT_SESSION = 'ASTRO_CLI_SESSION_STARTED';
interface ConfigInfo {
markdownPlugins: string[];
adapter: string | null;
integrations: string[];
trailingSlash: undefined | 'always' | 'never' | 'ignore';
build:
| undefined
| {
format: undefined | 'file' | 'directory';
};
markdown:
| undefined
| {
drafts: undefined | boolean;
syntaxHighlight: undefined | 'shiki' | 'prism' | false;
};
}
interface EventPayload {
cliCommand: string;
config?: ConfigInfo;
@ -28,87 +11,126 @@ interface EventPayload {
optionalIntegrations?: number;
}
const multiLevelKeys = new Set([
'build',
'markdown',
'markdown.shikiConfig',
'server',
'vite',
'vite.resolve',
'vite.css',
'vite.json',
'vite.server',
'vite.server.fs',
'vite.build',
'vite.preview',
'vite.optimizeDeps',
'vite.ssr',
'vite.worker',
]);
function configKeys(obj: Record<string, any> | undefined, parentKey: string): string[] {
if (!obj) {
return [];
type ConfigInfoValue = string | boolean | string[] | undefined;
type ConfigInfoRecord = Record<string, ConfigInfoValue>;
type ConfigInfoBase = {
[alias in keyof AstroUserConfig]: ConfigInfoValue | ConfigInfoRecord;
};
export interface ConfigInfo extends ConfigInfoBase {
build: ConfigInfoRecord;
image: ConfigInfoRecord;
markdown: ConfigInfoRecord;
experimental: ConfigInfoRecord;
legacy: ConfigInfoRecord;
vite: ConfigInfoRecord | undefined;
}
function measureIsDefined(val: unknown) {
// if val is undefined, measure undefined as a value
if (val === undefined) {
return undefined;
}
// otherwise, convert the value to a boolean
return Boolean(val);
}
return Object.entries(obj)
.map(([key, value]) => {
if (typeof value === 'object' && !Array.isArray(value)) {
const localKey = parentKey ? parentKey + '.' + key : key;
if (multiLevelKeys.has(localKey)) {
let keys = configKeys(value, localKey).map((subkey) => key + '.' + subkey);
keys.unshift(key);
return keys;
}
}
type StringLiteral<T> = T extends string ? (string extends T ? never : T) : never;
return key;
})
.flat(1);
/**
* Measure supports string literal values. Passing a generic `string` type
* results in an error, to make sure generic user input is never measured directly.
*/
function measureStringLiteral<T extends string>(
val: StringLiteral<T> | boolean | undefined
): string | boolean | undefined {
return val;
}
function measureIntegration(val: AstroIntegration | false | null | undefined): string | undefined {
if (!val || !val.name) {
return undefined;
}
return val.name;
}
function sanitizeConfigInfo(obj: object | undefined, validKeys: string[]): ConfigInfoRecord {
if (!obj || validKeys.length === 0) {
return {};
}
return validKeys.reduce(
(result, key) => {
result[key] = measureIsDefined((obj as Record<string, unknown>)[key]);
return result;
},
{} as Record<string, boolean | undefined>
);
}
/**
* This function creates an anonymous ConfigInfo object from the user's config.
* All values are sanitized to preserve anonymity. Simple "exist" boolean checks
* are used by default, with a few additional sanitized values added manually.
* Helper functions should always be used to ensure correct sanitization.
*/
function createAnonymousConfigInfo(userConfig: AstroUserConfig) {
// Sanitize and measure the generic config object
// NOTE(fks): Using _def is the correct, documented way to get the `shape`
// from a Zod object that includes a wrapping default(), optional(), etc.
// Even though `_def` appears private, it is type-checked for us so that
// any changes between versions will be detected.
const configInfo: ConfigInfo = {
...sanitizeConfigInfo(userConfig, Object.keys(AstroConfigSchema.shape)),
build: sanitizeConfigInfo(
userConfig.build,
Object.keys(AstroConfigSchema.shape.build._def.innerType.shape)
),
image: sanitizeConfigInfo(
userConfig.image,
Object.keys(AstroConfigSchema.shape.image._def.innerType.shape)
),
markdown: sanitizeConfigInfo(
userConfig.markdown,
Object.keys(AstroConfigSchema.shape.markdown._def.innerType.shape)
),
experimental: sanitizeConfigInfo(
userConfig.experimental,
Object.keys(AstroConfigSchema.shape.experimental._def.innerType.shape)
),
legacy: sanitizeConfigInfo(
userConfig.legacy,
Object.keys(AstroConfigSchema.shape.legacy._def.innerType.shape)
),
vite: userConfig.vite
? sanitizeConfigInfo(userConfig.vite, Object.keys(userConfig.vite))
: undefined,
};
// Measure string literal/enum configuration values
configInfo.build.format = measureStringLiteral(userConfig.build?.format);
configInfo.markdown.syntaxHighlight = measureStringLiteral(userConfig.markdown?.syntaxHighlight);
configInfo.output = measureStringLiteral(userConfig.output);
configInfo.scopedStyleStrategy = measureStringLiteral(userConfig.scopedStyleStrategy);
configInfo.trailingSlash = measureStringLiteral(userConfig.trailingSlash);
// Measure integration & adapter usage
configInfo.adapter = measureIntegration(userConfig.adapter);
configInfo.integrations = userConfig.integrations
?.flat(100)
.map(measureIntegration)
.filter(Boolean) as string[];
// Return the sanitized ConfigInfo object
return configInfo;
}
export function eventCliSession(
cliCommand: string,
userConfig?: AstroUserConfig,
userConfig: AstroUserConfig,
flags?: Record<string, any>
): { eventName: string; payload: EventPayload }[] {
// Filter out falsy integrations
const configValues = userConfig
? {
markdownPlugins: [
...(userConfig?.markdown?.remarkPlugins?.map((p) =>
typeof p === 'string' ? p : typeof p
) ?? []),
...(userConfig?.markdown?.rehypePlugins?.map((p) =>
typeof p === 'string' ? p : typeof p
) ?? []),
] as string[],
adapter: userConfig?.adapter?.name ?? null,
integrations: (userConfig?.integrations ?? [])
.filter(Boolean)
.flat()
.map((i: any) => i?.name),
trailingSlash: userConfig?.trailingSlash,
build: userConfig?.build
? {
format: userConfig?.build?.format,
}
: undefined,
markdown: userConfig?.markdown
? {
drafts: userConfig.markdown?.drafts,
syntaxHighlight: userConfig.markdown?.syntaxHighlight,
}
: undefined,
}
: undefined;
// Filter out yargs default `_` flag which is the cli command
const cliFlags = flags ? Object.keys(flags).filter((name) => name != '_') : undefined;
const payload: EventPayload = {
cliCommand,
configKeys: userConfig ? configKeys(userConfig, '') : undefined,
config: configValues,
config: createAnonymousConfigInfo(userConfig),
flags: cliFlags,
};
return [{ eventName: EVENT_SESSION, payload }];

View file

@ -1,7 +1,7 @@
import type { SSRResult } from '../../@types/astro.js';
import islandScript from './astro-island.prebuilt.js';
const ISLAND_STYLES = `<style style="display:none">astro-island,astro-slot,astro-static-slot{display:contents}</style>`;
const ISLAND_STYLES = `<style>astro-island,astro-slot,astro-static-slot{display:contents}</style>`;
export function determineIfNeedsHydrationScript(result: SSRResult): boolean {
if (result._metadata.hasHydrationScript) {
@ -36,12 +36,12 @@ export function getPrescripts(result: SSRResult, type: PrescriptType, directive:
// deps to be loaded immediately.
switch (type) {
case 'both':
return `${ISLAND_STYLES}<script style="display:none">${getDirectiveScriptText(
return `${ISLAND_STYLES}<script>${getDirectiveScriptText(
result,
directive
)};${islandScript}</script>`;
case 'directive':
return `<script style="display:none">${getDirectiveScriptText(result, directive)}</script>`;
return `<script>${getDirectiveScriptText(result, directive)}</script>`;
}
return '';
}

View file

@ -90,7 +90,7 @@ export async function handleHotUpdate(
// Bugfix: sometimes style URLs get normalized and end with `lang.css=`
// These will cause full reloads, so filter them out here
const mods = ctx.modules.filter((m) => !m.url.endsWith('='));
const mods = [...filtered].filter((m) => !m.url.endsWith('='));
const file = ctx.file.replace(config.root.pathname, '/');
// If only styles are changed, remove the component file from the update list
@ -109,17 +109,6 @@ export async function handleHotUpdate(
}
}
// If this is a module that is imported from a <script>, invalidate the Astro
// component so that it is cached by the time the script gets transformed.
for (const mod of filtered) {
if (mod.id && isAstroScript(mod.id) && mod.file) {
const astroMod = ctx.server.moduleGraph.getModuleById(mod.file);
if (astroMod) {
mods.unshift(astroMod);
}
}
}
// TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be
const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte'));
if (isSelfAccepting) {

View file

@ -70,7 +70,8 @@ export default function configAliasVitePlugin({
const plugin: VitePlugin = {
name: 'astro:tsconfig-alias',
enforce: 'pre',
// use post to only resolve ids that all other plugins before it can't
enforce: 'post',
configResolved(config) {
patchCreateResolver(config, plugin);
},
@ -100,7 +101,7 @@ export default function configAliasVitePlugin({
*
* Vite may simplify this soon: https://github.com/vitejs/vite/pull/10555
*/
function patchCreateResolver(config: ResolvedConfig, prePlugin: VitePlugin) {
function patchCreateResolver(config: ResolvedConfig, postPlugin: VitePlugin) {
const _createResolver = config.createResolver;
// @ts-expect-error override readonly property intentionally
config.createResolver = function (...args1: any) {
@ -124,15 +125,16 @@ function patchCreateResolver(config: ResolvedConfig, prePlugin: VitePlugin) {
ssr,
};
const result = await resolver.apply(_createResolver, args2);
if (result) return result;
// @ts-expect-error resolveId exists
const resolved = await prePlugin.resolveId.apply(fakePluginContext, [
const resolved = await postPlugin.resolveId.apply(fakePluginContext, [
id,
importer,
fakeResolveIdOpts,
]);
if (resolved) return resolved;
return resolver.apply(_createResolver, args2);
};
};
}

View file

@ -12,7 +12,8 @@ import { normalizePath } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import { AstroError, AstroErrorData, MarkdownError } from '../core/errors/index.js';
import type { Logger } from '../core/logger/core.js';
import { isMarkdownFile, rootRelativePath } from '../core/util.js';
import { isMarkdownFile } from '../core/util.js';
import { shorthash } from '../runtime/server/shorthash.js';
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js';
@ -92,12 +93,13 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata;
// Resolve all the extracted images from the content
const imagePaths: { raw: string; resolved: string }[] = [];
const imagePaths: { raw: string; resolved: string; safeName: string }[] = [];
for (const imagePath of rawImagePaths.values()) {
imagePaths.push({
raw: imagePath,
resolved:
(await this.resolve(imagePath, id))?.id ?? path.join(path.dirname(id), imagePath),
safeName: shorthash(imagePath),
});
}
@ -118,39 +120,28 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
${layout ? `import Layout from ${JSON.stringify(layout)};` : ''}
import { getImage } from "astro:assets";
${imagePaths.map((entry) => `import Astro__${entry.safeName} from ${JSON.stringify(entry.raw)};`)}
export const images = {
${imagePaths.map(
(entry) =>
`'${entry.raw}': await getImageSafely((await import("${entry.raw}")).default, "${
entry.raw
}", "${rootRelativePath(settings.config.root, entry.resolved)}")`
)}
}
async function getImageSafely(imageSrc, imagePath, resolvedImagePath) {
if (!imageSrc) {
throw new AstroError({
...AstroErrorData.MarkdownImageNotFound,
message: AstroErrorData.MarkdownImageNotFound.message(
imagePath,
resolvedImagePath
),
location: { file: "${id}" },
});
const images = async function() {
return {
${imagePaths
.map((entry) => `"${entry.raw}": await getImage({src: Astro__${entry.safeName}})`)
.join('\n')}
}
return await getImage({src: imageSrc})
}
function updateImageReferences(html) {
return html.replaceAll(
/__ASTRO_IMAGE_="([^"]+)"/gm,
(full, imagePath) => spreadAttributes({src: images[imagePath].src, ...images[imagePath].attributes})
);
async function updateImageReferences(html) {
return images().then((images) => {
return html.replaceAll(/__ASTRO_IMAGE_="([^"]+)"/gm, (full, imagePath) =>
spreadAttributes({
src: images[imagePath].src,
...images[imagePath].attributes,
})
);
});
}
const html = updateImageReferences(${JSON.stringify(html)});
const html = await updateImageReferences(${JSON.stringify(html)});
export const frontmatter = ${JSON.stringify(frontmatter)};
export const file = ${JSON.stringify(fileId)};

View file

@ -244,6 +244,22 @@ describe('Content Collections', () => {
});
});
describe('With empty collections directory', () => {
it('Handles the empty directory correclty', async () => {
const fixture = await loadFixture({
root: './fixtures/content-collections-empty-dir/',
});
let error;
try {
await fixture.build();
} catch (e) {
error = e.message;
}
expect(error).to.be.undefined;
// TODO: try to render a page
});
});
describe('SSR integration', () => {
let app;

View file

@ -5,44 +5,7 @@ import * as events from '../dist/events/index.js';
describe('Events', () => {
describe('eventCliSession()', () => {
it('All top-level keys added', () => {
const config = {
root: 1,
srcDir: 2,
publicDir: 3,
outDir: 4,
site: 5,
base: 6,
trailingSlash: 7,
experimental: 8,
};
const expected = Object.keys(config);
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).to.deep.equal(expected);
});
it('configKeys includes format', () => {
const config = {
srcDir: 1,
build: {
format: 'file',
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).to.deep.equal(['srcDir', 'build', 'build.format']);
});
it('config.build.format', () => {
it('string literal "build.format" is included', () => {
const config = {
srcDir: 1,
build: {
@ -58,59 +21,7 @@ describe('Events', () => {
expect(payload.config.build.format).to.equal('file');
});
it('configKeys includes server props', () => {
const config = {
srcDir: 1,
server: {
host: 'example.com',
port: 8033,
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).to.deep.equal(['srcDir', 'server', 'server.host', 'server.port']);
});
it('configKeys is deep', () => {
const config = {
publicDir: 1,
markdown: {
drafts: true,
shikiConfig: {
lang: 1,
theme: 2,
wrap: 3,
},
syntaxHighlight: 'shiki',
remarkPlugins: [],
rehypePlugins: [],
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).to.deep.equal([
'publicDir',
'markdown',
'markdown.drafts',
'markdown.shikiConfig',
'markdown.shikiConfig.lang',
'markdown.shikiConfig.theme',
'markdown.shikiConfig.wrap',
'markdown.syntaxHighlight',
'markdown.remarkPlugins',
'markdown.rehypePlugins',
]);
});
it('syntaxHighlight', () => {
it('string literal "markdown.syntaxHighlight" is included', () => {
const config = {
markdown: {
syntaxHighlight: 'shiki',
@ -145,233 +56,16 @@ describe('Events', () => {
},
config
);
expect(payload.configKeys).is.deep.equal([
'root',
'vite',
'vite.css',
'vite.css.modules',
'vite.base',
'vite.mode',
'vite.define',
'vite.publicDir',
expect(Object.keys(payload.config.vite)).is.deep.equal([
'css',
'base',
'mode',
'define',
'publicDir',
]);
});
it('vite.resolve keys are captured', async () => {
const config = {
vite: {
resolve: {
alias: {
a: 'b',
},
dedupe: ['one', 'two'],
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.resolve',
'vite.resolve.alias',
'vite.resolve.dedupe',
]);
});
it('vite.css keys are captured', async () => {
const config = {
vite: {
resolve: {
dedupe: ['one', 'two'],
},
css: {
modules: [],
postcss: {},
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.resolve',
'vite.resolve.dedupe',
'vite.css',
'vite.css.modules',
'vite.css.postcss',
]);
});
it('vite.server keys are captured', async () => {
const config = {
vite: {
server: {
host: 'example.com',
open: true,
fs: {
strict: true,
allow: ['a', 'b'],
},
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.server',
'vite.server.host',
'vite.server.open',
'vite.server.fs',
'vite.server.fs.strict',
'vite.server.fs.allow',
]);
});
it('vite.build keys are captured', async () => {
const config = {
vite: {
build: {
target: 'one',
outDir: 'some/dir',
cssTarget: {
one: 'two',
},
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.build',
'vite.build.target',
'vite.build.outDir',
'vite.build.cssTarget',
]);
});
it('vite.preview keys are captured', async () => {
const config = {
vite: {
preview: {
host: 'example.com',
port: 8080,
another: {
a: 'b',
},
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.preview',
'vite.preview.host',
'vite.preview.port',
'vite.preview.another',
]);
});
it('vite.optimizeDeps keys are captured', async () => {
const config = {
vite: {
optimizeDeps: {
entries: ['one', 'two'],
exclude: ['secret', 'name'],
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.optimizeDeps',
'vite.optimizeDeps.entries',
'vite.optimizeDeps.exclude',
]);
});
it('vite.ssr keys are captured', async () => {
const config = {
vite: {
ssr: {
external: ['a'],
target: { one: 'two' },
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.ssr',
'vite.ssr.external',
'vite.ssr.target',
]);
});
it('vite.worker keys are captured', async () => {
const config = {
vite: {
worker: {
format: { a: 'b' },
plugins: ['a', 'b'],
},
},
};
const [{ payload }] = events.eventCliSession(
{
cliCommand: 'dev',
},
config
);
expect(payload.configKeys).is.deep.equal([
'vite',
'vite.worker',
'vite.worker.format',
'vite.worker.plugins',
]);
});
it('falsy integrations', () => {
it('falsy integrations are handled', () => {
const config = {
srcDir: 1,
integrations: [null, undefined, false],
@ -385,7 +79,7 @@ describe('Events', () => {
expect(payload.config.integrations.length).to.equal(0);
});
it('finds names for integration arrays', () => {
it('only integration names are included', () => {
const config = {
integrations: [{ name: 'foo' }, [{ name: 'bar' }, { name: 'baz' }]],
};
@ -393,6 +87,14 @@ describe('Events', () => {
expect(payload.config.integrations).to.deep.equal(['foo', 'bar', 'baz']);
});
it('only adapter name is included', () => {
const config = {
adapter: { name: 'ADAPTER_NAME' },
};
const [{ payload }] = events.eventCliSession({ cliCommand: 'dev' }, config);
expect(payload.config.adapter).to.equal('ADAPTER_NAME');
});
it('includes cli flags in payload', () => {
const config = {};
const flags = {

View file

@ -8,7 +8,7 @@ describe('Adapter', () => {
it("should error if the adapter doesn't support edge middleware", async () => {
try {
fixture = await loadFixture({
root: './fixtures/middleware-dev/',
root: './fixtures/middleware space/',
output: 'server',
build: {
excludeMiddleware: true,
@ -32,7 +32,7 @@ describe('Adapter', () => {
it("should error if the adapter doesn't support split build", async () => {
try {
fixture = await loadFixture({
root: './fixtures/middleware-dev/',
root: './fixtures/middleware space/',
output: 'server',
build: {
split: true,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Some files were not shown because too many files have changed in this diff Show more