@skivuha/img-shrink 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 js-nerds
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.
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # img-shrink
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@skivuha/img-shrink)](https://www.npmjs.com/package/@skivuha/img-shrink)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@skivuha/img-shrink)](https://www.npmjs.com/package/@skivuha/img-shrink)
5
+ [![coverage](https://codecov.io/gh/js-nerds/img-shrink/branch/main/graph/badge.svg)](https://codecov.io/gh/js-nerds/img-shrink)
6
+
7
+ Tiny browser-first image resizer with sane defaults. Pass a `File`/`Blob`, get back a resized `Blob` with optional crop/contain behavior.
8
+
9
+ ## Features
10
+ - Works with `File` and `Blob`
11
+ - `cover` (crop) and `contain` (fit) modes
12
+ - Preserve aspect ratio when only width or height is provided
13
+ - Output format selection (`jpeg`, `png`, `webp`)
14
+ - Throws on upscale (target size must not exceed source)
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install @skivuha/img-shrink
20
+ ```
21
+
22
+ ```bash
23
+ pnpm add @skivuha/img-shrink
24
+ ```
25
+
26
+ ```bash
27
+ yarn add @skivuha/img-shrink
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### Basic (cover crop)
33
+
34
+ ```ts
35
+ import { shrinkImage } from "@skivuha/img-shrink";
36
+
37
+ const file = input.files?.[0];
38
+ if (!file) {
39
+ return;
40
+ }
41
+
42
+ const resized = await shrinkImage(file, {
43
+ width: 100,
44
+ height: 100,
45
+ fit: "cover",
46
+ format: "image/webp",
47
+ quality: 0.9,
48
+ });
49
+ ```
50
+
51
+ ### Fit into a box (contain)
52
+
53
+ ```ts
54
+ const resized = await shrinkImage(file, {
55
+ width: 360,
56
+ height: 440,
57
+ fit: "contain",
58
+ background: "#ffffff",
59
+ });
60
+ ```
61
+
62
+ ### Only width or height
63
+
64
+ ```ts
65
+ // Height is computed using source aspect ratio
66
+ const resizedByWidth = await shrinkImage(file, { width: 800 });
67
+
68
+ // Width is computed using source aspect ratio
69
+ const resizedByHeight = await shrinkImage(file, { height: 600 });
70
+ ```
71
+
72
+ ## API
73
+
74
+ ### `shrinkImage(input, options)`
75
+
76
+ Resizes and re-encodes the input image.
77
+
78
+ **Params**
79
+ - `input: Blob` — source image
80
+ - `options: ResizeOptions` — resize config
81
+
82
+ **Returns**
83
+ - `Promise<Blob>` — resized image
84
+
85
+ ### `ResizeOptions`
86
+
87
+ ```ts
88
+ type ResizeOptions =
89
+ | { width: number; height?: number }
90
+ | { width?: number; height: number };
91
+
92
+ type ResizeFit = "cover" | "contain";
93
+ type ResizeFormat = "image/jpeg" | "image/png" | "image/webp";
94
+
95
+ type ResizeOptions = ResizeSize & {
96
+ fit?: ResizeFit;
97
+ format?: ResizeFormat;
98
+ quality?: number;
99
+ background?: string;
100
+ };
101
+ ```
102
+
103
+ **Notes**
104
+ - If both `width` and `height` are passed, exact size is used.
105
+ - If only one dimension is passed, the other is computed from the source aspect ratio.
106
+ - Upscale is not allowed. If target size exceeds source size, an error is thrown.
107
+ - Default `fit` is `"cover"`.
108
+ - Default `quality` is `0.92`.
109
+ - If `format` is not provided, the input type is used when possible, otherwise `image/jpeg`.
110
+
111
+ ## Runtime requirements
112
+
113
+ `img-shrink` uses Canvas (`OffscreenCanvas` when available) and image decoding APIs. It is intended for browser environments. Node.js is not supported without a DOM/canvas polyfill.
114
+
115
+ ## Coverage
116
+
117
+ ```bash
118
+ pnpm run test:coverage
119
+ ```
120
+
121
+ Generates a text summary in the terminal and an HTML report in `coverage/`.
122
+
123
+ ## License
124
+
125
+ MIT
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shrinkImage = void 0;
4
+ // Re-export all necessary entities for tree-shaking
5
+ var shrink_image_service_js_1 = require("./src/services/shrink-image.service.js");
6
+ Object.defineProperty(exports, "shrinkImage", { enumerable: true, get: function () { return shrink_image_service_js_1.shrinkImage; } });
@@ -0,0 +1,2 @@
1
+ export { shrinkImage } from "./src/services/shrink-image.service.js";
2
+ export type { ResizeFormat, ResizeFit, ResizeOptions, } from "./src/types/index.js";
@@ -0,0 +1,125 @@
1
+ import type { ResizeFormat, ResizeOptions } from "../types/index.js";
2
+ type Canvas2D = HTMLCanvasElement | OffscreenCanvas;
3
+ type SourceImage = ImageBitmap | HTMLImageElement;
4
+ type Canvas2DContext = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
5
+ /**
6
+ * Resize and encode an image Blob to a target size.
7
+ *
8
+ * @params {Blob} input: source image blob
9
+ * @params {ResizeOptions} options: resize configuration
10
+ * @returns {Promise<Blob>}
11
+ */
12
+ export declare function shrinkImage(input: Blob, options: ResizeOptions): Promise<Blob>;
13
+ /**
14
+ * Normalize a dimension value and round to an integer.
15
+ *
16
+ * @params {number} value: raw dimension value
17
+ * @params {string} name: dimension label for error messages
18
+ * @returns {number}
19
+ */
20
+ declare function normalizeDimension(value: number, name: string): number;
21
+ /**
22
+ * Resolve target size based on inputs and source aspect ratio.
23
+ *
24
+ * @params {number | undefined} width: requested width
25
+ * @params {number | undefined} height: requested height
26
+ * @params {number} srcWidth: source image width
27
+ * @params {number} srcHeight: source image height
28
+ * @returns {{ width: number; height: number }}
29
+ */
30
+ declare function resolveTargetSize(width: number | undefined, height: number | undefined, srcWidth: number, srcHeight: number): {
31
+ width: number;
32
+ height: number;
33
+ };
34
+ /**
35
+ * Normalize output quality when encoder supports it.
36
+ *
37
+ * @params {number | undefined} quality: requested quality value
38
+ * @returns {number | undefined}
39
+ */
40
+ declare function normalizeQuality(quality?: number): number | undefined;
41
+ /**
42
+ * Resolve output MIME type from options or input.
43
+ *
44
+ * @params {ResizeFormat | undefined} explicit: explicit output type
45
+ * @params {string} inputType: input blob type
46
+ * @returns {ResizeFormat}
47
+ */
48
+ declare function resolveOutputType(explicit: ResizeFormat | undefined, inputType: string): ResizeFormat;
49
+ /**
50
+ * Compute source rectangle for "cover" crop.
51
+ *
52
+ * @params {number} srcWidth: source width
53
+ * @params {number} srcHeight: source height
54
+ * @params {number} targetWidth: target width
55
+ * @params {number} targetHeight: target height
56
+ * @returns {{ sx: number; sy: number; sWidth: number; sHeight: number }}
57
+ */
58
+ declare function getCoverSourceRect(srcWidth: number, srcHeight: number, targetWidth: number, targetHeight: number): {
59
+ sx: number;
60
+ sy: number;
61
+ sWidth: number;
62
+ sHeight: number;
63
+ };
64
+ /**
65
+ * Create a 2D canvas instance.
66
+ *
67
+ * @params {number} width: canvas width
68
+ * @params {number} height: canvas height
69
+ * @returns {Canvas2D}
70
+ */
71
+ declare function createCanvas(width: number, height: number): Canvas2D;
72
+ /**
73
+ * Get a 2D rendering context from a canvas.
74
+ *
75
+ * @params {Canvas2D} canvas: target canvas
76
+ * @returns {Canvas2DContext | null}
77
+ */
78
+ declare function get2dContext(canvas: Canvas2D): Canvas2DContext | null;
79
+ /**
80
+ * Decode a Blob into a drawable image source.
81
+ *
82
+ * @params {Blob} input: source image blob
83
+ * @returns {Promise<SourceImage>}
84
+ */
85
+ declare function loadImage(input: Blob): Promise<SourceImage>;
86
+ /**
87
+ * Get the intrinsic size of an image source.
88
+ *
89
+ * @params {SourceImage} image: decoded image
90
+ * @returns {{ width: number; height: number }}
91
+ */
92
+ declare function getImageSize(image: SourceImage): {
93
+ width: number;
94
+ height: number;
95
+ };
96
+ /**
97
+ * Release resources used by an image source.
98
+ *
99
+ * @params {SourceImage} image: decoded image
100
+ * @returns {void}
101
+ */
102
+ declare function cleanupImage(image: SourceImage): void;
103
+ /**
104
+ * Encode a canvas into a Blob.
105
+ *
106
+ * @params {Canvas2D} canvas: source canvas
107
+ * @params {ResizeFormat} type: output MIME type
108
+ * @params {number | undefined} quality: encoder quality
109
+ * @returns {Promise<Blob>}
110
+ */
111
+ declare function canvasToBlob(canvas: Canvas2D, type: ResizeFormat, quality: number | undefined): Promise<Blob>;
112
+ export declare const __test__: {
113
+ normalizeDimension: typeof normalizeDimension;
114
+ resolveTargetSize: typeof resolveTargetSize;
115
+ normalizeQuality: typeof normalizeQuality;
116
+ resolveOutputType: typeof resolveOutputType;
117
+ getCoverSourceRect: typeof getCoverSourceRect;
118
+ createCanvas: typeof createCanvas;
119
+ get2dContext: typeof get2dContext;
120
+ loadImage: typeof loadImage;
121
+ getImageSize: typeof getImageSize;
122
+ cleanupImage: typeof cleanupImage;
123
+ canvasToBlob: typeof canvasToBlob;
124
+ };
125
+ export {};
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.__test__ = void 0;
4
+ exports.shrinkImage = shrinkImage;
5
+ const DEFAULT_QUALITY = 0.92;
6
+ const SUPPORTED_FORMATS = [
7
+ "image/jpeg",
8
+ "image/png",
9
+ "image/webp",
10
+ ];
11
+ /**
12
+ * Resize and encode an image Blob to a target size.
13
+ *
14
+ * @params {Blob} input: source image blob
15
+ * @params {ResizeOptions} options: resize configuration
16
+ * @returns {Promise<Blob>}
17
+ */
18
+ async function shrinkImage(input, options) {
19
+ const fit = options.fit ?? "cover";
20
+ const outputType = resolveOutputType(options.format, input.type);
21
+ const quality = normalizeQuality(options.quality);
22
+ const image = await loadImage(input);
23
+ try {
24
+ const { width: srcWidth, height: srcHeight } = getImageSize(image);
25
+ const { width: targetWidth, height: targetHeight } = resolveTargetSize(options.width, options.height, srcWidth, srcHeight);
26
+ if (targetWidth > srcWidth || targetHeight > srcHeight) {
27
+ throw new Error(`Target size ${targetWidth}x${targetHeight} exceeds source ${srcWidth}x${srcHeight}.`);
28
+ }
29
+ const canvas = createCanvas(targetWidth, targetHeight);
30
+ const ctx = get2dContext(canvas);
31
+ if (!ctx) {
32
+ throw new Error("Canvas 2D context is not available.");
33
+ }
34
+ ctx.imageSmoothingEnabled = true;
35
+ if ("imageSmoothingQuality" in ctx) {
36
+ ctx.imageSmoothingQuality = "high";
37
+ }
38
+ if (fit === "contain") {
39
+ const bg = options.background ??
40
+ (outputType === "image/jpeg" ? "#ffffff" : "transparent");
41
+ ctx.fillStyle = bg;
42
+ ctx.fillRect(0, 0, targetWidth, targetHeight);
43
+ const scale = Math.min(targetWidth / srcWidth, targetHeight / srcHeight);
44
+ const destWidth = Math.round(srcWidth * scale);
45
+ const destHeight = Math.round(srcHeight * scale);
46
+ const dx = Math.round((targetWidth - destWidth) / 2);
47
+ const dy = Math.round((targetHeight - destHeight) / 2);
48
+ ctx.drawImage(image, 0, 0, srcWidth, srcHeight, dx, dy, destWidth, destHeight);
49
+ }
50
+ else {
51
+ const { sx, sy, sWidth, sHeight } = getCoverSourceRect(srcWidth, srcHeight, targetWidth, targetHeight);
52
+ ctx.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, targetWidth, targetHeight);
53
+ }
54
+ return await canvasToBlob(canvas, outputType, quality);
55
+ }
56
+ finally {
57
+ cleanupImage(image);
58
+ }
59
+ }
60
+ /**
61
+ * Normalize a dimension value and round to an integer.
62
+ *
63
+ * @params {number} value: raw dimension value
64
+ * @params {string} name: dimension label for error messages
65
+ * @returns {number}
66
+ */
67
+ function normalizeDimension(value, name) {
68
+ if (!Number.isFinite(value) || value <= 0) {
69
+ throw new Error(`${name} must be a positive number.`);
70
+ }
71
+ const normalized = Math.round(value);
72
+ if (normalized <= 0) {
73
+ throw new Error(`${name} must be a positive number.`);
74
+ }
75
+ return normalized;
76
+ }
77
+ /**
78
+ * Resolve target size based on inputs and source aspect ratio.
79
+ *
80
+ * @params {number | undefined} width: requested width
81
+ * @params {number | undefined} height: requested height
82
+ * @params {number} srcWidth: source image width
83
+ * @params {number} srcHeight: source image height
84
+ * @returns {{ width: number; height: number }}
85
+ */
86
+ function resolveTargetSize(width, height, srcWidth, srcHeight) {
87
+ if (width === undefined && height === undefined) {
88
+ throw new Error("width or height must be provided.");
89
+ }
90
+ const normalizedWidth = width === undefined ? undefined : normalizeDimension(width, "width");
91
+ const normalizedHeight = height === undefined ? undefined : normalizeDimension(height, "height");
92
+ if (normalizedWidth !== undefined && normalizedHeight !== undefined) {
93
+ return { width: normalizedWidth, height: normalizedHeight };
94
+ }
95
+ const ratio = srcWidth / srcHeight;
96
+ if (normalizedWidth !== undefined) {
97
+ const computedHeight = Math.max(1, Math.round(normalizedWidth / ratio));
98
+ return { width: normalizedWidth, height: computedHeight };
99
+ }
100
+ const computedWidth = Math.max(1, Math.round(normalizedHeight * ratio));
101
+ return { width: computedWidth, height: normalizedHeight };
102
+ }
103
+ /**
104
+ * Normalize output quality when encoder supports it.
105
+ *
106
+ * @params {number | undefined} quality: requested quality value
107
+ * @returns {number | undefined}
108
+ */
109
+ function normalizeQuality(quality) {
110
+ if (quality === undefined) {
111
+ return DEFAULT_QUALITY;
112
+ }
113
+ if (!Number.isFinite(quality) || quality < 0 || quality > 1) {
114
+ throw new Error("quality must be between 0 and 1.");
115
+ }
116
+ return quality;
117
+ }
118
+ /**
119
+ * Resolve output MIME type from options or input.
120
+ *
121
+ * @params {ResizeFormat | undefined} explicit: explicit output type
122
+ * @params {string} inputType: input blob type
123
+ * @returns {ResizeFormat}
124
+ */
125
+ function resolveOutputType(explicit, inputType) {
126
+ if (explicit && SUPPORTED_FORMATS.indexOf(explicit) !== -1) {
127
+ return explicit;
128
+ }
129
+ const normalizedInput = inputType.toLowerCase();
130
+ if (SUPPORTED_FORMATS.indexOf(normalizedInput) !== -1) {
131
+ return normalizedInput;
132
+ }
133
+ return "image/jpeg";
134
+ }
135
+ /**
136
+ * Compute source rectangle for "cover" crop.
137
+ *
138
+ * @params {number} srcWidth: source width
139
+ * @params {number} srcHeight: source height
140
+ * @params {number} targetWidth: target width
141
+ * @params {number} targetHeight: target height
142
+ * @returns {{ sx: number; sy: number; sWidth: number; sHeight: number }}
143
+ */
144
+ function getCoverSourceRect(srcWidth, srcHeight, targetWidth, targetHeight) {
145
+ const srcRatio = srcWidth / srcHeight;
146
+ const targetRatio = targetWidth / targetHeight;
147
+ if (srcRatio > targetRatio) {
148
+ const sWidth = srcHeight * targetRatio;
149
+ const sx = (srcWidth - sWidth) / 2;
150
+ return { sx, sy: 0, sWidth, sHeight: srcHeight };
151
+ }
152
+ const sHeight = srcWidth / targetRatio;
153
+ const sy = (srcHeight - sHeight) / 2;
154
+ return { sx: 0, sy, sWidth: srcWidth, sHeight };
155
+ }
156
+ /**
157
+ * Create a 2D canvas instance.
158
+ *
159
+ * @params {number} width: canvas width
160
+ * @params {number} height: canvas height
161
+ * @returns {Canvas2D}
162
+ */
163
+ function createCanvas(width, height) {
164
+ if (typeof OffscreenCanvas !== "undefined") {
165
+ return new OffscreenCanvas(width, height);
166
+ }
167
+ if (typeof document === "undefined") {
168
+ throw new Error("Canvas is not available in this environment.");
169
+ }
170
+ const canvas = document.createElement("canvas");
171
+ canvas.width = width;
172
+ canvas.height = height;
173
+ return canvas;
174
+ }
175
+ /**
176
+ * Get a 2D rendering context from a canvas.
177
+ *
178
+ * @params {Canvas2D} canvas: target canvas
179
+ * @returns {Canvas2DContext | null}
180
+ */
181
+ function get2dContext(canvas) {
182
+ return canvas.getContext("2d");
183
+ }
184
+ /**
185
+ * Decode a Blob into a drawable image source.
186
+ *
187
+ * @params {Blob} input: source image blob
188
+ * @returns {Promise<SourceImage>}
189
+ */
190
+ async function loadImage(input) {
191
+ if (typeof createImageBitmap === "function") {
192
+ return createImageBitmap(input, { imageOrientation: "from-image" });
193
+ }
194
+ if (typeof Image === "undefined") {
195
+ throw new Error("Image decoding is not available in this environment.");
196
+ }
197
+ const url = URL.createObjectURL(input);
198
+ const image = new Image();
199
+ image.decoding = "async";
200
+ image.src = url;
201
+ try {
202
+ if (typeof image.decode === "function") {
203
+ await image.decode();
204
+ }
205
+ else {
206
+ await new Promise((resolve, reject) => {
207
+ image.onload = () => resolve();
208
+ image.onerror = () => reject(new Error("Failed to load image."));
209
+ });
210
+ }
211
+ }
212
+ finally {
213
+ URL.revokeObjectURL(url);
214
+ }
215
+ return image;
216
+ }
217
+ /**
218
+ * Get the intrinsic size of an image source.
219
+ *
220
+ * @params {SourceImage} image: decoded image
221
+ * @returns {{ width: number; height: number }}
222
+ */
223
+ function getImageSize(image) {
224
+ if ("naturalWidth" in image) {
225
+ return { width: image.naturalWidth, height: image.naturalHeight };
226
+ }
227
+ return { width: image.width, height: image.height };
228
+ }
229
+ /**
230
+ * Release resources used by an image source.
231
+ *
232
+ * @params {SourceImage} image: decoded image
233
+ * @returns {void}
234
+ */
235
+ function cleanupImage(image) {
236
+ if ("close" in image) {
237
+ image.close();
238
+ }
239
+ }
240
+ /**
241
+ * Encode a canvas into a Blob.
242
+ *
243
+ * @params {Canvas2D} canvas: source canvas
244
+ * @params {ResizeFormat} type: output MIME type
245
+ * @params {number | undefined} quality: encoder quality
246
+ * @returns {Promise<Blob>}
247
+ */
248
+ async function canvasToBlob(canvas, type, quality) {
249
+ if ("convertToBlob" in canvas) {
250
+ return canvas.convertToBlob({ type, quality });
251
+ }
252
+ return new Promise((resolve, reject) => {
253
+ canvas.toBlob((blob) => {
254
+ if (blob) {
255
+ resolve(blob);
256
+ }
257
+ else {
258
+ reject(new Error("Failed to create image blob."));
259
+ }
260
+ }, type, quality);
261
+ });
262
+ }
263
+ exports.__test__ = {
264
+ normalizeDimension,
265
+ resolveTargetSize,
266
+ normalizeQuality,
267
+ resolveOutputType,
268
+ getCoverSourceRect,
269
+ createCanvas,
270
+ get2dContext,
271
+ loadImage,
272
+ getImageSize,
273
+ cleanupImage,
274
+ canvasToBlob,
275
+ };
@@ -0,0 +1,16 @@
1
+ export type ResizeFit = "cover" | "contain";
2
+ export type ResizeFormat = "image/jpeg" | "image/png" | "image/webp";
3
+ type ResizeSize = {
4
+ width: number;
5
+ height?: number;
6
+ } | {
7
+ width?: number;
8
+ height: number;
9
+ };
10
+ export type ResizeOptions = ResizeSize & {
11
+ fit?: ResizeFit;
12
+ format?: ResizeFormat;
13
+ quality?: number;
14
+ background?: string;
15
+ };
16
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export { shrinkImage } from "./src/services/shrink-image.service.js";
2
+ export type { ResizeFormat, ResizeFit, ResizeOptions, } from "./src/types/index.js";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // Re-export all necessary entities for tree-shaking
2
+ export { shrinkImage } from "./src/services/shrink-image.service.js";
@@ -0,0 +1,125 @@
1
+ import type { ResizeFormat, ResizeOptions } from "../types/index.js";
2
+ type Canvas2D = HTMLCanvasElement | OffscreenCanvas;
3
+ type SourceImage = ImageBitmap | HTMLImageElement;
4
+ type Canvas2DContext = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
5
+ /**
6
+ * Resize and encode an image Blob to a target size.
7
+ *
8
+ * @params {Blob} input: source image blob
9
+ * @params {ResizeOptions} options: resize configuration
10
+ * @returns {Promise<Blob>}
11
+ */
12
+ export declare function shrinkImage(input: Blob, options: ResizeOptions): Promise<Blob>;
13
+ /**
14
+ * Normalize a dimension value and round to an integer.
15
+ *
16
+ * @params {number} value: raw dimension value
17
+ * @params {string} name: dimension label for error messages
18
+ * @returns {number}
19
+ */
20
+ declare function normalizeDimension(value: number, name: string): number;
21
+ /**
22
+ * Resolve target size based on inputs and source aspect ratio.
23
+ *
24
+ * @params {number | undefined} width: requested width
25
+ * @params {number | undefined} height: requested height
26
+ * @params {number} srcWidth: source image width
27
+ * @params {number} srcHeight: source image height
28
+ * @returns {{ width: number; height: number }}
29
+ */
30
+ declare function resolveTargetSize(width: number | undefined, height: number | undefined, srcWidth: number, srcHeight: number): {
31
+ width: number;
32
+ height: number;
33
+ };
34
+ /**
35
+ * Normalize output quality when encoder supports it.
36
+ *
37
+ * @params {number | undefined} quality: requested quality value
38
+ * @returns {number | undefined}
39
+ */
40
+ declare function normalizeQuality(quality?: number): number | undefined;
41
+ /**
42
+ * Resolve output MIME type from options or input.
43
+ *
44
+ * @params {ResizeFormat | undefined} explicit: explicit output type
45
+ * @params {string} inputType: input blob type
46
+ * @returns {ResizeFormat}
47
+ */
48
+ declare function resolveOutputType(explicit: ResizeFormat | undefined, inputType: string): ResizeFormat;
49
+ /**
50
+ * Compute source rectangle for "cover" crop.
51
+ *
52
+ * @params {number} srcWidth: source width
53
+ * @params {number} srcHeight: source height
54
+ * @params {number} targetWidth: target width
55
+ * @params {number} targetHeight: target height
56
+ * @returns {{ sx: number; sy: number; sWidth: number; sHeight: number }}
57
+ */
58
+ declare function getCoverSourceRect(srcWidth: number, srcHeight: number, targetWidth: number, targetHeight: number): {
59
+ sx: number;
60
+ sy: number;
61
+ sWidth: number;
62
+ sHeight: number;
63
+ };
64
+ /**
65
+ * Create a 2D canvas instance.
66
+ *
67
+ * @params {number} width: canvas width
68
+ * @params {number} height: canvas height
69
+ * @returns {Canvas2D}
70
+ */
71
+ declare function createCanvas(width: number, height: number): Canvas2D;
72
+ /**
73
+ * Get a 2D rendering context from a canvas.
74
+ *
75
+ * @params {Canvas2D} canvas: target canvas
76
+ * @returns {Canvas2DContext | null}
77
+ */
78
+ declare function get2dContext(canvas: Canvas2D): Canvas2DContext | null;
79
+ /**
80
+ * Decode a Blob into a drawable image source.
81
+ *
82
+ * @params {Blob} input: source image blob
83
+ * @returns {Promise<SourceImage>}
84
+ */
85
+ declare function loadImage(input: Blob): Promise<SourceImage>;
86
+ /**
87
+ * Get the intrinsic size of an image source.
88
+ *
89
+ * @params {SourceImage} image: decoded image
90
+ * @returns {{ width: number; height: number }}
91
+ */
92
+ declare function getImageSize(image: SourceImage): {
93
+ width: number;
94
+ height: number;
95
+ };
96
+ /**
97
+ * Release resources used by an image source.
98
+ *
99
+ * @params {SourceImage} image: decoded image
100
+ * @returns {void}
101
+ */
102
+ declare function cleanupImage(image: SourceImage): void;
103
+ /**
104
+ * Encode a canvas into a Blob.
105
+ *
106
+ * @params {Canvas2D} canvas: source canvas
107
+ * @params {ResizeFormat} type: output MIME type
108
+ * @params {number | undefined} quality: encoder quality
109
+ * @returns {Promise<Blob>}
110
+ */
111
+ declare function canvasToBlob(canvas: Canvas2D, type: ResizeFormat, quality: number | undefined): Promise<Blob>;
112
+ export declare const __test__: {
113
+ normalizeDimension: typeof normalizeDimension;
114
+ resolveTargetSize: typeof resolveTargetSize;
115
+ normalizeQuality: typeof normalizeQuality;
116
+ resolveOutputType: typeof resolveOutputType;
117
+ getCoverSourceRect: typeof getCoverSourceRect;
118
+ createCanvas: typeof createCanvas;
119
+ get2dContext: typeof get2dContext;
120
+ loadImage: typeof loadImage;
121
+ getImageSize: typeof getImageSize;
122
+ cleanupImage: typeof cleanupImage;
123
+ canvasToBlob: typeof canvasToBlob;
124
+ };
125
+ export {};
@@ -0,0 +1,271 @@
1
+ const DEFAULT_QUALITY = 0.92;
2
+ const SUPPORTED_FORMATS = [
3
+ "image/jpeg",
4
+ "image/png",
5
+ "image/webp",
6
+ ];
7
+ /**
8
+ * Resize and encode an image Blob to a target size.
9
+ *
10
+ * @params {Blob} input: source image blob
11
+ * @params {ResizeOptions} options: resize configuration
12
+ * @returns {Promise<Blob>}
13
+ */
14
+ export async function shrinkImage(input, options) {
15
+ const fit = options.fit ?? "cover";
16
+ const outputType = resolveOutputType(options.format, input.type);
17
+ const quality = normalizeQuality(options.quality);
18
+ const image = await loadImage(input);
19
+ try {
20
+ const { width: srcWidth, height: srcHeight } = getImageSize(image);
21
+ const { width: targetWidth, height: targetHeight } = resolveTargetSize(options.width, options.height, srcWidth, srcHeight);
22
+ if (targetWidth > srcWidth || targetHeight > srcHeight) {
23
+ throw new Error(`Target size ${targetWidth}x${targetHeight} exceeds source ${srcWidth}x${srcHeight}.`);
24
+ }
25
+ const canvas = createCanvas(targetWidth, targetHeight);
26
+ const ctx = get2dContext(canvas);
27
+ if (!ctx) {
28
+ throw new Error("Canvas 2D context is not available.");
29
+ }
30
+ ctx.imageSmoothingEnabled = true;
31
+ if ("imageSmoothingQuality" in ctx) {
32
+ ctx.imageSmoothingQuality = "high";
33
+ }
34
+ if (fit === "contain") {
35
+ const bg = options.background ??
36
+ (outputType === "image/jpeg" ? "#ffffff" : "transparent");
37
+ ctx.fillStyle = bg;
38
+ ctx.fillRect(0, 0, targetWidth, targetHeight);
39
+ const scale = Math.min(targetWidth / srcWidth, targetHeight / srcHeight);
40
+ const destWidth = Math.round(srcWidth * scale);
41
+ const destHeight = Math.round(srcHeight * scale);
42
+ const dx = Math.round((targetWidth - destWidth) / 2);
43
+ const dy = Math.round((targetHeight - destHeight) / 2);
44
+ ctx.drawImage(image, 0, 0, srcWidth, srcHeight, dx, dy, destWidth, destHeight);
45
+ }
46
+ else {
47
+ const { sx, sy, sWidth, sHeight } = getCoverSourceRect(srcWidth, srcHeight, targetWidth, targetHeight);
48
+ ctx.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, targetWidth, targetHeight);
49
+ }
50
+ return await canvasToBlob(canvas, outputType, quality);
51
+ }
52
+ finally {
53
+ cleanupImage(image);
54
+ }
55
+ }
56
+ /**
57
+ * Normalize a dimension value and round to an integer.
58
+ *
59
+ * @params {number} value: raw dimension value
60
+ * @params {string} name: dimension label for error messages
61
+ * @returns {number}
62
+ */
63
+ function normalizeDimension(value, name) {
64
+ if (!Number.isFinite(value) || value <= 0) {
65
+ throw new Error(`${name} must be a positive number.`);
66
+ }
67
+ const normalized = Math.round(value);
68
+ if (normalized <= 0) {
69
+ throw new Error(`${name} must be a positive number.`);
70
+ }
71
+ return normalized;
72
+ }
73
+ /**
74
+ * Resolve target size based on inputs and source aspect ratio.
75
+ *
76
+ * @params {number | undefined} width: requested width
77
+ * @params {number | undefined} height: requested height
78
+ * @params {number} srcWidth: source image width
79
+ * @params {number} srcHeight: source image height
80
+ * @returns {{ width: number; height: number }}
81
+ */
82
+ function resolveTargetSize(width, height, srcWidth, srcHeight) {
83
+ if (width === undefined && height === undefined) {
84
+ throw new Error("width or height must be provided.");
85
+ }
86
+ const normalizedWidth = width === undefined ? undefined : normalizeDimension(width, "width");
87
+ const normalizedHeight = height === undefined ? undefined : normalizeDimension(height, "height");
88
+ if (normalizedWidth !== undefined && normalizedHeight !== undefined) {
89
+ return { width: normalizedWidth, height: normalizedHeight };
90
+ }
91
+ const ratio = srcWidth / srcHeight;
92
+ if (normalizedWidth !== undefined) {
93
+ const computedHeight = Math.max(1, Math.round(normalizedWidth / ratio));
94
+ return { width: normalizedWidth, height: computedHeight };
95
+ }
96
+ const computedWidth = Math.max(1, Math.round(normalizedHeight * ratio));
97
+ return { width: computedWidth, height: normalizedHeight };
98
+ }
99
+ /**
100
+ * Normalize output quality when encoder supports it.
101
+ *
102
+ * @params {number | undefined} quality: requested quality value
103
+ * @returns {number | undefined}
104
+ */
105
+ function normalizeQuality(quality) {
106
+ if (quality === undefined) {
107
+ return DEFAULT_QUALITY;
108
+ }
109
+ if (!Number.isFinite(quality) || quality < 0 || quality > 1) {
110
+ throw new Error("quality must be between 0 and 1.");
111
+ }
112
+ return quality;
113
+ }
114
+ /**
115
+ * Resolve output MIME type from options or input.
116
+ *
117
+ * @params {ResizeFormat | undefined} explicit: explicit output type
118
+ * @params {string} inputType: input blob type
119
+ * @returns {ResizeFormat}
120
+ */
121
+ function resolveOutputType(explicit, inputType) {
122
+ if (explicit && SUPPORTED_FORMATS.indexOf(explicit) !== -1) {
123
+ return explicit;
124
+ }
125
+ const normalizedInput = inputType.toLowerCase();
126
+ if (SUPPORTED_FORMATS.indexOf(normalizedInput) !== -1) {
127
+ return normalizedInput;
128
+ }
129
+ return "image/jpeg";
130
+ }
131
+ /**
132
+ * Compute source rectangle for "cover" crop.
133
+ *
134
+ * @params {number} srcWidth: source width
135
+ * @params {number} srcHeight: source height
136
+ * @params {number} targetWidth: target width
137
+ * @params {number} targetHeight: target height
138
+ * @returns {{ sx: number; sy: number; sWidth: number; sHeight: number }}
139
+ */
140
+ function getCoverSourceRect(srcWidth, srcHeight, targetWidth, targetHeight) {
141
+ const srcRatio = srcWidth / srcHeight;
142
+ const targetRatio = targetWidth / targetHeight;
143
+ if (srcRatio > targetRatio) {
144
+ const sWidth = srcHeight * targetRatio;
145
+ const sx = (srcWidth - sWidth) / 2;
146
+ return { sx, sy: 0, sWidth, sHeight: srcHeight };
147
+ }
148
+ const sHeight = srcWidth / targetRatio;
149
+ const sy = (srcHeight - sHeight) / 2;
150
+ return { sx: 0, sy, sWidth: srcWidth, sHeight };
151
+ }
152
+ /**
153
+ * Create a 2D canvas instance.
154
+ *
155
+ * @params {number} width: canvas width
156
+ * @params {number} height: canvas height
157
+ * @returns {Canvas2D}
158
+ */
159
+ function createCanvas(width, height) {
160
+ if (typeof OffscreenCanvas !== "undefined") {
161
+ return new OffscreenCanvas(width, height);
162
+ }
163
+ if (typeof document === "undefined") {
164
+ throw new Error("Canvas is not available in this environment.");
165
+ }
166
+ const canvas = document.createElement("canvas");
167
+ canvas.width = width;
168
+ canvas.height = height;
169
+ return canvas;
170
+ }
171
+ /**
172
+ * Get a 2D rendering context from a canvas.
173
+ *
174
+ * @params {Canvas2D} canvas: target canvas
175
+ * @returns {Canvas2DContext | null}
176
+ */
177
+ function get2dContext(canvas) {
178
+ return canvas.getContext("2d");
179
+ }
180
+ /**
181
+ * Decode a Blob into a drawable image source.
182
+ *
183
+ * @params {Blob} input: source image blob
184
+ * @returns {Promise<SourceImage>}
185
+ */
186
+ async function loadImage(input) {
187
+ if (typeof createImageBitmap === "function") {
188
+ return createImageBitmap(input, { imageOrientation: "from-image" });
189
+ }
190
+ if (typeof Image === "undefined") {
191
+ throw new Error("Image decoding is not available in this environment.");
192
+ }
193
+ const url = URL.createObjectURL(input);
194
+ const image = new Image();
195
+ image.decoding = "async";
196
+ image.src = url;
197
+ try {
198
+ if (typeof image.decode === "function") {
199
+ await image.decode();
200
+ }
201
+ else {
202
+ await new Promise((resolve, reject) => {
203
+ image.onload = () => resolve();
204
+ image.onerror = () => reject(new Error("Failed to load image."));
205
+ });
206
+ }
207
+ }
208
+ finally {
209
+ URL.revokeObjectURL(url);
210
+ }
211
+ return image;
212
+ }
213
+ /**
214
+ * Get the intrinsic size of an image source.
215
+ *
216
+ * @params {SourceImage} image: decoded image
217
+ * @returns {{ width: number; height: number }}
218
+ */
219
+ function getImageSize(image) {
220
+ if ("naturalWidth" in image) {
221
+ return { width: image.naturalWidth, height: image.naturalHeight };
222
+ }
223
+ return { width: image.width, height: image.height };
224
+ }
225
+ /**
226
+ * Release resources used by an image source.
227
+ *
228
+ * @params {SourceImage} image: decoded image
229
+ * @returns {void}
230
+ */
231
+ function cleanupImage(image) {
232
+ if ("close" in image) {
233
+ image.close();
234
+ }
235
+ }
236
+ /**
237
+ * Encode a canvas into a Blob.
238
+ *
239
+ * @params {Canvas2D} canvas: source canvas
240
+ * @params {ResizeFormat} type: output MIME type
241
+ * @params {number | undefined} quality: encoder quality
242
+ * @returns {Promise<Blob>}
243
+ */
244
+ async function canvasToBlob(canvas, type, quality) {
245
+ if ("convertToBlob" in canvas) {
246
+ return canvas.convertToBlob({ type, quality });
247
+ }
248
+ return new Promise((resolve, reject) => {
249
+ canvas.toBlob((blob) => {
250
+ if (blob) {
251
+ resolve(blob);
252
+ }
253
+ else {
254
+ reject(new Error("Failed to create image blob."));
255
+ }
256
+ }, type, quality);
257
+ });
258
+ }
259
+ export const __test__ = {
260
+ normalizeDimension,
261
+ resolveTargetSize,
262
+ normalizeQuality,
263
+ resolveOutputType,
264
+ getCoverSourceRect,
265
+ createCanvas,
266
+ get2dContext,
267
+ loadImage,
268
+ getImageSize,
269
+ cleanupImage,
270
+ canvasToBlob,
271
+ };
@@ -0,0 +1,16 @@
1
+ export type ResizeFit = "cover" | "contain";
2
+ export type ResizeFormat = "image/jpeg" | "image/png" | "image/webp";
3
+ type ResizeSize = {
4
+ width: number;
5
+ height?: number;
6
+ } | {
7
+ width?: number;
8
+ height: number;
9
+ };
10
+ export type ResizeOptions = ResizeSize & {
11
+ fit?: ResizeFit;
12
+ format?: ResizeFormat;
13
+ quality?: number;
14
+ background?: string;
15
+ };
16
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"fileNames":["../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es5.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.dom.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/.pnpm/typescript@5.7.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../src/types/index.ts","../src/services/shrink-image.service.ts","../index.ts","../node_modules/.pnpm/@vitest+spy@3.2.4/node_modules/@vitest/spy/dist/index.d.ts","../node_modules/.pnpm/@vitest+pretty-format@3.2.4/node_modules/@vitest/pretty-format/dist/index.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/types.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/helpers.d.ts","../node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/index-8b61d5bc.d.ts","../node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/index.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/types.d-BCElaP-c.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/diff.d.ts","../node_modules/.pnpm/@vitest+expect@3.2.4/node_modules/@vitest/expect/dist/index.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/disposable.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/indexable.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/iterators.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/compatibility/index.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/globals.typedarray.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/buffer.buffer.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/globals.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/abortcontroller.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/domexception.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/events.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/header.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/readable.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/file.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/fetch.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/formdata.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/connector.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/client.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/errors.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/dispatcher.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-dispatcher.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-origin.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool-stats.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/handlers.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/balanced-pool.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/agent.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-interceptor.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-agent.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-client.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-pool.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-errors.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/proxy-agent.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-handler.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-agent.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/api.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/interceptors.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/util.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cookies.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/patch.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/websocket.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/eventsource.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/filereader.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/content-type.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cache.d.ts","../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/index.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/fetch.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/navigator.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/web-globals/storage.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/assert.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/assert/strict.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/async_hooks.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/buffer.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/child_process.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/cluster.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/console.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/constants.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/crypto.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/dgram.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/dns.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/dns/promises.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/domain.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/events.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/fs.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/fs/promises.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/http.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/http2.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/https.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/inspector.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/inspector.generated.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/module.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/net.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/os.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/path.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/perf_hooks.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/process.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/punycode.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/querystring.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/readline.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/readline/promises.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/repl.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/sea.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/sqlite.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream/promises.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream/consumers.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/stream/web.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/string_decoder.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/test.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/timers.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/timers/promises.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/tls.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/trace_events.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/tty.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/url.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/util.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/v8.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/vm.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/wasi.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/worker_threads.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/zlib.d.ts","../node_modules/.pnpm/@types+node@22.19.7/node_modules/@types/node/index.d.ts","../node_modules/.pnpm/@types+estree@1.0.8/node_modules/@types/estree/index.d.ts","../node_modules/.pnpm/rollup@4.55.3/node_modules/rollup/dist/rollup.d.ts","../node_modules/.pnpm/rollup@4.55.3/node_modules/rollup/dist/parseAst.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/hmrPayload.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/customEvent.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/hot.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/dist/node/moduleRunnerTransport.d-DJ_mE5sf.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/dist/node/module-runner.d.ts","../node_modules/.pnpm/esbuild@0.25.12/node_modules/esbuild/lib/main.d.ts","../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/source-map.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/previous-map.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/input.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/css-syntax-error.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/declaration.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/root.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/warning.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/lazy-result.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/no-work-result.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/processor.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/result.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/document.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/rule.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/node.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/comment.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/container.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/at-rule.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/list.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/postcss.d.ts","../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/postcss.d.mts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/internal/lightningcssOptions.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/internal/cssPreprocessorOptions.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/importGlob.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/types/metadata.d.ts","../node_modules/.pnpm/vite@6.4.1_@types+node@22.19.7/node_modules/vite/dist/node/index.d.ts","../node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/tasks.d-CkscK4of.d.ts","../node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/types.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/error.d.ts","../node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/index.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/optional-types.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/environment.d.cL3nLXbE.d.ts","../node_modules/.pnpm/@vitest+mocker@3.2.4_vite@6.4.1_@types+node@22.19.7_/node_modules/@vitest/mocker/dist/registry.d-D765pazg.d.ts","../node_modules/.pnpm/@vitest+mocker@3.2.4_vite@6.4.1_@types+node@22.19.7_/node_modules/@vitest/mocker/dist/types.d-D_aRZRdy.d.ts","../node_modules/.pnpm/@vitest+mocker@3.2.4_vite@6.4.1_@types+node@22.19.7_/node_modules/@vitest/mocker/dist/index.d.ts","../node_modules/.pnpm/@vitest+utils@3.2.4/node_modules/@vitest/utils/dist/source-map.d.ts","../node_modules/.pnpm/vite-node@3.2.4_@types+node@22.19.7/node_modules/vite-node/dist/trace-mapping.d-DLVdEqOp.d.ts","../node_modules/.pnpm/vite-node@3.2.4_@types+node@22.19.7/node_modules/vite-node/dist/index.d-DGmxD2U7.d.ts","../node_modules/.pnpm/vite-node@3.2.4_@types+node@22.19.7/node_modules/vite-node/dist/index.d.ts","../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/environment.d-DHdQ1Csl.d.ts","../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/rawSnapshot.d-lFsMJFUd.d.ts","../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/index.d.ts","../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/environment.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/config.d.D2ROskhv.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/worker.d.1GmBbd7G.d.ts","../node_modules/.pnpm/@types+deep-eql@4.0.2/node_modules/@types/deep-eql/index.d.ts","../node_modules/.pnpm/assertion-error@2.0.1/node_modules/assertion-error/index.d.ts","../node_modules/.pnpm/@types+chai@5.2.3/node_modules/@types/chai/index.d.ts","../node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/utils.d.ts","../node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/benchmark.d.BwvBVTda.d.ts","../node_modules/.pnpm/vite-node@3.2.4_@types+node@22.19.7/node_modules/vite-node/dist/client.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/coverage.d.S9RMNXIe.d.ts","../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/manager.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/reporters.d.BFLkQcL6.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/vite.d.CMLlLIFP.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/config.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/config.d.ts","../vitest.config.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/worker.d.CKwWzBSj.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/global.d.MAmajcmJ.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/mocker.d.BE_2ls6u.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/chunks/suite.d.FvehnV49.d.ts","../node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.d.ts","../node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.d.ts","../node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.d.ts","../node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.d.ts","../node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/dist/index.d.ts","../node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.7_@vitest+ui@3.2.4/node_modules/vitest/globals.d.ts"],"fileIdsList":[[52,53,70,118,135,136],[70,118,135,136,222,223],[70,118,135,136],[70,115,116,118,135,136],[70,117,118,135,136],[118,135,136],[70,118,123,135,136,153],[70,118,119,124,129,135,136,138,150,161],[70,118,119,120,129,135,136,138],[65,66,67,70,118,135,136],[70,118,121,135,136,162],[70,118,122,123,130,135,136,139],[70,118,123,135,136,150,158],[70,118,124,126,129,135,136,138],[70,117,118,125,135,136],[70,118,126,127,135,136],[70,118,128,129,135,136],[70,117,118,129,135,136],[70,118,129,130,131,135,136,150,161],[70,118,129,130,131,135,136,145,150,153],[70,111,118,126,129,132,135,136,138,150,161],[70,118,129,130,132,133,135,136,138,150,158,161],[70,118,132,134,135,136,150,158,161],[68,69,70,71,72,73,74,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167],[70,118,129,135,136],[70,118,135,136,137,161],[70,118,126,129,135,136,138,150],[70,118,135,136,139],[70,118,135,136,140],[70,117,118,135,136,141],[70,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167],[70,118,135,136,143],[70,118,135,136,144],[70,118,129,135,136,145,146],[70,118,135,136,145,147,162,164],[70,118,130,135,136],[70,118,129,135,136,150,151,153],[70,118,135,136,152,153],[70,118,135,136,150,151],[70,118,135,136,153],[70,118,135,136,154],[70,115,118,135,136,150,155],[70,118,129,135,136,156,157],[70,118,135,136,156,157],[70,118,123,135,136,138,150,158],[70,118,135,136,159],[70,118,135,136,138,160],[70,118,132,135,136,144,161],[70,118,123,135,136,162],[70,118,135,136,150,163],[70,118,135,136,137,164],[70,118,135,136,165],[70,111,118,135,136],[70,111,118,129,131,135,136,141,150,153,161,163,164,166],[70,118,135,136,150,167],[55,60,61,63,70,118,135,136],[70,118,135,136,209,210],[61,63,70,118,135,136,203,204,205],[61,70,118,135,136],[61,63,70,118,135,136,203],[61,70,118,135,136,203],[70,118,135,136,216],[56,70,118,135,136,216,217],[56,70,118,135,136,216],[56,62,70,118,135,136],[57,70,118,135,136],[56,57,58,60,70,118,135,136],[56,70,118,135,136],[70,118,135,136,240,241],[70,118,135,136,240,241,242,243],[70,118,135,136,240,242],[70,118,135,136,240],[70,118,135,136,193],[70,118,135,136,191,193],[70,118,135,136,182,190,191,192,194,196],[70,118,135,136,180],[70,118,135,136,183,188,193,196],[70,118,135,136,179,196],[70,118,135,136,183,184,187,188,189,196],[70,118,135,136,183,184,185,187,188,196],[70,118,135,136,180,181,182,183,184,188,189,190,192,193,194,196],[70,118,135,136,196],[70,118,135,136,178,180,181,182,183,184,185,187,188,189,190,191,192,193,194,195],[70,118,135,136,178,196],[70,118,135,136,183,185,186,188,189,196],[70,118,135,136,187,196],[70,118,135,136,188,189,193,196],[70,118,135,136,181,191],[70,118,135,136,170,201,202],[70,118,135,136,169,170],[59,70,118,135,136],[70,83,87,118,135,136,161],[70,83,118,135,136,150,161],[70,78,118,135,136],[70,80,83,118,135,136,158,161],[70,118,135,136,138,158],[70,118,135,136,168],[70,78,118,135,136,168],[70,80,83,118,135,136,138,161],[70,75,76,79,82,118,129,135,136,150,161],[70,83,90,118,135,136],[70,75,81,118,135,136],[70,83,104,105,118,135,136],[70,79,83,118,135,136,153,161,168],[70,104,118,135,136,168],[70,77,78,118,135,136,168],[70,83,118,135,136],[70,77,78,79,80,81,82,83,84,85,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,105,106,107,108,109,110,118,135,136],[70,83,98,118,135,136],[70,83,90,91,118,135,136],[70,81,83,91,92,118,135,136],[70,82,118,135,136],[70,75,78,83,118,135,136],[70,83,87,91,92,118,135,136],[70,87,118,135,136],[70,81,83,86,118,135,136,161],[70,75,80,83,90,118,135,136],[70,118,135,136,150],[70,78,83,104,118,135,136,166,168],[70,118,135,136,213,214],[70,118,135,136,213],[70,118,129,130,132,133,134,135,136,138,150,158,161,167,168,170,171,172,173,175,176,177,197,198,199,200,201,202],[70,118,135,136,172,173,174,175],[70,118,135,136,172],[70,118,135,136,173],[70,118,135,136,170,202],[64,70,118,135,136,233,237],[70,118,135,136,206,225,226,237],[56,63,70,118,135,136,206,218,219,237],[70,118,135,136,228],[70,118,135,136,207],[56,64,70,118,135,136,206,208,218,227,237],[70,118,135,136,211],[56,61,63,70,118,121,130,135,136,150,202,206,208,211,212,215,218,220,221,224,227,229,230,232,237],[70,118,135,136,206,225,226,227,237],[70,118,135,136,202,231,232],[70,118,135,136,206,208,215,218,220,237],[70,118,135,136,166,221],[56,61,63,70,118,121,130,135,136,150,202,206,207,208,211,212,215,218,219,220,221,224,225,226,227,228,229,230,231,232,237],[55,56,61,63,64,70,118,121,130,135,136,150,166,202,206,207,208,211,212,215,218,219,220,221,224,225,226,227,228,229,230,231,232,236,237,238,239,244],[70,118,135,136,245],[52,70,118,135,136],[70,118,135,136,140,234]],"fileInfos":[{"version":"e41c290ef7dd7dab3493e6cbe5909e0148edf4a8dad0271be08edec368a0f7b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"4fd3f3422b2d2a3dfd5cdd0f387b3a8ec45f006c6ea896a4cb41264c2100bb2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"62bb211266ee48b2d0edf0d8d1b191f0c24fc379a82bd4c1692a082c540bc6b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"f1e2a172204962276504466a6393426d2ca9c54894b1ad0a6c9dad867a65f876","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"cecbac77473a402e83c3abc28129fc0f0877e6595b4cdf831d7570cb677cfce4","signature":"7bddb2a5f9621edfa6d8bdfb4b2020d152a2dea7977ffbf014db417730de28df","impliedFormat":99},{"version":"cf14b0cfce93ee98341f88873b01e8387a63257d3312056af8b05171322645b0","signature":"3bea5bb001c317046a4f8b2c73357c1c63eb0ef3e66702128658303a92ff6e86","impliedFormat":99},{"version":"8dc364b70826c578afa38589cdb40668886c3b960ac155a90cbb749788c9ccb9","signature":"9d8b24ac26b7e2b332b26cbb8610eb6efc8926e75dd5bbd42f8cfaca52b9d8eb","impliedFormat":99},{"version":"04471dc55f802c29791cc75edda8c4dd2a121f71c2401059da61eff83099e8ab","impliedFormat":99},{"version":"5c54a34e3d91727f7ae840bfe4d5d1c9a2f93c54cb7b6063d06ee4a6c3322656","impliedFormat":99},{"version":"db4da53b03596668cf6cc9484834e5de3833b9e7e64620cf08399fe069cd398d","impliedFormat":99},{"version":"ac7c28f153820c10850457994db1462d8c8e462f253b828ad942a979f726f2f9","impliedFormat":99},{"version":"f9b028d3c3891dd817e24d53102132b8f696269309605e6ed4f0db2c113bbd82","impliedFormat":99},{"version":"fb7c8d90e52e2884509166f96f3d591020c7b7977ab473b746954b0c8d100960","impliedFormat":99},{"version":"0bff51d6ed0c9093f6955b9d8258ce152ddb273359d50a897d8baabcb34de2c4","impliedFormat":99},{"version":"ef13c73d6157a32933c612d476c1524dd674cf5b9a88571d7d6a0d147544d529","impliedFormat":99},{"version":"13918e2b81c4288695f9b1f3dcc2468caf0f848d5c1f3dc00071c619d34ff63a","impliedFormat":99},{"version":"120a80aa556732f684db3ed61aeff1d6671e1655bd6cba0aa88b22b88ac9a6b1","affectsGlobalScope":true,"impliedFormat":99},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"2cbe0621042e2a68c7cbce5dfed3906a1862a16a7d496010636cdbdb91341c0f","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"bb45cd435da536500f1d9692a9b49d0c570b763ccbf00473248b777f5c1f353b","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d2bc7425ef40526650d6db7e072c1ff4a51101c3ac2cc4b666623b19496a6e27","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"dba28a419aec76ed864ef43e5f577a5c99a010c32e5949fe4e17a4d57c58dd11","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c959a391a75be9789b43c8468f71e3fa06488b4d691d5729dde1416dcd38225b","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"0dba70b3fb0dcd713fda33c2df64fa6751fff6460e536971cee917260fb17882","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"4e741b9c88e80c9e4cedf07b5a698e8e3a3bd73cf649f664d6dd3f868c05c2f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"a660aa95476042d3fdcc1343cf6bb8fdf24772d31712b1db321c5a4dcc325434","impliedFormat":1},{"version":"a7ca8df4f2931bef2aa4118078584d84a0b16539598eaadf7dce9104dfaa381c","impliedFormat":1},{"version":"11443a1dcfaaa404c68d53368b5b818712b95dd19f188cab1669c39bee8b84b3","impliedFormat":1},{"version":"36977c14a7f7bfc8c0426ae4343875689949fb699f3f84ecbe5b300ebf9a2c55","impliedFormat":1},{"version":"035d0934d304483f07148427a5bd5b98ac265dae914a6b49749fe23fbd893ec7","impliedFormat":99},{"version":"e2ed5b81cbed3a511b21a18ab2539e79ac1f4bc1d1d28f8d35d8104caa3b429f","impliedFormat":99},{"version":"161c8e0690c46021506e32fda85956d785b70f309ae97011fd27374c065cac9b","affectsGlobalScope":true,"impliedFormat":1},{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"8885cf05f3e2abf117590bbb951dcf6359e3e5ac462af1c901cfd24c6a6472e2","impliedFormat":1},{"version":"333caa2bfff7f06017f114de738050dd99a765c7eb16571c6d25a38c0d5365dc","impliedFormat":1},{"version":"e61df3640a38d535fd4bc9f4a53aef17c296b58dc4b6394fd576b808dd2fe5e6","impliedFormat":1},{"version":"459920181700cec8cbdf2a5faca127f3f17fd8dd9d9e577ed3f5f3af5d12a2e4","impliedFormat":1},{"version":"4719c209b9c00b579553859407a7e5dcfaa1c472994bd62aa5dd3cc0757eb077","impliedFormat":1},{"version":"7ec359bbc29b69d4063fe7dad0baaf35f1856f914db16b3f4f6e3e1bca4099fa","impliedFormat":1},{"version":"70790a7f0040993ca66ab8a07a059a0f8256e7bb57d968ae945f696cbff4ac7a","impliedFormat":1},{"version":"d1b9a81e99a0050ca7f2d98d7eedc6cda768f0eb9fa90b602e7107433e64c04c","impliedFormat":1},{"version":"a022503e75d6953d0e82c2c564508a5c7f8556fad5d7f971372d2d40479e4034","impliedFormat":1},{"version":"b215c4f0096f108020f666ffcc1f072c81e9f2f95464e894a5d5f34c5ea2a8b1","impliedFormat":1},{"version":"644491cde678bd462bb922c1d0cfab8f17d626b195ccb7f008612dc31f445d2d","impliedFormat":1},{"version":"dfe54dab1fa4961a6bcfba68c4ca955f8b5bbeb5f2ab3c915aa7adaa2eabc03a","impliedFormat":1},{"version":"1251d53755b03cde02466064260bb88fd83c30006a46395b7d9167340bc59b73","impliedFormat":1},{"version":"47865c5e695a382a916b1eedda1b6523145426e48a2eae4647e96b3b5e52024f","impliedFormat":1},{"version":"4cdf27e29feae6c7826cdd5c91751cc35559125e8304f9e7aed8faef97dcf572","impliedFormat":1},{"version":"331b8f71bfae1df25d564f5ea9ee65a0d847c4a94baa45925b6f38c55c7039bf","impliedFormat":1},{"version":"2a771d907aebf9391ac1f50e4ad37952943515eeea0dcc7e78aa08f508294668","impliedFormat":1},{"version":"0146fd6262c3fd3da51cb0254bb6b9a4e42931eb2f56329edd4c199cb9aaf804","impliedFormat":1},{"version":"183f480885db5caa5a8acb833c2be04f98056bdcc5fb29e969ff86e07efe57ab","impliedFormat":99},{"version":"4ec16d7a4e366c06a4573d299e15fe6207fc080f41beac5da06f4af33ea9761e","impliedFormat":1},{"version":"7870becb94cbc11d2d01b77c4422589adcba4d8e59f726246d40cd0d129784d8","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f698624bbbb060ece7c0e51b7236520ebada74b747d7523c7df376453ed6fea","impliedFormat":1},{"version":"f70b8328a15ca1d10b1436b691e134a49bc30dcf3183a69bfaa7ba77e1b78ecd","impliedFormat":1},{"version":"683b035f752e318d02e303894e767a1ac16ac4493baa2b593195d7976e6b7310","impliedFormat":99},{"version":"45cec9a1ba6549060552eead8959d47226048e0b71c7d0702ae58b7e16a28912","impliedFormat":99},{"version":"6907b09850f86610e7a528348c15484c1e1c09a18a9c1e98861399dfe4b18b46","impliedFormat":99},{"version":"12deea8eaa7a4fc1a2908e67da99831e5c5a6b46ad4f4f948fd4759314ea2b80","impliedFormat":99},{"version":"f0a8b376568a18f9a4976ecb0855187672b16b96c4df1c183a7e52dc1b5d98e8","impliedFormat":99},{"version":"8124828a11be7db984fcdab052fd4ff756b18edcfa8d71118b55388176210923","impliedFormat":99},{"version":"092944a8c05f9b96579161e88c6f211d5304a76bd2c47f8d4c30053269146bc8","impliedFormat":99},{"version":"b34b5f6b506abb206b1ea73c6a332b9ee9c8c98be0f6d17cdbda9430ecc1efab","impliedFormat":99},{"version":"75d4c746c3d16af0df61e7b0afe9606475a23335d9f34fcc525d388c21e9058b","impliedFormat":99},{"version":"fa959bf357232201c32566f45d97e70538c75a093c940af594865d12f31d4912","impliedFormat":99},{"version":"d2c52abd76259fc39a30dfae70a2e5ce77fd23144457a7ff1b64b03de6e3aec7","impliedFormat":99},{"version":"e6233e1c976265e85aa8ad76c3881febe6264cb06ae3136f0257e1eab4a6cc5a","impliedFormat":99},{"version":"f73e2335e568014e279927321770da6fe26facd4ac96cdc22a56687f1ecbb58e","impliedFormat":99},{"version":"317878f156f976d487e21fd1d58ad0461ee0a09185d5b0a43eedf2a56eb7e4ea","impliedFormat":99},{"version":"324ac98294dab54fbd580c7d0e707d94506d7b2c3d5efe981a8495f02cf9ad96","impliedFormat":99},{"version":"9ec72eb493ff209b470467e24264116b6a8616484bca438091433a545dfba17e","impliedFormat":99},{"version":"d6ee22aba183d5fc0c7b8617f77ee82ecadc2c14359cc51271c135e23f6ed51f","impliedFormat":99},{"version":"49747416f08b3ba50500a215e7a55d75268b84e31e896a40313c8053e8dec908","impliedFormat":99},{"version":"81e634f1c5e1ca309e7e3dc69e2732eea932ef07b8b34517d452e5a3e9a36fa3","impliedFormat":99},{"version":"34f39f75f2b5aa9c84a9f8157abbf8322e6831430e402badeaf58dd284f9b9a6","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"891694d3694abd66f0b8872997b85fd8e52bc51632ce0f8128c96962b443189f","impliedFormat":99},{"version":"69bf2422313487956e4dacf049f30cb91b34968912058d244cb19e4baa24da97","impliedFormat":99},{"version":"971a2c327ff166c770c5fb35699575ba2d13bba1f6d2757309c9be4b30036c8e","impliedFormat":99},{"version":"4f45e8effab83434a78d17123b01124259fbd1e335732135c213955d85222234","impliedFormat":99},{"version":"7bd51996fb7717941cbe094b05adc0d80b9503b350a77b789bbb0fc786f28053","impliedFormat":99},{"version":"b62006bbc815fe8190c7aee262aad6bff993e3f9ade70d7057dfceab6de79d2f","impliedFormat":99},{"version":"13497c0d73306e27f70634c424cd2f3b472187164f36140b504b3756b0ff476d","impliedFormat":99},{"version":"a23a08b626aa4d4a1924957bd8c4d38a7ffc032e21407bbd2c97413e1d8c3dbd","impliedFormat":99},{"version":"c320fe76361c53cad266b46986aac4e68d644acda1629f64be29c95534463d28","impliedFormat":99},{"version":"7bbff6783e96c691a41a7cf12dd5486b8166a01b0c57d071dbcfca55c9525ec4","impliedFormat":99},{"version":"62551fca1c326304f190970a15aacc6c2196caae0088903ad061f1d4354df0f1","signature":"4b96dd19fd2949d28ce80e913412b0026dc421e5bf6c31d87c7b5eb11b5753b4","impliedFormat":99},{"version":"bf7a2d0f6d9e72d59044079d61000c38da50328ccdff28c47528a1a139c610ec","impliedFormat":99},{"version":"e58c0b5226aff07b63be6ac6e1bec9d55bc3d2bda3b11b9b68cccea8c24ae839","affectsGlobalScope":true,"impliedFormat":99},{"version":"5a88655bf852c8cc007d6bc874ab61d1d63fba97063020458177173c454e9b4a","impliedFormat":99},{"version":"7e4dfae2da12ec71ffd9f55f4641a6e05610ce0d6784838659490e259e4eb13c","impliedFormat":99},{"version":"c30a41267fc04c6518b17e55dcb2b810f267af4314b0b6d7df1c33a76ce1b330","impliedFormat":1},{"version":"72422d0bac4076912385d0c10911b82e4694fc106e2d70added091f88f0824ba","impliedFormat":1},{"version":"da251b82c25bee1d93f9fd80c5a61d945da4f708ca21285541d7aff83ecb8200","impliedFormat":1},{"version":"64db14db2bf37ac089766fdb3c7e1160fabc10e9929bc2deeede7237e4419fc8","impliedFormat":1},{"version":"98b94085c9f78eba36d3d2314affe973e8994f99864b8708122750788825c771","impliedFormat":1},{"version":"13573a613314e40482386fe9c7934f9d86f3e06f19b840466c75391fb833b99b","impliedFormat":99},{"version":"ed09d42b14a604190e8c9fc972d18ea47d5c03c6c4a0003c9620dca915a1973d","affectsGlobalScope":true,"impliedFormat":99}],"root":[[52,54],235],"options":{"composite":true,"declaration":true,"declarationMap":false,"emitDeclarationOnly":false,"module":199,"outDir":"./","target":8},"referencedMap":[[54,1],[224,2],[222,3],[169,3],[115,4],[116,4],[117,5],[70,6],[118,7],[119,8],[120,9],[65,3],[68,10],[66,3],[67,3],[121,11],[122,12],[123,13],[124,14],[125,15],[126,16],[127,16],[128,17],[129,18],[130,19],[131,20],[71,3],[69,3],[132,21],[133,22],[134,23],[168,24],[135,25],[136,3],[137,26],[138,27],[139,28],[140,29],[141,30],[142,31],[143,32],[144,33],[145,34],[146,34],[147,35],[148,3],[149,36],[150,37],[152,38],[151,39],[153,40],[154,41],[155,42],[156,43],[157,44],[158,45],[159,46],[160,47],[161,48],[162,49],[163,50],[164,51],[165,52],[72,3],[73,3],[74,3],[112,53],[113,3],[114,3],[166,54],[167,55],[64,56],[211,57],[209,3],[210,3],[56,3],[206,58],[203,59],[204,60],[225,61],[216,3],[219,62],[218,63],[230,63],[217,64],[55,3],[63,65],[205,65],[58,66],[61,67],[212,66],[62,68],[57,3],[223,3],[177,3],[242,69],[244,70],[243,71],[241,72],[240,3],[194,73],[192,74],[193,75],[181,76],[182,74],[189,77],[180,78],[185,79],[195,3],[186,80],[191,81],[197,82],[196,83],[179,84],[187,85],[188,86],[183,87],[190,73],[184,88],[171,89],[170,90],[178,3],[226,3],[59,3],[60,91],[50,3],[51,3],[9,3],[11,3],[10,3],[2,3],[12,3],[13,3],[14,3],[15,3],[16,3],[17,3],[18,3],[19,3],[3,3],[20,3],[21,3],[4,3],[22,3],[26,3],[23,3],[24,3],[25,3],[27,3],[28,3],[29,3],[5,3],[30,3],[31,3],[32,3],[33,3],[6,3],[37,3],[34,3],[35,3],[36,3],[38,3],[7,3],[39,3],[44,3],[45,3],[40,3],[41,3],[42,3],[43,3],[8,3],[49,3],[46,3],[47,3],[48,3],[1,3],[90,92],[100,93],[89,92],[110,94],[81,95],[80,96],[109,97],[103,98],[108,99],[83,100],[97,101],[82,102],[106,103],[78,104],[77,97],[107,105],[79,106],[84,107],[85,3],[88,107],[75,3],[111,108],[101,109],[92,110],[93,111],[95,112],[91,113],[94,114],[104,97],[86,115],[87,116],[96,117],[76,118],[99,109],[98,107],[102,3],[105,119],[228,120],[214,121],[215,120],[213,3],[202,122],[176,123],[175,124],[173,124],[172,3],[174,125],[200,3],[199,3],[198,3],[201,126],[234,127],[227,128],[220,129],[229,130],[208,131],[237,132],[238,133],[231,134],[239,135],[232,136],[221,137],[236,138],[233,139],[245,140],[246,141],[207,3],[53,142],[52,3],[235,143]],"latestChangedDtsFile":"./vitest.config.d.ts","version":"5.7.3"}
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
@@ -0,0 +1,34 @@
1
+ import { defineConfig } from "vitest/config";
2
+ import { resolve } from "path";
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: "node",
7
+ include: ["src/**/*.test.ts", "tests/**/*.test.ts"],
8
+ pool: "threads",
9
+ poolOptions: {
10
+ threads: {
11
+ minThreads: 1,
12
+ maxThreads: 1,
13
+ },
14
+ },
15
+ coverage: {
16
+ provider: "v8",
17
+ reporter: ["text", "json", "html", "lcov"],
18
+ reportsDirectory: "coverage",
19
+ exclude: [
20
+ "index.ts",
21
+ "src/types/**",
22
+ "dist/**",
23
+ "**/*.d.ts",
24
+ "vite.config.ts",
25
+ "vitest.config.ts",
26
+ ],
27
+ },
28
+ },
29
+ resolve: {
30
+ alias: {
31
+ "@": resolve(__dirname),
32
+ },
33
+ },
34
+ });
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@skivuha/img-shrink",
3
+ "version": "0.1.0",
4
+ "description": "Tiny browser-first image resizer with crop/contain and compression.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Igor Danylov <skivuha@hotmail.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/js-nerds/img-shrink.git"
11
+ },
12
+ "bugs": "https://github.com/js-nerds/img-shrink/issues",
13
+ "homepage": "https://github.com/js-nerds/img-shrink#readme",
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "engines": {
18
+ "node": ">=18.0.0"
19
+ },
20
+ "keywords": [
21
+ "image",
22
+ "resize",
23
+ "compress",
24
+ "shrink",
25
+ "crop",
26
+ "canvas",
27
+ "browser",
28
+ "file",
29
+ "blob",
30
+ "webp",
31
+ "jpeg",
32
+ "png"
33
+ ],
34
+ "main": "./dist/cjs/index.cjs",
35
+ "module": "./dist/index.js",
36
+ "types": "./dist/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.ts",
40
+ "import": "./dist/index.js",
41
+ "require": "./dist/cjs/index.cjs"
42
+ }
43
+ },
44
+ "files": [
45
+ "dist"
46
+ ],
47
+ "sideEffects": false,
48
+ "devDependencies": {
49
+ "@types/node": "^22.0.0",
50
+ "@vitest/coverage-v8": "^3.2.3",
51
+ "@vitest/ui": "^3.2.3",
52
+ "typescript": "~5.7.2",
53
+ "vite": "^6.3.5",
54
+ "vitest": "^3.2.3"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc --project tsconfig.json && tsc --project tsconfig.cjs.json && mv dist/cjs/index.js dist/cjs/index.cjs",
58
+ "build:esm": "tsc --project tsconfig.json",
59
+ "build:cjs": "tsc --project tsconfig.cjs.json && mv dist/cjs/index.js dist/cjs/index.cjs",
60
+ "test": "vitest run",
61
+ "test:ui": "vitest --ui",
62
+ "test:coverage": "vitest run --coverage",
63
+ "build:vite": "vite build && tsc --emitDeclarationOnly"
64
+ }
65
+ }