@pivanov/utils 0.0.3 โ 1.0.1
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/README.md +125 -335
- package/dist/cjs/assertion/index.js +7 -0
- package/dist/cjs/cache/index.js +7 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/object/index.js +7 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/promise/index.js +7 -0
- package/dist/cjs/string/index.js +7 -0
- package/dist/cjs/tools/index.js +7 -0
- package/dist/cjs/types/index.js +7 -0
- package/dist/esm/assertion/index.js +7 -0
- package/dist/esm/cache/index.js +7 -0
- package/dist/esm/chunk-3ymwkv74.js +8 -0
- package/dist/esm/chunk-jtvcg9xg.js +6 -0
- package/dist/esm/chunk-m1ymbxy0.js +8 -0
- package/dist/esm/chunk-m7vtwv05.js +8 -0
- package/dist/esm/chunk-vtcj34cd.js +8 -0
- package/dist/esm/chunk-y84wjyfx.js +7 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/object/index.js +7 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/promise/index.js +7 -0
- package/dist/esm/string/index.js +7 -0
- package/dist/esm/tools/index.js +7 -0
- package/dist/esm/types/index.js +7 -0
- package/dist/types/assertion/index.d.ts +145 -0
- package/dist/types/cache/index.d.ts +16 -0
- package/dist/types/cache/internal.d.ts +12 -0
- package/dist/types/cache/response.d.ts +91 -0
- package/dist/types/cache/storage.d.ts +75 -0
- package/dist/types/cache/support.d.ts +14 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/object/index.d.ts +118 -0
- package/dist/types/promise/index.d.ts +81 -0
- package/dist/types/string/index.d.ts +127 -0
- package/dist/types/tools/deepClone.d.ts +2 -0
- package/dist/types/tools/dom.d.ts +82 -0
- package/dist/types/tools/eventBus/eventBus.d.ts +37 -0
- package/dist/types/tools/eventBus/index.d.ts +3 -0
- package/dist/types/tools/eventBus/types.d.ts +47 -0
- package/dist/types/tools/eventBus/useEventBus.d.ts +3 -0
- package/dist/types/tools/index.d.ts +5 -0
- package/dist/types/tools/isEqual.d.ts +21 -0
- package/dist/types/types/index.d.ts +61 -0
- package/package.json +74 -35
- package/dist/index.d.ts +0 -691
package/README.md
CHANGED
|
@@ -1,408 +1,198 @@
|
|
|
1
1
|
# @pivanov/utils
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<i>A
|
|
5
|
-
<br />
|
|
6
|
-
<br />
|
|
4
|
+
<i>A focused collection of TypeScript utilities for modern web development.</i>
|
|
5
|
+
<br /><br />
|
|
7
6
|
<img src="https://img.shields.io/npm/v/@pivanov/utils?logo=npm" alt="NPM Version" />
|
|
8
|
-
 
|
|
9
|
-
<img src="https://img.shields.io/
|
|
10
|
-
 
|
|
7
|
+
|
|
8
|
+
<img src="https://img.shields.io/npm/dw/@pivanov/utils" alt="Weekly Downloads" />
|
|
9
|
+
|
|
11
10
|
<img src="https://github.com/pivanov/pivanov-utils/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI Status" />
|
|
12
|
-
 
