├── .editorconfig
├── .gitattributes
├── .github
├── dependabot.yml
├── pull_request_template.md
└── workflows
│ └── test.yml
├── .gitignore
├── .npmrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── biome.json
├── docs
├── index.html
└── style.css
├── example-2x.png
├── index.html
├── package-lock.json
├── package.json
├── src
├── constants.js
├── index.js
├── progressive-image-element.js
└── style.css
├── vite.config.js
└── vite.docs.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Automatically normalize line endings for all text-based files
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | # Enable version updates for npm
4 | - package-ecosystem: 'npm'
5 | # Look for `package.json` and `lock` files in the `root` directory
6 | directory: '/'
7 | # Check the npm registry for updates every day (weekdays)
8 | schedule:
9 | interval: 'daily'
10 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## What changed (additional context)
2 |
3 |
4 |
5 |
6 |
7 | Related:
8 |
9 | ## Proof of work (screenshots / screen recordings)
10 |
11 |
12 |
13 | | before | after |
14 | | ------ | ----- |
15 | | - | - |
16 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths-ignore:
8 | - '**.md'
9 | - '**.yml'
10 | pull_request:
11 | branches:
12 | - main
13 |
14 | # Cancel in progress workflows on pull_requests.
15 | # https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
16 | concurrency:
17 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | test:
22 | name: Test
23 | runs-on: ubuntu-latest
24 | steps:
25 | - name: Checkout repository
26 | uses: actions/checkout@v4
27 |
28 | - name: Setup node
29 | uses: actions/setup-node@v4.3.0
30 | with:
31 | node-version-file: 'package.json'
32 | cache: 'npm'
33 |
34 | - name: Install dependencies
35 | run: npm ci
36 |
37 | - name: Code quality
38 | run: npm run lint
39 |
40 | - name: Build
41 | run: npm run build
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | \__*
3 | *.log
4 | dist
5 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | save-exact=true
2 | engine-strict=true
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # [1.3.0](https://github.com/andreruffert/progressive-image-element/compare/v1.2.0...v1.3.0) (2025-03-25)
2 |
3 |
4 | ### Features
5 |
6 | * allow opt-out of define() ([f473c68](https://github.com/andreruffert/progressive-image-element/commit/f473c68cc30b3accdb08084f083dafe1077324b2))
7 | * introduce es module support ([2c345b8](https://github.com/andreruffert/progressive-image-element/commit/2c345b8783e39b84cdb8c7010984e28001097548))
8 |
9 |
10 |
11 | # 1.2.0 (2020-02-14)
12 |
13 |
14 | ### Bug Fixes
15 |
16 | * show dimension warning only if placeholder exists ([1e0f292](https://github.com/andreruffert/progressive-image-element/commit/1e0f2925d790e99d7f637441c969967e14fc645e))
17 |
18 |
19 | ### Features
20 |
21 | * add loading="lazy" attribute to image ([c371340](https://github.com/andreruffert/progressive-image-element/commit/c371340e49cda1e190a3cd9d23a5589fc5cc1ee7))
22 | * add support for sizes attribute ([3d19a84](https://github.com/andreruffert/progressive-image-element/commit/3d19a843bd56e94d8f534a717e2e573612d40e7c))
23 | * initiate observer only if loading lazy is not supported ([874027f](https://github.com/andreruffert/progressive-image-element/commit/874027fde83e6342a39323c0f1063ea35d0ede87))
24 | * messages for missing placeholder + dimensions ([2e85a31](https://github.com/andreruffert/progressive-image-element/commit/2e85a31a57d32b5c2931e7d6019eba3ca0d942a1))
25 | * use connection test for default savedata value ([1d3f6a0](https://github.com/andreruffert/progressive-image-element/commit/1d3f6a0c8a096cae4af053d1190536af86235044))
26 | * warn about missing placeholder or dimensions ([e6a2050](https://github.com/andreruffert/progressive-image-element/commit/e6a205041b6a28a6da0957834a8681817cce4c99))
27 |
28 |
29 |
30 | ## 1.1.2 (2020-02-03)
31 |
32 |
33 | ### Bug Fixes
34 |
35 | * **css:** contain aspect ratio for svg elements ([f65a8d4](https://github.com/andreruffert/progressive-image-element/commit/f65a8d4c8f16e1c41c42e7f1754614f3fcf9728a))
36 |
37 |
38 |
39 | ## 1.1.1 (2020-02-02)
40 |
41 |
42 | ### Bug Fixes
43 |
44 | * make srcset attribute optional ([62909ba](https://github.com/andreruffert/progressive-image-element/commit/62909ba38812b59419605561477de202f809af6d))
45 |
46 |
47 |
48 | # 1.1.0 (2020-02-01)
49 |
50 |
51 | ### Features
52 |
53 | * add save data option ([5141f85](https://github.com/andreruffert/progressive-image-element/commit/5141f8550f26f00e1cd8f71f1cf7d36b9a06ab96))
54 | * gh-pages example page ([7312d76](https://github.com/andreruffert/progressive-image-element/commit/7312d76dfbc51f43fbe09c383e5d1d8d9b1f879b))
55 | * image loading on slow connection needs action ([13f9292](https://github.com/andreruffert/progressive-image-element/commit/13f9292eb7dd16191d1f67ed81c013fb28bea478))
56 | * optional chaining for connection effectiveType ([0755bd2](https://github.com/andreruffert/progressive-image-element/commit/0755bd21d8908b0e961090d83ee2460bdc3861b9))
57 |
58 |
59 |
60 | # 1.0.0 (2020-01-31)
61 |
62 |
63 | ### Bug Fixes
64 |
65 | * add height auto css to keep aspect ratio ([e410f56](https://github.com/andreruffert/progressive-image-element/commit/e410f565195bc63d12988141fa86ace1aecdf550))
66 |
67 |
68 | ### Features
69 |
70 | * basic poc implementation ([9ddf521](https://github.com/andreruffert/progressive-image-element/commit/9ddf521b7b2e720cfd37062e3fac01f0af1a93aa))
71 |
72 |
73 |
74 | ## 1.1.2 (2020-02-03)
75 |
76 |
77 | ### Bug Fixes
78 |
79 | * **css:** contain aspect ratio for svg elements ([f65a8d4](https://github.com/andreruffert/progressive-image-element/commit/f65a8d4c8f16e1c41c42e7f1754614f3fcf9728a))
80 |
81 |
82 |
83 | ## 1.1.1 (2020-02-02)
84 |
85 |
86 | ### Bug Fixes
87 |
88 | * make srcset attribute optional ([62909ba](https://github.com/andreruffert/progressive-image-element/commit/62909ba38812b59419605561477de202f809af6d))
89 |
90 |
91 |
92 | # 1.1.0 (2020-02-01)
93 |
94 |
95 | ### Features
96 |
97 | * add save data option ([5141f85](https://github.com/andreruffert/progressive-image-element/commit/5141f8550f26f00e1cd8f71f1cf7d36b9a06ab96))
98 | * gh-pages example page ([7312d76](https://github.com/andreruffert/progressive-image-element/commit/7312d76dfbc51f43fbe09c383e5d1d8d9b1f879b))
99 | * image loading on slow connection needs action ([13f9292](https://github.com/andreruffert/progressive-image-element/commit/13f9292eb7dd16191d1f67ed81c013fb28bea478))
100 | * optional chaining for connection effectiveType ([0755bd2](https://github.com/andreruffert/progressive-image-element/commit/0755bd21d8908b0e961090d83ee2460bdc3861b9))
101 |
102 |
103 |
104 | # 1.0.0 (2020-01-31)
105 |
106 |
107 | ### Bug Fixes
108 |
109 | * add height auto css to keep aspect ratio ([e410f56](https://github.com/andreruffert/progressive-image-element/commit/e410f565195bc63d12988141fa86ace1aecdf550))
110 |
111 |
112 | ### Features
113 |
114 | * basic poc implementation ([9ddf521](https://github.com/andreruffert/progressive-image-element/commit/9ddf521b7b2e720cfd37062e3fac01f0af1a93aa))
115 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 André Ruffert
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # <progressive-image> element
2 |
3 | > Progressively enhance image placeholders once they are in the viewport.
4 |
5 | [](https://github.com/andreruffert/progressive-image-element/actions/workflows/test.yml)
6 | [](https://www.npmjs.com/package/progressive-image-element)
7 | [](https://www.npmjs.com/package/progressive-image-element)
8 | [](https://www.jsdelivr.com/package/npm/progressive-image-element)
9 |
10 | * **Faster page load**: Images are loaded only as they enter the viewport, using native browser lazy loading with placeholders
11 | * **Visual stability**: Prevent layout shifts when loading images
12 | * **Save data option**: Load images only on demand
13 | * **No dependencies**: Framework agnostic web component
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Install
21 |
22 | ```console
23 | $ npm install progressive-image-element
24 | ```
25 |
26 |
27 | ## Usage
28 |
29 | 1. Include the script & stylesheet within your application
30 |
31 | ```html
32 |
33 |
34 |
35 |
36 |
37 | ```
38 |
39 | or
40 |
41 | ```js
42 | // Import the custom element script
43 | import ProgressiveImageElement from 'progressive-image-element';
44 | ```
45 |
46 | 2. Use the `` element markup
47 |
48 | ```html
49 |
53 |
54 |
55 |
56 | ```
57 | The placeholder image should be a solid color placeholder, [LQIP](http://www.guypo.com/introducing-lqip-low-quality-image-placeholders) or [SQIP](https://github.com/technopagan/sqip) that hint at the content of the progressive image before it loads.
58 |
59 |
60 | ## Attributes
61 |
62 | - `src` Specifies the image to display
63 | - `srcset` One or more [image candidate strings](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset)
64 | - `sizes` Comma-separated list of [source size descriptors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes)
65 | - `savedata` Boolean attribute to load the images only after a click/tap on the placeholder image.
66 | By default enabled for slow connections (`slow-2g|2g|3g`).
67 |
68 |
69 | ## Styling states
70 |
71 | A CSS class `loadable` is present on `` when the image is ready to load on user interaction (`click`).
72 | Used for slow connections or when the `savedata` attribute is present.
73 | ```css
74 | progressive-image.loadable { ... }
75 | ```
76 |
77 | A CSS class `[loading]` is present on `` while the image is loading.
78 | ```css
79 | progressive-image.loading { ... }
80 | ```
81 |
82 | A CSS class `.loaded` is present on ` ` children of `` when the image was loaded.
83 | ```css
84 | progressive-image > img { opacity: 0; }
85 | progressive-image > img.loaded { opacity: 1; }
86 | ```
87 |
88 |
89 | ## License
90 |
91 | Distributed under the MIT license. See LICENSE for details.
92 |
93 | © [André Ruffert](https://andreruffert.com)
94 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
3 | "vcs": {
4 | "enabled": true,
5 | "clientKind": "git",
6 | "useIgnoreFile": true
7 | },
8 | "files": {
9 | "ignoreUnknown": false,
10 | "includes": ["**"]
11 | },
12 | "formatter": {
13 | "includes": ["**", "!**/package.json"],
14 | "enabled": true,
15 | "indentStyle": "space",
16 | "indentWidth": 2,
17 | "lineWidth": 100
18 | },
19 | "assist": { "actions": { "source": { "organizeImports": "on" } } },
20 | "linter": {
21 | "enabled": true,
22 | "rules": {
23 | "recommended": true,
24 | "style": {
25 | "noParameterAssign": "error",
26 | "useAsConstAssertion": "error",
27 | "useDefaultParameterLast": "error",
28 | "useEnumInitializers": "error",
29 | "useSelfClosingElements": "error",
30 | "useSingleVarDeclarator": "error",
31 | "noUnusedTemplateLiteral": "error",
32 | "useNumberNamespace": "error",
33 | "noInferrableTypes": "error",
34 | "noUselessElse": "error"
35 | }
36 | }
37 | },
38 | "javascript": {
39 | "formatter": {
40 | "quoteStyle": "single"
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <progressive-image> element - Web Component
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
31 |
32 |
33 |
34 |
43 |
44 |
45 | ⚡️
46 | <progressive-image>
47 | A simple web component to progressively enhance image placeholders once they are in the viewport.
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | npm i progressive-image-element
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
108 |
109 |
110 | Features
111 | According to Web Almanac , images account for a large portion of the page weight of a typical website and can have a significant impact on your site's LCP performance .
112 | The <progressive-image>
element extends the HTML <img>
element with features to improve the initial page weight:
113 |
114 | Faster page load : Images are loaded only as they enter the viewport, using native browser lazy loading with placeholders
115 | Visual stability : Prevent layout shifts when loading images
116 | Save data option : Load images only on demand
117 | No dependencies : Framework agnostic web component
118 |
119 |
120 |
121 |
122 | Install
123 | Install via npm
124 |
125 | npm i progressive-image-element
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | Usage
134 | 1. Include the script & stylesheet within your application
135 |
136 | <!-- Include the stylesheet, this could be direct from the package or CDN -->
137 | <link rel="stylesheet" href="https://unpkg.com/progressive-image-element@latest/dist/progressive-image-element.css" />
138 |
139 | <!-- Include the custom element script, this could be direct from the package or CDN -->
140 | <script src="https://unpkg.com/progressive-image-element@latest/dist/index.js"></script>
141 |
142 |
143 |
144 |
145 | or
146 |
147 | // Import the custom element script
148 | import ProgressiveImageElement from 'progressive-image-element';
149 |
150 |
151 |
152 |
153 | 2. Use the <progressive-image> element markup
154 |
155 | <progressive-image
156 | src="example-image-1x.jpg"
157 | srcset="example-image-2x.jpg 2x, example-image-1x.jpg 1x"
158 | >
159 | <!-- Make sure to specify image dimensions -->
160 | <img src="placeholder-image.jpg" width="300" height="200" alt="Image" />
161 | </progressive-image>
162 |
163 |
164 |
165 |
166 | Use a solid color, LQIP , or SQIP image placeholder. This will hint at the content of the progressive image before it loads.
167 |
168 |
169 |
170 |
171 | Attributes
172 |
173 | src
Specifies the image to display
174 | srcset
One or more image candidate strings
175 | sizes
Comma-separated list of source size descriptors
176 | savedata
Boolean attribute to load the images only after a click/tap on the placeholder image.
177 | By default enabled for slow connections (slow-2g|2g|3g
).
178 |
179 |
180 |
181 |
182 | Styling states
183 | A CSS class loadable
is present on the <progressive-image>
element when the image is ready to load on user interaction (click
).
184 | Used for slow connections or when the savedata
attribute is present.
185 |
186 | progressive-image.loadable { … }
187 |
188 |
189 |
190 |
191 | A CSS class loading
is present on the <progressive-image>
element while the image is loading.
192 |
193 | progressive-image.loading { … }
194 |
195 |
196 |
197 |
198 | A CSS class loaded
is present on the <img>
children of the <progressive-image>
element when the image was loaded.
199 |
200 | progressive-image > img { opacity: 0; }
201 | progressive-image > img.loaded { opacity: 1; }
202 |
203 |
204 |
205 |
206 |
207 |
208 |
212 |
213 |
214 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
246 |
247 |
262 |
263 |
264 |
--------------------------------------------------------------------------------
/docs/style.css:
--------------------------------------------------------------------------------
1 | @layer reset, tokens, syntax-highlight-element, layout;
2 |
3 | @layer layout {
4 | :root {
5 | font-family: var(--fonts-sans);
6 | line-height: 1.5;
7 | font-weight: 400;
8 |
9 | color-scheme: light dark;
10 | color: light-dark(var(--light-canvas-text), var(--dark-canvas-text));
11 | background-color: light-dark(var(--light-canvas), var(--dark-canvas));
12 |
13 | font-synthesis: none;
14 | text-rendering: optimizeLegibility;
15 | -webkit-font-smoothing: antialiased;
16 | -moz-osx-font-smoothing: grayscale;
17 | }
18 |
19 | body {
20 | display: grid;
21 | gap: var(--spacing-24);
22 | min-height: 100vh;
23 | }
24 |
25 | :focus-visible {
26 | outline-color: light-dark(var(--light-accent), var(--dark-accent));
27 | }
28 |
29 | a {
30 | color: inherit;
31 | text-underline-offset: var(--spacing-1);
32 | transition: text-decoration-color 0.3s;
33 | text-decoration-line: underline;
34 | }
35 |
36 | a:not(:is(:hover, :focus)) {
37 | text-decoration-color: color-mix(in srgb, currentColor, transparent 75%);
38 | }
39 |
40 | button,
41 | .button {
42 | display: flex;
43 | align-items: center;
44 | justify-content: center;
45 | border-radius: 8px;
46 | border: 1px solid transparent;
47 | padding: 0.6em 1.2em;
48 | font-weight: 500;
49 | font-family: inherit;
50 | background-color: light-dark(var(--light-button-face), var(--dark-button-face));
51 | cursor: pointer;
52 | user-select: none;
53 | transition-duration: 0.25s;
54 | transition-property: border-color, opacity, scale;
55 | }
56 | button:hover,
57 | .button:hover {
58 | border-color: currentColor;
59 | color: light-dark(var(--light-accent), var(--dark-accent));
60 | scale: 1.1;
61 | }
62 |
63 | code {
64 | background-color: light-dark(var(--light-button-face), var(--dark-button-face));
65 | border-radius: 0.25rem;
66 | padding: var(--spacing-0\.5) var(--spacing-1);
67 | }
68 |
69 | header {
70 | display: flex;
71 | align-items: center;
72 | justify-content: flex-end;
73 | flex-wrap: wrap;
74 | gap: var(--spacing-5);
75 | border-radius: 1rem;
76 | box-shadow:
77 | 0 10px 15px -3px rgba(0, 0, 0, 0.1),
78 | 0 4px 6px -4px rgba(0, 0, 0, 0.1);
79 | background-color: light-dark(var(--light-button-face-muted), var(--dark-button-face-muted));
80 | padding: var(--spacing-4);
81 | margin: var(--spacing-6) var(--spacing-4);
82 |
83 | color-scheme-switch.button {
84 | padding: var(--spacing-2);
85 | aspect-ratio: 1;
86 | align-self: flex-start;
87 | user-select: none;
88 | }
89 | }
90 |
91 | .header-links {
92 | font-size: 0.9rem;
93 | display: flex;
94 | flex-wrap: wrap;
95 | flex: 1;
96 | gap: var(--spacing-5);
97 | container-type: inline-size;
98 |
99 | a {
100 | color: inherit;
101 | display: inline-flex;
102 | align-items: center;
103 | gap: var(--spacing-2);
104 | text-wrap: nowrap;
105 | width: 100%;
106 | }
107 |
108 | a:first-of-type {
109 | margin-inline-end: auto;
110 | }
111 |
112 | svg {
113 | display: none;
114 | }
115 | }
116 |
117 | @container (min-width: 400px) {
118 | .header-links a {
119 | width: auto;
120 | }
121 |
122 | .header-links svg {
123 | display: initial;
124 | }
125 | }
126 |
127 | main {
128 | display: flex;
129 | flex-direction: column;
130 | gap: var(--spacing-10);
131 | margin-inline: auto;
132 | max-inline-size: var(--sizes-3xl);
133 | inline-size: var(--sizes-full);
134 | padding: var(--spacing-4);
135 | }
136 |
137 | footer {
138 | border-block-start: 1px solid light-dark(var(--light-button-face), var(--dark-button-face));
139 | text-align: center;
140 | margin-inline: auto;
141 | margin-block-start: auto;
142 | inline-size: var(--sizes-full);
143 | padding: var(--spacing-8) var(--spacing-4);
144 |
145 | p {
146 | margin: 0;
147 | }
148 | }
149 |
150 | .copy-code {
151 | display: flex;
152 | position: relative;
153 | inline-size: 0;
154 | min-inline-size: 100%;
155 |
156 | syntax-highlight {
157 | flex: 1;
158 | border-radius: 0.6rem;
159 | padding: var(--spacing-4);
160 | }
161 |
162 | .button {
163 | /* color: inherit; */
164 | opacity: 0;
165 | position: absolute;
166 | inset-inline-end: var(--spacing-2);
167 | inset-block-start: var(--spacing-2);
168 | padding: var(--spacing-2);
169 | aspect-ratio: 1;
170 | }
171 | }
172 |
173 | .copy-code:hover .button,
174 | .copy-code:focus-within .button {
175 | opacity: 1;
176 | }
177 |
178 | /* Intro */
179 | [data-section="intro"] {
180 | display: flex;
181 | flex-direction: column;
182 | align-items: center;
183 | gap: var(--spacing-4);
184 | text-align: center;
185 | text-wrap: balance;
186 | padding-block-end: var(--spacing-24);
187 |
188 | .emoji {
189 | font-size: clamp(2rem, 2vw + 1.6rem, 5rem);
190 | line-height: 1;
191 | }
192 |
193 | .heading {
194 | /* color: light-dark(var(--light-accent), var(--dark-accent)); */
195 | font-size: clamp(1.5rem, 2vw + 1.3rem, 3rem);
196 | font-weight: bold;
197 | line-height: 1.1;
198 | display: flex;
199 | flex-direction: column;
200 | margin: 0;
201 | }
202 |
203 | .tagline {
204 | font-size: clamp(1rem, 2vw, 1.25rem);
205 | font-weight: normal;
206 | margin: 0;
207 | }
208 |
209 | .badges {
210 | display: flex;
211 | justify-content: center;
212 | flex-wrap: wrap;
213 | gap: 0.5rem;
214 | font-size: 0;
215 | padding-block-start: var(--spacing-6);
216 | }
217 |
218 | .copy-code-container {
219 | text-align: initial;
220 | max-inline-size: var(--sizes-md);
221 | inline-size: var(--sizes-full);
222 | padding-block-start: var(--spacing-6);
223 | }
224 | }
225 |
226 | /* Content */
227 | [data-section="content"] {
228 | h1,
229 | h2 {
230 | margin-block-start: var(--spacing-6);
231 | margin-block-end: var(--spacing-4);
232 | }
233 |
234 | h1 {
235 | font-size: clamp(1.5rem, 2vw + 1rem, 2rem);
236 | line-height: 1.1;
237 | }
238 |
239 | h2 {
240 | font-size: clamp(1rem, 2vw + 0.75rem, 1.5rem);
241 | }
242 |
243 | p,
244 | li {
245 | text-wrap: balance;
246 | }
247 |
248 | li + li {
249 | margin-block-start: var(--spacing-2);
250 | }
251 |
252 | p,
253 | ul,
254 | .copy-code {
255 | margin-block-start: 0;
256 | margin-block-end: var(--spacing-4);
257 | }
258 |
259 | b {
260 | font-weight: 600;
261 | }
262 | }
263 |
264 | /* Exmaple */
265 | [data-section="example"] {
266 | display: flex;
267 | flex-direction: column;
268 | gap: var(--spacing-4);
269 | text-align: center;
270 |
271 | syntax-highlight {
272 | text-align: initial;
273 | }
274 |
275 | h1 {
276 | font-size: clamp(1.5rem, 2vw + 1rem, 2rem);
277 | line-height: 1.1;
278 | margin: 0;
279 | }
280 |
281 | figcaption {
282 | color: light-dark(var(--light-canvas-text-faded), var(--dark-canvas-text-faded));
283 | }
284 | }
285 |
286 | progressive-image {
287 | background-color: light-dark(var(--light-button-face-muted), var(--dark-button-face-muted));
288 | }
289 |
290 | progressive-image.loadable:before,
291 | progressive-image.loading:before {
292 | content: "";
293 | cursor: pointer;
294 | display: block;
295 | z-index: 1;
296 | position: absolute;
297 | top: 0;
298 | left: 0;
299 | }
300 |
301 | progressive-image.loadable:before {
302 | right: 0;
303 | bottom: 0;
304 | background-repeat: no-repeat;
305 | background-position: 16px 16px;
306 | background-size: 24px;
307 | background-image: url('data:image/svg+xml,\\ \ \ ');
308 | }
309 |
310 | progressive-image.loading:before {
311 | background-color: #000;
312 | animation: running-progress 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
313 | height: 3px;
314 | width: 100%;
315 | }
316 |
317 | progressive-image > img {
318 | opacity: 0;
319 | transition: opacity 400ms ease 0ms;
320 | }
321 |
322 | progressive-image > img[alt]:first-of-type {
323 | filter: blur(100px);
324 | }
325 |
326 | progressive-image > img.loaded {
327 | opacity: 1;
328 | }
329 |
330 | @keyframes running-progress {
331 | 0% {
332 | margin-left: 0px;
333 | margin-right: 100%;
334 | }
335 | 50% {
336 | margin-left: 25%;
337 | margin-right: 0%;
338 | }
339 | 100% {
340 | margin-left: 100%;
341 | margin-right: 0;
342 | }
343 | }
344 | }
345 |
346 | @layer reset {
347 | *,
348 | :after,
349 | :before {
350 | box-sizing: border-box;
351 | }
352 | body {
353 | margin: 0;
354 | }
355 | [hidden] {
356 | display: none !important;
357 | }
358 | }
359 |
360 | @layer tokens {
361 | :where(:root) {
362 | --spacing-0: 0rem;
363 | --spacing-0\.5: 0.125rem;
364 | --spacing-1: 0.25rem;
365 | --spacing-1\.5: 0.375rem;
366 | --spacing-2: 0.5rem;
367 | --spacing-2\.5: 0.625rem;
368 | --spacing-3: 0.75rem;
369 | --spacing-3\.5: 0.875rem;
370 | --spacing-4: 1rem;
371 | --spacing-5: 1.25rem;
372 | --spacing-6: 1.5rem;
373 | --spacing-7: 1.75rem;
374 | --spacing-8: 2rem;
375 | --spacing-9: 2.25rem;
376 | --spacing-10: 2.5rem;
377 | --spacing-11: 2.75rem;
378 | --spacing-12: 3rem;
379 | --spacing-14: 3.5rem;
380 | --spacing-16: 4rem;
381 | --spacing-20: 5rem;
382 | --spacing-24: 6rem;
383 | --spacing-28: 7rem;
384 | --spacing-32: 8rem;
385 |
386 | --sizes-xs: 20rem;
387 | --sizes-sm: 24rem;
388 | --sizes-md: 28rem;
389 | --sizes-lg: 32rem;
390 | --sizes-xl: 36rem;
391 | --sizes-2xl: 42rem;
392 | --sizes-3xl: 48rem;
393 | --sizes-4xl: 56rem;
394 | --sizes-5xl: 64rem;
395 | --sizes-6xl: 72rem;
396 | --sizes-7xl: 80rem;
397 | --sizes-8xl: 90rem;
398 | --sizes-full: 100%;
399 |
400 | --fonts-sans:
401 | ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
402 | --fonts-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
403 | "Courier New", monospace;
404 |
405 | --dark-accent: #ffc300;
406 | --dark-canvas: #111;
407 | --dark-canvas-text: #f3f4f6;
408 | --dark-canvas-text-faded: hsla(0, 0%, 100%, 0.5);
409 | --dark-button-face: hsla(0, 0%, 100%, 0.1);
410 | --dark-button-face-muted: rgba(255, 255, 255, 0.1);
411 |
412 | --light-accent: #ffc300;
413 | --light-canvas: #ffffff;
414 | --light-canvas-text: black;
415 | --light-canvas-text-faded: hsla(0, 0%, 0%, 0.6);
416 | --light-button-face: #f6f8fa;
417 | --light-button-face-muted: hsla(0, 0%, 0%, 0.04);
418 | }
419 | }
420 |
421 | @layer syntax-highlight-element {
422 | :root {
423 | --she-token-constant: #e06c75;
424 | --she-token-string: #d19a66;
425 | --she-token-comment: #7f848e;
426 | --she-token-keyword: #98c379;
427 | --she-token-parameter: #1a1a1a;
428 | --she-token-function: #61afef;
429 | --she-token-string-expression: #c678dd;
430 | --she-token-punctuation: #abb2bf;
431 | --she-token-link: #c1cff1;
432 | }
433 |
434 | syntax-highlight {
435 | display: block;
436 | font-family: var(--fonts-mono);
437 | white-space: pre;
438 | tab-size: 2;
439 | hyphens: none;
440 | line-height: 1.6;
441 | overflow: auto;
442 | background-color: #292929;
443 | color: #abb2bf;
444 | }
445 |
446 | ::highlight(parameter) {
447 | color: var(--she-token-parameter);
448 | }
449 |
450 | ::highlight(comment),
451 | ::highlight(prolog),
452 | ::highlight(doctype),
453 | ::highlight(cdata) {
454 | color: var(--she-token-comment);
455 | }
456 |
457 | ::highlight(comment) {
458 | font-style: italic;
459 | }
460 |
461 | ::highlight(punctuation) {
462 | color: var(--she-token-punctuation);
463 | }
464 |
465 | ::highlight(property),
466 | ::highlight(tag),
467 | ::highlight(boolean),
468 | ::highlight(number),
469 | ::highlight(constant),
470 | ::highlight(symbol),
471 | ::highlight(class-name) {
472 | color: var(--she-token-constant);
473 | }
474 |
475 | ::highlight(selector),
476 | ::highlight(attr-name),
477 | ::highlight(string),
478 | ::highlight(char),
479 | ::highlight(builtin) {
480 | color: var(--she-token-string);
481 | }
482 |
483 | ::highlight(operator),
484 | ::highlight(entity),
485 | ::highlight(url) {
486 | color: var(--she-token-link);
487 | background: hsla(0, 0%, 100%, 0.5);
488 | }
489 |
490 | ::highlight(atrule),
491 | ::highlight(attr-value),
492 | ::highlight(keyword) {
493 | color: var(--she-token-keyword);
494 | }
495 |
496 | ::highlight(function) {
497 | color: var(--she-token-function);
498 | }
499 |
500 | ::highlight(regex),
501 | ::highlight(important),
502 | ::highlight(variable) {
503 | color: var(--she-token-string-expression);
504 | }
505 | }
506 |
--------------------------------------------------------------------------------
/example-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andreruffert/progressive-image-element/4f63cf8928a4428ddebd7ca70160002db317df53/example-2x.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | progressive-image custom element demo
8 |
9 |
10 |
102 |
103 |
104 |
105 |
106 |
107 | With savedata
boolean attribute
108 |
112 |
113 |
114 |
115 |
116 |
117 | SVG placeholder
118 |
119 |
120 |
121 |
122 |
123 |
124 | No srcset
attribute
125 |
126 |
127 |
128 |
129 |
130 |
131 | Default
132 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "progressive-image-element",
3 | "version": "1.3.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "progressive-image-element",
9 | "version": "1.3.0",
10 | "license": "MIT",
11 | "devDependencies": {
12 | "@biomejs/biome": "2.0.0",
13 | "conventional-changelog-cli": "5.0.0",
14 | "vite": "7.0.0"
15 | },
16 | "funding": {
17 | "url": "https://github.com/andreruffert/progressive-image-element?sponsor=1"
18 | }
19 | },
20 | "node_modules/@babel/code-frame": {
21 | "version": "7.26.2",
22 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
23 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
24 | "dev": true,
25 | "license": "MIT",
26 | "dependencies": {
27 | "@babel/helper-validator-identifier": "^7.25.9",
28 | "js-tokens": "^4.0.0",
29 | "picocolors": "^1.0.0"
30 | },
31 | "engines": {
32 | "node": ">=6.9.0"
33 | }
34 | },
35 | "node_modules/@babel/helper-validator-identifier": {
36 | "version": "7.25.9",
37 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
38 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
39 | "dev": true,
40 | "license": "MIT",
41 | "engines": {
42 | "node": ">=6.9.0"
43 | }
44 | },
45 | "node_modules/@biomejs/biome": {
46 | "version": "2.0.0",
47 | "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.0.0.tgz",
48 | "integrity": "sha512-BlUoXEOI/UQTDEj/pVfnkMo8SrZw3oOWBDrXYFT43V7HTkIUDkBRY53IC5Jx1QkZbaB+0ai1wJIfYwp9+qaJTQ==",
49 | "dev": true,
50 | "license": "MIT OR Apache-2.0",
51 | "bin": {
52 | "biome": "bin/biome"
53 | },
54 | "engines": {
55 | "node": ">=14.21.3"
56 | },
57 | "funding": {
58 | "type": "opencollective",
59 | "url": "https://opencollective.com/biome"
60 | },
61 | "optionalDependencies": {
62 | "@biomejs/cli-darwin-arm64": "2.0.0",
63 | "@biomejs/cli-darwin-x64": "2.0.0",
64 | "@biomejs/cli-linux-arm64": "2.0.0",
65 | "@biomejs/cli-linux-arm64-musl": "2.0.0",
66 | "@biomejs/cli-linux-x64": "2.0.0",
67 | "@biomejs/cli-linux-x64-musl": "2.0.0",
68 | "@biomejs/cli-win32-arm64": "2.0.0",
69 | "@biomejs/cli-win32-x64": "2.0.0"
70 | }
71 | },
72 | "node_modules/@biomejs/cli-darwin-arm64": {
73 | "version": "2.0.0",
74 | "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0.tgz",
75 | "integrity": "sha512-QvqWYtFFhhxdf8jMAdJzXW+Frc7X8XsnHQLY+TBM1fnT1TfeV/v9vsFI5L2J7GH6qN1+QEEJ19jHibCY2Ypplw==",
76 | "cpu": [
77 | "arm64"
78 | ],
79 | "dev": true,
80 | "license": "MIT OR Apache-2.0",
81 | "optional": true,
82 | "os": [
83 | "darwin"
84 | ],
85 | "engines": {
86 | "node": ">=14.21.3"
87 | }
88 | },
89 | "node_modules/@biomejs/cli-darwin-x64": {
90 | "version": "2.0.0",
91 | "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.0.0.tgz",
92 | "integrity": "sha512-5JFhls1EfmuIH4QGFPlNpxJQFC6ic3X1ltcoLN+eSRRIPr6H/lUS1ttuD0Fj7rPgPhZqopK/jfH8UVj/1hIsQw==",
93 | "cpu": [
94 | "x64"
95 | ],
96 | "dev": true,
97 | "license": "MIT OR Apache-2.0",
98 | "optional": true,
99 | "os": [
100 | "darwin"
101 | ],
102 | "engines": {
103 | "node": ">=14.21.3"
104 | }
105 | },
106 | "node_modules/@biomejs/cli-linux-arm64": {
107 | "version": "2.0.0",
108 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.0.0.tgz",
109 | "integrity": "sha512-BAH4QVi06TzAbVchXdJPsL0Z/P87jOfes15rI+p3EX9/EGTfIjaQ9lBVlHunxcmoptaA5y1Hdb9UYojIhmnjIw==",
110 | "cpu": [
111 | "arm64"
112 | ],
113 | "dev": true,
114 | "license": "MIT OR Apache-2.0",
115 | "optional": true,
116 | "os": [
117 | "linux"
118 | ],
119 | "engines": {
120 | "node": ">=14.21.3"
121 | }
122 | },
123 | "node_modules/@biomejs/cli-linux-arm64-musl": {
124 | "version": "2.0.0",
125 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0.tgz",
126 | "integrity": "sha512-Bxsz8ki8+b3PytMnS5SgrGV+mbAWwIxI3ydChb/d1rURlJTMdxTTq5LTebUnlsUWAX6OvJuFeiVq9Gjn1YbCyA==",
127 | "cpu": [
128 | "arm64"
129 | ],
130 | "dev": true,
131 | "license": "MIT OR Apache-2.0",
132 | "optional": true,
133 | "os": [
134 | "linux"
135 | ],
136 | "engines": {
137 | "node": ">=14.21.3"
138 | }
139 | },
140 | "node_modules/@biomejs/cli-linux-x64": {
141 | "version": "2.0.0",
142 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.0.0.tgz",
143 | "integrity": "sha512-09PcOGYTtkopWRm6mZ/B6Mr6UHdkniUgIG/jLBv+2J8Z61ezRE+xQmpi3yNgUrFIAU4lPA9atg7mhvE/5Bo7Wg==",
144 | "cpu": [
145 | "x64"
146 | ],
147 | "dev": true,
148 | "license": "MIT OR Apache-2.0",
149 | "optional": true,
150 | "os": [
151 | "linux"
152 | ],
153 | "engines": {
154 | "node": ">=14.21.3"
155 | }
156 | },
157 | "node_modules/@biomejs/cli-linux-x64-musl": {
158 | "version": "2.0.0",
159 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0.tgz",
160 | "integrity": "sha512-tiQ0ABxMJb9I6GlfNp0ulrTiQSFacJRJO8245FFwE3ty3bfsfxlU/miblzDIi+qNrgGsLq5wIZcVYGp4c+HXZA==",
161 | "cpu": [
162 | "x64"
163 | ],
164 | "dev": true,
165 | "license": "MIT OR Apache-2.0",
166 | "optional": true,
167 | "os": [
168 | "linux"
169 | ],
170 | "engines": {
171 | "node": ">=14.21.3"
172 | }
173 | },
174 | "node_modules/@biomejs/cli-win32-arm64": {
175 | "version": "2.0.0",
176 | "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.0.0.tgz",
177 | "integrity": "sha512-vrTtuGu91xNTEQ5ZcMJBZuDlqr32DWU1r14UfePIGndF//s2WUAmer4FmgoPgruo76rprk37e8S2A2c0psXdxw==",
178 | "cpu": [
179 | "arm64"
180 | ],
181 | "dev": true,
182 | "license": "MIT OR Apache-2.0",
183 | "optional": true,
184 | "os": [
185 | "win32"
186 | ],
187 | "engines": {
188 | "node": ">=14.21.3"
189 | }
190 | },
191 | "node_modules/@biomejs/cli-win32-x64": {
192 | "version": "2.0.0",
193 | "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.0.0.tgz",
194 | "integrity": "sha512-2USVQ0hklNsph/KIR72ZdeptyXNnQ3JdzPn3NbjI4Sna34CnxeiYAaZcZzXPDl5PYNFBivV4xmvT3Z3rTmyDBg==",
195 | "cpu": [
196 | "x64"
197 | ],
198 | "dev": true,
199 | "license": "MIT OR Apache-2.0",
200 | "optional": true,
201 | "os": [
202 | "win32"
203 | ],
204 | "engines": {
205 | "node": ">=14.21.3"
206 | }
207 | },
208 | "node_modules/@conventional-changelog/git-client": {
209 | "version": "1.0.1",
210 | "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-1.0.1.tgz",
211 | "integrity": "sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==",
212 | "dev": true,
213 | "license": "MIT",
214 | "dependencies": {
215 | "@types/semver": "^7.5.5",
216 | "semver": "^7.5.2"
217 | },
218 | "engines": {
219 | "node": ">=18"
220 | },
221 | "peerDependencies": {
222 | "conventional-commits-filter": "^5.0.0",
223 | "conventional-commits-parser": "^6.0.0"
224 | },
225 | "peerDependenciesMeta": {
226 | "conventional-commits-filter": {
227 | "optional": true
228 | },
229 | "conventional-commits-parser": {
230 | "optional": true
231 | }
232 | }
233 | },
234 | "node_modules/@esbuild/aix-ppc64": {
235 | "version": "0.25.1",
236 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
237 | "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
238 | "cpu": [
239 | "ppc64"
240 | ],
241 | "dev": true,
242 | "license": "MIT",
243 | "optional": true,
244 | "os": [
245 | "aix"
246 | ],
247 | "engines": {
248 | "node": ">=18"
249 | }
250 | },
251 | "node_modules/@esbuild/android-arm": {
252 | "version": "0.25.1",
253 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
254 | "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
255 | "cpu": [
256 | "arm"
257 | ],
258 | "dev": true,
259 | "license": "MIT",
260 | "optional": true,
261 | "os": [
262 | "android"
263 | ],
264 | "engines": {
265 | "node": ">=18"
266 | }
267 | },
268 | "node_modules/@esbuild/android-arm64": {
269 | "version": "0.25.1",
270 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
271 | "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
272 | "cpu": [
273 | "arm64"
274 | ],
275 | "dev": true,
276 | "license": "MIT",
277 | "optional": true,
278 | "os": [
279 | "android"
280 | ],
281 | "engines": {
282 | "node": ">=18"
283 | }
284 | },
285 | "node_modules/@esbuild/android-x64": {
286 | "version": "0.25.1",
287 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
288 | "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
289 | "cpu": [
290 | "x64"
291 | ],
292 | "dev": true,
293 | "license": "MIT",
294 | "optional": true,
295 | "os": [
296 | "android"
297 | ],
298 | "engines": {
299 | "node": ">=18"
300 | }
301 | },
302 | "node_modules/@esbuild/darwin-arm64": {
303 | "version": "0.25.1",
304 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
305 | "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
306 | "cpu": [
307 | "arm64"
308 | ],
309 | "dev": true,
310 | "license": "MIT",
311 | "optional": true,
312 | "os": [
313 | "darwin"
314 | ],
315 | "engines": {
316 | "node": ">=18"
317 | }
318 | },
319 | "node_modules/@esbuild/darwin-x64": {
320 | "version": "0.25.1",
321 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
322 | "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
323 | "cpu": [
324 | "x64"
325 | ],
326 | "dev": true,
327 | "license": "MIT",
328 | "optional": true,
329 | "os": [
330 | "darwin"
331 | ],
332 | "engines": {
333 | "node": ">=18"
334 | }
335 | },
336 | "node_modules/@esbuild/freebsd-arm64": {
337 | "version": "0.25.1",
338 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
339 | "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
340 | "cpu": [
341 | "arm64"
342 | ],
343 | "dev": true,
344 | "license": "MIT",
345 | "optional": true,
346 | "os": [
347 | "freebsd"
348 | ],
349 | "engines": {
350 | "node": ">=18"
351 | }
352 | },
353 | "node_modules/@esbuild/freebsd-x64": {
354 | "version": "0.25.1",
355 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
356 | "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
357 | "cpu": [
358 | "x64"
359 | ],
360 | "dev": true,
361 | "license": "MIT",
362 | "optional": true,
363 | "os": [
364 | "freebsd"
365 | ],
366 | "engines": {
367 | "node": ">=18"
368 | }
369 | },
370 | "node_modules/@esbuild/linux-arm": {
371 | "version": "0.25.1",
372 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
373 | "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
374 | "cpu": [
375 | "arm"
376 | ],
377 | "dev": true,
378 | "license": "MIT",
379 | "optional": true,
380 | "os": [
381 | "linux"
382 | ],
383 | "engines": {
384 | "node": ">=18"
385 | }
386 | },
387 | "node_modules/@esbuild/linux-arm64": {
388 | "version": "0.25.1",
389 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
390 | "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
391 | "cpu": [
392 | "arm64"
393 | ],
394 | "dev": true,
395 | "license": "MIT",
396 | "optional": true,
397 | "os": [
398 | "linux"
399 | ],
400 | "engines": {
401 | "node": ">=18"
402 | }
403 | },
404 | "node_modules/@esbuild/linux-ia32": {
405 | "version": "0.25.1",
406 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
407 | "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
408 | "cpu": [
409 | "ia32"
410 | ],
411 | "dev": true,
412 | "license": "MIT",
413 | "optional": true,
414 | "os": [
415 | "linux"
416 | ],
417 | "engines": {
418 | "node": ">=18"
419 | }
420 | },
421 | "node_modules/@esbuild/linux-loong64": {
422 | "version": "0.25.1",
423 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
424 | "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
425 | "cpu": [
426 | "loong64"
427 | ],
428 | "dev": true,
429 | "license": "MIT",
430 | "optional": true,
431 | "os": [
432 | "linux"
433 | ],
434 | "engines": {
435 | "node": ">=18"
436 | }
437 | },
438 | "node_modules/@esbuild/linux-mips64el": {
439 | "version": "0.25.1",
440 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
441 | "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
442 | "cpu": [
443 | "mips64el"
444 | ],
445 | "dev": true,
446 | "license": "MIT",
447 | "optional": true,
448 | "os": [
449 | "linux"
450 | ],
451 | "engines": {
452 | "node": ">=18"
453 | }
454 | },
455 | "node_modules/@esbuild/linux-ppc64": {
456 | "version": "0.25.1",
457 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
458 | "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
459 | "cpu": [
460 | "ppc64"
461 | ],
462 | "dev": true,
463 | "license": "MIT",
464 | "optional": true,
465 | "os": [
466 | "linux"
467 | ],
468 | "engines": {
469 | "node": ">=18"
470 | }
471 | },
472 | "node_modules/@esbuild/linux-riscv64": {
473 | "version": "0.25.1",
474 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
475 | "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
476 | "cpu": [
477 | "riscv64"
478 | ],
479 | "dev": true,
480 | "license": "MIT",
481 | "optional": true,
482 | "os": [
483 | "linux"
484 | ],
485 | "engines": {
486 | "node": ">=18"
487 | }
488 | },
489 | "node_modules/@esbuild/linux-s390x": {
490 | "version": "0.25.1",
491 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
492 | "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
493 | "cpu": [
494 | "s390x"
495 | ],
496 | "dev": true,
497 | "license": "MIT",
498 | "optional": true,
499 | "os": [
500 | "linux"
501 | ],
502 | "engines": {
503 | "node": ">=18"
504 | }
505 | },
506 | "node_modules/@esbuild/linux-x64": {
507 | "version": "0.25.1",
508 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
509 | "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
510 | "cpu": [
511 | "x64"
512 | ],
513 | "dev": true,
514 | "license": "MIT",
515 | "optional": true,
516 | "os": [
517 | "linux"
518 | ],
519 | "engines": {
520 | "node": ">=18"
521 | }
522 | },
523 | "node_modules/@esbuild/netbsd-arm64": {
524 | "version": "0.25.1",
525 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
526 | "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
527 | "cpu": [
528 | "arm64"
529 | ],
530 | "dev": true,
531 | "license": "MIT",
532 | "optional": true,
533 | "os": [
534 | "netbsd"
535 | ],
536 | "engines": {
537 | "node": ">=18"
538 | }
539 | },
540 | "node_modules/@esbuild/netbsd-x64": {
541 | "version": "0.25.1",
542 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
543 | "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
544 | "cpu": [
545 | "x64"
546 | ],
547 | "dev": true,
548 | "license": "MIT",
549 | "optional": true,
550 | "os": [
551 | "netbsd"
552 | ],
553 | "engines": {
554 | "node": ">=18"
555 | }
556 | },
557 | "node_modules/@esbuild/openbsd-arm64": {
558 | "version": "0.25.1",
559 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
560 | "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
561 | "cpu": [
562 | "arm64"
563 | ],
564 | "dev": true,
565 | "license": "MIT",
566 | "optional": true,
567 | "os": [
568 | "openbsd"
569 | ],
570 | "engines": {
571 | "node": ">=18"
572 | }
573 | },
574 | "node_modules/@esbuild/openbsd-x64": {
575 | "version": "0.25.1",
576 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
577 | "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
578 | "cpu": [
579 | "x64"
580 | ],
581 | "dev": true,
582 | "license": "MIT",
583 | "optional": true,
584 | "os": [
585 | "openbsd"
586 | ],
587 | "engines": {
588 | "node": ">=18"
589 | }
590 | },
591 | "node_modules/@esbuild/sunos-x64": {
592 | "version": "0.25.1",
593 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
594 | "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
595 | "cpu": [
596 | "x64"
597 | ],
598 | "dev": true,
599 | "license": "MIT",
600 | "optional": true,
601 | "os": [
602 | "sunos"
603 | ],
604 | "engines": {
605 | "node": ">=18"
606 | }
607 | },
608 | "node_modules/@esbuild/win32-arm64": {
609 | "version": "0.25.1",
610 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
611 | "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
612 | "cpu": [
613 | "arm64"
614 | ],
615 | "dev": true,
616 | "license": "MIT",
617 | "optional": true,
618 | "os": [
619 | "win32"
620 | ],
621 | "engines": {
622 | "node": ">=18"
623 | }
624 | },
625 | "node_modules/@esbuild/win32-ia32": {
626 | "version": "0.25.1",
627 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
628 | "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
629 | "cpu": [
630 | "ia32"
631 | ],
632 | "dev": true,
633 | "license": "MIT",
634 | "optional": true,
635 | "os": [
636 | "win32"
637 | ],
638 | "engines": {
639 | "node": ">=18"
640 | }
641 | },
642 | "node_modules/@esbuild/win32-x64": {
643 | "version": "0.25.1",
644 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
645 | "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
646 | "cpu": [
647 | "x64"
648 | ],
649 | "dev": true,
650 | "license": "MIT",
651 | "optional": true,
652 | "os": [
653 | "win32"
654 | ],
655 | "engines": {
656 | "node": ">=18"
657 | }
658 | },
659 | "node_modules/@hutson/parse-repository-url": {
660 | "version": "5.0.0",
661 | "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-5.0.0.tgz",
662 | "integrity": "sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==",
663 | "dev": true,
664 | "license": "Apache-2.0",
665 | "engines": {
666 | "node": ">=10.13.0"
667 | }
668 | },
669 | "node_modules/@rollup/rollup-android-arm-eabi": {
670 | "version": "4.44.0",
671 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz",
672 | "integrity": "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==",
673 | "cpu": [
674 | "arm"
675 | ],
676 | "dev": true,
677 | "license": "MIT",
678 | "optional": true,
679 | "os": [
680 | "android"
681 | ]
682 | },
683 | "node_modules/@rollup/rollup-android-arm64": {
684 | "version": "4.44.0",
685 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz",
686 | "integrity": "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==",
687 | "cpu": [
688 | "arm64"
689 | ],
690 | "dev": true,
691 | "license": "MIT",
692 | "optional": true,
693 | "os": [
694 | "android"
695 | ]
696 | },
697 | "node_modules/@rollup/rollup-darwin-arm64": {
698 | "version": "4.44.0",
699 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz",
700 | "integrity": "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==",
701 | "cpu": [
702 | "arm64"
703 | ],
704 | "dev": true,
705 | "license": "MIT",
706 | "optional": true,
707 | "os": [
708 | "darwin"
709 | ]
710 | },
711 | "node_modules/@rollup/rollup-darwin-x64": {
712 | "version": "4.44.0",
713 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz",
714 | "integrity": "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==",
715 | "cpu": [
716 | "x64"
717 | ],
718 | "dev": true,
719 | "license": "MIT",
720 | "optional": true,
721 | "os": [
722 | "darwin"
723 | ]
724 | },
725 | "node_modules/@rollup/rollup-freebsd-arm64": {
726 | "version": "4.44.0",
727 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz",
728 | "integrity": "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==",
729 | "cpu": [
730 | "arm64"
731 | ],
732 | "dev": true,
733 | "license": "MIT",
734 | "optional": true,
735 | "os": [
736 | "freebsd"
737 | ]
738 | },
739 | "node_modules/@rollup/rollup-freebsd-x64": {
740 | "version": "4.44.0",
741 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz",
742 | "integrity": "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==",
743 | "cpu": [
744 | "x64"
745 | ],
746 | "dev": true,
747 | "license": "MIT",
748 | "optional": true,
749 | "os": [
750 | "freebsd"
751 | ]
752 | },
753 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
754 | "version": "4.44.0",
755 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz",
756 | "integrity": "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==",
757 | "cpu": [
758 | "arm"
759 | ],
760 | "dev": true,
761 | "license": "MIT",
762 | "optional": true,
763 | "os": [
764 | "linux"
765 | ]
766 | },
767 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
768 | "version": "4.44.0",
769 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz",
770 | "integrity": "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==",
771 | "cpu": [
772 | "arm"
773 | ],
774 | "dev": true,
775 | "license": "MIT",
776 | "optional": true,
777 | "os": [
778 | "linux"
779 | ]
780 | },
781 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
782 | "version": "4.44.0",
783 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz",
784 | "integrity": "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==",
785 | "cpu": [
786 | "arm64"
787 | ],
788 | "dev": true,
789 | "license": "MIT",
790 | "optional": true,
791 | "os": [
792 | "linux"
793 | ]
794 | },
795 | "node_modules/@rollup/rollup-linux-arm64-musl": {
796 | "version": "4.44.0",
797 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz",
798 | "integrity": "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==",
799 | "cpu": [
800 | "arm64"
801 | ],
802 | "dev": true,
803 | "license": "MIT",
804 | "optional": true,
805 | "os": [
806 | "linux"
807 | ]
808 | },
809 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
810 | "version": "4.44.0",
811 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz",
812 | "integrity": "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==",
813 | "cpu": [
814 | "loong64"
815 | ],
816 | "dev": true,
817 | "license": "MIT",
818 | "optional": true,
819 | "os": [
820 | "linux"
821 | ]
822 | },
823 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
824 | "version": "4.44.0",
825 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz",
826 | "integrity": "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==",
827 | "cpu": [
828 | "ppc64"
829 | ],
830 | "dev": true,
831 | "license": "MIT",
832 | "optional": true,
833 | "os": [
834 | "linux"
835 | ]
836 | },
837 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
838 | "version": "4.44.0",
839 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz",
840 | "integrity": "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==",
841 | "cpu": [
842 | "riscv64"
843 | ],
844 | "dev": true,
845 | "license": "MIT",
846 | "optional": true,
847 | "os": [
848 | "linux"
849 | ]
850 | },
851 | "node_modules/@rollup/rollup-linux-riscv64-musl": {
852 | "version": "4.44.0",
853 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz",
854 | "integrity": "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==",
855 | "cpu": [
856 | "riscv64"
857 | ],
858 | "dev": true,
859 | "license": "MIT",
860 | "optional": true,
861 | "os": [
862 | "linux"
863 | ]
864 | },
865 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
866 | "version": "4.44.0",
867 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz",
868 | "integrity": "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==",
869 | "cpu": [
870 | "s390x"
871 | ],
872 | "dev": true,
873 | "license": "MIT",
874 | "optional": true,
875 | "os": [
876 | "linux"
877 | ]
878 | },
879 | "node_modules/@rollup/rollup-linux-x64-gnu": {
880 | "version": "4.44.0",
881 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz",
882 | "integrity": "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==",
883 | "cpu": [
884 | "x64"
885 | ],
886 | "dev": true,
887 | "license": "MIT",
888 | "optional": true,
889 | "os": [
890 | "linux"
891 | ]
892 | },
893 | "node_modules/@rollup/rollup-linux-x64-musl": {
894 | "version": "4.44.0",
895 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz",
896 | "integrity": "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==",
897 | "cpu": [
898 | "x64"
899 | ],
900 | "dev": true,
901 | "license": "MIT",
902 | "optional": true,
903 | "os": [
904 | "linux"
905 | ]
906 | },
907 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
908 | "version": "4.44.0",
909 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz",
910 | "integrity": "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==",
911 | "cpu": [
912 | "arm64"
913 | ],
914 | "dev": true,
915 | "license": "MIT",
916 | "optional": true,
917 | "os": [
918 | "win32"
919 | ]
920 | },
921 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
922 | "version": "4.44.0",
923 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz",
924 | "integrity": "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==",
925 | "cpu": [
926 | "ia32"
927 | ],
928 | "dev": true,
929 | "license": "MIT",
930 | "optional": true,
931 | "os": [
932 | "win32"
933 | ]
934 | },
935 | "node_modules/@rollup/rollup-win32-x64-msvc": {
936 | "version": "4.44.0",
937 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz",
938 | "integrity": "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==",
939 | "cpu": [
940 | "x64"
941 | ],
942 | "dev": true,
943 | "license": "MIT",
944 | "optional": true,
945 | "os": [
946 | "win32"
947 | ]
948 | },
949 | "node_modules/@types/estree": {
950 | "version": "1.0.8",
951 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
952 | "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
953 | "dev": true,
954 | "license": "MIT"
955 | },
956 | "node_modules/@types/normalize-package-data": {
957 | "version": "2.4.4",
958 | "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
959 | "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
960 | "dev": true,
961 | "license": "MIT"
962 | },
963 | "node_modules/@types/semver": {
964 | "version": "7.5.8",
965 | "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
966 | "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
967 | "dev": true,
968 | "license": "MIT"
969 | },
970 | "node_modules/add-stream": {
971 | "version": "1.0.0",
972 | "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
973 | "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
974 | "dev": true,
975 | "license": "MIT"
976 | },
977 | "node_modules/array-ify": {
978 | "version": "1.0.0",
979 | "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
980 | "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
981 | "dev": true,
982 | "license": "MIT"
983 | },
984 | "node_modules/compare-func": {
985 | "version": "2.0.0",
986 | "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
987 | "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
988 | "dev": true,
989 | "license": "MIT",
990 | "dependencies": {
991 | "array-ify": "^1.0.0",
992 | "dot-prop": "^5.1.0"
993 | }
994 | },
995 | "node_modules/conventional-changelog": {
996 | "version": "6.0.0",
997 | "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-6.0.0.tgz",
998 | "integrity": "sha512-tuUH8H/19VjtD9Ig7l6TQRh+Z0Yt0NZ6w/cCkkyzUbGQTnUEmKfGtkC9gGfVgCfOL1Rzno5NgNF4KY8vR+Jo3w==",
999 | "dev": true,
1000 | "license": "MIT",
1001 | "dependencies": {
1002 | "conventional-changelog-angular": "^8.0.0",
1003 | "conventional-changelog-atom": "^5.0.0",
1004 | "conventional-changelog-codemirror": "^5.0.0",
1005 | "conventional-changelog-conventionalcommits": "^8.0.0",
1006 | "conventional-changelog-core": "^8.0.0",
1007 | "conventional-changelog-ember": "^5.0.0",
1008 | "conventional-changelog-eslint": "^6.0.0",
1009 | "conventional-changelog-express": "^5.0.0",
1010 | "conventional-changelog-jquery": "^6.0.0",
1011 | "conventional-changelog-jshint": "^5.0.0",
1012 | "conventional-changelog-preset-loader": "^5.0.0"
1013 | },
1014 | "engines": {
1015 | "node": ">=18"
1016 | }
1017 | },
1018 | "node_modules/conventional-changelog-angular": {
1019 | "version": "8.0.0",
1020 | "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz",
1021 | "integrity": "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==",
1022 | "dev": true,
1023 | "license": "ISC",
1024 | "dependencies": {
1025 | "compare-func": "^2.0.0"
1026 | },
1027 | "engines": {
1028 | "node": ">=18"
1029 | }
1030 | },
1031 | "node_modules/conventional-changelog-atom": {
1032 | "version": "5.0.0",
1033 | "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-5.0.0.tgz",
1034 | "integrity": "sha512-WfzCaAvSCFPkznnLgLnfacRAzjgqjLUjvf3MftfsJzQdDICqkOOpcMtdJF3wTerxSpv2IAAjX8doM3Vozqle3g==",
1035 | "dev": true,
1036 | "license": "ISC",
1037 | "engines": {
1038 | "node": ">=18"
1039 | }
1040 | },
1041 | "node_modules/conventional-changelog-cli": {
1042 | "version": "5.0.0",
1043 | "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-5.0.0.tgz",
1044 | "integrity": "sha512-9Y8fucJe18/6ef6ZlyIlT2YQUbczvoQZZuYmDLaGvcSBP+M6h+LAvf7ON7waRxKJemcCII8Yqu5/8HEfskTxJQ==",
1045 | "dev": true,
1046 | "license": "MIT",
1047 | "dependencies": {
1048 | "add-stream": "^1.0.0",
1049 | "conventional-changelog": "^6.0.0",
1050 | "meow": "^13.0.0",
1051 | "tempfile": "^5.0.0"
1052 | },
1053 | "bin": {
1054 | "conventional-changelog": "cli.js"
1055 | },
1056 | "engines": {
1057 | "node": ">=18"
1058 | }
1059 | },
1060 | "node_modules/conventional-changelog-codemirror": {
1061 | "version": "5.0.0",
1062 | "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-5.0.0.tgz",
1063 | "integrity": "sha512-8gsBDI5Y3vrKUCxN6Ue8xr6occZ5nsDEc4C7jO/EovFGozx8uttCAyfhRrvoUAWi2WMm3OmYs+0mPJU7kQdYWQ==",
1064 | "dev": true,
1065 | "license": "ISC",
1066 | "engines": {
1067 | "node": ">=18"
1068 | }
1069 | },
1070 | "node_modules/conventional-changelog-conventionalcommits": {
1071 | "version": "8.0.0",
1072 | "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-8.0.0.tgz",
1073 | "integrity": "sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA==",
1074 | "dev": true,
1075 | "license": "ISC",
1076 | "dependencies": {
1077 | "compare-func": "^2.0.0"
1078 | },
1079 | "engines": {
1080 | "node": ">=18"
1081 | }
1082 | },
1083 | "node_modules/conventional-changelog-core": {
1084 | "version": "8.0.0",
1085 | "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-8.0.0.tgz",
1086 | "integrity": "sha512-EATUx5y9xewpEe10UEGNpbSHRC6cVZgO+hXQjofMqpy+gFIrcGvH3Fl6yk2VFKh7m+ffenup2N7SZJYpyD9evw==",
1087 | "dev": true,
1088 | "license": "MIT",
1089 | "dependencies": {
1090 | "@hutson/parse-repository-url": "^5.0.0",
1091 | "add-stream": "^1.0.0",
1092 | "conventional-changelog-writer": "^8.0.0",
1093 | "conventional-commits-parser": "^6.0.0",
1094 | "git-raw-commits": "^5.0.0",
1095 | "git-semver-tags": "^8.0.0",
1096 | "hosted-git-info": "^7.0.0",
1097 | "normalize-package-data": "^6.0.0",
1098 | "read-package-up": "^11.0.0",
1099 | "read-pkg": "^9.0.0"
1100 | },
1101 | "engines": {
1102 | "node": ">=18"
1103 | }
1104 | },
1105 | "node_modules/conventional-changelog-ember": {
1106 | "version": "5.0.0",
1107 | "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-5.0.0.tgz",
1108 | "integrity": "sha512-RPflVfm5s4cSO33GH/Ey26oxhiC67akcxSKL8CLRT3kQX2W3dbE19sSOM56iFqUJYEwv9mD9r6k79weWe1urfg==",
1109 | "dev": true,
1110 | "license": "ISC",
1111 | "engines": {
1112 | "node": ">=18"
1113 | }
1114 | },
1115 | "node_modules/conventional-changelog-eslint": {
1116 | "version": "6.0.0",
1117 | "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-6.0.0.tgz",
1118 | "integrity": "sha512-eiUyULWjzq+ybPjXwU6NNRflApDWlPEQEHvI8UAItYW/h22RKkMnOAtfCZxMmrcMO1OKUWtcf2MxKYMWe9zJuw==",
1119 | "dev": true,
1120 | "license": "ISC",
1121 | "engines": {
1122 | "node": ">=18"
1123 | }
1124 | },
1125 | "node_modules/conventional-changelog-express": {
1126 | "version": "5.0.0",
1127 | "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-5.0.0.tgz",
1128 | "integrity": "sha512-D8Q6WctPkQpvr2HNCCmwU5GkX22BVHM0r4EW8vN0230TSyS/d6VQJDAxGb84lbg0dFjpO22MwmsikKL++Oo/oQ==",
1129 | "dev": true,
1130 | "license": "ISC",
1131 | "engines": {
1132 | "node": ">=18"
1133 | }
1134 | },
1135 | "node_modules/conventional-changelog-jquery": {
1136 | "version": "6.0.0",
1137 | "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-6.0.0.tgz",
1138 | "integrity": "sha512-2kxmVakyehgyrho2ZHBi90v4AHswkGzHuTaoH40bmeNqUt20yEkDOSpw8HlPBfvEQBwGtbE+5HpRwzj6ac2UfA==",
1139 | "dev": true,
1140 | "license": "ISC",
1141 | "engines": {
1142 | "node": ">=18"
1143 | }
1144 | },
1145 | "node_modules/conventional-changelog-jshint": {
1146 | "version": "5.0.0",
1147 | "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-5.0.0.tgz",
1148 | "integrity": "sha512-gGNphSb/opc76n2eWaO6ma4/Wqu3tpa2w7i9WYqI6Cs2fncDSI2/ihOfMvXveeTTeld0oFvwMVNV+IYQIk3F3g==",
1149 | "dev": true,
1150 | "license": "ISC",
1151 | "dependencies": {
1152 | "compare-func": "^2.0.0"
1153 | },
1154 | "engines": {
1155 | "node": ">=18"
1156 | }
1157 | },
1158 | "node_modules/conventional-changelog-preset-loader": {
1159 | "version": "5.0.0",
1160 | "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-5.0.0.tgz",
1161 | "integrity": "sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==",
1162 | "dev": true,
1163 | "license": "MIT",
1164 | "engines": {
1165 | "node": ">=18"
1166 | }
1167 | },
1168 | "node_modules/conventional-changelog-writer": {
1169 | "version": "8.0.1",
1170 | "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.0.1.tgz",
1171 | "integrity": "sha512-hlqcy3xHred2gyYg/zXSMXraY2mjAYYo0msUCpK+BGyaVJMFCKWVXPIHiaacGO2GGp13kvHWXFhYmxT4QQqW3Q==",
1172 | "dev": true,
1173 | "license": "MIT",
1174 | "dependencies": {
1175 | "conventional-commits-filter": "^5.0.0",
1176 | "handlebars": "^4.7.7",
1177 | "meow": "^13.0.0",
1178 | "semver": "^7.5.2"
1179 | },
1180 | "bin": {
1181 | "conventional-changelog-writer": "dist/cli/index.js"
1182 | },
1183 | "engines": {
1184 | "node": ">=18"
1185 | }
1186 | },
1187 | "node_modules/conventional-commits-filter": {
1188 | "version": "5.0.0",
1189 | "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz",
1190 | "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==",
1191 | "dev": true,
1192 | "license": "MIT",
1193 | "engines": {
1194 | "node": ">=18"
1195 | }
1196 | },
1197 | "node_modules/conventional-commits-parser": {
1198 | "version": "6.1.0",
1199 | "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.1.0.tgz",
1200 | "integrity": "sha512-5nxDo7TwKB5InYBl4ZC//1g9GRwB/F3TXOGR9hgUjMGfvSP4Vu5NkpNro2+1+TIEy1vwxApl5ircECr2ri5JIw==",
1201 | "dev": true,
1202 | "license": "MIT",
1203 | "dependencies": {
1204 | "meow": "^13.0.0"
1205 | },
1206 | "bin": {
1207 | "conventional-commits-parser": "dist/cli/index.js"
1208 | },
1209 | "engines": {
1210 | "node": ">=18"
1211 | }
1212 | },
1213 | "node_modules/dot-prop": {
1214 | "version": "5.3.0",
1215 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
1216 | "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
1217 | "dev": true,
1218 | "license": "MIT",
1219 | "dependencies": {
1220 | "is-obj": "^2.0.0"
1221 | },
1222 | "engines": {
1223 | "node": ">=8"
1224 | }
1225 | },
1226 | "node_modules/esbuild": {
1227 | "version": "0.25.1",
1228 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
1229 | "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
1230 | "dev": true,
1231 | "hasInstallScript": true,
1232 | "license": "MIT",
1233 | "bin": {
1234 | "esbuild": "bin/esbuild"
1235 | },
1236 | "engines": {
1237 | "node": ">=18"
1238 | },
1239 | "optionalDependencies": {
1240 | "@esbuild/aix-ppc64": "0.25.1",
1241 | "@esbuild/android-arm": "0.25.1",
1242 | "@esbuild/android-arm64": "0.25.1",
1243 | "@esbuild/android-x64": "0.25.1",
1244 | "@esbuild/darwin-arm64": "0.25.1",
1245 | "@esbuild/darwin-x64": "0.25.1",
1246 | "@esbuild/freebsd-arm64": "0.25.1",
1247 | "@esbuild/freebsd-x64": "0.25.1",
1248 | "@esbuild/linux-arm": "0.25.1",
1249 | "@esbuild/linux-arm64": "0.25.1",
1250 | "@esbuild/linux-ia32": "0.25.1",
1251 | "@esbuild/linux-loong64": "0.25.1",
1252 | "@esbuild/linux-mips64el": "0.25.1",
1253 | "@esbuild/linux-ppc64": "0.25.1",
1254 | "@esbuild/linux-riscv64": "0.25.1",
1255 | "@esbuild/linux-s390x": "0.25.1",
1256 | "@esbuild/linux-x64": "0.25.1",
1257 | "@esbuild/netbsd-arm64": "0.25.1",
1258 | "@esbuild/netbsd-x64": "0.25.1",
1259 | "@esbuild/openbsd-arm64": "0.25.1",
1260 | "@esbuild/openbsd-x64": "0.25.1",
1261 | "@esbuild/sunos-x64": "0.25.1",
1262 | "@esbuild/win32-arm64": "0.25.1",
1263 | "@esbuild/win32-ia32": "0.25.1",
1264 | "@esbuild/win32-x64": "0.25.1"
1265 | }
1266 | },
1267 | "node_modules/fdir": {
1268 | "version": "6.4.6",
1269 | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
1270 | "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
1271 | "dev": true,
1272 | "license": "MIT",
1273 | "peerDependencies": {
1274 | "picomatch": "^3 || ^4"
1275 | },
1276 | "peerDependenciesMeta": {
1277 | "picomatch": {
1278 | "optional": true
1279 | }
1280 | }
1281 | },
1282 | "node_modules/find-up-simple": {
1283 | "version": "1.0.1",
1284 | "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
1285 | "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
1286 | "dev": true,
1287 | "license": "MIT",
1288 | "engines": {
1289 | "node": ">=18"
1290 | },
1291 | "funding": {
1292 | "url": "https://github.com/sponsors/sindresorhus"
1293 | }
1294 | },
1295 | "node_modules/fsevents": {
1296 | "version": "2.3.3",
1297 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1298 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1299 | "dev": true,
1300 | "hasInstallScript": true,
1301 | "license": "MIT",
1302 | "optional": true,
1303 | "os": [
1304 | "darwin"
1305 | ],
1306 | "engines": {
1307 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1308 | }
1309 | },
1310 | "node_modules/git-raw-commits": {
1311 | "version": "5.0.0",
1312 | "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.0.tgz",
1313 | "integrity": "sha512-I2ZXrXeOc0KrCvC7swqtIFXFN+rbjnC7b2T943tvemIOVNl+XP8YnA9UVwqFhzzLClnSA60KR/qEjLpXzs73Qg==",
1314 | "dev": true,
1315 | "license": "MIT",
1316 | "dependencies": {
1317 | "@conventional-changelog/git-client": "^1.0.0",
1318 | "meow": "^13.0.0"
1319 | },
1320 | "bin": {
1321 | "git-raw-commits": "src/cli.js"
1322 | },
1323 | "engines": {
1324 | "node": ">=18"
1325 | }
1326 | },
1327 | "node_modules/git-semver-tags": {
1328 | "version": "8.0.0",
1329 | "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-8.0.0.tgz",
1330 | "integrity": "sha512-N7YRIklvPH3wYWAR2vysaqGLPRcpwQ0GKdlqTiVN5w1UmCdaeY3K8s6DMKRCh54DDdzyt/OAB6C8jgVtb7Y2Fg==",
1331 | "dev": true,
1332 | "license": "MIT",
1333 | "dependencies": {
1334 | "@conventional-changelog/git-client": "^1.0.0",
1335 | "meow": "^13.0.0"
1336 | },
1337 | "bin": {
1338 | "git-semver-tags": "src/cli.js"
1339 | },
1340 | "engines": {
1341 | "node": ">=18"
1342 | }
1343 | },
1344 | "node_modules/handlebars": {
1345 | "version": "4.7.8",
1346 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
1347 | "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
1348 | "dev": true,
1349 | "license": "MIT",
1350 | "dependencies": {
1351 | "minimist": "^1.2.5",
1352 | "neo-async": "^2.6.2",
1353 | "source-map": "^0.6.1",
1354 | "wordwrap": "^1.0.0"
1355 | },
1356 | "bin": {
1357 | "handlebars": "bin/handlebars"
1358 | },
1359 | "engines": {
1360 | "node": ">=0.4.7"
1361 | },
1362 | "optionalDependencies": {
1363 | "uglify-js": "^3.1.4"
1364 | }
1365 | },
1366 | "node_modules/hosted-git-info": {
1367 | "version": "7.0.2",
1368 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
1369 | "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
1370 | "dev": true,
1371 | "license": "ISC",
1372 | "dependencies": {
1373 | "lru-cache": "^10.0.1"
1374 | },
1375 | "engines": {
1376 | "node": "^16.14.0 || >=18.0.0"
1377 | }
1378 | },
1379 | "node_modules/index-to-position": {
1380 | "version": "1.0.0",
1381 | "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.0.0.tgz",
1382 | "integrity": "sha512-sCO7uaLVhRJ25vz1o8s9IFM3nVS4DkuQnyjMwiQPKvQuBYBDmb8H7zx8ki7nVh4HJQOdVWebyvLE0qt+clruxA==",
1383 | "dev": true,
1384 | "license": "MIT",
1385 | "engines": {
1386 | "node": ">=18"
1387 | },
1388 | "funding": {
1389 | "url": "https://github.com/sponsors/sindresorhus"
1390 | }
1391 | },
1392 | "node_modules/is-obj": {
1393 | "version": "2.0.0",
1394 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
1395 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
1396 | "dev": true,
1397 | "license": "MIT",
1398 | "engines": {
1399 | "node": ">=8"
1400 | }
1401 | },
1402 | "node_modules/js-tokens": {
1403 | "version": "4.0.0",
1404 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1405 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1406 | "dev": true,
1407 | "license": "MIT"
1408 | },
1409 | "node_modules/lru-cache": {
1410 | "version": "10.4.3",
1411 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1412 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1413 | "dev": true,
1414 | "license": "ISC"
1415 | },
1416 | "node_modules/meow": {
1417 | "version": "13.2.0",
1418 | "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
1419 | "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
1420 | "dev": true,
1421 | "license": "MIT",
1422 | "engines": {
1423 | "node": ">=18"
1424 | },
1425 | "funding": {
1426 | "url": "https://github.com/sponsors/sindresorhus"
1427 | }
1428 | },
1429 | "node_modules/minimist": {
1430 | "version": "1.2.8",
1431 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1432 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
1433 | "dev": true,
1434 | "license": "MIT",
1435 | "funding": {
1436 | "url": "https://github.com/sponsors/ljharb"
1437 | }
1438 | },
1439 | "node_modules/nanoid": {
1440 | "version": "3.3.11",
1441 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1442 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1443 | "dev": true,
1444 | "funding": [
1445 | {
1446 | "type": "github",
1447 | "url": "https://github.com/sponsors/ai"
1448 | }
1449 | ],
1450 | "license": "MIT",
1451 | "bin": {
1452 | "nanoid": "bin/nanoid.cjs"
1453 | },
1454 | "engines": {
1455 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1456 | }
1457 | },
1458 | "node_modules/neo-async": {
1459 | "version": "2.6.2",
1460 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
1461 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
1462 | "dev": true,
1463 | "license": "MIT"
1464 | },
1465 | "node_modules/normalize-package-data": {
1466 | "version": "6.0.2",
1467 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz",
1468 | "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==",
1469 | "dev": true,
1470 | "license": "BSD-2-Clause",
1471 | "dependencies": {
1472 | "hosted-git-info": "^7.0.0",
1473 | "semver": "^7.3.5",
1474 | "validate-npm-package-license": "^3.0.4"
1475 | },
1476 | "engines": {
1477 | "node": "^16.14.0 || >=18.0.0"
1478 | }
1479 | },
1480 | "node_modules/parse-json": {
1481 | "version": "8.2.0",
1482 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.2.0.tgz",
1483 | "integrity": "sha512-eONBZy4hm2AgxjNFd8a4nyDJnzUAH0g34xSQAwWEVGCjdZ4ZL7dKZBfq267GWP/JaS9zW62Xs2FeAdDvpHHJGQ==",
1484 | "dev": true,
1485 | "license": "MIT",
1486 | "dependencies": {
1487 | "@babel/code-frame": "^7.26.2",
1488 | "index-to-position": "^1.0.0",
1489 | "type-fest": "^4.37.0"
1490 | },
1491 | "engines": {
1492 | "node": ">=18"
1493 | },
1494 | "funding": {
1495 | "url": "https://github.com/sponsors/sindresorhus"
1496 | }
1497 | },
1498 | "node_modules/picocolors": {
1499 | "version": "1.1.1",
1500 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1501 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1502 | "dev": true,
1503 | "license": "ISC"
1504 | },
1505 | "node_modules/picomatch": {
1506 | "version": "4.0.2",
1507 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
1508 | "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
1509 | "dev": true,
1510 | "license": "MIT",
1511 | "engines": {
1512 | "node": ">=12"
1513 | },
1514 | "funding": {
1515 | "url": "https://github.com/sponsors/jonschlinkert"
1516 | }
1517 | },
1518 | "node_modules/postcss": {
1519 | "version": "8.5.6",
1520 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
1521 | "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
1522 | "dev": true,
1523 | "funding": [
1524 | {
1525 | "type": "opencollective",
1526 | "url": "https://opencollective.com/postcss/"
1527 | },
1528 | {
1529 | "type": "tidelift",
1530 | "url": "https://tidelift.com/funding/github/npm/postcss"
1531 | },
1532 | {
1533 | "type": "github",
1534 | "url": "https://github.com/sponsors/ai"
1535 | }
1536 | ],
1537 | "license": "MIT",
1538 | "dependencies": {
1539 | "nanoid": "^3.3.11",
1540 | "picocolors": "^1.1.1",
1541 | "source-map-js": "^1.2.1"
1542 | },
1543 | "engines": {
1544 | "node": "^10 || ^12 || >=14"
1545 | }
1546 | },
1547 | "node_modules/read-package-up": {
1548 | "version": "11.0.0",
1549 | "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
1550 | "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==",
1551 | "dev": true,
1552 | "license": "MIT",
1553 | "dependencies": {
1554 | "find-up-simple": "^1.0.0",
1555 | "read-pkg": "^9.0.0",
1556 | "type-fest": "^4.6.0"
1557 | },
1558 | "engines": {
1559 | "node": ">=18"
1560 | },
1561 | "funding": {
1562 | "url": "https://github.com/sponsors/sindresorhus"
1563 | }
1564 | },
1565 | "node_modules/read-pkg": {
1566 | "version": "9.0.1",
1567 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
1568 | "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
1569 | "dev": true,
1570 | "license": "MIT",
1571 | "dependencies": {
1572 | "@types/normalize-package-data": "^2.4.3",
1573 | "normalize-package-data": "^6.0.0",
1574 | "parse-json": "^8.0.0",
1575 | "type-fest": "^4.6.0",
1576 | "unicorn-magic": "^0.1.0"
1577 | },
1578 | "engines": {
1579 | "node": ">=18"
1580 | },
1581 | "funding": {
1582 | "url": "https://github.com/sponsors/sindresorhus"
1583 | }
1584 | },
1585 | "node_modules/rollup": {
1586 | "version": "4.44.0",
1587 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.0.tgz",
1588 | "integrity": "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==",
1589 | "dev": true,
1590 | "license": "MIT",
1591 | "dependencies": {
1592 | "@types/estree": "1.0.8"
1593 | },
1594 | "bin": {
1595 | "rollup": "dist/bin/rollup"
1596 | },
1597 | "engines": {
1598 | "node": ">=18.0.0",
1599 | "npm": ">=8.0.0"
1600 | },
1601 | "optionalDependencies": {
1602 | "@rollup/rollup-android-arm-eabi": "4.44.0",
1603 | "@rollup/rollup-android-arm64": "4.44.0",
1604 | "@rollup/rollup-darwin-arm64": "4.44.0",
1605 | "@rollup/rollup-darwin-x64": "4.44.0",
1606 | "@rollup/rollup-freebsd-arm64": "4.44.0",
1607 | "@rollup/rollup-freebsd-x64": "4.44.0",
1608 | "@rollup/rollup-linux-arm-gnueabihf": "4.44.0",
1609 | "@rollup/rollup-linux-arm-musleabihf": "4.44.0",
1610 | "@rollup/rollup-linux-arm64-gnu": "4.44.0",
1611 | "@rollup/rollup-linux-arm64-musl": "4.44.0",
1612 | "@rollup/rollup-linux-loongarch64-gnu": "4.44.0",
1613 | "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0",
1614 | "@rollup/rollup-linux-riscv64-gnu": "4.44.0",
1615 | "@rollup/rollup-linux-riscv64-musl": "4.44.0",
1616 | "@rollup/rollup-linux-s390x-gnu": "4.44.0",
1617 | "@rollup/rollup-linux-x64-gnu": "4.44.0",
1618 | "@rollup/rollup-linux-x64-musl": "4.44.0",
1619 | "@rollup/rollup-win32-arm64-msvc": "4.44.0",
1620 | "@rollup/rollup-win32-ia32-msvc": "4.44.0",
1621 | "@rollup/rollup-win32-x64-msvc": "4.44.0",
1622 | "fsevents": "~2.3.2"
1623 | }
1624 | },
1625 | "node_modules/semver": {
1626 | "version": "7.7.1",
1627 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
1628 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
1629 | "dev": true,
1630 | "license": "ISC",
1631 | "bin": {
1632 | "semver": "bin/semver.js"
1633 | },
1634 | "engines": {
1635 | "node": ">=10"
1636 | }
1637 | },
1638 | "node_modules/source-map": {
1639 | "version": "0.6.1",
1640 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1641 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1642 | "dev": true,
1643 | "license": "BSD-3-Clause",
1644 | "engines": {
1645 | "node": ">=0.10.0"
1646 | }
1647 | },
1648 | "node_modules/source-map-js": {
1649 | "version": "1.2.1",
1650 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1651 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1652 | "dev": true,
1653 | "license": "BSD-3-Clause",
1654 | "engines": {
1655 | "node": ">=0.10.0"
1656 | }
1657 | },
1658 | "node_modules/spdx-correct": {
1659 | "version": "3.2.0",
1660 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
1661 | "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
1662 | "dev": true,
1663 | "license": "Apache-2.0",
1664 | "dependencies": {
1665 | "spdx-expression-parse": "^3.0.0",
1666 | "spdx-license-ids": "^3.0.0"
1667 | }
1668 | },
1669 | "node_modules/spdx-exceptions": {
1670 | "version": "2.5.0",
1671 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
1672 | "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
1673 | "dev": true,
1674 | "license": "CC-BY-3.0"
1675 | },
1676 | "node_modules/spdx-expression-parse": {
1677 | "version": "3.0.1",
1678 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
1679 | "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
1680 | "dev": true,
1681 | "license": "MIT",
1682 | "dependencies": {
1683 | "spdx-exceptions": "^2.1.0",
1684 | "spdx-license-ids": "^3.0.0"
1685 | }
1686 | },
1687 | "node_modules/spdx-license-ids": {
1688 | "version": "3.0.21",
1689 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
1690 | "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
1691 | "dev": true,
1692 | "license": "CC0-1.0"
1693 | },
1694 | "node_modules/temp-dir": {
1695 | "version": "3.0.0",
1696 | "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz",
1697 | "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==",
1698 | "dev": true,
1699 | "license": "MIT",
1700 | "engines": {
1701 | "node": ">=14.16"
1702 | }
1703 | },
1704 | "node_modules/tempfile": {
1705 | "version": "5.0.0",
1706 | "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-5.0.0.tgz",
1707 | "integrity": "sha512-bX655WZI/F7EoTDw9JvQURqAXiPHi8o8+yFxPF2lWYyz1aHnmMRuXWqL6YB6GmeO0o4DIYWHLgGNi/X64T+X4Q==",
1708 | "dev": true,
1709 | "license": "MIT",
1710 | "dependencies": {
1711 | "temp-dir": "^3.0.0"
1712 | },
1713 | "engines": {
1714 | "node": ">=14.18"
1715 | },
1716 | "funding": {
1717 | "url": "https://github.com/sponsors/sindresorhus"
1718 | }
1719 | },
1720 | "node_modules/tinyglobby": {
1721 | "version": "0.2.14",
1722 | "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
1723 | "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
1724 | "dev": true,
1725 | "license": "MIT",
1726 | "dependencies": {
1727 | "fdir": "^6.4.4",
1728 | "picomatch": "^4.0.2"
1729 | },
1730 | "engines": {
1731 | "node": ">=12.0.0"
1732 | },
1733 | "funding": {
1734 | "url": "https://github.com/sponsors/SuperchupuDev"
1735 | }
1736 | },
1737 | "node_modules/type-fest": {
1738 | "version": "4.37.0",
1739 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz",
1740 | "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==",
1741 | "dev": true,
1742 | "license": "(MIT OR CC0-1.0)",
1743 | "engines": {
1744 | "node": ">=16"
1745 | },
1746 | "funding": {
1747 | "url": "https://github.com/sponsors/sindresorhus"
1748 | }
1749 | },
1750 | "node_modules/uglify-js": {
1751 | "version": "3.19.3",
1752 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
1753 | "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
1754 | "dev": true,
1755 | "license": "BSD-2-Clause",
1756 | "optional": true,
1757 | "bin": {
1758 | "uglifyjs": "bin/uglifyjs"
1759 | },
1760 | "engines": {
1761 | "node": ">=0.8.0"
1762 | }
1763 | },
1764 | "node_modules/unicorn-magic": {
1765 | "version": "0.1.0",
1766 | "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
1767 | "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
1768 | "dev": true,
1769 | "license": "MIT",
1770 | "engines": {
1771 | "node": ">=18"
1772 | },
1773 | "funding": {
1774 | "url": "https://github.com/sponsors/sindresorhus"
1775 | }
1776 | },
1777 | "node_modules/validate-npm-package-license": {
1778 | "version": "3.0.4",
1779 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
1780 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
1781 | "dev": true,
1782 | "license": "Apache-2.0",
1783 | "dependencies": {
1784 | "spdx-correct": "^3.0.0",
1785 | "spdx-expression-parse": "^3.0.0"
1786 | }
1787 | },
1788 | "node_modules/vite": {
1789 | "version": "7.0.0",
1790 | "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.0.tgz",
1791 | "integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==",
1792 | "dev": true,
1793 | "license": "MIT",
1794 | "dependencies": {
1795 | "esbuild": "^0.25.0",
1796 | "fdir": "^6.4.6",
1797 | "picomatch": "^4.0.2",
1798 | "postcss": "^8.5.6",
1799 | "rollup": "^4.40.0",
1800 | "tinyglobby": "^0.2.14"
1801 | },
1802 | "bin": {
1803 | "vite": "bin/vite.js"
1804 | },
1805 | "engines": {
1806 | "node": "^20.19.0 || >=22.12.0"
1807 | },
1808 | "funding": {
1809 | "url": "https://github.com/vitejs/vite?sponsor=1"
1810 | },
1811 | "optionalDependencies": {
1812 | "fsevents": "~2.3.3"
1813 | },
1814 | "peerDependencies": {
1815 | "@types/node": "^20.19.0 || >=22.12.0",
1816 | "jiti": ">=1.21.0",
1817 | "less": "^4.0.0",
1818 | "lightningcss": "^1.21.0",
1819 | "sass": "^1.70.0",
1820 | "sass-embedded": "^1.70.0",
1821 | "stylus": ">=0.54.8",
1822 | "sugarss": "^5.0.0",
1823 | "terser": "^5.16.0",
1824 | "tsx": "^4.8.1",
1825 | "yaml": "^2.4.2"
1826 | },
1827 | "peerDependenciesMeta": {
1828 | "@types/node": {
1829 | "optional": true
1830 | },
1831 | "jiti": {
1832 | "optional": true
1833 | },
1834 | "less": {
1835 | "optional": true
1836 | },
1837 | "lightningcss": {
1838 | "optional": true
1839 | },
1840 | "sass": {
1841 | "optional": true
1842 | },
1843 | "sass-embedded": {
1844 | "optional": true
1845 | },
1846 | "stylus": {
1847 | "optional": true
1848 | },
1849 | "sugarss": {
1850 | "optional": true
1851 | },
1852 | "terser": {
1853 | "optional": true
1854 | },
1855 | "tsx": {
1856 | "optional": true
1857 | },
1858 | "yaml": {
1859 | "optional": true
1860 | }
1861 | }
1862 | },
1863 | "node_modules/wordwrap": {
1864 | "version": "1.0.0",
1865 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1866 | "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
1867 | "dev": true,
1868 | "license": "MIT"
1869 | }
1870 | }
1871 | }
1872 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "progressive-image-element",
3 | "version": "1.3.0",
4 | "description": "A progressive image element",
5 | "license": "MIT",
6 | "funding": "https://github.com/andreruffert/progressive-image-element?sponsor=1",
7 | "homepage": "https://andreruffert.github.io/progressive-image-element/",
8 | "author": {
9 | "name": "André Ruffert",
10 | "url": "https://andreruffert.com"
11 | },
12 | "type": "module",
13 | "module": "dist/progressive-image-element.js",
14 | "main": "dist/progressive-image-element.umd.cjs",
15 | "exports": {
16 | ".": {
17 | "import": "./dist/progressive-image-element.js",
18 | "require": "./dist/progressive-image-element.umd.cjs"
19 | },
20 | "./style.css": "./dist/progressive-image-element.css"
21 | },
22 | "files": [
23 | "dist"
24 | ],
25 | "scripts": {
26 | "dev": "vite",
27 | "dev:docs": "vite --config vite.docs.config.js",
28 | "build": "vite build",
29 | "format": "biome check --write",
30 | "lint": "biome ci",
31 | "prepublishOnly": "npm run build",
32 | "version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md"
33 | },
34 | "devDependencies": {
35 | "@biomejs/biome": "2.0.0",
36 | "conventional-changelog-cli": "5.0.0",
37 | "vite": "7.0.0"
38 | },
39 | "volta": {
40 | "node": "22.13.1",
41 | "npm": "11.1.0"
42 | },
43 | "repository": {
44 | "type": "git",
45 | "url": "git+https://github.com/andreruffert/progressive-image-element.git"
46 | },
47 | "bugs": {
48 | "url": "https://github.com/andreruffert/progressive-image-element/issues"
49 | },
50 | "keywords": [
51 | "progressive",
52 | "image",
53 | "custom element",
54 | "web components",
55 | "ui"
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/src/constants.js:
--------------------------------------------------------------------------------
1 | export const DEFAULT_TAG_NAME = 'progressive-image';
2 | export const MESSAGES = {
3 | placeholderElement: {
4 | missing:
5 | ' requires a or element as its child. See https://andreruffert.github.io/progressive-image-element/examples',
6 | },
7 | dimensions: {
8 | missing:
9 | 'An element was loaded, but had no dimensions specified. Specifying dimensions is necessary. See https://github.com/andreruffert/progressive-image-element/pull/4',
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './style.css';
2 | import ProgressiveImageElement from './progressive-image-element';
3 |
4 | export default ProgressiveImageElement;
5 |
6 | if (!new URL(import.meta.url).searchParams.has('define', 'false')) {
7 | window.ProgressiveImageElement = ProgressiveImageElement.define();
8 | }
9 |
--------------------------------------------------------------------------------
/src/progressive-image-element.js:
--------------------------------------------------------------------------------
1 | import { DEFAULT_TAG_NAME, MESSAGES } from './constants';
2 |
3 | const LAZY_LOADING_SUPPORT = 'loading' in HTMLImageElement.prototype;
4 | const SLOW_CONNECTIONS = /\slow-2g|2g|3g/;
5 |
6 | class ProgressiveImageElement extends HTMLElement {
7 | static define(tagName = DEFAULT_TAG_NAME, registry = customElements) {
8 | if (!registry.get(tagName)) {
9 | registry.define(tagName, ProgressiveImageElement);
10 | return ProgressiveImageElement;
11 | }
12 | }
13 |
14 | constructor() {
15 | super();
16 | const placeholderElement = this.querySelector('img, svg');
17 | const width = placeholderElement?.getAttribute('width');
18 | const height = placeholderElement?.getAttribute('height');
19 | if (!placeholderElement) console.warn(MESSAGES.placeholderElement.missing);
20 | if (placeholderElement && !width && !height) console.warn(MESSAGES.dimensions.missing);
21 | this._placeholderImage = placeholderElement?.tagName === 'IMG' ? placeholderElement : null;
22 | this._image = this._placeholderImage?.cloneNode(true) || new Image();
23 | if (LAZY_LOADING_SUPPORT) return;
24 |
25 | this._observer = new IntersectionObserver(
26 | (entries) => {
27 | entries
28 | .filter((entry) => entry.isIntersecting)
29 | .forEach((entry) => {
30 | this.enhancePlaceholderImage(entry.target);
31 | this._observer.unobserve(this);
32 | });
33 | },
34 | {
35 | rootMargin: '0px 0px 200px 0px',
36 | },
37 | );
38 | }
39 |
40 | get src() {
41 | return this.getAttribute('src');
42 | }
43 | get srcset() {
44 | return this.getAttribute('srcset');
45 | }
46 | get sizes() {
47 | return this.getAttribute('sizes');
48 | }
49 |
50 | get savedata() {
51 | const effectiveType = navigator?.connection?.effectiveType;
52 | return this.hasAttribute('savedata') || SLOW_CONNECTIONS.test(effectiveType);
53 | }
54 |
55 | enhancePlaceholderImage() {
56 | if (!this.src && !this.srcset) return;
57 | this.classList.add('loading');
58 | this._image.onload = (e) => {
59 | e.target.classList.add('loaded');
60 | this.classList.remove('loadable');
61 | this.classList.remove('loading');
62 | };
63 | this._image.loading = 'lazy';
64 | this._image.src = this.src;
65 | if (this.srcset) this._image.srcset = this.srcset;
66 | if (this.sizes) this._image.sizes = this.sizes;
67 | this._image.style.position = 'absolute';
68 | this._image.style.top = '0';
69 | this._image.style.left = '0';
70 | this.appendChild(this._image);
71 |
72 | // TODO:
73 | // The decoding of large images can block the main thread.
74 | // this._image.decode().then(() => {
75 | // this.appendChild(this._image);
76 | // this._image.classList.add('loaded');
77 | // }).catch(error => {
78 | // console.error(error);
79 | // throw new Error(`Could not load/decode image (${this._image.src}).`);
80 | // });
81 | }
82 |
83 | connectedCallback() {
84 | if (this.savedata) {
85 | this.addEventListener('click', this.enhancePlaceholderImage, { once: true });
86 | this.classList.add('loadable');
87 | } else {
88 | if (LAZY_LOADING_SUPPORT) {
89 | this.enhancePlaceholderImage();
90 | } else {
91 | this._observer.observe(this);
92 | }
93 | }
94 | this._placeholderImage?.classList.add('loaded');
95 | }
96 |
97 | disconnectedCallback() {
98 | this._observer.disconnect();
99 | }
100 | }
101 |
102 | export default ProgressiveImageElement;
103 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | progressive-image {
2 | display: inline-block;
3 | position: relative;
4 | overflow: hidden;
5 | }
6 |
7 | progressive-image > img,
8 | progressive-image > svg {
9 | display: inline-block;
10 | max-width: 100%;
11 | height: auto;
12 | vertical-align: middle;
13 | }
14 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { dirname, resolve } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { defineConfig } from 'vite';
4 |
5 | const __dirname = dirname(fileURLToPath(import.meta.url));
6 |
7 | export default defineConfig({
8 | build: {
9 | lib: {
10 | entry: resolve(__dirname, 'src/index.js'),
11 | name: 'ProgressiveImageElement',
12 | fileName: 'progressive-image-element',
13 | cssFileName: 'progressive-image-element',
14 | },
15 | },
16 | });
17 |
--------------------------------------------------------------------------------
/vite.docs.config.js:
--------------------------------------------------------------------------------
1 | import { dirname, resolve } from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { defineConfig } from 'vite';
4 |
5 | const __dirname = dirname(fileURLToPath(import.meta.url));
6 |
7 | export default defineConfig({
8 | root: resolve(__dirname, 'docs'),
9 | build: {
10 | outDir: resolve(__dirname, 'dist/docs'),
11 | },
12 | });
13 |
--------------------------------------------------------------------------------