|
|
11
|
+
|
|
13
12
|
<img src="https://codecov.io/github/pivanov/pivanov-utils/graph/badge.svg?token=EPRKTP7D79" alt="Coverage Status" />
|
|
14
13
|
</p>
|
|
15
14
|
|
|
16
15
|
## Features
|
|
17
16
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- ๐ฆ **Modular** - Organized into focused modules for easy navigation
|
|
23
|
-
- ๐ **Well Documented** - Detailed JSDoc comments and examples
|
|
17
|
+
- **Fully typed** - strict TypeScript across every module, literal-type preserving where it matters
|
|
18
|
+
- **Tree-shakeable** - ESM + CJS + per-module subpath exports, `"sideEffects": false`
|
|
19
|
+
- **Zero dependencies** - React is an optional peer dep only for the `useEventBus` hook
|
|
20
|
+
- **Well tested** - 200+ tests, real edge cases (circular refs, typed arrays, Buffers, symbols)
|
|
24
21
|
|
|
25
22
|
## Installation
|
|
26
23
|
|
|
27
24
|
```bash
|
|
28
|
-
|
|
29
|
-
# or
|
|
30
|
-
npm install @pivanov/utils
|
|
31
|
-
# or
|
|
32
|
-
yarn add @pivanov/utils
|
|
25
|
+
bun add @pivanov/utils
|
|
33
26
|
```
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
import { camelCase } from '@pivanov/utils/string';
|
|
39
|
-
import { pick } from '@pivanov/utils/object';
|
|
40
|
-
import { isString } from '@pivanov/utils/assertion';
|
|
41
|
-
|
|
42
|
-
camelCase('foo-bar'); // 'fooBar'
|
|
43
|
-
pick({ name: 'John', age: 30 }, ['name']); // { name: 'John' }
|
|
44
|
-
isString('hello'); // true
|
|
28
|
+
```bash
|
|
29
|
+
npm install @pivanov/utils
|
|
45
30
|
```
|
|
46
31
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### Type Guards & Assertions
|
|
50
|
-
|
|
51
|
-
Runtime type checking with TypeScript type narrowing.
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import {
|
|
55
|
-
isString,
|
|
56
|
-
isNumber,
|
|
57
|
-
isBoolean,
|
|
58
|
-
isObject,
|
|
59
|
-
isFunction,
|
|
60
|
-
isNull,
|
|
61
|
-
isUndefined,
|
|
62
|
-
} from '@pivanov/utils/assertion';
|
|
63
|
-
|
|
64
|
-
// Type guards automatically narrow TypeScript types
|
|
65
|
-
function processValue(value: unknown) {
|
|
66
|
-
if (isString(value)) {
|
|
67
|
-
return value.toUpperCase(); // TypeScript knows this is a string
|
|
68
|
-
}
|
|
69
|
-
if (isNumber(value)) {
|
|
70
|
-
return value.toFixed(2); // TypeScript knows this is a number
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Examples
|
|
75
|
-
isString('hello'); // true
|
|
76
|
-
isNumber(42); // true
|
|
77
|
-
isBoolean(true); // true
|
|
78
|
-
isObject({}); // true (plain objects only, not arrays)
|
|
79
|
-
isFunction(() => {}); // true
|
|
80
|
-
isNull(null); // true
|
|
81
|
-
isUndefined(undefined); // true
|
|
32
|
+
```bash
|
|
33
|
+
yarn add @pivanov/utils
|
|
82
34
|
```
|
|
83
35
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Immutable object manipulation with full type safety.
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import { pick, omit, merge, deepMerge } from '@pivanov/utils/object';
|
|
90
|
-
|
|
91
|
-
// Pick specific properties
|
|
92
|
-
const user = { name: 'John', age: 30, email: 'john@example.com' };
|
|
93
|
-
pick(user, ['name', 'email']);
|
|
94
|
-
// { name: 'John', email: 'john@example.com' }
|
|
95
|
-
|
|
96
|
-
// Omit specific properties
|
|
97
|
-
omit(user, ['email']);
|
|
98
|
-
// { name: 'John', age: 30 }
|
|
99
|
-
|
|
100
|
-
// Shallow merge
|
|
101
|
-
merge({ a: 1, b: 2 }, { b: 3, c: 4 });
|
|
102
|
-
// { a: 1, b: 3, c: 4 }
|
|
103
|
-
|
|
104
|
-
// Deep merge with nested structures
|
|
105
|
-
deepMerge(
|
|
106
|
-
{ user: { name: 'John', settings: { theme: 'dark' } } },
|
|
107
|
-
{ user: { settings: { fontSize: 14 } } }
|
|
108
|
-
);
|
|
109
|
-
// { user: { name: 'John', settings: { theme: 'dark', fontSize: 14 } } }
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @pivanov/utils
|
|
110
38
|
```
|
|
111
39
|
|
|
112
|
-
|
|
40
|
+
## Quick start
|
|
113
41
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
import {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
kebabCase,
|
|
121
|
-
slugify,
|
|
122
|
-
capitalize,
|
|
123
|
-
uncapitalize,
|
|
124
|
-
capitalizeFirstLetter,
|
|
125
|
-
} from '@pivanov/utils/string';
|
|
126
|
-
|
|
127
|
-
// Case transformations
|
|
128
|
-
camelCase('foo-bar'); // 'fooBar'
|
|
129
|
-
camelCase('FOO_BAR'); // 'fooBar'
|
|
130
|
-
|
|
131
|
-
pascalCase('foo-bar'); // 'FooBar'
|
|
132
|
-
pascalCase('foo_bar_baz'); // 'FooBarBaz'
|
|
133
|
-
|
|
134
|
-
kebabCase('fooBar'); // 'foo-bar'
|
|
135
|
-
kebabCase('XMLHttpRequest'); // 'xml-http-request'
|
|
136
|
-
|
|
137
|
-
slugify('Hello World!'); // 'hello-world'
|
|
138
|
-
slugify('รber Cafรฉ'); // 'uber-cafe'
|
|
139
|
-
|
|
140
|
-
// Capitalization with TypeScript support
|
|
141
|
-
capitalize('hello'); // 'Hello' (type: Capitalize<'hello'>)
|
|
142
|
-
uncapitalize('Hello'); // 'hello' (type: Uncapitalize<'Hello'>)
|
|
143
|
-
capitalizeFirstLetter('hello world'); // 'Hello world'
|
|
42
|
+
```ts
|
|
43
|
+
import { camelCase, snakeCase, slugify } from '@pivanov/utils/string';
|
|
44
|
+
import { pick, groupBy, deepMerge } from '@pivanov/utils/object';
|
|
45
|
+
import { isString, isNil, isDefined } from '@pivanov/utils/assertion';
|
|
46
|
+
import { sleep, timeout, retry, parallelLimit } from '@pivanov/utils/promise';
|
|
47
|
+
import { deepClone, isEqual, busDispatch, useEventBus } from '@pivanov/utils/tools';
|
|
144
48
|
```
|
|
145
49
|
|
|
146
|
-
|
|
50
|
+
## What's inside
|
|
147
51
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
52
|
+
| Module | Surface |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `assertion` | `isString`, `isNumber`, `isBoolean`, `isFunction`, `isObject`, `isRecord`, `isNull`, `isUndefined`, `isNil`, `isDefined`, `isArray`, `isDate`, `isRegExp`, `isError`, `isPromise`, `isMap`, `isSet`, `isPrimitive`, `isEmpty` |
|
|
55
|
+
| `object` | `pick`, `omit`, `pickBy`, `omitBy`, `merge`, `deepMerge`, `mapValues`, `mapKeys`, `groupBy`, `invert`, `hasOwn`, `keysOf`, `entriesOf`, `fromEntries` |
|
|
56
|
+
| `promise` | `sleep`, `timeout`, `retry`, `defer`, `parallelLimit` - all AbortSignal-aware where relevant |
|
|
57
|
+
| `string` | `camelCase`, `pascalCase`, `kebabCase`, `snakeCase`, `titleCase`, `slugify`, `capitalize`, `uncapitalize`, `capitalizeFirstLetter`, `truncate`, `escapeHtml`, `escapeRegExp`, `words`, `lines` |
|
|
58
|
+
| `tools/deepClone` | Rich deep clone (prototypes, getters/setters, symbols, Buffers, TypedArrays, circular refs) |
|
|
59
|
+
| `tools/isEqual` | Deep equality with cycle detection; compares RegExp, Error, TypedArrays, ArrayBuffer |
|
|
60
|
+
| `tools/dom` | `isBrowser`, `checkVisibility`, `isInViewport`, `setStyleProperties`, `calculateRenderedTextWidth` |
|
|
61
|
+
| `cache` | Cache Storage helpers: JSON metadata with optional TTL, plus raw `Request`/`Response` caching. Shipped as a standalone `@pivanov/utils/cache` entry point |
|
|
62
|
+
| `tools/eventBus` | `busDispatch`, `busSubscribe`, `busOnce`, `useEventBus` - typed topics, optional error handler |
|
|
63
|
+
| `types` | `TDict`, `TObjType`, `DeepPartial`, `DeepReadonly`, `Mutable`, `Prettify` |
|
|
152
64
|
|
|
153
|
-
|
|
65
|
+
See the full **[API documentation](https://pivanov.github.io/pivanov-utils/)**.
|
|
154
66
|
|
|
155
|
-
|
|
67
|
+
## Tree shaking
|
|
156
68
|
|
|
157
|
-
|
|
158
|
-
import { sleep } from '@pivanov/utils/promise';
|
|
69
|
+
Subpath imports give the smallest bundles:
|
|
159
70
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
console.log('Done');
|
|
164
|
-
}
|
|
71
|
+
```ts
|
|
72
|
+
import { camelCase } from '@pivanov/utils/string';
|
|
73
|
+
import { deepClone } from '@pivanov/utils/tools';
|
|
165
74
|
```
|
|
166
75
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
High-performance deep cloning and comparison with circular reference handling.
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
import { deepClone, isEqual } from '@pivanov/utils/tools';
|
|
173
|
-
|
|
174
|
-
// Deep clone complex structures
|
|
175
|
-
const original = {
|
|
176
|
-
nested: { array: [1, 2, { value: 3 }] },
|
|
177
|
-
date: new Date(),
|
|
178
|
-
map: new Map([['key', 'value']]),
|
|
179
|
-
set: new Set([1, 2, 3]),
|
|
180
|
-
circular: {} as any,
|
|
181
|
-
};
|
|
182
|
-
original.circular = original; // Circular reference
|
|
76
|
+
Top-level imports tree-shake fine in modern bundlers:
|
|
183
77
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Deep equality comparison
|
|
188
|
-
isEqual({ a: [1, 2, 3] }, { a: [1, 2, 3] }); // true
|
|
189
|
-
isEqual(new Date('2024-01-01'), new Date('2024-01-01')); // true
|
|
190
|
-
isEqual([1, 2, [3, 4]], [1, 2, [3, 4]]); // true
|
|
191
|
-
isEqual(new Set([1, 2]), new Set([2, 1])); // false (Sets maintain order)
|
|
78
|
+
```ts
|
|
79
|
+
import { camelCase, deepClone } from '@pivanov/utils';
|
|
192
80
|
```
|
|
193
81
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- Primitives (string, number, boolean, null, undefined, symbol, bigint)
|
|
197
|
-
- Arrays (including sparse arrays)
|
|
198
|
-
- Plain objects (with getters/setters)
|
|
199
|
-
- Date, RegExp, Map, Set
|
|
200
|
-
- TypedArrays, ArrayBuffer, Buffer
|
|
201
|
-
- Circular references
|
|
82
|
+
## A few highlights
|
|
202
83
|
|
|
203
|
-
###
|
|
84
|
+
### Async that cancels
|
|
204
85
|
|
|
205
|
-
|
|
86
|
+
```ts
|
|
87
|
+
import { sleep, timeout, retry } from '@pivanov/utils/promise';
|
|
206
88
|
|
|
207
|
-
|
|
208
|
-
|
|
89
|
+
const ctrl = new AbortController();
|
|
90
|
+
await sleep(1000, ctrl.signal); // cancellable
|
|
91
|
+
await timeout(fetch('/slow'), 3000); // race with timer
|
|
92
|
+
await retry(() => fetch('/api'), { attempts: 5, backoff: (n) => 100 * 2 ** n });
|
|
93
|
+
```
|
|
209
94
|
|
|
210
|
-
|
|
211
|
-
type AppEvents = {
|
|
212
|
-
'user-logged-in': { id: number; name: string };
|
|
213
|
-
'data-updated': { timestamp: number };
|
|
214
|
-
'notification': { message: string; type: 'info' | 'error' };
|
|
215
|
-
};
|
|
95
|
+
### Typed event bus
|
|
216
96
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
useEventBus<AppEvents>('user-logged-in', (data) => {
|
|
220
|
-
console.log(`Welcome ${data.name}!`);
|
|
221
|
-
});
|
|
97
|
+
```ts
|
|
98
|
+
import { busDispatch, useEventBus, type IEventBus } from '@pivanov/utils/tools';
|
|
222
99
|
|
|
223
|
-
|
|
100
|
+
interface UserLoggedIn extends IEventBus<{ id: number; name: string }> {
|
|
101
|
+
topic: 'user:logged-in';
|
|
224
102
|
}
|
|
225
103
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.log('Updated at:', data.timestamp);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// Later: cleanup
|
|
232
|
-
unsubscribe();
|
|
233
|
-
|
|
234
|
-
// Dispatch events anywhere in your app
|
|
235
|
-
busDispatch<AppEvents>('user-logged-in', { id: 1, name: 'John' });
|
|
236
|
-
busDispatch<AppEvents>('notification', {
|
|
237
|
-
message: 'Settings saved',
|
|
238
|
-
type: 'info',
|
|
239
|
-
});
|
|
104
|
+
useEventBus<UserLoggedIn>('user:logged-in', (user) => console.log(user.name));
|
|
105
|
+
busDispatch<UserLoggedIn>('user:logged-in', { id: 1, name: 'Ada' });
|
|
240
106
|
```
|
|
241
107
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- Fully type-safe with TypeScript
|
|
245
|
-
- Works across React and vanilla JavaScript
|
|
246
|
-
- Automatic cleanup with React hook
|
|
247
|
-
- Uses hashed topic names to avoid collisions
|
|
248
|
-
- Zero dependencies
|
|
108
|
+
See the [Typed Events guide](https://pivanov.github.io/pivanov-utils/guides/typed-events) for an event-map pattern at scale.
|
|
249
109
|
|
|
250
|
-
###
|
|
110
|
+
### Cache with TTL
|
|
251
111
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
112
|
+
```ts
|
|
255
113
|
import {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
storageExists,
|
|
260
|
-
storageClear,
|
|
261
|
-
storageClearByPrefixOrSuffix,
|
|
262
|
-
storageGetAllKeys,
|
|
263
|
-
storageCalculateSize,
|
|
264
|
-
} from '@pivanov/utils/tools';
|
|
265
|
-
|
|
266
|
-
const CACHE_NAME = 'my-app-cache';
|
|
267
|
-
|
|
268
|
-
// Store data
|
|
269
|
-
await storageSetItem(CACHE_NAME, 'user-data', {
|
|
270
|
-
id: 1,
|
|
271
|
-
name: 'John',
|
|
272
|
-
bigNumber: BigInt(9007199254740991), // BigInt support!
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
// Retrieve data
|
|
276
|
-
const userData = await storageGetItem<{ id: number; name: string }>(
|
|
277
|
-
CACHE_NAME,
|
|
278
|
-
'user-data'
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
// Check existence
|
|
282
|
-
const exists = await storageExists(CACHE_NAME, 'user-data');
|
|
283
|
-
|
|
284
|
-
// Remove specific item
|
|
285
|
-
await storageRemoveItem(CACHE_NAME, 'user-data');
|
|
286
|
-
|
|
287
|
-
// Get all keys
|
|
288
|
-
const keys = await storageGetAllKeys(CACHE_NAME);
|
|
289
|
-
|
|
290
|
-
// Clear items by prefix
|
|
291
|
-
await storageClearByPrefixOrSuffix(CACHE_NAME, 'temp-', true);
|
|
292
|
-
|
|
293
|
-
// Clear items by suffix
|
|
294
|
-
await storageClearByPrefixOrSuffix(CACHE_NAME, '-cache', false);
|
|
114
|
+
storageSetItemWithTTL,
|
|
115
|
+
storageGetItemWithTTL,
|
|
116
|
+
} from '@pivanov/utils/cache';
|
|
295
117
|
|
|
296
|
-
|
|
297
|
-
const totalSize = await storageCalculateSize(CACHE_NAME);
|
|
298
|
-
const itemSize = await storageCalculateSize(CACHE_NAME, 'user-data');
|
|
118
|
+
await storageSetItemWithTTL('app', 'token', 'abc123', 10 * 60 * 1000);
|
|
299
119
|
|
|
300
|
-
|
|
301
|
-
|
|
120
|
+
const token = await storageGetItemWithTTL<string>('app', 'token');
|
|
121
|
+
// null if missing or expired; expired entries are deleted on read
|
|
302
122
|
```
|
|
303
123
|
|
|
304
|
-
|
|
124
|
+
### Raw response caching in a service worker
|
|
305
125
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
- Size calculation utilities
|
|
126
|
+
`@pivanov/utils/cache` is built as its own bundle with no React, no event bus and
|
|
127
|
+
no DOM helpers, so a service worker can import it without dragging the rest of
|
|
128
|
+
the package in. Alongside the JSON helpers it exposes a raw layer that stores a
|
|
129
|
+
`Response` byte for byte, preserving body, status and headers.
|
|
311
130
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
Browser-safe DOM manipulation helpers.
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
131
|
+
```ts
|
|
317
132
|
import {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
} from '@pivanov/utils/
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
setStyleProperties(element, {
|
|
338
|
-
'--primary-color': '#3b82f6',
|
|
339
|
-
'--spacing': '1rem',
|
|
340
|
-
'--border-radius': '8px',
|
|
133
|
+
cacheDelete,
|
|
134
|
+
cacheMatchResponse,
|
|
135
|
+
cacheNames,
|
|
136
|
+
cachePutResponse,
|
|
137
|
+
} from '@pivanov/utils/cache';
|
|
138
|
+
|
|
139
|
+
const CACHE = 'assets-v3';
|
|
140
|
+
|
|
141
|
+
self.addEventListener('fetch', (event: FetchEvent) => {
|
|
142
|
+
event.respondWith((async () => {
|
|
143
|
+
const hit = await cacheMatchResponse(CACHE, event.request);
|
|
144
|
+
if (hit) {
|
|
145
|
+
return hit;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const response = await fetch(event.request);
|
|
149
|
+
await cachePutResponse(CACHE, event.request, response); // caches a clone
|
|
150
|
+
return response; // still readable
|
|
151
|
+
})());
|
|
341
152
|
});
|
|
342
153
|
|
|
343
|
-
//
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
const widthCustomFont = calculateRenderedTextWidth(
|
|
347
|
-
'Hello World',
|
|
348
|
-
16,
|
|
349
|
-
false,
|
|
350
|
-
'Arial'
|
|
351
|
-
);
|
|
154
|
+
// Revision cleanup
|
|
155
|
+
const outdated = (await cacheNames()).filter((name) => name !== CACHE);
|
|
156
|
+
await Promise.all(outdated.map(cacheDelete));
|
|
352
157
|
```
|
|
353
158
|
|
|
354
|
-
|
|
159
|
+
### Deep clone that actually preserves shape
|
|
355
160
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
// โ
Good: Import specific utilities
|
|
360
|
-
import { camelCase } from '@pivanov/utils/string';
|
|
161
|
+
```ts
|
|
361
162
|
import { deepClone } from '@pivanov/utils/tools';
|
|
362
163
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
## TypeScript Support
|
|
164
|
+
class User {
|
|
165
|
+
constructor(public name: string) {}
|
|
166
|
+
greet() { return `hi ${this.name}`; }
|
|
167
|
+
}
|
|
368
168
|
|
|
369
|
-
|
|
169
|
+
const clone = deepClone(new User('Ada'));
|
|
170
|
+
clone instanceof User; // true
|
|
171
|
+
clone.greet(); // 'hi Ada'
|
|
172
|
+
```
|
|
370
173
|
|
|
371
|
-
|
|
372
|
-
import { pick } from '@pivanov/utils/object';
|
|
373
|
-
import { capitalize } from '@pivanov/utils/string';
|
|
174
|
+
## Compatibility
|
|
374
175
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
176
|
+
- Modern browsers (ES2022)
|
|
177
|
+
- Bun, Node 18+ (ESM or CJS)
|
|
178
|
+
- Cache API requires browser support (Chrome 40+, Firefox 41+, Safari 11.1+)
|
|
179
|
+
- React hook requires React 18+
|
|
379
180
|
|
|
380
|
-
|
|
381
|
-
const capitalized = capitalize(str);
|
|
382
|
-
// Type: "Hello"
|
|
383
|
-
```
|
|
181
|
+
## Development
|
|
384
182
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
โโโ /tools - Various tools
|
|
394
|
-
โโโ deepClone
|
|
395
|
-
โโโ isEqual
|
|
396
|
-
โโโ DOM utilities (isBrowser, checkVisibility, etc.)
|
|
397
|
-
โโโ eventBus (busDispatch, busSubscribe, useEventBus)
|
|
398
|
-
โโโ Cache API (storageSetItem, storageGetItem, etc.)
|
|
183
|
+
```bash
|
|
184
|
+
bun install
|
|
185
|
+
bun test # run tests
|
|
186
|
+
bun run test:coverage # with coverage (lcov)
|
|
187
|
+
bun run typecheck
|
|
188
|
+
bun run lint
|
|
189
|
+
bun run build # ESM + CJS + .d.ts
|
|
190
|
+
bun run docs:dev # run VitePress docs site locally
|
|
399
191
|
```
|
|
400
192
|
|
|
401
|
-
##
|
|
193
|
+
## Sponsors
|
|
402
194
|
|
|
403
|
-
|
|
404
|
-
- Cache API requires browser support (Chrome 40+, Firefox 41+, Safari 11.1+)
|
|
405
|
-
- SSR-safe with browser environment detection
|
|
195
|
+
Supported by [LogicStar AI](https://logicstar.ai/)
|
|
406
196
|
|
|
407
197
|
## License
|
|
408
198
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pivanov/utils v1.0.1
|
|
3
|
+
* (c) 2024-present Pavel Ivanov
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
* https://github.com/pivanov/utils
|
|
6
|
+
*/
|
|
7
|
+
var{defineProperty:G,getOwnPropertyNames:I,getOwnPropertyDescriptor:J}=Object,K=Object.prototype.hasOwnProperty;function L(q){return this[q]}var N=(q)=>{var B=(H??=new WeakMap).get(q),D;if(B)return B;if(B=G({},"__esModule",{value:!0}),q&&typeof q==="object"||typeof q==="function"){for(var F of I(q))if(!K.call(B,F))G(B,F,{get:L.bind(q,F),enumerable:!(D=J(q,F))||D.enumerable})}return H.set(q,B),B},H;var O=(q)=>q;function Q(q,B){this[q]=O.bind(null,B)}var R=(q,B)=>{for(var D in B)G(q,D,{get:B[D],enumerable:!0,configurable:!0,set:Q.bind(B,D)})};var M={};R(M,{isUndefined:()=>Z,isString:()=>V,isSet:()=>d,isRegExp:()=>A,isRecord:()=>Y,isPromise:()=>P,isPrimitive:()=>f,isObject:()=>X,isNumber:()=>U,isNull:()=>_,isNil:()=>$,isMap:()=>b,isFunction:()=>W,isError:()=>C,isEmpty:()=>k,isDefined:()=>j,isDate:()=>z,isBoolean:()=>T,isArray:()=>x});module.exports=N(M);var T=(q)=>{return typeof q==="boolean"},U=(q)=>{return typeof q==="number"},V=(q)=>{return typeof q==="string"},W=(q)=>{return typeof q==="function"},X=(q)=>{if(q===null||typeof q!=="object")return!1;let B=Object.getPrototypeOf(q);return B===Object.prototype||B===null},Y=(q)=>{return typeof q==="object"&&q!==null},Z=(q)=>{return q===void 0},_=(q)=>{return q===null},$=(q)=>{return q===null||q===void 0},j=(q)=>{return q!==void 0},x=(q)=>{return Array.isArray(q)},z=(q)=>{return q instanceof Date},A=(q)=>{return q instanceof RegExp},C=(q)=>{return q instanceof Error},P=(q)=>{return q!==null&&(typeof q==="object"||typeof q==="function")&&typeof q.then==="function"},b=(q)=>{return q instanceof Map},d=(q)=>{return q instanceof Set},f=(q)=>{if(q===null||q===void 0)return!0;let B=typeof q;return B==="string"||B==="number"||B==="boolean"||B==="bigint"||B==="symbol"},k=(q)=>{if(q===null||q===void 0)return!0;if(typeof q==="string"||Array.isArray(q))return q.length===0;if(q instanceof Map||q instanceof Set)return q.size===0;if(typeof q==="object")return Object.keys(q).length===0;return!1};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pivanov/utils v1.0.1
|
|
3
|
+
* (c) 2024-present Pavel Ivanov
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
* https://github.com/pivanov/utils
|
|
6
|
+
*/
|
|
7
|
+
var{defineProperty:Q,getOwnPropertyNames:G,getOwnPropertyDescriptor:M}=Object,S=Object.prototype.hasOwnProperty;function U(b){return this[b]}var $=(b)=>{var d=(Y??=new WeakMap).get(b),w;if(d)return d;if(d=Q({},"__esModule",{value:!0}),b&&typeof b==="object"||typeof b==="function"){for(var R of G(b))if(!S.call(d,R))Q(d,R,{get:U.bind(b,R),enumerable:!(w=M(b,R))||w.enumerable})}return Y.set(b,d),d},Y;var L=(b)=>b;function B(b,d){this[b]=L.bind(null,d)}var I=(b,d)=>{for(var w in d)Q(b,w,{get:d[w],enumerable:!0,configurable:!0,set:B.bind(d,w)})};var N={};I(N,{stringifyBigIntValues:()=>Z,storageSetItemWithTTL:()=>p,storageSetItem:()=>_,storageRemoveItem:()=>E,storageGetItemWithTTL:()=>q,storageGetItem:()=>D,storageGetAllKeys:()=>u,storageExists:()=>l,storageClearBySuffix:()=>k,storageClearByPrefixOrSuffix:()=>X,storageClearByPrefix:()=>C,storageClear:()=>o,storageCalculateSize:()=>r,isCacheStorageSupported:()=>W,cacheResponseKeys:()=>z,cachePutResponse:()=>V,cacheNames:()=>v,cacheMatchResponse:()=>f,cacheHasResponse:()=>x,cacheExists:()=>K,cacheDeleteResponse:()=>g,cacheDelete:()=>i,cacheClear:()=>P});module.exports=$(N);var W=()=>{return typeof caches<"u"};var O=()=>{if(!W())throw Error("[@pivanov/utils/cache] Cache Storage is not available in this environment.");return caches},A=(b)=>{return O().open(b)},F=(b)=>{if(b.startsWith("http://")||b.startsWith("https://"))return b;return`https://cache.internal/${b}`};var V=async(b,d,w)=>{if(w.bodyUsed)throw TypeError("[@pivanov/utils/cache] cachePutResponse received a Response whose body has already been consumed.");await(await A(b)).put(d,w.clone())},f=async(b,d,w)=>{return(await A(b)).match(d,w)},g=async(b,d,w)=>{return(await A(b)).delete(d,w)},x=async(b,d,w)=>{return await(await A(b)).match(d,w)!==void 0},z=async(b)=>{return(await(await A(b)).keys()).map((R)=>R.url)},P=async(b)=>{let d=await A(b),w=await d.keys();await Promise.all(w.map((R)=>d.delete(R)))},v=async()=>{return O().keys()},K=async(b)=>{return O().has(b)},i=async(b)=>{return O().delete(b)};var Z=(b,d)=>{return typeof d==="bigint"?d.toString():d},_=async(b,d,w)=>{let R=await A(b),T=JSON.stringify(w,Z),J=new Response(T,{headers:{"Content-Type":"application/json"}}),j=F(d);await R.put(new Request(j),J)},D=async(b,d)=>{let w=await A(b),R=F(d),T=await w.match(new Request(R));if(!T)return null;let J=await T.text();return JSON.parse(J)},n=(b)=>{return typeof b==="object"&&b!==null&&b.__ttl===!0&&typeof b.exp==="number"},p=async(b,d,w,R)=>{let T={__ttl:!0,v:w,exp:Date.now()+R};await _(b,d,T)},q=async(b,d)=>{let w=await D(b,d);if(!n(w))return null;if(Date.now()>=w.exp)return await E(b,d),null;return w.v},E=async(b,d)=>{let w=await A(b),R=F(d);return w.delete(new Request(R))},o=async(b)=>{let d=await A(b),w=await d.keys();for(let R of w)await d.delete(R)},X=async(b,d,w=!0)=>{let R=await A(b),T=await R.keys();for(let J of T){let j=J.url.split("/"),H=j[j.length-1]||"";if(w&&H.startsWith(d)||!w&&H.endsWith(d))await R.delete(J)}},C=async(b,d)=>{await X(b,d,!0)},k=async(b,d)=>{await X(b,d,!1)},l=async(b,d)=>{let w=await A(b),R=F(d);return await w.match(new Request(R))!==void 0},u=async(b)=>{return(await(await A(b)).keys()).map((R)=>{let T=R.url.split("/");return T[T.length-1]||""})},r=async(b,d)=>{let w=await A(b);if(d){let J=F(d),j=await w.match(new Request(J));if(j)return(await j.clone().arrayBuffer()).byteLength;return 0}let R=await w.keys(),T=0;for(let J of R){let j=await w.match(J);if(j){let H=await j.clone().arrayBuffer();T+=H.byteLength}}return T};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @pivanov/utils
|
|
2
|
+
* @pivanov/utils v1.0.1
|
|
3
3
|
* (c) 2024-present Pavel Ivanov
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
* https://github.com/pivanov/utils
|
|
6
6
|
*/
|
|
7
|
-
"use strict";var e=require("react");const t=e=>{if(null===e||"object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t},r=(e,...n)=>{if(!n.length)return e;const s=n.shift();if(void 0===s)return e;if(t(e)&&t(s))for(const n of Object.keys(s)){const o=s[n];if(t(o)){e[n]||Object.assign(e,{[n]:{}});const s=e[n];t(s)&&r(s,o)}else Object.assign(e,{[n]:o})}return r(e,...n)},n=(e,t)=>"bigint"==typeof t?t.toString():t,s=e=>e.startsWith("http://")||e.startsWith("https://")?e:`https://cache.internal/${e}`,o=e=>`${((e,t="๐")=>{let r=0;const n=e+t;for(let e=0;e<n.length;e++)r=(r<<5)-r+n.charCodeAt(e),r|=0;return(r>>>0).toString(16)})(e)}::${e}`,i=(e,t)=>{if(!e||"function"!=typeof t)return()=>{};const r=(e=>t=>{if(t instanceof CustomEvent)try{e(t.detail)}catch(e){console.error("Event listener error:",e)}})(t),n=o(e);return window.addEventListener(n,r),()=>window.removeEventListener(n,r)},a=(e,t)=>{if(null===e||"object"!=typeof e)return e;const r=t.get(e);if(r)return r;if(Array.isArray(e)){const r=e.length;if(r<32){const n=new Array(r);t.set(e,n);for(let s=0;s<r;s++)s in e&&(n[s]=a(e[s],t));return n}const n=new Array(r);if(t.set(e,n),Object.keys(e).length===r){let s=0;const o=r-r%8;for(;s<o;)n[s]=a(e[s],t),n[s+1]=a(e[s+1],t),n[s+2]=a(e[s+2],t),n[s+3]=a(e[s+3],t),n[s+4]=a(e[s+4],t),n[s+5]=a(e[s+5],t),n[s+6]=a(e[s+6],t),n[s+7]=a(e[s+7],t),s+=8;for(;s<r;)n[s]=a(e[s],t),s++}else for(let s=0;s<r;s++)s in e&&(n[s]=a(e[s],t));return n}if(e instanceof Date||e instanceof RegExp){return new(0,e.constructor)(e)}if("undefined"!=typeof Buffer)try{if(Buffer.isBuffer(e))return Buffer.from(e)}catch(e){if(e instanceof Error)throw e}if(ArrayBuffer.isView(e)){const t=e.constructor;if("buffer"in e){const r=e;return new t(r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength))}return new t(new ArrayBuffer(e.byteLength))}if(e instanceof ArrayBuffer)return e.slice(0);if(e&&"object"==typeof e&&"buffer"in e&&"byteLength"in e){const t=e;if("undefined"==typeof Buffer){const e=new Uint8Array(t.buffer,t.byteOffset||0,t.byteLength),r=new Uint8Array(e.length);return r.set(e),r}return{buffer:t.buffer instanceof ArrayBuffer?t.buffer.slice(0):new ArrayBuffer(t.byteLength),byteLength:t.byteLength,byteOffset:t.byteOffset||0,length:t.length||t.byteLength,BYTES_PER_ELEMENT:t.BYTES_PER_ELEMENT||1}}if(e instanceof Set){const r=new Set;t.set(e,r);const n=Array.from(e),s=n.length;for(let e=0;e<s;e++)r.add(a(n[e],t));return r}if(e instanceof Map){const r=new Map;t.set(e,r);const n=Array.from(e),s=n.length;for(let e=0;e<s;e++){const[s,o]=n[e];r.set(s,a(o,t))}return r}if(Object.getPrototypeOf(e)===Object.prototype){const r={};t.set(e,r);const n=Object.getOwnPropertySymbols(e),s=n.length;if(s>0)for(let t=0;t<s;t++){const s=n[t],o=Object.getOwnPropertyDescriptor(e,s);o?.enumerable&&Object.defineProperty(r,s,o)}const o=Object.getOwnPropertyDescriptors(e),i=Object.keys(e),c=i.length;let f=!1;for(let e=0;e<c;e++){const t=o[i[e]];if(t.get||t.set){f=!0;break}}if(f)for(let e=0;e<c;e++){const n=i[e],s=o[n];if(s.enumerable)if(s.get||s.set)Object.defineProperty(r,n,s);else{const e=a(s.value,t);Object.defineProperty(r,n,{...s,value:e})}}else{let n=0;const s=c-c%8;for(;n<s;){const s=i[n],o=i[n+1],c=i[n+2],f=i[n+3],l=i[n+4],p=i[n+5],u=i[n+6],y=i[n+7],g=e;r[s]=a(g[s],t),r[o]=a(g[o],t),r[c]=a(g[c],t),r[f]=a(g[f],t),r[l]=a(g[l],t),r[p]=a(g[p],t),r[u]=a(g[u],t),r[y]=a(g[y],t),n+=8}for(;n<c;){const s=i[n++];r[s]=a(e[s],t)}}return r}const n=Object.getPrototypeOf(e),s=Object.create(n);t.set(e,s);const o=Object.getOwnPropertyDescriptors(e),i=Object.keys(o),c=i.length;for(let e=0;e<c;e++){const r=i[e],n=o[r];if(n.enumerable)if(n.get||n.set)Object.defineProperty(s,r,n);else{const e=a(n.value,t);Object.defineProperty(s,r,{...n,value:e})}}const f=Object.getOwnPropertySymbols(e),l=f.length;for(let t=0;t<l;t++){const r=f[t],n=Object.getOwnPropertyDescriptor(e,r);n?.enumerable&&Object.defineProperty(s,r,n)}return s},c=(e,t)=>{if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!c(e[r],t[r]))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(const r of e)if(!t.has(r))return!1;return!0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(const[r,n]of e)if(!t.has(r)||!c(n,t.get(r)))return!1;return!0}if(null!==e&&"object"==typeof e&&!Array.isArray(e)&&null!==t&&"object"==typeof t&&!Array.isArray(t)){const r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(const n of r)if(!c(e[n],t[n]))return!1;return!0}return e===t};exports.busDispatch=(e,t)=>{if(!e)return;const r=o(e);window.dispatchEvent(new CustomEvent(r,{detail:t,bubbles:!0,cancelable:!1}))},exports.busSubscribe=i,exports.calculateRenderedTextWidth=(e,t,r=!1,n='Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"')=>{const s=r?e.toUpperCase():e,o=document.createElement("canvas").getContext("2d");return o.font=`${t}px ${n}`,o.measureText(s).width},exports.camelCase=e=>e.trim().toLowerCase().replace(/^[-_\s]+/,"").replace(/[-_\s]+(.)?/g,((e,t)=>t?t.toUpperCase():"")),exports.capitalize=e=>e.charAt(0).toUpperCase()+e.slice(1),exports.capitalizeFirstLetter=e=>e.charAt(0).toUpperCase()+e.slice(1),exports.checkVisibility=e=>{const t=e.getBoundingClientRect(),r=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(t.bottom<0||t.top-r>=0)},exports.deepClone=e=>a(e,new WeakMap),exports.deepMerge=r,exports.isBoolean=e=>"boolean"==typeof e,exports.isBrowser=()=>"undefined"!=typeof window,exports.isEqual=c,exports.isFunction=e=>"function"==typeof e,exports.isNull=e=>null===e,exports.isNumber=e=>"number"==typeof e,exports.isObject=t,exports.isString=e=>"string"==typeof e,exports.isUndefined=e=>void 0===e,exports.kebabCase=e=>null==e?e:e.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z][a-z])/g,"$1-$2").replace(/[-_\s]+/g,"-").toLowerCase().replace(/^-+|-+$/g,"").trim(),exports.merge=(e,...t)=>Object.assign(e,...t),exports.omit=(e,t)=>t.reduce(((e,t)=>(delete e[t],e)),{...e}),exports.pascalCase=e=>e.split(/(?=[0-9])|(?<=[0-9])|[^a-zA-Z0-9]+/g).filter(Boolean).map((e=>e.toLowerCase())).map((e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`)).join(""),exports.pick=(e,t)=>{const r={};for(const n of t)n in e&&(r[n]=e[n]);return r},exports.setStyleProperties=(e,t)=>{if(e)for(const[r,n]of Object.entries(t))e.style.setProperty(r,n)},exports.sleep=e=>new Promise((t=>{setTimeout(t,e)})),exports.slugify=e=>e.normalize("NFKD").toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[-\s_]+/g,"-").replace(/^-+|-+$/g,""),exports.storageCalculateSize=async(e,t)=>{const r=await caches.open(e);if(t){const e=s(t),n=await r.match(new Request(e));if(n){const e=n.clone();return(await e.arrayBuffer()).byteLength}return 0}const n=await r.keys();let o=0;for(const e of n){const t=await r.match(e);if(t){const e=t.clone();o+=(await e.arrayBuffer()).byteLength}}return o},exports.storageClear=async e=>{const t=await caches.open(e),r=await t.keys();for(const e of r)await t.delete(e)},exports.storageClearByPrefixOrSuffix=async(e,t,r=!0)=>{const n=await caches.open(e),s=await n.keys();for(const e of s){const s=e.url.split("/"),o=s[s.length-1]||"";(r&&o.startsWith(t)||!r&&o.endsWith(t))&&await n.delete(e)}},exports.storageExists=async(e,t)=>{const r=await caches.open(e),n=s(t);return void 0!==await r.match(new Request(n))},exports.storageGetAllKeys=async e=>{const t=await caches.open(e);return(await t.keys()).map((e=>{const t=e.url.split("/");return t[t.length-1]||""}))},exports.storageGetItem=async(e,t)=>{const r=await caches.open(e),n=s(t),o=await r.match(new Request(n));if(!o)return null;const i=await o.text();return JSON.parse(i)},exports.storageRemoveItem=async(e,t)=>{const r=await caches.open(e),n=s(t);return await r.delete(new Request(n))},exports.storageSetItem=async(e,t,r)=>{const o=await caches.open(e),i=JSON.stringify(r,n),a=new Response(i,{headers:{"Content-Type":"application/json"}}),c=s(t);await o.put(new Request(c),a)},exports.stringifyBigIntValues=n,exports.uncapitalize=e=>e.charAt(0).toLowerCase()+e.slice(1),exports.useEventBus=(t,r,n=[])=>{e.useEffect((()=>{if(t&&"function"==typeof r)return i(t,r)}),[t,r,...n])};
|
|
7
|
+
var{defineProperty:g,getOwnPropertyNames:PQ,getOwnPropertyDescriptor:EQ}=Object,VQ=Object.prototype.hasOwnProperty;function qQ(J){return this[J]}var P=(J)=>{var Q=(s??=new WeakMap).get(J),X;if(Q)return Q;if(Q=g({},"__esModule",{value:!0}),J&&typeof J==="object"||typeof J==="function"){for(var Y of PQ(J))if(!VQ.call(Q,Y))g(Q,Y,{get:qQ.bind(J,Y),enumerable:!(X=EQ(J,Y))||X.enumerable})}return s.set(J,Q),Q},s;var LQ=(J)=>J;function DQ(J,Q){this[J]=LQ.bind(null,Q)}var V=(J,Q)=>{for(var X in Q)g(J,X,{get:Q[X],enumerable:!0,configurable:!0,set:DQ.bind(Q,X)})};var wQ={};V(wQ,{isUndefined:()=>XJ,isString:()=>e,isSet:()=>HJ,isRegExp:()=>FJ,isRecord:()=>QJ,isPromise:()=>WJ,isPrimitive:()=>OJ,isObject:()=>D,isNumber:()=>a,isNull:()=>YJ,isNil:()=>ZJ,isMap:()=>BJ,isFunction:()=>JJ,isError:()=>UJ,isEmpty:()=>IJ,isDefined:()=>GJ,isDate:()=>_J,isBoolean:()=>t,isArray:()=>$J});module.exports=P(wQ);var t=(J)=>{return typeof J==="boolean"},a=(J)=>{return typeof J==="number"},e=(J)=>{return typeof J==="string"},JJ=(J)=>{return typeof J==="function"},D=(J)=>{if(J===null||typeof J!=="object")return!1;let Q=Object.getPrototypeOf(J);return Q===Object.prototype||Q===null},QJ=(J)=>{return typeof J==="object"&&J!==null},XJ=(J)=>{return J===void 0},YJ=(J)=>{return J===null},ZJ=(J)=>{return J===null||J===void 0},GJ=(J)=>{return J!==void 0},$J=(J)=>{return Array.isArray(J)},_J=(J)=>{return J instanceof Date},FJ=(J)=>{return J instanceof RegExp},UJ=(J)=>{return J instanceof Error},WJ=(J)=>{return J!==null&&(typeof J==="object"||typeof J==="function")&&typeof J.then==="function"},BJ=(J)=>{return J instanceof Map},HJ=(J)=>{return J instanceof Set},OJ=(J)=>{if(J===null||J===void 0)return!0;let Q=typeof J;return Q==="string"||Q==="number"||Q==="boolean"||Q==="bigint"||Q==="symbol"},IJ=(J)=>{if(J===null||J===void 0)return!0;if(typeof J==="string"||Array.isArray(J))return J.length===0;if(J instanceof Map||J instanceof Set)return J.size===0;if(typeof J==="object")return Object.keys(J).length===0;return!1};var xQ={};V(xQ,{pickBy:()=>d,pick:()=>TJ,omitBy:()=>MJ,omit:()=>RJ,merge:()=>LJ,mapValues:()=>zJ,mapKeys:()=>AJ,keysOf:()=>EJ,invert:()=>KJ,hasOwn:()=>PJ,groupBy:()=>SJ,fromEntries:()=>qJ,entriesOf:()=>VJ,deepMerge:()=>v});module.exports=P(xQ);var RJ=(J,Q)=>{let X={...J};for(let Y of Q)delete X[Y];return X},TJ=(J,Q)=>{let X={};for(let Y of Q)if(Y in J)X[Y]=J[Y];return X},d=(J,Q)=>{let X={};for(let Y of Object.keys(J))if(Q(J[Y],Y))X[Y]=J[Y];return X},MJ=(J,Q)=>{return d(J,(X,Y)=>!Q(X,Y))},zJ=(J,Q)=>{let X={};for(let Y of Object.keys(J))X[Y]=Q(J[Y],Y);return X},AJ=(J,Q)=>{let X={};for(let Y of Object.keys(J))X[Q(J[Y],Y)]=J[Y];return X},SJ=(J,Q)=>{let X={};return J.forEach((Y,Z)=>{let _=Q(Y,Z);if(X[_])X[_].push(Y);else X[_]=[Y]}),X},KJ=(J)=>{let Q={};for(let X of Object.keys(J))Q[J[X]]=X;return Q},PJ=(J,Q)=>{return Object.hasOwn(J,Q)},EJ=(J)=>{return Object.keys(J)},VJ=(J)=>{return Object.entries(J)},qJ=(J)=>{return Object.fromEntries(J)},LJ=(J,...Q)=>{return Object.assign({},J,...Q)},v=(J,...Q)=>{let X={...J};for(let Y of Q){if(Y===void 0)continue;for(let Z of Object.keys(Y)){let _=Y[Z],F=X[Z];if(D(_))X[Z]=v(D(F)?F:{},_);else X[Z]=_}}return X};var NQ={};V(NQ,{timeout:()=>DJ,sleep:()=>k,retry:()=>wJ,parallelLimit:()=>NJ,defer:()=>xJ});module.exports=P(NQ);var k=(J,Q)=>{return new Promise((X,Y)=>{if(Q?.aborted){Y(Q.reason);return}let Z=setTimeout(()=>{Q?.removeEventListener("abort",_),X()},J),_=()=>{clearTimeout(Z),Y(Q?.reason)};Q?.addEventListener("abort",_,{once:!0})})},DJ=(J,Q,X)=>{return new Promise((Y,Z)=>{let _=setTimeout(()=>{Z(X??Error(`Operation timed out after ${Q}ms`))},Q);J.then((F)=>{clearTimeout(_),Y(F)},(F)=>{clearTimeout(_),Z(F)})})},wJ=async(J,Q={})=>{let{attempts:X=3,backoff:Y=0,signal:Z,shouldRetry:_}=Q,F;for(let H=1;H<=X;H++){if(Z?.aborted)throw Z.reason;try{return await J(H)}catch(A){if(F=A,H>=X)break;if(_&&!_(A,H))break;let E=typeof Y==="function"?Y(H):Y;if(E>0)await k(E,Z)}}throw F},xJ=()=>{let J,Q;return{promise:new Promise((Y,Z)=>{J=Y,Q=Z}),resolve:J,reject:Q}},NJ=async(J,Q,X)=>{if(Q<1)throw Error("parallelLimit: concurrency must be >= 1");let Y=Array(J.length),Z=0,_=async()=>{while(!0){let H=Z++;if(H>=J.length)return;Y[H]=await X(J[H],H)}},F=Array.from({length:Math.min(Q,J.length)},_);return await Promise.all(F),Y};var CQ={};V(CQ,{words:()=>bJ,uncapitalize:()=>yJ,truncate:()=>jJ,titleCase:()=>kJ,snakeCase:()=>vJ,slugify:()=>mJ,pascalCase:()=>CJ,lines:()=>lJ,kebabCase:()=>dJ,escapeRegExp:()=>uJ,escapeHtml:()=>pJ,capitalizeFirstLetter:()=>gJ,capitalize:()=>hJ,camelCase:()=>fJ});module.exports=P(CQ);var fJ=(J)=>{return J.trim().toLowerCase().replace(/^[-_\s]+/,"").replace(/[-_\s]+(.)?/g,(Q,X)=>X?X.toUpperCase():"")},CJ=(J)=>{return J.split(/(?=[0-9])|(?<=[0-9])|[^a-zA-Z0-9]+/g).filter(Boolean).map((Q)=>Q.toLowerCase()).map((Q)=>`${Q.charAt(0).toUpperCase()}${Q.slice(1)}`).join("")},gJ=(J)=>J.charAt(0).toUpperCase()+J.slice(1),dJ=(J)=>{if(J==null)return J;return J.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z][a-z])/g,"$1-$2").replace(/[-_\s]+/g,"-").toLowerCase().replace(/^-+|-+$/g,"").trim()},vJ=(J)=>{if(J==null)return J;return J.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").replace(/[-_\s]+/g,"_").toLowerCase().replace(/^_+|_+$/g,"").trim()},kJ=(J)=>{return J.normalize("NFKD").replace(/[^\w\s-]/g," ").split(/[-_\s]+/).filter(Boolean).map((Q)=>Q.charAt(0).toUpperCase()+Q.slice(1).toLowerCase()).join(" ")},mJ=(J)=>{return J.normalize("NFKD").toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[-\s_]+/g,"-").replace(/^-+|-+$/g,"")},hJ=(J)=>{return J.charAt(0).toUpperCase()+J.slice(1)},yJ=(J)=>{return J.charAt(0).toLowerCase()+J.slice(1)},jJ=(J,Q,X="โฆ")=>{if(J.length<=Q)return J;if(Q<=X.length)return X.slice(0,Q);return J.slice(0,Q-X.length)+X},fQ={"&":"&","<":"<",">":">",'"':""","'":"'"},pJ=(J)=>{return J.replace(/[&<>"']/g,(Q)=>fQ[Q])},uJ=(J)=>{return J.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},bJ=(J)=>{return J.split(/[-_\s]+/).filter(Boolean)},lJ=(J)=>{return J.split(/\r\n|\r|\n/)};var mQ={};V(mQ,{useEventBus:()=>AQ,stringifyBigIntValues:()=>m,storageSetItemWithTTL:()=>JQ,storageSetItem:()=>h,storageRemoveItem:()=>j,storageGetItemWithTTL:()=>QQ,storageGetItem:()=>y,storageGetAllKeys:()=>$Q,storageExists:()=>GQ,storageClearBySuffix:()=>ZQ,storageClearByPrefixOrSuffix:()=>C,storageClearByPrefix:()=>YQ,storageClear:()=>XQ,storageCalculateSize:()=>_Q,setStyleProperties:()=>WQ,isInViewport:()=>OQ,isEqual:()=>KQ,isCacheStorageSupported:()=>f,isBrowser:()=>UQ,deepClone:()=>FQ,checkVisibility:()=>BQ,calculateRenderedTextWidth:()=>IQ,cacheResponseKeys:()=>rJ,cachePutResponse:()=>cJ,cacheNames:()=>tJ,cacheMatchResponse:()=>nJ,cacheHasResponse:()=>oJ,cacheExists:()=>aJ,cacheDeleteResponse:()=>iJ,cacheDelete:()=>eJ,cacheClear:()=>sJ,busSubscribe:()=>x,busOnce:()=>MQ,busDispatch:()=>TQ,__resetTextMeasurementCache:()=>HQ});module.exports=P(mQ);var f=()=>{return typeof caches<"u"};var w=()=>{if(!f())throw Error("[@pivanov/utils/cache] Cache Storage is not available in this environment.");return caches},R=(J)=>{return w().open(J)},q=(J)=>{if(J.startsWith("http://")||J.startsWith("https://"))return J;return`https://cache.internal/${J}`};var cJ=async(J,Q,X)=>{if(X.bodyUsed)throw TypeError("[@pivanov/utils/cache] cachePutResponse received a Response whose body has already been consumed.");await(await R(J)).put(Q,X.clone())},nJ=async(J,Q,X)=>{return(await R(J)).match(Q,X)},iJ=async(J,Q,X)=>{return(await R(J)).delete(Q,X)},oJ=async(J,Q,X)=>{return await(await R(J)).match(Q,X)!==void 0},rJ=async(J)=>{return(await(await R(J)).keys()).map((Y)=>Y.url)},sJ=async(J)=>{let Q=await R(J),X=await Q.keys();await Promise.all(X.map((Y)=>Q.delete(Y)))},tJ=async()=>{return w().keys()},aJ=async(J)=>{return w().has(J)},eJ=async(J)=>{return w().delete(J)};var m=(J,Q)=>{return typeof Q==="bigint"?Q.toString():Q},h=async(J,Q,X)=>{let Y=await R(J),Z=JSON.stringify(X,m),_=new Response(Z,{headers:{"Content-Type":"application/json"}}),F=q(Q);await Y.put(new Request(F),_)},y=async(J,Q)=>{let X=await R(J),Y=q(Q),Z=await X.match(new Request(Y));if(!Z)return null;let _=await Z.text();return JSON.parse(_)},gQ=(J)=>{return typeof J==="object"&&J!==null&&J.__ttl===!0&&typeof J.exp==="number"},JQ=async(J,Q,X,Y)=>{let Z={__ttl:!0,v:X,exp:Date.now()+Y};await h(J,Q,Z)},QQ=async(J,Q)=>{let X=await y(J,Q);if(!gQ(X))return null;if(Date.now()>=X.exp)return await j(J,Q),null;return X.v},j=async(J,Q)=>{let X=await R(J),Y=q(Q);return X.delete(new Request(Y))},XQ=async(J)=>{let Q=await R(J),X=await Q.keys();for(let Y of X)await Q.delete(Y)},C=async(J,Q,X=!0)=>{let Y=await R(J),Z=await Y.keys();for(let _ of Z){let F=_.url.split("/"),H=F[F.length-1]||"";if(X&&H.startsWith(Q)||!X&&H.endsWith(Q))await Y.delete(_)}},YQ=async(J,Q)=>{await C(J,Q,!0)},ZQ=async(J,Q)=>{await C(J,Q,!1)},GQ=async(J,Q)=>{let X=await R(J),Y=q(Q);return await X.match(new Request(Y))!==void 0},$Q=async(J)=>{return(await(await R(J)).keys()).map((Y)=>{let Z=Y.url.split("/");return Z[Z.length-1]||""})},_Q=async(J,Q)=>{let X=await R(J);if(Q){let _=q(Q),F=await X.match(new Request(_));if(F)return(await F.clone().arrayBuffer()).byteLength;return 0}let Y=await X.keys(),Z=0;for(let _ of Y){let F=await X.match(_);if(F){let H=await F.clone().arrayBuffer();Z+=H.byteLength}}return Z};var FQ=(J)=>{return B(J,new WeakMap)},B=(J,Q)=>{if(J===null||typeof J!=="object")return J;let X=Q.get(J);if(X)return X;if(Array.isArray(J)){let G=J.length;if(G<32){let $=Array(G);Q.set(J,$);for(let W=0;W<G;W++)if(W in J)$[W]=B(J[W],Q);return $}let U=Array(G);if(Q.set(J,U),Object.keys(J).length===G){let $=0,W=G%8,I=G-W;while($<I)U[$]=B(J[$],Q),U[$+1]=B(J[$+1],Q),U[$+2]=B(J[$+2],Q),U[$+3]=B(J[$+3],Q),U[$+4]=B(J[$+4],Q),U[$+5]=B(J[$+5],Q),U[$+6]=B(J[$+6],Q),U[$+7]=B(J[$+7],Q),$+=8;while($<G)U[$]=B(J[$],Q),$++}else for(let $=0;$<G;$++)if($ in J)U[$]=B(J[$],Q);return U}if(J instanceof Date||J instanceof RegExp)return new J.constructor(J);if(typeof Buffer<"u")try{if(Buffer.isBuffer(J))return Buffer.from(J)}catch(G){if(G instanceof Error)throw G}if(ArrayBuffer.isView(J)){let G=J.constructor;if("buffer"in J){let $=J,W=$.buffer.slice($.byteOffset,$.byteOffset+$.byteLength);return new G(W)}return new G(new ArrayBuffer(J.byteLength))}if(J instanceof ArrayBuffer)return J.slice(0);if(J&&typeof J==="object"&&"buffer"in J&&"byteLength"in J){let G=J;if(typeof Buffer>"u"){let $=new Uint8Array(G.buffer,G.byteOffset||0,G.byteLength),W=new Uint8Array($.length);return W.set($),W}return{buffer:G.buffer instanceof ArrayBuffer?G.buffer.slice(0):new ArrayBuffer(G.byteLength),byteLength:G.byteLength,byteOffset:G.byteOffset||0,length:G.length||G.byteLength,BYTES_PER_ELEMENT:G.BYTES_PER_ELEMENT||1}}if(J instanceof Set){let G=new Set;Q.set(J,G);let U=Array.from(J),$=U.length;for(let W=0;W<$;W++)G.add(B(U[W],Q));return G}if(J instanceof Map){let G=new Map;Q.set(J,G);let U=Array.from(J),$=U.length;for(let W=0;W<$;W++){let[I,S]=U[W];G.set(I,B(S,Q))}return G}if(Object.getPrototypeOf(J)===Object.prototype){let G={};Q.set(J,G);let U=Object.getOwnPropertySymbols(J),$=U.length;if($>0)for(let O=0;O<$;O++){let T=U[O],M=Object.getOwnPropertyDescriptor(J,T);if(M?.enumerable)Object.defineProperty(G,T,M)}let W=Object.getOwnPropertyDescriptors(J),I=Object.keys(J),S=I.length,u=!1;for(let O=0;O<S;O++){let T=W[I[O]];if(T.get||T.set){u=!0;break}}if(u)for(let O=0;O<S;O++){let T=I[O],M=W[T];if(M.enumerable)if(M.get||M.set)Object.defineProperty(G,T,M);else{let K=B(M.value,Q);Object.defineProperty(G,T,{...M,value:K})}}else{let O=0,T=S%8,M=S-T;while(O<M){let K=I[O],b=I[O+1],l=I[O+2],c=I[O+3],n=I[O+4],i=I[O+5],o=I[O+6],r=I[O+7],z=J;G[K]=B(z[K],Q),G[b]=B(z[b],Q),G[l]=B(z[l],Q),G[c]=B(z[c],Q),G[n]=B(z[n],Q),G[i]=B(z[i],Q),G[o]=B(z[o],Q),G[r]=B(z[r],Q),O+=8}while(O<S){let K=I[O++];G[K]=B(J[K],Q)}}return G}let Y=Object.getPrototypeOf(J),Z=Object.create(Y);Q.set(J,Z);let _=Object.getOwnPropertyDescriptors(J),F=Object.keys(_),H=F.length;for(let G=0;G<H;G++){let U=F[G],$=_[U];if(!$.enumerable)continue;if($.get||$.set)Object.defineProperty(Z,U,$);else{let W=B($.value,Q);Object.defineProperty(Z,U,{...$,value:W})}}let A=Object.getOwnPropertySymbols(J),E=A.length;for(let G=0;G<E;G++){let U=A[G],$=Object.getOwnPropertyDescriptor(J,U);if(!$?.enumerable)continue;Object.defineProperty(Z,U,$)}return Z};var UQ=()=>{return typeof window<"u"&&typeof document<"u"},WQ=(J,Q)=>{if(!J)return;for(let[X,Y]of Object.entries(Q))J.style.setProperty(X,Y)},BQ=(J,Q={})=>{let{checkViewport:X=!0,checkDisplay:Y=!0,checkVisibility:Z=!0,checkOpacity:_=!0}=Q;if(!J.isConnected)return!1;if(Y||Z||_){let F=window.getComputedStyle(J);if(Y&&F.display==="none")return!1;if(Z&&F.visibility!==""&&F.visibility!=="visible")return!1;if(_&&F.opacity!==""){let H=Number.parseFloat(F.opacity);if(!Number.isNaN(H)&&H===0)return!1}}if(X){let F=J.getBoundingClientRect();if(F.width!==0||F.height!==0){let H=window.innerHeight||document.documentElement.clientHeight,A=window.innerWidth||document.documentElement.clientWidth,E=F.bottom<=0||F.top>=H,G=F.right<=0||F.left>=A;if(E||G)return!1}}return!0};var p,L,dQ=()=>{if(L!==void 0)return L;if(typeof document>"u")return L=null,null;return p=document.createElement("canvas"),L=p.getContext("2d"),L},HQ=()=>{p=void 0,L=void 0},OQ=(J,Q={})=>{let{vertical:X=!0,horizontal:Y=!0}=Q,Z=J.getBoundingClientRect();if(Z.width===0&&Z.height===0)return!0;let _=window.innerHeight||document.documentElement.clientHeight,F=window.innerWidth||document.documentElement.clientWidth;if(X&&(Z.bottom<=0||Z.top>=_))return!1;if(Y&&(Z.right<=0||Z.left>=F))return!1;return!0},IQ=(J,Q,X=!1,Y='Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"')=>{let Z=dQ();if(!Z)return 0;let _=X?J.toUpperCase():J;return Z.font=`${Q}px ${Y}`,Z.measureText(_).width};var vQ=(J,Q="\uD83D\uDE80")=>{let X=0,Y=J+Q;for(let Z=0;Z<Y.length;Z++){let _=Y.charCodeAt(Z);X=(X<<5)-X+_,X|=0}return(X>>>0).toString(16)},RQ=(J)=>{return`${vQ(J)}::${J}`},kQ=(J,Q)=>{return(X)=>{if(!(X instanceof CustomEvent))return;try{J(X.detail)}catch(Y){if(Q)Q(Y);else console.error("Event listener error:",Y)}}},TQ=(J,Q)=>{if(!J)return;let X=RQ(J);window.dispatchEvent(new CustomEvent(X,{detail:Q,bubbles:!0,cancelable:!1}))},x=(J,Q,X={})=>{if(!J||typeof Q!=="function")return()=>{};let Y=kQ(Q,X.onError),Z=RQ(J);return window.addEventListener(Z,Y),()=>window.removeEventListener(Z,Y)},MQ=(J,Q,X={})=>{if(!J||typeof Q!=="function")return()=>{};let Y=x(J,(Z)=>{Y(),Q(Z)},X);return Y};var zQ=require("react");var AQ=(J,Q,X=[])=>{zQ.useEffect(()=>{if(!J||typeof Q!=="function")return;return x(J,Q)},[J,Q,...X])};var KQ=(J,Q)=>{return N(J,Q,new WeakMap)},N=(J,Q,X)=>{if(Object.is(J,Q))return!0;if(J instanceof Date&&Q instanceof Date)return J.getTime()===Q.getTime();if(J instanceof RegExp&&Q instanceof RegExp)return J.source===Q.source&&J.flags===Q.flags;if(J instanceof Error&&Q instanceof Error)return J.name===Q.name&&J.message===Q.message;if(J instanceof ArrayBuffer&&Q instanceof ArrayBuffer){if(J.byteLength!==Q.byteLength)return!1;return SQ(new Uint8Array(J),new Uint8Array(Q))}if(ArrayBuffer.isView(J)&&ArrayBuffer.isView(Q)){if(J.constructor!==Q.constructor)return!1;if(J.byteLength!==Q.byteLength)return!1;let Y=new Uint8Array(J.buffer,J.byteOffset,J.byteLength),Z=new Uint8Array(Q.buffer,Q.byteOffset,Q.byteLength);return SQ(Y,Z)}if(typeof J==="object"&&J!==null&&typeof Q==="object"&&Q!==null){let Y=X.get(J);if(Y?.has(Q))return!0;if(Y)Y.add(Q);else X.set(J,new WeakSet([Q]))}if(Array.isArray(J)&&Array.isArray(Q)){if(J.length!==Q.length)return!1;for(let Y=0;Y<J.length;Y++)if(!N(J[Y],Q[Y],X))return!1;return!0}if(J instanceof Set&&Q instanceof Set){if(J.size!==Q.size)return!1;let Y=Array.from(Q);for(let Z of J){let _=Y.findIndex((F)=>N(Z,F,X));if(_===-1)return!1;Y.splice(_,1)}return!0}if(J instanceof Map&&Q instanceof Map){if(J.size!==Q.size)return!1;for(let[Y,Z]of J)if(!Q.has(Y)||!N(Z,Q.get(Y),X))return!1;return!0}if(J!==null&&typeof J==="object"&&Q!==null&&typeof Q==="object"){let Y=J,Z=Q,_=Object.keys(Y);if(_.length!==Object.keys(Z).length)return!1;for(let F of _)if(!N(Y[F],Z[F],X))return!1;return!0}return!1},SQ=(J,Q)=>{for(let X=0;X<J.length;X++)if(J[X]!==Q[X])return!1;return!0};var hQ={};module.exports=P(hQ);var yQ={};V(yQ,{words:()=>bJ,useEventBus:()=>AQ,uncapitalize:()=>yJ,truncate:()=>jJ,titleCase:()=>kJ,timeout:()=>DJ,stringifyBigIntValues:()=>m,storageSetItemWithTTL:()=>JQ,storageSetItem:()=>h,storageRemoveItem:()=>j,storageGetItemWithTTL:()=>QQ,storageGetItem:()=>y,storageGetAllKeys:()=>$Q,storageExists:()=>GQ,storageClearBySuffix:()=>ZQ,storageClearByPrefixOrSuffix:()=>C,storageClearByPrefix:()=>YQ,storageClear:()=>XQ,storageCalculateSize:()=>_Q,snakeCase:()=>vJ,slugify:()=>mJ,sleep:()=>k,setStyleProperties:()=>WQ,retry:()=>wJ,pickBy:()=>d,pick:()=>TJ,pascalCase:()=>CJ,parallelLimit:()=>NJ,omitBy:()=>MJ,omit:()=>RJ,merge:()=>LJ,mapValues:()=>zJ,mapKeys:()=>AJ,lines:()=>lJ,keysOf:()=>EJ,kebabCase:()=>dJ,isUndefined:()=>XJ,isString:()=>e,isSet:()=>HJ,isRegExp:()=>FJ,isRecord:()=>QJ,isPromise:()=>WJ,isPrimitive:()=>OJ,isObject:()=>D,isNumber:()=>a,isNull:()=>YJ,isNil:()=>ZJ,isMap:()=>BJ,isInViewport:()=>OQ,isFunction:()=>JJ,isError:()=>UJ,isEqual:()=>KQ,isEmpty:()=>IJ,isDefined:()=>GJ,isDate:()=>_J,isCacheStorageSupported:()=>f,isBrowser:()=>UQ,isBoolean:()=>t,isArray:()=>$J,invert:()=>KJ,hasOwn:()=>PJ,groupBy:()=>SJ,fromEntries:()=>qJ,escapeRegExp:()=>uJ,escapeHtml:()=>pJ,entriesOf:()=>VJ,defer:()=>xJ,deepMerge:()=>v,deepClone:()=>FQ,checkVisibility:()=>BQ,capitalizeFirstLetter:()=>gJ,capitalize:()=>hJ,camelCase:()=>fJ,calculateRenderedTextWidth:()=>IQ,cacheResponseKeys:()=>rJ,cachePutResponse:()=>cJ,cacheNames:()=>tJ,cacheMatchResponse:()=>nJ,cacheHasResponse:()=>oJ,cacheExists:()=>aJ,cacheDeleteResponse:()=>iJ,cacheDelete:()=>eJ,cacheClear:()=>sJ,busSubscribe:()=>x,busOnce:()=>MQ,busDispatch:()=>TQ,__resetTextMeasurementCache:()=>HQ});module.exports=P(yQ);
|